Skip to content

Commit e3c0955

Browse files
committed
fix(sbom-generator): resolve exactOptionalPropertyTypes type errors
Fix TypeScript strict mode errors with exactOptionalPropertyTypes flag. Changes: - Use conditional spread operator for optional properties instead of assigning undefined - Add null check guard for primary result in combineSbom - Use IIFE to avoid calling buildExternalReferences twice - Add fallback for array access that could return undefined - Prefix unused variables with underscore
1 parent dcf9c4f commit e3c0955

File tree

2 files changed

+41
-30
lines changed

2 files changed

+41
-30
lines changed

packages/sbom-generator/src/index.mts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ function combineSbom(
105105
): Sbom {
106106
// Use first result as primary metadata (typically root project).
107107
const primary = results[0]
108+
if (!primary) {
109+
throw new Error('No results provided to buildSbom')
110+
}
108111

109112
// Collect all components and dependencies.
110113
const allComponents: Component[] = []
@@ -133,17 +136,24 @@ function combineSbom(
133136
version: '1.0.0',
134137
},
135138
],
136-
component: {
137-
type: 'application',
138-
'bom-ref': `pkg:${results[0].ecosystem}/${primary.metadata.name}@${primary.metadata.version}`,
139-
name: primary.metadata.name,
140-
version: primary.metadata.version,
141-
description: primary.metadata.description,
142-
licenses: primary.metadata.license
143-
? [{ license: { id: primary.metadata.license } }]
144-
: undefined,
145-
externalReferences: buildExternalReferences(primary.metadata),
146-
},
139+
component: (() => {
140+
const extRefs = buildExternalReferences(primary.metadata)
141+
return {
142+
type: 'application',
143+
'bom-ref': `pkg:${primary.ecosystem}/${primary.metadata.name}@${primary.metadata.version}`,
144+
name: primary.metadata.name,
145+
version: primary.metadata.version,
146+
...(primary.metadata.description && {
147+
description: primary.metadata.description,
148+
}),
149+
...(primary.metadata.license && {
150+
licenses: [{ license: { id: primary.metadata.license } }],
151+
}),
152+
...(extRefs && extRefs.length > 0 && {
153+
externalReferences: extRefs,
154+
}),
155+
}
156+
})(),
147157
},
148158
components: uniqueComponents,
149159
dependencies: allDependencies,

packages/sbom-generator/src/parsers/npm/index.mts

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,9 @@ export class NpmParser implements Parser {
226226
dependencies: pkgData.dependencies
227227
? Object.keys(pkgData.dependencies)
228228
: [],
229-
resolved: pkgData.resolved,
230-
integrity: pkgData.integrity,
231-
license: pkgData.license,
229+
...(pkgData.resolved && { resolved: pkgData.resolved }),
230+
...(pkgData.integrity && { integrity: pkgData.integrity }),
231+
...(pkgData.license && { license: pkgData.license }),
232232
})
233233
}
234234
}
@@ -254,7 +254,7 @@ export class NpmParser implements Parser {
254254
}
255255

256256
// Regular packages.
257-
return withoutPrefix.split('/')[0]
257+
return withoutPrefix.split('/')[0] || withoutPrefix
258258
}
259259

260260
/**
@@ -264,7 +264,7 @@ export class NpmParser implements Parser {
264264
deps: Record<string, PackageLockDependency>,
265265
result: Map<string, DependencyInfo>,
266266
options: ParseOptions,
267-
parentKey?: string,
267+
_parentKey?: string,
268268
): void {
269269
for (const [name, data] of Object.entries(deps)) {
270270
// Skip dev dependencies if not included.
@@ -283,9 +283,8 @@ export class NpmParser implements Parser {
283283
isDev: !!data.dev,
284284
isOptional: !!data.optional,
285285
dependencies: data.requires ? Object.keys(data.requires) : [],
286-
resolved: data.resolved,
287-
integrity: data.integrity,
288-
license: undefined,
286+
...(data.resolved && { resolved: data.resolved }),
287+
...(data.integrity && { integrity: data.integrity }),
289288
})
290289
}
291290

@@ -331,9 +330,12 @@ export class NpmParser implements Parser {
331330
dependencies: pkgData.dependencies
332331
? Object.keys(pkgData.dependencies)
333332
: [],
334-
resolved: pkgData.resolution?.tarball,
335-
integrity: pkgData.resolution?.integrity,
336-
license: undefined,
333+
...(pkgData.resolution?.tarball && {
334+
resolved: pkgData.resolution.tarball,
335+
}),
336+
...(pkgData.resolution?.integrity && {
337+
integrity: pkgData.resolution.integrity,
338+
}),
337339
})
338340
}
339341
}
@@ -361,7 +363,7 @@ export class NpmParser implements Parser {
361363

362364
// Regular packages (e.g., "axios/0.21.0").
363365
const parts = withoutSlash.split('/')
364-
const name = parts[0]
366+
const name = parts[0] || withoutSlash
365367
const version = parts[1] || '0.0.0'
366368
return { name, version }
367369
}
@@ -400,9 +402,8 @@ export class NpmParser implements Parser {
400402
dependencies: pkgData.dependencies
401403
? Object.keys(pkgData.dependencies)
402404
: [],
403-
resolved: pkgData.resolved,
404-
integrity: pkgData.integrity,
405-
license: undefined,
405+
...(pkgData.resolved && { resolved: pkgData.resolved }),
406+
...(pkgData.integrity && { integrity: pkgData.integrity }),
406407
})
407408
}
408409

@@ -431,7 +432,7 @@ export class NpmParser implements Parser {
431432
): Component[] {
432433
const components: Component[] = []
433434

434-
for (const [key, dep] of dependencies.entries()) {
435+
for (const [_key, dep] of dependencies.entries()) {
435436
// Skip dev dependencies if not included.
436437
if (!options.includeDevDependencies && dep.isDev) {
437438
continue
@@ -532,7 +533,7 @@ export class NpmParser implements Parser {
532533
})
533534

534535
// Add transitive dependencies.
535-
for (const [key, dep] of dependencies.entries()) {
536+
for (const [_key, dep] of dependencies.entries()) {
536537
const ref = `pkg:npm/${dep.name}@${dep.version}`
537538
const dependsOn: string[] = []
538539

@@ -547,7 +548,7 @@ export class NpmParser implements Parser {
547548

548549
graph.push({
549550
ref,
550-
dependsOn: dependsOn.length > 0 ? dependsOn : undefined,
551+
...(dependsOn.length > 0 && { dependsOn }),
551552
})
552553
}
553554

@@ -561,7 +562,7 @@ export class NpmParser implements Parser {
561562
name: string,
562563
dependencies: Map<string, DependencyInfo>,
563564
): DependencyInfo | undefined {
564-
for (const [key, dep] of dependencies.entries()) {
565+
for (const [_key, dep] of dependencies.entries()) {
565566
if (dep.name === name) {
566567
return dep
567568
}

0 commit comments

Comments
 (0)