Removed the Requirement to Install Python and NodeJS (Now Bundled with Borealis)
This commit is contained in:
182
Dependencies/NodeJS/node_modules/npm/lib/utils/sbom-spdx.js
generated
vendored
Normal file
182
Dependencies/NodeJS/node_modules/npm/lib/utils/sbom-spdx.js
generated
vendored
Normal file
@ -0,0 +1,182 @@
|
||||
|
||||
const crypto = require('node:crypto')
|
||||
const normalizeData = require('normalize-package-data')
|
||||
const npa = require('npm-package-arg')
|
||||
const ssri = require('ssri')
|
||||
|
||||
const SPDX_SCHEMA_VERSION = 'SPDX-2.3'
|
||||
const SPDX_DATA_LICENSE = 'CC0-1.0'
|
||||
const SPDX_IDENTIFER = 'SPDXRef-DOCUMENT'
|
||||
|
||||
const NO_ASSERTION = 'NOASSERTION'
|
||||
|
||||
const REL_DESCRIBES = 'DESCRIBES'
|
||||
const REL_PREREQ = 'PREREQUISITE_FOR'
|
||||
const REL_OPTIONAL = 'OPTIONAL_DEPENDENCY_OF'
|
||||
const REL_DEV = 'DEV_DEPENDENCY_OF'
|
||||
const REL_DEP = 'DEPENDENCY_OF'
|
||||
|
||||
const REF_CAT_PACKAGE_MANAGER = 'PACKAGE-MANAGER'
|
||||
const REF_TYPE_PURL = 'purl'
|
||||
|
||||
const spdxOutput = ({ npm, nodes, packageType }) => {
|
||||
const rootNode = nodes.find(node => node.isRoot)
|
||||
const childNodes = nodes.filter(node => !node.isRoot && !node.isLink)
|
||||
const rootID = rootNode.pkgid
|
||||
const uuid = crypto.randomUUID()
|
||||
const ns = `http://spdx.org/spdxdocs/${npa(rootID).escapedName}-${rootNode.version}-${uuid}`
|
||||
|
||||
const relationships = []
|
||||
const seen = new Set()
|
||||
for (let node of nodes) {
|
||||
if (node.isLink) {
|
||||
node = node.target
|
||||
}
|
||||
|
||||
if (seen.has(node)) {
|
||||
continue
|
||||
}
|
||||
seen.add(node)
|
||||
|
||||
const rels = [...node.edgesOut.values()]
|
||||
// Filter out edges that are linking to nodes not in the list
|
||||
.filter(edge => nodes.find(n => n === edge.to))
|
||||
.map(edge => toSpdxRelationship(node, edge))
|
||||
.filter(rel => rel)
|
||||
|
||||
relationships.push(...rels)
|
||||
}
|
||||
|
||||
const extraRelationships = nodes.filter(node => node.extraneous)
|
||||
.map(node => toSpdxRelationship(rootNode, { to: node, type: 'optional' }))
|
||||
|
||||
relationships.push(...extraRelationships)
|
||||
|
||||
const bom = {
|
||||
spdxVersion: SPDX_SCHEMA_VERSION,
|
||||
dataLicense: SPDX_DATA_LICENSE,
|
||||
SPDXID: SPDX_IDENTIFER,
|
||||
name: rootID,
|
||||
documentNamespace: ns,
|
||||
creationInfo: {
|
||||
created: new Date().toISOString(),
|
||||
creators: [
|
||||
`Tool: npm/cli-${npm.version}`,
|
||||
],
|
||||
},
|
||||
documentDescribes: [toSpdxID(rootNode)],
|
||||
packages: [toSpdxItem(rootNode, { packageType }), ...childNodes.map(toSpdxItem)],
|
||||
relationships: [
|
||||
{
|
||||
spdxElementId: SPDX_IDENTIFER,
|
||||
relatedSpdxElement: toSpdxID(rootNode),
|
||||
relationshipType: REL_DESCRIBES,
|
||||
},
|
||||
...relationships,
|
||||
],
|
||||
}
|
||||
|
||||
return bom
|
||||
}
|
||||
|
||||
const toSpdxItem = (node, { packageType }) => {
|
||||
normalizeData(node.package)
|
||||
|
||||
// Calculate purl from package spec
|
||||
let spec = npa(node.pkgid)
|
||||
spec = (spec.type === 'alias') ? spec.subSpec : spec
|
||||
const purl = npa.toPurl(spec) + (isGitNode(node) ? `?vcs_url=${node.resolved}` : '')
|
||||
|
||||
/* For workspace nodes, use the location from their linkNode */
|
||||
let location = node.location
|
||||
if (node.isWorkspace && node.linksIn.size > 0) {
|
||||
location = node.linksIn.values().next().value.location
|
||||
}
|
||||
|
||||
let license = node.package?.license
|
||||
if (license) {
|
||||
if (typeof license === 'object') {
|
||||
license = license.type
|
||||
}
|
||||
}
|
||||
|
||||
const pkg = {
|
||||
name: node.packageName,
|
||||
SPDXID: toSpdxID(node),
|
||||
versionInfo: node.version,
|
||||
packageFileName: location,
|
||||
description: node.package?.description || undefined,
|
||||
primaryPackagePurpose: packageType ? packageType.toUpperCase() : undefined,
|
||||
downloadLocation: (node.isLink ? undefined : node.resolved) || NO_ASSERTION,
|
||||
filesAnalyzed: false,
|
||||
homepage: node.package?.homepage || NO_ASSERTION,
|
||||
licenseDeclared: license || NO_ASSERTION,
|
||||
externalRefs: [
|
||||
{
|
||||
referenceCategory: REF_CAT_PACKAGE_MANAGER,
|
||||
referenceType: REF_TYPE_PURL,
|
||||
referenceLocator: purl,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
if (node.integrity) {
|
||||
const integrity = ssri.parse(node.integrity, { single: true })
|
||||
pkg.checksums = [{
|
||||
algorithm: integrity.algorithm.toUpperCase(),
|
||||
checksumValue: integrity.hexDigest(),
|
||||
}]
|
||||
}
|
||||
return pkg
|
||||
}
|
||||
|
||||
const toSpdxRelationship = (node, edge) => {
|
||||
let type
|
||||
switch (edge.type) {
|
||||
case 'peer':
|
||||
type = REL_PREREQ
|
||||
break
|
||||
case 'optional':
|
||||
type = REL_OPTIONAL
|
||||
break
|
||||
case 'dev':
|
||||
type = REL_DEV
|
||||
break
|
||||
default:
|
||||
type = REL_DEP
|
||||
}
|
||||
|
||||
return {
|
||||
spdxElementId: toSpdxID(edge.to),
|
||||
relatedSpdxElement: toSpdxID(node),
|
||||
relationshipType: type,
|
||||
}
|
||||
}
|
||||
|
||||
const toSpdxID = (node) => {
|
||||
let name = node.packageName
|
||||
|
||||
// Strip leading @ for scoped packages
|
||||
name = name.replace(/^@/, '')
|
||||
|
||||
// Replace slashes with dots
|
||||
name = name.replace(/\//g, '.')
|
||||
|
||||
return `SPDXRef-Package-${name}-${node.version}`
|
||||
}
|
||||
|
||||
const isGitNode = (node) => {
|
||||
if (!node.resolved) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const { type } = npa(node.resolved)
|
||||
return type === 'git' || type === 'hosted'
|
||||
} catch (err) {
|
||||
/* istanbul ignore next */
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { spdxOutput }
|
Reference in New Issue
Block a user