cogsbox-shape
Version:
A TypeScript library for creating type-safe database schemas with Zod validation, SQL type definitions, and automatic client/server transformations. Unifies client, server, and database types through a single schema definition, with built-in support for r
99 lines (98 loc) • 3.73 kB
TypeScript
import { Kysely } from "kysely";
import type { TableDBApi } from "./table-db.js";
type FirstArg<T> = T extends (arg: infer A, ...args: any[]) => any ? A : never;
type Return<T> = T extends (...args: any[]) => infer R ? R : never;
type Row<T> = T extends readonly (infer TItem)[] ? TItem : T;
type Prettify<T> = {
[K in keyof T]: T[K];
} & {};
type SchemaMetaKey = "_tableName" | "__primaryKeySQL" | "__derives" | "__refines" | "primaryKeySQL" | "derive" | "refine";
type SqlConfigOf<TField> = TField extends {
config: {
sql: infer TSql;
};
} ? TSql : TField extends {
__meta: {
_fieldType: infer TInner;
};
} ? SqlConfigOf<TInner> : never;
type SqlConfigBaseValue<TSql> = TSql extends {
type: "int" | "boolean";
} ? number : TSql extends {
type: "date" | "datetime" | "timestamp";
} ? Date : TSql extends {
type: "varchar" | "char" | "text" | "longtext" | "enum";
} ? string : unknown;
type SqlOnlyValue<TField> = SqlConfigOf<TField> extends infer TSql ? TSql extends {
nullable: true;
} ? SqlConfigBaseValue<TSql> | null : SqlConfigBaseValue<TSql> : unknown;
type IsSqlOnlyField<TField> = SqlConfigOf<TField> extends infer TSql ? TSql extends {
sqlOnly: true;
} ? true : false : false;
type IsOptionalSqlOnly<TField> = TField extends {
config: {
sql: {
nullable: true;
};
};
} ? true : TField extends {
config: {
sql: {
default: any;
};
};
} ? true : TField extends {
config: {
sql: {
defaultValue: any;
};
};
} ? true : false;
type IsDerivedDbField<TTable, TKey> = TTable extends {
rawSchema: {
__derives?: {
forDb?: infer TForDb;
};
};
} ? TKey extends keyof NonNullable<TForDb> ? true : false : false;
type SqlOnlyInput<T> = T extends {
definition: infer TDefinition;
} ? Prettify<{
[K in keyof TDefinition as IsSqlOnlyField<TDefinition[K]> extends true ? K extends SchemaMetaKey ? never : TDefinition[K] extends {
__type: "reference";
} ? never : IsDerivedDbField<T, K> extends true ? never : IsOptionalSqlOnly<TDefinition[K]> extends true ? never : K : never]: SqlOnlyValue<TDefinition[K]>;
} & {
[K in keyof TDefinition as IsSqlOnlyField<TDefinition[K]> extends true ? K extends SchemaMetaKey ? never : TDefinition[K] extends {
__type: "reference";
} ? never : IsOptionalSqlOnly<TDefinition[K]> extends true ? K : never : never]?: SqlOnlyValue<TDefinition[K]>;
}> : Record<string, never>;
type DbApiFor<T> = T extends {
transforms: {
parseForDb: (...args: any[]) => any;
parseFromDb: (...args: any[]) => any;
};
} ? TableDBApi<Row<Return<T["transforms"]["parseFromDb"]>>, Row<FirstArg<T["transforms"]["parseForDb"]>>, SqlOnlyInput<T>> : never;
type ConnectedView<T> = T extends {
transforms: {
parseForDb: (...args: any[]) => any;
parseFromDb: (...args: any[]) => any;
};
} ? Omit<T, keyof DbApiFor<T>> & DbApiFor<T> : T;
type ConnectedCreateView<T> = T extends {
createView: (...args: infer TArgs) => infer TView;
} ? {
createView: (...args: TArgs) => ConnectedView<TView>;
} : {};
type ConnectedTable<T> = T extends {
transforms: {
parseForDb: (...args: any[]) => any;
parseFromDb: (...args: any[]) => any;
};
} ? Omit<T, "createView" | keyof DbApiFor<T>> & DbApiFor<T> & ConnectedCreateView<T> : T;
type ConnectedBox<T extends Record<string, unknown>> = {
[K in keyof T]: ConnectedTable<T[K]>;
} & {
transaction: <R>(fn: (txBox: ConnectedBox<T>) => Promise<R>) => Promise<R>;
};
export declare function connect<T extends Record<string, unknown>>(box: T, db: Kysely<any>): ConnectedBox<T>;
export {};