summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/npm-pick-manifest/lib/index.js
diff options
context:
space:
mode:
authornpm team <ops+robot@npmjs.com>2022-02-24 21:41:49 +0000
committerLuigi Pinca <luigipinca@gmail.com>2022-02-26 08:15:26 +0100
commit1b8300b238923822ea0934b196e3a9e97e0a0893 (patch)
tree474bd5d5a4ee73358f4feebd433cc3f67d65b6e2 /deps/npm/node_modules/npm-pick-manifest/lib/index.js
parente84b635db49d629f119959c9f0a31762ac22770b (diff)
downloadnode-new-1b8300b238923822ea0934b196e3a9e97e0a0893.tar.gz
deps: upgrade npm to 8.5.2
PR-URL: https://github.com/nodejs/node/pull/42122 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Mestery <mestery@protonmail.com> Reviewed-By: Danielle Adams <adamzdanielle@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Diffstat (limited to 'deps/npm/node_modules/npm-pick-manifest/lib/index.js')
-rw-r--r--deps/npm/node_modules/npm-pick-manifest/lib/index.js218
1 files changed, 218 insertions, 0 deletions
diff --git a/deps/npm/node_modules/npm-pick-manifest/lib/index.js b/deps/npm/node_modules/npm-pick-manifest/lib/index.js
new file mode 100644
index 0000000000..f2934e9ca1
--- /dev/null
+++ b/deps/npm/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,
+ })
+}