@xenos1996/usa 2.27.0 → 2.28.1
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 +3 -3
- package/dist/cli-help.d.ts.map +1 -1
- package/dist/cli-help.js +13 -0
- package/dist/cli-help.js.map +1 -1
- package/dist/cli-intent.d.ts +4 -0
- package/dist/cli-intent.d.ts.map +1 -0
- package/dist/cli-intent.js +108 -0
- package/dist/cli-intent.js.map +1 -0
- package/dist/cli-scan.d.ts +12 -0
- package/dist/cli-scan.d.ts.map +1 -0
- package/dist/cli-scan.js +142 -0
- package/dist/cli-scan.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -1
- package/dist/engine/evaluate.d.ts.map +1 -1
- package/dist/engine/evaluate.js +31 -8
- package/dist/engine/evaluate.js.map +1 -1
- package/dist/intent/match.d.ts +38 -0
- package/dist/intent/match.d.ts.map +1 -0
- package/dist/intent/match.js +108 -0
- package/dist/intent/match.js.map +1 -0
- package/dist/intent/otm.d.ts +16 -0
- package/dist/intent/otm.d.ts.map +1 -0
- package/dist/intent/otm.js +144 -0
- package/dist/intent/otm.js.map +1 -0
- package/dist/intent/types.d.ts +111 -0
- package/dist/intent/types.d.ts.map +1 -0
- package/dist/intent/types.js +16 -0
- package/dist/intent/types.js.map +1 -0
- package/dist/scanner/adapters/codeql.d.ts +14 -0
- package/dist/scanner/adapters/codeql.d.ts.map +1 -0
- package/dist/scanner/adapters/codeql.js +134 -0
- package/dist/scanner/adapters/codeql.js.map +1 -0
- package/dist/scanner/adapters/dependency-cruiser.d.ts +3 -0
- package/dist/scanner/adapters/dependency-cruiser.d.ts.map +1 -0
- package/dist/scanner/adapters/dependency-cruiser.js +195 -0
- package/dist/scanner/adapters/dependency-cruiser.js.map +1 -0
- package/dist/scanner/adapters/ort.d.ts +12 -0
- package/dist/scanner/adapters/ort.d.ts.map +1 -0
- package/dist/scanner/adapters/ort.js +259 -0
- package/dist/scanner/adapters/ort.js.map +1 -0
- package/dist/scanner/adapters/scorecard.d.ts +7 -0
- package/dist/scanner/adapters/scorecard.d.ts.map +1 -0
- package/dist/scanner/adapters/scorecard.js +209 -0
- package/dist/scanner/adapters/scorecard.js.map +1 -0
- package/dist/scanner/adapters/semgrep.d.ts +3 -0
- package/dist/scanner/adapters/semgrep.d.ts.map +1 -0
- package/dist/scanner/adapters/semgrep.js +163 -0
- package/dist/scanner/adapters/semgrep.js.map +1 -0
- package/dist/scanner/adapters/trivy.d.ts +3 -0
- package/dist/scanner/adapters/trivy.d.ts.map +1 -0
- package/dist/scanner/adapters/trivy.js +163 -0
- package/dist/scanner/adapters/trivy.js.map +1 -0
- package/dist/scanner/config.d.ts +4 -0
- package/dist/scanner/config.d.ts.map +1 -0
- package/dist/scanner/config.js +15 -0
- package/dist/scanner/config.js.map +1 -0
- package/dist/scanner/identity.d.ts +17 -0
- package/dist/scanner/identity.d.ts.map +1 -0
- package/dist/scanner/identity.js +50 -0
- package/dist/scanner/identity.js.map +1 -0
- package/dist/scanner/normalize.d.ts +40 -0
- package/dist/scanner/normalize.d.ts.map +1 -0
- package/dist/scanner/normalize.js +85 -0
- package/dist/scanner/normalize.js.map +1 -0
- package/dist/scanner/registry.d.ts +19 -0
- package/dist/scanner/registry.d.ts.map +1 -0
- package/dist/scanner/registry.js +43 -0
- package/dist/scanner/registry.js.map +1 -0
- package/dist/scanner/run.d.ts +71 -0
- package/dist/scanner/run.d.ts.map +1 -0
- package/dist/scanner/run.js +461 -0
- package/dist/scanner/run.js.map +1 -0
- package/dist/scanner/sarif.d.ts +21 -0
- package/dist/scanner/sarif.d.ts.map +1 -0
- package/dist/scanner/sarif.js +156 -0
- package/dist/scanner/sarif.js.map +1 -0
- package/dist/scanner/types.d.ts +242 -0
- package/dist/scanner/types.d.ts.map +1 -0
- package/dist/scanner/types.js +11 -0
- package/dist/scanner/types.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content-addressed ids for evidence and findings.
|
|
3
|
+
*
|
|
4
|
+
* Ids are a hash over the fields that make a claim *the same claim*: the tool
|
|
5
|
+
* that made it, its native category and identifier, the location, and the claim
|
|
6
|
+
* text. Timestamps and execution ids are deliberately excluded, so the same
|
|
7
|
+
* observation made in two runs, or by two adapters, shares one id. That is what
|
|
8
|
+
* makes deduplication and two-run trending work without similarity heuristics.
|
|
9
|
+
*/
|
|
10
|
+
import { createHash } from 'node:crypto';
|
|
11
|
+
/** Short, stable, non-reversible id. Collisions are theoretical at 20 hex chars. */
|
|
12
|
+
function hash(parts) {
|
|
13
|
+
const h = createHash('sha256');
|
|
14
|
+
for (const p of parts)
|
|
15
|
+
h.update(`${p ?? ''}\u0000`);
|
|
16
|
+
return h.digest('hex').slice(0, 20);
|
|
17
|
+
}
|
|
18
|
+
export function evidenceId(source, location, claim) {
|
|
19
|
+
return hash([
|
|
20
|
+
'evidence-v1',
|
|
21
|
+
source.tool,
|
|
22
|
+
source.kind,
|
|
23
|
+
source.identifier,
|
|
24
|
+
location?.file,
|
|
25
|
+
location?.line,
|
|
26
|
+
claim,
|
|
27
|
+
]);
|
|
28
|
+
}
|
|
29
|
+
export function buildEvidence(args) {
|
|
30
|
+
const source = {
|
|
31
|
+
tool: args.source.tool,
|
|
32
|
+
version: args.source.version ?? 'unknown',
|
|
33
|
+
kind: args.source.kind,
|
|
34
|
+
identifier: args.source.identifier,
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
id: evidenceId(source, args.location, args.claim),
|
|
38
|
+
source,
|
|
39
|
+
provenance: args.provenance,
|
|
40
|
+
claim: args.claim,
|
|
41
|
+
severity: args.severity,
|
|
42
|
+
severitySource: args.severitySource ?? 'tool-native',
|
|
43
|
+
confidence: args.confidence,
|
|
44
|
+
status: args.status,
|
|
45
|
+
location: args.location,
|
|
46
|
+
rawReference: args.rawReference ?? {},
|
|
47
|
+
...(args.cwes && args.cwes.length > 0 ? { cwes: args.cwes } : {}),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/scanner/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,oFAAoF;AACpF,SAAS,IAAI,CAAC,KAA6C;IACzD,MAAM,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACpD,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,MAAsB,EACtB,QAAiC,EACjC,KAAa;IAEb,OAAO,IAAI,CAAC;QACV,aAAa;QACb,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,UAAU;QACjB,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,IAAI;QACd,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAW7B;IACC,MAAM,MAAM,GAAmB;QAC7B,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;QACtB,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,SAAS;QACzC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;QACtB,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU;KACnC,CAAC;IACF,OAAO;QACL,EAAE,EAAE,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC;QACjD,MAAM;QACN,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,aAAa;QACpD,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,EAAE;QACrC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Evidence, ScannerSeverity } from './types.js';
|
|
2
|
+
/** The tool's severity word, quoted. Unknown words degrade to LOW. */
|
|
3
|
+
export declare function severity(word: unknown): ScannerSeverity;
|
|
4
|
+
/** Confidence for deterministic facts; a param, not a guess, everywhere else. */
|
|
5
|
+
export declare const DETERMINISTIC_CONFIDENCE = 1;
|
|
6
|
+
export interface UnknownOptions {
|
|
7
|
+
adapterId: string;
|
|
8
|
+
adapterVersion: string;
|
|
9
|
+
reason: string;
|
|
10
|
+
/** Where the failure was detected. */
|
|
11
|
+
location?: Evidence['location'];
|
|
12
|
+
}
|
|
13
|
+
/** An evidence row that says "this tool could not tell us". */
|
|
14
|
+
export declare function unknownEvidence(o: UnknownOptions): Evidence;
|
|
15
|
+
/** Parse a payload once; a malformed one is UNKNOWN, never an exception. */
|
|
16
|
+
export declare function tryParseJson(raw: string): {
|
|
17
|
+
ok: true;
|
|
18
|
+
value: unknown;
|
|
19
|
+
} | {
|
|
20
|
+
ok: false;
|
|
21
|
+
error: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Read a nested key defensively: an absent path yields `undefined`, never
|
|
25
|
+
* throws. Array indices are accepted as numbers so callers can write
|
|
26
|
+
* `dig(x, ['locations', 0])` without stringifying.
|
|
27
|
+
*/
|
|
28
|
+
export declare function dig(obj: unknown, path: (string | number)[]): unknown;
|
|
29
|
+
/**
|
|
30
|
+
* Make a tool-reported path relative to the scanned root.
|
|
31
|
+
*
|
|
32
|
+
* Tools report absolute paths when handed an absolute target, and the scanner
|
|
33
|
+
* runner always runs in a scratch copy — so an unnormalised location points at
|
|
34
|
+
* a temp directory that will not exist when the evidence is read. A path that
|
|
35
|
+
* is already relative, or outside the root, is left alone.
|
|
36
|
+
*/
|
|
37
|
+
export declare function relativePath(root: string, file: string): string;
|
|
38
|
+
/** A line number, only when the source actually gave one. */
|
|
39
|
+
export declare function lineNumber(value: unknown): number | undefined;
|
|
40
|
+
//# sourceMappingURL=normalize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/scanner/normalize.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAI5D,sEAAsE;AACtE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,eAAe,CAGvD;AAED,iFAAiF;AACjF,eAAO,MAAM,wBAAwB,IAAM,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,QAAQ,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;CACjC;AAED,+DAA+D;AAC/D,wBAAgB,eAAe,CAAC,CAAC,EAAE,cAAc,GAAG,QAAQ,CAsB3D;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAC1B,GAAG,EAAE,MAAM,GACV;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAM7D;AAED;;;;GAIG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,OAAO,CAQpE;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAI/D;AAED,6DAA6D;AAC7D,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAG7D"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool output → Evidence.
|
|
3
|
+
*
|
|
4
|
+
* Only adapters import this. The functions are total: unknown severity words
|
|
5
|
+
* become `LOW` (never dropped), missing locations become `null` (never
|
|
6
|
+
* invented), and an unparseable payload yields `UNKNOWN` evidence rather than a
|
|
7
|
+
* thrown error — a scanner that breaks must blind the audit, not fail it.
|
|
8
|
+
*/
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
const KNOWN = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'INFO', 'UNKNOWN'];
|
|
11
|
+
/** The tool's severity word, quoted. Unknown words degrade to LOW. */
|
|
12
|
+
export function severity(word) {
|
|
13
|
+
const w = String(word ?? '').toUpperCase();
|
|
14
|
+
return KNOWN.includes(w) ? w : 'LOW';
|
|
15
|
+
}
|
|
16
|
+
/** Confidence for deterministic facts; a param, not a guess, everywhere else. */
|
|
17
|
+
export const DETERMINISTIC_CONFIDENCE = 1.0;
|
|
18
|
+
/** An evidence row that says "this tool could not tell us". */
|
|
19
|
+
export function unknownEvidence(o) {
|
|
20
|
+
return {
|
|
21
|
+
id: `UNKNOWN-${o.adapterId}-${o.reason}`.replace(/\s+/g, '-').slice(0, 40),
|
|
22
|
+
source: { tool: o.adapterId, version: o.adapterVersion, kind: 'check', identifier: 'UNKNOWN' },
|
|
23
|
+
provenance: {
|
|
24
|
+
executionId: 'unknown',
|
|
25
|
+
command: [],
|
|
26
|
+
config: {},
|
|
27
|
+
repositoryRevision: 'unknown',
|
|
28
|
+
timestamp: '',
|
|
29
|
+
executable: '',
|
|
30
|
+
timeoutMs: 0,
|
|
31
|
+
elapsedMs: 0,
|
|
32
|
+
},
|
|
33
|
+
claim: o.reason,
|
|
34
|
+
severity: 'INFO',
|
|
35
|
+
severitySource: 'adapter-default',
|
|
36
|
+
confidence: DETERMINISTIC_CONFIDENCE,
|
|
37
|
+
status: 'UNKNOWN',
|
|
38
|
+
location: o.location ?? null,
|
|
39
|
+
rawReference: {},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** Parse a payload once; a malformed one is UNKNOWN, never an exception. */
|
|
43
|
+
export function tryParseJson(raw) {
|
|
44
|
+
try {
|
|
45
|
+
return { ok: true, value: JSON.parse(raw) };
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
return { ok: false, error: err.message };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Read a nested key defensively: an absent path yields `undefined`, never
|
|
53
|
+
* throws. Array indices are accepted as numbers so callers can write
|
|
54
|
+
* `dig(x, ['locations', 0])` without stringifying.
|
|
55
|
+
*/
|
|
56
|
+
export function dig(obj, path) {
|
|
57
|
+
let node = obj;
|
|
58
|
+
for (const key of path) {
|
|
59
|
+
const k = String(key);
|
|
60
|
+
if (typeof node !== 'object' || node === null || !(k in node))
|
|
61
|
+
return undefined;
|
|
62
|
+
node = node[k];
|
|
63
|
+
}
|
|
64
|
+
return node;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Make a tool-reported path relative to the scanned root.
|
|
68
|
+
*
|
|
69
|
+
* Tools report absolute paths when handed an absolute target, and the scanner
|
|
70
|
+
* runner always runs in a scratch copy — so an unnormalised location points at
|
|
71
|
+
* a temp directory that will not exist when the evidence is read. A path that
|
|
72
|
+
* is already relative, or outside the root, is left alone.
|
|
73
|
+
*/
|
|
74
|
+
export function relativePath(root, file) {
|
|
75
|
+
if (!path.isAbsolute(file))
|
|
76
|
+
return file;
|
|
77
|
+
const rel = path.relative(root, file);
|
|
78
|
+
return rel.startsWith('..') || path.isAbsolute(rel) ? file : rel;
|
|
79
|
+
}
|
|
80
|
+
/** A line number, only when the source actually gave one. */
|
|
81
|
+
export function lineNumber(value) {
|
|
82
|
+
const n = Number(value);
|
|
83
|
+
return Number.isFinite(n) && n > 0 ? Math.floor(n) : undefined;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=normalize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/scanner/normalize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ScannerAdapter } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Every registered adapter. Tier 1 first (cheap, local), then Tier 2.
|
|
4
|
+
* Adding an adapter means appending here — nothing else in the system changes.
|
|
5
|
+
*/
|
|
6
|
+
export declare const scanners: ScannerAdapter[];
|
|
7
|
+
/**
|
|
8
|
+
* Default-disabled adapters, and why:
|
|
9
|
+
* - codeql needs a database build and hundreds of MB of disk.
|
|
10
|
+
* - ort needs a JVM and a full dependency resolution per package manager.
|
|
11
|
+
* - scorecard is enabled in its default `local` mode (offline, file-based);
|
|
12
|
+
* `mode: repo` opts into network and a token.
|
|
13
|
+
*/
|
|
14
|
+
export declare const DEFAULT_DISABLED: ReadonlySet<string>;
|
|
15
|
+
export declare function enabledAdapters(config: Record<string, {
|
|
16
|
+
enabled?: boolean;
|
|
17
|
+
}> | undefined): ScannerAdapter[];
|
|
18
|
+
export declare function byId(id: string): ScannerAdapter | undefined;
|
|
19
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/scanner/registry.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,cAAc,EAOpC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAA8B,CAAC;AAEhF,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GAAG,SAAS,GACxD,cAAc,EAAE,CAKlB;AAED,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE3D"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry — the only place that knows which adapters exist.
|
|
3
|
+
*
|
|
4
|
+
* Adding an adapter must not require touching the runner, the CLI, or the rule
|
|
5
|
+
* packs; appending to this list is the whole integration.
|
|
6
|
+
*/
|
|
7
|
+
import { trivyAdapter } from './adapters/trivy.js';
|
|
8
|
+
import { dependencyCruiserAdapter } from './adapters/dependency-cruiser.js';
|
|
9
|
+
import { semgrepAdapter } from './adapters/semgrep.js';
|
|
10
|
+
import { codeqlAdapter } from './adapters/codeql.js';
|
|
11
|
+
import { scorecardAdapter } from './adapters/scorecard.js';
|
|
12
|
+
import { ortAdapter } from './adapters/ort.js';
|
|
13
|
+
/**
|
|
14
|
+
* Every registered adapter. Tier 1 first (cheap, local), then Tier 2.
|
|
15
|
+
* Adding an adapter means appending here — nothing else in the system changes.
|
|
16
|
+
*/
|
|
17
|
+
export const scanners = [
|
|
18
|
+
trivyAdapter,
|
|
19
|
+
dependencyCruiserAdapter,
|
|
20
|
+
semgrepAdapter,
|
|
21
|
+
codeqlAdapter,
|
|
22
|
+
scorecardAdapter,
|
|
23
|
+
ortAdapter,
|
|
24
|
+
];
|
|
25
|
+
/**
|
|
26
|
+
* Default-disabled adapters, and why:
|
|
27
|
+
* - codeql needs a database build and hundreds of MB of disk.
|
|
28
|
+
* - ort needs a JVM and a full dependency resolution per package manager.
|
|
29
|
+
* - scorecard is enabled in its default `local` mode (offline, file-based);
|
|
30
|
+
* `mode: repo` opts into network and a token.
|
|
31
|
+
*/
|
|
32
|
+
export const DEFAULT_DISABLED = new Set(['codeql', 'ort']);
|
|
33
|
+
export function enabledAdapters(config) {
|
|
34
|
+
return scanners.filter((a) => {
|
|
35
|
+
if (config && typeof config[a.id]?.enabled === 'boolean')
|
|
36
|
+
return config[a.id].enabled;
|
|
37
|
+
return !DEFAULT_DISABLED.has(a.id);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
export function byId(id) {
|
|
41
|
+
return scanners.find((a) => a.id === id);
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/scanner/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG/C;;;GAGG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAqB;IACxC,YAAY;IACZ,wBAAwB;IACxB,cAAc;IACd,aAAa;IACb,gBAAgB;IAChB,UAAU;CACX,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAwB,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;AAEhF,MAAM,UAAU,eAAe,CAC7B,MAAyD;IAEzD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3B,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,CAAE,CAAC,OAAQ,CAAC;QACxF,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,EAAU;IAC7B,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { ScanOptions, ScanResult, ScannerAdapter, ScannerCommand, AdapterRun, ScanTarget } from './types.js';
|
|
2
|
+
export declare const DEFAULT_TIMEOUT_MS = 300000;
|
|
3
|
+
export declare const OUTPUT_CAP_BYTES: number;
|
|
4
|
+
/**
|
|
5
|
+
* The environment a scanner child inherits: an allow-list, then a deny-list
|
|
6
|
+
* applied over it. A scanner gets PATH and TMPDIR and nothing that carries a
|
|
7
|
+
* credential — that is the whole point of the deny list existing.
|
|
8
|
+
*/
|
|
9
|
+
export declare function childEnv(allow: string[], prependToPath?: string[]): NodeJS.ProcessEnv;
|
|
10
|
+
export declare class ScannerRunner {
|
|
11
|
+
private readonly adapters;
|
|
12
|
+
constructor(adapters: ScannerAdapter[]);
|
|
13
|
+
/**
|
|
14
|
+
* Run the selected adapters and return the manifest plus what they found.
|
|
15
|
+
* `options.adapters` filters the registry; an unknown id is a loud error
|
|
16
|
+
* rather than an empty run, because "0 evidence" must never be mistaken for
|
|
17
|
+
* "nothing wrong".
|
|
18
|
+
*/
|
|
19
|
+
run(options: ScanOptions): ScanResult;
|
|
20
|
+
private select;
|
|
21
|
+
private runAdapter;
|
|
22
|
+
}
|
|
23
|
+
type ArtifactRead = {
|
|
24
|
+
ok: true;
|
|
25
|
+
path: string;
|
|
26
|
+
content: string;
|
|
27
|
+
} | {
|
|
28
|
+
ok: false;
|
|
29
|
+
reason: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Run the stages a pipeline tool needs before its evidence command.
|
|
33
|
+
*
|
|
34
|
+
* A prepare stage produces no payload to judge, so its exit status is the only
|
|
35
|
+
* signal it has. Using it to *stop* is not a verdict about the project — the
|
|
36
|
+
* adapter is reported as a blind spot, never as a finding.
|
|
37
|
+
*/
|
|
38
|
+
export declare function runPrepare(adapter: ScannerAdapter, target: ScanTarget, command: ScannerCommand, version: string, timeoutMs: number): {
|
|
39
|
+
prepared: string[][];
|
|
40
|
+
} | {
|
|
41
|
+
manifest: AdapterRun;
|
|
42
|
+
};
|
|
43
|
+
/** The bytes to parse: the declared artifact if the tool writes one, else stdout. */
|
|
44
|
+
export declare function resolveOutput(spawn: SpawnSuccess, command: ScannerCommand, workdir: string): {
|
|
45
|
+
ok: true;
|
|
46
|
+
raw: string;
|
|
47
|
+
artifact?: string;
|
|
48
|
+
} | {
|
|
49
|
+
ok: false;
|
|
50
|
+
reason: string;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Read the first declared artifact that exists.
|
|
54
|
+
*
|
|
55
|
+
* A declared artifact that is missing is an `error` with a reason, never an
|
|
56
|
+
* empty result: "the tool produced no file" and "the policy passed" are
|
|
57
|
+
* different sentences and only one of them is usually true.
|
|
58
|
+
*/
|
|
59
|
+
export declare function readArtifact(workdir: string, declared: string[]): ArtifactRead;
|
|
60
|
+
type SpawnSuccess = {
|
|
61
|
+
stdout: string;
|
|
62
|
+
stderr: string;
|
|
63
|
+
exitCode: number;
|
|
64
|
+
elapsedMs: number;
|
|
65
|
+
startedAt: number;
|
|
66
|
+
};
|
|
67
|
+
export declare function copyTreeForScan(from: string, into: string): void;
|
|
68
|
+
/** The commit the checkout points at, or `unversioned` — never blank. */
|
|
69
|
+
export declare function detectRevision(dir: string): string;
|
|
70
|
+
export {};
|
|
71
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/scanner/run.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,cAAc,EAEd,cAAc,EAKd,UAAU,EACV,UAAU,EACX,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAC1C,eAAO,MAAM,gBAAgB,QAAmB,CAAC;AAmBjD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,aAAa,GAAE,MAAM,EAAO,GAAG,MAAM,CAAC,UAAU,CAWzF;AAED,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,cAAc,EAAE;IAEvD;;;;;OAKG;IACH,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU;IAmDrC,OAAO,CAAC,MAAM;IAUd,OAAO,CAAC,UAAU;CAyFnB;AA+DD,KAAK,YAAY,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhG;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB;IAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,UAAU,CAAA;CAAE,CA6BrD;AAED,qFAAqF;AACrF,wBAAgB,aAAa,CAC3B,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,MAAM,GACd;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAO9E;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,YAAY,CAuB9E;AA0CD,KAAK,YAAY,GAAG;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AA6EF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAehE;AAED,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAelD"}
|