@goatlab/fluent
Version:
Readable query Interface & API generator for TS and Node
142 lines (141 loc) • 6.17 kB
TypeScript
import { ObjectID } from 'bson';
export interface AnyObject {
[key: string]: any;
}
declare type Unpacked<T> = T extends (infer U)[] ? U : T;
export declare type ExpandRecursively<T> = T extends (...args: infer A) => infer R ? (...args: ExpandRecursively<A>) => ExpandRecursively<R> : T extends object ? T extends infer O ? O extends any[] ? {
[K in keyof Unpacked<O>]: ExpandRecursively<Unpacked<O>[K]>;
}[] : {
[K in keyof O]: ExpandRecursively<O[K]>;
} : never : T;
export declare type Concrete<Type> = {
[Property in keyof Type]-?: Type[Property];
};
export declare type Subset<T, U> = {
[key in keyof T]: key extends keyof U ? T[key] : never;
};
export declare type QueryFieldSelector<T> = Partial<{
[K in keyof Concrete<T>]: Concrete<T>[K] extends object ? true | Unpacked<Partial<QueryFieldSelector<Concrete<T>[K]>>> : true | undefined;
}>;
export declare type QueryOrderSelector<T> = Partial<{
[K in keyof Concrete<T>]: Concrete<T>[K] extends object ? Partial<QueryOrderSelector<Concrete<T>[K]>> : 'asc' | 'desc' | undefined;
}>;
export declare type QueryOperations<T> = {
[key in LogicOperator]: key extends LogicOperator.in ? T[] : key extends LogicOperator.notIn ? T[] : T;
};
export declare 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 declare type QueryInsert<T> = {
[K in keyof T]: T[K] extends object ? QueryInsert<T[K]> : T[K];
};
export declare type ModelRelation<T> = T;
export declare type QueryIncludeRelation<T> = {
[K in keyof Partial<T>]: (FluentQuery<Unpacked<T[K]>> & {
withPivot?: true;
}) | true;
};
export declare 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 declare type AddUndefinedIfNullable<T> = T extends null | undefined ? undefined : never;
export declare type GetSelectedFromInclude<T extends FluentQuery<Model>, Model> = {
[P in keyof T['include']]: T['include'][P] extends object ? NonNullable<Model[P]> extends any[] ? T['include'][P] extends {
withPivot: true;
} ? (QueryOutput<T['include'][P], Unpacked<NonNullable<Model[P]>>> & {
pivot: AnyObject;
})[] | AddUndefinedIfNullable<Model[P]> : (QueryOutput<T['include'][P], Unpacked<NonNullable<Model[P]>>> & {
pivot: AnyObject;
})[] | AddUndefinedIfNullable<Model[P]> : T['include'][P] extends {
withPivot: true;
} ? (QueryOutput<T['include'][P], Unpacked<NonNullable<Model[P]>>> & {
pivot: AnyObject;
}) | AddUndefinedIfNullable<Model[P]> : QueryOutput<T['include'][P], Unpacked<NonNullable<Model[P]>>> | AddUndefinedIfNullable<Model[P]> : Model[P];
};
export declare type GetSelectedFromObject<T extends FluentQuery<Model>, Model> = {
[P in keyof T['select']]: 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 declare 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 PaginatedData<T> {
currentPage: number;
data: T[];
firstPageUrl?: string;
nextPageUrl?: string;
prevPageUrl?: string;
path?: string;
perPage: number;
total: number;
lastPage: number;
firstPage: number;
nextPage: number;
prevPage: number | null;
from: number;
to: number;
}
export interface Paginator {
page: number;
perPage: number;
}
export interface Deleted {
deleted: number;
}
export declare type Primitives = boolean | string | number | ObjectID;
export declare type PrimitivesArray = boolean[] | string[] | number[] | ObjectID[];
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 declare type FluentHasManyRelatedAttribute<T> = Partial<{
[K in keyof Concrete<T>]: Concrete<T>[K] extends object ? Unpacked<Partial<FluentHasManyRelatedAttribute<Concrete<T>[K]>>> | true : true | undefined;
}>;
export declare type FluentHasManyParams<T extends FluentHasManyParams<T>> = {
repository: new () => InstanceType<T['repository']>;
};
export declare type FluentBelongsToParams<T extends FluentHasManyParams<T>> = {
repository: new () => InstanceType<T['repository']>;
};
export declare type FluentBelongsToManyParams<T extends FluentBelongsToManyParams<T>> = {
repository: new () => InstanceType<T['repository']>;
pivot: new () => InstanceType<T['pivot']>;
};
export declare type FindByIdFilter<T> = {
select?: FluentQuery<T>['select'];
include?: FluentQuery<T>['include'];
limit?: number;
};
export declare type LoadedResult<T> = Omit<T, 'findMany' | 'insert' | 'insertMany' | 'loadFirst' | 'byId' | 'replaceById' | 'updateById' | 'clear' | 'requireById' | 'collect' | 'findByIds' | 'findFirst' | 'isMongoDB' | 'pluck' | 'raw' | 'associate' | 'attach' | 'withPivot' | 'loadById'>;
export {};