tspace-mysql
Version:
Tspace MySQL is a promise-based ORM for Node.js, designed with modern TypeScript and providing type safety for schema databases.
168 lines (167 loc) • 14.1 kB
TypeScript
import { Model } from "../../core/Model";
import type { T } from "../../core";
import type { TConnection, TConnectionTransaction, TNestedBoolean, TRawStringQuery, TRelationKeys, TSchemaKeys } from "..";
import type { TColumnsDecorator, TRelationsDecorator } from "../decorator";
export type TRepositorySelect<T = unknown, R = unknown, M extends Model = Model> = [unknown, unknown] extends [T, R] ? keyof TColumnsDecorator<M> extends never ? TNestedBoolean : Partial<{
[K in keyof TColumnsDecorator<M> | keyof TRelationsDecorator<M>]: K extends `${string}.${string}` | TRawStringQuery ? boolean : K extends keyof TRelationsDecorator<M> ? M[K] extends (infer U)[] ? U extends Model ? "*" | TRepositorySelect<any, unknown, U> : boolean : M[K] extends Model ? "*" | TRepositorySelect<any, unknown, M[K]> : boolean : K extends keyof TColumnsDecorator<M> ? boolean : boolean;
}> : Partial<{
[K in TSchemaKeys<T> | TRelationKeys<R>]: K extends TRelationKeys<R> ? K extends TRawStringQuery | `${string}.${string}` ? boolean : K extends `$${string & K}` ? R extends Record<string, any> ? boolean : never : R extends Record<string, any> ? R[`$${string & K}`] extends (infer U)[] ? U extends Model ? "*" | TRepositorySelect<T.SchemaModel<U>, T.RelationModel<U>> : never : R[`$${K & string}`] extends Model ? "*" | TRepositorySelect<T.SchemaModel<R[`$${K & string}`]>, T.RelationModel<R[`$${K & string}`]>> : never : never : K extends keyof T ? boolean : never;
}>;
export type TRepositoryExcept<T = unknown, R = unknown, M extends Model = Model> = [unknown, unknown] extends [T, R] ? keyof TColumnsDecorator<M> extends never ? TNestedBoolean : Partial<{
[K in keyof TColumnsDecorator<M> | keyof TRelationsDecorator<M>]: K extends `${string}.${string}` | TRawStringQuery ? boolean : K extends keyof TRelationsDecorator<M> ? M[K] extends (infer U)[] ? U extends Model ? TRepositoryExcept<any, unknown, U> : boolean : M[K] extends Model ? TRepositoryExcept<any, unknown, M[K]> : boolean : K extends keyof TColumnsDecorator<M> ? boolean : boolean;
}> : Partial<{
[K in TSchemaKeys<T> | TRelationKeys<R>]: K extends TRelationKeys<R> ? K extends TRawStringQuery | `${string}.${string}` ? boolean : K extends `$${string & K}` ? R extends Record<string, any> ? boolean : never : R extends Record<string, any> ? R[`$${string & K}`] extends (infer U)[] ? U extends Model ? TRepositoryExcept<T.SchemaModel<U>, T.RelationModel<U>> : never : R[`$${K & string}`] extends Model ? TRepositoryExcept<T.SchemaModel<R[`$${K & string}`]>, T.RelationModel<R[`$${K & string}`]>> : never : never : K extends keyof T ? boolean : never;
}>;
export type TRepositoryWhere<T = unknown, R = unknown, M extends Model = Model> = [unknown, unknown] extends [T, R] ? keyof TColumnsDecorator<M> extends never ? Record<string, any> : Partial<{
[K in keyof TColumnsDecorator<M> | keyof TRelationsDecorator<M> | `${string}.${string}` | TRawStringQuery]: K extends keyof TRelationsDecorator<M> ? TRelationsDecorator<M>[K] extends (infer U)[] ? U extends Model ? TRepositoryWhere<any, unknown, U> | boolean : never : TRelationsDecorator<M>[K] extends Model ? TRepositoryWhere<any, unknown, TRelationsDecorator<M>[K]> | boolean : never : K extends keyof TColumnsDecorator<M> ? TColumnsDecorator<M>[K] : never;
}> : Partial<{
[K in TSchemaKeys<T> | TRelationKeys<R> | `${string}.${string}` | TRawStringQuery]: K extends TRelationKeys<R> ? K extends `$${string & K}` ? R extends Record<string, any> ? R[K] : never : R extends Record<string, any> ? R[`$${string & K}`] extends (infer U)[] ? U extends Model ? TRepositoryWhere<T.SchemaModel<U>, T.RelationModel<U>, M> | boolean : never : R[`$${K & string}`] extends Model ? TRepositoryWhere<T.SchemaModel<R[`$${K & string}`]>, T.RelationModel<R[`$${K & string}`]>, M> | boolean : never : never : K extends keyof T ? T[K] : never;
}>;
export type TRepositoryOrderBy<T = unknown, R = unknown, M extends Model = Model> = [unknown, unknown] extends [T, R] ? keyof TColumnsDecorator<M> extends never ? Record<string, "ASC" | "DESC"> : Partial<{
[K in keyof TColumnsDecorator<M> | keyof TRelationsDecorator<M>]: K extends `${string}.${string}` | TRawStringQuery ? "ASC" | "DESC" : K extends keyof TRelationsDecorator<M> ? M[K] extends (infer U)[] ? U extends Model ? TRepositoryOrderBy<any, unknown, U> : never : M[K] extends Model ? TRepositoryOrderBy<any, unknown, M[K]> : never : K extends keyof TColumnsDecorator<M> ? "ASC" | "DESC" : never;
}> : Partial<{
[K in TSchemaKeys<T> | TRelationKeys<R>]: K extends TRelationKeys<R> ? K extends TRawStringQuery | `${string}.${string}` ? "ASC" | "DESC" : K extends `$${string & K}` ? R extends Record<string, any> ? "ASC" | "DESC" : never : R extends Record<string, any> ? R[`$${string & K}`] extends (infer U)[] ? U extends Model ? TRepositoryOrderBy<T.SchemaModel<U>, T.RelationModel<U>> : never : R[`$${K & string}`] extends Model ? TRepositoryOrderBy<T.SchemaModel<R[`$${K & string}`]>, T.RelationModel<R[`$${K & string}`]>> : never : never : K extends keyof T ? "ASC" | "DESC" : never;
}>;
export type TRepositoryGroupBy<T = unknown, R = unknown, M extends Model = Model> = [unknown, unknown] extends [T, R] ? keyof TColumnsDecorator<M> extends never ? Record<string, boolean> : Partial<{
[K in keyof TColumnsDecorator<M> | keyof TRelationsDecorator<M>]: K extends `${string}.${string}` | TRawStringQuery ? boolean : K extends keyof TRelationsDecorator<M> ? M[K] extends (infer U)[] ? U extends Model ? "*" | TRepositoryGroupBy<any, unknown, U> : boolean : M[K] extends Model ? "*" | TRepositoryGroupBy<any, unknown, M[K]> : boolean : K extends keyof TColumnsDecorator<M> ? boolean : boolean;
}> : Partial<{
[K in TSchemaKeys<T> | TRelationKeys<R>]: K extends TRelationKeys<R> ? K extends TRawStringQuery | `${string}.${string}` ? boolean : K extends `$${string & K}` ? R extends Record<string, any> ? boolean : never : R extends Record<string, any> ? R[`$${string & K}`] extends (infer U)[] ? U extends Model ? "*" | TRepositoryGroupBy<T.SchemaModel<U>, T.RelationModel<U>> : never : R[`$${K & string}`] extends Model ? "*" | TRepositoryGroupBy<T.SchemaModel<R[`$${K & string}`]>, T.RelationModel<R[`$${K & string}`]>> : never : never : K extends keyof T ? boolean : never;
}>;
export type TRepositoryRelation<R = unknown, M extends Model = Model> = [
unknown
] extends [R] ? keyof TRelationsDecorator<M> extends never ? Record<string, any> : Partial<{
[K in keyof TRelationsDecorator<M>]: K extends keyof TRelationsDecorator<M> ? TRelationsDecorator<M>[K] extends (infer U)[] ? U extends Model ? boolean | (TRepositoryRequest<any, unknown, U> & TRepositoryRelation<unknown, U>) : never : TRelationsDecorator<M>[K] extends Model ? boolean | (TRepositoryRequest<any, unknown, TRelationsDecorator<M>[K]> & TRepositoryRelation<unknown, TRelationsDecorator<M>[K]>) : never : never;
}> : Partial<{
[K in TRelationKeys<R>]: K extends TRelationKeys<R> ? K extends `$${string & K}` ? R extends Record<string, any> ? boolean : never : R extends Record<string, any> ? R[`$${string & K}`] extends (infer U)[] ? U extends Model ? boolean | (TRepositoryRequest<T.SchemaModel<U>, T.RelationModel<U>> & TRepositoryRelation<T.RelationModel<U>>) : never : R[`$${K & string}`] extends Model ? boolean | (TRepositoryRequest<T.SchemaModel<R[`$${K & string}`]>, T.RelationModel<R[`$${K & string}`]>> & TRepositoryRelation<T.RelationModel<R[`$${K & string}`]>>) : never : never : never;
}>;
type Without<T, U> = {
[P in Exclude<keyof T, keyof U>]?: never;
};
type XOR<T, U> = (T & Without<U, T>) | (U & Without<T, U>);
type SelectBlock<T, R, M extends Model<any, any>, S> = {
select?: S extends {} ? S & {
[K in keyof S]: K extends keyof TRepositorySelect<T, R, M> ? S[K] : never;
} : "*" | TRepositorySelect<T, R, M>;
};
type ExceptBlock<T, R, M extends Model<any, any>, E> = {
except?: E extends {} ? E & {
[K in keyof E]: K extends keyof TRepositoryExcept<T, R, M> ? E[K] : never;
} : TRepositoryExcept<T, R, M>;
};
export type TRepositoryRequest<T = unknown, R = unknown, M extends Model<any, any> = Model<any, any>, S = undefined, SR = undefined, E = undefined, SRS = undefined, G = undefined> = XOR<SelectBlock<T, R, M, S>, // select ?:
ExceptBlock<T, R, M, E>> & {
selectRaw?: SRS extends {} ? SRS & {
[K in keyof SRS]: SRS[K] extends TRawStringQuery ? SRS[K] : never;
} : Record<string, TRawStringQuery>;
join?: {
localKey: `${string}.${string}`;
referenceKey: `${string}.${string}`;
}[];
leftJoin?: {
localKey: `${string}.${string}`;
referenceKey: `${string}.${string}`;
}[];
rightJoin?: {
localKey: `${string}.${string}`;
referenceKey: `${string}.${string}`;
}[];
where?: TRepositoryWhere<T, R, M>;
whereRaw?: string[];
whereQuery?: TRepositoryWhere<T, R, M>;
groupBy?: TRepositoryGroupBy<T, R, M>;
having?: string;
orderBy?: TRepositoryOrderBy<T, R, M>;
limit?: number;
offset?: number;
extend?: G extends {} ? G & {
[K in keyof G]: G[K];
} : Record<string, T.RepositoryGenericTypeOptions>;
debug?: boolean;
cache?: {
key: string;
expires: number;
namespace?: boolean;
};
when?: {
condition: boolean;
query: () => TRepositoryRequest<T, R, M, S, SR>;
};
using?: (model: M) => M;
hooks?: Function[];
audit?: {
userId: number;
metadata?: Record<string, any>;
};
relations?: SR extends {} ? SR & {
[K in keyof SR]: K extends keyof TRepositoryRelation<R, M> ? SR[K] : never;
} : TRepositoryRelation<R, M>;
relationsExists?: SR extends {} ? SR & {
[K in keyof SR]: K extends keyof TRepositoryRelation<R, M> ? SR[K] : never;
} : TRepositoryRelation<R, M>;
};
export type TRepositoryRequestHandler<T extends Record<string, any> = any, R = unknown, M extends Model<any, any> = Model<any, any>> = Partial<TRepositoryRequest<T, R, M> & {
instance?: Model;
}>;
export type TRepositoryRequestPagination<T extends Record<string, any> = any, R = unknown, M extends Model<any, any> = Model<any, any>> = Partial<TRepositoryRequest<T, R, M>> & {
page?: number;
};
export type TRepositoryRequestAggregate<T extends Record<string, any> = any, R = any, M extends Model<any, any> = Model<any, any>> = Partial<Omit<TRepositoryRequest<T, R, M>, "relations" | "relationQuery">>;
export type TRepositoryCreate<M extends Model<any, any> = Model<any, any>, NR extends boolean | undefined = false, K extends T.ColumnKeys<M> = T.ColumnKeys<M>, C extends T.ColumnOptions<M> = T.ColumnOptions<M>> = {
data: {
[P in Exclude<K & keyof C, "id" | "uuid"> as null extends C[P] ? any : P]: Extract<C[P], Date> extends never ? Extract<C[P], Record<string, unknown>> extends never ? C[P] : string : any;
};
debug?: boolean;
transaction?: TConnection | TConnectionTransaction;
noReturn?: NR;
};
export type TRepositoryCreateMultiple<M extends Model<any, any> = Model<any, any>, NR extends boolean | undefined = false, K extends T.ColumnKeys<M> = T.ColumnKeys<M>, C extends T.ColumnOptions<M> = T.ColumnOptions<M>> = {
data: {
[P in Exclude<K & keyof C, "id" | "uuid"> as null extends C[P] ? any : undefined extends C[P] ? never : P]: Extract<C[P], Date> extends never ? Extract<C[P], Record<string, unknown>> extends never ? C[P] : string : any;
}[];
debug?: boolean;
transaction?: TConnection | TConnectionTransaction;
noReturn?: NR;
};
export type TRepositoryCreateOrThings<M extends Model<any, any> = Model<any, any>, NR extends boolean | undefined = false, K extends T.ColumnKeys<M> = T.ColumnKeys<M>, C extends T.ColumnOptions<M> = T.ColumnOptions<M>> = {
data: {
[P in Exclude<K & keyof C, "id" | "uuid"> as null extends C[P] ? any : undefined extends C[P] ? never : P]: Extract<C[P], Date> extends never ? Extract<C[P], Record<string, unknown>> extends never ? C[P] : string : any;
};
where: T.WhereOptions<M>;
debug?: boolean;
transaction?: TConnection | TConnectionTransaction;
noReturn?: NR;
};
export type TRepositoryUpdate<M extends Model<any, any> = Model<any, any>, NR extends boolean | undefined = false, K extends T.ColumnKeys<M> = T.ColumnKeys<M>, C extends T.ColumnOptions<M> = T.ColumnOptions<M>> = {
data: Partial<{
[P in K & keyof C]: Extract<C[P], Date> extends never ? Extract<C[P], Record<string, unknown>> extends never ? C[P] : string : any;
}>;
where: T.WhereOptions<M>;
debug?: boolean;
transaction?: TConnection | TConnectionTransaction;
noReturn?: NR;
};
export type TRepositoryUpdateMultiple<M extends Model<any, any> = Model<any, any>, NR extends boolean | undefined = false, K extends T.ColumnKeys<M> = T.ColumnKeys<M>, C extends T.ColumnOptions<M> = T.ColumnOptions<M>> = {
cases: {
condition: ((query: M) => M) | Partial<{
[P in K & keyof C]: Extract<C[P], Date> extends never ? Extract<C[P], Record<string, unknown>> extends never ? C[P] : string : any;
}>;
columns: Partial<{
[P in K & keyof C]: Extract<C[P], Date> extends never ? Extract<C[P], Record<string, unknown>> extends never ? C[P] : string : any;
}>;
}[];
debug?: boolean;
transaction?: TConnection | TConnectionTransaction;
noReturn?: NR;
};
export type TRepositoryDelete<M extends Model<any, any> = Model<any, any>> = {
where: T.WhereOptions<M>;
debug?: boolean;
transaction?: TConnection | TConnectionTransaction;
};
export type TRepositoryPrimitiveExtendType<T> = T extends NumberConstructor ? number : T extends StringConstructor ? string : T extends BooleanConstructor ? boolean : T extends DateConstructor ? Date : T extends readonly (infer U)[] ? TRepositoryPrimitiveExtendType<U>[] : T extends Record<string, any> ? {
[K in keyof T]: TRepositoryPrimitiveExtendType<T[K]>;
} : T;
export type TRepositoryExtendType = NumberConstructor | StringConstructor | BooleanConstructor | DateConstructor | readonly TRepositoryExtendType[] | {
[_: string]: TRepositoryExtendType;
};
export {};