From 861c4a4035db616db743a13d869b1af3d47c1e3f Mon Sep 17 00:00:00 2001 From: Daniel Flanagan Date: Tue, 20 Feb 2024 13:29:29 -0600 Subject: [PATCH] WIP --- api.ts | 43 ++++++++++++++++++++++++++++++--------- db.ts | 7 ++++++- fresh.gen.ts | 2 ++ lyrics | Bin 0 -> 36864 bytes routes/api/db/[table].ts | 29 ++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 11 deletions(-) create mode 100644 lyrics create mode 100644 routes/api/db/[table].ts 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 0000000000000000000000000000000000000000..1f41350bda4017adcc126e2eea6b87199d8369f3 GIT binary patch literal 36864 zcmeI%J#W)M7{Kv!k|t?N`Z5%c+(6YvEr_b>z<@-73`i{!r2{M&C%&{+9J_VwG!;|Y z&&e0yBhZDjlZd!hJ1{}?w-Uv7=d`{`B$Cjg;&JVb6}_o>&!yf_N>Z5Tc;J zi~2h~lJnBEpnr{-^ZQN<;(6z1efg`XE**=N!Sau#<9d5}@6mpJYx(-VPShiS00Iag zfB*srAn^YPjJ_2s=GvNZvmMzjPjv^~LFw&r^WdZ@PY&K3Hf47pw`x*$Wy=d%@;r2V zc6cSb>S{;V4#u^95J^AwytK+vemihn|5Unuq)t^RGtDaOyMdo;tL@0Xy2w>aM|JGj zi{y(PsfOonXh*uY)$8AX<+I&}ymX_pAdX}hT)NKayj(FiH;tPoX^0oGij@_{zOToa zDO56nXPOcMN7;_&`YQM6By87_ks4}-84Aaa>^xA*Zg+!D$LhDwloNX@-%sQAEw^LE zzN0*MphD%`y^Vh2%v8v&>DYGkKpM5i%Szci+BAf#?=b9NczV-h*>M!4Wh)bzwVNqc zM@OZKX`06M)gP_&iiNyRx-z2tT>JwdQGY_wSSXvX%!et)1ZADIPm|0Yt&el!dOe>L zU#ewuf6e%wN_GcUW>H$MGwco)Cs6M{ylZ~e`IEm!>I6vgD$}_!dR(ZO8ym(bNFST5 z9!pPtk}k97#mqd+woDRrnsze_Bu&h}&Ai5_VpPoSZDZ6-2i9{>Cu!J^>`2`y7Ba)T z(>VSonGSH8E3-@a!I3uVdUlMJUqXL45I_I{1Q0*~0R#|0009ILKw$0!N}?!?;&}gm zD^_mjEq009ILKmY**5I_I{1Q0*~f%z9;|3Ck8 XOoRv^fB*srAb { + 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 }, + ) + } +}