UNPKG

@goatlab/fluent

Version:

Readable query Interface & API generator for TS and Node

105 lines (104 loc) 5.26 kB
import { AnyObject, Concrete, ExpandRecursively, PaginatedData, Paginator, Primitives, PrimitivesArray, Unpacked } from '@goatlab/js-utils'; export { Primitives, PrimitivesArray, AnyObject, Concrete, Unpacked, PaginatedData, ExpandRecursively, Paginator, }; export type QueryFieldSelector<T> = Partial<{ [K in keyof Concrete<T>]: Concrete<T>[K] extends object ? true | false | Unpacked<Partial<QueryFieldSelector<Concrete<T>[K]>>> : true | false | undefined; }>; export type QueryOrderSelector<T> = Partial<{ [K in keyof Concrete<T>]: Concrete<T>[K] extends object ? Partial<QueryOrderSelector<Concrete<T>[K]>> : 'asc' | 'desc' | undefined; }>; export type QueryOperations<T> = { [key in LogicOperator]: key extends LogicOperator.In ? T[] : key extends LogicOperator.NotIn ? T[] : T; }; export type QueryWhereFitler<T> = Partial<{ [K in keyof Concrete<T>]: Concrete<T>[K] extends object ? Unpacked<Partial<QueryWhereFitler<Concrete<T>[K]>>> : Unpacked<Partial<QueryOperations<Concrete<T>[K]>>> | T[K]; }>; export type QueryInsert<T> = { [K in keyof T]: T[K] extends object ? QueryInsert<T[K]> : T[K]; }; export type ModelRelation<T> = T; export type QueryIncludeRelation<T> = { [K in keyof Partial<T>]: (FluentQuery<Unpacked<T[K]>> & { withPivot?: true; }) | true; }; export type FluentQuery<T> = { select?: QueryFieldSelector<T>; where?: { OR: FluentQuery<T>['where'][]; AND: FluentQuery<T>['where'][]; } | QueryWhereFitler<T>; orderBy?: QueryOrderSelector<T>[]; limit?: number; offset?: number; take?: number; include?: QueryIncludeRelation<T>; paginated?: Paginator; }; export type AddUndefinedIfNullable<T> = T extends null | undefined ? undefined : never; export type GetSelectedFromInclude<T extends FluentQuery<Model>, Model> = { [P in keyof T['include'] & keyof Model]: T['include'][P] extends object ? NonNullable<Model[P]> extends any[] ? T['include'][P] extends { withPivot: true; } ? (QueryOutput<T['include'][P] & FluentQuery<Unpacked<NonNullable<Model[P]>>>, Unpacked<NonNullable<Model[P]>>> & { pivot: AnyObject; })[] | AddUndefinedIfNullable<Model[P]> : (QueryOutput<T['include'][P] & FluentQuery<Unpacked<NonNullable<Model[P]>>>, Unpacked<NonNullable<Model[P]>>> & { pivot: AnyObject; })[] | AddUndefinedIfNullable<Model[P]> : T['include'][P] extends { withPivot: true; } ? (QueryOutput<T['include'][P] & FluentQuery<Unpacked<NonNullable<Model[P]>>>, Unpacked<NonNullable<Model[P]>>> & { pivot: AnyObject; }) | AddUndefinedIfNullable<Model[P]> : QueryOutput<T['include'][P] & FluentQuery<Unpacked<NonNullable<Model[P]>>>, Unpacked<NonNullable<Model[P]>>> | AddUndefinedIfNullable<Model[P]> : Model[P]; }; export type GetSelectedFromObject<T extends FluentQuery<Model>, Model> = { [P in keyof T['select'] & keyof Model]: T['select'][P] extends object ? NonNullable<Model[P]> extends any[] ? QueryOutput<{ select: T['select'][P]; }, Unpacked<NonNullable<Model[P]>>>[] | AddUndefinedIfNullable<Model[P]> : QueryOutput<{ select: T['select'][P]; }, Unpacked<NonNullable<Model[P]>>> | AddUndefinedIfNullable<Model[P]> : Model[P]; } & GetSelectedFromInclude<T, Model>; export type QueryOutput<T extends FluentQuery<Model>, Model> = ExpandRecursively<T extends { select: T['select']; } ? T extends { paginated: T['paginated']; } ? PaginatedData<GetSelectedFromObject<T, Model>> : ExpandRecursively<GetSelectedFromObject<T, Model>> : T extends { paginated: T['paginated']; } ? PaginatedData<Model> : Model & GetSelectedFromInclude<T, Model>>; export interface Deleted { deleted: number; } export declare enum LogicOperator { Equals = "equals", LessThan = "lessThan", GreaterThan = "greaterThan", LessOrEqualThan = "lessOrEqualThan", GreaterOrEqualThan = "greaterOrEqualThan", IsNot = "isNot", In = "in", NotIn = "notIn", Like = "like", Regexp = "regexp", StartsWith = "startsWith", EndsWith = "endsWith", Contains = "contains", ArrayContains = "arrayContains", Exists = "exists", NotExists = "notExists" } export type FluentHasManyRelatedAttribute<T> = Partial<{ [K in keyof Concrete<T>]: Concrete<T>[K] extends object ? Unpacked<Partial<FluentHasManyRelatedAttribute<Concrete<T>[K]>>> | true : true | undefined; }>; export type FluentHasManyParams<T extends FluentHasManyParams<T>> = { repository: new () => InstanceType<T['repository']>; }; export type FluentBelongsToParams<T extends FluentHasManyParams<T>> = { repository: new () => InstanceType<T['repository']>; }; export type FluentBelongsToManyParams<T extends FluentBelongsToManyParams<T>> = { repository: new () => InstanceType<T['repository']>; pivot: new () => InstanceType<T['pivot']>; }; export type FindByIdFilter<T> = { select?: FluentQuery<T>['select']; include?: FluentQuery<T>['include']; limit?: number; }; export type LoadedResult<T> = Omit<T, 'findMany' | 'insert' | 'insertMany' | 'loadFirst' | 'byId' | 'replaceById' | 'updateById' | 'clear' | 'requireById' | 'collect' | 'findByIds' | 'findFirst' | 'isMongoDB' | 'pluck' | 'raw' | 'associate' | 'attach' | 'withPivot' | 'loadById'>;