lakutata
Version:
An IoC-based universal application framework.
543 lines (499 loc) • 21.4 kB
TypeScript
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 };