@runlot/api 0.1.0-rc.162 → 0.1.0-rc.164
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 +476 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +665 -0
- package/dist/index.js.map +1 -1
- package/dist/schema.d.ts +21663 -8459
- package/dist/schema.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -16,6 +16,15 @@ function gitQuery(ref, path) {
|
|
|
16
16
|
q.set("path", path);
|
|
17
17
|
return q.size > 0 ? `?${q.toString()}` : "";
|
|
18
18
|
}
|
|
19
|
+
function obsProfileQS(q = {}) {
|
|
20
|
+
const p = new URLSearchParams();
|
|
21
|
+
for (const [k, v] of Object.entries(q)) {
|
|
22
|
+
if (v !== undefined && v !== "")
|
|
23
|
+
p.set(k, String(v));
|
|
24
|
+
}
|
|
25
|
+
const s = p.toString();
|
|
26
|
+
return s ? `?${s}` : "";
|
|
27
|
+
}
|
|
19
28
|
export const API_SCOPES = [
|
|
20
29
|
"project:read",
|
|
21
30
|
"deploy",
|
|
@@ -405,6 +414,634 @@ export class Client {
|
|
|
405
414
|
getDeployment(org, name, deploymentId) {
|
|
406
415
|
return this.json("GET", `${this.projectPath(org, name)}/deployments/${encodeURIComponent(deploymentId)}`);
|
|
407
416
|
}
|
|
417
|
+
/** Completed-front HTTP outcomes only; native crash-free health is unknown. */
|
|
418
|
+
getReleaseHealth(org, name) {
|
|
419
|
+
return this.json("GET", `${this.projectPath(org, name)}/error-releases`);
|
|
420
|
+
}
|
|
421
|
+
/** Historical first transition per issue; never substitutes a latest occurrence. */
|
|
422
|
+
listReleaseIssues(org, name, version, opts) {
|
|
423
|
+
const q = new URLSearchParams({ kind: opts.kind, windowStart: opts.windowStart, windowEnd: opts.windowEnd });
|
|
424
|
+
if (opts.cursor !== undefined)
|
|
425
|
+
q.set("cursor", opts.cursor);
|
|
426
|
+
return this.json("GET", `${this.projectPath(org, name)}/error-releases/${encodeURIComponent(String(version))}/issues?${q}`);
|
|
427
|
+
}
|
|
428
|
+
/** Runlot Errors: the issue stream (docs/customer-error-tracking.md). */
|
|
429
|
+
listErrorIssues(org, name, opts = {}) {
|
|
430
|
+
const q = new URLSearchParams();
|
|
431
|
+
if (opts.status)
|
|
432
|
+
q.set("status", opts.status);
|
|
433
|
+
if (opts.query)
|
|
434
|
+
q.set("query", opts.query);
|
|
435
|
+
if (opts.cursor)
|
|
436
|
+
q.set("cursor", opts.cursor);
|
|
437
|
+
if (opts.limit !== undefined)
|
|
438
|
+
q.set("limit", String(opts.limit));
|
|
439
|
+
const qs = q.size > 0 ? `?${q}` : "";
|
|
440
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors${qs}`);
|
|
441
|
+
}
|
|
442
|
+
getErrorIssue(org, name, issueId) {
|
|
443
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}`);
|
|
444
|
+
}
|
|
445
|
+
updateErrorIssue(org, name, issueId, update) {
|
|
446
|
+
return this.json("PATCH", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}`, update);
|
|
447
|
+
}
|
|
448
|
+
/** Source context, suspects and owners for the selected stored occurrence, or latest when omitted. */
|
|
449
|
+
async getErrorInsights(org, name, issueId, opts = {}) {
|
|
450
|
+
const eventId = opts.eventId;
|
|
451
|
+
const q = new URLSearchParams();
|
|
452
|
+
if (eventId !== undefined)
|
|
453
|
+
q.set("eventId", eventId);
|
|
454
|
+
const qs = q.size > 0 ? `?${q}` : "";
|
|
455
|
+
const out = await this.json("GET", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/insights${qs}`);
|
|
456
|
+
if (eventId !== undefined && (eventId === "" || out.eventId !== eventId)) {
|
|
457
|
+
throw new Error("Code insights did not identify the requested occurrence; this server may not support event selection.");
|
|
458
|
+
}
|
|
459
|
+
return out;
|
|
460
|
+
}
|
|
461
|
+
listErrorEvents(org, name, issueId, opts = {}) {
|
|
462
|
+
const q = new URLSearchParams();
|
|
463
|
+
if (opts.cursor)
|
|
464
|
+
q.set("cursor", opts.cursor);
|
|
465
|
+
if (opts.limit !== undefined)
|
|
466
|
+
q.set("limit", String(opts.limit));
|
|
467
|
+
const qs = q.size > 0 ? `?${q}` : "";
|
|
468
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/events${qs}`);
|
|
469
|
+
}
|
|
470
|
+
getErrorEvent(org, name, issueId, eventId) {
|
|
471
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/events/${encodeURIComponent(eventId)}`);
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Other events of the project joined to this one by front's request ID or a
|
|
475
|
+
* browser-minted trace ID (§12). Correlation only: issues are never merged.
|
|
476
|
+
*/
|
|
477
|
+
getRelatedErrorEvents(org, name, issueId, eventId) {
|
|
478
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/events/${encodeURIComponent(eventId)}/related`);
|
|
479
|
+
}
|
|
480
|
+
/** An issue's hourly history from the ClickHouse store; `available: false` where there is none. */
|
|
481
|
+
getErrorHistory(org, name, issueId, days) {
|
|
482
|
+
const qs = days !== undefined ? `?days=${encodeURIComponent(String(days))}` : "";
|
|
483
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/history${qs}`);
|
|
484
|
+
}
|
|
485
|
+
/** Assign an issue to an org member, or clear it with null. */
|
|
486
|
+
assignErrorIssue(org, name, issueId, userId) {
|
|
487
|
+
return this.json("PUT", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/assignee`, { userId });
|
|
488
|
+
}
|
|
489
|
+
listErrorComments(org, name, issueId) {
|
|
490
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/comments`);
|
|
491
|
+
}
|
|
492
|
+
/** Plain text, at most 4000 characters; the author is the signed-in user. */
|
|
493
|
+
addErrorComment(org, name, issueId, body) {
|
|
494
|
+
return this.json("POST", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/comments`, { body });
|
|
495
|
+
}
|
|
496
|
+
/** Merge up to ten issues of the same origin into `targetIssueId`. */
|
|
497
|
+
mergeErrorIssues(org, name, targetIssueId, sourceIssueIds) {
|
|
498
|
+
return this.json("POST", `${this.projectPath(org, name)}/errors/${encodeURIComponent(targetIssueId)}/merge`, {
|
|
499
|
+
sourceIssueIds,
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
/** Take a merged source back out of the issue it was merged into. */
|
|
503
|
+
unmergeErrorIssue(org, name, issueId) {
|
|
504
|
+
return this.json("POST", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/unmerge`);
|
|
505
|
+
}
|
|
506
|
+
/** Shared stack hints: frame overlap, never a merge or a causal claim. */
|
|
507
|
+
similarErrorIssues(org, name, issueId) {
|
|
508
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/similar`);
|
|
509
|
+
}
|
|
510
|
+
getErrorFingerprintRules(org, name) {
|
|
511
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors-fingerprint-rules`);
|
|
512
|
+
}
|
|
513
|
+
putErrorFingerprintRules(org, name, rules) {
|
|
514
|
+
return this.json("PUT", `${this.projectPath(org, name)}/errors-fingerprint-rules`, { rules });
|
|
515
|
+
}
|
|
516
|
+
getErrorAlerts(org, name) { return this.json("GET", `${this.projectPath(org, name)}/error-alerts`); }
|
|
517
|
+
putErrorAlertRule(org, name, id, rule) { return this.json("PUT", `${this.projectPath(org, name)}/error-alerts/rules/${encodeURIComponent(id)}`, rule); }
|
|
518
|
+
deleteErrorAlertRule(org, name, id) { return this.json("DELETE", `${this.projectPath(org, name)}/error-alerts/rules/${encodeURIComponent(id)}`); }
|
|
519
|
+
putErrorAlertDestination(org, name, id, input) { return this.json("PUT", `${this.projectPath(org, name)}/error-alerts/destinations/${encodeURIComponent(id)}`, input); }
|
|
520
|
+
deleteErrorAlertDestination(org, name, id) { return this.json("DELETE", `${this.projectPath(org, name)}/error-alerts/destinations/${encodeURIComponent(id)}`); }
|
|
521
|
+
getErrorAlertMail(org, name) { return this.json("GET", `${this.projectPath(org, name)}/error-alerts/mail`); }
|
|
522
|
+
putErrorAlertMail(org, name, preference) { return this.json("PUT", `${this.projectPath(org, name)}/error-alerts/mail`, preference); }
|
|
523
|
+
listErrorAlertDeliveries(org, name) { return this.json("GET", `${this.projectPath(org, name)}/error-alerts/deliveries`); }
|
|
524
|
+
// Monitors, downtimes and SLOs (docs/customer-observability.md §17.8, §17.9).
|
|
525
|
+
// Destinations are the error-alert destinations above, shared by both.
|
|
526
|
+
listMonitors(org, name) { return this.json("GET", `${this.projectPath(org, name)}/observability/monitors`); }
|
|
527
|
+
exportMonitors(org, name) { return this.json("GET", `${this.projectPath(org, name)}/observability/monitors/export`); }
|
|
528
|
+
getMonitor(org, name, id) { return this.json("GET", `${this.projectPath(org, name)}/observability/monitors/${encodeURIComponent(id)}`); }
|
|
529
|
+
putMonitor(org, name, id, monitor) { return this.json("PUT", `${this.projectPath(org, name)}/observability/monitors/${encodeURIComponent(id)}`, monitor); }
|
|
530
|
+
deleteMonitor(org, name, id) { return this.json("DELETE", `${this.projectPath(org, name)}/observability/monitors/${encodeURIComponent(id)}`); }
|
|
531
|
+
getMonitorHistory(org, name, id, limit) {
|
|
532
|
+
const q = limit ? `?limit=${encodeURIComponent(String(limit))}` : "";
|
|
533
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/monitors/${encodeURIComponent(id)}/history${q}`);
|
|
534
|
+
}
|
|
535
|
+
testMonitor(org, name, id) { return this.json("POST", `${this.projectPath(org, name)}/observability/monitors/${encodeURIComponent(id)}/test`); }
|
|
536
|
+
listDowntimes(org, name) { return this.json("GET", `${this.projectPath(org, name)}/observability/downtimes`); }
|
|
537
|
+
putDowntime(org, name, id, downtime) { return this.json("PUT", `${this.projectPath(org, name)}/observability/downtimes/${encodeURIComponent(id)}`, downtime); }
|
|
538
|
+
deleteDowntime(org, name, id) { return this.json("DELETE", `${this.projectPath(org, name)}/observability/downtimes/${encodeURIComponent(id)}`); }
|
|
539
|
+
listSLOs(org, name) { return this.json("GET", `${this.projectPath(org, name)}/observability/slos`); }
|
|
540
|
+
getSLO(org, name, id) { return this.json("GET", `${this.projectPath(org, name)}/observability/slos/${encodeURIComponent(id)}`); }
|
|
541
|
+
putSLO(org, name, id, slo) { return this.json("PUT", `${this.projectPath(org, name)}/observability/slos/${encodeURIComponent(id)}`, slo); }
|
|
542
|
+
deleteSLO(org, name, id) { return this.json("DELETE", `${this.projectPath(org, name)}/observability/slos/${encodeURIComponent(id)}`); }
|
|
543
|
+
/**
|
|
544
|
+
* Observability access and governance (customer-observability.md §12, §16, §17.15):
|
|
545
|
+
* the caller's grants, per-project role overrides, the audit trail, the data page,
|
|
546
|
+
* caps, export destinations and rehydration.
|
|
547
|
+
*/
|
|
548
|
+
getObservabilityPermissions(org, name) {
|
|
549
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/permissions`);
|
|
550
|
+
}
|
|
551
|
+
listObservabilityRoles(org, name) {
|
|
552
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/roles`);
|
|
553
|
+
}
|
|
554
|
+
putObservabilityRole(org, name, userId, grants) {
|
|
555
|
+
return this.json("PUT", `${this.projectPath(org, name)}/observability/roles/${encodeURIComponent(userId)}`, { grants });
|
|
556
|
+
}
|
|
557
|
+
deleteObservabilityRole(org, name, userId) {
|
|
558
|
+
return this.json("DELETE", `${this.projectPath(org, name)}/observability/roles/${encodeURIComponent(userId)}`);
|
|
559
|
+
}
|
|
560
|
+
listObservabilityAudit(org, name, opts = {}) {
|
|
561
|
+
const q = new URLSearchParams();
|
|
562
|
+
if (opts.limit !== undefined)
|
|
563
|
+
q.set("limit", String(opts.limit));
|
|
564
|
+
if (opts.before !== undefined)
|
|
565
|
+
q.set("before", opts.before);
|
|
566
|
+
const qs = q.size > 0 ? `?${q.toString()}` : "";
|
|
567
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/audit${qs}`);
|
|
568
|
+
}
|
|
569
|
+
getObservabilityData(org, name) {
|
|
570
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/data`);
|
|
571
|
+
}
|
|
572
|
+
getObservabilityCaps(org, name) {
|
|
573
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/caps`);
|
|
574
|
+
}
|
|
575
|
+
/** Named meters only: a number, -1 (no cap, Pro) or null (the plan's included amount). */
|
|
576
|
+
putObservabilityCaps(org, name, caps) {
|
|
577
|
+
return this.json("PUT", `${this.projectPath(org, name)}/observability/caps`, caps);
|
|
578
|
+
}
|
|
579
|
+
listObservabilityExports(org, name) {
|
|
580
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/exports`);
|
|
581
|
+
}
|
|
582
|
+
getObservabilityExport(org, name, exportId) {
|
|
583
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/exports/${encodeURIComponent(exportId)}`);
|
|
584
|
+
}
|
|
585
|
+
createObservabilityExport(org, name, input) {
|
|
586
|
+
return this.json("POST", `${this.projectPath(org, name)}/observability/exports`, input);
|
|
587
|
+
}
|
|
588
|
+
updateObservabilityExport(org, name, exportId, input) {
|
|
589
|
+
return this.json("PATCH", `${this.projectPath(org, name)}/observability/exports/${encodeURIComponent(exportId)}`, input);
|
|
590
|
+
}
|
|
591
|
+
deleteObservabilityExport(org, name, exportId) {
|
|
592
|
+
return this.json("DELETE", `${this.projectPath(org, name)}/observability/exports/${encodeURIComponent(exportId)}`);
|
|
593
|
+
}
|
|
594
|
+
listObservabilityRehydrations(org, name) {
|
|
595
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/rehydrations`);
|
|
596
|
+
}
|
|
597
|
+
getObservabilityRehydration(org, name, jobId) {
|
|
598
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/rehydrations/${encodeURIComponent(jobId)}`);
|
|
599
|
+
}
|
|
600
|
+
/** Loads an archived range back for seven days; the answer is the queued job. */
|
|
601
|
+
createObservabilityRehydration(org, name, input) {
|
|
602
|
+
return this.json("POST", `${this.projectPath(org, name)}/observability/rehydrations`, input);
|
|
603
|
+
}
|
|
604
|
+
/** `runlot bug-report` (customer-observability.md §14): the CP snapshots what the references name. */
|
|
605
|
+
createBugReport(org, input) {
|
|
606
|
+
return this.json("POST", `/v1/orgs/${encodeURIComponent(org)}/bug-reports`, input);
|
|
607
|
+
}
|
|
608
|
+
listBugReports(org) {
|
|
609
|
+
return this.json("GET", `/v1/orgs/${encodeURIComponent(org)}/bug-reports`);
|
|
610
|
+
}
|
|
611
|
+
getBugReport(org, reportId, opts = {}) {
|
|
612
|
+
const qs = opts.snapshot === false ? "?snapshot=0" : "";
|
|
613
|
+
return this.json("GET", `/v1/orgs/${encodeURIComponent(org)}/bug-reports/${encodeURIComponent(reportId)}${qs}`);
|
|
614
|
+
}
|
|
615
|
+
deleteBugReport(org, reportId) {
|
|
616
|
+
return this.json("DELETE", `/v1/orgs/${encodeURIComponent(org)}/bug-reports/${encodeURIComponent(reportId)}`);
|
|
617
|
+
}
|
|
618
|
+
/** Synthetic HTTP checks of the project's own addresses (customer-observability.md §17.11). */
|
|
619
|
+
listUptimeChecks(org, name) {
|
|
620
|
+
return this.json("GET", `${this.projectPath(org, name)}/uptime-checks`);
|
|
621
|
+
}
|
|
622
|
+
putUptimeCheck(org, name, id, input) {
|
|
623
|
+
return this.json("PUT", `${this.projectPath(org, name)}/uptime-checks/${encodeURIComponent(id)}`, input);
|
|
624
|
+
}
|
|
625
|
+
deleteUptimeCheck(org, name, id) {
|
|
626
|
+
return this.json("DELETE", `${this.projectPath(org, name)}/uptime-checks/${encodeURIComponent(id)}`);
|
|
627
|
+
}
|
|
628
|
+
listUptimeRuns(org, name, id, limit) {
|
|
629
|
+
const qs = limit !== undefined ? `?limit=${encodeURIComponent(String(limit))}` : "";
|
|
630
|
+
return this.json("GET", `${this.projectPath(org, name)}/uptime-checks/${encodeURIComponent(id)}/runs${qs}`);
|
|
631
|
+
}
|
|
632
|
+
/** Dashboards (customer-observability.md §17.7). A built-in's id is `builtin:<key>`. */
|
|
633
|
+
listDashboards(org, name) {
|
|
634
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/dashboards`);
|
|
635
|
+
}
|
|
636
|
+
createDashboard(org, name, input) {
|
|
637
|
+
return this.json("POST", `${this.projectPath(org, name)}/observability/dashboards`, input);
|
|
638
|
+
}
|
|
639
|
+
getDashboard(org, name, id) {
|
|
640
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/dashboards/${encodeURIComponent(id)}`);
|
|
641
|
+
}
|
|
642
|
+
putDashboard(org, name, id, input) {
|
|
643
|
+
return this.json("PUT", `${this.projectPath(org, name)}/observability/dashboards/${encodeURIComponent(id)}`, input);
|
|
644
|
+
}
|
|
645
|
+
deleteDashboard(org, name, id) {
|
|
646
|
+
return this.json("DELETE", `${this.projectPath(org, name)}/observability/dashboards/${encodeURIComponent(id)}`);
|
|
647
|
+
}
|
|
648
|
+
/** The `.runlot/dashboards/<key>.json` form of a dashboard. */
|
|
649
|
+
exportDashboard(org, name, id) {
|
|
650
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/dashboards/${encodeURIComponent(id)}/export`);
|
|
651
|
+
}
|
|
652
|
+
/** Make (or rotate) the public link; the token is shown once. */
|
|
653
|
+
shareDashboard(org, name, id, isPublic = true) {
|
|
654
|
+
return this.json("POST", `${this.projectPath(org, name)}/observability/dashboards/${encodeURIComponent(id)}/share`, { public: isPublic });
|
|
655
|
+
}
|
|
656
|
+
unshareDashboard(org, name, id) {
|
|
657
|
+
return this.json("DELETE", `${this.projectPath(org, name)}/observability/dashboards/${encodeURIComponent(id)}/share`);
|
|
658
|
+
}
|
|
659
|
+
getDashboardWidgetData(org, name, id, widgetId, req = {}) {
|
|
660
|
+
return this.json("POST", `${this.projectPath(org, name)}/observability/dashboards/${encodeURIComponent(id)}/widgets/${encodeURIComponent(widgetId)}/data`, req);
|
|
661
|
+
}
|
|
662
|
+
getDashboardSettings(org, name) {
|
|
663
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/dashboard-settings`);
|
|
664
|
+
}
|
|
665
|
+
putDashboardSettings(org, name, settings) {
|
|
666
|
+
return this.json("PUT", `${this.projectPath(org, name)}/observability/dashboard-settings`, settings);
|
|
667
|
+
}
|
|
668
|
+
/** Deploy and OOM markers for every time series. */
|
|
669
|
+
getObservabilityMarkers(org, name, range = {}) {
|
|
670
|
+
const q = new URLSearchParams();
|
|
671
|
+
if (range.from)
|
|
672
|
+
q.set("from", range.from);
|
|
673
|
+
if (range.to)
|
|
674
|
+
q.set("to", range.to);
|
|
675
|
+
const qs = q.toString();
|
|
676
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/markers${qs ? `?${qs}` : ""}`);
|
|
677
|
+
}
|
|
678
|
+
/** Watchdog insights (§17.10). Free: deploy regressions only. */
|
|
679
|
+
listInsights(org, name, opts = {}) {
|
|
680
|
+
const q = new URLSearchParams();
|
|
681
|
+
if (opts.state)
|
|
682
|
+
q.set("state", opts.state);
|
|
683
|
+
if (opts.limit !== undefined)
|
|
684
|
+
q.set("limit", String(opts.limit));
|
|
685
|
+
const qs = q.toString();
|
|
686
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/insights${qs ? `?${qs}` : ""}`);
|
|
687
|
+
}
|
|
688
|
+
resolveInsight(org, name, id) {
|
|
689
|
+
return this.json("POST", `${this.projectPath(org, name)}/observability/insights/${encodeURIComponent(id)}/resolve`);
|
|
690
|
+
}
|
|
691
|
+
/** Synthetic checks (§17.11): the uptime checks, including multi-step API checks. */
|
|
692
|
+
listSynthetics(org, name) {
|
|
693
|
+
return this.json("GET", `${this.projectPath(org, name)}/synthetics`);
|
|
694
|
+
}
|
|
695
|
+
putSynthetic(org, name, id, input) {
|
|
696
|
+
return this.json("PUT", `${this.projectPath(org, name)}/synthetics/${encodeURIComponent(id)}`, input);
|
|
697
|
+
}
|
|
698
|
+
deleteSynthetic(org, name, id) {
|
|
699
|
+
return this.json("DELETE", `${this.projectPath(org, name)}/synthetics/${encodeURIComponent(id)}`);
|
|
700
|
+
}
|
|
701
|
+
listSyntheticRuns(org, name, id, limit) {
|
|
702
|
+
const qs = limit !== undefined ? `?limit=${encodeURIComponent(String(limit))}` : "";
|
|
703
|
+
return this.json("GET", `${this.projectPath(org, name)}/synthetics/${encodeURIComponent(id)}/runs${qs}`);
|
|
704
|
+
}
|
|
705
|
+
/** A public dashboard link. Needs no credential. */
|
|
706
|
+
getSharedDashboard(token) {
|
|
707
|
+
return this.json("GET", `/v1/shared/dashboards/${encodeURIComponent(token)}`);
|
|
708
|
+
}
|
|
709
|
+
getSharedDashboardWidgetData(token, widgetId, req = {}) {
|
|
710
|
+
return this.json("POST", `/v1/shared/dashboards/${encodeURIComponent(token)}/widgets/${encodeURIComponent(widgetId)}/data`, req);
|
|
711
|
+
}
|
|
712
|
+
// Customer observability, APM read side (docs/customer-observability.md §8, §17.2–§17.4,
|
|
713
|
+
// §17.6). Range options are RFC 3339 times; `step` is seconds or a duration ("5m").
|
|
714
|
+
obsApmPath(org, name, sub, q) {
|
|
715
|
+
const qs = new URLSearchParams();
|
|
716
|
+
for (const [k, v] of Object.entries(q ?? {}))
|
|
717
|
+
if (v !== undefined && v !== "")
|
|
718
|
+
qs.set(k, String(v));
|
|
719
|
+
const tail = qs.size > 0 ? `?${qs}` : "";
|
|
720
|
+
return `${this.projectPath(org, name)}/observability/${sub}${tail}`;
|
|
721
|
+
}
|
|
722
|
+
getObsMetricsOverview(org, name, opts = {}) {
|
|
723
|
+
return this.json("GET", this.obsApmPath(org, name, "metrics/overview", opts));
|
|
724
|
+
}
|
|
725
|
+
getObsMetricsMemory(org, name, opts = {}) {
|
|
726
|
+
return this.json("GET", this.obsApmPath(org, name, "metrics/memory", opts));
|
|
727
|
+
}
|
|
728
|
+
getObsMetricsInfrastructure(org, name, opts = {}) {
|
|
729
|
+
return this.json("GET", this.obsApmPath(org, name, "metrics/infrastructure", opts));
|
|
730
|
+
}
|
|
731
|
+
getObsMetricsCustom(org, name, opts) {
|
|
732
|
+
return this.json("GET", this.obsApmPath(org, name, "metrics/custom", opts));
|
|
733
|
+
}
|
|
734
|
+
getObsMetricsCustomNames(org, name) {
|
|
735
|
+
return this.json("GET", this.obsApmPath(org, name, "metrics/custom/names"));
|
|
736
|
+
}
|
|
737
|
+
listObsRoutes(org, name) {
|
|
738
|
+
return this.json("GET", this.obsApmPath(org, name, "routes"));
|
|
739
|
+
}
|
|
740
|
+
putObsRoute(org, name, input) {
|
|
741
|
+
return this.json("PUT", this.obsApmPath(org, name, "routes"), input);
|
|
742
|
+
}
|
|
743
|
+
getObsAPMRoutes(org, name, opts = {}) {
|
|
744
|
+
return this.json("GET", this.obsApmPath(org, name, "apm/routes", opts));
|
|
745
|
+
}
|
|
746
|
+
getObsAPMBreakdown(org, name, route, opts = {}) {
|
|
747
|
+
return this.json("GET", this.obsApmPath(org, name, `apm/routes/${encodeURIComponent(route)}/breakdown`, opts));
|
|
748
|
+
}
|
|
749
|
+
getObsAPMServiceMap(org, name, opts = {}) {
|
|
750
|
+
return this.json("GET", this.obsApmPath(org, name, "apm/service-map", opts));
|
|
751
|
+
}
|
|
752
|
+
getObsAPMCompare(org, name, a, b, opts = {}) {
|
|
753
|
+
return this.json("GET", this.obsApmPath(org, name, "apm/compare", { ...opts, a, b }));
|
|
754
|
+
}
|
|
755
|
+
listObsAPMTraces(org, name, opts = {}) {
|
|
756
|
+
return this.json("GET", this.obsApmPath(org, name, "apm/traces", opts));
|
|
757
|
+
}
|
|
758
|
+
getObsAPMTrace(org, name, traceId) {
|
|
759
|
+
return this.json("GET", this.obsApmPath(org, name, `apm/traces/${encodeURIComponent(traceId)}`));
|
|
760
|
+
}
|
|
761
|
+
listObsTraceFilters(org, name) {
|
|
762
|
+
return this.json("GET", this.obsApmPath(org, name, "trace-filters"));
|
|
763
|
+
}
|
|
764
|
+
createObsTraceFilter(org, name, input) {
|
|
765
|
+
return this.json("POST", this.obsApmPath(org, name, "trace-filters"), input);
|
|
766
|
+
}
|
|
767
|
+
updateObsTraceFilter(org, name, id, input) {
|
|
768
|
+
return this.json("PUT", this.obsApmPath(org, name, `trace-filters/${encodeURIComponent(id)}`), input);
|
|
769
|
+
}
|
|
770
|
+
deleteObsTraceFilter(org, name, id) {
|
|
771
|
+
return this.json("DELETE", this.obsApmPath(org, name, `trace-filters/${encodeURIComponent(id)}`));
|
|
772
|
+
}
|
|
773
|
+
listObsDBQueries(org, name, opts = {}) {
|
|
774
|
+
return this.json("GET", this.obsApmPath(org, name, "database/queries", opts));
|
|
775
|
+
}
|
|
776
|
+
getObsDBQuery(org, name, fingerprint, opts = {}) {
|
|
777
|
+
return this.json("GET", this.obsApmPath(org, name, `database/queries/${encodeURIComponent(fingerprint)}`, opts));
|
|
778
|
+
}
|
|
779
|
+
getObsDBHealth(org, name) {
|
|
780
|
+
return this.json("GET", this.obsApmPath(org, name, "database/health"));
|
|
781
|
+
}
|
|
782
|
+
/** The continuous profiler's switch (customer-observability.md §17.13). */
|
|
783
|
+
getObsProfilerSettings(org, name) {
|
|
784
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/profiler`);
|
|
785
|
+
}
|
|
786
|
+
/** On, off, or null for the default. Applies from the next deployment or restart. Admin. */
|
|
787
|
+
putObsProfilerSettings(org, name, enabled) {
|
|
788
|
+
return this.json("PUT", `${this.projectPath(org, name)}/observability/profiler`, { enabled });
|
|
789
|
+
}
|
|
790
|
+
/** The logs/traces sampling override; a null field is the manifest's. */
|
|
791
|
+
getObsSampling(org, name) {
|
|
792
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/sampling`);
|
|
793
|
+
}
|
|
794
|
+
/** Replaces the override (null = the manifest's). Admin. */
|
|
795
|
+
putObsSampling(org, name, body) {
|
|
796
|
+
return this.json("PUT", `${this.projectPath(org, name)}/observability/sampling`, body);
|
|
797
|
+
}
|
|
798
|
+
listObsProfiles(org, name, q = {}) {
|
|
799
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/profiles${obsProfileQS({ ...q })}`);
|
|
800
|
+
}
|
|
801
|
+
/** The windows within a minute of `ts` — the profile of a slow trace's minute. */
|
|
802
|
+
nearObsProfiles(org, name, ts) {
|
|
803
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/profiles/near${obsProfileQS({ ts })}`);
|
|
804
|
+
}
|
|
805
|
+
getObsFlamegraph(org, name, q = {}) {
|
|
806
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/profiles/flamegraph${obsProfileQS({ ...q })}`);
|
|
807
|
+
}
|
|
808
|
+
getObsProfileTop(org, name, q = {}) {
|
|
809
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/profiles/top${obsProfileQS({ ...q })}`);
|
|
810
|
+
}
|
|
811
|
+
/** Self-time share per function, version a against version b. */
|
|
812
|
+
compareObsProfiles(org, name, a, b, q = {}) {
|
|
813
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/profiles/compare${obsProfileQS({ a, b, ...q })}`);
|
|
814
|
+
}
|
|
815
|
+
/** RUM: page views, sessions and p75 vitals over time (Pro). */
|
|
816
|
+
getObsRUMOverview(org, name, q = {}) {
|
|
817
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/rum/overview${obsProfileQS({ ...q })}`);
|
|
818
|
+
}
|
|
819
|
+
/** RUM by page template, with vitals, long tasks and resource/fetch timings (Pro). */
|
|
820
|
+
listObsRUMPages(org, name, q = {}) {
|
|
821
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/rum/pages${obsProfileQS({ ...q })}`);
|
|
822
|
+
}
|
|
823
|
+
/** RUM by device class (Pro). */
|
|
824
|
+
listObsRUMDevices(org, name, q = {}) {
|
|
825
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/rum/devices${obsProfileQS({ ...q })}`);
|
|
826
|
+
}
|
|
827
|
+
/** RUM page views, newest (or slowest LCP) first (Pro). */
|
|
828
|
+
listObsRUMViews(org, name, q = {}) {
|
|
829
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/rum/views${obsProfileQS({ ...q })}`);
|
|
830
|
+
}
|
|
831
|
+
/** One page view and the server requests it caused (Pro). */
|
|
832
|
+
getObsRUMView(org, name, viewId) {
|
|
833
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/rum/views/${encodeURIComponent(viewId)}`);
|
|
834
|
+
}
|
|
835
|
+
/** Starts one heap snapshot (Pro, admin; pauses the app while taken). Poll the list. */
|
|
836
|
+
createObsHeapSnapshot(org, name) {
|
|
837
|
+
return this.json("POST", `${this.projectPath(org, name)}/observability/heap-snapshots`, {});
|
|
838
|
+
}
|
|
839
|
+
listObsHeapSnapshots(org, name) {
|
|
840
|
+
return this.json("GET", `${this.projectPath(org, name)}/observability/heap-snapshots`);
|
|
841
|
+
}
|
|
842
|
+
/** The download URL of a ready snapshot (a `.heapsnapshot` file). */
|
|
843
|
+
obsHeapSnapshotURL(org, name, snapshotId) {
|
|
844
|
+
return new URL(`${this.projectPath(org, name)}/observability/heap-snapshots/${encodeURIComponent(snapshotId)}`, this.opts.baseUrl).toString();
|
|
845
|
+
}
|
|
846
|
+
/** A ready snapshot's text (Chrome DevTools heap snapshot JSON). */
|
|
847
|
+
downloadObsHeapSnapshot(org, name, snapshotId) {
|
|
848
|
+
return this.text("GET", `${this.projectPath(org, name)}/observability/heap-snapshots/${encodeURIComponent(snapshotId)}`);
|
|
849
|
+
}
|
|
850
|
+
getErrorOwnership(org, name) {
|
|
851
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors-ownership`);
|
|
852
|
+
}
|
|
853
|
+
createErrorOwnershipPin(org, name, input) {
|
|
854
|
+
return this.json("POST", `${this.projectPath(org, name)}/errors-ownership/pins`, input);
|
|
855
|
+
}
|
|
856
|
+
revokeErrorOwnershipPin(org, name, deploymentId, selector) {
|
|
857
|
+
return this.json("DELETE", `${this.projectPath(org, name)}/errors-ownership/pins/${encodeURIComponent(deploymentId)}/${encodeURIComponent(selector)}`);
|
|
858
|
+
}
|
|
859
|
+
getErrorCapturePolicy(org, name) {
|
|
860
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors-capture-policy`);
|
|
861
|
+
}
|
|
862
|
+
putErrorCapturePolicy(org, name, policy, acknowledgePII = false) {
|
|
863
|
+
return this.json("PUT", `${this.projectPath(org, name)}/errors-capture-policy`, { policy, acknowledgePII });
|
|
864
|
+
}
|
|
865
|
+
// ---- Observability (docs/customer-observability.md §7, §17.5) ----
|
|
866
|
+
obsPath(org, name) {
|
|
867
|
+
return `${this.projectPath(org, name)}/observability`;
|
|
868
|
+
}
|
|
869
|
+
getObservabilityCapabilities(org, name) {
|
|
870
|
+
return this.json("GET", `${this.obsPath(org, name)}/capabilities`);
|
|
871
|
+
}
|
|
872
|
+
/** Runs a query; `{ available: false }` where there is no event store. */
|
|
873
|
+
queryObservability(org, name, query) {
|
|
874
|
+
return this.json("POST", `${this.obsPath(org, name)}/query`, query);
|
|
875
|
+
}
|
|
876
|
+
listObservabilityKeys(org, name, opts = {}) {
|
|
877
|
+
return this.json("GET", `${this.obsPath(org, name)}/keys${obsQS(opts)}`);
|
|
878
|
+
}
|
|
879
|
+
listObservabilityValues(org, name, key, opts = {}) {
|
|
880
|
+
return this.json("GET", `${this.obsPath(org, name)}/values${obsQS({ ...opts, key })}`);
|
|
881
|
+
}
|
|
882
|
+
listObservabilityPatterns(org, name, opts = {}) {
|
|
883
|
+
return this.json("GET", `${this.obsPath(org, name)}/patterns${obsQS(opts)}`);
|
|
884
|
+
}
|
|
885
|
+
getObservabilityRequest(org, name, requestId) {
|
|
886
|
+
return this.json("GET", `${this.obsPath(org, name)}/requests/${encodeURIComponent(requestId)}`);
|
|
887
|
+
}
|
|
888
|
+
listSavedQueries(org, name) {
|
|
889
|
+
return this.json("GET", `${this.obsPath(org, name)}/saved-queries`);
|
|
890
|
+
}
|
|
891
|
+
getSavedQuery(org, name, queryId) {
|
|
892
|
+
return this.json("GET", `${this.obsPath(org, name)}/saved-queries/${encodeURIComponent(queryId)}`);
|
|
893
|
+
}
|
|
894
|
+
createSavedQuery(org, name, input) {
|
|
895
|
+
return this.json("POST", `${this.obsPath(org, name)}/saved-queries`, input);
|
|
896
|
+
}
|
|
897
|
+
updateSavedQuery(org, name, queryId, input) {
|
|
898
|
+
return this.json("PUT", `${this.obsPath(org, name)}/saved-queries/${encodeURIComponent(queryId)}`, input);
|
|
899
|
+
}
|
|
900
|
+
deleteSavedQuery(org, name, queryId) {
|
|
901
|
+
return this.json("DELETE", `${this.obsPath(org, name)}/saved-queries/${encodeURIComponent(queryId)}`);
|
|
902
|
+
}
|
|
903
|
+
starSavedQuery(org, name, queryId) {
|
|
904
|
+
return this.json("PUT", `${this.obsPath(org, name)}/saved-queries/${encodeURIComponent(queryId)}/star`);
|
|
905
|
+
}
|
|
906
|
+
unstarSavedQuery(org, name, queryId) {
|
|
907
|
+
return this.json("DELETE", `${this.obsPath(org, name)}/saved-queries/${encodeURIComponent(queryId)}/star`);
|
|
908
|
+
}
|
|
909
|
+
getObservabilityPipeline(org, name) {
|
|
910
|
+
return this.json("GET", `${this.obsPath(org, name)}/pipeline`);
|
|
911
|
+
}
|
|
912
|
+
putObservabilityPipeline(org, name, processors) {
|
|
913
|
+
return this.json("PUT", `${this.obsPath(org, name)}/pipeline`, { processors });
|
|
914
|
+
}
|
|
915
|
+
getObservabilityScanner(org, name) {
|
|
916
|
+
return this.json("GET", `${this.obsPath(org, name)}/scanner`);
|
|
917
|
+
}
|
|
918
|
+
putObservabilityScanner(org, name, scanner) {
|
|
919
|
+
return this.json("PUT", `${this.obsPath(org, name)}/scanner`, scanner);
|
|
920
|
+
}
|
|
921
|
+
/** Runs a scanner (the project's, or `scanner`) over a sample; nothing is stored. */
|
|
922
|
+
testObservabilityScanner(org, name, text, scanner) {
|
|
923
|
+
return this.json("POST", `${this.obsPath(org, name)}/scanner/test`, scanner ? { text, scanner } : { text });
|
|
924
|
+
}
|
|
925
|
+
/** The whole ingest configuration, shaped as `.runlot/logs.json`. */
|
|
926
|
+
exportObservabilityLogsConfig(org, name) {
|
|
927
|
+
return this.json("GET", `${this.obsPath(org, name)}/logs-config`);
|
|
928
|
+
}
|
|
929
|
+
listObservabilityLogMetrics(org, name) {
|
|
930
|
+
return this.json("GET", `${this.obsPath(org, name)}/log-metrics`);
|
|
931
|
+
}
|
|
932
|
+
putObservabilityLogMetric(org, name, metric, def) {
|
|
933
|
+
return this.json("PUT", `${this.obsPath(org, name)}/log-metrics/${encodeURIComponent(metric)}`, def);
|
|
934
|
+
}
|
|
935
|
+
deleteObservabilityLogMetric(org, name, metric) {
|
|
936
|
+
return this.json("DELETE", `${this.obsPath(org, name)}/log-metrics/${encodeURIComponent(metric)}`);
|
|
937
|
+
}
|
|
938
|
+
getErrorEventPII(org, name, issueId, eventId) {
|
|
939
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/events/${encodeURIComponent(eventId)}?includePII=true`);
|
|
940
|
+
}
|
|
941
|
+
getErrorSettings(org, name) {
|
|
942
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors-settings`);
|
|
943
|
+
}
|
|
944
|
+
putErrorSettings(org, name,
|
|
945
|
+
/** Omitted writable fields preserve their values; ownership assignment defaults off. */
|
|
946
|
+
settings) {
|
|
947
|
+
return this.json("PUT", `${this.projectPath(org, name)}/errors-settings`, settings);
|
|
948
|
+
}
|
|
949
|
+
/**
|
|
950
|
+
* One AI diagnosis of an issue, billed to the org's AI credit. There is no
|
|
951
|
+
* prompt to pass: the control plane builds it from the issue's stored event.
|
|
952
|
+
* The same `idempotencyKey` again returns the stored answer without a second
|
|
953
|
+
* charge, so a caller retrying after a timeout must reuse its key.
|
|
954
|
+
*/
|
|
955
|
+
diagnoseErrorIssue(org, name, issueId, body) {
|
|
956
|
+
return this.json("POST", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/diagnoses`, body);
|
|
957
|
+
}
|
|
958
|
+
listErrorDiagnoses(org, name, issueId) {
|
|
959
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/diagnoses`);
|
|
960
|
+
}
|
|
961
|
+
fixPath(org, name, issueId) {
|
|
962
|
+
return `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/fix-proposals`;
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* Ask a model to propose a fix for an issue. Billed to the org's AI credit and
|
|
966
|
+
* writes nothing: the repository, base commit and files are chosen by the control
|
|
967
|
+
* plane. Reuse `idempotencyKey` on a retry so it is not charged twice.
|
|
968
|
+
*/
|
|
969
|
+
proposeErrorFix(org, name, issueId, body) {
|
|
970
|
+
return this.json("POST", this.fixPath(org, name, issueId), body);
|
|
971
|
+
}
|
|
972
|
+
listErrorFixProposals(org, name, issueId) {
|
|
973
|
+
return this.json("GET", this.fixPath(org, name, issueId));
|
|
974
|
+
}
|
|
975
|
+
getErrorFixProposal(org, name, issueId, proposalId) {
|
|
976
|
+
return this.json("GET", `${this.fixPath(org, name, issueId)}/${encodeURIComponent(proposalId)}`);
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* Write a ready proposal as one commit on its own `runlot/autofix/` branch. It
|
|
980
|
+
* builds, deploys and merges nothing. `proposalSha` must be the proposal's exactly.
|
|
981
|
+
*/
|
|
982
|
+
applyErrorFix(org, name, issueId, proposalId, proposalSha) {
|
|
983
|
+
return this.json("POST", `${this.fixPath(org, name, issueId)}/${encodeURIComponent(proposalId)}/apply`, {
|
|
984
|
+
proposalSha,
|
|
985
|
+
acknowledgeUnreviewedCode: true,
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
lookupErrorFixProposal(org, name, issueId, key) {
|
|
989
|
+
return this.request("GET", `${this.fixPath(org, name, issueId)}/lookup`, { headers: { "Idempotency-Key": key } });
|
|
990
|
+
}
|
|
991
|
+
lookupErrorFixPreview(org, name, issueId, proposalId, key) {
|
|
992
|
+
return this.request("GET", `${this.fixPath(org, name, issueId)}/${encodeURIComponent(proposalId)}/previews/lookup`, { headers: { "Idempotency-Key": key } });
|
|
993
|
+
}
|
|
994
|
+
lookupErrorFixVerification(org, name, issueId, proposalId, jobId, key) {
|
|
995
|
+
return this.request("GET", `${this.fixPath(org, name, issueId)}/${encodeURIComponent(proposalId)}/previews/${encodeURIComponent(jobId)}/verify/lookup`, { headers: { "Idempotency-Key": key } });
|
|
996
|
+
}
|
|
997
|
+
approveErrorFixPreview(org, name, issueId, proposalId, body) {
|
|
998
|
+
return this.json("POST", `${this.fixPath(org, name, issueId)}/${encodeURIComponent(proposalId)}/previews`, body);
|
|
999
|
+
}
|
|
1000
|
+
getErrorFixPreview(org, name, issueId, proposalId, jobId) {
|
|
1001
|
+
return this.json("GET", `${this.fixPath(org, name, issueId)}/${encodeURIComponent(proposalId)}/previews/${encodeURIComponent(jobId)}`);
|
|
1002
|
+
}
|
|
1003
|
+
approveErrorFixPreviewVerification(org, name, issueId, proposalId, jobId, body) {
|
|
1004
|
+
return this.json("POST", `${this.fixPath(org, name, issueId)}/${encodeURIComponent(proposalId)}/previews/${encodeURIComponent(jobId)}/verify`, body);
|
|
1005
|
+
}
|
|
1006
|
+
/** Erase captured issue data, after explicit review. Admin; unmerge first. */
|
|
1007
|
+
deleteErrorIssue(org, name, issueId) {
|
|
1008
|
+
return this.json("DELETE", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}`);
|
|
1009
|
+
}
|
|
1010
|
+
/** Erase an exact application user ID; anonymous aggregates remain. Admin. */
|
|
1011
|
+
eraseErrorUser(org, name, userId) {
|
|
1012
|
+
return this.json("POST", `${this.projectPath(org, name)}/errors-erasure`, { userId });
|
|
1013
|
+
}
|
|
1014
|
+
/** Untrusted browser histograms and technical-fuse counters, not billed usage. Viewer. */
|
|
1015
|
+
getBrowserTelemetry(org, name) {
|
|
1016
|
+
return this.json("GET", `${this.projectPath(org, name)}/browser-telemetry`);
|
|
1017
|
+
}
|
|
1018
|
+
/** Unverified feedback whose exact browser error anchor belongs to this issue. Never includes email. */
|
|
1019
|
+
listBrowserFeedback(org, name, issueId) {
|
|
1020
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/feedback`);
|
|
1021
|
+
}
|
|
1022
|
+
/** Explicit sensitive read. Admin + errors:pii; optional unverified email only while feedback-email retention is on. */
|
|
1023
|
+
listBrowserFeedbackWithPII(org, name, issueId) {
|
|
1024
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/feedback?includePII=true`);
|
|
1025
|
+
}
|
|
1026
|
+
/** The masked structural replay switch, cap and this month's count. Viewer. */
|
|
1027
|
+
getErrorReplaySettings(org, name) {
|
|
1028
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors-replay-settings`);
|
|
1029
|
+
}
|
|
1030
|
+
/**
|
|
1031
|
+
* Both fields are required: `monthlyCap` null is the plan's amount, `0` stops collection,
|
|
1032
|
+
* `-1` removes the cap (Pro). Admin.
|
|
1033
|
+
*/
|
|
1034
|
+
putErrorReplaySettings(org, name, settings) {
|
|
1035
|
+
return this.json("PUT", `${this.projectPath(org, name)}/errors-replay-settings`, settings);
|
|
1036
|
+
}
|
|
1037
|
+
/** An issue's complete masked structural replays. Admin, until a granular PII scope exists. */
|
|
1038
|
+
listErrorReplays(org, name, issueId) {
|
|
1039
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/replays`);
|
|
1040
|
+
}
|
|
1041
|
+
/** One replay and its re-validated batches, for the sandboxed player. Admin. */
|
|
1042
|
+
getErrorReplay(org, name, issueId, replayId) {
|
|
1043
|
+
return this.json("GET", `${this.projectPath(org, name)}/errors/${encodeURIComponent(issueId)}/replays/${encodeURIComponent(replayId)}`);
|
|
1044
|
+
}
|
|
408
1045
|
/**
|
|
409
1046
|
* Scheduled runs: what the live deployment declares, when each fires next, and
|
|
410
1047
|
* the recent history (docs/cron.md §8). `limit` bounds the history rows only —
|
|
@@ -689,11 +1326,31 @@ export class Client {
|
|
|
689
1326
|
* (4xx/5xx) is the same `ApiError` as in every other method.
|
|
690
1327
|
*/
|
|
691
1328
|
async *tailLogs(org, name, opts = {}) {
|
|
1329
|
+
yield* this.tailStream(org, name, opts, undefined);
|
|
1330
|
+
}
|
|
1331
|
+
/**
|
|
1332
|
+
* The live tail as `LogRecord`s — the stored event's shape (`--format json`).
|
|
1333
|
+
* Pings and the end event still arrive as `LogEvent`s.
|
|
1334
|
+
*/
|
|
1335
|
+
async *tailLogRecords(org, name, opts = {}) {
|
|
1336
|
+
yield* this.tailStream(org, name, opts, "json");
|
|
1337
|
+
}
|
|
1338
|
+
async *tailStream(org, name, opts, format) {
|
|
692
1339
|
const q = new URLSearchParams();
|
|
693
1340
|
if (opts.tail !== undefined)
|
|
694
1341
|
q.set("tail", String(opts.tail));
|
|
695
1342
|
if (opts.follow !== undefined)
|
|
696
1343
|
q.set("follow", String(opts.follow));
|
|
1344
|
+
if (opts.level)
|
|
1345
|
+
q.set("level", opts.level);
|
|
1346
|
+
if (opts.source)
|
|
1347
|
+
q.set("source", opts.source);
|
|
1348
|
+
if (opts.q)
|
|
1349
|
+
q.set("q", opts.q);
|
|
1350
|
+
if (opts.requestId)
|
|
1351
|
+
q.set("requestId", opts.requestId);
|
|
1352
|
+
if (format)
|
|
1353
|
+
q.set("format", format);
|
|
697
1354
|
const path = `${this.projectPath(org, name)}/logs${q.size ? `?${q}` : ""}`;
|
|
698
1355
|
const res = await fetch(new URL(path, this.opts.baseUrl), {
|
|
699
1356
|
method: "GET",
|
|
@@ -1402,4 +2059,12 @@ export class Client {
|
|
|
1402
2059
|
return this.json("POST", `/v1/orgs/${encodeURIComponent(org)}/projects/${encodeURIComponent(name)}/rollback`, { version });
|
|
1403
2060
|
}
|
|
1404
2061
|
}
|
|
2062
|
+
/** A query string from the defined, non-empty options. */
|
|
2063
|
+
function obsQS(opts) {
|
|
2064
|
+
const q = new URLSearchParams();
|
|
2065
|
+
for (const [k, v] of Object.entries(opts))
|
|
2066
|
+
if (v)
|
|
2067
|
+
q.set(k, v);
|
|
2068
|
+
return q.size ? `?${q}` : "";
|
|
2069
|
+
}
|
|
1405
2070
|
//# sourceMappingURL=index.js.map
|