typed-wx-api
Version:
Typed Wechat API
1,773 lines (1,532 loc) • 114 kB
TypeScript
import IndexHints = require('./index-hints');
import { Association, BelongsTo, BelongsToMany, BelongsToManyOptions, BelongsToOptions, HasMany, HasManyOptions, HasOne, HasOneOptions } from './associations/index';
import { DataType } from './data-types';
import { Deferrable } from './deferrable';
import { HookReturn, Hooks, ModelHooks } from './hooks';
import { ValidationOptions } from './instance-validator';
import { IndexesOptions, QueryOptions, TableName } from './dialects/abstract/query-interface';
import { Sequelize, SyncOptions } from './sequelize';
import { Col, Fn, Literal, Where, MakeNullishOptional, AnyFunction, Cast, Json } from './utils';
import { LOCK, Transaction, Op, Optional } from './index';
import { SetRequired } from './utils/set-required';
// Backport of https://github.com/sequelize/sequelize/blob/a68b439fb3ea748d3f3d37356d9fe610f86184f6/src/utils/index.ts#L85
export type AllowReadonlyArray<T> = T | readonly T[];
export interface Logging {
/**
* A function that gets executed while running the query to log the sql.
*/
logging?: boolean | ((sql: string, timing?: number) => void);
/**
* Pass query execution time in milliseconds as second argument to logging function (options.logging).
*/
benchmark?: boolean;
}
export interface Poolable {
/**
* Force the query to use the write pool, regardless of the query type.
*
* @default false
*/
useMaster?: boolean;
}
export interface Transactionable {
/**
* Transaction to run query under
*/
transaction?: Transaction | null;
}
export interface SearchPathable {
/**
* An optional parameter to specify the schema search_path (Postgres only)
*/
searchPath?: string;
}
export interface Filterable<TAttributes = any> {
/**
* Attribute has to be matched for rows to be selected for the given action.
*/
where?: WhereOptions<TAttributes>;
}
export interface Projectable {
/**
* A list of the attributes that you want to select. To rename an attribute, you can pass an array, with
* two elements - the first is the name of the attribute in the DB (or some kind of expression such as
* `Sequelize.literal`, `Sequelize.fn` and so on), and the second is the name you want the attribute to
* have in the returned instance
*/
attributes?: FindAttributeOptions;
}
export interface Paranoid {
/**
* If true, only non-deleted records will be returned. If false, both deleted and non-deleted records will
* be returned. Only applies if `options.paranoid` is true for the model.
*/
paranoid?: boolean;
}
export type GroupOption = string | Fn | Col | (string | Fn | Col)[];
/**
* Options to pass to Model on drop
*/
export interface DropOptions extends Logging {
/**
* Also drop all objects depending on this table, such as views. Only works in postgres
*/
cascade?: boolean;
}
/**
* Schema Options provided for applying a schema to a model
*/
export interface SchemaOptions extends Logging {
/**
* The character(s) that separates the schema name from the table name
*/
schemaDelimiter?: string;
}
/**
* Scope Options for Model.scope
*/
export interface ScopeOptions {
/**
* The scope(s) to apply. Scopes can either be passed as consecutive arguments, or as an array of arguments.
* To apply simple scopes and scope functions with no arguments, pass them as strings. For scope function,
* pass an object, with a `method` property. The value can either be a string, if the method does not take
* any arguments, or an array, where the first element is the name of the method, and consecutive elements
* are arguments to that method. Pass null to remove all scopes, including the default.
*/
method: string | readonly [string, ...unknown[]];
}
type InvalidInSqlArray = ColumnReference | Fn | Cast | null | Literal;
/**
* This type allows using `Op.or`, `Op.and`, and `Op.not` recursively around another type.
* It also supports using a plain Array as an alias for `Op.and`. (unlike {@link AllowNotOrAndRecursive}).
*
* Example of plain-array treated as `Op.and`:
* User.findAll({ where: [{ id: 1 }, { id: 2 }] });
*
* Meant to be used by {@link WhereOptions}.
*/
type AllowNotOrAndWithImplicitAndArrayRecursive<T> = AllowArray<
// this is the equivalent of Op.and
| T
| { [Op.or]: AllowArray<AllowNotOrAndWithImplicitAndArrayRecursive<T>> }
| { [Op.and]: AllowArray<AllowNotOrAndWithImplicitAndArrayRecursive<T>> }
| { [Op.not]: AllowNotOrAndWithImplicitAndArrayRecursive<T> }
>;
/**
* This type allows using `Op.or`, `Op.and`, and `Op.not` recursively around another type.
* Unlike {@link AllowNotOrAndWithImplicitAndArrayRecursive}, it does not allow the 'implicit AND Array'.
*
* Example of plain-array NOT treated as Op.and:
* User.findAll({ where: { id: [1, 2] } });
*
* Meant to be used by {@link WhereAttributeHashValue}.
*/
type AllowNotOrAndRecursive<T> =
| T
| { [Op.or]: AllowArray<AllowNotOrAndRecursive<T>> }
| { [Op.and]: AllowArray<AllowNotOrAndRecursive<T>> }
| { [Op.not]: AllowNotOrAndRecursive<T> };
type AllowArray<T> = T | T[];
type AllowAnyAll<T> =
| T
// Op.all: [x, z] results in ALL (ARRAY[x, z])
// Some things cannot go in ARRAY. Op.values must be used to support them.
| { [Op.all]: Exclude<T, InvalidInSqlArray>[] | Literal | { [Op.values]: Array<T | DynamicValues<T>> } }
| { [Op.any]: Exclude<T, InvalidInSqlArray>[] | Literal | { [Op.values]: Array<T | DynamicValues<T>> } };
/**
* The type accepted by every `where` option
*/
export type WhereOptions<TAttributes = any> = AllowNotOrAndWithImplicitAndArrayRecursive<
| WhereAttributeHash<TAttributes>
| Literal
| Fn
| Where
| Json
>;
/**
* @deprecated unused
*/
export interface AnyOperator {
[Op.any]: readonly (string | number | Date | Literal)[] | Literal;
}
/** @deprecated unused */
export interface AllOperator {
[Op.all]: readonly (string | number | Date | Literal)[] | Literal;
}
// number is always allowed because -Infinity & +Infinity are valid
export type Rangable<T> = readonly [
lower: T | RangePart<T | number> | number | null,
higher: T | RangePart<T | number> | number | null
] | EmptyRange;
/**
* This type represents the output of the {@link RANGE} data type.
*/
// number is always allowed because -Infinity & +Infinity are valid
export type Range<T> = readonly [lower: RangePart<T | number>, higher: RangePart<T | number>] | EmptyRange;
type EmptyRange = [];
type RangePart<T> = { value: T, inclusive: boolean };
/**
* Internal type - prone to changes. Do not export.
* @private
*/
export type ColumnReference = Col | { [Op.col]: string };
/**
* Internal type - prone to changes. Do not export.
* @private
*/
type WhereSerializableValue = boolean | string | number | Buffer | Date;
/**
* Internal type - prone to changes. Do not export.
* @private
*/
type OperatorValues<AcceptableValues> =
| StaticValues<AcceptableValues>
| DynamicValues<AcceptableValues>;
/**
* Represents acceptable Dynamic values.
*
* Dynamic values, as opposed to {@link StaticValues}. i.e. column references, functions, etc...
*/
type DynamicValues<AcceptableValues> =
| Literal
| ColumnReference
| Fn
| Cast
// where() can only be used on boolean attributes
| (AcceptableValues extends boolean ? Where : never)
/**
* Represents acceptable Static values.
*
* Static values, as opposed to {@link DynamicValues}. i.e. booleans, strings, etc...
*/
type StaticValues<Type> =
Type extends Range<infer RangeType> ? [lower: RangeType | RangePart<RangeType>, higher: RangeType | RangePart<RangeType>]
: Type extends any[] ? { readonly [Key in keyof Type]: StaticValues<Type[Key]>}
: Type extends null ? Type | WhereSerializableValue | null
: Type | WhereSerializableValue;
/**
* Operators that can be used in {@link WhereOptions}
*
* @typeParam AttributeType - The JS type of the attribute the operator is operating on.
*
* See https://sequelize.org/master/en/v3/docs/querying/#operators
*/
// TODO: default to something more strict than `any` which lists serializable values
export interface WhereOperators<AttributeType = any> {
/**
* @example: `[Op.eq]: 6,` becomes `= 6`
* @example: `[Op.eq]: [6, 7]` becomes `= ARRAY[6, 7]`
* @example: `[Op.eq]: null` becomes `IS NULL`
* @example: `[Op.eq]: true` becomes `= true`
* @example: `[Op.eq]: literal('raw sql')` becomes `= raw sql`
* @example: `[Op.eq]: col('column')` becomes `= "column"`
* @example: `[Op.eq]: fn('NOW')` becomes `= NOW()`
*/
[Op.eq]?: AllowAnyAll<OperatorValues<AttributeType>>;
/**
* @example: `[Op.ne]: 20,` becomes `!= 20`
* @example: `[Op.ne]: [20, 21]` becomes `!= ARRAY[20, 21]`
* @example: `[Op.ne]: null` becomes `IS NOT NULL`
* @example: `[Op.ne]: true` becomes `!= true`
* @example: `[Op.ne]: literal('raw sql')` becomes `!= raw sql`
* @example: `[Op.ne]: col('column')` becomes `!= "column"`
* @example: `[Op.ne]: fn('NOW')` becomes `!= NOW()`
*/
[Op.ne]?: WhereOperators<AttributeType>[typeof Op.eq]; // accepts the same types as Op.eq
/**
* @example: `[Op.is]: null` becomes `IS NULL`
* @example: `[Op.is]: true` becomes `IS TRUE`
* @example: `[Op.is]: literal('value')` becomes `IS value`
*/
[Op.is]?: Extract<AttributeType, null | boolean> | Literal;
/**
* @example: `[Op.not]: true` becomes `IS NOT TRUE`
* @example: `{ col: { [Op.not]: { [Op.gt]: 5 } } }` becomes `NOT (col > 5)`
*/
[Op.not]?: WhereOperators<AttributeType>[typeof Op.eq]; // accepts the same types as Op.eq ('Op.not' is not strictly the opposite of 'Op.is' due to legacy reasons)
/** @example: `[Op.gte]: 6` becomes `>= 6` */
[Op.gte]?: AllowAnyAll<OperatorValues<NonNullable<AttributeType>>>;
/** @example: `[Op.lte]: 10` becomes `<= 10` */
[Op.lte]?: WhereOperators<AttributeType>[typeof Op.gte]; // accepts the same types as Op.gte
/** @example: `[Op.lt]: 10` becomes `< 10` */
[Op.lt]?: WhereOperators<AttributeType>[typeof Op.gte]; // accepts the same types as Op.gte
/** @example: `[Op.gt]: 6` becomes `> 6` */
[Op.gt]?: WhereOperators<AttributeType>[typeof Op.gte]; // accepts the same types as Op.gte
/**
* @example: `[Op.between]: [6, 10],` becomes `BETWEEN 6 AND 10`
*/
[Op.between]?:
| [
lowerInclusive: OperatorValues<NonNullable<AttributeType>>,
higherInclusive: OperatorValues<NonNullable<AttributeType>>,
]
| Literal;
/** @example: `[Op.notBetween]: [11, 15],` becomes `NOT BETWEEN 11 AND 15` */
[Op.notBetween]?: WhereOperators<AttributeType>[typeof Op.between];
/** @example: `[Op.in]: [1, 2],` becomes `IN (1, 2)` */
[Op.in]?: ReadonlyArray<OperatorValues<NonNullable<AttributeType>>> | Literal;
/** @example: `[Op.notIn]: [1, 2],` becomes `NOT IN (1, 2)` */
[Op.notIn]?: WhereOperators<AttributeType>[typeof Op.in];
/**
* @example: `[Op.like]: '%hat',` becomes `LIKE '%hat'`
* @example: `[Op.like]: { [Op.any]: ['cat', 'hat'] }` becomes `LIKE ANY ARRAY['cat', 'hat']`
*/
[Op.like]?: AllowAnyAll<OperatorValues<Extract<AttributeType, string>>>;
/**
* @example: `[Op.notLike]: '%hat'` becomes `NOT LIKE '%hat'`
* @example: `[Op.notLike]: { [Op.any]: ['cat', 'hat']}` becomes `NOT LIKE ANY ARRAY['cat', 'hat']`
*/
[Op.notLike]?: WhereOperators<AttributeType>[typeof Op.like];
/**
* case insensitive PG only
*
* @example: `[Op.iLike]: '%hat'` becomes `ILIKE '%hat'`
* @example: `[Op.iLike]: { [Op.any]: ['cat', 'hat']}` becomes `ILIKE ANY ARRAY['cat', 'hat']`
*/
[Op.iLike]?: WhereOperators<AttributeType>[typeof Op.like];
/**
* PG only
*
* @example: `[Op.notILike]: '%hat'` becomes `NOT ILIKE '%hat'`
* @example: `[Op.notLike]: ['cat', 'hat']` becomes `LIKE ANY ARRAY['cat', 'hat']`
*/
[Op.notILike]?: WhereOperators<AttributeType>[typeof Op.like];
/**
* PG array & range 'overlaps' operator
*
* @example: `[Op.overlap]: [1, 2]` becomes `&& [1, 2]`
*/
// https://www.postgresql.org/docs/14/functions-range.html range && range
// https://www.postgresql.org/docs/14/functions-array.html array && array
[Op.overlap]?: AllowAnyAll<
| (
// RANGE && RANGE
AttributeType extends Range<infer RangeType> ? Rangable<RangeType>
// ARRAY && ARRAY
: AttributeType extends any[] ? StaticValues<NonNullable<AttributeType>>
: never
)
| DynamicValues<AttributeType>
>;
/**
* PG array & range 'contains' operator
*
* @example: `[Op.contains]: [1, 2]` becomes `@> [1, 2]`
*/
// https://www.postgresql.org/docs/14/functions-json.html jsonb @> jsonb
// https://www.postgresql.org/docs/14/functions-range.html range @> range ; range @> element
// https://www.postgresql.org/docs/14/functions-array.html array @> array
[Op.contains]?:
// RANGE @> ELEMENT
| AttributeType extends Range<infer RangeType> ? OperatorValues<OperatorValues<NonNullable<RangeType>>> : never
// ARRAY @> ARRAY ; RANGE @> RANGE
| WhereOperators<AttributeType>[typeof Op.overlap];
/**
* PG array & range 'contained by' operator
*
* @example: `[Op.contained]: [1, 2]` becomes `<@ [1, 2]`
*/
[Op.contained]?:
AttributeType extends any[]
// ARRAY <@ ARRAY ; RANGE <@ RANGE
? WhereOperators<AttributeType>[typeof Op.overlap]
// ELEMENT <@ RANGE
: AllowAnyAll<OperatorValues<Rangable<AttributeType>>>;
/**
* Strings starts with value.
*/
[Op.startsWith]?: OperatorValues<Extract<AttributeType, string>>;
/**
* String ends with value.
*/
[Op.endsWith]?: WhereOperators<AttributeType>[typeof Op.startsWith];
/**
* String contains value.
*/
[Op.substring]?: WhereOperators<AttributeType>[typeof Op.startsWith];
/**
* MySQL/PG only
*
* Matches regular expression, case sensitive
*
* @example: `[Op.regexp]: '^[h|a|t]'` becomes `REGEXP/~ '^[h|a|t]'`
*/
[Op.regexp]?: AllowAnyAll<OperatorValues<Extract<AttributeType, string>>>;
/**
* MySQL/PG only
*
* Does not match regular expression, case sensitive
*
* @example: `[Op.notRegexp]: '^[h|a|t]'` becomes `NOT REGEXP/!~ '^[h|a|t]'`
*/
[Op.notRegexp]?: WhereOperators<AttributeType>[typeof Op.regexp];
/**
* PG only
*
* Matches regular expression, case insensitive
*
* @example: `[Op.iRegexp]: '^[h|a|t]'` becomes `~* '^[h|a|t]'`
*/
[Op.iRegexp]?: WhereOperators<AttributeType>[typeof Op.regexp];
/**
* PG only
*
* Does not match regular expression, case insensitive
*
* @example: `[Op.notIRegexp]: '^[h|a|t]'` becomes `!~* '^[h|a|t]'`
*/
[Op.notIRegexp]?: WhereOperators<AttributeType>[typeof Op.regexp];
/** @example: `[Op.match]: Sequelize.fn('to_tsquery', 'fat & rat')` becomes `@@ to_tsquery('fat & rat')` */
[Op.match]?: AllowAnyAll<DynamicValues<AttributeType>>;
/**
* PG only
*
* Whether the range is strictly left of the other range.
*
* @example:
* ```typescript
* { rangeAttribute: { [Op.strictLeft]: [1, 2] } }
* // results in
* // "rangeAttribute" << [1, 2)
* ```
*
* https://www.postgresql.org/docs/14/functions-range.html
*/
[Op.strictLeft]?:
| AttributeType extends Range<infer RangeType> ? Rangable<RangeType> : never
| DynamicValues<AttributeType>;
/**
* PG only
*
* Whether the range is strictly right of the other range.
*
* @example:
* ```typescript
* { rangeAttribute: { [Op.strictRight]: [1, 2] } }
* // results in
* // "rangeAttribute" >> [1, 2)
* ```
*
* https://www.postgresql.org/docs/14/functions-range.html
*/
[Op.strictRight]?: WhereOperators<AttributeType>[typeof Op.strictLeft];
/**
* PG only
*
* Whether the range extends to the left of the other range.
*
* @example:
* ```typescript
* { rangeAttribute: { [Op.noExtendLeft]: [1, 2] } }
* // results in
* // "rangeAttribute" &> [1, 2)
* ```
*
* https://www.postgresql.org/docs/14/functions-range.html
*/
[Op.noExtendLeft]?: WhereOperators<AttributeType>[typeof Op.strictLeft];
/**
* PG only
*
* Whether the range extends to the right of the other range.
*
* @example:
* ```typescript
* { rangeAttribute: { [Op.noExtendRight]: [1, 2] } }
* // results in
* // "rangeAttribute" &< [1, 2)
* ```
*
* https://www.postgresql.org/docs/14/functions-range.html
*/
[Op.noExtendRight]?: WhereOperators<AttributeType>[typeof Op.strictLeft];
/**
* PG only
*
* Whether the two ranges are adjacent.
*
* @example:
* ```typescript
* { rangeAttribute: { [Op.adjacent]: [1, 2] } }
* // results in
* // "rangeAttribute" -|- [1, 2)
* ```
*
* https://www.postgresql.org/docs/14/functions-range.html
*/
[Op.adjacent]?: WhereOperators<AttributeType>[typeof Op.strictLeft];
}
/**
* Example: `[Op.or]: [{a: 5}, {a: 6}]` becomes `(a = 5 OR a = 6)`
*
* @deprecated do not use me!
*/
// TODO [>6]: Remove me
export interface OrOperator<TAttributes = any> {
[Op.or]: WhereOptions<TAttributes> | readonly WhereOptions<TAttributes>[] | WhereValue<TAttributes> | readonly WhereValue<TAttributes>[];
}
/**
* Example: `[Op.and]: {a: 5}` becomes `AND (a = 5)`
*
* @deprecated do not use me!
*/
// TODO [>6]: Remove me
export interface AndOperator<TAttributes = any> {
[Op.and]: WhereOptions<TAttributes> | readonly WhereOptions<TAttributes>[] | WhereValue<TAttributes> | readonly WhereValue<TAttributes>[];
}
/**
* Where Geometry Options
*/
export interface WhereGeometryOptions {
type: string;
coordinates: readonly (number[] | number)[];
}
/**
* Used for the right hand side of WhereAttributeHash.
* WhereAttributeHash is in there for JSON columns.
*
* @deprecated do not use me
*/
// TODO [>6]: remove this
export type WhereValue<TAttributes = any> =
| string
| number
| bigint
| boolean
| Date
| Buffer
| null
| WhereAttributeHash<any> // for JSON columns
| Col // reference another column
| Fn
| WhereGeometryOptions
/**
* A hash of attributes to describe your search.
*
* Possible key values:
*
* - An attribute name: `{ id: 1 }`
* - A nested attribute: `{ '$projects.id$': 1 }`
* - A JSON key: `{ 'object.key': 1 }`
* - A cast: `{ 'id::integer': 1 }`
*
* - A combination of the above: `{ '$join.attribute$.json.path::integer': 1 }`
*/
export type WhereAttributeHash<TAttributes = any> = {
// support 'attribute' & '$attribute$'
[AttributeName in keyof TAttributes as AttributeName extends string ? AttributeName | `$${AttributeName}$` : never]?: WhereAttributeHashValue<TAttributes[AttributeName]>;
} & {
[AttributeName in keyof TAttributes as AttributeName extends string ?
// support 'json.path', '$json$.path'
| `${AttributeName}.${string}` | `$${AttributeName}$.${string}`
// support 'attribute::cast', '$attribute$::cast', 'json.path::cast' & '$json$.path::cast'
| `${AttributeName | `$${AttributeName}$` | `${AttributeName}.${string}` | `$${AttributeName}$.${string}`}::${string}`
: never]?: WhereAttributeHashValue<any>;
} & {
// support '$nested.attribute$', '$nested.attribute$::cast', '$nested.attribute$.json.path', & '$nested.attribute$.json.path::cast'
// TODO [2022-05-26]: Remove this ts-ignore once we drop support for TS < 4.4
// TypeScript < 4.4 does not support using a Template Literal Type as a key.
// note: this *must* be a ts-ignore, as it works in ts >= 4.4
// @ts-ignore
[attribute: `$${string}.${string}$` | `$${string}.${string}$::${string}` | `$${string}.${string}$.${string}` | `$${string}.${string}$.${string}::${string}`]: WhereAttributeHashValue<any>;
}
/**
* Types that can be compared to an attribute in a WHERE context.
*/
export type WhereAttributeHashValue<AttributeType> =
| AllowNotOrAndRecursive<
// if the right-hand side is an array, it will be equal to Op.in
// otherwise it will be equal to Op.eq
// Exception: array attribtues always use Op.eq, never Op.in.
| AttributeType extends any[]
? WhereOperators<AttributeType>[typeof Op.eq] | WhereOperators<AttributeType>
: (
| WhereOperators<AttributeType>[typeof Op.in]
| WhereOperators<AttributeType>[typeof Op.eq]
| WhereOperators<AttributeType>
)
>
// TODO: this needs a simplified version just for JSON columns
| WhereAttributeHash<any> // for JSON columns
/**
* Through options for Include Options
*/
export interface IncludeThroughOptions extends Filterable<any>, Projectable {
/**
* The alias of the relation, in case the model you want to eagerly load is aliassed. For `hasOne` /
* `belongsTo`, this should be the singular name, and for `hasMany`, it should be the plural
*/
as?: string;
/**
* If true, only non-deleted records will be returned from the join table.
* If false, both deleted and non-deleted records will be returned.
* Only applies if through model is paranoid.
*/
paranoid?: boolean;
}
/**
* Options for eager-loading associated models, also allowing for all associations to be loaded at once
*/
export type Includeable = ModelType | Association | IncludeOptions | { all: true, nested?: true } | string;
/**
* Complex include options
*/
export interface IncludeOptions extends Filterable<any>, Projectable, Paranoid {
/**
* Mark the include as duplicating, will prevent a subquery from being used.
*/
duplicating?: boolean;
/**
* The model you want to eagerly load
*/
model?: ModelType;
/**
* The alias of the relation, in case the model you want to eagerly load is aliassed. For `hasOne` /
* `belongsTo`, this should be the singular name, and for `hasMany`, it should be the plural
*/
as?: string;
/**
* The association you want to eagerly load. (This can be used instead of providing a model/as pair)
*/
association?: Association | string;
/**
* Custom `on` clause, overrides default.
*/
on?: WhereOptions<any>;
/**
* Note that this converts the eager load to an inner join,
* unless you explicitly set `required: false`
*/
where?: WhereOptions<any>;
/**
* If true, converts to an inner join, which means that the parent model will only be loaded if it has any
* matching children. True if `include.where` is set, false otherwise.
*/
required?: boolean;
/**
* If true, converts to a right join if dialect support it. Ignored if `include.required` is true.
*/
right?: boolean;
/**
* Limit include. Only available when setting `separate` to true.
*/
limit?: number;
/**
* Run include in separate queries.
*/
separate?: boolean;
/**
* Through Options
*/
through?: IncludeThroughOptions;
/**
* Load further nested related models
*/
include?: Includeable[];
/**
* Order include. Only available when setting `separate` to true.
*/
order?: Order;
/**
* Use sub queries. This should only be used if you know for sure the query does not result in a cartesian product.
*/
subQuery?: boolean;
}
type OrderItemAssociation = Association | ModelStatic<Model> | { model: ModelStatic<Model>; as: string } | string
type OrderItemColumn = string | Col | Fn | Literal
export type OrderItem =
| string
| Fn
| Col
| Literal
| [OrderItemColumn, string]
| [OrderItemAssociation, OrderItemColumn]
| [OrderItemAssociation, OrderItemColumn, string]
| [OrderItemAssociation, OrderItemAssociation, OrderItemColumn]
| [OrderItemAssociation, OrderItemAssociation, OrderItemColumn, string]
| [OrderItemAssociation, OrderItemAssociation, OrderItemAssociation, OrderItemColumn]
| [OrderItemAssociation, OrderItemAssociation, OrderItemAssociation, OrderItemColumn, string]
| [OrderItemAssociation, OrderItemAssociation, OrderItemAssociation, OrderItemAssociation, OrderItemColumn]
| [OrderItemAssociation, OrderItemAssociation, OrderItemAssociation, OrderItemAssociation, OrderItemColumn, string]
export type Order = Fn | Col | Literal | OrderItem[];
/**
* Please note if this is used the aliased property will not be available on the model instance
* as a property but only via `instance.get('alias')`.
*/
export type ProjectionAlias = readonly [string | Literal | Fn | Col, string];
export type FindAttributeOptions =
| (string | ProjectionAlias)[]
| {
exclude: string[];
include?: (string | ProjectionAlias)[];
}
| {
exclude?: string[];
include: (string | ProjectionAlias)[];
};
export interface IndexHint {
type: IndexHints;
values: string[];
}
export interface IndexHintable {
/**
* MySQL only.
*/
indexHints?: IndexHint[];
}
/**
* Options that are passed to any model creating a SELECT query
*
* A hash of options to describe the scope of the search
*/
export interface FindOptions<TAttributes = any>
extends QueryOptions, Filterable<TAttributes>, Projectable, Paranoid, IndexHintable
{
/**
* A list of associations to eagerly load using a left join (a single association is also supported). Supported is either
* `{ include: Model1 }`, `{ include: [ Model1, Model2, ...]}`, `{ include: [{ model: Model1, as: 'Alias' }]}` or
* `{ include: [{ all: true }]}`.
* If your association are set up with an `as` (eg. `X.hasMany(Y, { as: 'Z' }`, you need to specify Z in
* the as attribute when eager loading Y).
*/
include?: Includeable | Includeable[];
/**
* Specifies an ordering. If a string is provided, it will be escaped. Using an array, you can provide
* several columns / functions to order by. Each element can be further wrapped in a two-element array. The
* first element is the column / function to order by, the second is the direction. For example:
* `order: [['name', 'DESC']]`. In this way the column will be escaped, but the direction will not.
*/
order?: Order;
/**
* GROUP BY in sql
*/
group?: GroupOption;
/**
* Limits how many items will be retrieved by the operation.
*
* If `limit` and `include` are used together, Sequelize will turn the `subQuery` option on by default.
* This is done to ensure that `limit` only impacts the Model on the same level as the `limit` option.
*
* You can disable this behavior by explicitly setting `subQuery: false`, however `limit` will then
* affect the total count of returned values, including eager-loaded associations, instead of just one table.
*
* @example
* // in the following query, `limit` only affects the "User" model.
* // This will return 2 users, each including all of their projects.
* User.findAll({
* limit: 2,
* include: [User.associations.projects],
* });
*
* @example
* // in the following query, `limit` affects the total number of returned values, eager-loaded associations included.
* // This may return 2 users, each with one project,
* // or 1 user with 2 projects.
* User.findAll({
* limit: 2,
* include: [User.associations.projects],
* subQuery: false,
* });
*/
limit?: number;
// TODO: document this - this is an undocumented property but it exists and there are tests for it.
groupedLimit?: unknown;
/**
* Skip the results;
*/
offset?: number;
/**
* Lock the selected rows. Possible options are transaction.LOCK.UPDATE and transaction.LOCK.SHARE.
* Postgres also supports transaction.LOCK.KEY_SHARE, transaction.LOCK.NO_KEY_UPDATE and specific model
* locks with joins. See [transaction.LOCK for an example](transaction#lock)
*/
lock?:
| LOCK
| { level: LOCK; of: ModelStatic<Model> }
| boolean;
/**
* Skip locked rows. Only supported in Postgres.
*/
skipLocked?: boolean;
/**
* Return raw result. See sequelize.query for more information.
*/
raw?: boolean;
/**
* Select group rows after groups and aggregates are computed.
*/
having?: WhereOptions<any>;
/**
* Use sub queries (internal).
*
* If unspecified, this will `true` by default if `limit` is specified, and `false` otherwise.
* See {@link FindOptions#limit} for more information.
*/
subQuery?: boolean;
}
export interface NonNullFindOptions<TAttributes = any> extends FindOptions<TAttributes> {
/**
* Throw if nothing was found.
*/
rejectOnEmpty: boolean | Error;
}
/**
* Options for Model.count method
*/
export interface CountOptions<TAttributes = any>
extends Logging, Transactionable, Filterable<TAttributes>, Projectable, Paranoid, Poolable
{
/**
* Include options. See `find` for details
*/
include?: Includeable | Includeable[];
/**
* Apply COUNT(DISTINCT(col))
*/
distinct?: boolean;
/**
* GROUP BY in sql
* Used in conjunction with `attributes`.
*
* @see Projectable
*/
group?: GroupOption;
/**
* The column to aggregate on.
*/
col?: string;
}
/**
* Options for Model.count when GROUP BY is used
*/
export type CountWithOptions<TAttributes = any> = SetRequired<CountOptions<TAttributes>, 'group'>
export interface FindAndCountOptions<TAttributes = any> extends CountOptions<TAttributes>, FindOptions<TAttributes> { }
export interface GroupedCountResultItem {
[key: string]: unknown // projected attributes
count: number // the count for each group
}
/**
* Options for Model.build method
*/
export interface BuildOptions {
/**
* If set to true, values will ignore field and virtual setters.
*/
raw?: boolean;
/**
* Is this record new
*/
isNewRecord?: boolean;
/**
* An array of include options. A single option is also supported - Used to build prefetched/included model instances. See `set`
*
* TODO: See set
*/
include?: Includeable | Includeable[];
}
export interface Silent {
/**
* If true, the updatedAt timestamp will not be updated.
*
* @default false
*/
silent?: boolean;
}
/**
* Options for Model.create method
*/
export interface CreateOptions<TAttributes = any> extends BuildOptions, Logging, Silent, Transactionable, Hookable {
/**
* If set, only columns matching those in fields will be saved
*/
fields?: (keyof TAttributes)[];
/**
* dialect specific ON CONFLICT DO NOTHING / INSERT IGNORE
*/
ignoreDuplicates?: boolean;
/**
* Return the affected rows (only for postgres)
*/
returning?: boolean | (keyof TAttributes)[];
/**
* If false, validations won't be run.
*
* @default true
*/
validate?: boolean;
}
export interface Hookable {
/**
* If `false` the applicable hooks will not be called.
* The default value depends on the context.
*/
hooks?: boolean
}
/**
* Options for Model.findOrCreate method
*/
export interface FindOrCreateOptions<TAttributes = any, TCreationAttributes = TAttributes>
extends FindOptions<TAttributes>, CreateOptions<TAttributes>
{
/**
* Default values to use if building a new instance
*/
defaults?: TCreationAttributes;
}
/**
* Options for Model.findOrBuild method
*/
export interface FindOrBuildOptions<TAttributes = any, TCreationAttributes = TAttributes>
extends FindOptions<TAttributes>, BuildOptions
{
/**
* Default values to use if building a new instance
*/
defaults?: TCreationAttributes;
}
/**
* Options for Model.upsert method
*/
export interface UpsertOptions<TAttributes = any> extends Logging, Transactionable, SearchPathable, Hookable {
/**
* The fields to insert / update. Defaults to all fields
*/
fields?: (keyof TAttributes)[];
/**
* Return the affected rows (only for postgres)
*/
returning?: boolean | (keyof TAttributes)[];
/**
* Run validations before the row is inserted
*/
validate?: boolean;
/**
* Optional override for the conflict fields in the ON CONFLICT part of the query.
* Only supported in Postgres >= 9.5 and SQLite >= 3.24.0
*/
conflictFields?: (keyof TAttributes)[];
}
/**
* Options for Model.bulkCreate method
*/
export interface BulkCreateOptions<TAttributes = any> extends Logging, Transactionable, Hookable, SearchPathable {
/**
* Fields to insert (defaults to all fields)
*/
fields?: (keyof TAttributes)[];
/**
* Should each row be subject to validation before it is inserted. The whole insert will fail if one row
* fails validation
*/
validate?: boolean;
/**
* Run before / after create hooks for each individual Instance? BulkCreate hooks will still be run if
* options.hooks is true.
*/
individualHooks?: boolean;
/**
* Ignore duplicate values for primary keys?
*
* @default false
*/
ignoreDuplicates?: boolean;
/**
* Fields to update if row key already exists (on duplicate key update)? (only supported by MySQL,
* MariaDB, SQLite >= 3.24.0 & Postgres >= 9.5).
*/
updateOnDuplicate?: (keyof TAttributes)[];
/**
* Include options. See `find` for details
*/
include?: Includeable | Includeable[];
/**
* Return all columns or only the specified columns for the affected rows (only for postgres)
*/
returning?: boolean | (keyof TAttributes)[];
}
/**
* The options passed to Model.destroy in addition to truncate
*/
export interface TruncateOptions<TAttributes = any> extends Logging, Transactionable, Filterable<TAttributes>, Hookable {
/**
* Only used in conjuction with TRUNCATE. Truncates all tables that have foreign-key references to the
* named table, or to any tables added to the group due to CASCADE.
*
* @default false;
*/
cascade?: boolean;
/**
* If set to true, destroy will SELECT all records matching the where parameter and will execute before /
* after destroy hooks on each row
*/
individualHooks?: boolean;
/**
* How many rows to delete
*/
limit?: number;
/**
* Delete instead of setting deletedAt to current timestamp (only applicable if `paranoid` is enabled)
*/
force?: boolean;
/**
* Only used in conjunction with `truncate`.
* Automatically restart sequences owned by columns of the truncated table
*/
restartIdentity?: boolean;
}
/**
* Options used for Model.destroy
*/
export interface DestroyOptions<TAttributes = any> extends TruncateOptions<TAttributes> {
/**
* If set to true, dialects that support it will use TRUNCATE instead of DELETE FROM. If a table is
* truncated the where and limit options are ignored
*/
truncate?: boolean;
}
/**
* Options for Model.restore
*/
export interface RestoreOptions<TAttributes = any> extends Logging, Transactionable, Filterable<TAttributes>, Hookable {
/**
* If set to true, restore will find all records within the where parameter and will execute before / after
* bulkRestore hooks on each row
*/
individualHooks?: boolean;
/**
* How many rows to undelete
*/
limit?: number;
}
/**
* Options used for Model.update
*/
export interface UpdateOptions<TAttributes = any> extends Logging, Transactionable, Paranoid, Hookable {
/**
* Options to describe the scope of the search.
*/
where: WhereOptions<TAttributes>;
/**
* Fields to update (defaults to all fields)
*/
fields?: (keyof TAttributes)[];
/**
* Should each row be subject to validation before it is inserted. The whole insert will fail if one row
* fails validation.
*
* @default true
*/
validate?: boolean;
/**
* Whether or not to update the side effects of any virtual setters.
*
* @default true
*/
sideEffects?: boolean;
/**
* Run before / after update hooks?. If true, this will execute a SELECT followed by individual UPDATEs.
* A select is needed, because the row data needs to be passed to the hooks
*
* @default false
*/
individualHooks?: boolean;
/**
* Return the affected rows (only for postgres)
*/
returning?: boolean | (keyof TAttributes)[];
/**
* How many rows to update (only for mysql and mariadb)
*/
limit?: number;
/**
* If true, the updatedAt timestamp will not be updated.
*/
silent?: boolean;
}
/**
* Options used for Model.aggregate
*/
export interface AggregateOptions<T extends DataType | unknown, TAttributes = any>
extends QueryOptions, Filterable<TAttributes>, Paranoid
{
/**
* The type of the result. If `field` is a field in this Model, the default will be the type of that field,
* otherwise defaults to float.
*/
dataType?: string | T;
/**
* Applies DISTINCT to the field being aggregated over
*/
distinct?: boolean;
}
// instance
/**
* Options used for Instance.increment method
*/
export interface IncrementDecrementOptions<TAttributes = any>
extends Logging, Transactionable, Silent, SearchPathable, Filterable<TAttributes> { }
/**
* Options used for Instance.increment method
*/
export interface IncrementDecrementOptionsWithBy<TAttributes = any> extends IncrementDecrementOptions<TAttributes> {
/**
* The number to increment by
*
* @default 1
*/
by?: number;
}
/**
* Options used for Instance.restore method
*/
export interface InstanceRestoreOptions extends Logging, Transactionable { }
/**
* Options used for Instance.destroy method
*/
export interface InstanceDestroyOptions extends Logging, Transactionable, Hookable {
/**
* If set to true, paranoid models will actually be deleted
*/
force?: boolean;
}
/**
* Options used for Instance.update method
*/
export interface InstanceUpdateOptions<TAttributes = any> extends
SaveOptions<TAttributes>, SetOptions, Filterable<TAttributes> { }
/**
* Options used for Instance.set method
*/
export interface SetOptions {
/**
* If set to true, field and virtual setters will be ignored
*/
raw?: boolean;
/**
* Clear all previously set data values
*/
reset?: boolean;
}
/**
* Options used for Instance.save method
*/
export interface SaveOptions<TAttributes = any> extends Logging, Transactionable, Silent, Hookable {
/**
* An optional array of strings, representing database columns. If fields is provided, only those columns
* will be validated and saved.
*/
fields?: (keyof TAttributes)[];
/**
* If false, validations won't be run.
*
* @default true
*/
validate?: boolean;
/**
* A flag that defines if null values should be passed as values or not.
*
* @default false
*/
omitNull?: boolean;
}
/**
* Model validations, allow you to specify format/content/inheritance validations for each attribute of the
* model.
*
* Validations are automatically run on create, update and save. You can also call validate() to manually
* validate an instance.
*
* The validations are implemented by validator.js.
*/
export interface ModelValidateOptions {
/**
* - `{ is: ['^[a-z]+$','i'] }` will only allow letters
* - `{ is: /^[a-z]+$/i }` also only allows letters
*/
is?: string | readonly (string | RegExp)[] | RegExp | { msg: string; args: string | readonly (string | RegExp)[] | RegExp };
/**
* - `{ not: ['[a-z]','i'] }` will not allow letters
*/
not?: string | readonly (string | RegExp)[] | RegExp | { msg: string; args: string | readonly (string | RegExp)[] | RegExp };
/**
* checks for email format (foo@bar.com)
*/
isEmail?: boolean | { msg: string };
/**
* checks for url format (http://foo.com)
*/
isUrl?: boolean | { msg: string };
/**
* checks for IPv4 (129.89.23.1) or IPv6 format
*/
isIP?: boolean | { msg: string };
/**
* checks for IPv4 (129.89.23.1)
*/
isIPv4?: boolean | { msg: string };
/**
* checks for IPv6 format
*/
isIPv6?: boolean | { msg: string };
/**
* will only allow letters
*/
isAlpha?: boolean | { msg: string };
/**
* will only allow alphanumeric characters, so "_abc" will fail
*/
isAlphanumeric?: boolean | { msg: string };
/**
* will only allow numbers
*/
isNumeric?: boolean | { msg: string };
/**
* checks for valid integers
*/
isInt?: boolean | { msg: string };
/**
* checks for valid floating point numbers
*/
isFloat?: boolean | { msg: string };
/**
* checks for any numbers
*/
isDecimal?: boolean | { msg: string };
/**
* checks for lowercase
*/
isLowercase?: boolean | { msg: string };
/**
* checks for uppercase
*/
isUppercase?: boolean | { msg: string };
/**
* won't allow null
*/
notNull?: boolean | { msg: string };
/**
* only allows null
*/
isNull?: boolean | { msg: string };
/**
* don't allow empty strings
*/
notEmpty?: boolean | { msg: string };
/**
* only allow a specific value
*/
equals?: string | { msg: string };
/**
* force specific substrings
*/
contains?: string | { msg: string };
/**
* check the value is not one of these
*/
notIn?: ReadonlyArray<readonly any[]> | { msg: string; args: ReadonlyArray<readonly any[]> };
/**
* check the value is one of these
*/
isIn?: ReadonlyArray<readonly any[]> | { msg: string; args: ReadonlyArray<readonly any[]> };
/**
* don't allow specific substrings
*/
notContains?: readonly string[] | string | { msg: string; args: readonly string[] | string };
/**
* only allow values with length between 2 and 10
*/
len?: readonly [number, number] | { msg: string; args: readonly [number, number] };
/**
* only allow uuids
*/
isUUID?: number | { msg: string; args: number };
/**
* only allow date strings
*/
isDate?: boolean | { msg: string; args: boolean };
/**
* only allow date strings after a specific date
*/
isAfter?: string | { msg: string; args: string };
/**
* only allow date strings before a specific date
*/
isBefore?: string | { msg: string; args: string };
/**
* only allow values
*/
max?: number | { msg: string; args: readonly [number] };
/**
* only allow values >= 23
*/
min?: number | { msg: string; args: readonly [number] };
/**
* only allow arrays
*/
isArray?: boolean | { msg: string; args: boolean };
/**
* check for valid credit card numbers
*/
isCreditCard?: boolean | { msg: string; args: boolean };
// TODO: Enforce 'rest' indexes to have type `(value: unknown) => boolean`
// Blocked by: https://github.com/microsoft/TypeScript/issues/7765
/**
* Custom validations are also possible
*/
[name: string]: unknown;
}
/**
* Interface for indexes property in InitOptions
*/
export type ModelIndexesOptions = IndexesOptions
/**
* Interface for name property in InitOptions
*/
export interface ModelNameOptions {
/**
* Singular model name
*/
singular?: string;
/**
* Plural model name
*/
plural?: string;
}
/**
* Interface for getterMethods in InitOptions
*/
export interface ModelGetterOptions<M extends Model = Model> {
[name: string]: (this: M) => unknown;
}
/**
* Interface for setterMethods in InitOptions
*/
export interface ModelSetterOptions<M extends Model = Model> {
[name: string]: (this: M, val: any) => void;
}
/**
* Interface for Define Scope Options
*/
export interface ModelScopeOptions<TAttributes = any> {
/**
* Name of the scope and it's query
*/
[scopeName: string]: FindOptions<TAttributes> | ((...args: readonly any[]) => FindOptions<TAttributes>);
}
/**
* General column options
*/
export interface ColumnOptions {
/**
* If false, the column will have a NOT NULL constraint, and a not null validation will be run before an
* instance is saved.
*
* @default true
*/
allowNull?: boolean;
/**
* If set, sequelize will map the attribute name to a different name in the database
*/
field?: string;
/**
* A literal default value, a JavaScript function, or an SQL function (see `sequelize.fn`)
*/
defaultValue?: unknown;
}
/**
* References options for the column's attributes
*/
export interface ModelAttributeColumnReferencesOptions {
/**
* If this column references another table, provide it here as a Model, or a string
*/
model?: TableName | ModelType;
/**
* The column of the foreign table that this column references
*/
key?: string;
/**
* When to check for the foreign key constraing
*
* PostgreSQL only
*/
deferrable?: Deferrable;
}
/**
* Column options for the model schema attributes
*/
export interface ModelAttributeColumnOptions<M extends Model = Model> extends ColumnOptions {
/**
* A string or a data type
*/
type: DataType;
/**
* If true, the column will get a unique constraint. If a string is provided, the column will be part of a
* composite unique index. If multiple columns have the same string, they will be part of the same unique
* index
*/
unique?: boolean | string | { name: string; msg: string };
/**
* Primary key flag
*/
primaryKey?: boolean;
/**
* Is this field an auto increment field
*/
autoIncrement?: boolean;
/**
* If this field is a Postgres auto increment field, use Postgres `GENERATED BY DEFAULT AS IDENTITY` instead of `SERIAL`. Postgres 10+ only.
*/
autoIncrementIdentity?: boolean;
/**
* Comment for the database
*/
comment?: string;
/**
* An object with reference configurations or the column name as string
*/
references?: string | ModelAttributeColumnReferencesOptions;
/**
* What should happen when the referenced key is updated. One of CASCADE, RESTRICT, SET DEFAULT, SET NULL or
* NO ACTION
*/
onUpdate?: string;
/**
* What should happen when the referenced key is deleted. One of CASCADE, RESTRICT, SET DEFAULT, SET NULL or
* NO ACTION
*/
onDelete?: string;
/**
* An object of validations to execute for this column every time the model is saved. Can be either the
* name of a validation provided by validator.js, a validation function provided by extending validator.js
* (see the
* `DAOValidator` property for more details), or a custom validation function. Custom validation functions
* are called with the value of the field, and can possibly take a second callback argument, to signal that
* they are asynchronous. If the validator is sync, it should throw in the case of a failed validation, it
* it is async, the callback should be called with the error text.
*/
validate?: ModelValidateOptions;
/**
* Usage in object notation
*
* ```js
* class MyModel extends Model {}
* MyModel.init({
* states: {
* type: Sequelize.ENUM,
* values: ['active', 'pending', 'deleted']
* }
* }, { sequelize })
* ```
*/
values?: readonly string[];
/**
* Provide a custom getter for this column. Use `this.getDataValue(String)` to manipulate the underlying
* values.
*/
get?(this: M): unknown;
/**
* Provide a custom setter for this column. Use `this.setDataValue(String, Value)` to manipulate the
* underlying values.
*/
set?(this: M, val: unknown): void;
}
/**
* Interface for Attributes provided for all columns in a model
*/
export type ModelAttributes<M extends Model = Model, TAttributes = any> = {
/**
* The description of a database column
*/
[name in keyof TAttributes]: DataType | ModelAttributeColumnOptions<M>;
}
/**
* Possible types for primary keys
*/
export type Identifier = number | bigint | string | Buffer;
/**
* Options for model definition
*/
export interface ModelOptions<M extends Model = Model> {
/**
* Define the default search scope to use for this model. Scopes have the same form as the options passed to
* find / findAll.
*/
defaultScope?: FindOptions<Attributes<M>>;
/**
* More scopes, defined in the same way as defaultScope above. See `Model.scope` for more information about
* how scopes are defined, and what you can do with them
*/
scopes?: ModelScopeOptions<Attributes<M>>;
/**
* Don't persits null values. This means that all columns with null values will not be saved.
*/
omitNull?: boolean;
/**
* Adds createdAt and updatedAt timestamps to the model. Default true.
*/
timestamps?: boolean;
/**
* Calling destroy will not delete the model, but instead set a deletedAt timestamp if this is true. Needs
* timestamps=true to work. Default false.
*/
paranoid?: boolean;
/**
* Converts all camelCased columns to underscored if true. Default false.
*/
underscored?: boolean;
/**
* Indicates if the model's table has a trigger associated with it. Default false.
*/
hasTrigger?: boolean;
/**
* If freezeTableName is true, sequelize will not try to alter the DAO name to get the table name.
* Otherwise, the dao name will be pluralized. Default false.
*/
freezeTableName?: boolean;
/**
* An object with two attributes, `singular` and `plural`, which are used when this model is associated to
* others.
*/
name?: ModelNameOptions;
/**
* Set name of the model. By default its same as Class name.
*/
modelName?: string;
/**
* Indexes for the provided database table
*/
indexes?: readonly ModelIndexesOptions[];
/**
* Override the name of the createdAt column if a string is provided, or disable it if false. Timestamps
* must be true. Not affected by underscored setting.
*/
createdAt?: string | boolean;
/**
* Override the name of the deletedAt column if a string is provided, or disable it if false. Timestamps
* must be true. Not affected by underscored setting.
*/
deletedAt?: string | boolean;
/**
* Override the name of the updatedAt column if a string is provided, or disable it if false. Timestamps
* must be true. Not affected by underscored setting.
*/
updatedAt?: string | boolean;
/**
* @default pluralized model name, unless freezeTableName is true, in which case it uses model name
* verbatim
*/
tableName?: string;
schema?: string;
/**
* You can also change the database engine, e.g. to MyISAM. InnoDB is the default.
*/
engine?: string;
charset?: string;
/**
* Finaly you can specify a comment for the table in MySQL and PG
*/
comment?: string;
collate?: string;
/**
* Set the initial AUTO_INC