From 241f5a5bbb7bafa12dbffdcf2816089619288160 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 18 Feb 2026 15:15:01 +0100 Subject: [PATCH 01/35] chore: prep v10.0.0-dev Signed-off-by: Jan Kowalleck --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7c50895cb..b56887fd5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cyclonedx/cyclonedx-library", - "version": "9.4.1", + "version": "10.0.0-alpha.0", "description": "Core functionality of CycloneDX for JavaScript (Node.js or WebBrowser).", "license": "Apache-2.0", "keywords": [ From 47e7a400376ae51c523fdbf751ae977e55643dbf Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 18 Feb 2026 15:37:31 +0100 Subject: [PATCH 02/35] feat!: remove deprecated reexports Signed-off-by: Jan Kowalleck --- HISTORY.md | 3 ++ src/builders/fromNodePackageJson.node.ts | 44 ---------------- src/builders/index.node.ts | 21 -------- src/factories/fromNodePackageJson.node.ts | 34 ------------ src/factories/index.common.ts | 25 --------- src/factories/index.node.ts | 27 ---------- src/factories/index.web.ts | 26 --------- src/factories/license.ts | 27 ---------- src/factories/packageUrl.ts | 27 ---------- src/index.node.ts | 7 +-- src/index.web.ts | 4 -- src/types/index.ts | 25 --------- src/utils/bomUtility.ts | 27 ---------- src/utils/index.common.ts | 21 -------- src/utils/index.node.ts | 29 ---------- src/utils/index.web.ts | 26 --------- src/utils/licenseUtility.node.ts | 64 ----------------------- src/utils/npmjsUtility.node.ts | 34 ------------ 18 files changed, 4 insertions(+), 467 deletions(-) delete mode 100644 src/builders/fromNodePackageJson.node.ts delete mode 100644 src/builders/index.node.ts delete mode 100644 src/factories/fromNodePackageJson.node.ts delete mode 100644 src/factories/index.common.ts delete mode 100644 src/factories/index.node.ts delete mode 100644 src/factories/index.web.ts delete mode 100644 src/factories/license.ts delete mode 100644 src/factories/packageUrl.ts delete mode 100644 src/utils/bomUtility.ts delete mode 100644 src/utils/index.common.ts delete mode 100644 src/utils/index.node.ts delete mode 100644 src/utils/index.web.ts delete mode 100644 src/utils/licenseUtility.node.ts delete mode 100644 src/utils/npmjsUtility.node.ts diff --git a/HISTORY.md b/HISTORY.md index 1b2f97b23..189565997 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -6,11 +6,14 @@ All notable changes to this project will be documented in this file. +* Removed + * Deprecated symbol `` ([#1346] via [#]) * Build * Use _webpack_ `5.105.2` now, was `v5.103.0` (via [#1360], [#1374]) [#1360]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1360 [#1374]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1374 +[#1346]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1346 ## 9.4.1 -- 2025-12-04 diff --git a/src/builders/fromNodePackageJson.node.ts b/src/builders/fromNodePackageJson.node.ts deleted file mode 100644 index 9d931195c..000000000 --- a/src/builders/fromNodePackageJson.node.ts +++ /dev/null @@ -1,44 +0,0 @@ -/*! -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. -*/ - -/** - * Node-specifics. - * - * Intended to run on normalized data structures - * based on [PackageJson spec](https://github.com/SchemaStore/schemastore/blob/master/src/schemas/json/package.json) - * and explained by [PackageJson description](https://docs.npmjs.com/cli/v9/configuring-npm/package-json). - * Normalization should be done downstream, for example via [`normalize-package-data`](https://www.npmjs.com/package/normalize-package-data). - */ - -import {ComponentBuilder as _ComponentBuilder, ToolBuilder as _ToolBuilder} from '../contrib/fromNodePackageJson/builders' - - -/** - * Deprecated — Alias of {@link Contrib.FromNodePackageJson.Builders.ToolBuilder}. - * - * @deprecated Use `Contrib.FromNodePackageJson.Builders.ToolBuilder` instead. - */ -export class ToolBuilder extends _ToolBuilder {} - -/** - * Deprecated — Alias of {@link Contrib.FromNodePackageJson.Builders.ComponentBuilder}. - * - * @deprecated Use `Contrib.FromNodePackageJson.Builders.ComponentBuilder` instead. - */ -export class ComponentBuilder extends _ComponentBuilder {} diff --git a/src/builders/index.node.ts b/src/builders/index.node.ts deleted file mode 100644 index 966982a9e..000000000 --- a/src/builders/index.node.ts +++ /dev/null @@ -1,21 +0,0 @@ -/*! -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. -*/ - -/** @deprecated next */ -export * as FromNodePackageJson from './fromNodePackageJson.node' diff --git a/src/factories/fromNodePackageJson.node.ts b/src/factories/fromNodePackageJson.node.ts deleted file mode 100644 index 4e3371d09..000000000 --- a/src/factories/fromNodePackageJson.node.ts +++ /dev/null @@ -1,34 +0,0 @@ -/*! -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. -*/ - -import { ExternalReferenceFactory as _ExternalReferenceFactory, PackageUrlFactory as _PackageUrlFactory } from '../contrib/fromNodePackageJson/factories' - -/** - * Deprecated — Alias of {@link Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory}. - * - * @deprecated Use `Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory` instead. - */ -export class ExternalReferenceFactory extends _ExternalReferenceFactory {} - -/** - * Deprecated — Alias of {@link Contrib.FromNodePackageJson.Factories.PackageUrlFactory}. - * - * @deprecated Use `Contrib.FromNodePackageJson.Factories.PackageUrlFactory` instead. - */ -export class PackageUrlFactory extends _PackageUrlFactory {} diff --git a/src/factories/index.common.ts b/src/factories/index.common.ts deleted file mode 100644 index 3fc5f7029..000000000 --- a/src/factories/index.common.ts +++ /dev/null @@ -1,25 +0,0 @@ -/*! -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. -*/ - -// not everything is public, yet - -/** @deprecated next */ -export * from './license' -/** @deprecated next */ -export * from './packageUrl' diff --git a/src/factories/index.node.ts b/src/factories/index.node.ts deleted file mode 100644 index 2df6c8d2a..000000000 --- a/src/factories/index.node.ts +++ /dev/null @@ -1,27 +0,0 @@ -/*! -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. -*/ - -export * from './index.common' - -// region node-specifics - -/** @deprecated next */ -export * as FromNodePackageJson from './fromNodePackageJson.node' - -// endregion node-specifics diff --git a/src/factories/index.web.ts b/src/factories/index.web.ts deleted file mode 100644 index b2beefadf..000000000 --- a/src/factories/index.web.ts +++ /dev/null @@ -1,26 +0,0 @@ -/*! -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. -*/ - -export * from './index.common' - -// region web-specifics - -// ... nothing yet - -// endregion web-specifics diff --git a/src/factories/license.ts b/src/factories/license.ts deleted file mode 100644 index 7765ed4fe..000000000 --- a/src/factories/license.ts +++ /dev/null @@ -1,27 +0,0 @@ -/*! -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. -*/ - -import {LicenseFactory as _LicenseFactory} from '../contrib/license/factories' - -/** - * Deprecated — Alias of {@link Contrib.License.Factories.LicenseFactory}. - * - * @deprecated Use `Contrib.License.Factories.LicenseFactory` instead. - */ -export class LicenseFactory extends _LicenseFactory {} diff --git a/src/factories/packageUrl.ts b/src/factories/packageUrl.ts deleted file mode 100644 index c8ed16131..000000000 --- a/src/factories/packageUrl.ts +++ /dev/null @@ -1,27 +0,0 @@ -/*! -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. -*/ - -import { PackageUrlFactory as _PackageUrlFactory } from '../contrib/packageUrl/factories' - -/** - * Deprecated — Alias of {@link Contrib.PackageUrl.Factories.PackageUrlFactory}. - * - * @deprecated Use `Contrib.PackageUrl.Factories.PackageUrlFactory` instead. - */ -export class PackageUrlFactory extends _PackageUrlFactory {} diff --git a/src/index.node.ts b/src/index.node.ts index d3343da92..7b87e7b3f 100644 --- a/src/index.node.ts +++ b/src/index.node.ts @@ -25,14 +25,9 @@ export * from './index.common' // region node-specifics -/** @deprecated next */ -export * as Builders from './builders/index.node' + export * as Contrib from './contrib/index.node' -/** @deprecated next */ -export * as Factories from './factories/index.node' export * as Serialize from './serialize/index.node' -/** @deprecated next */ -export * as Utils from './utils/index.node' export * as Validation from './validation/index.node' /** diff --git a/src/index.web.ts b/src/index.web.ts index a64a69fa7..a4153f9e5 100644 --- a/src/index.web.ts +++ b/src/index.web.ts @@ -22,11 +22,7 @@ export * from './index.common' // region web-specifics export * as Contrib from './contrib/index.web' -/** @deprecated next */ -export * as Factories from './factories/index.web' export * as Serialize from './serialize/index.web' -/** @deprecated next */ -export * as Utils from './utils/index.web' export * as Validation from './validation/index.web' // endregion web-specifics diff --git a/src/types/index.ts b/src/types/index.ts index 31d681610..3ee7feb03 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -28,28 +28,3 @@ export * from './cpe' export * from './cwe' export * from './integer' export * from './mimeType' - -// region deprecated re-exports - -/** - * Deprecated — TypeAlias of {@link Contrib.FromNodePackageJson.Types.NodePackageJson}. - * - * @deprecated Use `Contrib.FromNodePackageJson.Types.NodePackageJson` instead. - */ -export type NodePackageJson = _NodePackageJson - -/** - * Deprecated — Alias of {@link Contrib.FromNodePackageJson.Types.assertNodePackageJson}. - * - * @deprecated Use `Contrib.FromNodePackageJson.Types.assertNodePackageJson` instead. - */ -export const assertNodePackageJson = _assertNodePackageJson - -/** - * Deprecated — Alias of {@link Contrib.FromNodePackageJson.Types.isNodePackageJson}. - * - * @deprecated Use `Contrib.FromNodePackageJson.Types.isNodePackageJson` instead. - */ -export const isNodePackageJson = _isNodePackageJson - -// endregion deprecated re-exports diff --git a/src/utils/bomUtility.ts b/src/utils/bomUtility.ts deleted file mode 100644 index 9222e160a..000000000 --- a/src/utils/bomUtility.ts +++ /dev/null @@ -1,27 +0,0 @@ -/*! -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. -*/ - -import { randomSerialNumber as _randomSerialNumber } from '../contrib/bom/utils' - -/** - * Deprecated — Alias of {@link Contrib.Bom.Utils.randomSerialNumber}. - * - * @deprecated Use `Contrib.Bom.Utils.randomSerialNumber` instead. - */ -export const randomSerialNumber = _randomSerialNumber diff --git a/src/utils/index.common.ts b/src/utils/index.common.ts deleted file mode 100644 index f4078895a..000000000 --- a/src/utils/index.common.ts +++ /dev/null @@ -1,21 +0,0 @@ -/*! -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. -*/ - -/** @deprecated next */ -export * as BomUtility from './bomUtility' diff --git a/src/utils/index.node.ts b/src/utils/index.node.ts deleted file mode 100644 index d427df44f..000000000 --- a/src/utils/index.node.ts +++ /dev/null @@ -1,29 +0,0 @@ -/*! -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. -*/ - -export * from './index.common' - -// region node-specifics - -/** @deprecated next */ -export * as LicenseUtility from './licenseUtility.node' -/** @deprecated next */ -export * as NpmjsUtility from './npmjsUtility.node' - -// endregion node-specifics diff --git a/src/utils/index.web.ts b/src/utils/index.web.ts deleted file mode 100644 index b2beefadf..000000000 --- a/src/utils/index.web.ts +++ /dev/null @@ -1,26 +0,0 @@ -/*! -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. -*/ - -export * from './index.common' - -// region web-specifics - -// ... nothing yet - -// endregion web-specifics diff --git a/src/utils/licenseUtility.node.ts b/src/utils/licenseUtility.node.ts deleted file mode 100644 index 7e31d89ec..000000000 --- a/src/utils/licenseUtility.node.ts +++ /dev/null @@ -1,64 +0,0 @@ -/*! -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. -*/ - -/** - * This module tries to be as compatible as possible, it only uses basic methods that are known to be working in all FileSystem abstraction-layers. - * In addition, we use type parameters for all `PathLike`s, so downstream users can utilize their implementations accordingly. - * - * @module - */ - -import type { ErrorReporter as _ErrorReporter, FileAttachment as _FileAttachment, FsUtils as _FsUtils, PathUtils as _PathUtils} from '../contrib/license/utils.node'; -import { LicenseEvidenceGatherer as _LicenseEvidenceGatherer } from '../contrib/license/utils.node'; - - -/** - * Deprecated — TypeAlias of {@link Contrib.License.Utils.FsUtils}. - * - * @deprecated Use `Contrib.License.Utils.FsUtils` instead. - */ -export interface FsUtils

extends _FsUtils

{} - -/** - * Deprecated — TypeAlias of {@link Contrib.License.Utils.PathUtils}. - * - * @deprecated Use `Contrib.License.Utils.PathUtils` instead. - */ -export interface PathUtils

extends _PathUtils

{} - -/** - * Deprecated — TypeAlias of {@link Contrib.License.Utils.FileAttachment}. - * - * @deprecated Use `Contrib.License.Utils.FileAttachment` instead. - */ -export interface FileAttachment

extends _FileAttachment

{} - -/** - * Deprecated — TypeAlias of {@link Contrib.License.Utils.ErrorReporter}. - * - * @deprecated Use `Contrib.License.Utils.ErrorReporter` instead. - */ -export type ErrorReporter = _ErrorReporter - -/** - * Deprecated — Alias of {@link Contrib.License.Utils.LicenseEvidenceGatherer}. - * - * @deprecated Use `Contrib.License.Utils.LicenseEvidenceGatherer` instead. - */ -export class LicenseEvidenceGatherer extends _LicenseEvidenceGatherer {} diff --git a/src/utils/npmjsUtility.node.ts b/src/utils/npmjsUtility.node.ts deleted file mode 100644 index 0b1fce4f3..000000000 --- a/src/utils/npmjsUtility.node.ts +++ /dev/null @@ -1,34 +0,0 @@ -/*! -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. -*/ - -import {defaultRegistryMatcher as _defaultRegistryMatcher, parsePackageIntegrity as _parsePackageIntegrity} from '../contrib/fromNodePackageJson/utils' - -/** - * Deprecated — Alias of {@link Contrib.FromNodePackageJson.Utils.parsePackageIntegrity}. - * - * @deprecated Use `Contrib.FromNodePackageJson.Utils.parsePackageIntegrity` instead. - */ -export const parsePackageIntegrity = _parsePackageIntegrity - -/** - * Deprecated — Alias of {@link Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher}. - * - * @deprecated Use `Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher` instead. - */ -export const defaultRegistryMatcher = _defaultRegistryMatcher From 2c66ffc8d1a0f34a31d54189ec343f52bf284a4e Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 18 Feb 2026 15:39:46 +0100 Subject: [PATCH 03/35] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 189565997..38b593f48 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -7,13 +7,14 @@ All notable changes to this project will be documented in this file. * Removed - * Deprecated symbol `` ([#1346] via [#]) + * Deprecated symbol `` ([#1346] via [#1377]) * Build * Use _webpack_ `5.105.2` now, was `v5.103.0` (via [#1360], [#1374]) +[#1346]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1346 [#1360]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1360 [#1374]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1374 -[#1346]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1346 +[#1377]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1377 ## 9.4.1 -- 2025-12-04 From 1988d6a282991839fbe59b6b9784aabb35b82139 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 18 Feb 2026 16:02:59 +0100 Subject: [PATCH 04/35] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 38b593f48..173a5753a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -6,8 +6,51 @@ All notable changes to this project will be documented in this file. +* BREAKING changes + * Removed deprecated symbols * Removed - * Deprecated symbol `` ([#1346] via [#1377]) + * Deprecated symbol `Builders` ([#1346] via [#1377]) + * Deprecated symbol `Builders.FromNodePackageJson` ([#1346] via [#1377]) + * Deprecated symbol `Builders.FromNodePackageJson.ToolBuilder` ([#1346] via [#1377]) + Use `Contrib.FromNodePackageJson.Builders.ToolBuilder` instead. + * Deprecated symbol `Builders.FromNodePackageJson.ComponentBuilder` ([#1346] via [#1377]) + Use `Contrib.FromNodePackageJson.Builders.ComponentBuilder` instead. + * Deprecated symbol `Factories` ([#1346] via [#1377]) + * Deprecated symbol `Factories.FromNodePackageJson` ([#1346] via [#1377]) + * Deprecated symbol `Factories.FromNodePackageJson.ExternalReferenceFactory` ([#1346] via [#1377]) + Use `Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory` instead. + * Deprecated symbol `Factories.FromNodePackageJson.PackageUrlFactory` ([#1346] via [#1377]) + Use `Contrib.FromNodePackageJson.Factories.PackageUrlFactory` instead. + * Deprecated symbol `Factories.LicenseFactory` ([#1346] via [#1377]) + Use `Contrib.License.Factories.LicenseFactory` instead. + * Deprecated symbol `Factories.PackageUrlFactory` ([#1346] via [#1377]) + Use `Contrib.PackageUrl.Factories.PackageUrlFactory` instead. + * Deprecated symbol `Types.NodePackageJson` ([#1346] via [#1377]) + Use `Contrib.FromNodePackageJson.Types.NodePackageJson` instead. + * Deprecated symbol `Types.assertNodePackageJson` ([#1346] via [#1377]) + Use `Contrib.FromNodePackageJson.Types.assertNodePackageJson` instead. + * Deprecated symbol `Types.isNodePackageJson` ([#1346] via [#1377]) + Use `Contrib.FromNodePackageJson.Types.isNodePackageJson` instead. + * Deprecated symbol `Utils` ([#1346] via [#1377]) + * Deprecated symbol `Utils.BomUtility` ([#1346] via [#1377]) + * Deprecated symbol `Utils.BomUtility.randomSerialNumber` ([#1346] via [#1377]) + Use `Contrib.Bom.Utils.randomSerialNumber` instead. + * Deprecated symbol `Utils.LicenseUtility` ([#1346] via [#1377]) + * Deprecated symbol `Utils.LicenseUtility.FsUtils` ([#1346] via [#1377]) + Use `Contrib.License.Utils.FsUtils` instead. + * Deprecated symbol `Utils.LicenseUtility.PathUtils` ([#1346] via [#1377]) + * Use `Contrib.License.Utils.PathUtils` instead. + * Deprecated symbol `Utils.LicenseUtility.FileAttachment` ([#1346] via [#1377]) + Use `Contrib.License.Utils.FileAttachment` instead. + * Deprecated symbol `Utils.LicenseUtility.ErrorReporter` ([#1346] via [#1377]) + Use `Contrib.License.Utils.ErrorReporter` instead. + * Deprecated symbol `Utils.LicenseUtility.LicenseEvidenceGatherer` ([#1346] via [#1377]) + Use `Contrib.License.Utils.LicenseEvidenceGatherer` instead. + * Deprecated symbol `Utils.NpmjsUtility` ([#1346] via [#1377]) + * Deprecated symbol `Utils.NpmjsUtility.parsePackageIntegrity` ([#1346] via [#1377]) + Use `Contrib.FromNodePackageJson.Utils.parsePackageIntegrity` instead. + * Deprecated symbol `Utils.NpmjsUtility.defaultRegistryMatcher` ([#1346] via [#1377]) + Use `Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher` instead. * Build * Use _webpack_ `5.105.2` now, was `v5.103.0` (via [#1360], [#1374]) From 84d7fa0335900ccc21b67188953565ae551d1a95 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 18 Feb 2026 16:05:08 +0100 Subject: [PATCH 05/35] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 173a5753a..46f58bc66 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -19,7 +19,7 @@ All notable changes to this project will be documented in this file. * Deprecated symbol `Factories.FromNodePackageJson` ([#1346] via [#1377]) * Deprecated symbol `Factories.FromNodePackageJson.ExternalReferenceFactory` ([#1346] via [#1377]) Use `Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory` instead. - * Deprecated symbol `Factories.FromNodePackageJson.PackageUrlFactory` ([#1346] via [#1377]) + * Deprecated symbol `Factories.FromNodePackageJson.PackageUrlFactory` ([#1346] via [#1377]) Use `Contrib.FromNodePackageJson.Factories.PackageUrlFactory` instead. * Deprecated symbol `Factories.LicenseFactory` ([#1346] via [#1377]) Use `Contrib.License.Factories.LicenseFactory` instead. From 75311d567b302d33fe3cdcf58afe4e39c0bc8d70 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 18 Feb 2026 16:44:31 +0100 Subject: [PATCH 06/35] tests Signed-off-by: Jan Kowalleck --- HISTORY.md | 3 +++ package.json | 12 ------------ ....FromNodePackageJson.ComponentBuilder.test.js | 9 ++++----- ...ders.FromNodePackageJson.ToolBuilders.test.js | 6 +++--- ...ePackageJson.ExternalReferenceFactory.test.js | 4 ++-- ...FromNodePackageJson.PackageUrlFactory.test.js | 4 ++-- .../integration/Factories.LicenseFactory.test.js | 8 ++++---- .../Factories.PackageUrlFactory.test.js | 4 ++-- ...eUtility.LicenseEvidenceGatherer.node.test.js | 16 ++++++++-------- ....FromNodePackageJson.ComponentBuilder.spec.js | 12 ++++-------- ...lders.FromNodePackageJson.ToolBuilder.spec.js | 7 +++---- tests/unit/Factories.PackageUrlFactory.spec.js | 4 ++-- tests/unit/Utils.BomUtility.spec.js | 8 +++----- tests/unit/Utils.NpmjsUtility.spec.js | 12 +++++------- 14 files changed, 45 insertions(+), 64 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 46f58bc66..dd1b695a5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -9,6 +9,9 @@ All notable changes to this project will be documented in this file. * BREAKING changes * Removed deprecated symbols * Removed + * Entrypoint `Builders` (via [#1377]) + * Entrypoint `Factories` (via [#1377]) + * Entrypoint `Utils` (via [#1377]) * Deprecated symbol `Builders` ([#1346] via [#1377]) * Deprecated symbol `Builders.FromNodePackageJson` ([#1346] via [#1377]) * Deprecated symbol `Builders.FromNodePackageJson.ToolBuilder` ([#1346] via [#1377]) diff --git a/package.json b/package.json index b56887fd5..7166d62e4 100644 --- a/package.json +++ b/package.json @@ -145,18 +145,10 @@ "default": "./dist.node/index.node.js" }, "./package.json": "./package.json", - "./Builders": { - "types": "./dist.d/builders/index.node.d.ts", - "default": "./dist.node/builders/index.node.js" - }, "./Enums": { "types": "./dist.d/enums/index.d.ts", "default": "./dist.node/enums/index.js" }, - "./Factories": { - "types": "./dist.d/factories/index.node.d.ts", - "default": "./dist.node/factories/index.node.js" - }, "./Models": { "types": "./dist.d/models/index.d.ts", "default": "./dist.node/models/index.js" @@ -177,10 +169,6 @@ "types": "./dist.d/types/index.d.ts", "default": "./dist.node/types/index.js" }, - "./Utils": { - "types": "./dist.d/utils/index.node.d.ts", - "default": "./dist.node/utils/index.node.js" - }, "./Validation": { "types": "./dist.d/validation/index.node.d.ts", "default": "./dist.node/validation/index.node.js" diff --git a/tests/integration/Builders.FromNodePackageJson.ComponentBuilder.test.js b/tests/integration/Builders.FromNodePackageJson.ComponentBuilder.test.js index f96b5f34f..9ef93d1ea 100644 --- a/tests/integration/Builders.FromNodePackageJson.ComponentBuilder.test.js +++ b/tests/integration/Builders.FromNodePackageJson.ComponentBuilder.test.js @@ -24,17 +24,16 @@ const { suite, test } = require('mocha') const { Enums, Models, - Factories, - Builders: { FromNodePackageJson: { ComponentBuilder } } + Contrib, } = require('../../') suite('integration: Builders.FromNodePackageJson.ComponentBuilder', () => { const salt = Math.random() - const extRefFactory = new Factories.FromNodePackageJson.ExternalReferenceFactory() - const licenseFactory = new Factories.LicenseFactory() + const extRefFactory = new Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory() + const licenseFactory = new Contrib.License.Factories.LicenseFactory() - const sut = new ComponentBuilder(extRefFactory, licenseFactory); + const sut = new Contrib.FromNodePackageJson.Builders.ComponentBuilder(extRefFactory, licenseFactory); [ [ diff --git a/tests/integration/Builders.FromNodePackageJson.ToolBuilders.test.js b/tests/integration/Builders.FromNodePackageJson.ToolBuilders.test.js index 0db754405..994a2f0b6 100644 --- a/tests/integration/Builders.FromNodePackageJson.ToolBuilders.test.js +++ b/tests/integration/Builders.FromNodePackageJson.ToolBuilders.test.js @@ -24,16 +24,16 @@ const { suite, test } = require('mocha') const { Models, Factories, - Builders: { FromNodePackageJson: { ToolBuilder } } + Contrib, } = require('../../') suite('integration: Builders.FromNodePackageJson.ToolBuilder', () => { const salt = Math.random() - const extRefFactory = new Factories.FromNodePackageJson.ExternalReferenceFactory() + const extRefFactory = new Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory() extRefFactory.makeExternalReferences = () => [`FAKE REFERENCES ${salt}`] - const sut = new ToolBuilder(extRefFactory) + const sut = new Contrib.FromNodePackageJson.Builders.ToolBuilder(extRefFactory) const data = { name: '@foo/bar', diff --git a/tests/integration/Factories.FromNodePackageJson.ExternalReferenceFactory.test.js b/tests/integration/Factories.FromNodePackageJson.ExternalReferenceFactory.test.js index f57be4b42..3d82a0a77 100644 --- a/tests/integration/Factories.FromNodePackageJson.ExternalReferenceFactory.test.js +++ b/tests/integration/Factories.FromNodePackageJson.ExternalReferenceFactory.test.js @@ -24,11 +24,11 @@ const { suite, test } = require('mocha') const { Enums: { ExternalReferenceType, HashAlgorithm }, Models: { ExternalReference, HashDictionary }, - Factories: { FromNodePackageJson: { ExternalReferenceFactory } } + Contrib, } = require('../../') suite('integration: Factories.FromNodePackageJson.ExternalReferenceFactory', () => { - const sut = new ExternalReferenceFactory() + const sut = new Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory() suite('from "homepage"', () => { test('is non-empty string', () => { diff --git a/tests/integration/Factories.FromNodePackageJson.PackageUrlFactory.test.js b/tests/integration/Factories.FromNodePackageJson.PackageUrlFactory.test.js index f97c715df..ff538e461 100644 --- a/tests/integration/Factories.FromNodePackageJson.PackageUrlFactory.test.js +++ b/tests/integration/Factories.FromNodePackageJson.PackageUrlFactory.test.js @@ -25,13 +25,13 @@ const { PackageURL } = require('packageurl-js') const { Enums, Models, - Factories: { FromNodePackageJson: { PackageUrlFactory } } + Contrib, } = require('../../') suite('integration: Factories.FromNodePackageJson.PackageUrlFactory', () => { const salt = Math.random() - const sut = new PackageUrlFactory('testing') + const sut = new Contrib.PackageUrl.Factories.PackageUrlFactory('testing') suite('makeFromComponent', () => { test('no-name-no-purl', () => { diff --git a/tests/integration/Factories.LicenseFactory.test.js b/tests/integration/Factories.LicenseFactory.test.js index ebfd52f74..9e9b7c0d0 100644 --- a/tests/integration/Factories.LicenseFactory.test.js +++ b/tests/integration/Factories.LicenseFactory.test.js @@ -22,13 +22,13 @@ const assert = require('node:assert') const { suite, test } = require('mocha') const { - Factories: { LicenseFactory }, + Contrib, Models: { LicenseExpression, NamedLicense, SpdxLicense } } = require('../../') suite('integration: Factories.LicenseFactory', () => { test('makeFromString() -> LicenseExpression', () => { - const sut = new LicenseFactory() + const sut = new Contrib.License.Factories.LicenseFactory() const expression = '(MIT OR Apache-2.0)' const license = sut.makeFromString(expression) @@ -38,7 +38,7 @@ suite('integration: Factories.LicenseFactory', () => { }) test('makeFromString() -> NamedLicense', () => { - const sut = new LicenseFactory() + const sut = new Contrib.License.Factories.LicenseFactory() const license = sut.makeFromString('(c) foo bar') @@ -49,7 +49,7 @@ suite('integration: Factories.LicenseFactory', () => { }) test('makeFromString() -> SpdxLicense', () => { - const sut = new LicenseFactory() + const sut = new Contrib.License.Factories.LicenseFactory() const license = sut.makeFromString('MIT') diff --git a/tests/integration/Factories.PackageUrlFactory.test.js b/tests/integration/Factories.PackageUrlFactory.test.js index 4aba9d5d3..d55606bcc 100644 --- a/tests/integration/Factories.PackageUrlFactory.test.js +++ b/tests/integration/Factories.PackageUrlFactory.test.js @@ -25,13 +25,13 @@ const { PackageURL } = require('packageurl-js') const { Enums, Models, - Factories: { PackageUrlFactory } + Contrib, } = require('../../') suite('integration: Factories.PackageUrlFactory', () => { const salt = Math.random() - const sut = new PackageUrlFactory('testing') + const sut = new Contrib.PackageUrl.Factories.PackageUrlFactory('testing') suite('makeFromComponent', () => { test('no-name-no-purl', () => { diff --git a/tests/integration/Utils.LicenseUtility.LicenseEvidenceGatherer.node.test.js b/tests/integration/Utils.LicenseUtility.LicenseEvidenceGatherer.node.test.js index ded6b551f..c846399a0 100644 --- a/tests/integration/Utils.LicenseUtility.LicenseEvidenceGatherer.node.test.js +++ b/tests/integration/Utils.LicenseUtility.LicenseEvidenceGatherer.node.test.js @@ -26,13 +26,13 @@ const { suite, test } = require('mocha') const { Models: { Attachment }, Enums: { AttachmentEncoding }, - Utils: { LicenseUtility: { LicenseEvidenceGatherer } } + Contrib, } = require('../../') suite('integration: Utils.LicenseUtility.LicenseEvidenceGatherer', () => { test('no path -> throws', () => { const { fs } = memfs({ '/': {} }) - const leg = new LicenseEvidenceGatherer({ fs }) + const leg = new Contrib.License.Utils.LicenseEvidenceGatherer({ fs }) assert.throws( () => { Array.from( @@ -48,7 +48,7 @@ suite('integration: Utils.LicenseUtility.LicenseEvidenceGatherer', () => { test('no files', () => { const { fs } = memfs({ '/': {} }) - const leg = new LicenseEvidenceGatherer({ fs }) + const leg = new Contrib.License.Utils.LicenseEvidenceGatherer({ fs }) const errors = [] const found = Array.from( leg.getFileAttachments( @@ -66,7 +66,7 @@ suite('integration: Utils.LicenseUtility.LicenseEvidenceGatherer', () => { 'GPL-3.0-or-later.txt': 'GPL-3.0-or-later License text here...' } }) - const leg = new LicenseEvidenceGatherer({ fs }) + const leg = new Contrib.License.Utils.LicenseEvidenceGatherer({ fs }) const found = Array.from( leg.getFileAttachments('/')) assert.deepEqual(found, []) @@ -80,7 +80,7 @@ suite('integration: Utils.LicenseUtility.LicenseEvidenceGatherer', () => { 'GPL-3.0-or-later.txt': 'GPL-3.0-or-later License text here...' } }) - const leg = new LicenseEvidenceGatherer({ fs }) + const leg = new Contrib.License.Utils.LicenseEvidenceGatherer({ fs }) const found = Array.from( leg.getFileAttachments('/')) assert.deepEqual(found, []) @@ -93,7 +93,7 @@ suite('integration: Utils.LicenseUtility.LicenseEvidenceGatherer', () => { `skipped license file ${sep}LICENSE`, { cause: new Error('Custom read error: Access denied!') }) fs.readFileSync = function () { throw expectedError.cause } - const leg = new LicenseEvidenceGatherer({ fs }) + const leg = new Contrib.License.Utils.LicenseEvidenceGatherer({ fs }) const errors = [] const found = Array.from( leg.getFileAttachments( @@ -132,7 +132,7 @@ suite('integration: Utils.LicenseUtility.LicenseEvidenceGatherer', () => { test('finds licenses as expected', () => { const { fs } = memfs({ '/': mockedLicenses }) - const leg = new LicenseEvidenceGatherer({ fs }) + const leg = new Contrib.License.Utils.LicenseEvidenceGatherer({ fs }) const errors = [] const found = Array.from( leg.getFileAttachments( @@ -218,7 +218,7 @@ suite('integration: Utils.LicenseUtility.LicenseEvidenceGatherer', () => { test('does not find licenses in subfolder', () => { const { fs } = memfs({ '/foo': mockedLicenses }) - const leg = new LicenseEvidenceGatherer({ fs }) + const leg = new Contrib.License.Utils.LicenseEvidenceGatherer({ fs }) const found = Array.from( leg.getFileAttachments('/')) assert.deepEqual(found, []) diff --git a/tests/unit/Builders.FromNodePackageJson.ComponentBuilder.spec.js b/tests/unit/Builders.FromNodePackageJson.ComponentBuilder.spec.js index 3cb820a09..00f39a97a 100644 --- a/tests/unit/Builders.FromNodePackageJson.ComponentBuilder.spec.js +++ b/tests/unit/Builders.FromNodePackageJson.ComponentBuilder.spec.js @@ -22,19 +22,15 @@ const assert = require('node:assert') const { suite, test } = require('mocha') const { - Builders: { FromNodePackageJson: { ComponentBuilder } }, - Factories: { - FromNodePackageJson: { ExternalReferenceFactory }, - LicenseFactory - } + Contrib, } = require('../../') suite('unit: Builders.FromNodePackageJson.ComponentBuilder', () => { test('construct', () => { - const extRefFactory = new ExternalReferenceFactory() - const licenseFactory = new LicenseFactory() + const extRefFactory = new Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory() + const licenseFactory = new Contrib.License.Factories.LicenseFactory() - const actual = new ComponentBuilder(extRefFactory, licenseFactory) + const actual = new Contrib.FromNodePackageJson.Builders.ComponentBuilder(extRefFactory, licenseFactory) assert.strictEqual(actual.extRefFactory, extRefFactory) assert.strictEqual(actual.licenseFactory, licenseFactory) diff --git a/tests/unit/Builders.FromNodePackageJson.ToolBuilder.spec.js b/tests/unit/Builders.FromNodePackageJson.ToolBuilder.spec.js index 25c20fd81..991d72df7 100644 --- a/tests/unit/Builders.FromNodePackageJson.ToolBuilder.spec.js +++ b/tests/unit/Builders.FromNodePackageJson.ToolBuilder.spec.js @@ -22,15 +22,14 @@ const assert = require('node:assert') const { suite, test } = require('mocha') const { - Builders: { FromNodePackageJson: { ToolBuilder } }, - Factories: { FromNodePackageJson: { ExternalReferenceFactory } } + Contrib, } = require('../../') suite('unit: Builders.FromNodePackageJson.ToolBuilder', () => { test('construct', () => { - const extRefFactory = new ExternalReferenceFactory() + const extRefFactory = new Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory() - const actual = new ToolBuilder(extRefFactory) + const actual = new Contrib.FromNodePackageJson.Builders.ToolBuilder(extRefFactory) assert.strictEqual(actual.extRefFactory, extRefFactory) }) diff --git a/tests/unit/Factories.PackageUrlFactory.spec.js b/tests/unit/Factories.PackageUrlFactory.spec.js index a72763ca5..fe117bbfc 100644 --- a/tests/unit/Factories.PackageUrlFactory.spec.js +++ b/tests/unit/Factories.PackageUrlFactory.spec.js @@ -22,7 +22,7 @@ const assert = require('node:assert') const { suite, test } = require('mocha') const { - Factories: { PackageUrlFactory } + Contrib, } = require('../../') const { randomString } = require('../_helpers/stringFunctions') @@ -30,7 +30,7 @@ suite('unit: Factories.PackageUrlFactory', () => { test('construct', () => { const type = randomString(5) - const actual = new PackageUrlFactory(type) + const actual = new Contrib.PackageUrl.Factories.PackageUrlFactory(type) assert.strictEqual(actual.type, type) }) diff --git a/tests/unit/Utils.BomUtility.spec.js b/tests/unit/Utils.BomUtility.spec.js index 9173fb3e2..17bf560fe 100644 --- a/tests/unit/Utils.BomUtility.spec.js +++ b/tests/unit/Utils.BomUtility.spec.js @@ -22,19 +22,17 @@ const assert = require('node:assert') const { suite, test } = require('mocha') const { - Utils: { - BomUtility - } + Contrib, } = require('../../') suite('unit: Utils.BomUtility', () => { suite('randomSerialNumber()', () => { test('has correct format according to XSD', () => { - const value = BomUtility.randomSerialNumber() + const value = Contrib.Bom.Utils.randomSerialNumber() assert.match(value, /^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('has correct format according to JSON schema', () => { - const value = BomUtility.randomSerialNumber() + const value = Contrib.Bom.Utils.randomSerialNumber() assert.match(value, /^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/) }) }) diff --git a/tests/unit/Utils.NpmjsUtility.spec.js b/tests/unit/Utils.NpmjsUtility.spec.js index b05cca8ba..536bfcd80 100644 --- a/tests/unit/Utils.NpmjsUtility.spec.js +++ b/tests/unit/Utils.NpmjsUtility.spec.js @@ -25,18 +25,16 @@ const { Enums: { HashAlgorithm }, - Utils: { - NpmjsUtility - } + Contrib, } = require('../../') suite('unit: Utils.NpmjsUtility.defaultRegistryMatcher', () => { test('matches pure domain', () => { - const actual = NpmjsUtility.defaultRegistryMatcher.test('https://registry.npmjs.org') + const actual = Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher.test('https://registry.npmjs.org') assert.strictEqual(actual, true) }) test('matches with path', () => { - const actual = NpmjsUtility.defaultRegistryMatcher.test('https://registry.npmjs.org/foo/bar') + const actual = Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher.test('https://registry.npmjs.org/foo/bar') assert.strictEqual(actual, true) }) suite('not match unexpected', () => { @@ -46,7 +44,7 @@ suite('unit: Utils.NpmjsUtility.defaultRegistryMatcher', () => { 'https://registry.npmjs.org.uk/foo/bar' ]) { test(c, () => { - const actual = NpmjsUtility.defaultRegistryMatcher.test(c) + const actual = Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher.test(c) assert.strictEqual(actual, false) }) } @@ -74,7 +72,7 @@ suite('unit: Utils.NpmjsUtility.parsePackageIntegrity', () => { ], ]) { test(c, () => { - const actual = NpmjsUtility.parsePackageIntegrity(c) + const actual = Contrib.FromNodePackageJson.Utils.parsePackageIntegrity(c) assert.deepStrictEqual(actual, expected) }) } From 643535dad72009561de8de34f5b6540fdaec94d3 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 18 Feb 2026 16:46:16 +0100 Subject: [PATCH 07/35] dings Signed-off-by: Jan Kowalleck --- src/types/index.ts | 7 ------- .../Builders.FromNodePackageJson.ComponentBuilder.test.js | 2 +- .../Builders.FromNodePackageJson.ToolBuilders.test.js | 3 +-- ...Factories.FromNodePackageJson.PackageUrlFactory.test.js | 2 +- tests/integration/Factories.PackageUrlFactory.test.js | 2 +- tests/unit/Utils.NpmjsUtility.spec.js | 2 +- 6 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/types/index.ts b/src/types/index.ts index 3ee7feb03..2db668d77 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -17,13 +17,6 @@ SPDX-License-Identifier: Apache-2.0 Copyright (c) OWASP Foundation. All Rights Reserved. */ -import { - assertNodePackageJson as _assertNodePackageJson, - isNodePackageJson as _isNodePackageJson, - type NodePackageJson as _NodePackageJson -} from '../contrib/fromNodePackageJson/types' - - export * from './cpe' export * from './cwe' export * from './integer' diff --git a/tests/integration/Builders.FromNodePackageJson.ComponentBuilder.test.js b/tests/integration/Builders.FromNodePackageJson.ComponentBuilder.test.js index 9ef93d1ea..752f4a748 100644 --- a/tests/integration/Builders.FromNodePackageJson.ComponentBuilder.test.js +++ b/tests/integration/Builders.FromNodePackageJson.ComponentBuilder.test.js @@ -22,9 +22,9 @@ const assert = require('node:assert') const { suite, test } = require('mocha') const { + Contrib, Enums, Models, - Contrib, } = require('../../') suite('integration: Builders.FromNodePackageJson.ComponentBuilder', () => { diff --git a/tests/integration/Builders.FromNodePackageJson.ToolBuilders.test.js b/tests/integration/Builders.FromNodePackageJson.ToolBuilders.test.js index 994a2f0b6..02af9d249 100644 --- a/tests/integration/Builders.FromNodePackageJson.ToolBuilders.test.js +++ b/tests/integration/Builders.FromNodePackageJson.ToolBuilders.test.js @@ -22,9 +22,8 @@ const assert = require('node:assert') const { suite, test } = require('mocha') const { - Models, - Factories, Contrib, + Models, } = require('../../') suite('integration: Builders.FromNodePackageJson.ToolBuilder', () => { diff --git a/tests/integration/Factories.FromNodePackageJson.PackageUrlFactory.test.js b/tests/integration/Factories.FromNodePackageJson.PackageUrlFactory.test.js index ff538e461..832504560 100644 --- a/tests/integration/Factories.FromNodePackageJson.PackageUrlFactory.test.js +++ b/tests/integration/Factories.FromNodePackageJson.PackageUrlFactory.test.js @@ -23,9 +23,9 @@ const { suite, test } = require('mocha') const { PackageURL } = require('packageurl-js') const { + Contrib, Enums, Models, - Contrib, } = require('../../') suite('integration: Factories.FromNodePackageJson.PackageUrlFactory', () => { diff --git a/tests/integration/Factories.PackageUrlFactory.test.js b/tests/integration/Factories.PackageUrlFactory.test.js index d55606bcc..1980bbf49 100644 --- a/tests/integration/Factories.PackageUrlFactory.test.js +++ b/tests/integration/Factories.PackageUrlFactory.test.js @@ -23,9 +23,9 @@ const { suite, test } = require('mocha') const { PackageURL } = require('packageurl-js') const { + Contrib, Enums, Models, - Contrib, } = require('../../') suite('integration: Factories.PackageUrlFactory', () => { diff --git a/tests/unit/Utils.NpmjsUtility.spec.js b/tests/unit/Utils.NpmjsUtility.spec.js index 536bfcd80..3d9b5e57f 100644 --- a/tests/unit/Utils.NpmjsUtility.spec.js +++ b/tests/unit/Utils.NpmjsUtility.spec.js @@ -85,7 +85,7 @@ suite('unit: Utils.NpmjsUtility.parsePackageIntegrity', () => { ]) { test(c, () => { assert.throws(() => { - NpmjsUtility.parsePackageIntegrity(c) + Contrib.FromNodePackageJson.Utils.parsePackageIntegrity(c) }) }) } From 098d3039849ea46b49c100eca05be13b69bcd0c2 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 18 Feb 2026 17:24:35 +0100 Subject: [PATCH 08/35] dings Signed-off-by: Jan Kowalleck --- ...b.FromNodePackageJson.Builders.ComponentBuilder.test.js} | 2 +- ...ontrib.FromNodePackageJson.Builders.ToolBuilder.test.js} | 2 +- ...ePackageJson.Factories.ExternalReferenceFactory.test.js} | 2 +- ...FromNodePackageJson.Factories.PackageUrlFactory.test.js} | 4 ++-- ....js => Contrib.License.Factories.LicenseFactory.test.js} | 2 +- ... Contrib.License.Utils.LicenseEvidenceGatherer(.test.js} | 2 +- ... Contrib.PackageUrl.Factories.PackageUrlFactory.test.js} | 2 +- ...spec.js => Contrib.Bom.Utils.randomSerialNumber.spec.js} | 2 +- ...b.FromNodePackageJson.Builders.ComponentBuilder.spec.js} | 2 +- ...ontrib.FromNodePackageJson.Builders.ToolBuilder.spec.js} | 2 +- ...FromNodePackageJson.Factories.PackageUrlFactory.spec.js} | 6 +++--- ...ty.spec.js => Contrib.FromNodePackageJson.Utils.spec.js} | 4 ++-- ...js => Contrib.PackageUrl.Factories.PackageUrlFactory.js} | 2 +- 13 files changed, 17 insertions(+), 17 deletions(-) rename tests/integration/{Builders.FromNodePackageJson.ComponentBuilder.test.js => Contrib.FromNodePackageJson.Builders.ComponentBuilder.test.js} (97%) rename tests/integration/{Builders.FromNodePackageJson.ToolBuilders.test.js => Contrib.FromNodePackageJson.Builders.ToolBuilder.test.js} (95%) rename tests/integration/{Factories.FromNodePackageJson.ExternalReferenceFactory.test.js => Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory.test.js} (99%) rename tests/integration/{Factories.FromNodePackageJson.PackageUrlFactory.test.js => Contrib.FromNodePackageJson.Factories.PackageUrlFactory.test.js} (98%) rename tests/integration/{Factories.LicenseFactory.test.js => Contrib.License.Factories.LicenseFactory.test.js} (96%) rename tests/integration/{Utils.LicenseUtility.LicenseEvidenceGatherer.node.test.js => Contrib.License.Utils.LicenseEvidenceGatherer(.test.js} (98%) rename tests/integration/{Factories.PackageUrlFactory.test.js => Contrib.PackageUrl.Factories.PackageUrlFactory.test.js} (99%) rename tests/unit/{Utils.BomUtility.spec.js => Contrib.Bom.Utils.randomSerialNumber.spec.js} (95%) rename tests/unit/{Builders.FromNodePackageJson.ComponentBuilder.spec.js => Contrib.FromNodePackageJson.Builders.ComponentBuilder.spec.js} (94%) rename tests/unit/{Builders.FromNodePackageJson.ToolBuilder.spec.js => Contrib.FromNodePackageJson.Builders.ToolBuilder.spec.js} (93%) rename tests/unit/{Factories.FromNodePackageJson.PackageUrlFactory.js => Contrib.FromNodePackageJson.Factories.PackageUrlFactory.spec.js} (94%) rename tests/unit/{Utils.NpmjsUtility.spec.js => Contrib.FromNodePackageJson.Utils.spec.js} (95%) rename tests/unit/{Factories.PackageUrlFactory.spec.js => Contrib.PackageUrl.Factories.PackageUrlFactory.js} (93%) diff --git a/tests/integration/Builders.FromNodePackageJson.ComponentBuilder.test.js b/tests/integration/Contrib.FromNodePackageJson.Builders.ComponentBuilder.test.js similarity index 97% rename from tests/integration/Builders.FromNodePackageJson.ComponentBuilder.test.js rename to tests/integration/Contrib.FromNodePackageJson.Builders.ComponentBuilder.test.js index 752f4a748..883e1debe 100644 --- a/tests/integration/Builders.FromNodePackageJson.ComponentBuilder.test.js +++ b/tests/integration/Contrib.FromNodePackageJson.Builders.ComponentBuilder.test.js @@ -27,7 +27,7 @@ const { Models, } = require('../../') -suite('integration: Builders.FromNodePackageJson.ComponentBuilder', () => { +suite('integration: Contrib.FromNodePackageJson.Builders.ComponentBuilder', () => { const salt = Math.random() const extRefFactory = new Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory() diff --git a/tests/integration/Builders.FromNodePackageJson.ToolBuilders.test.js b/tests/integration/Contrib.FromNodePackageJson.Builders.ToolBuilder.test.js similarity index 95% rename from tests/integration/Builders.FromNodePackageJson.ToolBuilders.test.js rename to tests/integration/Contrib.FromNodePackageJson.Builders.ToolBuilder.test.js index 02af9d249..f87664d85 100644 --- a/tests/integration/Builders.FromNodePackageJson.ToolBuilders.test.js +++ b/tests/integration/Contrib.FromNodePackageJson.Builders.ToolBuilder.test.js @@ -26,7 +26,7 @@ const { Models, } = require('../../') -suite('integration: Builders.FromNodePackageJson.ToolBuilder', () => { +suite('integration: Contrib.FromNodePackageJson.Builders.ToolBuilder', () => { const salt = Math.random() const extRefFactory = new Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory() diff --git a/tests/integration/Factories.FromNodePackageJson.ExternalReferenceFactory.test.js b/tests/integration/Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory.test.js similarity index 99% rename from tests/integration/Factories.FromNodePackageJson.ExternalReferenceFactory.test.js rename to tests/integration/Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory.test.js index 3d82a0a77..ecad5d059 100644 --- a/tests/integration/Factories.FromNodePackageJson.ExternalReferenceFactory.test.js +++ b/tests/integration/Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory.test.js @@ -27,7 +27,7 @@ const { Contrib, } = require('../../') -suite('integration: Factories.FromNodePackageJson.ExternalReferenceFactory', () => { +suite('integration: Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory', () => { const sut = new Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory() suite('from "homepage"', () => { diff --git a/tests/integration/Factories.FromNodePackageJson.PackageUrlFactory.test.js b/tests/integration/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.test.js similarity index 98% rename from tests/integration/Factories.FromNodePackageJson.PackageUrlFactory.test.js rename to tests/integration/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.test.js index 832504560..ed66a85ce 100644 --- a/tests/integration/Factories.FromNodePackageJson.PackageUrlFactory.test.js +++ b/tests/integration/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.test.js @@ -28,10 +28,10 @@ const { Models, } = require('../../') -suite('integration: Factories.FromNodePackageJson.PackageUrlFactory', () => { +suite('integration: Contrib.FromNodePackageJson.Factories.PackageUrlFactory', () => { const salt = Math.random() - const sut = new Contrib.PackageUrl.Factories.PackageUrlFactory('testing') + const sut = new Contrib.FromNodePackageJson.Factories.PackageUrlFactory('testing') suite('makeFromComponent', () => { test('no-name-no-purl', () => { diff --git a/tests/integration/Factories.LicenseFactory.test.js b/tests/integration/Contrib.License.Factories.LicenseFactory.test.js similarity index 96% rename from tests/integration/Factories.LicenseFactory.test.js rename to tests/integration/Contrib.License.Factories.LicenseFactory.test.js index 9e9b7c0d0..e0fd88f66 100644 --- a/tests/integration/Factories.LicenseFactory.test.js +++ b/tests/integration/Contrib.License.Factories.LicenseFactory.test.js @@ -26,7 +26,7 @@ const { Models: { LicenseExpression, NamedLicense, SpdxLicense } } = require('../../') -suite('integration: Factories.LicenseFactory', () => { +suite('integration: Contrib.License.Factories.LicenseFactory', () => { test('makeFromString() -> LicenseExpression', () => { const sut = new Contrib.License.Factories.LicenseFactory() const expression = '(MIT OR Apache-2.0)' diff --git a/tests/integration/Utils.LicenseUtility.LicenseEvidenceGatherer.node.test.js b/tests/integration/Contrib.License.Utils.LicenseEvidenceGatherer(.test.js similarity index 98% rename from tests/integration/Utils.LicenseUtility.LicenseEvidenceGatherer.node.test.js rename to tests/integration/Contrib.License.Utils.LicenseEvidenceGatherer(.test.js index c846399a0..12f01a4f4 100644 --- a/tests/integration/Utils.LicenseUtility.LicenseEvidenceGatherer.node.test.js +++ b/tests/integration/Contrib.License.Utils.LicenseEvidenceGatherer(.test.js @@ -29,7 +29,7 @@ const { Contrib, } = require('../../') -suite('integration: Utils.LicenseUtility.LicenseEvidenceGatherer', () => { +suite('integration: Contrib.License.Utils.LicenseEvidenceGatherer(', () => { test('no path -> throws', () => { const { fs } = memfs({ '/': {} }) const leg = new Contrib.License.Utils.LicenseEvidenceGatherer({ fs }) diff --git a/tests/integration/Factories.PackageUrlFactory.test.js b/tests/integration/Contrib.PackageUrl.Factories.PackageUrlFactory.test.js similarity index 99% rename from tests/integration/Factories.PackageUrlFactory.test.js rename to tests/integration/Contrib.PackageUrl.Factories.PackageUrlFactory.test.js index 1980bbf49..910ee6a17 100644 --- a/tests/integration/Factories.PackageUrlFactory.test.js +++ b/tests/integration/Contrib.PackageUrl.Factories.PackageUrlFactory.test.js @@ -28,7 +28,7 @@ const { Models, } = require('../../') -suite('integration: Factories.PackageUrlFactory', () => { +suite('integration: Contrib.PackageUrl.Factories.PackageUrlFactory', () => { const salt = Math.random() const sut = new Contrib.PackageUrl.Factories.PackageUrlFactory('testing') diff --git a/tests/unit/Utils.BomUtility.spec.js b/tests/unit/Contrib.Bom.Utils.randomSerialNumber.spec.js similarity index 95% rename from tests/unit/Utils.BomUtility.spec.js rename to tests/unit/Contrib.Bom.Utils.randomSerialNumber.spec.js index 17bf560fe..8463b88cb 100644 --- a/tests/unit/Utils.BomUtility.spec.js +++ b/tests/unit/Contrib.Bom.Utils.randomSerialNumber.spec.js @@ -25,7 +25,7 @@ const { Contrib, } = require('../../') -suite('unit: Utils.BomUtility', () => { +suite('unit: Contrib.Bom.Utils.randomSerialNumber', () => { suite('randomSerialNumber()', () => { test('has correct format according to XSD', () => { const value = Contrib.Bom.Utils.randomSerialNumber() diff --git a/tests/unit/Builders.FromNodePackageJson.ComponentBuilder.spec.js b/tests/unit/Contrib.FromNodePackageJson.Builders.ComponentBuilder.spec.js similarity index 94% rename from tests/unit/Builders.FromNodePackageJson.ComponentBuilder.spec.js rename to tests/unit/Contrib.FromNodePackageJson.Builders.ComponentBuilder.spec.js index 00f39a97a..23aeb7b5c 100644 --- a/tests/unit/Builders.FromNodePackageJson.ComponentBuilder.spec.js +++ b/tests/unit/Contrib.FromNodePackageJson.Builders.ComponentBuilder.spec.js @@ -25,7 +25,7 @@ const { Contrib, } = require('../../') -suite('unit: Builders.FromNodePackageJson.ComponentBuilder', () => { +suite('unit: Contrib.FromNodePackageJson.Builders.ComponentBuilder', () => { test('construct', () => { const extRefFactory = new Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory() const licenseFactory = new Contrib.License.Factories.LicenseFactory() diff --git a/tests/unit/Builders.FromNodePackageJson.ToolBuilder.spec.js b/tests/unit/Contrib.FromNodePackageJson.Builders.ToolBuilder.spec.js similarity index 93% rename from tests/unit/Builders.FromNodePackageJson.ToolBuilder.spec.js rename to tests/unit/Contrib.FromNodePackageJson.Builders.ToolBuilder.spec.js index 991d72df7..5dfbe91f9 100644 --- a/tests/unit/Builders.FromNodePackageJson.ToolBuilder.spec.js +++ b/tests/unit/Contrib.FromNodePackageJson.Builders.ToolBuilder.spec.js @@ -25,7 +25,7 @@ const { Contrib, } = require('../../') -suite('unit: Builders.FromNodePackageJson.ToolBuilder', () => { +suite('unit: Contrib.FromNodePackageJson.Builders.ToolBuilder', () => { test('construct', () => { const extRefFactory = new Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory() diff --git a/tests/unit/Factories.FromNodePackageJson.PackageUrlFactory.js b/tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.spec.js similarity index 94% rename from tests/unit/Factories.FromNodePackageJson.PackageUrlFactory.js rename to tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.spec.js index a91c4b1c1..15de3298e 100644 --- a/tests/unit/Factories.FromNodePackageJson.PackageUrlFactory.js +++ b/tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.spec.js @@ -22,16 +22,16 @@ const assert = require('node:assert') const { suite, test } = require('mocha') const { - Factories: { FromNodePackageJson: { PackageUrlFactory } }, + Contrib, Enums: { ComponentType, ExternalReferenceType }, Models: { Component, ExternalReference, ExternalReferenceRepository } } = require('../../') -suite('unit: Factories.FromNodePackageJson.PackageUrlFactory', () => { +suite('unit: Contrib.FromNodePackageJson.Factories.PackageUrlFactory', () => { suite('makeFromComponent()', () => { test('plain', () => { const component = new Component(ComponentType.Library, 'testing') - const purlFac = new PackageUrlFactory('npm') + const purlFac = new Contrib.FromNodePackageJson.Factories.PackageUrlFactory('npm') const actual = purlFac.makeFromComponent(component) assert.deepEqual(actual, 'TODO') }) diff --git a/tests/unit/Utils.NpmjsUtility.spec.js b/tests/unit/Contrib.FromNodePackageJson.Utils.spec.js similarity index 95% rename from tests/unit/Utils.NpmjsUtility.spec.js rename to tests/unit/Contrib.FromNodePackageJson.Utils.spec.js index 3d9b5e57f..3eaab60b0 100644 --- a/tests/unit/Utils.NpmjsUtility.spec.js +++ b/tests/unit/Contrib.FromNodePackageJson.Utils.spec.js @@ -28,7 +28,7 @@ const { Contrib, } = require('../../') -suite('unit: Utils.NpmjsUtility.defaultRegistryMatcher', () => { +suite('unit: Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher', () => { test('matches pure domain', () => { const actual = Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher.test('https://registry.npmjs.org') assert.strictEqual(actual, true) @@ -51,7 +51,7 @@ suite('unit: Utils.NpmjsUtility.defaultRegistryMatcher', () => { }) }) -suite('unit: Utils.NpmjsUtility.parsePackageIntegrity', () => { +suite('unit: Contrib.FromNodePackageJson.Utils.parsePackageIntegrity', () => { suite('as expected', () => { for (const [c, ...expected] of [ ['sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==', diff --git a/tests/unit/Factories.PackageUrlFactory.spec.js b/tests/unit/Contrib.PackageUrl.Factories.PackageUrlFactory.js similarity index 93% rename from tests/unit/Factories.PackageUrlFactory.spec.js rename to tests/unit/Contrib.PackageUrl.Factories.PackageUrlFactory.js index fe117bbfc..f38c7b99c 100644 --- a/tests/unit/Factories.PackageUrlFactory.spec.js +++ b/tests/unit/Contrib.PackageUrl.Factories.PackageUrlFactory.js @@ -26,7 +26,7 @@ const { } = require('../../') const { randomString } = require('../_helpers/stringFunctions') -suite('unit: Factories.PackageUrlFactory', () => { +suite('unit: Contrib.PackageUrl.Factories.PackageUrlFactory', () => { test('construct', () => { const type = randomString(5) From 03e617db615ef04c9b4303d0c0dde2c25d3c3c99 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 18 Feb 2026 17:38:28 +0100 Subject: [PATCH 09/35] dings Signed-off-by: Jan Kowalleck --- ...mber.spec.js => Contrib.Bom.Utils.spec.js} | 2 +- ...geJson.Factories.PackageUrlFactory.spec.js | 4 +- .../Contrib.FromNodePackageJson.Utils.spec.js | 118 +++++++++--------- 3 files changed, 63 insertions(+), 61 deletions(-) rename tests/unit/{Contrib.Bom.Utils.randomSerialNumber.spec.js => Contrib.Bom.Utils.spec.js} (95%) diff --git a/tests/unit/Contrib.Bom.Utils.randomSerialNumber.spec.js b/tests/unit/Contrib.Bom.Utils.spec.js similarity index 95% rename from tests/unit/Contrib.Bom.Utils.randomSerialNumber.spec.js rename to tests/unit/Contrib.Bom.Utils.spec.js index 8463b88cb..a58572f35 100644 --- a/tests/unit/Contrib.Bom.Utils.randomSerialNumber.spec.js +++ b/tests/unit/Contrib.Bom.Utils.spec.js @@ -25,7 +25,7 @@ const { Contrib, } = require('../../') -suite('unit: Contrib.Bom.Utils.randomSerialNumber', () => { +suite('unit: Contrib.Bom.Utils', () => { suite('randomSerialNumber()', () => { test('has correct format according to XSD', () => { const value = Contrib.Bom.Utils.randomSerialNumber() diff --git a/tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.spec.js b/tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.spec.js index 15de3298e..68f1df5a1 100644 --- a/tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.spec.js +++ b/tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.spec.js @@ -46,7 +46,7 @@ suite('unit: Contrib.FromNodePackageJson.Factories.PackageUrlFactory', () => { ) ]) }) - const purlFac = new PackageUrlFactory('npm') + const purlFac = new Contrib.FromNodePackageJson.Factories.PackageUrlFactory('npm') const actual = purlFac.makeFromComponent(component) assert.deepEqual(actual, { type: 'npm', @@ -68,7 +68,7 @@ suite('unit: Contrib.FromNodePackageJson.Factories.PackageUrlFactory', () => { ) ]) }) - const purlFac = new PackageUrlFactory('npm') + const purlFac = new Contrib.FromNodePackageJson.Factories.PackageUrlFactory('npm') const actual = purlFac.makeFromComponent(component) assert.deepEqual(actual, { diff --git a/tests/unit/Contrib.FromNodePackageJson.Utils.spec.js b/tests/unit/Contrib.FromNodePackageJson.Utils.spec.js index 3eaab60b0..fbcc619ec 100644 --- a/tests/unit/Contrib.FromNodePackageJson.Utils.spec.js +++ b/tests/unit/Contrib.FromNodePackageJson.Utils.spec.js @@ -28,66 +28,68 @@ const { Contrib, } = require('../../') -suite('unit: Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher', () => { - test('matches pure domain', () => { - const actual = Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher.test('https://registry.npmjs.org') - assert.strictEqual(actual, true) - }) - test('matches with path', () => { - const actual = Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher.test('https://registry.npmjs.org/foo/bar') - assert.strictEqual(actual, true) - }) - suite('not match unexpected', () => { - for (const c of [ - 'https://my-own=registry.local', - 'https://registry.npmjs.org.uk', - 'https://registry.npmjs.org.uk/foo/bar' - ]) { - test(c, () => { - const actual = Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher.test(c) - assert.strictEqual(actual, false) - }) - } +suite('unit: Contrib.FromNodePackageJson.Utils', () => { + suite('defaultRegistryMatcher', () => { + test('matches pure domain', () => { + const actual = Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher.test('https://registry.npmjs.org') + assert.strictEqual(actual, true) + }) + test('matches with path', () => { + const actual = Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher.test('https://registry.npmjs.org/foo/bar') + assert.strictEqual(actual, true) + }) + suite('not match unexpected', () => { + for (const c of [ + 'https://my-own=registry.local', + 'https://registry.npmjs.org.uk', + 'https://registry.npmjs.org.uk/foo/bar' + ]) { + test(c, () => { + const actual = Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher.test(c) + assert.strictEqual(actual, false) + }) + } + }) }) -}) -suite('unit: Contrib.FromNodePackageJson.Utils.parsePackageIntegrity', () => { - suite('as expected', () => { - for (const [c, ...expected] of [ - ['sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==', - HashAlgorithm['SHA-512'], - 'cef8fae53905788b778ba6a3e5b22f243ce38d0406b38a3fb0da1ece0d45d6461aa7d36eda3714769c334522531cc3331b41fb6d9927e2b350a489a1bb1597d8' - ], - ['sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0=', - HashAlgorithm['SHA-1'], - '2aae6c35c94fcfb415dbe95f408b9ce91ee846ed' - ], - ['sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=', - HashAlgorithm['SHA-256'], - 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' - ], - ['sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC', - HashAlgorithm['SHA-384'], - 'a2a56e01f5d129aa7b7dd81c098e6eca433af91f46a90f0afeec72f6bc7b1cd42519897590fcd0868d70c7827063cc02' - ], - ]) { - test(c, () => { - const actual = Contrib.FromNodePackageJson.Utils.parsePackageIntegrity(c) - assert.deepStrictEqual(actual, expected) - }) - } - }) - suite('fails', () => { - for (const c of [ - 'sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0', // missing character - 'sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0==', // additional character - 'sha512-Kq5sNclPz7QV2+lfQIuc6R7oRu0=', // alg and hash dont match - ]) { - test(c, () => { - assert.throws(() => { - Contrib.FromNodePackageJson.Utils.parsePackageIntegrity(c) + suite('unit: parsePackageIntegrity', () => { + suite('as expected', () => { + for (const [c, ...expected] of [ + ['sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==', + HashAlgorithm['SHA-512'], + 'cef8fae53905788b778ba6a3e5b22f243ce38d0406b38a3fb0da1ece0d45d6461aa7d36eda3714769c334522531cc3331b41fb6d9927e2b350a489a1bb1597d8' + ], + ['sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0=', + HashAlgorithm['SHA-1'], + '2aae6c35c94fcfb415dbe95f408b9ce91ee846ed' + ], + ['sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=', + HashAlgorithm['SHA-256'], + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' + ], + ['sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC', + HashAlgorithm['SHA-384'], + 'a2a56e01f5d129aa7b7dd81c098e6eca433af91f46a90f0afeec72f6bc7b1cd42519897590fcd0868d70c7827063cc02' + ], + ]) { + test(c, () => { + const actual = Contrib.FromNodePackageJson.Utils.parsePackageIntegrity(c) + assert.deepStrictEqual(actual, expected) + }) + } + }) + suite('fails', () => { + for (const c of [ + 'sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0', // missing character + 'sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0==', // additional character + 'sha512-Kq5sNclPz7QV2+lfQIuc6R7oRu0=', // alg and hash dont match + ]) { + test(c, () => { + assert.throws(() => { + Contrib.FromNodePackageJson.Utils.parsePackageIntegrity(c) + }) }) - }) - } + } + }) }) }) From aeb41fa46aed8ff96d8aec59d7db7838614c34d0 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 18 Feb 2026 17:40:55 +0100 Subject: [PATCH 10/35] dings Signed-off-by: Jan Kowalleck --- ...ib.FromNodePackageJson.Builders.ComponentBuilder.node.test.js} | 0 ...Contrib.FromNodePackageJson.Builders.ToolBuilder.node.test.js} | 0 ...dePackageJson.Factories.ExternalReferenceFactory.node.test.js} | 0 ....FromNodePackageJson.Factories.PackageUrlFactory.node.test.js} | 0 ...ib.FromNodePackageJson.Builders.ComponentBuilder.node.spec.js} | 0 ...Contrib.FromNodePackageJson.Builders.ToolBuilder.node.spec.js} | 0 ....FromNodePackageJson.Factories.PackageUrlFactory.node.spec.js} | 0 ...ils.spec.js => Contrib.FromNodePackageJson.Utils.node.spec.js} | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename tests/integration/{Contrib.FromNodePackageJson.Builders.ComponentBuilder.test.js => Contrib.FromNodePackageJson.Builders.ComponentBuilder.node.test.js} (100%) rename tests/integration/{Contrib.FromNodePackageJson.Builders.ToolBuilder.test.js => Contrib.FromNodePackageJson.Builders.ToolBuilder.node.test.js} (100%) rename tests/integration/{Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory.test.js => Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory.node.test.js} (100%) rename tests/integration/{Contrib.FromNodePackageJson.Factories.PackageUrlFactory.test.js => Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.test.js} (100%) rename tests/unit/{Contrib.FromNodePackageJson.Builders.ComponentBuilder.spec.js => Contrib.FromNodePackageJson.Builders.ComponentBuilder.node.spec.js} (100%) rename tests/unit/{Contrib.FromNodePackageJson.Builders.ToolBuilder.spec.js => Contrib.FromNodePackageJson.Builders.ToolBuilder.node.spec.js} (100%) rename tests/unit/{Contrib.FromNodePackageJson.Factories.PackageUrlFactory.spec.js => Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.spec.js} (100%) rename tests/unit/{Contrib.FromNodePackageJson.Utils.spec.js => Contrib.FromNodePackageJson.Utils.node.spec.js} (100%) diff --git a/tests/integration/Contrib.FromNodePackageJson.Builders.ComponentBuilder.test.js b/tests/integration/Contrib.FromNodePackageJson.Builders.ComponentBuilder.node.test.js similarity index 100% rename from tests/integration/Contrib.FromNodePackageJson.Builders.ComponentBuilder.test.js rename to tests/integration/Contrib.FromNodePackageJson.Builders.ComponentBuilder.node.test.js diff --git a/tests/integration/Contrib.FromNodePackageJson.Builders.ToolBuilder.test.js b/tests/integration/Contrib.FromNodePackageJson.Builders.ToolBuilder.node.test.js similarity index 100% rename from tests/integration/Contrib.FromNodePackageJson.Builders.ToolBuilder.test.js rename to tests/integration/Contrib.FromNodePackageJson.Builders.ToolBuilder.node.test.js diff --git a/tests/integration/Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory.test.js b/tests/integration/Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory.node.test.js similarity index 100% rename from tests/integration/Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory.test.js rename to tests/integration/Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory.node.test.js diff --git a/tests/integration/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.test.js b/tests/integration/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.test.js similarity index 100% rename from tests/integration/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.test.js rename to tests/integration/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.test.js diff --git a/tests/unit/Contrib.FromNodePackageJson.Builders.ComponentBuilder.spec.js b/tests/unit/Contrib.FromNodePackageJson.Builders.ComponentBuilder.node.spec.js similarity index 100% rename from tests/unit/Contrib.FromNodePackageJson.Builders.ComponentBuilder.spec.js rename to tests/unit/Contrib.FromNodePackageJson.Builders.ComponentBuilder.node.spec.js diff --git a/tests/unit/Contrib.FromNodePackageJson.Builders.ToolBuilder.spec.js b/tests/unit/Contrib.FromNodePackageJson.Builders.ToolBuilder.node.spec.js similarity index 100% rename from tests/unit/Contrib.FromNodePackageJson.Builders.ToolBuilder.spec.js rename to tests/unit/Contrib.FromNodePackageJson.Builders.ToolBuilder.node.spec.js diff --git a/tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.spec.js b/tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.spec.js similarity index 100% rename from tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.spec.js rename to tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.spec.js diff --git a/tests/unit/Contrib.FromNodePackageJson.Utils.spec.js b/tests/unit/Contrib.FromNodePackageJson.Utils.node.spec.js similarity index 100% rename from tests/unit/Contrib.FromNodePackageJson.Utils.spec.js rename to tests/unit/Contrib.FromNodePackageJson.Utils.node.spec.js From d4627f071e410c6a22fa54a2a6d88738e7eb6f37 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 18 Feb 2026 18:06:03 +0100 Subject: [PATCH 11/35] dings Signed-off-by: Jan Kowalleck --- examples/node/javascript/deprecated.cjs | 60 ---------------- examples/node/javascript/deprecated.mjs | 60 ---------------- .../typescript/example.cjs/src/deprecated.ts | 68 ------------------- .../typescript/example.mjs/src/deprecated.ts | 68 ------------------- 4 files changed, 256 deletions(-) delete mode 100644 examples/node/javascript/deprecated.cjs delete mode 100644 examples/node/javascript/deprecated.mjs delete mode 100644 examples/node/typescript/example.cjs/src/deprecated.ts delete mode 100644 examples/node/typescript/example.mjs/src/deprecated.ts diff --git a/examples/node/javascript/deprecated.cjs b/examples/node/javascript/deprecated.cjs deleted file mode 100644 index bffbf78e5..000000000 --- a/examples/node/javascript/deprecated.cjs +++ /dev/null @@ -1,60 +0,0 @@ -/*! -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. -*/ - -/** - * Example showcasing the deprecated symbols still work. - * @see https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1350 - */ - -const fs = require('node:fs') -const path = require('node:path') - -const CDX = require('@cyclonedx/cyclonedx-library') -// Full library is available as `CDX`, now. -// Alternative for better tree-shaking on bundling, import only the needed symbols like so: -// const { Bom, Component } = require('@cyclonedx/cyclonedx-library/Models') -// const { ComponentType } = require('@cyclonedx/cyclonedx-library/Enums') - -const dBU1 = CDX.Utils.BomUtility.randomSerialNumber() -console.log(dBU1) - -const dNU1 = CDX.Utils.NpmjsUtility.defaultRegistryMatcher.test('foo') -const dNU2 = CDX.Utils.NpmjsUtility.parsePackageIntegrity('sha1-aSbRsZT7xze47tUTdW3i/Np+pAg=') -console.log(dNU1, dNU2) - -const dLU1 = new CDX.Utils.LicenseUtility.LicenseEvidenceGatherer({fs, path}) -console.log(dLU1) - -/** @type {CDX.Types.NodePackageJson} */ -const dTnpj1 = {} -// const dTnpj2 =CDX.Types.isNodePackageJson(dTnpj1) -try { CDX.Types.assertNodePackageJson(dTnpj1) } catch { /* pass */ } -console.log(dTnpj1) - -const dF1 = new CDX.Factories.PackageUrlFactory('generic') -const dF2 = new CDX.Factories.LicenseFactory() -console.log(dF1, dF2) - -const dFnpj3 = new CDX.Factories.FromNodePackageJson.PackageUrlFactory('npm') -const dFnpj4 = new CDX.Factories.FromNodePackageJson.ExternalReferenceFactory() -console.log(dFnpj3, dFnpj4) - -const dBnpj1 = new CDX.Builders.FromNodePackageJson.ComponentBuilder(dFnpj4, dF2) -const dBnpj2 = new CDX.Builders.FromNodePackageJson.ToolBuilder(dFnpj4) -console.log(dBnpj1, dBnpj2) diff --git a/examples/node/javascript/deprecated.mjs b/examples/node/javascript/deprecated.mjs deleted file mode 100644 index db9ca6261..000000000 --- a/examples/node/javascript/deprecated.mjs +++ /dev/null @@ -1,60 +0,0 @@ -/*! -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. -*/ - -/** - * Example showcasing the deprecated symbols still work. - * @see https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1350 - */ - -import * as fs from 'node:fs' -import * as path from 'node:path' - -import * as CDX from '@cyclonedx/cyclonedx-library' -// Full library is available as `CDX`, now. -// Alternative for better tree-shaking on bundling, import only the needed symbols like so: -// import { Bom, Component } from '@cyclonedx/cyclonedx-library/Models' -// import { ComponentType } from '@cyclonedx/cyclonedx-library/Enums' - -const dBU1 = CDX.Utils.BomUtility.randomSerialNumber() -console.log(dBU1) - -const dNU1 = CDX.Utils.NpmjsUtility.defaultRegistryMatcher.test('foo') -const dNU2 = CDX.Utils.NpmjsUtility.parsePackageIntegrity('sha1-aSbRsZT7xze47tUTdW3i/Np+pAg=') -console.log(dNU1, dNU2) - -const dLU1 = new CDX.Utils.LicenseUtility.LicenseEvidenceGatherer({fs, path}) -console.log(dLU1) - -/** @type {CDX.Types.NodePackageJson} */ -const dTnpj1 = {} -// const dTnpj2 =CDX.Types.isNodePackageJson(dTnpj1) -try { CDX.Types.assertNodePackageJson(dTnpj1) } catch { /* pass */ } -console.log(dTnpj1) - -const dF1 = new CDX.Factories.PackageUrlFactory('generic') -const dF2 = new CDX.Factories.LicenseFactory() -console.log(dF1, dF2) - -const dFnpj3 = new CDX.Factories.FromNodePackageJson.PackageUrlFactory('npm') -const dFnpj4 = new CDX.Factories.FromNodePackageJson.ExternalReferenceFactory() -console.log(dFnpj3, dFnpj4) - -const dBnpj1 = new CDX.Builders.FromNodePackageJson.ComponentBuilder(dFnpj4, dF2) -const dBnpj2 = new CDX.Builders.FromNodePackageJson.ToolBuilder(dFnpj4) -console.log(dBnpj1, dBnpj2) diff --git a/examples/node/typescript/example.cjs/src/deprecated.ts b/examples/node/typescript/example.cjs/src/deprecated.ts deleted file mode 100644 index 6a166d0fb..000000000 --- a/examples/node/typescript/example.cjs/src/deprecated.ts +++ /dev/null @@ -1,68 +0,0 @@ -/*! -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. -*/ - -/** - * Example showcasing the deprecated symbols still work. - * @see https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1350 - */ - -import * as fs from 'node:fs' -import * as path from 'node:path' - -import * as CDX from '@cyclonedx/cyclonedx-library' -// Full library is available as `CDX`, now. -// Alternative for better tree-shaking on bundling, import only the needed symbols like so: -// import { Bom, Component } from '@cyclonedx/cyclonedx-library/Models' -// import { ComponentType } from '@cyclonedx/cyclonedx-library/Enums' - -const dBU1 = CDX.Utils.BomUtility.randomSerialNumber() -console.log(dBU1) - -const dNU1 = CDX.Utils.NpmjsUtility.defaultRegistryMatcher.test('foo') -const dNU2 = CDX.Utils.NpmjsUtility.parsePackageIntegrity('sha1-aSbRsZT7xze47tUTdW3i/Np+pAg=') -console.log(dNU1, dNU2) - -type dLU1_T = CDX.Utils.LicenseUtility.LicenseEvidenceGatherer -const fsU: CDX.Utils.LicenseUtility.FsUtils = fs -const pathU: CDX.Utils.LicenseUtility.PathUtils = path -const dLU1: dLU1_T = new CDX.Utils.LicenseUtility.LicenseEvidenceGatherer({fs: fsU, path: pathU}) -console.log(dLU1) - -const dTnpj1: CDX.Types.NodePackageJson = {} -// const dTnpj2 =CDX.Types.isNodePackageJson(dTnpj1) -try { CDX.Types.assertNodePackageJson(dTnpj1) } catch { /* pass */ } -console.log(dTnpj1) - -type dF1_T = CDX.Factories.PackageUrlFactory -type dF2_T = CDX.Factories.LicenseFactory -const dF1: dF1_T = new CDX.Factories.PackageUrlFactory('generic') -const dF2: dF2_T = new CDX.Factories.LicenseFactory() -console.log(dF1, dF2) - -type dFnpj3_T = CDX.Factories.FromNodePackageJson.PackageUrlFactory -const dFnpj3: dFnpj3_T = new CDX.Factories.FromNodePackageJson.PackageUrlFactory('npm') -type dFnpj4_T = CDX.Factories.FromNodePackageJson.ExternalReferenceFactory -const dFnpj4: dFnpj4_T = new CDX.Factories.FromNodePackageJson.ExternalReferenceFactory() -console.log(dFnpj3, dFnpj4) - -type dBnpj1_T = CDX.Builders.FromNodePackageJson.ComponentBuilder -const dBnpj1: dBnpj1_T = new CDX.Builders.FromNodePackageJson.ComponentBuilder(dFnpj4, dF2) -type dBnpj2_T = CDX.Builders.FromNodePackageJson.ToolBuilder -const dBnpj2: dBnpj2_T = new CDX.Builders.FromNodePackageJson.ToolBuilder(dFnpj4) -console.log(dBnpj1, dBnpj2) diff --git a/examples/node/typescript/example.mjs/src/deprecated.ts b/examples/node/typescript/example.mjs/src/deprecated.ts deleted file mode 100644 index 6a166d0fb..000000000 --- a/examples/node/typescript/example.mjs/src/deprecated.ts +++ /dev/null @@ -1,68 +0,0 @@ -/*! -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. -*/ - -/** - * Example showcasing the deprecated symbols still work. - * @see https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1350 - */ - -import * as fs from 'node:fs' -import * as path from 'node:path' - -import * as CDX from '@cyclonedx/cyclonedx-library' -// Full library is available as `CDX`, now. -// Alternative for better tree-shaking on bundling, import only the needed symbols like so: -// import { Bom, Component } from '@cyclonedx/cyclonedx-library/Models' -// import { ComponentType } from '@cyclonedx/cyclonedx-library/Enums' - -const dBU1 = CDX.Utils.BomUtility.randomSerialNumber() -console.log(dBU1) - -const dNU1 = CDX.Utils.NpmjsUtility.defaultRegistryMatcher.test('foo') -const dNU2 = CDX.Utils.NpmjsUtility.parsePackageIntegrity('sha1-aSbRsZT7xze47tUTdW3i/Np+pAg=') -console.log(dNU1, dNU2) - -type dLU1_T = CDX.Utils.LicenseUtility.LicenseEvidenceGatherer -const fsU: CDX.Utils.LicenseUtility.FsUtils = fs -const pathU: CDX.Utils.LicenseUtility.PathUtils = path -const dLU1: dLU1_T = new CDX.Utils.LicenseUtility.LicenseEvidenceGatherer({fs: fsU, path: pathU}) -console.log(dLU1) - -const dTnpj1: CDX.Types.NodePackageJson = {} -// const dTnpj2 =CDX.Types.isNodePackageJson(dTnpj1) -try { CDX.Types.assertNodePackageJson(dTnpj1) } catch { /* pass */ } -console.log(dTnpj1) - -type dF1_T = CDX.Factories.PackageUrlFactory -type dF2_T = CDX.Factories.LicenseFactory -const dF1: dF1_T = new CDX.Factories.PackageUrlFactory('generic') -const dF2: dF2_T = new CDX.Factories.LicenseFactory() -console.log(dF1, dF2) - -type dFnpj3_T = CDX.Factories.FromNodePackageJson.PackageUrlFactory -const dFnpj3: dFnpj3_T = new CDX.Factories.FromNodePackageJson.PackageUrlFactory('npm') -type dFnpj4_T = CDX.Factories.FromNodePackageJson.ExternalReferenceFactory -const dFnpj4: dFnpj4_T = new CDX.Factories.FromNodePackageJson.ExternalReferenceFactory() -console.log(dFnpj3, dFnpj4) - -type dBnpj1_T = CDX.Builders.FromNodePackageJson.ComponentBuilder -const dBnpj1: dBnpj1_T = new CDX.Builders.FromNodePackageJson.ComponentBuilder(dFnpj4, dF2) -type dBnpj2_T = CDX.Builders.FromNodePackageJson.ToolBuilder -const dBnpj2: dBnpj2_T = new CDX.Builders.FromNodePackageJson.ToolBuilder(dFnpj4) -console.log(dBnpj1, dBnpj2) From cffbe7e66a3dc88259a7a197b0aad1b5a9b98f79 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 18 Feb 2026 18:10:25 +0100 Subject: [PATCH 12/35] ci Signed-off-by: Jan Kowalleck --- .github/workflows/nodejs.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 04b053f1c..d7cdc01e5 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -360,9 +360,6 @@ jobs: - name: run example run: node -- 'example.${{ matrix.js-type }}' working-directory: ${{ env.EXAMPLE_DIR }} - - name: run deprecated - run: node -- 'deprecated.${{ matrix.js-type }}' - working-directory: ${{ env.EXAMPLE_DIR }} example-TS: needs: [ 'build' ] From 4e1f448677443cab5f0c88d785aa77e365fefc67 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 18 Feb 2026 18:23:41 +0100 Subject: [PATCH 13/35] test Signed-off-by: Jan Kowalleck --- ...ePackageJson.Factories.PackageUrlFactory.node.spec.js | 9 ++++++++- ...ntrib.PackageUrl.Factories.PackageUrlFactory.spec.js} | 0 2 files changed, 8 insertions(+), 1 deletion(-) rename tests/unit/{Contrib.PackageUrl.Factories.PackageUrlFactory.js => Contrib.PackageUrl.Factories.PackageUrlFactory.spec.js} (100%) diff --git a/tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.spec.js b/tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.spec.js index 68f1df5a1..78593dc88 100644 --- a/tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.spec.js +++ b/tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.spec.js @@ -33,7 +33,14 @@ suite('unit: Contrib.FromNodePackageJson.Factories.PackageUrlFactory', () => { const component = new Component(ComponentType.Library, 'testing') const purlFac = new Contrib.FromNodePackageJson.Factories.PackageUrlFactory('npm') const actual = purlFac.makeFromComponent(component) - assert.deepEqual(actual, 'TODO') + assert.deepEqual(actual, { + name: 'testing', + namespace: undefined, + qualifiers: undefined, + subpath: undefined, + type: 'npm', + version: undefined + }) }) test('strips default registry from qualifiers', () => { diff --git a/tests/unit/Contrib.PackageUrl.Factories.PackageUrlFactory.js b/tests/unit/Contrib.PackageUrl.Factories.PackageUrlFactory.spec.js similarity index 100% rename from tests/unit/Contrib.PackageUrl.Factories.PackageUrlFactory.js rename to tests/unit/Contrib.PackageUrl.Factories.PackageUrlFactory.spec.js From 4ed8754b2431b7e0e2dbf962208f3ee6533ecd73 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Thu, 19 Feb 2026 10:07:20 +0100 Subject: [PATCH 14/35] examples Signed-off-by: Jan Kowalleck --- examples/node/typescript/example.cjs/package.json | 2 +- examples/node/typescript/example.mjs/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/node/typescript/example.cjs/package.json b/examples/node/typescript/example.cjs/package.json index 5531d618b..d9c1885b5 100644 --- a/examples/node/typescript/example.cjs/package.json +++ b/examples/node/typescript/example.cjs/package.json @@ -23,6 +23,6 @@ "scripts": { "prebuild": "tsc -b --clean", "build": "tsc -b", - "example": "node dist/example.js && node dist/deprecated.js" + "example": "node dist/example.js" } } diff --git a/examples/node/typescript/example.mjs/package.json b/examples/node/typescript/example.mjs/package.json index 6404c5d98..742e6753d 100644 --- a/examples/node/typescript/example.mjs/package.json +++ b/examples/node/typescript/example.mjs/package.json @@ -23,6 +23,6 @@ "scripts": { "prebuild": "tsc -b --clean", "build": "tsc -b", - "example": "node dist/example.js && node dist/deprecated.js" + "example": "node dist/example.js" } } From dd164d1506f4143780ba6331543de5acedc95fb5 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Thu, 19 Feb 2026 20:09:20 +0100 Subject: [PATCH 15/35] feat!: `Component.purl` as `string` (#1379) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### 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 --- HISTORY.md | 4 ++++ examples/node/javascript/example.cjs | 3 +-- examples/node/javascript/example.mjs | 3 +-- examples/node/typescript/example.cjs/src/example.ts | 3 +-- examples/node/typescript/example.mjs/src/example.ts | 3 +-- src/models/component.ts | 6 ++---- tests/_data/models.js | 4 +--- tests/unit/Models.Component.spec.js | 3 +-- 8 files changed, 12 insertions(+), 17 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index dd1b695a5..d69577575 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. * BREAKING changes * Removed deprecated symbols + * No longer use external standard's implementations * Removed * Entrypoint `Builders` (via [#1377]) * Entrypoint `Factories` (via [#1377]) @@ -54,10 +55,13 @@ All notable changes to this project will be documented in this file. Use `Contrib.FromNodePackageJson.Utils.parsePackageIntegrity` instead. * Deprecated symbol `Utils.NpmjsUtility.defaultRegistryMatcher` ([#1346] via [#1377]) Use `Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher` instead. +* Changed + * `Component.purl` is a `string` now, was `PackaheUrl` ([#1348] via [#]) * Build * Use _webpack_ `5.105.2` now, was `v5.103.0` (via [#1360], [#1374]) [#1346]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1346 +[#1348]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1348 [#1360]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1360 [#1374]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1374 [#1377]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1377 diff --git a/examples/node/javascript/example.cjs b/examples/node/javascript/example.cjs index d69c9f5bb..7ee4cd260 100644 --- a/examples/node/javascript/example.cjs +++ b/examples/node/javascript/example.cjs @@ -26,7 +26,6 @@ const CDX = require('@cyclonedx/cyclonedx-library') // const { ComponentType } = require('@cyclonedx/cyclonedx-library/Enums') const lFac = new CDX.Contrib.License.Factories.LicenseFactory() -const purlFac = new CDX.Contrib.PackageUrl.Factories.PackageUrlFactory('generic') const bom = new CDX.Models.Bom() bom.metadata.component = new CDX.Models.Component( @@ -44,7 +43,7 @@ const componentA = new CDX.Models.Component( } ) componentA.licenses.add(lFac.makeFromString('Apache-2.0')) -componentA.purl = purlFac.makeFromComponent(componentA) +componentA.purl = `pkg:generic/${componentA.group}/${componentA.name}@${componentA.version}` bom.components.add(componentA) bom.metadata.component.dependencies.add(componentA.bomRef) diff --git a/examples/node/javascript/example.mjs b/examples/node/javascript/example.mjs index 3b5f92480..41c0cbd28 100644 --- a/examples/node/javascript/example.mjs +++ b/examples/node/javascript/example.mjs @@ -26,7 +26,6 @@ import * as CDX from '@cyclonedx/cyclonedx-library' // import { ComponentType } from '@cyclonedx/cyclonedx-library/Enums' const lFac = new CDX.Contrib.License.Factories.LicenseFactory() -const purlFac = new CDX.Contrib.PackageUrl.Factories.PackageUrlFactory('generic') const bom = new CDX.Models.Bom() bom.metadata.component = new CDX.Models.Component( @@ -44,7 +43,7 @@ const componentA = new CDX.Models.Component( } ) componentA.licenses.add(lFac.makeFromString('Apache-2.0')) -componentA.purl = purlFac.makeFromComponent(componentA) +componentA.purl = `pkg:generic/${componentA.group}/${componentA.name}@${componentA.version}` bom.components.add(componentA) bom.metadata.component.dependencies.add(componentA.bomRef) diff --git a/examples/node/typescript/example.cjs/src/example.ts b/examples/node/typescript/example.cjs/src/example.ts index 1b6a055d8..5d3a69237 100644 --- a/examples/node/typescript/example.cjs/src/example.ts +++ b/examples/node/typescript/example.cjs/src/example.ts @@ -26,7 +26,6 @@ import * as CDX from '@cyclonedx/cyclonedx-library' // import { ComponentType } from '@cyclonedx/cyclonedx-library/Enums' const lFac = new CDX.Contrib.License.Factories.LicenseFactory() -const purlFac = new CDX.Contrib.PackageUrl.Factories.PackageUrlFactory('generic') const bom = new CDX.Models.Bom() bom.metadata.component = new CDX.Models.Component( @@ -44,7 +43,7 @@ const componentA = new CDX.Models.Component( } ) componentA.licenses.add(lFac.makeFromString('Apache-2.0')) -componentA.purl = purlFac.makeFromComponent(componentA) +componentA.purl = `pkg:generic/${componentA.group}/${componentA.name}@${componentA.version}` bom.components.add(componentA) bom.metadata.component.dependencies.add(componentA.bomRef) diff --git a/examples/node/typescript/example.mjs/src/example.ts b/examples/node/typescript/example.mjs/src/example.ts index 2df810501..4022b236c 100644 --- a/examples/node/typescript/example.mjs/src/example.ts +++ b/examples/node/typescript/example.mjs/src/example.ts @@ -26,7 +26,6 @@ import * as CDX from '@cyclonedx/cyclonedx-library' // import { ComponentType } from '@cyclonedx/cyclonedx-library/Enums' const lFac = new CDX.Contrib.License.Factories.LicenseFactory() -const purlFac = new CDX.Contrib.PackageUrl.Factories.PackageUrlFactory('generic') const bom = new CDX.Models.Bom() bom.metadata.component = new CDX.Models.Component( @@ -44,7 +43,7 @@ const componentA = new CDX.Models.Component( } ) componentA.licenses.add(lFac.makeFromString('Apache-2.0')) -componentA.purl = purlFac.makeFromComponent(componentA) +componentA.purl = `pkg:generic/${componentA.group}/${componentA.name}@${componentA.version}` bom.components.add(componentA) bom.metadata.component.dependencies.add(componentA.bomRef) diff --git a/src/models/component.ts b/src/models/component.ts index a07c96388..45d21dfca 100644 --- a/src/models/component.ts +++ b/src/models/component.ts @@ -17,8 +17,6 @@ SPDX-License-Identifier: Apache-2.0 Copyright (c) OWASP Foundation. All Rights Reserved. */ -import type { PackageURL } from 'packageurl-js' - import type { Comparable } from '../_helpers/sortable' import { SortableComparables } from '../_helpers/sortable' import { treeIteratorSymbol } from '../_helpers/tree' @@ -69,7 +67,7 @@ export class Component implements Comparable { hashes: HashDictionary licenses: LicenseRepository publisher?: string - purl?: PackageURL + purl?: string scope?: ComponentScope supplier?: OrganizationalEntity swid?: SWID @@ -139,7 +137,7 @@ export class Component implements Comparable { return bomRefCompare } if (this.purl !== undefined && other.purl !== undefined) { - return this.purl.toString().localeCompare(other.purl.toString()) + return this.purl.localeCompare(other.purl) } if (this.#cpe !== undefined && other.#cpe !== undefined) { return this.#cpe.localeCompare(other.#cpe) diff --git a/tests/_data/models.js b/tests/_data/models.js index 321fbd74b..fbcdcf3f9 100644 --- a/tests/_data/models.js +++ b/tests/_data/models.js @@ -17,8 +17,6 @@ SPDX-License-Identifier: Apache-2.0 Copyright (c) OWASP Foundation. All Rights Reserved. */ -const { PackageURL } = require('packageurl-js') - const { Enums, Models, Types } = require('../../') /* eslint-disable jsdoc/no-undefined-types -- something is odd with type detection */ @@ -169,7 +167,7 @@ function createComplexStructure () { return license })(new Models.SpdxLicense('MIT'))) component.publisher = 'the publisher' - component.purl = new PackageURL('npm', 'acme', 'dummy-component', '1337-beta', undefined, undefined) + component.purl = 'pkg:npm/acme/dummy-component@1337-beta' component.scope = Enums.ComponentScope.Required component.supplier = new Models.OrganizationalEntity({ name: 'Component Supplier' }) component.supplier.url.add(new URL('https://localhost/componentSupplier-B')) diff --git a/tests/unit/Models.Component.spec.js b/tests/unit/Models.Component.spec.js index 7c7fa1e8f..b01d35a87 100644 --- a/tests/unit/Models.Component.spec.js +++ b/tests/unit/Models.Component.spec.js @@ -20,7 +20,6 @@ Copyright (c) OWASP Foundation. All Rights Reserved. const assert = require('node:assert') const { suite, test } = require('mocha') -const { PackageURL } = require('packageurl-js') const { Models: { @@ -62,7 +61,7 @@ suite('unit: Models.Component', () => { const dummyBomRef = new BomRef('testing') const dummyExtRef = new ExternalReference('../', 'other') const dummyLicense = new NamedLicense('mine') - const dummyPurl = new PackageURL('npm', 'ns', 'app', '1.33.7', {}, undefined) + const dummyPurl = 'pkg:npm/ns/app@1.33.7' const dummySupplier = new OrganizationalEntity({ name: 'dummySupplier' }) const dummySWID = new SWID('my-fake-swid', 'foo-bar') const subComponent = new Component('library', 'MySubComponent') From 1f7bf135b5ca53512314999db69a188d2a4df87f Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Thu, 19 Feb 2026 20:11:23 +0100 Subject: [PATCH 16/35] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index d69577575..b300bfaea 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -56,7 +56,7 @@ All notable changes to this project will be documented in this file. * Deprecated symbol `Utils.NpmjsUtility.defaultRegistryMatcher` ([#1346] via [#1377]) Use `Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher` instead. * Changed - * `Component.purl` is a `string` now, was `PackaheUrl` ([#1348] via [#]) + * `Component.purl` is a `string` now, was `PackaheUrl` ([#1348] via [#1379]) * Build * Use _webpack_ `5.105.2` now, was `v5.103.0` (via [#1360], [#1374]) @@ -65,6 +65,7 @@ All notable changes to this project will be documented in this file. [#1360]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1360 [#1374]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1374 [#1377]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1377 +[#1379]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1379 ## 9.4.1 -- 2025-12-04 From 7c69f36de5f5ee9fe2a20840a0625c25dbeab365 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Thu, 19 Feb 2026 20:12:40 +0100 Subject: [PATCH 17/35] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index b300bfaea..dca16e4be 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. * BREAKING changes * Removed deprecated symbols - * No longer use external standard's implementations + * No longer use external standards' implementations nor models * Removed * Entrypoint `Builders` (via [#1377]) * Entrypoint `Factories` (via [#1377]) From eb6ff9e843c0cc4e020e0066ba5a3ecfc0d251ff Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Thu, 19 Feb 2026 20:31:03 +0100 Subject: [PATCH 18/35] feat!: remove package url factory (#1378) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Description BREAKING Changes: removed symbols * `Contrib.PackageUrl.Factories.PackageUrlFactory` * `Contrib.FromNodePackageJson.Factories.PackageUrlFactory` No longer depend on `packageurl-js@^2.0.1` 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 --- HISTORY.md | 13 +- examples/web/webpack/src/index.js | 2 +- package.json | 5 - src/contrib/fromNodePackageJson/factories.ts | 61 +--- src/contrib/index.common.ts | 1 - src/contrib/packageUrl/factories.ts | 92 ------ src/contrib/packageUrl/index.ts | 20 -- ...n.Factories.PackageUrlFactory.node.test.js | 301 ------------------ ...ageUrl.Factories.PackageUrlFactory.test.js | 227 ------------- ...n.Factories.PackageUrlFactory.node.spec.js | 93 ------ ...ageUrl.Factories.PackageUrlFactory.spec.js | 37 --- 11 files changed, 11 insertions(+), 841 deletions(-) delete mode 100644 src/contrib/packageUrl/factories.ts delete mode 100644 src/contrib/packageUrl/index.ts delete mode 100644 tests/integration/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.test.js delete mode 100644 tests/integration/Contrib.PackageUrl.Factories.PackageUrlFactory.test.js delete mode 100644 tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.spec.js delete mode 100644 tests/unit/Contrib.PackageUrl.Factories.PackageUrlFactory.spec.js diff --git a/HISTORY.md b/HISTORY.md index dca16e4be..cdcaa4d77 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -8,11 +8,13 @@ All notable changes to this project will be documented in this file. * BREAKING changes * Removed deprecated symbols + * Removed PackageUrl factories * No longer use external standards' implementations nor models * Removed * Entrypoint `Builders` (via [#1377]) * Entrypoint `Factories` (via [#1377]) * Entrypoint `Utils` (via [#1377]) + * Entrypoint `Contrib/PackageUrl` (via [#1378]) * Deprecated symbol `Builders` ([#1346] via [#1377]) * Deprecated symbol `Builders.FromNodePackageJson` ([#1346] via [#1377]) * Deprecated symbol `Builders.FromNodePackageJson.ToolBuilder` ([#1346] via [#1377]) @@ -24,12 +26,10 @@ All notable changes to this project will be documented in this file. * Deprecated symbol `Factories.FromNodePackageJson.ExternalReferenceFactory` ([#1346] via [#1377]) Use `Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory` instead. * Deprecated symbol `Factories.FromNodePackageJson.PackageUrlFactory` ([#1346] via [#1377]) - Use `Contrib.FromNodePackageJson.Factories.PackageUrlFactory` instead. - * Deprecated symbol `Factories.LicenseFactory` ([#1346] via [#1377]) + * Deprecated symbol `Factories.LicenseFactory` ([#1346], [#1348] via [#1377], [#1378]) Use `Contrib.License.Factories.LicenseFactory` instead. * Deprecated symbol `Factories.PackageUrlFactory` ([#1346] via [#1377]) - Use `Contrib.PackageUrl.Factories.PackageUrlFactory` instead. - * Deprecated symbol `Types.NodePackageJson` ([#1346] via [#1377]) + * Deprecated symbol `Types.NodePackageJson` ([#1346], [#1348] via [#1377], [#1378]) Use `Contrib.FromNodePackageJson.Types.NodePackageJson` instead. * Deprecated symbol `Types.assertNodePackageJson` ([#1346] via [#1377]) Use `Contrib.FromNodePackageJson.Types.assertNodePackageJson` instead. @@ -55,8 +55,12 @@ All notable changes to this project will be documented in this file. Use `Contrib.FromNodePackageJson.Utils.parsePackageIntegrity` instead. * Deprecated symbol `Utils.NpmjsUtility.defaultRegistryMatcher` ([#1346] via [#1377]) Use `Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher` instead. + * Symbol `Contrib.PackageUrl.Factories.PackageUrlFactory` ([#1348] via [#1378]) + * Symbol `Contrib.FromNodePackageJson.Factories.PackageUrlFactory` ([#1348] via [#1378]) * Changed * `Component.purl` is a `string` now, was `PackaheUrl` ([#1348] via [#1379]) +* Dependencies + * No longer depend on `packageurl-js@^2.0.1` ([#1348] via [#1378]) * Build * Use _webpack_ `5.105.2` now, was `v5.103.0` (via [#1360], [#1374]) @@ -65,6 +69,7 @@ All notable changes to this project will be documented in this file. [#1360]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1360 [#1374]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1374 [#1377]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1377 +[#1378]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1378 [#1379]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1379 ## 9.4.1 -- 2025-12-04 diff --git a/examples/web/webpack/src/index.js b/examples/web/webpack/src/index.js index 0a024b70a..6e63e1984 100644 --- a/examples/web/webpack/src/index.js +++ b/examples/web/webpack/src/index.js @@ -41,7 +41,7 @@ const componentA = new CDX.Models.Component( } ) componentA.licenses.add(lFac.makeFromString('Apache-2.0')) -componentA.purl = purlFac.makeFromComponent(componentA) +componentA.purl = `pkg:generic/${componentA.group}/${componentA.name}@${componentA.version}` bom.components.add(componentA) bom.metadata.component.dependencies.add(componentA.bomRef) diff --git a/package.json b/package.json index 7166d62e4..55d7bc32e 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,6 @@ "node": ">=20.18.0" }, "dependencies": { - "packageurl-js": "^2.0.1", "spdx-expression-parse": "^3.0.1 || ^4" }, "peerDependencies": { @@ -188,10 +187,6 @@ "./Contrib/License": { "types": "./dist.d/contrib/license/index.node.d.ts", "default": "./dist.node/contrib/license/index.node.js" - }, - "./Contrib/PackageUrl": { - "types": "./dist.d/contrib/packageUrl/index.d.ts", - "default": "./dist.node/contrib/packageUrl/index.js" } }, "directories": { diff --git a/src/contrib/fromNodePackageJson/factories.ts b/src/contrib/fromNodePackageJson/factories.ts index d47b62c48..ba0ef5f4f 100644 --- a/src/contrib/fromNodePackageJson/factories.ts +++ b/src/contrib/fromNodePackageJson/factories.ts @@ -26,19 +26,14 @@ Copyright (c) OWASP Foundation. All Rights Reserved. * Normalization should be done downstream, for example via [`normalize-package-data`](https://www.npmjs.com/package/normalize-package-data). */ -import type { PackageURL } from 'packageurl-js' -import { PurlQualifierNames } from 'packageurl-js' - import { isNotUndefined } from '../../_helpers/notUndefined' import { ExternalReferenceType } from '../../enums/externalReferenceType' import { HashAlgorithm } from '../../enums/hashAlogorithm' -import type { Component } from '../../models/component' import { ExternalReference } from '../../models/externalReference' import { HashDictionary } from '../../models/hash' -import { PackageUrlFactory as PlainPackageUrlFactory } from '../packageUrl/factories' import { tryCanonicalizeGitUrl } from './_helpers/gitUrl' import type { NodePackageJson } from './types' -import { defaultRegistryMatcher, parsePackageIntegrity } from './utils' +import { parsePackageIntegrity } from './utils' /** * Node-specific ExternalReferenceFactory. @@ -130,57 +125,3 @@ export class ExternalReferenceFactory { return undefined } } - -/** - * Node-specific PackageUrlFactory. - * @see {@link https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#npm} - */ -export class PackageUrlFactory extends PlainPackageUrlFactory<'npm'> { - /* eslint-disable-next-line @typescript-eslint/no-inferrable-types -- docs */ - override makeFromComponent (component: Component, sort: boolean = false): PackageURL | undefined { - const purl = super.makeFromComponent(component, sort) - return purl === undefined - ? undefined - : this.#finalizeQualifiers(purl) - } - - /** - * Will strip unnecessary qualifiers according to [PURL-SPECIFICATION](https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst#known-qualifiers-keyvalue-pairs). - *

- * Do not abuse qualifiers: it can be tempting to use many qualifier keys but their usage should be limited - * to the bare minimum for proper package identification to ensure that a purl stays compact and readable - * in most cases. - *
- * - * Therefore: - * - "vcs_url" is stripped, if a "download_url" is given. - * - "download_url" is stripped, if it is NPM's default registry ("registry.npmjs.org") - * - "checksum" is stripped, unless a "download_url" or "vcs_url" is given. - */ - #finalizeQualifiers(purl: PackageURL): PackageURL { - /* eslint-disable no-param-reassign -- intended */ - const qualifiers = new Map(Object.entries(purl.qualifiers ?? {})) - - const downloadUrl = qualifiers.get(PurlQualifierNames.DownloadUrl) - if (downloadUrl !== undefined) { - qualifiers.delete(PurlQualifierNames.VcsUrl) - if (defaultRegistryMatcher.test(downloadUrl)) { - qualifiers.delete(PurlQualifierNames.DownloadUrl) - } - } - if (!qualifiers.has(PurlQualifierNames.DownloadUrl) && !qualifiers.has(PurlQualifierNames.VcsUrl)) { - // nothing to base a checksum on - qualifiers.delete(PurlQualifierNames.Checksum) - } - if (qualifiers.size > 0) { - purl.qualifiers = Object.fromEntries(qualifiers.entries()) - /* @ts-expect-error TS2322 */ - purl.qualifiers.__proto__ = null /* eslint-disable-line no-proto -- intended */ - } else { - purl.qualifiers = undefined - } - - return purl - /* eslint-enable no-param-reassign */ - } -} diff --git a/src/contrib/index.common.ts b/src/contrib/index.common.ts index 6c3872168..eb84f8aa3 100644 --- a/src/contrib/index.common.ts +++ b/src/contrib/index.common.ts @@ -22,4 +22,3 @@ Copyright (c) OWASP Foundation. All Rights Reserved. */ export * as Bom from './bom' -export * as PackageUrl from './packageUrl' diff --git a/src/contrib/packageUrl/factories.ts b/src/contrib/packageUrl/factories.ts deleted file mode 100644 index 8db56d2ff..000000000 --- a/src/contrib/packageUrl/factories.ts +++ /dev/null @@ -1,92 +0,0 @@ -/*! -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. -*/ - -import { PackageURL, PurlQualifierNames } from 'packageurl-js' - -import { ExternalReferenceType } from '../../enums/externalReferenceType' -import type { Component } from '../../models/component' - -export class PackageUrlFactory { - readonly #type: PurlType - - constructor (type: PurlType) { - this.#type = type - } - - get type (): PurlType { - return this.#type - } - - /* eslint-disable-next-line @typescript-eslint/no-inferrable-types -- docs */ - makeFromComponent (component: Component, sort: boolean = false): PackageURL | undefined { - const qualifiers: PackageURL['qualifiers'] = {} - /* @ts-expect-error TS2322 */ - qualifiers.__proto__ = null /* eslint-disable-line no-proto -- intended */ - let subpath: PackageURL['subpath'] = undefined - - // sorting to allow reproducibility: use the last instance for a `extRef.type`, if multiples exist - const extRefs = sort - ? component.externalReferences.sorted() - : component.externalReferences - for (const extRef of extRefs) { - const url = extRef.url.toString() - if (url.length <= 0) { - continue - } - // No further need for validation. - // According to https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst - // there is no formal requirement to a `..._url`. - // Everything is possible: URL-encoded, not encoded, with schema, without schema - /* eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- intended */ - switch (extRef.type) { - case ExternalReferenceType.VCS: - [qualifiers[PurlQualifierNames.VcsUrl], subpath] = url.split('#', 2) - break - case ExternalReferenceType.Distribution: - qualifiers[PurlQualifierNames.DownloadUrl] = url - break - } - } - - const hashes = component.hashes - if (hashes.size > 0) { - qualifiers[PurlQualifierNames.Checksum] = Array.from( - sort - ? hashes.sorted() - : hashes, - ([hashAlgo, hashCont]) => `${hashAlgo.toLowerCase()}:${hashCont.toLowerCase()}` - ).join(',') - } - - try { - // Do not beautify the parameters here, because that is in the domain of PackageURL and its representation. - // No need to convert an empty "subpath" string to `undefined` and such. - return new PackageURL( - this.#type, - component.group, - component.name, - component.version, - qualifiers, - subpath - ) - } catch { - return undefined - } - } -} diff --git a/src/contrib/packageUrl/index.ts b/src/contrib/packageUrl/index.ts deleted file mode 100644 index e898d6e94..000000000 --- a/src/contrib/packageUrl/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/*! -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. -*/ - -export * as Factories from './factories' diff --git a/tests/integration/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.test.js b/tests/integration/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.test.js deleted file mode 100644 index ed66a85ce..000000000 --- a/tests/integration/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.test.js +++ /dev/null @@ -1,301 +0,0 @@ -/*! -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. -*/ - -const assert = require('node:assert') - -const { suite, test } = require('mocha') -const { PackageURL } = require('packageurl-js') - -const { - Contrib, - Enums, - Models, -} = require('../../') - -suite('integration: Contrib.FromNodePackageJson.Factories.PackageUrlFactory', () => { - const salt = Math.random() - - const sut = new Contrib.FromNodePackageJson.Factories.PackageUrlFactory('testing') - - suite('makeFromComponent', () => { - test('no-name-no-purl', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - '' - ) - const expected = undefined - - const actual = sut.makeFromComponent(component) - - assert.strictEqual(actual, expected) - }) - - test('name-group-version', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - `name-${salt}`, - { - group: `@group-${salt}`, - version: `v1+${salt}`, - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('https://foo.bar', Enums.ExternalReferenceType.Website) - ]) - } - ) - const expected = new PackageURL('testing', `@group-${salt}`, `name-${salt}`, `v1+${salt}`, undefined, undefined) - - const actual = sut.makeFromComponent(component) - - assert.deepStrictEqual(actual, expected) - }) - - test('extRef[vcs] -> qualifiers.vcs-url without subpath', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - `name-${salt}`, - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('git+https://foo.bar/repo.git', Enums.ExternalReferenceType.VCS) - ]) - } - ) - const expected = new PackageURL('testing', undefined, `name-${salt}`, undefined, { vcs_url: 'git+https://foo.bar/repo.git' }, undefined) - - const actual = sut.makeFromComponent(component) - - assert.deepStrictEqual(actual, expected) - }) - - test('extRef[vcs] -> qualifiers.vcs-url with subpath', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - `name-${salt}`, - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('git+https://foo.bar/repo.git#sub/path', Enums.ExternalReferenceType.VCS) - ]) - } - ) - const expected = new PackageURL('testing', undefined, `name-${salt}`, undefined, { vcs_url: 'git+https://foo.bar/repo.git' }, 'sub/path') - - const actual = sut.makeFromComponent(component) - - assert.deepStrictEqual(actual, expected) - }) - - test('extRef[distribution] -> qualifiers.download_url', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - `name-${salt}`, - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('https://foo.bar/download', Enums.ExternalReferenceType.Distribution) - ]) - } - ) - const expected = new PackageURL('testing', undefined, `name-${salt}`, undefined, { download_url: 'https://foo.bar/download' }, undefined) - - const actual = sut.makeFromComponent(component) - - assert.deepStrictEqual(actual, expected) - }) - - test('extRef[vcs] and extRef[distribution] -> qualifiers.download_url', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - `name-${salt}`, - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('https://foo.bar/download', Enums.ExternalReferenceType.Distribution), - new Models.ExternalReference('git+https://foo.bar/repo.git', Enums.ExternalReferenceType.VCS) - ]) - } - ) - const expected = new PackageURL('testing', undefined, `name-${salt}`, undefined, { download_url: 'https://foo.bar/download' }, undefined) - - const actual = sut.makeFromComponent(component) - - assert.deepStrictEqual(actual, expected) - }) - - test('extRef[distribution] default repo -> omit', () => { - const downloadUrl = `https://registry.npmjs.org/name-${salt}/-/name-${salt}.tgz` - const component = new Models.Component( - Enums.ComponentType.Library, - `name-${salt}`, - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference(downloadUrl, Enums.ExternalReferenceType.Distribution) - ]) - } - ) - const expected = new PackageURL('testing', undefined, `name-${salt}`, undefined, undefined, undefined) - - const actual = sut.makeFromComponent(component) - - assert.deepStrictEqual(actual, expected) - }) - - test('extRef[vcs] and extRef[distribution] default repo -> omit', () => { - const downloadUrl = `https://registry.npmjs.org/name-${salt}/-/name-${salt}.tgz` - const component = new Models.Component( - Enums.ComponentType.Library, - `name-${salt}`, - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference(downloadUrl, Enums.ExternalReferenceType.Distribution), - new Models.ExternalReference('git+https://foo.bar/repo.git', Enums.ExternalReferenceType.VCS) - ]) - } - ) - const expected = new PackageURL('testing', undefined, `name-${salt}`, undefined, undefined, undefined) - - const actual = sut.makeFromComponent(component) - - assert.deepStrictEqual(actual, expected) - }) - - test('extRef empty url -> omit', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - `name-${salt}`, - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('', Enums.ExternalReferenceType.VCS), - new Models.ExternalReference('', Enums.ExternalReferenceType.Distribution) - ]) - } - ) - const expected = new PackageURL('testing', undefined, `name-${salt}`, undefined, undefined, undefined) - - const actual = sut.makeFromComponent(component) - - assert.deepStrictEqual(actual, expected) - }) - - test('hashes and extRef empty url -> omit', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - `name-${salt}`, - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('', Enums.ExternalReferenceType.VCS), - new Models.ExternalReference('', Enums.ExternalReferenceType.Distribution) - ]), - hashes: new Models.HashDictionary([ - [Enums.HashAlgorithm['SHA-256'], 'C3AB8FF13720E8AD9047DD39466B3C8974E592C2FA383D4A3960714CAEF0C4F2'] - ]) - } - ) - const expected = new PackageURL('testing', undefined, `name-${salt}`, undefined, undefined, undefined) - - const actual = sut.makeFromComponent(component) - - assert.deepStrictEqual(actual, expected) - }) - - test('hashes -> qualifiers.checksum', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - `name-${salt}`, - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('git+https://foo.bar/repo.git', Enums.ExternalReferenceType.VCS) - ]), - hashes: new Models.HashDictionary([ - [Enums.HashAlgorithm['SHA-256'], 'C3AB8FF13720E8AD9047DD39466B3C8974E592C2FA383D4A3960714CAEF0C4F2'] - ]) - } - ) - const expected = new PackageURL('testing', undefined, `name-${salt}`, undefined, { checksum: 'sha-256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2', vcs_url: 'git+https://foo.bar/repo.git' }, undefined) - - const actual = sut.makeFromComponent(component) - - assert.deepStrictEqual(actual, expected) - }) - - test('sorted hashes', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - 'name', - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('git+https://foo.bar/repo.git', Enums.ExternalReferenceType.VCS) - ]), - hashes: new Models.HashDictionary([ - [Enums.HashAlgorithm['SHA-256'], 'C3AB8FF13720E8AD9047DD39466B3C8974E592C2FA383D4A3960714CAEF0C4F2'], - [Enums.HashAlgorithm.BLAKE3, 'aa51dcd43d5c6c5203ee16906fd6b35db298b9b2e1de3fce81811d4806b76b7d'] - ]) - } - ) - const expectedObject = new PackageURL('testing', undefined, 'name', undefined, - { - // expect sorted hash list - checksum: 'blake3:aa51dcd43d5c6c5203ee16906fd6b35db298b9b2e1de3fce81811d4806b76b7d,sha-256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2', - vcs_url: 'git+https://foo.bar/repo.git' - }, undefined) - // expect objet's keys in alphabetical oder, expect sorted hash list - const expectedString = 'pkg:testing/name?checksum=blake3%3Aaa51dcd43d5c6c5203ee16906fd6b35db298b9b2e1de3fce81811d4806b76b7d%2Csha-256%3Ac3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2&vcs_url=git%2Bhttps%3A%2F%2Ffoo.bar%2Frepo.git' - - const actual = sut.makeFromComponent(component, true) - - assert.deepStrictEqual(actual, expectedObject) - assert.deepStrictEqual(actual.toString(), expectedString) - }) - - test('sorted references', () => { - const component1 = new Models.Component( - Enums.ComponentType.Library, - 'name', - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('https://foo.bar/download-1', Enums.ExternalReferenceType.Distribution), - new Models.ExternalReference('https://foo.bar/download-2', Enums.ExternalReferenceType.Distribution) - ]) - } - ) - const component2 = new Models.Component( - Enums.ComponentType.Library, - 'name', - { - externalReferences: new Models.ExternalReferenceRepository([ - // different order of extRefs - new Models.ExternalReference('https://foo.bar/download-2', Enums.ExternalReferenceType.Distribution), - new Models.ExternalReference('https://foo.bar/download-1', Enums.ExternalReferenceType.Distribution) - ]) - } - ) - const expectedObject = new PackageURL('testing', undefined, 'name', undefined, - { - // expect sorted hash list - download_url: 'https://foo.bar/download-2' - }, undefined) - // expect objet's keys in alphabetical oder, expect sorted hash list - const expectedString = 'pkg:testing/name?download_url=https%3A%2F%2Ffoo.bar%2Fdownload-2' - - const actual1 = sut.makeFromComponent(component1, true) - const actual2 = sut.makeFromComponent(component2, true) - - assert.deepStrictEqual(actual1, expectedObject) - assert.deepStrictEqual(actual1.toString(), expectedString) - assert.deepStrictEqual(actual2, expectedObject) - assert.deepStrictEqual(actual2.toString(), expectedString) - }) - }) -}) diff --git a/tests/integration/Contrib.PackageUrl.Factories.PackageUrlFactory.test.js b/tests/integration/Contrib.PackageUrl.Factories.PackageUrlFactory.test.js deleted file mode 100644 index 910ee6a17..000000000 --- a/tests/integration/Contrib.PackageUrl.Factories.PackageUrlFactory.test.js +++ /dev/null @@ -1,227 +0,0 @@ -/*! -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. -*/ - -const assert = require('node:assert') - -const { suite, test } = require('mocha') -const { PackageURL } = require('packageurl-js') - -const { - Contrib, - Enums, - Models, -} = require('../../') - -suite('integration: Contrib.PackageUrl.Factories.PackageUrlFactory', () => { - const salt = Math.random() - - const sut = new Contrib.PackageUrl.Factories.PackageUrlFactory('testing') - - suite('makeFromComponent', () => { - test('no-name-no-purl', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - '' - ) - const expected = undefined - - const actual = sut.makeFromComponent(component) - - assert.strictEqual(actual, expected) - }) - - test('name-group-version', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - `name-${salt}`, - { - group: `@group-${salt}`, - version: `v1+${salt}`, - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('https://foo.bar', Enums.ExternalReferenceType.Website) - ]) - } - ) - const expected = new PackageURL('testing', `@group-${salt}`, `name-${salt}`, `v1+${salt}`, {}, undefined) - - const actual = sut.makeFromComponent(component) - - assert.deepStrictEqual(actual, expected) - }) - - test('extRef[vcs] -> qualifiers.vcs-url without subpath', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - `name-${salt}`, - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('git+https://foo.bar/repo.git', Enums.ExternalReferenceType.VCS) - ]) - } - ) - const expected = new PackageURL('testing', undefined, `name-${salt}`, undefined, { vcs_url: 'git+https://foo.bar/repo.git' }, undefined) - - const actual = sut.makeFromComponent(component) - - assert.deepStrictEqual(actual, expected) - }) - - test('extRef[vcs] -> qualifiers.vcs-url with subpath', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - `name-${salt}`, - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('git+https://foo.bar/repo.git#sub/path', Enums.ExternalReferenceType.VCS) - ]) - } - ) - const expected = new PackageURL('testing', undefined, `name-${salt}`, undefined, { vcs_url: 'git+https://foo.bar/repo.git' }, 'sub/path') - - const actual = sut.makeFromComponent(component) - - assert.deepStrictEqual(actual, expected) - }) - - test('extRef[distribution] -> qualifiers.download_url', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - `name-${salt}`, - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('https://foo.bar/download', Enums.ExternalReferenceType.Distribution) - ]) - } - ) - const expected = new PackageURL('testing', undefined, `name-${salt}`, undefined, { download_url: 'https://foo.bar/download' }, undefined) - - const actual = sut.makeFromComponent(component) - - assert.deepStrictEqual(actual, expected) - }) - - test('extRef empty url -> omit', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - `name-${salt}`, - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('', Enums.ExternalReferenceType.VCS), - new Models.ExternalReference('', Enums.ExternalReferenceType.Distribution) - ]) - } - ) - const expected = new PackageURL('testing', undefined, `name-${salt}`, undefined, {}, undefined) - - const actual = sut.makeFromComponent(component) - - assert.deepStrictEqual(actual, expected) - }) - - test('hashes -> qualifiers.checksum', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - `name-${salt}`, - { - hashes: new Models.HashDictionary([ - [Enums.HashAlgorithm['SHA-256'], 'C3AB8FF13720E8AD9047DD39466B3C8974E592C2FA383D4A3960714CAEF0C4F2'] - ]) - } - ) - const expected = new PackageURL('testing', undefined, `name-${salt}`, undefined, { checksum: 'sha-256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2' }, undefined) - - const actual = sut.makeFromComponent(component) - - assert.deepStrictEqual(actual, expected) - }) - - test('sorted hashes', () => { - const component = new Models.Component( - Enums.ComponentType.Library, - 'name', - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('git+https://foo.bar/repo.git', Enums.ExternalReferenceType.VCS), - new Models.ExternalReference('https://foo.bar/download', Enums.ExternalReferenceType.Distribution) - ]), - hashes: new Models.HashDictionary([ - [Enums.HashAlgorithm['SHA-256'], 'C3AB8FF13720E8AD9047DD39466B3C8974E592C2FA383D4A3960714CAEF0C4F2'], - [Enums.HashAlgorithm.BLAKE3, 'aa51dcd43d5c6c5203ee16906fd6b35db298b9b2e1de3fce81811d4806b76b7d'] - ]) - } - ) - const expectedObject = new PackageURL('testing', undefined, 'name', undefined, - { - // expect sorted hash list - checksum: 'blake3:aa51dcd43d5c6c5203ee16906fd6b35db298b9b2e1de3fce81811d4806b76b7d,sha-256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2', - download_url: 'https://foo.bar/download', - vcs_url: 'git+https://foo.bar/repo.git' - }, undefined) - // expect objet's keys in alphabetical oder, expect sorted hash list - const expectedString = 'pkg:testing/name?checksum=blake3%3Aaa51dcd43d5c6c5203ee16906fd6b35db298b9b2e1de3fce81811d4806b76b7d%2Csha-256%3Ac3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2&download_url=https%3A%2F%2Ffoo.bar%2Fdownload&vcs_url=git%2Bhttps%3A%2F%2Ffoo.bar%2Frepo.git' - - const actual = sut.makeFromComponent(component, true) - - assert.deepStrictEqual(actual, expectedObject) - assert.deepStrictEqual(actual.toString(), expectedString) - }) - - test('sorted references', () => { - const component1 = new Models.Component( - Enums.ComponentType.Library, - 'name', - { - externalReferences: new Models.ExternalReferenceRepository([ - new Models.ExternalReference('https://foo.bar/download-1', Enums.ExternalReferenceType.Distribution), - new Models.ExternalReference('git+https://foo.bar/repo.git', Enums.ExternalReferenceType.VCS), - new Models.ExternalReference('https://foo.bar/download-2', Enums.ExternalReferenceType.Distribution) - ]) - } - ) - const component2 = new Models.Component( - Enums.ComponentType.Library, - 'name', - { - externalReferences: new Models.ExternalReferenceRepository([ - // different order of extRefs - new Models.ExternalReference('https://foo.bar/download-2', Enums.ExternalReferenceType.Distribution), - new Models.ExternalReference('git+https://foo.bar/repo.git', Enums.ExternalReferenceType.VCS), - new Models.ExternalReference('https://foo.bar/download-1', Enums.ExternalReferenceType.Distribution) - ]) - } - ) - const expectedObject = new PackageURL('testing', undefined, 'name', undefined, - { - // expect sorted hash list - download_url: 'https://foo.bar/download-2', - vcs_url: 'git+https://foo.bar/repo.git' - }, undefined) - // expect objet's keys in alphabetical oder, expect sorted hash list - const expectedString = 'pkg:testing/name?download_url=https%3A%2F%2Ffoo.bar%2Fdownload-2&vcs_url=git%2Bhttps%3A%2F%2Ffoo.bar%2Frepo.git' - - const actual1 = sut.makeFromComponent(component1, true) - const actual2 = sut.makeFromComponent(component2, true) - - assert.deepStrictEqual(actual1, expectedObject) - assert.deepStrictEqual(actual1.toString(), expectedString) - assert.deepStrictEqual(actual2, expectedObject) - assert.deepStrictEqual(actual2.toString(), expectedString) - }) - }) -}) diff --git a/tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.spec.js b/tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.spec.js deleted file mode 100644 index 78593dc88..000000000 --- a/tests/unit/Contrib.FromNodePackageJson.Factories.PackageUrlFactory.node.spec.js +++ /dev/null @@ -1,93 +0,0 @@ -/*! -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. -*/ - -const assert = require('node:assert') - -const { suite, test } = require('mocha') - -const { - Contrib, - Enums: { ComponentType, ExternalReferenceType }, - Models: { Component, ExternalReference, ExternalReferenceRepository } -} = require('../../') - -suite('unit: Contrib.FromNodePackageJson.Factories.PackageUrlFactory', () => { - suite('makeFromComponent()', () => { - test('plain', () => { - const component = new Component(ComponentType.Library, 'testing') - const purlFac = new Contrib.FromNodePackageJson.Factories.PackageUrlFactory('npm') - const actual = purlFac.makeFromComponent(component) - assert.deepEqual(actual, { - name: 'testing', - namespace: undefined, - qualifiers: undefined, - subpath: undefined, - type: 'npm', - version: undefined - }) - }) - - test('strips default registry from qualifiers', () => { - // see https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#npm - const component = new Component(ComponentType.Library, 'testing', { - externalReferences: new ExternalReferenceRepository([ - new ExternalReference( - 'https://registry.npmjs.org/@cyclonedx/cyclonedx-library/-/cyclonedx-library-1.0.0-beta.2.tgz', - ExternalReferenceType.Distribution - ) - ]) - }) - const purlFac = new Contrib.FromNodePackageJson.Factories.PackageUrlFactory('npm') - const actual = purlFac.makeFromComponent(component) - assert.deepEqual(actual, { - type: 'npm', - name: 'testing', - namespace: undefined, - version: undefined, - qualifiers: undefined, - subpath: undefined - }) - }) - - test('dont strip BA registry from qualifiers', () => { - // regression test for https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1073 - const component = new Component(ComponentType.Library, 'testing', { - externalReferences: new ExternalReferenceRepository([ - new ExternalReference( - 'https://registry.npmjs.org.badactor.net/@cyclonedx/cyclonedx-library/-/cyclonedx-library-1.0.0-beta.2.tgz', - ExternalReferenceType.Distribution - ) - ]) - }) - const purlFac = new Contrib.FromNodePackageJson.Factories.PackageUrlFactory('npm') - const actual = purlFac.makeFromComponent(component) - assert.deepEqual(actual, - { - type: 'npm', - name: 'testing', - namespace: undefined, - version: undefined, - qualifiers: { - download_url: 'https://registry.npmjs.org.badactor.net/@cyclonedx/cyclonedx-library/-/cyclonedx-library-1.0.0-beta.2.tgz' - }, - subpath: undefined - }) - }) - }) -}) diff --git a/tests/unit/Contrib.PackageUrl.Factories.PackageUrlFactory.spec.js b/tests/unit/Contrib.PackageUrl.Factories.PackageUrlFactory.spec.js deleted file mode 100644 index f38c7b99c..000000000 --- a/tests/unit/Contrib.PackageUrl.Factories.PackageUrlFactory.spec.js +++ /dev/null @@ -1,37 +0,0 @@ -/*! -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. -*/ - -const assert = require('node:assert') - -const { suite, test } = require('mocha') - -const { - Contrib, -} = require('../../') -const { randomString } = require('../_helpers/stringFunctions') - -suite('unit: Contrib.PackageUrl.Factories.PackageUrlFactory', () => { - test('construct', () => { - const type = randomString(5) - - const actual = new Contrib.PackageUrl.Factories.PackageUrlFactory(type) - - assert.strictEqual(actual.type, type) - }) -}) From 2857000951ab2fe8782868e10fd88c5dcd685f85 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Thu, 19 Feb 2026 23:14:21 +0100 Subject: [PATCH 19/35] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index cdcaa4d77..35a11c26b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file. * BREAKING changes * Removed deprecated symbols * Removed PackageUrl factories - * No longer use external standards' implementations nor models + * No longer use external standards' for models * Removed * Entrypoint `Builders` (via [#1377]) * Entrypoint `Factories` (via [#1377]) From 0b3cbdd0c8b81a789a0f7e94169f20b4791d568b Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Fri, 20 Feb 2026 10:44:59 +0100 Subject: [PATCH 20/35] chore: dev engines (#1380) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Description set dev-engines Resolves or fixes issue: #1301 ### 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 --- HISTORY.md | 4 ++++ package.json | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 35a11c26b..1cdeb1ea3 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -63,7 +63,10 @@ All notable changes to this project will be documented in this file. * No longer depend on `packageurl-js@^2.0.1` ([#1348] via [#1378]) * Build * Use _webpack_ `5.105.2` now, was `v5.103.0` (via [#1360], [#1374]) +* Chore + * Set dev-engines in `package.json` ([#1301] via [#1380]) +[#1301]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1301 [#1346]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1346 [#1348]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1348 [#1360]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1360 @@ -71,6 +74,7 @@ All notable changes to this project will be documented in this file. [#1377]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1377 [#1378]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1378 [#1379]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1379 +[#1380]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1380 ## 9.4.1 -- 2025-12-04 diff --git a/package.json b/package.json index 55d7bc32e..9d6c8b004 100644 --- a/package.json +++ b/package.json @@ -106,6 +106,18 @@ "optional": true } }, + "devEngines": { + "runtime": { + "name": "node", + "version": ">=20.18.0", + "onFail": "error" + }, + "packageManager": { + "name": "npm", + "version": ">=9", + "onFail": "error" + } + }, "devDependencies": { "ajv": "^8.12.0", "ajv-formats": "^3.0.1", From b71be486f5d0d2b088603deb138123329848c6e8 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Fri, 20 Feb 2026 12:00:04 +0100 Subject: [PATCH 21/35] tests: fix browser tests (#1381) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Description A clear and concise summary of the change and which issue (if any) it fixes. Should also include relevant motivation and context. Resolves or fixes issue: ### 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 --- examples/web/parcel/package.json | 2 +- examples/web/parcel/src/app.js | 3 +-- examples/web/parcel/src/index.html | 2 +- examples/web/webpack/dist/index.html | 28 ---------------------------- examples/web/webpack/package.json | 5 +++-- examples/web/webpack/src/index.js | 1 - package.json | 3 ++- 7 files changed, 8 insertions(+), 36 deletions(-) delete mode 100644 examples/web/webpack/dist/index.html diff --git a/examples/web/parcel/package.json b/examples/web/parcel/package.json index b39226cb4..6df45921a 100644 --- a/examples/web/parcel/package.json +++ b/examples/web/parcel/package.json @@ -10,7 +10,7 @@ "parcel": "^2" }, "scripts": { - "build": "parcel build --detailed-report", + "build": "parcel build --detailed-report --public-url .", "example": "parcel" } } diff --git a/examples/web/parcel/src/app.js b/examples/web/parcel/src/app.js index 0a024b70a..53434f746 100644 --- a/examples/web/parcel/src/app.js +++ b/examples/web/parcel/src/app.js @@ -23,7 +23,6 @@ const CDX = require('@cyclonedx/cyclonedx-library') // full Library is available as `CDX`, now const lFac = new CDX.Contrib.License.Factories.LicenseFactory() -const purlFac = new CDX.Contrib.PackageUrl.Factories.PackageUrlFactory('generic') const bom = new CDX.Models.Bom() bom.metadata.component = new CDX.Models.Component( @@ -41,7 +40,7 @@ const componentA = new CDX.Models.Component( } ) componentA.licenses.add(lFac.makeFromString('Apache-2.0')) -componentA.purl = purlFac.makeFromComponent(componentA) +componentA.purl = `pkg:generic/${componentA.group}/${componentA.name}@${componentA.version}` bom.components.add(componentA) bom.metadata.component.dependencies.add(componentA.bomRef) diff --git a/examples/web/parcel/src/index.html b/examples/web/parcel/src/index.html index ff2dba6ce..767b18a5b 100644 --- a/examples/web/parcel/src/index.html +++ b/examples/web/parcel/src/index.html @@ -22,7 +22,7 @@ example - +

see JavaScript Console output for result.

diff --git a/examples/web/webpack/dist/index.html b/examples/web/webpack/dist/index.html deleted file mode 100644 index 31596d46f..000000000 --- a/examples/web/webpack/dist/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - example - - - -

see JavaScript Console output for result.

- - diff --git a/examples/web/webpack/package.json b/examples/web/webpack/package.json index c991fa435..bccb70fbb 100644 --- a/examples/web/webpack/package.json +++ b/examples/web/webpack/package.json @@ -7,10 +7,11 @@ }, "devDependencies": { "webpack": "^5", - "webpack-cli": "^5||^6" + "webpack-cli": "^5||^6", + "webpack-dev-server": "^5" }, "scripts": { "build": "webpack build", - "example": "x-www-browser dist/index.html" + "example": "webpack serve --open --static . --output-path ./dist" } } diff --git a/examples/web/webpack/src/index.js b/examples/web/webpack/src/index.js index 6e63e1984..53434f746 100644 --- a/examples/web/webpack/src/index.js +++ b/examples/web/webpack/src/index.js @@ -23,7 +23,6 @@ const CDX = require('@cyclonedx/cyclonedx-library') // full Library is available as `CDX`, now const lFac = new CDX.Contrib.License.Factories.LicenseFactory() -const purlFac = new CDX.Contrib.PackageUrl.Factories.PackageUrlFactory('generic') const bom = new CDX.Models.Bom() bom.metadata.component = new CDX.Models.Component( diff --git a/package.json b/package.json index 9d6c8b004..92c6010ed 100644 --- a/package.json +++ b/package.json @@ -238,5 +238,6 @@ "api-doc": "run-p --aggregate-output -lc api-doc:\\*", "api-doc:node": "npm --prefix tools/docs-gen exec -- typedoc --options ./typedoc.node.json", "api-doc:web": "npm --prefix tools/docs-gen exec -- typedoc --options ./typedoc.web.json" - } + }, + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } From d6acb60aec1b941db1fd6c30d143050f178d342e Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Fri, 20 Feb 2026 15:20:02 +0100 Subject: [PATCH 22/35] feat!: remove spdx expression validation (#1382) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Description * Constructor of `Contrib.License.Factories.LicenseFactory` got an injectable argument `spdxExpressionValidate` for validating SPDX Expressions * Dependency `spdx-expression-parse` became a suggested (optional peer-dependency) library Used as an injectable in `Contrib.License.Factories.LicenseFactory.constructor`. Resolves or fixes issue: ### 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 --- HISTORY.md | 5 ++++ examples/node/javascript/example.cjs | 5 +++- examples/node/javascript/example.mjs | 5 +++- examples/node/javascript/package.json | 1 + .../node/typescript/example.cjs/package.json | 2 ++ .../typescript/example.cjs/src/example.ts | 5 +++- .../node/typescript/example.mjs/package.json | 2 ++ .../typescript/example.mjs/src/example.ts | 5 +++- examples/web/parcel/package.json | 3 ++- examples/web/parcel/src/app.js | 5 +++- examples/web/webpack/package.json | 3 ++- examples/web/webpack/src/index.js | 5 +++- package.json | 6 ++++- src/contrib/license/factories.ts | 27 ++++++++++++++++--- src/spdx.ts | 14 ---------- ...b.License.Factories.LicenseFactory.test.js | 5 +++- 16 files changed, 70 insertions(+), 28 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 1cdeb1ea3..175d7b995 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -59,8 +59,12 @@ All notable changes to this project will be documented in this file. * Symbol `Contrib.FromNodePackageJson.Factories.PackageUrlFactory` ([#1348] via [#1378]) * Changed * `Component.purl` is a `string` now, was `PackaheUrl` ([#1348] via [#1379]) + * Constructor of `Contrib.License.Factories.LicenseFactory` got an injectable argument `spdxExpressionValidate` for validating SPDXExpressions ([#1348] via [#1382]) + Suggested implementation is `spdx-expression-parse`. * Dependencies * No longer depend on `packageurl-js@^2.0.1` ([#1348] via [#1378]) + * Dependency `spdx-expression-parse` became a suggested (optional peer-dependency) library ([#1348] via [#1382]) + Used as an injectable in `Contrib.License.Factories.LicenseFactory.constructor`. * Build * Use _webpack_ `5.105.2` now, was `v5.103.0` (via [#1360], [#1374]) * Chore @@ -75,6 +79,7 @@ All notable changes to this project will be documented in this file. [#1378]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1378 [#1379]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1379 [#1380]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1380 +[#1382]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1382 ## 9.4.1 -- 2025-12-04 diff --git a/examples/node/javascript/example.cjs b/examples/node/javascript/example.cjs index 7ee4cd260..dec90204b 100644 --- a/examples/node/javascript/example.cjs +++ b/examples/node/javascript/example.cjs @@ -25,7 +25,10 @@ const CDX = require('@cyclonedx/cyclonedx-library') // const { Bom, Component } = require('@cyclonedx/cyclonedx-library/Models') // const { ComponentType } = require('@cyclonedx/cyclonedx-library/Enums') -const lFac = new CDX.Contrib.License.Factories.LicenseFactory() +const spdxExpressionParser = require('spdx-expression-parse') + + +const lFac = new CDX.Contrib.License.Factories.LicenseFactory(spdxExpressionParser) const bom = new CDX.Models.Bom() bom.metadata.component = new CDX.Models.Component( diff --git a/examples/node/javascript/example.mjs b/examples/node/javascript/example.mjs index 41c0cbd28..e596cc728 100644 --- a/examples/node/javascript/example.mjs +++ b/examples/node/javascript/example.mjs @@ -25,7 +25,10 @@ import * as CDX from '@cyclonedx/cyclonedx-library' // import { Bom, Component } from '@cyclonedx/cyclonedx-library/Models' // import { ComponentType } from '@cyclonedx/cyclonedx-library/Enums' -const lFac = new CDX.Contrib.License.Factories.LicenseFactory() +import spdxExpressionParser from 'spdx-expression-parse' + + +const lFac = new CDX.Contrib.License.Factories.LicenseFactory(spdxExpressionParser) const bom = new CDX.Models.Bom() bom.metadata.component = new CDX.Models.Component( diff --git a/examples/node/javascript/package.json b/examples/node/javascript/package.json index afab53392..bc8c9bd7d 100644 --- a/examples/node/javascript/package.json +++ b/examples/node/javascript/package.json @@ -8,6 +8,7 @@ }, "dependencies": { "@cyclonedx/cyclonedx-library": "file:../../..", + "spdx-expression-parse": "^3.0.1||^4", "xmlbuilder2": "^3.0.2||^4.0.0" }, "optionalDependencies": { diff --git a/examples/node/typescript/example.cjs/package.json b/examples/node/typescript/example.cjs/package.json index d9c1885b5..1400ca0c8 100644 --- a/examples/node/typescript/example.cjs/package.json +++ b/examples/node/typescript/example.cjs/package.json @@ -8,6 +8,7 @@ }, "dependencies": { "@cyclonedx/cyclonedx-library": "file:../../../..", + "spdx-expression-parse": "^3.0.1||^4", "xmlbuilder2": "^3.0.2||^4.0.0" }, "optionalDependencies": { @@ -18,6 +19,7 @@ }, "devDependencies": { "@types/node": "*", + "@types/spdx-expression-parse": "^3", "typescript": "^3.8 || ^4 || ^5" }, "scripts": { diff --git a/examples/node/typescript/example.cjs/src/example.ts b/examples/node/typescript/example.cjs/src/example.ts index 5d3a69237..185750e25 100644 --- a/examples/node/typescript/example.cjs/src/example.ts +++ b/examples/node/typescript/example.cjs/src/example.ts @@ -25,7 +25,10 @@ import * as CDX from '@cyclonedx/cyclonedx-library' // import { Bom, Component } from '@cyclonedx/cyclonedx-library/Models' // import { ComponentType } from '@cyclonedx/cyclonedx-library/Enums' -const lFac = new CDX.Contrib.License.Factories.LicenseFactory() +import * as spdxExpressionParser from 'spdx-expression-parse' + + +const lFac = new CDX.Contrib.License.Factories.LicenseFactory(spdxExpressionParser) const bom = new CDX.Models.Bom() bom.metadata.component = new CDX.Models.Component( diff --git a/examples/node/typescript/example.mjs/package.json b/examples/node/typescript/example.mjs/package.json index 742e6753d..8c0d8057d 100644 --- a/examples/node/typescript/example.mjs/package.json +++ b/examples/node/typescript/example.mjs/package.json @@ -8,6 +8,7 @@ }, "dependencies": { "@cyclonedx/cyclonedx-library": "file:../../../..", + "spdx-expression-parse": "^3.0.1||^4", "xmlbuilder2": "^3.0.2||^4.0.0" }, "optionalDependencies": { @@ -18,6 +19,7 @@ }, "devDependencies": { "@types/node": "*", + "@types/spdx-expression-parse": "^3", "typescript": "^4 || ^5" }, "scripts": { diff --git a/examples/node/typescript/example.mjs/src/example.ts b/examples/node/typescript/example.mjs/src/example.ts index 4022b236c..f10287b78 100644 --- a/examples/node/typescript/example.mjs/src/example.ts +++ b/examples/node/typescript/example.mjs/src/example.ts @@ -25,7 +25,10 @@ import * as CDX from '@cyclonedx/cyclonedx-library' // import { Bom, Component } from '@cyclonedx/cyclonedx-library/Models' // import { ComponentType } from '@cyclonedx/cyclonedx-library/Enums' -const lFac = new CDX.Contrib.License.Factories.LicenseFactory() +import spdxExpressionParser from 'spdx-expression-parse' + + +const lFac = new CDX.Contrib.License.Factories.LicenseFactory(spdxExpressionParser) const bom = new CDX.Models.Bom() bom.metadata.component = new CDX.Models.Component( diff --git a/examples/web/parcel/package.json b/examples/web/parcel/package.json index 6df45921a..619fac1f4 100644 --- a/examples/web/parcel/package.json +++ b/examples/web/parcel/package.json @@ -4,7 +4,8 @@ "license": "Apache-2.0", "source": "src/index.html", "dependencies": { - "@cyclonedx/cyclonedx-library": "file:../../.." + "@cyclonedx/cyclonedx-library": "file:../../..", + "spdx-expression-parse": "^3.0.1||^4" }, "devDependencies": { "parcel": "^2" diff --git a/examples/web/parcel/src/app.js b/examples/web/parcel/src/app.js index 53434f746..b87d25556 100644 --- a/examples/web/parcel/src/app.js +++ b/examples/web/parcel/src/app.js @@ -22,7 +22,10 @@ Copyright (c) OWASP Foundation. All Rights Reserved. const CDX = require('@cyclonedx/cyclonedx-library') // full Library is available as `CDX`, now -const lFac = new CDX.Contrib.License.Factories.LicenseFactory() +const spdxExpressionParser = require('spdx-expression-parse') + + +const lFac = new CDX.Contrib.License.Factories.LicenseFactory(spdxExpressionParser) const bom = new CDX.Models.Bom() bom.metadata.component = new CDX.Models.Component( diff --git a/examples/web/webpack/package.json b/examples/web/webpack/package.json index bccb70fbb..196320561 100644 --- a/examples/web/webpack/package.json +++ b/examples/web/webpack/package.json @@ -3,7 +3,8 @@ "name": "@cyclonedx/cyclonedx-library-examples-web-webpack", "license": "Apache-2.0", "dependencies": { - "@cyclonedx/cyclonedx-library": "file:../../.." + "@cyclonedx/cyclonedx-library": "file:../../..", + "spdx-expression-parse": "^3.0.1||^4" }, "devDependencies": { "webpack": "^5", diff --git a/examples/web/webpack/src/index.js b/examples/web/webpack/src/index.js index 53434f746..b87d25556 100644 --- a/examples/web/webpack/src/index.js +++ b/examples/web/webpack/src/index.js @@ -22,7 +22,10 @@ Copyright (c) OWASP Foundation. All Rights Reserved. const CDX = require('@cyclonedx/cyclonedx-library') // full Library is available as `CDX`, now -const lFac = new CDX.Contrib.License.Factories.LicenseFactory() +const spdxExpressionParser = require('spdx-expression-parse') + + +const lFac = new CDX.Contrib.License.Factories.LicenseFactory(spdxExpressionParser) const bom = new CDX.Models.Bom() bom.metadata.component = new CDX.Models.Component( diff --git a/package.json b/package.json index 92c6010ed..36eb5da54 100644 --- a/package.json +++ b/package.json @@ -80,13 +80,13 @@ "node": ">=20.18.0" }, "dependencies": { - "spdx-expression-parse": "^3.0.1 || ^4" }, "peerDependencies": { "ajv": "^8.12.0", "ajv-formats": "^3.0.1", "ajv-formats-draft2019": "^1.6.1", "libxmljs2": "^0.35||^0.37", + "spdx-expression-parse": "^3.0.1 || ^4", "xmlbuilder2": "^3.0.2||^4.0.0" }, "peerDependenciesMeta": { @@ -102,6 +102,9 @@ "libxmljs2": { "optional": true }, + "spdx-expression-parse": { + "optional": true + }, "xmlbuilder2": { "optional": true } @@ -124,6 +127,7 @@ "ajv-formats-draft2019": "^1.6.1", "libxmljs2": "^0.35||^0.37", "xmlbuilder2": "^3.0.2||^4.0.0", + "spdx-expression-parse": "^3.0.1||^4", "@types/mocha": "^10", "@types/node": "ts5.7", "@types/spdx-expression-parse": "^3", diff --git a/src/contrib/license/factories.ts b/src/contrib/license/factories.ts index c218f5bf8..8e41c5db0 100644 --- a/src/contrib/license/factories.ts +++ b/src/contrib/license/factories.ts @@ -19,9 +19,26 @@ Copyright (c) OWASP Foundation. All Rights Reserved. import type { DisjunctiveLicense, License } from '../../models/license' import { LicenseExpression, NamedLicense, SpdxLicense } from '../../models/license' -import { fixupSpdxId, isValidSpdxLicenseExpression } from '../../spdx' +import { fixupSpdxId } from '../../spdx' + +/** + * SPDXLicense Expression validation. + * + * We suggest one of the following 3rd-party libraries: + * - `spdx-expression-parse@^3.0.1||^4` - {@link https://www.npmjs.com/package/spdx-expression-parse} + * + * @throws {@link Error} when the argument is no valid SPDX License Expression + */ +type SpdxExpressionValidate = (data: string) => void export class LicenseFactory { + + readonly #spdxExpressionValidate: SpdxExpressionValidate + + constructor(spdxExpressionValidate: SpdxExpressionValidate) { + this.#spdxExpressionValidate = spdxExpressionValidate + } + makeFromString (value: string): License { try { return this.makeSpdxLicense(value) @@ -43,10 +60,12 @@ export class LicenseFactory { */ makeExpression (value: string | any): LicenseExpression { const expression = String(value) - if (isValidSpdxLicenseExpression(expression)) { - return new LicenseExpression(expression) + try { + this.#spdxExpressionValidate(expression) + } catch (err) { + throw new RangeError('Invalid SPDX license expression', { cause: err }) } - throw new RangeError('Invalid SPDX license expression') + return new LicenseExpression(expression) } makeDisjunctive (value: string): DisjunctiveLicense { diff --git a/src/spdx.ts b/src/spdx.ts index 85bdb1fe2..4847be9a0 100644 --- a/src/spdx.ts +++ b/src/spdx.ts @@ -17,8 +17,6 @@ SPDX-License-Identifier: Apache-2.0 Copyright (c) OWASP Foundation. All Rights Reserved. */ -import spdxExpressionParse from 'spdx-expression-parse' - /* @ts-expect-error: TS6059 -- this works as long as the file/path is available in dist-package. */ import { enum as _spdxSpecEnum } from '../res/schema/spdx.SNAPSHOT.schema.json' with { type: 'json' } @@ -48,15 +46,3 @@ export function fixupSpdxId (value: string | any): SpdxId | undefined { ? spdxLowerToActual[value.toLowerCase()] : undefined } - -export function isValidSpdxLicenseExpression (value: string | any): boolean { - if (typeof value !== 'string') { - return false - } - try { - spdxExpressionParse(value) - } catch (err) { - return false - } - return true -} diff --git a/tests/integration/Contrib.License.Factories.LicenseFactory.test.js b/tests/integration/Contrib.License.Factories.LicenseFactory.test.js index e0fd88f66..3f454efc9 100644 --- a/tests/integration/Contrib.License.Factories.LicenseFactory.test.js +++ b/tests/integration/Contrib.License.Factories.LicenseFactory.test.js @@ -20,6 +20,7 @@ Copyright (c) OWASP Foundation. All Rights Reserved. const assert = require('node:assert') const { suite, test } = require('mocha') +const spdxExpressionValidate = require('spdx-expression-parse') const { Contrib, @@ -28,7 +29,9 @@ const { suite('integration: Contrib.License.Factories.LicenseFactory', () => { test('makeFromString() -> LicenseExpression', () => { - const sut = new Contrib.License.Factories.LicenseFactory() + const sut = new Contrib.License.Factories.LicenseFactory( + spdxExpressionValidate + ) const expression = '(MIT OR Apache-2.0)' const license = sut.makeFromString(expression) From 9c9059aa5bacbc0cd63cf961caec5e4b37fe9809 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Fri, 20 Feb 2026 15:22:29 +0100 Subject: [PATCH 23/35] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 175d7b995..0048be9c7 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file. * BREAKING changes * Removed deprecated symbols * Removed PackageUrl factories - * No longer use external standards' for models + * No longer use external standards' implementations directly * Removed * Entrypoint `Builders` (via [#1377]) * Entrypoint `Factories` (via [#1377]) From 2302ef148264aa88ad30557bf513f173f1fb8df5 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Fri, 20 Feb 2026 15:24:47 +0100 Subject: [PATCH 24/35] cleanup Signed-off-by: Jan Kowalleck --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 36eb5da54..1c96d52ea 100644 --- a/package.json +++ b/package.json @@ -242,6 +242,5 @@ "api-doc": "run-p --aggregate-output -lc api-doc:\\*", "api-doc:node": "npm --prefix tools/docs-gen exec -- typedoc --options ./typedoc.node.json", "api-doc:web": "npm --prefix tools/docs-gen exec -- typedoc --options ./typedoc.web.json" - }, - "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" + } } From adacb5719cc6492e8506a0188da08a5bfb323932 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Fri, 20 Feb 2026 15:28:42 +0100 Subject: [PATCH 25/35] docs Signed-off-by: Jan Kowalleck --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index c28795774..7f4479197 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,6 @@ written in _TypeScript_ and compiled for the target. * Gather license evidences from files (for _Node.js_ only) * Factories for the following use cases: * Create data models from any license descriptor string - * Create `PackageURL` from `Component` data models * Specific to _Node.js_: create data models from PackageJson-like data structures and derived data * Builders for the following use cases: * Specific to _Node.js_: create deep data models `Tool` or `Component` from PackageJson-like data structures From 0c0d167fe12d7123addf5d7f12c102986a50e6ef Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Fri, 20 Feb 2026 15:31:07 +0100 Subject: [PATCH 26/35] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 0048be9c7..f53d900f0 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -57,6 +57,8 @@ All notable changes to this project will be documented in this file. Use `Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher` instead. * Symbol `Contrib.PackageUrl.Factories.PackageUrlFactory` ([#1348] via [#1378]) * Symbol `Contrib.FromNodePackageJson.Factories.PackageUrlFactory` ([#1348] via [#1378]) + * Symbol `SPDX.isValidSpdxLicenseExpression` ([#1348] via [#1382]) + Use package `spdx-expression-parse` instead. * Changed * `Component.purl` is a `string` now, was `PackaheUrl` ([#1348] via [#1379]) * Constructor of `Contrib.License.Factories.LicenseFactory` got an injectable argument `spdxExpressionValidate` for validating SPDXExpressions ([#1348] via [#1382]) From 5ae4665d19e7d30de3ee83e70ad9223306c8f960 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Fri, 20 Feb 2026 15:32:01 +0100 Subject: [PATCH 27/35] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index f53d900f0..428f3263b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -61,7 +61,7 @@ All notable changes to this project will be documented in this file. Use package `spdx-expression-parse` instead. * Changed * `Component.purl` is a `string` now, was `PackaheUrl` ([#1348] via [#1379]) - * Constructor of `Contrib.License.Factories.LicenseFactory` got an injectable argument `spdxExpressionValidate` for validating SPDXExpressions ([#1348] via [#1382]) + * Constructor of `Contrib.License.Factories.LicenseFactory` got an injectable argument `spdxExpressionValidate` for validating SPDX License Expressions ([#1348] via [#1382]) Suggested implementation is `spdx-expression-parse`. * Dependencies * No longer depend on `packageurl-js@^2.0.1` ([#1348] via [#1378]) From 174a2de52c764d4054ba334efcf12ce742ddaad3 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Fri, 20 Feb 2026 15:32:16 +0100 Subject: [PATCH 28/35] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 428f3263b..0e33c6072 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -57,7 +57,7 @@ All notable changes to this project will be documented in this file. Use `Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher` instead. * Symbol `Contrib.PackageUrl.Factories.PackageUrlFactory` ([#1348] via [#1378]) * Symbol `Contrib.FromNodePackageJson.Factories.PackageUrlFactory` ([#1348] via [#1378]) - * Symbol `SPDX.isValidSpdxLicenseExpression` ([#1348] via [#1382]) + * Symbol `SPDX.isValidSpdxLicenseExpression` ([#1348] via [#1382]) Use package `spdx-expression-parse` instead. * Changed * `Component.purl` is a `string` now, was `PackaheUrl` ([#1348] via [#1379]) From 5a83596e2b0e6cff8dbf9dc98ed03a7da783b65c Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Fri, 20 Feb 2026 16:27:26 +0100 Subject: [PATCH 29/35] docs Signed-off-by: Jan Kowalleck --- HISTORY.md | 11 ++++++++--- README.md | 6 ++++++ package.json | 12 ++++++++---- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 0e33c6072..a5b11065d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -26,9 +26,11 @@ All notable changes to this project will be documented in this file. * Deprecated symbol `Factories.FromNodePackageJson.ExternalReferenceFactory` ([#1346] via [#1377]) Use `Contrib.FromNodePackageJson.Factories.ExternalReferenceFactory` instead. * Deprecated symbol `Factories.FromNodePackageJson.PackageUrlFactory` ([#1346] via [#1377]) + Use `packageurl-js` downstream. * Deprecated symbol `Factories.LicenseFactory` ([#1346], [#1348] via [#1377], [#1378]) Use `Contrib.License.Factories.LicenseFactory` instead. * Deprecated symbol `Factories.PackageUrlFactory` ([#1346] via [#1377]) + Use `packageurl-js` downstream. * Deprecated symbol `Types.NodePackageJson` ([#1346], [#1348] via [#1377], [#1378]) Use `Contrib.FromNodePackageJson.Types.NodePackageJson` instead. * Deprecated symbol `Types.assertNodePackageJson` ([#1346] via [#1377]) @@ -55,8 +57,10 @@ All notable changes to this project will be documented in this file. Use `Contrib.FromNodePackageJson.Utils.parsePackageIntegrity` instead. * Deprecated symbol `Utils.NpmjsUtility.defaultRegistryMatcher` ([#1346] via [#1377]) Use `Contrib.FromNodePackageJson.Utils.defaultRegistryMatcher` instead. - * Symbol `Contrib.PackageUrl.Factories.PackageUrlFactory` ([#1348] via [#1378]) - * Symbol `Contrib.FromNodePackageJson.Factories.PackageUrlFactory` ([#1348] via [#1378]) + * Symbol `Contrib.PackageUrl.Factories.PackageUrlFactory` ([#1348] via [#1378]) + Use `packageurl-js` downstream. + * Symbol `Contrib.FromNodePackageJson.Factories.PackageUrlFactory` ([#1348] via [#1378]) + Use `packageurl-js` downstream. * Symbol `SPDX.isValidSpdxLicenseExpression` ([#1348] via [#1382]) Use package `spdx-expression-parse` instead. * Changed @@ -64,7 +68,8 @@ All notable changes to this project will be documented in this file. * Constructor of `Contrib.License.Factories.LicenseFactory` got an injectable argument `spdxExpressionValidate` for validating SPDX License Expressions ([#1348] via [#1382]) Suggested implementation is `spdx-expression-parse`. * Dependencies - * No longer depend on `packageurl-js@^2.0.1` ([#1348] via [#1378]) + * Dependency `packageurl-js` became a suggested (optional peer-dependency) library ([#1348] via [#1378]) + You may use it to craft and parse PackageURLs downstream. * Dependency `spdx-expression-parse` became a suggested (optional peer-dependency) library ([#1348] via [#1382]) Used as an injectable in `Contrib.License.Factories.LicenseFactory.constructor`. * Build diff --git a/README.md b/README.md index 7f4479197..6523bc1d5 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,12 @@ Some features require optional peer dependencies — see `package.json` for vers * [`libxmljs2`](https://www.npmjs.com/package/libxmljs2) * the system might need to meet the requirements for [`node-gyp`](https://github.com/TooTallNate/node-gyp#installation), in certain cases. +In addition, we have some suggestions for related 3rd-party standards: +* [`packageurl-js`](https://www.npmjs.com/package/packageurl-js) + for crafting and parsing PackageURLs. +* [`spdx-expression-parse`](https://www.npmjs.com/package/spdx-expression-parse) + for validating SPDX License Expressions. + ## Usage See extended [examples]. diff --git a/package.json b/package.json index 1c96d52ea..7c5d87d9f 100644 --- a/package.json +++ b/package.json @@ -86,8 +86,9 @@ "ajv-formats": "^3.0.1", "ajv-formats-draft2019": "^1.6.1", "libxmljs2": "^0.35||^0.37", - "spdx-expression-parse": "^3.0.1 || ^4", - "xmlbuilder2": "^3.0.2||^4.0.0" + "xmlbuilder2": "^3.0.2||^4.0.0", + "packageurl-js": "*", + "spdx-expression-parse": "*" }, "peerDependenciesMeta": { "ajv": { @@ -102,10 +103,13 @@ "libxmljs2": { "optional": true }, - "spdx-expression-parse": { + "xmlbuilder2": { "optional": true }, - "xmlbuilder2": { + "packageurl-js": { + "optional": true + }, + "spdx-expression-parse": { "optional": true } }, From 8e06489d9a06d6e28f9f000acdcc8388d63a2f78 Mon Sep 17 00:00:00 2001 From: jkowalleck Date: Mon, 23 Feb 2026 11:01:31 +0000 Subject: [PATCH 30/35] 10.0.0-rc.1 Signed-off-by: jkowalleck --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 7c5d87d9f..94bfa1207 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cyclonedx/cyclonedx-library", - "version": "10.0.0-alpha.0", + "version": "10.0.0-rc.1", "description": "Core functionality of CycloneDX for JavaScript (Node.js or WebBrowser).", "license": "Apache-2.0", "keywords": [ @@ -79,8 +79,7 @@ "engines": { "node": ">=20.18.0" }, - "dependencies": { - }, + "dependencies": {}, "peerDependencies": { "ajv": "^8.12.0", "ajv-formats": "^3.0.1", From a8387f46b6b0fc8cccff98390688f8f4bbd426e4 Mon Sep 17 00:00:00 2001 From: jkowalleck Date: Mon, 23 Feb 2026 13:06:44 +0000 Subject: [PATCH 31/35] 10.0.0-rc.2 Signed-off-by: jkowalleck --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 94bfa1207..469dbc824 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cyclonedx/cyclonedx-library", - "version": "10.0.0-rc.1", + "version": "10.0.0-rc.2", "description": "Core functionality of CycloneDX for JavaScript (Node.js or WebBrowser).", "license": "Apache-2.0", "keywords": [ From fb16e27a0259dcb34c6cf57c89d8167ae9603d6a Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 23 Feb 2026 15:09:29 +0100 Subject: [PATCH 32/35] docs Signed-off-by: Jan Kowalleck --- src/contrib/license/factories.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contrib/license/factories.ts b/src/contrib/license/factories.ts index 8e41c5db0..73a2e571f 100644 --- a/src/contrib/license/factories.ts +++ b/src/contrib/license/factories.ts @@ -22,7 +22,7 @@ import { LicenseExpression, NamedLicense, SpdxLicense } from '../../models/licen import { fixupSpdxId } from '../../spdx' /** - * SPDXLicense Expression validation. + * SPDX License Expression validation. * * We suggest one of the following 3rd-party libraries: * - `spdx-expression-parse@^3.0.1||^4` - {@link https://www.npmjs.com/package/spdx-expression-parse} From 5af9b1d8d1464fd3d65503d9db4adb901f305348 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 23 Feb 2026 15:12:53 +0100 Subject: [PATCH 33/35] docs Signed-off-by: Jan Kowalleck --- src/contrib/license/factories.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/contrib/license/factories.ts b/src/contrib/license/factories.ts index 73a2e571f..ef124e628 100644 --- a/src/contrib/license/factories.ts +++ b/src/contrib/license/factories.ts @@ -27,7 +27,8 @@ import { fixupSpdxId } from '../../spdx' * We suggest one of the following 3rd-party libraries: * - `spdx-expression-parse@^3.0.1||^4` - {@link https://www.npmjs.com/package/spdx-expression-parse} * - * @throws {@link Error} when the argument is no valid SPDX License Expression + * @throws {@link Error} + * Throws an error if the input is not a valid SPDX License Expression. */ type SpdxExpressionValidate = (data: string) => void From b626de81920acb2dec32c091ed16024c0eb68d80 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 23 Feb 2026 15:15:19 +0100 Subject: [PATCH 34/35] docs Signed-off-by: Jan Kowalleck --- src/contrib/license/factories.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/contrib/license/factories.ts b/src/contrib/license/factories.ts index ef124e628..5b6d10f3a 100644 --- a/src/contrib/license/factories.ts +++ b/src/contrib/license/factories.ts @@ -24,6 +24,8 @@ import { fixupSpdxId } from '../../spdx' /** * SPDX License Expression validation. * + * A function that is expected to throw an error if the input is not a valid SPDX License Expression. + * * We suggest one of the following 3rd-party libraries: * - `spdx-expression-parse@^3.0.1||^4` - {@link https://www.npmjs.com/package/spdx-expression-parse} * From 21e9cf8cc0923230025e104c5a25408a333fe229 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 2 Mar 2026 11:03:00 +0100 Subject: [PATCH 35/35] style: typed import extra Signed-off-by: Jan Kowalleck --- src/_optPlug.node/__xmlValidators/libxmljs2.ts | 3 ++- src/spec/_protocol.ts | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/_optPlug.node/__xmlValidators/libxmljs2.ts b/src/_optPlug.node/__xmlValidators/libxmljs2.ts index 63cadad19..bce1b4224 100644 --- a/src/_optPlug.node/__xmlValidators/libxmljs2.ts +++ b/src/_optPlug.node/__xmlValidators/libxmljs2.ts @@ -20,7 +20,8 @@ Copyright (c) OWASP Foundation. All Rights Reserved. import { readFile } from 'node:fs/promises' import { pathToFileURL } from 'node:url' -import { type ParserOptions, parseXml } from 'libxmljs2' +import type { ParserOptions } from 'libxmljs2' +import { parseXml } from 'libxmljs2' import type { ValidationError } from '../../validation/types' import type { Functionality, Validator } from '../xmlValidator' diff --git a/src/spec/_protocol.ts b/src/spec/_protocol.ts index b24cf740d..ed30698cd 100644 --- a/src/spec/_protocol.ts +++ b/src/spec/_protocol.ts @@ -18,7 +18,8 @@ Copyright (c) OWASP Foundation. All Rights Reserved. */ import type { ComponentType, ExternalReferenceType, HashAlgorithm, Vulnerability } from '../enums' -import { type HashContent, NamedLicense, SpdxLicense } from '../models' +import type { HashContent } from '../models' +import { NamedLicense, SpdxLicense } from '../models' import type { Format, Version } from './enums' /** @@ -172,7 +173,7 @@ export class _Spec implements _SpecProtocol { supportsProperties (model: any): boolean { switch (true) { case model instanceof NamedLicense || model instanceof SpdxLicense: - return this.#supportsLicenseProperties + return this.#supportsLicenseProperties default: return this.#supportsProperties }