app-template/packages/dao/src/users.ts

66 lines
2.1 KiB
TypeScript

import { desc, eq, sql } from "drizzle-orm";
import { users } from "@app/models";
import { db } from "@app/db";
export type UserRow = typeof users.$inferSelect;
export interface ListUsersParams {
limit: number;
offset: number;
}
export const userDao = {
async list(params: ListUsersParams): Promise<{ rows: UserRow[]; total: number }> {
const rows = await db
.select()
.from(users)
.orderBy(desc(users.createdAt))
.limit(params.limit)
.offset(params.offset);
const [countRow] = await db.select({ count: sql<number>`count(*)` }).from(users);
return { rows, total: Number(countRow?.["count"] ?? 0) };
},
async getById(id: string): Promise<UserRow | null> {
const [row] = await db.select().from(users).where(eq(users.id, id)).limit(1);
return row ?? null;
},
async getByEmail(email: string): Promise<UserRow | null> {
const [row] = await db
.select()
.from(users)
.where(eq(users.email, email.toLowerCase()))
.limit(1);
return row ?? null;
},
async create(
data: Omit<UserRow, "id" | "createdAt" | "updatedAt"> & { id?: string },
): Promise<UserRow> {
const payload = { ...data, email: data.email.toLowerCase() };
const rows = await db.insert(users).values(payload).returning();
const row = rows[0];
if (!row) throw new Error("Failed to create user");
return row;
},
async update(
id: string,
data: Partial<Omit<UserRow, "id" | "createdAt" | "updatedAt">>,
): Promise<UserRow | null> {
const payload: Partial<Omit<UserRow, "id" | "createdAt" | "updatedAt">> = { ...data };
if (payload.email !== undefined) payload.email = payload.email.toLowerCase();
const [row] = await db
.update(users)
.set({ ...payload, updatedAt: new Date() })
.where(eq(users.id, id))
.returning();
return row ?? null;
},
async delete(id: string): Promise<void> {
await db.delete(users).where(eq(users.id, id));
},
};