Skip to content

feat: add runtime engine constraints to metadata component - #589

Open
sidsri14 wants to merge 1 commit into
CycloneDX:mainfrom
sidsri14:fix/engine-constraint-properties
Open

feat: add runtime engine constraints to metadata component#589
sidsri14 wants to merge 1 commit into
CycloneDX:mainfrom
sidsri14:fix/engine-constraint-properties

Conversation

@sidsri14

Copy link
Copy Markdown

Description

Map string values from the root workspace's package.json engines object to metadata.component.properties using the CycloneDX npm property taxonomy:

cdx:npm:package:constraint:engine:<name> = <version range>

This preserves arbitrary runtime names, ignores malformed or non-string values, and leaves SBOM output unchanged when engines is absent. JSON and XML snapshots cover both a multi-runtime manifest and an existing Node-only manifest.

Resolves or fixes issue: #448

Validation

  • yarn test:node on Node.js 24: 61 passing
  • yarn test:standard
  • yarn test:lint
  • yarn test:dependencies

AI Tool Disclosure

  • My contribution does not include any AI-generated content
  • My contribution includes AI-generated content, as disclosed below:
    • AI Tools: OpenAI Codex
    • LLMs and versions: GPT-5
    • Prompts: Inspect the issue and contribution requirements; implement the engines-to-CycloneDX property mapping; update fixture snapshots; run focused and full tests; review the final diff.

Affirmation

Signed-off-by: sid sri <sidsri1502@gmail.com>
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 7 complexity · 0 duplication

Metric Results
Complexity 7
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@sidsri14
sidsri14 marked this pull request as ready for review August 12, 2026 09:17
@sidsri14
sidsri14 requested a review from a team as a code owner August 12, 2026 09:17

@jkowalleck jkowalleck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some implementation remarks that need changing.

i think this feature should be moved upstream.
see https://github.com/CycloneDX/cyclonedx-node-yarn/pull/589/changes#r3766004355

Comment thread src/builders.ts
type ManifestFetcher = (pkg: Package) => Promise<NonNullable<any>>
type LicenseEvidenceFetcher = (pkg: Package) => AsyncGenerator<License>

function addEngineConstraintProperties (component: Component, engines: unknown): void {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation detail:

I'd rather have this a pure function

either a generator ala

function * makeEngineConstraintProperties ( engines: unknown): Generator<Property> { }

or a

function makeEngineConstraintProperties ( engines: unknown): Iterable<Property> { }

and then, they shall be used like

makeEngineConstraintProperties(...).forEach(p => { component.properties.add(p) })

Comment thread src/builders.ts
type LicenseEvidenceFetcher = (pkg: Package) => AsyncGenerator<License>

function addEngineConstraintProperties (component: Component, engines: unknown): void {
if (engines === null || typeof engines !== 'object' || Array.isArray(engines)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add the docs:

Suggested change
if (engines === null || typeof engines !== 'object' || Array.isArray(engines)) {
// https://docs.npmjs.com/cli/v11/configuring-npm/package-json#engines
if (engines === null || typeof engines !== 'object' || Array.isArray(engines)) {

Comment thread src/properties.ts
PackageDevelopment = 'cdx:npm:package:development',
}

export const enum PropertyNamePrefixes {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add the docs. see how it is done with PropertyNames

Comment thread src/builders.ts
type ManifestFetcher = (pkg: Package) => Promise<NonNullable<any>>
type LicenseEvidenceFetcher = (pkg: Package) => AsyncGenerator<License>

function addEngineConstraintProperties (component: Component, engines: unknown): void {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please make this a private method of BomBuilder

Comment thread src/builders.ts
const rootComponent: Component = this.makeComponentFromWorkspace(workspace, this.metaComponentType)
?? new DummyComponent(this.metaComponentType, 'RootComponent')
rootComponent.licenses.forEach(setLicensesDeclared)
addEngineConstraintProperties(rootComponent, workspace.manifest.raw.engines)

@jkowalleck jkowalleck Aug 12, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this works well for the root component, but what about the other components?

better move this into makeComponent.

and while doing so, you might see that entire process can be moved to
@cyclonedx/cyclonedx-library.Contrib.FromNodePackageJsonBuilders.Builders.ComponentBuilder
-- https://github.com/CycloneDX/cyclonedx-javascript-library/blob/main/src/contrib/fromNodePackageJson/builders.ts

PS: still considdering merging this feature

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jkowalleck

jkowalleck commented Aug 12, 2026

Copy link
Copy Markdown
Member

Thank you for all your efforts.

looking into the implementation details, i think the entire feature shall be moved upstream.
see CycloneDX/cyclonedx-javascript-library#1506

PS: still considdering merging this feature

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants