UNPKG

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

751 lines (750 loc) 40.7 kB
import { z } from "zod"; export type DeepPartial<T> = T extends object ? { [P in keyof T]?: DeepPartial<T[P]>; } : T; type CurrentTimestampConfig = { default: "CURRENT_TIMESTAMP"; defaultValue: Date; }; export declare const isFunction: (fn: unknown) => fn is Function; export declare function currentTimeStamp(): CurrentTimestampConfig; type DbConfig = SQLType | RelationConfig<any> | null; export type SQLDialect = "sqlite" | "postgres" | "mysql"; type SQLTypeConfig = ({ type: "int"; nullable?: boolean; default?: number; } | { type: "real"; nullable?: boolean; default?: number; } | { type: "boolean"; nullable?: boolean; default?: boolean; } | { type: "date" | "datetime" | "timestamp"; nullable?: boolean; default?: "CURRENT_TIMESTAMP"; defaultValue?: string; } | { type: "date" | "datetime"; nullable?: boolean; default?: Date; } | { type: "varchar" | "char" | "text" | "longtext"; nullable?: boolean; length?: number; default?: string; } | { type: "enum"; values: readonly [string, ...string[]]; nullable?: boolean; default?: string; name?: string; }) & BaseConfig; export type SQLType = SQLTypeConfig & { dialect: SQLDialect; }; type SQLTypeInput = SQLTypeConfig; type WithDialect<T extends SQLTypeInput, TDialect extends SQLDialect> = SQLType & T & { dialect: TDialect; }; type BaseConfig = { nullable?: boolean; pk?: true; field?: string; sqlOnly?: true; }; type SQLToZodType<T extends SQLTypeInput, TDefault extends boolean> = T["pk"] extends true ? TDefault extends true ? z.ZodString : z.ZodNumber : T["nullable"] extends true ? T["type"] extends "varchar" | "char" | "text" | "longtext" ? z.ZodNullable<z.ZodString> : T["type"] extends "enum" ? T extends { values: infer TValues extends readonly [string, ...string[]]; } ? z.ZodNullable<z.ZodType<TValues[number]>> : never : T["type"] extends "int" | "real" ? z.ZodNullable<z.ZodNumber> : T["type"] extends "boolean" ? z.ZodNullable<z.ZodNumber> : T["type"] extends "date" | "datetime" | "timestamp" ? T extends { default: "CURRENT_TIMESTAMP"; } ? TDefault extends true ? never : z.ZodNullable<z.ZodDate> : z.ZodNullable<z.ZodDate> : never : T["type"] extends "varchar" | "char" | "text" | "longtext" ? z.ZodString : T["type"] extends "enum" ? T extends { values: infer TValues extends readonly [string, ...string[]]; } ? z.ZodType<TValues[number]> : never : T["type"] extends "int" | "real" ? z.ZodNumber : T["type"] extends "boolean" ? z.ZodNumber : T["type"] extends "date" | "datetime" | "timestamp" ? T extends { default: "CURRENT_TIMESTAMP"; } ? TDefault extends true ? never : z.ZodDate : z.ZodDate : never; type ZodTypeFromPrimitive<T> = T extends string ? z.ZodString : T extends number ? z.ZodNumber : T extends boolean ? z.ZodBoolean : T extends Date ? z.ZodDate : z.ZodAny; type CollapsedUnion<A extends z.ZodTypeAny, B extends z.ZodTypeAny> = A extends B ? (B extends A ? A : z.ZodUnion<[A, B]>) : z.ZodUnion<[A, B]>; export interface IBuilderMethods<T extends DbConfig, TSql extends z.ZodTypeAny, TInitialValue, TClient extends z.ZodTypeAny, TValidation extends z.ZodTypeAny> { client<const TValue, const TSchema extends z.ZodTypeAny>(options: { value: TValue | ((tools: { uuid: () => string; }) => TValue); schema: TSchema | ((base: ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>) => TSchema); clientPk?: boolean | ((val: any) => boolean); }): Prettify<Builder<"client", T, TSql, TValue extends () => infer R ? R : TValue, TSchema, CollapsedUnion<TSql, TSchema>>>; client<const TValue>(options: { value: TValue | ((tools: { uuid: () => string; }) => TValue); schema?: never; clientPk?: boolean | ((val: any) => boolean); }): Prettify<Builder<"client", T, TSql, TValue extends () => infer R ? R : TValue, ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>, CollapsedUnion<TSql, ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>>>>; client<const TSchema extends z.ZodTypeAny>(options: { value?: never; schema: TSchema; clientPk?: boolean | ((val: any) => boolean); }): Prettify<Builder<"client", T, TSql, z.infer<TSchema>, TSchema, CollapsedUnion<TSql, TSchema>>>; client<const TSchema extends z.ZodTypeAny>(options: { value?: never; schema: TSchema | ((tools: any) => TSchema); clientPk?: boolean | ((val: any) => boolean); }): Prettify<Builder<"client", T, TSql, z.infer<TSchema>, TSchema, CollapsedUnion<TSql, TSchema>>>; client<const TValue>(options: { value: TValue | ((tools: { uuid: () => string; }) => TValue); schema?: never; clientPk?: boolean | ((val: any) => boolean); }): Prettify<Builder<"client", T, TSql, TValue extends () => infer R ? R : TValue, ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>, CollapsedUnion<TSql, ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>>>>; client(options: { value?: never; schema: (tools: any) => z.ZodTypeAny; }): Prettify<Builder<"client", T, TSql, unknown, z.ZodTypeAny, z.ZodTypeAny>>; client<TClientNext extends z.ZodTypeAny>(schema: ((tools: { sql: TSql; }) => TClientNext) | TClientNext): Prettify<Builder<"client", T, TSql, z.infer<TClientNext>, TClientNext, CollapsedUnion<TSql, TClientNext>>>; clientCheck: <TClientNext extends z.ZodTypeAny>(schema: ((tools: { sql: TSql; client: TClient; clientCheck: z.ZodUnion<[TSql, TClient]>; }) => TClientNext) | TClientNext) => Prettify<Builder<"clientCheck", T, TSql, TInitialValue, TClient, z.ZodUnion<[TSql, TClientNext]>>>; reference: <TRefSchema extends { _tableName: string; }>(fieldGetter: () => any) => Builder<"sql", T & { references: typeof fieldGetter; }, TSql, TInitialValue, TClient, TValidation>; server: <TValidationNext extends z.ZodTypeAny>(schema: ((tools: { sql: TSql; client: TClient; clientCheck: z.ZodUnion<[TSql, TClient]>; }) => TValidationNext) | TValidationNext) => Prettify<Builder<"server", T, TSql, TInitialValue, TClient, TValidationNext>>; transform: (transforms: { toClient: (dbValue: z.infer<TSql>) => z.infer<TClient>; toDb: (clientValue: z.infer<TClient>) => z.infer<TSql>; }) => { config: Prettify<BuilderConfig<T, TSql, TInitialValue, TClient, TValidation>> & { transforms: typeof transforms; }; }; } type BaseRelationConfig<T extends Schema<any>> = { fromKey: string; toKey: () => any; schema: () => T; defaultCount?: number; }; export type RelationConfig<T extends Schema<any>> = (BaseRelationConfig<T> & { type: "hasMany"; }) | (BaseRelationConfig<T> & { type: "hasOne"; }) | (BaseRelationConfig<T> & { type: "belongsTo"; }) | (BaseRelationConfig<T> & { type: "manyToMany"; }); type Stage = "sql" | "relation" | "client" | "clientCheck" | "server" | "done"; type StageMethods = { sql: "client" | "clientCheck" | "server" | "transform" | "reference"; relation: "client" | "clientCheck" | "server" | "transform"; client: "clientCheck" | "server" | "transform"; clientCheck: "server" | "transform"; server: "transform"; done: never; }; type BuilderConfig<T extends DbConfig, TSql extends z.ZodTypeAny, TInitialValue, TClient extends z.ZodTypeAny, TValidation extends z.ZodTypeAny> = { sql: T; zodSqlSchema: TSql; initialValue: TInitialValue; zodClientSchema: TClient; zodClientCheckedSchema: TClient; zodValidationSchema: TValidation; clientTransform?: (schema: z.ZodTypeAny) => z.ZodTypeAny; validationTransform?: (schema: z.ZodTypeAny) => z.ZodTypeAny; }; export type Builder<TStage extends Stage, T extends DbConfig, TSql extends z.ZodTypeAny, TInitialValue, TClient extends z.ZodTypeAny, TValidation extends z.ZodTypeAny> = { config: { sql: T; zodSqlSchema: TSql; initialValue: TInitialValue; zodClientSchema: TClient; zodClientCheckedSchema: TValidation; zodValidationSchema: TValidation; }; } & Pick<IBuilderMethods<T, TSql, TInitialValue, TClient, TValidation>, StageMethods[TStage]>; type HasManyDefault = true | undefined | [] | { count: number; }; type HasOneDefault = true | undefined | null; export type Reference<TGetter extends () => any> = { __type: "reference"; getter: TGetter; }; interface ShapeAPI { client<const TValue, const TSchema extends z.ZodTypeAny>(options: { value: TValue | ((tools: { uuid: () => string; }) => TValue); schema: TSchema | ((base: ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>) => TSchema); clientPk?: boolean | ((val: any) => boolean); }): Builder<"client", null, z.ZodUndefined, TValue extends () => infer R ? R : TValue, TSchema, TSchema>; client<const TValue>(options: { value: TValue | ((tools: { uuid: () => string; }) => TValue); schema?: never; clientPk?: boolean | ((val: any) => boolean); }): Builder<"client", null, z.ZodUndefined, TValue extends () => infer R ? R : TValue, ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>, ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>>; client<const TSchema extends z.ZodTypeAny>(options: { value?: never; schema: TSchema; clientPk?: boolean | ((val: any) => boolean); }): Builder<"client", null, z.ZodUndefined, z.infer<TSchema>, TSchema, TSchema>; client<const TValue>(value: TValue | ((tools: { uuid: () => string; }) => TValue)): Builder<"client", null, z.ZodUndefined, TValue extends () => infer R ? R : TValue, ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>, ZodTypeFromPrimitive<TValue extends () => infer R ? R : TValue>>; sqlite: <const T extends SQLTypeInput>(sqlConfig: T) => Builder<"sql", WithDialect<T, "sqlite">, SQLToZodType<T, false>, z.infer<SQLToZodType<T, false>>, SQLToZodType<T, false>, SQLToZodType<T, false>>; postgres: <const T extends SQLTypeInput>(sqlConfig: T) => Builder<"sql", WithDialect<T, "postgres">, SQLToZodType<T, false>, z.infer<SQLToZodType<T, false>>, SQLToZodType<T, false>, SQLToZodType<T, false>>; mysql: <const T extends SQLTypeInput>(sqlConfig: T) => Builder<"sql", WithDialect<T, "mysql">, SQLToZodType<T, false>, z.infer<SQLToZodType<T, false>>, SQLToZodType<T, false>, SQLToZodType<T, false>>; reference: <TGetter extends () => any>(getter: TGetter) => Reference<TGetter>; hasMany: <T extends HasManyDefault>(config?: T) => PlaceholderRelation<"hasMany">; hasOne: (config?: HasOneDefault) => PlaceholderRelation<"hasOne">; manyToMany: (config?: { defaultCount?: number; defaultConfig?: HasManyDefault; }) => PlaceholderRelation<"manyToMany">; } export declare const s: ShapeAPI; export type EnrichedField<K extends string, V, TSchema extends ShapeSchema> = V & { __meta: { _key: K; _fieldType: V; }; __parentTableType: TSchema; }; export type EnrichFields<T extends ShapeSchema> = { [K in keyof T]: K extends "_tableName" ? T[K] : K extends string ? EnrichedField<K, T[K], T> : T[K]; }; export declare const SchemaWrapperBrand: unique symbol; export type RefinementError = { path: string[]; message: string; }; type RefineLayer = "client" | "clientCheck" | "server" | "sql" | "all"; type RefineEntry = { layers: RefineLayer[]; deps: string[] | null; check: (row: any) => RefinementError | RefinementError[] | undefined | null; }; type RefineHelper<T extends ShapeSchema> = { (layer: "clientCheck", check: (row: InferClientCheckedRow<T>) => RefinementError | RefinementError[] | undefined | null, deps?: string | string[]): RefineEntry; (layer: "client", check: (row: InferClientRow<T>) => RefinementError | RefinementError[] | undefined | null, deps?: string | string[]): RefineEntry; (layer: "server", check: (row: InferValidationRow<T>) => RefinementError | RefinementError[] | undefined | null, deps?: string | string[]): RefineEntry; (layer: "sql", check: (row: InferSqlRow<T>) => RefinementError | RefinementError[] | undefined | null, deps?: string | string[]): RefineEntry; (layer: "all", check: (row: InferClientRow<T>) => RefinementError | RefinementError[] | undefined | null, deps?: string | string[]): RefineEntry; (layer: RefineLayer[], check: (row: InferClientRow<T>) => RefinementError | RefinementError[] | undefined | null, deps?: string | string[]): RefineEntry; }; type PickPrimaryKeys<T extends ShapeSchema> = { [K in keyof T as T[K] extends { config: { sql: { pk: true; }; }; } ? K : never]: T[K]; }; type PickClientOnlyKeys<T extends ShapeSchema> = { [K in keyof T]: T[K] extends { config: { sql: null; }; } ? K : never; }[keyof T]; type PickDbFieldKeys<T extends ShapeSchema> = { [K in keyof T]: T[K] extends { config: { sql: infer TSql; }; } ? TSql extends null ? never : TSql extends { type: "hasMany" | "hasOne" | "belongsTo" | "manyToMany"; } ? never : K : never; }[keyof T]; type InferClientCheckedRow<T extends ShapeSchema> = Prettify<z.infer<z.ZodObject<Prettify<DeriveSchemaByKey<T, "zodClientCheckedSchema">>>>>; type InferClientRow<T extends ShapeSchema> = Prettify<z.infer<z.ZodObject<Prettify<DeriveSchemaByKey<T, "zodClientSchema">>>>>; type InferValidationRow<T extends ShapeSchema> = Prettify<z.infer<z.ZodObject<Prettify<DeriveSchemaByKey<T, "zodValidationSchema">>>>>; type InferSqlRow<T extends ShapeSchema> = Prettify<z.infer<z.ZodObject<Prettify<DeriveSchemaByKey<T, "zodSqlSchema">>>>>; type SchemaBuilder<T extends ShapeSchema> = Prettify<EnrichFields<T>> & { __primaryKeySQL?: string; __derives?: { forClient?: Record<string, (row: any) => any>; forDb?: Record<string, (row: any) => any>; }; __refines?: RefineEntry[]; primaryKeySQL: (definer: (pkFields: PickPrimaryKeys<T>) => string) => SchemaBuilder<T>; derive: (derivers: { forClient?: { [K in PickClientOnlyKeys<T>]?: (row: InferClientRow<T>) => any; }; forDb?: { [K in PickDbFieldKeys<T>]?: (row: InferClientRow<T>) => any; }; }) => SchemaBuilder<T>; refine: (fn: (r: RefineHelper<T>) => RefineEntry[]) => SchemaBuilder<T>; }; export declare function schema<T extends string, U extends ShapeSchema<T>>(schema: U): SchemaBuilder<U>; export type RelationType = "hasMany" | "hasOne" | "manyToMany"; type BaseSchemaField<T extends SQLType = SQLType> = { type: "field"; sql: T; zodDbSchema: z.ZodType<any>; zodClientCheckedSchema: z.ZodType<any>; defaultValue?: any; __fieldId?: string; toClient?: (dbValue: any) => any; toDb?: (clientValue: any) => any; }; type SchemaField<T extends SQLType = SQLType> = BaseSchemaField<T>; export type Schema<T extends Record<string, SchemaField | (() => Relation<any>)>> = { _tableName: string; __schemaId?: string; [key: string]: T[keyof T] | string | ((id: number) => string) | true | undefined; }; type ValidShapeField = ReturnType<typeof s.sqlite> | ReturnType<typeof s.postgres> | ReturnType<typeof s.mysql>; export type ShapeSchema<T extends string = string> = { _tableName: T; [SchemaWrapperBrand]?: true; [key: string]: string | ((id: number) => string) | ValidShapeField | true | undefined; }; type Relation<U extends Schema<any>> = { type: RelationType; fromKey: keyof U; toKey: () => SchemaField; schema: U; defaultCount?: number; }; export declare function createSchema<T extends { _tableName: string; [SchemaWrapperBrand]?: true; }, R extends Record<string, any> = {}, TActualSchema extends Omit<T & R, typeof SchemaWrapperBrand> = Omit<T & R, typeof SchemaWrapperBrand>>(schema: T, relations?: R): { pk: string[] | null; clientPk: string[] | null; deriveDependencies: Record<string, string[]>; refineInfo: { groups: RefineEntry[]; fieldToGroup: Record<string, number[]>; }; isClientRecord: (record: any) => boolean; sqlSchema: z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodSqlSchema">>>; clientSchema: z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodClientSchema">>>; clientCheckedSchema: z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodClientCheckedSchema">>>; serverSchema: z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodValidationSchema">>>; validators: { sql: z.ZodTypeAny; client: z.ZodTypeAny; clientChecked: z.ZodTypeAny; server: z.ZodTypeAny; }; defaultValues: Prettify<DeriveDefaults<TActualSchema>>; stateType: Prettify<DeriveStateType<TActualSchema>>; generateDefaults: () => Prettify<DeriveDefaults<TActualSchema>>; toClient: (dbObject: Partial<z.infer<z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodSqlSchema">>>>>) => z.infer<z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodClientCheckedSchema">>>>; toDb: (clientObject: Partial<z.infer<z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodClientCheckedSchema">>>>>) => z.infer<z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodSqlSchema">>>>; parseForDb: (appData: z.input<z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodValidationSchema">>>>) => z.infer<z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodSqlSchema">>>>; parsePatchForDb: (patchData: Partial<z.input<z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodValidationSchema">>>>>) => Partial<z.infer<z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodSqlSchema">>>>>; parseFromDb: (dbData: Partial<z.infer<z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodSqlSchema">>>>>) => z.infer<z.ZodObject<Prettify<DeriveSchemaByKey<TActualSchema, "zodClientCheckedSchema">>>>; }; export type PlaceholderReference = { __type: "placeholder-reference"; }; export type PlaceholderRelation<T extends RelationType> = { __type: "placeholder-relation"; relationType: T; defaultCount?: number; defaultConfig?: HasManyDefault | HasOneDefault; }; type SchemaWithPlaceholders = { _tableName: string; [key: string]: any | PlaceholderReference | PlaceholderRelation<any>; }; type KnownKeys<T> = keyof { [K in keyof T as string extends K ? never : K]: T[K]; }; type ResolutionMap<S extends Record<string, SchemaWithPlaceholders>> = { [TableName in keyof S]?: { [FieldName in keyof S[TableName] as S[TableName][FieldName] extends PlaceholderReference | PlaceholderRelation<any> ? FieldName : never]?: S[TableName][FieldName] extends PlaceholderRelation<any> ? { fromKey: KnownKeys<S[TableName]>; toKey: { __meta: any; __parentTableType: any; }; defaultCount?: number; } : S[TableName][FieldName] extends PlaceholderReference ? { __meta: any; __parentTableType: any; } : never; }; }; type ResolveField<Field, Resolution> = Field extends PlaceholderReference ? Resolution : Field extends Reference<any> ? Resolution : Field extends PlaceholderRelation<infer RelType> ? Resolution extends { toKey: infer ToKey; } ? ToKey extends { __parentTableType: infer TargetSchema extends Schema<any>; } ? Builder<"relation", RelType extends "hasMany" ? BaseRelationConfig<TargetSchema> & { type: "hasMany"; } : RelType extends "hasOne" ? BaseRelationConfig<TargetSchema> & { type: "hasOne"; } : RelType extends "belongsTo" ? BaseRelationConfig<TargetSchema> & { type: "belongsTo"; } : RelType extends "manyToMany" ? BaseRelationConfig<TargetSchema> & { type: "manyToMany"; } : never, RelType extends "hasMany" | "manyToMany" ? z.ZodArray<z.ZodObject<any>> : z.ZodObject<any>, RelType extends "hasMany" | "manyToMany" ? any[] : any, RelType extends "hasMany" | "manyToMany" ? z.ZodArray<z.ZodObject<any>> : z.ZodObject<any>, RelType extends "hasMany" | "manyToMany" ? z.ZodArray<z.ZodObject<any>> : z.ZodObject<any>> : never : never : Field; type ResolveSchema<Schema extends SchemaWithPlaceholders, Resolutions extends Record<string, any>> = { [K in keyof Schema]: K extends keyof Resolutions ? ResolveField<Schema[K], Resolutions[K]> : Schema[K]; }; type ResolvedRegistryWithSchemas<S extends Record<string, SchemaWithPlaceholders>, R extends ResolutionMap<S>> = { [K in keyof S]: { rawSchema: ResolveSchema<S[K], K extends keyof R ? (R[K] extends object ? R[K] : {}) : {}>; zodSchemas: { sqlSchema: z.ZodObject<Prettify<DeriveSchemaByKey<ResolveSchema<S[K], K extends keyof R ? (R[K] extends object ? R[K] : {}) : {}>, "zodSqlSchema">>>; clientSchema: z.ZodObject<Prettify<DeriveSchemaByKey<ResolveSchema<S[K], K extends keyof R ? (R[K] extends object ? R[K] : {}) : {}>, "zodClientSchema">>>; clientCheckedSchema: z.ZodObject<Prettify<DeriveSchemaByKey<ResolveSchema<S[K], K extends keyof R ? (R[K] extends object ? R[K] : {}) : {}>, "zodClientCheckedSchema">>>; serverSchema: z.ZodObject<Prettify<DeriveSchemaByKey<ResolveSchema<S[K], K extends keyof R ? (R[K] extends object ? R[K] : {}) : {}>, "zodValidationSchema">>>; validators: { sql: z.ZodTypeAny; client: z.ZodTypeAny; clientChecked: z.ZodTypeAny; server: z.ZodTypeAny; }; defaultValues: Prettify<DeriveDefaults<ResolveSchema<S[K], K extends keyof R ? (R[K] extends object ? R[K] : {}) : {}>>>; stateType: Prettify<DeriveStateType<ResolveSchema<S[K], K extends keyof R ? (R[K] extends object ? R[K] : {}) : {}>>>; }; transforms: { toClient: (dbObject: any) => any; toDb: (clientObject: any) => any; parseForDb: (appData: any) => any; parsePatchForDb: (patchData: any) => any; parseFromDb: (dbData: any) => any; }; pk: string[] | null; clientPk: string[] | null; refineInfo: { groups: RefineEntry[]; fieldToGroup: Record<string, number[]>; }; isClientRecord: (record: any) => boolean; generateDefaults: () => Prettify<DeriveDefaults<ResolveSchema<S[K], K extends keyof R ? (R[K] extends object ? R[K] : {}) : {}>>>; }; }; type IsRelationField<Field> = Field extends { config: { sql: { type: "hasMany" | "hasOne" | "belongsTo" | "manyToMany"; schema: () => any; }; }; } ? true : false; type GetRelationRegistryKey<Field, TRegistry extends RegistryShape> = Field extends { config: { sql: { schema: () => infer S; }; }; } ? S extends { _tableName: infer T; } ? { [K in keyof TRegistry]: TRegistry[K]["rawSchema"]["_tableName"] extends T ? K : never; }[keyof TRegistry] : never : never; type OmitRelationFields<Shape, RawSchema> = Omit<Shape, { [K in keyof Shape]: K extends keyof RawSchema ? IsRelationField<RawSchema[K]> extends true ? K : never : never; }[keyof Shape]>; type _DeriveViewShape<TTableName extends keyof TRegistry, TSelection, TRegistry extends RegistryShape, TKey extends "clientSchema" | "clientCheckedSchema" | "serverSchema" | "sqlSchema", Depth extends any[] = []> = Depth["length"] extends 10 ? any : TKey extends "sqlSchema" ? TRegistry[TTableName]["zodSchemas"]["sqlSchema"] extends z.ZodObject<infer BaseShape> ? _DeriveViewShapeInner<BaseShape, TTableName, TSelection, TRegistry, TKey, Depth> : never : TRegistry[TTableName]["zodSchemas"][TKey] extends z.ZodObject<infer BaseShape> ? _DeriveViewShapeInner<BaseShape, TTableName, TSelection, TRegistry, TKey, Depth> : never; type _DeriveViewShapeInner<BaseShape, TTableName extends keyof TRegistry, TSelection, TRegistry extends RegistryShape, TKey extends "clientSchema" | "clientCheckedSchema" | "serverSchema" | "sqlSchema", Depth extends any[] = []> = TSelection extends Record<string, any> ? Prettify<OmitRelationFields<BaseShape, TRegistry[TTableName]["rawSchema"]> & { [K in keyof TSelection & keyof TRegistry[TTableName]["rawSchema"] as IsRelationField<TRegistry[TTableName]["rawSchema"][K]> extends true ? K : never]: GetRelationRegistryKey<TRegistry[TTableName]["rawSchema"][K], TRegistry> extends infer TargetKey ? TargetKey extends keyof TRegistry ? TRegistry[TTableName]["rawSchema"][K] extends { config: { sql: { type: infer RelType; }; }; } ? RelType extends "hasMany" | "manyToMany" ? z.ZodArray<z.ZodObject<_DeriveViewShape<TargetKey, TSelection[K], TRegistry, TKey, [ ...Depth, 1 ]>>> : z.ZodNullable<z.ZodObject<_DeriveViewShape<TargetKey, TSelection[K], TRegistry, TKey, [ ...Depth, 1 ]>>> : never : never : never; }> : OmitRelationFields<BaseShape, TRegistry[TTableName]["rawSchema"]>; type DeriveViewDefaults<TTableName extends keyof TRegistry, TSelection, TRegistry extends RegistryShape, Depth extends any[] = []> = Prettify<TRegistry[TTableName]["zodSchemas"]["defaultValues"] & (TSelection extends Record<string, any> ? { [K in keyof TSelection & keyof TRegistry[TTableName]["rawSchema"] as IsRelationField<TRegistry[TTableName]["rawSchema"][K]> extends true ? K : never]: TRegistry[TTableName]["rawSchema"][K] extends { config: { sql: { type: infer RelType; schema: any; }; }; } ? GetRelationRegistryKey<TRegistry[TTableName]["rawSchema"][K], TRegistry> extends infer TargetKey ? TargetKey extends keyof TRegistry ? RelType extends "hasMany" | "manyToMany" ? DeriveViewDefaults<TargetKey, TSelection[K], TRegistry, [ ...Depth, 1 ]>[] : DeriveViewDefaults<TargetKey, TSelection[K], TRegistry, [ ...Depth, 1 ]> | null : never : never : never; } : {})>; export type DeriveViewDefaultsDefinition<TTableName extends keyof TRegistry, TSelection, TRegistry extends RegistryShape, Depth extends any[] = []> = Depth["length"] extends 10 ? any : Prettify<TRegistry[TTableName]["zodSchemas"]["defaultValues"] & { [K in keyof TRegistry[TTableName]["rawSchema"] as IsRelationField<TRegistry[TTableName]["rawSchema"][K]> extends true ? K : never]: TRegistry[TTableName]["rawSchema"][K] extends { config: { sql: { type: infer RelType; schema: any; }; }; } ? GetRelationRegistryKey<TRegistry[TTableName]["rawSchema"][K], TRegistry> extends infer TargetKey ? TargetKey extends keyof TRegistry ? K extends keyof TSelection ? TSelection[K] extends true ? RelType extends "hasMany" | "manyToMany" ? TRegistry[TargetKey]["zodSchemas"]["defaultValues"][] : TRegistry[TargetKey]["zodSchemas"]["defaultValues"] | null : TSelection[K] extends false | undefined ? RelType extends "hasMany" | "manyToMany" ? TRegistry[TargetKey]["zodSchemas"]["defaultValues"][] : TRegistry[TargetKey]["zodSchemas"]["defaultValues"] | null : RelType extends "hasMany" | "manyToMany" ? DeriveViewDefaultsDefinition<TargetKey, TSelection[K], TRegistry, [ ...Depth, 1 ]>[] : DeriveViewDefaultsDefinition<TargetKey, TSelection[K], TRegistry, [ ...Depth, 1 ]> | null : RelType extends "hasMany" | "manyToMany" ? TRegistry[TargetKey]["zodSchemas"]["defaultValues"][] : TRegistry[TargetKey]["zodSchemas"]["defaultValues"] | null : never : never : never; } & { [K in keyof TRegistry[TTableName]["rawSchema"] as IsRelationField<TRegistry[TTableName]["rawSchema"][K]> extends true ? `__def__${K & string}` : never]: TRegistry[TTableName]["rawSchema"][K] extends { config: { sql: { type: any; schema: any; }; }; } ? GetRelationRegistryKey<TRegistry[TTableName]["rawSchema"][K], TRegistry> extends infer TargetKey ? TargetKey extends keyof TRegistry ? K extends keyof TSelection ? TSelection[K] extends true ? TRegistry[TargetKey]["zodSchemas"]["defaultValues"] : TSelection[K] extends false | undefined ? TRegistry[TargetKey]["zodSchemas"]["defaultValues"] : DeriveViewDefaultsDefinition<TargetKey, TSelection[K], TRegistry, [ ...Depth, 1 ]> : TRegistry[TargetKey]["zodSchemas"]["defaultValues"] : never : never : never; }>; export type DeriveViewResult<TTableName extends keyof TRegistry, TSelection, TRegistry extends RegistryShape> = { definition: TRegistry[TTableName]["rawSchema"]; schemaKey: TTableName; schemas: { sql: TRegistry[TTableName]["zodSchemas"]["sqlSchema"]; client: z.ZodObject<_DeriveViewShape<TTableName, TSelection, TRegistry, "clientSchema">>; clientChecked: z.ZodObject<_DeriveViewShape<TTableName, TSelection, TRegistry, "clientCheckedSchema">>; server: z.ZodObject<_DeriveViewShape<TTableName, TSelection, TRegistry, "serverSchema">>; }; validators: { sql: TRegistry[TTableName]["zodSchemas"]["validators"]["sql"]; client: TRegistry[TTableName]["zodSchemas"]["validators"]["client"]; clientChecked: TRegistry[TTableName]["zodSchemas"]["validators"]["clientChecked"]; server: TRegistry[TTableName]["zodSchemas"]["validators"]["server"]; }; transforms: { toClient: TRegistry[TTableName]["transforms"]["toClient"]; toDb: TRegistry[TTableName]["transforms"]["toDb"]; parseForDb: (appData: z.input<z.ZodObject<_DeriveViewShape<TTableName, TSelection, TRegistry, "serverSchema">>>) => z.infer<z.ZodObject<_DeriveViewShape<TTableName, TSelection, TRegistry, "sqlSchema">>>; parsePatchForDb: (patchData: Partial<z.input<z.ZodObject<_DeriveViewShape<TTableName, TSelection, TRegistry, "serverSchema">>>>) => Partial<z.infer<z.ZodObject<_DeriveViewShape<TTableName, TSelection, TRegistry, "sqlSchema">>>>; parseFromDb: (dbData: Partial<z.infer<z.ZodObject<_DeriveViewShape<TTableName, TSelection, TRegistry, "sqlSchema">>>>) => z.infer<z.ZodObject<_DeriveViewShape<TTableName, TSelection, TRegistry, "clientSchema">>>; }; reconcile: (clientData: z.infer<z.ZodObject<_DeriveViewShape<TTableName, TSelection, TRegistry, "clientSchema">>> | z.infer<z.ZodObject<_DeriveViewShape<TTableName, TSelection, TRegistry, "clientSchema">>>[]) => { withServer: (serverData: DeepPartial<z.infer<z.ZodObject<_DeriveViewShape<TTableName, TSelection, TRegistry, "sqlSchema">>>> | DeepPartial<z.infer<z.ZodObject<_DeriveViewShape<TTableName, TSelection, TRegistry, "sqlSchema">>>>[]) => z.infer<z.ZodObject<_DeriveViewShape<TTableName, TSelection, TRegistry, "clientSchema">>> | z.infer<z.ZodObject<_DeriveViewShape<TTableName, TSelection, TRegistry, "clientSchema">>>[]; }; defaults: () => DeriveViewDefaults<TTableName, TSelection, TRegistry>; defaultsDefinition: () => DeriveViewDefaultsDefinition<TTableName, TSelection, TRegistry>; pk: string[] | null; clientPk: string[] | null; supportsReconciliation: boolean; isView: true; viewSelection: TSelection; baseTable: TTableName; nav?: undefined; createView?: undefined; RelationSelection?: undefined; __registry: TRegistry; }; type RelationKeysOf<Cur extends string, Reg extends RegistryShape> = Cur extends keyof Reg ? { [K in keyof Reg[Cur]["rawSchema"]]: IsRelationField<Reg[Cur]["rawSchema"][K]> extends true ? K : never; }[keyof Reg[Cur]["rawSchema"]] : never; type NavigationProxy<CurrentTable extends string, Registry extends RegistryShape> = CurrentTable extends keyof Registry ? RelationKeysOf<CurrentTable, Registry> extends never ? never : { [K in RelationKeysOf<CurrentTable, Registry>]: GetRelationRegistryKey<Registry[CurrentTable]["rawSchema"][K], Registry> extends infer TargetKey ? TargetKey extends keyof Registry ? NavigationProxy<TargetKey & string, Registry> : never : never; } : never; type IsEffectivelyEmpty<T> = [T] extends [never] ? true : [keyof T] extends [never] ? true : string extends keyof T ? true : number extends keyof T ? true : symbol extends keyof T ? true : false; type NavigationToSelection<T> = IsEffectivelyEmpty<T> extends true ? never : { [K in keyof T]?: boolean | NavigationToSelection<T[K]>; }; export type OmitRelations<Shape, RawSchema> = Omit<Shape, { [K in keyof Shape]: K extends keyof RawSchema ? RawSchema[K] extends { config: { sql: { schema: any; }; }; } ? K : never : never; }[keyof Shape]>; type RegistryShape = Record<string, { rawSchema: any; zodSchemas: { sqlSchema: z.ZodObject<any>; clientSchema: z.ZodObject<any>; clientCheckedSchema: z.ZodObject<any>; serverSchema: z.ZodObject<any>; validators: { sql: z.ZodTypeAny; client: z.ZodTypeAny; clientChecked: z.ZodTypeAny; server: z.ZodTypeAny; }; defaultValues: any; stateType: any; deriveDependencies: Record<string, string[]>; refineInfo: { groups: RefineEntry[]; fieldToGroup: Record<string, number[]>; }; }; transforms: { toClient: (dbObject: any) => any; toDb: (clientObject: any) => any; parseForDb: (appData: any) => any; parsePatchForDb: (patchData: any) => any; parseFromDb: (dbData: any) => any; }; pk: string[] | null; clientPk: string[] | null; deriveDependencies: Record<string, string[]>; refineInfo: { groups: RefineEntry[]; fieldToGroup: Record<string, number[]>; }; isClientRecord: (record: any) => boolean; generateDefaults: () => any; }>; type CreateSchemaBoxReturn<S extends Record<string, SchemaWithPlaceholders>, R extends ResolutionMap<S>, Resolved extends Record<string, any> = ResolvedRegistryWithSchemas<S, R>> = { [K in keyof Resolved]: { definition: Resolved[K]["rawSchema"]; schemaKey: K; schemas: { sql: Resolved[K]["zodSchemas"]["sqlSchema"]; client: Resolved[K]["zodSchemas"]["clientSchema"]; clientChecked: Resolved[K]["zodSchemas"]["clientCheckedSchema"]; server: Resolved[K]["zodSchemas"]["serverSchema"]; }; validators: { sql: Resolved[K]["zodSchemas"]["validators"]["sql"]; client: Resolved[K]["zodSchemas"]["validators"]["client"]; clientChecked: Resolved[K]["zodSchemas"]["validators"]["clientChecked"]; server: Resolved[K]["zodSchemas"]["validators"]["server"]; }; transforms: { toClient: (dbData: z.infer<Resolved[K]["zodSchemas"]["sqlSchema"]>) => z.infer<Resolved[K]["zodSchemas"]["clientSchema"]>; toDb: (clientData: z.infer<Resolved[K]["zodSchemas"]["clientSchema"]>) => z.infer<Resolved[K]["zodSchemas"]["sqlSchema"]>; parseForDb: (appData: z.input<Resolved[K]["zodSchemas"]["serverSchema"]>) => z.infer<Resolved[K]["zodSchemas"]["sqlSchema"]>; parsePatchForDb: (patchData: Partial<z.input<Resolved[K]["zodSchemas"]["serverSchema"]>>) => Partial<z.infer<Resolved[K]["zodSchemas"]["sqlSchema"]>>; parseFromDb: (dbData: Partial<z.infer<Resolved[K]["zodSchemas"]["sqlSchema"]>>) => z.infer<Resolved[K]["zodSchemas"]["clientSchema"]>; }; defaults: Resolved[K]["zodSchemas"]["defaultValues"]; defaultsDefinition: DeriveViewDefaultsDefinition<K & string, {}, Resolved>; stateType: Resolved[K]["zodSchemas"]["stateType"]; generateDefaults: () => Resolved[K]["zodSchemas"]["defaultValues"]; pk: string[] | null; clientPk: string[] | null; deriveDependencies: Record<string, string[]>; refineInfo: { groups: RefineEntry[]; fieldToGroup: Record<string, number[]>; }; isClientRecord: (record: any) => boolean; nav: NavigationProxy<K & string, Resolved>; RelationSelection: NavigationToSelection<NavigationProxy<K & string, Resolved>>; createView: <const TSelection extends NavigationToSelection<NavigationProxy<K & string, Resolved>>>(selection: TSelection) => DeriveViewResult<K & string, TSelection, Resolved>; __registry: Resolved; }; }; export declare function createSchemaBox<S extends Record<string, SchemaWithPlaceholders>, R extends ResolutionMap<S>>(schemas: S, resolutions: R): CreateSchemaBoxReturn<S, R>; export declare function addViews<S extends Record<string, SchemaWithPlaceholders>, R extends ResolutionMap<S>, V extends Record<string, DeriveViewResult<any, any, any>>>(box: CreateSchemaBoxReturn<S, R>, views: V): Prettify<CreateSchemaBoxReturn<S, R> & { [K in keyof V]: V[K]; }>; type Prettify<T> = { [K in keyof T]: T[K]; } & {}; type GetDbKey<K, Field> = Field extends Reference<infer TGetter> ? ReturnType<TGetter> extends { config: { sql: { field: infer F extends string; }; }; } ? string extends F ? K : F : K : Field extends { config: { sql: { field: infer F extends string; }; }; } ? string extends F ? K : F : K; type DeriveSchemaByKey<T, Key extends "zodSqlSchema" | "zodClientSchema" | "zodClientCheckedSchema" | "zodValidationSchema", Depth extends any[] = []> = Depth["length"] extends 10 ? any : { [K in keyof T as K extends "_tableName" | typeof SchemaWrapperBrand | "__primaryKeySQL" | "primaryKeySQL" | "derive" | "__derives" | "refine" | "__refines" ? never : K extends keyof T ? T[K] extends { config: { sql: { sqlOnly: true; }; }; } ? Key extends "zodSqlSchema" ? GetDbKey<K, T[K]> : never : T[K] extends Reference<any> ? Key extends "zodSqlSchema" ? GetDbKey<K, T[K]> : K : T[K] extends { config: { sql: { type: "hasMany" | "manyToMany" | "hasOne" | "belongsTo"; }; }; } ? never : T[K] extends { config: { sql: null; }; } ? Key extends "zodSqlSchema" ? never : K : Key extends "zodSqlSchema" ? GetDbKey<K, T[K]> : K : never]: T[K] extends Reference<infer TGetter> ? ReturnType<TGetter> extends { config: { [P in Key]: infer ZodSchema extends z.ZodTypeAny; }; } ? ZodSchema : never : T[K] extends { config: { [P in Key]: infer ZodSchema extends z.ZodTypeAny; }; } ? ZodSchema : never; }; type DeriveDefaults<T, Depth extends any[] = []> = Prettify<Depth["length"] extends 10 ? any : { [K in keyof T as K extends "_tableName" | typeof SchemaWrapperBrand | "__primaryKeySQL" | "primaryKeySQL" | "derive" | "__derives" | "refine" | "__refines" ? never : K extends keyof T ? T[K] extends { config: { sql: { sqlOnly: true; }; }; } ? never : T[K] extends Reference<any> ? K : T[K] extends { config: { sql: { type: "hasMany" | "manyToMany" | "hasOne" | "belongsTo"; }; }; } ? never : K : never]: T[K] extends Reference<infer TGetter> ? ReturnType<TGetter> extends { config: { initialValue: infer D; }; } ? D extends () => infer R ? R : D : never : T[K] extends { config: { zodClientSchema: infer TClient extends z.ZodTypeAny; }; } ? z.infer<TClient> : never; }>; type DeriveStateType<T, Depth extends any[] = []> = Prettify<Depth["length"] extends 10 ? any : { [K in keyof T as K extends "_tableName" | typeof SchemaWrapperBrand | "__primaryKeySQL" | "primaryKeySQL" | "derive" | "__derives" | "refine" | "__refines" ? never : K extends keyof T ? T[K] extends { config: { sql: { sqlOnly: true; }; }; } ? never : T[K] extends Reference<any> ? K : T[K] extends { config: { sql: { type: "hasMany" | "manyToMany" | "hasOne" | "belongsTo"; }; }; } ? never : K : never]: T[K] extends Reference<infer TGetter> ? ReturnType<TGetter> extends { config: { zodClientSchema: infer TClient extends z.ZodTypeAny; }; } ? z.infer<TClient> : never : T[K] extends { config: { zodClientSchema: infer TClient extends z.ZodTypeAny; }; } ? z.infer<TClient> : never; }>; export {};