@zksecurity/zkao-sdk 0.1.0
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/LICENSE +21 -0
- package/README.md +36 -0
- package/dist/index.d.ts +1278 -0
- package/dist/index.js +335 -0
- package/package.json +52 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base-URL resolution for the SDK and CLI.
|
|
3
|
+
*
|
|
4
|
+
* One env var, `ZKAO_URL`, points at an environment. It accepts a bare host, an
|
|
5
|
+
* origin, or a full API URL (e.g. `staging.zkao.io`, `http://localhost:3000`, or
|
|
6
|
+
* `https://zkao.io/api/v1`) and is normalized to `<origin>[/path]/api/v1`. The
|
|
7
|
+
* normalization is idempotent: a value already ending in `/api/vN` is left as-is.
|
|
8
|
+
*
|
|
9
|
+
* An explicit `baseUrl` passed to the client (or the CLI `--base-url` flag) wins
|
|
10
|
+
* and is used verbatim, for the rare case that needs an exact, non-standard base.
|
|
11
|
+
*/
|
|
12
|
+
/** Production default; the `/api/v1` path is part of the base. */
|
|
13
|
+
declare const DEFAULT_BASE_URL = "https://zkao.io/api/v1";
|
|
14
|
+
/**
|
|
15
|
+
* Turn a host or origin (with or without scheme/path) into a full API base URL
|
|
16
|
+
* ending in `/api/v1`. Idempotent: an input already ending in `/api/v<n>` is
|
|
17
|
+
* left as-is. A bare host gets `https://` unless it is localhost (then `http://`).
|
|
18
|
+
* A path component is preserved (and `/api/v1` appended after it).
|
|
19
|
+
*/
|
|
20
|
+
declare function normalizeBaseUrl(value: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Resolve a base URL from `ZKAO_URL`, or `undefined` if it is not set. The value
|
|
23
|
+
* (host, origin, or full API URL) is normalized to `<origin>[/path]/api/v1`.
|
|
24
|
+
*/
|
|
25
|
+
declare function resolveBaseUrlFromEnv(env?: Record<string, string | undefined>): string | undefined;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* This file was auto-generated by openapi-typescript.
|
|
29
|
+
* Do not make direct changes to the file.
|
|
30
|
+
*/
|
|
31
|
+
interface paths {
|
|
32
|
+
"/projects/{projectId}/repositories": {
|
|
33
|
+
parameters: {
|
|
34
|
+
query?: never;
|
|
35
|
+
header?: never;
|
|
36
|
+
path?: never;
|
|
37
|
+
cookie?: never;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* List repositories in the project
|
|
41
|
+
* @description Requires scope: `read`. Limited to the token's repo allowlist when set.
|
|
42
|
+
*/
|
|
43
|
+
get: operations["listRepositories"];
|
|
44
|
+
put?: never;
|
|
45
|
+
post?: never;
|
|
46
|
+
delete?: never;
|
|
47
|
+
options?: never;
|
|
48
|
+
head?: never;
|
|
49
|
+
patch?: never;
|
|
50
|
+
trace?: never;
|
|
51
|
+
};
|
|
52
|
+
"/projects/{projectId}/repositories/{repositoryId}/guidance": {
|
|
53
|
+
parameters: {
|
|
54
|
+
query?: never;
|
|
55
|
+
header?: never;
|
|
56
|
+
path?: never;
|
|
57
|
+
cookie?: never;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Get a repository's guidance
|
|
61
|
+
* @description Requires scope: `read`. Returns the per-repo guidance configured for this repository. Guidance is layered on top of any `zkao.md` committed in the repo at scan time; a per-scan `guidance` on launch replaces this layer for that one scan only.
|
|
62
|
+
*/
|
|
63
|
+
get: operations["getRepositoryGuidance"];
|
|
64
|
+
/**
|
|
65
|
+
* Set or clear a repository's guidance
|
|
66
|
+
* @description Requires scope: `guidance:write`. Sets `content` as the repository's guidance (or clears it with `null`), recording a revision. Writing the same content that is already stored is a no-op (`unchanged: true`, no revision). Pass `expectedContent` for an optimistic compare-and-set: omit it for last-writer-wins, or send the content you last read (or `null` for "currently cleared") to get a `409` instead of clobbering a concurrent change.
|
|
67
|
+
*/
|
|
68
|
+
put: operations["setRepositoryGuidance"];
|
|
69
|
+
post?: never;
|
|
70
|
+
delete?: never;
|
|
71
|
+
options?: never;
|
|
72
|
+
head?: never;
|
|
73
|
+
patch?: never;
|
|
74
|
+
trace?: never;
|
|
75
|
+
};
|
|
76
|
+
"/projects/{projectId}/scans": {
|
|
77
|
+
parameters: {
|
|
78
|
+
query?: never;
|
|
79
|
+
header?: never;
|
|
80
|
+
path?: never;
|
|
81
|
+
cookie?: never;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* List scans (most recent first)
|
|
85
|
+
* @description Requires scope: `read`.
|
|
86
|
+
*/
|
|
87
|
+
get: operations["listScans"];
|
|
88
|
+
put?: never;
|
|
89
|
+
/**
|
|
90
|
+
* Launch a scan
|
|
91
|
+
* @description Requires scope: `scans:launch`. Reserves `creditBudget` credits from the
|
|
92
|
+
* project balance. The repo must be in the token's allowlist (when set) and
|
|
93
|
+
* ACTIVE. Discover valid `presetRef` / `optInFlowIds` via the discovery
|
|
94
|
+
* endpoints. Per-token spend limits and the project plan are enforced.
|
|
95
|
+
*/
|
|
96
|
+
post: operations["launchScan"];
|
|
97
|
+
delete?: never;
|
|
98
|
+
options?: never;
|
|
99
|
+
head?: never;
|
|
100
|
+
patch?: never;
|
|
101
|
+
trace?: never;
|
|
102
|
+
};
|
|
103
|
+
"/projects/{projectId}/scans/{scanId}": {
|
|
104
|
+
parameters: {
|
|
105
|
+
query?: never;
|
|
106
|
+
header?: never;
|
|
107
|
+
path?: never;
|
|
108
|
+
cookie?: never;
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Get a single scan's status and detail
|
|
112
|
+
* @description Requires scope: `read`. Use for polling a launched scan. While the scan is not yet terminal the response carries an advisory `Retry-After` header telling you how long to wait before polling again; respect it (and back off on `429`) instead of polling in a tight loop.
|
|
113
|
+
*/
|
|
114
|
+
get: operations["getScan"];
|
|
115
|
+
put?: never;
|
|
116
|
+
post?: never;
|
|
117
|
+
delete?: never;
|
|
118
|
+
options?: never;
|
|
119
|
+
head?: never;
|
|
120
|
+
patch?: never;
|
|
121
|
+
trace?: never;
|
|
122
|
+
};
|
|
123
|
+
"/projects/{projectId}/scans/{scanId}/cancel": {
|
|
124
|
+
parameters: {
|
|
125
|
+
query?: never;
|
|
126
|
+
header?: never;
|
|
127
|
+
path?: never;
|
|
128
|
+
cookie?: never;
|
|
129
|
+
};
|
|
130
|
+
get?: never;
|
|
131
|
+
put?: never;
|
|
132
|
+
/**
|
|
133
|
+
* Cancel a running or queued scan
|
|
134
|
+
* @description Requires scope: `scans:launch`. Signals any in-flight jobs to stop, marks the scan CANCELLED, and releases its reserved credits (in-flight jobs settle their actual spend as they wind down). A scan that already reached COMPLETED or FAILED cannot be cancelled (`400`).
|
|
135
|
+
*/
|
|
136
|
+
post: operations["cancelScan"];
|
|
137
|
+
delete?: never;
|
|
138
|
+
options?: never;
|
|
139
|
+
head?: never;
|
|
140
|
+
patch?: never;
|
|
141
|
+
trace?: never;
|
|
142
|
+
};
|
|
143
|
+
"/projects/{projectId}/findings": {
|
|
144
|
+
parameters: {
|
|
145
|
+
query?: never;
|
|
146
|
+
header?: never;
|
|
147
|
+
path?: never;
|
|
148
|
+
cookie?: never;
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* List findings
|
|
152
|
+
* @description Requires scope: `read`. Optionally filter by `scanId`.
|
|
153
|
+
*/
|
|
154
|
+
get: operations["listFindings"];
|
|
155
|
+
put?: never;
|
|
156
|
+
post?: never;
|
|
157
|
+
delete?: never;
|
|
158
|
+
options?: never;
|
|
159
|
+
head?: never;
|
|
160
|
+
patch?: never;
|
|
161
|
+
trace?: never;
|
|
162
|
+
};
|
|
163
|
+
"/projects/{projectId}/findings/{findingId}": {
|
|
164
|
+
parameters: {
|
|
165
|
+
query?: never;
|
|
166
|
+
header?: never;
|
|
167
|
+
path?: never;
|
|
168
|
+
cookie?: never;
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* Get a single finding (full detail)
|
|
172
|
+
* @description Requires scope: `read`. Includes description, PoC, recommended fix, and notes.
|
|
173
|
+
*/
|
|
174
|
+
get: operations["getFinding"];
|
|
175
|
+
put?: never;
|
|
176
|
+
post?: never;
|
|
177
|
+
delete?: never;
|
|
178
|
+
options?: never;
|
|
179
|
+
head?: never;
|
|
180
|
+
patch?: never;
|
|
181
|
+
trace?: never;
|
|
182
|
+
};
|
|
183
|
+
"/projects/{projectId}/findings/{findingId}/notes": {
|
|
184
|
+
parameters: {
|
|
185
|
+
query?: never;
|
|
186
|
+
header?: never;
|
|
187
|
+
path?: never;
|
|
188
|
+
cookie?: never;
|
|
189
|
+
};
|
|
190
|
+
get?: never;
|
|
191
|
+
put?: never;
|
|
192
|
+
/**
|
|
193
|
+
* Add a comment (note) to a finding
|
|
194
|
+
* @description Requires scope: `findings:write`.
|
|
195
|
+
*/
|
|
196
|
+
post: operations["addFindingNote"];
|
|
197
|
+
delete?: never;
|
|
198
|
+
options?: never;
|
|
199
|
+
head?: never;
|
|
200
|
+
patch?: never;
|
|
201
|
+
trace?: never;
|
|
202
|
+
};
|
|
203
|
+
"/projects/{projectId}/findings/{findingId}/notes/{noteId}/pin": {
|
|
204
|
+
parameters: {
|
|
205
|
+
query?: never;
|
|
206
|
+
header?: never;
|
|
207
|
+
path?: never;
|
|
208
|
+
cookie?: never;
|
|
209
|
+
};
|
|
210
|
+
get?: never;
|
|
211
|
+
put?: never;
|
|
212
|
+
/**
|
|
213
|
+
* Pin a note as the resolution note
|
|
214
|
+
* @description Requires scope: `findings:write`.
|
|
215
|
+
*/
|
|
216
|
+
post: operations["pinFindingNote"];
|
|
217
|
+
delete?: never;
|
|
218
|
+
options?: never;
|
|
219
|
+
head?: never;
|
|
220
|
+
patch?: never;
|
|
221
|
+
trace?: never;
|
|
222
|
+
};
|
|
223
|
+
"/projects/{projectId}/findings/{findingId}/severity": {
|
|
224
|
+
parameters: {
|
|
225
|
+
query?: never;
|
|
226
|
+
header?: never;
|
|
227
|
+
path?: never;
|
|
228
|
+
cookie?: never;
|
|
229
|
+
};
|
|
230
|
+
get?: never;
|
|
231
|
+
put?: never;
|
|
232
|
+
post?: never;
|
|
233
|
+
delete?: never;
|
|
234
|
+
options?: never;
|
|
235
|
+
head?: never;
|
|
236
|
+
/**
|
|
237
|
+
* Override (or clear) a finding's severity
|
|
238
|
+
* @description Requires scope: `findings:write`. Set `severity` to null to clear the override.
|
|
239
|
+
*/
|
|
240
|
+
patch: operations["updateFindingSeverity"];
|
|
241
|
+
trace?: never;
|
|
242
|
+
};
|
|
243
|
+
"/projects/{projectId}/findings/{findingId}/resolution": {
|
|
244
|
+
parameters: {
|
|
245
|
+
query?: never;
|
|
246
|
+
header?: never;
|
|
247
|
+
path?: never;
|
|
248
|
+
cookie?: never;
|
|
249
|
+
};
|
|
250
|
+
get?: never;
|
|
251
|
+
put?: never;
|
|
252
|
+
post?: never;
|
|
253
|
+
delete?: never;
|
|
254
|
+
options?: never;
|
|
255
|
+
head?: never;
|
|
256
|
+
/**
|
|
257
|
+
* Change a finding's resolution status
|
|
258
|
+
* @description Requires scope: `findings:write`.
|
|
259
|
+
*/
|
|
260
|
+
patch: operations["updateFindingResolution"];
|
|
261
|
+
trace?: never;
|
|
262
|
+
};
|
|
263
|
+
"/projects/{projectId}/findings/{findingId}/publish": {
|
|
264
|
+
parameters: {
|
|
265
|
+
query?: never;
|
|
266
|
+
header?: never;
|
|
267
|
+
path?: never;
|
|
268
|
+
cookie?: never;
|
|
269
|
+
};
|
|
270
|
+
get?: never;
|
|
271
|
+
put?: never;
|
|
272
|
+
/**
|
|
273
|
+
* Publish a finding as a public artifact
|
|
274
|
+
* @description Requires scope: `publish`. Pin a note as the published note via `noteId`.
|
|
275
|
+
*/
|
|
276
|
+
post: operations["publishFinding"];
|
|
277
|
+
delete?: never;
|
|
278
|
+
options?: never;
|
|
279
|
+
head?: never;
|
|
280
|
+
patch?: never;
|
|
281
|
+
trace?: never;
|
|
282
|
+
};
|
|
283
|
+
"/projects/{projectId}/scans/{scanId}/publish": {
|
|
284
|
+
parameters: {
|
|
285
|
+
query?: never;
|
|
286
|
+
header?: never;
|
|
287
|
+
path?: never;
|
|
288
|
+
cookie?: never;
|
|
289
|
+
};
|
|
290
|
+
get?: never;
|
|
291
|
+
put?: never;
|
|
292
|
+
/**
|
|
293
|
+
* Publish a scan as a public artifact
|
|
294
|
+
* @description Requires scope: `publish`. The scan must be COMPLETED.
|
|
295
|
+
*/
|
|
296
|
+
post: operations["publishScan"];
|
|
297
|
+
delete?: never;
|
|
298
|
+
options?: never;
|
|
299
|
+
head?: never;
|
|
300
|
+
patch?: never;
|
|
301
|
+
trace?: never;
|
|
302
|
+
};
|
|
303
|
+
"/projects/{projectId}/scan-presets": {
|
|
304
|
+
parameters: {
|
|
305
|
+
query?: never;
|
|
306
|
+
header?: never;
|
|
307
|
+
path?: never;
|
|
308
|
+
cookie?: never;
|
|
309
|
+
};
|
|
310
|
+
/**
|
|
311
|
+
* List the scan presets (scan types) the project can launch
|
|
312
|
+
* @description Requires scope: `read`. Use a preset's `ref` as `presetRef` when launching.
|
|
313
|
+
*/
|
|
314
|
+
get: operations["listScanPresets"];
|
|
315
|
+
put?: never;
|
|
316
|
+
post?: never;
|
|
317
|
+
delete?: never;
|
|
318
|
+
options?: never;
|
|
319
|
+
head?: never;
|
|
320
|
+
patch?: never;
|
|
321
|
+
trace?: never;
|
|
322
|
+
};
|
|
323
|
+
"/projects/{projectId}/optional-flows": {
|
|
324
|
+
parameters: {
|
|
325
|
+
query?: never;
|
|
326
|
+
header?: never;
|
|
327
|
+
path?: never;
|
|
328
|
+
cookie?: never;
|
|
329
|
+
};
|
|
330
|
+
/**
|
|
331
|
+
* List opt-in flows available at launch
|
|
332
|
+
* @description Requires scope: `read`. Pass the chosen ids as `optInFlowIds` when launching.
|
|
333
|
+
*/
|
|
334
|
+
get: operations["listOptionalFlows"];
|
|
335
|
+
put?: never;
|
|
336
|
+
post?: never;
|
|
337
|
+
delete?: never;
|
|
338
|
+
options?: never;
|
|
339
|
+
head?: never;
|
|
340
|
+
patch?: never;
|
|
341
|
+
trace?: never;
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
interface components {
|
|
345
|
+
schemas: {
|
|
346
|
+
Error: {
|
|
347
|
+
error: {
|
|
348
|
+
/** @enum {string} */
|
|
349
|
+
code: "unauthorized" | "forbidden" | "not_found" | "bad_request" | "conflict" | "plan_inactive" | "rate_limited" | "internal";
|
|
350
|
+
message: string;
|
|
351
|
+
};
|
|
352
|
+
};
|
|
353
|
+
/** @enum {string} */
|
|
354
|
+
Severity: "CRITICAL" | "HIGH" | "MEDIUM" | "LOW" | "INFO";
|
|
355
|
+
/** @enum {string} */
|
|
356
|
+
ResolutionStatus: "NOT_STARTED" | "IN_PROGRESS" | "RESOLVED" | "WONT_FIX" | "MITIGATED" | "FALSE_POSITIVE" | "DUPLICATE";
|
|
357
|
+
/** @enum {string} */
|
|
358
|
+
TriageStatus: "PENDING" | "NEW" | "DUPLICATE" | "RECURRING" | "CONFIRMED" | "FALSE_POSITIVE" | "INCONCLUSIVE";
|
|
359
|
+
/** @enum {string} */
|
|
360
|
+
ScanStatus: "QUEUED" | "PROCESSING" | "COMPLETED" | "FAILED" | "CANCELLED";
|
|
361
|
+
Repository: {
|
|
362
|
+
id: string;
|
|
363
|
+
owner: string;
|
|
364
|
+
name: string;
|
|
365
|
+
url: string;
|
|
366
|
+
defaultBranch?: string | null;
|
|
367
|
+
/** @description ACTIVE | MARKED_FOR_DELETION */
|
|
368
|
+
status: string;
|
|
369
|
+
};
|
|
370
|
+
Scan: {
|
|
371
|
+
id: string;
|
|
372
|
+
status: components["schemas"]["ScanStatus"];
|
|
373
|
+
repositoryId: string;
|
|
374
|
+
commitHash?: string | null;
|
|
375
|
+
commitMessage?: string | null;
|
|
376
|
+
presetName?: string | null;
|
|
377
|
+
/** Format: date-time */
|
|
378
|
+
createdAt: string;
|
|
379
|
+
/** Format: date-time */
|
|
380
|
+
startedAt?: string | null;
|
|
381
|
+
/** Format: date-time */
|
|
382
|
+
completedAt?: string | null;
|
|
383
|
+
};
|
|
384
|
+
ScanDetail: components["schemas"]["Scan"] & {
|
|
385
|
+
branch?: string | null;
|
|
386
|
+
/** @description Reserved budget for the scan, in credits. */
|
|
387
|
+
creditBudget?: number | null;
|
|
388
|
+
findingsSummary?: {
|
|
389
|
+
total?: number;
|
|
390
|
+
bySeverity?: {
|
|
391
|
+
[key: string]: number;
|
|
392
|
+
};
|
|
393
|
+
} | null;
|
|
394
|
+
};
|
|
395
|
+
Finding: {
|
|
396
|
+
id: string;
|
|
397
|
+
displayId: number;
|
|
398
|
+
title: string;
|
|
399
|
+
location: string;
|
|
400
|
+
/** @description Effective severity (user override if set, else AI severity). */
|
|
401
|
+
severity: components["schemas"]["Severity"];
|
|
402
|
+
category: string;
|
|
403
|
+
triageStatus: components["schemas"]["TriageStatus"];
|
|
404
|
+
resolutionStatus: components["schemas"]["ResolutionStatus"];
|
|
405
|
+
notesCount: number;
|
|
406
|
+
};
|
|
407
|
+
FindingNote: {
|
|
408
|
+
id: string;
|
|
409
|
+
body: string;
|
|
410
|
+
/** Format: date-time */
|
|
411
|
+
createdAt: string;
|
|
412
|
+
author?: {
|
|
413
|
+
id?: string;
|
|
414
|
+
name?: string | null;
|
|
415
|
+
email?: string;
|
|
416
|
+
} | null;
|
|
417
|
+
};
|
|
418
|
+
FindingDetail: components["schemas"]["Finding"] & {
|
|
419
|
+
description: string;
|
|
420
|
+
pocReport?: string | null;
|
|
421
|
+
recommendedFix?: string | null;
|
|
422
|
+
scanId: string;
|
|
423
|
+
commitHash?: string | null;
|
|
424
|
+
repo?: {
|
|
425
|
+
owner?: string;
|
|
426
|
+
name?: string;
|
|
427
|
+
url?: string;
|
|
428
|
+
} | null;
|
|
429
|
+
/** Format: date-time */
|
|
430
|
+
createdAt: string;
|
|
431
|
+
notes: components["schemas"]["FindingNote"][];
|
|
432
|
+
};
|
|
433
|
+
PaginatedScans: {
|
|
434
|
+
items: components["schemas"]["Scan"][];
|
|
435
|
+
page: number;
|
|
436
|
+
limit: number;
|
|
437
|
+
total: number;
|
|
438
|
+
};
|
|
439
|
+
PaginatedFindings: {
|
|
440
|
+
items: components["schemas"]["Finding"][];
|
|
441
|
+
page: number;
|
|
442
|
+
limit: number;
|
|
443
|
+
total: number;
|
|
444
|
+
};
|
|
445
|
+
ScanPreset: {
|
|
446
|
+
/** @description Pass as `presetRef` when launching. */
|
|
447
|
+
ref: string;
|
|
448
|
+
name: string;
|
|
449
|
+
description?: string | null;
|
|
450
|
+
/** @description 0 = use the default floor. */
|
|
451
|
+
minCredits: number;
|
|
452
|
+
modelTier: string;
|
|
453
|
+
};
|
|
454
|
+
OptionalFlow: {
|
|
455
|
+
/** @description Pass in `optInFlowIds` when launching. */
|
|
456
|
+
id: string;
|
|
457
|
+
flowId: string;
|
|
458
|
+
title: string;
|
|
459
|
+
description: string;
|
|
460
|
+
};
|
|
461
|
+
LaunchScanRequest: {
|
|
462
|
+
repositoryId: string;
|
|
463
|
+
/** @description Max budget for the scan, in credits. Reserved at launch. */
|
|
464
|
+
creditBudget: number;
|
|
465
|
+
/** @description A preset ref from /scan-presets. Defaults to the first active preset. */
|
|
466
|
+
presetRef?: string;
|
|
467
|
+
/** @description Branch to scan (resolved to its head commit server-side). Ignored if commitHash is set. */
|
|
468
|
+
branch?: string | null;
|
|
469
|
+
/** @description Pin a specific commit SHA (7-40 hex chars). */
|
|
470
|
+
commitHash?: string | null;
|
|
471
|
+
commitMessage?: string | null;
|
|
472
|
+
/** @description Optional-flow ids from /optional-flows. */
|
|
473
|
+
optInFlowIds?: string[];
|
|
474
|
+
/** @description Guidance for this scan only, replacing the repository's configured guidance layer (it is still layered over any committed zkao.md). Omit the field to inherit the repository's guidance; send null to scan with no guidance layer. */
|
|
475
|
+
guidance?: string | null;
|
|
476
|
+
};
|
|
477
|
+
LaunchScanResult: {
|
|
478
|
+
scanId: string;
|
|
479
|
+
queued: boolean;
|
|
480
|
+
};
|
|
481
|
+
RepositoryGuidance: {
|
|
482
|
+
repositoryId: string;
|
|
483
|
+
/** @description The configured guidance, or null when none is set. */
|
|
484
|
+
content: string | null;
|
|
485
|
+
/**
|
|
486
|
+
* Format: date-time
|
|
487
|
+
* @description When the guidance last changed. Null when the repo has no revision history (guidance never set, or set before revisions were tracked).
|
|
488
|
+
*/
|
|
489
|
+
updatedAt: string | null;
|
|
490
|
+
};
|
|
491
|
+
SetGuidanceRequest: {
|
|
492
|
+
/** @description New guidance content; null clears it. */
|
|
493
|
+
content: string | null;
|
|
494
|
+
/** @description Optional compare-and-set. Omit for last-writer-wins. Send the content you last read (or null for "currently cleared") to receive a 409 if the guidance changed underneath you instead of overwriting it. */
|
|
495
|
+
expectedContent?: string | null;
|
|
496
|
+
};
|
|
497
|
+
SetGuidanceResult: {
|
|
498
|
+
repositoryId: string;
|
|
499
|
+
/** @description The recorded revision id, or null on a no-op write. */
|
|
500
|
+
revisionId: string | null;
|
|
501
|
+
/** @description True when the content already matched (no revision recorded). */
|
|
502
|
+
unchanged: boolean;
|
|
503
|
+
};
|
|
504
|
+
CancelScanResult: {
|
|
505
|
+
scanId: string;
|
|
506
|
+
/** @description Terminal status after cancellation (always CANCELLED). */
|
|
507
|
+
status: components["schemas"]["ScanStatus"];
|
|
508
|
+
/** @description Number of in-flight jobs signalled to stop. */
|
|
509
|
+
cancelledJobs: number;
|
|
510
|
+
};
|
|
511
|
+
/** @description Optionally attach or reuse a note alongside a resolution change. */
|
|
512
|
+
ChangeNote: {
|
|
513
|
+
/** @description Create a new note with this body. */
|
|
514
|
+
content?: string;
|
|
515
|
+
/** @description Reuse an existing note by id. */
|
|
516
|
+
existingNoteId?: string;
|
|
517
|
+
};
|
|
518
|
+
FindingNoteResult: {
|
|
519
|
+
noteId: string;
|
|
520
|
+
findingId: string;
|
|
521
|
+
};
|
|
522
|
+
FindingPinResult: {
|
|
523
|
+
findingId: string;
|
|
524
|
+
noteId: string | null;
|
|
525
|
+
};
|
|
526
|
+
FindingSeverityResult: {
|
|
527
|
+
findingId: string;
|
|
528
|
+
userSeverity?: components["schemas"]["Severity"] | null;
|
|
529
|
+
effectiveSeverity: components["schemas"]["Severity"];
|
|
530
|
+
};
|
|
531
|
+
FindingResolutionResult: {
|
|
532
|
+
findingId: string;
|
|
533
|
+
resolutionStatus: components["schemas"]["ResolutionStatus"];
|
|
534
|
+
};
|
|
535
|
+
PublishFindingRequest: {
|
|
536
|
+
/** @description A note id on the finding to pin as the published note. */
|
|
537
|
+
noteId?: string;
|
|
538
|
+
/** @description Generate a password to gate access to the public artifact. */
|
|
539
|
+
withPassword?: boolean;
|
|
540
|
+
};
|
|
541
|
+
PublishScanRequest: {
|
|
542
|
+
/** @description Generate a password to gate access to the public artifact. */
|
|
543
|
+
withPassword?: boolean;
|
|
544
|
+
};
|
|
545
|
+
PublishArtifactResult: {
|
|
546
|
+
artifactId: string;
|
|
547
|
+
/** @description Slug in /public/{scans,findings}/<publicId>. */
|
|
548
|
+
publicId: string;
|
|
549
|
+
/** @description The generated access password when withPassword was requested; otherwise null. */
|
|
550
|
+
accessPassword?: string | null;
|
|
551
|
+
};
|
|
552
|
+
};
|
|
553
|
+
responses: {
|
|
554
|
+
/** @description Invalid request */
|
|
555
|
+
BadRequest: {
|
|
556
|
+
headers: {
|
|
557
|
+
[name: string]: unknown;
|
|
558
|
+
};
|
|
559
|
+
content: {
|
|
560
|
+
"application/json": components["schemas"]["Error"];
|
|
561
|
+
};
|
|
562
|
+
};
|
|
563
|
+
/** @description Missing, malformed, expired, or revoked token */
|
|
564
|
+
Unauthorized: {
|
|
565
|
+
headers: {
|
|
566
|
+
[name: string]: unknown;
|
|
567
|
+
};
|
|
568
|
+
content: {
|
|
569
|
+
"application/json": components["schemas"]["Error"];
|
|
570
|
+
};
|
|
571
|
+
};
|
|
572
|
+
/** @description The token lacks the required scope */
|
|
573
|
+
Forbidden: {
|
|
574
|
+
headers: {
|
|
575
|
+
[name: string]: unknown;
|
|
576
|
+
};
|
|
577
|
+
content: {
|
|
578
|
+
"application/json": components["schemas"]["Error"];
|
|
579
|
+
};
|
|
580
|
+
};
|
|
581
|
+
/** @description Resource not in this token's project or repo allowlist */
|
|
582
|
+
NotFound: {
|
|
583
|
+
headers: {
|
|
584
|
+
[name: string]: unknown;
|
|
585
|
+
};
|
|
586
|
+
content: {
|
|
587
|
+
"application/json": components["schemas"]["Error"];
|
|
588
|
+
};
|
|
589
|
+
};
|
|
590
|
+
/** @description A compare-and-set (`expectedContent`) missed: the guidance changed since it was read. Re-read the current guidance and retry. */
|
|
591
|
+
Conflict: {
|
|
592
|
+
headers: {
|
|
593
|
+
[name: string]: unknown;
|
|
594
|
+
};
|
|
595
|
+
content: {
|
|
596
|
+
"application/json": components["schemas"]["Error"];
|
|
597
|
+
};
|
|
598
|
+
};
|
|
599
|
+
/** @description Rate limited. Either the token's spend limit for the current period is reached (on launch), or the token is sending too many requests. Wait the number of seconds in the `Retry-After` header before retrying. */
|
|
600
|
+
RateLimited: {
|
|
601
|
+
headers: {
|
|
602
|
+
/** @description Seconds to wait before retrying. */
|
|
603
|
+
"Retry-After"?: number;
|
|
604
|
+
[name: string]: unknown;
|
|
605
|
+
};
|
|
606
|
+
content: {
|
|
607
|
+
"application/json": components["schemas"]["Error"];
|
|
608
|
+
};
|
|
609
|
+
};
|
|
610
|
+
};
|
|
611
|
+
parameters: {
|
|
612
|
+
ProjectId: string;
|
|
613
|
+
ScanId: string;
|
|
614
|
+
FindingId: string;
|
|
615
|
+
RepositoryId: string;
|
|
616
|
+
Page: number;
|
|
617
|
+
Limit: number;
|
|
618
|
+
};
|
|
619
|
+
requestBodies: never;
|
|
620
|
+
headers: never;
|
|
621
|
+
pathItems: never;
|
|
622
|
+
}
|
|
623
|
+
interface operations {
|
|
624
|
+
listRepositories: {
|
|
625
|
+
parameters: {
|
|
626
|
+
query?: never;
|
|
627
|
+
header?: never;
|
|
628
|
+
path: {
|
|
629
|
+
projectId: components["parameters"]["ProjectId"];
|
|
630
|
+
};
|
|
631
|
+
cookie?: never;
|
|
632
|
+
};
|
|
633
|
+
requestBody?: never;
|
|
634
|
+
responses: {
|
|
635
|
+
/** @description OK */
|
|
636
|
+
200: {
|
|
637
|
+
headers: {
|
|
638
|
+
[name: string]: unknown;
|
|
639
|
+
};
|
|
640
|
+
content: {
|
|
641
|
+
"application/json": {
|
|
642
|
+
repositories: components["schemas"]["Repository"][];
|
|
643
|
+
};
|
|
644
|
+
};
|
|
645
|
+
};
|
|
646
|
+
401: components["responses"]["Unauthorized"];
|
|
647
|
+
403: components["responses"]["Forbidden"];
|
|
648
|
+
404: components["responses"]["NotFound"];
|
|
649
|
+
};
|
|
650
|
+
};
|
|
651
|
+
getRepositoryGuidance: {
|
|
652
|
+
parameters: {
|
|
653
|
+
query?: never;
|
|
654
|
+
header?: never;
|
|
655
|
+
path: {
|
|
656
|
+
projectId: components["parameters"]["ProjectId"];
|
|
657
|
+
repositoryId: components["parameters"]["RepositoryId"];
|
|
658
|
+
};
|
|
659
|
+
cookie?: never;
|
|
660
|
+
};
|
|
661
|
+
requestBody?: never;
|
|
662
|
+
responses: {
|
|
663
|
+
/** @description OK */
|
|
664
|
+
200: {
|
|
665
|
+
headers: {
|
|
666
|
+
[name: string]: unknown;
|
|
667
|
+
};
|
|
668
|
+
content: {
|
|
669
|
+
"application/json": components["schemas"]["RepositoryGuidance"];
|
|
670
|
+
};
|
|
671
|
+
};
|
|
672
|
+
401: components["responses"]["Unauthorized"];
|
|
673
|
+
403: components["responses"]["Forbidden"];
|
|
674
|
+
404: components["responses"]["NotFound"];
|
|
675
|
+
};
|
|
676
|
+
};
|
|
677
|
+
setRepositoryGuidance: {
|
|
678
|
+
parameters: {
|
|
679
|
+
query?: never;
|
|
680
|
+
header?: never;
|
|
681
|
+
path: {
|
|
682
|
+
projectId: components["parameters"]["ProjectId"];
|
|
683
|
+
repositoryId: components["parameters"]["RepositoryId"];
|
|
684
|
+
};
|
|
685
|
+
cookie?: never;
|
|
686
|
+
};
|
|
687
|
+
requestBody: {
|
|
688
|
+
content: {
|
|
689
|
+
"application/json": components["schemas"]["SetGuidanceRequest"];
|
|
690
|
+
};
|
|
691
|
+
};
|
|
692
|
+
responses: {
|
|
693
|
+
/** @description OK */
|
|
694
|
+
200: {
|
|
695
|
+
headers: {
|
|
696
|
+
[name: string]: unknown;
|
|
697
|
+
};
|
|
698
|
+
content: {
|
|
699
|
+
"application/json": components["schemas"]["SetGuidanceResult"];
|
|
700
|
+
};
|
|
701
|
+
};
|
|
702
|
+
400: components["responses"]["BadRequest"];
|
|
703
|
+
401: components["responses"]["Unauthorized"];
|
|
704
|
+
403: components["responses"]["Forbidden"];
|
|
705
|
+
404: components["responses"]["NotFound"];
|
|
706
|
+
409: components["responses"]["Conflict"];
|
|
707
|
+
};
|
|
708
|
+
};
|
|
709
|
+
listScans: {
|
|
710
|
+
parameters: {
|
|
711
|
+
query?: {
|
|
712
|
+
page?: components["parameters"]["Page"];
|
|
713
|
+
limit?: components["parameters"]["Limit"];
|
|
714
|
+
};
|
|
715
|
+
header?: never;
|
|
716
|
+
path: {
|
|
717
|
+
projectId: components["parameters"]["ProjectId"];
|
|
718
|
+
};
|
|
719
|
+
cookie?: never;
|
|
720
|
+
};
|
|
721
|
+
requestBody?: never;
|
|
722
|
+
responses: {
|
|
723
|
+
/** @description OK */
|
|
724
|
+
200: {
|
|
725
|
+
headers: {
|
|
726
|
+
[name: string]: unknown;
|
|
727
|
+
};
|
|
728
|
+
content: {
|
|
729
|
+
"application/json": components["schemas"]["PaginatedScans"];
|
|
730
|
+
};
|
|
731
|
+
};
|
|
732
|
+
401: components["responses"]["Unauthorized"];
|
|
733
|
+
403: components["responses"]["Forbidden"];
|
|
734
|
+
404: components["responses"]["NotFound"];
|
|
735
|
+
};
|
|
736
|
+
};
|
|
737
|
+
launchScan: {
|
|
738
|
+
parameters: {
|
|
739
|
+
query?: never;
|
|
740
|
+
header?: never;
|
|
741
|
+
path: {
|
|
742
|
+
projectId: components["parameters"]["ProjectId"];
|
|
743
|
+
};
|
|
744
|
+
cookie?: never;
|
|
745
|
+
};
|
|
746
|
+
requestBody: {
|
|
747
|
+
content: {
|
|
748
|
+
"application/json": components["schemas"]["LaunchScanRequest"];
|
|
749
|
+
};
|
|
750
|
+
};
|
|
751
|
+
responses: {
|
|
752
|
+
/** @description Scan accepted (queued) */
|
|
753
|
+
202: {
|
|
754
|
+
headers: {
|
|
755
|
+
[name: string]: unknown;
|
|
756
|
+
};
|
|
757
|
+
content: {
|
|
758
|
+
"application/json": components["schemas"]["LaunchScanResult"];
|
|
759
|
+
};
|
|
760
|
+
};
|
|
761
|
+
400: components["responses"]["BadRequest"];
|
|
762
|
+
401: components["responses"]["Unauthorized"];
|
|
763
|
+
403: components["responses"]["Forbidden"];
|
|
764
|
+
404: components["responses"]["NotFound"];
|
|
765
|
+
429: components["responses"]["RateLimited"];
|
|
766
|
+
};
|
|
767
|
+
};
|
|
768
|
+
getScan: {
|
|
769
|
+
parameters: {
|
|
770
|
+
query?: never;
|
|
771
|
+
header?: never;
|
|
772
|
+
path: {
|
|
773
|
+
projectId: components["parameters"]["ProjectId"];
|
|
774
|
+
scanId: components["parameters"]["ScanId"];
|
|
775
|
+
};
|
|
776
|
+
cookie?: never;
|
|
777
|
+
};
|
|
778
|
+
requestBody?: never;
|
|
779
|
+
responses: {
|
|
780
|
+
/** @description OK */
|
|
781
|
+
200: {
|
|
782
|
+
headers: {
|
|
783
|
+
/** @description Advisory seconds to wait before polling again. Present only while the scan is still running (not for terminal scans). */
|
|
784
|
+
"Retry-After"?: number;
|
|
785
|
+
[name: string]: unknown;
|
|
786
|
+
};
|
|
787
|
+
content: {
|
|
788
|
+
"application/json": {
|
|
789
|
+
scan: components["schemas"]["ScanDetail"];
|
|
790
|
+
};
|
|
791
|
+
};
|
|
792
|
+
};
|
|
793
|
+
401: components["responses"]["Unauthorized"];
|
|
794
|
+
403: components["responses"]["Forbidden"];
|
|
795
|
+
404: components["responses"]["NotFound"];
|
|
796
|
+
429: components["responses"]["RateLimited"];
|
|
797
|
+
};
|
|
798
|
+
};
|
|
799
|
+
cancelScan: {
|
|
800
|
+
parameters: {
|
|
801
|
+
query?: never;
|
|
802
|
+
header?: never;
|
|
803
|
+
path: {
|
|
804
|
+
projectId: components["parameters"]["ProjectId"];
|
|
805
|
+
scanId: components["parameters"]["ScanId"];
|
|
806
|
+
};
|
|
807
|
+
cookie?: never;
|
|
808
|
+
};
|
|
809
|
+
requestBody?: never;
|
|
810
|
+
responses: {
|
|
811
|
+
/** @description OK */
|
|
812
|
+
200: {
|
|
813
|
+
headers: {
|
|
814
|
+
[name: string]: unknown;
|
|
815
|
+
};
|
|
816
|
+
content: {
|
|
817
|
+
"application/json": components["schemas"]["CancelScanResult"];
|
|
818
|
+
};
|
|
819
|
+
};
|
|
820
|
+
400: components["responses"]["BadRequest"];
|
|
821
|
+
401: components["responses"]["Unauthorized"];
|
|
822
|
+
403: components["responses"]["Forbidden"];
|
|
823
|
+
404: components["responses"]["NotFound"];
|
|
824
|
+
429: components["responses"]["RateLimited"];
|
|
825
|
+
};
|
|
826
|
+
};
|
|
827
|
+
listFindings: {
|
|
828
|
+
parameters: {
|
|
829
|
+
query?: {
|
|
830
|
+
page?: components["parameters"]["Page"];
|
|
831
|
+
limit?: components["parameters"]["Limit"];
|
|
832
|
+
/** @description Only findings belonging to this scan. */
|
|
833
|
+
scanId?: string;
|
|
834
|
+
};
|
|
835
|
+
header?: never;
|
|
836
|
+
path: {
|
|
837
|
+
projectId: components["parameters"]["ProjectId"];
|
|
838
|
+
};
|
|
839
|
+
cookie?: never;
|
|
840
|
+
};
|
|
841
|
+
requestBody?: never;
|
|
842
|
+
responses: {
|
|
843
|
+
/** @description OK */
|
|
844
|
+
200: {
|
|
845
|
+
headers: {
|
|
846
|
+
[name: string]: unknown;
|
|
847
|
+
};
|
|
848
|
+
content: {
|
|
849
|
+
"application/json": components["schemas"]["PaginatedFindings"];
|
|
850
|
+
};
|
|
851
|
+
};
|
|
852
|
+
401: components["responses"]["Unauthorized"];
|
|
853
|
+
403: components["responses"]["Forbidden"];
|
|
854
|
+
404: components["responses"]["NotFound"];
|
|
855
|
+
};
|
|
856
|
+
};
|
|
857
|
+
getFinding: {
|
|
858
|
+
parameters: {
|
|
859
|
+
query?: never;
|
|
860
|
+
header?: never;
|
|
861
|
+
path: {
|
|
862
|
+
projectId: components["parameters"]["ProjectId"];
|
|
863
|
+
findingId: components["parameters"]["FindingId"];
|
|
864
|
+
};
|
|
865
|
+
cookie?: never;
|
|
866
|
+
};
|
|
867
|
+
requestBody?: never;
|
|
868
|
+
responses: {
|
|
869
|
+
/** @description OK */
|
|
870
|
+
200: {
|
|
871
|
+
headers: {
|
|
872
|
+
[name: string]: unknown;
|
|
873
|
+
};
|
|
874
|
+
content: {
|
|
875
|
+
"application/json": {
|
|
876
|
+
finding: components["schemas"]["FindingDetail"];
|
|
877
|
+
};
|
|
878
|
+
};
|
|
879
|
+
};
|
|
880
|
+
401: components["responses"]["Unauthorized"];
|
|
881
|
+
403: components["responses"]["Forbidden"];
|
|
882
|
+
404: components["responses"]["NotFound"];
|
|
883
|
+
};
|
|
884
|
+
};
|
|
885
|
+
addFindingNote: {
|
|
886
|
+
parameters: {
|
|
887
|
+
query?: never;
|
|
888
|
+
header?: never;
|
|
889
|
+
path: {
|
|
890
|
+
projectId: components["parameters"]["ProjectId"];
|
|
891
|
+
findingId: components["parameters"]["FindingId"];
|
|
892
|
+
};
|
|
893
|
+
cookie?: never;
|
|
894
|
+
};
|
|
895
|
+
requestBody: {
|
|
896
|
+
content: {
|
|
897
|
+
"application/json": {
|
|
898
|
+
/** @description The comment body (markdown). */
|
|
899
|
+
content: string;
|
|
900
|
+
};
|
|
901
|
+
};
|
|
902
|
+
};
|
|
903
|
+
responses: {
|
|
904
|
+
/** @description Note created */
|
|
905
|
+
201: {
|
|
906
|
+
headers: {
|
|
907
|
+
[name: string]: unknown;
|
|
908
|
+
};
|
|
909
|
+
content: {
|
|
910
|
+
"application/json": components["schemas"]["FindingNoteResult"];
|
|
911
|
+
};
|
|
912
|
+
};
|
|
913
|
+
400: components["responses"]["BadRequest"];
|
|
914
|
+
401: components["responses"]["Unauthorized"];
|
|
915
|
+
403: components["responses"]["Forbidden"];
|
|
916
|
+
404: components["responses"]["NotFound"];
|
|
917
|
+
};
|
|
918
|
+
};
|
|
919
|
+
pinFindingNote: {
|
|
920
|
+
parameters: {
|
|
921
|
+
query?: never;
|
|
922
|
+
header?: never;
|
|
923
|
+
path: {
|
|
924
|
+
projectId: components["parameters"]["ProjectId"];
|
|
925
|
+
findingId: components["parameters"]["FindingId"];
|
|
926
|
+
noteId: string;
|
|
927
|
+
};
|
|
928
|
+
cookie?: never;
|
|
929
|
+
};
|
|
930
|
+
requestBody: {
|
|
931
|
+
content: {
|
|
932
|
+
"application/json": {
|
|
933
|
+
/** @enum {string} */
|
|
934
|
+
kind: "resolution";
|
|
935
|
+
};
|
|
936
|
+
};
|
|
937
|
+
};
|
|
938
|
+
responses: {
|
|
939
|
+
/** @description OK */
|
|
940
|
+
200: {
|
|
941
|
+
headers: {
|
|
942
|
+
[name: string]: unknown;
|
|
943
|
+
};
|
|
944
|
+
content: {
|
|
945
|
+
"application/json": components["schemas"]["FindingPinResult"];
|
|
946
|
+
};
|
|
947
|
+
};
|
|
948
|
+
400: components["responses"]["BadRequest"];
|
|
949
|
+
401: components["responses"]["Unauthorized"];
|
|
950
|
+
403: components["responses"]["Forbidden"];
|
|
951
|
+
404: components["responses"]["NotFound"];
|
|
952
|
+
};
|
|
953
|
+
};
|
|
954
|
+
updateFindingSeverity: {
|
|
955
|
+
parameters: {
|
|
956
|
+
query?: never;
|
|
957
|
+
header?: never;
|
|
958
|
+
path: {
|
|
959
|
+
projectId: components["parameters"]["ProjectId"];
|
|
960
|
+
findingId: components["parameters"]["FindingId"];
|
|
961
|
+
};
|
|
962
|
+
cookie?: never;
|
|
963
|
+
};
|
|
964
|
+
requestBody: {
|
|
965
|
+
content: {
|
|
966
|
+
"application/json": {
|
|
967
|
+
/** @description New severity override, or null to clear. */
|
|
968
|
+
severity: components["schemas"]["Severity"] | null;
|
|
969
|
+
};
|
|
970
|
+
};
|
|
971
|
+
};
|
|
972
|
+
responses: {
|
|
973
|
+
/** @description OK */
|
|
974
|
+
200: {
|
|
975
|
+
headers: {
|
|
976
|
+
[name: string]: unknown;
|
|
977
|
+
};
|
|
978
|
+
content: {
|
|
979
|
+
"application/json": components["schemas"]["FindingSeverityResult"];
|
|
980
|
+
};
|
|
981
|
+
};
|
|
982
|
+
400: components["responses"]["BadRequest"];
|
|
983
|
+
401: components["responses"]["Unauthorized"];
|
|
984
|
+
403: components["responses"]["Forbidden"];
|
|
985
|
+
404: components["responses"]["NotFound"];
|
|
986
|
+
};
|
|
987
|
+
};
|
|
988
|
+
updateFindingResolution: {
|
|
989
|
+
parameters: {
|
|
990
|
+
query?: never;
|
|
991
|
+
header?: never;
|
|
992
|
+
path: {
|
|
993
|
+
projectId: components["parameters"]["ProjectId"];
|
|
994
|
+
findingId: components["parameters"]["FindingId"];
|
|
995
|
+
};
|
|
996
|
+
cookie?: never;
|
|
997
|
+
};
|
|
998
|
+
requestBody: {
|
|
999
|
+
content: {
|
|
1000
|
+
"application/json": {
|
|
1001
|
+
resolutionStatus: components["schemas"]["ResolutionStatus"];
|
|
1002
|
+
note?: components["schemas"]["ChangeNote"];
|
|
1003
|
+
};
|
|
1004
|
+
};
|
|
1005
|
+
};
|
|
1006
|
+
responses: {
|
|
1007
|
+
/** @description OK */
|
|
1008
|
+
200: {
|
|
1009
|
+
headers: {
|
|
1010
|
+
[name: string]: unknown;
|
|
1011
|
+
};
|
|
1012
|
+
content: {
|
|
1013
|
+
"application/json": components["schemas"]["FindingResolutionResult"];
|
|
1014
|
+
};
|
|
1015
|
+
};
|
|
1016
|
+
400: components["responses"]["BadRequest"];
|
|
1017
|
+
401: components["responses"]["Unauthorized"];
|
|
1018
|
+
403: components["responses"]["Forbidden"];
|
|
1019
|
+
404: components["responses"]["NotFound"];
|
|
1020
|
+
};
|
|
1021
|
+
};
|
|
1022
|
+
publishFinding: {
|
|
1023
|
+
parameters: {
|
|
1024
|
+
query?: never;
|
|
1025
|
+
header?: never;
|
|
1026
|
+
path: {
|
|
1027
|
+
projectId: components["parameters"]["ProjectId"];
|
|
1028
|
+
findingId: components["parameters"]["FindingId"];
|
|
1029
|
+
};
|
|
1030
|
+
cookie?: never;
|
|
1031
|
+
};
|
|
1032
|
+
requestBody?: {
|
|
1033
|
+
content: {
|
|
1034
|
+
"application/json": components["schemas"]["PublishFindingRequest"];
|
|
1035
|
+
};
|
|
1036
|
+
};
|
|
1037
|
+
responses: {
|
|
1038
|
+
/** @description OK */
|
|
1039
|
+
200: {
|
|
1040
|
+
headers: {
|
|
1041
|
+
[name: string]: unknown;
|
|
1042
|
+
};
|
|
1043
|
+
content: {
|
|
1044
|
+
"application/json": components["schemas"]["PublishArtifactResult"];
|
|
1045
|
+
};
|
|
1046
|
+
};
|
|
1047
|
+
400: components["responses"]["BadRequest"];
|
|
1048
|
+
401: components["responses"]["Unauthorized"];
|
|
1049
|
+
403: components["responses"]["Forbidden"];
|
|
1050
|
+
404: components["responses"]["NotFound"];
|
|
1051
|
+
};
|
|
1052
|
+
};
|
|
1053
|
+
publishScan: {
|
|
1054
|
+
parameters: {
|
|
1055
|
+
query?: never;
|
|
1056
|
+
header?: never;
|
|
1057
|
+
path: {
|
|
1058
|
+
projectId: components["parameters"]["ProjectId"];
|
|
1059
|
+
scanId: components["parameters"]["ScanId"];
|
|
1060
|
+
};
|
|
1061
|
+
cookie?: never;
|
|
1062
|
+
};
|
|
1063
|
+
requestBody?: {
|
|
1064
|
+
content: {
|
|
1065
|
+
"application/json": components["schemas"]["PublishScanRequest"];
|
|
1066
|
+
};
|
|
1067
|
+
};
|
|
1068
|
+
responses: {
|
|
1069
|
+
/** @description OK */
|
|
1070
|
+
200: {
|
|
1071
|
+
headers: {
|
|
1072
|
+
[name: string]: unknown;
|
|
1073
|
+
};
|
|
1074
|
+
content: {
|
|
1075
|
+
"application/json": components["schemas"]["PublishArtifactResult"];
|
|
1076
|
+
};
|
|
1077
|
+
};
|
|
1078
|
+
400: components["responses"]["BadRequest"];
|
|
1079
|
+
401: components["responses"]["Unauthorized"];
|
|
1080
|
+
403: components["responses"]["Forbidden"];
|
|
1081
|
+
404: components["responses"]["NotFound"];
|
|
1082
|
+
};
|
|
1083
|
+
};
|
|
1084
|
+
listScanPresets: {
|
|
1085
|
+
parameters: {
|
|
1086
|
+
query?: never;
|
|
1087
|
+
header?: never;
|
|
1088
|
+
path: {
|
|
1089
|
+
projectId: components["parameters"]["ProjectId"];
|
|
1090
|
+
};
|
|
1091
|
+
cookie?: never;
|
|
1092
|
+
};
|
|
1093
|
+
requestBody?: never;
|
|
1094
|
+
responses: {
|
|
1095
|
+
/** @description OK */
|
|
1096
|
+
200: {
|
|
1097
|
+
headers: {
|
|
1098
|
+
[name: string]: unknown;
|
|
1099
|
+
};
|
|
1100
|
+
content: {
|
|
1101
|
+
"application/json": {
|
|
1102
|
+
presets: components["schemas"]["ScanPreset"][];
|
|
1103
|
+
};
|
|
1104
|
+
};
|
|
1105
|
+
};
|
|
1106
|
+
401: components["responses"]["Unauthorized"];
|
|
1107
|
+
403: components["responses"]["Forbidden"];
|
|
1108
|
+
404: components["responses"]["NotFound"];
|
|
1109
|
+
};
|
|
1110
|
+
};
|
|
1111
|
+
listOptionalFlows: {
|
|
1112
|
+
parameters: {
|
|
1113
|
+
query?: never;
|
|
1114
|
+
header?: never;
|
|
1115
|
+
path: {
|
|
1116
|
+
projectId: components["parameters"]["ProjectId"];
|
|
1117
|
+
};
|
|
1118
|
+
cookie?: never;
|
|
1119
|
+
};
|
|
1120
|
+
requestBody?: never;
|
|
1121
|
+
responses: {
|
|
1122
|
+
/** @description OK */
|
|
1123
|
+
200: {
|
|
1124
|
+
headers: {
|
|
1125
|
+
[name: string]: unknown;
|
|
1126
|
+
};
|
|
1127
|
+
content: {
|
|
1128
|
+
"application/json": {
|
|
1129
|
+
optionalFlows: components["schemas"]["OptionalFlow"][];
|
|
1130
|
+
};
|
|
1131
|
+
};
|
|
1132
|
+
};
|
|
1133
|
+
401: components["responses"]["Unauthorized"];
|
|
1134
|
+
403: components["responses"]["Forbidden"];
|
|
1135
|
+
404: components["responses"]["NotFound"];
|
|
1136
|
+
};
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
type Schemas = components["schemas"];
|
|
1141
|
+
type Repository = Schemas["Repository"];
|
|
1142
|
+
type Scan = Schemas["Scan"];
|
|
1143
|
+
type ScanDetail = Schemas["ScanDetail"];
|
|
1144
|
+
type Finding = Schemas["Finding"];
|
|
1145
|
+
type FindingDetail = Schemas["FindingDetail"];
|
|
1146
|
+
type FindingNote = Schemas["FindingNote"];
|
|
1147
|
+
type ScanPreset = Schemas["ScanPreset"];
|
|
1148
|
+
type OptionalFlow = Schemas["OptionalFlow"];
|
|
1149
|
+
type LaunchScanRequest = Schemas["LaunchScanRequest"];
|
|
1150
|
+
type LaunchScanResult = Schemas["LaunchScanResult"];
|
|
1151
|
+
type CancelScanResult = Schemas["CancelScanResult"];
|
|
1152
|
+
type ChangeNote = Schemas["ChangeNote"];
|
|
1153
|
+
type Severity = Schemas["Severity"];
|
|
1154
|
+
type ResolutionStatus = Schemas["ResolutionStatus"];
|
|
1155
|
+
type TriageStatus = Schemas["TriageStatus"];
|
|
1156
|
+
type ScanStatus = Schemas["ScanStatus"];
|
|
1157
|
+
type PublishArtifactResult = Schemas["PublishArtifactResult"];
|
|
1158
|
+
type RepositoryGuidance = Schemas["RepositoryGuidance"];
|
|
1159
|
+
type SetGuidanceResult = Schemas["SetGuidanceResult"];
|
|
1160
|
+
type Paginated<T> = {
|
|
1161
|
+
items: T[];
|
|
1162
|
+
page: number;
|
|
1163
|
+
limit: number;
|
|
1164
|
+
total: number;
|
|
1165
|
+
};
|
|
1166
|
+
type ZkaoClientOptions = {
|
|
1167
|
+
/** A project API token: `zkao_proj_<keyId>_<secret>`. */
|
|
1168
|
+
token: string;
|
|
1169
|
+
/** The id of the project the token belongs to. */
|
|
1170
|
+
projectId: string;
|
|
1171
|
+
/**
|
|
1172
|
+
* API base URL, used verbatim. When omitted, resolved from `ZKAO_URL`
|
|
1173
|
+
* (see {@link resolveBaseUrlFromEnv}), falling back to production
|
|
1174
|
+
* (`https://zkao.io/api/v1`).
|
|
1175
|
+
*/
|
|
1176
|
+
baseUrl?: string;
|
|
1177
|
+
/** Optional custom fetch (e.g. for tests or proxies). */
|
|
1178
|
+
fetch?: typeof fetch;
|
|
1179
|
+
};
|
|
1180
|
+
/** Terminal scan statuses: polling can stop once a scan reaches one of these. */
|
|
1181
|
+
declare const TERMINAL_SCAN_STATUSES: readonly ScanStatus[];
|
|
1182
|
+
declare function isTerminalScanStatus(status: ScanStatus): boolean;
|
|
1183
|
+
type WaitForScanOptions = {
|
|
1184
|
+
/** First poll delay, in ms (default 5000). Grows with backoff up to maxIntervalMs. */
|
|
1185
|
+
intervalMs?: number;
|
|
1186
|
+
/** Cap on the poll delay, in ms (default 30000). */
|
|
1187
|
+
maxIntervalMs?: number;
|
|
1188
|
+
/** Give up after this long, in ms (default 1h). Throws on timeout. */
|
|
1189
|
+
timeoutMs?: number;
|
|
1190
|
+
/** Abort the wait (e.g. on Ctrl-C). Rejects with the abort reason. */
|
|
1191
|
+
signal?: AbortSignal;
|
|
1192
|
+
/** Called with the latest detail on each non-terminal poll (for progress UI). */
|
|
1193
|
+
onPoll?: (scan: ScanDetail) => void;
|
|
1194
|
+
};
|
|
1195
|
+
/** Thrown for any non-2xx response, carrying the API error envelope. */
|
|
1196
|
+
declare class ZkaoApiError extends Error {
|
|
1197
|
+
readonly status: number;
|
|
1198
|
+
readonly code: string;
|
|
1199
|
+
constructor(status: number, code: string, message: string);
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Typed client for one zkao project. Every call is scoped to the project the
|
|
1203
|
+
* token belongs to; see https://zkao.io/openapi/v1.yaml for the full contract.
|
|
1204
|
+
*/
|
|
1205
|
+
declare class ZkaoClient {
|
|
1206
|
+
private readonly http;
|
|
1207
|
+
private readonly projectId;
|
|
1208
|
+
constructor(options: ZkaoClientOptions);
|
|
1209
|
+
private get path();
|
|
1210
|
+
listRepositories(): Promise<Repository[]>;
|
|
1211
|
+
/** Read a repository's configured guidance (requires the `read` scope). */
|
|
1212
|
+
getRepositoryGuidance(repositoryId: string): Promise<RepositoryGuidance>;
|
|
1213
|
+
/**
|
|
1214
|
+
* Set (or clear, with `null`) a repository's guidance (requires the
|
|
1215
|
+
* `guidance:write` scope). Pass `expectedContent` for an optimistic
|
|
1216
|
+
* compare-and-set: send the content you last read (or `null` for "currently
|
|
1217
|
+
* cleared") to get a `409` instead of clobbering a concurrent change. Writing
|
|
1218
|
+
* the same content that is already stored is a no-op (`unchanged: true`).
|
|
1219
|
+
*/
|
|
1220
|
+
setRepositoryGuidance(repositoryId: string, content: string | null, opts?: {
|
|
1221
|
+
expectedContent?: string | null;
|
|
1222
|
+
}): Promise<SetGuidanceResult>;
|
|
1223
|
+
listScans(opts?: {
|
|
1224
|
+
page?: number;
|
|
1225
|
+
limit?: number;
|
|
1226
|
+
}): Promise<Paginated<Scan>>;
|
|
1227
|
+
getScan(scanId: string): Promise<ScanDetail>;
|
|
1228
|
+
/**
|
|
1229
|
+
* Poll a scan until it reaches a terminal status (COMPLETED / FAILED /
|
|
1230
|
+
* CANCELLED) and return the final detail. Honors the server's `Retry-After`
|
|
1231
|
+
* header when present; otherwise backs off exponentially with jitter between
|
|
1232
|
+
* `intervalMs` and `maxIntervalMs`. A `429` is treated as "slow down", not an
|
|
1233
|
+
* error. Prefer this over a hand-rolled `getScan` loop so the server is not
|
|
1234
|
+
* hammered.
|
|
1235
|
+
*/
|
|
1236
|
+
waitForScan(scanId: string, opts?: WaitForScanOptions): Promise<ScanDetail>;
|
|
1237
|
+
launchScan(body: LaunchScanRequest): Promise<LaunchScanResult>;
|
|
1238
|
+
/**
|
|
1239
|
+
* Cancel a running or queued scan. Signals in-flight jobs to stop, marks the
|
|
1240
|
+
* scan CANCELLED, and releases its reserved credits. A scan already in a
|
|
1241
|
+
* terminal COMPLETED/FAILED state cannot be cancelled.
|
|
1242
|
+
*/
|
|
1243
|
+
cancelScan(scanId: string): Promise<CancelScanResult>;
|
|
1244
|
+
publishScan(scanId: string, opts?: {
|
|
1245
|
+
withPassword?: boolean;
|
|
1246
|
+
}): Promise<PublishArtifactResult>;
|
|
1247
|
+
listFindings(opts?: {
|
|
1248
|
+
page?: number;
|
|
1249
|
+
limit?: number;
|
|
1250
|
+
scanId?: string;
|
|
1251
|
+
}): Promise<Paginated<Finding>>;
|
|
1252
|
+
getFinding(findingId: string): Promise<FindingDetail>;
|
|
1253
|
+
addFindingNote(findingId: string, content: string): Promise<{
|
|
1254
|
+
noteId: string;
|
|
1255
|
+
findingId: string;
|
|
1256
|
+
}>;
|
|
1257
|
+
pinFindingNote(findingId: string, noteId: string, kind?: "resolution"): Promise<{
|
|
1258
|
+
findingId: string;
|
|
1259
|
+
noteId: string | null;
|
|
1260
|
+
}>;
|
|
1261
|
+
setFindingSeverity(findingId: string, severity: Severity | null): Promise<{
|
|
1262
|
+
findingId: string;
|
|
1263
|
+
userSeverity?: Severity | null;
|
|
1264
|
+
effectiveSeverity: Severity;
|
|
1265
|
+
}>;
|
|
1266
|
+
setFindingResolution(findingId: string, resolutionStatus: ResolutionStatus, note?: ChangeNote): Promise<{
|
|
1267
|
+
findingId: string;
|
|
1268
|
+
resolutionStatus: ResolutionStatus;
|
|
1269
|
+
}>;
|
|
1270
|
+
publishFinding(findingId: string, opts?: {
|
|
1271
|
+
noteId?: string;
|
|
1272
|
+
withPassword?: boolean;
|
|
1273
|
+
}): Promise<PublishArtifactResult>;
|
|
1274
|
+
listScanPresets(): Promise<ScanPreset[]>;
|
|
1275
|
+
listOptionalFlows(): Promise<OptionalFlow[]>;
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
export { type CancelScanResult, type ChangeNote, DEFAULT_BASE_URL, type Finding, type FindingDetail, type FindingNote, type LaunchScanRequest, type LaunchScanResult, type OptionalFlow, type Paginated, type PublishArtifactResult, type Repository, type ResolutionStatus, type Scan, type ScanDetail, type ScanPreset, type ScanStatus, type Severity, TERMINAL_SCAN_STATUSES, type TriageStatus, type WaitForScanOptions, ZkaoApiError, ZkaoClient, type ZkaoClientOptions, type components, isTerminalScanStatus, normalizeBaseUrl, type paths, resolveBaseUrlFromEnv };
|