This commit is contained in:
Daniel Flanagan 2024-02-20 13:29:29 -06:00
parent 3ddb34bee5
commit 861c4a4035
Signed by: lytedev
GPG key ID: 5B2020A0F9921EF4
5 changed files with 70 additions and 11 deletions

41
api.ts
View file

@ -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)))
}
},
}
}

7
db.ts
View file

@ -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<T[]> {
@ -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'),

View file

@ -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,

BIN
lyrics Normal file

Binary file not shown.

29
routes/api/db/[table].ts Normal file
View file

@ -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 },
)
}
}