Store phone/tablet/photo-frame shells with catalogs, append pages from extra images or PDFs, and reorder drafts with drag-and-drop. Co-authored-by: Cursor <cursoragent@cursor.com>
87 lines
2.3 KiB
TypeScript
87 lines
2.3 KiB
TypeScript
import { eq } from "drizzle-orm";
|
|
import type { EffectId, FrameId } from "../shared/types";
|
|
import { DEFAULT_FLIP_MS, DEFAULT_FRAME, isFrameId } from "../shared/types";
|
|
import type { DbBundle } from "./db";
|
|
import { catalogsTable } from "./schema";
|
|
|
|
export type CatalogRow = {
|
|
id: string;
|
|
deleteToken: string;
|
|
title: string;
|
|
effect: EffectId;
|
|
frame: FrameId;
|
|
pageCount: number;
|
|
flipMs: number;
|
|
createdAt: string;
|
|
};
|
|
|
|
export type CatalogInsert = Omit<CatalogRow, "createdAt" | "flipMs" | "frame"> & {
|
|
createdAt?: string;
|
|
flipMs?: number;
|
|
frame?: FrameId;
|
|
};
|
|
|
|
function toRow(record: typeof catalogsTable.$inferSelect): CatalogRow {
|
|
const frameRaw = record.frame ?? DEFAULT_FRAME;
|
|
return {
|
|
id: record.id,
|
|
deleteToken: record.deleteToken,
|
|
title: record.title,
|
|
effect: record.effect as EffectId,
|
|
frame: isFrameId(frameRaw) ? frameRaw : DEFAULT_FRAME,
|
|
pageCount: record.pageCount,
|
|
flipMs: record.flipMs ?? DEFAULT_FLIP_MS,
|
|
createdAt: record.createdAt,
|
|
};
|
|
}
|
|
|
|
export function createCatalogRepo(db: DbBundle) {
|
|
return {
|
|
create(input: CatalogInsert): CatalogRow {
|
|
const createdAt = input.createdAt ?? new Date().toISOString();
|
|
const flipMs = input.flipMs ?? DEFAULT_FLIP_MS;
|
|
const frame = input.frame ?? DEFAULT_FRAME;
|
|
db.drizzle.insert(catalogsTable).values({
|
|
id: input.id,
|
|
deleteToken: input.deleteToken,
|
|
title: input.title,
|
|
effect: input.effect,
|
|
pageCount: input.pageCount,
|
|
flipMs,
|
|
frame,
|
|
createdAt,
|
|
}).run();
|
|
db.persist();
|
|
return {
|
|
id: input.id,
|
|
deleteToken: input.deleteToken,
|
|
title: input.title,
|
|
effect: input.effect,
|
|
frame,
|
|
pageCount: input.pageCount,
|
|
flipMs,
|
|
createdAt,
|
|
};
|
|
},
|
|
|
|
getById(id: string): CatalogRow | null {
|
|
const row = db.drizzle
|
|
.select()
|
|
.from(catalogsTable)
|
|
.where(eq(catalogsTable.id, id))
|
|
.get();
|
|
return row ? toRow(row) : null;
|
|
},
|
|
|
|
deleteById(id: string): boolean {
|
|
const existing = this.getById(id);
|
|
if (!existing) return false;
|
|
db.drizzle.delete(catalogsTable).where(eq(catalogsTable.id, id)).run();
|
|
db.persist();
|
|
return true;
|
|
},
|
|
};
|
|
}
|
|
|
|
export type CatalogRepo = ReturnType<typeof createCatalogRepo>;
|