Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

publish semver checking bugfixes #8038

Merged
merged 4 commits into from
Jan 17, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion lib/base-cmd.js
Original file line number Diff line number Diff line change
@@ -124,7 +124,6 @@ class BaseCommand {
} else if (!this.npm.config.isDefault('expect-result-count')) {
const expected = this.npm.config.get('expect-result-count')
if (expected !== entries) {
/* eslint-disable-next-line max-len */
log.warn(this.name, `Expected ${expected} result${expected === 1 ? '' : 's'}, got ${entries}`)
process.exitCode = 1
}
2 changes: 0 additions & 2 deletions lib/cli/entry.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
/* eslint-disable max-len */

// Separated out for easier unit testing
module.exports = async (process, validateEngines) => {
// set it here so that regardless of what happens later, we don't
2 changes: 0 additions & 2 deletions lib/cli/validate-engines.js
Original file line number Diff line number Diff line change
@@ -11,10 +11,8 @@ const npm = `v${version}`
module.exports = (process, getCli) => {
const node = process.version

/* eslint-disable-next-line max-len */
const unsupportedMessage = `npm ${npm} does not support Node.js ${node}. This version of npm supports the following node versions: \`${engines}\`. You can find the latest version at https://nodejs.org/.`

/* eslint-disable-next-line max-len */
const brokenMessage = `ERROR: npm ${npm} is known not to run on Node.js ${node}. This version of npm supports the following node versions: \`${engines}\`. You can find the latest version at https://nodejs.org/.`

// coverage ignored because this is only hit in very unsupported node versions
2 changes: 0 additions & 2 deletions lib/commands/cache.js
Original file line number Diff line number Diff line change
@@ -10,7 +10,6 @@ const localeCompare = require('@isaacs/string-locale-compare')('en')
const { log, output } = require('proc-log')

const searchCachePackage = async (path, parsed, cacheKeys) => {
/* eslint-disable-next-line max-len */
const searchMFH = new RegExp(`^make-fetch-happen:request-cache:.*(?<!/[@a-zA-Z]+)/${parsed.name}/-/(${parsed.name}[^/]+.tgz)$`)
const searchPack = new RegExp(`^make-fetch-happen:request-cache:.*/${parsed.escapedName}$`)
const results = new Set()
@@ -181,7 +180,6 @@ class Cache extends BaseCommand {
output.standard(`Corrupted content removed: ${stats.badContentCount}`)
}
if (stats.reclaimedCount) {
/* eslint-disable-next-line max-len */
output.standard(`Content garbage-collected: ${stats.reclaimedCount} (${stats.reclaimedSize} bytes)`)
}
if (stats.missingContent) {
1 change: 0 additions & 1 deletion lib/commands/doctor.js
Original file line number Diff line number Diff line change
@@ -128,7 +128,6 @@ class Doctor extends BaseCommand {

if (!allOk) {
if (this.npm.silent) {
/* eslint-disable-next-line max-len */
throw new Error('Some problems found. Check logs or disable silent mode for recommendations.')
} else {
throw new Error('Some problems found. See above for recommendations.')
1 change: 0 additions & 1 deletion lib/commands/install.js
Original file line number Diff line number Diff line change
@@ -115,7 +115,6 @@ class Install extends ArboristWorkspaceCmd {
if (forced) {
log.warn(
'install',
/* eslint-disable-next-line max-len */
`Forcing global npm install with incompatible version ${npmManifest.version} into node ${process.version}`
)
} else {
1 change: 0 additions & 1 deletion lib/commands/org.js
Original file line number Diff line number Diff line change
@@ -61,7 +61,6 @@ class Org extends BaseCommand {

if (!['owner', 'admin', 'developer'].find(x => x === role)) {
throw new Error(
/* eslint-disable-next-line max-len */
'Third argument `role` must be one of `owner`, `admin`, or `developer`, with `developer` being the default value if omitted.'
)
}
14 changes: 7 additions & 7 deletions lib/commands/publish.js
Original file line number Diff line number Diff line change
@@ -61,7 +61,6 @@ class Publish extends BaseCommand {
if (err.code !== 'EPRIVATE') {
throw err
}
// eslint-disable-next-line max-len
log.warn('publish', `Skipping workspace ${this.npm.chalk.cyan(name)}, marked as ${this.npm.chalk.bold('private')}`)
}
}
@@ -117,7 +116,7 @@ class Publish extends BaseCommand {
manifest = await this.#getManifest(spec, opts, true)

const isPreRelease = Boolean(semver.parse(manifest.version).prerelease.length)
const isDefaultTag = this.npm.config.isDefault('tag')
const isDefaultTag = this.npm.config.isDefault('tag') && !manifest.publishConfig?.tag

if (isPreRelease && isDefaultTag) {
throw new Error('You must specify a tag using --tag when publishing a prerelease version.')
@@ -157,11 +156,10 @@ class Publish extends BaseCommand {
}
}

const latestVersion = await this.#latestPublishedVersion(resolved, registry)
const latestVersion = await this.#highestPublishedVersion(resolved, registry)
const latestSemverIsGreater = !!latestVersion && semver.gte(latestVersion, manifest.version)

if (latestSemverIsGreater && isDefaultTag) {
/* eslint-disable-next-line max-len */
throw new Error(`Cannot implicitly apply the "latest" tag because published version ${latestVersion} is higher than the new version ${manifest.version}. You must specify a tag using --tag.`)
}

@@ -204,7 +202,7 @@ class Publish extends BaseCommand {
}
}

async #latestPublishedVersion (spec, registry) {
async #highestPublishedVersion (spec, registry) {
try {
const packument = await pacote.packument(spec, {
...this.npm.flatOptions,
@@ -217,7 +215,10 @@ class Publish extends BaseCommand {
const ordered = Object.keys(packument?.versions)
.flatMap(v => {
const s = new semver.SemVer(v)
return s.prerelease.length > 0 ? [] : s
if ((s.prerelease.length > 0) || packument.versions[v].deprecated) {
return []
}
return s
})
.sort((a, b) => b.compare(a))
return ordered.length >= 1 ? ordered[0].version : null
@@ -235,7 +236,6 @@ class Publish extends BaseCommand {
const changes = []
const pkg = await pkgJson.fix(spec.fetchSpec, { changes })
if (changes.length && logWarnings) {
/* eslint-disable-next-line max-len */
log.warn('publish', 'npm auto-corrected some errors in your package.json when publishing. Please run "npm pkg fix" to address these errors.')
log.warn('publish', `errors corrected:\n${changes.join('\n')}`)
}
2 changes: 0 additions & 2 deletions lib/commands/sbom.js
Original file line number Diff line number Diff line change
@@ -27,7 +27,6 @@ class SBOM extends BaseCommand {
const packageLockOnly = this.npm.config.get('package-lock-only')

if (!sbomFormat) {
/* eslint-disable-next-line max-len */
throw this.usageError(`Must specify --sbom-format flag with one of: ${SBOM_FORMATS.join(', ')}.`)
}

@@ -40,7 +39,6 @@ class SBOM extends BaseCommand {
const arb = new Arborist(opts)

const tree = packageLockOnly ? await arb.loadVirtual(opts).catch(() => {
/* eslint-disable-next-line max-len */
throw this.usageError('A package lock or shrinkwrap file is required in package-lock-only mode')
}) : await arb.loadActual(opts)

2 changes: 0 additions & 2 deletions lib/commands/token.js
Original file line number Diff line number Diff line change
@@ -73,7 +73,6 @@ class Token extends BaseCommand {
for (const token of tokens) {
const level = token.readonly ? 'Read only token' : 'Publish token'
const created = String(token.created).slice(0, 10)
/* eslint-disable-next-line max-len */
output.standard(`${chalk.blue(level)} ${token.token}… with id ${chalk.cyan(token.id)} created ${created}`)
if (token.cidr_whitelist) {
output.standard(`with IP whitelist: ${chalk.green(token.cidr_whitelist.join(','))}`)
@@ -99,7 +98,6 @@ class Token extends BaseCommand {
toRemove.push(matches[0].key)
} else if (matches.length > 1) {
throw new Error(
/* eslint-disable-next-line max-len */
`Token ID "${id}" was ambiguous, a new token may have been created since you last ran \`npm token list\`.`
)
} else {
1 change: 0 additions & 1 deletion lib/commands/version.js
Original file line number Diff line number Diff line change
@@ -22,7 +22,6 @@ class Version extends BaseCommand {
static workspaces = true
static ignoreImplicitWorkspace = false

/* eslint-disable-next-line max-len */
static usage = ['[<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]']

static async completion (opts) {
1 change: 0 additions & 1 deletion lib/utils/did-you-mean.js
Original file line number Diff line number Diff line change
@@ -19,7 +19,6 @@ const didYouMean = (pkg, scmd) => {
.map(str => [`run ${str}`, `run the "${str}" package script`]),
...Object.keys(bin)
.filter(cmd => isClose(scmd, cmd))
/* eslint-disable-next-line max-len */
.map(str => [`exec ${str}`, `run the "${str}" command from either this or a remote npm package`]),
]

6 changes: 4 additions & 2 deletions lib/utils/format-search-stream.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable max-len */
const { stripVTControlCharacters: strip } = require('node:util')
const { Minipass } = require('minipass')

@@ -83,7 +82,10 @@ class TextOutputStream extends Minipass {
constructor (opts) {
super()
// Consider a search for "cowboys" and "boy". If we highlight "boys" first the "cowboys" string will no longer string match because of the ansi highlighting added to "boys". If we highlight "boy" second then the ansi reset at the end will make the highlighting only on "cowboy" with a normal "s". Neither is perfect but at least the first option doesn't do partial highlighting. So, we sort strings smaller to larger
this.#args = opts.args.map(s => s.toLowerCase()).filter(Boolean).sort((a, b) => a.length - b.length)
this.#args = opts.args
.map(s => s.toLowerCase())
.filter(Boolean)
.sort((a, b) => a.length - b.length)
this.#chalk = opts.npm.chalk
this.#exclude = opts.exclude
this.#parseable = opts.parseable
2 changes: 0 additions & 2 deletions lib/utils/reify-output.js
Original file line number Diff line number Diff line change
@@ -50,7 +50,6 @@ const reifyOutput = (npm, arb) => {
switch (d.action) {
case 'REMOVE':
if (showDiff) {
/* eslint-disable-next-line max-len */
output.standard(`${chalk.blue('remove')} ${d.actual.name} ${d.actual.package.version}`)
}
summary.removed++
@@ -63,7 +62,6 @@ const reifyOutput = (npm, arb) => {
break
case 'CHANGE':
if (showDiff) {
/* eslint-disable-next-line max-len */
output.standard(`${chalk.cyan('change')} ${d.actual.name} ${d.actual.package.version} => ${d.ideal.package.version}`)
}
summary.changed++
1 change: 0 additions & 1 deletion lib/utils/tar.js
Original file line number Diff line number Diff line change
@@ -36,7 +36,6 @@ const logTar = (tarball, { unicode = false, json, key } = {}) => {
log.notice('', `package size: ${formatBytes(tarball.size)}`)
log.notice('', `unpacked size: ${formatBytes(tarball.unpackedSize)}`)
log.notice('', `shasum: ${tarball.shasum}`)
/* eslint-disable-next-line max-len */
log.notice('', `integrity: ${tarball.integrity.toString().slice(0, 20)}[...]${tarball.integrity.toString().slice(80)}`)
if (tarball.bundled.length) {
log.notice('', `bundled deps: ${tarball.bundled.length}`)
10 changes: 0 additions & 10 deletions lib/utils/verify-signatures.js
Original file line number Diff line number Diff line change
@@ -75,21 +75,17 @@ class VerifySignatures {
const verifiedBold = this.npm.chalk.bold('verified')
if (this.verifiedSignatureCount) {
if (this.verifiedSignatureCount === 1) {
/* eslint-disable-next-line max-len */
output.standard(`${this.verifiedSignatureCount} package has a ${verifiedBold} registry signature`)
} else {
/* eslint-disable-next-line max-len */
output.standard(`${this.verifiedSignatureCount} packages have ${verifiedBold} registry signatures`)
}
output.standard('')
}

if (this.verifiedAttestationCount) {
if (this.verifiedAttestationCount === 1) {
/* eslint-disable-next-line max-len */
output.standard(`${this.verifiedAttestationCount} package has a ${verifiedBold} attestation`)
} else {
/* eslint-disable-next-line max-len */
output.standard(`${this.verifiedAttestationCount} packages have ${verifiedBold} attestations`)
}
output.standard('')
@@ -98,10 +94,8 @@ class VerifySignatures {
if (missing.length) {
const missingClr = this.npm.chalk.redBright('missing')
if (missing.length === 1) {
/* eslint-disable-next-line max-len */
output.standard(`1 package has a ${missingClr} registry signature but the registry is providing signing keys:`)
} else {
/* eslint-disable-next-line max-len */
output.standard(`${missing.length} packages have ${missingClr} registry signatures but the registry is providing signing keys:`)
}
output.standard('')
@@ -121,7 +115,6 @@ class VerifySignatures {
if (invalidSignatures.length === 1) {
output.standard(`1 package has an ${invalidClr} registry signature:`)
} else {
/* eslint-disable-next-line max-len */
output.standard(`${invalidSignatures.length} packages have ${invalidClr} registry signatures:`)
}
output.standard('')
@@ -136,7 +129,6 @@ class VerifySignatures {
if (invalidAttestations.length === 1) {
output.standard(`1 package has an ${invalidClr} attestation:`)
} else {
/* eslint-disable-next-line max-len */
output.standard(`${invalidAttestations.length} packages have ${invalidClr} attestations:`)
}
output.standard('')
@@ -147,10 +139,8 @@ class VerifySignatures {
}

if (invalid.length === 1) {
/* eslint-disable-next-line max-len */
output.standard(`Someone might have tampered with this package since it was published on the registry!`)
} else {
/* eslint-disable-next-line max-len */
output.standard(`Someone might have tampered with these packages since they were published on the registry!`)
}
output.standard('')
8 changes: 4 additions & 4 deletions package-lock.json
Original file line number Diff line number Diff line change
@@ -157,7 +157,7 @@
},
"devDependencies": {
"@npmcli/docs": "^1.0.0",
"@npmcli/eslint-config": "^5.0.1",
"@npmcli/eslint-config": "^5.1.0",
"@npmcli/git": "^6.0.1",
"@npmcli/mock-globals": "^1.0.0",
"@npmcli/mock-registry": "^1.0.0",
@@ -3411,9 +3411,9 @@
"link": true
},
"node_modules/@npmcli/eslint-config": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@npmcli/eslint-config/-/eslint-config-5.0.1.tgz",
"integrity": "sha512-S/YyfSAyiQWGzXBeX8D/Fe363628zXwraLVbRe080VdWn9FdT9ILVk55ATRpAXefa5JJwgsbMM5vA1V9tDrjqw==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@npmcli/eslint-config/-/eslint-config-5.1.0.tgz",
"integrity": "sha512-L4FAYndvARxkbTBNbsbDDkArIf8A8WmTFGVKdevJ3jd9nPzDKWiuC9TW0QtEnRsFHr5IX7G6qkRLK+drLIGoEA==",
"dev": true,
"license": "ISC",
"dependencies": {
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -188,7 +188,7 @@
],
"devDependencies": {
"@npmcli/docs": "^1.0.0",
"@npmcli/eslint-config": "^5.0.1",
"@npmcli/eslint-config": "^5.1.0",
"@npmcli/git": "^6.0.1",
"@npmcli/mock-globals": "^1.0.0",
"@npmcli/mock-registry": "^1.0.0",
6 changes: 3 additions & 3 deletions tap-snapshots/test/lib/commands/install.js.test.cjs
Original file line number Diff line number Diff line change
@@ -134,7 +134,7 @@ silly logfile done cleaning log files
verbose stack Error: The developer of this package has specified the following through devEngines
verbose stack Invalid engine "runtime"
verbose stack Invalid name "nondescript" does not match "node" for "runtime"
verbose stack at Install.checkDevEngines ({CWD}/lib/base-cmd.js:182:27)
verbose stack at Install.checkDevEngines ({CWD}/lib/base-cmd.js:181:27)
verbose stack at MockNpm.#exec ({CWD}/lib/npm.js:251:7)
verbose stack at MockNpm.exec ({CWD}/lib/npm.js:207:9)
error code EBADDEVENGINES
@@ -199,7 +199,7 @@ warn EBADDEVENGINES }
verbose stack Error: The developer of this package has specified the following through devEngines
verbose stack Invalid engine "runtime"
verbose stack Invalid name "nondescript" does not match "node" for "runtime"
verbose stack at Install.checkDevEngines ({CWD}/lib/base-cmd.js:182:27)
verbose stack at Install.checkDevEngines ({CWD}/lib/base-cmd.js:181:27)
verbose stack at MockNpm.#exec ({CWD}/lib/npm.js:251:7)
verbose stack at MockNpm.exec ({CWD}/lib/npm.js:207:9)
error code EBADDEVENGINES
@@ -225,7 +225,7 @@ silly logfile done cleaning log files
verbose stack Error: The developer of this package has specified the following through devEngines
verbose stack Invalid engine "runtime"
verbose stack Invalid name "nondescript" does not match "node" for "runtime"
verbose stack at Install.checkDevEngines ({CWD}/lib/base-cmd.js:182:27)
verbose stack at Install.checkDevEngines ({CWD}/lib/base-cmd.js:181:27)
verbose stack at MockNpm.#exec ({CWD}/lib/npm.js:251:7)
verbose stack at MockNpm.exec ({CWD}/lib/npm.js:207:9)
error code EBADDEVENGINES
28 changes: 14 additions & 14 deletions tap-snapshots/test/lib/commands/publish.js.test.cjs
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@
*/
'use strict'
exports[`test/lib/commands/publish.js TAP _auth config default registry > new package version 1`] = `
+ test-package@1.0.0
+ @npmcli/test-package@1.0.0
`

exports[`test/lib/commands/publish.js TAP bare _auth and registry config > new package version 1`] = `
@@ -15,15 +15,15 @@ exports[`test/lib/commands/publish.js TAP bare _auth and registry config > new p

exports[`test/lib/commands/publish.js TAP dry-run > must match snapshot 1`] = `
Array [
"package: test-package@1.0.0",
"package: @npmcli/test-package@1.0.0",
"Tarball Contents",
"87B package.json",
"95B package.json",
"Tarball Details",
"name: test-package",
"name: @npmcli/test-package",
"version: 1.0.0",
"filename: test-package-1.0.0.tgz",
"filename: npmcli-test-package-1.0.0.tgz",
"package size: {size}",
"unpacked size: 87 B",
"unpacked size: 95 B",
"shasum: {sha}",
"integrity: {integrity}
"total files: 1",
@@ -76,7 +76,7 @@ exports[`test/lib/commands/publish.js TAP has token auth for scope configured re
`

exports[`test/lib/commands/publish.js TAP ignore-scripts > new package version 1`] = `
+ test-package@1.0.0
+ @npmcli/test-package@1.0.0
`

exports[`test/lib/commands/publish.js TAP json > must match snapshot 1`] = `
@@ -87,14 +87,14 @@ Array [

exports[`test/lib/commands/publish.js TAP json > new package json 1`] = `
{
"id": "test-package@1.0.0",
"name": "test-package",
"id": "@npmcli/test-package@1.0.0",
"name": "@npmcli/test-package",
"version": "1.0.0",
"size": "{size}",
"unpackedSize": 87,
"unpackedSize": 95,
"shasum": "{sha}",
"integrity": "{integrity}",
"filename": "test-package-1.0.0.tgz",
"filename": "npmcli-test-package-1.0.0.tgz",
"files": [
{
"path": "package.json",
@@ -249,7 +249,7 @@ Object {
`

exports[`test/lib/commands/publish.js TAP no auth dry-run > must match snapshot 1`] = `
+ test-package@1.0.0
+ @npmcli/test-package@1.0.0
`

exports[`test/lib/commands/publish.js TAP no auth dry-run > warns about auth being needed 1`] = `
@@ -259,7 +259,7 @@ Array [
`

exports[`test/lib/commands/publish.js TAP prioritize CLI flags over publishConfig > new package version 1`] = `
+ test-package@1.0.0
+ @npmcli/test-package@1.0.0
`

exports[`test/lib/commands/publish.js TAP public access > must match snapshot 1`] = `
@@ -285,7 +285,7 @@ exports[`test/lib/commands/publish.js TAP public access > new package version 1`
`

exports[`test/lib/commands/publish.js TAP re-loads publishConfig.registry if added during script process > new package version 1`] = `
+ test-package@1.0.0
+ @npmcli/test-package@1.0.0
`

exports[`test/lib/commands/publish.js TAP respects publishConfig.registry, runs appropriate scripts > new package version 1`] = `
1 change: 0 additions & 1 deletion test/lib/cli/exit-handler.js
Original file line number Diff line number Diff line change
@@ -46,7 +46,6 @@ t.cleanSnapshot = (path) => cleanDate(cleanCwd(path))
mockGlobals(t, {
process: Object.assign(new EventEmitter(), {
// these are process properties that are needed in the running code and tests
// eslint-disable-next-line max-len
...pick(process, 'version', 'execPath', 'stdout', 'stderr', 'stdin', 'cwd', 'chdir', 'env', 'umask'),
pid: 123456,
argv: ['/node', ...process.argv.slice(1)],
1 change: 0 additions & 1 deletion test/lib/cli/validate-engines.js
Original file line number Diff line number Diff line change
@@ -23,7 +23,6 @@ t.test('validate engines', async t => {
node: 'v4.5.6',
npm: 'v1.2.3',
engines: '>=0',
/* eslint-disable-next-line max-len */
unsupportedMessage: 'npm v1.2.3 does not support Node.js v4.5.6. This version of npm supports the following node versions: `>=0`. You can find the latest version at https://nodejs.org/.',
})

6 changes: 0 additions & 6 deletions test/lib/commands/audit.js
Original file line number Diff line number Diff line change
@@ -825,12 +825,9 @@ t.test('audit signatures', async t => {
packuments: [{
version: '1.0.0',
dist: {
// eslint-disable-next-line max-len
integrity: 'sha512-e+qfbn/zf1+rCza/BhIA//Awmf0v1pa5HQS8Xk8iXrn9bgytytVLqYD0P7NSqZ6IELTgq+tcDvLPkQjNHyWLNg==',
tarball: 'https://registry.npmjs.org/sigstore/-/sigstore-1.0.0.tgz',
// eslint-disable-next-line max-len
attestations: { url: 'https://registry.npmjs.org/-/npm/v1/attestations/sigstore@1.0.0', provenance: { predicateType: 'https://slsa.dev/provenance/v0.2' } },
// eslint-disable-next-line max-len
signatures: [{ keyid: 'SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA', sig: 'MEQCIBlpcHT68iWOpx8pJr3WUzD1EqQ7tb0CmY36ebbceR6IAiAVGRaxrFoyh0/5B7H1o4VFhfsHw9F8G+AxOZQq87q+lg==' }],
},
}],
@@ -844,12 +841,9 @@ t.test('audit signatures', async t => {
packuments: [{
version: '1.0.0',
dist: {
// eslint-disable-next-line max-len
integrity: 'sha512-1dxsQwESDzACJjTdYHQ4wJ1f/of7jALWKfJEHSBWUQB/5UTJUx9SW6GHXp4mZ1KvdBRJCpGjssoPFGi4hvw8/A==',
tarball: 'https://registry.npmjs.org/tuf-js/-/tuf-js-1.0.0.tgz',
// eslint-disable-next-line max-len
attestations: { url: 'https://registry.npmjs.org/-/npm/v1/attestations/tuf-js@1.0.0', provenance: { predicateType: 'https://slsa.dev/provenance/v0.2' } },
// eslint-disable-next-line max-len
signatures: [{ keyid: 'SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA', sig: 'MEYCIQDgGQeY2QLkLuoO9YxOqFZ+a6zYuaZpXhc77kUfdCUXDQIhAJp/vV+9Xg1bfM5YlTvKIH9agUEOu5T76+tQaHY2vZyO' }],
},
}],
14 changes: 0 additions & 14 deletions test/lib/commands/cache.js
Original file line number Diff line number Diff line change
@@ -78,9 +78,7 @@ t.test('cache add single pkg', async t => {
})
await npm.exec('cache', ['add', pkg])
t.equal(joinedOutput(), '')
// eslint-disable-next-line max-len
t.resolves(cacache.get(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package/-/test-package-1.0.0.tgz'))
// eslint-disable-next-line max-len
t.resolves(cacache.get(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package'))
})

@@ -113,20 +111,15 @@ t.test('cache add multiple pkgs', async t => {
})
await npm.exec('cache', ['add', pkg, pkg2])
t.equal(joinedOutput(), '')
// eslint-disable-next-line max-len
t.resolves(cacache.get(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package/-/test-package-1.0.0.tgz'))
// eslint-disable-next-line max-len
t.resolves(cacache.get(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package'))
// eslint-disable-next-line max-len
t.resolves(cacache.get(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package-two/-/test-package-two-1.0.0.tgz'))
// eslint-disable-next-line max-len
t.resolves(cacache.get(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package-two'))
})

t.test('cache ls', async t => {
const keys = [
'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package',
// eslint-disable-next-line max-len
'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package/-/test-package-1.0.0.tgz',
]
const { npm, joinedOutput } = await loadMockNpm(t)
@@ -204,10 +197,8 @@ t.test('cache ls tagged', async t => {

t.test('cache ls scoped and scoped slash', async t => {
const keys = [
// eslint-disable-next-line max-len
'make-fetch-happen:request-cache:https://registry.npmjs.org/@fritzy/staydown/-/@fritzy/staydown-3.1.1.tgz',
'make-fetch-happen:request-cache:https://registry.npmjs.org/@fritzy%2fstaydown',
// eslint-disable-next-line max-len
'make-fetch-happen:request-cache:https://registry.npmjs.org/@gar/npm-expansion/-/@gar/npm-expansion-2.1.0.tgz',
'make-fetch-happen:request-cache:https://registry.npmjs.org/@gar%2fnpm-expansion',
]
@@ -248,16 +239,11 @@ t.test('cache ls missing packument version not an object', async t => {
t.test('cache rm', async t => {
const { npm, joinedOutput } = await loadMockNpm(t)
const cache = path.join(npm.cache, '_cacache')
// eslint-disable-next-line max-len
await cacache.put(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package', '{}')
// eslint-disable-next-line max-len
await cacache.put(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package/-/test-package-1.0.0.tgz', 'test data')
// eslint-disable-next-line max-len
await npm.exec('cache', ['rm', 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package/-/test-package-1.0.0.tgz'])
t.matchSnapshot(joinedOutput(), 'logs deleting single entry')
// eslint-disable-next-line max-len
t.resolves(cacache.get(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package'))
// eslint-disable-next-line max-len
t.rejects(cacache.get(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package/-/test-package-1.0.0.tgz'))
})

2 changes: 0 additions & 2 deletions test/lib/commands/help-search.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const t = require('tap')
const { load: loadMockNpm } = require('../../fixtures/mock-npm.js')

/* eslint-disable max-len */
const docsFixtures = {
dir1: {
'npm-exec.md': 'the exec command\nhelp has multiple lines of exec help\none of them references exec',
@@ -19,7 +18,6 @@ const docsFixtures = {
'npm-extra-useless.md': 'exec\nexec\nexec',
},
}
/* eslint-enable max-len */

const execHelpSearch = async (t, exec = [], opts) => {
const { npm, ...rest } = await loadMockNpm(t, {
40 changes: 0 additions & 40 deletions test/lib/commands/ls.js
Original file line number Diff line number Diff line change
@@ -408,7 +408,6 @@ t.test('ls', async t => {
await ls.exec(['dog@*', 'chai@1.0.0'])
t.matchSnapshot(
cleanCwd(result()),
/* eslint-disable-next-line max-len */
'should output tree contaning only occurrences of multiple filtered packages and their ancestors'
)
})
@@ -1314,7 +1313,6 @@ t.test('ls', async t => {
name: 'abbrev',
version: '1.1.1',
from: 'git+https://github.com/isaacs/abbrev-js.git',
/* eslint-disable-next-line max-len */
resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
},
},
@@ -1325,7 +1323,6 @@ t.test('ls', async t => {
version: '1.1.1',
_id: 'abbrev@1.1.1',
_from: 'git+https://github.com/isaacs/abbrev-js.git',
/* eslint-disable-next-line max-len */
_resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
_requested: {
type: 'git',
@@ -1372,7 +1369,6 @@ t.test('ls', async t => {
a: {
version: '1.0.1',
resolved: 'foo@dog://b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
/* eslint-disable-next-line max-len */
integrity: 'sha512-8AN9lNCcBt5Xeje7fMEEpp5K3rgcAzIpTtAjYb/YMUYu8SbIVF6wz0WqACDVKvpQOUcSfNHZQNLNmue0QSwXOQ==',
},
},
@@ -1901,7 +1897,6 @@ t.test('ls --parseable', async t => {
await ls.exec(['dog@*', 'chai@1.0.0'])
t.matchSnapshot(
cleanCwd(result()),
/* eslint-disable-next-line max-len */
'should output parseable contaning only occurrences of multiple filtered packages and their ancestors'
)
})
@@ -2465,7 +2460,6 @@ t.test('ls --parseable', async t => {
'node_modules/abbrev': {
name: 'abbrev',
version: '1.1.1',
/* eslint-disable-next-line max-len */
resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
},
},
@@ -2476,7 +2470,6 @@ t.test('ls --parseable', async t => {
version: '1.1.1',
_id: 'abbrev@1.1.1',
_from: 'git+https://github.com/isaacs/abbrev-js.git',
/* eslint-disable-next-line max-len */
_resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
_requested: {
type: 'git',
@@ -3043,7 +3036,6 @@ t.test('ls --json', async t => {
},
},
},
/* eslint-disable-next-line max-len */
'should output json contaning only occurrences of multiple filtered packages and their ancestors'
)
})
@@ -3489,9 +3481,7 @@ t.test('ls --json', async t => {
'node_modules/@isaacs/dedupe-tests-a': {
name: '@isaacs/dedupe-tests-a',
version: '1.0.1',
/* eslint-disable-next-line max-len */
resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-a/-/dedupe-tests-a-1.0.1.tgz',
/* eslint-disable-next-line max-len */
integrity: 'sha512-8AN9lNCcBt5Xeje7fMEEpp5K3rgcAzIpTtAjYb/YMUYu8SbIVF6wz0WqACDVKvpQOUcSfNHZQNLNmue0QSwXOQ==',
dependencies: {
'@isaacs/dedupe-tests-b': '1',
@@ -3500,45 +3490,35 @@ t.test('ls --json', async t => {
'node_modules/@isaacs/dedupe-tests-a/node_modules/@isaacs/dedupe-tests-b': {
name: '@isaacs/dedupe-tests-b',
version: '1.0.0',
/* eslint-disable-next-line max-len */
resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-1.0.0.tgz',
/* eslint-disable-next-line max-len */
integrity: 'sha512-3nmvzIb8QL8OXODzipwoV3U8h9OQD9g9RwOPuSBQqjqSg9JZR1CCFOWNsDUtOfmwY8HFUJV9EAZ124uhqVxq+w==',
},
'node_modules/@isaacs/dedupe-tests-b': {
name: '@isaacs/dedupe-tests-b',
version: '2.0.0',
/* eslint-disable-next-line max-len */
resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-2.0.0.tgz',
/* eslint-disable-next-line max-len */
integrity: 'sha512-KTYkpRv9EzlmCg4Gsm/jpclWmRYFCXow8GZKJXjK08sIZBlElTZEa5Bw/UQxIvEfcKmWXczSqItD49Kr8Ax4UA==',
},
},
dependencies: {
'@isaacs/dedupe-tests-a': {
version: '1.0.1',
/* eslint-disable-next-line max-len */
resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-a/-/dedupe-tests-a-1.0.1.tgz',
/* eslint-disable-next-line max-len */
integrity: 'sha512-8AN9lNCcBt5Xeje7fMEEpp5K3rgcAzIpTtAjYb/YMUYu8SbIVF6wz0WqACDVKvpQOUcSfNHZQNLNmue0QSwXOQ==',
requires: {
'@isaacs/dedupe-tests-b': '1',
},
dependencies: {
'@isaacs/dedupe-tests-b': {
version: '1.0.0',
/* eslint-disable-next-line max-len */
resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-1.0.0.tgz',
/* eslint-disable-next-line max-len */
integrity: 'sha512-3nmvzIb8QL8OXODzipwoV3U8h9OQD9g9RwOPuSBQqjqSg9JZR1CCFOWNsDUtOfmwY8HFUJV9EAZ124uhqVxq+w==',
},
},
},
'@isaacs/dedupe-tests-b': {
version: '2.0.0',
/* eslint-disable-next-line max-len */
resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-2.0.0.tgz',
/* eslint-disable-next-line max-len */
integrity: 'sha512-KTYkpRv9EzlmCg4Gsm/jpclWmRYFCXow8GZKJXjK08sIZBlElTZEa5Bw/UQxIvEfcKmWXczSqItD49Kr8Ax4UA==',
},
},
@@ -3572,7 +3552,6 @@ t.test('ls --json', async t => {
extraneous: true,
overridden: false,
problems: [
/* eslint-disable-next-line max-len */
'extraneous: @isaacs/dedupe-tests-b@ {CWD}/prefix/node_modules/@isaacs/dedupe-tests-a/node_modules/@isaacs/dedupe-tests-b',
],
},
@@ -3586,7 +3565,6 @@ t.test('ls --json', async t => {
},
},
problems: [
/* eslint-disable-next-line max-len */
'extraneous: @isaacs/dedupe-tests-b@ {CWD}/prefix/node_modules/@isaacs/dedupe-tests-a/node_modules/@isaacs/dedupe-tests-b',
],
},
@@ -4212,7 +4190,6 @@ t.test('ls --json', async t => {
version: '1.1.1',
id: 'abbrev@1.1.1',
from: 'git+https://github.com/isaacs/abbrev-js.git',
/* eslint-disable-next-line max-len */
resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
},
},
@@ -4223,7 +4200,6 @@ t.test('ls --json', async t => {
version: '1.1.1',
_id: 'abbrev@1.1.1',
_from: 'git+https://github.com/isaacs/abbrev-js.git',
/* eslint-disable-next-line max-len */
_resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
_requested: {
type: 'git',
@@ -4249,7 +4225,6 @@ t.test('ls --json', async t => {
abbrev: {
version: '1.1.1',
overridden: false,
/* eslint-disable-next-line max-len */
resolved: 'git+ssh://git@github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
},
},
@@ -4813,7 +4788,6 @@ t.test('ls --package-lock-only', async t => {
},
},
},
/* eslint-disable-next-line max-len */
'should output json contaning only occurrences of multiple filtered packages and their ancestors'
)
})
@@ -5137,9 +5111,7 @@ t.test('ls --package-lock-only', async t => {
'node_modules/@isaacs/dedupe-tests-a': {
name: '@isaacs/dedupe-tests-a',
version: '1.0.1',
/* eslint-disable-next-line max-len */
resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-a/-/dedupe-tests-a-1.0.1.tgz',
/* eslint-disable-next-line max-len */
integrity: 'sha512-8AN9lNCcBt5Xeje7fMEEpp5K3rgcAzIpTtAjYb/YMUYu8SbIVF6wz0WqACDVKvpQOUcSfNHZQNLNmue0QSwXOQ==',
dependencies: {
'@isaacs/dedupe-tests-b': '1',
@@ -5148,45 +5120,35 @@ t.test('ls --package-lock-only', async t => {
'node_modules/@isaacs/dedupe-tests-a/node_modules/@isaacs/dedupe-tests-b': {
name: '@isaacs/dedupe-tests-b',
version: '1.0.0',
/* eslint-disable-next-line max-len */
resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-1.0.0.tgz',
/* eslint-disable-next-line max-len */
integrity: 'sha512-3nmvzIb8QL8OXODzipwoV3U8h9OQD9g9RwOPuSBQqjqSg9JZR1CCFOWNsDUtOfmwY8HFUJV9EAZ124uhqVxq+w==',
},
'node_modules/@isaacs/dedupe-tests-b': {
name: '@isaacs/dedupe-tests-b',
version: '2.0.0',
/* eslint-disable-next-line max-len */
resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-2.0.0.tgz',
/* eslint-disable-next-line max-len */
integrity: 'sha512-KTYkpRv9EzlmCg4Gsm/jpclWmRYFCXow8GZKJXjK08sIZBlElTZEa5Bw/UQxIvEfcKmWXczSqItD49Kr8Ax4UA==',
},
},
dependencies: {
'@isaacs/dedupe-tests-a': {
version: '1.0.1',
/* eslint-disable-next-line max-len */
resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-a/-/dedupe-tests-a-1.0.1.tgz',
/* eslint-disable-next-line max-len */
integrity: 'sha512-8AN9lNCcBt5Xeje7fMEEpp5K3rgcAzIpTtAjYb/YMUYu8SbIVF6wz0WqACDVKvpQOUcSfNHZQNLNmue0QSwXOQ==',
requires: {
'@isaacs/dedupe-tests-b': '1',
},
dependencies: {
'@isaacs/dedupe-tests-b': {
version: '1.0.0',
/* eslint-disable-next-line max-len */
resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-1.0.0.tgz',
/* eslint-disable-next-line max-len */
integrity: 'sha512-3nmvzIb8QL8OXODzipwoV3U8h9OQD9g9RwOPuSBQqjqSg9JZR1CCFOWNsDUtOfmwY8HFUJV9EAZ124uhqVxq+w==',
},
},
},
'@isaacs/dedupe-tests-b': {
version: '2.0.0',
/* eslint-disable-next-line max-len */
resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-2.0.0.tgz',
/* eslint-disable-next-line max-len */
integrity: 'sha512-KTYkpRv9EzlmCg4Gsm/jpclWmRYFCXow8GZKJXjK08sIZBlElTZEa5Bw/UQxIvEfcKmWXczSqItD49Kr8Ax4UA==',
},
},
@@ -5298,7 +5260,6 @@ t.test('ls --package-lock-only', async t => {
requires: true,
dependencies: {
abbrev: {
/* eslint-disable-next-line max-len */
version: 'git+ssh://git@github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
from: 'abbrev@git+https://github.com/isaacs/abbrev-js.git',
},
@@ -5314,7 +5275,6 @@ t.test('ls --package-lock-only', async t => {
version: '1.0.0',
dependencies: {
abbrev: {
/* eslint-disable-next-line max-len */
resolved: 'git+ssh://git@github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
overridden: false,
},
46 changes: 29 additions & 17 deletions test/lib/commands/publish.js
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ const Arborist = require('@npmcli/arborist')
const path = require('node:path')
const fs = require('node:fs')

const pkg = 'test-package'
const pkg = '@npmcli/test-package'
const token = 'test-auth-token'
const auth = { '//registry.npmjs.org/:_authToken': token }
const alternateRegistry = 'https://other.registry.npmjs.org'
@@ -238,8 +238,7 @@ t.test('throws when invalid tag when not url encodable', async t => {
await t.rejects(
npm.exec('publish', []),
{
/* eslint-disable-next-line max-len */
message: 'Invalid tag name "@test" of package "test-package@@test": Tags may not have any characters that encodeURIComponent encodes.',
message: `Invalid tag name "@test" of package "${pkg}@@test": Tags may not have any characters that encodeURIComponent encodes.`,
}
)
})
@@ -857,15 +856,16 @@ t.test('prerelease dist tag', (t) => {
t.end()
})

t.test('latest dist tag', (t) => {
const init = (version) => ({
t.test('semver highest dist tag', async t => {
const init = ({ version, pkgExtra = {} }) => ({
config: {
loglevel: 'silent',
...auth,
},
prefixDir: {
'package.json': JSON.stringify({
...pkgJson,
...pkgExtra,
version,
}, null, 2),
},
@@ -876,49 +876,61 @@ t.test('latest dist tag', (t) => {
// this needs more than one item in it to cover the sort logic
{ version: '50.0.0' },
{ version: '100.0.0' },
{ version: '102.0.0', deprecated: 'oops' },
{ version: '105.0.0-pre' },
]

t.test('PREVENTS publish when latest version is HIGHER than publishing version', async t => {
await t.test('PREVENTS publish when highest version is HIGHER than publishing version', async t => {
const version = '99.0.0'
const { npm, registry } = await loadNpmWithRegistry(t, init(version))
const { npm, registry } = await loadNpmWithRegistry(t, init({ version }))
registry.publish(pkg, { noPut: true, packuments })
await t.rejects(async () => {
await npm.exec('publish', [])
/* eslint-disable-next-line max-len */
}, new Error('Cannot implicitly apply the "latest" tag because published version 100.0.0 is higher than the new version 99.0.0. You must specify a tag using --tag.'))
})

t.test('ALLOWS publish when latest is HIGHER than publishing version and flag', async t => {
await t.test('ALLOWS publish when highest is HIGHER than publishing version and flag', async t => {
const version = '99.0.0'
const { npm, registry } = await loadNpmWithRegistry(t, {
...init(version),
...init({ version }),
argv: ['--tag', 'latest'],
})
registry.publish(pkg, { packuments })
await npm.exec('publish', [])
})

t.test('ALLOWS publish when latest versions are LOWER than publishing version', async t => {
await t.test('ALLOWS publish when highest versions are LOWER than publishing version', async t => {
const version = '101.0.0'
const { npm, registry } = await loadNpmWithRegistry(t, init(version))
const { npm, registry } = await loadNpmWithRegistry(t, init({ version }))
registry.publish(pkg, { packuments })
await npm.exec('publish', [])
})

t.test('ALLOWS publish when packument has empty versions (for coverage)', async t => {
await t.test('ALLOWS publish when packument has empty versions (for coverage)', async t => {
const version = '1.0.0'
const { npm, registry } = await loadNpmWithRegistry(t, init(version))
const { npm, registry } = await loadNpmWithRegistry(t, init({ version }))
registry.publish(pkg, { manifest: { versions: { } } })
await npm.exec('publish', [])
})

t.test('ALLOWS publish when packument has empty manifest (for coverage)', async t => {
await t.test('ALLOWS publish when packument has empty manifest (for coverage)', async t => {
const version = '1.0.0'
const { npm, registry } = await loadNpmWithRegistry(t, init(version))
const { npm, registry } = await loadNpmWithRegistry(t, init({ version }))
registry.publish(pkg, { manifest: {} })
await npm.exec('publish', [])
})

t.end()
await t.test('ALLOWS publish when highest version is HIGHER than publishing version with publishConfig', async t => {
const version = '99.0.0'
const { npm, registry } = await loadNpmWithRegistry(t, init({
version,
pkgExtra: {
publishConfig: {
tag: 'next',
},
},
}))
registry.publish(pkg, { packuments })
await npm.exec('publish', [])
})
})
1 change: 0 additions & 1 deletion test/lib/utils/sbom-cyclonedx.js
Original file line number Diff line number Diff line change
@@ -107,7 +107,6 @@ t.test('single node - with author object', t => {
})

t.test('single node - with integrity', t => {
/* eslint-disable-next-line max-len */
const node = { ...root, integrity: 'sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==' }
const res = cyclonedxOutput({ npm, nodes: [node] })
t.matchSnapshot(JSON.stringify(res))
1 change: 0 additions & 1 deletion test/lib/utils/sbom-spdx.js
Original file line number Diff line number Diff line change
@@ -163,7 +163,6 @@ t.test('single node - with homepage', t => {
})

t.test('single node - with integrity', t => {
/* eslint-disable-next-line max-len */
const node = { ...root, integrity: 'sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==' }
const res = spdxOutput({ npm, nodes: [node] })
t.matchSnapshot(JSON.stringify(res))