Initial import

This commit is contained in:
how2ice
2026-04-21 03:33:23 +09:00
commit 9e4b70f1f1
495 changed files with 94680 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
import type { FastifyInstance } from 'fastify';
import { z } from 'zod';
import { db } from '../db/client.js';
import { assertIdentifier } from '../lib/identifier.js';
const columnSchema = z.object({
name: z.string(),
type: z.string(),
nullable: z.boolean().optional(),
primary: z.boolean().optional(),
unique: z.boolean().optional(),
defaultTo: z.any().optional(),
});
const createTableSchema = z.object({
tableName: z.string(),
columns: z.array(columnSchema).min(1),
});
const dropTableSchema = z.object({
tableName: z.string(),
});
const addColumnSchema = z.object({
tableName: z.string(),
column: columnSchema,
});
const dropColumnSchema = z.object({
tableName: z.string(),
columnName: z.string(),
});
const rawDdlSchema = z.object({
sql: z.string().min(1),
});
function applyColumn(tableBuilder: any, column: z.infer<typeof columnSchema>) {
const name = assertIdentifier(column.name, 'column name');
const definition = tableBuilder.specificType(name, column.type);
if (column.nullable === false) {
definition.notNullable();
}
if (column.nullable === true) {
definition.nullable();
}
if (column.primary) {
definition.primary();
}
if (column.unique) {
definition.unique();
}
if (column.defaultTo !== undefined) {
definition.defaultTo(column.defaultTo);
}
}
export async function registerDdlRoutes(app: FastifyInstance) {
app.post('/api/ddl/create-table', async (request) => {
const payload = createTableSchema.parse(request.body);
const tableName = assertIdentifier(payload.tableName, 'table name');
await db.schema.createTable(tableName, (table) => {
payload.columns.forEach((column) => {
applyColumn(table, column);
});
});
return { ok: true, action: 'create-table', tableName };
});
app.post('/api/ddl/drop-table', async (request) => {
const payload = dropTableSchema.parse(request.body);
const tableName = assertIdentifier(payload.tableName, 'table name');
await db.schema.dropTableIfExists(tableName);
return { ok: true, action: 'drop-table', tableName };
});
app.post('/api/ddl/add-column', async (request) => {
const payload = addColumnSchema.parse(request.body);
const tableName = assertIdentifier(payload.tableName, 'table name');
await db.schema.alterTable(tableName, (table) => {
applyColumn(table, payload.column);
});
return { ok: true, action: 'add-column', tableName, column: payload.column.name };
});
app.post('/api/ddl/drop-column', async (request) => {
const payload = dropColumnSchema.parse(request.body);
const tableName = assertIdentifier(payload.tableName, 'table name');
const columnName = assertIdentifier(payload.columnName, 'column name');
await db.schema.alterTable(tableName, (table) => {
table.dropColumn(columnName);
});
return { ok: true, action: 'drop-column', tableName, columnName };
});
app.post('/api/ddl/raw', async (request) => {
const payload = rawDdlSchema.parse(request.body);
const result = await db.raw(payload.sql);
return {
ok: true,
action: 'raw',
result,
};
});
}