@zksecurity/zkao-sdk 0.25.0-next.16 → 0.27.0-next.18

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
@@ -165,6 +165,32 @@ interface paths {
165
165
  patch?: never;
166
166
  trace?: never;
167
167
  };
168
+ "/projects/{projectId}/repositories/{repositoryId}/reports": {
169
+ parameters: {
170
+ query?: never;
171
+ header?: never;
172
+ path?: never;
173
+ cookie?: never;
174
+ };
175
+ get?: never;
176
+ put?: never;
177
+ /**
178
+ * File a vulnerability report against a repository
179
+ * @description Requires scope: `reports:write`. Files a report into the programme that takes reports for this repository, as prose. It arrives exactly as a GitHub private vulnerability report does and is read and split into claims by the same step, so nothing downstream distinguishes them.
180
+ *
181
+ * Returns with `intakeState: PENDING`. `investigateReport` refuses a report until that reaches `COMPLETE`, so poll `/projects/{projectId}/reports` before asking for an investigation.
182
+ *
183
+ * Idempotent on content: the same title and body against the same repository name the same report, so a retried call returns the original with `200` rather than filing a second copy.
184
+ *
185
+ * Free. The reading that follows is charged to the project, and the investigation is charged when someone asks for it.
186
+ */
187
+ post: operations["submitReport"];
188
+ delete?: never;
189
+ options?: never;
190
+ head?: never;
191
+ patch?: never;
192
+ trace?: never;
193
+ };
168
194
  "/projects/{projectId}/scans": {
169
195
  parameters: {
170
196
  query?: never;
@@ -736,8 +762,10 @@ interface components {
736
762
  Error: {
737
763
  error: {
738
764
  /** @enum {string} */
739
- code: "unauthorized" | "forbidden" | "not_found" | "bad_request" | "conflict" | "insufficient_credits" | "repository_initializing" | "diff_base_required" | "diff_base_not_allowed" | "diff_base_invalid" | "diff_empty" | "rate_limited" | "internal";
765
+ code: "unauthorized" | "forbidden" | "not_found" | "bad_request" | "conflict" | "insufficient_credits" | "budget_below_minimum" | "repository_initializing" | "diff_base_required" | "diff_base_not_allowed" | "diff_base_invalid" | "diff_empty" | "rate_limited" | "internal";
740
766
  message: string;
767
+ /** @description budget_below_minimum only: the least the launch could have reserved, in credits. A diff scan's first scan of a repository also builds its overview, so its minimum is higher. */
768
+ minimumCredits?: number;
741
769
  };
742
770
  };
743
771
  /** @enum {string} */
@@ -1044,7 +1072,7 @@ interface components {
1044
1072
  };
1045
1073
  LaunchScanRequest: {
1046
1074
  repositoryId: string;
1047
- /** @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. That is the last such scan's budget, or half again when that scan ran short of it, never above twice the scan type's minimum. A first scan starts at twice the minimum. A diff scan is sized from its change instead: the minimum for up to 500 changed lines, then in proportion, up to three times the minimum. */
1075
+ /** @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. A Flash or Max scan of the code is sized from the audit areas it reads: the selected areas, or every area in the repository map. One area gets the minimum, and the budget grows with the square root of the area count. With no map, or with `auditScope`, it is twice the minimum. It is half again the last budget when the last scan of the same scope ran short of it. A diff scan is sized from its change instead: the minimum for up to 500 changed lines, then in proportion, up to three times the minimum. Other scan types use the last such scan's budget, or half again when that scan ran short of it, and a first scan starts at twice the minimum. Except for a diff, the recommendation never exceeds twice the minimum. A budget below the minimum is refused with `400` `budget_below_minimum`, whose `minimumCredits` names it. */
1048
1076
  creditBudget?: number;
1049
1077
  /** @description A preset ref from /scan-presets. Defaults to the first active preset. */
1050
1078
  presetRef?: string;
@@ -1053,7 +1081,7 @@ interface components {
1053
1081
  /** @description Pin a specific commit SHA (7-40 hex chars). */
1054
1082
  commitHash?: string | null;
1055
1083
  commitMessage?: string | null;
1056
- /** @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. */
1084
+ /** @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. When no earlier scan of the repository built its overview, the diff scan builds one first, and its minimum and recommended budgets rise. */
1057
1085
  baseCommit?: string | null;
1058
1086
  /** @description Options for Recheck open findings. Omit to reassess eligible Not started findings on the selected branch. Fresh rechecks require the branch's latest commit and reject a pinned commit or audit scope. */
1059
1087
  backlogRecheck?: {
@@ -1078,6 +1106,8 @@ interface components {
1078
1106
  queued: boolean;
1079
1107
  /** @description The budget the scan was launched with, in credits. */
1080
1108
  creditBudget: number;
1109
+ /** @description True when no earlier scan of the repository built its overview, so this diff scan builds one first. It takes longer, and its minimum and recommended budgets are higher. */
1110
+ buildsOverview: boolean;
1081
1111
  };
1082
1112
  RepositoryGuidance: {
1083
1113
  repositoryId: string;
@@ -1211,6 +1241,29 @@ interface components {
1211
1241
  /** @description Claims queued for triage, or null when an investigation was already running and this call started nothing. */
1212
1242
  claimsQueued: number | null;
1213
1243
  };
1244
+ SubmitReportRequest: {
1245
+ /** @description One line naming the flaw. */
1246
+ title: string;
1247
+ /** @description What the flaw is, how to reach it, and what it costs. Prose: this is read and split into claims, so write it for a reader rather than as fields. Anything past the limit would be stored and never read. */
1248
+ body: string;
1249
+ /**
1250
+ * @description What the reporter claims, which is not an assessment. It decides how closely the report is read, so an inflated claim costs the programme more.
1251
+ * @enum {string|null}
1252
+ */
1253
+ claimedSeverity?: "CRITICAL" | "HIGH" | "MEDIUM" | "LOW" | "INFO" | null;
1254
+ /** @description Who found it, all self-asserted. Used for attribution on the advisory, never for authorization. */
1255
+ reporter?: {
1256
+ name?: string | null;
1257
+ email?: string | null;
1258
+ githubLogin?: string | null;
1259
+ };
1260
+ };
1261
+ SubmitReportResult: {
1262
+ /** @description The identifier `investigateReport` takes. */
1263
+ publicId: string;
1264
+ /** @description Always PENDING here. The report is queued to be read and split into claims, and an investigation waits for COMPLETE. */
1265
+ intakeState: string;
1266
+ };
1214
1267
  /** @description Optionally attach or reuse a note alongside a resolution change. */
1215
1268
  ChangeNote: {
1216
1269
  /** @description Create a new note with this body. */
@@ -1652,6 +1705,48 @@ interface operations {
1652
1705
  404: components["responses"]["NotFound"];
1653
1706
  };
1654
1707
  };
1708
+ submitReport: {
1709
+ parameters: {
1710
+ query?: never;
1711
+ header?: never;
1712
+ path: {
1713
+ projectId: components["parameters"]["ProjectId"];
1714
+ repositoryId: components["parameters"]["RepositoryId"];
1715
+ };
1716
+ cookie?: never;
1717
+ };
1718
+ requestBody: {
1719
+ content: {
1720
+ "application/json": components["schemas"]["SubmitReportRequest"];
1721
+ };
1722
+ };
1723
+ responses: {
1724
+ /** @description Already filed, by an identical earlier call */
1725
+ 200: {
1726
+ headers: {
1727
+ [name: string]: unknown;
1728
+ };
1729
+ content: {
1730
+ "application/json": components["schemas"]["SubmitReportResult"];
1731
+ };
1732
+ };
1733
+ /** @description Filed */
1734
+ 201: {
1735
+ headers: {
1736
+ [name: string]: unknown;
1737
+ };
1738
+ content: {
1739
+ "application/json": components["schemas"]["SubmitReportResult"];
1740
+ };
1741
+ };
1742
+ 400: components["responses"]["BadRequest"];
1743
+ 401: components["responses"]["Unauthorized"];
1744
+ 403: components["responses"]["Forbidden"];
1745
+ 404: components["responses"]["NotFound"];
1746
+ 409: components["responses"]["Conflict"];
1747
+ 429: components["responses"]["RateLimited"];
1748
+ };
1749
+ };
1655
1750
  listScans: {
1656
1751
  parameters: {
1657
1752
  query?: {
@@ -2478,6 +2573,8 @@ type UsageEventType = Schemas["UsageEventType"];
2478
2573
  type BillingSummary = Schemas["BillingSummary"];
2479
2574
  type InvestigateReportResult = Schemas["InvestigateReportResult"];
2480
2575
  type Report = Schemas["Report"];
2576
+ type SubmitReportRequest = Schemas["SubmitReportRequest"];
2577
+ type SubmitReportResult = Schemas["SubmitReportResult"];
2481
2578
  /** The triage statuses a report moves through. */
2482
2579
  type ReportStatus = "NEW" | "TRIAGING" | "NEEDS_INFO" | "ACCEPTED" | "DUPLICATE" | "REJECTED";
2483
2580
  type Advisory = Schemas["Advisory"];
@@ -2584,7 +2681,9 @@ type WaitForScanOptions = {
2584
2681
  declare class ZkaoApiError extends Error {
2585
2682
  readonly status: number;
2586
2683
  readonly code: string;
2587
- constructor(status: number, code: string, message: string);
2684
+ /** `budget_below_minimum` only: the least the launch could reserve, in credits. */
2685
+ readonly minimumCredits?: number;
2686
+ constructor(status: number, code: string, message: string, minimumCredits?: number);
2588
2687
  }
2589
2688
  /**
2590
2689
  * Typed client for one zkao project. Every call is scoped to the project the
@@ -2777,6 +2876,21 @@ declare class ZkaoClient {
2777
2876
  * confirmation mail is sent from the app.
2778
2877
  */
2779
2878
  addAdvisoryContact(contact: AdvisoryContactInput): Promise<AdvisoryContact>;
2879
+ /**
2880
+ * File a vulnerability report against one of the programme's repositories.
2881
+ *
2882
+ * Requires the `reports:write` scope. Send prose: this is read and split
2883
+ * into claims for you, so write it for a reader rather than as fields.
2884
+ *
2885
+ * Comes back with `intakeState: "PENDING"`, because the reading is queued.
2886
+ * {@link investigateReport} refuses the report until that reaches
2887
+ * `COMPLETE`, so poll {@link listReports} before asking for one.
2888
+ *
2889
+ * Idempotent on content: the same title and body against the same
2890
+ * repository name the same report, so a retry after a timeout returns the
2891
+ * original rather than filing a second copy.
2892
+ */
2893
+ submitReport(repositoryId: string, report: SubmitReportRequest): Promise<SubmitReportResult>;
2780
2894
  /**
2781
2895
  * Reports the programme has received, newest first.
2782
2896
  *
package/dist/index.js CHANGED
@@ -81,11 +81,16 @@ function isTerminalScanStatus(status) {
81
81
  var ZkaoApiError = class extends Error {
82
82
  status;
83
83
  code;
84
- constructor(status, code, message) {
84
+ /** `budget_below_minimum` only: the least the launch could reserve, in credits. */
85
+ minimumCredits;
86
+ constructor(status, code, message, minimumCredits) {
85
87
  super(message);
86
88
  this.name = "ZkaoApiError";
87
89
  this.status = status;
88
90
  this.code = code;
91
+ if (minimumCredits !== void 0) {
92
+ this.minimumCredits = minimumCredits;
93
+ }
89
94
  }
90
95
  };
91
96
  function unwrap(result) {
@@ -93,10 +98,12 @@ function unwrap(result) {
93
98
  return result.data;
94
99
  }
95
100
  const envelope = result.error;
101
+ const minimumCredits = envelope?.error?.minimumCredits;
96
102
  throw new ZkaoApiError(
97
103
  result.response.status,
98
104
  envelope?.error?.code ?? "error",
99
- envelope?.error?.message ?? result.response.statusText
105
+ envelope?.error?.message ?? result.response.statusText,
106
+ typeof minimumCredits === "number" ? minimumCredits : void 0
100
107
  );
101
108
  }
102
109
  async function getTokenInfo(options) {
@@ -529,6 +536,30 @@ var ZkaoClient = class {
529
536
  return unwrap(res).contact;
530
537
  }
531
538
  // --- Incoming reports ---------------------------------------------------
539
+ /**
540
+ * File a vulnerability report against one of the programme's repositories.
541
+ *
542
+ * Requires the `reports:write` scope. Send prose: this is read and split
543
+ * into claims for you, so write it for a reader rather than as fields.
544
+ *
545
+ * Comes back with `intakeState: "PENDING"`, because the reading is queued.
546
+ * {@link investigateReport} refuses the report until that reaches
547
+ * `COMPLETE`, so poll {@link listReports} before asking for one.
548
+ *
549
+ * Idempotent on content: the same title and body against the same
550
+ * repository name the same report, so a retry after a timeout returns the
551
+ * original rather than filing a second copy.
552
+ */
553
+ async submitReport(repositoryId, report) {
554
+ const res = await this.http.POST(
555
+ "/projects/{projectId}/repositories/{repositoryId}/reports",
556
+ {
557
+ params: { path: { ...this.path, repositoryId } },
558
+ body: report
559
+ }
560
+ );
561
+ return unwrap(res);
562
+ }
532
563
  /**
533
564
  * Reports the programme has received, newest first.
534
565
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zksecurity/zkao-sdk",
3
- "version": "0.25.0-next.16",
3
+ "version": "0.27.0-next.18",
4
4
  "description": "TypeScript SDK for the zkao Project API",
5
5
  "license": "MIT",
6
6
  "author": "zkSecurity",