Types
Type definitions for the repository package.
Core Types
Executor
Alias of AnyExecutor from @kysera/core: a raw Kysely instance, a
transaction, or a plugin-aware KyseraExecutor (a Kysely proxy carrying the
executor marker from @kysera/executor).
type Executor<DB> = AnyExecutor<DB>
// = Kysely<DB> | Transaction<DB> | (Kysely<DB> & KyseraExecutorMarker<DB>)
Repository
Full repository interface with all methods.
interface Repository<Entity, DB, PK = number> extends BaseRepository<DB, Entity, PK> {
readonly executor: Executor<DB>
readonly tableName: string
withTransaction(trx: Transaction<DB>): Repository<Entity, DB, PK>
}
interface BaseRepository<DB, Entity, PK = number> {
// Single operations
findById(id: PK): Promise<Entity | null>
create(input: unknown): Promise<Entity>
update(id: PK, input: unknown): Promise<Entity>
delete(id: PK): Promise<boolean>
// Batch operations
findByIds(ids: PK[]): Promise<Entity[]>
bulkCreate(inputs: unknown[]): Promise<Entity[]>
bulkUpdate(updates: Array<{ id: PK; data: unknown }>): Promise<Entity[]>
bulkDelete(ids: PK[]): Promise<number>
// Query operations (with operator support)
findAll(): Promise<Entity[]>
find<Cols extends keyof Entity = keyof Entity>(
options?: FindOptions<Entity, Cols>
): Promise<Pick<Entity, Cols>[] | Entity[]>
findOne<Cols extends keyof Entity = keyof Entity>(
options?: FindOptions<Entity, Cols>
): Promise<Pick<Entity, Cols> | Entity | null>
count(options?: { where?: WhereClause<Entity> | Record<string, unknown> }): Promise<number>
exists(options?: { where?: WhereClause<Entity> | Record<string, unknown> }): Promise<boolean>
findAndCount<Cols extends keyof Entity = keyof Entity>(
options?: FindOptions<Entity, Cols>
): Promise<{ items: Pick<Entity, Cols>[] | Entity[]; total: number }>
// Pagination (option/result shapes are inline — they are not exported types)
paginate(options: {
limit: number
offset?: number
orderBy?: string // Default: first primary-key column
orderDirection?: 'asc' | 'desc'
}): Promise<{ items: Entity[]; total: number; limit: number; offset: number }>
paginateCursor<K extends keyof Entity>(options: {
limit: number
cursor?: { value: Entity[K]; id: PK } | null
orderBy?: K // Default: first primary-key column
orderDirection?: 'asc' | 'desc'
}): Promise<{
items: Entity[]
nextCursor: { value: Entity[K]; id: PK } | null
hasMore: boolean
}>
// Transaction
transaction<R>(fn: (trx: Transaction<DB>) => Promise<R>): Promise<R>
}
Primary Key Types
// Single value
type PrimaryKeyValue = string | number
// Column configuration
type PrimaryKeyColumn = string | string[]
// Type hint
type PrimaryKeyTypeHint = 'number' | 'string' | 'uuid'
// Input type
type PrimaryKeyInput = PrimaryKeyValue | CompositeKeyValue
// Composite key
type CompositeKeyValue = Record<string, PrimaryKeyValue>
// Full configuration
interface PrimaryKeyConfig {
columns: PrimaryKeyColumn
type: PrimaryKeyTypeHint
}
Query Options
Filtering, sorting, and column selection use the exported FindOptions type
(and its companions SortSpec, WhereClause, and FindResult) — see
Query Operators for the
full operator reference:
interface FindOptions<Entity, Columns extends keyof Entity = keyof Entity> {
where?: WhereClause<Entity> | Record<string, unknown>
orderBy?: keyof Entity | string
orderDirection?: 'asc' | 'desc'
sort?: SortSpec<Entity>[]
select?: Columns[]
limit?: number
offset?: number
}
interface SortSpec<Entity> {
column: keyof Entity
direction: 'asc' | 'desc'
}
// Result of find(): Pick<Entity, Columns>[] when select is used, Entity[] otherwise
type FindResult<Entity, Columns extends keyof Entity> = [Columns] extends [keyof Entity]
? Pick<Entity, Columns>[]
: Entity[]
:::note Pagination shapes are not exported
There is no QueryOptions type, and names like PaginateOptions or
PaginatedItems are not importable from @kysera/repository. The
paginate() / paginateCursor() option and result shapes are declared inline
in the BaseRepository method signatures shown above.
:::
Type Utilities
Unwrap Generated
Remove Generated<> wrapper from types.
type Unwrap<T> = T extends Generated<infer U> ? U : T
Domain Type
Convert table type to domain type.
type DomainType<Table> = {
[K in keyof Table]: Unwrap<Table[K]>
}
Entity Type
Alias for Kysely's Selectable.
type EntityType<Table> = Selectable<Table>
Input Types
// Create input (omit generated fields)
type CreateInput<Table> = {
[K in keyof Table as Table[K] extends Generated<unknown> ? never : K]: Table[K]
}
// Update input (partial create)
type UpdateInput<Table> = Partial<CreateInput<Table>>
Table Utilities
// Type-safe table name
type TableName<DB> = keyof DB & string
// Extract table from database
type ExtractTable<DB, TN extends keyof DB> = DB[TN]
// Selectable row type
type SelectableRow<DB, TN extends keyof DB> = Selectable<ExtractTable<DB, TN>>
// Insertable row type
type InsertableRow<DB, TN extends keyof DB> = Insertable<ExtractTable<DB, TN>>
// Updateable row type
type UpdateableRow<DB, TN extends keyof DB> = Updateable<ExtractTable<DB, TN>>
// WHERE conditions
type WhereConditions<DB, TN extends keyof DB> = Partial<SelectableRow<DB, TN>>
Transaction Handler
type TransactionHandler<DB, R> = (trx: Transaction<DB>) => Promise<R>
Repository Bundle Helper
Extracts the repository bundle type from a createRepositoriesFactory result:
type RepositoriesFromFactory<T extends (...args: never[]) => unknown> = ReturnType<T>
// type Repositories = RepositoriesFromFactory<typeof createRepositories>
Helper Functions
normalizePrimaryKeyConfig
function normalizePrimaryKeyConfig(
primaryKey?: PrimaryKeyColumn,
primaryKeyType?: PrimaryKeyTypeHint
): PrimaryKeyConfig
isCompositeKey
function isCompositeKey(columns: PrimaryKeyColumn): columns is string[]
getPrimaryKeyColumns
function getPrimaryKeyColumns(columns: PrimaryKeyColumn): string[]
normalizePrimaryKeyInput
function normalizePrimaryKeyInput(
columns: PrimaryKeyColumn,
input: PrimaryKeyInput
): CompositeKeyValue
isValidRow
function isValidRow<T>(value: unknown): value is T
Plugin Types
interface Plugin {
readonly name: string
readonly version: string
readonly dependencies?: readonly string[]
readonly priority?: number
readonly conflictsWith?: readonly string[]
onInit?<DB>(db: Kysely<DB>): Promise<void> | void
onDestroy?(): Promise<void> | void
interceptQuery?<QB>(qb: QB, context: QueryBuilderContext): QB
extendRepository?<T extends object>(repo: T): T
}
interface QueryBuilderContext {
readonly operation: 'select' | 'insert' | 'update' | 'delete' | 'replace' | 'merge'
/** Base table name without schema qualifier or alias ('public.users as u' -> 'users') */
readonly table: string
/** Table alias when aliased ('users as u' -> 'u'). Plugins adding column conditions must qualify with alias ?? table */
readonly alias?: string
/** Original table expression as passed to the query method (e.g. 'public.users as u'); equals table for plain references */
readonly tableExpression?: string
/** Schema from withSchema(...) or an explicit qualifier in the table expression */
readonly schema?: string
readonly metadata: Record<string, unknown>
}
Usage Examples
Type-Safe Repository
interface UsersTable {
id: Generated<number>
email: string
name: string
created_at: Generated<Date>
}
interface Database {
users: UsersTable
}
type User = Selectable<UsersTable>
type CreateUser = CreateInput<UsersTable>
type UpdateUser = UpdateInput<UsersTable>
const userRepo: Repository<User, Database, number> = factory.create({
tableName: 'users',
mapRow: (row): User => row,
schemas: {
create: zodAdapter(z.object({ email: z.string().email(), name: z.string() })),
update: zodAdapter(z.object({ email: z.string().email(), name: z.string() }).partial())
}
})