Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ All notable changes to this project will be documented in this file.

<!-- add unreleased items here -->

* Added
* Public export `types.NodePackageJson`, which is the input type for various factories and builders (via [#1263])

[#1263]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1263

## 8.4.0 -- 2025-06-16

* Fixed
Expand Down
31 changes: 0 additions & 31 deletions src/_helpers/packageJson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,34 +33,3 @@ export function splitNameGroup (data: string): [string, string?] {
: [data, undefined]
}

/**
* Intended to represent 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).
*/
export interface PackageJson {
name?: string
version?: string
description?: string
license?: string
licenses?: Array<{
type?: string
url?: string
}>
author?: string | {
name?: string
email?: string
}
bugs?: string | {
url?: string
}
homepage?: string
repository?: string | {
type?: string
url?: string
directory?: string
}
// ... to be continued
dist?: any // see https://github.com/CycloneDX/cyclonedx-node-npm/issues/1300
}
6 changes: 3 additions & 3 deletions src/builders/fromNodePackageJson.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +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 { PackageJson } from '../_helpers/packageJson'
import { splitNameGroup } from '../_helpers/packageJson'
import { ComponentType } from '../enums/componentType'
import type * as Factories from '../factories/index.node'
import { Component } from '../models/component'
import { ExternalReferenceRepository } from '../models/externalReference'
import { LicenseRepository } from '../models/license'
import { Tool } from '../models/tool'
import type { NodePackageJson } from '../types/nodePackageJson'

/**
* Node-specific ToolBuilder.
Expand All @@ -51,7 +51,7 @@ export class ToolBuilder {

// Current implementation does not return `undefined` yet, but it is an option for future implementation.
// To prevent future breaking changes, it is declared to return `undefined`.
makeTool (data: PackageJson): Tool | undefined {
makeTool (data: NodePackageJson): Tool | undefined {
const [name, vendor] = typeof data.name === 'string'
? splitNameGroup(data.name)
: []
Expand Down Expand Up @@ -90,7 +90,7 @@ export class ComponentBuilder {
return this.#licenseFactory
}

makeComponent (data: PackageJson, type: ComponentType = ComponentType.Library): Component | undefined {
makeComponent (data: NodePackageJson, type: ComponentType = ComponentType.Library): Component | undefined {
if (typeof data.name !== 'string') {
return undefined
}
Expand Down
12 changes: 6 additions & 6 deletions src/factories/fromNodePackageJson.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,20 @@ import { PurlQualifierNames } from 'packageurl-js'

import { tryCanonicalizeGitUrl } from "../_helpers/gitUrl"
import { isNotUndefined } from '../_helpers/notUndefined'
import type { PackageJson } from '../_helpers/packageJson'
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 type { NodePackageJson } from '../types/nodePackageJson'
import { defaultRegistryMatcher, parsePackageIntegrity } from '../utils/npmjsUtility.node'
import { PackageUrlFactory as PlainPackageUrlFactory } from './packageUrl'

/**
* Node-specific ExternalReferenceFactory.
*/
export class ExternalReferenceFactory {
makeExternalReferences (data: PackageJson): ExternalReference[] {
makeExternalReferences (data: NodePackageJson): ExternalReference[] {
const refs: Array<ExternalReference | undefined> = []

try { refs.push(this.makeVcs(data)) } catch { /* pass */ }
Expand All @@ -55,7 +55,7 @@ export class ExternalReferenceFactory {
return refs.filter(isNotUndefined)
}

makeVcs (data: PackageJson): ExternalReference | undefined {
makeVcs (data: NodePackageJson): ExternalReference | undefined {
/* see https://docs.npmjs.com/cli/v9/configuring-npm/package-json#repositoryc */
const repository = data.repository
let url = undefined
Expand All @@ -78,7 +78,7 @@ export class ExternalReferenceFactory {
: new ExternalReference(url.toString(), ExternalReferenceType.VCS, { comment })
}

makeHomepage (data: PackageJson): ExternalReference | undefined {
makeHomepage (data: NodePackageJson): ExternalReference | undefined {
/* see https://docs.npmjs.com/cli/v9/configuring-npm/package-json#homepage */
const url = data.homepage
return typeof url === 'string' && url.length > 0
Expand All @@ -88,7 +88,7 @@ export class ExternalReferenceFactory {
: undefined
}

makeIssueTracker (data: PackageJson): ExternalReference | undefined {
makeIssueTracker (data: NodePackageJson): ExternalReference | undefined {
/* see https://docs.npmjs.com/cli/v9/configuring-npm/package-json#bugs */
const bugs = data.bugs
let url = undefined
Expand All @@ -105,7 +105,7 @@ export class ExternalReferenceFactory {
: undefined
}

makeDist(data: PackageJson): ExternalReference | undefined {
makeDist(data: NodePackageJson): ExternalReference | undefined {
// "dist" might be used in bundled dependencies' manifests.
// docs: https://blog.npmjs.org/post/172999548390/new-pgp-machinery
/* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- acknowledged */
Expand Down
3 changes: 3 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ export * from './cpe'
export * from './cwe'
export * from './integer'
export * from './mimeType'

// yes, this is node-specific, but who cares - these are just types
export * from './nodePackageJson'
86 changes: 86 additions & 0 deletions src/types/nodePackageJson.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*!
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.
*/

/**
* Intended to represent 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).
*/
export interface NodePackageJson {
name?: string
version?: string
description?: string
license?: string
licenses?: Array<{
type?: string
url?: string
}>
author?: string | {
name?: string
email?: string
}
bugs?: string | {
url?: string
}
homepage?: string
repository?: string | {
type?: string
url?: string
directory?: string
}
// ... to be continued
dist?: any // see https://github.com/CycloneDX/cyclonedx-node-npm/issues/1300
}

/**
*
* Not implemented, yet.
* TODO: write type guard -- pull-requests welcome
*
* @alpha
*/
export function isNodePackageJson (value: any): value is NodePackageJson {
throw new Error('Not implemented')
/* possible implementation:
try { assertNodePackageJson(value) }
catch { return false }
return true
*/
}

/**
*
* Not implemented, yet.
* TODO: write type assertion -- pull-requests welcome
*
* @throws {@link Error} on error; includes qualitative message
*
* @alpha
*/
export function assertNodePackageJson (value: any): asserts value is NodePackageJson {
throw new Error('Not implemented')
/* possible implementation:
if ( value === null || value === undefined ) { throw new Error('value not an object') }
if ( !(typeof value.name in ['undefined', 'string']) ) { throw new Error('unexpected name') }
etc...
*/
}
Loading