@hasna/uptime 0.1.9 → 0.1.10
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/CHANGELOG.md +13 -0
- package/SECURITY.md +4 -2
- package/dist/api.js +104 -47
- package/dist/checks.d.ts +2 -1
- package/dist/checks.d.ts.map +1 -1
- package/dist/checks.js +2 -1
- package/dist/cli/index.js +105 -48
- package/dist/cloud-plan.js +1 -1
- package/dist/index.js +105 -48
- package/dist/mcp/index.js +92 -37
- package/dist/service.d.ts +33 -9
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +92 -37
- package/dist/store.d.ts +13 -3
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +78 -25
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/aws-deployment-runbook.md +214 -5
- package/infra/aws/terraform.tfvars.example +1 -1
- package/infra/aws/variables.tf +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -3426,7 +3426,7 @@ var REQUIRED_TABLES = [
|
|
|
3426
3426
|
];
|
|
3427
3427
|
var PROBE_TABLES = new Set(["probe_identities", "probe_check_jobs", "probe_submissions"]);
|
|
3428
3428
|
var REPORT_AUDIT_TABLES = new Set(["report_schedules", "report_runs", "audit_events"]);
|
|
3429
|
-
var CURRENT_SCHEMA_VERSION = "
|
|
3429
|
+
var CURRENT_SCHEMA_VERSION = "4";
|
|
3430
3430
|
|
|
3431
3431
|
class StaleCheckResultError extends Error {
|
|
3432
3432
|
constructor(message) {
|
|
@@ -3487,7 +3487,8 @@ class UptimeStore {
|
|
|
3487
3487
|
this.db.run(`
|
|
3488
3488
|
CREATE TABLE IF NOT EXISTS monitors (
|
|
3489
3489
|
id TEXT PRIMARY KEY,
|
|
3490
|
-
|
|
3490
|
+
workspace_id TEXT NOT NULL DEFAULT 'local',
|
|
3491
|
+
name TEXT NOT NULL,
|
|
3491
3492
|
kind TEXT NOT NULL CHECK (kind IN ('http', 'tcp', 'browser_page')),
|
|
3492
3493
|
url TEXT,
|
|
3493
3494
|
host TEXT,
|
|
@@ -3502,9 +3503,11 @@ class UptimeStore {
|
|
|
3502
3503
|
last_checked_at TEXT,
|
|
3503
3504
|
revision INTEGER NOT NULL DEFAULT 1,
|
|
3504
3505
|
created_at TEXT NOT NULL,
|
|
3505
|
-
updated_at TEXT NOT NULL
|
|
3506
|
+
updated_at TEXT NOT NULL,
|
|
3507
|
+
UNIQUE (workspace_id, name)
|
|
3506
3508
|
)
|
|
3507
3509
|
`);
|
|
3510
|
+
this.ensureColumn("monitors", "workspace_id", "TEXT NOT NULL DEFAULT 'local'");
|
|
3508
3511
|
this.ensureColumn("monitors", "revision", "INTEGER NOT NULL DEFAULT 1");
|
|
3509
3512
|
this.ensureMonitorKindAllowsBrowserPage();
|
|
3510
3513
|
this.db.run(`
|
|
@@ -3654,6 +3657,7 @@ class UptimeStore {
|
|
|
3654
3657
|
`);
|
|
3655
3658
|
this.db.query("INSERT OR REPLACE INTO schema_migrations (key, value, updated_at) VALUES ('schema_version', ?, ?)").run(CURRENT_SCHEMA_VERSION, new Date().toISOString());
|
|
3656
3659
|
this.db.run("CREATE INDEX IF NOT EXISTS idx_results_monitor_time ON check_results(monitor_id, checked_at DESC)");
|
|
3660
|
+
this.db.run("CREATE INDEX IF NOT EXISTS idx_monitors_workspace_enabled_name ON monitors(workspace_id, enabled, name)");
|
|
3657
3661
|
this.db.run("CREATE INDEX IF NOT EXISTS idx_incidents_monitor_status ON incidents(monitor_id, status)");
|
|
3658
3662
|
this.db.run("CREATE INDEX IF NOT EXISTS idx_check_leases_until ON check_leases(leased_until)");
|
|
3659
3663
|
this.db.run("CREATE INDEX IF NOT EXISTS idx_monitor_provenance_monitor ON monitor_provenance(monitor_id)");
|
|
@@ -3715,8 +3719,10 @@ class UptimeStore {
|
|
|
3715
3719
|
if (this.mode === "hosted")
|
|
3716
3720
|
assertHostedTargetAllowed(normalized);
|
|
3717
3721
|
const now = new Date().toISOString();
|
|
3722
|
+
const workspaceId = normalizeWorkspaceId(options.workspaceId ?? input.workspaceId ?? "local");
|
|
3718
3723
|
const monitor = {
|
|
3719
3724
|
id: newId("mon"),
|
|
3725
|
+
workspaceId,
|
|
3720
3726
|
name: normalized.name,
|
|
3721
3727
|
kind: normalized.kind,
|
|
3722
3728
|
url: normalized.url ?? null,
|
|
@@ -3735,22 +3741,33 @@ class UptimeStore {
|
|
|
3735
3741
|
updatedAt: now
|
|
3736
3742
|
};
|
|
3737
3743
|
this.db.query(`INSERT INTO monitors (
|
|
3738
|
-
id, name, kind, url, host, port, method, expected_status,
|
|
3744
|
+
id, workspace_id, name, kind, url, host, port, method, expected_status,
|
|
3739
3745
|
interval_seconds, timeout_ms, retry_count, enabled, status,
|
|
3740
3746
|
last_checked_at, revision, created_at, updated_at
|
|
3741
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(monitor.id, monitor.name, monitor.kind, monitor.url, monitor.host, monitor.port, monitor.method, monitor.expectedStatus, monitor.intervalSeconds, monitor.timeoutMs, monitor.retryCount, monitor.enabled ? 1 : 0, monitor.status, monitor.lastCheckedAt, monitor.revision, monitor.createdAt, monitor.updatedAt);
|
|
3747
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(monitor.id, monitor.workspaceId, monitor.name, monitor.kind, monitor.url, monitor.host, monitor.port, monitor.method, monitor.expectedStatus, monitor.intervalSeconds, monitor.timeoutMs, monitor.retryCount, monitor.enabled ? 1 : 0, monitor.status, monitor.lastCheckedAt, monitor.revision, monitor.createdAt, monitor.updatedAt);
|
|
3742
3748
|
return monitor;
|
|
3743
3749
|
}
|
|
3744
3750
|
listMonitors(options = {}) {
|
|
3745
|
-
const
|
|
3751
|
+
const workspaceId = options.workspaceId ? normalizeWorkspaceId(options.workspaceId) : undefined;
|
|
3752
|
+
const clauses = [];
|
|
3753
|
+
const args = [];
|
|
3754
|
+
if (workspaceId) {
|
|
3755
|
+
clauses.push("workspace_id = ?");
|
|
3756
|
+
args.push(workspaceId);
|
|
3757
|
+
}
|
|
3758
|
+
if (!options.includeDisabled)
|
|
3759
|
+
clauses.push("enabled = 1");
|
|
3760
|
+
const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
|
|
3761
|
+
const rows = this.db.query(`SELECT * FROM monitors ${where} ORDER BY name ASC`).all(...args);
|
|
3746
3762
|
return rows.map(monitorFromRow);
|
|
3747
3763
|
}
|
|
3748
|
-
getMonitor(idOrName) {
|
|
3749
|
-
const
|
|
3764
|
+
getMonitor(idOrName, options = {}) {
|
|
3765
|
+
const workspaceId = options.workspaceId ? normalizeWorkspaceId(options.workspaceId) : undefined;
|
|
3766
|
+
const row = this.db.query(`SELECT * FROM monitors WHERE (id = ? OR name = ?)${workspaceId ? " AND workspace_id = ?" : ""}`).get(...workspaceId ? [idOrName, idOrName, workspaceId] : [idOrName, idOrName]);
|
|
3750
3767
|
return row ? monitorFromRow(row) : null;
|
|
3751
3768
|
}
|
|
3752
3769
|
updateMonitor(idOrName, input, options = {}) {
|
|
3753
|
-
const current = this.getMonitor(idOrName);
|
|
3770
|
+
const current = this.getMonitor(idOrName, { workspaceId: options.workspaceId });
|
|
3754
3771
|
if (!current)
|
|
3755
3772
|
throw new Error(`Monitor not found: ${idOrName}`);
|
|
3756
3773
|
if (this.mode === "hosted") {
|
|
@@ -3774,10 +3791,10 @@ class UptimeStore {
|
|
|
3774
3791
|
if (definitionChanged(current, next)) {
|
|
3775
3792
|
this.closeOpenIncident(current.id, updatedAt);
|
|
3776
3793
|
}
|
|
3777
|
-
return this.getMonitor(current.id);
|
|
3794
|
+
return this.getMonitor(current.id, { workspaceId: options.workspaceId });
|
|
3778
3795
|
}
|
|
3779
|
-
deleteMonitor(idOrName) {
|
|
3780
|
-
const current = this.getMonitor(idOrName);
|
|
3796
|
+
deleteMonitor(idOrName, options = {}) {
|
|
3797
|
+
const current = this.getMonitor(idOrName, { workspaceId: options.workspaceId });
|
|
3781
3798
|
if (!current)
|
|
3782
3799
|
return false;
|
|
3783
3800
|
this.db.query("DELETE FROM monitors WHERE id = ?").run(current.id);
|
|
@@ -4154,7 +4171,20 @@ class UptimeStore {
|
|
|
4154
4171
|
}
|
|
4155
4172
|
listResults(options = {}) {
|
|
4156
4173
|
const limit = clampLimit(options.limit ?? 50);
|
|
4157
|
-
const
|
|
4174
|
+
const workspaceId = options.workspaceId ? normalizeWorkspaceId(options.workspaceId) : undefined;
|
|
4175
|
+
const clauses = [];
|
|
4176
|
+
const args = [];
|
|
4177
|
+
if (options.monitorId) {
|
|
4178
|
+
clauses.push("check_results.monitor_id = ?");
|
|
4179
|
+
args.push(options.monitorId);
|
|
4180
|
+
}
|
|
4181
|
+
if (workspaceId) {
|
|
4182
|
+
clauses.push("monitors.workspace_id = ?");
|
|
4183
|
+
args.push(workspaceId);
|
|
4184
|
+
}
|
|
4185
|
+
const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
|
|
4186
|
+
args.push(limit);
|
|
4187
|
+
const rows = this.db.query(`SELECT check_results.* FROM check_results JOIN monitors ON monitors.id = check_results.monitor_id ${where} ORDER BY checked_at DESC LIMIT ?`).all(...args);
|
|
4158
4188
|
return rows.map(checkResultFromRow);
|
|
4159
4189
|
}
|
|
4160
4190
|
getProvenance(source, sourceId) {
|
|
@@ -4197,24 +4227,28 @@ class UptimeStore {
|
|
|
4197
4227
|
const clauses = [];
|
|
4198
4228
|
const args = [];
|
|
4199
4229
|
if (options.status) {
|
|
4200
|
-
clauses.push("status = ?");
|
|
4230
|
+
clauses.push("incidents.status = ?");
|
|
4201
4231
|
args.push(options.status);
|
|
4202
4232
|
}
|
|
4203
4233
|
if (options.monitorId) {
|
|
4204
|
-
clauses.push("monitor_id = ?");
|
|
4234
|
+
clauses.push("incidents.monitor_id = ?");
|
|
4205
4235
|
args.push(options.monitorId);
|
|
4206
4236
|
}
|
|
4237
|
+
if (options.workspaceId) {
|
|
4238
|
+
clauses.push("monitors.workspace_id = ?");
|
|
4239
|
+
args.push(normalizeWorkspaceId(options.workspaceId));
|
|
4240
|
+
}
|
|
4207
4241
|
const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
|
|
4208
4242
|
args.push(clampLimit(options.limit ?? 50));
|
|
4209
|
-
const rows = this.db.query(`SELECT
|
|
4243
|
+
const rows = this.db.query(`SELECT incidents.* FROM incidents JOIN monitors ON monitors.id = incidents.monitor_id ${where} ORDER BY opened_at DESC LIMIT ?`).all(...args);
|
|
4210
4244
|
return rows.map(incidentFromRow);
|
|
4211
4245
|
}
|
|
4212
4246
|
getOpenIncident(monitorId) {
|
|
4213
4247
|
const row = this.db.query("SELECT * FROM incidents WHERE monitor_id = ? AND status = 'open' ORDER BY opened_at DESC LIMIT 1").get(monitorId);
|
|
4214
4248
|
return row ? incidentFromRow(row) : null;
|
|
4215
4249
|
}
|
|
4216
|
-
summary() {
|
|
4217
|
-
const monitors = this.listMonitors({ includeDisabled: true });
|
|
4250
|
+
summary(options = {}) {
|
|
4251
|
+
const monitors = this.listMonitors({ includeDisabled: true, workspaceId: options.workspaceId });
|
|
4218
4252
|
const summaries = monitors.map((monitor) => this.monitorSummary(monitor));
|
|
4219
4253
|
return {
|
|
4220
4254
|
generatedAt: new Date().toISOString(),
|
|
@@ -4226,11 +4260,15 @@ class UptimeStore {
|
|
|
4226
4260
|
down: monitors.filter((m) => m.status === "down").length,
|
|
4227
4261
|
paused: monitors.filter((m) => !m.enabled || m.status === "paused").length,
|
|
4228
4262
|
unknown: monitors.filter((m) => m.status === "unknown").length,
|
|
4229
|
-
openIncidents: this.countOpenIncidents()
|
|
4263
|
+
openIncidents: this.countOpenIncidents(options.workspaceId)
|
|
4230
4264
|
}
|
|
4231
4265
|
};
|
|
4232
4266
|
}
|
|
4233
|
-
countOpenIncidents() {
|
|
4267
|
+
countOpenIncidents(workspaceId) {
|
|
4268
|
+
if (workspaceId) {
|
|
4269
|
+
const row2 = this.db.query("SELECT COUNT(*) AS count FROM incidents JOIN monitors ON monitors.id = incidents.monitor_id WHERE incidents.status = 'open' AND monitors.workspace_id = ?").get(normalizeWorkspaceId(workspaceId));
|
|
4270
|
+
return Number(row2?.count ?? 0);
|
|
4271
|
+
}
|
|
4234
4272
|
const row = this.db.query("SELECT COUNT(*) AS count FROM incidents WHERE status = 'open'").get();
|
|
4235
4273
|
return Number(row?.count ?? 0);
|
|
4236
4274
|
}
|
|
@@ -4294,7 +4332,9 @@ class UptimeStore {
|
|
|
4294
4332
|
}
|
|
4295
4333
|
ensureMonitorKindAllowsBrowserPage() {
|
|
4296
4334
|
const row = this.db.query("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'monitors'").get();
|
|
4297
|
-
|
|
4335
|
+
const needsBrowserPage = !row?.sql?.includes("browser_page");
|
|
4336
|
+
const needsWorkspaceUnique = Boolean(row?.sql?.includes("name TEXT NOT NULL UNIQUE"));
|
|
4337
|
+
if (!row?.sql || !needsBrowserPage && !needsWorkspaceUnique)
|
|
4298
4338
|
return;
|
|
4299
4339
|
this.db.run("PRAGMA foreign_keys = OFF");
|
|
4300
4340
|
this.db.run("PRAGMA legacy_alter_table = ON");
|
|
@@ -4304,7 +4344,8 @@ class UptimeStore {
|
|
|
4304
4344
|
this.db.run(`
|
|
4305
4345
|
CREATE TABLE monitors (
|
|
4306
4346
|
id TEXT PRIMARY KEY,
|
|
4307
|
-
|
|
4347
|
+
workspace_id TEXT NOT NULL DEFAULT 'local',
|
|
4348
|
+
name TEXT NOT NULL,
|
|
4308
4349
|
kind TEXT NOT NULL CHECK (kind IN ('http', 'tcp', 'browser_page')),
|
|
4309
4350
|
url TEXT,
|
|
4310
4351
|
host TEXT,
|
|
@@ -4319,17 +4360,18 @@ class UptimeStore {
|
|
|
4319
4360
|
last_checked_at TEXT,
|
|
4320
4361
|
revision INTEGER NOT NULL DEFAULT 1,
|
|
4321
4362
|
created_at TEXT NOT NULL,
|
|
4322
|
-
updated_at TEXT NOT NULL
|
|
4363
|
+
updated_at TEXT NOT NULL,
|
|
4364
|
+
UNIQUE (workspace_id, name)
|
|
4323
4365
|
)
|
|
4324
4366
|
`);
|
|
4325
4367
|
this.db.run(`
|
|
4326
4368
|
INSERT INTO monitors (
|
|
4327
|
-
id, name, kind, url, host, port, method, expected_status,
|
|
4369
|
+
id, workspace_id, name, kind, url, host, port, method, expected_status,
|
|
4328
4370
|
interval_seconds, timeout_ms, retry_count, enabled, status,
|
|
4329
4371
|
last_checked_at, revision, created_at, updated_at
|
|
4330
4372
|
)
|
|
4331
4373
|
SELECT
|
|
4332
|
-
id, name, kind, url, host, port, method, expected_status,
|
|
4374
|
+
id, workspace_id, name, kind, url, host, port, method, expected_status,
|
|
4333
4375
|
interval_seconds, timeout_ms, retry_count, enabled, status,
|
|
4334
4376
|
last_checked_at, revision, created_at, updated_at
|
|
4335
4377
|
FROM monitors_old_kind
|
|
@@ -4529,6 +4571,16 @@ function rejectControlCharacters2(value, label) {
|
|
|
4529
4571
|
throw new Error(`${label} must not contain control characters`);
|
|
4530
4572
|
}
|
|
4531
4573
|
}
|
|
4574
|
+
function normalizeWorkspaceId(value) {
|
|
4575
|
+
const normalized = value.trim();
|
|
4576
|
+
if (!normalized)
|
|
4577
|
+
throw new Error("Workspace id is required");
|
|
4578
|
+
rejectControlCharacters2(normalized, "Workspace id");
|
|
4579
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$/.test(normalized)) {
|
|
4580
|
+
throw new Error("Workspace id contains unsupported characters");
|
|
4581
|
+
}
|
|
4582
|
+
return normalized;
|
|
4583
|
+
}
|
|
4532
4584
|
function normalizeScheduleSlot(value) {
|
|
4533
4585
|
const slot = value.trim();
|
|
4534
4586
|
if (!slot)
|
|
@@ -4715,6 +4767,7 @@ function assertIsoTimestamp(value, label) {
|
|
|
4715
4767
|
function monitorFromRow(row) {
|
|
4716
4768
|
return {
|
|
4717
4769
|
id: row.id,
|
|
4770
|
+
workspaceId: row.workspace_id ?? "local",
|
|
4718
4771
|
name: row.name,
|
|
4719
4772
|
kind: row.kind,
|
|
4720
4773
|
url: row.url,
|
|
@@ -5195,20 +5248,20 @@ class UptimeService {
|
|
|
5195
5248
|
close() {
|
|
5196
5249
|
this.store.close();
|
|
5197
5250
|
}
|
|
5198
|
-
createMonitor(input) {
|
|
5199
|
-
return this.store.createMonitor(input);
|
|
5251
|
+
createMonitor(input, options = {}) {
|
|
5252
|
+
return this.store.createMonitor(input, options);
|
|
5200
5253
|
}
|
|
5201
|
-
updateMonitor(idOrName, input) {
|
|
5202
|
-
return this.store.updateMonitor(idOrName, input);
|
|
5254
|
+
updateMonitor(idOrName, input, options = {}) {
|
|
5255
|
+
return this.store.updateMonitor(idOrName, input, options);
|
|
5203
5256
|
}
|
|
5204
|
-
deleteMonitor(idOrName) {
|
|
5205
|
-
return this.store.deleteMonitor(idOrName);
|
|
5257
|
+
deleteMonitor(idOrName, options = {}) {
|
|
5258
|
+
return this.store.deleteMonitor(idOrName, options);
|
|
5206
5259
|
}
|
|
5207
5260
|
listMonitors(options = {}) {
|
|
5208
5261
|
return this.store.listMonitors(options);
|
|
5209
5262
|
}
|
|
5210
|
-
getMonitor(idOrName) {
|
|
5211
|
-
return this.store.getMonitor(idOrName);
|
|
5263
|
+
getMonitor(idOrName, options = {}) {
|
|
5264
|
+
return this.store.getMonitor(idOrName, options);
|
|
5212
5265
|
}
|
|
5213
5266
|
listResults(options = {}) {
|
|
5214
5267
|
return this.store.listResults(options);
|
|
@@ -5216,8 +5269,8 @@ class UptimeService {
|
|
|
5216
5269
|
listIncidents(options = {}) {
|
|
5217
5270
|
return this.store.listIncidents(options);
|
|
5218
5271
|
}
|
|
5219
|
-
summary() {
|
|
5220
|
-
return this.store.summary();
|
|
5272
|
+
summary(options = {}) {
|
|
5273
|
+
return this.store.summary(options);
|
|
5221
5274
|
}
|
|
5222
5275
|
createProbe(input) {
|
|
5223
5276
|
const store = this.probeStore();
|
|
@@ -5273,7 +5326,8 @@ class UptimeService {
|
|
|
5273
5326
|
return this.store.verifyBackup(backupPath);
|
|
5274
5327
|
}
|
|
5275
5328
|
buildReport(options = {}) {
|
|
5276
|
-
|
|
5329
|
+
const { workspaceId, ...reportOptions } = options;
|
|
5330
|
+
return buildUptimeReport(this.summary({ workspaceId }), reportOptions);
|
|
5277
5331
|
}
|
|
5278
5332
|
async sendReport(options = {}) {
|
|
5279
5333
|
if (this.store.mode === "hosted" && (options.email || options.sms || options.logs)) {
|
|
@@ -5597,6 +5651,7 @@ class UptimeService {
|
|
|
5597
5651
|
throw new Error("Probe job fencing token is invalid");
|
|
5598
5652
|
if (!job.leaseExpiresAt || job.leaseExpiresAt <= new Date().toISOString())
|
|
5599
5653
|
throw new Error("Probe job lease expired");
|
|
5654
|
+
const evidence = input.evidence ? normalizeBrowserEvidence(monitor.url ?? monitor.host ?? "https://example.invalid", input.evidence) : null;
|
|
5600
5655
|
const result = this.store.recordCheckResult({
|
|
5601
5656
|
monitorId: monitor.id,
|
|
5602
5657
|
checkedAt: input.checkedAt,
|
|
@@ -5604,7 +5659,7 @@ class UptimeService {
|
|
|
5604
5659
|
latencyMs: input.latencyMs,
|
|
5605
5660
|
statusCode: input.statusCode ?? null,
|
|
5606
5661
|
error: input.error ?? null,
|
|
5607
|
-
evidence
|
|
5662
|
+
evidence,
|
|
5608
5663
|
attemptCount: input.attemptCount ?? 1,
|
|
5609
5664
|
expectedMonitorRevision: input.monitorRevision
|
|
5610
5665
|
});
|
|
@@ -6165,11 +6220,11 @@ async function handleHostedRequest(service, request, url, options) {
|
|
|
6165
6220
|
}
|
|
6166
6221
|
const apiPath = `/api${url.pathname.slice("/api/v1".length)}`;
|
|
6167
6222
|
const scope = hostedScopeFor(request.method, apiPath);
|
|
6168
|
-
requireHostedActor(request, url, options, scope);
|
|
6223
|
+
const actor = requireHostedActor(request, url, options, scope);
|
|
6169
6224
|
if (["POST", "PATCH", "DELETE"].includes(request.method)) {
|
|
6170
6225
|
validateHostedMutationOrigin(request, url, options);
|
|
6171
6226
|
}
|
|
6172
|
-
return handleApiRoute(service, request, url, apiPath, options, true);
|
|
6227
|
+
return handleApiRoute(service, request, url, apiPath, options, true, actor);
|
|
6173
6228
|
}
|
|
6174
6229
|
function validateHostedMutationOrigin(request, url, options) {
|
|
6175
6230
|
const rawOrigin = request.headers.get("origin");
|
|
@@ -6184,12 +6239,12 @@ function validateHostedMutationOrigin(request, url, options) {
|
|
|
6184
6239
|
throw new ApiError("cross-origin mutation rejected", 403);
|
|
6185
6240
|
}
|
|
6186
6241
|
}
|
|
6187
|
-
async function handleApiRoute(service, request, url, apiPath, options, hosted) {
|
|
6242
|
+
async function handleApiRoute(service, request, url, apiPath, options, hosted, actor) {
|
|
6188
6243
|
if (request.method === "GET" && apiPath === "/api/summary") {
|
|
6189
|
-
return json(service.summary());
|
|
6244
|
+
return json(service.summary({ workspaceId: actor?.workspaceId }));
|
|
6190
6245
|
}
|
|
6191
6246
|
if (request.method === "GET" && apiPath === "/api/report") {
|
|
6192
|
-
return json(service.buildReport());
|
|
6247
|
+
return json(service.buildReport({ workspaceId: actor?.workspaceId }));
|
|
6193
6248
|
}
|
|
6194
6249
|
if (request.method === "POST" && apiPath === "/api/report") {
|
|
6195
6250
|
if (hosted)
|
|
@@ -6246,22 +6301,24 @@ async function handleApiRoute(service, request, url, apiPath, options, hosted) {
|
|
|
6246
6301
|
}));
|
|
6247
6302
|
}
|
|
6248
6303
|
if (request.method === "GET" && apiPath === "/api/monitors") {
|
|
6249
|
-
return json(service.listMonitors({ includeDisabled: url.searchParams.get("includeDisabled") === "true" }));
|
|
6304
|
+
return json(service.listMonitors({ includeDisabled: url.searchParams.get("includeDisabled") === "true", workspaceId: actor?.workspaceId }));
|
|
6250
6305
|
}
|
|
6251
6306
|
if (request.method === "POST" && apiPath === "/api/monitors") {
|
|
6252
|
-
return json(service.createMonitor(await jsonBody(request)), 201);
|
|
6307
|
+
return json(service.createMonitor(await jsonBody(request), { workspaceId: actor?.workspaceId }), 201);
|
|
6253
6308
|
}
|
|
6254
6309
|
if (request.method === "GET" && apiPath === "/api/incidents") {
|
|
6255
6310
|
const status = url.searchParams.get("status");
|
|
6256
6311
|
return json(service.listIncidents({
|
|
6257
6312
|
status: status === "open" || status === "closed" ? status : undefined,
|
|
6258
6313
|
monitorId: url.searchParams.get("monitorId") ?? undefined,
|
|
6314
|
+
workspaceId: actor?.workspaceId,
|
|
6259
6315
|
limit: numericParam(url, "limit", 50)
|
|
6260
6316
|
}));
|
|
6261
6317
|
}
|
|
6262
6318
|
if (request.method === "GET" && apiPath === "/api/results") {
|
|
6263
6319
|
return json(service.listResults({
|
|
6264
6320
|
monitorId: url.searchParams.get("monitorId") ?? undefined,
|
|
6321
|
+
workspaceId: actor?.workspaceId,
|
|
6265
6322
|
limit: numericParam(url, "limit", 50)
|
|
6266
6323
|
}));
|
|
6267
6324
|
}
|
|
@@ -6320,14 +6377,14 @@ async function handleApiRoute(service, request, url, apiPath, options, hosted) {
|
|
|
6320
6377
|
if (monitorMatch) {
|
|
6321
6378
|
const id = decodeURIComponent(monitorMatch[1]);
|
|
6322
6379
|
if (request.method === "GET" && !monitorMatch[2]) {
|
|
6323
|
-
const monitor = service.getMonitor(id);
|
|
6380
|
+
const monitor = service.getMonitor(id, { workspaceId: actor?.workspaceId });
|
|
6324
6381
|
return monitor ? json(monitor) : json({ error: "not found" }, 404);
|
|
6325
6382
|
}
|
|
6326
6383
|
if (request.method === "PATCH" && !monitorMatch[2]) {
|
|
6327
|
-
return json(service.updateMonitor(id, await jsonBody(request)));
|
|
6384
|
+
return json(service.updateMonitor(id, await jsonBody(request), { workspaceId: actor?.workspaceId }));
|
|
6328
6385
|
}
|
|
6329
6386
|
if (request.method === "DELETE" && !monitorMatch[2]) {
|
|
6330
|
-
return json({ deleted: service.deleteMonitor(id) });
|
|
6387
|
+
return json({ deleted: service.deleteMonitor(id, { workspaceId: actor?.workspaceId }) });
|
|
6331
6388
|
}
|
|
6332
6389
|
if (request.method === "POST" && monitorMatch[2] === "check") {
|
|
6333
6390
|
if (hosted)
|
|
@@ -6478,7 +6535,7 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
6478
6535
|
const image = clean(options.image, `${imageRepositoryUri}@sha256:<image-digest>`);
|
|
6479
6536
|
const evidenceBucket = clean(options.evidenceBucket, `hasna-${stage}-${prefix}-evidence`);
|
|
6480
6537
|
const hostedSqliteDbPath = clean(options.hostedSqliteDbPath, DEFAULT_HOSTED_SQLITE_DB);
|
|
6481
|
-
const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.
|
|
6538
|
+
const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.10");
|
|
6482
6539
|
const protectedAccessMode = options.protectedAccessMode ?? DEFAULT_PROTECTED_ACCESS_MODE;
|
|
6483
6540
|
const protectedAccessUrl = protectedAccessMode === "cloudfront_default_domain" ? "https://<cloudfront-domain>" : `https://${hostname}`;
|
|
6484
6541
|
const cluster = `${prefix}-${stage}`;
|
package/dist/cloud-plan.js
CHANGED
|
@@ -21,7 +21,7 @@ function buildAwsDeploymentPlan(options = {}) {
|
|
|
21
21
|
const image = clean(options.image, `${imageRepositoryUri}@sha256:<image-digest>`);
|
|
22
22
|
const evidenceBucket = clean(options.evidenceBucket, `hasna-${stage}-${prefix}-evidence`);
|
|
23
23
|
const hostedSqliteDbPath = clean(options.hostedSqliteDbPath, DEFAULT_HOSTED_SQLITE_DB);
|
|
24
|
-
const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.
|
|
24
|
+
const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.10");
|
|
25
25
|
const protectedAccessMode = options.protectedAccessMode ?? DEFAULT_PROTECTED_ACCESS_MODE;
|
|
26
26
|
const protectedAccessUrl = protectedAccessMode === "cloudfront_default_domain" ? "https://<cloudfront-domain>" : `https://${hostname}`;
|
|
27
27
|
const cluster = `${prefix}-${stage}`;
|