home-hosted 0.7.7 → 0.7.9

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.js CHANGED
@@ -6033,9 +6033,20 @@ var init_logs = __esmMin((() => {
6033
6033
  }));
6034
6034
  //#endregion
6035
6035
  //#region src/api/metrics.ts
6036
+ /**
6037
+ * Escapes a value for the quoted form of a Prometheus label, per the exposition
6038
+ * format: only `\\`, `"` and a newline are special, and each needs a backslash.
6039
+ *
6040
+ * A raw Windows path is the reachable case — `diskPaths` is user config and
6041
+ * `C:\Users\me` emits `\U`, which is not a valid escape, so the scraper rejects the
6042
+ * whole sample. The ids are charset-constrained by their schemas, but the paths are not.
6043
+ */
6044
+ function labelValue(value) {
6045
+ return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, "\\n");
6046
+ }
6036
6047
  /** A server id repeats across workspaces, so every sample names both. */
6037
6048
  function labels(server) {
6038
- return `server="${server.id}",workspace="${server.workspaceId ?? ""}"`;
6049
+ return `server="${labelValue(server.id)}",workspace="${labelValue(server.workspaceId ?? "")}"`;
6039
6050
  }
6040
6051
  /**
6041
6052
  * Prometheus text for whatever wants to scrape the panel (Beszel, Grafana,
@@ -6066,7 +6077,7 @@ function createMetricsRoute(deps) {
6066
6077
  metric("hh_server_response_ms", "Last health probe latency in milliseconds", servers.filter((server) => server.responseMs !== null).map((server) => `hh_server_response_ms{${labels(server)}} ${server.responseMs}`));
6067
6078
  metric("hh_server_rss_bytes", "RSS of the server process tree", servers.filter((server) => server.resources?.rssBytes != null).map((server) => `hh_server_rss_bytes{${labels(server)}} ${server.resources.rssBytes}`));
6068
6079
  metric("hh_server_cpu_percent", "CPU percent of the server process tree", servers.filter((server) => server.resources?.cpuPercent != null).map((server) => `hh_server_cpu_percent{${labels(server)}} ${server.resources.cpuPercent}`));
6069
- metric("hh_host_disk_used_percent", "Disk usage percent per configured path", host.disks.map((disk) => `hh_host_disk_used_percent{mount="${disk.path}"} ${disk.usedPercent.toFixed(2)}`));
6080
+ metric("hh_host_disk_used_percent", "Disk usage percent per configured path", host.disks.map((disk) => `hh_host_disk_used_percent{mount="${labelValue(disk.path)}"} ${disk.usedPercent.toFixed(2)}`));
6070
6081
  metric("hh_host_memory_used_percent", "Memory usage percent", [`hh_host_memory_used_percent ${host.memoryUsedPercent.toFixed(2)}`]);
6071
6082
  metric("hh_host_swap_used_percent", "Swap usage percent", [`hh_host_swap_used_percent ${host.swapUsedPercent.toFixed(2)}`]);
6072
6083
  metric("hh_host_load1_per_cpu", "1 minute load average per cpu", [`hh_host_load1_per_cpu ${((host.loadAvg[0] ?? 0) / Math.max(1, host.cpus)).toFixed(3)}`]);
@@ -6566,7 +6577,29 @@ function splitCommandLine(line) {
6566
6577
  let current = "";
6567
6578
  let quoted = false;
6568
6579
  let started = false;
6569
- for (const char of line.trim()) {
6580
+ const chars = [...line.trim()];
6581
+ for (let index = 0; index < chars.length; index += 1) {
6582
+ const char = chars[index];
6583
+ if (char === "\\") {
6584
+ let run = 0;
6585
+ while (chars[index + run] === "\\") run += 1;
6586
+ if (chars[index + run] !== "\"") {
6587
+ current += "\\".repeat(run);
6588
+ started = true;
6589
+ index += run - 1;
6590
+ continue;
6591
+ }
6592
+ current += "\\".repeat(Math.floor(run / 2));
6593
+ started = true;
6594
+ if (run % 2 === 1) {
6595
+ current += "\"";
6596
+ index += run;
6597
+ continue;
6598
+ }
6599
+ quoted = !quoted;
6600
+ index += run;
6601
+ continue;
6602
+ }
6570
6603
  if (char === "\"") {
6571
6604
  quoted = !quoted;
6572
6605
  started = true;
@@ -9430,7 +9463,7 @@ function createServersRoute(deps) {
9430
9463
  responses: {
9431
9464
  201: {
9432
9465
  description: "Created",
9433
- content: jsonBody(serverResponse)
9466
+ content: jsonBody(storedServerResponse)
9434
9467
  },
9435
9468
  400: ERROR_RESPONSES[400]
9436
9469
  }
@@ -9623,7 +9656,7 @@ function createServersRoute(deps) {
9623
9656
  responses: {
9624
9657
  200: {
9625
9658
  description: "The server",
9626
- content: jsonBody(serverResponse)
9659
+ content: jsonBody(storedServerResponse)
9627
9660
  },
9628
9661
  400: ERROR_RESPONSES[400],
9629
9662
  404: ERROR_RESPONSES[404]
@@ -9665,7 +9698,7 @@ function createServersRoute(deps) {
9665
9698
  }
9666
9699
  });
9667
9700
  }
9668
- var idParam$1, MAX_PENDING_WRITES, serverResponse, serversResponse, okResponse, bufferedLogsQuery;
9701
+ var idParam$1, MAX_PENDING_WRITES, serverResponse, serversResponse, storedServerResponse, okResponse, bufferedLogsQuery;
9669
9702
  var init_$_routes$1 = __esmMin((() => {
9670
9703
  init_store();
9671
9704
  init_action_result();
@@ -9679,6 +9712,7 @@ var init_$_routes$1 = __esmMin((() => {
9679
9712
  MAX_PENDING_WRITES = 200;
9680
9713
  serverResponse = type({ server: serverViewSchema });
9681
9714
  serversResponse = type({ servers: serverViewSchema.array() });
9715
+ storedServerResponse = type({ server: serverSchema });
9682
9716
  okResponse = type({ ok: "boolean" });
9683
9717
  bufferedLogsQuery = logQuerySchema.merge(workspaceQuerySchema);
9684
9718
  }));