diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index a344d29..741375e 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -62,3 +62,16 @@ jobs: - run: npm ci - run: npm run format:check + + type-check-tests: + name: Type-Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '24' + cache: 'npm' + + - run: npm ci + - run: npm run type-check diff --git a/package.json b/package.json index 6478c56..5682a0a 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "lint:fix": "oxlint --fix --fix-suggestions", "format:check": "prettier --check .", "format:write": "prettier --write .", + "type-check": "tsc --noEmit", "download-schemas": "node scripts/sbom-schema-downloader.js", "prepare": "npm run build" }, diff --git a/src/cdx-xml-to-json.test.ts b/src/cdx-xml-to-json.test.ts index 9fbab24..36497d1 100644 --- a/src/cdx-xml-to-json.test.ts +++ b/src/cdx-xml-to-json.test.ts @@ -23,17 +23,17 @@ describe('CycloneDX XML to JSON Converter', () => { assert.equal(result.version, 1); // Metadata validation - assert(Array.isArray(result.metadata.tools)); - assert(result.metadata.tools.length >= 2); + assert(Array.isArray(result.metadata?.tools)); + assert(result.metadata?.tools.length >= 2); - const firstTool = result.metadata.tools[0]; - assert.equal(firstTool.vendor, '@cyclonedx'); - assert.equal(firstTool.name, 'cyclonedx-library'); + const firstTool = result.metadata?.tools[0]; + assert.equal(firstTool?.vendor, '@cyclonedx'); + assert.equal(firstTool?.name, 'cyclonedx-library'); // Component validation const component = result.metadata.component; assert(!Array.isArray(component)); - assert.equal(component.type, 'application'); + assert.equal(component?.type, 'application'); assert.equal(component['bom-ref'], 'juice-shop@14.1.1'); // Components array validation @@ -53,8 +53,8 @@ describe('CycloneDX XML to JSON Converter', () => { assert.equal(result.bomFormat, 'CycloneDX'); assert.equal(result.specVersion, version); - assert(Array.isArray(result.metadata.tools)); - assert(!Array.isArray(result.metadata.component)); + assert(Array.isArray(result.metadata?.tools)); + assert(!Array.isArray(result.metadata?.component)); } }); }); diff --git a/src/eol/utils.test.ts b/src/eol/utils.test.ts index cdb3cb5..d94c939 100644 --- a/src/eol/utils.test.ts +++ b/src/eol/utils.test.ts @@ -3,6 +3,18 @@ import { strict as assert } from 'node:assert'; import { deriveComponentStatus } from './utils.ts'; import type { EolScanComponentMetadata } from '../types/eol-scan.ts'; +// These are required for the object but not used to derive the status +const defaultMetadataProps = { + eolReasons: [], + cveStats: [], + ecosystem: 'npm', + releasedAt: new Date(), + isNesPackage: false, + nextSupportedVersion: null, + daysBehindNextSupported: null, + majorVersionsFromNextSupported: null, +}; + describe('deriveComponentStatus', () => { test('should return UNKNOWN when there is no metadata', () => { const result = deriveComponentStatus(null); @@ -11,10 +23,9 @@ describe('deriveComponentStatus', () => { test('should return EOL when isEol is true', () => { const metadata: EolScanComponentMetadata = { + ...defaultMetadataProps, isEol: true, eolAt: null, - eolReasons: ['End of life'], - cve: [], }; const result = deriveComponentStatus(metadata); @@ -23,10 +34,9 @@ describe('deriveComponentStatus', () => { test('should return EOL when eolAt is in the past', () => { const metadata: EolScanComponentMetadata = { + ...defaultMetadataProps, isEol: false, eolAt: '2020-01-01T00:00:00.000Z', - eolReasons: ['End of life'], - cve: [], }; const result = deriveComponentStatus(metadata); @@ -36,10 +46,9 @@ describe('deriveComponentStatus', () => { test('should return EOL when eolAt is current date', () => { const currentDate = new Date().toISOString(); const metadata: EolScanComponentMetadata = { + ...defaultMetadataProps, isEol: false, eolAt: currentDate, - eolReasons: [], - cve: [], }; const result = deriveComponentStatus(metadata); @@ -51,10 +60,9 @@ describe('deriveComponentStatus', () => { futureDate.setFullYear(futureDate.getFullYear() + 1); const metadata: EolScanComponentMetadata = { + ...defaultMetadataProps, isEol: false, eolAt: futureDate.toISOString(), - eolReasons: [], - cve: [], }; const result = deriveComponentStatus(metadata); @@ -63,10 +71,9 @@ describe('deriveComponentStatus', () => { test('should return OK when isEol is false and eolAt is null', () => { const metadata: EolScanComponentMetadata = { + ...defaultMetadataProps, isEol: false, eolAt: null, - eolReasons: [], - cve: [], }; const result = deriveComponentStatus(metadata); diff --git a/src/index.ts b/src/index.ts index 63ef028..2cd88c1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,29 +3,8 @@ export { trimCdxBom } from './trim-cdx-bom.js'; export { spdxToCdxBom } from './spdx-to-cdx.js'; export { deriveComponentStatus, extractPurlsFromCdxBom } from './eol/utils.js'; -export type { - ComponentStatus, - CreateEolReportInput, - CveStats, - EolScanComponentMetadata, - EolScanComponent, - EolReportMetadata, - EolReport, - EolReportQueryResponse, - EolReportMutationResponse, - NesRemediation, -} from './types/eol-scan.js'; - -export type { - CdxBom, - Component, - Dependency, - ExternalReference, - Hash, - License, - SPDX23, - SupportedBom, -} from './types/index.js'; +export type * from './types/eol-scan.js'; +export type * from './types/index.js'; export { ComponentScope } from './types/index.js'; export { isCdxBom, isSpdxBom, isSupportedBom } from './bom/validation.js';