@hasna/uptime 0.1.22 → 0.1.24

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/cli/index.js CHANGED
@@ -2813,8 +2813,9 @@ async function runMonitorCheck(monitor, options = {}) {
2813
2813
  }
2814
2814
  if (monitor.kind === "browser_page")
2815
2815
  return runBrowserPageCheck(monitor, { fetch: options.fetch, runner: options.browserPage });
2816
- if (monitor.kind === "tcp")
2817
- return runTcpCheck(monitor);
2816
+ if (monitor.kind === "tcp") {
2817
+ return options.hostedTargetPolicy ? runHostedTcpCheck(monitor, { resolveHost: options.resolveHost }) : runTcpCheck(monitor);
2818
+ }
2818
2819
  return { status: "down", latencyMs: null, error: `unsupported monitor kind: ${monitor.kind ?? "unknown"}` };
2819
2820
  }
2820
2821
  async function runHttpCheck(monitor, fetchImpl = fetch) {
@@ -2926,9 +2927,30 @@ async function runHostedHttpCheck(monitor, options = {}) {
2926
2927
  async function runTcpCheck(monitor) {
2927
2928
  if (!monitor.host || !monitor.port)
2928
2929
  return { status: "down", latencyMs: null, error: "missing host or port" };
2930
+ return runTcpSocket(monitor.host, monitor.port, monitor.timeoutMs);
2931
+ }
2932
+ async function runHostedTcpCheck(monitor, options = {}) {
2933
+ if (!monitor.host || !monitor.port)
2934
+ return { status: "down", latencyMs: null, error: "missing host or port" };
2935
+ const resolver = options.resolveHost ?? resolveHostedHost;
2936
+ try {
2937
+ const addresses = normalizeResolvedAddresses(await resolver(normalizeHostedHost(monitor.host)));
2938
+ assertHostedResolvedAddressesAllowed(monitor.host, addresses, "TCP resolved address");
2939
+ const address = addresses[0];
2940
+ return runTcpSocket(address.address, monitor.port, monitor.timeoutMs, address.family);
2941
+ } catch (error) {
2942
+ return {
2943
+ status: "down",
2944
+ latencyMs: null,
2945
+ statusCode: null,
2946
+ error: error instanceof Error ? error.message : String(error)
2947
+ };
2948
+ }
2949
+ }
2950
+ async function runTcpSocket(host, port, timeoutMs, family) {
2929
2951
  const started = performance.now();
2930
2952
  return new Promise((resolve) => {
2931
- const socket = net2.createConnection({ host: monitor.host, port: monitor.port, timeout: monitor.timeoutMs });
2953
+ const socket = net2.createConnection({ host, port, timeout: timeoutMs, family });
2932
2954
  let settled = false;
2933
2955
  const finish = (result) => {
2934
2956
  if (settled)
@@ -3344,7 +3366,7 @@ function previewRecord(store, source, record, defaults, options) {
3344
3366
  };
3345
3367
  }
3346
3368
  const monitorOptions = options.workspaceId ? { workspaceId: options.workspaceId } : undefined;
3347
- const rawProvenance = store.getProvenance(candidate.source, candidate.sourceId);
3369
+ const rawProvenance = store.getProvenance(candidate.source, candidate.sourceId, monitorOptions);
3348
3370
  const provenanceMonitor = rawProvenance ? store.getMonitor(rawProvenance.monitorId, monitorOptions) : null;
3349
3371
  const provenance = provenanceMonitor ? rawProvenance : null;
3350
3372
  const monitor = provenanceMonitor ?? store.getMonitor(candidate.name, monitorOptions);
@@ -3816,7 +3838,7 @@ var REQUIRED_TABLES = [
3816
3838
  ];
3817
3839
  var PROBE_TABLES = new Set(["probe_identities", "probe_check_jobs", "probe_submissions"]);
3818
3840
  var REPORT_AUDIT_TABLES = new Set(["report_schedules", "report_runs", "audit_events"]);
3819
- var CURRENT_SCHEMA_VERSION = "4";
3841
+ var CURRENT_SCHEMA_VERSION = "5";
3820
3842
 
3821
3843
  class StaleCheckResultError extends Error {
3822
3844
  constructor(message) {
@@ -3929,15 +3951,17 @@ class UptimeStore {
3929
3951
  `);
3930
3952
  this.db.run(`
3931
3953
  CREATE TABLE IF NOT EXISTS monitor_provenance (
3954
+ workspace_id TEXT NOT NULL DEFAULT 'local',
3932
3955
  monitor_id TEXT NOT NULL REFERENCES monitors(id) ON DELETE CASCADE,
3933
3956
  source TEXT NOT NULL,
3934
3957
  source_id TEXT NOT NULL,
3935
3958
  source_label TEXT,
3936
3959
  imported_at TEXT NOT NULL,
3937
3960
  snapshot_json TEXT NOT NULL,
3938
- PRIMARY KEY (source, source_id)
3961
+ PRIMARY KEY (workspace_id, source, source_id)
3939
3962
  )
3940
3963
  `);
3964
+ this.ensureMonitorProvenanceWorkspaceScoped();
3941
3965
  this.db.run(`
3942
3966
  CREATE TABLE IF NOT EXISTS import_batches (
3943
3967
  id TEXT PRIMARY KEY,
@@ -4029,6 +4053,7 @@ class UptimeStore {
4029
4053
  this.db.run(`
4030
4054
  CREATE TABLE IF NOT EXISTS audit_events (
4031
4055
  id TEXT PRIMARY KEY,
4056
+ workspace_id TEXT,
4032
4057
  action TEXT NOT NULL,
4033
4058
  resource_type TEXT,
4034
4059
  resource_id TEXT,
@@ -4038,6 +4063,7 @@ class UptimeStore {
4038
4063
  created_at TEXT NOT NULL
4039
4064
  )
4040
4065
  `);
4066
+ this.ensureColumn("audit_events", "workspace_id", "TEXT");
4041
4067
  this.db.run(`
4042
4068
  CREATE TABLE IF NOT EXISTS schema_migrations (
4043
4069
  key TEXT PRIMARY KEY,
@@ -4051,6 +4077,7 @@ class UptimeStore {
4051
4077
  this.db.run("CREATE INDEX IF NOT EXISTS idx_incidents_monitor_status ON incidents(monitor_id, status)");
4052
4078
  this.db.run("CREATE INDEX IF NOT EXISTS idx_check_leases_until ON check_leases(leased_until)");
4053
4079
  this.db.run("CREATE INDEX IF NOT EXISTS idx_monitor_provenance_monitor ON monitor_provenance(monitor_id)");
4080
+ this.db.run("CREATE INDEX IF NOT EXISTS idx_monitor_provenance_workspace_source ON monitor_provenance(workspace_id, source, source_id)");
4054
4081
  this.db.run("CREATE INDEX IF NOT EXISTS idx_probe_jobs_status_due ON probe_check_jobs(status, due_at)");
4055
4082
  this.db.run("CREATE INDEX IF NOT EXISTS idx_probe_jobs_probe_status ON probe_check_jobs(claimed_by_probe_id, status)");
4056
4083
  this.db.run("CREATE INDEX IF NOT EXISTS idx_probe_submissions_probe_time ON probe_submissions(probe_id, submitted_at DESC)");
@@ -4059,6 +4086,7 @@ class UptimeStore {
4059
4086
  this.db.run("CREATE INDEX IF NOT EXISTS idx_report_schedules_due ON report_schedules(enabled, next_run_at)");
4060
4087
  this.db.run("CREATE INDEX IF NOT EXISTS idx_report_runs_schedule_time ON report_runs(schedule_id, started_at DESC)");
4061
4088
  this.db.run("CREATE INDEX IF NOT EXISTS idx_audit_events_resource_time ON audit_events(resource_type, resource_id, created_at DESC)");
4089
+ this.db.run("CREATE INDEX IF NOT EXISTS idx_audit_events_workspace_time ON audit_events(workspace_id, created_at DESC)");
4062
4090
  this.db.run("CREATE INDEX IF NOT EXISTS idx_audit_events_time ON audit_events(created_at DESC)");
4063
4091
  }
4064
4092
  backup(destinationPath) {
@@ -4108,6 +4136,9 @@ class UptimeStore {
4108
4136
  const normalized = normalizeCreateMonitor(input, options.allowBrowserPage === true);
4109
4137
  if (this.mode === "hosted")
4110
4138
  assertHostedTargetAllowed(normalized);
4139
+ if (this.mode === "hosted" && normalized.kind === "browser_page" && normalized.enabled !== false) {
4140
+ throw new Error("hosted browser_page monitors must remain disabled until browser evidence workers are configured");
4141
+ }
4111
4142
  const now = new Date().toISOString();
4112
4143
  const workspaceId = normalizeWorkspaceId(options.workspaceId ?? input.workspaceId ?? "local");
4113
4144
  const monitor = {
@@ -4172,6 +4203,9 @@ class UptimeStore {
4172
4203
  const next = normalizeUpdateMonitor(current, input, updatedAt, options.allowBrowserPage === true);
4173
4204
  if (this.mode === "hosted")
4174
4205
  assertHostedTargetAllowed(next);
4206
+ if (this.mode === "hosted" && next.kind === "browser_page" && next.enabled) {
4207
+ throw new Error("hosted browser_page monitors must remain disabled until browser evidence workers are configured");
4208
+ }
4175
4209
  this.db.query(`UPDATE monitors SET
4176
4210
  name = ?, kind = ?, url = ?, host = ?, port = ?, method = ?,
4177
4211
  expected_status = ?, interval_seconds = ?, timeout_ms = ?,
@@ -4468,8 +4502,10 @@ class UptimeStore {
4468
4502
  const action = normalizeAuditText(input.action, "Audit action", 160);
4469
4503
  const createdAt = input.createdAt ?? new Date().toISOString();
4470
4504
  assertIsoTimestamp(createdAt, "Audit event createdAt");
4505
+ const workspaceId = input.workspaceId == null ? null : normalizeWorkspaceId(input.workspaceId);
4471
4506
  const event = {
4472
4507
  id: newId("aud"),
4508
+ workspaceId,
4473
4509
  action,
4474
4510
  resourceType: normalizeNullableAuditText(input.resourceType, "Audit resourceType", 80),
4475
4511
  resourceId: normalizeNullableAuditText(input.resourceId, "Audit resourceId", 160),
@@ -4479,13 +4515,17 @@ class UptimeStore {
4479
4515
  createdAt
4480
4516
  };
4481
4517
  this.db.query(`INSERT INTO audit_events (
4482
- id, action, resource_type, resource_id, message, metadata_json, actor, created_at
4483
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(event.id, event.action, event.resourceType, event.resourceId, event.message, JSON.stringify(event.metadata), event.actor, event.createdAt);
4518
+ id, workspace_id, action, resource_type, resource_id, message, metadata_json, actor, created_at
4519
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(event.id, event.workspaceId, event.action, event.resourceType, event.resourceId, event.message, JSON.stringify(event.metadata), event.actor, event.createdAt);
4484
4520
  return event;
4485
4521
  }
4486
4522
  listAuditEvents(options = {}) {
4487
4523
  const clauses = [];
4488
4524
  const args = [];
4525
+ if (options.workspaceId) {
4526
+ clauses.push("workspace_id = ?");
4527
+ args.push(normalizeWorkspaceId(options.workspaceId));
4528
+ }
4489
4529
  if (options.resourceType) {
4490
4530
  clauses.push("resource_type = ?");
4491
4531
  args.push(options.resourceType);
@@ -4577,21 +4617,24 @@ class UptimeStore {
4577
4617
  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);
4578
4618
  return rows.map(checkResultFromRow);
4579
4619
  }
4580
- getProvenance(source, sourceId) {
4581
- const row = this.db.query("SELECT * FROM monitor_provenance WHERE source = ? AND source_id = ?").get(source, sourceId);
4620
+ getProvenance(source, sourceId, options = {}) {
4621
+ const workspaceId = options.workspaceId ? normalizeWorkspaceId(options.workspaceId) : undefined;
4622
+ const row = workspaceId ? this.db.query("SELECT * FROM monitor_provenance WHERE workspace_id = ? AND source = ? AND source_id = ?").get(workspaceId, source, sourceId) : this.db.query("SELECT * FROM monitor_provenance WHERE source = ? AND source_id = ? ORDER BY imported_at DESC LIMIT 1").get(source, sourceId);
4582
4623
  return row ? provenanceFromRow(row) : null;
4583
4624
  }
4584
4625
  upsertMonitorProvenance(input) {
4585
4626
  const importedAt = new Date().toISOString();
4627
+ const monitor = this.getMonitor(input.monitorId);
4628
+ const workspaceId = normalizeWorkspaceId(input.workspaceId ?? monitor?.workspaceId ?? "local");
4586
4629
  this.db.query(`INSERT INTO monitor_provenance (
4587
- monitor_id, source, source_id, source_label, imported_at, snapshot_json
4588
- ) VALUES (?, ?, ?, ?, ?, ?)
4589
- ON CONFLICT(source, source_id) DO UPDATE SET
4630
+ workspace_id, monitor_id, source, source_id, source_label, imported_at, snapshot_json
4631
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)
4632
+ ON CONFLICT(workspace_id, source, source_id) DO UPDATE SET
4590
4633
  monitor_id = excluded.monitor_id,
4591
4634
  source_label = excluded.source_label,
4592
4635
  imported_at = excluded.imported_at,
4593
- snapshot_json = excluded.snapshot_json`).run(input.monitorId, input.source, input.sourceId, input.sourceLabel ?? null, importedAt, JSON.stringify(input.snapshot));
4594
- return this.getProvenance(input.source, input.sourceId);
4636
+ snapshot_json = excluded.snapshot_json`).run(workspaceId, input.monitorId, input.source, input.sourceId, input.sourceLabel ?? null, importedAt, JSON.stringify(input.snapshot));
4637
+ return this.getProvenance(input.source, input.sourceId, { workspaceId });
4595
4638
  }
4596
4639
  saveImportBatch(input) {
4597
4640
  const createdAt = new Date().toISOString();
@@ -4774,6 +4817,49 @@ class UptimeStore {
4774
4817
  this.db.run("PRAGMA foreign_keys = ON");
4775
4818
  }
4776
4819
  }
4820
+ ensureMonitorProvenanceWorkspaceScoped() {
4821
+ const row = this.db.query("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'monitor_provenance'").get();
4822
+ const columns = this.db.query("PRAGMA table_info(monitor_provenance)").all();
4823
+ const hasWorkspaceId = columns.some((column) => column.name === "workspace_id");
4824
+ const hasWorkspacePrimaryKey = Boolean(row?.sql?.includes("PRIMARY KEY (workspace_id, source, source_id)"));
4825
+ if (hasWorkspaceId && hasWorkspacePrimaryKey)
4826
+ return;
4827
+ this.db.run("PRAGMA foreign_keys = OFF");
4828
+ this.db.run("PRAGMA legacy_alter_table = ON");
4829
+ try {
4830
+ const migrate = this.db.transaction(() => {
4831
+ this.db.run("ALTER TABLE monitor_provenance RENAME TO monitor_provenance_old_workspace");
4832
+ this.db.run(`
4833
+ CREATE TABLE monitor_provenance (
4834
+ workspace_id TEXT NOT NULL DEFAULT 'local',
4835
+ monitor_id TEXT NOT NULL REFERENCES monitors(id) ON DELETE CASCADE,
4836
+ source TEXT NOT NULL,
4837
+ source_id TEXT NOT NULL,
4838
+ source_label TEXT,
4839
+ imported_at TEXT NOT NULL,
4840
+ snapshot_json TEXT NOT NULL,
4841
+ PRIMARY KEY (workspace_id, source, source_id)
4842
+ )
4843
+ `);
4844
+ const workspaceSelect = hasWorkspaceId ? "COALESCE(old.workspace_id, monitors.workspace_id, 'local')" : "COALESCE(monitors.workspace_id, 'local')";
4845
+ this.db.run(`
4846
+ INSERT OR REPLACE INTO monitor_provenance (
4847
+ workspace_id, monitor_id, source, source_id, source_label, imported_at, snapshot_json
4848
+ )
4849
+ SELECT
4850
+ ${workspaceSelect}, old.monitor_id, old.source, old.source_id, old.source_label,
4851
+ old.imported_at, old.snapshot_json
4852
+ FROM monitor_provenance_old_workspace old
4853
+ LEFT JOIN monitors ON monitors.id = old.monitor_id
4854
+ `);
4855
+ this.db.run("DROP TABLE monitor_provenance_old_workspace");
4856
+ });
4857
+ migrate();
4858
+ } finally {
4859
+ this.db.run("PRAGMA legacy_alter_table = OFF");
4860
+ this.db.run("PRAGMA foreign_keys = ON");
4861
+ }
4862
+ }
4777
4863
  vacuumInto(backupPath) {
4778
4864
  const quoted = backupPath.replace(/'/g, "''");
4779
4865
  this.db.run(`VACUUM INTO '${quoted}'`);
@@ -4803,10 +4889,11 @@ function verifyBackupFile(backupPath) {
4803
4889
  const missingTables = REQUIRED_TABLES.filter((table) => !tableExists(db, table));
4804
4890
  const schemaVersion = missingTables.includes("schema_migrations") ? null : db.query("SELECT value FROM schema_migrations WHERE key = 'schema_version'").get()?.value ?? null;
4805
4891
  const currentOk = missingTables.length === 0 && schemaVersion === CURRENT_SCHEMA_VERSION;
4892
+ const restorableV4 = schemaVersion === "4" && missingTables.length === 0;
4806
4893
  const restorableV1 = schemaVersion === "1" && missingTables.every((table) => PROBE_TABLES.has(table) || REPORT_AUDIT_TABLES.has(table));
4807
4894
  const restorableV2 = schemaVersion === "2" && missingTables.every((table) => REPORT_AUDIT_TABLES.has(table));
4808
4895
  return {
4809
- ok: integrity === "ok" && (currentOk || restorableV1 || restorableV2),
4896
+ ok: integrity === "ok" && (currentOk || restorableV4 || restorableV1 || restorableV2),
4810
4897
  backupPath,
4811
4898
  integrity,
4812
4899
  schemaVersion,
@@ -5191,6 +5278,7 @@ function checkResultFromRow(row) {
5191
5278
  }
5192
5279
  function provenanceFromRow(row) {
5193
5280
  return {
5281
+ workspaceId: row.workspace_id,
5194
5282
  monitorId: row.monitor_id,
5195
5283
  source: row.source,
5196
5284
  sourceId: row.source_id,
@@ -5278,6 +5366,7 @@ function reportRunFromRow(row) {
5278
5366
  function auditEventFromRow(row) {
5279
5367
  return {
5280
5368
  id: row.id,
5369
+ workspaceId: row.workspace_id,
5281
5370
  action: row.action,
5282
5371
  resourceType: row.resource_type,
5283
5372
  resourceId: row.resource_id,
@@ -5639,12 +5728,18 @@ var MAX_PROBE_RESULT_FUTURE_MS = 5 * 60000;
5639
5728
  class UptimeService {
5640
5729
  store;
5641
5730
  checkRunner;
5731
+ hostedResolveHost;
5732
+ hostedHttpRequest;
5733
+ hostedMaxRedirects;
5642
5734
  leaseOwner = `svc_${randomUUID3().replace(/-/g, "").slice(0, 18)}`;
5643
5735
  inFlightChecks = new Set;
5644
5736
  inFlightReportSchedules = new Set;
5645
5737
  constructor(options = {}) {
5646
5738
  this.store = options.store ?? new UptimeStore({ mode: "local", ...options });
5647
5739
  this.checkRunner = options.checkRunner ?? runMonitorCheck;
5740
+ this.hostedResolveHost = options.hostedResolveHost;
5741
+ this.hostedHttpRequest = options.hostedHttpRequest;
5742
+ this.hostedMaxRedirects = options.hostedMaxRedirects;
5648
5743
  }
5649
5744
  close() {
5650
5745
  this.store.close();
@@ -5779,10 +5874,10 @@ class UptimeService {
5779
5874
  return this.reportStore().listReportRuns(options);
5780
5875
  }
5781
5876
  listAuditEvents(options = {}) {
5782
- return this.reportStore().listAuditEvents(options);
5877
+ return this.auditStore().listAuditEvents(options);
5783
5878
  }
5784
5879
  recordAuditEvent(input) {
5785
- return this.reportStore().recordAuditEvent(input);
5880
+ return this.auditStore().recordAuditEvent(input);
5786
5881
  }
5787
5882
  async runReportSchedule(idOrName, options = {}) {
5788
5883
  const store = this.reportStore();
@@ -5851,39 +5946,7 @@ class UptimeService {
5851
5946
  const monitor = this.store.getMonitor(idOrName);
5852
5947
  if (!monitor)
5853
5948
  throw new Error(`Monitor not found: ${idOrName}`);
5854
- if (!monitor.enabled)
5855
- throw new Error(`Monitor is disabled: ${monitor.name}`);
5856
- if (this.inFlightChecks.has(monitor.id))
5857
- throw new Error(`Monitor check already in progress: ${monitor.name}`);
5858
- const leaseTtlMs = Math.max(60000, (monitor.retryCount + 1) * monitor.timeoutMs + 1e4);
5859
- if (!this.store.acquireCheckLease(monitor.id, this.leaseOwner, leaseTtlMs)) {
5860
- throw new MonitorCheckBusyError(`Monitor check already in progress: ${monitor.name}`);
5861
- }
5862
- this.inFlightChecks.add(monitor.id);
5863
- try {
5864
- let attemptCount = 0;
5865
- let last = null;
5866
- const maxAttempts = Math.max(1, monitor.retryCount + 1);
5867
- while (attemptCount < maxAttempts) {
5868
- attemptCount += 1;
5869
- last = await this.checkRunner(monitor);
5870
- if (last.status === "up")
5871
- break;
5872
- }
5873
- return this.store.recordCheckResult({
5874
- monitorId: monitor.id,
5875
- status: last.status,
5876
- latencyMs: last.latencyMs,
5877
- statusCode: last.statusCode ?? null,
5878
- error: last.error ?? null,
5879
- evidence: last.evidence ?? null,
5880
- attemptCount,
5881
- expectedMonitorRevision: monitor.revision
5882
- });
5883
- } finally {
5884
- this.inFlightChecks.delete(monitor.id);
5885
- this.store.releaseCheckLease(monitor.id, this.leaseOwner);
5886
- }
5949
+ return this.recordMonitorCheck(monitor, { hostedTargetPolicy: false });
5887
5950
  }
5888
5951
  async checkAll() {
5889
5952
  if (this.store.mode === "hosted")
@@ -5895,6 +5958,49 @@ class UptimeService {
5895
5958
  }
5896
5959
  return results;
5897
5960
  }
5961
+ async checkHostedPublicMonitor(idOrName, options = {}) {
5962
+ this.assertHostedPublicChecksEnabled();
5963
+ const workspaceId = this.requireHostedWorkerWorkspaceId(options.workspaceId);
5964
+ const monitor = this.store.getMonitor(idOrName, { workspaceId });
5965
+ if (!monitor)
5966
+ throw new Error(`Monitor not found: ${idOrName}`);
5967
+ this.assertHostedPublicMonitor(monitor);
5968
+ const result = await this.recordMonitorCheck(monitor, { hostedTargetPolicy: true });
5969
+ this.auditStore().recordAuditEvent({
5970
+ workspaceId,
5971
+ action: "hosted_public_check.run",
5972
+ resourceType: "monitor",
5973
+ resourceId: monitor.id,
5974
+ message: `Ran hosted public check for ${monitor.name}`,
5975
+ metadata: {
5976
+ checkResultId: result.id,
5977
+ status: result.status,
5978
+ monitorKind: monitor.kind,
5979
+ operatorPath: "hosted_public_check"
5980
+ },
5981
+ actor: "hosted-public-check-worker"
5982
+ });
5983
+ return result;
5984
+ }
5985
+ async runDueHostedPublicChecks(now = new Date, options = {}) {
5986
+ this.assertHostedPublicChecksEnabled();
5987
+ const workspaceId = this.requireHostedWorkerWorkspaceId(options.workspaceId);
5988
+ const due = this.store.listMonitors({ workspaceId }).filter((monitor) => this.isHostedPublicMonitor(monitor) && this.isDue(monitor, now));
5989
+ const results = [];
5990
+ for (const monitor of due) {
5991
+ const current = this.store.getMonitor(monitor.id, { workspaceId });
5992
+ if (!current || !this.isHostedPublicMonitor(current) || !this.isDue(current, now))
5993
+ continue;
5994
+ try {
5995
+ results.push(await this.checkHostedPublicMonitor(current.id, { workspaceId }));
5996
+ } catch (error) {
5997
+ if (error instanceof MonitorCheckBusyError || error instanceof StaleCheckResultError)
5998
+ continue;
5999
+ throw error;
6000
+ }
6001
+ }
6002
+ return results;
6003
+ }
5898
6004
  startScheduler(options = {}) {
5899
6005
  if (this.store.mode === "hosted")
5900
6006
  throw new Error("hosted scheduler requires check_jobs and probes");
@@ -5940,6 +6046,67 @@ class UptimeService {
5940
6046
  const last = new Date(monitor.lastCheckedAt).getTime();
5941
6047
  return now.getTime() - last >= monitor.intervalSeconds * 1000;
5942
6048
  }
6049
+ async recordMonitorCheck(monitor, options) {
6050
+ if (!monitor.enabled)
6051
+ throw new Error(`Monitor is disabled: ${monitor.name}`);
6052
+ if (this.inFlightChecks.has(monitor.id))
6053
+ throw new Error(`Monitor check already in progress: ${monitor.name}`);
6054
+ const leaseTtlMs = Math.max(60000, (monitor.retryCount + 1) * monitor.timeoutMs + 1e4);
6055
+ if (!this.store.acquireCheckLease(monitor.id, this.leaseOwner, leaseTtlMs)) {
6056
+ throw new MonitorCheckBusyError(`Monitor check already in progress: ${monitor.name}`);
6057
+ }
6058
+ this.inFlightChecks.add(monitor.id);
6059
+ try {
6060
+ let attemptCount = 0;
6061
+ let last = null;
6062
+ const maxAttempts = Math.max(1, monitor.retryCount + 1);
6063
+ while (attemptCount < maxAttempts) {
6064
+ attemptCount += 1;
6065
+ last = options.hostedTargetPolicy ? await this.runHostedPublicCheckAttempt(monitor) : await this.checkRunner(monitor);
6066
+ if (last.status === "up")
6067
+ break;
6068
+ }
6069
+ return this.store.recordCheckResult({
6070
+ monitorId: monitor.id,
6071
+ status: last.status,
6072
+ latencyMs: last.latencyMs,
6073
+ statusCode: last.statusCode ?? null,
6074
+ error: last.error ?? null,
6075
+ evidence: last.evidence ?? null,
6076
+ attemptCount,
6077
+ expectedMonitorRevision: monitor.revision
6078
+ });
6079
+ } finally {
6080
+ this.inFlightChecks.delete(monitor.id);
6081
+ this.store.releaseCheckLease(monitor.id, this.leaseOwner);
6082
+ }
6083
+ }
6084
+ runHostedPublicCheckAttempt(monitor) {
6085
+ return runMonitorCheck(monitor, {
6086
+ hostedTargetPolicy: true,
6087
+ resolveHost: this.hostedResolveHost,
6088
+ hostedHttpRequest: this.hostedHttpRequest,
6089
+ maxRedirects: this.hostedMaxRedirects
6090
+ });
6091
+ }
6092
+ assertHostedPublicChecksEnabled() {
6093
+ if (this.store.mode !== "hosted")
6094
+ throw new Error("hosted public checks require hosted mode");
6095
+ }
6096
+ requireHostedWorkerWorkspaceId(workspaceId) {
6097
+ const value = workspaceId?.trim() || process.env.HASNA_UPTIME_WORKSPACE_ID?.trim();
6098
+ if (!value)
6099
+ throw new Error("hosted public checks require a workspace id");
6100
+ return value;
6101
+ }
6102
+ assertHostedPublicMonitor(monitor) {
6103
+ if (!this.isHostedPublicMonitor(monitor)) {
6104
+ throw new Error("hosted public checks support only HTTP and TCP monitors");
6105
+ }
6106
+ }
6107
+ isHostedPublicMonitor(monitor) {
6108
+ return monitor.kind === "http" || monitor.kind === "tcp";
6109
+ }
5943
6110
  probeStore() {
5944
6111
  if (this.store.mode === "hosted") {
5945
6112
  throw new Error("hosted probe APIs require cloud check_jobs, workspace stores, and audit logging");
@@ -5989,6 +6156,13 @@ class UptimeService {
5989
6156
  }
5990
6157
  return store;
5991
6158
  }
6159
+ auditStore() {
6160
+ const store = this.store;
6161
+ if (typeof store.recordAuditEvent !== "function" || typeof store.listAuditEvents !== "function") {
6162
+ throw new Error("audit logging requires an audit-capable store");
6163
+ }
6164
+ return store;
6165
+ }
5992
6166
  audit(action, resourceType, resourceId, message, metadata) {
5993
6167
  this.reportStore().recordAuditEvent({
5994
6168
  action,
@@ -6712,7 +6886,10 @@ async function handleApiRoute(service, request, url, apiPath, options, hosted, a
6712
6886
  return json(service.listMonitors({ includeDisabled: url.searchParams.get("includeDisabled") === "true", workspaceId: actor?.workspaceId }));
6713
6887
  }
6714
6888
  if (request.method === "POST" && apiPath === "/api/monitors") {
6715
- return json(service.createMonitor(await jsonBody(request), { workspaceId: actor?.workspaceId }), 201);
6889
+ const monitor = service.createMonitor(await jsonBody(request), { workspaceId: actor?.workspaceId });
6890
+ if (hosted && actor)
6891
+ recordHostedMonitorAudit(service, actor, "monitor.create", monitor, { method: request.method, apiPath });
6892
+ return json(monitor, 201);
6716
6893
  }
6717
6894
  if (request.method === "GET" && apiPath === "/api/incidents") {
6718
6895
  const status = url.searchParams.get("status");
@@ -6789,10 +6966,25 @@ async function handleApiRoute(service, request, url, apiPath, options, hosted, a
6789
6966
  return monitor ? json(monitor) : json({ error: "not found" }, 404);
6790
6967
  }
6791
6968
  if (request.method === "PATCH" && !monitorMatch[2]) {
6792
- return json(service.updateMonitor(id, await jsonBody(request), { workspaceId: actor?.workspaceId }));
6969
+ const before = hosted ? service.getMonitor(id, { workspaceId: actor?.workspaceId }) : null;
6970
+ const monitor = service.updateMonitor(id, await jsonBody(request), { workspaceId: actor?.workspaceId });
6971
+ if (hosted && actor) {
6972
+ recordHostedMonitorAudit(service, actor, "monitor.update", monitor, {
6973
+ method: request.method,
6974
+ apiPath,
6975
+ previousRevision: before?.revision ?? null,
6976
+ nextRevision: monitor.revision
6977
+ });
6978
+ }
6979
+ return json(monitor);
6793
6980
  }
6794
6981
  if (request.method === "DELETE" && !monitorMatch[2]) {
6795
- return json({ deleted: service.deleteMonitor(id, { workspaceId: actor?.workspaceId }) });
6982
+ const before = hosted ? service.getMonitor(id, { workspaceId: actor?.workspaceId }) : null;
6983
+ const deleted = service.deleteMonitor(id, { workspaceId: actor?.workspaceId });
6984
+ if (hosted && actor && deleted && before) {
6985
+ recordHostedMonitorAudit(service, actor, "monitor.delete", before, { method: request.method, apiPath });
6986
+ }
6987
+ return json({ deleted });
6796
6988
  }
6797
6989
  if (request.method === "POST" && monitorMatch[2] === "check") {
6798
6990
  if (hosted)
@@ -6836,7 +7028,29 @@ function requireHostedActor(request, url, options, scope) {
6836
7028
  if (requestedWorkspace && requestedWorkspace !== workspaceId) {
6837
7029
  throw new ApiError("workspace access denied", 403);
6838
7030
  }
6839
- return { scopes, workspaceId };
7031
+ return {
7032
+ scopes,
7033
+ workspaceId,
7034
+ actor: token.actor ?? `hosted-token:${workspaceId}:${[...scopes].sort().join(",")}`
7035
+ };
7036
+ }
7037
+ function recordHostedMonitorAudit(service, actor, action, monitor, metadata) {
7038
+ service.recordAuditEvent({
7039
+ workspaceId: actor.workspaceId,
7040
+ action,
7041
+ actor: actor.actor,
7042
+ resourceType: "monitor",
7043
+ resourceId: monitor.id,
7044
+ metadata: {
7045
+ ...metadata,
7046
+ monitorName: monitor.name,
7047
+ monitorKind: monitor.kind,
7048
+ monitorEnabled: monitor.enabled,
7049
+ monitorRevision: monitor.revision,
7050
+ workspaceId: monitor.workspaceId,
7051
+ scopes: [...actor.scopes].sort()
7052
+ }
7053
+ });
6840
7054
  }
6841
7055
  function isLoopbackHost(hostname) {
6842
7056
  const host = hostname.toLowerCase().replace(/^\[|\]$/g, "");
@@ -6914,7 +7128,8 @@ function normalizeHostedTokenEntry(entry, defaultWorkspaceId, source) {
6914
7128
  }
6915
7129
  const scopes = normalizeHostedScopes(entry.scopes, `${source}.scopes`);
6916
7130
  const workspaceId = typeof entry.workspaceId === "string" && entry.workspaceId.trim() ? entry.workspaceId.trim() : defaultWorkspaceId;
6917
- return { token: entry.token.trim(), scopes, workspaceId };
7131
+ const actor = typeof entry.actor === "string" && entry.actor.trim() ? entry.actor.trim() : typeof entry.subject === "string" && entry.subject.trim() ? entry.subject.trim() : typeof entry.id === "string" && entry.id.trim() ? entry.id.trim() : undefined;
7132
+ return { token: entry.token.trim(), scopes, workspaceId, actor };
6918
7133
  }
6919
7134
  function normalizeHostedScopes(value, source) {
6920
7135
  if (!Array.isArray(value) || value.length === 0) {
@@ -7014,7 +7229,7 @@ function buildAwsDeploymentPlan(options = {}) {
7014
7229
  const image = clean(options.image, `${imageRepositoryUri}@sha256:<image-digest>`);
7015
7230
  const evidenceBucket = clean(options.evidenceBucket, `hasna-${stage}-${prefix}-evidence`);
7016
7231
  const hostedSqliteDbPath = clean(options.hostedSqliteDbPath, DEFAULT_HOSTED_SQLITE_DB);
7017
- const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.22");
7232
+ const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.24");
7018
7233
  const protectedAccessMode = options.protectedAccessMode ?? DEFAULT_PROTECTED_ACCESS_MODE;
7019
7234
  const protectedAccessUrl = protectedAccessMode === "cloudfront_default_domain" ? "https://<cloudfront-domain>" : `https://${hostname}`;
7020
7235
  const cluster = `${prefix}-${stage}`;
@@ -7259,7 +7474,10 @@ function buildPrivateProbeCloudConfig(options = {}) {
7259
7474
  }
7260
7475
  };
7261
7476
  }
7262
- function renderPrivateProbeEnv(config) {
7477
+ function renderPrivateProbeEnv(config, options = {}) {
7478
+ if (!options.allowBlocked && (!config.canStart || config.blockers.length > 0)) {
7479
+ throw new Error("private probe env output is blocked until hosted probe routes and cloud jobs are implemented");
7480
+ }
7263
7481
  const required = ["HASNA_UPTIME_PRIVATE_PROBE_ID"];
7264
7482
  const missing = required.filter((key) => !config.env[key]);
7265
7483
  if (missing.length > 0) {
@@ -7302,6 +7520,13 @@ program2.name("uptime").description("Local-first uptime and downtime monitoring"
7302
7520
  function service() {
7303
7521
  return new UptimeService({ mode: "local" });
7304
7522
  }
7523
+ function hostedService(opts) {
7524
+ return new UptimeService({
7525
+ mode: "hosted",
7526
+ hostedSqliteDbPath: opts.hostedSqliteDb,
7527
+ allowHostedLocalStore: opts.allowHostedLocalStore
7528
+ });
7529
+ }
7305
7530
  function wantsJson(opts) {
7306
7531
  return Boolean(opts?.json || program2.opts().json);
7307
7532
  }
@@ -7627,7 +7852,7 @@ cloud.command("plan").description("Generate a dry-run AWS deployment plan").opti
7627
7852
  fail(error);
7628
7853
  }
7629
7854
  });
7630
- cloud.command("private-probe-config").description("Generate hosted-targeted private probe preflight configuration").option("--api-url <url>", "hosted Open Uptime API URL", "https://uptime.example.com/api/v1").option("--workspace-id <id>", "workspace id", "workspace-id").option("--probe-id <id>", "cloud registered private probe id").option("--private-key-file <path>", "private probe key file", "~/.hasna/uptime/probes/private-probe-01.key.pem").option("--machine-id <id>", "machine id", "private-probe-01").option("--log-level <level>", "probe log level", "info").option("--env", "print shell env file instead of summary text").option("-j, --json", "print JSON").action((opts) => {
7855
+ cloud.command("private-probe-config").description("Generate hosted-targeted private probe preflight configuration").option("--api-url <url>", "hosted Open Uptime API URL", "https://uptime.example.com/api/v1").option("--workspace-id <id>", "workspace id", "workspace-id").option("--probe-id <id>", "cloud registered private probe id").option("--private-key-file <path>", "private probe key file", "~/.hasna/uptime/probes/private-probe-01.key.pem").option("--machine-id <id>", "machine id", "private-probe-01").option("--log-level <level>", "probe log level", "info").option("--env", "print shell env file instead of summary text").option("--allow-blocked-env", "print the blocked preflight env anyway for review artifacts; do not start the probe").option("-j, --json", "print JSON").action((opts) => {
7631
7856
  try {
7632
7857
  const config = buildPrivateProbeCloudConfig({
7633
7858
  apiUrl: opts.apiUrl,
@@ -7638,7 +7863,7 @@ cloud.command("private-probe-config").description("Generate hosted-targeted priv
7638
7863
  logLevel: opts.logLevel
7639
7864
  });
7640
7865
  if (opts.env && !wantsJson(opts)) {
7641
- console.log(renderPrivateProbeEnv(config));
7866
+ console.log(renderPrivateProbeEnv(config, { allowBlocked: opts.allowBlockedEnv }));
7642
7867
  return;
7643
7868
  }
7644
7869
  print(config, renderPrivateProbeConfig(config), opts);
@@ -7646,6 +7871,22 @@ cloud.command("private-probe-config").description("Generate hosted-targeted priv
7646
7871
  fail(error);
7647
7872
  }
7648
7873
  });
7874
+ var cloudPublicChecks = cloud.command("public-checks").description("Run hosted public HTTP/TCP checks against the configured hosted store");
7875
+ cloudPublicChecks.command("run-due").description("Run due hosted public HTTP/TCP checks for one workspace").option("--workspace-id <id>", "workspace id; defaults to HASNA_UPTIME_WORKSPACE_ID").option("--now <iso>", "due timestamp", new Date().toISOString()).option("--hosted-sqlite-db <path>", "hosted SQLite path on cloud-mounted storage").option("--allow-hosted-local-store", "allow hosted mode to use local SQLite as an explicit fallback").option("-j, --json", "print JSON").action(async (opts) => {
7876
+ try {
7877
+ const svc = hostedService({
7878
+ hostedSqliteDb: opts.hostedSqliteDb,
7879
+ allowHostedLocalStore: opts.allowHostedLocalStore
7880
+ });
7881
+ const workspaceId = opts.workspaceId || process.env.HASNA_UPTIME_WORKSPACE_ID;
7882
+ const results = await svc.runDueHostedPublicChecks(new Date(opts.now), { workspaceId });
7883
+ svc.close();
7884
+ const data = { ok: true, workspaceId, checked: results.length, results };
7885
+ print(data, results.length ? renderCheckResults(results) : "No due hosted public checks", opts);
7886
+ } catch (error) {
7887
+ fail(error);
7888
+ }
7889
+ });
7649
7890
  program2.command("results").description("List recent check results").option("--monitor <id>", "filter by monitor id").option("--limit <n>", "max rows", parseInteger, 20).option("-j, --json", "print JSON").action((opts) => {
7650
7891
  try {
7651
7892
  const svc = service();
@@ -137,5 +137,7 @@ export interface PrivateProbeCloudConfig {
137
137
  }
138
138
  export declare function buildAwsDeploymentPlan(options?: AwsDeploymentPlanOptions): AwsDeploymentPlan;
139
139
  export declare function buildPrivateProbeCloudConfig(options?: PrivateProbeCloudConfigOptions): PrivateProbeCloudConfig;
140
- export declare function renderPrivateProbeEnv(config: PrivateProbeCloudConfig): string;
140
+ export declare function renderPrivateProbeEnv(config: PrivateProbeCloudConfig, options?: {
141
+ allowBlocked?: boolean;
142
+ }): string;
141
143
  //# sourceMappingURL=cloud-plan.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-plan.d.ts","sourceRoot":"","sources":["../src/cloud-plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cloud-plan.d.ts","sourceRoot":"","sources":["../src/cloud-plan.ts"],"names":[],"mappings":"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"}