initial
This commit is contained in:
49
apps/server/src/routes/settings.ts
Normal file
49
apps/server/src/routes/settings.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import type { FastifyInstance } from 'fastify';
|
||||
import { z } from 'zod';
|
||||
import type { Sql } from '../db.js';
|
||||
|
||||
export async function getSetting<T = unknown>(
|
||||
sql: Sql,
|
||||
key: string
|
||||
): Promise<T | null> {
|
||||
const rows = await sql<{ value: T }[]>`SELECT value FROM settings WHERE key = ${key}`;
|
||||
return rows[0]?.value ?? null;
|
||||
}
|
||||
|
||||
export async function setSetting(
|
||||
sql: Sql,
|
||||
key: string,
|
||||
value: unknown
|
||||
): Promise<void> {
|
||||
await sql`
|
||||
INSERT INTO settings (key, value)
|
||||
VALUES (${key}, ${sql.json(value as never)})
|
||||
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value
|
||||
`;
|
||||
}
|
||||
|
||||
const PatchBody = z.record(z.string(), z.unknown());
|
||||
|
||||
export function registerSettingsRoutes(app: FastifyInstance, sql: Sql): void {
|
||||
app.get('/api/settings', async () => {
|
||||
const rows = await sql<{ key: string; value: unknown }[]>`SELECT key, value FROM settings`;
|
||||
const out: Record<string, unknown> = {};
|
||||
for (const r of rows) out[r.key] = r.value;
|
||||
return out;
|
||||
});
|
||||
|
||||
app.patch('/api/settings', async (req, reply) => {
|
||||
const parsed = PatchBody.safeParse(req.body);
|
||||
if (!parsed.success) {
|
||||
reply.code(400);
|
||||
return { error: 'invalid body', details: parsed.error.flatten() };
|
||||
}
|
||||
for (const [k, v] of Object.entries(parsed.data)) {
|
||||
await setSetting(sql, k, v);
|
||||
}
|
||||
const rows = await sql<{ key: string; value: unknown }[]>`SELECT key, value FROM settings`;
|
||||
const out: Record<string, unknown> = {};
|
||||
for (const r of rows) out[r.key] = r.value;
|
||||
return out;
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user