-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
/
where-sql-builder-types.ts
108 lines (103 loc) · 4.22 KB
/
where-sql-builder-types.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import type { AllowArray } from '@sequelize/utils';
import type { DynamicSqlExpression } from '../expression-builders/base-sql-expression.js';
import type { WhereOperators } from '../model.js';
import type { Op } from '../operators.js';
/**
* 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`:
* ```ts
* User.findAll({ where: [{ id: 1 }, { id: 2 }] });
* ```
*
* Meant to be used by {@link WhereOptions}.
*/
export 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> }
>;
/**
* The type accepted by every `where` option
*/
export type WhereOptions<TAttributes = any> =
// "where" is typically optional. If the user sets it to undefined, we treat is as if the option was not set.
| undefined
| AllowNotOrAndWithImplicitAndArrayRecursive<
WhereAttributeHash<TAttributes> | DynamicSqlExpression
>;
/**
* 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:
* ```ts
* 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> };
/**
* 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
/**
* 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', json[index]', '$json$[index]'
| `${AttributeName}.${string}`
| `$${AttributeName}$.${string}`
| `${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', '$nested.attribute$[index]', & '$nested.attribute$[index]::cast'
[
attribute:
| `$${string}.${string}$`
| `$${string}.${string}$::${string}`
| `$${string}.${string}$.${string}`
| `$${string}.${string}$.${string}:${string}`
| `$${string}.${string}$[${string}`
| `$${string}.${string}$[${string}:${string}`
]: WhereAttributeHashValue<any>;
};