verimu 0.0.9 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -6
- package/dist/{cli.mjs → cli.js} +1295 -65
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +1503 -182
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +415 -24
- package/dist/index.d.ts +415 -24
- package/dist/index.mjs +1495 -182
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -3
- package/dist/cli.mjs.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -8,7 +8,7 @@ import { execSync } from 'child_process';
|
|
|
8
8
|
* → CveSource → Vulnerability[]
|
|
9
9
|
*/
|
|
10
10
|
/** Supported package ecosystems */
|
|
11
|
-
type Ecosystem = 'npm' | 'nuget' | 'cargo' | 'maven' | 'pip' | 'go' | 'ruby' | 'composer';
|
|
11
|
+
type Ecosystem = 'npm' | 'nuget' | 'cargo' | 'maven' | 'pip' | 'poetry' | 'uv' | 'go' | 'ruby' | 'composer' | 'deno';
|
|
12
12
|
/** Supported CI/CD providers */
|
|
13
13
|
type CiProvider = 'github' | 'gitlab' | 'bitbucket';
|
|
14
14
|
/** A single resolved dependency from a lockfile */
|
|
@@ -37,8 +37,8 @@ interface ScanResult {
|
|
|
37
37
|
/** Timestamp of when the scan was performed */
|
|
38
38
|
scannedAt: string;
|
|
39
39
|
}
|
|
40
|
-
/** Supported
|
|
41
|
-
type SbomFormat = 'cyclonedx-json' | 'cyclonedx-xml' | 'spdx-json';
|
|
40
|
+
/** Supported software inventory output formats */
|
|
41
|
+
type SbomFormat = 'cyclonedx-json' | 'cyclonedx-xml' | 'spdx-json' | 'swid-xml';
|
|
42
42
|
/** A generated Software Bill of Materials */
|
|
43
43
|
interface Sbom {
|
|
44
44
|
/** The format of this SBOM */
|
|
@@ -52,6 +52,15 @@ interface Sbom {
|
|
|
52
52
|
/** Timestamp of generation */
|
|
53
53
|
generatedAt: string;
|
|
54
54
|
}
|
|
55
|
+
/** All software inventory artifacts generated for a scan */
|
|
56
|
+
interface SbomArtifacts {
|
|
57
|
+
/** Primary CRA-compatible SBOM used for backend parsing */
|
|
58
|
+
cyclonedx: Sbom;
|
|
59
|
+
/** SPDX 2.3 JSON document for interoperability */
|
|
60
|
+
spdx: Sbom;
|
|
61
|
+
/** Minimal SWID XML tag for root product identity */
|
|
62
|
+
swid: Sbom;
|
|
63
|
+
}
|
|
55
64
|
/** Severity levels aligned with CVSS v3 */
|
|
56
65
|
type Severity = 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW' | 'UNKNOWN';
|
|
57
66
|
/** A single known vulnerability */
|
|
@@ -109,6 +118,8 @@ interface VerimuReport {
|
|
|
109
118
|
};
|
|
110
119
|
/** Generated SBOM */
|
|
111
120
|
sbom: Sbom;
|
|
121
|
+
/** All generated software inventory artifacts (CycloneDX + SPDX + SWID) */
|
|
122
|
+
artifacts?: SbomArtifacts;
|
|
112
123
|
/** CVE check results */
|
|
113
124
|
cveCheck: CveCheckResult;
|
|
114
125
|
/** Overall summary */
|
|
@@ -128,10 +139,12 @@ interface VerimuReport {
|
|
|
128
139
|
interface VerimuConfig {
|
|
129
140
|
/** Path to the project to scan */
|
|
130
141
|
projectPath: string;
|
|
131
|
-
/** Where to write the SBOM file (default: ./sbom.cdx.json) */
|
|
142
|
+
/** Where to write the CycloneDX SBOM file (default: ./sbom.cdx.json) */
|
|
132
143
|
sbomOutput?: string;
|
|
133
|
-
/**
|
|
144
|
+
/** Reserved for future per-format selection (currently all formats are generated) */
|
|
134
145
|
sbomFormat?: SbomFormat;
|
|
146
|
+
/** CycloneDX spec version to generate (default: '1.7') */
|
|
147
|
+
cyclonedxVersion?: '1.4' | '1.5' | '1.6' | '1.7';
|
|
135
148
|
/** Minimum severity to report (default: LOW) */
|
|
136
149
|
severityThreshold?: Severity;
|
|
137
150
|
/** Whether to fail CI on vulnerabilities at or above threshold */
|
|
@@ -183,6 +196,32 @@ interface GenerateSbomResult {
|
|
|
183
196
|
/** ISO timestamp of generation */
|
|
184
197
|
generatedAt: string;
|
|
185
198
|
}
|
|
199
|
+
/** Output of the pure `generateSpdxSbom()` function */
|
|
200
|
+
interface GenerateSpdxSbomResult {
|
|
201
|
+
/** The SPDX document as a parsed JavaScript object */
|
|
202
|
+
sbom: Record<string, unknown>;
|
|
203
|
+
/** The SPDX document as a formatted JSON string */
|
|
204
|
+
content: string;
|
|
205
|
+
/** Number of dependency components represented in the document */
|
|
206
|
+
componentCount: number;
|
|
207
|
+
/** SPDX spec version used */
|
|
208
|
+
specVersion: string;
|
|
209
|
+
/** ISO timestamp of generation */
|
|
210
|
+
generatedAt: string;
|
|
211
|
+
}
|
|
212
|
+
/** Output of the pure `generateSwidTag()` function */
|
|
213
|
+
interface GenerateSwidTagResult {
|
|
214
|
+
/** The SWID XML tag */
|
|
215
|
+
tag: string;
|
|
216
|
+
/** Alias of `tag` for consistency with the JSON generators */
|
|
217
|
+
content: string;
|
|
218
|
+
/** Number of components represented in the tag */
|
|
219
|
+
componentCount: number;
|
|
220
|
+
/** SWID spec identifier */
|
|
221
|
+
specVersion: string;
|
|
222
|
+
/** ISO timestamp of generation */
|
|
223
|
+
generatedAt: string;
|
|
224
|
+
}
|
|
186
225
|
|
|
187
226
|
/**
|
|
188
227
|
* Generates an NTIA-compliant CycloneDX 1.7 SBOM from structured dependency data.
|
|
@@ -210,6 +249,21 @@ interface GenerateSbomResult {
|
|
|
210
249
|
*/
|
|
211
250
|
declare function generateSbom(input: GenerateSbomInput): GenerateSbomResult;
|
|
212
251
|
|
|
252
|
+
/**
|
|
253
|
+
* Generates an SPDX 2.3 JSON document from structured dependency data.
|
|
254
|
+
*
|
|
255
|
+
* This is a pure function with no filesystem or network access.
|
|
256
|
+
*/
|
|
257
|
+
declare function generateSpdxSbom(input: GenerateSbomInput): GenerateSpdxSbomResult;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Generates a minimal SWID XML tag for the root software product.
|
|
261
|
+
*
|
|
262
|
+
* This is intentionally minimal for v1. The current tag describes the root
|
|
263
|
+
* product identity and generator metadata only.
|
|
264
|
+
*/
|
|
265
|
+
declare function generateSwidTag(input: GenerateSbomInput): GenerateSwidTagResult;
|
|
266
|
+
|
|
213
267
|
/**
|
|
214
268
|
* Verimu API client — communicates with the Verimu backend.
|
|
215
269
|
*
|
|
@@ -257,6 +311,11 @@ interface ScanResponse {
|
|
|
257
311
|
vulnerable_dependencies: number;
|
|
258
312
|
};
|
|
259
313
|
}
|
|
314
|
+
interface SbomUploadBundle {
|
|
315
|
+
cyclonedx: Record<string, unknown>;
|
|
316
|
+
spdx?: Record<string, unknown>;
|
|
317
|
+
swid?: string;
|
|
318
|
+
}
|
|
260
319
|
declare class VerimuApiClient {
|
|
261
320
|
private readonly baseUrl;
|
|
262
321
|
private readonly apiKey;
|
|
@@ -272,9 +331,13 @@ declare class VerimuApiClient {
|
|
|
272
331
|
platform?: string;
|
|
273
332
|
}): Promise<UpsertProjectResponse>;
|
|
274
333
|
/**
|
|
275
|
-
* Upload a
|
|
334
|
+
* Upload a software inventory artifact payload to a project and trigger CVE scanning.
|
|
335
|
+
*
|
|
336
|
+
* Backward-compatible:
|
|
337
|
+
* - string payloads are treated as legacy raw CycloneDX JSON
|
|
338
|
+
* - object payloads can include CycloneDX + SPDX + SWID together
|
|
276
339
|
*/
|
|
277
|
-
uploadSbom(projectId: string,
|
|
340
|
+
uploadSbom(projectId: string, payload: string | SbomUploadBundle): Promise<ScanResponse>;
|
|
278
341
|
private headers;
|
|
279
342
|
/**
|
|
280
343
|
* Maps internal ecosystem names to what the backend expects.
|
|
@@ -295,7 +358,7 @@ interface UploadResult {
|
|
|
295
358
|
/**
|
|
296
359
|
* Main scan pipeline — orchestrates the full Verimu workflow:
|
|
297
360
|
* 1. Detect ecosystem & parse lockfile
|
|
298
|
-
* 2. Generate CycloneDX
|
|
361
|
+
* 2. Generate software inventory artifacts (CycloneDX + SPDX + SWID)
|
|
299
362
|
* 3. Check dependencies for CVEs (via OSV)
|
|
300
363
|
* 4. Produce report
|
|
301
364
|
* 5. Upload to Verimu platform (if API key provided)
|
|
@@ -305,7 +368,7 @@ declare function scan(config: VerimuConfig): Promise<VerimuReport>;
|
|
|
305
368
|
* Uploads scan results to the Verimu platform.
|
|
306
369
|
*
|
|
307
370
|
* 1. Upserts the project (create-if-not-exists by name)
|
|
308
|
-
* 2. POSTs the
|
|
371
|
+
* 2. POSTs the artifact bundle for dependency tracking + CVE scanning
|
|
309
372
|
*/
|
|
310
373
|
declare function uploadToVerimu(report: VerimuReport, config: VerimuConfig): Promise<UploadResult>;
|
|
311
374
|
/**
|
|
@@ -752,6 +815,316 @@ declare class ComposerScanner implements DependencyScanner {
|
|
|
752
815
|
private buildPurl;
|
|
753
816
|
}
|
|
754
817
|
|
|
818
|
+
/**
|
|
819
|
+
* Yarn dependency scanner.
|
|
820
|
+
*
|
|
821
|
+
* Supports Yarn v1 (Classic) and Yarn v2/v3/v4 (Berry) lockfile formats.
|
|
822
|
+
*
|
|
823
|
+
* - Yarn v1: Plain text format with indentation
|
|
824
|
+
* - Yarn v2+: YAML-based format with __metadata section
|
|
825
|
+
*
|
|
826
|
+
* Parses yarn.lock to extract the full resolved dependency tree.
|
|
827
|
+
* Also reads package.json to determine which dependencies are direct vs transitive.
|
|
828
|
+
*
|
|
829
|
+
* Note: Yarn uses the npm ecosystem since it's an alternative
|
|
830
|
+
* package manager for the npm registry.
|
|
831
|
+
*/
|
|
832
|
+
declare class YarnScanner implements DependencyScanner {
|
|
833
|
+
readonly ecosystem: Ecosystem;
|
|
834
|
+
readonly lockfileNames: string[];
|
|
835
|
+
detect(projectPath: string): Promise<string | null>;
|
|
836
|
+
scan(projectPath: string, lockfilePath: string): Promise<ScanResult>;
|
|
837
|
+
/**
|
|
838
|
+
* Parses yarn.lock file and extracts dependencies.
|
|
839
|
+
* Automatically detects and handles both v1 (Classic) and v2+ (Berry) formats.
|
|
840
|
+
*/
|
|
841
|
+
private parseLockfile;
|
|
842
|
+
/**
|
|
843
|
+
* Detects if the lockfile is Yarn v2+ (Berry) format.
|
|
844
|
+
* v2+ uses YAML format and contains __metadata section.
|
|
845
|
+
*/
|
|
846
|
+
private isYarnV2Plus;
|
|
847
|
+
/**
|
|
848
|
+
* Parses Yarn v2+ (Berry) lockfile format.
|
|
849
|
+
*
|
|
850
|
+
* Yarn v2+ format (YAML):
|
|
851
|
+
* ```yaml
|
|
852
|
+
* __metadata:
|
|
853
|
+
* version: 6
|
|
854
|
+
*
|
|
855
|
+
* "package-name@npm:^1.0.0":
|
|
856
|
+
* version: 1.2.3
|
|
857
|
+
* resolution: "package-name@npm:1.2.3"
|
|
858
|
+
* dependencies:
|
|
859
|
+
* dep1: ^2.0.0
|
|
860
|
+
* checksum: ...
|
|
861
|
+
* languageName: node
|
|
862
|
+
* linkType: hard
|
|
863
|
+
* ```
|
|
864
|
+
*/
|
|
865
|
+
private parseLockfileV2Plus;
|
|
866
|
+
/**
|
|
867
|
+
* Extracts package name from Yarn v2+ resolution field.
|
|
868
|
+
* The resolution field contains the real package name.
|
|
869
|
+
* Examples:
|
|
870
|
+
* "express@npm:4.18.2" → "express"
|
|
871
|
+
* "@types/node@npm:20.11.5" → "@types/node"
|
|
872
|
+
* "lodash@npm:4.17.21" → "lodash"
|
|
873
|
+
*/
|
|
874
|
+
private extractPackageNameFromResolution;
|
|
875
|
+
/**
|
|
876
|
+
* Extracts package name from Yarn v2+ package key.
|
|
877
|
+
* Examples:
|
|
878
|
+
* "express@npm:^4.18.0" → "express"
|
|
879
|
+
* "@types/node@npm:^20.0.0" → "@types/node"
|
|
880
|
+
* "pkg@npm:other@npm:^1.0.0" → "pkg" (aliased packages)
|
|
881
|
+
*/
|
|
882
|
+
private extractPackageNameV2Plus;
|
|
883
|
+
/**
|
|
884
|
+
* Parses Yarn v1 (Classic) lockfile format.
|
|
885
|
+
*
|
|
886
|
+
* Yarn v1 format:
|
|
887
|
+
* ```
|
|
888
|
+
* "package-name@^1.0.0":
|
|
889
|
+
* version "1.2.3"
|
|
890
|
+
* resolved "https://..."
|
|
891
|
+
* integrity sha512-...
|
|
892
|
+
* dependencies:
|
|
893
|
+
* dep1 "^2.0.0"
|
|
894
|
+
* ```
|
|
895
|
+
*/
|
|
896
|
+
private parseLockfileV1;
|
|
897
|
+
/**
|
|
898
|
+
* Adds a dependency to the result list (deduplicates by name@version)
|
|
899
|
+
*/
|
|
900
|
+
private addDependency;
|
|
901
|
+
/**
|
|
902
|
+
* Extracts package name from yarn.lock package declaration.
|
|
903
|
+
* Examples:
|
|
904
|
+
* "express@^4.18.0" → "express"
|
|
905
|
+
* "@types/node@^20.0.0" → "@types/node"
|
|
906
|
+
* "pkg@npm:other@^1.0.0" → "pkg" (aliased packages)
|
|
907
|
+
*/
|
|
908
|
+
private extractPackageName;
|
|
909
|
+
/**
|
|
910
|
+
* Builds a purl (Package URL) for an npm package.
|
|
911
|
+
*
|
|
912
|
+
* Per the purl spec:
|
|
913
|
+
* "The npm scope @ sign prefix is always percent encoded."
|
|
914
|
+
*
|
|
915
|
+
* So @types/node@20.11.5 → pkg:npm/%40types/node@20.11.5
|
|
916
|
+
* And express@4.18.2 → pkg:npm/express@4.18.2
|
|
917
|
+
*/
|
|
918
|
+
private buildPurl;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* pnpm dependency scanner.
|
|
923
|
+
*
|
|
924
|
+
* Parses pnpm-lock.yaml to extract the full resolved dependency tree
|
|
925
|
+
* and determine which dependencies are direct vs transitive.
|
|
926
|
+
*
|
|
927
|
+
* Note: pnpm uses the npm ecosystem since it's an alternative
|
|
928
|
+
* package manager for the npm registry.
|
|
929
|
+
*/
|
|
930
|
+
declare class PnpmScanner implements DependencyScanner {
|
|
931
|
+
readonly ecosystem: Ecosystem;
|
|
932
|
+
readonly lockfileNames: string[];
|
|
933
|
+
detect(projectPath: string): Promise<string | null>;
|
|
934
|
+
scan(projectPath: string, lockfilePath: string): Promise<ScanResult>;
|
|
935
|
+
/**
|
|
936
|
+
* Parses pnpm-lock.yaml file and extracts dependencies.
|
|
937
|
+
*
|
|
938
|
+
* pnpm-lock.yaml format (v5.4+):
|
|
939
|
+
* ```yaml
|
|
940
|
+
* lockfileVersion: 5.4
|
|
941
|
+
*
|
|
942
|
+
* dependencies:
|
|
943
|
+
* express: 4.18.2
|
|
944
|
+
*
|
|
945
|
+
* devDependencies:
|
|
946
|
+
* typescript: 5.0.0
|
|
947
|
+
*
|
|
948
|
+
* packages:
|
|
949
|
+
* /express/4.18.2:
|
|
950
|
+
* resolution: {integrity: sha512-...}
|
|
951
|
+
* dependencies:
|
|
952
|
+
* accepts: 1.3.8
|
|
953
|
+
* /@types/node/20.11.5:
|
|
954
|
+
* resolution: {integrity: sha512-...}
|
|
955
|
+
* dev: true
|
|
956
|
+
* ```
|
|
957
|
+
*
|
|
958
|
+
* pnpm-lock.yaml format (v6.0+):
|
|
959
|
+
* ```yaml
|
|
960
|
+
* lockfileVersion: '6.0'
|
|
961
|
+
*
|
|
962
|
+
* dependencies:
|
|
963
|
+
* express:
|
|
964
|
+
* specifier: ^4.18.0
|
|
965
|
+
* version: 4.18.2
|
|
966
|
+
*
|
|
967
|
+
* packages:
|
|
968
|
+
* /express@4.18.2:
|
|
969
|
+
* resolution: {integrity: sha512-...}
|
|
970
|
+
* ```
|
|
971
|
+
*/
|
|
972
|
+
private parseLockfile;
|
|
973
|
+
/**
|
|
974
|
+
* Extracts direct dependency names from pnpm lockfile.
|
|
975
|
+
*
|
|
976
|
+
* Supports both formats:
|
|
977
|
+
* - pnpm v5.x: root-level dependencies/devDependencies
|
|
978
|
+
* - pnpm v6+: importers['.'].dependencies/devDependencies
|
|
979
|
+
*/
|
|
980
|
+
private extractDirectDependencies;
|
|
981
|
+
/**
|
|
982
|
+
* Parses lockfile version (can be string or number)
|
|
983
|
+
*/
|
|
984
|
+
private parseLockfileVersion;
|
|
985
|
+
/**
|
|
986
|
+
* Extracts dependencies from the lockfile packages section
|
|
987
|
+
*/
|
|
988
|
+
private extractDependencies;
|
|
989
|
+
/**
|
|
990
|
+
* Parses package path to extract name and version.
|
|
991
|
+
*
|
|
992
|
+
* pnpm v5.x format:
|
|
993
|
+
* "/express/4.18.2" → name: "express", version: "4.18.2"
|
|
994
|
+
* "/@types/node/20.11.5" → name: "@types/node", version: "20.11.5"
|
|
995
|
+
* "/accepts/1.3.8" → name: "accepts", version: "1.3.8"
|
|
996
|
+
*
|
|
997
|
+
* pnpm v6+ format:
|
|
998
|
+
* "/express@4.18.2" → name: "express", version: "4.18.2"
|
|
999
|
+
* "/@types/node@20.11.5" → name: "@types/node", version: "20.11.5"
|
|
1000
|
+
* "/accepts@1.3.8" → name: "accepts", version: "1.3.8"
|
|
1001
|
+
*
|
|
1002
|
+
* Also handles peer dependency suffixes:
|
|
1003
|
+
* "/pkg@1.0.0_dep@2.0.0" → name: "pkg", version: "1.0.0"
|
|
1004
|
+
* "/pkg@1.0.0(dep@2.0.0)" → name: "pkg", version: "1.0.0"
|
|
1005
|
+
*/
|
|
1006
|
+
private parsePackagePath;
|
|
1007
|
+
/**
|
|
1008
|
+
* Parses v6+ format: "express@4.18.2" or "@types/node@20.11.5"
|
|
1009
|
+
*/
|
|
1010
|
+
private parseV6Format;
|
|
1011
|
+
/**
|
|
1012
|
+
* Parses v5.x format: "express/4.18.2" or "@types/node/20.11.5"
|
|
1013
|
+
*/
|
|
1014
|
+
private parseV5Format;
|
|
1015
|
+
/**
|
|
1016
|
+
* Builds a purl (Package URL) for an npm package.
|
|
1017
|
+
*
|
|
1018
|
+
* Per the purl spec:
|
|
1019
|
+
* "The npm scope @ sign prefix is always percent encoded."
|
|
1020
|
+
*
|
|
1021
|
+
* So @types/node@20.11.5 → pkg:npm/%40types/node@20.11.5
|
|
1022
|
+
* And express@4.18.2 → pkg:npm/express@4.18.2
|
|
1023
|
+
*/
|
|
1024
|
+
private buildPurl;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
/**
|
|
1028
|
+
* Deno dependency scanner.
|
|
1029
|
+
*
|
|
1030
|
+
* Limitations:
|
|
1031
|
+
* - HTTPS/remote imports (deno.lock `remote` section) are not scanned.
|
|
1032
|
+
* - JSR packages are not directly supported by OSV so vulnerability scan will fail
|
|
1033
|
+
*
|
|
1034
|
+
* deno.lock v4/v5 format:
|
|
1035
|
+
* ```json
|
|
1036
|
+
* {
|
|
1037
|
+
* "version": "4",
|
|
1038
|
+
* "specifiers": {
|
|
1039
|
+
* "jsr:@std/assert@^1.0.0": "1.0.10",
|
|
1040
|
+
* "npm:express@^4.18.0": "4.21.2"
|
|
1041
|
+
* },
|
|
1042
|
+
* "jsr": {
|
|
1043
|
+
* "@std/assert@1.0.10": { "integrity": "..." },
|
|
1044
|
+
* "@std/internal@1.0.6": { "integrity": "..." }
|
|
1045
|
+
* },
|
|
1046
|
+
* "npm": {
|
|
1047
|
+
* "express@4.21.2": { "integrity": "...", "dependencies": {...} }
|
|
1048
|
+
* }
|
|
1049
|
+
* }
|
|
1050
|
+
* ```
|
|
1051
|
+
*
|
|
1052
|
+
* deno.lock v3 format:
|
|
1053
|
+
* ```json
|
|
1054
|
+
* {
|
|
1055
|
+
* "version": "3",
|
|
1056
|
+
* "packages": {
|
|
1057
|
+
* "specifiers": {
|
|
1058
|
+
* "jsr:@std/path@^1.0.0": "jsr:@std/path@1.0.8",
|
|
1059
|
+
* "npm:hono@^4.0.0": "npm:hono@4.6.20"
|
|
1060
|
+
* },
|
|
1061
|
+
* "jsr": {
|
|
1062
|
+
* "@std/path@1.0.8": { "integrity": "..." },
|
|
1063
|
+
* "@std/internal@1.0.6": { "integrity": "..." }
|
|
1064
|
+
* },
|
|
1065
|
+
* "npm": {
|
|
1066
|
+
* "hono@4.6.20": { "integrity": "...", "dependencies": {...} }
|
|
1067
|
+
* }
|
|
1068
|
+
* }
|
|
1069
|
+
* }
|
|
1070
|
+
* ```
|
|
1071
|
+
*/
|
|
1072
|
+
declare class DenoScanner implements DependencyScanner {
|
|
1073
|
+
readonly ecosystem: Ecosystem;
|
|
1074
|
+
readonly lockfileNames: string[];
|
|
1075
|
+
detect(projectPath: string): Promise<string | null>;
|
|
1076
|
+
scan(projectPath: string, lockfilePath: string): Promise<ScanResult>;
|
|
1077
|
+
/**
|
|
1078
|
+
* Parses the lockfile and extracts dependencies from both
|
|
1079
|
+
* npm and jsr package registries.
|
|
1080
|
+
*
|
|
1081
|
+
* Supports v3 (packages nested under `packages`), v4, and v5 (top-level jsr/npm sections).
|
|
1082
|
+
* Uses lockfile specifiers to determine direct vs transitive dependencies.
|
|
1083
|
+
*/
|
|
1084
|
+
private parseLockfile;
|
|
1085
|
+
/**
|
|
1086
|
+
* Extracts direct dependency names from lockfile specifiers.
|
|
1087
|
+
*
|
|
1088
|
+
* Returns a set of ecosystem-qualified package names like "jsr:@std/assert" or "npm:express".
|
|
1089
|
+
* The ecosystem prefix prevents collisions if the same package name exists in both registries.
|
|
1090
|
+
*/
|
|
1091
|
+
private extractDirectDependencies;
|
|
1092
|
+
/**
|
|
1093
|
+
* Parses a package key like "@std/assert@1.0.10" or "express@4.21.2"
|
|
1094
|
+
* into { name, version }.
|
|
1095
|
+
*
|
|
1096
|
+
* Handles scoped packages where the name starts with @ (e.g., @std/assert).
|
|
1097
|
+
* In that case the version separator is the LAST @ sign.
|
|
1098
|
+
*/
|
|
1099
|
+
private parsePackageKey;
|
|
1100
|
+
/**
|
|
1101
|
+
* Extracts the package name from a Deno import specifier.
|
|
1102
|
+
*
|
|
1103
|
+
* Examples:
|
|
1104
|
+
* "jsr:@std/assert@^1.0.0" → "@std/assert"
|
|
1105
|
+
* "npm:express@^4.18.0" → "express"
|
|
1106
|
+
* "npm:@hono/hono@^4.0.0" → "@hono/hono"
|
|
1107
|
+
* "lodash" (bare) → "lodash"
|
|
1108
|
+
*/
|
|
1109
|
+
private extractNameFromSpecifier;
|
|
1110
|
+
/**
|
|
1111
|
+
* Builds a purl for a JSR package.
|
|
1112
|
+
*
|
|
1113
|
+
* JSR packages use the "jsr" purl type (non-standard but descriptive).
|
|
1114
|
+
* For scoped packages, both @ and all / characters are percent-encoded.
|
|
1115
|
+
* Example: `pkg:jsr/%40std%2Fassert@1.0.10`
|
|
1116
|
+
*/
|
|
1117
|
+
private buildJsrPurl;
|
|
1118
|
+
/**
|
|
1119
|
+
* Builds a purl for an npm package used via Deno.
|
|
1120
|
+
*
|
|
1121
|
+
* Uses the standard npm purl type since these are npm packages.
|
|
1122
|
+
* Per npm purl spec, only @ is encoded, / remains as namespace separator.
|
|
1123
|
+
* Example: `pkg:npm/%40std/assert@1.0.10` or `pkg:npm/express@4.21.2`
|
|
1124
|
+
*/
|
|
1125
|
+
private buildNpmPurl;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
755
1128
|
/**
|
|
756
1129
|
* Registry of all available dependency scanners.
|
|
757
1130
|
* Auto-detects the correct scanner for a given project.
|
|
@@ -781,34 +1154,32 @@ interface SbomGenerator {
|
|
|
781
1154
|
generate(scanResult: ScanResult, toolVersion?: string): Sbom;
|
|
782
1155
|
}
|
|
783
1156
|
|
|
1157
|
+
/** Supported CycloneDX spec versions */
|
|
1158
|
+
type CycloneDxSpecVersion = '1.4' | '1.5' | '1.6' | '1.7';
|
|
784
1159
|
/**
|
|
785
|
-
* Generates CycloneDX 1.
|
|
1160
|
+
* Generates CycloneDX JSON SBOMs (versions 1.4 – 1.7).
|
|
786
1161
|
*
|
|
787
1162
|
* CycloneDX is the preferred SBOM format for CRA compliance.
|
|
788
|
-
* Spec: https://cyclonedx.org/
|
|
1163
|
+
* Spec: https://cyclonedx.org/specification/overview/
|
|
789
1164
|
*
|
|
790
1165
|
* NTIA minimum elements are satisfied:
|
|
791
1166
|
* - metadata.supplier (supplier of the root software)
|
|
792
1167
|
* - components[].supplier (supplier of each dependency)
|
|
793
1168
|
* - components[].name, version, purl, bom-ref
|
|
794
1169
|
* - dependencies[] graph
|
|
1170
|
+
*
|
|
1171
|
+
* Schema differences handled per version:
|
|
1172
|
+
* - 1.4: metadata.tools is a flat array of { vendor, name, version, ... }
|
|
1173
|
+
* - 1.5+: metadata.tools is { components: [...] }
|
|
795
1174
|
*/
|
|
796
1175
|
declare class CycloneDxGenerator implements SbomGenerator {
|
|
1176
|
+
private readonly specVersion;
|
|
797
1177
|
readonly format: SbomFormat;
|
|
1178
|
+
constructor(specVersion?: CycloneDxSpecVersion);
|
|
798
1179
|
generate(scanResult: ScanResult, toolVersion?: string): Sbom;
|
|
799
1180
|
private buildBom;
|
|
800
1181
|
/** Converts a Verimu Dependency to a CycloneDX component */
|
|
801
1182
|
private toComponent;
|
|
802
|
-
/**
|
|
803
|
-
* Derives a supplier name from a package name.
|
|
804
|
-
*
|
|
805
|
-
* For scoped packages like "@vue/reactivity" → "@vue"
|
|
806
|
-
* For unscoped packages like "express" → "express"
|
|
807
|
-
*
|
|
808
|
-
* This is the same heuristic used by Syft, Trivy, and other SBOM tools
|
|
809
|
-
* when registry metadata (author/publisher) isn't available from the lockfile.
|
|
810
|
-
*/
|
|
811
|
-
private deriveSupplierName;
|
|
812
1183
|
/**
|
|
813
1184
|
* Builds the dependency graph section of the SBOM.
|
|
814
1185
|
*
|
|
@@ -821,8 +1192,28 @@ declare class CycloneDxGenerator implements SbomGenerator {
|
|
|
821
1192
|
* dependency relationship.
|
|
822
1193
|
*/
|
|
823
1194
|
private buildDependencyGraph;
|
|
824
|
-
/**
|
|
825
|
-
|
|
1195
|
+
/**
|
|
1196
|
+
* Builds the tools metadata section.
|
|
1197
|
+
*
|
|
1198
|
+
* CycloneDX 1.4: tools is a flat array of { vendor, name, version, ... }
|
|
1199
|
+
* CycloneDX 1.5+: tools is an object { components: [...] }
|
|
1200
|
+
*/
|
|
1201
|
+
private buildTools;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
/** Generates every supported software inventory artifact for a scan. */
|
|
1205
|
+
declare function generateSbomArtifacts(scanResult: ScanResult, toolVersion?: string, cyclonedxVersion?: CycloneDxSpecVersion): SbomArtifacts;
|
|
1206
|
+
|
|
1207
|
+
/** Generates SPDX 2.3 JSON SBOMs. */
|
|
1208
|
+
declare class SpdxJsonGenerator implements SbomGenerator {
|
|
1209
|
+
readonly format: SbomFormat;
|
|
1210
|
+
generate(scanResult: ScanResult, toolVersion?: string): Sbom;
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
/** Generates a minimal SWID XML tag for the root software product. */
|
|
1214
|
+
declare class SwidTagGenerator implements SbomGenerator {
|
|
1215
|
+
readonly format: SbomFormat;
|
|
1216
|
+
generate(scanResult: ScanResult, toolVersion?: string): Sbom;
|
|
826
1217
|
}
|
|
827
1218
|
|
|
828
1219
|
/**
|
|
@@ -930,4 +1321,4 @@ declare class ConsoleReporter implements Reporter {
|
|
|
930
1321
|
report(result: VerimuReport): string;
|
|
931
1322
|
}
|
|
932
1323
|
|
|
933
|
-
export { ApiKeyRequiredError, CargoScanner, type CiProvider, ComposerScanner, ConsoleReporter, CveAggregator, type CveCheckResult, CveSourceError, CycloneDxGenerator, type Dependency, type Ecosystem, type GenerateSbomInput, type GenerateSbomResult, GoScanner, LockfileParseError, MavenScanner, NoLockfileError, NpmScanner, NugetScanner, OsvSource, PipScanner, RubyScanner, type Sbom, type SbomDependency, type SbomFormat, type ScanResult, ScannerRegistry, type Severity, type UploadResult, VerimuApiClient, type VerimuConfig, VerimuError, type VerimuReport, type Vulnerability, type VulnerabilitySource, generateSbom, printReport, scan, shouldFailCi, uploadToVerimu };
|
|
1324
|
+
export { ApiKeyRequiredError, CargoScanner, type CiProvider, ComposerScanner, ConsoleReporter, CveAggregator, type CveCheckResult, CveSourceError, CycloneDxGenerator, DenoScanner, type Dependency, type Ecosystem, type GenerateSbomInput, type GenerateSbomResult, type GenerateSpdxSbomResult, type GenerateSwidTagResult, GoScanner, LockfileParseError, MavenScanner, NoLockfileError, NpmScanner, NugetScanner, OsvSource, PipScanner, PnpmScanner, RubyScanner, type Sbom, type SbomArtifacts, type SbomDependency, type SbomFormat, type ScanResult, ScannerRegistry, type Severity, SpdxJsonGenerator, SwidTagGenerator, type UploadResult, VerimuApiClient, type VerimuConfig, VerimuError, type VerimuReport, type Vulnerability, type VulnerabilitySource, YarnScanner, generateSbom, generateSbomArtifacts, generateSpdxSbom, generateSwidTag, printReport, scan, shouldFailCi, uploadToVerimu };
|