@zksecurity/zkao-sdk 0.2.0 → 0.5.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/dist/index.d.ts +260 -5
- package/dist/index.js +98 -0
- package/package.json +6 -2
package/dist/index.d.ts
CHANGED
|
@@ -73,6 +73,50 @@ interface paths {
|
|
|
73
73
|
patch?: never;
|
|
74
74
|
trace?: never;
|
|
75
75
|
};
|
|
76
|
+
"/projects/{projectId}/repositories/{repositoryId}/audit-areas": {
|
|
77
|
+
parameters: {
|
|
78
|
+
query?: never;
|
|
79
|
+
header?: never;
|
|
80
|
+
path?: never;
|
|
81
|
+
cookie?: never;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* List a repository's audit areas
|
|
85
|
+
* @description Requires scope: `read`. Audit areas are the named subsystems a scan can be scoped to (`auditAreaKeys` on launch). Each scan that maps the repository keeps the list current; sizes come from one branch's map, so an area that map no longer names is returned without one.
|
|
86
|
+
*/
|
|
87
|
+
get: operations["listAuditAreas"];
|
|
88
|
+
put?: never;
|
|
89
|
+
/**
|
|
90
|
+
* Add a custom audit area
|
|
91
|
+
* @description Requires scope: `guidance:write`. An area is a name and a description, never a file list: a scan resolves it against the code at the commit it runs on. The `key` is derived from the name and disambiguated on collision.
|
|
92
|
+
*/
|
|
93
|
+
post: operations["createAuditArea"];
|
|
94
|
+
delete?: never;
|
|
95
|
+
options?: never;
|
|
96
|
+
head?: never;
|
|
97
|
+
patch?: never;
|
|
98
|
+
trace?: never;
|
|
99
|
+
};
|
|
100
|
+
"/projects/{projectId}/repositories/{repositoryId}/audit-areas/{areaKey}": {
|
|
101
|
+
parameters: {
|
|
102
|
+
query?: never;
|
|
103
|
+
header?: never;
|
|
104
|
+
path?: never;
|
|
105
|
+
cookie?: never;
|
|
106
|
+
};
|
|
107
|
+
get?: never;
|
|
108
|
+
put?: never;
|
|
109
|
+
post?: never;
|
|
110
|
+
/**
|
|
111
|
+
* Delete a custom audit area
|
|
112
|
+
* @description Requires scope: `guidance:write`. Only an area with `source: custom` can be deleted; a discovered one is the map's own account of the repository and is refused with `409`. Scans that already ran keep the scope they ran with.
|
|
113
|
+
*/
|
|
114
|
+
delete: operations["deleteAuditArea"];
|
|
115
|
+
options?: never;
|
|
116
|
+
head?: never;
|
|
117
|
+
patch?: never;
|
|
118
|
+
trace?: never;
|
|
119
|
+
};
|
|
76
120
|
"/projects/{projectId}/scans": {
|
|
77
121
|
parameters: {
|
|
78
122
|
query?: never;
|
|
@@ -93,6 +137,10 @@ interface paths {
|
|
|
93
137
|
* ACTIVE. Discover valid `presetRef` / `optInFlowIds` via the discovery
|
|
94
138
|
* endpoints. Per-token spend limits are enforced, and the project must have
|
|
95
139
|
* enough prepaid credits to cover the budget (otherwise `402`).
|
|
140
|
+
*
|
|
141
|
+
* A repository added moments ago may still be analyzing, in which case
|
|
142
|
+
* this returns `409 repository_initializing`. Wait for its `readiness` to
|
|
143
|
+
* be `ready` in `GET /repositories` and launch again.
|
|
96
144
|
*/
|
|
97
145
|
post: operations["launchScan"];
|
|
98
146
|
delete?: never;
|
|
@@ -330,7 +378,7 @@ interface paths {
|
|
|
330
378
|
};
|
|
331
379
|
/**
|
|
332
380
|
* List opt-in flows available at launch
|
|
333
|
-
* @description Requires scope: `read`. Pass the chosen ids as `optInFlowIds` when launching.
|
|
381
|
+
* @description Requires scope: `read`. Pass the chosen ids as `optInFlowIds` when launching. A flow marked `rotating` may run without being asked for.
|
|
334
382
|
*/
|
|
335
383
|
get: operations["listOptionalFlows"];
|
|
336
384
|
put?: never;
|
|
@@ -445,7 +493,7 @@ interface components {
|
|
|
445
493
|
Error: {
|
|
446
494
|
error: {
|
|
447
495
|
/** @enum {string} */
|
|
448
|
-
code: "unauthorized" | "forbidden" | "not_found" | "bad_request" | "conflict" | "insufficient_credits" | "rate_limited" | "internal";
|
|
496
|
+
code: "unauthorized" | "forbidden" | "not_found" | "bad_request" | "conflict" | "insufficient_credits" | "repository_initializing" | "rate_limited" | "internal";
|
|
449
497
|
message: string;
|
|
450
498
|
};
|
|
451
499
|
};
|
|
@@ -465,6 +513,11 @@ interface components {
|
|
|
465
513
|
defaultBranch?: string | null;
|
|
466
514
|
/** @description ACTIVE | MARKED_FOR_DELETION */
|
|
467
515
|
status: string;
|
|
516
|
+
/**
|
|
517
|
+
* @description Whether a scan can start on this repository. A newly added repository is `analyzing` until a one-time pass over it finishes; launching a scan meanwhile fails with `repository_initializing`. Poll this endpoint rather than retrying the launch blind.
|
|
518
|
+
* @enum {string}
|
|
519
|
+
*/
|
|
520
|
+
readiness: "ready" | "analyzing";
|
|
468
521
|
};
|
|
469
522
|
Scan: {
|
|
470
523
|
id: string;
|
|
@@ -557,7 +610,7 @@ interface components {
|
|
|
557
610
|
ref: string;
|
|
558
611
|
name: string;
|
|
559
612
|
description?: string | null;
|
|
560
|
-
/** @description 0 = use the default floor. */
|
|
613
|
+
/** @description Minimum budget for a launch that names no optInFlowIds. Adding a flow raises it. 0 = use the default floor. */
|
|
561
614
|
minCredits: number;
|
|
562
615
|
modelTier: string;
|
|
563
616
|
};
|
|
@@ -567,6 +620,8 @@ interface components {
|
|
|
567
620
|
flowId: string;
|
|
568
621
|
title: string;
|
|
569
622
|
description: string;
|
|
623
|
+
/** @description True when this flow belongs to a group the preset rotates through. Some of the group runs on every scan without being asked for, and which members depends on the repository. Naming it in `optInFlowIds` adds it whether or not the rotation picked it, and raises the scan's minimum budget. */
|
|
624
|
+
rotating: boolean;
|
|
570
625
|
};
|
|
571
626
|
LaunchScanRequest: {
|
|
572
627
|
repositoryId: string;
|
|
@@ -579,8 +634,10 @@ interface components {
|
|
|
579
634
|
/** @description Pin a specific commit SHA (7-40 hex chars). */
|
|
580
635
|
commitHash?: string | null;
|
|
581
636
|
commitMessage?: string | null;
|
|
582
|
-
/** @description Optional-flow ids from /optional-flows. */
|
|
637
|
+
/** @description Optional-flow ids from /optional-flows, added to the scan on top of whatever a rotating group already contributes. */
|
|
583
638
|
optInFlowIds?: string[];
|
|
639
|
+
/** @description Area keys from /audit-areas to scope this scan to. Omit or send an empty array to scan the whole repository. A key the repository's current map no longer names fails the launch rather than being dropped, so a scan budgeted for one subsystem never silently runs against everything. */
|
|
640
|
+
auditAreaKeys?: string[];
|
|
584
641
|
/** @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. */
|
|
585
642
|
guidance?: string | null;
|
|
586
643
|
};
|
|
@@ -611,6 +668,44 @@ interface components {
|
|
|
611
668
|
/** @description True when the content already matched (no revision recorded). */
|
|
612
669
|
unchanged: boolean;
|
|
613
670
|
};
|
|
671
|
+
AuditArea: {
|
|
672
|
+
/** @description Stable slug, unique per repository. Pass it in `auditAreaKeys` when launching a scan. */
|
|
673
|
+
key: string;
|
|
674
|
+
name: string;
|
|
675
|
+
description: string | null;
|
|
676
|
+
/**
|
|
677
|
+
* @description `discovered` was named by a scan's map of the repository; `custom` was added through this API or the app.
|
|
678
|
+
* @enum {string}
|
|
679
|
+
*/
|
|
680
|
+
source: "discovered" | "custom";
|
|
681
|
+
/** @description Whether the branch's latest map still names this area. */
|
|
682
|
+
inLatestMap: boolean;
|
|
683
|
+
/** @description Files this area covers at that map. Null when the map does not name it. */
|
|
684
|
+
files: number | null;
|
|
685
|
+
/** @description Lines this area covers at that map. Null when the map does not name it. */
|
|
686
|
+
lines: number | null;
|
|
687
|
+
};
|
|
688
|
+
AuditAreaList: {
|
|
689
|
+
repositoryId: string;
|
|
690
|
+
/** @description Branch the sizes were read from. */
|
|
691
|
+
branch: string | null;
|
|
692
|
+
/** @description Whether that branch has a stored map at all. */
|
|
693
|
+
mapped: boolean;
|
|
694
|
+
totalFiles: number | null;
|
|
695
|
+
totalLines: number | null;
|
|
696
|
+
/** @description The map's own audit order first, then the areas it no longer names. */
|
|
697
|
+
areas: components["schemas"]["AuditArea"][];
|
|
698
|
+
};
|
|
699
|
+
CreateAuditAreaRequest: {
|
|
700
|
+
name: string;
|
|
701
|
+
/** @description What this part of the code does. */
|
|
702
|
+
description?: string | null;
|
|
703
|
+
};
|
|
704
|
+
DeleteAuditAreaResult: {
|
|
705
|
+
repositoryId: string;
|
|
706
|
+
key: string;
|
|
707
|
+
deleted: boolean;
|
|
708
|
+
};
|
|
614
709
|
CancelScanResult: {
|
|
615
710
|
scanId: string;
|
|
616
711
|
/** @description Terminal status after cancellation (always CANCELLED). */
|
|
@@ -696,6 +791,15 @@ interface components {
|
|
|
696
791
|
"application/json": components["schemas"]["Error"];
|
|
697
792
|
};
|
|
698
793
|
};
|
|
794
|
+
/** @description The repository is still being analyzed and cannot be scanned yet. The same request succeeds once `GET /repositories` reports its `readiness` as `ready`. (code `repository_initializing`) */
|
|
795
|
+
RepositoryInitializing: {
|
|
796
|
+
headers: {
|
|
797
|
+
[name: string]: unknown;
|
|
798
|
+
};
|
|
799
|
+
content: {
|
|
800
|
+
"application/json": components["schemas"]["Error"];
|
|
801
|
+
};
|
|
802
|
+
};
|
|
699
803
|
/** @description The token lacks the required scope */
|
|
700
804
|
Forbidden: {
|
|
701
805
|
headers: {
|
|
@@ -738,6 +842,7 @@ interface components {
|
|
|
738
842
|
parameters: {
|
|
739
843
|
ProjectId: string;
|
|
740
844
|
ScanId: string;
|
|
845
|
+
/** @description The finding id, or the `ZK-` label shown on the finding page (the id's last eight characters, prefix optional). A label that matches more than one finding in the project is refused with `409 conflict`; use the full id. */
|
|
741
846
|
FindingId: string;
|
|
742
847
|
RepositoryId: string;
|
|
743
848
|
Page: number;
|
|
@@ -833,6 +938,97 @@ interface operations {
|
|
|
833
938
|
409: components["responses"]["Conflict"];
|
|
834
939
|
};
|
|
835
940
|
};
|
|
941
|
+
listAuditAreas: {
|
|
942
|
+
parameters: {
|
|
943
|
+
query?: {
|
|
944
|
+
/** @description Branch whose map the sizes come from. Defaults to the repository's default branch. */
|
|
945
|
+
branch?: string;
|
|
946
|
+
};
|
|
947
|
+
header?: never;
|
|
948
|
+
path: {
|
|
949
|
+
projectId: components["parameters"]["ProjectId"];
|
|
950
|
+
repositoryId: components["parameters"]["RepositoryId"];
|
|
951
|
+
};
|
|
952
|
+
cookie?: never;
|
|
953
|
+
};
|
|
954
|
+
requestBody?: never;
|
|
955
|
+
responses: {
|
|
956
|
+
/** @description OK */
|
|
957
|
+
200: {
|
|
958
|
+
headers: {
|
|
959
|
+
[name: string]: unknown;
|
|
960
|
+
};
|
|
961
|
+
content: {
|
|
962
|
+
"application/json": components["schemas"]["AuditAreaList"];
|
|
963
|
+
};
|
|
964
|
+
};
|
|
965
|
+
401: components["responses"]["Unauthorized"];
|
|
966
|
+
403: components["responses"]["Forbidden"];
|
|
967
|
+
404: components["responses"]["NotFound"];
|
|
968
|
+
};
|
|
969
|
+
};
|
|
970
|
+
createAuditArea: {
|
|
971
|
+
parameters: {
|
|
972
|
+
query?: never;
|
|
973
|
+
header?: never;
|
|
974
|
+
path: {
|
|
975
|
+
projectId: components["parameters"]["ProjectId"];
|
|
976
|
+
repositoryId: components["parameters"]["RepositoryId"];
|
|
977
|
+
};
|
|
978
|
+
cookie?: never;
|
|
979
|
+
};
|
|
980
|
+
requestBody: {
|
|
981
|
+
content: {
|
|
982
|
+
"application/json": components["schemas"]["CreateAuditAreaRequest"];
|
|
983
|
+
};
|
|
984
|
+
};
|
|
985
|
+
responses: {
|
|
986
|
+
/** @description Created */
|
|
987
|
+
201: {
|
|
988
|
+
headers: {
|
|
989
|
+
[name: string]: unknown;
|
|
990
|
+
};
|
|
991
|
+
content: {
|
|
992
|
+
"application/json": {
|
|
993
|
+
area: components["schemas"]["AuditArea"];
|
|
994
|
+
};
|
|
995
|
+
};
|
|
996
|
+
};
|
|
997
|
+
400: components["responses"]["BadRequest"];
|
|
998
|
+
401: components["responses"]["Unauthorized"];
|
|
999
|
+
403: components["responses"]["Forbidden"];
|
|
1000
|
+
404: components["responses"]["NotFound"];
|
|
1001
|
+
409: components["responses"]["Conflict"];
|
|
1002
|
+
};
|
|
1003
|
+
};
|
|
1004
|
+
deleteAuditArea: {
|
|
1005
|
+
parameters: {
|
|
1006
|
+
query?: never;
|
|
1007
|
+
header?: never;
|
|
1008
|
+
path: {
|
|
1009
|
+
projectId: components["parameters"]["ProjectId"];
|
|
1010
|
+
repositoryId: components["parameters"]["RepositoryId"];
|
|
1011
|
+
areaKey: string;
|
|
1012
|
+
};
|
|
1013
|
+
cookie?: never;
|
|
1014
|
+
};
|
|
1015
|
+
requestBody?: never;
|
|
1016
|
+
responses: {
|
|
1017
|
+
/** @description OK */
|
|
1018
|
+
200: {
|
|
1019
|
+
headers: {
|
|
1020
|
+
[name: string]: unknown;
|
|
1021
|
+
};
|
|
1022
|
+
content: {
|
|
1023
|
+
"application/json": components["schemas"]["DeleteAuditAreaResult"];
|
|
1024
|
+
};
|
|
1025
|
+
};
|
|
1026
|
+
401: components["responses"]["Unauthorized"];
|
|
1027
|
+
403: components["responses"]["Forbidden"];
|
|
1028
|
+
404: components["responses"]["NotFound"];
|
|
1029
|
+
409: components["responses"]["Conflict"];
|
|
1030
|
+
};
|
|
1031
|
+
};
|
|
836
1032
|
listScans: {
|
|
837
1033
|
parameters: {
|
|
838
1034
|
query?: {
|
|
@@ -890,6 +1086,7 @@ interface operations {
|
|
|
890
1086
|
402: components["responses"]["InsufficientCredits"];
|
|
891
1087
|
403: components["responses"]["Forbidden"];
|
|
892
1088
|
404: components["responses"]["NotFound"];
|
|
1089
|
+
409: components["responses"]["RepositoryInitializing"];
|
|
893
1090
|
429: components["responses"]["RateLimited"];
|
|
894
1091
|
};
|
|
895
1092
|
};
|
|
@@ -988,6 +1185,7 @@ interface operations {
|
|
|
988
1185
|
header?: never;
|
|
989
1186
|
path: {
|
|
990
1187
|
projectId: components["parameters"]["ProjectId"];
|
|
1188
|
+
/** @description The finding id, or the `ZK-` label shown on the finding page (the id's last eight characters, prefix optional). A label that matches more than one finding in the project is refused with `409 conflict`; use the full id. */
|
|
991
1189
|
findingId: components["parameters"]["FindingId"];
|
|
992
1190
|
};
|
|
993
1191
|
cookie?: never;
|
|
@@ -1008,6 +1206,7 @@ interface operations {
|
|
|
1008
1206
|
401: components["responses"]["Unauthorized"];
|
|
1009
1207
|
403: components["responses"]["Forbidden"];
|
|
1010
1208
|
404: components["responses"]["NotFound"];
|
|
1209
|
+
409: components["responses"]["Conflict"];
|
|
1011
1210
|
};
|
|
1012
1211
|
};
|
|
1013
1212
|
addFindingNote: {
|
|
@@ -1016,6 +1215,7 @@ interface operations {
|
|
|
1016
1215
|
header?: never;
|
|
1017
1216
|
path: {
|
|
1018
1217
|
projectId: components["parameters"]["ProjectId"];
|
|
1218
|
+
/** @description The finding id, or the `ZK-` label shown on the finding page (the id's last eight characters, prefix optional). A label that matches more than one finding in the project is refused with `409 conflict`; use the full id. */
|
|
1019
1219
|
findingId: components["parameters"]["FindingId"];
|
|
1020
1220
|
};
|
|
1021
1221
|
cookie?: never;
|
|
@@ -1042,6 +1242,7 @@ interface operations {
|
|
|
1042
1242
|
401: components["responses"]["Unauthorized"];
|
|
1043
1243
|
403: components["responses"]["Forbidden"];
|
|
1044
1244
|
404: components["responses"]["NotFound"];
|
|
1245
|
+
409: components["responses"]["Conflict"];
|
|
1045
1246
|
};
|
|
1046
1247
|
};
|
|
1047
1248
|
pinFindingNote: {
|
|
@@ -1050,6 +1251,7 @@ interface operations {
|
|
|
1050
1251
|
header?: never;
|
|
1051
1252
|
path: {
|
|
1052
1253
|
projectId: components["parameters"]["ProjectId"];
|
|
1254
|
+
/** @description The finding id, or the `ZK-` label shown on the finding page (the id's last eight characters, prefix optional). A label that matches more than one finding in the project is refused with `409 conflict`; use the full id. */
|
|
1053
1255
|
findingId: components["parameters"]["FindingId"];
|
|
1054
1256
|
noteId: string;
|
|
1055
1257
|
};
|
|
@@ -1077,6 +1279,7 @@ interface operations {
|
|
|
1077
1279
|
401: components["responses"]["Unauthorized"];
|
|
1078
1280
|
403: components["responses"]["Forbidden"];
|
|
1079
1281
|
404: components["responses"]["NotFound"];
|
|
1282
|
+
409: components["responses"]["Conflict"];
|
|
1080
1283
|
};
|
|
1081
1284
|
};
|
|
1082
1285
|
updateFindingSeverity: {
|
|
@@ -1085,6 +1288,7 @@ interface operations {
|
|
|
1085
1288
|
header?: never;
|
|
1086
1289
|
path: {
|
|
1087
1290
|
projectId: components["parameters"]["ProjectId"];
|
|
1291
|
+
/** @description The finding id, or the `ZK-` label shown on the finding page (the id's last eight characters, prefix optional). A label that matches more than one finding in the project is refused with `409 conflict`; use the full id. */
|
|
1088
1292
|
findingId: components["parameters"]["FindingId"];
|
|
1089
1293
|
};
|
|
1090
1294
|
cookie?: never;
|
|
@@ -1111,6 +1315,7 @@ interface operations {
|
|
|
1111
1315
|
401: components["responses"]["Unauthorized"];
|
|
1112
1316
|
403: components["responses"]["Forbidden"];
|
|
1113
1317
|
404: components["responses"]["NotFound"];
|
|
1318
|
+
409: components["responses"]["Conflict"];
|
|
1114
1319
|
};
|
|
1115
1320
|
};
|
|
1116
1321
|
updateFindingResolution: {
|
|
@@ -1119,6 +1324,7 @@ interface operations {
|
|
|
1119
1324
|
header?: never;
|
|
1120
1325
|
path: {
|
|
1121
1326
|
projectId: components["parameters"]["ProjectId"];
|
|
1327
|
+
/** @description The finding id, or the `ZK-` label shown on the finding page (the id's last eight characters, prefix optional). A label that matches more than one finding in the project is refused with `409 conflict`; use the full id. */
|
|
1122
1328
|
findingId: components["parameters"]["FindingId"];
|
|
1123
1329
|
};
|
|
1124
1330
|
cookie?: never;
|
|
@@ -1146,6 +1352,7 @@ interface operations {
|
|
|
1146
1352
|
401: components["responses"]["Unauthorized"];
|
|
1147
1353
|
403: components["responses"]["Forbidden"];
|
|
1148
1354
|
404: components["responses"]["NotFound"];
|
|
1355
|
+
409: components["responses"]["Conflict"];
|
|
1149
1356
|
};
|
|
1150
1357
|
};
|
|
1151
1358
|
publishFinding: {
|
|
@@ -1154,6 +1361,7 @@ interface operations {
|
|
|
1154
1361
|
header?: never;
|
|
1155
1362
|
path: {
|
|
1156
1363
|
projectId: components["parameters"]["ProjectId"];
|
|
1364
|
+
/** @description The finding id, or the `ZK-` label shown on the finding page (the id's last eight characters, prefix optional). A label that matches more than one finding in the project is refused with `409 conflict`; use the full id. */
|
|
1157
1365
|
findingId: components["parameters"]["FindingId"];
|
|
1158
1366
|
};
|
|
1159
1367
|
cookie?: never;
|
|
@@ -1177,6 +1385,7 @@ interface operations {
|
|
|
1177
1385
|
401: components["responses"]["Unauthorized"];
|
|
1178
1386
|
403: components["responses"]["Forbidden"];
|
|
1179
1387
|
404: components["responses"]["NotFound"];
|
|
1388
|
+
409: components["responses"]["Conflict"];
|
|
1180
1389
|
};
|
|
1181
1390
|
};
|
|
1182
1391
|
publishScan: {
|
|
@@ -1368,6 +1577,9 @@ type TriageStatus = Schemas["TriageStatus"];
|
|
|
1368
1577
|
type ScanStatus = Schemas["ScanStatus"];
|
|
1369
1578
|
type PublishArtifactResult = Schemas["PublishArtifactResult"];
|
|
1370
1579
|
type RepositoryGuidance = Schemas["RepositoryGuidance"];
|
|
1580
|
+
type AuditArea = Schemas["AuditArea"];
|
|
1581
|
+
type AuditAreaList = Schemas["AuditAreaList"];
|
|
1582
|
+
type DeleteAuditAreaResult = Schemas["DeleteAuditAreaResult"];
|
|
1371
1583
|
type SetGuidanceResult = Schemas["SetGuidanceResult"];
|
|
1372
1584
|
type BillingBalance = Schemas["BillingBalance"];
|
|
1373
1585
|
type BillingUsage = Schemas["BillingUsage"];
|
|
@@ -1398,6 +1610,16 @@ type ZkaoClientOptions = {
|
|
|
1398
1610
|
/** Terminal scan statuses: polling can stop once a scan reaches one of these. */
|
|
1399
1611
|
declare const TERMINAL_SCAN_STATUSES: readonly ScanStatus[];
|
|
1400
1612
|
declare function isTerminalScanStatus(status: ScanStatus): boolean;
|
|
1613
|
+
type WaitForRepositoryReadyOptions = {
|
|
1614
|
+
/** First poll delay, in ms (default 5000). Grows with backoff up to maxIntervalMs. */
|
|
1615
|
+
intervalMs?: number;
|
|
1616
|
+
/** Cap on the poll delay, in ms (default 30000). */
|
|
1617
|
+
maxIntervalMs?: number;
|
|
1618
|
+
/** Give up after this long, in ms (default 30m). Throws on timeout. */
|
|
1619
|
+
timeoutMs?: number;
|
|
1620
|
+
/** Abort the wait (e.g. on Ctrl-C). Rejects with the abort reason. */
|
|
1621
|
+
signal?: AbortSignal;
|
|
1622
|
+
};
|
|
1401
1623
|
type WaitForScanOptions = {
|
|
1402
1624
|
/** First poll delay, in ms (default 5000). Grows with backoff up to maxIntervalMs. */
|
|
1403
1625
|
intervalMs?: number;
|
|
@@ -1426,6 +1648,15 @@ declare class ZkaoClient {
|
|
|
1426
1648
|
constructor(options: ZkaoClientOptions);
|
|
1427
1649
|
private get path();
|
|
1428
1650
|
listRepositories(): Promise<Repository[]>;
|
|
1651
|
+
/**
|
|
1652
|
+
* Block until a repository is ready to scan, then return it.
|
|
1653
|
+
*
|
|
1654
|
+
* A repository added moments ago is still being analyzed, and launching a
|
|
1655
|
+
* scan against it fails with `repository_initializing`. Call this between
|
|
1656
|
+
* adding a repository and launching its first scan rather than retrying the
|
|
1657
|
+
* launch and swallowing the error.
|
|
1658
|
+
*/
|
|
1659
|
+
waitForRepositoryReady(repositoryId: string, opts?: WaitForRepositoryReadyOptions): Promise<Repository>;
|
|
1429
1660
|
/** Read a repository's configured guidance (requires the `read` scope). */
|
|
1430
1661
|
getRepositoryGuidance(repositoryId: string): Promise<RepositoryGuidance>;
|
|
1431
1662
|
/**
|
|
@@ -1438,6 +1669,30 @@ declare class ZkaoClient {
|
|
|
1438
1669
|
setRepositoryGuidance(repositoryId: string, content: string | null, opts?: {
|
|
1439
1670
|
expectedContent?: string | null;
|
|
1440
1671
|
}): Promise<SetGuidanceResult>;
|
|
1672
|
+
/**
|
|
1673
|
+
* List a repository's audit areas (requires the `read` scope).
|
|
1674
|
+
*
|
|
1675
|
+
* An area is a named subsystem a scan can be scoped to: pass its `key` in
|
|
1676
|
+
* `auditAreaKeys` when launching. Sizes come from one branch's map, so an
|
|
1677
|
+
* area that map no longer names is returned without one. Defaults to the
|
|
1678
|
+
* repository's default branch.
|
|
1679
|
+
*/
|
|
1680
|
+
listAuditAreas(repositoryId: string, opts?: {
|
|
1681
|
+
branch?: string;
|
|
1682
|
+
}): Promise<AuditAreaList>;
|
|
1683
|
+
/**
|
|
1684
|
+
* Add a custom audit area (requires the `guidance:write` scope).
|
|
1685
|
+
*
|
|
1686
|
+
* An area is a name and a description, never a file list: a scan resolves it
|
|
1687
|
+
* against the code at the commit it runs on. The returned `key` is derived
|
|
1688
|
+
* from the name.
|
|
1689
|
+
*/
|
|
1690
|
+
createAuditArea(repositoryId: string, name: string, description?: string | null): Promise<AuditArea>;
|
|
1691
|
+
/**
|
|
1692
|
+
* Delete a custom audit area (requires the `guidance:write` scope). An area
|
|
1693
|
+
* a scan's map named is refused with a `409`.
|
|
1694
|
+
*/
|
|
1695
|
+
deleteAuditArea(repositoryId: string, areaKey: string): Promise<DeleteAuditAreaResult>;
|
|
1441
1696
|
listScans(opts?: {
|
|
1442
1697
|
page?: number;
|
|
1443
1698
|
limit?: number;
|
|
@@ -1530,4 +1785,4 @@ declare class ZkaoClient {
|
|
|
1530
1785
|
}): Promise<UsageMonthSummary[]>;
|
|
1531
1786
|
}
|
|
1532
1787
|
|
|
1533
|
-
export { type BillingBalance, type BillingSummary, type BillingUsage, 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 RepositoryGuidance, type ResolutionReason, type ResolutionStatus, type Scan, type ScanDetail, type ScanPreset, type ScanStatus, type SetGuidanceResult, type Severity, TERMINAL_SCAN_STATUSES, type TriageStatus, type UsageEvent, type UsageEventType, type UsageMonthSummary, type WaitForScanOptions, ZkaoApiError, ZkaoClient, type ZkaoClientOptions, type components, isTerminalScanStatus, normalizeBaseUrl, type paths, resolveBaseUrlFromEnv };
|
|
1788
|
+
export { type BillingBalance, type BillingSummary, type BillingUsage, 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 RepositoryGuidance, type ResolutionReason, type ResolutionStatus, type Scan, type ScanDetail, type ScanPreset, type ScanStatus, type SetGuidanceResult, type Severity, TERMINAL_SCAN_STATUSES, type TriageStatus, type UsageEvent, type UsageEventType, type UsageMonthSummary, type WaitForRepositoryReadyOptions, type WaitForScanOptions, ZkaoApiError, ZkaoClient, type ZkaoClientOptions, type components, isTerminalScanStatus, normalizeBaseUrl, type paths, resolveBaseUrlFromEnv };
|
package/dist/index.js
CHANGED
|
@@ -120,6 +120,55 @@ var ZkaoClient = class {
|
|
|
120
120
|
});
|
|
121
121
|
return unwrap(res).repositories;
|
|
122
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Block until a repository is ready to scan, then return it.
|
|
125
|
+
*
|
|
126
|
+
* A repository added moments ago is still being analyzed, and launching a
|
|
127
|
+
* scan against it fails with `repository_initializing`. Call this between
|
|
128
|
+
* adding a repository and launching its first scan rather than retrying the
|
|
129
|
+
* launch and swallowing the error.
|
|
130
|
+
*/
|
|
131
|
+
async waitForRepositoryReady(repositoryId, opts = {}) {
|
|
132
|
+
const intervalMs = opts.intervalMs ?? 5e3;
|
|
133
|
+
const maxIntervalMs = opts.maxIntervalMs ?? 3e4;
|
|
134
|
+
const timeoutMs = opts.timeoutMs ?? 30 * 60 * 1e3;
|
|
135
|
+
const deadline = Date.now() + timeoutMs;
|
|
136
|
+
for (let attempt = 0; ; attempt++) {
|
|
137
|
+
throwIfAborted(opts.signal);
|
|
138
|
+
const res = await this.http.GET("/projects/{projectId}/repositories", {
|
|
139
|
+
params: { path: this.path },
|
|
140
|
+
signal: opts.signal
|
|
141
|
+
});
|
|
142
|
+
const retryAfterMs = parseRetryAfterMs(
|
|
143
|
+
res.response.headers.get("retry-after")
|
|
144
|
+
);
|
|
145
|
+
if (res.response.status !== 429) {
|
|
146
|
+
const repository = unwrap(res).repositories.find(
|
|
147
|
+
(candidate) => candidate.id === repositoryId
|
|
148
|
+
);
|
|
149
|
+
if (!repository) {
|
|
150
|
+
throw new Error(
|
|
151
|
+
`Repository ${repositoryId} is not in this project (or this token's allowlist)`
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
if (repository.readiness === "ready") {
|
|
155
|
+
return repository;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const backoffMs = Math.min(
|
|
159
|
+
maxIntervalMs,
|
|
160
|
+
Math.round(intervalMs * 1.5 ** attempt)
|
|
161
|
+
);
|
|
162
|
+
const baseMs = retryAfterMs ?? backoffMs;
|
|
163
|
+
const delayMs = baseMs + Math.round(Math.random() * baseMs * 0.2);
|
|
164
|
+
if (Date.now() + delayMs > deadline) {
|
|
165
|
+
throw new Error(
|
|
166
|
+
`Timed out waiting for repository ${repositoryId} to be ready after ${timeoutMs}ms`
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
await sleep(delayMs, opts.signal);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
123
172
|
/** Read a repository's configured guidance (requires the `read` scope). */
|
|
124
173
|
async getRepositoryGuidance(repositoryId) {
|
|
125
174
|
const res = await this.http.GET(
|
|
@@ -145,6 +194,55 @@ var ZkaoClient = class {
|
|
|
145
194
|
);
|
|
146
195
|
return unwrap(res);
|
|
147
196
|
}
|
|
197
|
+
// --- Audit areas --------------------------------------------------------
|
|
198
|
+
/**
|
|
199
|
+
* List a repository's audit areas (requires the `read` scope).
|
|
200
|
+
*
|
|
201
|
+
* An area is a named subsystem a scan can be scoped to: pass its `key` in
|
|
202
|
+
* `auditAreaKeys` when launching. Sizes come from one branch's map, so an
|
|
203
|
+
* area that map no longer names is returned without one. Defaults to the
|
|
204
|
+
* repository's default branch.
|
|
205
|
+
*/
|
|
206
|
+
async listAuditAreas(repositoryId, opts = {}) {
|
|
207
|
+
const res = await this.http.GET(
|
|
208
|
+
"/projects/{projectId}/repositories/{repositoryId}/audit-areas",
|
|
209
|
+
{
|
|
210
|
+
params: {
|
|
211
|
+
path: { ...this.path, repositoryId },
|
|
212
|
+
query: opts.branch === void 0 ? {} : { branch: opts.branch }
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
);
|
|
216
|
+
return unwrap(res);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Add a custom audit area (requires the `guidance:write` scope).
|
|
220
|
+
*
|
|
221
|
+
* An area is a name and a description, never a file list: a scan resolves it
|
|
222
|
+
* against the code at the commit it runs on. The returned `key` is derived
|
|
223
|
+
* from the name.
|
|
224
|
+
*/
|
|
225
|
+
async createAuditArea(repositoryId, name, description) {
|
|
226
|
+
const res = await this.http.POST(
|
|
227
|
+
"/projects/{projectId}/repositories/{repositoryId}/audit-areas",
|
|
228
|
+
{
|
|
229
|
+
params: { path: { ...this.path, repositoryId } },
|
|
230
|
+
body: { name, description: description ?? null }
|
|
231
|
+
}
|
|
232
|
+
);
|
|
233
|
+
return unwrap(res).area;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Delete a custom audit area (requires the `guidance:write` scope). An area
|
|
237
|
+
* a scan's map named is refused with a `409`.
|
|
238
|
+
*/
|
|
239
|
+
async deleteAuditArea(repositoryId, areaKey) {
|
|
240
|
+
const res = await this.http.DELETE(
|
|
241
|
+
"/projects/{projectId}/repositories/{repositoryId}/audit-areas/{areaKey}",
|
|
242
|
+
{ params: { path: { ...this.path, repositoryId, areaKey } } }
|
|
243
|
+
);
|
|
244
|
+
return unwrap(res);
|
|
245
|
+
}
|
|
148
246
|
// --- Scans --------------------------------------------------------------
|
|
149
247
|
async listScans(opts = {}) {
|
|
150
248
|
const res = await this.http.GET("/projects/{projectId}/scans", {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zksecurity/zkao-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "TypeScript SDK for the zkao Project API",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "zkSecurity",
|
|
@@ -29,7 +29,11 @@
|
|
|
29
29
|
"import": "./dist/index.js"
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
|
-
"files": [
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"LICENSE",
|
|
35
|
+
"README.md"
|
|
36
|
+
],
|
|
33
37
|
"engines": {
|
|
34
38
|
"node": ">=18"
|
|
35
39
|
},
|