UNPKG

typed-wx-api

Version:
1,773 lines (1,532 loc) 114 kB
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