trawly 0.0.1 → 0.1.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 +124 -20
- package/dist/cli.js +3122 -583
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +202 -8
- package/dist/index.js +2123 -118
- package/dist/index.js.map +1 -1
- package/package.json +11 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,30 +1,48 @@
|
|
|
1
1
|
type Severity = "critical" | "high" | "moderate" | "low" | "unknown";
|
|
2
|
-
type Ecosystem =
|
|
3
|
-
type FindingType = "vulnerability" | "malware" | "risk-signal" | "integrity";
|
|
2
|
+
type Ecosystem = string;
|
|
3
|
+
type FindingType = "vulnerability" | "malware" | "secret" | "risk-signal" | "integrity";
|
|
4
|
+
type FindingSource = "osv" | "trawly";
|
|
5
|
+
type InputKind = "lockfile" | "sbom" | "adhoc";
|
|
4
6
|
declare const SEVERITY_RANK: Record<Severity, number>;
|
|
5
7
|
interface PackageInstance {
|
|
6
8
|
name: string;
|
|
7
9
|
version: string;
|
|
8
10
|
ecosystem: Ecosystem;
|
|
9
|
-
/** Path within the
|
|
11
|
+
/** Path within the source manifest, e.g. "node_modules/foo" or an SBOM ref. */
|
|
10
12
|
path: string;
|
|
11
13
|
direct: boolean;
|
|
12
14
|
dev: boolean;
|
|
13
15
|
optional: boolean;
|
|
16
|
+
inputKind?: InputKind;
|
|
17
|
+
purl?: string;
|
|
18
|
+
sourceFile?: string;
|
|
19
|
+
line?: number;
|
|
20
|
+
manager?: "npm" | "pnpm" | "yarn" | "sbom" | string;
|
|
14
21
|
resolved?: string;
|
|
15
22
|
integrity?: string;
|
|
23
|
+
registry?: string;
|
|
24
|
+
hasInstallScript?: boolean;
|
|
25
|
+
publishedAt?: string;
|
|
26
|
+
packagePublishedAt?: string;
|
|
16
27
|
}
|
|
17
28
|
interface Finding {
|
|
18
29
|
id: string;
|
|
19
|
-
source:
|
|
30
|
+
source: FindingSource;
|
|
20
31
|
type: FindingType;
|
|
21
32
|
severity: Severity;
|
|
33
|
+
ecosystem: Ecosystem;
|
|
22
34
|
packageName: string;
|
|
23
35
|
installedVersion: string;
|
|
24
36
|
summary: string;
|
|
25
37
|
url?: string;
|
|
26
38
|
fixedVersions: string[];
|
|
27
39
|
affectedPaths: string[];
|
|
40
|
+
fingerprint: string;
|
|
41
|
+
aliases: string[];
|
|
42
|
+
sourceFile?: string;
|
|
43
|
+
line?: number;
|
|
44
|
+
ignored?: boolean;
|
|
45
|
+
baseline?: "new" | "existing";
|
|
28
46
|
}
|
|
29
47
|
interface ScanError {
|
|
30
48
|
message: string;
|
|
@@ -34,24 +52,75 @@ interface ScanResult {
|
|
|
34
52
|
scannedAt: string;
|
|
35
53
|
packagesScanned: number;
|
|
36
54
|
findings: Finding[];
|
|
55
|
+
ignoredFindings: Finding[];
|
|
37
56
|
summary: Record<Severity, number>;
|
|
38
57
|
errors: ScanError[];
|
|
58
|
+
warnings: string[];
|
|
59
|
+
baseline?: BaselineResult;
|
|
60
|
+
}
|
|
61
|
+
interface IgnoreEntry {
|
|
62
|
+
id: string;
|
|
63
|
+
package?: string;
|
|
64
|
+
ecosystem?: string;
|
|
65
|
+
version?: string;
|
|
66
|
+
expires: string;
|
|
67
|
+
reason: string;
|
|
68
|
+
}
|
|
69
|
+
interface TrawlyConfig {
|
|
70
|
+
failOn?: FailOnLevel;
|
|
71
|
+
policy?: PolicyPresetName;
|
|
72
|
+
risk?: boolean;
|
|
73
|
+
env?: boolean;
|
|
74
|
+
allowedRegistries?: string[];
|
|
75
|
+
ignore: IgnoreEntry[];
|
|
76
|
+
}
|
|
77
|
+
interface BaselineFile {
|
|
78
|
+
version: 1;
|
|
79
|
+
generatedAt: string;
|
|
80
|
+
findings: string[];
|
|
81
|
+
}
|
|
82
|
+
interface BaselineResult {
|
|
83
|
+
path?: string;
|
|
84
|
+
loaded: boolean;
|
|
85
|
+
written?: string;
|
|
86
|
+
total: number;
|
|
87
|
+
existing: number;
|
|
88
|
+
new: number;
|
|
39
89
|
}
|
|
40
90
|
interface ScanProjectOptions {
|
|
41
91
|
cwd?: string;
|
|
42
|
-
lockfile?: string;
|
|
92
|
+
lockfile?: string | string[];
|
|
93
|
+
sbom?: string | string[];
|
|
94
|
+
config?: string;
|
|
95
|
+
policy?: PolicyPresetName;
|
|
96
|
+
baseline?: string;
|
|
97
|
+
writeBaseline?: string;
|
|
98
|
+
risk?: boolean;
|
|
99
|
+
env?: boolean;
|
|
100
|
+
allowedRegistries?: string[];
|
|
43
101
|
includeDev?: boolean;
|
|
44
102
|
prodOnly?: boolean;
|
|
45
|
-
cache?: boolean;
|
|
46
103
|
fetchImpl?: typeof fetch;
|
|
104
|
+
now?: Date;
|
|
47
105
|
}
|
|
48
106
|
interface ScanLockfileOptions {
|
|
49
|
-
lockfilePath: string;
|
|
107
|
+
lockfilePath: string | string[];
|
|
108
|
+
sbom?: string | string[];
|
|
109
|
+
cwd?: string;
|
|
110
|
+
config?: string;
|
|
111
|
+
policy?: PolicyPresetName;
|
|
112
|
+
baseline?: string;
|
|
113
|
+
writeBaseline?: string;
|
|
114
|
+
risk?: boolean;
|
|
115
|
+
env?: boolean;
|
|
116
|
+
allowedRegistries?: string[];
|
|
50
117
|
includeDev?: boolean;
|
|
51
118
|
prodOnly?: boolean;
|
|
52
119
|
fetchImpl?: typeof fetch;
|
|
120
|
+
now?: Date;
|
|
53
121
|
}
|
|
54
122
|
type FailOnLevel = Severity | "none";
|
|
123
|
+
type PolicyPresetName = "ci" | "strict" | "library" | "app";
|
|
55
124
|
|
|
56
125
|
declare function scanProject(options?: ScanProjectOptions): Promise<ScanResult>;
|
|
57
126
|
declare function scanLockfile(options: ScanLockfileOptions): Promise<ScanResult>;
|
|
@@ -66,6 +135,81 @@ declare function summarize(findings: Finding[]): Record<Severity, number>;
|
|
|
66
135
|
*/
|
|
67
136
|
declare function meetsThreshold(findings: Finding[], threshold: Severity | "none"): boolean;
|
|
68
137
|
|
|
138
|
+
type EnvIssueKind = "tracked-by-git" | "not-gitignored" | "would-be-published" | "secret-in-example" | "no-gitignore";
|
|
139
|
+
interface EnvIssue {
|
|
140
|
+
kind: EnvIssueKind;
|
|
141
|
+
severity: Severity;
|
|
142
|
+
file: string;
|
|
143
|
+
message: string;
|
|
144
|
+
detail?: string;
|
|
145
|
+
}
|
|
146
|
+
interface EnvScanResult$1 {
|
|
147
|
+
scannedAt: string;
|
|
148
|
+
cwd: string;
|
|
149
|
+
envFiles: string[];
|
|
150
|
+
issues: EnvIssue[];
|
|
151
|
+
summary: Record<Severity, number>;
|
|
152
|
+
errors: {
|
|
153
|
+
message: string;
|
|
154
|
+
cause?: string;
|
|
155
|
+
}[];
|
|
156
|
+
}
|
|
157
|
+
interface EnvScanOptions {
|
|
158
|
+
cwd?: string;
|
|
159
|
+
/** Cap on directory recursion depth from cwd. Default 6. */
|
|
160
|
+
maxDepth?: number;
|
|
161
|
+
/** Override directory skip list (replaces the default). */
|
|
162
|
+
skipDirs?: string[];
|
|
163
|
+
}
|
|
164
|
+
declare function scanEnv(options?: EnvScanOptions): Promise<EnvScanResult$1>;
|
|
165
|
+
declare function envIssuesMeetThreshold(issues: EnvIssue[], threshold: Severity | "none"): boolean;
|
|
166
|
+
|
|
167
|
+
interface InitOptions {
|
|
168
|
+
cwd?: string;
|
|
169
|
+
config?: string;
|
|
170
|
+
baseline?: string;
|
|
171
|
+
policy?: PolicyPresetName;
|
|
172
|
+
risk?: boolean;
|
|
173
|
+
env?: boolean;
|
|
174
|
+
writeBaseline?: boolean;
|
|
175
|
+
overwrite?: boolean;
|
|
176
|
+
fetchImpl?: typeof fetch;
|
|
177
|
+
}
|
|
178
|
+
interface InitResult {
|
|
179
|
+
configPath: string;
|
|
180
|
+
configWritten: boolean;
|
|
181
|
+
baselinePath?: string;
|
|
182
|
+
baselineWritten: boolean;
|
|
183
|
+
scan?: ScanResult;
|
|
184
|
+
warnings: string[];
|
|
185
|
+
}
|
|
186
|
+
declare function initProject(options?: InitOptions): Promise<InitResult>;
|
|
187
|
+
|
|
188
|
+
interface WhyOptions {
|
|
189
|
+
cwd?: string;
|
|
190
|
+
lockfile?: string | string[];
|
|
191
|
+
}
|
|
192
|
+
interface WhyMatch {
|
|
193
|
+
package: PackageInstance;
|
|
194
|
+
chain: string[];
|
|
195
|
+
note?: string;
|
|
196
|
+
}
|
|
197
|
+
interface WhyResult {
|
|
198
|
+
packageName: string;
|
|
199
|
+
lockfiles: string[];
|
|
200
|
+
matches: WhyMatch[];
|
|
201
|
+
}
|
|
202
|
+
declare function explainWhy(packageName: string, options?: WhyOptions): WhyResult;
|
|
203
|
+
|
|
204
|
+
interface PolicyPreset {
|
|
205
|
+
failOn: FailOnLevel;
|
|
206
|
+
risk: boolean;
|
|
207
|
+
env: boolean;
|
|
208
|
+
includeDev: boolean;
|
|
209
|
+
}
|
|
210
|
+
declare const POLICY_PRESETS: Record<PolicyPresetName, PolicyPreset>;
|
|
211
|
+
declare function resolvePolicy(requested: PolicyPresetName | undefined, configured: PolicyPresetName | undefined): PolicyPreset | undefined;
|
|
212
|
+
|
|
69
213
|
/**
|
|
70
214
|
* Parse an npm `package-lock.json` (v2 or v3) and return one
|
|
71
215
|
* PackageInstance per node in the `packages` map.
|
|
@@ -74,12 +218,51 @@ declare function meetsThreshold(findings: Finding[], threshold: Severity | "none
|
|
|
74
218
|
*/
|
|
75
219
|
declare function parseNpmPackageLock(filePath: string): PackageInstance[];
|
|
76
220
|
|
|
221
|
+
declare function parsePnpmLock(filePath: string): PackageInstance[];
|
|
222
|
+
declare function parsePnpmPackageKey(key: string): {
|
|
223
|
+
name: string;
|
|
224
|
+
version: string;
|
|
225
|
+
} | null;
|
|
226
|
+
|
|
227
|
+
declare function parseYarnLock(filePath: string): PackageInstance[];
|
|
228
|
+
declare function parseYarnDescriptorName(descriptor: string): string | null;
|
|
229
|
+
|
|
230
|
+
declare function parseLockfile(filePath: string): PackageInstance[];
|
|
231
|
+
|
|
232
|
+
interface PurlPackage {
|
|
233
|
+
name: string;
|
|
234
|
+
version: string;
|
|
235
|
+
ecosystem: Ecosystem;
|
|
236
|
+
purl: string;
|
|
237
|
+
}
|
|
238
|
+
declare function parseSbom(filePath: string): PackageInstance[];
|
|
239
|
+
declare function parsePurlPackage(purl: string): PurlPackage | null;
|
|
240
|
+
|
|
241
|
+
interface EnvScanResult {
|
|
242
|
+
findings: Finding[];
|
|
243
|
+
warnings: string[];
|
|
244
|
+
filesScanned: number;
|
|
245
|
+
}
|
|
246
|
+
declare function scanEnvFiles(cwd: string): EnvScanResult;
|
|
247
|
+
|
|
248
|
+
interface AppliedBaseline {
|
|
249
|
+
result: BaselineResult;
|
|
250
|
+
findings: Finding[];
|
|
251
|
+
}
|
|
252
|
+
declare class BaselineError extends Error {
|
|
253
|
+
constructor(message: string);
|
|
254
|
+
}
|
|
255
|
+
declare function applyBaseline(findings: Finding[], cwd: string, baselinePath?: string): AppliedBaseline | undefined;
|
|
256
|
+
declare function writeBaseline(findings: Finding[], cwd: string, baselinePath: string, existing?: BaselineResult): BaselineResult;
|
|
257
|
+
|
|
77
258
|
interface OsvQueryDeps {
|
|
78
259
|
fetchImpl?: typeof fetch;
|
|
79
260
|
}
|
|
80
261
|
interface UniquePackage {
|
|
81
262
|
name: string;
|
|
82
263
|
version: string;
|
|
264
|
+
ecosystem?: Ecosystem;
|
|
265
|
+
purl?: string;
|
|
83
266
|
}
|
|
84
267
|
/**
|
|
85
268
|
* Build the deduplicated list of unique name@version pairs to query OSV with.
|
|
@@ -91,4 +274,15 @@ declare function dedupeForQuery(packages: PackageInstance[]): UniquePackage[];
|
|
|
91
274
|
*/
|
|
92
275
|
declare function queryOsv(packages: PackageInstance[], deps?: OsvQueryDeps): Promise<Finding[]>;
|
|
93
276
|
|
|
94
|
-
|
|
277
|
+
interface LoadedConfig {
|
|
278
|
+
path?: string;
|
|
279
|
+
config: TrawlyConfig;
|
|
280
|
+
}
|
|
281
|
+
declare class ConfigError extends Error {
|
|
282
|
+
constructor(message: string);
|
|
283
|
+
}
|
|
284
|
+
declare function loadConfig(cwd: string, explicitPath?: string): LoadedConfig;
|
|
285
|
+
|
|
286
|
+
declare const TRAWLY_VERSION: string;
|
|
287
|
+
|
|
288
|
+
export { type AppliedBaseline, BaselineError, type BaselineFile, type BaselineResult, ConfigError, type Ecosystem, type EnvIssue, type EnvIssueKind, type EnvScanOptions, type EnvScanResult$1 as EnvScanResult, type FailOnLevel, type Finding, type FindingSource, type FindingType, type IgnoreEntry, type InputKind, POLICY_PRESETS, type PackageInstance, type PolicyPresetName, SEVERITY_RANK, type ScanError, ScanInputError, type ScanLockfileOptions, type ScanProjectOptions, type ScanResult, type Severity, TRAWLY_VERSION, type TrawlyConfig, applyBaseline, compareFindings, dedupeForQuery, envIssuesMeetThreshold, explainWhy, initProject, loadConfig, meetsThreshold, parseLockfile, parseNpmPackageLock, parsePnpmLock, parsePnpmPackageKey, parsePurlPackage, parseSbom, parseYarnDescriptorName, parseYarnLock, queryOsv, resolvePolicy, scanEnv, scanEnvFiles, scanLockfile, scanProject, summarize, writeBaseline };
|