fix(api): create the SQLite parent dir before opening the DB
A fresh local `yarn db:migrate`/`yarn dev` failed with SQLITE_CANTOPEN (14) because libsql does not create the parent directory for a file: URL and the gitignored apps/api/data/ does not exist on checkout. Added ensureDbDir() and call it before createClient in both the client and the migrator. No-op for non-file URLs and for the Docker /data volume. Verified: fresh db:migrate now creates data/ and all tables; tests + typecheck still green; live round-trip (/health, sign-up, sign-in, /api/me, 401) works.
This commit is contained in:
@@ -2,6 +2,8 @@ import { drizzle } from 'drizzle-orm/libsql';
|
||||
import { createClient } from '@libsql/client';
|
||||
import { env } from '../env';
|
||||
import * as schema from './schema';
|
||||
import { ensureDbDir } from './ensure-dir';
|
||||
|
||||
ensureDbDir(env.DATABASE_URL);
|
||||
const client = createClient({ url: env.DATABASE_URL });
|
||||
export const db = drizzle(client, { schema });
|
||||
|
||||
13
apps/api/src/db/ensure-dir.ts
Normal file
13
apps/api/src/db/ensure-dir.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { mkdirSync } from 'node:fs';
|
||||
import { dirname } from 'node:path';
|
||||
|
||||
// libsql/SQLite does NOT create the parent directory for a `file:` URL — it fails
|
||||
// with SQLITE_CANTOPEN (error 14). Create it first so a fresh local `db:migrate`
|
||||
// or `dev` works without a manual `mkdir`. No-op for non-file URLs and for paths
|
||||
// whose directory already exists (e.g. the Docker `/data` volume).
|
||||
export function ensureDbDir(databaseUrl: string): void {
|
||||
if (!databaseUrl.startsWith('file:')) return;
|
||||
const path = databaseUrl.slice('file:'.length);
|
||||
const dir = dirname(path);
|
||||
if (dir && dir !== '.') mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
@@ -3,8 +3,10 @@ import { drizzle } from 'drizzle-orm/libsql';
|
||||
import { migrate } from 'drizzle-orm/libsql/migrator';
|
||||
import { createClient } from '@libsql/client';
|
||||
import { env } from '../env';
|
||||
import { ensureDbDir } from './ensure-dir';
|
||||
|
||||
export async function runMigrations(): Promise<void> {
|
||||
ensureDbDir(env.DATABASE_URL);
|
||||
const client = createClient({ url: env.DATABASE_URL });
|
||||
const db = drizzle(client);
|
||||
await migrate(db, { migrationsFolder: './drizzle' });
|
||||
|
||||
Reference in New Issue
Block a user