46 lines
1.3 KiB
TypeScript
46 lines
1.3 KiB
TypeScript
import { Identifiable, Task, Todo, User } from '@homeman/models.ts'
|
|
import { z } from 'https://deno.land/x/zod@v3.21.4/mod.ts'
|
|
import { Created } from '@homeman/models.ts'
|
|
|
|
export const kv = await Deno.openKv('homeman.db')
|
|
|
|
export const schema = {
|
|
// key is table name, value is zod schema
|
|
user: User,
|
|
todo: Todo,
|
|
task: Task,
|
|
}
|
|
|
|
export type Schema = typeof schema
|
|
export type Table = keyof Schema
|
|
export type Model<T extends Table> = z.infer<Schema[T]>
|
|
|
|
export async function get<T extends Table>(
|
|
a: T,
|
|
id: z.infer<typeof Identifiable>['id'],
|
|
): Promise<Deno.KvEntryMaybe<Model<T>>> {
|
|
return await kv.get<Model<T>>([a, id])
|
|
}
|
|
|
|
export function all<T extends Table>(
|
|
a: T,
|
|
): Deno.KvListIterator<Model<T>> {
|
|
return kv.list<Model<T>>({ prefix: [a] })
|
|
}
|
|
|
|
type Create<T> = Omit<T, 'id' | 'createdAt'> | Partial<T>
|
|
|
|
export async function create<T extends Table, K extends typeof Identifiable>(
|
|
a: T,
|
|
payload: Create<K>,
|
|
): Promise<Deno.KvCommitResult> {
|
|
const data: Create<Model<T>> | undefined = schema[a].parse(payload)
|
|
// we want to create our own ID since this is `create` and not `update`
|
|
if (Identifiable.safeParse(data).success) {
|
|
delete data.id
|
|
}
|
|
if (Created.safeParse(data).success) {
|
|
delete data.createdBy
|
|
}
|
|
return await kv.set([a, payload.id], payload)
|
|
}
|