├── .commitlintrc.js
├── .eslintrc.js
├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── bug.yml
│ └── config.yml
├── actions
│ ├── create-check
│ │ └── action.yml
│ └── install-latest-npm
│ │ └── action.yml
├── dependabot.yml
├── matchers
│ └── tap.json
├── settings.yml
└── workflows
│ ├── audit.yml
│ ├── ci-release.yml
│ ├── ci.yml
│ ├── codeql-analysis.yml
│ ├── post-dependabot.yml
│ ├── pull-request.yml
│ ├── release-integration.yml
│ └── release.yml
├── .gitignore
├── .npmrc
├── .release-please-manifest.json
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SECURITY.md
├── bin
└── index.js
├── lib
├── dir.js
├── fetcher.js
├── file.js
├── git.js
├── index.js
├── registry.js
├── remote.js
└── util
│ ├── add-git-sha.js
│ ├── cache-dir.js
│ ├── is-package-bin.js
│ ├── npm.js
│ ├── protected.js
│ ├── tar-create-options.js
│ └── trailing-slashes.js
├── package.json
├── release-please-config.json
├── tap-snapshots
└── test
│ ├── bin.js.test.cjs
│ ├── dir.js.test.cjs
│ ├── fetcher.js-fake-sudo.test.cjs
│ ├── fetcher.js.test.cjs
│ ├── file.js.test.cjs
│ ├── index.js.test.cjs
│ ├── remote.js.test.cjs
│ └── util
│ └── npm.js.test.cjs
└── test
├── bin.js
├── dir.js
├── fetcher.js
├── file.js
├── fixtures
├── abbrev-1.1.1.tgz
├── abbrev-manifest-file.json
├── abbrev-manifest-min.json
├── abbrev-packument-file.json
├── abbrev-packument-full.json
├── abbrev-packument-min.json
├── abbrev
│ ├── LICENSE
│ ├── README.md
│ ├── abbrev.js
│ └── package.json
├── bin-good.tgz
├── bin-good
│ ├── package.json
│ └── script.js
├── bin-missing.tgz
├── bin-missing
│ └── package.json
├── bin-object.tgz
├── bin-object
│ ├── package.json
│ └── script.js
├── bin-string.tgz
├── bin-string
│ ├── package.json
│ └── script.js
├── npm-mock.js
├── prepack-script
│ ├── .gitignore
│ ├── .npmignore
│ ├── node_modules
│ │ └── abbrev
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── abbrev.js
│ │ │ └── package.json
│ ├── package-lock.json
│ ├── package.json
│ └── prepack.js
├── prepare-requires-gitignore-1.2.3.tgz
├── prepare-requires-gitignore
│ ├── .gitignore
│ ├── index.js
│ ├── package.json
│ └── prepare.js
├── prepare-script
│ ├── .gitignore
│ ├── .npmignore
│ ├── node_modules
│ │ └── abbrev
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── abbrev.js
│ │ │ └── package.json
│ ├── package-lock.json
│ ├── package.json
│ └── prepare.js
├── sigstore
│ ├── invalid-attestations.json
│ ├── malformed-subject-attestations.json
│ ├── mismatched-keyid-attestations.json
│ ├── mismatched-subject-digest-attestations.json
│ ├── mismatched-subject-name-attestations.json
│ ├── no-keyid-attestations.json
│ ├── unsupported-attestations.json
│ └── valid-attestations.json
├── tnock.js
└── weird-pkg.tgz
├── git.js
├── helpers
├── clean-snapshot.js
└── script-mode.js
├── index.js
├── registry.js
├── remote.js
└── util
├── add-git-sha.js
├── cache-dir.js
├── is-package-bin.js
├── npm.js
└── tar-create-options.js
/.commitlintrc.js:
--------------------------------------------------------------------------------
1 | /* This file is automatically added by @npmcli/template-oss. Do not edit. */
2 |
3 | module.exports = {
4 | extends: ['@commitlint/config-conventional'],
5 | rules: {
6 | 'type-enum': [2, 'always', ['feat', 'fix', 'docs', 'deps', 'chore']],
7 | 'header-max-length': [2, 'always', 80],
8 | 'subject-case': [0],
9 | 'body-max-line-length': [0],
10 | 'footer-max-line-length': [0],
11 | },
12 | }
13 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | /* This file is automatically added by @npmcli/template-oss. Do not edit. */
2 |
3 | 'use strict'
4 |
5 | const { readdirSync: readdir } = require('fs')
6 |
7 | const localConfigs = readdir(__dirname)
8 | .filter((file) => file.startsWith('.eslintrc.local.'))
9 | .map((file) => `./${file}`)
10 |
11 | module.exports = {
12 | root: true,
13 | ignorePatterns: [
14 | 'tap-testdir*/',
15 | ],
16 | extends: [
17 | '@npmcli',
18 | ...localConfigs,
19 | ],
20 | }
21 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | * @npm/cli-team
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug.yml:
--------------------------------------------------------------------------------
1 | # This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | name: Bug
4 | description: File a bug/issue
5 | title: "[BUG]
"
6 | labels: [ Bug, Needs Triage ]
7 |
8 | body:
9 | - type: checkboxes
10 | attributes:
11 | label: Is there an existing issue for this?
12 | description: Please [search here](./issues) to see if an issue already exists for your problem.
13 | options:
14 | - label: I have searched the existing issues
15 | required: true
16 | - type: textarea
17 | attributes:
18 | label: Current Behavior
19 | description: A clear & concise description of what you're experiencing.
20 | validations:
21 | required: false
22 | - type: textarea
23 | attributes:
24 | label: Expected Behavior
25 | description: A clear & concise description of what you expected to happen.
26 | validations:
27 | required: false
28 | - type: textarea
29 | attributes:
30 | label: Steps To Reproduce
31 | description: Steps to reproduce the behavior.
32 | value: |
33 | 1. In this environment...
34 | 2. With this config...
35 | 3. Run '...'
36 | 4. See error...
37 | validations:
38 | required: false
39 | - type: textarea
40 | attributes:
41 | label: Environment
42 | description: |
43 | examples:
44 | - **npm**: 7.6.3
45 | - **Node**: 13.14.0
46 | - **OS**: Ubuntu 20.04
47 | - **platform**: Macbook Pro
48 | value: |
49 | - npm:
50 | - Node:
51 | - OS:
52 | - platform:
53 | validations:
54 | required: false
55 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | # This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | blank_issues_enabled: true
4 |
--------------------------------------------------------------------------------
/.github/actions/create-check/action.yml:
--------------------------------------------------------------------------------
1 | # This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | name: 'Create Check'
4 | inputs:
5 | name:
6 | required: true
7 | token:
8 | required: true
9 | sha:
10 | required: true
11 | check-name:
12 | default: ''
13 | outputs:
14 | check-id:
15 | value: ${{ steps.create-check.outputs.check_id }}
16 | runs:
17 | using: "composite"
18 | steps:
19 | - name: Get Workflow Job
20 | uses: actions/github-script@v7
21 | id: workflow
22 | env:
23 | JOB_NAME: "${{ inputs.name }}"
24 | SHA: "${{ inputs.sha }}"
25 | with:
26 | result-encoding: string
27 | script: |
28 | const { repo: { owner, repo}, runId, serverUrl } = context
29 | const { JOB_NAME, SHA } = process.env
30 |
31 | const job = await github.rest.actions.listJobsForWorkflowRun({
32 | owner,
33 | repo,
34 | run_id: runId,
35 | per_page: 100
36 | }).then(r => r.data.jobs.find(j => j.name.endsWith(JOB_NAME)))
37 |
38 | return [
39 | `This check is assosciated with ${serverUrl}/${owner}/${repo}/commit/${SHA}.`,
40 | 'Run logs:',
41 | job?.html_url || `could not be found for a job ending with: "${JOB_NAME}"`,
42 | ].join(' ')
43 | - name: Create Check
44 | uses: LouisBrunner/checks-action@v1.6.0
45 | id: create-check
46 | with:
47 | token: ${{ inputs.token }}
48 | sha: ${{ inputs.sha }}
49 | status: in_progress
50 | name: ${{ inputs.check-name || inputs.name }}
51 | output: |
52 | {"summary":"${{ steps.workflow.outputs.result }}"}
53 |
--------------------------------------------------------------------------------
/.github/actions/install-latest-npm/action.yml:
--------------------------------------------------------------------------------
1 | # This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | name: 'Install Latest npm'
4 | description: 'Install the latest version of npm compatible with the Node version'
5 | inputs:
6 | node:
7 | description: 'Current Node version'
8 | required: true
9 | runs:
10 | using: "composite"
11 | steps:
12 | # node 10/12/14 ship with npm@6, which is known to fail when updating itself in windows
13 | - name: Update Windows npm
14 | if: |
15 | runner.os == 'Windows' && (
16 | startsWith(inputs.node, 'v10.') ||
17 | startsWith(inputs.node, 'v12.') ||
18 | startsWith(inputs.node, 'v14.')
19 | )
20 | shell: cmd
21 | run: |
22 | curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz
23 | tar xf npm-7.5.4.tgz
24 | cd package
25 | node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz
26 | cd ..
27 | rmdir /s /q package
28 | - name: Install Latest npm
29 | shell: bash
30 | env:
31 | NODE_VERSION: ${{ inputs.node }}
32 | working-directory: ${{ runner.temp }}
33 | run: |
34 | MATCH=""
35 | SPECS=("latest" "next-10" "next-9" "next-8" "next-7" "next-6")
36 |
37 | echo "node@$NODE_VERSION"
38 |
39 | for SPEC in ${SPECS[@]}; do
40 | ENGINES=$(npm view npm@$SPEC --json | jq -r '.engines.node')
41 | echo "Checking if node@$NODE_VERSION satisfies npm@$SPEC ($ENGINES)"
42 |
43 | if npx semver -r "$ENGINES" "$NODE_VERSION" > /dev/null; then
44 | MATCH=$SPEC
45 | echo "Found compatible version: npm@$MATCH"
46 | break
47 | fi
48 | done
49 |
50 | if [ -z $MATCH ]; then
51 | echo "Could not find a compatible version of npm for node@$NODE_VERSION"
52 | exit 1
53 | fi
54 |
55 | npm i --prefer-online --no-fund --no-audit -g npm@$MATCH
56 | - name: npm Version
57 | shell: bash
58 | run: npm -v
59 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | version: 2
4 |
5 | updates:
6 | - package-ecosystem: npm
7 | directory: /
8 | schedule:
9 | interval: daily
10 | target-branch: "main"
11 | allow:
12 | - dependency-type: direct
13 | versioning-strategy: increase-if-necessary
14 | commit-message:
15 | prefix: deps
16 | prefix-development: chore
17 | labels:
18 | - "Dependencies"
19 | open-pull-requests-limit: 10
20 |
--------------------------------------------------------------------------------
/.github/matchers/tap.json:
--------------------------------------------------------------------------------
1 | {
2 | "//@npmcli/template-oss": "This file is automatically added by @npmcli/template-oss. Do not edit.",
3 | "problemMatcher": [
4 | {
5 | "owner": "tap",
6 | "pattern": [
7 | {
8 | "regexp": "^\\s*not ok \\d+ - (.*)",
9 | "message": 1
10 | },
11 | {
12 | "regexp": "^\\s*---"
13 | },
14 | {
15 | "regexp": "^\\s*at:"
16 | },
17 | {
18 | "regexp": "^\\s*line:\\s*(\\d+)",
19 | "line": 1
20 | },
21 | {
22 | "regexp": "^\\s*column:\\s*(\\d+)",
23 | "column": 1
24 | },
25 | {
26 | "regexp": "^\\s*file:\\s*(.*)",
27 | "file": 1
28 | }
29 | ]
30 | }
31 | ]
32 | }
33 |
--------------------------------------------------------------------------------
/.github/settings.yml:
--------------------------------------------------------------------------------
1 | # This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | repository:
4 | allow_merge_commit: false
5 | allow_rebase_merge: true
6 | allow_squash_merge: true
7 | squash_merge_commit_title: PR_TITLE
8 | squash_merge_commit_message: PR_BODY
9 | delete_branch_on_merge: true
10 | enable_automated_security_fixes: true
11 | enable_vulnerability_alerts: true
12 |
13 | branches:
14 | - name: main
15 | protection:
16 | required_status_checks: null
17 | enforce_admins: true
18 | block_creations: true
19 | required_pull_request_reviews:
20 | required_approving_review_count: 1
21 | require_code_owner_reviews: true
22 | require_last_push_approval: true
23 | dismiss_stale_reviews: true
24 | restrictions:
25 | apps: []
26 | users: []
27 | teams: [ "cli-team" ]
28 |
--------------------------------------------------------------------------------
/.github/workflows/audit.yml:
--------------------------------------------------------------------------------
1 | # This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | name: Audit
4 |
5 | on:
6 | workflow_dispatch:
7 | schedule:
8 | # "At 08:00 UTC (01:00 PT) on Monday" https://crontab.guru/#0_8_*_*_1
9 | - cron: "0 8 * * 1"
10 |
11 | jobs:
12 | audit:
13 | name: Audit Dependencies
14 | if: github.repository_owner == 'npm'
15 | runs-on: ubuntu-latest
16 | defaults:
17 | run:
18 | shell: bash
19 | steps:
20 | - name: Checkout
21 | uses: actions/checkout@v4
22 | - name: Setup Git User
23 | run: |
24 | git config --global user.email "npm-cli+bot@github.com"
25 | git config --global user.name "npm CLI robot"
26 | - name: Setup Node
27 | uses: actions/setup-node@v4
28 | id: node
29 | with:
30 | node-version: 22.x
31 | check-latest: contains('22.x', '.x')
32 | - name: Install Latest npm
33 | uses: ./.github/actions/install-latest-npm
34 | with:
35 | node: ${{ steps.node.outputs.node-version }}
36 | - name: Install Dependencies
37 | run: npm i --ignore-scripts --no-audit --no-fund --package-lock
38 | - name: Run Production Audit
39 | run: npm audit --omit=dev
40 | - name: Run Full Audit
41 | run: npm audit --audit-level=none
42 |
--------------------------------------------------------------------------------
/.github/workflows/ci-release.yml:
--------------------------------------------------------------------------------
1 | # This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | name: CI - Release
4 |
5 | on:
6 | workflow_dispatch:
7 | inputs:
8 | ref:
9 | required: true
10 | type: string
11 | default: main
12 | workflow_call:
13 | inputs:
14 | ref:
15 | required: true
16 | type: string
17 | check-sha:
18 | required: true
19 | type: string
20 |
21 | jobs:
22 | lint-all:
23 | name: Lint All
24 | if: github.repository_owner == 'npm'
25 | runs-on: ubuntu-latest
26 | defaults:
27 | run:
28 | shell: bash
29 | steps:
30 | - name: Checkout
31 | uses: actions/checkout@v4
32 | with:
33 | ref: ${{ inputs.ref }}
34 | - name: Setup Git User
35 | run: |
36 | git config --global user.email "npm-cli+bot@github.com"
37 | git config --global user.name "npm CLI robot"
38 | - name: Create Check
39 | id: create-check
40 | if: ${{ inputs.check-sha }}
41 | uses: ./.github/actions/create-check
42 | with:
43 | name: "Lint All"
44 | token: ${{ secrets.GITHUB_TOKEN }}
45 | sha: ${{ inputs.check-sha }}
46 | - name: Setup Node
47 | uses: actions/setup-node@v4
48 | id: node
49 | with:
50 | node-version: 22.x
51 | check-latest: contains('22.x', '.x')
52 | - name: Install Latest npm
53 | uses: ./.github/actions/install-latest-npm
54 | with:
55 | node: ${{ steps.node.outputs.node-version }}
56 | - name: Install Dependencies
57 | run: npm i --ignore-scripts --no-audit --no-fund
58 | - name: Lint
59 | run: npm run lint --ignore-scripts
60 | - name: Post Lint
61 | run: npm run postlint --ignore-scripts
62 | - name: Conclude Check
63 | uses: LouisBrunner/checks-action@v1.6.0
64 | if: steps.create-check.outputs.check-id && always()
65 | with:
66 | token: ${{ secrets.GITHUB_TOKEN }}
67 | conclusion: ${{ job.status }}
68 | check_id: ${{ steps.create-check.outputs.check-id }}
69 |
70 | test-all:
71 | name: Test All - ${{ matrix.platform.name }} - ${{ matrix.node-version }}
72 | if: github.repository_owner == 'npm'
73 | strategy:
74 | fail-fast: false
75 | matrix:
76 | platform:
77 | - name: Linux
78 | os: ubuntu-latest
79 | shell: bash
80 | - name: macOS
81 | os: macos-latest
82 | shell: bash
83 | - name: macOS
84 | os: macos-13
85 | shell: bash
86 | node-version:
87 | - 20.17.0
88 | - 20.x
89 | - 22.9.0
90 | - 22.x
91 | exclude:
92 | - platform: { name: macOS, os: macos-13, shell: bash }
93 | node-version: 20.17.0
94 | - platform: { name: macOS, os: macos-13, shell: bash }
95 | node-version: 20.x
96 | - platform: { name: macOS, os: macos-13, shell: bash }
97 | node-version: 22.9.0
98 | - platform: { name: macOS, os: macos-13, shell: bash }
99 | node-version: 22.x
100 | runs-on: ${{ matrix.platform.os }}
101 | defaults:
102 | run:
103 | shell: ${{ matrix.platform.shell }}
104 | steps:
105 | - name: Checkout
106 | uses: actions/checkout@v4
107 | with:
108 | ref: ${{ inputs.ref }}
109 | - name: Setup Git User
110 | run: |
111 | git config --global user.email "npm-cli+bot@github.com"
112 | git config --global user.name "npm CLI robot"
113 | - name: Create Check
114 | id: create-check
115 | if: ${{ inputs.check-sha }}
116 | uses: ./.github/actions/create-check
117 | with:
118 | name: "Test All - ${{ matrix.platform.name }} - ${{ matrix.node-version }}"
119 | token: ${{ secrets.GITHUB_TOKEN }}
120 | sha: ${{ inputs.check-sha }}
121 | - name: Setup Node
122 | uses: actions/setup-node@v4
123 | id: node
124 | with:
125 | node-version: ${{ matrix.node-version }}
126 | check-latest: contains(matrix.node-version, '.x')
127 | - name: Install Latest npm
128 | uses: ./.github/actions/install-latest-npm
129 | with:
130 | node: ${{ steps.node.outputs.node-version }}
131 | - name: Install Dependencies
132 | run: npm i --ignore-scripts --no-audit --no-fund
133 | - name: Add Problem Matcher
134 | run: echo "::add-matcher::.github/matchers/tap.json"
135 | - name: Test
136 | run: npm test --ignore-scripts
137 | - name: Conclude Check
138 | uses: LouisBrunner/checks-action@v1.6.0
139 | if: steps.create-check.outputs.check-id && always()
140 | with:
141 | token: ${{ secrets.GITHUB_TOKEN }}
142 | conclusion: ${{ job.status }}
143 | check_id: ${{ steps.create-check.outputs.check-id }}
144 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | # This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | name: CI
4 |
5 | on:
6 | workflow_dispatch:
7 | pull_request:
8 | push:
9 | branches:
10 | - main
11 | schedule:
12 | # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1
13 | - cron: "0 9 * * 1"
14 |
15 | jobs:
16 | lint:
17 | name: Lint
18 | if: github.repository_owner == 'npm'
19 | runs-on: ubuntu-latest
20 | defaults:
21 | run:
22 | shell: bash
23 | steps:
24 | - name: Checkout
25 | uses: actions/checkout@v4
26 | - name: Setup Git User
27 | run: |
28 | git config --global user.email "npm-cli+bot@github.com"
29 | git config --global user.name "npm CLI robot"
30 | - name: Setup Node
31 | uses: actions/setup-node@v4
32 | id: node
33 | with:
34 | node-version: 22.x
35 | check-latest: contains('22.x', '.x')
36 | - name: Install Latest npm
37 | uses: ./.github/actions/install-latest-npm
38 | with:
39 | node: ${{ steps.node.outputs.node-version }}
40 | - name: Install Dependencies
41 | run: npm i --ignore-scripts --no-audit --no-fund
42 | - name: Lint
43 | run: npm run lint --ignore-scripts
44 | - name: Post Lint
45 | run: npm run postlint --ignore-scripts
46 |
47 | test:
48 | name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }}
49 | if: github.repository_owner == 'npm'
50 | strategy:
51 | fail-fast: false
52 | matrix:
53 | platform:
54 | - name: Linux
55 | os: ubuntu-latest
56 | shell: bash
57 | - name: macOS
58 | os: macos-latest
59 | shell: bash
60 | - name: macOS
61 | os: macos-13
62 | shell: bash
63 | node-version:
64 | - 20.17.0
65 | - 20.x
66 | - 22.9.0
67 | - 22.x
68 | exclude:
69 | - platform: { name: macOS, os: macos-13, shell: bash }
70 | node-version: 20.17.0
71 | - platform: { name: macOS, os: macos-13, shell: bash }
72 | node-version: 20.x
73 | - platform: { name: macOS, os: macos-13, shell: bash }
74 | node-version: 22.9.0
75 | - platform: { name: macOS, os: macos-13, shell: bash }
76 | node-version: 22.x
77 | runs-on: ${{ matrix.platform.os }}
78 | defaults:
79 | run:
80 | shell: ${{ matrix.platform.shell }}
81 | steps:
82 | - name: Checkout
83 | uses: actions/checkout@v4
84 | - name: Setup Git User
85 | run: |
86 | git config --global user.email "npm-cli+bot@github.com"
87 | git config --global user.name "npm CLI robot"
88 | - name: Setup Node
89 | uses: actions/setup-node@v4
90 | id: node
91 | with:
92 | node-version: ${{ matrix.node-version }}
93 | check-latest: contains(matrix.node-version, '.x')
94 | - name: Install Latest npm
95 | uses: ./.github/actions/install-latest-npm
96 | with:
97 | node: ${{ steps.node.outputs.node-version }}
98 | - name: Install Dependencies
99 | run: npm i --ignore-scripts --no-audit --no-fund
100 | - name: Add Problem Matcher
101 | run: echo "::add-matcher::.github/matchers/tap.json"
102 | - name: Test
103 | run: npm test --ignore-scripts
104 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | name: CodeQL
4 |
5 | on:
6 | push:
7 | branches:
8 | - main
9 | pull_request:
10 | branches:
11 | - main
12 | schedule:
13 | # "At 10:00 UTC (03:00 PT) on Monday" https://crontab.guru/#0_10_*_*_1
14 | - cron: "0 10 * * 1"
15 |
16 | jobs:
17 | analyze:
18 | name: Analyze
19 | runs-on: ubuntu-latest
20 | permissions:
21 | actions: read
22 | contents: read
23 | security-events: write
24 | steps:
25 | - name: Checkout
26 | uses: actions/checkout@v4
27 | - name: Setup Git User
28 | run: |
29 | git config --global user.email "npm-cli+bot@github.com"
30 | git config --global user.name "npm CLI robot"
31 | - name: Initialize CodeQL
32 | uses: github/codeql-action/init@v3
33 | with:
34 | languages: javascript
35 | - name: Perform CodeQL Analysis
36 | uses: github/codeql-action/analyze@v3
37 |
--------------------------------------------------------------------------------
/.github/workflows/post-dependabot.yml:
--------------------------------------------------------------------------------
1 | # This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | name: Post Dependabot
4 |
5 | on: pull_request
6 |
7 | permissions:
8 | contents: write
9 |
10 | jobs:
11 | template-oss:
12 | name: template-oss
13 | if: github.repository_owner == 'npm' && github.actor == 'dependabot[bot]'
14 | runs-on: ubuntu-latest
15 | defaults:
16 | run:
17 | shell: bash
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@v4
21 | with:
22 | ref: ${{ github.event.pull_request.head.ref }}
23 | - name: Setup Git User
24 | run: |
25 | git config --global user.email "npm-cli+bot@github.com"
26 | git config --global user.name "npm CLI robot"
27 | - name: Setup Node
28 | uses: actions/setup-node@v4
29 | id: node
30 | with:
31 | node-version: 22.x
32 | check-latest: contains('22.x', '.x')
33 | - name: Install Latest npm
34 | uses: ./.github/actions/install-latest-npm
35 | with:
36 | node: ${{ steps.node.outputs.node-version }}
37 | - name: Install Dependencies
38 | run: npm i --ignore-scripts --no-audit --no-fund
39 | - name: Fetch Dependabot Metadata
40 | id: metadata
41 | uses: dependabot/fetch-metadata@v1
42 | with:
43 | github-token: ${{ secrets.GITHUB_TOKEN }}
44 |
45 | # Dependabot can update multiple directories so we output which directory
46 | # it is acting on so we can run the command for the correct root or workspace
47 | - name: Get Dependabot Directory
48 | if: contains(steps.metadata.outputs.dependency-names, '@npmcli/template-oss')
49 | id: flags
50 | run: |
51 | dependabot_dir="${{ steps.metadata.outputs.directory }}"
52 | if [[ "$dependabot_dir" == "/" || "$dependabot_dir" == "/main" ]]; then
53 | echo "workspace=-iwr" >> $GITHUB_OUTPUT
54 | else
55 | # strip leading slash from directory so it works as a
56 | # a path to the workspace flag
57 | echo "workspace=-w ${dependabot_dir#/}" >> $GITHUB_OUTPUT
58 | fi
59 |
60 | - name: Apply Changes
61 | if: steps.flags.outputs.workspace
62 | id: apply
63 | run: |
64 | npm run template-oss-apply ${{ steps.flags.outputs.workspace }}
65 | if [[ `git status --porcelain` ]]; then
66 | echo "changes=true" >> $GITHUB_OUTPUT
67 | fi
68 | # This only sets the conventional commit prefix. This workflow can't reliably determine
69 | # what the breaking change is though. If a BREAKING CHANGE message is required then
70 | # this PR check will fail and the commit will be amended with stafftools
71 | if [[ "${{ steps.metadata.outputs.update-type }}" == "version-update:semver-major" ]]; then
72 | prefix='feat!'
73 | else
74 | prefix='chore'
75 | fi
76 | echo "message=$prefix: postinstall for dependabot template-oss PR" >> $GITHUB_OUTPUT
77 |
78 | # This step will fail if template-oss has made any workflow updates. It is impossible
79 | # for a workflow to update other workflows. In the case it does fail, we continue
80 | # and then try to apply only a portion of the changes in the next step
81 | - name: Push All Changes
82 | if: steps.apply.outputs.changes
83 | id: push
84 | continue-on-error: true
85 | env:
86 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
87 | run: |
88 | git commit -am "${{ steps.apply.outputs.message }}"
89 | git push
90 |
91 | # If the previous step failed, then reset the commit and remove any workflow changes
92 | # and attempt to commit and push again. This is helpful because we will have a commit
93 | # with the correct prefix that we can then --amend with @npmcli/stafftools later.
94 | - name: Push All Changes Except Workflows
95 | if: steps.apply.outputs.changes && steps.push.outcome == 'failure'
96 | env:
97 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
98 | run: |
99 | git reset HEAD~
100 | git checkout HEAD -- .github/workflows/
101 | git clean -fd .github/workflows/
102 | git commit -am "${{ steps.apply.outputs.message }}"
103 | git push
104 |
105 | # Check if all the necessary template-oss changes were applied. Since we continued
106 | # on errors in one of the previous steps, this check will fail if our follow up
107 | # only applied a portion of the changes and we need to followup manually.
108 | #
109 | # Note that this used to run `lint` and `postlint` but that will fail this action
110 | # if we've also shipped any linting changes separate from template-oss. We do
111 | # linting in another action, so we want to fail this one only if there are
112 | # template-oss changes that could not be applied.
113 | - name: Check Changes
114 | if: steps.apply.outputs.changes
115 | run: |
116 | npm exec --offline ${{ steps.flags.outputs.workspace }} -- template-oss-check
117 |
118 | - name: Fail on Breaking Change
119 | if: steps.apply.outputs.changes && startsWith(steps.apply.outputs.message, 'feat!')
120 | run: |
121 | echo "This PR has a breaking change. Run 'npx -p @npmcli/stafftools gh template-oss-fix'"
122 | echo "for more information on how to fix this with a BREAKING CHANGE footer."
123 | exit 1
124 |
--------------------------------------------------------------------------------
/.github/workflows/pull-request.yml:
--------------------------------------------------------------------------------
1 | # This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | name: Pull Request
4 |
5 | on:
6 | pull_request:
7 | types:
8 | - opened
9 | - reopened
10 | - edited
11 | - synchronize
12 |
13 | jobs:
14 | commitlint:
15 | name: Lint Commits
16 | if: github.repository_owner == 'npm'
17 | runs-on: ubuntu-latest
18 | defaults:
19 | run:
20 | shell: bash
21 | steps:
22 | - name: Checkout
23 | uses: actions/checkout@v4
24 | with:
25 | fetch-depth: 0
26 | - name: Setup Git User
27 | run: |
28 | git config --global user.email "npm-cli+bot@github.com"
29 | git config --global user.name "npm CLI robot"
30 | - name: Setup Node
31 | uses: actions/setup-node@v4
32 | id: node
33 | with:
34 | node-version: 22.x
35 | check-latest: contains('22.x', '.x')
36 | - name: Install Latest npm
37 | uses: ./.github/actions/install-latest-npm
38 | with:
39 | node: ${{ steps.node.outputs.node-version }}
40 | - name: Install Dependencies
41 | run: npm i --ignore-scripts --no-audit --no-fund
42 | - name: Run Commitlint on Commits
43 | id: commit
44 | continue-on-error: true
45 | run: npx --offline commitlint -V --from 'origin/${{ github.base_ref }}' --to ${{ github.event.pull_request.head.sha }}
46 | - name: Run Commitlint on PR Title
47 | if: steps.commit.outcome == 'failure'
48 | env:
49 | PR_TITLE: ${{ github.event.pull_request.title }}
50 | run: echo "$PR_TITLE" | npx --offline commitlint -V
51 |
--------------------------------------------------------------------------------
/.github/workflows/release-integration.yml:
--------------------------------------------------------------------------------
1 | # This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | name: Release Integration
4 |
5 | on:
6 | workflow_dispatch:
7 | inputs:
8 | releases:
9 | required: true
10 | type: string
11 | description: 'A json array of releases. Required fields: publish: tagName, publishTag. publish check: pkgName, version'
12 | workflow_call:
13 | inputs:
14 | releases:
15 | required: true
16 | type: string
17 | description: 'A json array of releases. Required fields: publish: tagName, publishTag. publish check: pkgName, version'
18 | secrets:
19 | PUBLISH_TOKEN:
20 | required: true
21 |
22 | jobs:
23 | publish:
24 | name: Publish
25 | runs-on: ubuntu-latest
26 | defaults:
27 | run:
28 | shell: bash
29 | permissions:
30 | id-token: write
31 | steps:
32 | - name: Checkout
33 | uses: actions/checkout@v4
34 | with:
35 | ref: ${{ fromJSON(inputs.releases)[0].tagName }}
36 | - name: Setup Git User
37 | run: |
38 | git config --global user.email "npm-cli+bot@github.com"
39 | git config --global user.name "npm CLI robot"
40 | - name: Setup Node
41 | uses: actions/setup-node@v4
42 | id: node
43 | with:
44 | node-version: 22.x
45 | check-latest: contains('22.x', '.x')
46 | - name: Install Latest npm
47 | uses: ./.github/actions/install-latest-npm
48 | with:
49 | node: ${{ steps.node.outputs.node-version }}
50 | - name: Install Dependencies
51 | run: npm i --ignore-scripts --no-audit --no-fund
52 | - name: Set npm authToken
53 | run: npm config set '//registry.npmjs.org/:_authToken'=\${PUBLISH_TOKEN}
54 | - name: Publish
55 | env:
56 | PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }}
57 | RELEASES: ${{ inputs.releases }}
58 | run: |
59 | EXIT_CODE=0
60 |
61 | for release in $(echo $RELEASES | jq -r '.[] | @base64'); do
62 | PUBLISH_TAG=$(echo "$release" | base64 --decode | jq -r .publishTag)
63 | npm publish --provenance --tag="$PUBLISH_TAG"
64 | STATUS=$?
65 | if [[ "$STATUS" -eq 1 ]]; then
66 | EXIT_CODE=$STATUS
67 | fi
68 | done
69 |
70 | exit $EXIT_CODE
71 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | # ignore everything in the root
4 | /*
5 |
6 | !**/.gitignore
7 | !/.commitlintrc.js
8 | !/.eslintrc.js
9 | !/.eslintrc.local.*
10 | !/.git-blame-ignore-revs
11 | !/.github/
12 | !/.gitignore
13 | !/.npmrc
14 | !/.prettierignore
15 | !/.prettierrc.js
16 | !/.release-please-manifest.json
17 | !/bin/
18 | !/CHANGELOG*
19 | !/CODE_OF_CONDUCT.md
20 | !/CONTRIBUTING.md
21 | !/docs/
22 | !/lib/
23 | !/LICENSE*
24 | !/map.js
25 | !/package.json
26 | !/README*
27 | !/release-please-config.json
28 | !/scripts/
29 | !/SECURITY.md
30 | !/tap-snapshots/
31 | !/test/
32 | !/tsconfig.json
33 | tap-testdir*/
34 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | ; This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | package-lock=false
4 |
--------------------------------------------------------------------------------
/.release-please-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | ".": "21.0.0"
3 | }
4 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | All interactions in this repo are covered by the [npm Code of
4 | Conduct](https://docs.npmjs.com/policies/conduct)
5 |
6 | The npm cli team may, at its own discretion, moderate, remove, or edit
7 | any interactions such as pull requests, issues, and comments.
8 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Contributing
4 |
5 | ## Code of Conduct
6 |
7 | All interactions in the **npm** organization on GitHub are considered to be covered by our standard [Code of Conduct](https://docs.npmjs.com/policies/conduct).
8 |
9 | ## Reporting Bugs
10 |
11 | Before submitting a new bug report please search for an existing or similar report.
12 |
13 | Use one of our existing issue templates if you believe you've come across a unique problem.
14 |
15 | Duplicate issues, or issues that don't use one of our templates may get closed without a response.
16 |
17 | ## Pull Request Conventions
18 |
19 | ### Commits
20 |
21 | We use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
22 |
23 | When opening a pull request please be sure that either the pull request title, or each commit in the pull request, has one of the following prefixes:
24 |
25 | - `feat`: For when introducing a new feature. The result will be a new semver minor version of the package when it is next published.
26 | - `fix`: For bug fixes. The result will be a new semver patch version of the package when it is next published.
27 | - `docs`: For documentation updates. The result will be a new semver patch version of the package when it is next published.
28 | - `chore`: For changes that do not affect the published module. Often these are changes to tests. The result will be *no* change to the version of the package when it is next published (as the commit does not affect the published version).
29 |
30 | ### Test Coverage
31 |
32 | Pull requests made against this repo will run `npm test` automatically. Please make sure tests pass locally before submitting a PR.
33 |
34 | Every new feature or bug fix should come with a corresponding test or tests that validate the solutions. Testing also reports on code coverage and will fail if code coverage drops.
35 |
36 | ### Linting
37 |
38 | Linting is also done automatically once tests pass. `npm run lintfix` will fix most linting errors automatically.
39 |
40 | Please make sure linting passes before submitting a PR.
41 |
42 | ## What _not_ to contribute?
43 |
44 | ### Dependencies
45 |
46 | It should be noted that our team does not accept third-party dependency updates/PRs. If you submit a PR trying to update our dependencies we will close it with or without a reference to these contribution guidelines.
47 |
48 | ### Tools/Automation
49 |
50 | Our core team is responsible for the maintenance of the tooling/automation in this project and we ask contributors to not make changes to these when contributing (e.g. `.github/*`, `.eslintrc.json`, `.licensee.json`). Most of those files also have a header at the top to remind folks they are automatically generated. Pull requests that alter these will not be accepted.
51 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The ISC License
2 |
3 | Copyright (c) Isaac Z. Schlueter, Kat Marchán, npm, Inc., and Contributors
4 |
5 | Permission to use, copy, modify, and/or distribute this software for any
6 | purpose with or without fee is hereby granted, provided that the above
7 | copyright notice and this permission notice appear in all copies.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
15 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | 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).
4 |
5 | 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.
6 |
7 | 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).
8 |
9 | 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.
10 |
11 | **Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.**
12 |
13 | Thanks for helping make GitHub safe for everyone.
14 |
--------------------------------------------------------------------------------
/bin/index.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const run = conf => {
4 | const pacote = require('../')
5 | switch (conf._[0]) {
6 | case 'resolve':
7 | case 'manifest':
8 | case 'packument':
9 | if (conf._[0] === 'resolve' && conf.long) {
10 | return pacote.manifest(conf._[1], conf).then(mani => ({
11 | resolved: mani._resolved,
12 | integrity: mani._integrity,
13 | from: mani._from,
14 | }))
15 | }
16 | return pacote[conf._[0]](conf._[1], conf)
17 |
18 | case 'tarball':
19 | if (!conf._[2] || conf._[2] === '-') {
20 | return pacote.tarball.stream(conf._[1], stream => {
21 | stream.pipe(
22 | conf.testStdout ||
23 | /* istanbul ignore next */
24 | process.stdout
25 | )
26 | // make sure it resolves something falsey
27 | return stream.promise().then(() => {
28 | return false
29 | })
30 | }, conf)
31 | } else {
32 | return pacote.tarball.file(conf._[1], conf._[2], conf)
33 | }
34 |
35 | case 'extract':
36 | return pacote.extract(conf._[1], conf._[2], conf)
37 |
38 | default: /* istanbul ignore next */ {
39 | throw new Error(`bad command: ${conf._[0]}`)
40 | }
41 | }
42 | }
43 |
44 | const version = require('../package.json').version
45 | const usage = () =>
46 | `Pacote - The JavaScript Package Handler, v${version}
47 |
48 | Usage:
49 |
50 | pacote resolve
51 | Resolve a specifier and output the fully resolved target
52 | Returns integrity and from if '--long' flag is set.
53 |
54 | pacote manifest
55 | Fetch a manifest and print to stdout
56 |
57 | pacote packument
58 | Fetch a full packument and print to stdout
59 |
60 | pacote tarball []
61 | Fetch a package tarball and save to
62 | If is missing or '-', the tarball will be streamed to stdout.
63 |
64 | pacote extract
65 | Extract a package to the destination folder.
66 |
67 | Configuration values all match the names of configs passed to npm, or
68 | options passed to Pacote. Additional flags for this executable:
69 |
70 | --long Print an object from 'resolve', including integrity and spec.
71 | --json Print result objects as JSON rather than node's default.
72 | (This is the default if stdout is not a TTY.)
73 | --help -h Print this helpful text.
74 |
75 | For example '--cache=/path/to/folder' will use that folder as the cache.
76 | `
77 |
78 | const shouldJSON = (conf, result) =>
79 | conf.json ||
80 | !process.stdout.isTTY &&
81 | conf.json === undefined &&
82 | result &&
83 | typeof result === 'object'
84 |
85 | const pretty = (conf, result) =>
86 | shouldJSON(conf, result) ? JSON.stringify(result, 0, 2) : result
87 |
88 | let addedLogListener = false
89 | const main = args => {
90 | const conf = parse(args)
91 | if (conf.help || conf.h) {
92 | return console.log(usage())
93 | }
94 |
95 | if (!addedLogListener) {
96 | process.on('log', console.error)
97 | addedLogListener = true
98 | }
99 |
100 | try {
101 | return run(conf)
102 | .then(result => result && console.log(pretty(conf, result)))
103 | .catch(er => {
104 | console.error(er)
105 | process.exit(1)
106 | })
107 | } catch (er) {
108 | console.error(er.message)
109 | console.error(usage())
110 | }
111 | }
112 |
113 | const parseArg = arg => {
114 | const split = arg.slice(2).split('=')
115 | const k = split.shift()
116 | const v = split.join('=')
117 | const no = /^no-/.test(k) && !v
118 | const key = (no ? k.slice(3) : k)
119 | .replace(/^tag$/, 'defaultTag')
120 | .replace(/-([a-z])/g, (_, c) => c.toUpperCase())
121 | const value = v ? v.replace(/^~/, process.env.HOME) : !no
122 | return { key, value }
123 | }
124 |
125 | const parse = args => {
126 | const conf = {
127 | _: [],
128 | cache: process.env.HOME + '/.npm/_cacache',
129 | }
130 | let dashdash = false
131 | args.forEach(arg => {
132 | if (dashdash) {
133 | conf._.push(arg)
134 | } else if (arg === '--') {
135 | dashdash = true
136 | } else if (arg === '-h') {
137 | conf.help = true
138 | } else if (/^--/.test(arg)) {
139 | const { key, value } = parseArg(arg)
140 | conf[key] = value
141 | } else {
142 | conf._.push(arg)
143 | }
144 | })
145 | return conf
146 | }
147 |
148 | if (module === require.main) {
149 | main(process.argv.slice(2))
150 | } else {
151 | module.exports = {
152 | main,
153 | run,
154 | usage,
155 | parseArg,
156 | parse,
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/lib/dir.js:
--------------------------------------------------------------------------------
1 | const { resolve } = require('node:path')
2 | const packlist = require('npm-packlist')
3 | const runScript = require('@npmcli/run-script')
4 | const tar = require('tar')
5 | const { Minipass } = require('minipass')
6 | const Fetcher = require('./fetcher.js')
7 | const FileFetcher = require('./file.js')
8 | const _ = require('./util/protected.js')
9 | const tarCreateOptions = require('./util/tar-create-options.js')
10 |
11 | class DirFetcher extends Fetcher {
12 | constructor(spec, opts) {
13 | super(spec, opts)
14 | // just the fully resolved filename
15 | this.resolved = this.spec.fetchSpec
16 |
17 | this.tree = opts.tree || null
18 | this.Arborist = opts.Arborist || null
19 | }
20 |
21 | // exposes tarCreateOptions as public API
22 | static tarCreateOptions(manifest) {
23 | return tarCreateOptions(manifest)
24 | }
25 |
26 | get types() {
27 | return ['directory']
28 | }
29 |
30 | #prepareDir() {
31 | return this.manifest().then(mani => {
32 | if (!mani.scripts || !mani.scripts.prepare) {
33 | return
34 | }
35 | if (this.opts.ignoreScripts) {
36 | return
37 | }
38 |
39 | // we *only* run prepare.
40 | // pre/post-pack is run by the npm CLI for publish and pack,
41 | // but this function is *also* run when installing git deps
42 | const stdio = this.opts.foregroundScripts ? 'inherit' : 'pipe'
43 |
44 | return runScript({
45 | // this || undefined is because runScript will be unhappy with the default null value
46 | scriptShell: this.opts.scriptShell || undefined,
47 | pkg: mani,
48 | event: 'prepare',
49 | path: this.resolved,
50 | stdio,
51 | env: {
52 | npm_package_resolved: this.resolved,
53 | npm_package_integrity: this.integrity,
54 | npm_package_json: resolve(this.resolved, 'package.json'),
55 | },
56 | }).then(() =>
57 | process.env._PACOTE_FROM_GIT_ === "yes" && runScript({
58 | // this || undefined is because runScript will be unhappy with the default null value
59 | scriptShell: this.opts.scriptShell || undefined,
60 | pkg: mani,
61 | event: 'prepack',
62 | path: this.resolved,
63 | stdio,
64 | env: {
65 | npm_package_resolved: this.resolved,
66 | npm_package_integrity: this.integrity,
67 | npm_package_json: resolve(this.resolved, 'package.json'),
68 | },
69 | }))
70 | })
71 | }
72 |
73 | [_.tarballFromResolved]() {
74 | if (!this.tree && !this.Arborist) {
75 | throw new Error('DirFetcher requires either a tree or an Arborist constructor to pack')
76 | }
77 |
78 | const stream = new Minipass()
79 | stream.resolved = this.resolved
80 | stream.integrity = this.integrity
81 |
82 | const { prefix, workspaces } = this.opts
83 |
84 | // run the prepare script, get the list of files, and tar it up
85 | // pipe to the stream, and proxy errors the chain.
86 | this.#prepareDir()
87 | .then(async () => {
88 | if (!this.tree) {
89 | const arb = new this.Arborist({ path: this.resolved })
90 | this.tree = await arb.loadActual()
91 | }
92 | return packlist(this.tree, { path: this.resolved, prefix, workspaces })
93 | })
94 | .then(files => tar.c(tarCreateOptions(this.package), files)
95 | .on('error', er => stream.emit('error', er)).pipe(stream))
96 | .catch(er => stream.emit('error', er))
97 | return stream
98 | }
99 |
100 | manifest() {
101 | if (this.package) {
102 | return Promise.resolve(this.package)
103 | }
104 |
105 | return this[_.readPackageJson](this.resolved)
106 | .then(mani => this.package = {
107 | ...mani,
108 | _integrity: this.integrity && String(this.integrity),
109 | _resolved: this.resolved,
110 | _from: this.from,
111 | })
112 | }
113 |
114 | packument() {
115 | return FileFetcher.prototype.packument.apply(this)
116 | }
117 | }
118 | module.exports = DirFetcher
119 |
--------------------------------------------------------------------------------
/lib/file.js:
--------------------------------------------------------------------------------
1 | const { resolve } = require('node:path')
2 | const { stat, chmod } = require('node:fs/promises')
3 | const cacache = require('cacache')
4 | const fsm = require('fs-minipass')
5 | const Fetcher = require('./fetcher.js')
6 | const _ = require('./util/protected.js')
7 |
8 | class FileFetcher extends Fetcher {
9 | constructor (spec, opts) {
10 | super(spec, opts)
11 | // just the fully resolved filename
12 | this.resolved = this.spec.fetchSpec
13 | }
14 |
15 | get types () {
16 | return ['file']
17 | }
18 |
19 | manifest () {
20 | if (this.package) {
21 | return Promise.resolve(this.package)
22 | }
23 |
24 | // have to unpack the tarball for this.
25 | return cacache.tmp.withTmp(this.cache, this.opts, dir =>
26 | this.extract(dir)
27 | .then(() => this[_.readPackageJson](dir))
28 | .then(mani => this.package = {
29 | ...mani,
30 | _integrity: this.integrity && String(this.integrity),
31 | _resolved: this.resolved,
32 | _from: this.from,
33 | }))
34 | }
35 |
36 | #exeBins (pkg, dest) {
37 | if (!pkg.bin) {
38 | return Promise.resolve()
39 | }
40 |
41 | return Promise.all(Object.keys(pkg.bin).map(async k => {
42 | const script = resolve(dest, pkg.bin[k])
43 | // Best effort. Ignore errors here, the only result is that
44 | // a bin script is not executable. But if it's missing or
45 | // something, we just leave it for a later stage to trip over
46 | // when we can provide a more useful contextual error.
47 | try {
48 | const st = await stat(script)
49 | const mode = st.mode | 0o111
50 | if (mode === st.mode) {
51 | return
52 | }
53 | await chmod(script, mode)
54 | } catch {
55 | // Ignore errors here
56 | }
57 | }))
58 | }
59 |
60 | extract (dest) {
61 | // if we've already loaded the manifest, then the super got it.
62 | // but if not, read the unpacked manifest and chmod properly.
63 | return super.extract(dest)
64 | .then(result => this.package ? result
65 | : this[_.readPackageJson](dest).then(pkg =>
66 | this.#exeBins(pkg, dest)).then(() => result))
67 | }
68 |
69 | [_.tarballFromResolved] () {
70 | // create a read stream and return it
71 | return new fsm.ReadStream(this.resolved)
72 | }
73 |
74 | packument () {
75 | // simulate based on manifest
76 | return this.manifest().then(mani => ({
77 | name: mani.name,
78 | 'dist-tags': {
79 | [this.defaultTag]: mani.version,
80 | },
81 | versions: {
82 | [mani.version]: {
83 | ...mani,
84 | dist: {
85 | tarball: `file:${this.resolved}`,
86 | integrity: this.integrity && String(this.integrity),
87 | },
88 | },
89 | },
90 | }))
91 | }
92 | }
93 |
94 | module.exports = FileFetcher
95 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | const { get } = require('./fetcher.js')
2 | const GitFetcher = require('./git.js')
3 | const RegistryFetcher = require('./registry.js')
4 | const FileFetcher = require('./file.js')
5 | const DirFetcher = require('./dir.js')
6 | const RemoteFetcher = require('./remote.js')
7 |
8 | const tarball = (spec, opts) => get(spec, opts).tarball()
9 | tarball.stream = (spec, handler, opts) => get(spec, opts).tarballStream(handler)
10 | tarball.file = (spec, dest, opts) => get(spec, opts).tarballFile(dest)
11 |
12 | module.exports = {
13 | GitFetcher,
14 | RegistryFetcher,
15 | FileFetcher,
16 | DirFetcher,
17 | RemoteFetcher,
18 | resolve: (spec, opts) => get(spec, opts).resolve(),
19 | extract: (spec, dest, opts) => get(spec, opts).extract(dest),
20 | manifest: (spec, opts) => get(spec, opts).manifest(),
21 | packument: (spec, opts) => get(spec, opts).packument(),
22 | tarball,
23 | }
24 |
--------------------------------------------------------------------------------
/lib/remote.js:
--------------------------------------------------------------------------------
1 | const fetch = require('npm-registry-fetch')
2 | const { Minipass } = require('minipass')
3 | const Fetcher = require('./fetcher.js')
4 | const FileFetcher = require('./file.js')
5 | const _ = require('./util/protected.js')
6 | const pacoteVersion = require('../package.json').version
7 |
8 | class RemoteFetcher extends Fetcher {
9 | constructor (spec, opts) {
10 | super(spec, opts)
11 | this.resolved = this.spec.fetchSpec
12 | const resolvedURL = new URL(this.resolved)
13 | if (this.replaceRegistryHost !== 'never'
14 | && (this.replaceRegistryHost === 'always'
15 | || this.replaceRegistryHost === resolvedURL.host)) {
16 | this.resolved = new URL(resolvedURL.pathname, this.registry).href
17 | }
18 |
19 | // nam is a fermented pork sausage that is good to eat
20 | const nameat = this.spec.name ? `${this.spec.name}@` : ''
21 | this.pkgid = opts.pkgid ? opts.pkgid : `remote:${nameat}${this.resolved}`
22 | }
23 |
24 | // Don't need to cache tarball fetches in pacote, because make-fetch-happen
25 | // will write into cacache anyway.
26 | get [_.cacheFetches] () {
27 | return false
28 | }
29 |
30 | [_.tarballFromResolved] () {
31 | const stream = new Minipass()
32 | stream.hasIntegrityEmitter = true
33 |
34 | const fetchOpts = {
35 | ...this.opts,
36 | headers: this.#headers(),
37 | spec: this.spec,
38 | integrity: this.integrity,
39 | algorithms: [this.pickIntegrityAlgorithm()],
40 | }
41 |
42 | // eslint-disable-next-line promise/always-return
43 | fetch(this.resolved, fetchOpts).then(res => {
44 | res.body.on('error',
45 | /* istanbul ignore next - exceedingly rare and hard to simulate */
46 | er => stream.emit('error', er)
47 | )
48 |
49 | res.body.on('integrity', i => {
50 | this.integrity = i
51 | stream.emit('integrity', i)
52 | })
53 |
54 | res.body.pipe(stream)
55 | }).catch(er => stream.emit('error', er))
56 |
57 | return stream
58 | }
59 |
60 | #headers () {
61 | return {
62 | // npm will override this, but ensure that we always send *something*
63 | 'user-agent': this.opts.userAgent ||
64 | `pacote/${pacoteVersion} node/${process.version}`,
65 | ...(this.opts.headers || {}),
66 | 'pacote-version': pacoteVersion,
67 | 'pacote-req-type': 'tarball',
68 | 'pacote-pkg-id': this.pkgid,
69 | ...(this.integrity ? { 'pacote-integrity': String(this.integrity) }
70 | : {}),
71 | ...(this.opts.headers || {}),
72 | }
73 | }
74 |
75 | get types () {
76 | return ['remote']
77 | }
78 |
79 | // getting a packument and/or manifest is the same as with a file: spec.
80 | // unpack the tarball stream, and then read from the package.json file.
81 | packument () {
82 | return FileFetcher.prototype.packument.apply(this)
83 | }
84 |
85 | manifest () {
86 | return FileFetcher.prototype.manifest.apply(this)
87 | }
88 | }
89 | module.exports = RemoteFetcher
90 |
--------------------------------------------------------------------------------
/lib/util/add-git-sha.js:
--------------------------------------------------------------------------------
1 | // add a sha to a git remote url spec
2 | const addGitSha = (spec, sha) => {
3 | if (spec.hosted) {
4 | const h = spec.hosted
5 | const opt = { noCommittish: true }
6 | const base = h.https && h.auth ? h.https(opt) : h.shortcut(opt)
7 |
8 | return `${base}#${sha}`
9 | } else {
10 | // don't use new URL for this, because it doesn't handle scp urls
11 | return spec.rawSpec.replace(/#.*$/, '') + `#${sha}`
12 | }
13 | }
14 |
15 | module.exports = addGitSha
16 |
--------------------------------------------------------------------------------
/lib/util/cache-dir.js:
--------------------------------------------------------------------------------
1 | const { resolve } = require('node:path')
2 | const { tmpdir, homedir } = require('node:os')
3 |
4 | module.exports = (fakePlatform = false) => {
5 | const temp = tmpdir()
6 | const uidOrPid = process.getuid ? process.getuid() : process.pid
7 | const home = homedir() || resolve(temp, 'npm-' + uidOrPid)
8 | const platform = fakePlatform || process.platform
9 | const cacheExtra = platform === 'win32' ? 'npm-cache' : '.npm'
10 | const cacheRoot = (platform === 'win32' && process.env.LOCALAPPDATA) || home
11 | return {
12 | cacache: resolve(cacheRoot, cacheExtra, '_cacache'),
13 | tufcache: resolve(cacheRoot, cacheExtra, '_tuf'),
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/lib/util/is-package-bin.js:
--------------------------------------------------------------------------------
1 | // Function to determine whether a path is in the package.bin set.
2 | // Used to prevent issues when people publish a package from a
3 | // windows machine, and then install with --no-bin-links.
4 | //
5 | // Note: this is not possible in remote or file fetchers, since
6 | // we don't have the manifest until AFTER we've unpacked. But the
7 | // main use case is registry fetching with git a distant second,
8 | // so that's an acceptable edge case to not handle.
9 |
10 | const binObj = (name, bin) =>
11 | typeof bin === 'string' ? { [name]: bin } : bin
12 |
13 | const hasBin = (pkg, path) => {
14 | const bin = binObj(pkg.name, pkg.bin)
15 | const p = path.replace(/^[^\\/]*\//, '')
16 | for (const kv of Object.entries(bin)) {
17 | if (kv[1] === p) {
18 | return true
19 | }
20 | }
21 | return false
22 | }
23 |
24 | module.exports = (pkg, path) =>
25 | pkg && pkg.bin ? hasBin(pkg, path) : false
26 |
--------------------------------------------------------------------------------
/lib/util/npm.js:
--------------------------------------------------------------------------------
1 | // run an npm command
2 | const spawn = require('@npmcli/promise-spawn')
3 |
4 | module.exports = (npmBin, npmCommand, cwd, env, extra) => {
5 | const isJS = npmBin.endsWith('.js')
6 | const cmd = isJS ? process.execPath : npmBin
7 | const args = (isJS ? [npmBin] : []).concat(npmCommand)
8 | // when installing to run the `prepare` script for a git dep, we need
9 | // to ensure that we don't run into a cycle of checking out packages
10 | // in temp directories. this lets us link previously-seen repos that
11 | // are also being prepared.
12 |
13 | return spawn(cmd, args, { cwd, env }, extra)
14 | }
15 |
--------------------------------------------------------------------------------
/lib/util/protected.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | cacheFetches: Symbol.for('pacote.Fetcher._cacheFetches'),
3 | readPackageJson: Symbol.for('package.Fetcher._readPackageJson'),
4 | tarballFromResolved: Symbol.for('pacote.Fetcher._tarballFromResolved'),
5 | }
6 |
--------------------------------------------------------------------------------
/lib/util/tar-create-options.js:
--------------------------------------------------------------------------------
1 | const isPackageBin = require('./is-package-bin.js')
2 |
3 | const tarCreateOptions = manifest => ({
4 | cwd: manifest._resolved,
5 | prefix: 'package/',
6 | portable: true,
7 | gzip: {
8 | // forcing the level to 9 seems to avoid some
9 | // platform specific optimizations that cause
10 | // integrity mismatch errors due to differing
11 | // end results after compression
12 | level: 9,
13 | },
14 |
15 | // ensure that package bins are always executable
16 | // Note that npm-packlist is already filtering out
17 | // anything that is not a regular file, ignored by
18 | // .npmignore or package.json "files", etc.
19 | filter: (path, stat) => {
20 | if (isPackageBin(manifest, path)) {
21 | stat.mode |= 0o111
22 | }
23 | return true
24 | },
25 |
26 | // Provide a specific date in the 1980s for the benefit of zip,
27 | // which is confounded by files dated at the Unix epoch 0.
28 | mtime: new Date('1985-10-26T08:15:00.000Z'),
29 | })
30 |
31 | module.exports = tarCreateOptions
32 |
--------------------------------------------------------------------------------
/lib/util/trailing-slashes.js:
--------------------------------------------------------------------------------
1 | const removeTrailingSlashes = (input) => {
2 | // in order to avoid regexp redos detection
3 | let output = input
4 | while (output.endsWith('/')) {
5 | output = output.slice(0, -1)
6 | }
7 | return output
8 | }
9 |
10 | module.exports = removeTrailingSlashes
11 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pacote",
3 | "version": "21.0.0",
4 | "description": "JavaScript package downloader",
5 | "author": "GitHub Inc.",
6 | "bin": {
7 | "pacote": "bin/index.js"
8 | },
9 | "license": "ISC",
10 | "main": "lib/index.js",
11 | "scripts": {
12 | "test": "tap",
13 | "snap": "tap",
14 | "lint": "npm run eslint",
15 | "postlint": "template-oss-check",
16 | "lintfix": "npm run eslint -- --fix",
17 | "posttest": "npm run lint",
18 | "template-oss-apply": "template-oss-apply --force",
19 | "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\""
20 | },
21 | "tap": {
22 | "timeout": 300,
23 | "nyc-arg": [
24 | "--exclude",
25 | "tap-snapshots/**"
26 | ]
27 | },
28 | "devDependencies": {
29 | "@npmcli/arborist": "^8.0.0",
30 | "@npmcli/eslint-config": "^5.0.0",
31 | "@npmcli/template-oss": "4.23.4",
32 | "hosted-git-info": "^8.0.0",
33 | "mutate-fs": "^2.1.1",
34 | "nock": "^13.2.4",
35 | "npm-registry-mock": "^1.3.2",
36 | "rimraf": "^6.0.1",
37 | "tap": "^16.0.1"
38 | },
39 | "files": [
40 | "bin/",
41 | "lib/"
42 | ],
43 | "keywords": [
44 | "packages",
45 | "npm",
46 | "git"
47 | ],
48 | "dependencies": {
49 | "@npmcli/git": "^6.0.0",
50 | "@npmcli/installed-package-contents": "^3.0.0",
51 | "@npmcli/package-json": "^6.0.0",
52 | "@npmcli/promise-spawn": "^8.0.0",
53 | "@npmcli/run-script": "^9.0.0",
54 | "cacache": "^19.0.0",
55 | "fs-minipass": "^3.0.0",
56 | "minipass": "^7.0.2",
57 | "npm-package-arg": "^12.0.0",
58 | "npm-packlist": "^10.0.0",
59 | "npm-pick-manifest": "^10.0.0",
60 | "npm-registry-fetch": "^18.0.0",
61 | "proc-log": "^5.0.0",
62 | "promise-retry": "^2.0.1",
63 | "sigstore": "^3.0.0",
64 | "ssri": "^12.0.0",
65 | "tar": "^6.1.11"
66 | },
67 | "engines": {
68 | "node": "^20.17.0 || >=22.9.0"
69 | },
70 | "repository": {
71 | "type": "git",
72 | "url": "git+https://github.com/npm/pacote.git"
73 | },
74 | "templateOSS": {
75 | "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
76 | "version": "4.23.4",
77 | "windowsCI": false,
78 | "publish": "true"
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/release-please-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "group-pull-request-title-pattern": "chore: release ${version}",
3 | "pull-request-title-pattern": "chore: release${component} ${version}",
4 | "changelog-sections": [
5 | {
6 | "type": "feat",
7 | "section": "Features",
8 | "hidden": false
9 | },
10 | {
11 | "type": "fix",
12 | "section": "Bug Fixes",
13 | "hidden": false
14 | },
15 | {
16 | "type": "docs",
17 | "section": "Documentation",
18 | "hidden": false
19 | },
20 | {
21 | "type": "deps",
22 | "section": "Dependencies",
23 | "hidden": false
24 | },
25 | {
26 | "type": "chore",
27 | "section": "Chores",
28 | "hidden": true
29 | }
30 | ],
31 | "packages": {
32 | ".": {
33 | "package-name": "",
34 | "prerelease": false
35 | }
36 | },
37 | "prerelease-type": "pre"
38 | }
39 |
--------------------------------------------------------------------------------
/tap-snapshots/test/bin.js.test.cjs:
--------------------------------------------------------------------------------
1 | /* IMPORTANT
2 | * This snapshot file is auto-generated, but designed for humans.
3 | * It should be checked into source control and tracked carefully.
4 | * Re-generate by setting TAP_SNAPSHOT=1 and running tests.
5 | * Make sure to inspect the output below. Do not ignore changes!
6 | */
7 | 'use strict'
8 | exports[`test/bin.js TAP main --help > must match snapshot 1`] = `
9 | Object {
10 | "errorlog": Array [],
11 | "exitlog": Array [],
12 | "loglog": Array [
13 | Array [
14 | String(
15 | Pacote - The JavaScript Package Handler, v{VERSION}
16 |
17 | Usage:
18 |
19 | pacote resolve
20 | Resolve a specifier and output the fully resolved target
21 | Returns integrity and from if '--long' flag is set.
22 |
23 | pacote manifest
24 | Fetch a manifest and print to stdout
25 |
26 | pacote packument
27 | Fetch a full packument and print to stdout
28 |
29 | pacote tarball []
30 | Fetch a package tarball and save to
31 | If is missing or '-', the tarball will be streamed to stdout.
32 |
33 | pacote extract
34 | Extract a package to the destination folder.
35 |
36 | Configuration values all match the names of configs passed to npm, or
37 | options passed to Pacote. Additional flags for this executable:
38 |
39 | --long Print an object from 'resolve', including integrity and spec.
40 | --json Print result objects as JSON rather than node's default.
41 | (This is the default if stdout is not a TTY.)
42 | --help -h Print this helpful text.
43 |
44 | For example '--cache=/path/to/folder' will use that folder as the cache.
45 |
46 | ),
47 | ],
48 | ],
49 | }
50 | `
51 |
52 | exports[`test/bin.js TAP main blerg glorb glork > must match snapshot 1`] = `
53 | Object {
54 | "errorlog": Array [
55 | Array [
56 | "bad command: blerg",
57 | ],
58 | Array [
59 | String(
60 | Pacote - The JavaScript Package Handler, v{VERSION}
61 |
62 | Usage:
63 |
64 | pacote resolve
65 | Resolve a specifier and output the fully resolved target
66 | Returns integrity and from if '--long' flag is set.
67 |
68 | pacote manifest
69 | Fetch a manifest and print to stdout
70 |
71 | pacote packument
72 | Fetch a full packument and print to stdout
73 |
74 | pacote tarball []
75 | Fetch a package tarball and save to
76 | If is missing or '-', the tarball will be streamed to stdout.
77 |
78 | pacote extract
79 | Extract a package to the destination folder.
80 |
81 | Configuration values all match the names of configs passed to npm, or
82 | options passed to Pacote. Additional flags for this executable:
83 |
84 | --long Print an object from 'resolve', including integrity and spec.
85 | --json Print result objects as JSON rather than node's default.
86 | (This is the default if stdout is not a TTY.)
87 | --help -h Print this helpful text.
88 |
89 | For example '--cache=/path/to/folder' will use that folder as the cache.
90 |
91 | ),
92 | ],
93 | ],
94 | "exitlog": Array [],
95 | "loglog": Array [],
96 | }
97 | `
98 |
99 | exports[`test/bin.js TAP main extract npm@latest-6 folder --json > must match snapshot 1`] = `
100 | Object {
101 | "errorlog": Array [],
102 | "exitlog": Array [],
103 | "loglog": Array [
104 | Array [
105 | String(
106 | {
107 | "method": "extract",
108 | "spec": "npm@latest-6",
109 | "dest": "folder",
110 | "conf": {
111 | "_": [
112 | "extract",
113 | "npm@latest-6",
114 | "folder"
115 | ],
116 | "cache": "{HOME}/.npm/_cacache",
117 | "json": true
118 | }
119 | }
120 | ),
121 | ],
122 | ],
123 | }
124 | `
125 |
126 | exports[`test/bin.js TAP main extract npm@latest-6 folder --no-json > must match snapshot 1`] = `
127 | Object {
128 | "errorlog": Array [],
129 | "exitlog": Array [],
130 | "loglog": Array [
131 | Array [
132 | Object {
133 | "conf": Object {
134 | "_": Array [
135 | "extract",
136 | "npm@latest-6",
137 | "folder",
138 | ],
139 | "cache": "{HOME}/.npm/_cacache",
140 | "json": false,
141 | },
142 | "dest": "folder",
143 | "method": "extract",
144 | "spec": "npm@latest-6",
145 | },
146 | ],
147 | ],
148 | }
149 | `
150 |
151 | exports[`test/bin.js TAP main manifest bar@foo > must match snapshot 1`] = `
152 | Object {
153 | "errorlog": Array [],
154 | "exitlog": Array [],
155 | "loglog": Array [
156 | Array [
157 | String(
158 | {
159 | "method": "manifest",
160 | "spec": "bar@foo",
161 | "conf": {
162 | "_": [
163 | "manifest",
164 | "bar@foo"
165 | ],
166 | "cache": "{HOME}/.npm/_cacache"
167 | },
168 | "_resolved": "manifest resolved",
169 | "_integrity": "manifest integrity",
170 | "_from": "manifest from"
171 | }
172 | ),
173 | ],
174 | ],
175 | }
176 | `
177 |
178 | exports[`test/bin.js TAP main packument paku@mint > must match snapshot 1`] = `
179 | Object {
180 | "errorlog": Array [],
181 | "exitlog": Array [],
182 | "loglog": Array [
183 | Array [
184 | String(
185 | {
186 | "method": "packument",
187 | "spec": "paku@mint",
188 | "conf": {
189 | "_": [
190 | "packument",
191 | "paku@mint"
192 | ],
193 | "cache": "{HOME}/.npm/_cacache"
194 | }
195 | }
196 | ),
197 | ],
198 | ],
199 | }
200 | `
201 |
202 | exports[`test/bin.js TAP main resolve fail > must match snapshot 1`] = `
203 | Object {
204 | "errorlog": Array [
205 | Array [
206 | Error: fail,
207 | ],
208 | ],
209 | "exitlog": Array [
210 | 1,
211 | ],
212 | "loglog": Array [],
213 | }
214 | `
215 |
216 | exports[`test/bin.js TAP main resolve foo@bar --long > must match snapshot 1`] = `
217 | Object {
218 | "errorlog": Array [],
219 | "exitlog": Array [],
220 | "loglog": Array [
221 | Array [
222 | String(
223 | {
224 | "resolved": "manifest resolved",
225 | "integrity": "manifest integrity",
226 | "from": "manifest from"
227 | }
228 | ),
229 | ],
230 | ],
231 | }
232 | `
233 |
234 | exports[`test/bin.js TAP main resolve foo@bar > must match snapshot 1`] = `
235 | Object {
236 | "errorlog": Array [],
237 | "exitlog": Array [],
238 | "loglog": Array [
239 | Array [
240 | String(
241 | {
242 | "method": "resolve",
243 | "spec": "foo@bar",
244 | "conf": {
245 | "_": [
246 | "resolve",
247 | "foo@bar"
248 | ],
249 | "cache": "{HOME}/.npm/_cacache"
250 | }
251 | }
252 | ),
253 | ],
254 | ],
255 | }
256 | `
257 |
258 | exports[`test/bin.js TAP main resolve string --json > must match snapshot 1`] = `
259 | Object {
260 | "errorlog": Array [],
261 | "exitlog": Array [],
262 | "loglog": Array [
263 | Array [
264 | "\\"just a string\\"",
265 | ],
266 | ],
267 | }
268 | `
269 |
270 | exports[`test/bin.js TAP main resolve string > must match snapshot 1`] = `
271 | Object {
272 | "errorlog": Array [],
273 | "exitlog": Array [],
274 | "loglog": Array [
275 | Array [
276 | "just a string",
277 | ],
278 | ],
279 | }
280 | `
281 |
282 | exports[`test/bin.js TAP main tarball tar@ball file.tgz > must match snapshot 1`] = `
283 | Object {
284 | "errorlog": Array [],
285 | "exitlog": Array [],
286 | "loglog": Array [
287 | Array [
288 | String(
289 | {
290 | "method": "tarball",
291 | "spec": "tar@ball",
292 | "file": "file.tgz",
293 | "conf": {
294 | "_": [
295 | "tarball",
296 | "tar@ball",
297 | "file.tgz"
298 | ],
299 | "cache": "{HOME}/.npm/_cacache"
300 | }
301 | }
302 | ),
303 | ],
304 | ],
305 | }
306 | `
307 |
308 | exports[`test/bin.js TAP run > expect resolving Promise 1`] = `
309 | Object {
310 | "conf": Object {
311 | "_": Array [
312 | "resolve",
313 | "spec",
314 | ],
315 | "some": "configs",
316 | },
317 | "method": "resolve",
318 | "spec": "spec",
319 | }
320 | `
321 |
322 | exports[`test/bin.js TAP run > expect resolving Promise 2`] = `
323 | Object {
324 | "_from": "manifest from",
325 | "_integrity": "manifest integrity",
326 | "_resolved": "manifest resolved",
327 | "conf": Object {
328 | "_": Array [
329 | "manifest",
330 | "spec",
331 | ],
332 | "some": "configs",
333 | },
334 | "method": "manifest",
335 | "spec": "spec",
336 | }
337 | `
338 |
339 | exports[`test/bin.js TAP run > expect resolving Promise 3`] = `
340 | Object {
341 | "conf": Object {
342 | "_": Array [
343 | "packument",
344 | "spec",
345 | ],
346 | "some": "configs",
347 | },
348 | "method": "packument",
349 | "spec": "spec",
350 | }
351 | `
352 |
353 | exports[`test/bin.js TAP run > expect resolving Promise 4`] = `
354 | Object {
355 | "conf": Object {
356 | "_": Array [
357 | "tarball",
358 | "spec",
359 | "file",
360 | ],
361 | "some": "configs",
362 | },
363 | "file": "file",
364 | "method": "tarball",
365 | "spec": "spec",
366 | }
367 | `
368 |
369 | exports[`test/bin.js TAP run > expect resolving Promise 5`] = `
370 | Object {
371 | "conf": Object {
372 | "_": Array [
373 | "extract",
374 | "spec",
375 | "dest",
376 | ],
377 | "some": "configs",
378 | },
379 | "dest": "dest",
380 | "method": "extract",
381 | "spec": "spec",
382 | }
383 | `
384 |
385 | exports[`test/bin.js TAP run > expect resolving Promise 6`] = `
386 | false
387 | `
388 |
389 | exports[`test/bin.js TAP running bin runs main file > helpful output 1`] = `
390 | Pacote - The JavaScript Package Handler, v{VERSION}
391 |
392 | Usage:
393 |
394 | pacote resolve
395 | Resolve a specifier and output the fully resolved target
396 | Returns integrity and from if '--long' flag is set.
397 |
398 | pacote manifest
399 | Fetch a manifest and print to stdout
400 |
401 | pacote packument
402 | Fetch a full packument and print to stdout
403 |
404 | pacote tarball []
405 | Fetch a package tarball and save to
406 | If is missing or '-', the tarball will be streamed to stdout.
407 |
408 | pacote extract
409 | Extract a package to the destination folder.
410 |
411 | Configuration values all match the names of configs passed to npm, or
412 | options passed to Pacote. Additional flags for this executable:
413 |
414 | --long Print an object from 'resolve', including integrity and spec.
415 | --json Print result objects as JSON rather than node's default.
416 | (This is the default if stdout is not a TTY.)
417 | --help -h Print this helpful text.
418 |
419 | For example '--cache=/path/to/folder' will use that folder as the cache.
420 |
421 |
422 | `
423 |
--------------------------------------------------------------------------------
/tap-snapshots/test/dir.js.test.cjs:
--------------------------------------------------------------------------------
1 | /* IMPORTANT
2 | * This snapshot file is auto-generated, but designed for humans.
3 | * It should be checked into source control and tracked carefully.
4 | * Re-generate by setting TAP_SNAPSHOT=1 and running tests.
5 | * Make sure to inspect the output below. Do not ignore changes!
6 | */
7 | 'use strict'
8 | exports[`test/dir.js TAP basic > extract 1`] = `
9 | Object {
10 | "from": "file:test/fixtures/abbrev",
11 | "integrity": "{integrity}",
12 | "resolved": "{CWD}/test/fixtures/abbrev",
13 | }
14 | `
15 |
16 | exports[`test/dir.js TAP basic > manifest 1`] = `
17 | Object {
18 | "_from": "file:test/fixtures/abbrev",
19 | "_id": "abbrev@1.1.1",
20 | "_integrity": null,
21 | "_resolved": "{CWD}/test/fixtures/abbrev",
22 | "author": "Isaac Z. Schlueter ",
23 | "description": "Like ruby's abbrev module, but in js",
24 | "devDependencies": Object {
25 | "tap": "^10.1",
26 | },
27 | "files": Array [
28 | "abbrev.js",
29 | ],
30 | "license": "ISC",
31 | "main": "abbrev.js",
32 | "name": "abbrev",
33 | "repository": "http://github.com/isaacs/abbrev-js",
34 | "scripts": Object {
35 | "postpublish": "git push origin --all; git push origin --tags",
36 | "postversion": "npm publish",
37 | "preversion": "npm test",
38 | "test": "tap test.js --100",
39 | },
40 | "version": "1.1.1",
41 | }
42 | `
43 |
44 | exports[`test/dir.js TAP basic > package.json extracted 1`] = `
45 | Object {
46 | "author": "Isaac Z. Schlueter ",
47 | "description": "Like ruby's abbrev module, but in js",
48 | "devDependencies": Object {
49 | "tap": "^10.1",
50 | },
51 | "files": Array [
52 | "abbrev.js",
53 | ],
54 | "license": "ISC",
55 | "main": "abbrev.js",
56 | "name": "abbrev",
57 | "repository": "http://github.com/isaacs/abbrev-js",
58 | "scripts": Object {
59 | "postpublish": "git push origin --all; git push origin --tags",
60 | "postversion": "npm publish",
61 | "preversion": "npm test",
62 | "test": "tap test.js --100",
63 | },
64 | "version": "1.1.1",
65 | }
66 | `
67 |
68 | exports[`test/dir.js TAP basic > packument 1`] = `
69 | Object {
70 | "dist-tags": Object {
71 | "latest": "1.1.1",
72 | },
73 | "name": "abbrev",
74 | "versions": Object {
75 | "1.1.1": Object {
76 | "_from": "file:test/fixtures/abbrev",
77 | "_id": "abbrev@1.1.1",
78 | "_integrity": null,
79 | "_resolved": "{CWD}/test/fixtures/abbrev",
80 | "author": "Isaac Z. Schlueter ",
81 | "description": "Like ruby's abbrev module, but in js",
82 | "devDependencies": Object {
83 | "tap": "^10.1",
84 | },
85 | "dist": Object {
86 | "integrity": null,
87 | "tarball": "file:{CWD}/test/fixtures/abbrev",
88 | },
89 | "files": Array [
90 | "abbrev.js",
91 | ],
92 | "license": "ISC",
93 | "main": "abbrev.js",
94 | "name": "abbrev",
95 | "repository": "http://github.com/isaacs/abbrev-js",
96 | "scripts": Object {
97 | "postpublish": "git push origin --all; git push origin --tags",
98 | "postversion": "npm publish",
99 | "preversion": "npm test",
100 | "test": "tap test.js --100",
101 | },
102 | "version": "1.1.1",
103 | },
104 | },
105 | }
106 | `
107 |
108 | exports[`test/dir.js TAP basic > saved package.json 1`] = `
109 | Object {
110 | "_from": "file:test/fixtures/abbrev",
111 | "_id": "abbrev@1.1.1",
112 | "_integrity": null,
113 | "_resolved": "{CWD}/test/fixtures/abbrev",
114 | "author": "Isaac Z. Schlueter ",
115 | "description": "Like ruby's abbrev module, but in js",
116 | "devDependencies": Object {
117 | "tap": "^10.1",
118 | },
119 | "files": Array [
120 | "abbrev.js",
121 | ],
122 | "license": "ISC",
123 | "main": "abbrev.js",
124 | "name": "abbrev",
125 | "repository": "http://github.com/isaacs/abbrev-js",
126 | "scripts": Object {
127 | "postpublish": "git push origin --all; git push origin --tags",
128 | "postversion": "npm publish",
129 | "preversion": "npm test",
130 | "test": "tap test.js --100",
131 | },
132 | "version": "1.1.1",
133 | }
134 | `
135 |
136 | exports[`test/dir.js TAP dir with integrity > packument 1`] = `
137 | Object {
138 | "dist-tags": Object {
139 | "latest": "1.1.1",
140 | },
141 | "name": "abbrev",
142 | "versions": Object {
143 | "1.1.1": Object {
144 | "_from": "file:test/fixtures/abbrev",
145 | "_id": "abbrev@1.1.1",
146 | "_integrity": "sha512-whatever-this-is-only-checked-if-we-extract-it",
147 | "_resolved": "{CWD}/test/fixtures/abbrev",
148 | "author": "Isaac Z. Schlueter ",
149 | "description": "Like ruby's abbrev module, but in js",
150 | "devDependencies": Object {
151 | "tap": "^10.1",
152 | },
153 | "dist": Object {
154 | "integrity": "{integrity}",
155 | "tarball": "file:{CWD}/test/fixtures/abbrev",
156 | },
157 | "files": Array [
158 | "abbrev.js",
159 | ],
160 | "license": "ISC",
161 | "main": "abbrev.js",
162 | "name": "abbrev",
163 | "repository": "http://github.com/isaacs/abbrev-js",
164 | "scripts": Object {
165 | "postpublish": "git push origin --all; git push origin --tags",
166 | "postversion": "npm publish",
167 | "preversion": "npm test",
168 | "test": "tap test.js --100",
169 | },
170 | "version": "1.1.1",
171 | },
172 | },
173 | }
174 | `
175 |
176 | exports[`test/dir.js TAP make bins executable > results of unpack 1`] = `
177 | Object {
178 | "from": "file:test/fixtures/bin-object",
179 | "integrity": "{integrity}",
180 | "resolved": "{CWD}/test/fixtures/bin-object",
181 | }
182 | `
183 |
184 | exports[`test/dir.js TAP responds to foregroundScripts: true > extract 1`] = `
185 | Object {
186 | "from": "file:test/fixtures/prepare-script",
187 | "integrity": "{integrity}",
188 | "resolved": "{CWD}/test/fixtures/prepare-script",
189 | }
190 | `
191 |
192 | exports[`test/dir.js TAP responds to foregroundScripts: true > file list 1`] = `
193 | Array [
194 | "index.js",
195 | "package.json",
196 | "prepare.js",
197 | ]
198 | `
199 |
200 | exports[`test/dir.js TAP responds to foregroundScripts: true > manifest 1`] = `
201 | Object {
202 | "_from": "file:test/fixtures/prepare-script",
203 | "_id": "git-prepare-script@1.0.0",
204 | "_integrity": null,
205 | "_resolved": "{CWD}/test/fixtures/prepare-script",
206 | "devDependencies": Object {
207 | "abbrev": "^1.1.1",
208 | },
209 | "license": "ISC",
210 | "main": "index.js",
211 | "name": "git-prepare-script",
212 | "scripts": Object {
213 | "prepare": "node prepare.js",
214 | },
215 | "version": "1.0.0",
216 | }
217 | `
218 |
219 | exports[`test/dir.js TAP responds to foregroundScripts: true > packument 1`] = `
220 | Object {
221 | "dist-tags": Object {
222 | "latest": "1.0.0",
223 | },
224 | "name": "git-prepare-script",
225 | "versions": Object {
226 | "1.0.0": Object {
227 | "_from": "file:test/fixtures/prepare-script",
228 | "_id": "git-prepare-script@1.0.0",
229 | "_integrity": null,
230 | "_resolved": "{CWD}/test/fixtures/prepare-script",
231 | "devDependencies": Object {
232 | "abbrev": "^1.1.1",
233 | },
234 | "dist": Object {
235 | "integrity": null,
236 | "tarball": "file:{CWD}/test/fixtures/prepare-script",
237 | },
238 | "license": "ISC",
239 | "main": "index.js",
240 | "name": "git-prepare-script",
241 | "scripts": Object {
242 | "prepare": "node prepare.js",
243 | },
244 | "version": "1.0.0",
245 | },
246 | },
247 | }
248 | `
249 |
250 | exports[`test/dir.js TAP with prepare script > extract 1`] = `
251 | Object {
252 | "from": "file:test/fixtures/prepare-script",
253 | "integrity": "{integrity}",
254 | "resolved": "{CWD}/test/fixtures/prepare-script",
255 | }
256 | `
257 |
258 | exports[`test/dir.js TAP with prepare script > file list 1`] = `
259 | Array [
260 | "index.js",
261 | "package.json",
262 | "prepare.js",
263 | ]
264 | `
265 |
266 | exports[`test/dir.js TAP with prepare script > manifest 1`] = `
267 | Object {
268 | "_from": "file:test/fixtures/prepare-script",
269 | "_id": "git-prepare-script@1.0.0",
270 | "_integrity": null,
271 | "_resolved": "{CWD}/test/fixtures/prepare-script",
272 | "devDependencies": Object {
273 | "abbrev": "^1.1.1",
274 | },
275 | "license": "ISC",
276 | "main": "index.js",
277 | "name": "git-prepare-script",
278 | "scripts": Object {
279 | "prepare": "node prepare.js",
280 | },
281 | "version": "1.0.0",
282 | }
283 | `
284 |
285 | exports[`test/dir.js TAP with prepare script > packument 1`] = `
286 | Object {
287 | "dist-tags": Object {
288 | "latest": "1.0.0",
289 | },
290 | "name": "git-prepare-script",
291 | "versions": Object {
292 | "1.0.0": Object {
293 | "_from": "file:test/fixtures/prepare-script",
294 | "_id": "git-prepare-script@1.0.0",
295 | "_integrity": null,
296 | "_resolved": "{CWD}/test/fixtures/prepare-script",
297 | "devDependencies": Object {
298 | "abbrev": "^1.1.1",
299 | },
300 | "dist": Object {
301 | "integrity": null,
302 | "tarball": "file:{CWD}/test/fixtures/prepare-script",
303 | },
304 | "license": "ISC",
305 | "main": "index.js",
306 | "name": "git-prepare-script",
307 | "scripts": Object {
308 | "prepare": "node prepare.js",
309 | },
310 | "version": "1.0.0",
311 | },
312 | },
313 | }
314 | `
315 |
316 | exports[`test/dir.js TAP with prepare script with scriptshell configuration > extract 1`] = `
317 | Object {
318 | "from": "file:test/fixtures/prepare-script",
319 | "integrity": "{integrity}",
320 | "resolved": "{CWD}/test/fixtures/prepare-script",
321 | }
322 | `
323 |
324 | exports[`test/dir.js TAP with prepare script with scriptshell configuration > file list 1`] = `
325 | Array [
326 | "index.js",
327 | "package.json",
328 | "prepare.js",
329 | ]
330 | `
331 |
332 | exports[`test/dir.js TAP with prepare script with scriptshell configuration > manifest 1`] = `
333 | Object {
334 | "_from": "file:test/fixtures/prepare-script",
335 | "_id": "git-prepare-script@1.0.0",
336 | "_integrity": null,
337 | "_resolved": "{CWD}/test/fixtures/prepare-script",
338 | "devDependencies": Object {
339 | "abbrev": "^1.1.1",
340 | },
341 | "license": "ISC",
342 | "main": "index.js",
343 | "name": "git-prepare-script",
344 | "scripts": Object {
345 | "prepare": "node prepare.js",
346 | },
347 | "version": "1.0.0",
348 | }
349 | `
350 |
351 | exports[`test/dir.js TAP with prepare script with scriptshell configuration > packument 1`] = `
352 | Object {
353 | "dist-tags": Object {
354 | "latest": "1.0.0",
355 | },
356 | "name": "git-prepare-script",
357 | "versions": Object {
358 | "1.0.0": Object {
359 | "_from": "file:test/fixtures/prepare-script",
360 | "_id": "git-prepare-script@1.0.0",
361 | "_integrity": null,
362 | "_resolved": "{CWD}/test/fixtures/prepare-script",
363 | "devDependencies": Object {
364 | "abbrev": "^1.1.1",
365 | },
366 | "dist": Object {
367 | "integrity": null,
368 | "tarball": "file:{CWD}/test/fixtures/prepare-script",
369 | },
370 | "license": "ISC",
371 | "main": "index.js",
372 | "name": "git-prepare-script",
373 | "scripts": Object {
374 | "prepare": "node prepare.js",
375 | },
376 | "version": "1.0.0",
377 | },
378 | },
379 | }
380 | `
381 |
--------------------------------------------------------------------------------
/tap-snapshots/test/fetcher.js-fake-sudo.test.cjs:
--------------------------------------------------------------------------------
1 | /* IMPORTANT
2 | * This snapshot file is auto-generated, but designed for humans.
3 | * It should be checked into source control and tracked carefully.
4 | * Re-generate by setting TAP_SNAPSHOT=1 and running tests.
5 | * Make sure to inspect the output below. Do not ignore changes!
6 | */
7 | 'use strict'
8 | exports[`test/fetcher.js fake-sudo TAP make bins executable > results of unpack 1`] = `
9 | Object {
10 | "from": "file:test/fixtures/bin-object.tgz",
11 | "integrity": "sha512-TqzCjecWyQe8vqLbT0nv/OaWf0ptRZ2DnPmiuGUYJJb70shp02+/uu37IJSkM2ZEP1SAOeKrYrWPVIIYW+d//g==",
12 | "resolved": "{CWD}/test/fixtures/bin-object.tgz",
13 | }
14 | `
15 |
16 | exports[`test/fetcher.js fake-sudo TAP snapshot the npmInstallCmd and npmInstallConfig > customized npmInstallCmd 1`] = `
17 | Array [
18 | "install",
19 | "blerg",
20 | ]
21 | `
22 |
23 | exports[`test/fetcher.js fake-sudo TAP snapshot the npmInstallCmd and npmInstallConfig > default install cmd 1`] = `
24 | Array [
25 | "install",
26 | "--force",
27 | ]
28 | `
29 |
30 | exports[`test/fetcher.js fake-sudo TAP snapshot the npmInstallCmd and npmInstallConfig > default install cmd with before 1`] = `
31 | Array [
32 | "install",
33 | "--force",
34 | ]
35 | `
36 |
37 | exports[`test/fetcher.js fake-sudo TAP snapshot the npmInstallCmd and npmInstallConfig > default install config 1`] = `
38 | Array [
39 | "--cache={CACHE}",
40 | "--prefer-offline=false",
41 | "--prefer-online=false",
42 | "--offline=false",
43 | "--no-progress",
44 | "--no-save",
45 | "--no-audit",
46 | "--include=dev",
47 | "--include=peer",
48 | "--include=optional",
49 | "--no-package-lock-only",
50 | "--no-dry-run",
51 | ]
52 | `
53 |
54 | exports[`test/fetcher.js fake-sudo TAP snapshot the npmInstallCmd and npmInstallConfig > default install config with before 1`] = `
55 | Array [
56 | "--cache={CACHE}",
57 | "--prefer-offline=false",
58 | "--prefer-online=false",
59 | "--offline=false",
60 | "--before=1979-07-01T19:10:00.000Z",
61 | "--no-progress",
62 | "--no-save",
63 | "--no-audit",
64 | "--include=dev",
65 | "--include=peer",
66 | "--include=optional",
67 | "--no-package-lock-only",
68 | "--no-dry-run",
69 | ]
70 | `
71 |
72 | exports[`test/fetcher.js fake-sudo TAP snapshot the npmInstallCmd and npmInstallConfig > yarn style cli config stuff 1`] = `
73 | Array [
74 | "--some",
75 | "--yarn",
76 | "--stuff",
77 | ]
78 | `
79 |
--------------------------------------------------------------------------------
/tap-snapshots/test/fetcher.js.test.cjs:
--------------------------------------------------------------------------------
1 | /* IMPORTANT
2 | * This snapshot file is auto-generated, but designed for humans.
3 | * It should be checked into source control and tracked carefully.
4 | * Re-generate by setting TAP_SNAPSHOT=1 and running tests.
5 | * Make sure to inspect the output below. Do not ignore changes!
6 | */
7 | 'use strict'
8 | exports[`test/fetcher.js TAP make bins executable > results of unpack 1`] = `
9 | Object {
10 | "from": "file:test/fixtures/bin-object.tgz",
11 | "integrity": "sha512-TqzCjecWyQe8vqLbT0nv/OaWf0ptRZ2DnPmiuGUYJJb70shp02+/uu37IJSkM2ZEP1SAOeKrYrWPVIIYW+d//g==",
12 | "resolved": "{CWD}/test/fixtures/bin-object.tgz",
13 | }
14 | `
15 |
16 | exports[`test/fetcher.js TAP snapshot the npmInstallCmd and npmInstallConfig > customized npmInstallCmd 1`] = `
17 | Array [
18 | "install",
19 | "blerg",
20 | ]
21 | `
22 |
23 | exports[`test/fetcher.js TAP snapshot the npmInstallCmd and npmInstallConfig > default install cmd 1`] = `
24 | Array [
25 | "install",
26 | "--force",
27 | ]
28 | `
29 |
30 | exports[`test/fetcher.js TAP snapshot the npmInstallCmd and npmInstallConfig > default install cmd with before 1`] = `
31 | Array [
32 | "install",
33 | "--force",
34 | ]
35 | `
36 |
37 | exports[`test/fetcher.js TAP snapshot the npmInstallCmd and npmInstallConfig > default install config 1`] = `
38 | Array [
39 | "--cache={CACHE}",
40 | "--prefer-offline=false",
41 | "--prefer-online=false",
42 | "--offline=false",
43 | "--no-progress",
44 | "--no-save",
45 | "--no-audit",
46 | "--include=dev",
47 | "--include=peer",
48 | "--include=optional",
49 | "--no-package-lock-only",
50 | "--no-dry-run",
51 | ]
52 | `
53 |
54 | exports[`test/fetcher.js TAP snapshot the npmInstallCmd and npmInstallConfig > default install config with before 1`] = `
55 | Array [
56 | "--cache={CACHE}",
57 | "--prefer-offline=false",
58 | "--prefer-online=false",
59 | "--offline=false",
60 | "--before=1979-07-01T19:10:00.000Z",
61 | "--no-progress",
62 | "--no-save",
63 | "--no-audit",
64 | "--include=dev",
65 | "--include=peer",
66 | "--include=optional",
67 | "--no-package-lock-only",
68 | "--no-dry-run",
69 | ]
70 | `
71 |
72 | exports[`test/fetcher.js TAP snapshot the npmInstallCmd and npmInstallConfig > yarn style cli config stuff 1`] = `
73 | Array [
74 | "--some",
75 | "--yarn",
76 | "--stuff",
77 | ]
78 | `
79 |
--------------------------------------------------------------------------------
/tap-snapshots/test/file.js.test.cjs:
--------------------------------------------------------------------------------
1 | /* IMPORTANT
2 | * This snapshot file is auto-generated, but designed for humans.
3 | * It should be checked into source control and tracked carefully.
4 | * Re-generate by setting TAP_SNAPSHOT=1 and running tests.
5 | * Make sure to inspect the output below. Do not ignore changes!
6 | */
7 | 'use strict'
8 | exports[`test/file.js TAP basic > extract 1`] = `
9 | Object {
10 | "from": "file:test/fixtures/abbrev-1.1.1.tgz",
11 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
12 | "resolved": "{CWD}/test/fixtures/abbrev-1.1.1.tgz",
13 | }
14 | `
15 |
16 | exports[`test/file.js TAP basic > manifest 1`] = `
17 | Object {
18 | "_from": "file:test/fixtures/abbrev-1.1.1.tgz",
19 | "_id": "abbrev@1.1.1",
20 | "_integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
21 | "_resolved": "{CWD}/test/fixtures/abbrev-1.1.1.tgz",
22 | "author": "Isaac Z. Schlueter ",
23 | "description": "Like ruby's abbrev module, but in js",
24 | "devDependencies": Object {
25 | "tap": "^10.1",
26 | },
27 | "files": Array [
28 | "abbrev.js",
29 | ],
30 | "license": "ISC",
31 | "main": "abbrev.js",
32 | "name": "abbrev",
33 | "repository": "http://github.com/isaacs/abbrev-js",
34 | "scripts": Object {
35 | "postpublish": "git push origin --all; git push origin --tags",
36 | "postversion": "npm publish",
37 | "preversion": "npm test",
38 | "test": "tap test.js --100",
39 | },
40 | "version": "1.1.1",
41 | }
42 | `
43 |
44 | exports[`test/file.js TAP basic > package.json extracted 1`] = `
45 | Object {
46 | "author": "Isaac Z. Schlueter ",
47 | "description": "Like ruby's abbrev module, but in js",
48 | "devDependencies": Object {
49 | "tap": "^10.1",
50 | },
51 | "files": Array [
52 | "abbrev.js",
53 | ],
54 | "license": "ISC",
55 | "main": "abbrev.js",
56 | "name": "abbrev",
57 | "repository": "http://github.com/isaacs/abbrev-js",
58 | "scripts": Object {
59 | "postpublish": "git push origin --all; git push origin --tags",
60 | "postversion": "npm publish",
61 | "preversion": "npm test",
62 | "test": "tap test.js --100",
63 | },
64 | "version": "1.1.1",
65 | }
66 | `
67 |
68 | exports[`test/file.js TAP basic > packument 1`] = `
69 | Object {
70 | "dist-tags": Object {
71 | "latest": "1.1.1",
72 | },
73 | "name": "abbrev",
74 | "versions": Object {
75 | "1.1.1": Object {
76 | "_from": "file:test/fixtures/abbrev-1.1.1.tgz",
77 | "_id": "abbrev@1.1.1",
78 | "_integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
79 | "_resolved": "{CWD}/test/fixtures/abbrev-1.1.1.tgz",
80 | "author": "Isaac Z. Schlueter ",
81 | "description": "Like ruby's abbrev module, but in js",
82 | "devDependencies": Object {
83 | "tap": "^10.1",
84 | },
85 | "dist": Object {
86 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
87 | "tarball": "file:{CWD}/test/fixtures/abbrev-1.1.1.tgz",
88 | },
89 | "files": Array [
90 | "abbrev.js",
91 | ],
92 | "license": "ISC",
93 | "main": "abbrev.js",
94 | "name": "abbrev",
95 | "repository": "http://github.com/isaacs/abbrev-js",
96 | "scripts": Object {
97 | "postpublish": "git push origin --all; git push origin --tags",
98 | "postversion": "npm publish",
99 | "preversion": "npm test",
100 | "test": "tap test.js --100",
101 | },
102 | "version": "1.1.1",
103 | },
104 | },
105 | }
106 | `
107 |
108 | exports[`test/file.js TAP make bins executable bin-good > results of unpack 1`] = `
109 | Object {
110 | "from": "file:test/fixtures/bin-good.tgz",
111 | "integrity": "sha512-Fx11OiHxV82CztnPk+k0S6H/66J4/eUzZEMGX2dJjP+Mxfrm8fSzE4SQG604zWk17ELZsOGENCdWSkvj4cpjUw==",
112 | "resolved": "{CWD}/test/fixtures/bin-good.tgz",
113 | }
114 | `
115 |
116 | exports[`test/file.js TAP make bins executable bin-object > results of unpack 1`] = `
117 | Object {
118 | "from": "file:test/fixtures/bin-object.tgz",
119 | "integrity": "sha512-TqzCjecWyQe8vqLbT0nv/OaWf0ptRZ2DnPmiuGUYJJb70shp02+/uu37IJSkM2ZEP1SAOeKrYrWPVIIYW+d//g==",
120 | "resolved": "{CWD}/test/fixtures/bin-object.tgz",
121 | }
122 | `
123 |
124 | exports[`test/file.js TAP make bins executable bin-string > results of unpack 1`] = `
125 | Object {
126 | "from": "file:test/fixtures/bin-string.tgz",
127 | "integrity": "sha512-iCc87DMYVMofO221ksAlMD88Zgsr4OIvqeX73KxTPikWaQPvBFZpzI9FGWnD4PTLTyJzOSETQh86+IwEidJRZg==",
128 | "resolved": "{CWD}/test/fixtures/bin-string.tgz",
129 | }
130 | `
131 |
132 | exports[`test/file.js TAP with readme > extract-slow-json 1`] = `
133 | Object {
134 | "from": "file:test/fixtures/abbrev-1.1.1.tgz",
135 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
136 | "resolved": "{CWD}/test/fixtures/abbrev-1.1.1.tgz",
137 | }
138 | `
139 |
140 | exports[`test/file.js TAP with readme > manifest-slow-json 1`] = `
141 | Object {
142 | "_from": "file:test/fixtures/abbrev-1.1.1.tgz",
143 | "_id": "abbrev@1.1.1",
144 | "_integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
145 | "_resolved": "{CWD}/test/fixtures/abbrev-1.1.1.tgz",
146 | "author": Object {
147 | "email": "i@izs.me",
148 | "name": "Isaac Z. Schlueter",
149 | },
150 | "bugs": Object {
151 | "url": "https://github.com/isaacs/abbrev-js/issues",
152 | },
153 | "description": "Like ruby's abbrev module, but in js",
154 | "devDependencies": Object {
155 | "tap": "^10.1",
156 | },
157 | "files": Array [
158 | "abbrev.js",
159 | ],
160 | "homepage": "https://github.com/isaacs/abbrev-js#readme",
161 | "license": "ISC",
162 | "main": "abbrev.js",
163 | "name": "abbrev",
164 | "readme": String(
165 | # abbrev-js
166 |
167 | Just like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).
168 |
169 | Usage:
170 |
171 | var abbrev = require("abbrev");
172 | abbrev("foo", "fool", "folding", "flop");
173 |
174 | // returns:
175 | { fl: 'flop'
176 | , flo: 'flop'
177 | , flop: 'flop'
178 | , fol: 'folding'
179 | , fold: 'folding'
180 | , foldi: 'folding'
181 | , foldin: 'folding'
182 | , folding: 'folding'
183 | , foo: 'foo'
184 | , fool: 'fool'
185 | }
186 |
187 | This is handy for command-line scripts, or other cases where you want to be able to accept shorthands.
188 |
189 | ),
190 | "readmeFilename": "README.md",
191 | "repository": Object {
192 | "type": "git",
193 | "url": "git+ssh://git@github.com/isaacs/abbrev-js.git",
194 | },
195 | "scripts": Object {
196 | "postpublish": "git push origin --all; git push origin --tags",
197 | "postversion": "npm publish",
198 | "preversion": "npm test",
199 | "test": "tap test.js --100",
200 | },
201 | "version": "1.1.1",
202 | }
203 | `
204 |
205 | exports[`test/file.js TAP with readme > package.json extracted slow json 1`] = `
206 | Object {
207 | "author": "Isaac Z. Schlueter ",
208 | "description": "Like ruby's abbrev module, but in js",
209 | "devDependencies": Object {
210 | "tap": "^10.1",
211 | },
212 | "files": Array [
213 | "abbrev.js",
214 | ],
215 | "license": "ISC",
216 | "main": "abbrev.js",
217 | "name": "abbrev",
218 | "repository": "http://github.com/isaacs/abbrev-js",
219 | "scripts": Object {
220 | "postpublish": "git push origin --all; git push origin --tags",
221 | "postversion": "npm publish",
222 | "preversion": "npm test",
223 | "test": "tap test.js --100",
224 | },
225 | "version": "1.1.1",
226 | }
227 | `
228 |
229 | exports[`test/file.js TAP with readme > packument-slow-json 1`] = `
230 | Object {
231 | "dist-tags": Object {
232 | "latest": "1.1.1",
233 | },
234 | "name": "abbrev",
235 | "versions": Object {
236 | "1.1.1": Object {
237 | "_from": "file:test/fixtures/abbrev-1.1.1.tgz",
238 | "_id": "abbrev@1.1.1",
239 | "_integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
240 | "_resolved": "{CWD}/test/fixtures/abbrev-1.1.1.tgz",
241 | "author": Object {
242 | "email": "i@izs.me",
243 | "name": "Isaac Z. Schlueter",
244 | },
245 | "bugs": Object {
246 | "url": "https://github.com/isaacs/abbrev-js/issues",
247 | },
248 | "description": "Like ruby's abbrev module, but in js",
249 | "devDependencies": Object {
250 | "tap": "^10.1",
251 | },
252 | "dist": Object {
253 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
254 | "tarball": "file:{CWD}/test/fixtures/abbrev-1.1.1.tgz",
255 | },
256 | "files": Array [
257 | "abbrev.js",
258 | ],
259 | "homepage": "https://github.com/isaacs/abbrev-js#readme",
260 | "license": "ISC",
261 | "main": "abbrev.js",
262 | "name": "abbrev",
263 | "readme": String(
264 | # abbrev-js
265 |
266 | Just like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).
267 |
268 | Usage:
269 |
270 | var abbrev = require("abbrev");
271 | abbrev("foo", "fool", "folding", "flop");
272 |
273 | // returns:
274 | { fl: 'flop'
275 | , flo: 'flop'
276 | , flop: 'flop'
277 | , fol: 'folding'
278 | , fold: 'folding'
279 | , foldi: 'folding'
280 | , foldin: 'folding'
281 | , folding: 'folding'
282 | , foo: 'foo'
283 | , fool: 'fool'
284 | }
285 |
286 | This is handy for command-line scripts, or other cases where you want to be able to accept shorthands.
287 |
288 | ),
289 | "readmeFilename": "README.md",
290 | "repository": Object {
291 | "type": "git",
292 | "url": "git+ssh://git@github.com/isaacs/abbrev-js.git",
293 | },
294 | "scripts": Object {
295 | "postpublish": "git push origin --all; git push origin --tags",
296 | "postversion": "npm publish",
297 | "preversion": "npm test",
298 | "test": "tap test.js --100",
299 | },
300 | "version": "1.1.1",
301 | },
302 | },
303 | }
304 | `
305 |
--------------------------------------------------------------------------------
/tap-snapshots/test/index.js.test.cjs:
--------------------------------------------------------------------------------
1 | /* IMPORTANT
2 | * This snapshot file is auto-generated, but designed for humans.
3 | * It should be checked into source control and tracked carefully.
4 | * Re-generate by setting TAP_SNAPSHOT=1 and running tests.
5 | * Make sure to inspect the output below. Do not ignore changes!
6 | */
7 | 'use strict'
8 | exports[`test/index.js TAP > extract 1`] = `
9 | Object {
10 | "from": "file:test/fixtures/abbrev-1.1.1.tgz",
11 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
12 | "resolved": "{CWD}/test/fixtures/abbrev-1.1.1.tgz",
13 | }
14 | `
15 |
16 | exports[`test/index.js TAP > manifest 1`] = `
17 | Object {
18 | "_from": "file:test/fixtures/abbrev-1.1.1.tgz",
19 | "_id": "abbrev@1.1.1",
20 | "_integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
21 | "_resolved": "{CWD}/test/fixtures/abbrev-1.1.1.tgz",
22 | "author": "Isaac Z. Schlueter ",
23 | "description": "Like ruby's abbrev module, but in js",
24 | "devDependencies": Object {
25 | "tap": "^10.1",
26 | },
27 | "files": Array [
28 | "abbrev.js",
29 | ],
30 | "license": "ISC",
31 | "main": "abbrev.js",
32 | "name": "abbrev",
33 | "repository": "http://github.com/isaacs/abbrev-js",
34 | "scripts": Object {
35 | "postpublish": "git push origin --all; git push origin --tags",
36 | "postversion": "npm publish",
37 | "preversion": "npm test",
38 | "test": "tap test.js --100",
39 | },
40 | "version": "1.1.1",
41 | }
42 | `
43 |
44 | exports[`test/index.js TAP > manifest 2`] = `
45 | Object {
46 | "_from": "file:test/fixtures/abbrev-1.1.1.tgz",
47 | "_id": "abbrev@1.1.1",
48 | "_integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
49 | "_resolved": "{CWD}/test/fixtures/abbrev-1.1.1.tgz",
50 | "author": "Isaac Z. Schlueter ",
51 | "description": "Like ruby's abbrev module, but in js",
52 | "devDependencies": Object {
53 | "tap": "^10.1",
54 | },
55 | "files": Array [
56 | "abbrev.js",
57 | ],
58 | "license": "ISC",
59 | "main": "abbrev.js",
60 | "name": "abbrev",
61 | "repository": "http://github.com/isaacs/abbrev-js",
62 | "scripts": Object {
63 | "postpublish": "git push origin --all; git push origin --tags",
64 | "postversion": "npm publish",
65 | "preversion": "npm test",
66 | "test": "tap test.js --100",
67 | },
68 | "version": "1.1.1",
69 | }
70 | `
71 |
72 | exports[`test/index.js TAP > packument 1`] = `
73 | Object {
74 | "dist-tags": Object {
75 | "latest": "1.1.1",
76 | },
77 | "name": "abbrev",
78 | "versions": Object {
79 | "1.1.1": Object {
80 | "_from": "file:test/fixtures/abbrev-1.1.1.tgz",
81 | "_id": "abbrev@1.1.1",
82 | "_integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
83 | "_resolved": "{CWD}/test/fixtures/abbrev-1.1.1.tgz",
84 | "author": "Isaac Z. Schlueter ",
85 | "description": "Like ruby's abbrev module, but in js",
86 | "devDependencies": Object {
87 | "tap": "^10.1",
88 | },
89 | "dist": Object {
90 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
91 | "tarball": "file:{CWD}/test/fixtures/abbrev-1.1.1.tgz",
92 | },
93 | "files": Array [
94 | "abbrev.js",
95 | ],
96 | "license": "ISC",
97 | "main": "abbrev.js",
98 | "name": "abbrev",
99 | "repository": "http://github.com/isaacs/abbrev-js",
100 | "scripts": Object {
101 | "postpublish": "git push origin --all; git push origin --tags",
102 | "postversion": "npm publish",
103 | "preversion": "npm test",
104 | "test": "tap test.js --100",
105 | },
106 | "version": "1.1.1",
107 | },
108 | },
109 | }
110 | `
111 |
112 | exports[`test/index.js TAP > resolve 1`] = `
113 | {CWD}/test/fixtures/abbrev-1.1.1.tgz
114 | `
115 |
116 | exports[`test/index.js TAP > tarball to file 1`] = `
117 | Object {
118 | "from": "file:test/fixtures/abbrev-1.1.1.tgz",
119 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
120 | "resolved": "{CWD}/test/fixtures/abbrev-1.1.1.tgz",
121 | }
122 | `
123 |
--------------------------------------------------------------------------------
/tap-snapshots/test/remote.js.test.cjs:
--------------------------------------------------------------------------------
1 | /* IMPORTANT
2 | * This snapshot file is auto-generated, but designed for humans.
3 | * It should be checked into source control and tracked carefully.
4 | * Re-generate by setting TAP_SNAPSHOT=1 and running tests.
5 | * Make sure to inspect the output below. Do not ignore changes!
6 | */
7 | 'use strict'
8 | exports[`test/remote.js TAP packument > packument 1`] = `
9 | Object {
10 | "dist-tags": Object {
11 | "latest": "1.1.1",
12 | },
13 | "name": "abbrev",
14 | "versions": Object {
15 | "1.1.1": Object {
16 | "_from": "https://registry.npmjs.org/abbrev.tgz",
17 | "_id": "abbrev@1.1.1",
18 | "_integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
19 | "_resolved": "http://localhost:{PORT}/abbrev.tgz",
20 | "author": "Isaac Z. Schlueter ",
21 | "description": "Like ruby's abbrev module, but in js",
22 | "devDependencies": Object {
23 | "tap": "^10.1",
24 | },
25 | "dist": Object {
26 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
27 | "tarball": "file:http://localhost:{PORT}/abbrev.tgz",
28 | },
29 | "files": Array [
30 | "abbrev.js",
31 | ],
32 | "license": "ISC",
33 | "main": "abbrev.js",
34 | "name": "abbrev",
35 | "repository": "http://github.com/isaacs/abbrev-js",
36 | "scripts": Object {
37 | "postpublish": "git push origin --all; git push origin --tags",
38 | "postversion": "npm publish",
39 | "preversion": "npm test",
40 | "test": "tap test.js --100",
41 | },
42 | "version": "1.1.1",
43 | },
44 | },
45 | }
46 | `
47 |
48 | exports[`test/remote.js TAP packument > packument 2 1`] = `
49 | Object {
50 | "dist-tags": Object {
51 | "latest": "1.1.1",
52 | },
53 | "name": "abbrev",
54 | "versions": Object {
55 | "1.1.1": Object {
56 | "_from": "https://registry.npmjs.org/abbrev.tgz",
57 | "_id": "abbrev@1.1.1",
58 | "_integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
59 | "_resolved": "http://localhost:{PORT}/abbrev.tgz",
60 | "author": "Isaac Z. Schlueter ",
61 | "description": "Like ruby's abbrev module, but in js",
62 | "devDependencies": Object {
63 | "tap": "^10.1",
64 | },
65 | "dist": Object {
66 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
67 | "tarball": "file:http://localhost:{PORT}/abbrev.tgz",
68 | },
69 | "files": Array [
70 | "abbrev.js",
71 | ],
72 | "license": "ISC",
73 | "main": "abbrev.js",
74 | "name": "abbrev",
75 | "repository": "http://github.com/isaacs/abbrev-js",
76 | "scripts": Object {
77 | "postpublish": "git push origin --all; git push origin --tags",
78 | "postversion": "npm publish",
79 | "preversion": "npm test",
80 | "test": "tap test.js --100",
81 | },
82 | "version": "1.1.1",
83 | },
84 | },
85 | }
86 | `
87 |
--------------------------------------------------------------------------------
/tap-snapshots/test/util/npm.js.test.cjs:
--------------------------------------------------------------------------------
1 | /* IMPORTANT
2 | * This snapshot file is auto-generated, but designed for humans.
3 | * It should be checked into source control and tracked carefully.
4 | * Re-generate by setting TAP_SNAPSHOT=1 and running tests.
5 | * Make sure to inspect the output below. Do not ignore changes!
6 | */
7 | 'use strict'
8 | exports[`test/util/npm.js TAP do the things > expect resolving Promise 1`] = `
9 | Object {
10 | "args": Array [
11 | "/path/to/npm/bin/npm-cli.js",
12 | "flerb",
13 | ],
14 | "cmd": "{NODE}",
15 | "code": undefined,
16 | "message": "oopsie",
17 | "signal": undefined,
18 | "stderr": "",
19 | "stdout": "[\\"{NODE}\\",[\\"/path/to/npm/bin/npm-cli.js\\",\\"flerb\\"],{\\"cwd\\":\\"/cwd\\",\\"env\\":{\\"environmental\\":\\"variables\\"}}]",
20 | }
21 | `
22 |
23 | exports[`test/util/npm.js TAP do the things > expect resolving Promise 2`] = `
24 | Object {
25 | "args": Array [
26 | "flerb",
27 | ],
28 | "cmd": "/path/to/npm",
29 | "code": undefined,
30 | "message": "oopsie",
31 | "signal": undefined,
32 | "stderr": "",
33 | "stdout": "[\\"/path/to/npm\\",[\\"flerb\\"],{\\"cwd\\":\\"/cwd\\",\\"env\\":{\\"environmental\\":\\"variables\\"}}]",
34 | }
35 | `
36 |
--------------------------------------------------------------------------------
/test/bin.js:
--------------------------------------------------------------------------------
1 | const t = require('tap')
2 | const { spawn } = require('node:child_process')
3 | const { Minipass } = require('minipass')
4 | const pkg = require('../package.json')
5 | const bin = require.resolve(`../${pkg.bin.pacote}`)
6 | const { main, run, parseArg, parse } = require(bin)
7 | const cleanSnapshot = require('./helpers/clean-snapshot.js')
8 |
9 | t.cleanSnapshot = str => cleanSnapshot(str)
10 | .split(pkg.version).join('{VERSION}')
11 |
12 | const pacote = require('../')
13 | pacote.resolve = (spec, conf) =>
14 | spec === 'fail' ? Promise.reject(new Error('fail'))
15 | : spec === 'string' ? Promise.resolve('just a string')
16 | : Promise.resolve({ method: 'resolve', spec, conf })
17 | pacote.manifest = (spec, conf) => Promise.resolve({
18 | method: 'manifest',
19 | spec,
20 | conf,
21 | _resolved: 'manifest resolved',
22 | _integrity: 'manifest integrity',
23 | _from: 'manifest from',
24 | })
25 | pacote.packument = (spec, conf) => Promise.resolve({ method: 'packument', spec, conf })
26 | pacote.tarball.file = (spec, file, conf) => Promise.resolve({ method: 'tarball', spec, file, conf })
27 | pacote.tarball.stream = (spec, handler) => handler(new Minipass().end('tarball data'))
28 | pacote.extract = (spec, dest, conf) => Promise.resolve({ method: 'extract', spec, dest, conf })
29 |
30 | t.test('running bin runs main file', t => {
31 | const proc = spawn(process.execPath, [bin, '-h'])
32 | const out = []
33 | proc.stdout.on('data', c => out.push(c))
34 | proc.on('close', (code, signal) => {
35 | t.equal(code, 0)
36 | t.equal(signal, null)
37 | t.matchSnapshot(Buffer.concat(out).toString('utf8'), 'helpful output')
38 | t.end()
39 | })
40 | })
41 |
42 | t.test('parseArg', t => {
43 | t.same(parseArg('--foo-bar=baz=boo'), { key: 'fooBar', value: 'baz=boo' })
44 | t.same(parseArg('--tag=boo'), { key: 'defaultTag', value: 'boo' })
45 | t.same(parseArg('--foo'), { key: 'foo', value: true })
46 | t.same(parseArg('--path=~'), { key: 'path', value: process.env.HOME })
47 | t.same(parseArg('--no-foo'), { key: 'foo', value: false })
48 | t.end()
49 | })
50 |
51 | t.test('parse', t => {
52 | t.same(parse(['a', 'b', '--foo', '--no-json']), {
53 | _: ['a', 'b'],
54 | foo: true,
55 | json: false,
56 | cache: process.env.HOME + '/.npm/_cacache',
57 | })
58 | t.same(parse(['a', 'b', '--foo', '--json']), {
59 | _: ['a', 'b'],
60 | foo: true,
61 | json: true,
62 | cache: process.env.HOME + '/.npm/_cacache',
63 | })
64 | t.same(parse(['a', 'b', '--', '--json']), {
65 | _: ['a', 'b', '--json'],
66 | cache: process.env.HOME + '/.npm/_cacache',
67 | })
68 | t.match(parse(['-h']), { help: true })
69 | t.end()
70 | })
71 |
72 | t.test('run', t => {
73 | const conf = { some: 'configs' }
74 | t.resolveMatchSnapshot(run({ ...conf, _: ['resolve', 'spec'] }))
75 | t.resolveMatchSnapshot(run({ ...conf, _: ['manifest', 'spec'] }))
76 | t.resolveMatchSnapshot(run({ ...conf, _: ['packument', 'spec'] }))
77 | t.resolveMatchSnapshot(run({ ...conf, _: ['tarball', 'spec', 'file'] }))
78 | t.resolveMatchSnapshot(run({ ...conf, _: ['extract', 'spec', 'dest'] }))
79 | t.throws(() => run({ ...conf, _: ['x'] }), { message: 'bad command: x' })
80 |
81 | const testStdout = new Minipass({ encoding: 'utf8' })
82 | return t.resolveMatchSnapshot(run({
83 | ...conf,
84 | _: ['tarball'],
85 | testStdout,
86 | })).then(() => t.equal(testStdout.read(), 'tarball data'))
87 | })
88 |
89 | t.test('main', t => {
90 | const { log, error } = console
91 | const { exit } = process
92 | t.teardown(() => {
93 | console.log = log
94 | console.error = error
95 | process.exit = exit
96 | })
97 |
98 | const errorlog = []
99 | console.error = (...args) => errorlog.push(args)
100 | const loglog = []
101 | console.log = (...args) => loglog.push(args)
102 |
103 | const exitlog = []
104 | process.exit = code => exitlog.push(code)
105 |
106 | t.beforeEach(() => {
107 | errorlog.length = 0
108 | loglog.length = 0
109 | exitlog.length = 0
110 | })
111 |
112 | Object.defineProperty(process.stdout, 'isTTY', { value: false })
113 |
114 | const test = (...args) =>
115 | t.test(args.join(' '), t => Promise.resolve(main(args))
116 | .then(() => t.matchSnapshot({ errorlog, loglog, exitlog })))
117 |
118 | test('--help')
119 | test('resolve', 'foo@bar')
120 | test('resolve', 'foo@bar', '--long')
121 | test('resolve', 'string')
122 | test('resolve', 'string', '--json')
123 | test('manifest', 'bar@foo')
124 | test('packument', 'paku@mint')
125 | test('tarball', 'tar@ball', 'file.tgz')
126 | test('extract', 'npm@latest-6', 'folder', '--no-json')
127 | test('extract', 'npm@latest-6', 'folder', '--json')
128 | test('blerg', 'glorb', 'glork')
129 | test('resolve', 'fail')
130 | t.end()
131 | })
132 |
--------------------------------------------------------------------------------
/test/dir.js:
--------------------------------------------------------------------------------
1 | const runScript = require('@npmcli/run-script')
2 | const RUNS = []
3 | const t = require('tap')
4 | const Arborist = require('@npmcli/arborist')
5 | const fs = require('node:fs')
6 | const { relative, resolve, basename } = require('node:path')
7 | const cleanSnapshot = require('./helpers/clean-snapshot.js')
8 | const scriptMode = require('./helpers/script-mode.js')
9 |
10 | const loadActual = async (path) => {
11 | const arb = new Arborist({ path })
12 | const tree = await arb.loadActual()
13 | return tree
14 | }
15 |
16 | const DirFetcher = t.mock('../lib/dir.js', {
17 | '@npmcli/run-script': (opts) => {
18 | RUNS.push(opts)
19 | // don't actually inherit or print banner in the test, though.
20 | return runScript({ ...opts, stdio: 'pipe', banner: false })
21 | },
22 | })
23 |
24 | const me = t.testdir()
25 |
26 | t.cleanSnapshot = str => cleanSnapshot(str)
27 | .replace(/"integrity": ".*",/g, '"integrity": "{integrity}",')
28 |
29 | const abbrev = resolve(__dirname, 'fixtures/abbrev')
30 | const abbrevspec = `file:${relative(process.cwd(), abbrev)}`
31 |
32 | t.test('basic', async t => {
33 | const f = new DirFetcher(abbrevspec, { tree: await loadActual(abbrev) })
34 | t.same(f.types, ['directory'])
35 | t.resolveMatchSnapshot(f.packument(), 'packument')
36 | t.resolveMatchSnapshot(f.manifest(), 'manifest')
37 | const pj = me + '/abbrev/package.json'
38 | return t.resolveMatchSnapshot(f.extract(me + '/abbrev'), 'extract')
39 | .then(() => t.matchSnapshot(require(pj), 'package.json extracted'))
40 | .then(() => t.matchSnapshot(f.package, 'saved package.json'))
41 | .then(() => f.manifest().then(mani => t.equal(mani, f.package)))
42 | })
43 |
44 | t.test('dir with integrity', async t => {
45 | const f = new DirFetcher(abbrevspec, {
46 | integrity: 'sha512-whatever-this-is-only-checked-if-we-extract-it',
47 | tree: await loadActual(abbrev),
48 | })
49 | t.same(f.types, ['directory'])
50 | return t.resolveMatchSnapshot(f.packument(), 'packument')
51 | })
52 |
53 | const prepare = resolve(__dirname, 'fixtures/prepare-script')
54 | const preparespec = `file:${relative(process.cwd(), prepare)}`
55 |
56 | t.test('with prepare script', async t => {
57 | RUNS.length = 0
58 | const f = new DirFetcher(preparespec, { tree: await loadActual(prepare) })
59 | t.resolveMatchSnapshot(f.packument(), 'packument')
60 | t.resolveMatchSnapshot(f.manifest(), 'manifest')
61 | const index = me + '/prepare/index.js'
62 | return t.resolveMatchSnapshot(f.extract(me + '/prepare'), 'extract')
63 | .then(() => t.spawn(process.execPath, [index], 'test prepared result'))
64 | .then(() => t.matchSnapshot(fs.readdirSync(me + '/prepare').sort(), 'file list'))
65 | .then(() => t.match(RUNS[0], {
66 | stdio: 'pipe',
67 | }, 'should run in background'))
68 | })
69 |
70 | const prepack = resolve(__dirname, 'fixtures/prepack-script')
71 | const prepackspec = `file:${relative(process.cwd(), prepack)}`
72 |
73 | t.test('with prepack script with _PACOTE_FROM_GIT_ is enabled', async t => {
74 | RUNS.length = 0
75 | process.env._PACOTE_FROM_GIT_ = "yes"
76 | t.teardown(() => {
77 | delete process.env._PACOTE_FROM_GIT_
78 | })
79 | const f = new DirFetcher(prepackspec, { tree: await loadActual(prepack) })
80 | t.resolveMatchSnapshot(f.packument(), 'packument')
81 | t.resolveMatchSnapshot(f.manifest(), 'manifest')
82 | const index = me + '/prepack/index.js'
83 | return t.resolveMatchSnapshot(f.extract(me + '/prepack'), 'extract')
84 | .then(() => t.spawn(process.execPath, [index], 'test prepacked result'))
85 | .then(() => t.matchSnapshot(fs.readdirSync(me + '/prepack').sort(), 'file list'))
86 | .then(() => t.match(RUNS[0], {
87 | stdio: 'pipe',
88 | }, 'should run in background'))
89 | })
90 |
91 | t.test('with prepack script and _PACOTE_FROM_GIT_ is disabled', async t => {
92 | let shouldNotBePopulated = false
93 |
94 | const DirFetcherIsolate = t.mock('../lib/dir.js', {
95 | '@npmcli/run-script': () => {
96 | shouldNotBePopulated = true
97 | },
98 | })
99 |
100 | const dir = t.testdir({
101 | 'package.json': JSON.stringify({
102 | name: 'meow',
103 | version: '1.0.0',
104 | scripts: {
105 | prepack: 'noop',
106 | },
107 | }),
108 | })
109 | const f = new DirFetcherIsolate(`file:${relative(process.cwd(), dir)}`, {
110 | tree: await loadActual(dir)
111 | })
112 | await f.extract(me + '/prepack-ignore')
113 | t.ok(!shouldNotBePopulated)
114 | })
115 |
116 | t.test('with prepare script with scriptshell configuration', async t => {
117 | RUNS.length = 0
118 | const f = new DirFetcher(preparespec, { tree: await loadActual(prepare), scriptShell: 'sh' })
119 | t.resolveMatchSnapshot(f.packument(), 'packument')
120 | t.resolveMatchSnapshot(f.manifest(), 'manifest')
121 | const index = me + '/prepare/index.js'
122 | return t.resolveMatchSnapshot(f.extract(me + '/prepare'), 'extract')
123 | .then(() => t.spawn(process.execPath, [index], 'test prepared result'))
124 | .then(() => t.matchSnapshot(fs.readdirSync(me + '/prepare').sort(), 'file list'))
125 | .then(() => t.match(RUNS,
126 | [{
127 | stdio: 'pipe',
128 | scriptShell: 'sh',
129 | }], 'should run in background and use scriptshell configuration'))
130 | })
131 |
132 | t.test('responds to foregroundScripts: true', async t => {
133 | RUNS.length = 0
134 | const opt = { foregroundScripts: true, tree: await loadActual(prepare) }
135 | const f = new DirFetcher(preparespec, opt)
136 | t.resolveMatchSnapshot(f.packument(), 'packument')
137 | t.resolveMatchSnapshot(f.manifest(), 'manifest')
138 | const index = me + '/prepare/index.js'
139 | return t.resolveMatchSnapshot(f.extract(me + '/prepare'), 'extract')
140 | .then(() => t.spawn(process.execPath, [index], 'test prepared result'))
141 | .then(() => t.matchSnapshot(fs.readdirSync(me + '/prepare').sort(), 'file list'))
142 | .then(() => t.match(RUNS[0], {
143 | stdio: 'inherit',
144 | }, 'should run in foreground'))
145 | })
146 |
147 | t.test('missing dir cannot be packed', async t => {
148 | const f = new DirFetcher('file:/this/dir/doesnt/exist', { tree: await loadActual() })
149 | if (process.platform !== 'win32') {
150 | return t.rejects(f.extract(me + '/nope'), {
151 | message: `no such file or directory, open '/this/dir/doesnt/exist/package.json`,
152 | errno: Number,
153 | code: 'ENOENT',
154 | syscall: 'open',
155 | path: '/this/dir/doesnt/exist/package.json',
156 | })
157 | } else {
158 | return t.rejects(f.extract(me + '/nope'), {
159 | errno: Number,
160 | code: 'ENOENT',
161 | syscall: 'open',
162 | path: new RegExp('\\\\this\\\\dir\\\\doesnt\\\\exist\\\\package.json'),
163 | name: 'Error',
164 | })
165 | }
166 | })
167 |
168 | t.test('when read fails', async t => {
169 | const read = fs.read
170 | t.teardown(() => fs.read = read)
171 | const poop = new Error('poop')
172 | fs.read = (...args) => setTimeout(() => args[args.length - 1](poop))
173 | const f = new DirFetcher(preparespec, { tree: await loadActual() })
174 | return t.rejects(f.extract(me + '/nope'), poop)
175 | })
176 |
177 | t.test('make bins executable', async t => {
178 | const file = resolve(__dirname, 'fixtures/bin-object')
179 | const spec = `file:${relative(process.cwd(), file)}`
180 | const f = new DirFetcher(spec, { tree: await loadActual(file) })
181 | const target = resolve(me, basename(file))
182 | const res = await f.extract(target)
183 | // node v13.8 swapped out their zlib implementation with chromium's
184 | // This is slightly faster and results in better compression for most
185 | // tarballs. However, it does mean that the snapshotted integrity is
186 | // not valid. Check if it's the new one, and if so, use the old instead,
187 | // so that the snapshot continues to be valid. At some point, when we
188 | // drop support for node versions prior to 14, we can just remove this
189 | // and re-generate the snapshot.
190 |
191 | // eslint-disable-next-line max-len
192 | const oldIntegrity = 'sha512-rlE32nBV7XgKCm0I7YqAewyVPbaRJWUQMZUFLlngGK3imG+som3Hin7d/zPTikWg64tHIxb8VXeeq6u0IRRfmQ=='
193 | // eslint-disable-next-line max-len
194 | const newIntegrity = 'sha512-J9g/qC58EQ6h3xMyc1lPP2vlmjy6N5symUYih/l9M3A340A1OHPc88oMSAwVdLKj/lT3NbekLXVjU6ONnPbJYg=='
195 | const resTest = {
196 | ...res,
197 | ...(res.integrity === newIntegrity ? { integrity: oldIntegrity } : {}),
198 | }
199 | t.matchSnapshot(resTest, 'results of unpack')
200 | t.equal(fs.statSync(target + '/script.js').mode & scriptMode(), scriptMode())
201 | })
202 |
203 | t.test('exposes tarCreateOptions method', async t => {
204 | const simpleOpts = DirFetcher.tarCreateOptions({ _resolved: '/home/foo' })
205 | t.match(
206 | simpleOpts,
207 | {
208 | cwd: '/home/foo',
209 | prefix: 'package/',
210 | portable: true,
211 | gzip: {
212 | level: 9,
213 | },
214 | mtime: new Date('1985-10-26T08:15:00.000Z'),
215 | },
216 | 'should return standard options'
217 | )
218 | })
219 |
220 | t.test('fails without a tree or constructor', async t => {
221 | const f = new DirFetcher(abbrevspec, {})
222 | t.rejects(() => f.extract(me + '/prepare'))
223 | })
224 |
225 | t.test('with prepare script and ignoreScripts true', async t => {
226 | let shouldNotBePopulated = false
227 |
228 | const DirFetcherIsolate = t.mock('../lib/dir.js', {
229 | '@npmcli/run-script': () => {
230 | shouldNotBePopulated = true
231 | },
232 | })
233 |
234 | const dir = t.testdir({
235 | 'package.json': JSON.stringify({
236 | name: 'meow',
237 | version: '1.0.0',
238 | scripts: {
239 | prepare: 'noop',
240 | },
241 | }),
242 | })
243 | const f = new DirFetcherIsolate(`file:${relative(process.cwd(), dir)}`, {
244 | tree: await loadActual(dir),
245 | ignoreScripts: true,
246 | })
247 | await f.extract(me + '/prepare-ignore')
248 | t.ok(!shouldNotBePopulated)
249 | })
--------------------------------------------------------------------------------
/test/file.js:
--------------------------------------------------------------------------------
1 | const t = require('tap')
2 | const { relative, resolve, basename } = require('node:path')
3 | const fs = require('node:fs')
4 | const FileFetcher = require('../lib/file.js')
5 | const cleanSnapshot = require('./helpers/clean-snapshot.js')
6 | const scriptMode = require('./helpers/script-mode.js')
7 |
8 | t.cleanSnapshot = str => cleanSnapshot(str)
9 |
10 | const me = t.testdir({ cache: {} })
11 | const cache = resolve(me, 'cache')
12 | const abbrev = resolve(__dirname, 'fixtures/abbrev-1.1.1.tgz')
13 | const abbrevspec = `file:${relative(process.cwd(), abbrev)}`
14 |
15 | t.test('basic', async t => {
16 | const f = new FileFetcher(abbrevspec, { cache })
17 | t.same(f.types, ['file'])
18 | const fm = await f.manifest()
19 | t.matchSnapshot(fm, 'manifest')
20 | t.equal(fm, f.package)
21 | t.equal(await f.manifest(), fm, 'cached manifest')
22 | t.matchSnapshot(await f.packument(), 'packument')
23 | const pj = me + '/extract/package.json'
24 | t.matchSnapshot(await f.extract(me + '/extract'), 'extract')
25 | t.matchSnapshot(require(pj), 'package.json extracted')
26 | // just verify that the file is there.
27 | t.same(fs.readdirSync(resolve(cache, 'content-v2/sha512/9e/77')), [
28 | // eslint-disable-next-line max-len
29 | 'bdfc8890fe1cc8858ea97439db06dcfb0e33d32ab634d0fff3bcf4a6e69385925eb1b86ac69d79ff56d4cd35f36d01f67dff546d7a192ccd4f6a7138a2d1',
30 | ], 'write cache content file')
31 | })
32 |
33 | const binString = resolve(__dirname, 'fixtures/bin-string.tgz')
34 | const binObject = resolve(__dirname, 'fixtures/bin-object.tgz')
35 | // this one actually doesn't need any help
36 | const binGood = resolve(__dirname, 'fixtures/bin-good.tgz')
37 |
38 | t.test('make bins executable', t => {
39 | const files = [binString, binObject, binGood]
40 | t.plan(files.length)
41 | files.forEach(file => t.test(basename(file, '.tgz'), async t => {
42 | const spec = `file:${relative(process.cwd(), file)}`
43 | const f = new FileFetcher(spec, {})
44 | const target = resolve(me, basename(file, '.tgz'))
45 | const res = await f.extract(target)
46 | t.matchSnapshot(res, 'results of unpack')
47 | t.equal(fs.statSync(target + '/script.js').mode & scriptMode(), scriptMode())
48 | }))
49 | })
50 |
51 | t.test('dont bork on missing script', async t => {
52 | const file = resolve(__dirname, 'fixtures/bin-missing.tgz')
53 | const spec = `file:${relative(process.cwd(), file)}`
54 | const f = new FileFetcher(spec, {})
55 | const target = resolve(me, basename(file, '.tgz'))
56 | await f.extract(target)
57 | t.throws(() => fs.statSync(target + '/script.js'), 'should be missing')
58 | })
59 |
60 | t.test('with readme', async t => {
61 | const f = new FileFetcher(abbrevspec, { cache, fullReadJson: true })
62 | t.same(f.types, ['file'])
63 | const fm = await f.manifest()
64 | delete fm.gitHead
65 | t.matchSnapshot(fm, 'manifest-slow-json')
66 | t.equal(fm, f.package)
67 | t.equal(await f.manifest(), fm, 'cached manifest')
68 | t.matchSnapshot(await f.packument(), 'packument-slow-json')
69 | const pj = me + '/extract/package.json'
70 | t.matchSnapshot(await f.extract(me + '/extract'), 'extract-slow-json')
71 | t.matchSnapshot(require(pj), 'package.json extracted slow json')
72 | // just verify that the file is there.
73 | t.same(fs.readdirSync(resolve(cache, 'content-v2/sha512/9e/77')), [
74 | // eslint-disable-next-line max-len
75 | 'bdfc8890fe1cc8858ea97439db06dcfb0e33d32ab634d0fff3bcf4a6e69385925eb1b86ac69d79ff56d4cd35f36d01f67dff546d7a192ccd4f6a7138a2d1',
76 | ], 'write cache content file')
77 | })
78 |
--------------------------------------------------------------------------------
/test/fixtures/abbrev-1.1.1.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zkat/pacote-old/ebf5db458a0e00c84f160cd546f04e46fae13c77/test/fixtures/abbrev-1.1.1.tgz
--------------------------------------------------------------------------------
/test/fixtures/abbrev-manifest-file.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "abbrev",
3 | "version": "1.1.1",
4 | "description": "Like ruby's abbrev module, but in js",
5 | "author": {
6 | "name": "Isaac Z. Schlueter",
7 | "email": "i@izs.me"
8 | },
9 | "main": "abbrev.js",
10 | "scripts": {
11 | "test": "tap test.js --100",
12 | "preversion": "npm test",
13 | "postversion": "npm publish",
14 | "postpublish": "git push origin --all; git push origin --tags"
15 | },
16 | "repository": {
17 | "type": "git",
18 | "url": "git+ssh://git@github.com/isaacs/abbrev-js.git"
19 | },
20 | "license": "ISC",
21 | "devDependencies": {
22 | "tap": "^10.1"
23 | },
24 | "files": [
25 | "abbrev.js"
26 | ],
27 | "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",
28 | "readmeFilename": "README.md",
29 | "bugs": {
30 | "url": "https://github.com/isaacs/abbrev-js/issues"
31 | },
32 | "homepage": "https://github.com/isaacs/abbrev-js#readme",
33 | "_id": "abbrev@1.1.1",
34 | "_integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
35 | "_resolved": "{CWD}/test/fixtures/abbrev-1.1.1.tgz"
36 | }
37 |
--------------------------------------------------------------------------------
/test/fixtures/abbrev-manifest-min.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "abbrev",
3 | "version": "1.1.1",
4 | "devDependencies": {
5 | "tap": "^10.1"
6 | },
7 | "directories": {},
8 | "dist": {
9 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
10 | "shasum": "f8f2c887ad10bf67f634f005b6987fed3179aac8",
11 | "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz"
12 | },
13 | "_resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
14 | "_integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
15 | }
16 |
--------------------------------------------------------------------------------
/test/fixtures/abbrev-packument-file.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "abbrev",
3 | "dist-tags": {
4 | "latest": "1.1.1"
5 | },
6 | "versions": {
7 | "1.1.1": {
8 | "name": "abbrev",
9 | "version": "1.1.1",
10 | "description": "Like ruby's abbrev module, but in js",
11 | "author": {
12 | "name": "Isaac Z. Schlueter",
13 | "email": "i@izs.me"
14 | },
15 | "main": "abbrev.js",
16 | "scripts": {
17 | "test": "tap test.js --100",
18 | "preversion": "npm test",
19 | "postversion": "npm publish",
20 | "postpublish": "git push origin --all; git push origin --tags"
21 | },
22 | "repository": {
23 | "type": "git",
24 | "url": "git+ssh://git@github.com/isaacs/abbrev-js.git"
25 | },
26 | "license": "ISC",
27 | "devDependencies": {
28 | "tap": "^10.1"
29 | },
30 | "files": [
31 | "abbrev.js"
32 | ],
33 | "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",
34 | "readmeFilename": "README.md",
35 | "bugs": {
36 | "url": "https://github.com/isaacs/abbrev-js/issues"
37 | },
38 | "homepage": "https://github.com/isaacs/abbrev-js#readme",
39 | "_id": "abbrev@1.1.1",
40 | "_integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
41 | "_resolved": "{CWD}/test/fixtures/abbrev-1.1.1.tgz",
42 | "dist": {
43 | "tarball": "file:{CWD}/test/fixtures/abbrev-1.1.1.tgz",
44 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/test/fixtures/abbrev-packument-min.json:
--------------------------------------------------------------------------------
1 | {
2 | "versions": {
3 | "1.0.3": {
4 | "name": "abbrev",
5 | "version": "1.0.3",
6 | "directories": {},
7 | "dist": {
8 | "shasum": "aa049c967f999222aa42e14434f0c562ef468241",
9 | "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.3.tgz"
10 | },
11 | "engines": {
12 | "node": "*"
13 | }
14 | },
15 | "1.0.4": {
16 | "name": "abbrev",
17 | "version": "1.0.4",
18 | "directories": {},
19 | "dist": {
20 | "shasum": "bd55ae5e413ba1722ee4caba1f6ea10414a59ecd",
21 | "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz"
22 | }
23 | },
24 | "1.0.5": {
25 | "name": "abbrev",
26 | "version": "1.0.5",
27 | "directories": {},
28 | "dist": {
29 | "shasum": "5d8257bd9ebe435e698b2fa431afde4fe7b10b03",
30 | "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz"
31 | }
32 | },
33 | "1.0.6": {
34 | "name": "abbrev",
35 | "version": "1.0.6",
36 | "directories": {},
37 | "dist": {
38 | "shasum": "b6d632b859b3fa2d6f7e4b195472461b9e32dc30",
39 | "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.6.tgz"
40 | }
41 | },
42 | "1.0.7": {
43 | "name": "abbrev",
44 | "version": "1.0.7",
45 | "devDependencies": {
46 | "tap": "^1.2.0"
47 | },
48 | "directories": {},
49 | "dist": {
50 | "shasum": "5b6035b2ee9d4fb5cf859f08a9be81b208491843",
51 | "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz"
52 | }
53 | },
54 | "1.0.9": {
55 | "name": "abbrev",
56 | "version": "1.0.9",
57 | "devDependencies": {
58 | "tap": "^5.7.2"
59 | },
60 | "directories": {},
61 | "dist": {
62 | "shasum": "91b4792588a7738c25f35dd6f63752a2f8776135",
63 | "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz"
64 | }
65 | },
66 | "1.1.0": {
67 | "name": "abbrev",
68 | "version": "1.1.0",
69 | "devDependencies": {
70 | "tap": "^10.1"
71 | },
72 | "directories": {},
73 | "dist": {
74 | "shasum": "d0554c2256636e2f56e7c2e5ad183f859428d81f",
75 | "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz"
76 | }
77 | },
78 | "1.1.1": {
79 | "name": "abbrev",
80 | "version": "1.1.1",
81 | "devDependencies": {
82 | "tap": "^10.1"
83 | },
84 | "directories": {},
85 | "dist": {
86 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
87 | "shasum": "f8f2c887ad10bf67f634f005b6987fed3179aac8",
88 | "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz"
89 | }
90 | }
91 | },
92 | "name": "abbrev",
93 | "dist-tags": {
94 | "latest": "1.1.1"
95 | },
96 | "modified": "2019-08-19T22:32:42.280Z",
97 | "_cached": false,
98 | "_contentLength": 1866
99 | }
100 |
--------------------------------------------------------------------------------
/test/fixtures/abbrev/LICENSE:
--------------------------------------------------------------------------------
1 | This software is dual-licensed under the ISC and MIT licenses.
2 | You may use this software under EITHER of the following licenses.
3 |
4 | ----------
5 |
6 | The ISC License
7 |
8 | Copyright (c) Isaac Z. Schlueter and Contributors
9 |
10 | Permission to use, copy, modify, and/or distribute this software for any
11 | purpose with or without fee is hereby granted, provided that the above
12 | copyright notice and this permission notice appear in all copies.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
20 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 |
22 | ----------
23 |
24 | Copyright Isaac Z. Schlueter and Contributors
25 | All rights reserved.
26 |
27 | Permission is hereby granted, free of charge, to any person
28 | obtaining a copy of this software and associated documentation
29 | files (the "Software"), to deal in the Software without
30 | restriction, including without limitation the rights to use,
31 | copy, modify, merge, publish, distribute, sublicense, and/or sell
32 | copies of the Software, and to permit persons to whom the
33 | Software is furnished to do so, subject to the following
34 | conditions:
35 |
36 | The above copyright notice and this permission notice shall be
37 | included in all copies or substantial portions of the Software.
38 |
39 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
40 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
41 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
42 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
43 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
44 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
45 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
46 | OTHER DEALINGS IN THE SOFTWARE.
47 |
--------------------------------------------------------------------------------
/test/fixtures/abbrev/README.md:
--------------------------------------------------------------------------------
1 | # abbrev-js
2 |
3 | Just like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).
4 |
5 | Usage:
6 |
7 | var abbrev = require("abbrev");
8 | abbrev("foo", "fool", "folding", "flop");
9 |
10 | // returns:
11 | { fl: 'flop'
12 | , flo: 'flop'
13 | , flop: 'flop'
14 | , fol: 'folding'
15 | , fold: 'folding'
16 | , foldi: 'folding'
17 | , foldin: 'folding'
18 | , folding: 'folding'
19 | , foo: 'foo'
20 | , fool: 'fool'
21 | }
22 |
23 | This is handy for command-line scripts, or other cases where you want to be able to accept shorthands.
24 |
--------------------------------------------------------------------------------
/test/fixtures/abbrev/abbrev.js:
--------------------------------------------------------------------------------
1 | module.exports = exports = abbrev.abbrev = abbrev
2 |
3 | abbrev.monkeyPatch = monkeyPatch
4 |
5 | function monkeyPatch () {
6 | // eslint-disable-next-line no-extend-native
7 | Object.defineProperty(Array.prototype, 'abbrev', {
8 | value: function () {
9 | return abbrev(this)
10 | },
11 | enumerable: false,
12 | configurable: true,
13 | writable: true,
14 | })
15 | // eslint-disable-next-line no-extend-native
16 | Object.defineProperty(Object.prototype, 'abbrev', {
17 | value: function () {
18 | return abbrev(Object.keys(this))
19 | },
20 | enumerable: false,
21 | configurable: true,
22 | writable: true,
23 | })
24 | }
25 |
26 | function abbrev (list) {
27 | if (arguments.length !== 1 || !Array.isArray(list)) {
28 | list = Array.prototype.slice.call(arguments, 0)
29 | }
30 | let args = []
31 | for (let i = 0, l = list.length; i < l; i++) {
32 | args[i] = typeof list[i] === 'string' ? list[i] : String(list[i])
33 | }
34 |
35 | // sort them lexicographically, so that they're next to their nearest kin
36 | args = args.sort(lexSort)
37 |
38 | // walk through each, seeing how much it has in common with the next and previous
39 | var abbrevs = {}
40 | var prev = ''
41 | for (var i = 0, l = args.length; i < l; i++) {
42 | var current = args[i]
43 | var next = args[i + 1] || ''
44 | var nextMatches = true
45 | var prevMatches = true
46 | if (current === next) {
47 | continue
48 | }
49 | for (var j = 0, cl = current.length; j < cl; j++) {
50 | var curChar = current.charAt(j)
51 | nextMatches = nextMatches && curChar === next.charAt(j)
52 | prevMatches = prevMatches && curChar === prev.charAt(j)
53 | if (!nextMatches && !prevMatches) {
54 | j++
55 | break
56 | }
57 | }
58 | prev = current
59 | if (j === cl) {
60 | abbrevs[current] = current
61 | continue
62 | }
63 | for (var a = current.slice(0, j); j <= cl; j++) {
64 | abbrevs[a] = current
65 | a += current.charAt(j)
66 | }
67 | }
68 | return abbrevs
69 | }
70 |
71 | function lexSort (a, b) {
72 | return a === b ? 0 : a > b ? 1 : -1
73 | }
74 |
--------------------------------------------------------------------------------
/test/fixtures/abbrev/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "abbrev",
3 | "version": "1.1.1",
4 | "description": "Like ruby's abbrev module, but in js",
5 | "author": "Isaac Z. Schlueter ",
6 | "main": "abbrev.js",
7 | "scripts": {
8 | "test": "tap test.js --100",
9 | "preversion": "npm test",
10 | "postversion": "npm publish",
11 | "postpublish": "git push origin --all; git push origin --tags"
12 | },
13 | "repository": "http://github.com/isaacs/abbrev-js",
14 | "license": "ISC",
15 | "devDependencies": {
16 | "tap": "^10.1"
17 | },
18 | "files": [
19 | "abbrev.js"
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/test/fixtures/bin-good.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zkat/pacote-old/ebf5db458a0e00c84f160cd546f04e46fae13c77/test/fixtures/bin-good.tgz
--------------------------------------------------------------------------------
/test/fixtures/bin-good/package.json:
--------------------------------------------------------------------------------
1 | {"name":"bin-object","version":"1.2.3","bin":{"bin-object":"script.js"}}
2 |
--------------------------------------------------------------------------------
/test/fixtures/bin-good/script.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const fs = require('fs')
3 | const assert = require('assert')
4 | assert.equal(fs.statSync(__filename).mode & 0o111, 0o111)
5 | console.log('ok')
6 |
--------------------------------------------------------------------------------
/test/fixtures/bin-missing.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zkat/pacote-old/ebf5db458a0e00c84f160cd546f04e46fae13c77/test/fixtures/bin-missing.tgz
--------------------------------------------------------------------------------
/test/fixtures/bin-missing/package.json:
--------------------------------------------------------------------------------
1 | {"name":"bin-string","version":"1.2.3","bin":"script.js"}
2 |
--------------------------------------------------------------------------------
/test/fixtures/bin-object.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zkat/pacote-old/ebf5db458a0e00c84f160cd546f04e46fae13c77/test/fixtures/bin-object.tgz
--------------------------------------------------------------------------------
/test/fixtures/bin-object/package.json:
--------------------------------------------------------------------------------
1 | {"name":"bin-object","version":"1.2.3","bin":{"bin-object":"script.js"}}
2 |
--------------------------------------------------------------------------------
/test/fixtures/bin-object/script.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const fs = require('fs')
3 | const assert = require('assert')
4 | assert.equal(fs.statSync(__filename).mode & 0o111, 0o111)
5 | console.log('ok')
6 |
--------------------------------------------------------------------------------
/test/fixtures/bin-string.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zkat/pacote-old/ebf5db458a0e00c84f160cd546f04e46fae13c77/test/fixtures/bin-string.tgz
--------------------------------------------------------------------------------
/test/fixtures/bin-string/package.json:
--------------------------------------------------------------------------------
1 | {"name":"bin-string","version":"1.2.3","bin":"script.js"}
2 |
--------------------------------------------------------------------------------
/test/fixtures/bin-string/script.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const fs = require('fs')
3 | const assert = require('assert')
4 | assert.equal(fs.statSync(__filename).mode & 0o111, 0o111)
5 | console.log('ok')
6 |
--------------------------------------------------------------------------------
/test/fixtures/npm-mock.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const { argv, env } = process
3 |
4 | const pnp = env._PACOTE_NO_PREPARE_ || ''
5 | const pfg = env._PACOTE_FROM_GIT_
6 | const pacotePath = env._PACOTE_TEST_PATH_
7 | const pacoteOpts = env._PACOTE_TEST_OPTS_
8 |
9 | const data = {
10 | argv,
11 | noPrepare: pnp ? pnp.split('\\n') : [],
12 | pfg,
13 | cwd: process.cwd(),
14 | }
15 |
16 | if (data.noPrepare.length > 5) {
17 | throw new Error('infinite regress detected!')
18 | }
19 |
20 | // just an incredibly rudimentary package manager
21 | const pkg = require(process.cwd() + '/package.json')
22 | const pacote = require(pacotePath)
23 | for (const [name, spec] of Object.entries(pkg.dependencies)) {
24 | pacote.extract(spec, process.cwd() + '/' + name, {
25 | npmBin: __filename,
26 | ...JSON.parse(pacoteOpts),
27 | Arborist: require('@npmcli/arborist'),
28 | })
29 | }
30 |
31 | require('fs').writeFileSync('log', JSON.stringify(data, 0, 2))
32 |
--------------------------------------------------------------------------------
/test/fixtures/prepack-script/.gitignore:
--------------------------------------------------------------------------------
1 | index.js
2 |
--------------------------------------------------------------------------------
/test/fixtures/prepack-script/.npmignore:
--------------------------------------------------------------------------------
1 | !index.js
2 | !prepare.js
3 |
--------------------------------------------------------------------------------
/test/fixtures/prepack-script/node_modules/abbrev/LICENSE:
--------------------------------------------------------------------------------
1 | This software is dual-licensed under the ISC and MIT licenses.
2 | You may use this software under EITHER of the following licenses.
3 |
4 | ----------
5 |
6 | The ISC License
7 |
8 | Copyright (c) Isaac Z. Schlueter and Contributors
9 |
10 | Permission to use, copy, modify, and/or distribute this software for any
11 | purpose with or without fee is hereby granted, provided that the above
12 | copyright notice and this permission notice appear in all copies.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
20 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 |
22 | ----------
23 |
24 | Copyright Isaac Z. Schlueter and Contributors
25 | All rights reserved.
26 |
27 | Permission is hereby granted, free of charge, to any person
28 | obtaining a copy of this software and associated documentation
29 | files (the "Software"), to deal in the Software without
30 | restriction, including without limitation the rights to use,
31 | copy, modify, merge, publish, distribute, sublicense, and/or sell
32 | copies of the Software, and to permit persons to whom the
33 | Software is furnished to do so, subject to the following
34 | conditions:
35 |
36 | The above copyright notice and this permission notice shall be
37 | included in all copies or substantial portions of the Software.
38 |
39 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
40 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
41 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
42 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
43 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
44 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
45 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
46 | OTHER DEALINGS IN THE SOFTWARE.
47 |
--------------------------------------------------------------------------------
/test/fixtures/prepack-script/node_modules/abbrev/README.md:
--------------------------------------------------------------------------------
1 | # abbrev-js
2 |
3 | Just like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).
4 |
5 | Usage:
6 |
7 | var abbrev = require("abbrev");
8 | abbrev("foo", "fool", "folding", "flop");
9 |
10 | // returns:
11 | { fl: 'flop'
12 | , flo: 'flop'
13 | , flop: 'flop'
14 | , fol: 'folding'
15 | , fold: 'folding'
16 | , foldi: 'folding'
17 | , foldin: 'folding'
18 | , folding: 'folding'
19 | , foo: 'foo'
20 | , fool: 'fool'
21 | }
22 |
23 | This is handy for command-line scripts, or other cases where you want to be able to accept shorthands.
24 |
--------------------------------------------------------------------------------
/test/fixtures/prepack-script/node_modules/abbrev/abbrev.js:
--------------------------------------------------------------------------------
1 | module.exports = exports = abbrev.abbrev = abbrev
2 |
3 | abbrev.monkeyPatch = monkeyPatch
4 |
5 | function monkeyPatch () {
6 | Object.defineProperty(Array.prototype, 'abbrev', {
7 | value: function () { return abbrev(this) },
8 | enumerable: false, configurable: true, writable: true
9 | })
10 |
11 | Object.defineProperty(Object.prototype, 'abbrev', {
12 | value: function () { return abbrev(Object.keys(this)) },
13 | enumerable: false, configurable: true, writable: true
14 | })
15 | }
16 |
17 | function abbrev (list) {
18 | if (arguments.length !== 1 || !Array.isArray(list)) {
19 | list = Array.prototype.slice.call(arguments, 0)
20 | }
21 | for (var i = 0, l = list.length, args = [] ; i < l ; i ++) {
22 | args[i] = typeof list[i] === "string" ? list[i] : String(list[i])
23 | }
24 |
25 | // sort them lexicographically, so that they're next to their nearest kin
26 | args = args.sort(lexSort)
27 |
28 | // walk through each, seeing how much it has in common with the next and previous
29 | var abbrevs = {}
30 | , prev = ""
31 | for (var i = 0, l = args.length ; i < l ; i ++) {
32 | var current = args[i]
33 | , next = args[i + 1] || ""
34 | , nextMatches = true
35 | , prevMatches = true
36 | if (current === next) continue
37 | for (var j = 0, cl = current.length ; j < cl ; j ++) {
38 | var curChar = current.charAt(j)
39 | nextMatches = nextMatches && curChar === next.charAt(j)
40 | prevMatches = prevMatches && curChar === prev.charAt(j)
41 | if (!nextMatches && !prevMatches) {
42 | j ++
43 | break
44 | }
45 | }
46 | prev = current
47 | if (j === cl) {
48 | abbrevs[current] = current
49 | continue
50 | }
51 | for (var a = current.substr(0, j) ; j <= cl ; j ++) {
52 | abbrevs[a] = current
53 | a += current.charAt(j)
54 | }
55 | }
56 | return abbrevs
57 | }
58 |
59 | function lexSort (a, b) {
60 | return a === b ? 0 : a > b ? 1 : -1
61 | }
62 |
--------------------------------------------------------------------------------
/test/fixtures/prepack-script/node_modules/abbrev/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "abbrev",
3 | "version": "1.1.1",
4 | "description": "Like ruby's abbrev module, but in js",
5 | "author": "Isaac Z. Schlueter ",
6 | "main": "abbrev.js",
7 | "scripts": {
8 | "test": "tap test.js --100",
9 | "preversion": "npm test",
10 | "postversion": "npm publish",
11 | "postpublish": "git push origin --all; git push origin --tags"
12 | },
13 | "repository": "http://github.com/isaacs/abbrev-js",
14 | "license": "ISC",
15 | "devDependencies": {
16 | "tap": "^10.1"
17 | },
18 | "files": [
19 | "abbrev.js"
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/test/fixtures/prepack-script/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "git-prepack-script",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "abbrev": {
8 | "version": "1.1.1",
9 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
10 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
11 | "dev": true
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/fixtures/prepack-script/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "git-prepack-script",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "prepack": "node prepack.js"
7 | },
8 | "license": "ISC",
9 | "devDependencies": {
10 | "abbrev": "^1.1.1"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/fixtures/prepack-script/prepack.js:
--------------------------------------------------------------------------------
1 | require('./node_modules/abbrev')
2 | const fs = require('fs')
3 | const { join } = require('path')
4 | fs.writeFileSync(join(__dirname, 'index.js'), `
5 | // abbrev should not be here in production!
6 | console.log('TAP version 13')
7 | console.log('1..1')
8 | try {
9 | require('./node_modules/abbrev')
10 | console.log('not ok 1 - dev dep present')
11 | process.exit(1)
12 | } catch (er) {
13 | console.log('ok 1 - no dev dep')
14 | }
15 | `)
16 |
--------------------------------------------------------------------------------
/test/fixtures/prepare-requires-gitignore-1.2.3.tgz:
--------------------------------------------------------------------------------
1 | prepare-requires-gitignore/ 000755 000765 000024 00000000000 14001650265 016743 5 ustar 00isaacs staff 000000 000000 prepare-requires-gitignore/index.js 000644 000765 000024 00000000034 14000374432 020403 0 ustar 00isaacs staff 000000 000000 console.log('this is fine')
2 | prepare-requires-gitignore/.gitignore 000644 000765 000024 00000000035 14000374512 020726 0 ustar 00isaacs staff 000000 000000 # just a file you can ignore
3 | prepare-requires-gitignore/package.json 000644 000765 000024 00000000267 14001647705 021243 0 ustar 00isaacs staff 000000 000000 {
4 | "name": "prepare-requires-gitignore",
5 | "version": "1.2.3",
6 | "files": [
7 | "index.js",
8 | "prepare_ran_successfully"
9 | ],
10 | "scripts": {
11 | "prepare": "node prepare.js"
12 | }
13 | }
14 | prepare-requires-gitignore/prepare.js 000644 000765 000024 00000000262 14001650265 020737 0 ustar 00isaacs staff 000000 000000 const { statSync, writeFileSync } = require('fs')
15 | statSync(`${__dirname}/.gitignore`)
16 | writeFileSync(`${__dirname}/prepare_ran_successfully`, 'hello')
17 | console.log('this is fine')
18 |
--------------------------------------------------------------------------------
/test/fixtures/prepare-requires-gitignore/.gitignore:
--------------------------------------------------------------------------------
1 | # just a file you can ignore
2 |
--------------------------------------------------------------------------------
/test/fixtures/prepare-requires-gitignore/index.js:
--------------------------------------------------------------------------------
1 | console.log('this is fine')
2 |
--------------------------------------------------------------------------------
/test/fixtures/prepare-requires-gitignore/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "prepare-requires-gitignore",
3 | "version": "1.2.3",
4 | "files": [
5 | "index.js",
6 | "prepare_ran_successfully"
7 | ],
8 | "scripts": {
9 | "prepare": "node prepare.js"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/fixtures/prepare-requires-gitignore/prepare.js:
--------------------------------------------------------------------------------
1 | const { statSync, writeFileSync } = require('fs')
2 | statSync(`${__dirname}/.gitignore`)
3 | writeFileSync(`${__dirname}/prepare_ran_successfully`, 'hello')
4 | console.log('this is fine')
5 |
--------------------------------------------------------------------------------
/test/fixtures/prepare-script/.gitignore:
--------------------------------------------------------------------------------
1 | index.js
2 |
--------------------------------------------------------------------------------
/test/fixtures/prepare-script/.npmignore:
--------------------------------------------------------------------------------
1 | !index.js
2 | !prepare.js
3 |
--------------------------------------------------------------------------------
/test/fixtures/prepare-script/node_modules/abbrev/LICENSE:
--------------------------------------------------------------------------------
1 | This software is dual-licensed under the ISC and MIT licenses.
2 | You may use this software under EITHER of the following licenses.
3 |
4 | ----------
5 |
6 | The ISC License
7 |
8 | Copyright (c) Isaac Z. Schlueter and Contributors
9 |
10 | Permission to use, copy, modify, and/or distribute this software for any
11 | purpose with or without fee is hereby granted, provided that the above
12 | copyright notice and this permission notice appear in all copies.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
20 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 |
22 | ----------
23 |
24 | Copyright Isaac Z. Schlueter and Contributors
25 | All rights reserved.
26 |
27 | Permission is hereby granted, free of charge, to any person
28 | obtaining a copy of this software and associated documentation
29 | files (the "Software"), to deal in the Software without
30 | restriction, including without limitation the rights to use,
31 | copy, modify, merge, publish, distribute, sublicense, and/or sell
32 | copies of the Software, and to permit persons to whom the
33 | Software is furnished to do so, subject to the following
34 | conditions:
35 |
36 | The above copyright notice and this permission notice shall be
37 | included in all copies or substantial portions of the Software.
38 |
39 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
40 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
41 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
42 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
43 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
44 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
45 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
46 | OTHER DEALINGS IN THE SOFTWARE.
47 |
--------------------------------------------------------------------------------
/test/fixtures/prepare-script/node_modules/abbrev/README.md:
--------------------------------------------------------------------------------
1 | # abbrev-js
2 |
3 | Just like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).
4 |
5 | Usage:
6 |
7 | var abbrev = require("abbrev");
8 | abbrev("foo", "fool", "folding", "flop");
9 |
10 | // returns:
11 | { fl: 'flop'
12 | , flo: 'flop'
13 | , flop: 'flop'
14 | , fol: 'folding'
15 | , fold: 'folding'
16 | , foldi: 'folding'
17 | , foldin: 'folding'
18 | , folding: 'folding'
19 | , foo: 'foo'
20 | , fool: 'fool'
21 | }
22 |
23 | This is handy for command-line scripts, or other cases where you want to be able to accept shorthands.
24 |
--------------------------------------------------------------------------------
/test/fixtures/prepare-script/node_modules/abbrev/abbrev.js:
--------------------------------------------------------------------------------
1 | module.exports = exports = abbrev.abbrev = abbrev
2 |
3 | abbrev.monkeyPatch = monkeyPatch
4 |
5 | function monkeyPatch () {
6 | Object.defineProperty(Array.prototype, 'abbrev', {
7 | value: function () { return abbrev(this) },
8 | enumerable: false, configurable: true, writable: true
9 | })
10 |
11 | Object.defineProperty(Object.prototype, 'abbrev', {
12 | value: function () { return abbrev(Object.keys(this)) },
13 | enumerable: false, configurable: true, writable: true
14 | })
15 | }
16 |
17 | function abbrev (list) {
18 | if (arguments.length !== 1 || !Array.isArray(list)) {
19 | list = Array.prototype.slice.call(arguments, 0)
20 | }
21 | for (var i = 0, l = list.length, args = [] ; i < l ; i ++) {
22 | args[i] = typeof list[i] === "string" ? list[i] : String(list[i])
23 | }
24 |
25 | // sort them lexicographically, so that they're next to their nearest kin
26 | args = args.sort(lexSort)
27 |
28 | // walk through each, seeing how much it has in common with the next and previous
29 | var abbrevs = {}
30 | , prev = ""
31 | for (var i = 0, l = args.length ; i < l ; i ++) {
32 | var current = args[i]
33 | , next = args[i + 1] || ""
34 | , nextMatches = true
35 | , prevMatches = true
36 | if (current === next) continue
37 | for (var j = 0, cl = current.length ; j < cl ; j ++) {
38 | var curChar = current.charAt(j)
39 | nextMatches = nextMatches && curChar === next.charAt(j)
40 | prevMatches = prevMatches && curChar === prev.charAt(j)
41 | if (!nextMatches && !prevMatches) {
42 | j ++
43 | break
44 | }
45 | }
46 | prev = current
47 | if (j === cl) {
48 | abbrevs[current] = current
49 | continue
50 | }
51 | for (var a = current.substr(0, j) ; j <= cl ; j ++) {
52 | abbrevs[a] = current
53 | a += current.charAt(j)
54 | }
55 | }
56 | return abbrevs
57 | }
58 |
59 | function lexSort (a, b) {
60 | return a === b ? 0 : a > b ? 1 : -1
61 | }
62 |
--------------------------------------------------------------------------------
/test/fixtures/prepare-script/node_modules/abbrev/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "abbrev",
3 | "version": "1.1.1",
4 | "description": "Like ruby's abbrev module, but in js",
5 | "author": "Isaac Z. Schlueter ",
6 | "main": "abbrev.js",
7 | "scripts": {
8 | "test": "tap test.js --100",
9 | "preversion": "npm test",
10 | "postversion": "npm publish",
11 | "postpublish": "git push origin --all; git push origin --tags"
12 | },
13 | "repository": "http://github.com/isaacs/abbrev-js",
14 | "license": "ISC",
15 | "devDependencies": {
16 | "tap": "^10.1"
17 | },
18 | "files": [
19 | "abbrev.js"
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/test/fixtures/prepare-script/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "git-prepare-script",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "abbrev": {
8 | "version": "1.1.1",
9 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
10 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
11 | "dev": true
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/fixtures/prepare-script/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "git-prepare-script",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "prepare": "node prepare.js"
7 | },
8 | "license": "ISC",
9 | "devDependencies": {
10 | "abbrev": "^1.1.1"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/fixtures/prepare-script/prepare.js:
--------------------------------------------------------------------------------
1 | require('./node_modules/abbrev')
2 | const fs = require('fs')
3 | const { join } = require('path')
4 | fs.writeFileSync(join(__dirname, 'index.js'), `
5 | // abbrev should not be here in production!
6 | console.log('TAP version 13')
7 | console.log('1..1')
8 | try {
9 | require('./node_modules/abbrev')
10 | console.log('not ok 1 - dev dep present')
11 | process.exit(1)
12 | } catch (er) {
13 | console.log('ok 1 - no dev dep')
14 | }
15 | `)
16 |
--------------------------------------------------------------------------------
/test/fixtures/sigstore/invalid-attestations.json:
--------------------------------------------------------------------------------
1 | {
2 | "attestations": [
3 | {
4 | "predicateType": "https://slsa.dev/provenance/v0.2",
5 | "bundle": {
6 | "mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1",
7 | "verificationMaterial": {
8 | "x509CertificateChain": {
9 | "certificates": [
10 | {
11 | "rawBytes": "MIIDnDCCAyKgAwIBAgIUEg2LbBC+v12QtPBt2jawiYrF33UwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjMwMTExMTczMTUyWhcNMjMwMTExMTc0MTUyWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEscmo8xVdr+olWHVVpTlLdKdTwTDvNpINwLXi6W2OlPwTkMbJj0zCpO99heNH4ZxF1+NmO6NyjcbynKjf/GPUV6OCAkEwggI9MA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUdsZZ492PIgVwGjT/q8AwgHhDkj4wHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wZAYDVR0RAQH/BFowWIZWaHR0cHM6Ly9naXRodWIuY29tL3NpZ3N0b3JlL3NpZ3N0b3JlLWpzLy5naXRodWIvd29ya2Zsb3dzL3B1Ymxpc2gueW1sQHJlZnMvdGFncy92MC40LjAwOQYKKwYBBAGDvzABAQQraHR0cHM6Ly90b2tlbi5hY3Rpb25zLmdpdGh1YnVzZXJjb250ZW50LmNvbTAVBgorBgEEAYO/MAECBAdyZWxlYXNlMDYGCisGAQQBg78wAQMEKDhhMmVlMmZkMjBkZGE1OGZmYTRhOGQ4MDhhNjVjYjFlMDQ3MTFjMDMwFQYKKwYBBAGDvzABBAQHcHVibGlzaDAiBgorBgEEAYO/MAEFBBRzaWdzdG9yZS9zaWdzdG9yZS1qczAeBgorBgEEAYO/MAEGBBByZWZzL3RhZ3MvdjAuNC4wMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGFoeNlfwAABAMARzBFAiBqYOxNKEMS4gXVBqU3Mr/w+yYXYtZDYa6daYOZJZB++wIhANat2b2mVTeHERPyhATU/Z8HOfC6iqY/IwiXnwWKsp9xMAoGCCqGSM49BAMDA2gAMGUCMQD5OzgtStQId/HNXGwVM1Ydjux8x2d4cr7tzWreGSbMUJhRuVlJliOdJKsu8ufHQfYCMC8M76uThWeCI2A5GndGj0TTaI1Cq92T8oXm5iHHFPxmvZtjXtnwCuGzLAKHILlmlg=="
12 | },
13 | {
14 | "rawBytes": "MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow="
15 | },
16 | {
17 | "rawBytes": "MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ"
18 | }
19 | ]
20 | },
21 | "tlogEntries": [
22 | {
23 | "logIndex": "10960845",
24 | "logId": {
25 | "keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
26 | },
27 | "kindVersion": {
28 | "kind": "intoto",
29 | "version": "0.0.2"
30 | },
31 | "integratedTime": "1673458312",
32 | "inclusionPromise": {
33 | "signedEntryTimestamp": "MEYCIQDzgIQqH7VfIGmZ3wQ7WQ5wnGnhZrv6/3Q90rOK2vsWrgIhAJUvX2WQ/BDp4oti3LEdFzG8KpJIU7sMfSRehK8BRQ+r"
34 | },
35 | "inclusionProof": null,
36 | "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJ1UkVORFFYbExaMEYzU1VKQlowbFZSV2N5VEdKQ1F5dDJNVEpSZEZCQ2RESnFZWGRwV1hKR016TlZkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BOZDAxVVJYaE5WR042VFZSVmVWZG9ZMDVOYWsxM1RWUkZlRTFVWXpCTlZGVjVWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWelkyMXZPSGhXWkhJcmIyeFhTRlpXY0ZSc1RHUkxaRlIzVkVSMlRuQkpUbmRNV0drS05sY3lUMnhRZDFSclRXSkthakI2UTNCUE9UbG9aVTVJTkZwNFJqRXJUbTFQTms1NWFtTmllVzVMYW1ZdlIxQlZWalpQUTBGclJYZG5aMGs1VFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZWa2MxcGFDalE1TWxCSloxWjNSMnBVTDNFNFFYZG5TR2hFYTJvMGQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQxcEJXVVJXVWpCU1FWRklMMEpHYjNkWFNWcFhZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRETk9jRm96VGpCaU0wcHNURE5PY0FwYU0wNHdZak5LYkV4WGNIcE1lVFZ1WVZoU2IyUlhTWFprTWpsNVlUSmFjMkl6WkhwTU0wSXhXVzE0Y0dNeVozVmxWekZ6VVVoS2JGcHVUWFprUjBadUNtTjVPVEpOUXpRd1RHcEJkMDlSV1V0TGQxbENRa0ZIUkhaNlFVSkJVVkZ5WVVoU01HTklUVFpNZVRrd1lqSjBiR0pwTldoWk0xSndZakkxZWt4dFpIQUtaRWRvTVZsdVZucGFXRXBxWWpJMU1GcFhOVEJNYlU1MllsUkJWa0puYjNKQ1owVkZRVmxQTDAxQlJVTkNRV1I1V2xkNGJGbFlUbXhOUkZsSFEybHpSd3BCVVZGQ1p6YzRkMEZSVFVWTFJHaG9UVzFXYkUxdFdtdE5ha0pyV2tkRk1VOUhXbTFaVkZKb1QwZFJORTFFYUdoT2FsWnFXV3BHYkUxRVVUTk5WRVpxQ2sxRVRYZEdVVmxMUzNkWlFrSkJSMFIyZWtGQ1FrRlJTR05JVm1saVIyeDZZVVJCYVVKbmIzSkNaMFZGUVZsUEwwMUJSVVpDUWxKNllWZGtlbVJIT1hrS1dsTTVlbUZYWkhwa1J6bDVXbE14Y1dONlFXVkNaMjl5UW1kRlJVRlpUeTlOUVVWSFFrSkNlVnBYV25wTU0xSm9Xak5OZG1ScVFYVk9RelIzVFVsSFN3cENaMjl5UW1kRlJVRmtXalZCWjFGRFFraDNSV1ZuUWpSQlNGbEJNMVF3ZDJGellraEZWRXBxUjFJMFkyMVhZek5CY1VwTFdISnFaVkJMTXk5b05IQjVDbWRET0hBM2J6UkJRVUZIUm05bFRteG1kMEZCUWtGTlFWSjZRa1pCYVVKeFdVOTRUa3RGVFZNMFoxaFdRbkZWTTAxeUwzY3JlVmxZV1hSYVJGbGhObVFLWVZsUFdrcGFRaXNyZDBsb1FVNWhkREppTW0xV1ZHVklSVkpRZVdoQlZGVXZXamhJVDJaRE5tbHhXUzlKZDJsWWJuZFhTM053T1hoTlFXOUhRME54UndwVFRUUTVRa0ZOUkVFeVowRk5SMVZEVFZGRU5VOTZaM1JUZEZGSlpDOUlUbGhIZDFaTk1WbGthblY0T0hneVpEUmpjamQwZWxkeVpVZFRZazFWU21oU0NuVldiRXBzYVU5a1NrdHpkVGgxWmtoUlpsbERUVU00VFRjMmRWUm9WMlZEU1RKQk5VZHVaRWRxTUZSVVlVa3hRM0U1TWxRNGIxaHROV2xJU0VaUWVHMEtkbHAwYWxoMGJuZERkVWQ2VEVGTFNFbE1iRzFzWnowOUNpMHRMUzB0UlU1RUlFTkZVbFJKUmtsRFFWUkZMUzB0TFMwSyIsInNpZyI6IlRVVlJRMGxDYXpobFl6SXZSMjB5ZGxOSllWbHVWelZaZFdKc1RIaE1ZM1J4UmxkRWExVldRbWhSU0doWlltdFFRV2xDWWpGWE1Hd3ZVM2xvUkV3NGFGSnBZbUZrT1VNM1pqaHFkM2R3T1dkU1lVdDVZV2xZWkROQlNEaHZVVDA5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjI1NTdhZGNjYjFiZGYxNjA2NzExYjkwM2UxYmRiOGMwMmFhNjE2MzM4YzY0NjM2NTdiYmQwM2ViYjRmNzQyMTEifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI1NjM0MjMyZmU2MTg4NWM0OTAyNGJmMWExMGJmZDNmYjljYzZhNmFjM2U5OTE1OGYxMjgzYmM0Yzk3MzEzYTAzIn19fX0="
37 | }
38 | ],
39 | "timestampVerificationData": {
40 | "rfc3161Timestamps": []
41 | }
42 | },
43 | "dsseEnvelope": {
44 | "payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInN1YmplY3QiOlt7Im5hbWUiOiJwa2c6bnBtL3NpZ3N0b3JlQDAuNC4wIiwiZGlnZXN0Ijp7InNoYTUxMiI6IjI4MmMwYzVmYTkzNmQyNjQzMjE2NDM1ODFiNjVkM2RlNWMwYWY2ZWQ0ZmRmYWMxMmY1ODUxMTE1ZGYzOWNjMjVjZmFmMGFkMjJkOTA4NDg3YmZlZjMwMTE0ZDYxYzI1NzQ2MjA2ZDE4MzRiZTRmOGZkMTY1OTE3OGY3N2NjMDA0In19XSwicHJlZGljYXRlVHlwZSI6Imh0dHBzOi8vc2xzYS5kZXYvcHJvdmVuYW5jZS92MC4yIiwicHJlZGljYXRlIjp7ImJ1aWxkVHlwZSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9ucG0vY2xpL2doYUB2MCIsImJ1aWxkZXIiOnsiaWQiOiJodHRwczovL2dpdGh1Yi5jb20vbnBtL2NsaUA5LjIuMCJ9LCJpbnZvY2F0aW9uIjp7ImNvbmZpZ1NvdXJjZSI6eyJ1cmkiOiJnaXQraHR0cHM6Ly9naXRodWIuY29tL3NpZ3N0b3JlL3NpZ3N0b3JlLWpzQHJlZnMvdGFncy92MC40LjAiLCJkaWdlc3QiOnsic2hhMSI6IjhhMmVlMmZkMjBkZGE1OGZmYTRhOGQ4MDhhNjVjYjFlMDQ3MTFjMDMifSwiZW50cnlQb2ludCI6InNpZ3N0b3JlL3NpZ3N0b3JlLWpzLy5naXRodWIvd29ya2Zsb3dzL3B1Ymxpc2gueW1sQHJlZnMvdGFncy92MC40LjAifSwicGFyYW1ldGVycyI6e30sImVudmlyb25tZW50Ijp7IkdJVEhVQl9BQ1RPUl9JRCI6IjM5ODAyNyIsIkdJVEhVQl9FVkVOVF9OQU1FIjoicmVsZWFzZSIsIkdJVEhVQl9KT0IiOiJwdWJsaXNoIiwiR0lUSFVCX1JFRiI6InJlZnMvdGFncy92MC40LjAiLCJHSVRIVUJfUkVGX1RZUEUiOiJ0YWciLCJHSVRIVUJfUkVQT1NJVE9SWSI6InNpZ3N0b3JlL3NpZ3N0b3JlLWpzIiwiR0lUSFVCX1JFUE9TSVRPUllfSUQiOiI0OTU1NzQ1NTUiLCJHSVRIVUJfUkVQT1NJVE9SWV9PV05FUl9JRCI6IjcxMDk2MzUzIiwiR0lUSFVCX1JVTl9BVFRFTVBUIjoiMSIsIkdJVEhVQl9SVU5fSUQiOiIzODk1MTk3NzI1IiwiR0lUSFVCX1JVTl9OVU1CRVIiOiI3IiwiR0lUSFVCX1NIQSI6IjhhMmVlMmZkMjBkZGE1OGZmYTRhOGQ4MDhhNjVjYjFlMDQ3MTFjMDMiLCJHSVRIVUJfV09SS0ZMT1ciOiJwdWJsaXNoIiwiR0lUSFVCX1dPUktGTE9XX1JFRiI6InNpZ3N0b3JlL3NpZ3N0b3JlLWpzLy5naXRodWIvd29ya2Zsb3dzL3B1Ymxpc2gueW1sQHJlZnMvdGFncy92MC40LjAiLCJHSVRIVUJfV09SS0ZMT1dfU0hBIjoiOGEyZWUyZmQyMGRkYTU4ZmZhNGE4ZDgwOGE2NWNiMWUwNDcxMWMwMyIsIklNQUdFX09TIjoidWJ1bnR1MjIiLCJJTUFHRV9WRVJTSU9OIjoiMjAyMjEyMTIuMSIsIlJVTk5FUl9BUkNIIjoiWDY0IiwiUlVOTkVSX05BTUUiOiJIb3N0ZWQgQWdlbnQiLCJSVU5ORVJfT1MiOiJMaW51eCJ9fSwibWV0YWRhdGEiOnsiYnVpbGRJbnZvY2F0aW9uSWQiOiIzODk1MTk3NzI1LTEiLCJjb21wbGV0ZW5lc3MiOnsicGFyYW1ldGVycyI6ZmFsc2UsImVudmlyb25tZW50IjpmYWxzZSwibWF0ZXJpYWxzIjpmYWxzZX0sInJlcHJvZHVjaWJsZSI6ZmFsc2V9LCJtYXRlcmlhbHMiOlt7InVyaSI6ImdpdCtodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUvc2lnc3RvcmUtanMiLCJkaWdlc3QiOnsic2hhMSI6IjhhMmVlMmZkMjBkZGE1OGZmYTRhOGQ4MDhhNjVjYjFlMDQ3MTFjMDMifX1dfX0=",
45 | "payloadType": "application/vnd.in-toto+json",
46 | "signatures": [
47 | {
48 | "sig": "MEQCIBk8ec2/Gm2vSIaYnW5YublLxLctqFWDkUVBhQHhYbkPAiBb1W0l/SyhDL8hRibad9C7f8jwwp9gRaKyaiXd3AH8oQ==",
49 | "keyid": ""
50 | }
51 | ]
52 | }
53 | }
54 | },
55 | {
56 | "predicateType": "https://github.com/npm/attestation/tree/main/specs/publish/v0.1",
57 | "bundle": {
58 | "mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1",
59 | "verificationMaterial": {
60 | "publicKey": {
61 | "hint": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"
62 | },
63 | "tlogEntries": [
64 | {
65 | "logIndex": "10960848",
66 | "logId": {
67 | "keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
68 | },
69 | "kindVersion": {
70 | "kind": "intoto",
71 | "version": "0.0.2"
72 | },
73 | "integratedTime": "1673458314",
74 | "inclusionPromise": {
75 | "signedEntryTimestamp": "MEQCIEEIjIhzK2F4a9yt9peEarFYCBQETNkLAvHh4Q+suCbvAiAMOAoaKdW/+cU07wHSiG//gSJTeFDB30dl0dSx9dRG4g=="
76 | },
77 | "inclusionProof": null,
78 | "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiU0hBMjU2OmpsM2J3c3d1ODBQampva0NnaDBvMnc1YzJVNExoUUFFNTdnajljejFrekEiLCJwdWJsaWNLZXkiOiJMUzB0TFMxQ1JVZEpUaUJRVlVKTVNVTWdTMFZaTFMwdExTMEtUVVpyZDBWM1dVaExiMXBKZW1vd1EwRlJXVWxMYjFwSmVtb3dSRUZSWTBSUlowRkZNVTlzWWpONlRVRkdSbmhZUzBocFNXdFJUelZqU2pOWmFHdzFhVFpWVUhBclNXaDFkR1ZDU21KMVNHTkJOVlZ2WjB0dk1FVlhkR3hYZDFjMlMxTmhTMjlVVGtWWlREZEtiRU5SYVZadWEyaENhM1JWWjJjOVBRb3RMUzB0TFVWT1JDQlFWVUpNU1VNZ1MwVlpMUzB0TFMwPSIsInNpZyI6IlRVVlZRMGxSUXk4elpVdHVjRVpwY1dkMlZGbElORmxDUlhZMU5sQnlXa2NyV1ZGcE5VaGFXVlZMWVZCamFUVXlTRUZKWjFwMU16QkxjRk4zUWxWTGFWcENTemc0TjNOUlFVcEdRV1pyZUVKQmVXWklURUZNU2psR05sb3diREE5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjE0MzQ3ZjQxMjYwMTRiOTE3NDNkNjU5ZGNmY2ZkNmZiNjU4YTBmOWYzZDMxMGM1MDdmNWUzNWM3MGYwMGRjZGQifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI2NWE5MDU3MmQ3ZjUwODYyZDE4ZjdkYzljYjRlNTY2N2M4ZTMwYjZiN2VlZDk1MDVhYzMxZmE5NzIxOGMwYjA1In19fX0="
79 | }
80 | ],
81 | "timestampVerificationData": {
82 | "rfc3161Timestamps": []
83 | }
84 | },
85 | "dsseEnvelope": {
86 | "payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInN1YmplY3QiOlt7Im5hbWUiOiJwa2c6bnBtL3NpZ3N0b3JlQDAuNC4wIiwiZGlnZXN0Ijp7InNoYTUxMiI6IjI4MmMwYzVmYTkzNmQyNjQzMjE2NDM1ODFiNjVkM2RlNWMwYWY2ZWQ0ZmRmYWMxMmY1ODUxMTE1ZGYzOWNjMjVjZmFmMGFkMjJkOTA4NDg3YmZlZjMwMTE0ZDYxYzI1NzQ2MjA2ZDE4MzRiZTRmOGZkMTY1OTE3OGY3N2NjMDA0In19XSwicHJlZGljYXRlVHlwZSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9ucG0vYXR0ZXN0YXRpb24vdHJlZS9tYWluL3NwZWNzL3B1Ymxpc2gvdjAuMSIsInByZWRpY2F0ZSI6eyJuYW1lIjoic2lnc3RvcmUiLCJ2ZXJzaW9uIjoiMC40LjAiLCJyZWdpc3RyeSI6Imh0dHBzOi8vcmVnaXN0cnkubnBtanMub3JnIn19",
87 | "payloadType": "application/vnd.in-toto+json",
88 | "signatures": [
89 | {
90 | "sig": "invalid-signature",
91 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"
92 | }
93 | ]
94 | }
95 | }
96 | }
97 | ]
98 | }
99 |
--------------------------------------------------------------------------------
/test/fixtures/sigstore/malformed-subject-attestations.json:
--------------------------------------------------------------------------------
1 | {
2 | "attestations": [
3 | {
4 | "predicateType": "https://slsa.dev/provenance/v0.2",
5 | "bundle": {
6 | "mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1",
7 | "verificationMaterial": {
8 | "x509CertificateChain": {
9 | "certificates": [
10 | {
11 | "rawBytes": "MIIDnDCCAyKgAwIBAgIUEg2LbBC+v12QtPBt2jawiYrF33UwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjMwMTExMTczMTUyWhcNMjMwMTExMTc0MTUyWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEscmo8xVdr+olWHVVpTlLdKdTwTDvNpINwLXi6W2OlPwTkMbJj0zCpO99heNH4ZxF1+NmO6NyjcbynKjf/GPUV6OCAkEwggI9MA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUdsZZ492PIgVwGjT/q8AwgHhDkj4wHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wZAYDVR0RAQH/BFowWIZWaHR0cHM6Ly9naXRodWIuY29tL3NpZ3N0b3JlL3NpZ3N0b3JlLWpzLy5naXRodWIvd29ya2Zsb3dzL3B1Ymxpc2gueW1sQHJlZnMvdGFncy92MC40LjAwOQYKKwYBBAGDvzABAQQraHR0cHM6Ly90b2tlbi5hY3Rpb25zLmdpdGh1YnVzZXJjb250ZW50LmNvbTAVBgorBgEEAYO/MAECBAdyZWxlYXNlMDYGCisGAQQBg78wAQMEKDhhMmVlMmZkMjBkZGE1OGZmYTRhOGQ4MDhhNjVjYjFlMDQ3MTFjMDMwFQYKKwYBBAGDvzABBAQHcHVibGlzaDAiBgorBgEEAYO/MAEFBBRzaWdzdG9yZS9zaWdzdG9yZS1qczAeBgorBgEEAYO/MAEGBBByZWZzL3RhZ3MvdjAuNC4wMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGFoeNlfwAABAMARzBFAiBqYOxNKEMS4gXVBqU3Mr/w+yYXYtZDYa6daYOZJZB++wIhANat2b2mVTeHERPyhATU/Z8HOfC6iqY/IwiXnwWKsp9xMAoGCCqGSM49BAMDA2gAMGUCMQD5OzgtStQId/HNXGwVM1Ydjux8x2d4cr7tzWreGSbMUJhRuVlJliOdJKsu8ufHQfYCMC8M76uThWeCI2A5GndGj0TTaI1Cq92T8oXm5iHHFPxmvZtjXtnwCuGzLAKHILlmlg=="
12 | },
13 | {
14 | "rawBytes": "MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow="
15 | },
16 | {
17 | "rawBytes": "MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ"
18 | }
19 | ]
20 | },
21 | "tlogEntries": [
22 | {
23 | "logIndex": "10960845",
24 | "logId": {
25 | "keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
26 | },
27 | "kindVersion": {
28 | "kind": "intoto",
29 | "version": "0.0.2"
30 | },
31 | "integratedTime": "1673458312",
32 | "inclusionPromise": {
33 | "signedEntryTimestamp": "MEYCIQDzgIQqH7VfIGmZ3wQ7WQ5wnGnhZrv6/3Q90rOK2vsWrgIhAJUvX2WQ/BDp4oti3LEdFzG8KpJIU7sMfSRehK8BRQ+r"
34 | },
35 | "inclusionProof": null,
36 | "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJ1UkVORFFYbExaMEYzU1VKQlowbFZSV2N5VEdKQ1F5dDJNVEpSZEZCQ2RESnFZWGRwV1hKR016TlZkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BOZDAxVVJYaE5WR042VFZSVmVWZG9ZMDVOYWsxM1RWUkZlRTFVWXpCTlZGVjVWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWelkyMXZPSGhXWkhJcmIyeFhTRlpXY0ZSc1RHUkxaRlIzVkVSMlRuQkpUbmRNV0drS05sY3lUMnhRZDFSclRXSkthakI2UTNCUE9UbG9aVTVJTkZwNFJqRXJUbTFQTms1NWFtTmllVzVMYW1ZdlIxQlZWalpQUTBGclJYZG5aMGs1VFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZWa2MxcGFDalE1TWxCSloxWjNSMnBVTDNFNFFYZG5TR2hFYTJvMGQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQxcEJXVVJXVWpCU1FWRklMMEpHYjNkWFNWcFhZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRETk9jRm96VGpCaU0wcHNURE5PY0FwYU0wNHdZak5LYkV4WGNIcE1lVFZ1WVZoU2IyUlhTWFprTWpsNVlUSmFjMkl6WkhwTU0wSXhXVzE0Y0dNeVozVmxWekZ6VVVoS2JGcHVUWFprUjBadUNtTjVPVEpOUXpRd1RHcEJkMDlSV1V0TGQxbENRa0ZIUkhaNlFVSkJVVkZ5WVVoU01HTklUVFpNZVRrd1lqSjBiR0pwTldoWk0xSndZakkxZWt4dFpIQUtaRWRvTVZsdVZucGFXRXBxWWpJMU1GcFhOVEJNYlU1MllsUkJWa0puYjNKQ1owVkZRVmxQTDAxQlJVTkNRV1I1V2xkNGJGbFlUbXhOUkZsSFEybHpSd3BCVVZGQ1p6YzRkMEZSVFVWTFJHaG9UVzFXYkUxdFdtdE5ha0pyV2tkRk1VOUhXbTFaVkZKb1QwZFJORTFFYUdoT2FsWnFXV3BHYkUxRVVUTk5WRVpxQ2sxRVRYZEdVVmxMUzNkWlFrSkJSMFIyZWtGQ1FrRlJTR05JVm1saVIyeDZZVVJCYVVKbmIzSkNaMFZGUVZsUEwwMUJSVVpDUWxKNllWZGtlbVJIT1hrS1dsTTVlbUZYWkhwa1J6bDVXbE14Y1dONlFXVkNaMjl5UW1kRlJVRlpUeTlOUVVWSFFrSkNlVnBYV25wTU0xSm9Xak5OZG1ScVFYVk9RelIzVFVsSFN3cENaMjl5UW1kRlJVRmtXalZCWjFGRFFraDNSV1ZuUWpSQlNGbEJNMVF3ZDJGellraEZWRXBxUjFJMFkyMVhZek5CY1VwTFdISnFaVkJMTXk5b05IQjVDbWRET0hBM2J6UkJRVUZIUm05bFRteG1kMEZCUWtGTlFWSjZRa1pCYVVKeFdVOTRUa3RGVFZNMFoxaFdRbkZWTTAxeUwzY3JlVmxZV1hSYVJGbGhObVFLWVZsUFdrcGFRaXNyZDBsb1FVNWhkREppTW0xV1ZHVklSVkpRZVdoQlZGVXZXamhJVDJaRE5tbHhXUzlKZDJsWWJuZFhTM053T1hoTlFXOUhRME54UndwVFRUUTVRa0ZOUkVFeVowRk5SMVZEVFZGRU5VOTZaM1JUZEZGSlpDOUlUbGhIZDFaTk1WbGthblY0T0hneVpEUmpjamQwZWxkeVpVZFRZazFWU21oU0NuVldiRXBzYVU5a1NrdHpkVGgxWmtoUlpsbERUVU00VFRjMmRWUm9WMlZEU1RKQk5VZHVaRWRxTUZSVVlVa3hRM0U1TWxRNGIxaHROV2xJU0VaUWVHMEtkbHAwYWxoMGJuZERkVWQ2VEVGTFNFbE1iRzFzWnowOUNpMHRMUzB0UlU1RUlFTkZVbFJKUmtsRFFWUkZMUzB0TFMwSyIsInNpZyI6IlRVVlJRMGxDYXpobFl6SXZSMjB5ZGxOSllWbHVWelZaZFdKc1RIaE1ZM1J4UmxkRWExVldRbWhSU0doWlltdFFRV2xDWWpGWE1Hd3ZVM2xvUkV3NGFGSnBZbUZrT1VNM1pqaHFkM2R3T1dkU1lVdDVZV2xZWkROQlNEaHZVVDA5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjI1NTdhZGNjYjFiZGYxNjA2NzExYjkwM2UxYmRiOGMwMmFhNjE2MzM4YzY0NjM2NTdiYmQwM2ViYjRmNzQyMTEifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI1NjM0MjMyZmU2MTg4NWM0OTAyNGJmMWExMGJmZDNmYjljYzZhNmFjM2U5OTE1OGYxMjgzYmM0Yzk3MzEzYTAzIn19fX0="
37 | }
38 | ],
39 | "timestampVerificationData": {
40 | "rfc3161Timestamps": []
41 | }
42 | },
43 | "dsseEnvelope": {
44 | "payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInN1YmplY3QiOlt7Im5hbWUiOiJwa2c6bnBtL3NpZ3N0b3JlQDAuNC4wIiwiZGlnZXN0Ijp7InNoYTUxMiI6IjI4MmMwYzVmYTkzNmQyNjQzMjE2NDM1ODFiNjVkM2RlNWMwYWY2ZWQ0ZmRmYWMxMmY1ODUxMTE1ZGYzOWNjMjVjZmFmMGFkMjJkOTA4NDg3YmZlZjMwMTE0ZDYxYzI1NzQ2MjA2ZDE4MzRiZTRmOGZkMTY1OTE3OGY3N2NjMDA0In19XSwicHJlZGljYXRlVHlwZSI6Imh0dHBzOi8vc2xzYS5kZXYvcHJvdmVuYW5jZS92MC4yIiwicHJlZGljYXRlIjp7ImJ1aWxkVHlwZSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9ucG0vY2xpL2doYUB2MCIsImJ1aWxkZXIiOnsiaWQiOiJodHRwczovL2dpdGh1Yi5jb20vbnBtL2NsaUA5LjIuMCJ9LCJpbnZvY2F0aW9uIjp7ImNvbmZpZ1NvdXJjZSI6eyJ1cmkiOiJnaXQraHR0cHM6Ly9naXRodWIuY29tL3NpZ3N0b3JlL3NpZ3N0b3JlLWpzQHJlZnMvdGFncy92MC40LjAiLCJkaWdlc3QiOnsic2hhMSI6IjhhMmVlMmZkMjBkZGE1OGZmYTRhOGQ4MDhhNjVjYjFlMDQ3MTFjMDMifSwiZW50cnlQb2ludCI6InNpZ3N0b3JlL3NpZ3N0b3JlLWpzLy5naXRodWIvd29ya2Zsb3dzL3B1Ymxpc2gueW1sQHJlZnMvdGFncy92MC40LjAifSwicGFyYW1ldGVycyI6e30sImVudmlyb25tZW50Ijp7IkdJVEhVQl9BQ1RPUl9JRCI6IjM5ODAyNyIsIkdJVEhVQl9FVkVOVF9OQU1FIjoicmVsZWFzZSIsIkdJVEhVQl9KT0IiOiJwdWJsaXNoIiwiR0lUSFVCX1JFRiI6InJlZnMvdGFncy92MC40LjAiLCJHSVRIVUJfUkVGX1RZUEUiOiJ0YWciLCJHSVRIVUJfUkVQT1NJVE9SWSI6InNpZ3N0b3JlL3NpZ3N0b3JlLWpzIiwiR0lUSFVCX1JFUE9TSVRPUllfSUQiOiI0OTU1NzQ1NTUiLCJHSVRIVUJfUkVQT1NJVE9SWV9PV05FUl9JRCI6IjcxMDk2MzUzIiwiR0lUSFVCX1JVTl9BVFRFTVBUIjoiMSIsIkdJVEhVQl9SVU5fSUQiOiIzODk1MTk3NzI1IiwiR0lUSFVCX1JVTl9OVU1CRVIiOiI3IiwiR0lUSFVCX1NIQSI6IjhhMmVlMmZkMjBkZGE1OGZmYTRhOGQ4MDhhNjVjYjFlMDQ3MTFjMDMiLCJHSVRIVUJfV09SS0ZMT1ciOiJwdWJsaXNoIiwiR0lUSFVCX1dPUktGTE9XX1JFRiI6InNpZ3N0b3JlL3NpZ3N0b3JlLWpzLy5naXRodWIvd29ya2Zsb3dzL3B1Ymxpc2gueW1sQHJlZnMvdGFncy92MC40LjAiLCJHSVRIVUJfV09SS0ZMT1dfU0hBIjoiOGEyZWUyZmQyMGRkYTU4ZmZhNGE4ZDgwOGE2NWNiMWUwNDcxMWMwMyIsIklNQUdFX09TIjoidWJ1bnR1MjIiLCJJTUFHRV9WRVJTSU9OIjoiMjAyMjEyMTIuMSIsIlJVTk5FUl9BUkNIIjoiWDY0IiwiUlVOTkVSX05BTUUiOiJIb3N0ZWQgQWdlbnQiLCJSVU5ORVJfT1MiOiJMaW51eCJ9fSwibWV0YWRhdGEiOnsiYnVpbGRJbnZvY2F0aW9uSWQiOiIzODk1MTk3NzI1LTEiLCJjb21wbGV0ZW5lc3MiOnsicGFyYW1ldGVycyI6ZmFsc2UsImVudmlyb25tZW50IjpmYWxzZSwibWF0ZXJpYWxzIjpmYWxzZX0sInJlcHJvZHVjaWJsZSI6ZmFsc2V9LCJtYXRlcmlhbHMiOlt7InVyaSI6ImdpdCtodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUvc2lnc3RvcmUtanMiLCJkaWdlc3QiOnsic2hhMSI6IjhhMmVlMmZkMjBkZGE1OGZmYTRhOGQ4MDhhNjVjYjFlMDQ3MTFjMDMifX1dfX0=",
45 | "payloadType": "application/vnd.in-toto+json",
46 | "signatures": [
47 | {
48 | "sig": "MEQCIBk8ec2/Gm2vSIaYnW5YublLxLctqFWDkUVBhQHhYbkPAiBb1W0l/SyhDL8hRibad9C7f8jwwp9gRaKyaiXd3AH8oQ==",
49 | "keyid": ""
50 | }
51 | ]
52 | }
53 | }
54 | },
55 | {
56 | "predicateType": "https://github.com/npm/attestation/tree/main/specs/publish/v0.1",
57 | "bundle": {
58 | "mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1",
59 | "verificationMaterial": {
60 | "publicKey": {
61 | "hint": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"
62 | },
63 | "tlogEntries": [
64 | {
65 | "logIndex": "10960848",
66 | "logId": {
67 | "keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
68 | },
69 | "kindVersion": {
70 | "kind": "intoto",
71 | "version": "0.0.2"
72 | },
73 | "integratedTime": "1673458314",
74 | "inclusionPromise": {
75 | "signedEntryTimestamp": "MEQCIEEIjIhzK2F4a9yt9peEarFYCBQETNkLAvHh4Q+suCbvAiAMOAoaKdW/+cU07wHSiG//gSJTeFDB30dl0dSx9dRG4g=="
76 | },
77 | "inclusionProof": null,
78 | "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiU0hBMjU2OmpsM2J3c3d1ODBQampva0NnaDBvMnc1YzJVNExoUUFFNTdnajljejFrekEiLCJwdWJsaWNLZXkiOiJMUzB0TFMxQ1JVZEpUaUJRVlVKTVNVTWdTMFZaTFMwdExTMEtUVVpyZDBWM1dVaExiMXBKZW1vd1EwRlJXVWxMYjFwSmVtb3dSRUZSWTBSUlowRkZNVTlzWWpONlRVRkdSbmhZUzBocFNXdFJUelZqU2pOWmFHdzFhVFpWVUhBclNXaDFkR1ZDU21KMVNHTkJOVlZ2WjB0dk1FVlhkR3hYZDFjMlMxTmhTMjlVVGtWWlREZEtiRU5SYVZadWEyaENhM1JWWjJjOVBRb3RMUzB0TFVWT1JDQlFWVUpNU1VNZ1MwVlpMUzB0TFMwPSIsInNpZyI6IlRVVlZRMGxSUXk4elpVdHVjRVpwY1dkMlZGbElORmxDUlhZMU5sQnlXa2NyV1ZGcE5VaGFXVlZMWVZCamFUVXlTRUZKWjFwMU16QkxjRk4zUWxWTGFWcENTemc0TjNOUlFVcEdRV1pyZUVKQmVXWklURUZNU2psR05sb3diREE5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjE0MzQ3ZjQxMjYwMTRiOTE3NDNkNjU5ZGNmY2ZkNmZiNjU4YTBmOWYzZDMxMGM1MDdmNWUzNWM3MGYwMGRjZGQifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI2NWE5MDU3MmQ3ZjUwODYyZDE4ZjdkYzljYjRlNTY2N2M4ZTMwYjZiN2VlZDk1MDVhYzMxZmE5NzIxOGMwYjA1In19fX0="
79 | }
80 | ],
81 | "timestampVerificationData": {
82 | "rfc3161Timestamps": []
83 | }
84 | },
85 | "dsseEnvelope": {
86 | "payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInN1YmplY3QiOlt7Im5hbWUiOiJwa2c6bnBtL3NpZ3N0b3JlQDAuNC4wIn1dLCJwcmVkaWNhdGVUeXBlIjoiaHR0cHM6Ly9naXRodWIuY29tL25wbS9hdHRlc3RhdGlvbi90cmVlL21haW4vc3BlY3MvcHVibGlzaC92MC4xIiwicHJlZGljYXRlIjp7Im5hbWUiOiJzaWdzdG9yZSIsInZlcnNpb24iOiIwLjQuMCIsInJlZ2lzdHJ5IjoiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcifX0=",
87 | "payloadType": "application/vnd.in-toto+json",
88 | "signatures": [
89 | {
90 | "sig": "MEUCIQC/3eKnpFiqgvTYH4YBEv56PrZG+YQi5HZYUKaPci52HAIgZu30KpSwBUKiZBK887sQAJFAfkxBAyfHLALJ9F6Z0l0=",
91 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"
92 | }
93 | ]
94 | }
95 | }
96 | }
97 | ]
98 | }
99 |
--------------------------------------------------------------------------------
/test/fixtures/tnock.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const nock = require('nock')
4 |
5 | module.exports = tnock
6 | function tnock (t, host) {
7 | const server = nock(host)
8 | nock.disableNetConnect()
9 | t.teardown(function () {
10 | nock.enableNetConnect()
11 | server.done()
12 | })
13 | return server
14 | }
15 |
--------------------------------------------------------------------------------
/test/fixtures/weird-pkg.tgz:
--------------------------------------------------------------------------------
1 | weird-pkg/ 000755 000765 000024 00000000000 13534316721 013362 5 ustar 00isaacs staff 000000 000000 weird-pkg/.npmignore 000644 000765 000024 00000000000 13534316467 015356 0 ustar 00isaacs staff 000000 000000 weird-pkg/index-symlink.js 000755 000765 000024 00000000000 13534315626 020154 2index.js ustar 00isaacs staff 000000 000000 weird-pkg/no-gitignore-here/ 000755 000765 000024 00000000000 13534316730 016704 5 ustar 00isaacs staff 000000 000000 weird-pkg/index.js 000644 000765 000024 00000000000 13534315606 015016 0 ustar 00isaacs staff 000000 000000 weird-pkg/.gitignore 000644 000765 000024 00000000000 13534316465 015345 0 ustar 00isaacs staff 000000 000000 weird-pkg/package.json 000644 000765 000024 00000000337 13534316602 015651 0 ustar 00isaacs staff 000000 000000 {
2 | "name": "weird-pkg",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC"
12 | }
13 | weird-pkg/lib/ 000755 000765 000024 00000000000 13534316667 014141 5 ustar 00isaacs staff 000000 000000 weird-pkg/index-hardlink.js 000644 000765 000024 00000000000 13534315606 022145 1weird-pkg/index.js ustar 00isaacs staff 000000 000000 weird-pkg/lib/.gitignore 000644 000765 000024 00000000000 13534316455 016112 0 ustar 00isaacs staff 000000 000000 weird-pkg/no-gitignore-here/.gitignore 000644 000765 000024 00000000000 13534316730 020662 0 ustar 00isaacs staff 000000 000000
--------------------------------------------------------------------------------
/test/helpers/clean-snapshot.js:
--------------------------------------------------------------------------------
1 | // paths used in snapshot testing
2 | const cwd = process.cwd()
3 | const home = process.env.HOME
4 | const execPath = process.execPath
5 |
6 | const cleanSnapshot = (input) => {
7 | // On MacOS in GitHub Actions, NODE is a subdirectory of HOME so replace NODE first
8 | let output = input
9 | .split(cwd).join('{CWD}')
10 | .split(execPath).join('{NODE}')
11 | .split(home).join('{HOME}')
12 |
13 | // On Windows, also replace variations with escaped backslashes
14 | if (process.platform === 'win32') {
15 | output = output
16 | .split(cwd.replace(/\\/g, '\\\\')).join('{CWD}')
17 | .split(cwd.replace(/\\/g, '\\\\\\\\')).join('{CWD}')
18 | .split(execPath.replace(/\\/g, '\\\\')).join('{NODE}')
19 | .split(execPath.replace(/\\/g, '\\\\\\\\')).join('{NODE}')
20 | .split(home.replace(/\\/g, '\\\\')).join('{HOME}')
21 | .split(home.replace(/\\/g, '\\\\\\\\')).join('{HOME}')
22 | .replace(/\\\\/g, '/')
23 | .replace(/\\(?!")/g, '/')
24 | }
25 |
26 | return output
27 | }
28 |
29 | module.exports = cleanSnapshot
30 |
--------------------------------------------------------------------------------
/test/helpers/script-mode.js:
--------------------------------------------------------------------------------
1 | const scriptMode = () => {
2 | // On Windows, scripts are r/w but not executable
3 | if (process.platform === 'win32') {
4 | return 0o666
5 | } else {
6 | // On Unix, scripts are executable
7 | return 0o111
8 | }
9 | }
10 |
11 | module.exports = scriptMode
12 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | const t = require('tap')
2 | const fs = require('node:fs')
3 | const { resolve, relative } = require('node:path')
4 | const DirFetcher = require('../lib/dir.js')
5 | const FileFetcher = require('../lib/file.js')
6 | const GitFetcher = require('../lib/git.js')
7 | const RegistryFetcher = require('../lib/registry.js')
8 | const RemoteFetcher = require('../lib/remote.js')
9 | const pacote = require('../lib/index.js')
10 | const cleanSnapshot = require('./helpers/clean-snapshot.js')
11 |
12 | const abbrev = resolve(__dirname, 'fixtures/abbrev-1.1.1.tgz')
13 | const abbrevspec = `file:${relative(process.cwd(), abbrev)}`
14 |
15 | const me = t.testdir()
16 |
17 | t.cleanSnapshot = str => cleanSnapshot(str)
18 |
19 | // Putting all these tests inside a `t.test` suite broke the tests. They either
20 | // didn't run or failed w/ no message. Ignoring promise/catch-or-return for now.
21 | t.resolveMatchSnapshot(pacote.resolve(abbrevspec), 'resolve')
22 | t.resolveMatchSnapshot(pacote.extract(abbrevspec, me + '/extract'), 'extract')
23 | t.resolveMatchSnapshot(pacote.manifest(abbrevspec), 'manifest')
24 | t.resolveMatchSnapshot(pacote.packument(abbrevspec), 'packument')
25 | t.resolveMatch(pacote.tarball(abbrevspec), fs.readFileSync(abbrev), 'tarball')
26 | // eslint-disable-next-line promise/catch-or-return
27 | t.resolveMatchSnapshot(pacote.tarball.file(abbrevspec, me + '/tarball.tgz'),
28 | 'tarball to file').then(() =>
29 | t.match(fs.readFileSync(me + '/tarball.tgz'), fs.readFileSync(abbrev)))
30 | // eslint-disable-next-line promise/catch-or-return
31 | pacote.tarball.stream(abbrevspec, stream =>
32 | new Promise((res, rej) => {
33 | stream.on('end', res)
34 | stream.on('error', rej)
35 | stream.pipe(fs.createWriteStream(me + '/stream.tgz'))
36 | })).then(() =>
37 | t.match(fs.readFileSync(me + '/stream.tgz'), fs.readFileSync(abbrev)))
38 |
39 | t.resolveMatchSnapshot(pacote.manifest(abbrevspec), 'manifest')
40 |
41 | t.equal(pacote.GitFetcher, GitFetcher, 'should expose fetcher classes')
42 | t.equal(pacote.RegistryFetcher, RegistryFetcher, 'should expose fetcher classes')
43 | t.equal(pacote.FileFetcher, FileFetcher, 'should expose fetcher classes')
44 | t.equal(pacote.DirFetcher, DirFetcher, 'should expose fetcher classes')
45 | t.equal(pacote.RemoteFetcher, RemoteFetcher, 'should expose fetcher classes')
46 |
--------------------------------------------------------------------------------
/test/remote.js:
--------------------------------------------------------------------------------
1 | const t = require('tap')
2 | const fs = require('node:fs')
3 | const http = require('node:http')
4 | const { resolve } = require('node:path')
5 | const ssri = require('ssri')
6 | const RemoteFetcher = require('../lib/remote.js')
7 |
8 | const me = t.testdir()
9 | const cache = resolve(me, 'cache')
10 | const abbrev = resolve(__dirname, 'fixtures/abbrev-1.1.1.tgz')
11 | const port = 12345 + (+process.env.TAP_CHILD_ID || 0)
12 | const server = `http://localhost:${port}`
13 |
14 | t.cleanSnapshot = str => str.split('' + port).join('{PORT}')
15 |
16 | let abbrevIntegrity
17 | const requestLog = []
18 | t.test('start server', t => {
19 | const data = fs.readFileSync(abbrev)
20 | abbrevIntegrity = ssri.fromData(data)
21 | const httpServer = http.createServer((req, res) => {
22 | res.setHeader('cache-control', 'max-age=432000')
23 | res.setHeader('accept-ranges', 'bytes')
24 | res.setHeader('etag', '"a2177e7d2ad8d263e6c38e6fe8dd6f79"')
25 | res.setHeader('last-modified', 'Sat, 26 May 2018 16:03:07 GMT')
26 | res.setHeader('vary', 'Accept-Encoding')
27 | res.setHeader('connection', 'close')
28 | requestLog.push([req.url, req.headers])
29 | if (req.url === '/404') {
30 | res.statusCode = 404
31 | res.setHeader('content-type', 'application/json')
32 | res.end(JSON.stringify({ error: 'not found' }))
33 | } else if (req.url === '/not-tgz') {
34 | const nonTarData = Buffer.from('this is lovely data but not a tarball')
35 | res.setHeader('content-length', nonTarData.length + 2048)
36 | res.write(nonTarData)
37 | res.end(Buffer.alloc(2048))
38 | } else if (req.url === '/timeout') {
39 | res.statusCode = 200
40 | // your call is important to us
41 | } else {
42 | res.setHeader('content-type', 'application/octet-stream')
43 | res.setHeader('content-length', data.length)
44 | res.end(data)
45 | }
46 | })
47 | httpServer.listen(port, () => {
48 | t.parent.teardown(() => httpServer.close())
49 | t.end()
50 | })
51 | })
52 |
53 | t.test('packument', async t => {
54 | // const url = 'https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz'
55 | const url = `https://registry.npmjs.org/abbrev.tgz`
56 | const f = new RemoteFetcher(url, {
57 | registry: server,
58 | cache,
59 | preferOffline: true,
60 | headers: {
61 | 'not-referer': 'http://example.com',
62 | },
63 | scope: '@npmcli',
64 | npmSession: 'foobarbaz',
65 | })
66 | // run twice to pull from cache the second time
67 | await t.resolveMatchSnapshot(f.packument(), 'packument')
68 | const f2 = new RemoteFetcher(`abbrev@${url}`, {
69 | registry: server,
70 | pkgid: `remote:abbrev@${url}`,
71 | cache,
72 | })
73 | await t.resolveMatchSnapshot(f2.packument(), 'packument 2')
74 | const version = require('../package.json').version
75 | t.equal(requestLog.length, 1, 'only one request hit the server')
76 | t.match(requestLog, [
77 | [
78 | '/abbrev.tgz',
79 | {
80 | connection: 'keep-alive',
81 | 'user-agent': `pacote/${version} node/${process.version}`,
82 | 'pacote-version': version,
83 | 'pacote-req-type': 'tarball',
84 | 'pacote-pkg-id': `remote:${server}/abbrev.tgz`,
85 | accept: '*/*',
86 | 'accept-encoding': 'gzip,deflate',
87 | host: new URL(server).host,
88 | 'npm-session': 'foobarbaz',
89 | 'npm-scope': '@npmcli',
90 | 'not-referer': 'http://example.com',
91 | },
92 | ],
93 | ])
94 | requestLog.length = 0
95 | })
96 |
97 | t.test('bad integrity', t => {
98 | const url = `${server}/abbrev.tgz`
99 | // eslint-disable-next-line max-len
100 | const integrity = 'sha512-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='
101 | const f = new RemoteFetcher(url, { cache, integrity })
102 | return t.rejects(f.extract(me + '/bad-integrity'), {
103 | code: 'EINTEGRITY',
104 | sri: {
105 | sha512: [
106 | // create a buffer of nulls, the base64 is an endless scream
107 | // eslint-disable-next-line max-len
108 | { digest: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==' },
109 | ],
110 | },
111 | })
112 | })
113 |
114 | t.test('known integrity', async t => {
115 | const url = `${server}/abbrev.tgz`
116 | const f = new RemoteFetcher(url, { cache, integrity: abbrevIntegrity })
117 | await f.extract(me + '/good-integrity')
118 | t.same(f.integrity, abbrevIntegrity, 'got the right integrity back out')
119 | })
120 |
121 | t.test('an missing tarball', t => {
122 | const url = `${server}/404`
123 | const f = new RemoteFetcher(url, { cache })
124 | return t.rejects(f.extract(me + '/404'), {
125 | statusCode: 404,
126 | code: 'E404',
127 | body: { error: 'not found' },
128 | pkgid: `${server}/404`,
129 | })
130 | })
131 |
132 | t.test('not a tarball', t => {
133 | const url = `${server}/not-tgz`
134 | const f = new RemoteFetcher(url, { cache })
135 | return t.rejects(f.extract(me + '/not-tgz'), {
136 | code: 'TAR_BAD_ARCHIVE',
137 | message: 'Unrecognized archive format',
138 | })
139 | })
140 |
141 | t.test('get a timeout error from the http fetch', t => {
142 | const url = `${server}/timeout`
143 | const f = new RemoteFetcher(url, { cache: cache + '/fresh', timeout: 1 })
144 | return t.rejects(f.extract(me + '/timeout'), {
145 | name: 'FetchError',
146 | message: /timeout/,
147 | code: /FETCH_ERROR|ERR_SOCKET_TIMEOUT/,
148 | })
149 | })
150 |
151 | t.test('option replaceRegistryHost', rhTest => {
152 | const tnock = require('./fixtures/tnock')
153 | const { join } = require('path')
154 | const abbrevTGZ = fs.readFileSync(abbrev)
155 |
156 | rhTest.test('host should be replaced if set to always on npmjs registry', async ct => {
157 | const testdir = t.testdir()
158 | tnock(ct, 'https://registry.github.com')
159 | .get('/abbrev/-/abbrev-1.1.1.tgz')
160 | .reply(200, abbrevTGZ)
161 |
162 | const fetcher = new RemoteFetcher(
163 | 'https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz',
164 | {
165 | registry: 'https://registry.github.com',
166 | cache: join(testdir, 'cache'),
167 | fullReadJson: true,
168 | replaceRegistryHost: 'always',
169 | })
170 | ct.equal(fetcher.replaceRegistryHost, 'always')
171 | const tarball = await fetcher.tarball()
172 | ct.match(tarball, abbrevTGZ)
173 | })
174 |
175 | rhTest.test('host should be replaced if set to always on other registry', async ct => {
176 | const testdir = t.testdir()
177 | tnock(ct, 'https://registry.github.com')
178 | .get('/abbrev/-/abbrev-1.1.1.tgz')
179 | .reply(200, abbrevTGZ)
180 |
181 | const fetcher = new RemoteFetcher(
182 | 'https://registry.somethingelse.org/abbrev/-/abbrev-1.1.1.tgz',
183 | {
184 | registry: 'https://registry.github.com',
185 | cache: join(testdir, 'cache'),
186 | fullReadJson: true,
187 | replaceRegistryHost: 'always',
188 | })
189 | ct.equal(fetcher.replaceRegistryHost, 'always')
190 | const tarball = await fetcher.tarball()
191 | ct.match(tarball, abbrevTGZ)
192 | })
193 |
194 | rhTest.end()
195 | })
196 |
--------------------------------------------------------------------------------
/test/util/add-git-sha.js:
--------------------------------------------------------------------------------
1 | const t = require('tap')
2 | const npa = require('npm-package-arg')
3 | const addGitSha = require('../../lib/util/add-git-sha.js')
4 |
5 | const cases = [
6 | // unknown host
7 | ['git+ssh://git@some-host:user/repo', 'sha', 'git+ssh://git@some-host:user/repo#sha'],
8 | ['git+ssh://git@some-host:user/repo#othersha', 'sha', 'git+ssh://git@some-host:user/repo#sha'],
9 | [
10 | 'git+ssh://git@some-host:user/repo#othersha#otherothersha',
11 | 'sha',
12 | 'git+ssh://git@some-host:user/repo#sha'],
13 | ['git+ssh://git@some-host/user/repo', 'sha', 'git+ssh://git@some-host/user/repo#sha'],
14 | ['git+ssh://git@some-host/user/repo#othersha', 'sha', 'git+ssh://git@some-host/user/repo#sha'],
15 | ['git+ssh://git@some-host/user/repo#othersha#otherothersha',
16 | 'sha',
17 | 'git+ssh://git@some-host/user/repo#sha'],
18 | // github shorthand
19 | ['github:user/repo', 'sha', 'github:user/repo#sha'],
20 | ['github:user/repo#othersha', 'sha', 'github:user/repo#sha'],
21 | ['github:user/repo#othersha#otherothersha', 'sha', 'github:user/repo#sha'],
22 | // github https with auth
23 | ['git+https://git@github.com/user/repo', 'sha', 'https://git@github.com/user/repo.git#sha'],
24 | ['git+https://git@github.com/user/repo#othersha',
25 | 'sha',
26 | 'https://git@github.com/user/repo.git#sha'],
27 | ['git+https://git@github.com/user/repo#othersha#otherothersha',
28 | 'sha',
29 | 'https://git@github.com/user/repo.git#sha'],
30 | // github https no auth
31 | ['git+https://github.com/user/repo', 'sha', 'github:user/repo#sha'],
32 | ['git+https://github.com/user/repo#othersha', 'sha', 'github:user/repo#sha'],
33 | ['git+https://github.com/user/repo#othersha#otherothersha', 'sha', 'github:user/repo#sha'],
34 | // github ssh
35 | ['git+ssh://git@github.com/user/repo', 'sha', 'github:user/repo#sha'],
36 | ['git+ssh://git@github.com/user/repo#othersha', 'sha', 'github:user/repo#sha'],
37 | ['git+ssh://git@github.com/user/repo#othersha#otherothersha', 'sha', 'github:user/repo#sha'],
38 | ['git+ssh://git@github.com:user/repo', 'sha', 'github:user/repo#sha'],
39 | ['git+ssh://git@github.com:user/repo#othersha', 'sha', 'github:user/repo#sha'],
40 | ['git+ssh://git@github.com:user/repo#othersha#otherothersha', 'sha', 'github:user/repo#sha'],
41 | ]
42 |
43 | t.plan(cases.length)
44 | for (const [spec, sha, result] of cases) {
45 | t.equal(addGitSha(npa(spec), sha), result, `${spec} + ${sha} = ${result}`)
46 | }
47 |
--------------------------------------------------------------------------------
/test/util/cache-dir.js:
--------------------------------------------------------------------------------
1 | const t = require('tap')
2 | const path = require('node:path')
3 | process.getuid = () => 69420
4 | process.env.LOCALAPPDATA = ''
5 | const isWindows = process.platform === 'win32'
6 | const posix = isWindows ? 'posix' : null
7 | const windows = isWindows ? null : 'win32'
8 |
9 | let homedir = '/home/isaacs'
10 | const cacheDir = t.mock('../../lib/util/cache-dir.js', {
11 | 'node:path': {
12 | resolve: path.posix.resolve,
13 | },
14 | 'node:os': {
15 | tmpdir: () => '/tmp',
16 | homedir: () => homedir,
17 | },
18 | })
19 |
20 | // call it once just to cover the default arg setting
21 | // the tests all specify something, so they work predictably
22 | // on all platforms.
23 | t.ok(cacheDir(), 'a cache dir is ok')
24 |
25 | t.equal(cacheDir(posix).cacache, '/home/isaacs/.npm/_cacache')
26 | t.equal(cacheDir(windows).cacache, '/home/isaacs/npm-cache/_cacache')
27 | t.equal(cacheDir(posix).tufcache, '/home/isaacs/.npm/_tuf')
28 | t.equal(cacheDir(windows).tufcache, '/home/isaacs/npm-cache/_tuf')
29 |
30 | homedir = null
31 | t.equal(cacheDir(posix).cacache, '/tmp/npm-69420/.npm/_cacache')
32 | t.equal(cacheDir(windows).cacache, '/tmp/npm-69420/npm-cache/_cacache')
33 | t.equal(cacheDir(posix).tufcache, '/tmp/npm-69420/.npm/_tuf')
34 | t.equal(cacheDir(windows).tufcache, '/tmp/npm-69420/npm-cache/_tuf')
35 |
36 | process.env.LOCALAPPDATA = '/%LOCALAPPDATA%'
37 | t.equal(cacheDir(windows).cacache, '/%LOCALAPPDATA%/npm-cache/_cacache')
38 | t.equal(cacheDir(windows).tufcache, '/%LOCALAPPDATA%/npm-cache/_tuf')
39 |
40 | process.getuid = null
41 | t.equal(cacheDir(posix).cacache, `/tmp/npm-${process.pid}/.npm/_cacache`)
42 | t.equal(cacheDir(posix).tufcache, `/tmp/npm-${process.pid}/.npm/_tuf`)
43 |
--------------------------------------------------------------------------------
/test/util/is-package-bin.js:
--------------------------------------------------------------------------------
1 | const t = require('tap')
2 | const isPackageBin = require('../../lib/util/is-package-bin.js')
3 |
4 | t.ok(isPackageBin({ bin: 'foo' }, 'package/foo'), 'finds string')
5 | t.ok(isPackageBin({ bin: { bar: 'foo' } }, 'package/foo'), 'finds in obj')
6 | t.notOk(isPackageBin(null, 'anything'), 'return false if pkg is not')
7 | t.notOk(isPackageBin({ bin: 'foo' }, 'package/bar'), 'not the bin string')
8 | t.notOk(isPackageBin({ bin: { bar: 'foo' } }, 'package/bar'), 'not in obj')
9 |
--------------------------------------------------------------------------------
/test/util/npm.js:
--------------------------------------------------------------------------------
1 | const t = require('tap')
2 | const cp = require('node:child_process')
3 | const EventEmitter = require('node:events')
4 | const { Minipass } = require('minipass')
5 | const cleanSnapshot = require('../helpers/clean-snapshot.js')
6 |
7 | const { spawn } = cp
8 |
9 | cp.spawn = (...args) => {
10 | const proc = new EventEmitter()
11 | proc.stdout = new Minipass()
12 | proc.stdout.end(JSON.stringify(args))
13 | proc.stdout.on('end', () => setTimeout(() => proc.emit('close')))
14 | return proc
15 | }
16 | t.teardown = () => cp.spawn = spawn
17 |
18 | t.cleanSnapshot = str => cleanSnapshot(str)
19 |
20 | const npm = require('../../lib/util/npm.js')
21 | t.test('do the things', t => {
22 | const env = { environmental: 'variables' }
23 | t.resolveMatchSnapshot(
24 | npm('/path/to/npm/bin/npm-cli.js', 'flerb', '/cwd', env, { message: 'oopsie' }))
25 | t.resolveMatchSnapshot(npm('/path/to/npm', 'flerb', '/cwd', env, { message: 'oopsie' }))
26 | t.end()
27 | })
28 |
--------------------------------------------------------------------------------
/test/util/tar-create-options.js:
--------------------------------------------------------------------------------
1 | const t = require('tap')
2 | const tarCreateOptions = require('../../lib/util/tar-create-options.js')
3 |
4 | const simpleOpts = tarCreateOptions({ _resolved: '/home/foo' })
5 | t.match(
6 | simpleOpts,
7 | {
8 | cwd: '/home/foo',
9 | prefix: 'package/',
10 | portable: true,
11 | gzip: {
12 | level: 9,
13 | },
14 | mtime: new Date('1985-10-26T08:15:00.000Z'),
15 | },
16 | 'should return standard options'
17 | )
18 |
19 | t.ok(simpleOpts.filter('foo', {}), 'should not filter anything')
20 |
21 | const optsWithBins = tarCreateOptions({
22 | bin: { a: 'index.js' },
23 | _resolved: '/foo',
24 | })
25 |
26 | const stat = { mode: 0o644 }
27 | const filterRes = optsWithBins.filter('index.js', stat)
28 | t.equal(stat.mode, 0o755, 'should return an executable stat')
29 | t.equal(filterRes, true, 'should not filter out files')
30 |
--------------------------------------------------------------------------------