Skip to content

Commit 7089396

Browse files
authored
feat: public export of type NodePackageJson (#1263)
## Added * Public export `types.NodePackageJson`, which is the input type for various factories and builders this enables type checking downstream, like - `const foo: NodePackageJson = {...}` - `const foo = {...} satisfies NodePackageJson` --------- Signed-off-by: Jan Kowalleck <[email protected]>
1 parent 1e335d8 commit 7089396

File tree

6 files changed

+103
-40
lines changed

6 files changed

+103
-40
lines changed

HISTORY.md

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

77
<!-- add unreleased items here -->
88

9+
* Added
10+
* Public export `types.NodePackageJson`, which is the input type for various factories and builders (via [#1263])
11+
12+
[#1263]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1263
13+
914
## 8.4.0 -- 2025-06-16
1015

1116
* Fixed

src/_helpers/packageJson.ts

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -33,34 +33,3 @@ export function splitNameGroup (data: string): [string, string?] {
3333
: [data, undefined]
3434
}
3535

36-
/**
37-
* Intended to represent normalized data structures
38-
* based on [PackageJson spec](https://github.com/SchemaStore/schemastore/blob/master/src/schemas/json/package.json)
39-
* and explained by [PackageJson description](https://docs.npmjs.com/cli/v9/configuring-npm/package-json).
40-
* Normalization should be done downstream, for example via [`normalize-package-data`](https://www.npmjs.com/package/normalize-package-data).
41-
*/
42-
export interface PackageJson {
43-
name?: string
44-
version?: string
45-
description?: string
46-
license?: string
47-
licenses?: Array<{
48-
type?: string
49-
url?: string
50-
}>
51-
author?: string | {
52-
name?: string
53-
email?: string
54-
}
55-
bugs?: string | {
56-
url?: string
57-
}
58-
homepage?: string
59-
repository?: string | {
60-
type?: string
61-
url?: string
62-
directory?: string
63-
}
64-
// ... to be continued
65-
dist?: any // see https://github.com/CycloneDX/cyclonedx-node-npm/issues/1300
66-
}

src/builders/fromNodePackageJson.node.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ Copyright (c) OWASP Foundation. All Rights Reserved.
2626
* Normalization should be done downstream, for example via [`normalize-package-data`](https://www.npmjs.com/package/normalize-package-data).
2727
*/
2828

29-
import type { PackageJson } from '../_helpers/packageJson'
3029
import { splitNameGroup } from '../_helpers/packageJson'
3130
import { ComponentType } from '../enums/componentType'
3231
import type * as Factories from '../factories/index.node'
3332
import { Component } from '../models/component'
3433
import { ExternalReferenceRepository } from '../models/externalReference'
3534
import { LicenseRepository } from '../models/license'
3635
import { Tool } from '../models/tool'
36+
import type { NodePackageJson } from '../types/nodePackageJson'
3737

3838
/**
3939
* Node-specific ToolBuilder.
@@ -51,7 +51,7 @@ export class ToolBuilder {
5151

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

93-
makeComponent (data: PackageJson, type: ComponentType = ComponentType.Library): Component | undefined {
93+
makeComponent (data: NodePackageJson, type: ComponentType = ComponentType.Library): Component | undefined {
9494
if (typeof data.name !== 'string') {
9595
return undefined
9696
}

src/factories/fromNodePackageJson.node.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,20 @@ import { PurlQualifierNames } from 'packageurl-js'
3131

3232
import { tryCanonicalizeGitUrl } from "../_helpers/gitUrl"
3333
import { isNotUndefined } from '../_helpers/notUndefined'
34-
import type { PackageJson } from '../_helpers/packageJson'
3534
import { ExternalReferenceType } from '../enums/externalReferenceType'
3635
import { HashAlgorithm } from "../enums/hashAlogorithm";
3736
import type { Component } from '../models/component'
3837
import { ExternalReference } from '../models/externalReference'
3938
import { HashDictionary } from '../models/hash'
39+
import type { NodePackageJson } from '../types/nodePackageJson'
4040
import { defaultRegistryMatcher, parsePackageIntegrity } from '../utils/npmjsUtility.node'
4141
import { PackageUrlFactory as PlainPackageUrlFactory } from './packageUrl'
4242

4343
/**
4444
* Node-specific ExternalReferenceFactory.
4545
*/
4646
export class ExternalReferenceFactory {
47-
makeExternalReferences (data: PackageJson): ExternalReference[] {
47+
makeExternalReferences (data: NodePackageJson): ExternalReference[] {
4848
const refs: Array<ExternalReference | undefined> = []
4949

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

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

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

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

108-
makeDist(data: PackageJson): ExternalReference | undefined {
108+
makeDist(data: NodePackageJson): ExternalReference | undefined {
109109
// "dist" might be used in bundled dependencies' manifests.
110110
// docs: https://blog.npmjs.org/post/172999548390/new-pgp-machinery
111111
/* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- acknowledged */

src/types/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@ export * from './cpe'
2121
export * from './cwe'
2222
export * from './integer'
2323
export * from './mimeType'
24+
25+
// yes, this is node-specific, but who cares - these are just types
26+
export * from './nodePackageJson'

src/types/nodePackageJson.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*!
2+
This file is part of CycloneDX JavaScript Library.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
16+
SPDX-License-Identifier: Apache-2.0
17+
Copyright (c) OWASP Foundation. All Rights Reserved.
18+
*/
19+
20+
/**
21+
* Intended to represent normalized data structures
22+
* based on [PackageJson spec](https://github.com/SchemaStore/schemastore/blob/master/src/schemas/json/package.json)
23+
* and explained by [PackageJson description](https://docs.npmjs.com/cli/v9/configuring-npm/package-json).
24+
*
25+
* Normalization should be done downstream, for example
26+
* via [`normalize-package-data`](https://www.npmjs.com/package/normalize-package-data).
27+
*/
28+
export interface NodePackageJson {
29+
name?: string
30+
version?: string
31+
description?: string
32+
license?: string
33+
licenses?: Array<{
34+
type?: string
35+
url?: string
36+
}>
37+
author?: string | {
38+
name?: string
39+
email?: string
40+
}
41+
bugs?: string | {
42+
url?: string
43+
}
44+
homepage?: string
45+
repository?: string | {
46+
type?: string
47+
url?: string
48+
directory?: string
49+
}
50+
// ... to be continued
51+
dist?: any // see https://github.com/CycloneDX/cyclonedx-node-npm/issues/1300
52+
}
53+
54+
/**
55+
*
56+
* Not implemented, yet.
57+
* TODO: write type guard -- pull-requests welcome
58+
*
59+
* @alpha
60+
*/
61+
export function isNodePackageJson (value: any): value is NodePackageJson {
62+
throw new Error('Not implemented')
63+
/* possible implementation:
64+
try { assertNodePackageJson(value) }
65+
catch { return false }
66+
return true
67+
*/
68+
}
69+
70+
/**
71+
*
72+
* Not implemented, yet.
73+
* TODO: write type assertion -- pull-requests welcome
74+
*
75+
* @throws {@link Error} on error; includes qualitative message
76+
*
77+
* @alpha
78+
*/
79+
export function assertNodePackageJson (value: any): asserts value is NodePackageJson {
80+
throw new Error('Not implemented')
81+
/* possible implementation:
82+
if ( value === null || value === undefined ) { throw new Error('value not an object') }
83+
if ( !(typeof value.name in ['undefined', 'string']) ) { throw new Error('unexpected name') }
84+
etc...
85+
*/
86+
}

0 commit comments

Comments
 (0)