update
This commit is contained in:
15
package/node_modules/@npmcli/metavuln-calculator/LICENSE
generated
vendored
Normal file
15
package/node_modules/@npmcli/metavuln-calculator/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
The 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 AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
435
package/node_modules/@npmcli/metavuln-calculator/lib/advisory.js
generated
vendored
Normal file
435
package/node_modules/@npmcli/metavuln-calculator/lib/advisory.js
generated
vendored
Normal file
@@ -0,0 +1,435 @@
|
||||
const hash = require('./hash.js')
|
||||
const semver = require('semver')
|
||||
const semverOpt = { includePrerelease: true, loose: true }
|
||||
const getDepSpec = require('./get-dep-spec.js')
|
||||
|
||||
// any fields that we don't want in the cache need to be hidden
|
||||
const _source = Symbol('source')
|
||||
const _packument = Symbol('packument')
|
||||
const _versionVulnMemo = Symbol('versionVulnMemo')
|
||||
const _updated = Symbol('updated')
|
||||
const _options = Symbol('options')
|
||||
const _specVulnMemo = Symbol('specVulnMemo')
|
||||
const _testVersion = Symbol('testVersion')
|
||||
const _testVersions = Symbol('testVersions')
|
||||
const _calculateRange = Symbol('calculateRange')
|
||||
const _markVulnerable = Symbol('markVulnerable')
|
||||
const _testSpec = Symbol('testSpec')
|
||||
|
||||
class Advisory {
|
||||
constructor (name, source, options = {}) {
|
||||
this.source = source.id
|
||||
this[_source] = source
|
||||
this[_options] = options
|
||||
this.name = name
|
||||
if (!source.name) {
|
||||
source.name = name
|
||||
}
|
||||
|
||||
this.dependency = source.name
|
||||
|
||||
if (this.type === 'advisory') {
|
||||
this.title = source.title
|
||||
this.url = source.url
|
||||
} else {
|
||||
this.title = `Depends on vulnerable versions of ${source.name}`
|
||||
this.url = null
|
||||
}
|
||||
|
||||
this.severity = source.severity || 'high'
|
||||
this.versions = []
|
||||
this.vulnerableVersions = []
|
||||
this.cwe = source.cwe
|
||||
this.cvss = source.cvss
|
||||
|
||||
// advisories have the range, metavulns do not
|
||||
// if an advisory doesn't specify range, assume all are vulnerable
|
||||
this.range = this.type === 'advisory' ? source.vulnerable_versions || '*'
|
||||
: null
|
||||
|
||||
this.id = hash(this)
|
||||
|
||||
this[_packument] = null
|
||||
// memoized list of which versions are vulnerable
|
||||
this[_versionVulnMemo] = new Map()
|
||||
// memoized list of which dependency specs are vulnerable
|
||||
this[_specVulnMemo] = new Map()
|
||||
this[_updated] = false
|
||||
}
|
||||
|
||||
// true if we updated from what we had in cache
|
||||
get updated () {
|
||||
return this[_updated]
|
||||
}
|
||||
|
||||
get type () {
|
||||
return this.dependency === this.name ? 'advisory' : 'metavuln'
|
||||
}
|
||||
|
||||
get packument () {
|
||||
return this[_packument]
|
||||
}
|
||||
|
||||
// load up the data from a cache entry and a fetched packument
|
||||
load (cached, packument) {
|
||||
// basic data integrity gutcheck
|
||||
if (!cached || typeof cached !== 'object') {
|
||||
throw new TypeError('invalid cached data, expected object')
|
||||
}
|
||||
|
||||
if (!packument || typeof packument !== 'object') {
|
||||
throw new TypeError('invalid packument data, expected object')
|
||||
}
|
||||
|
||||
if (cached.id && cached.id !== this.id) {
|
||||
throw Object.assign(new Error('loading from incorrect cache entry'), {
|
||||
expected: this.id,
|
||||
actual: cached.id,
|
||||
})
|
||||
}
|
||||
if (packument.name !== this.name) {
|
||||
throw Object.assign(new Error('loading from incorrect packument'), {
|
||||
expected: this.name,
|
||||
actual: packument.name,
|
||||
})
|
||||
}
|
||||
if (this[_packument]) {
|
||||
throw new Error('advisory object already loaded')
|
||||
}
|
||||
|
||||
// if we have a range from the initialization, and the cached
|
||||
// data has a *different* range, then we know we have to recalc.
|
||||
// just don't use the cached data, so we will definitely not match later
|
||||
if (!this.range || cached.range && cached.range === this.range) {
|
||||
Object.assign(this, cached)
|
||||
}
|
||||
|
||||
this[_packument] = packument
|
||||
|
||||
const pakuVersions = Object.keys(packument.versions || {})
|
||||
const allVersions = new Set([...pakuVersions, ...this.versions])
|
||||
const versionsAdded = []
|
||||
const versionsRemoved = []
|
||||
for (const v of allVersions) {
|
||||
if (!this.versions.includes(v)) {
|
||||
versionsAdded.push(v)
|
||||
this.versions.push(v)
|
||||
} else if (!pakuVersions.includes(v)) {
|
||||
versionsRemoved.push(v)
|
||||
}
|
||||
}
|
||||
|
||||
// strip out any removed versions from our lists, and sort by semver
|
||||
this.versions = semver.sort(this.versions.filter(v =>
|
||||
!versionsRemoved.includes(v)), semverOpt)
|
||||
|
||||
// if no changes, then just return what we got from cache
|
||||
// versions added or removed always means we changed
|
||||
// otherwise, advisories change if the range changes, and
|
||||
// metavulns change if the source was updated
|
||||
const unchanged = this.type === 'advisory'
|
||||
? this.range && this.range === cached.range
|
||||
: !this[_source].updated
|
||||
|
||||
// if the underlying source changed, by an advisory updating the
|
||||
// range, or a source advisory being updated, then we have to re-check
|
||||
// otherwise, only recheck the new ones.
|
||||
this.vulnerableVersions = !unchanged ? []
|
||||
: semver.sort(this.vulnerableVersions.filter(v =>
|
||||
!versionsRemoved.includes(v)), semverOpt)
|
||||
|
||||
if (unchanged && !versionsAdded.length && !versionsRemoved.length) {
|
||||
// nothing added or removed, nothing to do here. use the cached copy.
|
||||
return this
|
||||
}
|
||||
|
||||
this[_updated] = true
|
||||
|
||||
// test any versions newly added
|
||||
if (!unchanged || versionsAdded.length) {
|
||||
this[_testVersions](unchanged ? versionsAdded : this.versions)
|
||||
}
|
||||
this.vulnerableVersions = semver.sort(this.vulnerableVersions, semverOpt)
|
||||
|
||||
// metavulns have to calculate their range, since cache is invalidated
|
||||
// advisories just get their range from the advisory above
|
||||
if (this.type === 'metavuln') {
|
||||
this[_calculateRange]()
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
[_calculateRange] () {
|
||||
// calling semver.simplifyRange with a massive list of versions, and those
|
||||
// versions all concatenated with `||` is a geometric CPU explosion!
|
||||
// we can try to be a *little* smarter up front by doing x-y for all
|
||||
// contiguous version sets in the list
|
||||
const ranges = []
|
||||
this.versions = semver.sort(this.versions, semverOpt)
|
||||
this.vulnerableVersions = semver.sort(this.vulnerableVersions, semverOpt)
|
||||
for (let v = 0, vulnVer = 0; v < this.versions.length; v++) {
|
||||
// figure out the vulnerable subrange
|
||||
const vr = [this.versions[v]]
|
||||
while (v < this.versions.length) {
|
||||
if (this.versions[v] !== this.vulnerableVersions[vulnVer]) {
|
||||
// we don't test prerelease versions, so just skip past it
|
||||
if (/-/.test(this.versions[v])) {
|
||||
v++
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
if (vr.length > 1) {
|
||||
vr[1] = this.versions[v]
|
||||
} else {
|
||||
vr.push(this.versions[v])
|
||||
}
|
||||
v++
|
||||
vulnVer++
|
||||
}
|
||||
// it'll either be just the first version, which means no overlap,
|
||||
// or the start and end versions, which might be the same version
|
||||
if (vr.length > 1) {
|
||||
const tail = this.versions[this.versions.length - 1]
|
||||
ranges.push(vr[1] === tail ? `>=${vr[0]}`
|
||||
: vr[0] === vr[1] ? vr[0]
|
||||
: vr.join(' - '))
|
||||
}
|
||||
}
|
||||
const metavuln = ranges.join(' || ').trim()
|
||||
this.range = !metavuln ? '<0.0.0-0'
|
||||
: semver.simplifyRange(this.versions, metavuln, semverOpt)
|
||||
}
|
||||
|
||||
// returns true if marked as vulnerable, false if ok
|
||||
// spec is a dependency specifier, for metavuln cases
|
||||
// where the version might not be in the packument. if
|
||||
// we have the packument and spec is not provided, then
|
||||
// we use the dependency version from the manifest.
|
||||
testVersion (version, spec = null) {
|
||||
const sv = String(version)
|
||||
if (this[_versionVulnMemo].has(sv)) {
|
||||
return this[_versionVulnMemo].get(sv)
|
||||
}
|
||||
|
||||
const result = this[_testVersion](version, spec)
|
||||
if (result) {
|
||||
this[_markVulnerable](version)
|
||||
}
|
||||
this[_versionVulnMemo].set(sv, !!result)
|
||||
return result
|
||||
}
|
||||
|
||||
[_markVulnerable] (version) {
|
||||
const sv = String(version)
|
||||
if (!this.vulnerableVersions.includes(sv)) {
|
||||
this.vulnerableVersions.push(sv)
|
||||
}
|
||||
}
|
||||
|
||||
[_testVersion] (version, spec) {
|
||||
const sv = String(version)
|
||||
if (this.vulnerableVersions.includes(sv)) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (this.type === 'advisory') {
|
||||
// advisory, just test range
|
||||
return semver.satisfies(version, this.range, semverOpt)
|
||||
}
|
||||
|
||||
// check the dependency of this version on the vulnerable dep
|
||||
// if we got a version that's not in the packument, fall back on
|
||||
// the spec provided, if possible.
|
||||
const mani = this[_packument]?.versions?.[version] || {
|
||||
dependencies: {
|
||||
[this.dependency]: spec,
|
||||
},
|
||||
}
|
||||
|
||||
if (!spec) {
|
||||
spec = getDepSpec(mani, this.dependency)
|
||||
}
|
||||
|
||||
// no dep, no vuln
|
||||
if (spec === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!semver.validRange(spec, semverOpt)) {
|
||||
// not a semver range, nothing we can hope to do about it
|
||||
return true
|
||||
}
|
||||
|
||||
const bd = mani.bundleDependencies
|
||||
const bundled = bd && bd.includes(this[_source].name)
|
||||
// XXX if bundled, then semver.intersects() means vulnerable
|
||||
// else, pick a manifest and see if it can't be avoided
|
||||
// try to pick a version of the dep that isn't vulnerable
|
||||
const avoid = this[_source].range
|
||||
|
||||
if (bundled) {
|
||||
return semver.intersects(spec, avoid, semverOpt)
|
||||
}
|
||||
|
||||
return this[_source].testSpec(spec)
|
||||
}
|
||||
|
||||
testSpec (spec) {
|
||||
// testing all the versions is a bit costly, and the spec tends to stay
|
||||
// consistent across multiple versions, so memoize this as well, in case
|
||||
// we're testing lots of versions.
|
||||
const memo = this[_specVulnMemo]
|
||||
if (memo.has(spec)) {
|
||||
return memo.get(spec)
|
||||
}
|
||||
|
||||
const res = this[_testSpec](spec)
|
||||
memo.set(spec, res)
|
||||
return res
|
||||
}
|
||||
|
||||
[_testSpec] (spec) {
|
||||
for (const v of this.versions) {
|
||||
const satisfies = semver.satisfies(v, spec)
|
||||
if (!satisfies) {
|
||||
continue
|
||||
}
|
||||
if (!this.testVersion(v)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// either vulnerable, or not installable because nothing satisfied
|
||||
// either way, best avoided.
|
||||
return true
|
||||
}
|
||||
|
||||
[_testVersions] (versions) {
|
||||
if (!versions.length) {
|
||||
return
|
||||
}
|
||||
|
||||
// set of lists of versions
|
||||
const versionSets = new Set()
|
||||
versions = semver.sort(versions.map(v => semver.parse(v, semverOpt)))
|
||||
|
||||
// start out with the versions grouped by major and minor
|
||||
let last = versions[0].major + '.' + versions[0].minor
|
||||
let list = []
|
||||
versionSets.add(list)
|
||||
for (const v of versions) {
|
||||
const k = v.major + '.' + v.minor
|
||||
if (k !== last) {
|
||||
last = k
|
||||
list = []
|
||||
versionSets.add(list)
|
||||
}
|
||||
list.push(v)
|
||||
}
|
||||
|
||||
for (const set of versionSets) {
|
||||
// it's common to have version lists like:
|
||||
// 1.0.0
|
||||
// 1.0.1-alpha.0
|
||||
// 1.0.1-alpha.1
|
||||
// ...
|
||||
// 1.0.1-alpha.999
|
||||
// 1.0.1
|
||||
// 1.0.2-alpha.0
|
||||
// ...
|
||||
// 1.0.2-alpha.99
|
||||
// 1.0.2
|
||||
// with a huge number of prerelease versions that are not installable
|
||||
// anyway.
|
||||
// If mid has a prerelease tag, and set[0] does not, then walk it
|
||||
// back until we hit a non-prerelease version
|
||||
// If mid has a prerelease tag, and set[set.length-1] does not,
|
||||
// then walk it forward until we hit a version without a prerelease tag
|
||||
// Similarly, if the head/tail is a prerelease, but there is a non-pr
|
||||
// version in the set, then start there instead.
|
||||
let h = 0
|
||||
const origHeadVuln = this.testVersion(set[h])
|
||||
while (h < set.length && /-/.test(String(set[h]))) {
|
||||
h++
|
||||
}
|
||||
|
||||
// don't filter out the whole list! they might all be pr's
|
||||
if (h === set.length) {
|
||||
h = 0
|
||||
} else if (origHeadVuln) {
|
||||
// if the original was vulnerable, assume so are all of these
|
||||
for (let hh = 0; hh < h; hh++) {
|
||||
this[_markVulnerable](set[hh])
|
||||
}
|
||||
}
|
||||
|
||||
let t = set.length - 1
|
||||
const origTailVuln = this.testVersion(set[t])
|
||||
while (t > h && /-/.test(String(set[t]))) {
|
||||
t--
|
||||
}
|
||||
|
||||
// don't filter out the whole list! might all be pr's
|
||||
if (t === h) {
|
||||
t = set.length - 1
|
||||
} else if (origTailVuln) {
|
||||
// if original tail was vulnerable, assume these are as well
|
||||
for (let tt = set.length - 1; tt > t; tt--) {
|
||||
this[_markVulnerable](set[tt])
|
||||
}
|
||||
}
|
||||
|
||||
const headVuln = h === 0 ? origHeadVuln
|
||||
: this.testVersion(set[h])
|
||||
|
||||
const tailVuln = t === set.length - 1 ? origTailVuln
|
||||
: this.testVersion(set[t])
|
||||
|
||||
// if head and tail both vulnerable, whole list is thrown out
|
||||
if (headVuln && tailVuln) {
|
||||
for (let v = h; v < t; v++) {
|
||||
this[_markVulnerable](set[v])
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// if length is 2 or 1, then we marked them all already
|
||||
if (t < h + 2) {
|
||||
continue
|
||||
}
|
||||
|
||||
const mid = Math.floor(set.length / 2)
|
||||
const pre = set.slice(0, mid)
|
||||
const post = set.slice(mid)
|
||||
|
||||
// if the parent list wasn't prereleases, then drop pr tags
|
||||
// from end of the pre list, and beginning of the post list,
|
||||
// marking as vulnerable if the midpoint item we picked is.
|
||||
if (!/-/.test(String(pre[0]))) {
|
||||
const midVuln = this.testVersion(pre[pre.length - 1])
|
||||
while (/-/.test(String(pre[pre.length - 1]))) {
|
||||
const v = pre.pop()
|
||||
if (midVuln) {
|
||||
this[_markVulnerable](v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!/-/.test(String(post[post.length - 1]))) {
|
||||
const midVuln = this.testVersion(post[0])
|
||||
while (/-/.test(String(post[0]))) {
|
||||
const v = post.shift()
|
||||
if (midVuln) {
|
||||
this[_markVulnerable](v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
versionSets.add(pre)
|
||||
versionSets.add(post)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Advisory
|
15
package/node_modules/@npmcli/metavuln-calculator/lib/get-dep-spec.js
generated
vendored
Normal file
15
package/node_modules/@npmcli/metavuln-calculator/lib/get-dep-spec.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
module.exports = (mani, name) => {
|
||||
// skip dev because that only matters at the root,
|
||||
// where we aren't fetching a manifest from the registry
|
||||
// with multiple versions anyway.
|
||||
const {
|
||||
dependencies: deps = {},
|
||||
optionalDependencies: optDeps = {},
|
||||
peerDependencies: peerDeps = {},
|
||||
} = mani
|
||||
|
||||
return deps && typeof deps[name] === 'string' ? deps[name]
|
||||
: optDeps && typeof optDeps[name] === 'string' ? optDeps[name]
|
||||
: peerDeps && typeof peerDeps[name] === 'string' ? peerDeps[name]
|
||||
: null
|
||||
}
|
5
package/node_modules/@npmcli/metavuln-calculator/lib/hash.js
generated
vendored
Normal file
5
package/node_modules/@npmcli/metavuln-calculator/lib/hash.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const { createHash } = require('crypto')
|
||||
|
||||
module.exports = ({ name, source }) => createHash('sha512')
|
||||
.update(JSON.stringify([name, source]))
|
||||
.digest('base64')
|
128
package/node_modules/@npmcli/metavuln-calculator/lib/index.js
generated
vendored
Normal file
128
package/node_modules/@npmcli/metavuln-calculator/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
// this is the public class that is used by consumers.
|
||||
// the Advisory class handles all the calculation, and this
|
||||
// class handles all the IO with the registry and cache.
|
||||
const pacote = require('pacote')
|
||||
const cacache = require('cacache')
|
||||
const { time } = require('proc-log')
|
||||
const Advisory = require('./advisory.js')
|
||||
const { homedir } = require('os')
|
||||
const jsonParse = require('json-parse-even-better-errors')
|
||||
|
||||
const _packument = Symbol('packument')
|
||||
const _cachePut = Symbol('cachePut')
|
||||
const _cacheGet = Symbol('cacheGet')
|
||||
const _cacheData = Symbol('cacheData')
|
||||
const _packuments = Symbol('packuments')
|
||||
const _cache = Symbol('cache')
|
||||
const _options = Symbol('options')
|
||||
const _advisories = Symbol('advisories')
|
||||
const _calculate = Symbol('calculate')
|
||||
|
||||
class Calculator {
|
||||
constructor (options = {}) {
|
||||
this[_options] = { ...options }
|
||||
this[_cache] = this[_options].cache || (homedir() + '/.npm/_cacache')
|
||||
this[_options].cache = this[_cache]
|
||||
this[_packuments] = new Map()
|
||||
this[_cacheData] = new Map()
|
||||
this[_advisories] = new Map()
|
||||
}
|
||||
|
||||
get cache () {
|
||||
return this[_cache]
|
||||
}
|
||||
|
||||
get options () {
|
||||
return { ...this[_options] }
|
||||
}
|
||||
|
||||
async calculate (name, source) {
|
||||
const k = `security-advisory:${name}:${source.id}`
|
||||
if (this[_advisories].has(k)) {
|
||||
return this[_advisories].get(k)
|
||||
}
|
||||
|
||||
const p = this[_calculate](name, source)
|
||||
this[_advisories].set(k, p)
|
||||
return p
|
||||
}
|
||||
|
||||
async [_calculate] (name, source) {
|
||||
const k = `security-advisory:${name}:${source.id}`
|
||||
const timeEnd = time.start(`metavuln:calculate:${k}`)
|
||||
const advisory = new Advisory(name, source, this[_options])
|
||||
// load packument and cached advisory
|
||||
const [cached, packument] = await Promise.all([
|
||||
this[_cacheGet](advisory),
|
||||
this[_packument](name),
|
||||
])
|
||||
const timeEndLoad = time.start(`metavuln:load:${k}`)
|
||||
advisory.load(cached, packument)
|
||||
timeEndLoad()
|
||||
if (advisory.updated) {
|
||||
await this[_cachePut](advisory)
|
||||
}
|
||||
this[_advisories].set(k, advisory)
|
||||
timeEnd()
|
||||
return advisory
|
||||
}
|
||||
|
||||
async [_cachePut] (advisory) {
|
||||
const { name, id } = advisory
|
||||
const key = `security-advisory:${name}:${id}`
|
||||
const timeEnd = time.start(`metavuln:cache:put:${key}`)
|
||||
const data = JSON.stringify(advisory)
|
||||
const options = { ...this[_options] }
|
||||
this[_cacheData].set(key, jsonParse(data))
|
||||
await cacache.put(this[_cache], key, data, options).catch(() => {})
|
||||
timeEnd()
|
||||
}
|
||||
|
||||
async [_cacheGet] (advisory) {
|
||||
const { name, id } = advisory
|
||||
const key = `security-advisory:${name}:${id}`
|
||||
/* istanbul ignore if - should be impossible, since we memoize the
|
||||
* advisory object itself using the same key, just being cautious */
|
||||
if (this[_cacheData].has(key)) {
|
||||
return this[_cacheData].get(key)
|
||||
}
|
||||
|
||||
const timeEnd = time.start(`metavuln:cache:get:${key}`)
|
||||
const p = cacache.get(this[_cache], key, { ...this[_options] })
|
||||
.catch(() => ({ data: '{}' }))
|
||||
.then(({ data }) => {
|
||||
data = jsonParse(data)
|
||||
timeEnd()
|
||||
this[_cacheData].set(key, data)
|
||||
return data
|
||||
})
|
||||
this[_cacheData].set(key, p)
|
||||
return p
|
||||
}
|
||||
|
||||
async [_packument] (name) {
|
||||
if (this[_packuments].has(name)) {
|
||||
return this[_packuments].get(name)
|
||||
}
|
||||
|
||||
const timeEnd = time.start(`metavuln:packument:${name}`)
|
||||
const p = pacote.packument(name, { ...this[_options] })
|
||||
.catch(() => {
|
||||
// presumably not something from the registry.
|
||||
// an empty packument will have an effective range of *
|
||||
return {
|
||||
name,
|
||||
versions: {},
|
||||
}
|
||||
})
|
||||
.then(paku => {
|
||||
timeEnd()
|
||||
this[_packuments].set(name, paku)
|
||||
return paku
|
||||
})
|
||||
this[_packuments].set(name, p)
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Calculator
|
62
package/node_modules/@npmcli/metavuln-calculator/package.json
generated
vendored
Normal file
62
package/node_modules/@npmcli/metavuln-calculator/package.json
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"name": "@npmcli/metavuln-calculator",
|
||||
"version": "7.1.1",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
"bin/",
|
||||
"lib/"
|
||||
],
|
||||
"description": "Calculate meta-vulnerabilities from package security advisories",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/npm/metavuln-calculator.git"
|
||||
},
|
||||
"author": "GitHub Inc.",
|
||||
"license": "ISC",
|
||||
"scripts": {
|
||||
"test": "tap",
|
||||
"posttest": "npm run lint",
|
||||
"snap": "tap",
|
||||
"postsnap": "npm run lint",
|
||||
"eslint": "eslint",
|
||||
"lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
|
||||
"lintfix": "npm run lint -- --fix",
|
||||
"postlint": "template-oss-check",
|
||||
"template-oss-apply": "template-oss-apply --force"
|
||||
},
|
||||
"tap": {
|
||||
"check-coverage": true,
|
||||
"coverage-map": "map.js",
|
||||
"nyc-arg": [
|
||||
"--exclude",
|
||||
"tap-snapshots/**"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@npmcli/eslint-config": "^4.0.0",
|
||||
"@npmcli/template-oss": "4.22.0",
|
||||
"require-inject": "^1.4.4",
|
||||
"tap": "^16.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"cacache": "^18.0.0",
|
||||
"json-parse-even-better-errors": "^3.0.0",
|
||||
"pacote": "^18.0.0",
|
||||
"proc-log": "^4.1.0",
|
||||
"semver": "^7.3.5"
|
||||
},
|
||||
"engines": {
|
||||
"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.22.0",
|
||||
"publish": "true",
|
||||
"ciVersions": [
|
||||
"16.14.0",
|
||||
"16.x",
|
||||
"18.0.0",
|
||||
"18.x"
|
||||
]
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user