Files
template-showcase/src/entities/file/api/repository.ts
T

51 lines
1.7 KiB
TypeScript

import { and, eq } from 'drizzle-orm'
import type { drizzle } from 'drizzle-orm/postgres-js'
import { files, type FileRow } from '@/entities/file/model/schema'
/** The handle the shared `db()` returns (`@/shared/api`). */
type Db = ReturnType<typeof drizzle>
export type NewFile = Omit<FileRow, 'id' | 'createdAt'>
/**
* Attachment persistence. Writes name their author, as the notes repository does:
* a visitor removes only the files they attached.
*/
export function fileRepository(db: Db) {
return {
async create(input: NewFile): Promise<FileRow> {
const [row] = await db.insert(files).values(input).returning()
if (!row) throw new Error('the insert returned no row')
return row
},
async listByNote(noteId: string): Promise<FileRow[]> {
return db.select().from(files).where(eq(files.noteId, noteId))
},
/** The attachment, or `undefined` when `authorId` did not attach it. */
async get(id: string, authorId: string): Promise<FileRow | undefined> {
const [row] = await db
.select()
.from(files)
.where(and(eq(files.id, id), eq(files.authorId, authorId)))
.limit(1)
return row
},
/** Every attachment the visitor made, across their notes. */
async listByAuthor(authorId: string): Promise<FileRow[]> {
return db.select().from(files).where(eq(files.authorId, authorId))
},
/** The removed file, or `undefined` when `authorId` did not attach it. */
async remove(id: string, authorId: string): Promise<FileRow | undefined> {
const [row] = await db
.delete(files)
.where(and(eq(files.id, id), eq(files.authorId, authorId)))
.returning()
return row
},
}
}