diff --git a/api.ts b/api.ts index 6b8ea4a..82cf58e 100644 --- a/api.ts +++ b/api.ts @@ -1,17 +1,40 @@ -import { FreshContext, Handler } from '$fresh/server.ts' -import { TablesForModels } from '@lyrics/db.ts' +import { FreshContext, Handlers } from '$fresh/server.ts' +import { db, TablesForModels } from '@lyrics/db.ts' +import { ulid } from 'https://deno.land/std@0.209.0/ulid/mod.ts' export function crudHandlerFor< T extends { id: string }, - M extends { parse: (a: T) => T }, + M extends { parse: (a: unknown) => T }, P extends keyof typeof TablesForModels, ->(m: M, p: P): Handler { +>(m: M, p: P): Handlers { return { - async GET(req: Request, ctx: FreshContext) { - if (req. - const resp = await ctx.render(); - resp.headers.set("X-Custom-Header", "Hello"); - return resp; - } + async GET(req: Request, _ctx: FreshContext) { + const url = new URL(req.url) + const id = url.searchParams.get('id') + if (id == null) { + return new Response(JSON.stringify(await db[p].all())) + } else { + return new Response(JSON.stringify(await db[p].get(id))) + } + }, + + async PUT(req: Request, _ctx: FreshContext) { + const data = m.parse(await req.json()) + if (!data.id) data.id = ulid() + return new Response(JSON.stringify(await db[p].save(data))) + }, + + async DELETE(req: Request, _ctx: FreshContext) { + const url = new URL(req.url) + const id = url.searchParams.get('id') + if (id == null) { + return new Response( + JSON.stringify({ message: 'no id query parameter provided' }), + { status: 401 }, + ) + } else { + return new Response(JSON.stringify(await db[p].delete(id))) + } + }, } } diff --git a/db.ts b/db.ts index 8468d2a..b3f25a1 100644 --- a/db.ts +++ b/db.ts @@ -7,11 +7,12 @@ export const TablesForModels = { 'playlist': Playlist, 'display': Display, } +export type Table = keyof typeof TablesForModels function crudFor< P extends keyof typeof TablesForModels, T extends { id: string }, - M extends { parse: (a: T) => T }, + M extends { parse: (a: unknown) => T }, >(m: M, p: P) { return { async all(): Promise { @@ -35,6 +36,10 @@ function crudFor< } } +export function isTable(value: string): value is Table { + return (value in TablesForModels) +} + export const db = { song: crudFor(Song, 'song'), playlist: crudFor(Playlist, 'playlist'), diff --git a/fresh.gen.ts b/fresh.gen.ts index 5bda1cd..3581199 100644 --- a/fresh.gen.ts +++ b/fresh.gen.ts @@ -5,6 +5,7 @@ import * as $_404 from './routes/_404.tsx' import * as $_app from './routes/_app.tsx' import * as $api_db from './routes/api/db.ts' +import * as $api_db_table_ from './routes/api/db/[table].ts' import * as $api_joke from './routes/api/joke.ts' import * as $greet_name_ from './routes/greet/[name].tsx' import * as $index from './routes/index.tsx' @@ -16,6 +17,7 @@ const manifest = { './routes/_404.tsx': $_404, './routes/_app.tsx': $_app, './routes/api/db.ts': $api_db, + './routes/api/db/[table].ts': $api_db_table_, './routes/api/joke.ts': $api_joke, './routes/greet/[name].tsx': $greet_name_, './routes/index.tsx': $index, diff --git a/lyrics b/lyrics new file mode 100644 index 0000000..1f41350 Binary files /dev/null and b/lyrics differ diff --git a/routes/api/db/[table].ts b/routes/api/db/[table].ts new file mode 100644 index 0000000..9eb5e18 --- /dev/null +++ b/routes/api/db/[table].ts @@ -0,0 +1,29 @@ +import { FreshContext, Handlers } from '$fresh/server.ts' +import { knownMethods } from '$fresh/server/router.ts' +import { isTable } from '@lyrics/db.ts' +import { crudHandlerFor } from '@lyrics/api.ts' +import { Display, Playlist, Song } from '@lyrics/models.ts' + +export const subHandlers = { + song: crudHandlerFor(Song, 'song'), + playlist: crudHandlerFor(Playlist, 'playlist'), + display: crudHandlerFor(Display, 'display'), +} + +export function isMethod(value: string): value is Table { + return (value in []) +} + +export const handler = (req: Request, ctx: FreshContext): Response => { + const table = ctx.params.table + req.method + if (isTable(table)) { + console.log({ table }) + return new Response('yo') + } else { + return new Response( + JSON.stringify({ message: `invalid table: ${ctx.params.table}` }), + { status: 401 }, + ) + } +}