UNPKG

lakutata

Version:

An IoC-based universal application framework.

543 lines (499 loc) 21.4 kB
import { ObjectLiteral } from './TypeDef.internal.36.js'; import { ValueTransformer } from './TypeDef.internal.68.js'; import { ObjectId } from './TypeDef.internal.55.js'; import { SelectQueryBuilder } from './TypeDef.internal.38.js'; import { EntityMetadata } from './TypeDef.internal.47.js'; /** * Special object that defines order condition for ORDER BY in sql. * * Example: * { * "name": "ASC", * "id": "DESC" * } * * @deprecated */ type OrderByCondition = { [columnName: string]: ("ASC" | "DESC") | { order: "ASC" | "DESC"; nulls?: "NULLS FIRST" | "NULLS LAST"; }; }; /** * Used to specify what entity relations should be loaded. * * Example: * const options: JoinOptions = { * alias: "photo", * leftJoin: { * author: "photo.author", * categories: "categories", * user: "categories.user", * profile: "user.profile" * }, * innerJoin: { * author: "photo.author", * categories: "categories", * user: "categories.user", * profile: "user.profile" * }, * leftJoinAndSelect: { * author: "photo.author", * categories: "categories", * user: "categories.user", * profile: "user.profile" * }, * innerJoinAndSelect: { * author: "photo.author", * categories: "categories", * user: "categories.user", * profile: "user.profile" * } * }; * * @deprecated */ interface JoinOptions { /** * Alias of the main entity. */ alias: string; /** * Object where each key represents the LEFT JOIN alias, * and the corresponding value represents the relation path. * * The columns of the joined table are included in the selection. */ leftJoinAndSelect?: { [key: string]: string; }; /** * Object where each key represents the INNER JOIN alias, * and the corresponding value represents the relation path. * * The columns of the joined table are included in the selection. */ innerJoinAndSelect?: { [key: string]: string; }; /** * Object where each key represents the LEFT JOIN alias, * and the corresponding value represents the relation path. * * This method does not select the columns of the joined table. */ leftJoin?: { [key: string]: string; }; /** * Object where each key represents the INNER JOIN alias, * and the corresponding value represents the relation path. * * This method does not select the columns of the joined table. */ innerJoin?: { [key: string]: string; }; } /** * List of types that FindOperator can be. */ type FindOperatorType = "not" | "lessThan" | "lessThanOrEqual" | "moreThan" | "moreThanOrEqual" | "equal" | "between" | "in" | "any" | "isNull" | "ilike" | "like" | "raw" | "arrayContains" | "arrayContainedBy" | "arrayOverlap" | "and" | "jsonContains" | "or"; type SqlGeneratorType = (aliasPath: string) => string; /** * Find Operator used in Find Conditions. */ declare class FindOperator<T> { readonly "@instanceof": symbol; /** * Operator type. */ private _type; /** * Parameter value. */ private _value; /** * ObjectLiteral parameters. */ private _objectLiteralParameters; /** * Indicates if parameter is used or not for this operator. */ private _useParameter; /** * Indicates if multiple parameters must be used for this operator. */ private _multipleParameters; /** * SQL generator */ private _getSql; constructor(type: FindOperatorType, value: T | FindOperator<T>, useParameter?: boolean, multipleParameters?: boolean, getSql?: SqlGeneratorType, objectLiteralParameters?: ObjectLiteral); /** * Indicates if parameter is used or not for this operator. * Extracts final value if value is another find operator. */ get useParameter(): boolean; /** * Indicates if multiple parameters must be used for this operator. * Extracts final value if value is another find operator. */ get multipleParameters(): boolean; /** * Gets the Type of this FindOperator */ get type(): FindOperatorType; /** * Gets the final value needs to be used as parameter value. */ get value(): T; /** * Gets ObjectLiteral parameters. */ get objectLiteralParameters(): ObjectLiteral | undefined; /** * Gets the child FindOperator if it exists */ get child(): FindOperator<T> | undefined; /** * Gets the SQL generator */ get getSql(): SqlGeneratorType | undefined; transformValue(transformer: ValueTransformer | ValueTransformer[]): void; } declare class EqualOperator<T> extends FindOperator<T> { readonly "@instanceof": symbol; constructor(value: T | FindOperator<T>); } /** * A single property handler for FindOptionsWhere. * * The reason why we have both "PropertyToBeNarrowed" and "Property" is that Union is narrowed down when extends is used. * It means the result of FindOptionsWhereProperty<1 | 2> doesn't include FindOperator<1 | 2> but FindOperator<1> | FindOperator<2>. * So we keep the original Union as Original and pass it to the FindOperator too. Original remains Union as extends is not used for it. */ type FindOptionsWhereProperty<PropertyToBeNarrowed, Property = PropertyToBeNarrowed> = PropertyToBeNarrowed extends Promise<infer I> ? FindOptionsWhereProperty<NonNullable<I>> : PropertyToBeNarrowed extends Array<infer I> ? FindOptionsWhereProperty<NonNullable<I>> : PropertyToBeNarrowed extends Function ? never : PropertyToBeNarrowed extends Buffer ? Property | FindOperator<Property> : PropertyToBeNarrowed extends Date ? Property | FindOperator<Property> : PropertyToBeNarrowed extends ObjectId ? Property | FindOperator<Property> : PropertyToBeNarrowed extends string ? Property | FindOperator<Property> : PropertyToBeNarrowed extends number ? Property | FindOperator<Property> : PropertyToBeNarrowed extends boolean ? Property | FindOperator<Property> : PropertyToBeNarrowed extends object ? FindOptionsWhere<Property> | FindOptionsWhere<Property>[] | EqualOperator<Property> | FindOperator<any> | boolean | Property : Property | FindOperator<Property>; /** * Used for find operations. */ type FindOptionsWhere<Entity> = { [P in keyof Entity]?: P extends "toString" ? unknown : FindOptionsWhereProperty<NonNullable<Entity[P]>>; }; /** * A single property handler for FindOptionsSelect. */ type FindOptionsSelectProperty<Property> = Property extends Promise<infer I> ? FindOptionsSelectProperty<I> | boolean : Property extends Array<infer I> ? FindOptionsSelectProperty<I> | boolean : Property extends string ? boolean : Property extends number ? boolean : Property extends boolean ? boolean : Property extends Function ? never : Property extends Buffer ? boolean : Property extends Date ? boolean : Property extends ObjectId ? boolean : Property extends object ? FindOptionsSelect<Property> | boolean : boolean; /** * Select find options. */ type FindOptionsSelect<Entity> = { [P in keyof Entity]?: P extends "toString" ? unknown : FindOptionsSelectProperty<NonNullable<Entity[P]>>; }; /** * Property paths (column names) to be selected by "find" defined as string. * Old selection mechanism in TypeORM. * * @deprecated will be removed in the next version, use FindOptionsSelect type notation instead */ type FindOptionsSelectByString<Entity> = (keyof Entity)[]; /** * A single property handler for FindOptionsRelations. */ type FindOptionsRelationsProperty<Property> = Property extends Promise<infer I> ? FindOptionsRelationsProperty<NonNullable<I>> | boolean : Property extends Array<infer I> ? FindOptionsRelationsProperty<NonNullable<I>> | boolean : Property extends string ? never : Property extends number ? never : Property extends boolean ? never : Property extends Function ? never : Property extends Buffer ? never : Property extends Date ? never : Property extends ObjectId ? never : Property extends object ? FindOptionsRelations<Property> | boolean : boolean; /** * Relations find options. */ type FindOptionsRelations<Entity> = { [P in keyof Entity]?: P extends "toString" ? unknown : FindOptionsRelationsProperty<NonNullable<Entity[P]>>; }; /** * Relation names to be selected by "relation" defined as string. * Old relation mechanism in TypeORM. * * @deprecated will be removed in the next version, use FindOptionsRelation type notation instead */ type FindOptionsRelationByString = string[]; /** * A single property handler for FindOptionsOrder. */ type FindOptionsOrderProperty<Property> = Property extends Promise<infer I> ? FindOptionsOrderProperty<NonNullable<I>> : Property extends Array<infer I> ? FindOptionsOrderProperty<NonNullable<I>> : Property extends Function ? never : Property extends string ? FindOptionsOrderValue : Property extends number ? FindOptionsOrderValue : Property extends boolean ? FindOptionsOrderValue : Property extends Buffer ? FindOptionsOrderValue : Property extends Date ? FindOptionsOrderValue : Property extends ObjectId ? FindOptionsOrderValue : Property extends object ? FindOptionsOrder<Property> | FindOptionsOrderValue : FindOptionsOrderValue; /** * Order by find options. */ type FindOptionsOrder<Entity> = { [P in keyof Entity]?: P extends "toString" ? unknown : FindOptionsOrderProperty<NonNullable<Entity[P]>>; }; /** * Value of order by in find options. */ type FindOptionsOrderValue = "ASC" | "DESC" | "asc" | "desc" | 1 | -1 | { direction?: "asc" | "desc" | "ASC" | "DESC"; nulls?: "first" | "last" | "FIRST" | "LAST"; }; /** * Defines a special criteria to find specific entity. */ interface FindOneOptions<Entity = any> { /** * Adds a comment with the supplied string in the generated query. This is * helpful for debugging purposes, such as finding a specific query in the * database server's logs, or for categorization using an APM product. */ comment?: string; /** * Specifies what columns should be retrieved. */ select?: FindOptionsSelect<Entity> | FindOptionsSelectByString<Entity>; /** * Simple condition that should be applied to match entities. */ where?: FindOptionsWhere<Entity>[] | FindOptionsWhere<Entity>; /** * Indicates what relations of entity should be loaded (simplified left join form). */ relations?: FindOptionsRelations<Entity> | FindOptionsRelationByString; /** * Specifies how relations must be loaded - using "joins" or separate queries. * If you are loading too much data with nested joins it's better to load relations * using separate queries. * * Default strategy is "join", but default can be customized in connection options. */ relationLoadStrategy?: "join" | "query"; /** * Specifies what relations should be loaded. * * @deprecated */ join?: JoinOptions; /** * Order, in which entities should be ordered. */ order?: FindOptionsOrder<Entity>; /** * Enables or disables query result caching. */ cache?: boolean | number | { id: any; milliseconds: number; }; /** * Indicates what locking mode should be used. * * Note: For lock tables, you must specify the table names and not the relation names */ lock?: { mode: "optimistic"; version: number | Date; } | { mode: "pessimistic_read" | "pessimistic_write" | "dirty_read" | "pessimistic_partial_write" | "pessimistic_write_or_fail" | "for_no_key_update" | "for_key_share"; tables?: string[]; onLocked?: "nowait" | "skip_locked"; }; /** * Indicates if soft-deleted rows should be included in entity result. */ withDeleted?: boolean; /** * If sets to true then loads all relation ids of the entity and maps them into relation values (not relation objects). * If array of strings is given then loads only relation ids of the given properties. */ loadRelationIds?: boolean | { relations?: string[]; disableMixedMap?: boolean; }; /** * Indicates if eager relations should be loaded or not. * By default, they are loaded when find methods are used. */ loadEagerRelations?: boolean; /** * If this is set to true, SELECT query in a `find` method will be executed in a transaction. */ transaction?: boolean; } /** * Defines a special criteria to find specific entities. */ interface FindManyOptions<Entity = any> extends FindOneOptions<Entity> { /** * Offset (paginated) where from entities should be taken. */ skip?: number; /** * Limit (paginated) - max number of entities should be taken. */ take?: number; } /** * Defines a special criteria to find specific entities. */ interface FindTreeOptions { /** * Indicates what relations of entity should be loaded (simplified left join form). */ relations?: string[]; /** * When loading a tree from a TreeRepository, limits the depth of the descendents loaded */ depth?: number; } /** * Utilities to work with FindOptions. */ declare class FindOptionsUtils { /** * Checks if given object is really instance of FindOneOptions interface. */ static isFindOneOptions<Entity = any>(obj: any): obj is FindOneOptions<Entity>; /** * Checks if given object is really instance of FindManyOptions interface. */ static isFindManyOptions<Entity = any>(obj: any): obj is FindManyOptions<Entity>; /** * Checks if given object is really instance of FindOptions interface. */ static extractFindManyOptionsAlias(object: any): string | undefined; /** * Applies give find many options to the given query builder. static applyFindManyOptionsOrConditionsToQueryBuilder<T>(qb: SelectQueryBuilder<T>, options: FindManyOptions<T>|Partial<T>|undefined): SelectQueryBuilder<T> { if (this.isFindManyOptions(options)) return this.applyOptionsToQueryBuilder(qb, options); if (options) return qb.where(options); return qb; }*/ /** * Applies give find options to the given query builder. static applyOptionsToQueryBuilder<T>(qb: SelectQueryBuilder<T>, options: FindOneOptions<T>|FindManyOptions<T>|undefined): SelectQueryBuilder<T> { // if options are not set then simply return query builder. This is made for simplicity of usage. if (!options || (!this.isFindOneOptions(options) && !this.isFindManyOptions(options))) return qb; if (options.transaction === true) { qb.expressionMap.useTransaction = true; } if (!qb.expressionMap.mainAlias || !qb.expressionMap.mainAlias.hasMetadata) return qb; const metadata = qb.expressionMap.mainAlias!.metadata; // apply all options from FindOptions if (options.comment) { qb.comment(options.comment); } if (options.withDeleted) { qb.withDeleted(); } if (options.select) { qb.select([]); options.select.forEach(select => { if (!metadata.hasColumnWithPropertyPath(`${select}`)) throw new TypeORMError(`${select} column was not found in the ${metadata.name} entity.`); const columns = metadata.findColumnsWithPropertyPath(`${select}`); for (const column of columns) { qb.addSelect(qb.alias + "." + column.propertyPath); } }); } if (options.relations) { // Copy because `applyRelationsRecursively` modifies it const allRelations = [...options.relations]; this.applyRelationsRecursively(qb, allRelations, qb.expressionMap.mainAlias!.name, qb.expressionMap.mainAlias!.metadata, ""); // recursive removes found relations from allRelations array // if there are relations left in this array it means those relations were not found in the entity structure // so, we give an exception about not found relations if (allRelations.length > 0) throw new FindRelationsNotFoundError(allRelations); } if (options.join) { if (options.join.leftJoin) Object.keys(options.join.leftJoin).forEach(key => { qb.leftJoin(options.join!.leftJoin![key], key); }); if (options.join.innerJoin) Object.keys(options.join.innerJoin).forEach(key => { qb.innerJoin(options.join!.innerJoin![key], key); }); if (options.join.leftJoinAndSelect) Object.keys(options.join.leftJoinAndSelect).forEach(key => { qb.leftJoinAndSelect(options.join!.leftJoinAndSelect![key], key); }); if (options.join.innerJoinAndSelect) Object.keys(options.join.innerJoinAndSelect).forEach(key => { qb.innerJoinAndSelect(options.join!.innerJoinAndSelect![key], key); }); } if (options.cache) { if (options.cache instanceof Object) { const cache = options.cache as { id: any, milliseconds: number }; qb.cache(cache.id, cache.milliseconds); } else { qb.cache(options.cache); } } if (options.lock) { if (options.lock.mode === "optimistic") { qb.setLock(options.lock.mode, options.lock.version); } else if ( options.lock.mode === "pessimistic_read" || options.lock.mode === "pessimistic_write" || options.lock.mode === "dirty_read" || options.lock.mode === "pessimistic_partial_write" || options.lock.mode === "pessimistic_write_or_fail" || options.lock.mode === "for_no_key_update" || options.lock.mode === "for_key_share" ) { const tableNames = options.lock.tables ? options.lock.tables.map((table) => { const tableAlias = qb.expressionMap.aliases.find((alias) => { return alias.metadata.tableNameWithoutPrefix === table; }); if (!tableAlias) { throw new TypeORMError(`"${table}" is not part of this query`); } return qb.escape(tableAlias.name); }) : undefined; qb.setLock(options.lock.mode, undefined, tableNames); } } if (options.loadRelationIds === true) { qb.loadAllRelationIds(); } else if (options.loadRelationIds instanceof Object) { qb.loadAllRelationIds(options.loadRelationIds as any); } if (options.where) qb.where(options.where); if ((options as FindManyOptions<T>).skip) qb.skip((options as FindManyOptions<T>).skip!); if ((options as FindManyOptions<T>).take) qb.take((options as FindManyOptions<T>).take!); if (options.order) Object.keys(options.order).forEach(key => { const order = ((options as FindOneOptions<T>).order as any)[key as any]; if (!metadata.findColumnWithPropertyPath(key)) throw new Error(`${key} column was not found in the ${metadata.name} entity.`); switch (order) { case 1: qb.addOrderBy(qb.alias + "." + key, "ASC"); break; case -1: qb.addOrderBy(qb.alias + "." + key, "DESC"); break; case "ASC": qb.addOrderBy(qb.alias + "." + key, "ASC"); break; case "DESC": qb.addOrderBy(qb.alias + "." + key, "DESC"); break; } }); return qb; }*/ static applyOptionsToTreeQueryBuilder<T extends ObjectLiteral>(qb: SelectQueryBuilder<T>, options?: FindTreeOptions): SelectQueryBuilder<T>; /** * Adds joins for all relations and sub-relations of the given relations provided in the find options. */ static applyRelationsRecursively(qb: SelectQueryBuilder<any>, allRelations: string[], alias: string, metadata: EntityMetadata, prefix: string): void; static joinEagerRelations(qb: SelectQueryBuilder<any>, alias: string, metadata: EntityMetadata): void; } export { EqualOperator, FindOperator, FindOptionsUtils }; export type { FindManyOptions, FindOneOptions, FindOperatorType, FindOptionsOrder, FindOptionsOrderProperty, FindOptionsOrderValue, FindOptionsRelationByString, FindOptionsRelations, FindOptionsRelationsProperty, FindOptionsSelect, FindOptionsSelectByString, FindOptionsSelectProperty, FindOptionsWhere, FindOptionsWhereProperty, FindTreeOptions, JoinOptions, OrderByCondition };