import { type SQL } from "drizzle-orm"; import type { AnyPgTable } from "drizzle-orm/pg-core"; import type { z } from "zod"; import type { DrizzleClient } from "./types.js"; /** * Options accepted by {@link createCrudService}. */ export interface CrudServiceOptions { /** Optional Zod schema run against inputs passed to `create`. */ insertSchema?: TInsertSchema; /** Optional Zod schema run against inputs passed to `update`. */ updateSchema?: TUpdateSchema; } /** * Options for list-style queries. */ export interface ListOptions { /** WHERE clause, typically composed with `and()`. */ where?: SQL; /** Max number of rows to return. */ limit?: number; /** Offset for pagination. */ offset?: number; /** * ORDER BY clauses. Accept a single clause or array. Consumers pass * `asc(table.column)` / `desc(table.column)` builders. */ orderBy?: SQL | SQL[]; /** * When the table has a `deletedAt` column, soft-deleted rows are filtered * out by default. Pass `true` to include them — useful for admin recycle * bins, audit reports, or background reconciliation jobs. */ includeDeleted?: boolean; } /** * Options for retrieve-style lookups by id. */ export interface RetrieveOptions { /** Include soft-deleted rows. Default: false. */ includeDeleted?: boolean; } /** * A generic CRUD service bound to a single Drizzle table. * * Generated methods: * - `list(db, opts)` — returns rows * - `count(db, where?)` — returns integer count * - `listAndCount(db, opts)` — returns `{ data, total }` * - `retrieve(db, id)` — returns row or `null` * - `create(db, data)` — inserts and returns the row * - `update(db, id, data)` — updates and returns the row (or `null` if missing); * automatically sets `updatedAt: new Date()` when the table has that column * - `delete(db, id)` — hard-deletes and returns `{ id }` or `null` * - `softDelete(db, id)` — sets `deletedAt: new Date()` when the column exists * - `restore(db, id)` — clears `deletedAt` when the column exists * * Consumers compose custom methods by spreading the result: * ```ts * const crud = createCrudService(peopleTable) * export const peopleService = { * ...crud, * async findByEmail(db: DrizzleClient, email: string) { ... }, * } * ``` */ export declare function createCrudService(table: TTable, options?: CrudServiceOptions): { table: TTable; list: (db: DrizzleClient, opts?: ListOptions) => Promise<({ [Key in keyof TTable["_"]["columns"] & string as Key]: TTable["_"]["columns"][Key]["_"]["notNull"] extends true ? TTable["_"]["columns"][Key]["_"]["data"] : TTable["_"]["columns"][Key]["_"]["data"] | null; } extends infer T ? { [K in keyof T]: T[K]; } : never)[]>; count: (db: DrizzleClient, where?: SQL, opts?: { includeDeleted?: boolean; }) => Promise; listAndCount: (db: DrizzleClient, opts?: ListOptions) => Promise<{ data: ({ [Key in keyof TTable["_"]["columns"] & string as Key]: TTable["_"]["columns"][Key]["_"]["notNull"] extends true ? TTable["_"]["columns"][Key]["_"]["data"] : TTable["_"]["columns"][Key]["_"]["data"] | null; } extends infer T ? { [K in keyof T]: T[K]; } : never)[]; total: number; }>; retrieve: (db: DrizzleClient, id: string, opts?: RetrieveOptions) => Promise<({ [Key in keyof TTable["_"]["columns"] & string as Key]: TTable["_"]["columns"][Key]["_"]["notNull"] extends true ? TTable["_"]["columns"][Key]["_"]["data"] : TTable["_"]["columns"][Key]["_"]["data"] | null; } extends infer T ? { [K in keyof T]: T[K]; } : never) | null>; create: (db: DrizzleClient, data: { [Key in keyof TTable["_"]["columns"] & string as import("drizzle-orm").RequiredKeyOnly]: TTable["_"]["columns"][Key]["_"]["notNull"] extends true ? TTable["_"]["columns"][Key]["_"]["data"] : TTable["_"]["columns"][Key]["_"]["data"] | null; } & { [Key_1 in keyof TTable["_"]["columns"] & string as import("drizzle-orm").OptionalKeyOnly]?: (TTable["_"]["columns"][Key_1]["_"]["notNull"] extends true ? TTable["_"]["columns"][Key_1]["_"]["data"] : TTable["_"]["columns"][Key_1]["_"]["data"] | null) | undefined; } extends infer T ? { [K in keyof T]: T[K]; } : never) => Promise<{ [Key_2 in keyof TTable["_"]["columns"] & string as Key_2]: TTable["_"]["columns"][Key_2]["_"]["notNull"] extends true ? TTable["_"]["columns"][Key_2]["_"]["data"] : TTable["_"]["columns"][Key_2]["_"]["data"] | null; } extends infer T_1 ? { [K_1 in keyof T_1]: T_1[K_1]; } : never>; update: (db: DrizzleClient, id: string, data: Partial<{ [Key in keyof TTable["_"]["columns"] & string as import("drizzle-orm").RequiredKeyOnly]: TTable["_"]["columns"][Key]["_"]["notNull"] extends true ? TTable["_"]["columns"][Key]["_"]["data"] : TTable["_"]["columns"][Key]["_"]["data"] | null; } & { [Key_1 in keyof TTable["_"]["columns"] & string as import("drizzle-orm").OptionalKeyOnly]?: (TTable["_"]["columns"][Key_1]["_"]["notNull"] extends true ? TTable["_"]["columns"][Key_1]["_"]["data"] : TTable["_"]["columns"][Key_1]["_"]["data"] | null) | undefined; } extends infer T ? { [K in keyof T]: T[K]; } : never>) => Promise<({ [Key_2 in keyof TTable["_"]["columns"] & string as Key_2]: TTable["_"]["columns"][Key_2]["_"]["notNull"] extends true ? TTable["_"]["columns"][Key_2]["_"]["data"] : TTable["_"]["columns"][Key_2]["_"]["data"] | null; } extends infer T_1 ? { [K_1 in keyof T_1]: T_1[K_1]; } : never) | null>; delete: (db: DrizzleClient, id: string) => Promise<{ id: string; } | null>; softDelete: (db: DrizzleClient, id: string) => Promise<({ [Key in keyof TTable["_"]["columns"] & string as Key]: TTable["_"]["columns"][Key]["_"]["notNull"] extends true ? TTable["_"]["columns"][Key]["_"]["data"] : TTable["_"]["columns"][Key]["_"]["data"] | null; } extends infer T ? { [K in keyof T]: T[K]; } : never) | null>; restore: (db: DrizzleClient, id: string) => Promise<({ [Key in keyof TTable["_"]["columns"] & string as Key]: TTable["_"]["columns"][Key]["_"]["notNull"] extends true ? TTable["_"]["columns"][Key]["_"]["data"] : TTable["_"]["columns"][Key]["_"]["data"] | null; } extends infer T ? { [K in keyof T]: T[K]; } : never) | null>; hasSoftDelete: boolean; }; //# sourceMappingURL=crud.d.ts.map