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
TypeScript
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 {};