import { createId } from "../cuid";import type { CustomMigrationFn } from "../migration-engine/create";import type { Condition, ConditionBuilder } from "../query/condition-builder";import { validateSchema } from "./validate"; export type AnySchema = Schema<string, Record<string, AnyTable>>; export type AnyRelation = Relation; export interface AnyTable { names: NameVariants; ormName: string; columns: Record<string, AnyColumn>; relations: Record<string, AnyRelation>; foreignKeys: ForeignKey[]; policies: StoredTablePolicy[]; getUniqueConstraints: (level?: "table" | "column" | "all") => UniqueConstraint[]; getColumnByName: (name: string, type?: keyof NameVariants) => AnyColumn | undefined; getIdColumn: () => AnyColumn; clone: () => AnyTable;} export type AnyColumn = | Column<keyof TypeMap, unknown, unknown> | IdColumn<IdColumnType, unknown, unknown>; export type TableColumnName<T extends AnyTable> = Extract<keyof T["columns"], string>; export type TableColumnValues<T extends AnyTable> = { [K in keyof T["columns"]]: T["columns"][K]["$out"];}; type Simplify<T> = { [K in keyof T]: T[K];}; type TableColumnInputValues<T extends AnyTable> = { [K in keyof T["columns"]]: T["columns"][K]["$in"];}; type PickNotNullable<T> = { [P in keyof T as null extends T[P] ? never : P]: T[P];}; export type TableInsertValues<T extends AnyTable> = Simplify< { [K in keyof T["columns"]]?: T["columns"][K]["$in"]; } & PickNotNullable<TableColumnInputValues<T>>>; export type TableUpdateValues<T extends AnyTable> = { [K in keyof T["columns"]]?: T["columns"][K] extends IdColumn ? never : T["columns"][K]["$in"];}; type MaybePromise<T> = T | Promise<T>;export type TablePolicyCondition = Condition | boolean | void; export interface TableReadPolicyInput<TTable extends AnyTable, TContext> { readonly where: Condition | undefined; readonly context: TContext; readonly builder: ConditionBuilder<TTable["columns"]>;} export interface TableCreatePolicyInput<TTable extends AnyTable, TContext> { readonly values: TableInsertValues<TTable>; readonly context: TContext;} export interface TableUpdatePolicyInput<TTable extends AnyTable, TContext> { readonly where: Condition | undefined; readonly set: TableUpdateValues<TTable>; readonly create?: TableInsertValues<TTable>; readonly context: TContext; readonly builder: ConditionBuilder<TTable["columns"]>; readonly operation: "update" | "upsert";} export interface TableDeletePolicyInput<TTable extends AnyTable, TContext> { readonly where: Condition | undefined; readonly context: TContext; readonly builder: ConditionBuilder<TTable["columns"]>;} export type TableReadPolicyCallback<TTable extends AnyTable, TContext> = ( input: TableReadPolicyInput<TTable, TContext>) => MaybePromise<TablePolicyCondition>; export type TableCreatePolicyCallback<TTable extends AnyTable, TContext> = ( input: TableCreatePolicyInput<TTable, TContext>) => MaybePromise<void>; export type TableUpdatePolicyCallback<TTable extends AnyTable, TContext> = ( input: TableUpdatePolicyInput<TTable, TContext>) => MaybePromise<TablePolicyCondition>; export type TableDeletePolicyCallback<TTable extends AnyTable, TContext> = ( input: TableDeletePolicyInput<TTable, TContext>) => MaybePromise<TablePolicyCondition>; export interface TablePolicy< TTable extends AnyTable = AnyTable, TContext = unknown,> { readonly name?: string; onRead?: TableReadPolicyCallback<TTable, TContext>; onCreate?: TableCreatePolicyCallback<TTable, TContext>; onUpdate?: TableUpdatePolicyCallback<TTable, TContext>; onDelete?: TableDeletePolicyCallback<TTable, TContext>;} export interface StoredTablePolicy { readonly name?: string; onRead?: TableReadPolicyCallback<AnyTable, unknown>; onCreate?: TableCreatePolicyCallback<AnyTable, unknown>; onUpdate?: TableUpdatePolicyCallback<AnyTable, unknown>; onDelete?: TableDeletePolicyCallback<AnyTable, unknown>;} export type ForeignKeyAction = "RESTRICT" | "CASCADE" | "SET NULL"; export interface NameVariants { sql: string; drizzle: string; prisma: string; convex: string; mongodb: string;} export interface ForeignKey { name: string; table: AnyTable; columns: AnyColumn[]; referencedTable: AnyTable; referencedColumns: AnyColumn[]; onUpdate: ForeignKeyAction; onDelete: ForeignKeyAction;} class RelationInit< Type extends RelationType, Tables extends Record<string, AnyTable>, T extends keyof Tables,> { type: Type; referencedTable: Tables[T]; referencer: AnyTable; constructor(type: Type, referencedTable: Tables[T], referencer: AnyTable) { this.type = type; this.referencedTable = referencedTable; this.referencer = referencer; }} export class ImplicitRelationInit< Type extends RelationType, Tables extends Record<string, AnyTable>, T extends keyof Tables,> extends RelationInit<Type, Tables, T> { init(ormName: string, impliedBy: ExplicitRelation) { const output: ImplicitRelation<Type, Tables[T]> = { id: impliedBy.id, on: impliedBy.on.map(([left, right]) => [right, left]), type: this.type, table: this.referencedTable, implied: true, impliedBy, name: ormName, referencer: this.referencer, }; impliedBy.implying = output; return output; }} export interface UniqueConstraint { name: string; columns: AnyColumn[];} interface ForeignKeyConfig { name: string; onUpdate: ForeignKeyAction; onDelete: ForeignKeyAction;} export class ExplicitRelationInit< Type extends RelationType, Tables extends Record<string, AnyTable>, T extends keyof Tables,> extends RelationInit<Type, Tables, T> { private foreignKeyConfig?: Partial<ForeignKeyConfig>; implyingRelationName?: string; on: [string, string][] = []; imply(implyingRelationName: string) { this.implyingRelationName = implyingRelationName; return this; } private initForeignKey(ormName: string): ForeignKey | undefined { const config = this.foreignKeyConfig; if (!config) return; const columns: AnyColumn[] = []; const referencedColumns: AnyColumn[] = []; for (const [left, right] of this.on) { columns.push(this.referencer.columns[left]); referencedColumns.push(this.referencedTable.columns[right]); } return { columns, referencedColumns, referencedTable: this.referencedTable, table: this.referencer, name: config.name ?? `${this.referencer.ormName}_${this.referencedTable.ormName}_${ormName}_fk`, onDelete: config.onDelete ?? "RESTRICT", onUpdate: config.onUpdate ?? "RESTRICT", }; } init(ormName: string): ExplicitRelation<Type, Tables[T]> { let id = `${this.referencer.ormName}_${this.referencedTable.ormName}`; if (this.implyingRelationName) id += `_${this.implyingRelationName}`; return { id, implied: false, foreignKey: this.initForeignKey(ormName), implying: undefined, on: this.on, name: ormName, referencer: this.referencer, table: this.referencedTable, type: this.type, }; } /** * Define foreign key for explicit relation, please note that: * * - this constraint is ignored for MongoDB (without Prisma). * - you **must** define foreign key for explicit relations, due to the limitations of Prisma. */ foreignKey(config: Partial<ForeignKeyConfig> = {}) { this.foreignKeyConfig = config; return this; }} interface BaseRelation< Type extends RelationType = RelationType, T extends AnyTable = AnyTable,> { /** * The relation id shared between implied/implying relation */ id: string; name: string; type: Type; table: T; referencer: AnyTable; on: [string, string][];} export interface ImplicitRelation< Type extends RelationType = RelationType, T extends AnyTable = AnyTable,> extends BaseRelation<Type, T> { implied: true; readonly impliedBy: ExplicitRelation;} export interface ExplicitRelation< Type extends RelationType = RelationType, T extends AnyTable = AnyTable,> extends BaseRelation<Type, T> { implied: false; implying: ImplicitRelation | undefined; foreignKey?: ForeignKey;} export type Relation< Type extends RelationType = RelationType, T extends AnyTable = AnyTable,> = ImplicitRelation<Type, T> | ExplicitRelation<Type, T>; export interface Table< Columns extends Record<string, AnyColumn> = Record<string, AnyColumn>, Relations extends Record<string, AnyRelation> = Record<string, AnyRelation>,> { names: NameVariants; ormName: string; columns: Columns; relations: Relations; foreignKeys: ForeignKey[]; policies: StoredTablePolicy[]; /** * @param level default to 'all' */ getUniqueConstraints: ( level?: "table" | "column" | "all" ) => UniqueConstraint[]; /** * @param name - name * @param type - default to "sql" */ getColumnByName: ( name: string, type?: keyof NameVariants ) => AnyColumn | undefined; getIdColumn: () => AnyColumn; /** * Add unique constraint to the fields, for consistency, duplicated null values are allowed. */ unique(name: string, columns: (keyof Columns)[]): Table<Columns, Relations>; policy<TContext>(policy: TablePolicy<this, TContext>): this; clone: () => Table<Columns, Relations>;} type DefaultFunctionMap = { date: "now"; timestamp: "now"; string: "auto";} & Record<`varchar(${number})`, "auto">; type DefaultFunction<Type extends keyof TypeMap> = | (Type extends keyof DefaultFunctionMap ? DefaultFunctionMap[Type] : never) | (() => TypeMap[Type]); type IdColumnType = `varchar(${number})` | "uuid"; export type TypeMap = { string: string; bigint: bigint; integer: number; decimal: number; bool: boolean; json: unknown; /** * this follows the same specs as Prisma `Bytes` for consistency. */ binary: Uint8Array; date: Date; timestamp: Date; uuid: string;} & Record<`varchar(${number})`, string>; export class Column<Type extends keyof TypeMap, In = unknown, Out = unknown> { type: Type; ormName: string = ""; isNullable: boolean = false; isUnique: boolean = false; default?: | { value: TypeMap[Type] } | { runtime: DefaultFunction<Type>; }; table: AnyTable = undefined as unknown as AnyTable; private initNames: (ormName: string) => NameVariants; get names(): NameVariants { return this.initNames(this.ormName); } set names(v: NameVariants) { this.initNames = () => v; } constructor(type: Type, onInitNames: (ormName: string) => NameVariants) { this.type = type; this.initNames = onInitNames; } nullable<T extends boolean = true>(nullable?: T) { this.isNullable = nullable ?? true; return this as Column< Type, T extends true ? In | null : Exclude<In, null>, T extends true ? Out | null : Exclude<Out, null> >; } /** * Add unique constraint to the field, for consistency, duplicated null values are allowed. */ unique(unique: boolean = true) { this.isUnique = unique; return this; } /** * Generate default value on runtime */ defaultTo$(fn: DefaultFunction<Type>): Column<Type, In | null, Out> { this.default = { runtime: fn }; return this; } /** * Set a database-level default value * * For schemaless database, it's still generated on runtime */ defaultTo(value: TypeMap[Type]): Column<Type, In | null, Out> { this.default = { value }; return this; } clone() { const clone = new Column(this.type, () => this.names); clone.ormName = this.ormName; clone.isNullable = this.isNullable; clone.isUnique = this.isUnique; clone.default = this.default; clone.table = this.table; return clone; } getUniqueConstraintName(): string { return `unique_c_${this.table.ormName}_${this.ormName}`; } /** * Generate default value for the column on runtime. */ generateDefaultValue(): TypeMap[Type] | undefined { if (!this.default) return; if ("value" in this.default) return this.default.value; if (this.default.runtime === "auto") return createId() as TypeMap[Type]; if (this.default.runtime === "now") return new Date(Date.now()) as TypeMap[Type]; return this.default.runtime(); } get $in(): In { throw new Error("Type inference only"); } get $out(): Out { throw new Error("Type inference only"); }} export class IdColumn< Type extends IdColumnType = IdColumnType, In = unknown, Out = unknown,> extends Column<Type, In, Out> { id = true; constructor(type: Type, onInitNames: (ormName: string) => NameVariants) { super(type, (ormName) => ({ ...onInitNames(ormName), mongodb: "_id", })); } override clone() { const clone = new IdColumn(this.type, () => this.names); clone.ormName = this.ormName; clone.isNullable = this.isNullable; clone.isUnique = this.isUnique; clone.default = this.default; clone.table = this.table; return clone; } override defaultTo$(fn: DefaultFunction<Type>) { return super.defaultTo$(fn) as IdColumn<Type, In | null, Out>; } override defaultTo(value: TypeMap[Type]) { return super.defaultTo(value) as IdColumn<Type, In | null, Out>; }} export function column<Type extends keyof TypeMap>( name: string | Partial<NameVariants>, type: TypeLines 1–500 of 926. Load more
import { createId } from "../cuid"; import type { CustomMigrationFn } from "../migration-engine/create"; import type { Condition, ConditionBuilder } from "../query/condition-builder"; import { validateSchema } from "./validate"; export type AnySchema = Schema<string, Record<string, AnyTable>>; export type AnyRelation = Relation; export interface AnyTable { names: NameVariants; ormName: string; columns: Record<string, AnyColumn>; relations: Record<string, AnyRelation>; foreignKeys: ForeignKey[]; policies: StoredTablePolicy[]; getUniqueConstraints: (level?: "table" | "column" | "all") => UniqueConstraint[]; getColumnByName: (name: string, type?: keyof NameVariants) => AnyColumn | undefined; getIdColumn: () => AnyColumn; clone: () => AnyTable; } export type AnyColumn = | Column<keyof TypeMap, unknown, unknown> | IdColumn<IdColumnType, unknown, unknown>; export type TableColumnName<T extends AnyTable> = Extract<keyof T["columns"], string>; export type TableColumnValues<T extends AnyTable> = { [K in keyof T["columns"]]: T["columns"][K]["$out"]; }; type Simplify<T> = { [K in keyof T]: T[K]; }; type TableColumnInputValues<T extends AnyTable> = { [K in keyof T["columns"]]: T["columns"][K]["$in"]; }; type PickNotNullable<T> = { [P in keyof T as null extends T[P] ? never : P]: T[P]; }; export type TableInsertValues<T extends AnyTable> = Simplify< { [K in keyof T["columns"]]?: T["columns"][K]["$in"]; } & PickNotNullable<TableColumnInputValues<T>> >; export type TableUpdateValues<T extends AnyTable> = { [K in keyof T["columns"]]?: T["columns"][K] extends IdColumn ? never : T["columns"][K]["$in"]; }; type MaybePromise<T> = T | Promise<T>; export type TablePolicyCondition = Condition | boolean | void; export interface TableReadPolicyInput<TTable extends AnyTable, TContext> { readonly where: Condition | undefined; readonly context: TContext; readonly builder: ConditionBuilder<TTable["columns"]>; } export interface TableCreatePolicyInput<TTable extends AnyTable, TContext> { readonly values: TableInsertValues<TTable>; readonly context: TContext; } export interface TableUpdatePolicyInput<TTable extends AnyTable, TContext> { readonly where: Condition | undefined; readonly set: TableUpdateValues<TTable>; readonly create?: TableInsertValues<TTable>; readonly context: TContext; readonly builder: ConditionBuilder<TTable["columns"]>; readonly operation: "update" | "upsert"; } export interface TableDeletePolicyInput<TTable extends AnyTable, TContext> { readonly where: Condition | undefined; readonly context: TContext; readonly builder: ConditionBuilder<TTable["columns"]>; } export type TableReadPolicyCallback<TTable extends AnyTable, TContext> = ( input: TableReadPolicyInput<TTable, TContext> ) => MaybePromise<TablePolicyCondition>; export type TableCreatePolicyCallback<TTable extends AnyTable, TContext> = ( input: TableCreatePolicyInput<TTable, TContext> ) => MaybePromise<void>; export type TableUpdatePolicyCallback<TTable extends AnyTable, TContext> = ( input: TableUpdatePolicyInput<TTable, TContext> ) => MaybePromise<TablePolicyCondition>; export type TableDeletePolicyCallback<TTable extends AnyTable, TContext> = ( input: TableDeletePolicyInput<TTable, TContext> ) => MaybePromise<TablePolicyCondition>; export interface TablePolicy< TTable extends AnyTable = AnyTable, TContext = unknown, > { readonly name?: string; onRead?: TableReadPolicyCallback<TTable, TContext>; onCreate?: TableCreatePolicyCallback<TTable, TContext>; onUpdate?: TableUpdatePolicyCallback<TTable, TContext>; onDelete?: TableDeletePolicyCallback<TTable, TContext>; } export interface StoredTablePolicy { readonly name?: string; onRead?: TableReadPolicyCallback<AnyTable, unknown>; onCreate?: TableCreatePolicyCallback<AnyTable, unknown>; onUpdate?: TableUpdatePolicyCallback<AnyTable, unknown>; onDelete?: TableDeletePolicyCallback<AnyTable, unknown>; } export type ForeignKeyAction = "RESTRICT" | "CASCADE" | "SET NULL"; export interface NameVariants { sql: string; drizzle: string; prisma: string; convex: string; mongodb: string; } export interface ForeignKey { name: string; table: AnyTable; columns: AnyColumn[]; referencedTable: AnyTable; referencedColumns: AnyColumn[]; onUpdate: ForeignKeyAction; onDelete: ForeignKeyAction; } class RelationInit< Type extends RelationType, Tables extends Record<string, AnyTable>, T extends keyof Tables, > { type: Type; referencedTable: Tables[T]; referencer: AnyTable; constructor(type: Type, referencedTable: Tables[T], referencer: AnyTable) { this.type = type; this.referencedTable = referencedTable; this.referencer = referencer; } } export class ImplicitRelationInit< Type extends RelationType, Tables extends Record<string, AnyTable>, T extends keyof Tables, > extends RelationInit<Type, Tables, T> { init(ormName: string, impliedBy: ExplicitRelation) { const output: ImplicitRelation<Type, Tables[T]> = { id: impliedBy.id, on: impliedBy.on.map(([left, right]) => [right, left]), type: this.type, table: this.referencedTable, implied: true, impliedBy, name: ormName, referencer: this.referencer, }; impliedBy.implying = output; return output; } } export interface UniqueConstraint { name: string; columns: AnyColumn[]; } interface ForeignKeyConfig { name: string; onUpdate: ForeignKeyAction; onDelete: ForeignKeyAction; } export class ExplicitRelationInit< Type extends RelationType, Tables extends Record<string, AnyTable>, T extends keyof Tables, > extends RelationInit<Type, Tables, T> { private foreignKeyConfig?: Partial<ForeignKeyConfig>; implyingRelationName?: string; on: [string, string][] = []; imply(implyingRelationName: string) { this.implyingRelationName = implyingRelationName; return this; } private initForeignKey(ormName: string): ForeignKey | undefined { const config = this.foreignKeyConfig; if (!config) return; const columns: AnyColumn[] = []; const referencedColumns: AnyColumn[] = []; for (const [left, right] of this.on) { columns.push(this.referencer.columns[left]); referencedColumns.push(this.referencedTable.columns[right]); } return { columns, referencedColumns, referencedTable: this.referencedTable, table: this.referencer, name: config.name ?? `${this.referencer.ormName}_${this.referencedTable.ormName}_${ormName}_fk`, onDelete: config.onDelete ?? "RESTRICT", onUpdate: config.onUpdate ?? "RESTRICT", }; } init(ormName: string): ExplicitRelation<Type, Tables[T]> { let id = `${this.referencer.ormName}_${this.referencedTable.ormName}`; if (this.implyingRelationName) id += `_${this.implyingRelationName}`; return { id, implied: false, foreignKey: this.initForeignKey(ormName), implying: undefined, on: this.on, name: ormName, referencer: this.referencer, table: this.referencedTable, type: this.type, }; } /** * Define foreign key for explicit relation, please note that: * * - this constraint is ignored for MongoDB (without Prisma). * - you **must** define foreign key for explicit relations, due to the limitations of Prisma. */ foreignKey(config: Partial<ForeignKeyConfig> = {}) { this.foreignKeyConfig = config; return this; } } interface BaseRelation< Type extends RelationType = RelationType, T extends AnyTable = AnyTable, > { /** * The relation id shared between implied/implying relation */ id: string; name: string; type: Type; table: T; referencer: AnyTable; on: [string, string][]; } export interface ImplicitRelation< Type extends RelationType = RelationType, T extends AnyTable = AnyTable, > extends BaseRelation<Type, T> { implied: true; readonly impliedBy: ExplicitRelation; } export interface ExplicitRelation< Type extends RelationType = RelationType, T extends AnyTable = AnyTable, > extends BaseRelation<Type, T> { implied: false; implying: ImplicitRelation | undefined; foreignKey?: ForeignKey; } export type Relation< Type extends RelationType = RelationType, T extends AnyTable = AnyTable, > = ImplicitRelation<Type, T> | ExplicitRelation<Type, T>; export interface Table< Columns extends Record<string, AnyColumn> = Record<string, AnyColumn>, Relations extends Record<string, AnyRelation> = Record<string, AnyRelation>, > { names: NameVariants; ormName: string; columns: Columns; relations: Relations; foreignKeys: ForeignKey[]; policies: StoredTablePolicy[]; /** * @param level default to 'all' */ getUniqueConstraints: ( level?: "table" | "column" | "all" ) => UniqueConstraint[]; /** * @param name - name * @param type - default to "sql" */ getColumnByName: ( name: string, type?: keyof NameVariants ) => AnyColumn | undefined; getIdColumn: () => AnyColumn; /** * Add unique constraint to the fields, for consistency, duplicated null values are allowed. */ unique(name: string, columns: (keyof Columns)[]): Table<Columns, Relations>; policy<TContext>(policy: TablePolicy<this, TContext>): this; clone: () => Table<Columns, Relations>; } type DefaultFunctionMap = { date: "now"; timestamp: "now"; string: "auto"; } & Record<`varchar(${number})`, "auto">; type DefaultFunction<Type extends keyof TypeMap> = | (Type extends keyof DefaultFunctionMap ? DefaultFunctionMap[Type] : never) | (() => TypeMap[Type]); type IdColumnType = `varchar(${number})` | "uuid"; export type TypeMap = { string: string; bigint: bigint; integer: number; decimal: number; bool: boolean; json: unknown; /** * this follows the same specs as Prisma `Bytes` for consistency. */ binary: Uint8Array; date: Date; timestamp: Date; uuid: string; } & Record<`varchar(${number})`, string>; export class Column<Type extends keyof TypeMap, In = unknown, Out = unknown> { type: Type; ormName: string = ""; isNullable: boolean = false; isUnique: boolean = false; default?: | { value: TypeMap[Type] } | { runtime: DefaultFunction<Type>; }; table: AnyTable = undefined as unknown as AnyTable; private initNames: (ormName: string) => NameVariants; get names(): NameVariants { return this.initNames(this.ormName); } set names(v: NameVariants) { this.initNames = () => v; } constructor(type: Type, onInitNames: (ormName: string) => NameVariants) { this.type = type; this.initNames = onInitNames; } nullable<T extends boolean = true>(nullable?: T) { this.isNullable = nullable ?? true; return this as Column< Type, T extends true ? In | null : Exclude<In, null>, T extends true ? Out | null : Exclude<Out, null> >; } /** * Add unique constraint to the field, for consistency, duplicated null values are allowed. */ unique(unique: boolean = true) { this.isUnique = unique; return this; } /** * Generate default value on runtime */ defaultTo$(fn: DefaultFunction<Type>): Column<Type, In | null, Out> { this.default = { runtime: fn }; return this; } /** * Set a database-level default value * * For schemaless database, it's still generated on runtime */ defaultTo(value: TypeMap[Type]): Column<Type, In | null, Out> { this.default = { value }; return this; } clone() { const clone = new Column(this.type, () => this.names); clone.ormName = this.ormName; clone.isNullable = this.isNullable; clone.isUnique = this.isUnique; clone.default = this.default; clone.table = this.table; return clone; } getUniqueConstraintName(): string { return `unique_c_${this.table.ormName}_${this.ormName}`; } /** * Generate default value for the column on runtime. */ generateDefaultValue(): TypeMap[Type] | undefined { if (!this.default) return; if ("value" in this.default) return this.default.value; if (this.default.runtime === "auto") return createId() as TypeMap[Type]; if (this.default.runtime === "now") return new Date(Date.now()) as TypeMap[Type]; return this.default.runtime(); } get $in(): In { throw new Error("Type inference only"); } get $out(): Out { throw new Error("Type inference only"); } } export class IdColumn< Type extends IdColumnType = IdColumnType, In = unknown, Out = unknown, > extends Column<Type, In, Out> { id = true; constructor(type: Type, onInitNames: (ormName: string) => NameVariants) { super(type, (ormName) => ({ ...onInitNames(ormName), mongodb: "_id", })); } override clone() { const clone = new IdColumn(this.type, () => this.names); clone.ormName = this.ormName; clone.isNullable = this.isNullable; clone.isUnique = this.isUnique; clone.default = this.default; clone.table = this.table; return clone; } override defaultTo$(fn: DefaultFunction<Type>) { return super.defaultTo$(fn) as IdColumn<Type, In | null, Out>; } override defaultTo(value: TypeMap[Type]) { return super.defaultTo(value) as IdColumn<Type, In | null, Out>; } } export function column<Type extends keyof TypeMap>( name: string | Partial<NameVariants>, type: Type