Raw SQL migration endpoint (bypass drizzle schema requirement)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -51,12 +51,30 @@ const app = new Hono<AppEnv>()
|
||||
.get('/health', (c) => c.json({ status: 'ok' }))
|
||||
.post('/migrate', async (c) => {
|
||||
try {
|
||||
const path = await import('path');
|
||||
const folder = path.resolve(process.cwd(), 'packages/db/src/migrations');
|
||||
await migrate(db, { migrationsFolder: folder });
|
||||
return c.json({ status: 'ok', message: 'Migrations applied', folder });
|
||||
const fs = await import('fs');
|
||||
const pathMod = await import('path');
|
||||
const { sql: dsql } = await import('drizzle-orm');
|
||||
const folder = pathMod.resolve(process.cwd(), 'packages/db/src/migrations');
|
||||
const journal = JSON.parse(fs.readFileSync(pathMod.join(folder, 'meta', '_journal.json'), 'utf8'));
|
||||
const results: string[] = [];
|
||||
for (const entry of journal.entries) {
|
||||
const sqlFile = pathMod.join(folder, `${entry.tag}.sql`);
|
||||
if (!fs.existsSync(sqlFile)) { results.push(`skip: ${entry.tag} (not found)`); continue; }
|
||||
const rawSql = fs.readFileSync(sqlFile, 'utf8');
|
||||
const statements = rawSql.split('--> statement-breakpoint').map((s: string) => s.trim()).filter(Boolean);
|
||||
for (const stmt of statements) {
|
||||
try {
|
||||
await db.execute(dsql.raw(stmt));
|
||||
} catch (err: any) {
|
||||
if (err.message?.includes('already exists') || err.message?.includes('duplicate')) continue;
|
||||
results.push(`error in ${entry.tag}: ${err.message?.slice(0, 150)}`);
|
||||
}
|
||||
}
|
||||
results.push(`ok: ${entry.tag}`);
|
||||
}
|
||||
return c.json({ status: 'ok', results });
|
||||
} catch (err: any) {
|
||||
return c.json({ status: 'error', message: err.message, stack: err.stack?.slice(0, 500) }, 500);
|
||||
return c.json({ status: 'error', message: err.message }, 500);
|
||||
}
|
||||
})
|
||||
.basePath('/api/v1')
|
||||
|
||||
Reference in New Issue
Block a user