@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/dist/service.js CHANGED
@@ -844,7 +844,7 @@ var REQUIRED_TABLES = [
844
844
  ];
845
845
  var PROBE_TABLES = new Set(["probe_identities", "probe_check_jobs", "probe_submissions"]);
846
846
  var REPORT_AUDIT_TABLES = new Set(["report_schedules", "report_runs", "audit_events"]);
847
- var CURRENT_SCHEMA_VERSION = "3";
847
+ var CURRENT_SCHEMA_VERSION = "4";
848
848
 
849
849
  class StaleCheckResultError extends Error {
850
850
  constructor(message) {
@@ -905,7 +905,8 @@ class UptimeStore {
905
905
  this.db.run(`
906
906
  CREATE TABLE IF NOT EXISTS monitors (
907
907
  id TEXT PRIMARY KEY,
908
- name TEXT NOT NULL UNIQUE,
908
+ workspace_id TEXT NOT NULL DEFAULT 'local',
909
+ name TEXT NOT NULL,
909
910
  kind TEXT NOT NULL CHECK (kind IN ('http', 'tcp', 'browser_page')),
910
911
  url TEXT,
911
912
  host TEXT,
@@ -920,9 +921,11 @@ class UptimeStore {
920
921
  last_checked_at TEXT,
921
922
  revision INTEGER NOT NULL DEFAULT 1,
922
923
  created_at TEXT NOT NULL,
923
- updated_at TEXT NOT NULL
924
+ updated_at TEXT NOT NULL,
925
+ UNIQUE (workspace_id, name)
924
926
  )
925
927
  `);
928
+ this.ensureColumn("monitors", "workspace_id", "TEXT NOT NULL DEFAULT 'local'");
926
929
  this.ensureColumn("monitors", "revision", "INTEGER NOT NULL DEFAULT 1");
927
930
  this.ensureMonitorKindAllowsBrowserPage();
928
931
  this.db.run(`
@@ -1072,6 +1075,7 @@ class UptimeStore {
1072
1075
  `);
1073
1076
  this.db.query("INSERT OR REPLACE INTO schema_migrations (key, value, updated_at) VALUES ('schema_version', ?, ?)").run(CURRENT_SCHEMA_VERSION, new Date().toISOString());
1074
1077
  this.db.run("CREATE INDEX IF NOT EXISTS idx_results_monitor_time ON check_results(monitor_id, checked_at DESC)");
1078
+ this.db.run("CREATE INDEX IF NOT EXISTS idx_monitors_workspace_enabled_name ON monitors(workspace_id, enabled, name)");
1075
1079
  this.db.run("CREATE INDEX IF NOT EXISTS idx_incidents_monitor_status ON incidents(monitor_id, status)");
1076
1080
  this.db.run("CREATE INDEX IF NOT EXISTS idx_check_leases_until ON check_leases(leased_until)");
1077
1081
  this.db.run("CREATE INDEX IF NOT EXISTS idx_monitor_provenance_monitor ON monitor_provenance(monitor_id)");
@@ -1133,8 +1137,10 @@ class UptimeStore {
1133
1137
  if (this.mode === "hosted")
1134
1138
  assertHostedTargetAllowed(normalized);
1135
1139
  const now = new Date().toISOString();
1140
+ const workspaceId = normalizeWorkspaceId(options.workspaceId ?? input.workspaceId ?? "local");
1136
1141
  const monitor = {
1137
1142
  id: newId("mon"),
1143
+ workspaceId,
1138
1144
  name: normalized.name,
1139
1145
  kind: normalized.kind,
1140
1146
  url: normalized.url ?? null,
@@ -1153,22 +1159,33 @@ class UptimeStore {
1153
1159
  updatedAt: now
1154
1160
  };
1155
1161
  this.db.query(`INSERT INTO monitors (
1156
- id, name, kind, url, host, port, method, expected_status,
1162
+ id, workspace_id, name, kind, url, host, port, method, expected_status,
1157
1163
  interval_seconds, timeout_ms, retry_count, enabled, status,
1158
1164
  last_checked_at, revision, created_at, updated_at
1159
- ) 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);
1165
+ ) 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);
1160
1166
  return monitor;
1161
1167
  }
1162
1168
  listMonitors(options = {}) {
1163
- const rows = options.includeDisabled ? this.db.query("SELECT * FROM monitors ORDER BY name ASC").all() : this.db.query("SELECT * FROM monitors WHERE enabled = 1 ORDER BY name ASC").all();
1169
+ const workspaceId = options.workspaceId ? normalizeWorkspaceId(options.workspaceId) : undefined;
1170
+ const clauses = [];
1171
+ const args = [];
1172
+ if (workspaceId) {
1173
+ clauses.push("workspace_id = ?");
1174
+ args.push(workspaceId);
1175
+ }
1176
+ if (!options.includeDisabled)
1177
+ clauses.push("enabled = 1");
1178
+ const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
1179
+ const rows = this.db.query(`SELECT * FROM monitors ${where} ORDER BY name ASC`).all(...args);
1164
1180
  return rows.map(monitorFromRow);
1165
1181
  }
1166
- getMonitor(idOrName) {
1167
- const row = this.db.query("SELECT * FROM monitors WHERE id = ? OR name = ?").get(idOrName, idOrName);
1182
+ getMonitor(idOrName, options = {}) {
1183
+ const workspaceId = options.workspaceId ? normalizeWorkspaceId(options.workspaceId) : undefined;
1184
+ const row = this.db.query(`SELECT * FROM monitors WHERE (id = ? OR name = ?)${workspaceId ? " AND workspace_id = ?" : ""}`).get(...workspaceId ? [idOrName, idOrName, workspaceId] : [idOrName, idOrName]);
1168
1185
  return row ? monitorFromRow(row) : null;
1169
1186
  }
1170
1187
  updateMonitor(idOrName, input, options = {}) {
1171
- const current = this.getMonitor(idOrName);
1188
+ const current = this.getMonitor(idOrName, { workspaceId: options.workspaceId });
1172
1189
  if (!current)
1173
1190
  throw new Error(`Monitor not found: ${idOrName}`);
1174
1191
  if (this.mode === "hosted") {
@@ -1192,10 +1209,10 @@ class UptimeStore {
1192
1209
  if (definitionChanged(current, next)) {
1193
1210
  this.closeOpenIncident(current.id, updatedAt);
1194
1211
  }
1195
- return this.getMonitor(current.id);
1212
+ return this.getMonitor(current.id, { workspaceId: options.workspaceId });
1196
1213
  }
1197
- deleteMonitor(idOrName) {
1198
- const current = this.getMonitor(idOrName);
1214
+ deleteMonitor(idOrName, options = {}) {
1215
+ const current = this.getMonitor(idOrName, { workspaceId: options.workspaceId });
1199
1216
  if (!current)
1200
1217
  return false;
1201
1218
  this.db.query("DELETE FROM monitors WHERE id = ?").run(current.id);
@@ -1572,7 +1589,20 @@ class UptimeStore {
1572
1589
  }
1573
1590
  listResults(options = {}) {
1574
1591
  const limit = clampLimit(options.limit ?? 50);
1575
- const rows = options.monitorId ? this.db.query("SELECT * FROM check_results WHERE monitor_id = ? ORDER BY checked_at DESC LIMIT ?").all(options.monitorId, limit) : this.db.query("SELECT * FROM check_results ORDER BY checked_at DESC LIMIT ?").all(limit);
1592
+ const workspaceId = options.workspaceId ? normalizeWorkspaceId(options.workspaceId) : undefined;
1593
+ const clauses = [];
1594
+ const args = [];
1595
+ if (options.monitorId) {
1596
+ clauses.push("check_results.monitor_id = ?");
1597
+ args.push(options.monitorId);
1598
+ }
1599
+ if (workspaceId) {
1600
+ clauses.push("monitors.workspace_id = ?");
1601
+ args.push(workspaceId);
1602
+ }
1603
+ const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
1604
+ args.push(limit);
1605
+ 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);
1576
1606
  return rows.map(checkResultFromRow);
1577
1607
  }
1578
1608
  getProvenance(source, sourceId) {
@@ -1615,24 +1645,28 @@ class UptimeStore {
1615
1645
  const clauses = [];
1616
1646
  const args = [];
1617
1647
  if (options.status) {
1618
- clauses.push("status = ?");
1648
+ clauses.push("incidents.status = ?");
1619
1649
  args.push(options.status);
1620
1650
  }
1621
1651
  if (options.monitorId) {
1622
- clauses.push("monitor_id = ?");
1652
+ clauses.push("incidents.monitor_id = ?");
1623
1653
  args.push(options.monitorId);
1624
1654
  }
1655
+ if (options.workspaceId) {
1656
+ clauses.push("monitors.workspace_id = ?");
1657
+ args.push(normalizeWorkspaceId(options.workspaceId));
1658
+ }
1625
1659
  const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
1626
1660
  args.push(clampLimit(options.limit ?? 50));
1627
- const rows = this.db.query(`SELECT * FROM incidents ${where} ORDER BY opened_at DESC LIMIT ?`).all(...args);
1661
+ 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);
1628
1662
  return rows.map(incidentFromRow);
1629
1663
  }
1630
1664
  getOpenIncident(monitorId) {
1631
1665
  const row = this.db.query("SELECT * FROM incidents WHERE monitor_id = ? AND status = 'open' ORDER BY opened_at DESC LIMIT 1").get(monitorId);
1632
1666
  return row ? incidentFromRow(row) : null;
1633
1667
  }
1634
- summary() {
1635
- const monitors = this.listMonitors({ includeDisabled: true });
1668
+ summary(options = {}) {
1669
+ const monitors = this.listMonitors({ includeDisabled: true, workspaceId: options.workspaceId });
1636
1670
  const summaries = monitors.map((monitor) => this.monitorSummary(monitor));
1637
1671
  return {
1638
1672
  generatedAt: new Date().toISOString(),
@@ -1644,11 +1678,15 @@ class UptimeStore {
1644
1678
  down: monitors.filter((m) => m.status === "down").length,
1645
1679
  paused: monitors.filter((m) => !m.enabled || m.status === "paused").length,
1646
1680
  unknown: monitors.filter((m) => m.status === "unknown").length,
1647
- openIncidents: this.countOpenIncidents()
1681
+ openIncidents: this.countOpenIncidents(options.workspaceId)
1648
1682
  }
1649
1683
  };
1650
1684
  }
1651
- countOpenIncidents() {
1685
+ countOpenIncidents(workspaceId) {
1686
+ if (workspaceId) {
1687
+ 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));
1688
+ return Number(row2?.count ?? 0);
1689
+ }
1652
1690
  const row = this.db.query("SELECT COUNT(*) AS count FROM incidents WHERE status = 'open'").get();
1653
1691
  return Number(row?.count ?? 0);
1654
1692
  }
@@ -1712,7 +1750,9 @@ class UptimeStore {
1712
1750
  }
1713
1751
  ensureMonitorKindAllowsBrowserPage() {
1714
1752
  const row = this.db.query("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'monitors'").get();
1715
- if (!row?.sql || row.sql.includes("browser_page"))
1753
+ const needsBrowserPage = !row?.sql?.includes("browser_page");
1754
+ const needsWorkspaceUnique = Boolean(row?.sql?.includes("name TEXT NOT NULL UNIQUE"));
1755
+ if (!row?.sql || !needsBrowserPage && !needsWorkspaceUnique)
1716
1756
  return;
1717
1757
  this.db.run("PRAGMA foreign_keys = OFF");
1718
1758
  this.db.run("PRAGMA legacy_alter_table = ON");
@@ -1722,7 +1762,8 @@ class UptimeStore {
1722
1762
  this.db.run(`
1723
1763
  CREATE TABLE monitors (
1724
1764
  id TEXT PRIMARY KEY,
1725
- name TEXT NOT NULL UNIQUE,
1765
+ workspace_id TEXT NOT NULL DEFAULT 'local',
1766
+ name TEXT NOT NULL,
1726
1767
  kind TEXT NOT NULL CHECK (kind IN ('http', 'tcp', 'browser_page')),
1727
1768
  url TEXT,
1728
1769
  host TEXT,
@@ -1737,17 +1778,18 @@ class UptimeStore {
1737
1778
  last_checked_at TEXT,
1738
1779
  revision INTEGER NOT NULL DEFAULT 1,
1739
1780
  created_at TEXT NOT NULL,
1740
- updated_at TEXT NOT NULL
1781
+ updated_at TEXT NOT NULL,
1782
+ UNIQUE (workspace_id, name)
1741
1783
  )
1742
1784
  `);
1743
1785
  this.db.run(`
1744
1786
  INSERT INTO monitors (
1745
- id, name, kind, url, host, port, method, expected_status,
1787
+ id, workspace_id, name, kind, url, host, port, method, expected_status,
1746
1788
  interval_seconds, timeout_ms, retry_count, enabled, status,
1747
1789
  last_checked_at, revision, created_at, updated_at
1748
1790
  )
1749
1791
  SELECT
1750
- id, name, kind, url, host, port, method, expected_status,
1792
+ id, workspace_id, name, kind, url, host, port, method, expected_status,
1751
1793
  interval_seconds, timeout_ms, retry_count, enabled, status,
1752
1794
  last_checked_at, revision, created_at, updated_at
1753
1795
  FROM monitors_old_kind
@@ -1947,6 +1989,16 @@ function rejectControlCharacters2(value, label) {
1947
1989
  throw new Error(`${label} must not contain control characters`);
1948
1990
  }
1949
1991
  }
1992
+ function normalizeWorkspaceId(value) {
1993
+ const normalized = value.trim();
1994
+ if (!normalized)
1995
+ throw new Error("Workspace id is required");
1996
+ rejectControlCharacters2(normalized, "Workspace id");
1997
+ if (!/^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$/.test(normalized)) {
1998
+ throw new Error("Workspace id contains unsupported characters");
1999
+ }
2000
+ return normalized;
2001
+ }
1950
2002
  function normalizeScheduleSlot(value) {
1951
2003
  const slot = value.trim();
1952
2004
  if (!slot)
@@ -2133,6 +2185,7 @@ function assertIsoTimestamp(value, label) {
2133
2185
  function monitorFromRow(row) {
2134
2186
  return {
2135
2187
  id: row.id,
2188
+ workspaceId: row.workspace_id ?? "local",
2136
2189
  name: row.name,
2137
2190
  kind: row.kind,
2138
2191
  url: row.url,
@@ -2614,20 +2667,20 @@ class UptimeService {
2614
2667
  close() {
2615
2668
  this.store.close();
2616
2669
  }
2617
- createMonitor(input) {
2618
- return this.store.createMonitor(input);
2670
+ createMonitor(input, options = {}) {
2671
+ return this.store.createMonitor(input, options);
2619
2672
  }
2620
- updateMonitor(idOrName, input) {
2621
- return this.store.updateMonitor(idOrName, input);
2673
+ updateMonitor(idOrName, input, options = {}) {
2674
+ return this.store.updateMonitor(idOrName, input, options);
2622
2675
  }
2623
- deleteMonitor(idOrName) {
2624
- return this.store.deleteMonitor(idOrName);
2676
+ deleteMonitor(idOrName, options = {}) {
2677
+ return this.store.deleteMonitor(idOrName, options);
2625
2678
  }
2626
2679
  listMonitors(options = {}) {
2627
2680
  return this.store.listMonitors(options);
2628
2681
  }
2629
- getMonitor(idOrName) {
2630
- return this.store.getMonitor(idOrName);
2682
+ getMonitor(idOrName, options = {}) {
2683
+ return this.store.getMonitor(idOrName, options);
2631
2684
  }
2632
2685
  listResults(options = {}) {
2633
2686
  return this.store.listResults(options);
@@ -2635,8 +2688,8 @@ class UptimeService {
2635
2688
  listIncidents(options = {}) {
2636
2689
  return this.store.listIncidents(options);
2637
2690
  }
2638
- summary() {
2639
- return this.store.summary();
2691
+ summary(options = {}) {
2692
+ return this.store.summary(options);
2640
2693
  }
2641
2694
  createProbe(input) {
2642
2695
  const store = this.probeStore();
@@ -2692,7 +2745,8 @@ class UptimeService {
2692
2745
  return this.store.verifyBackup(backupPath);
2693
2746
  }
2694
2747
  buildReport(options = {}) {
2695
- return buildUptimeReport(this.summary(), options);
2748
+ const { workspaceId, ...reportOptions } = options;
2749
+ return buildUptimeReport(this.summary({ workspaceId }), reportOptions);
2696
2750
  }
2697
2751
  async sendReport(options = {}) {
2698
2752
  if (this.store.mode === "hosted" && (options.email || options.sms || options.logs)) {
@@ -3016,6 +3070,7 @@ class UptimeService {
3016
3070
  throw new Error("Probe job fencing token is invalid");
3017
3071
  if (!job.leaseExpiresAt || job.leaseExpiresAt <= new Date().toISOString())
3018
3072
  throw new Error("Probe job lease expired");
3073
+ const evidence = input.evidence ? normalizeBrowserEvidence(monitor.url ?? monitor.host ?? "https://example.invalid", input.evidence) : null;
3019
3074
  const result = this.store.recordCheckResult({
3020
3075
  monitorId: monitor.id,
3021
3076
  checkedAt: input.checkedAt,
@@ -3023,7 +3078,7 @@ class UptimeService {
3023
3078
  latencyMs: input.latencyMs,
3024
3079
  statusCode: input.statusCode ?? null,
3025
3080
  error: input.error ?? null,
3026
- evidence: input.evidence ?? null,
3081
+ evidence,
3027
3082
  attemptCount: input.attemptCount ?? 1,
3028
3083
  expectedMonitorRevision: input.monitorRevision
3029
3084
  });
package/dist/store.d.ts CHANGED
@@ -69,15 +69,22 @@ export declare class UptimeStore {
69
69
  static restoreBackup(backupPath: string, destinationPath?: string): UptimeBackup;
70
70
  createMonitor(input: ImportedMonitorInput, options?: {
71
71
  allowBrowserPage?: boolean;
72
+ workspaceId?: string;
72
73
  }): Monitor;
73
74
  listMonitors(options?: {
74
75
  includeDisabled?: boolean;
76
+ workspaceId?: string;
75
77
  }): Monitor[];
76
- getMonitor(idOrName: string): Monitor | null;
78
+ getMonitor(idOrName: string, options?: {
79
+ workspaceId?: string;
80
+ }): Monitor | null;
77
81
  updateMonitor(idOrName: string, input: ImportedUpdateMonitorInput, options?: {
78
82
  allowBrowserPage?: boolean;
83
+ workspaceId?: string;
79
84
  }): Monitor;
80
- deleteMonitor(idOrName: string): boolean;
85
+ deleteMonitor(idOrName: string, options?: {
86
+ workspaceId?: string;
87
+ }): boolean;
81
88
  createProbeIdentity(input: {
82
89
  name: string;
83
90
  publicKeyPem: string;
@@ -153,10 +160,13 @@ export declare class UptimeStore {
153
160
  listIncidents(options?: {
154
161
  status?: "open" | "closed";
155
162
  monitorId?: string;
163
+ workspaceId?: string;
156
164
  limit?: number;
157
165
  }): Incident[];
158
166
  getOpenIncident(monitorId: string): Incident | null;
159
- summary(): UptimeSummary;
167
+ summary(options?: {
168
+ workspaceId?: string;
169
+ }): UptimeSummary;
160
170
  private countOpenIncidents;
161
171
  private monitorSummary;
162
172
  private reconcileIncidentInTransaction;
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EACV,UAAU,EAEV,WAAW,EACX,yBAAyB,EACzB,QAAQ,EACR,oBAAoB,EACpB,0BAA0B,EAC1B,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EAClB,OAAO,EAGP,aAAa,EAEb,aAAa,EACb,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,SAAS,EACT,eAAe,EACf,cAAc,EAEd,yBAAyB,EACzB,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEnD,eAAO,MAAM,6BAA6B,2BAA2B,CAAC;AAKtE,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,GAAG,aAAa,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,OAAO,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,EAAE,CAAC;CACpB;AAgLD,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,WAAW;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,cAAc,GAAG,qBAAqB,GAAG,mBAAmB,CAAC;IAChF,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAW;gBAElB,OAAO,GAAE,kBAAuB;IAyC5C,KAAK,IAAI,IAAI;IAIb,OAAO,IAAI,IAAI;IA2Lf,MAAM,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,YAAY;IAiB9C,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,iBAAiB;IAInD,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,iBAAiB;IAI1D,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,SAAiB,GAAG,YAAY;IAkBxF,aAAa,CAAC,KAAK,EAAE,oBAAoB,EAAE,OAAO,GAAE;QAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO;IAsDjG,YAAY,CAAC,OAAO,GAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,EAAE;IAOpE,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAO5C,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,0BAA0B,EAAE,OAAO,GAAE;QAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO;IA8CzH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAOxC,mBAAmB,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,oBAAoB,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,aAAa;IAiClI,mBAAmB,CAAC,OAAO,GAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,aAAa,EAAE;IAOjF,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAOxD,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,aAAa;IAajG,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,SAA2B,GAAG,IAAI;IAM7E,mBAAmB,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,aAAa;IAoDtG,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAKlD,kBAAkB,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,aAAa;IAwCjG,qBAAqB,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,aAAa;IA2BlJ,OAAO,CAAC,mBAAmB;IAM3B,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI;IAOjF,qBAAqB,CAAC,KAAK,EAAE,IAAI,CAAC,sBAAsB,EAAE,IAAI,GAAG,aAAa,CAAC,GAAG;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,sBAAsB;IA+BnI,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,GAAG,cAAc;IAqCtE,mBAAmB,CAAC,OAAO,GAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,cAAc,EAAE;IAOlF,sBAAsB,CAAC,MAAM,SAA2B,GAAG,cAAc,EAAE;IAQ3E,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAO1D,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,yBAAyB,GAAG,cAAc;IAgCxF,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAO/C,eAAe,CAAC,KAAK,EAAE;QACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,MAAM,EAAE,eAAe,CAAC;QACxB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,oBAAoB,EAAE,CAAC;QACpC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;KAC7C,GAAG,SAAS;IA4Cb,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,SAAS,EAAE;IAUhE,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,UAAU;IAiC1D,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,UAAU,EAAE;IAmBnE,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAmB3E,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIzD,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,uBAAuB,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,WAAW;IA0DvI,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAK9C,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,EAAE;IAU5D,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI;IAOzE,uBAAuB,CAAC,KAAK,EAAE,4BAA4B,GAAG,iBAAiB;IAwB/E,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,iBAAiB;IAQ/D,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI;IAOzD,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAU7D,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAInC,aAAa,CAAC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,QAAQ,EAAE;IAmB3G,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAOnD,OAAO,IAAI,aAAa;IAkBxB,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,cAAc;IAyBtB,OAAO,CAAC,8BAA8B;IA4BtC,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,qBAAqB;IAc7B,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,kCAAkC;IAoD1C,OAAO,CAAC,UAAU;CAInB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,CAI9E"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
package/dist/store.js CHANGED
@@ -127,7 +127,7 @@ var REQUIRED_TABLES = [
127
127
  ];
128
128
  var PROBE_TABLES = new Set(["probe_identities", "probe_check_jobs", "probe_submissions"]);
129
129
  var REPORT_AUDIT_TABLES = new Set(["report_schedules", "report_runs", "audit_events"]);
130
- var CURRENT_SCHEMA_VERSION = "3";
130
+ var CURRENT_SCHEMA_VERSION = "4";
131
131
 
132
132
  class StaleCheckResultError extends Error {
133
133
  constructor(message) {
@@ -188,7 +188,8 @@ class UptimeStore {
188
188
  this.db.run(`
189
189
  CREATE TABLE IF NOT EXISTS monitors (
190
190
  id TEXT PRIMARY KEY,
191
- name TEXT NOT NULL UNIQUE,
191
+ workspace_id TEXT NOT NULL DEFAULT 'local',
192
+ name TEXT NOT NULL,
192
193
  kind TEXT NOT NULL CHECK (kind IN ('http', 'tcp', 'browser_page')),
193
194
  url TEXT,
194
195
  host TEXT,
@@ -203,9 +204,11 @@ class UptimeStore {
203
204
  last_checked_at TEXT,
204
205
  revision INTEGER NOT NULL DEFAULT 1,
205
206
  created_at TEXT NOT NULL,
206
- updated_at TEXT NOT NULL
207
+ updated_at TEXT NOT NULL,
208
+ UNIQUE (workspace_id, name)
207
209
  )
208
210
  `);
211
+ this.ensureColumn("monitors", "workspace_id", "TEXT NOT NULL DEFAULT 'local'");
209
212
  this.ensureColumn("monitors", "revision", "INTEGER NOT NULL DEFAULT 1");
210
213
  this.ensureMonitorKindAllowsBrowserPage();
211
214
  this.db.run(`
@@ -355,6 +358,7 @@ class UptimeStore {
355
358
  `);
356
359
  this.db.query("INSERT OR REPLACE INTO schema_migrations (key, value, updated_at) VALUES ('schema_version', ?, ?)").run(CURRENT_SCHEMA_VERSION, new Date().toISOString());
357
360
  this.db.run("CREATE INDEX IF NOT EXISTS idx_results_monitor_time ON check_results(monitor_id, checked_at DESC)");
361
+ this.db.run("CREATE INDEX IF NOT EXISTS idx_monitors_workspace_enabled_name ON monitors(workspace_id, enabled, name)");
358
362
  this.db.run("CREATE INDEX IF NOT EXISTS idx_incidents_monitor_status ON incidents(monitor_id, status)");
359
363
  this.db.run("CREATE INDEX IF NOT EXISTS idx_check_leases_until ON check_leases(leased_until)");
360
364
  this.db.run("CREATE INDEX IF NOT EXISTS idx_monitor_provenance_monitor ON monitor_provenance(monitor_id)");
@@ -416,8 +420,10 @@ class UptimeStore {
416
420
  if (this.mode === "hosted")
417
421
  assertHostedTargetAllowed(normalized);
418
422
  const now = new Date().toISOString();
423
+ const workspaceId = normalizeWorkspaceId(options.workspaceId ?? input.workspaceId ?? "local");
419
424
  const monitor = {
420
425
  id: newId("mon"),
426
+ workspaceId,
421
427
  name: normalized.name,
422
428
  kind: normalized.kind,
423
429
  url: normalized.url ?? null,
@@ -436,22 +442,33 @@ class UptimeStore {
436
442
  updatedAt: now
437
443
  };
438
444
  this.db.query(`INSERT INTO monitors (
439
- id, name, kind, url, host, port, method, expected_status,
445
+ id, workspace_id, name, kind, url, host, port, method, expected_status,
440
446
  interval_seconds, timeout_ms, retry_count, enabled, status,
441
447
  last_checked_at, revision, created_at, updated_at
442
- ) 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);
448
+ ) 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);
443
449
  return monitor;
444
450
  }
445
451
  listMonitors(options = {}) {
446
- const rows = options.includeDisabled ? this.db.query("SELECT * FROM monitors ORDER BY name ASC").all() : this.db.query("SELECT * FROM monitors WHERE enabled = 1 ORDER BY name ASC").all();
452
+ const workspaceId = options.workspaceId ? normalizeWorkspaceId(options.workspaceId) : undefined;
453
+ const clauses = [];
454
+ const args = [];
455
+ if (workspaceId) {
456
+ clauses.push("workspace_id = ?");
457
+ args.push(workspaceId);
458
+ }
459
+ if (!options.includeDisabled)
460
+ clauses.push("enabled = 1");
461
+ const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
462
+ const rows = this.db.query(`SELECT * FROM monitors ${where} ORDER BY name ASC`).all(...args);
447
463
  return rows.map(monitorFromRow);
448
464
  }
449
- getMonitor(idOrName) {
450
- const row = this.db.query("SELECT * FROM monitors WHERE id = ? OR name = ?").get(idOrName, idOrName);
465
+ getMonitor(idOrName, options = {}) {
466
+ const workspaceId = options.workspaceId ? normalizeWorkspaceId(options.workspaceId) : undefined;
467
+ const row = this.db.query(`SELECT * FROM monitors WHERE (id = ? OR name = ?)${workspaceId ? " AND workspace_id = ?" : ""}`).get(...workspaceId ? [idOrName, idOrName, workspaceId] : [idOrName, idOrName]);
451
468
  return row ? monitorFromRow(row) : null;
452
469
  }
453
470
  updateMonitor(idOrName, input, options = {}) {
454
- const current = this.getMonitor(idOrName);
471
+ const current = this.getMonitor(idOrName, { workspaceId: options.workspaceId });
455
472
  if (!current)
456
473
  throw new Error(`Monitor not found: ${idOrName}`);
457
474
  if (this.mode === "hosted") {
@@ -475,10 +492,10 @@ class UptimeStore {
475
492
  if (definitionChanged(current, next)) {
476
493
  this.closeOpenIncident(current.id, updatedAt);
477
494
  }
478
- return this.getMonitor(current.id);
495
+ return this.getMonitor(current.id, { workspaceId: options.workspaceId });
479
496
  }
480
- deleteMonitor(idOrName) {
481
- const current = this.getMonitor(idOrName);
497
+ deleteMonitor(idOrName, options = {}) {
498
+ const current = this.getMonitor(idOrName, { workspaceId: options.workspaceId });
482
499
  if (!current)
483
500
  return false;
484
501
  this.db.query("DELETE FROM monitors WHERE id = ?").run(current.id);
@@ -855,7 +872,20 @@ class UptimeStore {
855
872
  }
856
873
  listResults(options = {}) {
857
874
  const limit = clampLimit(options.limit ?? 50);
858
- const rows = options.monitorId ? this.db.query("SELECT * FROM check_results WHERE monitor_id = ? ORDER BY checked_at DESC LIMIT ?").all(options.monitorId, limit) : this.db.query("SELECT * FROM check_results ORDER BY checked_at DESC LIMIT ?").all(limit);
875
+ const workspaceId = options.workspaceId ? normalizeWorkspaceId(options.workspaceId) : undefined;
876
+ const clauses = [];
877
+ const args = [];
878
+ if (options.monitorId) {
879
+ clauses.push("check_results.monitor_id = ?");
880
+ args.push(options.monitorId);
881
+ }
882
+ if (workspaceId) {
883
+ clauses.push("monitors.workspace_id = ?");
884
+ args.push(workspaceId);
885
+ }
886
+ const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
887
+ args.push(limit);
888
+ 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);
859
889
  return rows.map(checkResultFromRow);
860
890
  }
861
891
  getProvenance(source, sourceId) {
@@ -898,24 +928,28 @@ class UptimeStore {
898
928
  const clauses = [];
899
929
  const args = [];
900
930
  if (options.status) {
901
- clauses.push("status = ?");
931
+ clauses.push("incidents.status = ?");
902
932
  args.push(options.status);
903
933
  }
904
934
  if (options.monitorId) {
905
- clauses.push("monitor_id = ?");
935
+ clauses.push("incidents.monitor_id = ?");
906
936
  args.push(options.monitorId);
907
937
  }
938
+ if (options.workspaceId) {
939
+ clauses.push("monitors.workspace_id = ?");
940
+ args.push(normalizeWorkspaceId(options.workspaceId));
941
+ }
908
942
  const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
909
943
  args.push(clampLimit(options.limit ?? 50));
910
- const rows = this.db.query(`SELECT * FROM incidents ${where} ORDER BY opened_at DESC LIMIT ?`).all(...args);
944
+ 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);
911
945
  return rows.map(incidentFromRow);
912
946
  }
913
947
  getOpenIncident(monitorId) {
914
948
  const row = this.db.query("SELECT * FROM incidents WHERE monitor_id = ? AND status = 'open' ORDER BY opened_at DESC LIMIT 1").get(monitorId);
915
949
  return row ? incidentFromRow(row) : null;
916
950
  }
917
- summary() {
918
- const monitors = this.listMonitors({ includeDisabled: true });
951
+ summary(options = {}) {
952
+ const monitors = this.listMonitors({ includeDisabled: true, workspaceId: options.workspaceId });
919
953
  const summaries = monitors.map((monitor) => this.monitorSummary(monitor));
920
954
  return {
921
955
  generatedAt: new Date().toISOString(),
@@ -927,11 +961,15 @@ class UptimeStore {
927
961
  down: monitors.filter((m) => m.status === "down").length,
928
962
  paused: monitors.filter((m) => !m.enabled || m.status === "paused").length,
929
963
  unknown: monitors.filter((m) => m.status === "unknown").length,
930
- openIncidents: this.countOpenIncidents()
964
+ openIncidents: this.countOpenIncidents(options.workspaceId)
931
965
  }
932
966
  };
933
967
  }
934
- countOpenIncidents() {
968
+ countOpenIncidents(workspaceId) {
969
+ if (workspaceId) {
970
+ 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));
971
+ return Number(row2?.count ?? 0);
972
+ }
935
973
  const row = this.db.query("SELECT COUNT(*) AS count FROM incidents WHERE status = 'open'").get();
936
974
  return Number(row?.count ?? 0);
937
975
  }
@@ -995,7 +1033,9 @@ class UptimeStore {
995
1033
  }
996
1034
  ensureMonitorKindAllowsBrowserPage() {
997
1035
  const row = this.db.query("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'monitors'").get();
998
- if (!row?.sql || row.sql.includes("browser_page"))
1036
+ const needsBrowserPage = !row?.sql?.includes("browser_page");
1037
+ const needsWorkspaceUnique = Boolean(row?.sql?.includes("name TEXT NOT NULL UNIQUE"));
1038
+ if (!row?.sql || !needsBrowserPage && !needsWorkspaceUnique)
999
1039
  return;
1000
1040
  this.db.run("PRAGMA foreign_keys = OFF");
1001
1041
  this.db.run("PRAGMA legacy_alter_table = ON");
@@ -1005,7 +1045,8 @@ class UptimeStore {
1005
1045
  this.db.run(`
1006
1046
  CREATE TABLE monitors (
1007
1047
  id TEXT PRIMARY KEY,
1008
- name TEXT NOT NULL UNIQUE,
1048
+ workspace_id TEXT NOT NULL DEFAULT 'local',
1049
+ name TEXT NOT NULL,
1009
1050
  kind TEXT NOT NULL CHECK (kind IN ('http', 'tcp', 'browser_page')),
1010
1051
  url TEXT,
1011
1052
  host TEXT,
@@ -1020,17 +1061,18 @@ class UptimeStore {
1020
1061
  last_checked_at TEXT,
1021
1062
  revision INTEGER NOT NULL DEFAULT 1,
1022
1063
  created_at TEXT NOT NULL,
1023
- updated_at TEXT NOT NULL
1064
+ updated_at TEXT NOT NULL,
1065
+ UNIQUE (workspace_id, name)
1024
1066
  )
1025
1067
  `);
1026
1068
  this.db.run(`
1027
1069
  INSERT INTO monitors (
1028
- id, name, kind, url, host, port, method, expected_status,
1070
+ id, workspace_id, name, kind, url, host, port, method, expected_status,
1029
1071
  interval_seconds, timeout_ms, retry_count, enabled, status,
1030
1072
  last_checked_at, revision, created_at, updated_at
1031
1073
  )
1032
1074
  SELECT
1033
- id, name, kind, url, host, port, method, expected_status,
1075
+ id, workspace_id, name, kind, url, host, port, method, expected_status,
1034
1076
  interval_seconds, timeout_ms, retry_count, enabled, status,
1035
1077
  last_checked_at, revision, created_at, updated_at
1036
1078
  FROM monitors_old_kind
@@ -1230,6 +1272,16 @@ function rejectControlCharacters(value, label) {
1230
1272
  throw new Error(`${label} must not contain control characters`);
1231
1273
  }
1232
1274
  }
1275
+ function normalizeWorkspaceId(value) {
1276
+ const normalized = value.trim();
1277
+ if (!normalized)
1278
+ throw new Error("Workspace id is required");
1279
+ rejectControlCharacters(normalized, "Workspace id");
1280
+ if (!/^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$/.test(normalized)) {
1281
+ throw new Error("Workspace id contains unsupported characters");
1282
+ }
1283
+ return normalized;
1284
+ }
1233
1285
  function normalizeScheduleSlot(value) {
1234
1286
  const slot = value.trim();
1235
1287
  if (!slot)
@@ -1416,6 +1468,7 @@ function assertIsoTimestamp(value, label) {
1416
1468
  function monitorFromRow(row) {
1417
1469
  return {
1418
1470
  id: row.id,
1471
+ workspaceId: row.workspace_id ?? "local",
1419
1472
  name: row.name,
1420
1473
  kind: row.kind,
1421
1474
  url: row.url,
package/dist/types.d.ts CHANGED
@@ -5,6 +5,7 @@ export type CheckStatus = "up" | "down";
5
5
  export type IncidentStatus = "open" | "closed";
6
6
  export interface Monitor {
7
7
  id: string;
8
+ workspaceId: string;
8
9
  name: string;
9
10
  kind: MonitorKind;
10
11
  url: string | null;
@@ -23,6 +24,7 @@ export interface Monitor {
23
24
  updatedAt: string;
24
25
  }
25
26
  export interface CreateMonitorInput {
27
+ workspaceId?: string;
26
28
  name: string;
27
29
  kind: CreateMonitorKind;
28
30
  url?: string;
@@ -275,6 +277,7 @@ export interface UptimeSummary {
275
277
  }
276
278
  export interface ListResultsOptions {
277
279
  monitorId?: string;
280
+ workspaceId?: string;
278
281
  limit?: number;
279
282
  }
280
283
  export interface SchedulerHandle {