import type { InferInput, InferMetadata, InferOutput, MetadataAction, ObjectSchema, } from "valibot"; export type Db< // eslint-disable-next-line @typescript-eslint/no-explicit-any Schema extends Record>, R extends Relations = Relations, F extends Flatten = Flatten, > = { [Table in keyof R]: Table extends keyof F & keyof Schema & string ? { delete(where: { [K in keyof Schema[Table]["entries"]]?: | InferOutput | InferOutput[]; }): void; select< W extends Partial> & { where?: { [K in keyof Schema[Table]["entries"]]?: | InferOutput | InferOutput[]; }; }, >( props?: W, ): Select[]; update(query: { set: Partial>; where: { [K in keyof Schema[Table]["entries"]]?: | InferOutput | InferOutput[]; }; }): void; upsert( ...values: InferInput[] ): InferOutput[]; } : never; }; export type Flatten< // eslint-disable-next-line @typescript-eslint/no-explicit-any Schema extends Record>, R extends Relations = Relations, > = { [Self in keyof R]: Self extends string ? UnionToIntersection< { [Own in keyof R[Self]]: Own extends string ? { [Other in keyof R[Self][Own]]: Other extends string ? R[Self][Own][Other] extends Record ? { [ Its in keyof R[Self][Own][Other] as R[Self][Own][Other][Its]["name"] ]: Its extends string ? R[Self][Own][Other][Its] : never; } : never : never; }[keyof R[Self][Own]] : never; }[keyof R[Self]] > : never; }; export type Join = UnionToIntersection< { [Own in keyof Relations[Self]]: Own extends string ? { [Other in keyof Relations[Self][Own]]: Other extends keyof Relations ? { [Its in keyof Relations[Self][Own][Other]]: Its extends string ? Relations[Self][Own][Other] extends Record< string, { name: string } > ? { // Turning this into partial record would cause infinite depth. // eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style with: { [K in Relations[Self][Own][Other][Its]["name"]]?: Join | true; }; } : never : never; }[keyof Relations[Self][Own][Other]] : never; }[keyof Relations[Self][Own]] : never; }[keyof Relations[Self]] >; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type Relations>> = { [Self in keyof Schema]: Self extends string ? OmitExtendsRecordUndefined<{ [Own in keyof Schema[Self]["entries"]]: Own extends string ? OmitExtendsRecordUndefined<{ [Other in keyof Schema]: Other extends string ? OmitExtendsUndefined<{ [Its in keyof Schema[Other]["entries"]]: Its extends string ? InferMetadata extends { key: Schema[Other]["entries"][Its]; references: Schema[Other]; } ? Schema[Other] extends InferMetadata< Schema[Self]["entries"][Own] >["references"] ? Schema[Other]["entries"][Its] extends InferMetadata< Schema[Self]["entries"][Own] >["key"] ? { Its: Its; name: Rewrite; Other: Other; Own: Own; type: "references"; } : undefined : undefined : InferMetadata extends { key: Schema[Self]["entries"][Own]; references: Schema[Self]; } ? Schema[Self] extends InferMetadata< Schema[Other]["entries"][Its] >["references"] ? Schema[Self]["entries"][Own] extends InferMetadata< Schema[Other]["entries"][Its] >["key"] ? { Its: Its; name: Rewrite; Other: Other; Own: Own; type: "referencedBy"; } : undefined : undefined : undefined : undefined; }> : undefined; }> : undefined; }> : undefined; }; type OmitExtends = { [K in keyof T as T[K] extends U ? never : K]: T[K]; }; type OmitExtendsRecordUndefined = OmitExtends>; type OmitExtendsUndefined = OmitExtends; type Rewrite< Self extends string, Own extends string, Other extends string, Its extends string, > = // Image.id, Question.imageId -> Image.Question. Its extends `${Uncapitalize}${Capitalize}` ? Other : // Question.quizId, Quiz.id -> Question.Quiz. Own extends `${Uncapitalize}${Capitalize}` ? Other : // Quiz.coverId, Image.id -> Quiz.cover. Own extends `${infer R}${Capitalize}` ? R : // Image.id, Quiz.coverId -> Image.CoverQuiz. Its extends `${infer R}${Capitalize}` ? `${Capitalize}${Other}` : never; type Select< // eslint-disable-next-line @typescript-eslint/no-explicit-any Schema extends Record>, R extends Relations = Relations, F extends Flatten = Flatten, Table extends keyof F & keyof Schema = keyof F & keyof Schema, W extends Join = Join, // eslint-disable-next-line @typescript-eslint/no-explicit-any > = W extends { with: any } ? InferOutput & { [K in keyof W["with"]]: K extends keyof F[Table] ? F[Table][K] extends { Other: keyof F & keyof Schema; type: "referencedBy"; } ? // eslint-disable-next-line @typescript-eslint/no-explicit-any (W["with"][K] extends { with: any } ? Select : InferOutput)[] : F[Table][K] extends { Other: keyof F & keyof Schema; type: "references"; } ? | undefined // eslint-disable-next-line @typescript-eslint/no-explicit-any | (W["with"][K] extends { with: any } ? Select : InferOutput) : never : never; } : InferOutput; // https://www.geeksforgeeks.org/typescript/union-type-to-intersection-type-in-typescript/ type UnionToIntersection = ( U extends object ? (k: U) => void : never ) extends (k: infer I) => void ? I : never; export function flatten< Schema extends Record>, // eslint-disable-line @typescript-eslint/no-explicit-any >(relations: Relations): Flatten; export function primary(): MetadataAction; export function references< // eslint-disable-next-line @typescript-eslint/no-explicit-any R extends { entries: any }, K extends keyof R["entries"], T, >( references: R, key: K, ): MetadataAction; export function relations< Schema extends Record>, // eslint-disable-line @typescript-eslint/no-explicit-any >(schema: Schema): Relations;