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
22 changes: 22 additions & 0 deletions src/_helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ Copyright (c) OWASP Foundation. All Rights Reserved.
import { existsSync, readFileSync } from 'node:fs'
import { dirname, isAbsolute, join, sep } from 'node:path'

import normalizePackageData from 'normalize-package-data'


export function isNonNullable<T>(value: T): value is NonNullable<T> {
// NonNullable: not null and not undefined
return value !== null && value !== undefined
Expand Down Expand Up @@ -116,3 +119,22 @@ export function iterableSome<T>(i: Iterable<T>, t: (v: T) => boolean): boolean {
}

// endregion polyfills


export function isString (v: any): v is string {
return typeof v === 'string'
}

export function normalizePackageManifest (data: any, warn?: normalizePackageData.WarnFn): asserts data is normalizePackageData.Package {
/* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access -- ack*/
const oVersion = data.version

/* eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- ack */
normalizePackageData(data as normalizePackageData.Input, warn)

if (isString(oVersion)) {
// normalizer might have stripped version or sanitized it to SemVer -- we want the original
/* eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- ack */
data.version = oVersion.trim()
}
}
29 changes: 9 additions & 20 deletions src/extractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,14 @@ Copyright (c) OWASP Foundation. All Rights Reserved.
import { dirname } from 'node:path'

import * as CDX from '@cyclonedx/cyclonedx-library'
import normalizePackageJson from 'normalize-package-data'
import type { Compilation, Module } from 'webpack'

import {
getPackageDescription,
isNonNullable,
normalizePackageManifest,
type PackageDescription,
structuredClonePolyfill
} from './_helpers'
structuredClonePolyfill} from './_helpers'

type WebpackLogger = Compilation['logger']

Expand Down Expand Up @@ -93,29 +92,19 @@ export class Extractor {
*/
makeComponent (pkg: PackageDescription, collectEvidence: boolean, logger?: WebpackLogger): CDX.Models.Component {
try {
/* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- expected */
// work with a deep copy, because `normalizePackageManifest()` might modify the data
/* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- ach */
const _packageJson = structuredClonePolyfill(pkg.packageJson)
/* eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- hint hont */
normalizePackageJson(_packageJson as normalizePackageJson.Input /* add debug for warnings? */)
// region fix normalizations
/* eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- expected */
if (typeof pkg.packageJson.version === 'string') {
// allow non-SemVer strings
/* eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
, @typescript-eslint/no-unsafe-type-assertion
-- hint hint */
_packageJson.version = (pkg.packageJson.version as string).trim()
}
// endregion fix normalizations
/* eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- hint hint */
pkg.packageJson = _packageJson as normalizePackageJson.Package
normalizePackageManifest(_packageJson)
pkg.packageJson = _packageJson
} catch (e) {
logger?.warn('normalizePackageJson from PkgPath', pkg.path, 'failed:', e)
}

const component = this.#componentBuilder.makeComponent(
/* eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- hint hint */
pkg.packageJson as normalizePackageJson.Package)
/* @ts-expect-error TS2559 */
pkg.packageJson as PackageDescription) /* eslint-disable-line @typescript-eslint/no-unsafe-type-assertion -- ack */

if (component === undefined) {
throw new Error(`failed building Component from PkgPath ${pkg.path}`)
}
Expand Down
29 changes: 15 additions & 14 deletions src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@ import { existsSync } from 'node:fs'
import { join as joinPath, resolve } from 'node:path'

import * as CDX from '@cyclonedx/cyclonedx-library'
import normalizePackageJson from 'normalize-package-data'
import { Compilation, type Compiler, sources, version as WEBPACK_VERSION } from 'webpack'

import { getPackageDescription, iterableSome, loadJsonFile, type PackageDescription } from './_helpers'
import {
getPackageDescription,
iterableSome,
loadJsonFile,
normalizePackageManifest,
type PackageDescription
} from './_helpers'
import { Extractor } from './extractor'

type WebpackLogger = Compilation['logger']
Expand Down Expand Up @@ -381,13 +386,13 @@ export class CycloneDxWebpackPlugin {
? getPackageDescription(path)?.packageJson
: { name: this.rootComponentName, version: this.rootComponentVersion }
if (thisPackageJson === undefined) { return undefined }
normalizePackageJson(
/* eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- hint hint */
thisPackageJson as normalizePackageJson.Input,
normalizePackageManifest(
thisPackageJson,
w => { logger.debug('normalizePackageJson from PkgPath', path, 'caused:', w) }
)
/* eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- hint hint */
return builder.makeComponent(thisPackageJson as normalizePackageJson.Package)
return builder.makeComponent(thisPackageJson)
}

#finalizeBom (
Expand Down Expand Up @@ -447,15 +452,11 @@ export class CycloneDxWebpackPlugin {
logger.log('try to build new Tool from PkgPath', packageJsonPath)
/* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- expected */
const packageJson: PackageDescription['packageJson'] = loadJsonFile(packageJsonPath) ?? {}
normalizePackageJson(
/* eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- hint hint */
packageJson as normalizePackageJson.Input,
normalizePackageManifest(
packageJson,
w => { logger.debug('normalizePackageJson from PkgPath', packageJsonPath, 'caused:', w) }
)
const tool = builder.makeComponent(
/* eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- hint hint */
packageJson as normalizePackageJson.Package,
cType)
const tool = builder.makeComponent(packageJson, cType)
if (tool !== undefined) {
yield tool
}
Expand Down