@zksecurity/zkao-sdk 0.5.0 → 0.11.0-next.2

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 CHANGED
@@ -29,6 +29,26 @@ declare function resolveBaseUrlFromEnv(env?: Record<string, string | undefined>)
29
29
  * Do not make direct changes to the file.
30
30
  */
31
31
  interface paths {
32
+ "/token": {
33
+ parameters: {
34
+ query?: never;
35
+ header?: never;
36
+ path?: never;
37
+ cookie?: never;
38
+ };
39
+ /**
40
+ * The calling token and its project
41
+ * @description Any valid token may call this, whatever its scopes. Use it to learn which project (and organization) a token belongs to.
42
+ */
43
+ get: operations["getTokenInfo"];
44
+ put?: never;
45
+ post?: never;
46
+ delete?: never;
47
+ options?: never;
48
+ head?: never;
49
+ patch?: never;
50
+ trace?: never;
51
+ };
32
52
  "/projects/{projectId}/repositories": {
33
53
  parameters: {
34
54
  query?: never;
@@ -134,13 +154,21 @@ interface paths {
134
154
  * Launch a scan
135
155
  * @description Requires scope: `scans:launch`. Reserves `creditBudget` credits from the
136
156
  * project balance. The repo must be in the token's allowlist (when set) and
137
- * ACTIVE. Discover valid `presetRef` / `optInFlowIds` via the discovery
138
- * endpoints. Per-token spend limits are enforced, and the project must have
139
- * enough prepaid credits to cover the budget (otherwise `402`).
157
+ * ACTIVE. Discover valid `presetRef` values via `/scan-presets`. Each scan
158
+ * type runs a fixed set of flows. Per-token spend limits are enforced, and
159
+ * the project must have enough prepaid credits to cover the budget
160
+ * (otherwise `402`).
140
161
  *
141
162
  * A repository added moments ago may still be analyzing, in which case
142
163
  * this returns `409 repository_initializing`. Wait for its `readiness` to
143
164
  * be `ready` in `GET /repositories` and launch again.
165
+ *
166
+ * A diff scan preset audits only the change from `baseCommit` to the
167
+ * scanned commit, and requires `baseCommit`. Every other preset refuses
168
+ * it. A malformed, unknown, or misplaced base is a `400` with code
169
+ * `diff_base_required`, `diff_base_not_allowed`, or `diff_base_invalid`.
170
+ * A diff scan also needs an earlier full scan of the branch, and a
171
+ * change to audit (otherwise `422`).
144
172
  */
145
173
  post: operations["launchScan"];
146
174
  delete?: never;
@@ -369,26 +397,6 @@ interface paths {
369
397
  patch?: never;
370
398
  trace?: never;
371
399
  };
372
- "/projects/{projectId}/optional-flows": {
373
- parameters: {
374
- query?: never;
375
- header?: never;
376
- path?: never;
377
- cookie?: never;
378
- };
379
- /**
380
- * List opt-in flows available at launch
381
- * @description Requires scope: `read`. Pass the chosen ids as `optInFlowIds` when launching. A flow marked `rotating` may run without being asked for.
382
- */
383
- get: operations["listOptionalFlows"];
384
- put?: never;
385
- post?: never;
386
- delete?: never;
387
- options?: never;
388
- head?: never;
389
- patch?: never;
390
- trace?: never;
391
- };
392
400
  "/projects/{projectId}/billing/balance": {
393
401
  parameters: {
394
402
  query?: never;
@@ -397,8 +405,8 @@ interface paths {
397
405
  cookie?: never;
398
406
  };
399
407
  /**
400
- * Current prepaid credit balance
401
- * @description Requires scope: `read`. All amounts are in credits.
408
+ * Credits available to this project
409
+ * @description Requires scope: `read`. The organization's shared prepaid balance, available to this project and to the organization's other projects. All amounts are in credits.
402
410
  */
403
411
  get: operations["getBillingBalance"];
404
412
  put?: never;
@@ -417,8 +425,8 @@ interface paths {
417
425
  cookie?: never;
418
426
  };
419
427
  /**
420
- * Credit usage events
421
- * @description Requires scope: `read`. Signed credit delta per ledger event. Defaults to the last 30 days; newest first; max 1000 rows.
428
+ * Credit usage events attributed to this project
429
+ * @description Requires scope: `read`. Signed credit delta per ledger event attributed to this project; organization-wide movements such as a top-up made outside any project are not included. Defaults to the last 30 days; newest first; max 1000 rows.
422
430
  */
423
431
  get: operations["getBillingUsage"];
424
432
  put?: never;
@@ -437,8 +445,8 @@ interface paths {
437
445
  cookie?: never;
438
446
  };
439
447
  /**
440
- * Monthly spend and purchase summary
441
- * @description Requires scope: `read`. Per-month net scan spend and net purchases, in credits, newest first.
448
+ * Monthly spend and purchase summary for this project
449
+ * @description Requires scope: `read`. Per-month net scan spend and net purchases attributed to this project, in credits, newest first. Purchases land in the organization's shared balance.
442
450
  */
443
451
  get: operations["getBillingSummary"];
444
452
  put?: never;
@@ -452,12 +460,38 @@ interface paths {
452
460
  }
453
461
  interface components {
454
462
  schemas: {
463
+ /** @description The organization a project belongs to. Credits are held and billed at this level and shared by every project in it. */
464
+ Organization: {
465
+ id: string;
466
+ /** @description URL segment of the organization (`/orgs/<slug>`), unique across zkao. */
467
+ slug: string;
468
+ name: string;
469
+ };
470
+ TokenInfo: {
471
+ id: string;
472
+ name: string;
473
+ scopes: string[];
474
+ /** @description Repositories the token is restricted to. Empty means every repository of the project. */
475
+ repositoryIds: string[];
476
+ /** Format: date-time */
477
+ expiresAt: string | null;
478
+ /** @description Credits this token may spend. Null means no limit. */
479
+ spendLimitCredits: number | null;
480
+ project: {
481
+ id: string;
482
+ slug: string;
483
+ name: string;
484
+ organization: components["schemas"]["Organization"];
485
+ };
486
+ };
455
487
  BillingBalance: {
456
- /** @description Total prepaid credit balance. */
488
+ /** @description The organization whose shared balance this is. */
489
+ organization: components["schemas"]["Organization"];
490
+ /** @description The organization's total prepaid credit balance, shared by all of its projects. */
457
491
  balanceCredits: number;
458
- /** @description Balance minus credits reserved by in-flight scans. */
492
+ /** @description Balance minus credits reserved by the organization's in-flight scans. */
459
493
  availableCredits: number;
460
- /** @description Credits held by queued/running scans. */
494
+ /** @description Credits held by the organization's queued/running scans. */
461
495
  reservedCredits: number;
462
496
  };
463
497
  /** @enum {string} */
@@ -488,12 +522,14 @@ interface components {
488
522
  purchasedCredits: number;
489
523
  };
490
524
  BillingSummary: {
525
+ /** @description The organization whose shared balance the purchases were made into. */
526
+ organization: components["schemas"]["Organization"];
491
527
  months: components["schemas"]["UsageMonthSummary"][];
492
528
  };
493
529
  Error: {
494
530
  error: {
495
531
  /** @enum {string} */
496
- code: "unauthorized" | "forbidden" | "not_found" | "bad_request" | "conflict" | "insufficient_credits" | "repository_initializing" | "rate_limited" | "internal";
532
+ code: "unauthorized" | "forbidden" | "not_found" | "bad_request" | "conflict" | "insufficient_credits" | "repository_initializing" | "diff_base_required" | "diff_base_not_allowed" | "diff_base_invalid" | "diff_empty" | "diff_overview_missing" | "rate_limited" | "internal";
497
533
  message: string;
498
534
  };
499
535
  };
@@ -507,6 +543,8 @@ interface components {
507
543
  ScanStatus: "QUEUED" | "PROCESSING" | "COMPLETED" | "FAILED" | "CANCELLED";
508
544
  Repository: {
509
545
  id: string;
546
+ /** @description URL segment of the repository inside its project (`/orgs/<org>/projects/<project>/repos/<slug>`). Unique per project. */
547
+ slug: string;
510
548
  owner: string;
511
549
  name: string;
512
550
  url: string;
@@ -524,6 +562,8 @@ interface components {
524
562
  status: components["schemas"]["ScanStatus"];
525
563
  repositoryId: string;
526
564
  commitHash?: string | null;
565
+ /** @description A diff scan's base, as the merge base SHA its change is measured from. Null for other scans. */
566
+ baseCommit?: string | null;
527
567
  commitMessage?: string | null;
528
568
  presetName?: string | null;
529
569
  /** Format: date-time */
@@ -564,6 +604,11 @@ interface components {
564
604
  severity: components["schemas"]["Severity"];
565
605
  category: string;
566
606
  triageStatus: components["schemas"]["TriageStatus"];
607
+ /**
608
+ * @description What backs a CONFIRMED verdict. POC means a proof of concept ran and demonstrated the issue. ANALYSIS means it was confirmed by code analysis alone. Null for other statuses or when not recorded.
609
+ * @enum {string|null}
610
+ */
611
+ confirmationEvidence?: "POC" | "ANALYSIS" | null;
567
612
  resolutionStatus: components["schemas"]["ResolutionStatus"];
568
613
  notesCount: number;
569
614
  };
@@ -610,23 +655,14 @@ interface components {
610
655
  ref: string;
611
656
  name: string;
612
657
  description?: string | null;
613
- /** @description 0 = use the default floor. */
658
+ /** @description Minimum budget for a launch. 0 = use the default floor. */
614
659
  minCredits: number;
615
660
  modelTier: string;
616
661
  };
617
- OptionalFlow: {
618
- /** @description Pass in `optInFlowIds` when launching. */
619
- id: string;
620
- flowId: string;
621
- title: string;
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;
625
- };
626
662
  LaunchScanRequest: {
627
663
  repositoryId: string;
628
- /** @description Max budget for the scan, in credits. Reserved at launch. */
629
- creditBudget: number;
664
+ /** @description Max budget for the scan, in credits. Reserved at launch. Omit it to launch at the budget zkao recommends for this scan type and scope on this repository: sized from what past scans of it spent, half again the last budget when that scan ran short of it, or the scan type's minimum on the first. */
665
+ creditBudget?: number;
630
666
  /** @description A preset ref from /scan-presets. Defaults to the first active preset. */
631
667
  presetRef?: string;
632
668
  /** @description Branch to scan (resolved to its head commit server-side). Ignored if commitHash is set. */
@@ -634,8 +670,8 @@ interface components {
634
670
  /** @description Pin a specific commit SHA (7-40 hex chars). */
635
671
  commitHash?: string | null;
636
672
  commitMessage?: string | null;
637
- /** @description Optional-flow ids from /optional-flows, added to the scan on top of whatever a rotating group already contributes. */
638
- optInFlowIds?: string[];
673
+ /** @description What a diff scan's change is measured from: a commit SHA, branch, or tag. Required by a diff scan preset and refused by every other. The scan records the merge base of this and the scanned commit. */
674
+ baseCommit?: string | null;
639
675
  /** @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
676
  auditAreaKeys?: string[];
641
677
  /** @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. */
@@ -644,6 +680,8 @@ interface components {
644
680
  LaunchScanResult: {
645
681
  scanId: string;
646
682
  queued: boolean;
683
+ /** @description The budget the scan was launched with, in credits. */
684
+ creditBudget: number;
647
685
  };
648
686
  RepositoryGuidance: {
649
687
  repositoryId: string;
@@ -800,6 +838,15 @@ interface components {
800
838
  "application/json": components["schemas"]["Error"];
801
839
  };
802
840
  };
841
+ /** @description The diff scan cannot run on this repository yet. Code `diff_empty`: the base and the scanned commit have no change between them. Code `diff_overview_missing`: no earlier full scan of the branch (or the default branch) exists to compare against. Run a full scan first. */
842
+ DiffUnavailable: {
843
+ headers: {
844
+ [name: string]: unknown;
845
+ };
846
+ content: {
847
+ "application/json": components["schemas"]["Error"];
848
+ };
849
+ };
803
850
  /** @description The token lacks the required scope */
804
851
  Forbidden: {
805
852
  headers: {
@@ -842,6 +889,7 @@ interface components {
842
889
  parameters: {
843
890
  ProjectId: string;
844
891
  ScanId: string;
892
+ /** @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. */
845
893
  FindingId: string;
846
894
  RepositoryId: string;
847
895
  Page: number;
@@ -852,6 +900,27 @@ interface components {
852
900
  pathItems: never;
853
901
  }
854
902
  interface operations {
903
+ getTokenInfo: {
904
+ parameters: {
905
+ query?: never;
906
+ header?: never;
907
+ path?: never;
908
+ cookie?: never;
909
+ };
910
+ requestBody?: never;
911
+ responses: {
912
+ /** @description OK */
913
+ 200: {
914
+ headers: {
915
+ [name: string]: unknown;
916
+ };
917
+ content: {
918
+ "application/json": components["schemas"]["TokenInfo"];
919
+ };
920
+ };
921
+ 401: components["responses"]["Unauthorized"];
922
+ };
923
+ };
855
924
  listRepositories: {
856
925
  parameters: {
857
926
  query?: never;
@@ -1086,6 +1155,7 @@ interface operations {
1086
1155
  403: components["responses"]["Forbidden"];
1087
1156
  404: components["responses"]["NotFound"];
1088
1157
  409: components["responses"]["RepositoryInitializing"];
1158
+ 422: components["responses"]["DiffUnavailable"];
1089
1159
  429: components["responses"]["RateLimited"];
1090
1160
  };
1091
1161
  };
@@ -1184,6 +1254,7 @@ interface operations {
1184
1254
  header?: never;
1185
1255
  path: {
1186
1256
  projectId: components["parameters"]["ProjectId"];
1257
+ /** @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. */
1187
1258
  findingId: components["parameters"]["FindingId"];
1188
1259
  };
1189
1260
  cookie?: never;
@@ -1204,6 +1275,7 @@ interface operations {
1204
1275
  401: components["responses"]["Unauthorized"];
1205
1276
  403: components["responses"]["Forbidden"];
1206
1277
  404: components["responses"]["NotFound"];
1278
+ 409: components["responses"]["Conflict"];
1207
1279
  };
1208
1280
  };
1209
1281
  addFindingNote: {
@@ -1212,6 +1284,7 @@ interface operations {
1212
1284
  header?: never;
1213
1285
  path: {
1214
1286
  projectId: components["parameters"]["ProjectId"];
1287
+ /** @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. */
1215
1288
  findingId: components["parameters"]["FindingId"];
1216
1289
  };
1217
1290
  cookie?: never;
@@ -1238,6 +1311,7 @@ interface operations {
1238
1311
  401: components["responses"]["Unauthorized"];
1239
1312
  403: components["responses"]["Forbidden"];
1240
1313
  404: components["responses"]["NotFound"];
1314
+ 409: components["responses"]["Conflict"];
1241
1315
  };
1242
1316
  };
1243
1317
  pinFindingNote: {
@@ -1246,6 +1320,7 @@ interface operations {
1246
1320
  header?: never;
1247
1321
  path: {
1248
1322
  projectId: components["parameters"]["ProjectId"];
1323
+ /** @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. */
1249
1324
  findingId: components["parameters"]["FindingId"];
1250
1325
  noteId: string;
1251
1326
  };
@@ -1273,6 +1348,7 @@ interface operations {
1273
1348
  401: components["responses"]["Unauthorized"];
1274
1349
  403: components["responses"]["Forbidden"];
1275
1350
  404: components["responses"]["NotFound"];
1351
+ 409: components["responses"]["Conflict"];
1276
1352
  };
1277
1353
  };
1278
1354
  updateFindingSeverity: {
@@ -1281,6 +1357,7 @@ interface operations {
1281
1357
  header?: never;
1282
1358
  path: {
1283
1359
  projectId: components["parameters"]["ProjectId"];
1360
+ /** @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. */
1284
1361
  findingId: components["parameters"]["FindingId"];
1285
1362
  };
1286
1363
  cookie?: never;
@@ -1307,6 +1384,7 @@ interface operations {
1307
1384
  401: components["responses"]["Unauthorized"];
1308
1385
  403: components["responses"]["Forbidden"];
1309
1386
  404: components["responses"]["NotFound"];
1387
+ 409: components["responses"]["Conflict"];
1310
1388
  };
1311
1389
  };
1312
1390
  updateFindingResolution: {
@@ -1315,6 +1393,7 @@ interface operations {
1315
1393
  header?: never;
1316
1394
  path: {
1317
1395
  projectId: components["parameters"]["ProjectId"];
1396
+ /** @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. */
1318
1397
  findingId: components["parameters"]["FindingId"];
1319
1398
  };
1320
1399
  cookie?: never;
@@ -1342,6 +1421,7 @@ interface operations {
1342
1421
  401: components["responses"]["Unauthorized"];
1343
1422
  403: components["responses"]["Forbidden"];
1344
1423
  404: components["responses"]["NotFound"];
1424
+ 409: components["responses"]["Conflict"];
1345
1425
  };
1346
1426
  };
1347
1427
  publishFinding: {
@@ -1350,6 +1430,7 @@ interface operations {
1350
1430
  header?: never;
1351
1431
  path: {
1352
1432
  projectId: components["parameters"]["ProjectId"];
1433
+ /** @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. */
1353
1434
  findingId: components["parameters"]["FindingId"];
1354
1435
  };
1355
1436
  cookie?: never;
@@ -1373,6 +1454,7 @@ interface operations {
1373
1454
  401: components["responses"]["Unauthorized"];
1374
1455
  403: components["responses"]["Forbidden"];
1375
1456
  404: components["responses"]["NotFound"];
1457
+ 409: components["responses"]["Conflict"];
1376
1458
  };
1377
1459
  };
1378
1460
  publishScan: {
@@ -1433,33 +1515,6 @@ interface operations {
1433
1515
  404: components["responses"]["NotFound"];
1434
1516
  };
1435
1517
  };
1436
- listOptionalFlows: {
1437
- parameters: {
1438
- query?: never;
1439
- header?: never;
1440
- path: {
1441
- projectId: components["parameters"]["ProjectId"];
1442
- };
1443
- cookie?: never;
1444
- };
1445
- requestBody?: never;
1446
- responses: {
1447
- /** @description OK */
1448
- 200: {
1449
- headers: {
1450
- [name: string]: unknown;
1451
- };
1452
- content: {
1453
- "application/json": {
1454
- optionalFlows: components["schemas"]["OptionalFlow"][];
1455
- };
1456
- };
1457
- };
1458
- 401: components["responses"]["Unauthorized"];
1459
- 403: components["responses"]["Forbidden"];
1460
- 404: components["responses"]["NotFound"];
1461
- };
1462
- };
1463
1518
  getBillingBalance: {
1464
1519
  parameters: {
1465
1520
  query?: never;
@@ -1552,7 +1607,6 @@ type Finding = Schemas["Finding"];
1552
1607
  type FindingDetail = Schemas["FindingDetail"];
1553
1608
  type FindingNote = Schemas["FindingNote"];
1554
1609
  type ScanPreset = Schemas["ScanPreset"];
1555
- type OptionalFlow = Schemas["OptionalFlow"];
1556
1610
  type LaunchScanRequest = Schemas["LaunchScanRequest"];
1557
1611
  type LaunchScanResult = Schemas["LaunchScanResult"];
1558
1612
  type CancelScanResult = Schemas["CancelScanResult"];
@@ -1568,6 +1622,7 @@ type AuditArea = Schemas["AuditArea"];
1568
1622
  type AuditAreaList = Schemas["AuditAreaList"];
1569
1623
  type DeleteAuditAreaResult = Schemas["DeleteAuditAreaResult"];
1570
1624
  type SetGuidanceResult = Schemas["SetGuidanceResult"];
1625
+ type TokenInfo = Schemas["TokenInfo"];
1571
1626
  type BillingBalance = Schemas["BillingBalance"];
1572
1627
  type BillingUsage = Schemas["BillingUsage"];
1573
1628
  type UsageEvent = Schemas["UsageEvent"];
@@ -1580,6 +1635,25 @@ type Paginated<T> = {
1580
1635
  limit: number;
1581
1636
  total: number;
1582
1637
  };
1638
+ /**
1639
+ * Body of `createManualAudit`. Not part of the published OpenAPI spec: the
1640
+ * endpoint needs the `admin` scope, which only a zkao site admin can grant.
1641
+ */
1642
+ type ManualAuditRequest = {
1643
+ /** Repository the audit covers. */
1644
+ repositoryId: string;
1645
+ /** Commit the audit reviewed (7-64 hex characters). */
1646
+ commitHash: string;
1647
+ commitMessage?: string | null;
1648
+ /** Findings YAML, as report-tool's `just export-findings <slug>` prints it. */
1649
+ findingsYaml: string;
1650
+ /** Report body markdown, shown on the scan page. */
1651
+ reportMarkdown?: string | null;
1652
+ };
1653
+ type ManualAuditResult = {
1654
+ scanId: string;
1655
+ findingsCreated: number;
1656
+ };
1583
1657
  type ZkaoClientOptions = {
1584
1658
  /** A project API token: `zkao_proj_<keyId>_<secret>`. */
1585
1659
  token: string;
@@ -1629,11 +1703,27 @@ declare class ZkaoApiError extends Error {
1629
1703
  * Typed client for one zkao project. Every call is scoped to the project the
1630
1704
  * token belongs to; see https://zkao.io/openapi/v1.yaml for the full contract.
1631
1705
  */
1706
+ /**
1707
+ * Which project (and organization) a token belongs to, plus its scopes and
1708
+ * limits. Needs no project id, so it works with a token whose project is
1709
+ * unknown. Any valid token may call it.
1710
+ */
1711
+ declare function getTokenInfo(options: Omit<ZkaoClientOptions, "projectId">): Promise<TokenInfo>;
1632
1712
  declare class ZkaoClient {
1633
1713
  private readonly http;
1634
1714
  private readonly projectId;
1715
+ private readonly baseUrl;
1716
+ private readonly token;
1717
+ private readonly fetchImpl;
1635
1718
  constructor(options: ZkaoClientOptions);
1719
+ /**
1720
+ * POST a JSON body to a project route that is not in the generated `paths`.
1721
+ * Same error envelope handling as the typed calls.
1722
+ */
1723
+ private postUntyped;
1636
1724
  private get path();
1725
+ /** The calling token, and the project and organization it belongs to. */
1726
+ getTokenInfo(): Promise<TokenInfo>;
1637
1727
  listRepositories(): Promise<Repository[]>;
1638
1728
  /**
1639
1729
  * Block until a repository is ready to scan, then return it.
@@ -1704,6 +1794,12 @@ declare class ZkaoClient {
1704
1794
  publishScan(scanId: string, opts?: {
1705
1795
  withPassword?: boolean;
1706
1796
  }): Promise<PublishArtifactResult>;
1797
+ /**
1798
+ * Record a zkSecurity audit report on the project as a manual audit: a
1799
+ * completed scan whose findings are pre-confirmed. Requires the `admin`
1800
+ * scope, which only a zkao site admin can grant; any other token gets 404.
1801
+ */
1802
+ createManualAudit(body: ManualAuditRequest): Promise<ManualAuditResult>;
1707
1803
  listFindings(opts?: {
1708
1804
  page?: number;
1709
1805
  limit?: number;
@@ -1744,7 +1840,6 @@ declare class ZkaoClient {
1744
1840
  withPassword?: boolean;
1745
1841
  }): Promise<PublishArtifactResult>;
1746
1842
  listScanPresets(): Promise<ScanPreset[]>;
1747
- listOptionalFlows(): Promise<OptionalFlow[]>;
1748
1843
  /**
1749
1844
  * Get the project's prepaid credit balance (requires the `read` scope). zkao
1750
1845
  * is pay-as-you-go: `balanceCredits` is the total, `reservedCredits` is held
@@ -1772,4 +1867,4 @@ declare class ZkaoClient {
1772
1867
  }): Promise<UsageMonthSummary[]>;
1773
1868
  }
1774
1869
 
1775
- 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 };
1870
+ 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 ManualAuditRequest, type ManualAuditResult, 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 TokenInfo, type TriageStatus, type UsageEvent, type UsageEventType, type UsageMonthSummary, type WaitForRepositoryReadyOptions, type WaitForScanOptions, ZkaoApiError, ZkaoClient, type ZkaoClientOptions, type components, getTokenInfo, isTerminalScanStatus, normalizeBaseUrl, type paths, resolveBaseUrlFromEnv };
package/dist/index.js CHANGED
@@ -99,20 +99,64 @@ function unwrap(result) {
99
99
  envelope?.error?.message ?? result.response.statusText
100
100
  );
101
101
  }
102
+ async function getTokenInfo(options) {
103
+ const http = createClient({
104
+ baseUrl: options.baseUrl ?? resolveBaseUrlFromEnv() ?? DEFAULT_BASE_URL,
105
+ headers: { Authorization: `Bearer ${options.token}` },
106
+ ...options.fetch ? { fetch: options.fetch } : {}
107
+ });
108
+ return unwrap(await http.GET("/token"));
109
+ }
102
110
  var ZkaoClient = class {
103
111
  http;
104
112
  projectId;
113
+ baseUrl;
114
+ token;
115
+ fetchImpl;
105
116
  constructor(options) {
106
117
  this.projectId = options.projectId;
118
+ this.baseUrl = options.baseUrl ?? resolveBaseUrlFromEnv() ?? DEFAULT_BASE_URL;
119
+ this.token = options.token;
120
+ this.fetchImpl = options.fetch ?? fetch;
107
121
  this.http = createClient({
108
- baseUrl: options.baseUrl ?? resolveBaseUrlFromEnv() ?? DEFAULT_BASE_URL,
109
- headers: { Authorization: `Bearer ${options.token}` },
122
+ baseUrl: this.baseUrl,
123
+ headers: { Authorization: `Bearer ${this.token}` },
110
124
  ...options.fetch ? { fetch: options.fetch } : {}
111
125
  });
112
126
  }
127
+ /**
128
+ * POST a JSON body to a project route that is not in the generated `paths`.
129
+ * Same error envelope handling as the typed calls.
130
+ */
131
+ async postUntyped(path, body) {
132
+ const url = `${this.baseUrl.replace(/\/+$/, "")}/projects/${encodeURIComponent(this.projectId)}${path}`;
133
+ const response = await this.fetchImpl(url, {
134
+ method: "POST",
135
+ headers: {
136
+ Authorization: `Bearer ${this.token}`,
137
+ "Content-Type": "application/json"
138
+ },
139
+ body: JSON.stringify(body)
140
+ });
141
+ let payload;
142
+ try {
143
+ payload = await response.json();
144
+ } catch {
145
+ payload = void 0;
146
+ }
147
+ if (response.ok && payload !== void 0) {
148
+ return payload;
149
+ }
150
+ return unwrap({ error: payload, response });
151
+ }
113
152
  get path() {
114
153
  return { projectId: this.projectId };
115
154
  }
155
+ // --- Token --------------------------------------------------------------
156
+ /** The calling token, and the project and organization it belongs to. */
157
+ async getTokenInfo() {
158
+ return unwrap(await this.http.GET("/token"));
159
+ }
116
160
  // --- Repositories -------------------------------------------------------
117
161
  async listRepositories() {
118
162
  const res = await this.http.GET("/projects/{projectId}/repositories", {
@@ -324,6 +368,14 @@ var ZkaoClient = class {
324
368
  });
325
369
  return unwrap(res);
326
370
  }
371
+ /**
372
+ * Record a zkSecurity audit report on the project as a manual audit: a
373
+ * completed scan whose findings are pre-confirmed. Requires the `admin`
374
+ * scope, which only a zkao site admin can grant; any other token gets 404.
375
+ */
376
+ async createManualAudit(body) {
377
+ return this.postUntyped("/manual-audits", body);
378
+ }
327
379
  // --- Findings -----------------------------------------------------------
328
380
  async listFindings(opts = {}) {
329
381
  const res = await this.http.GET("/projects/{projectId}/findings", {
@@ -391,12 +443,6 @@ var ZkaoClient = class {
391
443
  });
392
444
  return unwrap(res).presets;
393
445
  }
394
- async listOptionalFlows() {
395
- const res = await this.http.GET("/projects/{projectId}/optional-flows", {
396
- params: { path: this.path }
397
- });
398
- return unwrap(res).optionalFlows;
399
- }
400
446
  // --- Billing ------------------------------------------------------------
401
447
  /**
402
448
  * Get the project's prepaid credit balance (requires the `read` scope). zkao
@@ -474,6 +520,7 @@ export {
474
520
  TERMINAL_SCAN_STATUSES,
475
521
  ZkaoApiError,
476
522
  ZkaoClient,
523
+ getTokenInfo,
477
524
  isTerminalScanStatus,
478
525
  normalizeBaseUrl,
479
526
  resolveBaseUrlFromEnv
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zksecurity/zkao-sdk",
3
- "version": "0.5.0",
3
+ "version": "0.11.0-next.2",
4
4
  "description": "TypeScript SDK for the zkao Project API",
5
5
  "license": "MIT",
6
6
  "author": "zkSecurity",