UNPKG

drizzle-typebox

Version:

Generate Typebox schemas from Drizzle ORM schemas

23 lines (22 loc) 2.65 kB
import type * as t from '@sinclair/typebox'; import type { Assume, Column, DrizzleTypeError, SelectedFieldsFlat, Simplify, Table, View } from 'drizzle-orm'; import type { GetTypeboxType, HandleColumn } from "./column.types.cjs"; import type { ColumnIsGeneratedAlwaysAs, GetSelection } from "./utils.cjs"; export interface Conditions { never: (column?: Column) => boolean; optional: (column: Column) => boolean; nullable: (column: Column) => boolean; } type BuildRefineField<T> = T extends t.TSchema ? ((schema: T) => t.TSchema) | t.TSchema : never; export type BuildRefine<TColumns extends Record<string, any>> = { [K in keyof TColumns as TColumns[K] extends Column | SelectedFieldsFlat<Column> | Table | View ? K : never]?: TColumns[K] extends Column ? BuildRefineField<GetTypeboxType<TColumns[K]>> : BuildRefine<GetSelection<TColumns[K]>>; }; type HandleRefinement<TType extends 'select' | 'insert' | 'update', TRefinement, TColumn extends Column> = TRefinement extends (schema: any) => t.TSchema ? (TColumn['_']['notNull'] extends true ? ReturnType<TRefinement> : t.TUnion<[ReturnType<TRefinement>, t.TNull]>) extends infer TSchema ? TType extends 'update' ? t.TOptional<Assume<TSchema, t.TSchema>> : TSchema : t.TSchema : TRefinement; type IsRefinementDefined<TRefinements extends Record<string | symbol | number, any> | undefined, TKey extends string | symbol | number> = TRefinements extends object ? TRefinements[TKey] extends t.TSchema | ((schema: any) => any) ? true : false : false; export type BuildSchema<TType extends 'select' | 'insert' | 'update', TColumns extends Record<string, any>, TRefinements extends Record<string, any> | undefined> = t.TObject<Simplify<{ [K in keyof TColumns as ColumnIsGeneratedAlwaysAs<TColumns[K]> extends true ? never : K]: TColumns[K] extends infer TColumn extends Column ? IsRefinementDefined<TRefinements, K> extends true ? Assume<HandleRefinement<TType, TRefinements[K & keyof TRefinements], TColumn>, t.TSchema> : HandleColumn<TType, TColumn> : TColumns[K] extends infer TObject extends SelectedFieldsFlat<Column> | Table | View ? BuildSchema<TType, GetSelection<TObject>, TRefinements extends object ? TRefinements[K & keyof TRefinements] : undefined> : t.TAny; }>>; export type NoUnknownKeys<TRefinement extends Record<string, any>, TCompare extends Record<string, any>> = { [K in keyof TRefinement]: K extends keyof TCompare ? TRefinement[K] extends t.TSchema ? TRefinement[K] : TRefinement[K] extends Record<string, t.TSchema> ? NoUnknownKeys<TRefinement[K], TCompare[K]> : TRefinement[K] : DrizzleTypeError<`Found unknown key in refinement: "${K & string}"`>; }; export {};