Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Metadata.licenses & Metadata.properties #1020

Merged
merged 5 commits into from
Feb 26, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -34,6 +34,8 @@ Run the tests:
npm test
```

See the [dedicated test docs](tests/README.md) for details and advanced instructions.

## Coding standards

Apply coding standards via:
7 changes: 7 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.

## unreleased

* Added
* Class `Models.Metadata` got a new property `licenses` ([#1019] via [#1020])
* Class `Models.Metadata` got a new property `properties` ([#1019] via [#1020])

[#1019]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1019
[#1020]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1020

## 6.3.2 -- 2024-02-25

* Refactor
8 changes: 8 additions & 0 deletions src/models/metadata.ts
Original file line number Diff line number Diff line change
@@ -18,9 +18,11 @@ Copyright (c) OWASP Foundation. All Rights Reserved.
*/

import type { Component } from './component'
import { LicenseRepository } from './license'
import { LifecycleRepository } from './lifecycle'
import { OrganizationalContactRepository } from './organizationalContact'
import type { OrganizationalEntity } from './organizationalEntity'
import { PropertyRepository } from './property'
import { ToolRepository } from './tool'

export interface OptionalMetadataProperties {
@@ -31,6 +33,8 @@ export interface OptionalMetadataProperties {
component?: Metadata['component']
manufacture?: Metadata['manufacture']
supplier?: Metadata['supplier']
licenses?: Metadata['licenses']
properties?: Metadata['properties']
}

export class Metadata {
@@ -41,6 +45,8 @@ export class Metadata {
component?: Component
manufacture?: OrganizationalEntity
supplier?: OrganizationalEntity
licenses: LicenseRepository
properties: PropertyRepository

constructor (op: OptionalMetadataProperties = {}) {
this.timestamp = op.timestamp
@@ -50,5 +56,7 @@ export class Metadata {
this.component = op.component
this.manufacture = op.manufacture
this.supplier = op.supplier
this.licenses = op.licenses ?? new LicenseRepository()
this.properties = op.properties ?? new PropertyRepository()
}
}
8 changes: 7 additions & 1 deletion src/serialize/json/normalize.ts
Original file line number Diff line number Diff line change
@@ -223,7 +223,13 @@ export class MetadataNormalizer extends BaseJsonNormalizer<Models.Metadata> {
: orgEntityNormalizer.normalize(data.manufacture, options),
supplier: data.supplier === undefined
? undefined
: orgEntityNormalizer.normalize(data.supplier, options)
: orgEntityNormalizer.normalize(data.supplier, options),
licenses: this._factory.spec.supportsMetadataLicenses && data.licenses.size > 0
? this._factory.makeForLicense().normalizeIterable(data.licenses, options)
: undefined,
properties: this._factory.spec.supportsMetadataProperties && data.properties.size > 0
? this._factory.makeForProperty().normalizeIterable(data.properties, options)
: undefined
}
}
}
1 change: 1 addition & 0 deletions src/serialize/json/types.ts
Original file line number Diff line number Diff line change
@@ -94,6 +94,7 @@ export namespace Normalized {
manufacture?: OrganizationalEntity
supplier?: OrganizationalEntity
licenses?: License[]
properties?: Property[]
}

export interface LifecyclePhase {
18 changes: 17 additions & 1 deletion src/serialize/xml/normalize.ts
Original file line number Diff line number Diff line change
@@ -246,6 +246,20 @@ export class MetadataNormalizer extends BaseXmlNormalizer<Models.Metadata> {
children: this._factory.makeForOrganizationalContact().normalizeIterable(data.authors, options, 'author')
}
: undefined
const licenses: SimpleXml.Element | undefined = this._factory.spec.supportsMetadataLicenses && data.licenses.size > 0
? {
type: 'element',
name: 'licenses',
children: this._factory.makeForLicense().normalizeIterable(data.licenses, options)
}
: undefined
const properties: SimpleXml.Element | undefined = 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,
@@ -262,7 +276,9 @@ export class MetadataNormalizer extends BaseXmlNormalizer<Models.Metadata> {
: orgEntityNormalizer.normalize(data.manufacture, options, 'manufacture'),
data.supplier === undefined
? undefined
: orgEntityNormalizer.normalize(data.supplier, options, 'supplier')
: orgEntityNormalizer.normalize(data.supplier, options, 'supplier'),
licenses,
properties
].filter(isNotUndefined)
}
}
16 changes: 16 additions & 0 deletions src/spec/_protocol.ts
Original file line number Diff line number Diff line change
@@ -43,6 +43,8 @@ export interface _SpecProtocol {
supportsVulnerabilityRatingMethod: (rm: Vulnerability.RatingMethod | any) => boolean
supportsComponentEvidence: boolean
supportsMetadataLifecycles: boolean
supportsMetadataLicenses: boolean
supportsMetadataProperties: boolean
supportsExternalReferenceHashes: boolean
}

@@ -68,6 +70,8 @@ export class _Spec implements _SpecProtocol {
readonly #supportsVulnerabilities: boolean
readonly #supportsComponentEvidence: boolean
readonly #supportsMetadataLifecycles: boolean
readonly #supportsMetadataLicenses: boolean
readonly #supportsMetadataProperties: boolean
readonly #supportsExternalReferenceHashes: boolean

constructor (
@@ -85,6 +89,8 @@ export class _Spec implements _SpecProtocol {
vulnerabilityRatingMethods: Iterable<Vulnerability.RatingMethod>,
supportsComponentEvidence: boolean,
supportsMetadataLifecycles: boolean,
supportsMetadataLicenses: boolean,
supportsMetadataProperties: boolean,
supportsExternalReferenceHashes: boolean
) {
this.#version = version
@@ -101,6 +107,8 @@ export class _Spec implements _SpecProtocol {
this.#vulnerabilityRatingMethods = new Set(vulnerabilityRatingMethods)
this.#supportsComponentEvidence = supportsComponentEvidence
this.#supportsMetadataLifecycles = supportsMetadataLifecycles
this.#supportsMetadataLicenses = supportsMetadataLicenses
this.#supportsMetadataProperties = supportsMetadataProperties
this.#supportsExternalReferenceHashes = supportsExternalReferenceHashes
}

@@ -167,6 +175,14 @@ export class _Spec implements _SpecProtocol {
return this.#supportsMetadataLifecycles
}

get supportsMetadataLicenses (): boolean {
return this.#supportsMetadataLicenses
}

get supportsMetadataProperties (): boolean {
return this.#supportsMetadataProperties
}

get supportsExternalReferenceHashes (): boolean {
return this.#supportsExternalReferenceHashes
}
8 changes: 8 additions & 0 deletions src/spec/consts.ts
Original file line number Diff line number Diff line change
@@ -79,6 +79,8 @@ export const Spec1dot2: Readonly<_SpecProtocol> = Object.freeze(new _Spec(
[],
false,
false,
false,
false,
false
))

@@ -139,6 +141,8 @@ export const Spec1dot3: Readonly<_SpecProtocol> = Object.freeze(new _Spec(
[],
true,
false,
true,
true,
true
))

@@ -206,6 +210,8 @@ export const Spec1dot4: Readonly<_SpecProtocol> = Object.freeze(new _Spec(
],
true,
false,
true,
true,
true
))

@@ -302,6 +308,8 @@ export const Spec1dot5: Readonly<_SpecProtocol> = Object.freeze(new _Spec(
],
true,
true,
true,
true,
true
))

28 changes: 16 additions & 12 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
# Tests

Tests are written in plain JavaScript, and
they are intended to test the build result(`dist.node/` & `dist.web/`),
instead of the source(`src/`).
Tests are written in plain JavaScript.
Tests are intended to test the build result(`dist.node/` & `dist.web/`), instead of the source(`src/`).

## Writing tests

Test files must follow the pattern `**.{spec,test}.[cm]?js`,
to be picked up.
The test runner will NOT build the project; you need to do so manually on demand.
See the [dedicated contributing docs](../CONTRIBUTING.md) for details and advanced instructions.

## Snapshots
## Writing tests

Some tests check against snapshots.
To update these, set the env var `CJL_TEST_UPDATE_SNAPSHOTS` to a non-falsy value.
Test files must follow the pattern `**.{spec,test}.[cm]?js`, to be picked up.

## Run node tests

Test runner is `mocha`,
configured in [mocharc file](../.mocharc.js).
Test runner is `mocha`, configured in [mocharc file](../.mocharc.js).

```shell
npm test
```
### Snapshots

Some tests check against snapshots.
To update these, set the env var `CJL_TEST_UPDATE_SNAPSHOTS` to a non-falsy value.

like so:
```shell
CJL_TEST_UPDATE_SNAPSHOTS=1 npm test
```

## Run browser tests

10 changes: 9 additions & 1 deletion tests/_data/models.js
Original file line number Diff line number Diff line change
@@ -87,7 +87,15 @@ module.exports.createComplexStructure = function () {
name: 'Jane "the-other-supplier" Doe'
})
])
})
}),
licenses: new Models.LicenseRepository([
new Models.SpdxLicense('0BSD'),
new Models.NamedLicense('Some license name')
]),
properties: new Models.PropertyRepository([
new Models.Property('a', 'b'),
new Models.Property('cdx:reproducible', 'true')
])
})
})

24 changes: 23 additions & 1 deletion tests/_data/normalizeResults/json_sortedLists_spec1.3.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 23 additions & 1 deletion tests/_data/normalizeResults/json_sortedLists_spec1.4.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 23 additions & 1 deletion tests/_data/normalizeResults/json_sortedLists_spec1.5.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading