patchrelay 0.4.0 → 0.4.1

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "service": "patchrelay",
3
- "version": "0.4.0",
4
- "commit": "94bb0a0f517c",
5
- "builtAt": "2026-03-13T09:13:16.897Z"
3
+ "version": "0.4.1",
4
+ "commit": "13439842db03",
5
+ "builtAt": "2026-03-13T09:25:15.012Z"
6
6
  }
package/dist/preflight.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import { accessSync, constants, existsSync, mkdirSync, statSync } from "node:fs";
2
2
  import path from "node:path";
3
+ import { runPatchRelayMigrations } from "./db/migrations.js";
4
+ import { SqliteConnection } from "./db/shared.js";
3
5
  import { execCommand } from "./utils.js";
4
6
  export async function runPreflight(config) {
5
7
  const checks = [];
@@ -62,6 +64,7 @@ export async function runPreflight(config) {
62
64
  checks.push(...checkPublicBaseUrl(config));
63
65
  checks.push(...checkOAuthRedirectUri(config));
64
66
  checks.push(...checkPath("database", path.dirname(config.database.path), "directory", { createIfMissing: true, writable: true }));
67
+ checks.push(checkDatabaseSchema(config));
65
68
  checks.push(...checkPath("logging", path.dirname(config.logging.filePath), "directory", { createIfMissing: true, writable: true }));
66
69
  if (config.logging.webhookArchiveDir) {
67
70
  checks.push(...checkPath("archive", config.logging.webhookArchiveDir, "directory", { createIfMissing: true, writable: true }));
@@ -86,6 +89,42 @@ export async function runPreflight(config) {
86
89
  ok: checks.every((check) => check.status !== "fail"),
87
90
  };
88
91
  }
92
+ function checkDatabaseSchema(config) {
93
+ let connection;
94
+ try {
95
+ connection = new SqliteConnection(config.database.path);
96
+ connection.pragma("foreign_keys = ON");
97
+ if (config.database.wal) {
98
+ connection.pragma("journal_mode = WAL");
99
+ }
100
+ runPatchRelayMigrations(connection);
101
+ const quickCheck = connection.prepare("PRAGMA quick_check").get();
102
+ const quickCheckResult = quickCheck ? Object.values(quickCheck)[0] : undefined;
103
+ if (quickCheckResult !== "ok") {
104
+ return fail("database_schema", `SQLite quick_check failed: ${String(quickCheckResult ?? "unknown result")}`);
105
+ }
106
+ const schemaStats = connection
107
+ .prepare(`
108
+ SELECT
109
+ COUNT(*) AS object_count
110
+ FROM sqlite_master
111
+ WHERE type IN ('table', 'index', 'view', 'trigger')
112
+ AND name NOT LIKE 'sqlite_%'
113
+ `)
114
+ .get();
115
+ const objectCount = Number(schemaStats?.object_count ?? 0);
116
+ if (objectCount < 1) {
117
+ return fail("database_schema", "Database schema is empty after migrations");
118
+ }
119
+ return pass("database_schema", `Database opened, migrations applied, and schema is readable (${objectCount} objects)`);
120
+ }
121
+ catch (error) {
122
+ return fail("database_schema", `Unable to open or validate database schema at ${config.database.path}: ${formatError(error)}`);
123
+ }
124
+ finally {
125
+ connection?.close();
126
+ }
127
+ }
89
128
  function checkPath(scope, targetPath, expectedType, options) {
90
129
  const checks = [];
91
130
  if (!existsSync(targetPath)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchrelay",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {