@zksecurity/zkao-sdk 0.1.0 → 0.2.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/dist/index.d.ts +259 -4
- package/dist/index.js +49 -2
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -91,7 +91,8 @@ interface paths {
|
|
|
91
91
|
* @description Requires scope: `scans:launch`. Reserves `creditBudget` credits from the
|
|
92
92
|
* project balance. The repo must be in the token's allowlist (when set) and
|
|
93
93
|
* ACTIVE. Discover valid `presetRef` / `optInFlowIds` via the discovery
|
|
94
|
-
* endpoints. Per-token spend limits and the project
|
|
94
|
+
* endpoints. Per-token spend limits are enforced, and the project must have
|
|
95
|
+
* enough prepaid credits to cover the budget (otherwise `402`).
|
|
95
96
|
*/
|
|
96
97
|
post: operations["launchScan"];
|
|
97
98
|
delete?: never;
|
|
@@ -340,13 +341,111 @@ interface paths {
|
|
|
340
341
|
patch?: never;
|
|
341
342
|
trace?: never;
|
|
342
343
|
};
|
|
344
|
+
"/projects/{projectId}/billing/balance": {
|
|
345
|
+
parameters: {
|
|
346
|
+
query?: never;
|
|
347
|
+
header?: never;
|
|
348
|
+
path?: never;
|
|
349
|
+
cookie?: never;
|
|
350
|
+
};
|
|
351
|
+
/**
|
|
352
|
+
* Current prepaid credit balance
|
|
353
|
+
* @description Requires scope: `read`. All amounts are in credits.
|
|
354
|
+
*/
|
|
355
|
+
get: operations["getBillingBalance"];
|
|
356
|
+
put?: never;
|
|
357
|
+
post?: never;
|
|
358
|
+
delete?: never;
|
|
359
|
+
options?: never;
|
|
360
|
+
head?: never;
|
|
361
|
+
patch?: never;
|
|
362
|
+
trace?: never;
|
|
363
|
+
};
|
|
364
|
+
"/projects/{projectId}/billing/usage": {
|
|
365
|
+
parameters: {
|
|
366
|
+
query?: never;
|
|
367
|
+
header?: never;
|
|
368
|
+
path?: never;
|
|
369
|
+
cookie?: never;
|
|
370
|
+
};
|
|
371
|
+
/**
|
|
372
|
+
* Credit usage events
|
|
373
|
+
* @description Requires scope: `read`. Signed credit delta per ledger event. Defaults to the last 30 days; newest first; max 1000 rows.
|
|
374
|
+
*/
|
|
375
|
+
get: operations["getBillingUsage"];
|
|
376
|
+
put?: never;
|
|
377
|
+
post?: never;
|
|
378
|
+
delete?: never;
|
|
379
|
+
options?: never;
|
|
380
|
+
head?: never;
|
|
381
|
+
patch?: never;
|
|
382
|
+
trace?: never;
|
|
383
|
+
};
|
|
384
|
+
"/projects/{projectId}/billing/summary": {
|
|
385
|
+
parameters: {
|
|
386
|
+
query?: never;
|
|
387
|
+
header?: never;
|
|
388
|
+
path?: never;
|
|
389
|
+
cookie?: never;
|
|
390
|
+
};
|
|
391
|
+
/**
|
|
392
|
+
* Monthly spend and purchase summary
|
|
393
|
+
* @description Requires scope: `read`. Per-month net scan spend and net purchases, in credits, newest first.
|
|
394
|
+
*/
|
|
395
|
+
get: operations["getBillingSummary"];
|
|
396
|
+
put?: never;
|
|
397
|
+
post?: never;
|
|
398
|
+
delete?: never;
|
|
399
|
+
options?: never;
|
|
400
|
+
head?: never;
|
|
401
|
+
patch?: never;
|
|
402
|
+
trace?: never;
|
|
403
|
+
};
|
|
343
404
|
}
|
|
344
405
|
interface components {
|
|
345
406
|
schemas: {
|
|
407
|
+
BillingBalance: {
|
|
408
|
+
/** @description Total prepaid credit balance. */
|
|
409
|
+
balanceCredits: number;
|
|
410
|
+
/** @description Balance minus credits reserved by in-flight scans. */
|
|
411
|
+
availableCredits: number;
|
|
412
|
+
/** @description Credits held by queued/running scans. */
|
|
413
|
+
reservedCredits: number;
|
|
414
|
+
};
|
|
415
|
+
/** @enum {string} */
|
|
416
|
+
UsageEventType: "SCAN_DEDUCTION" | "SCAN_REFUND" | "PURCHASE" | "STRIPE_REFUND" | "ADMIN_ADJUSTMENT";
|
|
417
|
+
UsageEvent: {
|
|
418
|
+
id: string;
|
|
419
|
+
/** Format: date-time */
|
|
420
|
+
at: string;
|
|
421
|
+
type: components["schemas"]["UsageEventType"];
|
|
422
|
+
/** @description Signed credit delta: negative = spent/clawed back, positive = added/refunded. */
|
|
423
|
+
credits: number;
|
|
424
|
+
scanId: string | null;
|
|
425
|
+
description: string;
|
|
426
|
+
};
|
|
427
|
+
BillingUsage: {
|
|
428
|
+
/** Format: date-time */
|
|
429
|
+
from: string;
|
|
430
|
+
/** Format: date-time */
|
|
431
|
+
to: string;
|
|
432
|
+
events: components["schemas"]["UsageEvent"][];
|
|
433
|
+
};
|
|
434
|
+
UsageMonthSummary: {
|
|
435
|
+
/** @description YYYY-MM (UTC). */
|
|
436
|
+
month: string;
|
|
437
|
+
/** @description Net scan spend (deductions less refunds), in credits. */
|
|
438
|
+
spentCredits: number;
|
|
439
|
+
/** @description Net purchases (purchases less clawbacks), in credits. */
|
|
440
|
+
purchasedCredits: number;
|
|
441
|
+
};
|
|
442
|
+
BillingSummary: {
|
|
443
|
+
months: components["schemas"]["UsageMonthSummary"][];
|
|
444
|
+
};
|
|
346
445
|
Error: {
|
|
347
446
|
error: {
|
|
348
447
|
/** @enum {string} */
|
|
349
|
-
code: "unauthorized" | "forbidden" | "not_found" | "bad_request" | "conflict" | "
|
|
448
|
+
code: "unauthorized" | "forbidden" | "not_found" | "bad_request" | "conflict" | "insufficient_credits" | "rate_limited" | "internal";
|
|
350
449
|
message: string;
|
|
351
450
|
};
|
|
352
451
|
};
|
|
@@ -380,6 +479,17 @@ interface components {
|
|
|
380
479
|
startedAt?: string | null;
|
|
381
480
|
/** Format: date-time */
|
|
382
481
|
completedAt?: string | null;
|
|
482
|
+
/** @description Phase progress while the scan is in flight. Null once the scan reaches a terminal state, and null before it has been dispatched (no phases exist yet). */
|
|
483
|
+
progress?: components["schemas"]["ScanProgress"] | null;
|
|
484
|
+
};
|
|
485
|
+
/** @description How far a running scan has got through its phases. Deliberately not a time estimate: a phase's duration moves with the guidance it was given, the repository, and the model that ran it. */
|
|
486
|
+
ScanProgress: {
|
|
487
|
+
/** @description Phases that reached a terminal state (completed, failed, or skipped). */
|
|
488
|
+
phasesCompleted: number;
|
|
489
|
+
/** @description Phases this scan will run, fixed when it was dispatched. */
|
|
490
|
+
phasesTotal: number;
|
|
491
|
+
/** @description Weighted completion. Each phase counts for its share of the scan budget, so this does not simply equal phasesCompleted / phasesTotal. */
|
|
492
|
+
percent: number;
|
|
383
493
|
};
|
|
384
494
|
ScanDetail: components["schemas"]["Scan"] & {
|
|
385
495
|
branch?: string | null;
|
|
@@ -532,6 +642,14 @@ interface components {
|
|
|
532
642
|
findingId: string;
|
|
533
643
|
resolutionStatus: components["schemas"]["ResolutionStatus"];
|
|
534
644
|
};
|
|
645
|
+
/**
|
|
646
|
+
* @description Short code for why a finding is being closed, chosen from the set offered for the `resolutionStatus` it is sent with; a code belonging to a different status is rejected with 400. Ignored for the open statuses (`NOT_STARTED`, `IN_PROGRESS`) and when `note` is also given. It is not stored as a field: it is recorded as a comment on the finding stating what was chosen, which is returned by the notes endpoints.
|
|
647
|
+
*
|
|
648
|
+
* Codes per status. `RESOLVED`: fixed_in_code, fixed_upstream, code_removed. `MITIGATED`: compensating_control, limited_exposure, monitored. `FALSE_POSITIVE`: not_reachable, guarded_elsewhere, intended_behavior, misread_code, bad_assumption. `WONT_FIX`: risk_accepted, out_of_scope, not_worth_fixing, code_being_removed. `DUPLICATE`: duplicate_of_finding, same_root_cause.
|
|
649
|
+
* @example not_reachable
|
|
650
|
+
* @enum {string}
|
|
651
|
+
*/
|
|
652
|
+
ResolutionReason: "fixed_in_code" | "fixed_upstream" | "code_removed" | "compensating_control" | "limited_exposure" | "monitored" | "not_reachable" | "guarded_elsewhere" | "intended_behavior" | "misread_code" | "bad_assumption" | "risk_accepted" | "out_of_scope" | "not_worth_fixing" | "code_being_removed" | "duplicate_of_finding" | "same_root_cause";
|
|
535
653
|
PublishFindingRequest: {
|
|
536
654
|
/** @description A note id on the finding to pin as the published note. */
|
|
537
655
|
noteId?: string;
|
|
@@ -569,6 +687,15 @@ interface components {
|
|
|
569
687
|
"application/json": components["schemas"]["Error"];
|
|
570
688
|
};
|
|
571
689
|
};
|
|
690
|
+
/** @description The project does not have enough prepaid credits to cover the scan budget. Top up credits and retry. (code `insufficient_credits`) */
|
|
691
|
+
InsufficientCredits: {
|
|
692
|
+
headers: {
|
|
693
|
+
[name: string]: unknown;
|
|
694
|
+
};
|
|
695
|
+
content: {
|
|
696
|
+
"application/json": components["schemas"]["Error"];
|
|
697
|
+
};
|
|
698
|
+
};
|
|
572
699
|
/** @description The token lacks the required scope */
|
|
573
700
|
Forbidden: {
|
|
574
701
|
headers: {
|
|
@@ -760,6 +887,7 @@ interface operations {
|
|
|
760
887
|
};
|
|
761
888
|
400: components["responses"]["BadRequest"];
|
|
762
889
|
401: components["responses"]["Unauthorized"];
|
|
890
|
+
402: components["responses"]["InsufficientCredits"];
|
|
763
891
|
403: components["responses"]["Forbidden"];
|
|
764
892
|
404: components["responses"]["NotFound"];
|
|
765
893
|
429: components["responses"]["RateLimited"];
|
|
@@ -1000,6 +1128,7 @@ interface operations {
|
|
|
1000
1128
|
"application/json": {
|
|
1001
1129
|
resolutionStatus: components["schemas"]["ResolutionStatus"];
|
|
1002
1130
|
note?: components["schemas"]["ChangeNote"];
|
|
1131
|
+
reason?: components["schemas"]["ResolutionReason"];
|
|
1003
1132
|
};
|
|
1004
1133
|
};
|
|
1005
1134
|
};
|
|
@@ -1135,6 +1264,88 @@ interface operations {
|
|
|
1135
1264
|
404: components["responses"]["NotFound"];
|
|
1136
1265
|
};
|
|
1137
1266
|
};
|
|
1267
|
+
getBillingBalance: {
|
|
1268
|
+
parameters: {
|
|
1269
|
+
query?: never;
|
|
1270
|
+
header?: never;
|
|
1271
|
+
path: {
|
|
1272
|
+
projectId: components["parameters"]["ProjectId"];
|
|
1273
|
+
};
|
|
1274
|
+
cookie?: never;
|
|
1275
|
+
};
|
|
1276
|
+
requestBody?: never;
|
|
1277
|
+
responses: {
|
|
1278
|
+
/** @description OK */
|
|
1279
|
+
200: {
|
|
1280
|
+
headers: {
|
|
1281
|
+
[name: string]: unknown;
|
|
1282
|
+
};
|
|
1283
|
+
content: {
|
|
1284
|
+
"application/json": components["schemas"]["BillingBalance"];
|
|
1285
|
+
};
|
|
1286
|
+
};
|
|
1287
|
+
401: components["responses"]["Unauthorized"];
|
|
1288
|
+
403: components["responses"]["Forbidden"];
|
|
1289
|
+
404: components["responses"]["NotFound"];
|
|
1290
|
+
};
|
|
1291
|
+
};
|
|
1292
|
+
getBillingUsage: {
|
|
1293
|
+
parameters: {
|
|
1294
|
+
query?: {
|
|
1295
|
+
from?: string;
|
|
1296
|
+
to?: string;
|
|
1297
|
+
limit?: number;
|
|
1298
|
+
};
|
|
1299
|
+
header?: never;
|
|
1300
|
+
path: {
|
|
1301
|
+
projectId: components["parameters"]["ProjectId"];
|
|
1302
|
+
};
|
|
1303
|
+
cookie?: never;
|
|
1304
|
+
};
|
|
1305
|
+
requestBody?: never;
|
|
1306
|
+
responses: {
|
|
1307
|
+
/** @description OK */
|
|
1308
|
+
200: {
|
|
1309
|
+
headers: {
|
|
1310
|
+
[name: string]: unknown;
|
|
1311
|
+
};
|
|
1312
|
+
content: {
|
|
1313
|
+
"application/json": components["schemas"]["BillingUsage"];
|
|
1314
|
+
};
|
|
1315
|
+
};
|
|
1316
|
+
400: components["responses"]["BadRequest"];
|
|
1317
|
+
401: components["responses"]["Unauthorized"];
|
|
1318
|
+
403: components["responses"]["Forbidden"];
|
|
1319
|
+
404: components["responses"]["NotFound"];
|
|
1320
|
+
};
|
|
1321
|
+
};
|
|
1322
|
+
getBillingSummary: {
|
|
1323
|
+
parameters: {
|
|
1324
|
+
query?: {
|
|
1325
|
+
months?: number;
|
|
1326
|
+
};
|
|
1327
|
+
header?: never;
|
|
1328
|
+
path: {
|
|
1329
|
+
projectId: components["parameters"]["ProjectId"];
|
|
1330
|
+
};
|
|
1331
|
+
cookie?: never;
|
|
1332
|
+
};
|
|
1333
|
+
requestBody?: never;
|
|
1334
|
+
responses: {
|
|
1335
|
+
/** @description OK */
|
|
1336
|
+
200: {
|
|
1337
|
+
headers: {
|
|
1338
|
+
[name: string]: unknown;
|
|
1339
|
+
};
|
|
1340
|
+
content: {
|
|
1341
|
+
"application/json": components["schemas"]["BillingSummary"];
|
|
1342
|
+
};
|
|
1343
|
+
};
|
|
1344
|
+
401: components["responses"]["Unauthorized"];
|
|
1345
|
+
403: components["responses"]["Forbidden"];
|
|
1346
|
+
404: components["responses"]["NotFound"];
|
|
1347
|
+
};
|
|
1348
|
+
};
|
|
1138
1349
|
}
|
|
1139
1350
|
|
|
1140
1351
|
type Schemas = components["schemas"];
|
|
@@ -1152,11 +1363,18 @@ type CancelScanResult = Schemas["CancelScanResult"];
|
|
|
1152
1363
|
type ChangeNote = Schemas["ChangeNote"];
|
|
1153
1364
|
type Severity = Schemas["Severity"];
|
|
1154
1365
|
type ResolutionStatus = Schemas["ResolutionStatus"];
|
|
1366
|
+
type ResolutionReason = Schemas["ResolutionReason"];
|
|
1155
1367
|
type TriageStatus = Schemas["TriageStatus"];
|
|
1156
1368
|
type ScanStatus = Schemas["ScanStatus"];
|
|
1157
1369
|
type PublishArtifactResult = Schemas["PublishArtifactResult"];
|
|
1158
1370
|
type RepositoryGuidance = Schemas["RepositoryGuidance"];
|
|
1159
1371
|
type SetGuidanceResult = Schemas["SetGuidanceResult"];
|
|
1372
|
+
type BillingBalance = Schemas["BillingBalance"];
|
|
1373
|
+
type BillingUsage = Schemas["BillingUsage"];
|
|
1374
|
+
type UsageEvent = Schemas["UsageEvent"];
|
|
1375
|
+
type UsageEventType = Schemas["UsageEventType"];
|
|
1376
|
+
type BillingSummary = Schemas["BillingSummary"];
|
|
1377
|
+
type UsageMonthSummary = Schemas["UsageMonthSummary"];
|
|
1160
1378
|
type Paginated<T> = {
|
|
1161
1379
|
items: T[];
|
|
1162
1380
|
page: number;
|
|
@@ -1263,7 +1481,19 @@ declare class ZkaoClient {
|
|
|
1263
1481
|
userSeverity?: Severity | null;
|
|
1264
1482
|
effectiveSeverity: Severity;
|
|
1265
1483
|
}>;
|
|
1266
|
-
|
|
1484
|
+
/**
|
|
1485
|
+
* Change a finding's resolution status (requires the `findings:write` scope).
|
|
1486
|
+
*
|
|
1487
|
+
* `note` attaches free text in the same call. `reason` picks a catalog code
|
|
1488
|
+
* instead, recorded as a generated comment; the codes offered depend on the
|
|
1489
|
+
* status, and a code from another status is rejected with 400. A `note` takes
|
|
1490
|
+
* precedence: pass one or the other. Both are ignored for the open statuses
|
|
1491
|
+
* (`NOT_STARTED`, `IN_PROGRESS`).
|
|
1492
|
+
*/
|
|
1493
|
+
setFindingResolution(findingId: string, resolutionStatus: ResolutionStatus, opts?: {
|
|
1494
|
+
note?: ChangeNote;
|
|
1495
|
+
reason?: ResolutionReason;
|
|
1496
|
+
}): Promise<{
|
|
1267
1497
|
findingId: string;
|
|
1268
1498
|
resolutionStatus: ResolutionStatus;
|
|
1269
1499
|
}>;
|
|
@@ -1273,6 +1503,31 @@ declare class ZkaoClient {
|
|
|
1273
1503
|
}): Promise<PublishArtifactResult>;
|
|
1274
1504
|
listScanPresets(): Promise<ScanPreset[]>;
|
|
1275
1505
|
listOptionalFlows(): Promise<OptionalFlow[]>;
|
|
1506
|
+
/**
|
|
1507
|
+
* Get the project's prepaid credit balance (requires the `read` scope). zkao
|
|
1508
|
+
* is pay-as-you-go: `balanceCredits` is the total, `reservedCredits` is held
|
|
1509
|
+
* by active scans, and `availableCredits` is what remains for new scans.
|
|
1510
|
+
*/
|
|
1511
|
+
getBillingBalance(): Promise<BillingBalance>;
|
|
1512
|
+
/**
|
|
1513
|
+
* List credit-ledger movements for reconciliation (requires the `read`
|
|
1514
|
+
* scope). `credits` on each event is signed (negative = spent). Defaults to
|
|
1515
|
+
* the last 30 days when `from`/`to` are omitted; the range actually used is
|
|
1516
|
+
* echoed back on the response.
|
|
1517
|
+
*/
|
|
1518
|
+
getBillingUsage(opts?: {
|
|
1519
|
+
from?: string;
|
|
1520
|
+
to?: string;
|
|
1521
|
+
limit?: number;
|
|
1522
|
+
}): Promise<BillingUsage>;
|
|
1523
|
+
/**
|
|
1524
|
+
* Per-calendar-month (UTC) totals of net credits spent on scans and net
|
|
1525
|
+
* credits purchased (requires the `read` scope). Quiet months are returned as
|
|
1526
|
+
* zeros; newest month first.
|
|
1527
|
+
*/
|
|
1528
|
+
getBillingSummary(opts?: {
|
|
1529
|
+
months?: number;
|
|
1530
|
+
}): Promise<UsageMonthSummary[]>;
|
|
1276
1531
|
}
|
|
1277
1532
|
|
|
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 };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -263,10 +263,19 @@ var ZkaoClient = class {
|
|
|
263
263
|
});
|
|
264
264
|
return unwrap(res);
|
|
265
265
|
}
|
|
266
|
-
|
|
266
|
+
/**
|
|
267
|
+
* Change a finding's resolution status (requires the `findings:write` scope).
|
|
268
|
+
*
|
|
269
|
+
* `note` attaches free text in the same call. `reason` picks a catalog code
|
|
270
|
+
* instead, recorded as a generated comment; the codes offered depend on the
|
|
271
|
+
* status, and a code from another status is rejected with 400. A `note` takes
|
|
272
|
+
* precedence: pass one or the other. Both are ignored for the open statuses
|
|
273
|
+
* (`NOT_STARTED`, `IN_PROGRESS`).
|
|
274
|
+
*/
|
|
275
|
+
async setFindingResolution(findingId, resolutionStatus, opts = {}) {
|
|
267
276
|
const res = await this.http.PATCH("/projects/{projectId}/findings/{findingId}/resolution", {
|
|
268
277
|
params: { path: { ...this.path, findingId } },
|
|
269
|
-
body: { resolutionStatus, note }
|
|
278
|
+
body: { resolutionStatus, note: opts.note, reason: opts.reason }
|
|
270
279
|
});
|
|
271
280
|
return unwrap(res);
|
|
272
281
|
}
|
|
@@ -290,6 +299,44 @@ var ZkaoClient = class {
|
|
|
290
299
|
});
|
|
291
300
|
return unwrap(res).optionalFlows;
|
|
292
301
|
}
|
|
302
|
+
// --- Billing ------------------------------------------------------------
|
|
303
|
+
/**
|
|
304
|
+
* Get the project's prepaid credit balance (requires the `read` scope). zkao
|
|
305
|
+
* is pay-as-you-go: `balanceCredits` is the total, `reservedCredits` is held
|
|
306
|
+
* by active scans, and `availableCredits` is what remains for new scans.
|
|
307
|
+
*/
|
|
308
|
+
async getBillingBalance() {
|
|
309
|
+
const res = await this.http.GET("/projects/{projectId}/billing/balance", {
|
|
310
|
+
params: { path: this.path }
|
|
311
|
+
});
|
|
312
|
+
return unwrap(res);
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* List credit-ledger movements for reconciliation (requires the `read`
|
|
316
|
+
* scope). `credits` on each event is signed (negative = spent). Defaults to
|
|
317
|
+
* the last 30 days when `from`/`to` are omitted; the range actually used is
|
|
318
|
+
* echoed back on the response.
|
|
319
|
+
*/
|
|
320
|
+
async getBillingUsage(opts = {}) {
|
|
321
|
+
const res = await this.http.GET("/projects/{projectId}/billing/usage", {
|
|
322
|
+
params: {
|
|
323
|
+
path: this.path,
|
|
324
|
+
query: { from: opts.from, to: opts.to, limit: opts.limit }
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
return unwrap(res);
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Per-calendar-month (UTC) totals of net credits spent on scans and net
|
|
331
|
+
* credits purchased (requires the `read` scope). Quiet months are returned as
|
|
332
|
+
* zeros; newest month first.
|
|
333
|
+
*/
|
|
334
|
+
async getBillingSummary(opts = {}) {
|
|
335
|
+
const res = await this.http.GET("/projects/{projectId}/billing/summary", {
|
|
336
|
+
params: { path: this.path, query: { months: opts.months } }
|
|
337
|
+
});
|
|
338
|
+
return unwrap(res).months;
|
|
339
|
+
}
|
|
293
340
|
};
|
|
294
341
|
function throwIfAborted(signal) {
|
|
295
342
|
if (signal?.aborted) {
|