Skip to content

Commit

Permalink
fix: engine-strict issue on npm install
Browse files Browse the repository at this point in the history
  • Loading branch information
kchindam-infy committed Oct 10, 2024
1 parent f68698d commit f81a40c
Showing 1 changed file with 78 additions and 32 deletions.
110 changes: 78 additions & 32 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const pickManifest = (packument, wanted, opts) => {
includeStaged = false,
avoid = null,
avoidStrict = false,
engineStrict = false,
} = opts

const { name, time: verTimes } = packument
Expand Down Expand Up @@ -101,7 +102,18 @@ const pickManifest = (packument, wanted, opts) => {
// 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)
const mani = versions[ver] || staged[ver] || restricted[ver]
if (engineStrict && mani && !engineOk(mani, npmVersion, nodeVersion)) {
throw Object.assign(new Error(`No compatible version found: ${name}@${ver}`), {
code: 'ENOTENGINECOMPLIANT',
type,
wanted,
versions: Object.keys(versions),
name,
distTags,
})
}
return decorateAvoid(mani, avoid)
} else {
return pickManifest(packument, `<=${ver}`, opts)
}
Expand All @@ -111,7 +123,21 @@ const pickManifest = (packument, wanted, opts) => {
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
if (isBefore(verTimes, ver, time)) {
if (engineStrict && mani && !engineOk(mani, npmVersion, nodeVersion)) {
throw Object.assign(new Error(`No compatible version found: ${name}@${ver}`), {
code: 'ENOTENGINECOMPLIANT',
type,
wanted,
versions: Object.keys(versions),
name,
distTags,
})
}
return decorateAvoid(mani, avoid)
} else {
return null
}
}

// ok, sort based on our heuristics, and pick the best fit
Expand Down Expand Up @@ -153,38 +179,58 @@ const pickManifest = (packument, wanted, opts) => {
})
}

const sortSemverOpt = { loose: true }
const entries = allEntries.filter(([ver]) =>
let entries = allEntries.filter(([ver]) =>
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[vera]
const notrestrb = !restricted[verb]
const notstagea = !staged[vera]
const notstageb = !staged[verb]
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)

// **Engine-Strict Filtering**
if (engineStrict) {
entries = entries.filter(([, mani]) =>
engineOk(mani, npmVersion, nodeVersion))
}

if (!entries.length) {
throw Object.assign(new Error(`No compatible version found: ${name}@${wanted}`), {
code: 'ENOTENGINECOMPLIANT',
name,
type,
wanted,
versions: Object.keys(versions),
nodeVersion,
npmVersion,
})
}

// Sort the entries to pick the best version
const sortSemverOpt = { loose: true }
entries = entries.sort((a, b) => {
const [vera, mania] = a
const [verb, manib] = b
const notavoida = !shouldAvoid(vera, avoid)
const notavoidb = !shouldAvoid(verb, avoid)
const notrestra = !restricted[vera]
const notrestrb = !restricted[verb]
const notstagea = !staged[vera]
const notstageb = !staged[verb]
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)
}
Expand Down

0 comments on commit f81a40c

Please sign in to comment.