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
Show file tree
Hide file tree
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
Expand Up @@ -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:
Expand Down
7 changes: 7 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions src/models/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -41,6 +45,8 @@ export class Metadata {
component?: Component
manufacture?: OrganizationalEntity
supplier?: OrganizationalEntity
licenses: LicenseRepository
properties: PropertyRepository

constructor (op: OptionalMetadataProperties = {}) {
this.timestamp = op.timestamp
Expand All @@ -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
Expand Up @@ -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
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/serialize/json/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export namespace Normalized {
manufacture?: OrganizationalEntity
supplier?: OrganizationalEntity
licenses?: License[]
properties?: Property[]
}

export interface LifecyclePhase {
Expand Down
18 changes: 17 additions & 1 deletion src/serialize/xml/normalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
}
}
Expand Down
16 changes: 16 additions & 0 deletions src/spec/_protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export interface _SpecProtocol {
supportsVulnerabilityRatingMethod: (rm: Vulnerability.RatingMethod | any) => boolean
supportsComponentEvidence: boolean
supportsMetadataLifecycles: boolean
supportsMetadataLicenses: boolean
supportsMetadataProperties: boolean
supportsExternalReferenceHashes: boolean
}

Expand All @@ -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 (
Expand All @@ -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
Expand All @@ -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
}

Expand Down Expand Up @@ -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
}
Expand Down
8 changes: 8 additions & 0 deletions src/spec/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ export const Spec1dot2: Readonly<_SpecProtocol> = Object.freeze(new _Spec(
[],
false,
false,
false,
false,
false
))

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

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

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

Expand Down
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

Expand Down
10 changes: 9 additions & 1 deletion tests/_data/models.js
Original file line number Diff line number Diff line change
Expand Up @@ -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')
])
})
})

Expand Down
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
Loading