├── .commitlintrc.cjs
├── .eslintrc.cjs
├── .eslintrc.local.cjs
├── .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
├── package.json
├── release-please-config.json
├── tap-snapshots
└── test
│ └── fixtures.ts.test.cjs
├── test
└── fixtures.ts
├── tsconfig.json
└── types
└── index.d.ts
/.commitlintrc.cjs:
--------------------------------------------------------------------------------
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.cjs:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/.eslintrc.local.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parser: '@typescript-eslint/parser',
3 | settings: {
4 | 'import/resolver': {
5 | typescript: {},
6 | },
7 | },
8 | }
9 |
--------------------------------------------------------------------------------
/.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 | permissions:
12 | contents: read
13 |
14 | jobs:
15 | audit:
16 | name: Audit Dependencies
17 | if: github.repository_owner == 'npm'
18 | runs-on: ubuntu-latest
19 | defaults:
20 | run:
21 | shell: bash
22 | steps:
23 | - name: Checkout
24 | uses: actions/checkout@v4
25 | - name: Setup Git User
26 | run: |
27 | git config --global user.email "npm-cli+bot@github.com"
28 | git config --global user.name "npm CLI robot"
29 | - name: Setup Node
30 | uses: actions/setup-node@v4
31 | id: node
32 | with:
33 | node-version: 18.x
34 | check-latest: contains('18.x', '.x')
35 | - name: Install Latest npm
36 | uses: ./.github/actions/install-latest-npm
37 | with:
38 | node: ${{ steps.node.outputs.node-version }}
39 | - name: Install Dependencies
40 | run: npm i --ignore-scripts --no-audit --no-fund --package-lock
41 | - name: Run Production Audit
42 | run: npm audit --omit=dev
43 | - name: Run Full Audit
44 | run: npm audit --audit-level=none
45 |
--------------------------------------------------------------------------------
/.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 | permissions:
22 | contents: read
23 | checks: write
24 |
25 | jobs:
26 | lint-all:
27 | name: Lint All
28 | if: github.repository_owner == 'npm'
29 | runs-on: ubuntu-latest
30 | defaults:
31 | run:
32 | shell: bash
33 | steps:
34 | - name: Checkout
35 | uses: actions/checkout@v4
36 | with:
37 | ref: ${{ inputs.ref }}
38 | - name: Setup Git User
39 | run: |
40 | git config --global user.email "npm-cli+bot@github.com"
41 | git config --global user.name "npm CLI robot"
42 | - name: Create Check
43 | id: create-check
44 | if: ${{ inputs.check-sha }}
45 | uses: ./.github/actions/create-check
46 | with:
47 | name: "Lint All"
48 | token: ${{ secrets.GITHUB_TOKEN }}
49 | sha: ${{ inputs.check-sha }}
50 | - name: Setup Node
51 | uses: actions/setup-node@v4
52 | id: node
53 | with:
54 | node-version: 18.x
55 | check-latest: contains('18.x', '.x')
56 | - name: Install Latest npm
57 | uses: ./.github/actions/install-latest-npm
58 | with:
59 | node: ${{ steps.node.outputs.node-version }}
60 | - name: Install Dependencies
61 | run: npm i --ignore-scripts --no-audit --no-fund
62 | - name: Lint
63 | run: npm run lint --ignore-scripts
64 | - name: Post Lint
65 | run: npm run postlint --ignore-scripts
66 | - name: Conclude Check
67 | uses: LouisBrunner/checks-action@v1.6.0
68 | if: steps.create-check.outputs.check-id && always()
69 | with:
70 | token: ${{ secrets.GITHUB_TOKEN }}
71 | conclusion: ${{ job.status }}
72 | check_id: ${{ steps.create-check.outputs.check-id }}
73 |
74 | test-all:
75 | name: Test All - ${{ matrix.platform.name }} - ${{ matrix.node-version }}
76 | if: github.repository_owner == 'npm'
77 | strategy:
78 | fail-fast: false
79 | matrix:
80 | platform:
81 | - name: Linux
82 | os: ubuntu-latest
83 | shell: bash
84 | node-version:
85 | - 18.6.0
86 | - 18.x
87 | runs-on: ${{ matrix.platform.os }}
88 | defaults:
89 | run:
90 | shell: ${{ matrix.platform.shell }}
91 | steps:
92 | - name: Checkout
93 | uses: actions/checkout@v4
94 | with:
95 | ref: ${{ inputs.ref }}
96 | - name: Setup Git User
97 | run: |
98 | git config --global user.email "npm-cli+bot@github.com"
99 | git config --global user.name "npm CLI robot"
100 | - name: Create Check
101 | id: create-check
102 | if: ${{ inputs.check-sha }}
103 | uses: ./.github/actions/create-check
104 | with:
105 | name: "Test All - ${{ matrix.platform.name }} - ${{ matrix.node-version }}"
106 | token: ${{ secrets.GITHUB_TOKEN }}
107 | sha: ${{ inputs.check-sha }}
108 | - name: Setup Node
109 | uses: actions/setup-node@v4
110 | id: node
111 | with:
112 | node-version: ${{ matrix.node-version }}
113 | check-latest: contains(matrix.node-version, '.x')
114 | - name: Install Latest npm
115 | uses: ./.github/actions/install-latest-npm
116 | with:
117 | node: ${{ steps.node.outputs.node-version }}
118 | - name: Install Dependencies
119 | run: npm i --ignore-scripts --no-audit --no-fund
120 | - name: Add Problem Matcher
121 | run: echo "::add-matcher::.github/matchers/tap.json"
122 | - name: Test
123 | run: npm test --ignore-scripts
124 | - name: Conclude Check
125 | uses: LouisBrunner/checks-action@v1.6.0
126 | if: steps.create-check.outputs.check-id && always()
127 | with:
128 | token: ${{ secrets.GITHUB_TOKEN }}
129 | conclusion: ${{ job.status }}
130 | check_id: ${{ steps.create-check.outputs.check-id }}
131 |
--------------------------------------------------------------------------------
/.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 | permissions:
16 | contents: read
17 |
18 | jobs:
19 | lint:
20 | name: Lint
21 | if: github.repository_owner == 'npm'
22 | runs-on: ubuntu-latest
23 | defaults:
24 | run:
25 | shell: bash
26 | steps:
27 | - name: Checkout
28 | uses: actions/checkout@v4
29 | - name: Setup Git User
30 | run: |
31 | git config --global user.email "npm-cli+bot@github.com"
32 | git config --global user.name "npm CLI robot"
33 | - name: Setup Node
34 | uses: actions/setup-node@v4
35 | id: node
36 | with:
37 | node-version: 18.x
38 | check-latest: contains('18.x', '.x')
39 | - name: Install Latest npm
40 | uses: ./.github/actions/install-latest-npm
41 | with:
42 | node: ${{ steps.node.outputs.node-version }}
43 | - name: Install Dependencies
44 | run: npm i --ignore-scripts --no-audit --no-fund
45 | - name: Lint
46 | run: npm run lint --ignore-scripts
47 | - name: Post Lint
48 | run: npm run postlint --ignore-scripts
49 |
50 | test:
51 | name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }}
52 | if: github.repository_owner == 'npm'
53 | strategy:
54 | fail-fast: false
55 | matrix:
56 | platform:
57 | - name: Linux
58 | os: ubuntu-latest
59 | shell: bash
60 | node-version:
61 | - 18.6.0
62 | - 18.x
63 | runs-on: ${{ matrix.platform.os }}
64 | defaults:
65 | run:
66 | shell: ${{ matrix.platform.shell }}
67 | steps:
68 | - name: Checkout
69 | uses: actions/checkout@v4
70 | - name: Setup Git User
71 | run: |
72 | git config --global user.email "npm-cli+bot@github.com"
73 | git config --global user.name "npm CLI robot"
74 | - name: Setup Node
75 | uses: actions/setup-node@v4
76 | id: node
77 | with:
78 | node-version: ${{ matrix.node-version }}
79 | check-latest: contains(matrix.node-version, '.x')
80 | - name: Install Latest npm
81 | uses: ./.github/actions/install-latest-npm
82 | with:
83 | node: ${{ steps.node.outputs.node-version }}
84 | - name: Install Dependencies
85 | run: npm i --ignore-scripts --no-audit --no-fund
86 | - name: Add Problem Matcher
87 | run: echo "::add-matcher::.github/matchers/tap.json"
88 | - name: Test
89 | run: npm test --ignore-scripts
90 |
--------------------------------------------------------------------------------
/.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 | permissions:
17 | contents: read
18 |
19 | jobs:
20 | analyze:
21 | name: Analyze
22 | runs-on: ubuntu-latest
23 | permissions:
24 | actions: read
25 | contents: read
26 | security-events: write
27 | steps:
28 | - name: Checkout
29 | uses: actions/checkout@v4
30 | - name: Setup Git User
31 | run: |
32 | git config --global user.email "npm-cli+bot@github.com"
33 | git config --global user.name "npm CLI robot"
34 | - name: Initialize CodeQL
35 | uses: github/codeql-action/init@v3
36 | with:
37 | languages: javascript
38 | - name: Perform CodeQL Analysis
39 | uses: github/codeql-action/analyze@v3
40 |
--------------------------------------------------------------------------------
/.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: 18.x
32 | check-latest: contains('18.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 | permissions:
14 | contents: read
15 |
16 | jobs:
17 | commitlint:
18 | name: Lint Commits
19 | if: github.repository_owner == 'npm'
20 | runs-on: ubuntu-latest
21 | defaults:
22 | run:
23 | shell: bash
24 | steps:
25 | - name: Checkout
26 | uses: actions/checkout@v4
27 | with:
28 | fetch-depth: 0
29 | - name: Setup Git User
30 | run: |
31 | git config --global user.email "npm-cli+bot@github.com"
32 | git config --global user.name "npm CLI robot"
33 | - name: Setup Node
34 | uses: actions/setup-node@v4
35 | id: node
36 | with:
37 | node-version: 18.x
38 | check-latest: contains('18.x', '.x')
39 | - name: Install Latest npm
40 | uses: ./.github/actions/install-latest-npm
41 | with:
42 | node: ${{ steps.node.outputs.node-version }}
43 | - name: Install Dependencies
44 | run: npm i --ignore-scripts --no-audit --no-fund
45 | - name: Run Commitlint on Commits
46 | id: commit
47 | continue-on-error: true
48 | run: npx --offline commitlint -V --from 'origin/${{ github.base_ref }}' --to ${{ github.event.pull_request.head.sha }}
49 | - name: Run Commitlint on PR Title
50 | if: steps.commit.outcome == 'failure'
51 | env:
52 | PR_TITLE: ${{ github.event.pull_request.title }}
53 | run: echo "$PR_TITLE" | npx --offline commitlint -V
54 |
--------------------------------------------------------------------------------
/.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 | permissions:
23 | contents: read
24 | id-token: write
25 |
26 | jobs:
27 | publish:
28 | name: Publish
29 | runs-on: ubuntu-latest
30 | defaults:
31 | run:
32 | shell: bash
33 | permissions:
34 | id-token: write
35 | steps:
36 | - name: Checkout
37 | uses: actions/checkout@v4
38 | with:
39 | ref: ${{ fromJSON(inputs.releases)[0].tagName }}
40 | - name: Setup Git User
41 | run: |
42 | git config --global user.email "npm-cli+bot@github.com"
43 | git config --global user.name "npm CLI robot"
44 | - name: Setup Node
45 | uses: actions/setup-node@v4
46 | id: node
47 | with:
48 | node-version: 18.x
49 | check-latest: contains('18.x', '.x')
50 | - name: Install Latest npm
51 | uses: ./.github/actions/install-latest-npm
52 | with:
53 | node: ${{ steps.node.outputs.node-version }}
54 | - name: Install Dependencies
55 | run: npm i --ignore-scripts --no-audit --no-fund
56 | - name: Set npm authToken
57 | run: npm config set '//registry.npmjs.org/:_authToken'=\${PUBLISH_TOKEN}
58 | - name: Publish
59 | env:
60 | PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }}
61 | RELEASES: ${{ inputs.releases }}
62 | run: |
63 | EXIT_CODE=0
64 |
65 | for release in $(echo $RELEASES | jq -r '.[] | @base64'); do
66 | PUBLISH_TAG=$(echo "$release" | base64 --decode | jq -r .publishTag)
67 | npm publish --provenance --tag="$PUBLISH_TAG"
68 | STATUS=$?
69 | if [[ "$STATUS" -eq 1 ]]; then
70 | EXIT_CODE=$STATUS
71 | fi
72 | done
73 |
74 | exit $EXIT_CODE
75 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | # This file is automatically added by @npmcli/template-oss. Do not edit.
2 |
3 | name: Release
4 |
5 | on:
6 | push:
7 | branches:
8 | - main
9 |
10 | permissions:
11 | contents: write
12 | pull-requests: write
13 | checks: write
14 |
15 | jobs:
16 | release:
17 | outputs:
18 | pr: ${{ steps.release.outputs.pr }}
19 | pr-branch: ${{ steps.release.outputs.pr-branch }}
20 | pr-number: ${{ steps.release.outputs.pr-number }}
21 | pr-sha: ${{ steps.release.outputs.pr-sha }}
22 | releases: ${{ steps.release.outputs.releases }}
23 | comment-id: ${{ steps.create-comment.outputs.comment-id || steps.update-comment.outputs.comment-id }}
24 | check-id: ${{ steps.create-check.outputs.check-id }}
25 | name: Release
26 | if: github.repository_owner == 'npm'
27 | runs-on: ubuntu-latest
28 | defaults:
29 | run:
30 | shell: bash
31 | steps:
32 | - name: Checkout
33 | uses: actions/checkout@v4
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: Setup Node
39 | uses: actions/setup-node@v4
40 | id: node
41 | with:
42 | node-version: 18.x
43 | check-latest: contains('18.x', '.x')
44 | - name: Install Latest npm
45 | uses: ./.github/actions/install-latest-npm
46 | with:
47 | node: ${{ steps.node.outputs.node-version }}
48 | - name: Install Dependencies
49 | run: npm i --ignore-scripts --no-audit --no-fund
50 | - name: Release Please
51 | id: release
52 | env:
53 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54 | run: npx --offline template-oss-release-please --branch="${{ github.ref_name }}" --backport="" --defaultTag="latest"
55 | - name: Create Release Manager Comment Text
56 | if: steps.release.outputs.pr-number
57 | uses: actions/github-script@v7
58 | id: comment-text
59 | with:
60 | result-encoding: string
61 | script: |
62 | const { runId, repo: { owner, repo } } = context
63 | const { data: workflow } = await github.rest.actions.getWorkflowRun({ owner, repo, run_id: runId })
64 | return['## Release Manager', `Release workflow run: ${workflow.html_url}`].join('\n\n')
65 | - name: Find Release Manager Comment
66 | uses: peter-evans/find-comment@v2
67 | if: steps.release.outputs.pr-number
68 | id: found-comment
69 | with:
70 | issue-number: ${{ steps.release.outputs.pr-number }}
71 | comment-author: 'github-actions[bot]'
72 | body-includes: '## Release Manager'
73 | - name: Create Release Manager Comment
74 | id: create-comment
75 | if: steps.release.outputs.pr-number && !steps.found-comment.outputs.comment-id
76 | uses: peter-evans/create-or-update-comment@v3
77 | with:
78 | issue-number: ${{ steps.release.outputs.pr-number }}
79 | body: ${{ steps.comment-text.outputs.result }}
80 | - name: Update Release Manager Comment
81 | id: update-comment
82 | if: steps.release.outputs.pr-number && steps.found-comment.outputs.comment-id
83 | uses: peter-evans/create-or-update-comment@v3
84 | with:
85 | comment-id: ${{ steps.found-comment.outputs.comment-id }}
86 | body: ${{ steps.comment-text.outputs.result }}
87 | edit-mode: 'replace'
88 | - name: Create Check
89 | id: create-check
90 | uses: ./.github/actions/create-check
91 | if: steps.release.outputs.pr-sha
92 | with:
93 | name: "Release"
94 | token: ${{ secrets.GITHUB_TOKEN }}
95 | sha: ${{ steps.release.outputs.pr-sha }}
96 |
97 | update:
98 | needs: release
99 | outputs:
100 | sha: ${{ steps.commit.outputs.sha }}
101 | check-id: ${{ steps.create-check.outputs.check-id }}
102 | name: Update - Release
103 | if: github.repository_owner == 'npm' && needs.release.outputs.pr
104 | runs-on: ubuntu-latest
105 | defaults:
106 | run:
107 | shell: bash
108 | steps:
109 | - name: Checkout
110 | uses: actions/checkout@v4
111 | with:
112 | fetch-depth: 0
113 | ref: ${{ needs.release.outputs.pr-branch }}
114 | - name: Setup Git User
115 | run: |
116 | git config --global user.email "npm-cli+bot@github.com"
117 | git config --global user.name "npm CLI robot"
118 | - name: Setup Node
119 | uses: actions/setup-node@v4
120 | id: node
121 | with:
122 | node-version: 18.x
123 | check-latest: contains('18.x', '.x')
124 | - name: Install Latest npm
125 | uses: ./.github/actions/install-latest-npm
126 | with:
127 | node: ${{ steps.node.outputs.node-version }}
128 | - name: Install Dependencies
129 | run: npm i --ignore-scripts --no-audit --no-fund
130 | - name: Create Release Manager Checklist Text
131 | id: comment-text
132 | env:
133 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
134 | run: npm exec --offline -- template-oss-release-manager --pr="${{ needs.release.outputs.pr-number }}" --backport="" --defaultTag="latest" --publish
135 | - name: Append Release Manager Comment
136 | uses: peter-evans/create-or-update-comment@v3
137 | with:
138 | comment-id: ${{ needs.release.outputs.comment-id }}
139 | body: ${{ steps.comment-text.outputs.result }}
140 | edit-mode: 'append'
141 | - name: Run Post Pull Request Actions
142 | env:
143 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
144 | run: npm run rp-pull-request --ignore-scripts --if-present -- --pr="${{ needs.release.outputs.pr-number }}" --commentId="${{ needs.release.outputs.comment-id }}"
145 | - name: Commit
146 | id: commit
147 | env:
148 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
149 | run: |
150 | git commit --all --amend --no-edit || true
151 | git push --force-with-lease
152 | echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
153 | - name: Create Check
154 | id: create-check
155 | uses: ./.github/actions/create-check
156 | with:
157 | name: "Update - Release"
158 | check-name: "Release"
159 | token: ${{ secrets.GITHUB_TOKEN }}
160 | sha: ${{ steps.commit.outputs.sha }}
161 | - name: Conclude Check
162 | uses: LouisBrunner/checks-action@v1.6.0
163 | with:
164 | token: ${{ secrets.GITHUB_TOKEN }}
165 | conclusion: ${{ job.status }}
166 | check_id: ${{ needs.release.outputs.check-id }}
167 |
168 | ci:
169 | name: CI - Release
170 | needs: [ release, update ]
171 | if: needs.release.outputs.pr
172 | uses: ./.github/workflows/ci-release.yml
173 | with:
174 | ref: ${{ needs.release.outputs.pr-branch }}
175 | check-sha: ${{ needs.update.outputs.sha }}
176 |
177 | post-ci:
178 | needs: [ release, update, ci ]
179 | name: Post CI - Release
180 | if: github.repository_owner == 'npm' && needs.release.outputs.pr && always()
181 | runs-on: ubuntu-latest
182 | defaults:
183 | run:
184 | shell: bash
185 | steps:
186 | - name: Get CI Conclusion
187 | id: conclusion
188 | run: |
189 | result=""
190 | if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]]; then
191 | result="failure"
192 | elif [[ "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then
193 | result="cancelled"
194 | else
195 | result="success"
196 | fi
197 | echo "result=$result" >> $GITHUB_OUTPUT
198 | - name: Conclude Check
199 | uses: LouisBrunner/checks-action@v1.6.0
200 | with:
201 | token: ${{ secrets.GITHUB_TOKEN }}
202 | conclusion: ${{ steps.conclusion.outputs.result }}
203 | check_id: ${{ needs.update.outputs.check-id }}
204 |
205 | post-release:
206 | needs: release
207 | outputs:
208 | comment-id: ${{ steps.create-comment.outputs.comment-id }}
209 | name: Post Release - Release
210 | if: github.repository_owner == 'npm' && needs.release.outputs.releases
211 | runs-on: ubuntu-latest
212 | defaults:
213 | run:
214 | shell: bash
215 | steps:
216 | - name: Create Release PR Comment Text
217 | id: comment-text
218 | uses: actions/github-script@v7
219 | env:
220 | RELEASES: ${{ needs.release.outputs.releases }}
221 | with:
222 | result-encoding: string
223 | script: |
224 | const releases = JSON.parse(process.env.RELEASES)
225 | const { runId, repo: { owner, repo } } = context
226 | const issue_number = releases[0].prNumber
227 | const runUrl = `https://github.com/${owner}/${repo}/actions/runs/${runId}`
228 |
229 | return [
230 | '## Release Workflow\n',
231 | ...releases.map(r => `- \`${r.pkgName}@${r.version}\` ${r.url}`),
232 | `- Workflow run: :arrows_counterclockwise: ${runUrl}`,
233 | ].join('\n')
234 | - name: Create Release PR Comment
235 | id: create-comment
236 | uses: peter-evans/create-or-update-comment@v3
237 | with:
238 | issue-number: ${{ fromJSON(needs.release.outputs.releases)[0].prNumber }}
239 | body: ${{ steps.comment-text.outputs.result }}
240 |
241 | release-integration:
242 | needs: release
243 | name: Release Integration
244 | if: needs.release.outputs.releases
245 | uses: ./.github/workflows/release-integration.yml
246 | permissions:
247 | contents: read
248 | id-token: write
249 | secrets:
250 | PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }}
251 | with:
252 | releases: ${{ needs.release.outputs.releases }}
253 |
254 | post-release-integration:
255 | needs: [ release, release-integration, post-release ]
256 | name: Post Release Integration - Release
257 | if: github.repository_owner == 'npm' && needs.release.outputs.releases && always()
258 | runs-on: ubuntu-latest
259 | defaults:
260 | run:
261 | shell: bash
262 | steps:
263 | - name: Get Post Release Conclusion
264 | id: conclusion
265 | run: |
266 | if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]]; then
267 | result="x"
268 | elif [[ "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then
269 | result="heavy_multiplication_x"
270 | else
271 | result="white_check_mark"
272 | fi
273 | echo "result=$result" >> $GITHUB_OUTPUT
274 | - name: Find Release PR Comment
275 | uses: peter-evans/find-comment@v2
276 | id: found-comment
277 | with:
278 | issue-number: ${{ fromJSON(needs.release.outputs.releases)[0].prNumber }}
279 | comment-author: 'github-actions[bot]'
280 | body-includes: '## Release Workflow'
281 | - name: Create Release PR Comment Text
282 | id: comment-text
283 | if: steps.found-comment.outputs.comment-id
284 | uses: actions/github-script@v7
285 | env:
286 | RESULT: ${{ steps.conclusion.outputs.result }}
287 | BODY: ${{ steps.found-comment.outputs.comment-body }}
288 | with:
289 | result-encoding: string
290 | script: |
291 | const { RESULT, BODY } = process.env
292 | const body = [BODY.replace(/(Workflow run: :)[a-z_]+(:)/, `$1${RESULT}$2`)]
293 | if (RESULT !== 'white_check_mark') {
294 | body.push(':rotating_light::rotating_light::rotating_light:')
295 | body.push([
296 | '@npm/cli-team: The post-release workflow failed for this release.',
297 | 'Manual steps may need to be taken after examining the workflow output.'
298 | ].join(' '))
299 | body.push(':rotating_light::rotating_light::rotating_light:')
300 | }
301 | return body.join('\n\n').trim()
302 | - name: Update Release PR Comment
303 | if: steps.comment-text.outputs.result
304 | uses: peter-evans/create-or-update-comment@v3
305 | with:
306 | comment-id: ${{ steps.found-comment.outputs.comment-id }}
307 | body: ${{ steps.comment-text.outputs.result }}
308 | edit-mode: 'replace'
309 |
--------------------------------------------------------------------------------
/.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.cjs
8 | !/.eslint.config.js
9 | !/.eslintrc.cjs
10 | !/.eslintrc.local.*
11 | !/.git-blame-ignore-revs
12 | !/.github/
13 | !/.gitignore
14 | !/.npmrc
15 | !/.prettierignore
16 | !/.prettierrc.cjs
17 | !/.release-please-manifest.json
18 | !/bin/
19 | !/CHANGELOG*
20 | !/CODE_OF_CONDUCT.md
21 | !/CONTRIBUTING.md
22 | !/docs/
23 | !/lib/
24 | !/LICENSE*
25 | !/map.js
26 | !/package.json
27 | !/README*
28 | !/release-please-config.json
29 | !/scripts/
30 | !/SECURITY.md
31 | !/tap-snapshots/
32 | !/test/
33 | !/tsconfig.json
34 | !/types/
35 | tap-testdir*/
36 |
--------------------------------------------------------------------------------
/.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 | ".": "2.1.0"
3 | }
4 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## [2.1.0](https://github.com/npm/types/compare/v2.0.0...v2.1.0) (2025-04-28)
4 | ### Features
5 | * [`9780470`](https://github.com/npm/types/commit/978047035dbe14c3dafb65eaa31413a5f8a9d197) [#85](https://github.com/npm/types/pull/85) add devEngines (#85) (@reggi)
6 | ### Chores
7 | * [`f8308cd`](https://github.com/npm/types/commit/f8308cdf83bead92de57d38bfba40755ee83ab40) [#115](https://github.com/npm/types/pull/115) postinstall workflow updates (#115) (@owlstronaut)
8 | * [`96d8414`](https://github.com/npm/types/commit/96d84144cdd03e0ff5ed098287c9529550a8220b) [#113](https://github.com/npm/types/pull/113) bump @types/node from 22.14.0 to 22.14.1 (#113) (@dependabot[bot])
9 | * [`b2b779e`](https://github.com/npm/types/commit/b2b779e667998606770e65fcbbbdce106582e724) [#111](https://github.com/npm/types/pull/111) bump eslint-import-resolver-typescript from 3.10.0 to 4.3.2 (#111) (@dependabot[bot])
10 | * [`1787777`](https://github.com/npm/types/commit/1787777be536e7465bd32d9f2e7dc282d767780e) [#110](https://github.com/npm/types/pull/110) bump @types/node from 22.1.0 to 22.14.0 (#110) (@dependabot[bot])
11 | * [`6d3f319`](https://github.com/npm/types/commit/6d3f319a4e717e48da34cd636acfdc6e17e96362) [#78](https://github.com/npm/types/pull/78) bump @npmcli/eslint-config from 4.0.5 to 5.0.0 (@dependabot[bot])
12 | * [`f85ed36`](https://github.com/npm/types/commit/f85ed36b1f38860a440c7e7805375eed2ffe98eb) [#112](https://github.com/npm/types/pull/112) bump @npmcli/template-oss from 4.23.3 to 4.24.3 (#112) (@dependabot[bot], @npm-cli-bot)
13 | * [`d721997`](https://github.com/npm/types/commit/d721997881c582f0f10514c513fafbfd739e8332) [#79](https://github.com/npm/types/pull/79) postinstall for dependabot template-oss PR (@hashtagchris)
14 |
15 | ## [2.0.0](https://github.com/npm/types/compare/v1.0.2...v2.0.0) (2024-08-07)
16 |
17 | ### ⚠️ BREAKING CHANGES
18 |
19 | * update types (#29)
20 | * refactor to use @npmcli/template-oss (#31)
21 |
22 | ### Features
23 |
24 | * [`123bb67`](https://github.com/npm/types/commit/123bb67ded41470435fca76f30911ffa344bc615) [#29](https://github.com/npm/types/pull/29) update types (#29) (@broofa, @jablko, @lukekarrys)
25 | * [`f09f754`](https://github.com/npm/types/commit/f09f7542fd8f5df1dbefd4461f4bc7c320d03eab) [#31](https://github.com/npm/types/pull/31) refactor to use @npmcli/template-oss (#31) (@lukekarrys)
26 |
27 | ### Bug Fixes
28 |
29 | * [`6ffee7f`](https://github.com/npm/types/commit/6ffee7fc58b1764e0ff50403d86dcb5a703b9490) [#60](https://github.com/npm/types/pull/60) add missing fields, fix up array type, add comments (#60) (@broofa, @styfle)
30 | * [`4548f2c`](https://github.com/npm/types/commit/4548f2cd83b631c951e622ff5c0f5112437e4d4d) [#39](https://github.com/npm/types/pull/39) linting cleanup (#39) (@lukekarrys)
31 |
32 | ### Documentation
33 |
34 | * [`5511d4b`](https://github.com/npm/types/commit/5511d4bc6c86bdf44b44efcea4ef038293c40773) [#40](https://github.com/npm/types/pull/40) fix README typo, improve PackageJSON description (#40) (@broofa, @styfle)
35 | * [`1a08144`](https://github.com/npm/types/commit/1a08144a61ef3db9100e303f9adec241fdc2011a) [#37](https://github.com/npm/types/pull/37) fix typo in readme (#37) (@lukekarrys)
36 |
37 | ### Chores
38 |
39 | * [`d323311`](https://github.com/npm/types/commit/d3233112ba9438425b3b709db478100e3c1efb97) [#70](https://github.com/npm/types/pull/70) bump @types/node from 20.12.10 to 22.1.0 (#70) (@dependabot[bot])
40 | * [`4761562`](https://github.com/npm/types/commit/4761562425fc1147109997455d09b8d1566444c2) [#71](https://github.com/npm/types/pull/71) bump @typescript-eslint/parser from 7.18.0 to 8.0.1 (#71) (@dependabot[bot])
41 | * [`3687a18`](https://github.com/npm/types/commit/3687a18e1be7e1dd99ffe90d4ed5cd15d57c9dfa) [#38](https://github.com/npm/types/pull/38) simplify template-oss config (#38) (@lukekarrys)
42 | * [`1a1fd85`](https://github.com/npm/types/commit/1a1fd851040cba2dbdb1653b80e94744e2bada53) [#36](https://github.com/npm/types/pull/36) remove build script and update snapshots and tsconfig (#36) (@lukekarrys)
43 | * [`3172a32`](https://github.com/npm/types/commit/3172a327b4f156c6d8f2a43105ef36a99c7b0c71) update template-oss files for main branch (@lukekarrys)
44 |
--------------------------------------------------------------------------------
/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 | Copyright (c) 2018 npm inc.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
19 | OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # @npm/types
2 |
3 | Typescript definitions for npm registry endpoints
4 |
5 | For example:
6 |
7 | ```typescript
8 | import * as npm from '@npm/types';
9 |
10 | fetch('https://registry.npmjs.org/cookie')
11 | .then((res) => res.json())
12 | .then((obj: npm.Packument) => {
13 | // `obj` has proper registry types!
14 | })
15 | ```
16 |
17 | ## Types
18 |
19 | ### Packument
20 | Response type for the `https://registry.npmjs.org/:packageName` endpoint
21 |
22 | ### PackumentVersion
23 | Response type for the `https://registry.npmjs.org/:packageName/:packageVersion` endpoint. Also the type of `Packument['versions']` entries.
24 |
25 | ### Manifest
26 | Response type for the `https://registry.npmjs.org/:packageName` endpoint, _when made with the 'Accept: application/vnd.npm.install-v1+json' header_.
27 |
28 | ### ManifestVersion
29 | Response type for the `https://registry.npmjs.org/:packageName/:packageVersion` endpoint, _when made with the 'Accept: application/vnd.npm.install-v1+json' header_. Also the type of `Manifest['versions']` entries.
30 |
31 | ### PackageJSON
32 | A "loose" definition of package.json structures.
33 |
34 | > [!NOTE]
35 | > This is not an authoritative definition of package.json structures. Rather, it is a best-effort attempt to describe the fields that are de-facto standards for Node.js, npm, and TypeScript development.
36 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@npm/types",
3 | "version": "2.1.0",
4 | "description": "Typescript definitions for npm registry content",
5 | "types": "./types/index.d.ts",
6 | "scripts": {
7 | "lint": "npm run eslint",
8 | "postlint": "template-oss-check",
9 | "template-oss-apply": "template-oss-apply --force",
10 | "lintfix": "npm run eslint -- --fix",
11 | "snap": "tap",
12 | "test": "tap",
13 | "posttest": "npm run lint",
14 | "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\""
15 | },
16 | "keywords": [
17 | "npm registry",
18 | "types",
19 | "typescript",
20 | "definitions",
21 | "typings"
22 | ],
23 | "author": "GitHub Inc.",
24 | "license": "MIT",
25 | "engines": {
26 | "node": ">=18.6.0"
27 | },
28 | "devDependencies": {
29 | "@npmcli/eslint-config": "^5.0.0",
30 | "@npmcli/template-oss": "4.24.3",
31 | "@types/node": "22.14.1",
32 | "@typescript-eslint/parser": "^8.0.1",
33 | "eslint-import-resolver-typescript": "^4.3.2",
34 | "tap": "^18.7.3",
35 | "typescript": "^5.4.5"
36 | },
37 | "files": [
38 | "bin/",
39 | "lib/",
40 | "types/"
41 | ],
42 | "repository": {
43 | "type": "git",
44 | "url": "git+https://github.com/npm/types.git"
45 | },
46 | "templateOSS": {
47 | "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
48 | "version": "4.24.3",
49 | "allowPaths": [
50 | "/types/"
51 | ],
52 | "distPaths": [
53 | "types/"
54 | ],
55 | "latestCiVersion": 18,
56 | "windowsCI": false,
57 | "macCI": false,
58 | "publish": true
59 | },
60 | "type": "module",
61 | "tap": {
62 | "typecheck": true,
63 | "disable-coverage": true,
64 | "show-full-coverage": true
65 | },
66 | "nyc": {
67 | "exclude": []
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/release-please-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "last-release-sha": "7f357f45e2b4205cd8474339a95092a5e6e77917",
3 | "group-pull-request-title-pattern": "chore: release ${version}",
4 | "pull-request-title-pattern": "chore: release${component} ${version}",
5 | "changelog-sections": [
6 | {
7 | "type": "feat",
8 | "section": "Features",
9 | "hidden": false
10 | },
11 | {
12 | "type": "fix",
13 | "section": "Bug Fixes",
14 | "hidden": false
15 | },
16 | {
17 | "type": "docs",
18 | "section": "Documentation",
19 | "hidden": false
20 | },
21 | {
22 | "type": "deps",
23 | "section": "Dependencies",
24 | "hidden": false
25 | },
26 | {
27 | "type": "chore",
28 | "section": "Chores",
29 | "hidden": true
30 | }
31 | ],
32 | "prerelease-type": "pre.0",
33 | "packages": {
34 | ".": {
35 | "package-name": ""
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/tap-snapshots/test/fixtures.ts.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/fixtures.ts > TAP > fixtures > snapshots > not-licensed.manifest.ts 1`] = `
9 | Manifest = {
10 | "dist-tags": {
11 | "latest": "1.0.0"
12 | },
13 | "modified": "2022-06-22T05:57:37.481Z",
14 | "name": "not-licensed",
15 | "versions": {
16 | "1.0.0": {
17 | "dist": {
18 | "integrity": "sha512-U9DmnjDE+hh2EGC4ug7XOKHlxVkbv2+vguUXeHT0ffGUChyt6LsX5MZ8q5cuH05el8BQrCrxzzBkrGnDuFwV0Q==",
19 | "shasum": "e0c0d3022af1e51a49d24703c9c7a0c30a0f59a8",
20 | "signatures": [
21 | {
22 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
23 | "sig": "MEUCICnUmc7y4OyUP8Cz5CFTnXBO3mzUTs+c5L9Fn7AjTml1AiEAk7VlYRz8GPdNGY+HgURUiX9ceiOLSZyMop2uBleTbOM="
24 | }
25 | ],
26 | "tarball": "https://registry.npmjs.org/not-licensed/-/not-licensed-1.0.0.tgz"
27 | },
28 | "name": "not-licensed",
29 | "version": "1.0.0"
30 | }
31 | }
32 | }
33 | `
34 |
35 | exports[`test/fixtures.ts > TAP > fixtures > snapshots > not-licensed.ts 1`] = `
36 | Packument = {
37 | "_id": "not-licensed",
38 | "_rev": "3-5e8502a05053da7c2cb1b51f8a08a0ec",
39 | "author": {
40 | "email": "kyle@kemitchell.com",
41 | "name": "Kyle E. Mitchell",
42 | "url": "https://kemitchell.com/"
43 | },
44 | "bugs": {
45 | "url": "https://github.com/jslicense/not-licensed.js/issues"
46 | },
47 | "description": "an empty package without license metadata",
48 | "dist-tags": {
49 | "latest": "1.0.0"
50 | },
51 | "homepage": "https://github.com/jslicense/not-licensed.js#readme",
52 | "maintainers": [
53 | {
54 | "email": "kyle@kemitchell.com",
55 | "name": "kemitchell"
56 | }
57 | ],
58 | "name": "not-licensed",
59 | "readme": "ERROR: No README data found!",
60 | "readmeFilename": "",
61 | "repository": {
62 | "type": "git",
63 | "url": "git+https://github.com/jslicense/not-licensed.js.git"
64 | },
65 | "time": {
66 | "1.0.0": "2016-02-06T06:03:32.362Z",
67 | "created": "2016-02-06T06:03:32.362Z",
68 | "modified": "2022-06-22T05:57:37.481Z"
69 | },
70 | "versions": {
71 | "1.0.0": {
72 | "_from": ".",
73 | "_id": "not-licensed@1.0.0",
74 | "_nodeVersion": "5.5.0",
75 | "_npmOperationalInternal": {
76 | "host": "packages-5-east.internal.npmjs.com",
77 | "tmp": "tmp/not-licensed-1.0.0.tgz_1454738610221_0.42489640787243843"
78 | },
79 | "_npmUser": {
80 | "email": "kyle@kemitchell.com",
81 | "name": "kemitchell"
82 | },
83 | "_npmVersion": "3.7.1",
84 | "_shasum": "e0c0d3022af1e51a49d24703c9c7a0c30a0f59a8",
85 | "author": {
86 | "email": "kyle@kemitchell.com",
87 | "name": "Kyle E. Mitchell",
88 | "url": "https://kemitchell.com/"
89 | },
90 | "bugs": {
91 | "url": "https://github.com/jslicense/not-licensed.js/issues"
92 | },
93 | "description": "an empty package without license metadata",
94 | "dist": {
95 | "integrity": "sha512-U9DmnjDE+hh2EGC4ug7XOKHlxVkbv2+vguUXeHT0ffGUChyt6LsX5MZ8q5cuH05el8BQrCrxzzBkrGnDuFwV0Q==",
96 | "shasum": "e0c0d3022af1e51a49d24703c9c7a0c30a0f59a8",
97 | "signatures": [
98 | {
99 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
100 | "sig": "MEUCICnUmc7y4OyUP8Cz5CFTnXBO3mzUTs+c5L9Fn7AjTml1AiEAk7VlYRz8GPdNGY+HgURUiX9ceiOLSZyMop2uBleTbOM="
101 | }
102 | ],
103 | "tarball": "https://registry.npmjs.org/not-licensed/-/not-licensed-1.0.0.tgz"
104 | },
105 | "gitHead": "bd842fd7a3ac910f4c9cf084253bf99d2aab0a46",
106 | "homepage": "https://github.com/jslicense/not-licensed.js#readme",
107 | "maintainers": [
108 | {
109 | "email": "kyle@kemitchell.com",
110 | "name": "kemitchell"
111 | }
112 | ],
113 | "name": "not-licensed",
114 | "repository": {
115 | "type": "git",
116 | "url": "git+https://github.com/jslicense/not-licensed.js.git"
117 | },
118 | "scripts": {},
119 | "version": "1.0.0"
120 | }
121 | }
122 | }
123 | `
124 |
125 | exports[`test/fixtures.ts > TAP > fixtures > snapshots > not-licensed@1.0.0.ts 1`] = `
126 | PackumentVersion = {
127 | "_from": ".",
128 | "_id": "not-licensed@1.0.0",
129 | "_nodeVersion": "5.5.0",
130 | "_npmOperationalInternal": {
131 | "host": "packages-5-east.internal.npmjs.com",
132 | "tmp": "tmp/not-licensed-1.0.0.tgz_1454738610221_0.42489640787243843"
133 | },
134 | "_npmUser": {
135 | "email": "kyle@kemitchell.com",
136 | "name": "kemitchell"
137 | },
138 | "_npmVersion": "3.7.1",
139 | "_shasum": "e0c0d3022af1e51a49d24703c9c7a0c30a0f59a8",
140 | "author": {
141 | "email": "kyle@kemitchell.com",
142 | "name": "Kyle E. Mitchell",
143 | "url": "https://kemitchell.com/"
144 | },
145 | "bugs": {
146 | "url": "https://github.com/jslicense/not-licensed.js/issues"
147 | },
148 | "description": "an empty package without license metadata",
149 | "dist": {
150 | "integrity": "sha512-U9DmnjDE+hh2EGC4ug7XOKHlxVkbv2+vguUXeHT0ffGUChyt6LsX5MZ8q5cuH05el8BQrCrxzzBkrGnDuFwV0Q==",
151 | "shasum": "e0c0d3022af1e51a49d24703c9c7a0c30a0f59a8",
152 | "signatures": [
153 | {
154 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
155 | "sig": "MEUCICnUmc7y4OyUP8Cz5CFTnXBO3mzUTs+c5L9Fn7AjTml1AiEAk7VlYRz8GPdNGY+HgURUiX9ceiOLSZyMop2uBleTbOM="
156 | }
157 | ],
158 | "tarball": "https://registry.npmjs.org/not-licensed/-/not-licensed-1.0.0.tgz"
159 | },
160 | "gitHead": "bd842fd7a3ac910f4c9cf084253bf99d2aab0a46",
161 | "homepage": "https://github.com/jslicense/not-licensed.js#readme",
162 | "maintainers": [
163 | {
164 | "email": "kyle@kemitchell.com",
165 | "name": "kemitchell"
166 | }
167 | ],
168 | "name": "not-licensed",
169 | "repository": {
170 | "type": "git",
171 | "url": "git+https://github.com/jslicense/not-licensed.js.git"
172 | },
173 | "scripts": {},
174 | "version": "1.0.0"
175 | }
176 | `
177 |
178 | exports[`test/fixtures.ts > TAP > fixtures > snapshots > tiny-tarball.manifest.ts 1`] = `
179 | Manifest = {
180 | "dist-tags": {
181 | "latest": "1.0.0"
182 | },
183 | "modified": "2022-06-27T07:01:30.945Z",
184 | "name": "tiny-tarball",
185 | "versions": {
186 | "1.0.0": {
187 | "dist": {
188 | "integrity": "sha512-SxmEuEiq4d9L2UjUCyP7g3KHND65MJnsFbEwCbaoMp9NYjHjufAzIUCRaRHB+FNTwzZ1e2xjBoYobBB8pqB5IQ==",
189 | "shasum": "bbf102d5ae73afe2c553295e0fb02230216f65b1",
190 | "signatures": [
191 | {
192 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
193 | "sig": "MEUCICguG74eMv+l6RBT6cDoOhWysqtjms2zSXyWwg6LC5XnAiEAq1VSNbCx+D4LT6lgzYx0JGs0PPWKgP9XuQn8tniow2c="
194 | }
195 | ],
196 | "tarball": "https://registry.npmjs.org/tiny-tarball/-/tiny-tarball-1.0.0.tgz"
197 | },
198 | "name": "tiny-tarball",
199 | "version": "1.0.0"
200 | }
201 | }
202 | }
203 | `
204 |
205 | exports[`test/fixtures.ts > TAP > fixtures > snapshots > tiny-tarball.ts 1`] = `
206 | Packument = {
207 | "_id": "tiny-tarball",
208 | "_rev": "5-6e3e9084c69f16db2d53a953e67d0f9e",
209 | "author": {
210 | "email": "ben@npmjs.com",
211 | "name": "Ben Coe"
212 | },
213 | "description": "tiny tarball used for health checks",
214 | "dist-tags": {
215 | "latest": "1.0.0"
216 | },
217 | "license": "ISC",
218 | "maintainers": [
219 | {
220 | "email": "ben@npmjs.com",
221 | "name": "bcoe"
222 | }
223 | ],
224 | "name": "tiny-tarball",
225 | "readme": "# TinyTarball\\n\\ntiny-tarball used for health checks\\n\\n**don't unpublish me!**\\n",
226 | "readmeFilename": "README.md",
227 | "time": {
228 | "1.0.0": "2015-03-24T00:12:24.039Z",
229 | "created": "2015-03-24T00:12:24.039Z",
230 | "modified": "2022-06-27T07:01:30.945Z"
231 | },
232 | "versions": {
233 | "1.0.0": {
234 | "_from": ".",
235 | "_id": "tiny-tarball@1.0.0",
236 | "_nodeVersion": "1.5.0",
237 | "_npmUser": {
238 | "email": "bencoe@gmail.com",
239 | "name": "bcoe"
240 | },
241 | "_npmVersion": "2.7.0",
242 | "_shasum": "bbf102d5ae73afe2c553295e0fb02230216f65b1",
243 | "author": {
244 | "email": "ben@npmjs.com",
245 | "name": "Ben Coe"
246 | },
247 | "description": "tiny tarball used for health checks",
248 | "dist": {
249 | "integrity": "sha512-SxmEuEiq4d9L2UjUCyP7g3KHND65MJnsFbEwCbaoMp9NYjHjufAzIUCRaRHB+FNTwzZ1e2xjBoYobBB8pqB5IQ==",
250 | "shasum": "bbf102d5ae73afe2c553295e0fb02230216f65b1",
251 | "signatures": [
252 | {
253 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
254 | "sig": "MEUCICguG74eMv+l6RBT6cDoOhWysqtjms2zSXyWwg6LC5XnAiEAq1VSNbCx+D4LT6lgzYx0JGs0PPWKgP9XuQn8tniow2c="
255 | }
256 | ],
257 | "tarball": "https://registry.npmjs.org/tiny-tarball/-/tiny-tarball-1.0.0.tgz"
258 | },
259 | "license": "ISC",
260 | "main": "index.js",
261 | "maintainers": [
262 | {
263 | "email": "bencoe@gmail.com",
264 | "name": "bcoe"
265 | }
266 | ],
267 | "name": "tiny-tarball",
268 | "scripts": {
269 | "test": "echo \\"Error: no test specified\\" && exit 1"
270 | },
271 | "version": "1.0.0"
272 | }
273 | }
274 | }
275 | `
276 |
277 | exports[`test/fixtures.ts > TAP > fixtures > snapshots > tiny-tarball@1.0.0.ts 1`] = `
278 | PackumentVersion = {
279 | "_from": ".",
280 | "_id": "tiny-tarball@1.0.0",
281 | "_nodeVersion": "1.5.0",
282 | "_npmUser": {
283 | "email": "bencoe@gmail.com",
284 | "name": "bcoe"
285 | },
286 | "_npmVersion": "2.7.0",
287 | "_shasum": "bbf102d5ae73afe2c553295e0fb02230216f65b1",
288 | "author": {
289 | "email": "ben@npmjs.com",
290 | "name": "Ben Coe"
291 | },
292 | "description": "tiny tarball used for health checks",
293 | "dist": {
294 | "integrity": "sha512-SxmEuEiq4d9L2UjUCyP7g3KHND65MJnsFbEwCbaoMp9NYjHjufAzIUCRaRHB+FNTwzZ1e2xjBoYobBB8pqB5IQ==",
295 | "shasum": "bbf102d5ae73afe2c553295e0fb02230216f65b1",
296 | "signatures": [
297 | {
298 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
299 | "sig": "MEUCICguG74eMv+l6RBT6cDoOhWysqtjms2zSXyWwg6LC5XnAiEAq1VSNbCx+D4LT6lgzYx0JGs0PPWKgP9XuQn8tniow2c="
300 | }
301 | ],
302 | "tarball": "https://registry.npmjs.org/tiny-tarball/-/tiny-tarball-1.0.0.tgz"
303 | },
304 | "license": "ISC",
305 | "main": "index.js",
306 | "maintainers": [
307 | {
308 | "email": "bencoe@gmail.com",
309 | "name": "bcoe"
310 | }
311 | ],
312 | "name": "tiny-tarball",
313 | "scripts": {
314 | "test": "echo \\"Error: no test specified\\" && exit 1"
315 | },
316 | "version": "1.0.0"
317 | }
318 | `
319 |
320 | exports[`test/fixtures.ts > TAP > fixtures > snapshots > uuid@0.0.2.ts 1`] = `
321 | PackumentVersion = {
322 | "_id": "uuid@0.0.2",
323 | "_nodeSupported": true,
324 | "_nodeVersion": "v0.3.1-pre",
325 | "_npmVersion": "0.2.7-2",
326 | "author": {
327 | "name": "Nikhil Marathe"
328 | },
329 | "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
330 | "description": "Simple libuuid bindings to allow UUIDs to be generated from JS.",
331 | "directories": {},
332 | "dist": {
333 | "bin": {
334 | "0.4-sunos-5.11": {
335 | "shasum": "2ff8d977261ddadfd1446cee661ab87863659e45",
336 | "tarball": "http://registry.npmjs.org/uuid/-/uuid-0.0.2-0.4-sunos-5.11.tgz"
337 | }
338 | },
339 | "integrity": "sha512-3h/4V/B5W+7FmanZTk1bQMDDoNstFk/2xy0W2W1s1WX8NPU2Sgrfi3GXZQvhqVZZiQAA7A7uUgOB4xzy0ngraA==",
340 | "shasum": "3171f2c4f58895b8b307692a335fb2349ddf6733",
341 | "signatures": [
342 | {
343 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
344 | "sig": "MEYCIQD1IQ4S7SggRuiiTxjJVzzfkHVzcPpPso/A+N++TgXqAgIhAP+LCzmHoT6q26ofm8BifbpLqynMNyNtpYHPSz7covx/"
345 | }
346 | ],
347 | "tarball": "https://registry.npmjs.org/uuid/-/uuid-0.0.2.tgz"
348 | },
349 | "engine": [
350 | "node >=0.1.103"
351 | ],
352 | "engines": {
353 | "node": "*"
354 | },
355 | "main": "build/default/uuid",
356 | "name": "uuid",
357 | "repository": {
358 | "type": "hg",
359 | "url": "http://bitbucket.org/nikhilm/uuidjs"
360 | },
361 | "scripts": {
362 | "preinstall": "node-waf configure && node-waf build"
363 | },
364 | "version": "0.0.2"
365 | }
366 | `
367 |
368 | exports[`test/fixtures.ts > TAP > fixtures > snapshots > uuid@1.4.1.ts 1`] = `
369 | PackumentVersion = {
370 | "_from": ".",
371 | "_id": "uuid@1.4.1",
372 | "_npmUser": {
373 | "email": "shtylman@gmail.com",
374 | "name": "shtylman"
375 | },
376 | "_npmVersion": "1.2.11",
377 | "author": {
378 | "email": "robert@broofa.com",
379 | "name": "Robert Kieffer"
380 | },
381 | "browser": {
382 | "./rng.js": "./rng-browser.js"
383 | },
384 | "contributors": [
385 | {
386 | "email": "dev@tavan.de",
387 | "name": "Christoph Tavan"
388 | }
389 | ],
390 | "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
391 | "description": "Rigorous implementation of RFC4122 (v1 and v4) UUIDs.",
392 | "devDependencies": {
393 | "mocha": "1.8.0"
394 | },
395 | "directories": {},
396 | "dist": {
397 | "integrity": "sha512-VvxWRJy+jqowMX1wClasj2BIORh82/X3wkRNNpXDOh1tUxmVAbdEWRUM+yRVg30a+XBmf+duDVtMgvRiuGq0qw==",
398 | "shasum": "a337828580d426e375b8ee11bd2bf901a596e0b8",
399 | "signatures": [
400 | {
401 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
402 | "sig": "MEYCIQDGPgY/8s7EsZsplI7wUj9zkdvyAiFBNx8EMgYI37OuuQIhAPjpphlukLKOEBmORh7gaKymp9hSVj6dxl46neHEGac2"
403 | }
404 | ],
405 | "tarball": "https://registry.npmjs.org/uuid/-/uuid-1.4.1.tgz"
406 | },
407 | "keywords": [
408 | "uuid",
409 | "guid",
410 | "rfc4122"
411 | ],
412 | "main": "./uuid.js",
413 | "maintainers": [
414 | {
415 | "email": "robert@broofa.com",
416 | "name": "broofa"
417 | },
418 | {
419 | "email": "tim@fostle.com",
420 | "name": "tim-smart"
421 | },
422 | {
423 | "email": "shtylman@gmail.com",
424 | "name": "shtylman"
425 | }
426 | ],
427 | "name": "uuid",
428 | "repository": {
429 | "type": "git",
430 | "url": "https://github.com/shtylman/node-uuid.git"
431 | },
432 | "scripts": {
433 | "test": "mocha test/test.js"
434 | },
435 | "testling": {
436 | "browsers": [
437 | "ie6..latest",
438 | "firefox/3.6..latest",
439 | "chrome/22..latest",
440 | "safari/5.1..latest"
441 | ],
442 | "files": "test/*.js",
443 | "harness": "mocha-tdd"
444 | },
445 | "version": "1.4.1"
446 | }
447 | `
448 |
--------------------------------------------------------------------------------
/test/fixtures.ts:
--------------------------------------------------------------------------------
1 | import { spawn } from 'node:child_process'
2 | import { readFile } from 'node:fs/promises'
3 | import { join, resolve } from 'node:path'
4 | import t from 'tap'
5 |
6 | const REGISTRY = 'https://registry.npmjs.org'
7 |
8 | const FIXTURES = [
9 | { name: 'not-licensed', version: '1.0.0' },
10 | { name: 'not-licensed' },
11 | { name: 'tiny-tarball', version: '1.0.0' },
12 | { name: 'tiny-tarball' },
13 | // Legacy packages that have informed type declarations
14 | { name: 'uuid', version: '0.0.2' },
15 | { name: 'uuid', version: '1.4.1' },
16 | ]
17 |
18 | /**
19 | * Unit test for types. Does the following...
20 | * 1. For each FIXTURES url, fetches the registry data
21 | * 2. ... generates a TS fixture file that assigns the data to a variable with
22 | * the appropriate type
23 | * 3. Runs `tsc` to validate registry data matches the type definition.
24 | */
25 | t.test('fixtures', async (t) => {
26 | const root = process.cwd()
27 | const tsConfig = await readFile(join(root, 'tsconfig.json'), 'utf-8')
28 | const fixtures = await getFixtures()
29 |
30 | const dir = t.testdir({
31 | 'tsconfig-test.json': JSON.stringify({
32 | compilerOptions: {
33 | ...JSON.parse(tsConfig).compilerOptions,
34 | rootDir: 'fixtures',
35 | },
36 | include: ['fixtures'],
37 | }),
38 | fixtures: Object.fromEntries(
39 | Object.entries(fixtures).map(([k, v]) => [
40 | k,
41 | `import type * as npmTypes from '../../../../types/index.d.ts'\n` +
42 | `export const metadata: npmTypes.${v}`,
43 | ])
44 | ),
45 | })
46 |
47 | t.test('snapshots', async (t) => {
48 | for (const [k, v] of Object.entries(fixtures)) {
49 | t.matchSnapshot(v, k)
50 | }
51 | })
52 |
53 | t.test('tsc', (t) =>
54 | new Promise((res) => {
55 | const proc = spawn(
56 | resolve(root, './node_modules/.bin/tsc'),
57 | ['--noEmit', '-p', './tsconfig-test.json'],
58 | { cwd: dir }
59 | )
60 | let output = ''
61 | proc.stdout.on('data', (d) => (output += d.toString()))
62 | proc.on('close', (code) => {
63 | t.equal(code, 0, output)
64 | res()
65 | })
66 | })
67 | )
68 | })
69 |
70 | async function getFixtures () {
71 | const fixtures: Record = {}
72 |
73 | for (const { name, version } of FIXTURES) {
74 | const fixtureName = `${name}${version ? `@${version}` : ''}`
75 |
76 | for (const corgi of [false, true]) {
77 | // Corgis are only available for Packument documents, not PackumentVersions
78 | if (corgi && version) {
79 | continue
80 | }
81 |
82 | const pkg = await registryFetch(name, version, corgi)
83 |
84 | const fixturePath = `${fixtureName}${corgi ? '.manifest' : ''}.ts`
85 | const tsType = `${corgi ? 'Manifest' : 'Packument'}${version ? 'Version' : ''}`
86 | fixtures[fixturePath] = `${tsType} = ${JSON.stringify(
87 | pkg,
88 | function (k: string, v: unknown) {
89 | return (!Array.isArray(v) && v && typeof v === 'object') ?
90 | Object.fromEntries(
91 | Object.entries(v).sort(([a], [b]) => a.localeCompare(b))
92 | ) : v
93 | },
94 | 2)}`
95 | }
96 | }
97 |
98 | return fixtures
99 | }
100 |
101 | // Note: We could use `pacote` or `npm-registry-fetch` here, but this package is
102 | // intended to document the types returned by registry requests. Fetching URLs
103 | // directly here insures there's no manipulation of the data between the
104 | // registry and the fixture.
105 | async function registryFetch (name: string, version?: string, corgi?: boolean) {
106 | const res = await fetch(`${REGISTRY}/${name}${version ? `/${version}` : ''}`, {
107 | headers: corgi ? { Accept: 'application/vnd.npm.install-v1+json' } : {},
108 | })
109 |
110 | if (!res.ok) {
111 | throw new Error(`Fetch failed: ${res.url} (status: ${res.status})`)
112 | }
113 |
114 | return res.json()
115 | }
116 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "esModuleInterop": true,
4 | "forceConsistentCasingInFileNames": true,
5 | "inlineSources": true,
6 | "module": "NodeNext",
7 | "moduleResolution": "nodenext",
8 | "sourceMap": true,
9 | "strict": true,
10 | "target": "es2022",
11 | "noEmit": true
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/types/index.d.ts:
--------------------------------------------------------------------------------
1 | // https://docs.npmjs.com/cli/v10/configuring-npm/package-json#people-fields-author-contributors
2 | interface Contact {
3 | email?: string
4 | url?: string
5 | name: string
6 | }
7 |
8 | interface Signature {
9 | keyid: string
10 | sig: string
11 | }
12 |
13 | // https://docs.npmjs.com/cli/v10/configuring-npm/package-json#repository
14 | interface Repository {
15 | directory?: string
16 | type?: string
17 | url: string
18 | }
19 |
20 | // https://docs.npmjs.com/cli/v10/configuring-npm/package-json#funding
21 | interface Funding {
22 | type: string
23 | url: string
24 | }
25 |
26 | // https://docs.npmjs.com/cli/v10/configuring-npm/package-json#overrides
27 | interface Overrides {
28 | [moduleName: string]: string | Overrides
29 | }
30 |
31 | // https://docs.npmjs.com/cli/v10/configuring-npm/package-json#peerdependenciesmeta
32 | interface PeerDependencyMeta {
33 | optional: boolean
34 | }
35 |
36 | // https://docs.npmjs.com/cli/v10/configuring-npm/package-json#license
37 | interface DeprecatedLicense {
38 | type: string
39 | url: string
40 | }
41 |
42 | /**
43 | * Dists are properties of Packument.versions
44 | * they have all the info you need to download and validate the tarball
45 | */
46 | interface Dist {
47 | // deprecated? (ref: found in uuid@0.0.2)
48 | bin?: Record
49 |
50 | /**
51 | * the number of files in the tarball. this is on most packages published >= 2018
52 | */
53 | fileCount?: number
54 |
55 | /**
56 | * subresource integrity string! `npm view ssri`
57 | * https://w3c.github.io/webappsec-subresource-integrity/
58 | */
59 | integrity?: string
60 |
61 | /**
62 | * PGP signature for the tarball
63 | */
64 | 'npm-signature'?: string
65 |
66 | /**
67 | * the sha1 sum of the tarball
68 | */
69 | shasum: string
70 |
71 | /**
72 | * Out-of-date blog post about this, below. (Says this is "npm-signature", but
73 | * that's not what the registry provides).
74 | * https://blog.npmjs.org/post/172999548390/new-pgp-machinery
75 | */
76 | signatures: Signature[]
77 |
78 | /**
79 | * the url to the tarball for the package version
80 | */
81 | tarball: string
82 |
83 | /**
84 | * the unpacked size of the files in the tarball. >= 2018
85 | */
86 | unpackedSize?: number
87 | }
88 |
89 | interface DevEngineDependency {
90 | name: string
91 | version?: string
92 | onFail?: 'ignore' | 'warn' | 'error' | 'download'
93 | }
94 |
95 | interface DevEngines {
96 | os?: DevEngineDependency | DevEngineDependency[]
97 | cpu?: DevEngineDependency | DevEngineDependency[]
98 | libc?: DevEngineDependency | DevEngineDependency[]
99 | runtime?: DevEngineDependency | DevEngineDependency[]
100 | packageManager?: DevEngineDependency | DevEngineDependency[]
101 | }
102 |
103 | // this is in the tarball for the project. it really could have anything in it.
104 | export interface PackageJSON {
105 | author?: Contact | string
106 | bin?: Record
107 | browser?: Record | string
108 | bugs?: Omit | string
109 | bundledDependencies?: string[] | boolean
110 | bundleDependencies?: string[] | boolean
111 | config?: Record
112 | contributors?: (Contact | string)[]
113 | cpu?: string[]
114 | dependencies?: Record
115 | description?: string
116 | devDependencies?: Record
117 | devEngines?: DevEngines
118 | directories?: Record
119 | engines?: Record
120 | files?: string[]
121 | funding?: Funding | string | (Funding | string)[]
122 | homepage?: string
123 | keywords?: string[]
124 | license?: string
125 | licenses?: DeprecatedLicense | DeprecatedLicense[]
126 | main?: string
127 | man?: string | string[]
128 | name: string
129 | optionalDependencies?: Record
130 | os?: string[]
131 | overrides?: Overrides
132 | peerDependencies?: Record
133 | peerDependenciesMeta?: Record
134 | private?: boolean
135 | publishConfig?: Record
136 | repository?: Repository | string
137 | scripts?: Record
138 | // https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html#editing-the-packagejson
139 | types?: string
140 | version: string
141 | workspaces?: string[] | Record
142 |
143 | [field: string]: unknown
144 | }
145 |
146 | // Note: Contacts (bugs, author, contributors, repository, etc) can be simple
147 | // strings in package.json, but not in registry metadata.
148 |
149 | export interface PackumentVersion extends PackageJSON {
150 | _hasShrinkwrap?: boolean
151 | _id: string
152 | _nodeVersion?: string // optional (ref: not defined in uuid@1.4.0)
153 | _npmUser?: Contact
154 | _npmVersion: string
155 | author?: Contact
156 | browser?: string | Record // ref: Record type found in uuid@1.4.1 et al
157 | bugs?: Omit
158 | contributors?: Contact[]
159 | deprecated?: string
160 | dist: Dist
161 | gitHead?: string
162 | maintainers?: Contact[]
163 | readme?: string
164 | readmeFilename?: string
165 | repository?: Repository
166 | }
167 |
168 | // this is what you get from the npm api.
169 | export type Packument = {
170 | _cached?: boolean
171 | _id: string
172 | _rev: string
173 | 'dist-tags': { latest?: string } & Record
174 | time: { modified: string; created: string } & Record
175 | users?: Record
176 | versions: Record
177 |
178 | // these fields are hoisted from the latest PackumentVersion
179 | } & Pick<
180 | PackumentVersion,
181 | | 'author'
182 | | 'bugs'
183 | | 'contributors'
184 | | 'description'
185 | | 'homepage'
186 | | 'keywords'
187 | | 'license'
188 | | 'maintainers'
189 | | 'name'
190 | | 'readme'
191 | | 'readmeFilename'
192 | | 'repository'
193 | >
194 |
195 | export type ManifestVersion = Pick<
196 | PackumentVersion,
197 | | '_hasShrinkwrap'
198 | | 'bin'
199 | | 'bundleDependencies'
200 | | 'bundledDependencies'
201 | | 'dependencies'
202 | | 'deprecated'
203 | | 'devDependencies'
204 | | 'directories'
205 | | 'dist'
206 | | 'engines'
207 | | 'name'
208 | | 'optionalDependencies'
209 | | 'peerDependencies'
210 | | 'version'
211 | >
212 |
213 | /**
214 | * abbreviated metadata format (aka corgi)
215 | *
216 | * https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md#abbreviated-metadata-format
217 | * returned from registry requests with accept header values conianing
218 | * `application/vnd.npm.install-v1+json`
219 | */
220 | export type Manifest = {
221 | modified: string
222 | versions: Record
223 | } & Pick
224 |
--------------------------------------------------------------------------------