diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index 4a2ff45175b42..324dbb190ca34 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -524,7 +524,6 @@ graph LR; npm-->libnpmteam; npm-->libnpmversion; npm-->licensee; - npm-->lru-cache; npm-->make-fetch-happen; npm-->minimatch; npm-->minipass-pipeline; diff --git a/node_modules/.gitignore b/node_modules/.gitignore index e39385838321d..c71880acbc340 100644 --- a/node_modules/.gitignore +++ b/node_modules/.gitignore @@ -22,6 +22,14 @@ !/@npmcli/disparity-colors !/@npmcli/fs !/@npmcli/git +!/@npmcli/git/node_modules/ +/@npmcli/git/node_modules/* +!/@npmcli/git/node_modules/hosted-git-info +!/@npmcli/git/node_modules/hosted-git-info/node_modules/ +/@npmcli/git/node_modules/hosted-git-info/node_modules/* +!/@npmcli/git/node_modules/hosted-git-info/node_modules/lru-cache +!/@npmcli/git/node_modules/npm-package-arg +!/@npmcli/git/node_modules/npm-pick-manifest !/@npmcli/installed-package-contents !/@npmcli/map-workspaces !/@npmcli/metavuln-calculator @@ -218,11 +226,6 @@ !/npm-package-arg !/npm-packlist !/npm-pick-manifest -!/npm-pick-manifest/node_modules/ -/npm-pick-manifest/node_modules/* -!/npm-pick-manifest/node_modules/hosted-git-info -!/npm-pick-manifest/node_modules/lru-cache -!/npm-pick-manifest/node_modules/npm-package-arg !/npm-profile !/npm-registry-fetch !/npm-registry-fetch/node_modules/ @@ -249,6 +252,7 @@ !/pacote/node_modules/hosted-git-info !/pacote/node_modules/lru-cache !/pacote/node_modules/npm-package-arg +!/pacote/node_modules/npm-pick-manifest !/parse-conflict-json !/path-is-absolute !/path-key diff --git a/node_modules/npm-pick-manifest/node_modules/hosted-git-info/LICENSE b/node_modules/@npmcli/git/node_modules/hosted-git-info/LICENSE similarity index 100% rename from node_modules/npm-pick-manifest/node_modules/hosted-git-info/LICENSE rename to node_modules/@npmcli/git/node_modules/hosted-git-info/LICENSE diff --git a/node_modules/npm-pick-manifest/node_modules/hosted-git-info/lib/from-url.js b/node_modules/@npmcli/git/node_modules/hosted-git-info/lib/from-url.js similarity index 100% rename from node_modules/npm-pick-manifest/node_modules/hosted-git-info/lib/from-url.js rename to node_modules/@npmcli/git/node_modules/hosted-git-info/lib/from-url.js diff --git a/node_modules/npm-pick-manifest/node_modules/hosted-git-info/lib/hosts.js b/node_modules/@npmcli/git/node_modules/hosted-git-info/lib/hosts.js similarity index 100% rename from node_modules/npm-pick-manifest/node_modules/hosted-git-info/lib/hosts.js rename to node_modules/@npmcli/git/node_modules/hosted-git-info/lib/hosts.js diff --git a/node_modules/npm-pick-manifest/node_modules/hosted-git-info/lib/index.js b/node_modules/@npmcli/git/node_modules/hosted-git-info/lib/index.js similarity index 100% rename from node_modules/npm-pick-manifest/node_modules/hosted-git-info/lib/index.js rename to node_modules/@npmcli/git/node_modules/hosted-git-info/lib/index.js diff --git a/node_modules/npm-pick-manifest/node_modules/hosted-git-info/lib/parse-url.js b/node_modules/@npmcli/git/node_modules/hosted-git-info/lib/parse-url.js similarity index 100% rename from node_modules/npm-pick-manifest/node_modules/hosted-git-info/lib/parse-url.js rename to node_modules/@npmcli/git/node_modules/hosted-git-info/lib/parse-url.js diff --git a/node_modules/npm-pick-manifest/node_modules/lru-cache/LICENSE b/node_modules/@npmcli/git/node_modules/hosted-git-info/node_modules/lru-cache/LICENSE similarity index 100% rename from node_modules/npm-pick-manifest/node_modules/lru-cache/LICENSE rename to node_modules/@npmcli/git/node_modules/hosted-git-info/node_modules/lru-cache/LICENSE diff --git a/node_modules/npm-pick-manifest/node_modules/lru-cache/index.js b/node_modules/@npmcli/git/node_modules/hosted-git-info/node_modules/lru-cache/index.js similarity index 100% rename from node_modules/npm-pick-manifest/node_modules/lru-cache/index.js rename to node_modules/@npmcli/git/node_modules/hosted-git-info/node_modules/lru-cache/index.js diff --git a/node_modules/npm-pick-manifest/node_modules/lru-cache/index.mjs b/node_modules/@npmcli/git/node_modules/hosted-git-info/node_modules/lru-cache/index.mjs similarity index 100% rename from node_modules/npm-pick-manifest/node_modules/lru-cache/index.mjs rename to node_modules/@npmcli/git/node_modules/hosted-git-info/node_modules/lru-cache/index.mjs diff --git a/node_modules/npm-pick-manifest/node_modules/lru-cache/package.json b/node_modules/@npmcli/git/node_modules/hosted-git-info/node_modules/lru-cache/package.json similarity index 100% rename from node_modules/npm-pick-manifest/node_modules/lru-cache/package.json rename to node_modules/@npmcli/git/node_modules/hosted-git-info/node_modules/lru-cache/package.json diff --git a/node_modules/npm-pick-manifest/node_modules/hosted-git-info/package.json b/node_modules/@npmcli/git/node_modules/hosted-git-info/package.json similarity index 100% rename from node_modules/npm-pick-manifest/node_modules/hosted-git-info/package.json rename to node_modules/@npmcli/git/node_modules/hosted-git-info/package.json diff --git a/node_modules/npm-pick-manifest/node_modules/npm-package-arg/LICENSE b/node_modules/@npmcli/git/node_modules/npm-package-arg/LICENSE similarity index 100% rename from node_modules/npm-pick-manifest/node_modules/npm-package-arg/LICENSE rename to node_modules/@npmcli/git/node_modules/npm-package-arg/LICENSE diff --git a/node_modules/npm-pick-manifest/node_modules/npm-package-arg/lib/npa.js b/node_modules/@npmcli/git/node_modules/npm-package-arg/lib/npa.js similarity index 100% rename from node_modules/npm-pick-manifest/node_modules/npm-package-arg/lib/npa.js rename to node_modules/@npmcli/git/node_modules/npm-package-arg/lib/npa.js diff --git a/node_modules/npm-pick-manifest/node_modules/npm-package-arg/package.json b/node_modules/@npmcli/git/node_modules/npm-package-arg/package.json similarity index 100% rename from node_modules/npm-pick-manifest/node_modules/npm-package-arg/package.json rename to node_modules/@npmcli/git/node_modules/npm-package-arg/package.json diff --git a/node_modules/@npmcli/git/node_modules/npm-pick-manifest/LICENSE.md b/node_modules/@npmcli/git/node_modules/npm-pick-manifest/LICENSE.md new file mode 100644 index 0000000000000..8d28acf866d93 --- /dev/null +++ b/node_modules/@npmcli/git/node_modules/npm-pick-manifest/LICENSE.md @@ -0,0 +1,16 @@ +ISC License + +Copyright (c) npm, Inc. + +Permission to use, copy, modify, and/or distribute this software for +any purpose with or without fee is hereby granted, provided that the +above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE COPYRIGHT HOLDER DISCLAIMS +ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE +USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/@npmcli/git/node_modules/npm-pick-manifest/lib/index.js b/node_modules/@npmcli/git/node_modules/npm-pick-manifest/lib/index.js new file mode 100644 index 0000000000000..8dbd2721c8996 --- /dev/null +++ b/node_modules/@npmcli/git/node_modules/npm-pick-manifest/lib/index.js @@ -0,0 +1,218 @@ +'use strict' + +const npa = require('npm-package-arg') +const semver = require('semver') +const { checkEngine } = require('npm-install-checks') +const normalizeBin = require('npm-normalize-package-bin') + +const engineOk = (manifest, npmVersion, nodeVersion) => { + try { + checkEngine(manifest, npmVersion, nodeVersion) + return true + } catch (_) { + return false + } +} + +const isBefore = (verTimes, ver, time) => + !verTimes || !verTimes[ver] || Date.parse(verTimes[ver]) <= time + +const avoidSemverOpt = { includePrerelease: true, loose: true } +const shouldAvoid = (ver, avoid) => + avoid && semver.satisfies(ver, avoid, avoidSemverOpt) + +const decorateAvoid = (result, avoid) => + result && shouldAvoid(result.version, avoid) + ? { ...result, _shouldAvoid: true } + : result + +const pickManifest = (packument, wanted, opts) => { + const { + defaultTag = 'latest', + before = null, + nodeVersion = process.version, + npmVersion = null, + includeStaged = false, + avoid = null, + avoidStrict = false, + } = opts + + const { name, time: verTimes } = packument + const versions = packument.versions || {} + + if (avoidStrict) { + const looseOpts = { + ...opts, + avoidStrict: false, + } + + const result = pickManifest(packument, wanted, looseOpts) + if (!result || !result._shouldAvoid) { + return result + } + + const caret = pickManifest(packument, `^${result.version}`, looseOpts) + if (!caret || !caret._shouldAvoid) { + return { + ...caret, + _outsideDependencyRange: true, + _isSemVerMajor: false, + } + } + + const star = pickManifest(packument, '*', looseOpts) + if (!star || !star._shouldAvoid) { + return { + ...star, + _outsideDependencyRange: true, + _isSemVerMajor: true, + } + } + + throw Object.assign(new Error(`No avoidable versions for ${name}`), { + code: 'ETARGET', + name, + wanted, + avoid, + before, + versions: Object.keys(versions), + }) + } + + const staged = (includeStaged && packument.stagedVersions && + packument.stagedVersions.versions) || {} + const restricted = (packument.policyRestrictions && + packument.policyRestrictions.versions) || {} + + const time = before && verTimes ? +(new Date(before)) : Infinity + const spec = npa.resolve(name, wanted || defaultTag) + const type = spec.type + const distTags = packument['dist-tags'] || {} + + if (type !== 'tag' && type !== 'version' && type !== 'range') { + throw new Error('Only tag, version, and range are supported') + } + + // if the type is 'tag', and not just the implicit default, then it must + // be that exactly, or nothing else will do. + if (wanted && type === 'tag') { + const ver = distTags[wanted] + // if the version in the dist-tags is before the before date, then + // we use that. Otherwise, we get the highest precedence version + // prior to the dist-tag. + if (isBefore(verTimes, ver, time)) { + return decorateAvoid(versions[ver] || staged[ver] || restricted[ver], avoid) + } else { + return pickManifest(packument, `<=${ver}`, opts) + } + } + + // similarly, if a specific version, then only that version will do + if (wanted && type === 'version') { + const ver = semver.clean(wanted, { loose: true }) + const mani = versions[ver] || staged[ver] || restricted[ver] + return isBefore(verTimes, ver, time) ? decorateAvoid(mani, avoid) : null + } + + // ok, sort based on our heuristics, and pick the best fit + const range = type === 'range' ? wanted : '*' + + // if the range is *, then we prefer the 'latest' if available + // but skip this if it should be avoided, in that case we have + // to try a little harder. + const defaultVer = distTags[defaultTag] + if (defaultVer && + (range === '*' || semver.satisfies(defaultVer, range, { loose: true })) && + !shouldAvoid(defaultVer, avoid)) { + const mani = versions[defaultVer] + if (mani && isBefore(verTimes, defaultVer, time)) { + return mani + } + } + + // ok, actually have to sort the list and take the winner + const allEntries = Object.entries(versions) + .concat(Object.entries(staged)) + .concat(Object.entries(restricted)) + .filter(([ver, mani]) => isBefore(verTimes, ver, time)) + + if (!allEntries.length) { + throw Object.assign(new Error(`No versions available for ${name}`), { + code: 'ENOVERSIONS', + name, + type, + wanted, + before, + versions: Object.keys(versions), + }) + } + + const sortSemverOpt = { loose: true } + const entries = allEntries.filter(([ver, mani]) => + semver.satisfies(ver, range, { loose: true })) + .sort((a, b) => { + const [vera, mania] = a + const [verb, manib] = b + const notavoida = !shouldAvoid(vera, avoid) + const notavoidb = !shouldAvoid(verb, avoid) + const notrestra = !restricted[a] + const notrestrb = !restricted[b] + const notstagea = !staged[a] + const notstageb = !staged[b] + const notdepra = !mania.deprecated + const notdeprb = !manib.deprecated + const enginea = engineOk(mania, npmVersion, nodeVersion) + const engineb = engineOk(manib, npmVersion, nodeVersion) + // sort by: + // - not an avoided version + // - not restricted + // - not staged + // - not deprecated and engine ok + // - engine ok + // - not deprecated + // - semver + return (notavoidb - notavoida) || + (notrestrb - notrestra) || + (notstageb - notstagea) || + ((notdeprb && engineb) - (notdepra && enginea)) || + (engineb - enginea) || + (notdeprb - notdepra) || + semver.rcompare(vera, verb, sortSemverOpt) + }) + + return decorateAvoid(entries[0] && entries[0][1], avoid) +} + +module.exports = (packument, wanted, opts = {}) => { + const mani = pickManifest(packument, wanted, opts) + const picked = mani && normalizeBin(mani) + const policyRestrictions = packument.policyRestrictions + const restricted = (policyRestrictions && policyRestrictions.versions) || {} + + if (picked && !restricted[picked.version]) { + return picked + } + + const { before = null, defaultTag = 'latest' } = opts + const bstr = before ? new Date(before).toLocaleString() : '' + const { name } = packument + const pckg = `${name}@${wanted}` + + (before ? ` with a date before ${bstr}` : '') + + const isForbidden = picked && !!restricted[picked.version] + const polMsg = isForbidden ? policyRestrictions.message : '' + + const msg = !isForbidden ? `No matching version found for ${pckg}.` + : `Could not download ${pckg} due to policy violations:\n${polMsg}` + + const code = isForbidden ? 'E403' : 'ETARGET' + throw Object.assign(new Error(msg), { + code, + type: npa.resolve(packument.name, wanted).type, + wanted, + versions: Object.keys(packument.versions ?? {}), + name, + distTags: packument['dist-tags'], + defaultTag, + }) +} diff --git a/node_modules/@npmcli/git/node_modules/npm-pick-manifest/package.json b/node_modules/@npmcli/git/node_modules/npm-pick-manifest/package.json new file mode 100644 index 0000000000000..feff81f5b2fee --- /dev/null +++ b/node_modules/@npmcli/git/node_modules/npm-pick-manifest/package.json @@ -0,0 +1,57 @@ +{ + "name": "npm-pick-manifest", + "version": "8.0.2", + "description": "Resolves a matching manifest from a package metadata document according to standard npm semver resolution rules.", + "main": "./lib", + "files": [ + "bin/", + "lib/" + ], + "scripts": { + "coverage": "tap", + "lint": "eslint \"**/*.js\"", + "test": "tap", + "posttest": "npm run lint", + "postlint": "template-oss-check", + "lintfix": "npm run lint -- --fix", + "snap": "tap", + "template-oss-apply": "template-oss-apply --force" + }, + "repository": { + "type": "git", + "url": "https://github.com/npm/npm-pick-manifest.git" + }, + "keywords": [ + "npm", + "semver", + "package manager" + ], + "author": "GitHub Inc.", + "license": "ISC", + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^10.0.0", + "semver": "^7.3.5" + }, + "devDependencies": { + "@npmcli/eslint-config": "^4.0.0", + "@npmcli/template-oss": "4.18.0", + "tap": "^16.0.1" + }, + "tap": { + "check-coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.18.0", + "publish": true + } +} diff --git a/node_modules/npm-pick-manifest/package.json b/node_modules/npm-pick-manifest/package.json index feff81f5b2fee..e30c2cfe341fc 100644 --- a/node_modules/npm-pick-manifest/package.json +++ b/node_modules/npm-pick-manifest/package.json @@ -1,6 +1,6 @@ { "name": "npm-pick-manifest", - "version": "8.0.2", + "version": "9.0.0", "description": "Resolves a matching manifest from a package metadata document according to standard npm semver resolution rules.", "main": "./lib", "files": [ @@ -31,7 +31,7 @@ "dependencies": { "npm-install-checks": "^6.0.0", "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^10.0.0", + "npm-package-arg": "^11.0.0", "semver": "^7.3.5" }, "devDependencies": { @@ -47,11 +47,17 @@ ] }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", "version": "4.18.0", - "publish": true + "publish": true, + "ciVersions": [ + "16.14.0", + "16.x", + "18.0.0", + "18.x" + ] } } diff --git a/node_modules/pacote/node_modules/npm-pick-manifest/LICENSE.md b/node_modules/pacote/node_modules/npm-pick-manifest/LICENSE.md new file mode 100644 index 0000000000000..8d28acf866d93 --- /dev/null +++ b/node_modules/pacote/node_modules/npm-pick-manifest/LICENSE.md @@ -0,0 +1,16 @@ +ISC License + +Copyright (c) npm, Inc. + +Permission to use, copy, modify, and/or distribute this software for +any purpose with or without fee is hereby granted, provided that the +above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE COPYRIGHT HOLDER DISCLAIMS +ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE +USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/pacote/node_modules/npm-pick-manifest/lib/index.js b/node_modules/pacote/node_modules/npm-pick-manifest/lib/index.js new file mode 100644 index 0000000000000..8dbd2721c8996 --- /dev/null +++ b/node_modules/pacote/node_modules/npm-pick-manifest/lib/index.js @@ -0,0 +1,218 @@ +'use strict' + +const npa = require('npm-package-arg') +const semver = require('semver') +const { checkEngine } = require('npm-install-checks') +const normalizeBin = require('npm-normalize-package-bin') + +const engineOk = (manifest, npmVersion, nodeVersion) => { + try { + checkEngine(manifest, npmVersion, nodeVersion) + return true + } catch (_) { + return false + } +} + +const isBefore = (verTimes, ver, time) => + !verTimes || !verTimes[ver] || Date.parse(verTimes[ver]) <= time + +const avoidSemverOpt = { includePrerelease: true, loose: true } +const shouldAvoid = (ver, avoid) => + avoid && semver.satisfies(ver, avoid, avoidSemverOpt) + +const decorateAvoid = (result, avoid) => + result && shouldAvoid(result.version, avoid) + ? { ...result, _shouldAvoid: true } + : result + +const pickManifest = (packument, wanted, opts) => { + const { + defaultTag = 'latest', + before = null, + nodeVersion = process.version, + npmVersion = null, + includeStaged = false, + avoid = null, + avoidStrict = false, + } = opts + + const { name, time: verTimes } = packument + const versions = packument.versions || {} + + if (avoidStrict) { + const looseOpts = { + ...opts, + avoidStrict: false, + } + + const result = pickManifest(packument, wanted, looseOpts) + if (!result || !result._shouldAvoid) { + return result + } + + const caret = pickManifest(packument, `^${result.version}`, looseOpts) + if (!caret || !caret._shouldAvoid) { + return { + ...caret, + _outsideDependencyRange: true, + _isSemVerMajor: false, + } + } + + const star = pickManifest(packument, '*', looseOpts) + if (!star || !star._shouldAvoid) { + return { + ...star, + _outsideDependencyRange: true, + _isSemVerMajor: true, + } + } + + throw Object.assign(new Error(`No avoidable versions for ${name}`), { + code: 'ETARGET', + name, + wanted, + avoid, + before, + versions: Object.keys(versions), + }) + } + + const staged = (includeStaged && packument.stagedVersions && + packument.stagedVersions.versions) || {} + const restricted = (packument.policyRestrictions && + packument.policyRestrictions.versions) || {} + + const time = before && verTimes ? +(new Date(before)) : Infinity + const spec = npa.resolve(name, wanted || defaultTag) + const type = spec.type + const distTags = packument['dist-tags'] || {} + + if (type !== 'tag' && type !== 'version' && type !== 'range') { + throw new Error('Only tag, version, and range are supported') + } + + // if the type is 'tag', and not just the implicit default, then it must + // be that exactly, or nothing else will do. + if (wanted && type === 'tag') { + const ver = distTags[wanted] + // if the version in the dist-tags is before the before date, then + // we use that. Otherwise, we get the highest precedence version + // prior to the dist-tag. + if (isBefore(verTimes, ver, time)) { + return decorateAvoid(versions[ver] || staged[ver] || restricted[ver], avoid) + } else { + return pickManifest(packument, `<=${ver}`, opts) + } + } + + // similarly, if a specific version, then only that version will do + if (wanted && type === 'version') { + const ver = semver.clean(wanted, { loose: true }) + const mani = versions[ver] || staged[ver] || restricted[ver] + return isBefore(verTimes, ver, time) ? decorateAvoid(mani, avoid) : null + } + + // ok, sort based on our heuristics, and pick the best fit + const range = type === 'range' ? wanted : '*' + + // if the range is *, then we prefer the 'latest' if available + // but skip this if it should be avoided, in that case we have + // to try a little harder. + const defaultVer = distTags[defaultTag] + if (defaultVer && + (range === '*' || semver.satisfies(defaultVer, range, { loose: true })) && + !shouldAvoid(defaultVer, avoid)) { + const mani = versions[defaultVer] + if (mani && isBefore(verTimes, defaultVer, time)) { + return mani + } + } + + // ok, actually have to sort the list and take the winner + const allEntries = Object.entries(versions) + .concat(Object.entries(staged)) + .concat(Object.entries(restricted)) + .filter(([ver, mani]) => isBefore(verTimes, ver, time)) + + if (!allEntries.length) { + throw Object.assign(new Error(`No versions available for ${name}`), { + code: 'ENOVERSIONS', + name, + type, + wanted, + before, + versions: Object.keys(versions), + }) + } + + const sortSemverOpt = { loose: true } + const entries = allEntries.filter(([ver, mani]) => + semver.satisfies(ver, range, { loose: true })) + .sort((a, b) => { + const [vera, mania] = a + const [verb, manib] = b + const notavoida = !shouldAvoid(vera, avoid) + const notavoidb = !shouldAvoid(verb, avoid) + const notrestra = !restricted[a] + const notrestrb = !restricted[b] + const notstagea = !staged[a] + const notstageb = !staged[b] + const notdepra = !mania.deprecated + const notdeprb = !manib.deprecated + const enginea = engineOk(mania, npmVersion, nodeVersion) + const engineb = engineOk(manib, npmVersion, nodeVersion) + // sort by: + // - not an avoided version + // - not restricted + // - not staged + // - not deprecated and engine ok + // - engine ok + // - not deprecated + // - semver + return (notavoidb - notavoida) || + (notrestrb - notrestra) || + (notstageb - notstagea) || + ((notdeprb && engineb) - (notdepra && enginea)) || + (engineb - enginea) || + (notdeprb - notdepra) || + semver.rcompare(vera, verb, sortSemverOpt) + }) + + return decorateAvoid(entries[0] && entries[0][1], avoid) +} + +module.exports = (packument, wanted, opts = {}) => { + const mani = pickManifest(packument, wanted, opts) + const picked = mani && normalizeBin(mani) + const policyRestrictions = packument.policyRestrictions + const restricted = (policyRestrictions && policyRestrictions.versions) || {} + + if (picked && !restricted[picked.version]) { + return picked + } + + const { before = null, defaultTag = 'latest' } = opts + const bstr = before ? new Date(before).toLocaleString() : '' + const { name } = packument + const pckg = `${name}@${wanted}` + + (before ? ` with a date before ${bstr}` : '') + + const isForbidden = picked && !!restricted[picked.version] + const polMsg = isForbidden ? policyRestrictions.message : '' + + const msg = !isForbidden ? `No matching version found for ${pckg}.` + : `Could not download ${pckg} due to policy violations:\n${polMsg}` + + const code = isForbidden ? 'E403' : 'ETARGET' + throw Object.assign(new Error(msg), { + code, + type: npa.resolve(packument.name, wanted).type, + wanted, + versions: Object.keys(packument.versions ?? {}), + name, + distTags: packument['dist-tags'], + defaultTag, + }) +} diff --git a/node_modules/pacote/node_modules/npm-pick-manifest/package.json b/node_modules/pacote/node_modules/npm-pick-manifest/package.json new file mode 100644 index 0000000000000..feff81f5b2fee --- /dev/null +++ b/node_modules/pacote/node_modules/npm-pick-manifest/package.json @@ -0,0 +1,57 @@ +{ + "name": "npm-pick-manifest", + "version": "8.0.2", + "description": "Resolves a matching manifest from a package metadata document according to standard npm semver resolution rules.", + "main": "./lib", + "files": [ + "bin/", + "lib/" + ], + "scripts": { + "coverage": "tap", + "lint": "eslint \"**/*.js\"", + "test": "tap", + "posttest": "npm run lint", + "postlint": "template-oss-check", + "lintfix": "npm run lint -- --fix", + "snap": "tap", + "template-oss-apply": "template-oss-apply --force" + }, + "repository": { + "type": "git", + "url": "https://github.com/npm/npm-pick-manifest.git" + }, + "keywords": [ + "npm", + "semver", + "package manager" + ], + "author": "GitHub Inc.", + "license": "ISC", + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^10.0.0", + "semver": "^7.3.5" + }, + "devDependencies": { + "@npmcli/eslint-config": "^4.0.0", + "@npmcli/template-oss": "4.18.0", + "tap": "^16.0.1" + }, + "tap": { + "check-coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.18.0", + "publish": true + } +} diff --git a/package-lock.json b/package-lock.json index c9990ac4f6087..693e245a4e45b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -132,7 +132,7 @@ "npm-audit-report": "^5.0.0", "npm-install-checks": "^6.2.0", "npm-package-arg": "^11.0.0", - "npm-pick-manifest": "^8.0.2", + "npm-pick-manifest": "^9.0.0", "npm-profile": "^8.0.0", "npm-registry-fetch": "^15.0.0", "npm-user-validate": "^2.0.0", @@ -2428,6 +2428,57 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/@npmcli/git/node_modules/hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "inBundle": true, + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "inBundle": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@npmcli/git/node_modules/npm-package-arg": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", + "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", + "inBundle": true, + "dependencies": { + "hosted-git-info": "^6.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/npm-pick-manifest": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz", + "integrity": "sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==", + "inBundle": true, + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^10.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/@npmcli/installed-package-contents": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz", @@ -2720,6 +2771,21 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/@npmcli/template-oss/node_modules/npm-pick-manifest": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz", + "integrity": "sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==", + "dev": true, + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^10.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/@octokit/auth-token": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.3.tgz", @@ -9873,54 +9939,18 @@ } }, "node_modules/npm-pick-manifest": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz", - "integrity": "sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.0.0.tgz", + "integrity": "sha512-VfvRSs/b6n9ol4Qb+bDwNGUXutpy76x6MARw/XssevE0TnctIKcmklJZM5Z7nqs5z5aW+0S63pgCNbpkUNNXBg==", "inBundle": true, "dependencies": { "npm-install-checks": "^6.0.0", "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^10.0.0", + "npm-package-arg": "^11.0.0", "semver": "^7.3.5" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-pick-manifest/node_modules/hosted-git-info": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", - "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", - "inBundle": true, - "dependencies": { - "lru-cache": "^7.5.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-pick-manifest/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "inBundle": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/npm-pick-manifest/node_modules/npm-package-arg": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", - "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", - "inBundle": true, - "dependencies": { - "hosted-git-info": "^6.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm-profile": { @@ -10691,6 +10721,21 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/pacote/node_modules/npm-pick-manifest": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz", + "integrity": "sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==", + "inBundle": true, + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^10.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -16284,7 +16329,7 @@ "nopt": "^7.0.0", "npm-install-checks": "^6.2.0", "npm-package-arg": "^11.0.0", - "npm-pick-manifest": "^8.0.2", + "npm-pick-manifest": "^9.0.0", "npm-registry-fetch": "^15.0.0", "npmlog": "^7.0.1", "pacote": "^16.0.0", diff --git a/package.json b/package.json index 6c5504b8f3520..2cc6dcb9e33f1 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "npm-audit-report": "^5.0.0", "npm-install-checks": "^6.2.0", "npm-package-arg": "^11.0.0", - "npm-pick-manifest": "^8.0.2", + "npm-pick-manifest": "^9.0.0", "npm-profile": "^8.0.0", "npm-registry-fetch": "^15.0.0", "npm-user-validate": "^2.0.0", diff --git a/workspaces/arborist/package.json b/workspaces/arborist/package.json index 0a33240ee91ea..912cfe79779dc 100644 --- a/workspaces/arborist/package.json +++ b/workspaces/arborist/package.json @@ -23,7 +23,7 @@ "nopt": "^7.0.0", "npm-install-checks": "^6.2.0", "npm-package-arg": "^11.0.0", - "npm-pick-manifest": "^8.0.2", + "npm-pick-manifest": "^9.0.0", "npm-registry-fetch": "^15.0.0", "npmlog": "^7.0.1", "pacote": "^16.0.0",