Skip to content

Commit dd164d1

Browse files
authored
feat!: Component.purl as string (#1379)
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅 You can expedite processing of your PR by using this template to provide context and additional information. Before actually opening a PR please make sure that it does NOT fall into any of the following categories 🚫 Spam PRs (accidental or intentional) - these will result in a 30-days or even ∞ ban from interacting with the project depending on reoccurrence and severity. 🚫 Lazy typo fixing PRs - if you fix a typo in a file, your PR will only be merged if all other typos in the same file are also fixed with the same PR 🚫 If you fail to provide any _Description_ below, your PR will be considered spam. If you do not check the _Affirmation_ box below, your PR will not be merged. 🚫 If you do not check one of the _AI Tool Disclosure_ boxes below, your PR will not be merged. If you used AI tools to assist you in writing code, but fail to provide the required disclosure, your PR will not be merged. 🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅--> ### Description <!-- ✍️--> `Component.purl` is a `string` now. No longer dependon external standards and 3rd-party libraries nor data models. Resolves or fixes issue: #1348 ### AI Tool Disclosure - [x] My contribution does not include any AI-generated content - [ ] My contribution includes AI-generated content, as disclosed below: - AI Tools: `[e.g. GitHub CoPilot, ChatGPT, JetBrains Junie etc.]` - LLMs and versions: `[e.g. GPT-4.1, Claude Haiku 4.5, Gemini 2.5 Pro etc.]` - Prompts: `[Summarize the key prompts or instructions given to the AI tools]` ### Affirmation - [x] My code follows the [CONTRIBUTING.md](https://github.com/CycloneDX/cyclonedx-javascript-library/blob/main/CONTRIBUTING.md) guidelines Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
1 parent 9d1b6e0 commit dd164d1

8 files changed

Lines changed: 12 additions & 17 deletions

File tree

HISTORY.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
88

99
* BREAKING changes
1010
* Removed deprecated symbols
11+
* No longer use external standard's implementations
1112
* Removed
1213
* Entrypoint `Builders` (via [#1377])
1314
* Entrypoint `Factories` (via [#1377])
@@ -54,10 +55,13 @@ All notable changes to this project will be documented in this file.
5455
Use `Contrib.FromNodePackageJson.Utils.parsePackageIntegrity` instead.
5556
* Deprecated symbol `Utils.NpmjsUtility.defaultRegistryMatcher` ([#1346] via [#1377])
5657
Use `Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher` instead.
58+
* Changed
59+
* `Component.purl` is a `string` now, was `PackaheUrl` ([#1348] via [#])
5760
* Build
5861
* Use _webpack_ `5.105.2` now, was `v5.103.0` (via [#1360], [#1374])
5962

6063
[#1346]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1346
64+
[#1348]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1348
6165
[#1360]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1360
6266
[#1374]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1374
6367
[#1377]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1377

examples/node/javascript/example.cjs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ const CDX = require('@cyclonedx/cyclonedx-library')
2626
// const { ComponentType } = require('@cyclonedx/cyclonedx-library/Enums')
2727

2828
const lFac = new CDX.Contrib.License.Factories.LicenseFactory()
29-
const purlFac = new CDX.Contrib.PackageUrl.Factories.PackageUrlFactory('generic')
3029

3130
const bom = new CDX.Models.Bom()
3231
bom.metadata.component = new CDX.Models.Component(
@@ -44,7 +43,7 @@ const componentA = new CDX.Models.Component(
4443
}
4544
)
4645
componentA.licenses.add(lFac.makeFromString('Apache-2.0'))
47-
componentA.purl = purlFac.makeFromComponent(componentA)
46+
componentA.purl = `pkg:generic/${componentA.group}/${componentA.name}@${componentA.version}`
4847

4948
bom.components.add(componentA)
5049
bom.metadata.component.dependencies.add(componentA.bomRef)

examples/node/javascript/example.mjs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import * as CDX from '@cyclonedx/cyclonedx-library'
2626
// import { ComponentType } from '@cyclonedx/cyclonedx-library/Enums'
2727

2828
const lFac = new CDX.Contrib.License.Factories.LicenseFactory()
29-
const purlFac = new CDX.Contrib.PackageUrl.Factories.PackageUrlFactory('generic')
3029

3130
const bom = new CDX.Models.Bom()
3231
bom.metadata.component = new CDX.Models.Component(
@@ -44,7 +43,7 @@ const componentA = new CDX.Models.Component(
4443
}
4544
)
4645
componentA.licenses.add(lFac.makeFromString('Apache-2.0'))
47-
componentA.purl = purlFac.makeFromComponent(componentA)
46+
componentA.purl = `pkg:generic/${componentA.group}/${componentA.name}@${componentA.version}`
4847

4948
bom.components.add(componentA)
5049
bom.metadata.component.dependencies.add(componentA.bomRef)

examples/node/typescript/example.cjs/src/example.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import * as CDX from '@cyclonedx/cyclonedx-library'
2626
// import { ComponentType } from '@cyclonedx/cyclonedx-library/Enums'
2727

2828
const lFac = new CDX.Contrib.License.Factories.LicenseFactory()
29-
const purlFac = new CDX.Contrib.PackageUrl.Factories.PackageUrlFactory('generic')
3029

3130
const bom = new CDX.Models.Bom()
3231
bom.metadata.component = new CDX.Models.Component(
@@ -44,7 +43,7 @@ const componentA = new CDX.Models.Component(
4443
}
4544
)
4645
componentA.licenses.add(lFac.makeFromString('Apache-2.0'))
47-
componentA.purl = purlFac.makeFromComponent(componentA)
46+
componentA.purl = `pkg:generic/${componentA.group}/${componentA.name}@${componentA.version}`
4847

4948
bom.components.add(componentA)
5049
bom.metadata.component.dependencies.add(componentA.bomRef)

examples/node/typescript/example.mjs/src/example.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import * as CDX from '@cyclonedx/cyclonedx-library'
2626
// import { ComponentType } from '@cyclonedx/cyclonedx-library/Enums'
2727

2828
const lFac = new CDX.Contrib.License.Factories.LicenseFactory()
29-
const purlFac = new CDX.Contrib.PackageUrl.Factories.PackageUrlFactory('generic')
3029

3130
const bom = new CDX.Models.Bom()
3231
bom.metadata.component = new CDX.Models.Component(
@@ -44,7 +43,7 @@ const componentA = new CDX.Models.Component(
4443
}
4544
)
4645
componentA.licenses.add(lFac.makeFromString('Apache-2.0'))
47-
componentA.purl = purlFac.makeFromComponent(componentA)
46+
componentA.purl = `pkg:generic/${componentA.group}/${componentA.name}@${componentA.version}`
4847

4948
bom.components.add(componentA)
5049
bom.metadata.component.dependencies.add(componentA.bomRef)

src/models/component.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ SPDX-License-Identifier: Apache-2.0
1717
Copyright (c) OWASP Foundation. All Rights Reserved.
1818
*/
1919

20-
import type { PackageURL } from 'packageurl-js'
21-
2220
import type { Comparable } from '../_helpers/sortable'
2321
import { SortableComparables } from '../_helpers/sortable'
2422
import { treeIteratorSymbol } from '../_helpers/tree'
@@ -69,7 +67,7 @@ export class Component implements Comparable<Component> {
6967
hashes: HashDictionary
7068
licenses: LicenseRepository
7169
publisher?: string
72-
purl?: PackageURL
70+
purl?: string
7371
scope?: ComponentScope
7472
supplier?: OrganizationalEntity
7573
swid?: SWID
@@ -139,7 +137,7 @@ export class Component implements Comparable<Component> {
139137
return bomRefCompare
140138
}
141139
if (this.purl !== undefined && other.purl !== undefined) {
142-
return this.purl.toString().localeCompare(other.purl.toString())
140+
return this.purl.localeCompare(other.purl)
143141
}
144142
if (this.#cpe !== undefined && other.#cpe !== undefined) {
145143
return this.#cpe.localeCompare(other.#cpe)

tests/_data/models.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ SPDX-License-Identifier: Apache-2.0
1717
Copyright (c) OWASP Foundation. All Rights Reserved.
1818
*/
1919

20-
const { PackageURL } = require('packageurl-js')
21-
2220
const { Enums, Models, Types } = require('../../')
2321

2422
/* eslint-disable jsdoc/no-undefined-types -- something is odd with type detection */
@@ -169,7 +167,7 @@ function createComplexStructure () {
169167
return license
170168
})(new Models.SpdxLicense('MIT')))
171169
component.publisher = 'the publisher'
172-
component.purl = new PackageURL('npm', 'acme', 'dummy-component', '1337-beta', undefined, undefined)
170+
component.purl = 'pkg:npm/acme/dummy-component@1337-beta'
173171
component.scope = Enums.ComponentScope.Required
174172
component.supplier = new Models.OrganizationalEntity({ name: 'Component Supplier' })
175173
component.supplier.url.add(new URL('https://localhost/componentSupplier-B'))

tests/unit/Models.Component.spec.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ Copyright (c) OWASP Foundation. All Rights Reserved.
2020
const assert = require('node:assert')
2121

2222
const { suite, test } = require('mocha')
23-
const { PackageURL } = require('packageurl-js')
2423

2524
const {
2625
Models: {
@@ -62,7 +61,7 @@ suite('unit: Models.Component', () => {
6261
const dummyBomRef = new BomRef('testing')
6362
const dummyExtRef = new ExternalReference('../', 'other')
6463
const dummyLicense = new NamedLicense('mine')
65-
const dummyPurl = new PackageURL('npm', 'ns', 'app', '1.33.7', {}, undefined)
64+
const dummyPurl = 'pkg:npm/ns/app@1.33.7'
6665
const dummySupplier = new OrganizationalEntity({ name: 'dummySupplier' })
6766
const dummySWID = new SWID('my-fake-swid', 'foo-bar')
6867
const subComponent = new Component('library', 'MySubComponent')

0 commit comments

Comments
 (0)