@cyclonedx/cyclonedx-library
Version:
Core functionality of CycloneDX for JavaScript (Node.js or WebBrowser).
1,110 lines (1,106 loc) • 45.3 kB
JavaScript
"use strict";
/*!
This file is part of CycloneDX JavaScript Library.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
Copyright (c) OWASP Foundation. All Rights Reserved.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.VulnerabilityAffectedVersionNormalizer = exports.VulnerabilityAffectNormalizer = exports.VulnerabilityAnalysisNormalizer = exports.VulnerabilityCreditsNormalizer = exports.VulnerabilityAdvisoryNormalizer = exports.VulnerabilityRatingNormalizer = exports.VulnerabilityReferenceNormalizer = exports.VulnerabilitySourceNormalizer = exports.VulnerabilityNormalizer = exports.DependencyGraphNormalizer = exports.PropertyNormalizer = exports.AttachmentNormalizer = exports.ExternalReferenceNormalizer = exports.SWIDNormalizer = exports.LicenseNormalizer = exports.ComponentEvidenceNormalizer = exports.ServiceNormalizer = exports.ComponentNormalizer = exports.OrganizationalEntityNormalizer = exports.OrganizationalContactNormalizer = exports.HashNormalizer = exports.ToolsNormalizer = exports.ToolNormalizer = exports.LifecycleNormalizer = exports.MetadataNormalizer = exports.BomNormalizer = exports.Factory = void 0;
const iterable_1 = require("../../_helpers/iterable");
const notUndefined_1 = require("../../_helpers/notUndefined");
const tree_1 = require("../../_helpers/tree");
const uri_1 = require("../../_helpers/uri");
const models_1 = require("../../models");
const license_1 = require("../../models/license");
const lifecycle_1 = require("../../models/lifecycle");
const affect_1 = require("../../models/vulnerability/affect");
const spdx_1 = require("../../spdx");
const enums_1 = require("../../spec/enums");
const _xsd_1 = require("./_xsd");
const types_1 = require("./types");
class Factory {
#spec;
constructor(spec) {
this.#spec = spec;
}
get spec() {
return this.#spec;
}
makeForBom() {
return new BomNormalizer(this);
}
makeForMetadata() {
return new MetadataNormalizer(this);
}
makeForLifecycle() {
return new LifecycleNormalizer(this);
}
makeForComponent() {
return new ComponentNormalizer(this);
}
makeForService() {
return new ServiceNormalizer(this);
}
makeForComponentEvidence() {
return new ComponentEvidenceNormalizer(this);
}
makeForTool() {
return new ToolNormalizer(this);
}
makeForTools() {
return new ToolsNormalizer(this);
}
makeForOrganizationalContact() {
return new OrganizationalContactNormalizer(this);
}
makeForOrganizationalEntity() {
return new OrganizationalEntityNormalizer(this);
}
makeForHash() {
return new HashNormalizer(this);
}
makeForLicense() {
return new LicenseNormalizer(this);
}
makeForSWID() {
return new SWIDNormalizer(this);
}
makeForExternalReference() {
return new ExternalReferenceNormalizer(this);
}
makeForAttachment() {
return new AttachmentNormalizer(this);
}
makeForProperty() {
return new PropertyNormalizer(this);
}
makeForDependencyGraph() {
return new DependencyGraphNormalizer(this);
}
makeForVulnerability() {
return new VulnerabilityNormalizer(this);
}
makeForVulnerabilitySource() {
return new VulnerabilitySourceNormalizer(this);
}
makeForVulnerabilityReference() {
return new VulnerabilityReferenceNormalizer(this);
}
makeForVulnerabilityRating() {
return new VulnerabilityRatingNormalizer(this);
}
makeForVulnerabilityAdvisory() {
return new VulnerabilityAdvisoryNormalizer(this);
}
makeForVulnerabilityCredits() {
return new VulnerabilityCreditsNormalizer(this);
}
makeForVulnerabilityAffect() {
return new VulnerabilityAffectNormalizer(this);
}
makeForVulnerabilityAffectedVersion() {
return new VulnerabilityAffectedVersionNormalizer(this);
}
makeForVulnerabilityAnalysis() {
return new VulnerabilityAnalysisNormalizer(this);
}
}
exports.Factory = Factory;
const xmlNamespace = new Map([
[enums_1.Version.v1dot6, 'http://cyclonedx.org/schema/bom/1.6'],
[enums_1.Version.v1dot5, 'http://cyclonedx.org/schema/bom/1.5'],
[enums_1.Version.v1dot4, 'http://cyclonedx.org/schema/bom/1.4'],
[enums_1.Version.v1dot3, 'http://cyclonedx.org/schema/bom/1.3'],
[enums_1.Version.v1dot2, 'http://cyclonedx.org/schema/bom/1.2'],
[enums_1.Version.v1dot1, 'http://cyclonedx.org/schema/bom/1.1'],
[enums_1.Version.v1dot0, 'http://cyclonedx.org/schema/bom/1.0']
]);
class BaseXmlNormalizer {
_factory;
constructor(factory) {
this._factory = factory;
}
get factory() {
return this._factory;
}
}
class BomNormalizer extends BaseXmlNormalizer {
normalize(data, options) {
const components = {
type: 'element',
name: 'components',
children: data.components.size > 0
? this._factory.makeForComponent().normalizeIterable(data.components, options, 'component')
: undefined
};
const services = this._factory.spec.supportsServices && data.services.size > 0
? {
type: 'element',
name: 'services',
children: this._factory.makeForService().normalizeIterable(data.services, options, 'service')
}
: undefined;
const vulnerabilities = this._factory.spec.supportsVulnerabilities && data.vulnerabilities.size > 0
? {
type: 'element',
name: 'vulnerabilities',
children: this._factory.makeForVulnerability().normalizeIterable(data.vulnerabilities, options, 'vulnerability')
}
: undefined;
return {
type: 'element',
name: 'bom',
namespace: xmlNamespace.get(this._factory.spec.version),
attributes: {
version: data.version,
serialNumber: this.#isEligibleSerialNumber(data.serialNumber)
? data.serialNumber
: undefined
},
children: [
this._factory.makeForMetadata().normalize(data.metadata, options, 'metadata'),
components,
services,
this._factory.spec.supportsDependencyGraph
? this._factory.makeForDependencyGraph().normalize(data, options, 'dependencies')
: undefined,
vulnerabilities
].filter(notUndefined_1.isNotUndefined)
};
}
#isEligibleSerialNumber(v) {
return v !== undefined &&
/^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$|^\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}$/.test(v);
}
}
exports.BomNormalizer = BomNormalizer;
class MetadataNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
const orgEntityNormalizer = this._factory.makeForOrganizationalEntity();
const lifecycles = this._factory.spec.supportsMetadataLifecycles && data.lifecycles.size > 0
? {
type: 'element',
name: 'lifecycles',
children: this._factory.makeForLifecycle().normalizeIterable(data.lifecycles, options, 'lifecycle')
}
: undefined;
const tools = data.tools.size > 0
? this._factory.makeForTools().normalize(data.tools, options, 'tools')
: undefined;
const authors = data.authors.size > 0
? {
type: 'element',
name: 'authors',
children: this._factory.makeForOrganizationalContact().normalizeIterable(data.authors, options, 'author')
}
: undefined;
const licenses = this._factory.spec.supportsMetadataLicenses && data.licenses.size > 0
? {
type: 'element',
name: 'licenses',
children: this._factory.makeForLicense().normalizeIterable(data.licenses, options)
}
: undefined;
const properties = this._factory.spec.supportsMetadataProperties && data.properties.size > 0
? {
type: 'element',
name: 'properties',
children: this._factory.makeForProperty().normalizeIterable(data.properties, options, 'property')
}
: undefined;
return {
type: 'element',
name: elementName,
children: [
makeOptionalDateTimeElement(data.timestamp, 'timestamp'),
lifecycles,
tools,
authors,
data.component === undefined
? undefined
: this._factory.makeForComponent().normalize(data.component, options, 'component'),
data.manufacture === undefined
? undefined
: orgEntityNormalizer.normalize(data.manufacture, options, 'manufacture'),
data.supplier === undefined
? undefined
: orgEntityNormalizer.normalize(data.supplier, options, 'supplier'),
licenses,
properties
].filter(notUndefined_1.isNotUndefined)
};
}
}
exports.MetadataNormalizer = MetadataNormalizer;
class LifecycleNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
return data instanceof lifecycle_1.NamedLifecycle
? {
type: 'element',
name: elementName,
children: [
makeTextElement(data.name, 'name', _xsd_1.normalizedString),
makeOptionalTextElement(data.description, 'description')
].filter(notUndefined_1.isNotUndefined)
}
: {
type: 'element',
name: elementName,
children: [
makeTextElement(data, 'phase')
]
};
}
normalizeIterable(data, options, elementName) {
return (options.sortLists ?? false
? data.sorted()
: Array.from(data)).map(t => this.normalize(t, options, elementName));
}
}
exports.LifecycleNormalizer = LifecycleNormalizer;
class ToolNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
const hashes = data.hashes.size > 0
? {
type: 'element',
name: 'hashes',
children: this._factory.makeForHash().normalizeIterable(data.hashes, options, 'hash')
}
: undefined;
const externalReferences = this._factory.spec.supportsToolReferences && data.externalReferences.size > 0
? {
type: 'element',
name: 'externalReferences',
children: this._factory.makeForExternalReference().normalizeIterable(data.externalReferences, options, 'reference')
}
: undefined;
return {
type: 'element',
name: elementName,
children: [
makeOptionalTextElement(data.vendor, 'vendor', _xsd_1.normalizedString),
makeOptionalTextElement(data.name, 'name', _xsd_1.normalizedString),
makeOptionalTextElement(data.version, 'version', _xsd_1.normalizedString),
hashes,
externalReferences
].filter(notUndefined_1.isNotUndefined)
};
}
normalizeIterable(data, options, elementName) {
return (options.sortLists ?? false
? data.sorted()
: Array.from(data)).map(t => this.normalize(t, options, elementName));
}
}
exports.ToolNormalizer = ToolNormalizer;
class ToolsNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
let children = [];
if (data.tools.size > 0 || !this._factory.spec.supportsToolsComponentsServices) {
children = this._factory.makeForTool().normalizeIterable(new models_1.ToolRepository((0, iterable_1.chainI)(Array.from(data.components, models_1.Tool.fromComponent), Array.from(data.services, models_1.Tool.fromService), data.tools)), options, 'tool');
}
else {
if (data.components.size > 0) {
children.push({
type: 'element',
name: 'components',
children: this._factory.makeForComponent().normalizeIterable(data.components, options, 'component')
});
}
if (data.services.size > 0) {
children.push({
type: 'element',
name: 'services',
children: this._factory.makeForService().normalizeIterable(data.services, options, 'service')
});
}
}
return {
type: 'element',
name: elementName,
children
};
}
}
exports.ToolsNormalizer = ToolsNormalizer;
class HashNormalizer extends BaseXmlNormalizer {
normalize([algorithm, content], options, elementName) {
const spec = this._factory.spec;
return spec.supportsHashAlgorithm(algorithm) && spec.supportsHashValue(content)
? {
type: 'element',
name: elementName,
attributes: { alg: algorithm },
children: (0, _xsd_1.token)(content)
}
: undefined;
}
normalizeIterable(data, options, elementName) {
return (options.sortLists ?? false
? data.sorted()
: Array.from(data)).map(h => this.normalize(h, options, elementName)).filter(notUndefined_1.isNotUndefined);
}
}
exports.HashNormalizer = HashNormalizer;
class OrganizationalContactNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
return {
type: 'element',
name: elementName,
children: [
makeOptionalTextElement(data.name, 'name', _xsd_1.normalizedString),
makeOptionalTextElement(data.email, 'email', _xsd_1.normalizedString),
makeOptionalTextElement(data.phone, 'phone', _xsd_1.normalizedString)
].filter(notUndefined_1.isNotUndefined)
};
}
normalizeIterable(data, options, elementName) {
return (options.sortLists ?? false
? data.sorted()
: Array.from(data)).map(oc => this.normalize(oc, options, elementName));
}
}
exports.OrganizationalContactNormalizer = OrganizationalContactNormalizer;
class OrganizationalEntityNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
return {
type: 'element',
name: elementName,
children: [
makeOptionalTextElement(data.name, 'name', _xsd_1.normalizedString),
...makeTextElementIter(Array.from(data.url, (s) => (0, uri_1.escapeUri)(s.toString())), options, 'url').filter(({ children: u }) => types_1.XmlSchema.isAnyURI(u)),
...this._factory.makeForOrganizationalContact().normalizeIterable(data.contact, options, 'contact')
].filter(notUndefined_1.isNotUndefined)
};
}
normalizeIterable(data, options, elementName) {
return (options.sortLists ?? false
? data.sorted()
: Array.from(data)).map(oe => this.normalize(oe, options, elementName));
}
}
exports.OrganizationalEntityNormalizer = OrganizationalEntityNormalizer;
class ComponentNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
const spec = this._factory.spec;
if (!spec.supportsComponentType(data.type)) {
return undefined;
}
const supplier = data.supplier === undefined
? undefined
: this._factory.makeForOrganizationalEntity().normalize(data.supplier, options, 'supplier');
const version = (spec.requiresComponentVersion
? makeTextElement
: makeOptionalTextElement)(data.version ?? '', 'version', _xsd_1.normalizedString);
const hashes = data.hashes.size > 0
? {
type: 'element',
name: 'hashes',
children: this._factory.makeForHash().normalizeIterable(data.hashes, options, 'hash')
}
: undefined;
const licenses = data.licenses.size > 0
? {
type: 'element',
name: 'licenses',
children: this._factory.makeForLicense().normalizeIterable(data.licenses, options)
}
: undefined;
const swid = data.swid === undefined
? undefined
: this._factory.makeForSWID().normalize(data.swid, options, 'swid');
const extRefs = data.externalReferences.size > 0
? {
type: 'element',
name: 'externalReferences',
children: this._factory.makeForExternalReference().normalizeIterable(data.externalReferences, options, 'reference')
}
: undefined;
const properties = spec.supportsProperties(data) && data.properties.size > 0
? {
type: 'element',
name: 'properties',
children: this._factory.makeForProperty().normalizeIterable(data.properties, options, 'property')
}
: undefined;
const components = data.components.size > 0
? {
type: 'element',
name: 'components',
children: this.normalizeIterable(data.components, options, 'component')
}
: undefined;
const evidence = spec.supportsComponentEvidence && data.evidence !== undefined
? this._factory.makeForComponentEvidence().normalize(data.evidence, options, 'evidence')
: undefined;
return {
type: 'element',
name: elementName,
attributes: {
type: data.type,
'bom-ref': data.bomRef.value
},
children: [
supplier,
makeOptionalTextElement(data.author, 'author', _xsd_1.normalizedString),
makeOptionalTextElement(data.publisher, 'publisher', _xsd_1.normalizedString),
makeOptionalTextElement(data.group, 'group', _xsd_1.normalizedString),
makeTextElement(data.name, 'name', _xsd_1.normalizedString),
version,
makeOptionalTextElement(data.description, 'description', _xsd_1.normalizedString),
makeOptionalTextElement(data.scope, 'scope'),
hashes,
licenses,
makeOptionalTextElement(data.copyright, 'copyright', _xsd_1.normalizedString),
makeOptionalTextElement(data.cpe, 'cpe'),
makeOptionalTextElement(data.purl, 'purl'),
swid,
extRefs,
properties,
components,
evidence
].filter(notUndefined_1.isNotUndefined)
};
}
normalizeIterable(data, options, elementName) {
return (options.sortLists ?? false
? data.sorted()
: Array.from(data)).map(c => this.normalize(c, options, elementName)).filter(notUndefined_1.isNotUndefined);
}
}
exports.ComponentNormalizer = ComponentNormalizer;
class ServiceNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
const spec = this._factory.spec;
const provider = data.provider === undefined
? undefined
: this._factory.makeForOrganizationalEntity().normalize(data.provider, options, 'provider');
const licenses = data.licenses.size > 0
? {
type: 'element',
name: 'licenses',
children: this._factory.makeForLicense().normalizeIterable(data.licenses, options)
}
: undefined;
const extRefs = data.externalReferences.size > 0
? {
type: 'element',
name: 'externalReferences',
children: this._factory.makeForExternalReference().normalizeIterable(data.externalReferences, options, 'reference')
}
: undefined;
const properties = spec.supportsProperties(data) && data.properties.size > 0
? {
type: 'element',
name: 'properties',
children: this._factory.makeForProperty().normalizeIterable(data.properties, options, 'property')
}
: undefined;
const services = data.services.size > 0
? {
type: 'element',
name: 'services',
children: this.normalizeIterable(data.services, options, 'service')
}
: undefined;
return {
type: 'element',
name: elementName,
attributes: {
'bom-ref': data.bomRef.value
},
children: [
provider,
makeOptionalTextElement(data.group, 'group', _xsd_1.normalizedString),
makeTextElement(data.name, 'name', _xsd_1.normalizedString),
makeOptionalTextElement(data.version, 'version', _xsd_1.normalizedString),
makeOptionalTextElement(data.description, 'description', _xsd_1.normalizedString),
licenses,
extRefs,
properties,
services,
].filter(notUndefined_1.isNotUndefined)
};
}
normalizeIterable(data, options, elementName) {
return (options.sortLists ?? false
? data.sorted()
: Array.from(data)).map(s => this.normalize(s, options, elementName));
}
}
exports.ServiceNormalizer = ServiceNormalizer;
class ComponentEvidenceNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
const licenses = data.licenses.size > 0
? {
type: 'element',
name: 'licenses',
children: this._factory.makeForLicense().normalizeIterable(data.licenses, options)
}
: undefined;
const copyright = data.copyright.size > 0
? {
type: 'element',
name: 'copyright',
children: makeTextElementIter(data.copyright, options, 'text')
}
: undefined;
return {
type: 'element',
name: elementName,
children: [
licenses,
copyright
].filter(notUndefined_1.isNotUndefined)
};
}
}
exports.ComponentEvidenceNormalizer = ComponentEvidenceNormalizer;
class LicenseNormalizer extends BaseXmlNormalizer {
normalize(data, options) {
switch (true) {
case data instanceof license_1.NamedLicense:
return this.#normalizeNamedLicense(data, options);
case data instanceof license_1.SpdxLicense:
return (0, spdx_1.isSupportedSpdxId)(data.id)
? this.#normalizeSpdxLicense(data, options)
: this.#normalizeNamedLicense(new license_1.NamedLicense(data.id, { url: data.url }), options);
case data instanceof license_1.LicenseExpression:
return this.#normalizeLicenseExpression(data);
default:
throw new TypeError('Unexpected LicenseChoice');
}
}
#normalizeNamedLicense(data, options) {
const url = (0, uri_1.escapeUri)(data.url?.toString());
return {
type: 'element',
name: 'license',
attributes: {
acknowledgement: this._factory.spec.supportsLicenseAcknowledgement
? data.acknowledgement
: undefined
},
children: [
makeTextElement(data.name, 'name', _xsd_1.normalizedString),
data.text === undefined
? undefined
: this._factory.makeForAttachment().normalize(data.text, options, 'text'),
types_1.XmlSchema.isAnyURI(url)
? makeTextElement(url, 'url')
: undefined
].filter(notUndefined_1.isNotUndefined)
};
}
#normalizeSpdxLicense(data, options) {
const url = (0, uri_1.escapeUri)(data.url?.toString());
return {
type: 'element',
name: 'license',
attributes: {
acknowledgement: this._factory.spec.supportsLicenseAcknowledgement
? data.acknowledgement
: undefined
},
children: [
makeTextElement(data.id, 'id'),
data.text === undefined
? undefined
: this._factory.makeForAttachment().normalize(data.text, options, 'text'),
types_1.XmlSchema.isAnyURI(url)
? makeTextElement(url, 'url')
: undefined
].filter(notUndefined_1.isNotUndefined)
};
}
#normalizeLicenseExpression(data) {
const elem = makeTextElement(data.expression, 'expression', _xsd_1.normalizedString);
elem.attributes = {
acknowledgement: this._factory.spec.supportsLicenseAcknowledgement
? data.acknowledgement
: undefined
};
return elem;
}
normalizeIterable(data, options) {
const licenses = options.sortLists ?? false
? data.sorted()
: Array.from(data);
if (licenses.length > 1) {
const expressions = licenses.filter(l => l instanceof license_1.LicenseExpression);
if (expressions.length > 0) {
return [this.#normalizeLicenseExpression(expressions[0])];
}
}
return licenses.map(l => this.normalize(l, options));
}
}
exports.LicenseNormalizer = LicenseNormalizer;
class SWIDNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
const url = (0, uri_1.escapeUri)(data.url?.toString());
return {
type: 'element',
name: elementName,
attributes: {
tagId: data.tagId,
name: data.name,
version: data.version || undefined,
tagVersion: data.tagVersion,
patch: data.patch === undefined
? undefined
: (data.patch ? 'true' : 'false')
},
children: [
data.text === undefined
? undefined
: this._factory.makeForAttachment().normalize(data.text, options, 'text'),
types_1.XmlSchema.isAnyURI(url)
? makeTextElement(url, 'url')
: undefined
].filter(notUndefined_1.isNotUndefined)
};
}
}
exports.SWIDNormalizer = SWIDNormalizer;
class ExternalReferenceNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
const url = (0, uri_1.escapeUri)(data.url.toString());
const hashes = this._factory.spec.supportsExternalReferenceHashes && data.hashes.size > 0
? {
type: 'element',
name: 'hashes',
children: this._factory.makeForHash().normalizeIterable(data.hashes, options, 'hash')
}
: undefined;
return this._factory.spec.supportsExternalReferenceType(data.type) &&
types_1.XmlSchema.isAnyURI(url)
? {
type: 'element',
name: elementName,
attributes: {
type: data.type
},
children: [
makeTextElement(url, 'url'),
makeOptionalTextElement(data.comment, 'comment'),
hashes
].filter(notUndefined_1.isNotUndefined)
}
: undefined;
}
normalizeIterable(data, options, elementName) {
return (options.sortLists ?? false
? data.sorted()
: Array.from(data)).map(r => this.normalize(r, options, elementName)).filter(notUndefined_1.isNotUndefined);
}
}
exports.ExternalReferenceNormalizer = ExternalReferenceNormalizer;
class AttachmentNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
return {
type: 'element',
name: elementName,
attributes: {
'content-type': data.contentType
? (0, _xsd_1.normalizedString)(data.contentType)
: undefined,
encoding: data.encoding || undefined
},
children: data.content.toString()
};
}
}
exports.AttachmentNormalizer = AttachmentNormalizer;
class PropertyNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
return {
type: 'element',
name: elementName,
attributes: {
name: data.name
},
children: (0, _xsd_1.normalizedString)(data.value)
};
}
normalizeIterable(data, options, elementName) {
return (options.sortLists ?? false
? data.sorted()
: Array.from(data)).map(p => this.normalize(p, options, elementName));
}
}
exports.PropertyNormalizer = PropertyNormalizer;
class DependencyGraphNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
const allRefs = new Map();
if (data.metadata.component !== undefined) {
allRefs.set(data.metadata.component.bomRef, data.metadata.component.dependencies);
for (const component of data.metadata.component.components[tree_1.treeIteratorSymbol]()) {
allRefs.set(component.bomRef, component.dependencies);
}
}
for (const component of data.components[tree_1.treeIteratorSymbol]()) {
allRefs.set(component.bomRef, component.dependencies);
}
for (const service of data.services[tree_1.treeIteratorSymbol]()) {
allRefs.set(service.bomRef, service.dependencies);
}
const normalized = [];
for (const [ref, deps] of allRefs) {
const dep = this.#normalizeDependency(ref, deps, allRefs, options);
if ((0, notUndefined_1.isNotUndefined)(dep)) {
normalized.push(dep);
}
}
if (options.sortLists ?? false) {
normalized.sort(({ attributes: { ref: a } }, { attributes: { ref: b } }) => a.localeCompare(b));
}
return {
type: 'element',
name: elementName,
children: normalized
};
}
#normalizeDependency(ref, deps, allRefs, options) {
const bomRef = ref.toString();
if (bomRef.length === 0) {
return undefined;
}
const dependsOn = Array.from(deps).filter(d => allRefs.has(d) && d !== ref)
.map(d => d.toString()).filter(d => d.length > 0);
if (options.sortLists ?? false) {
dependsOn.sort((a, b) => a.localeCompare(b));
}
return {
type: 'element',
name: 'dependency',
attributes: { ref: bomRef },
children: dependsOn.map(d => ({
type: 'element',
name: 'dependency',
attributes: { ref: d }
}))
};
}
}
exports.DependencyGraphNormalizer = DependencyGraphNormalizer;
class VulnerabilityNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
const references = data.references.size > 0
? {
type: 'element',
name: 'references',
children: this._factory.makeForVulnerabilityReference().normalizeIterable(data.references, options, 'reference')
}
: undefined;
const ratings = data.ratings.size > 0
? {
type: 'element',
name: 'ratings',
children: this._factory.makeForVulnerabilityRating().normalizeIterable(data.ratings, options, 'rating')
}
: undefined;
const cwes = data.cwes.size > 0
? {
type: 'element',
name: 'cwes',
children: (options.sortLists
? data.cwes.sorted()
: Array.from(data.cwes)).map(cwe => makeTextElement(cwe, 'cwe'))
}
: undefined;
const advisories = data.advisories.size > 0
? {
type: 'element',
name: 'advisories',
children: this._factory.makeForVulnerabilityAdvisory().normalizeIterable(data.advisories, options, 'advisory')
}
: undefined;
const tools = data.tools.size > 0
? this._factory.makeForTools().normalize(data.tools, options, 'tools')
: undefined;
const affects = data.affects.size > 0
? {
type: 'element',
name: 'affects',
children: this._factory.makeForVulnerabilityAffect().normalizeIterable(data.affects, options, 'target')
}
: undefined;
const properties = data.properties.size > 0
? {
type: 'element',
name: 'properties',
children: this._factory.makeForProperty().normalizeIterable(data.properties, options, 'property')
}
: undefined;
return {
type: 'element',
name: elementName,
attributes: { 'bom-ref': data.bomRef.value || undefined },
children: [
makeOptionalTextElement(data.id, 'id', _xsd_1.normalizedString),
data.source === undefined
? undefined
: this._factory.makeForVulnerabilitySource().normalize(data.source, options, 'source'),
references,
ratings,
cwes,
makeOptionalTextElement(data.description, 'description'),
makeOptionalTextElement(data.detail, 'detail'),
makeOptionalTextElement(data.recommendation, 'recommendation'),
advisories,
makeOptionalDateTimeElement(data.created, 'created'),
makeOptionalDateTimeElement(data.created, 'published'),
makeOptionalDateTimeElement(data.created, 'updated'),
data.credits === undefined
? undefined
: this._factory.makeForVulnerabilityCredits().normalize(data.credits, options, 'credits'),
tools,
data.analysis === undefined
? undefined
: this._factory.makeForVulnerabilityAnalysis().normalize(data.analysis, options, 'analysis'),
affects,
properties
].filter(notUndefined_1.isNotUndefined)
};
}
normalizeIterable(data, options, elementName) {
return (options.sortLists ?? false
? data.sorted()
: Array.from(data)).map(v => this.normalize(v, options, elementName));
}
}
exports.VulnerabilityNormalizer = VulnerabilityNormalizer;
class VulnerabilitySourceNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
const url = (0, uri_1.escapeUri)(data.url?.toString());
return {
type: 'element',
name: elementName,
children: [
makeOptionalTextElement(data.name, 'name', _xsd_1.normalizedString),
types_1.XmlSchema.isAnyURI(url)
? makeTextElement(url, 'url')
: undefined
].filter(notUndefined_1.isNotUndefined)
};
}
}
exports.VulnerabilitySourceNormalizer = VulnerabilitySourceNormalizer;
class VulnerabilityReferenceNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
return {
type: 'element',
name: elementName,
children: [
makeTextElement(data.id, 'id'),
this._factory.makeForVulnerabilitySource().normalize(data.source, options, 'source')
]
};
}
normalizeIterable(data, options, elementName) {
return (options.sortLists ?? false
? data.sorted()
: Array.from(data)).map(r => this.normalize(r, options, elementName));
}
}
exports.VulnerabilityReferenceNormalizer = VulnerabilityReferenceNormalizer;
class VulnerabilityRatingNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
return {
type: 'element',
name: elementName,
children: [
data.source === undefined
? undefined
: this._factory.makeForVulnerabilitySource().normalize(data.source, options, 'source'),
makeOptionalTextElement(data.score, 'score'),
makeOptionalTextElement(data.severity, 'severity'),
this._factory.spec.supportsVulnerabilityRatingMethod(data.method)
? makeOptionalTextElement(data.method, 'method')
: undefined,
makeOptionalTextElement(data.vector, 'vector', _xsd_1.normalizedString),
makeOptionalTextElement(data.justification, 'justification')
].filter(notUndefined_1.isNotUndefined)
};
}
normalizeIterable(data, options, elementName) {
return (options.sortLists ?? false
? data.sorted()
: Array.from(data)).map(r => this.normalize(r, options, elementName));
}
}
exports.VulnerabilityRatingNormalizer = VulnerabilityRatingNormalizer;
class VulnerabilityAdvisoryNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
const url = (0, uri_1.escapeUri)(data.url.toString());
if (!types_1.XmlSchema.isAnyURI(url)) {
return undefined;
}
return {
type: 'element',
name: elementName,
children: [
makeOptionalTextElement(data.title, 'title'),
makeTextElement(url, 'url')
].filter(notUndefined_1.isNotUndefined)
};
}
normalizeIterable(data, options, elementName) {
return (options.sortLists ?? false
? data.sorted()
: Array.from(data)).map(a => this.normalize(a, options, elementName)).filter(notUndefined_1.isNotUndefined);
}
}
exports.VulnerabilityAdvisoryNormalizer = VulnerabilityAdvisoryNormalizer;
class VulnerabilityCreditsNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
const organizations = data.organizations.size > 0
? {
type: 'element',
name: 'organizations',
children: this._factory.makeForOrganizationalEntity().normalizeIterable(data.organizations, options, 'organization')
}
: undefined;
const individuals = data.individuals.size > 0
? {
type: 'element',
name: 'individuals',
children: this._factory.makeForOrganizationalContact().normalizeIterable(data.individuals, options, 'individual')
}
: undefined;
return {
type: 'element',
name: elementName,
children: [
organizations,
individuals
].filter(notUndefined_1.isNotUndefined)
};
}
}
exports.VulnerabilityCreditsNormalizer = VulnerabilityCreditsNormalizer;
class VulnerabilityAnalysisNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
const responses = data.response.size > 0
? {
type: 'element',
name: 'responses',
children: (options.sortLists ?? false
? data.response.sorted()
: Array.from(data.response)).map(ar => makeTextElement(ar, 'response'))
}
: undefined;
return {
type: 'element',
name: elementName,
children: [
makeOptionalTextElement(data.state, 'state'),
makeOptionalTextElement(data.justification, 'justification'),
responses,
makeOptionalTextElement(data.detail, 'detail')
].filter(notUndefined_1.isNotUndefined)
};
}
}
exports.VulnerabilityAnalysisNormalizer = VulnerabilityAnalysisNormalizer;
class VulnerabilityAffectNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
const versions = data.versions.size > 0
? {
type: 'element',
name: 'versions',
children: this._factory.makeForVulnerabilityAffectedVersion().normalizeIterable(data.versions, options, 'version')
}
: undefined;
return {
type: 'element',
name: elementName,
children: [
makeTextElement(data.ref, 'ref'),
versions
].filter(notUndefined_1.isNotUndefined)
};
}
normalizeIterable(data, options, elementName) {
return (options.sortLists ?? false
? data.sorted()
: Array.from(data)).map(a => this.normalize(a, options, elementName));
}
}
exports.VulnerabilityAffectNormalizer = VulnerabilityAffectNormalizer;
class VulnerabilityAffectedVersionNormalizer extends BaseXmlNormalizer {
normalize(data, options, elementName) {
switch (true) {
case data instanceof affect_1.AffectedSingleVersion:
return this.#normalizeAffectedSingleVersion(data, elementName);
case data instanceof affect_1.AffectedVersionRange:
return this.#normalizeAffectedVersionRange(data, elementName);
default:
throw new TypeError('Unexpected Vulnerability AffectedVersion');
}
}
#normalizeAffectedSingleVersion(data, elementName) {
return {
type: 'element',
name: elementName,
children: [
makeTextElement(data.version, 'version', _xsd_1.normalizedString),
makeOptionalTextElement(data.status, 'status')
].filter(notUndefined_1.isNotUndefined)
};
}
#normalizeAffectedVersionRange(data, elementName) {
return {
type: 'element',
name: elementName,
children: [
makeTextElement(data.range, 'range', _xsd_1.normalizedString),
makeOptionalTextElement(data.status, 'status')
].filter(notUndefined_1.isNotUndefined)
};
}
normalizeIterable(data, options, elementName) {
return (options.sortLists ?? false
? data.sorted()
: Array.from(data)).map(av => this.normalize(av, options, elementName));
}
}
exports.VulnerabilityAffectedVersionNormalizer = VulnerabilityAffectedVersionNormalizer;
const noTEM = (s) => s;
function makeOptionalTextElement(data, elementName, mod = noTEM) {
const s = mod(data?.toString() ?? '');
return s.length > 0
? makeTextElement(s, elementName)
: undefined;
}
function makeTextElement(data, elementName, mod = noTEM) {
return {
type: 'element',
name: elementName,
children: mod(data.toString())
};
}
function makeTextElementIter(data, options, elementName, mod = noTEM) {
const r = Array.from(data, d => makeTextElement(d, elementName, mod));
if (options.sortLists ?? false) {
r.sort(({ children: a }, { children: b }) => a.localeCompare(b));
}
return r;
}
function makeOptionalDateTimeElement(data, elementName, mod = noTEM) {
const d = data?.toISOString();
return d === undefined
? undefined
: makeTextElement(d, elementName, mod);
}
//# sourceMappingURL=normalize.js.map