typeorm-extensions 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -5
- package/dist/extensions/typed/typed-where/typed-period-filter.extension.js +1 -1
- package/dist/extensions/typed/typed-where/typed-where-is-any.extension.d.ts +38 -129
- package/dist/extensions/typed/typed-where/typed-where-is-any.extension.js +2 -1
- package/dist/extensions/typed/typed-where/typed-where-is-distinct-from.extension.js +1 -1
- package/dist/extensions/typed/typed-where/typed-where-is-in.extension.d.ts +35 -117
- package/dist/extensions/typed/typed-where/typed-where-is-in.extension.js +11 -19
- package/dist/extensions/typed/typed-where/typed-where-json.extension.js +1 -1
- package/dist/extensions/typed/typed-where/typed-where.extension.d.ts +29 -73
- package/dist/extensions/typed/typed-where/typed-where.extension.js +10 -10
- package/dist/index.d.ts +1 -0
- package/dist/types/interfaces/config.interface.d.ts +17 -0
- package/dist/types/interfaces/config.interface.js +2 -0
- package/dist/types/interfaces/index.d.ts +1 -0
- package/dist/types/interfaces/index.js +1 -0
- package/dist/types/modules/proxy-callback.types.d.ts +28 -4
- package/dist/types/modules/typed-params.types.d.ts +45 -0
- package/dist/types/modules/typed-params.types.js +2 -0
- package/dist/utils/json-path.utils.d.ts +22 -0
- package/dist/utils/json-path.utils.js +57 -0
- package/dist/utils/proxy-key.utils.d.ts +6 -1
- package/dist/utils/proxy-key.utils.js +14 -7
- package/dist/utils/query-builder.utils.d.ts +5 -3
- package/dist/utils/query-builder.utils.js +66 -17
- package/dist/utils/sql.utils.d.ts +2 -0
- package/dist/utils/sql.utils.js +5 -1
- package/dist/utils/table.utils.js +3 -14
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -27,13 +27,10 @@ npm install typeorm-extensions
|
|
|
27
27
|
## Usage
|
|
28
28
|
|
|
29
29
|
```typescript
|
|
30
|
-
import
|
|
30
|
+
import 'typeorm-extensions'; // Importing the library root extends the QueryBuilder with all extensions
|
|
31
31
|
|
|
32
32
|
// Or init specific extension: import 'typeorm-extensions/dist/extensions/pagination.extension';
|
|
33
33
|
|
|
34
|
-
// Type-safe SQL fragments for an entity alias
|
|
35
|
-
const t = tableHelper<UserEntity>('users');
|
|
36
|
-
|
|
37
34
|
const query = myDataSource
|
|
38
35
|
.getRepository(UserEntity)
|
|
39
36
|
.createQueryBuilder('users')
|
|
@@ -47,7 +44,8 @@ const query = myDataSource
|
|
|
47
44
|
user.images.url,
|
|
48
45
|
])
|
|
49
46
|
.whereTyped(user => user.name, 'ILIKE', 'John')
|
|
50
|
-
|
|
47
|
+
// Paths into JSON columns: "users"."metadata" ->> 'role' = :param
|
|
48
|
+
.andWhereTyped(user => user.metadata.role, '=', 'admin')
|
|
51
49
|
// Order by type-safe own and relation properties
|
|
52
50
|
.orderByTyped(user => user.images.url, 'ASC', 'NULLS LAST')
|
|
53
51
|
// Use pagination as simple as that
|
|
@@ -10,7 +10,7 @@ const period_utils_1 = require("../../../utils/period.utils");
|
|
|
10
10
|
const extension = {
|
|
11
11
|
prototype: {
|
|
12
12
|
applyPeriodFilterTyped(selection, periodFilter, options) {
|
|
13
|
-
const column = (0, query_builder_utils_1.getTypedSingleColumnKey)(this, selection, 'applyPeriodFilterTyped');
|
|
13
|
+
const column = (0, query_builder_utils_1.getTypedSingleColumnKey)(this, selection, 'applyPeriodFilterTyped', { asTimestamp: true });
|
|
14
14
|
return (0, period_utils_1.attachPeriodFilter)(this, column, periodFilter, options);
|
|
15
15
|
},
|
|
16
16
|
},
|
|
@@ -1,144 +1,53 @@
|
|
|
1
1
|
import '../../where-is-any.extension';
|
|
2
2
|
import { ObjectLiteral } from 'typeorm';
|
|
3
3
|
import { DeepUnwrapArray, ProxyColumnValueType } from '../../../types/modules/proxy-callback.types';
|
|
4
|
-
import {
|
|
4
|
+
import { TypedArrayArg, TypeOrDefault, UnsetType } from '../../../types/modules/typed-params.types';
|
|
5
|
+
export interface TypedWhereIsAnyMethods<Entity extends ObjectLiteral> {
|
|
6
|
+
/**
|
|
7
|
+
* Sets WHERE `column = ANY(:array)` condition in the query builder (PostgreSQL).
|
|
8
|
+
* The array is bound as a single parameter instead of one parameter per value.
|
|
9
|
+
* `arrayType` (e.g. `'uuid[]'`) casts the parameter: `= ANY(CAST(:array AS uuid[]))`.
|
|
10
|
+
* If you had previously WHERE expression defined,
|
|
11
|
+
* calling this function will override previously set WHERE conditions.
|
|
12
|
+
*/
|
|
13
|
+
whereIsAnyTyped<Type extends ObjectLiteral = UnsetType, Value extends ProxyColumnValueType = ProxyColumnValueType>(where: (proxy: DeepUnwrapArray<TypeOrDefault<Type, Entity>>) => Value, array?: TypedArrayArg<Type, Value>, arrayType?: string): this;
|
|
14
|
+
/**
|
|
15
|
+
* Adds new AND WHERE `column = ANY(:array)` condition in the query builder (PostgreSQL).
|
|
16
|
+
*/
|
|
17
|
+
andWhereIsAnyTyped<Type extends ObjectLiteral = UnsetType, Value extends ProxyColumnValueType = ProxyColumnValueType>(where: (proxy: DeepUnwrapArray<TypeOrDefault<Type, Entity>>) => Value, array?: TypedArrayArg<Type, Value>, arrayType?: string): this;
|
|
18
|
+
/**
|
|
19
|
+
* Adds new OR WHERE `column = ANY(:array)` condition in the query builder (PostgreSQL).
|
|
20
|
+
*/
|
|
21
|
+
orWhereIsAnyTyped<Type extends ObjectLiteral = UnsetType, Value extends ProxyColumnValueType = ProxyColumnValueType>(where: (proxy: DeepUnwrapArray<TypeOrDefault<Type, Entity>>) => Value, array?: TypedArrayArg<Type, Value>, arrayType?: string): this;
|
|
22
|
+
/**
|
|
23
|
+
* Sets WHERE `column <> ALL(:array)` condition in the query builder (PostgreSQL):
|
|
24
|
+
* the column differs from every value of the array.
|
|
25
|
+
* If you had previously WHERE expression defined,
|
|
26
|
+
* calling this function will override previously set WHERE conditions.
|
|
27
|
+
*/
|
|
28
|
+
whereIsNotAnyTyped<Type extends ObjectLiteral = UnsetType, Value extends ProxyColumnValueType = ProxyColumnValueType>(where: (proxy: DeepUnwrapArray<TypeOrDefault<Type, Entity>>) => Value, array?: TypedArrayArg<Type, Value>, arrayType?: string): this;
|
|
29
|
+
/**
|
|
30
|
+
* Adds new AND WHERE `column <> ALL(:array)` condition in the query builder (PostgreSQL).
|
|
31
|
+
*/
|
|
32
|
+
andWhereIsNotAnyTyped<Type extends ObjectLiteral = UnsetType, Value extends ProxyColumnValueType = ProxyColumnValueType>(where: (proxy: DeepUnwrapArray<TypeOrDefault<Type, Entity>>) => Value, array?: TypedArrayArg<Type, Value>, arrayType?: string): this;
|
|
33
|
+
/**
|
|
34
|
+
* Adds new OR WHERE `column <> ALL(:array)` condition in the query builder (PostgreSQL).
|
|
35
|
+
*/
|
|
36
|
+
orWhereIsNotAnyTyped<Type extends ObjectLiteral = UnsetType, Value extends ProxyColumnValueType = ProxyColumnValueType>(where: (proxy: DeepUnwrapArray<TypeOrDefault<Type, Entity>>) => Value, array?: TypedArrayArg<Type, Value>, arrayType?: string): this;
|
|
37
|
+
}
|
|
5
38
|
declare module 'typeorm/query-builder/WhereExpressionBuilder' {
|
|
6
|
-
interface WhereExpressionBuilder {
|
|
7
|
-
/**
|
|
8
|
-
* Sets WHERE `column = ANY(:array)` condition in the query builder (PostgreSQL).
|
|
9
|
-
* The array is bound as a single parameter instead of one parameter per value.
|
|
10
|
-
* `arrayType` (e.g. `'uuid[]'`) casts the parameter: `= ANY(CAST(:array AS uuid[]))`.
|
|
11
|
-
* If you had previously WHERE expression defined,
|
|
12
|
-
* calling this function will override previously set WHERE conditions.
|
|
13
|
-
*/
|
|
14
|
-
whereIsAnyTyped<Type extends ObjectLiteral>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
15
|
-
/**
|
|
16
|
-
* Adds new AND WHERE `column = ANY(:array)` condition in the query builder (PostgreSQL).
|
|
17
|
-
*/
|
|
18
|
-
andWhereIsAnyTyped<Type extends ObjectLiteral>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
19
|
-
/**
|
|
20
|
-
* Adds new OR WHERE `column = ANY(:array)` condition in the query builder (PostgreSQL).
|
|
21
|
-
*/
|
|
22
|
-
orWhereIsAnyTyped<Type extends ObjectLiteral>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
23
|
-
/**
|
|
24
|
-
* Sets WHERE `column <> ALL(:array)` condition in the query builder (PostgreSQL):
|
|
25
|
-
* the column differs from every value of the array.
|
|
26
|
-
* If you had previously WHERE expression defined,
|
|
27
|
-
* calling this function will override previously set WHERE conditions.
|
|
28
|
-
*/
|
|
29
|
-
whereIsNotAnyTyped<Type extends ObjectLiteral>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
30
|
-
/**
|
|
31
|
-
* Adds new AND WHERE `column <> ALL(:array)` condition in the query builder (PostgreSQL).
|
|
32
|
-
*/
|
|
33
|
-
andWhereIsNotAnyTyped<Type extends ObjectLiteral>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
34
|
-
/**
|
|
35
|
-
* Adds new OR WHERE `column <> ALL(:array)` condition in the query builder (PostgreSQL).
|
|
36
|
-
*/
|
|
37
|
-
orWhereIsNotAnyTyped<Type extends ObjectLiteral>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
39
|
+
interface WhereExpressionBuilder extends TypedWhereIsAnyMethods<ObjectLiteral> {
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
declare module 'typeorm/query-builder/SelectQueryBuilder' {
|
|
41
|
-
interface SelectQueryBuilder<Entity extends ObjectLiteral> {
|
|
42
|
-
/**
|
|
43
|
-
* Sets WHERE `column = ANY(:array)` condition in the query builder (PostgreSQL).
|
|
44
|
-
* The array is bound as a single parameter instead of one parameter per value.
|
|
45
|
-
* `arrayType` (e.g. `'uuid[]'`) casts the parameter: `= ANY(CAST(:array AS uuid[]))`.
|
|
46
|
-
* If you had previously WHERE expression defined,
|
|
47
|
-
* calling this function will override previously set WHERE conditions.
|
|
48
|
-
*/
|
|
49
|
-
whereIsAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
50
|
-
/**
|
|
51
|
-
* Adds new AND WHERE `column = ANY(:array)` condition in the query builder (PostgreSQL).
|
|
52
|
-
*/
|
|
53
|
-
andWhereIsAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
54
|
-
/**
|
|
55
|
-
* Adds new OR WHERE `column = ANY(:array)` condition in the query builder (PostgreSQL).
|
|
56
|
-
*/
|
|
57
|
-
orWhereIsAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
58
|
-
/**
|
|
59
|
-
* Sets WHERE `column <> ALL(:array)` condition in the query builder (PostgreSQL):
|
|
60
|
-
* the column differs from every value of the array.
|
|
61
|
-
* If you had previously WHERE expression defined,
|
|
62
|
-
* calling this function will override previously set WHERE conditions.
|
|
63
|
-
*/
|
|
64
|
-
whereIsNotAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
65
|
-
/**
|
|
66
|
-
* Adds new AND WHERE `column <> ALL(:array)` condition in the query builder (PostgreSQL).
|
|
67
|
-
*/
|
|
68
|
-
andWhereIsNotAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
69
|
-
/**
|
|
70
|
-
* Adds new OR WHERE `column <> ALL(:array)` condition in the query builder (PostgreSQL).
|
|
71
|
-
*/
|
|
72
|
-
orWhereIsNotAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
43
|
+
interface SelectQueryBuilder<Entity extends ObjectLiteral> extends TypedWhereIsAnyMethods<Entity> {
|
|
73
44
|
}
|
|
74
45
|
}
|
|
75
46
|
declare module 'typeorm/query-builder/UpdateQueryBuilder' {
|
|
76
|
-
interface UpdateQueryBuilder<Entity extends ObjectLiteral> {
|
|
77
|
-
/**
|
|
78
|
-
* Sets WHERE `column = ANY(:array)` condition in the query builder (PostgreSQL).
|
|
79
|
-
* The array is bound as a single parameter instead of one parameter per value.
|
|
80
|
-
* `arrayType` (e.g. `'uuid[]'`) casts the parameter: `= ANY(CAST(:array AS uuid[]))`.
|
|
81
|
-
* If you had previously WHERE expression defined,
|
|
82
|
-
* calling this function will override previously set WHERE conditions.
|
|
83
|
-
*/
|
|
84
|
-
whereIsAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
85
|
-
/**
|
|
86
|
-
* Adds new AND WHERE `column = ANY(:array)` condition in the query builder (PostgreSQL).
|
|
87
|
-
*/
|
|
88
|
-
andWhereIsAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
89
|
-
/**
|
|
90
|
-
* Adds new OR WHERE `column = ANY(:array)` condition in the query builder (PostgreSQL).
|
|
91
|
-
*/
|
|
92
|
-
orWhereIsAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
93
|
-
/**
|
|
94
|
-
* Sets WHERE `column <> ALL(:array)` condition in the query builder (PostgreSQL):
|
|
95
|
-
* the column differs from every value of the array.
|
|
96
|
-
* If you had previously WHERE expression defined,
|
|
97
|
-
* calling this function will override previously set WHERE conditions.
|
|
98
|
-
*/
|
|
99
|
-
whereIsNotAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
100
|
-
/**
|
|
101
|
-
* Adds new AND WHERE `column <> ALL(:array)` condition in the query builder (PostgreSQL).
|
|
102
|
-
*/
|
|
103
|
-
andWhereIsNotAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
104
|
-
/**
|
|
105
|
-
* Adds new OR WHERE `column <> ALL(:array)` condition in the query builder (PostgreSQL).
|
|
106
|
-
*/
|
|
107
|
-
orWhereIsNotAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
47
|
+
interface UpdateQueryBuilder<Entity extends ObjectLiteral> extends TypedWhereIsAnyMethods<Entity> {
|
|
108
48
|
}
|
|
109
49
|
}
|
|
110
50
|
declare module 'typeorm/query-builder/DeleteQueryBuilder' {
|
|
111
|
-
interface DeleteQueryBuilder<Entity extends ObjectLiteral> {
|
|
112
|
-
/**
|
|
113
|
-
* Sets WHERE `column = ANY(:array)` condition in the query builder (PostgreSQL).
|
|
114
|
-
* The array is bound as a single parameter instead of one parameter per value.
|
|
115
|
-
* `arrayType` (e.g. `'uuid[]'`) casts the parameter: `= ANY(CAST(:array AS uuid[]))`.
|
|
116
|
-
* If you had previously WHERE expression defined,
|
|
117
|
-
* calling this function will override previously set WHERE conditions.
|
|
118
|
-
*/
|
|
119
|
-
whereIsAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
120
|
-
/**
|
|
121
|
-
* Adds new AND WHERE `column = ANY(:array)` condition in the query builder (PostgreSQL).
|
|
122
|
-
*/
|
|
123
|
-
andWhereIsAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
124
|
-
/**
|
|
125
|
-
* Adds new OR WHERE `column = ANY(:array)` condition in the query builder (PostgreSQL).
|
|
126
|
-
*/
|
|
127
|
-
orWhereIsAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
128
|
-
/**
|
|
129
|
-
* Sets WHERE `column <> ALL(:array)` condition in the query builder (PostgreSQL):
|
|
130
|
-
* the column differs from every value of the array.
|
|
131
|
-
* If you had previously WHERE expression defined,
|
|
132
|
-
* calling this function will override previously set WHERE conditions.
|
|
133
|
-
*/
|
|
134
|
-
whereIsNotAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
135
|
-
/**
|
|
136
|
-
* Adds new AND WHERE `column <> ALL(:array)` condition in the query builder (PostgreSQL).
|
|
137
|
-
*/
|
|
138
|
-
andWhereIsNotAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
139
|
-
/**
|
|
140
|
-
* Adds new OR WHERE `column <> ALL(:array)` condition in the query builder (PostgreSQL).
|
|
141
|
-
*/
|
|
142
|
-
orWhereIsNotAnyTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType, arrayType?: string): this;
|
|
51
|
+
interface DeleteQueryBuilder<Entity extends ObjectLiteral> extends TypedWhereIsAnyMethods<Entity> {
|
|
143
52
|
}
|
|
144
53
|
}
|
|
@@ -4,6 +4,7 @@ require("../../where-is-any.extension");
|
|
|
4
4
|
const typeorm_1 = require("typeorm");
|
|
5
5
|
const query_builder_utils_1 = require("../../../utils/query-builder.utils");
|
|
6
6
|
const prototype_utils_1 = require("../../../utils/prototype.utils");
|
|
7
|
+
/* eslint-enable @typescript-eslint/no-empty-interface */
|
|
7
8
|
// patching
|
|
8
9
|
const createWhereIsAnyTypedMethod = (method) => function (where, array, arrayType) {
|
|
9
10
|
return attachWhereIsAnyTyped(this, method, where, array, arrayType);
|
|
@@ -31,7 +32,7 @@ function attachWhereIsAnyTyped(builder, method, where, array, arrayType) {
|
|
|
31
32
|
if (typeof where !== 'function') {
|
|
32
33
|
return builder;
|
|
33
34
|
}
|
|
34
|
-
const key = (0, query_builder_utils_1.getTypedSingleColumnKey)(builder, where, `${method}Typed
|
|
35
|
+
const key = (0, query_builder_utils_1.getTypedSingleColumnKey)(builder, where, `${method}Typed`, { value: array });
|
|
35
36
|
// .andWhere(`"table"."column" = ANY(:param)`, { param: ['value'] })
|
|
36
37
|
return builder[method](key, array, arrayType);
|
|
37
38
|
}
|
|
@@ -32,7 +32,7 @@ function attachWhereDistinctTyped(builder, method, where, value) {
|
|
|
32
32
|
if (typeof where !== 'function') {
|
|
33
33
|
return builder;
|
|
34
34
|
}
|
|
35
|
-
const key = (0, query_builder_utils_1.getTypedSingleColumnKey)(builder, where, `${method}Typed
|
|
35
|
+
const key = (0, query_builder_utils_1.getTypedSingleColumnKey)(builder, where, `${method}Typed`, { value });
|
|
36
36
|
// .andWhereIsDistinctFrom(`"table"."column"`, value)
|
|
37
37
|
return builder[method](key, value);
|
|
38
38
|
}
|
|
@@ -1,132 +1,50 @@
|
|
|
1
1
|
import '../../where-is-in.extension';
|
|
2
2
|
import { ObjectLiteral } from 'typeorm';
|
|
3
3
|
import { DeepUnwrapArray, ProxyColumnValueType } from '../../../types/modules/proxy-callback.types';
|
|
4
|
-
import {
|
|
4
|
+
import { TypedArrayArg, TypeOrDefault, UnsetType } from '../../../types/modules/typed-params.types';
|
|
5
|
+
export interface TypedWhereIsInMethods<Entity extends ObjectLiteral> {
|
|
6
|
+
/**
|
|
7
|
+
* Sets WHERE IN condition in the query builder.
|
|
8
|
+
* If you had previously WHERE expression defined,
|
|
9
|
+
* calling this function will override previously set WHERE conditions.
|
|
10
|
+
*/
|
|
11
|
+
whereIsInTyped<Type extends ObjectLiteral = UnsetType, Value extends ProxyColumnValueType = ProxyColumnValueType>(where: (proxy: DeepUnwrapArray<TypeOrDefault<Type, Entity>>) => Value, array?: TypedArrayArg<Type, Value>): this;
|
|
12
|
+
/**
|
|
13
|
+
* Adds new AND WHERE IN condition in the query builder.
|
|
14
|
+
*/
|
|
15
|
+
andWhereIsInTyped<Type extends ObjectLiteral = UnsetType, Value extends ProxyColumnValueType = ProxyColumnValueType>(where: (proxy: DeepUnwrapArray<TypeOrDefault<Type, Entity>>) => Value, array?: TypedArrayArg<Type, Value>): this;
|
|
16
|
+
/**
|
|
17
|
+
* Adds new OR WHERE IN condition in the query builder.
|
|
18
|
+
*/
|
|
19
|
+
orWhereIsInTyped<Type extends ObjectLiteral = UnsetType, Value extends ProxyColumnValueType = ProxyColumnValueType>(where: (proxy: DeepUnwrapArray<TypeOrDefault<Type, Entity>>) => Value, array?: TypedArrayArg<Type, Value>): this;
|
|
20
|
+
/**
|
|
21
|
+
* Sets WHERE NOT IN condition in the query builder.
|
|
22
|
+
* If you had previously WHERE expression defined,
|
|
23
|
+
* calling this function will override previously set WHERE conditions.
|
|
24
|
+
*/
|
|
25
|
+
whereIsNotInTyped<Type extends ObjectLiteral = UnsetType, Value extends ProxyColumnValueType = ProxyColumnValueType>(where: (proxy: DeepUnwrapArray<TypeOrDefault<Type, Entity>>) => Value, array?: TypedArrayArg<Type, Value>): this;
|
|
26
|
+
/**
|
|
27
|
+
* Adds new AND WHERE NOT IN condition in the query builder.
|
|
28
|
+
*/
|
|
29
|
+
andWhereIsNotInTyped<Type extends ObjectLiteral = UnsetType, Value extends ProxyColumnValueType = ProxyColumnValueType>(where: (proxy: DeepUnwrapArray<TypeOrDefault<Type, Entity>>) => Value, array?: TypedArrayArg<Type, Value>): this;
|
|
30
|
+
/**
|
|
31
|
+
* Adds new OR WHERE NOT IN condition in the query builder.
|
|
32
|
+
*/
|
|
33
|
+
orWhereIsNotInTyped<Type extends ObjectLiteral = UnsetType, Value extends ProxyColumnValueType = ProxyColumnValueType>(where: (proxy: DeepUnwrapArray<TypeOrDefault<Type, Entity>>) => Value, array?: TypedArrayArg<Type, Value>): this;
|
|
34
|
+
}
|
|
5
35
|
declare module 'typeorm/query-builder/WhereExpressionBuilder' {
|
|
6
|
-
interface WhereExpressionBuilder {
|
|
7
|
-
/**
|
|
8
|
-
* Sets WHERE IN condition in the query builder.
|
|
9
|
-
* If you had previously WHERE expression defined,
|
|
10
|
-
* calling this function will override previously set WHERE conditions.
|
|
11
|
-
*/
|
|
12
|
-
whereIsInTyped<Type extends ObjectLiteral>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
13
|
-
/**
|
|
14
|
-
* Adds new AND WHERE IN condition in the query builder.
|
|
15
|
-
*/
|
|
16
|
-
andWhereIsInTyped<Type extends ObjectLiteral>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
17
|
-
/**
|
|
18
|
-
* Adds new OR WHERE IN condition in the query builder.
|
|
19
|
-
*/
|
|
20
|
-
orWhereIsInTyped<Type extends ObjectLiteral>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
21
|
-
/**
|
|
22
|
-
* Sets WHERE NOT IN condition in the query builder.
|
|
23
|
-
* If you had previously WHERE expression defined,
|
|
24
|
-
* calling this function will override previously set WHERE conditions.
|
|
25
|
-
*/
|
|
26
|
-
whereIsNotInTyped<Type extends ObjectLiteral>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
27
|
-
/**
|
|
28
|
-
* Adds new AND WHERE NOT IN condition in the query builder.
|
|
29
|
-
*/
|
|
30
|
-
andWhereIsNotInTyped<Type extends ObjectLiteral>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
31
|
-
/**
|
|
32
|
-
* Adds new OR WHERE NOT IN condition in the query builder.
|
|
33
|
-
*/
|
|
34
|
-
orWhereIsNotInTyped<Type extends ObjectLiteral>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
36
|
+
interface WhereExpressionBuilder extends TypedWhereIsInMethods<ObjectLiteral> {
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
declare module 'typeorm/query-builder/SelectQueryBuilder' {
|
|
38
|
-
interface SelectQueryBuilder<Entity extends ObjectLiteral> {
|
|
39
|
-
/**
|
|
40
|
-
* Sets WHERE IN condition in the query builder.
|
|
41
|
-
* If you had previously WHERE expression defined,
|
|
42
|
-
* calling this function will override previously set WHERE conditions.
|
|
43
|
-
*/
|
|
44
|
-
whereIsInTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
45
|
-
/**
|
|
46
|
-
* Adds new AND WHERE IN condition in the query builder.
|
|
47
|
-
*/
|
|
48
|
-
andWhereIsInTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
49
|
-
/**
|
|
50
|
-
* Adds new OR WHERE IN condition in the query builder.
|
|
51
|
-
*/
|
|
52
|
-
orWhereIsInTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
53
|
-
/**
|
|
54
|
-
* Sets WHERE NOT IN condition in the query builder.
|
|
55
|
-
* If you had previously WHERE expression defined,
|
|
56
|
-
* calling this function will override previously set WHERE conditions.
|
|
57
|
-
*/
|
|
58
|
-
whereIsNotInTyped<Type extends ObjectLiteral = Entity>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
59
|
-
/**
|
|
60
|
-
* Adds new AND WHERE NOT IN condition in the query builder.
|
|
61
|
-
*/
|
|
62
|
-
andWhereIsNotInTyped<Type extends ObjectLiteral = Entity>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
63
|
-
/**
|
|
64
|
-
* Adds new OR WHERE NOT IN condition in the query builder.
|
|
65
|
-
*/
|
|
66
|
-
orWhereIsNotInTyped<Type extends ObjectLiteral = Entity>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
40
|
+
interface SelectQueryBuilder<Entity extends ObjectLiteral> extends TypedWhereIsInMethods<Entity> {
|
|
67
41
|
}
|
|
68
42
|
}
|
|
69
43
|
declare module 'typeorm/query-builder/UpdateQueryBuilder' {
|
|
70
|
-
interface UpdateQueryBuilder<Entity extends ObjectLiteral> {
|
|
71
|
-
/**
|
|
72
|
-
* Sets WHERE IN condition in the query builder.
|
|
73
|
-
* If you had previously WHERE expression defined,
|
|
74
|
-
* calling this function will override previously set WHERE conditions.
|
|
75
|
-
*/
|
|
76
|
-
whereIsInTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
77
|
-
/**
|
|
78
|
-
* Adds new AND WHERE IN condition in the query builder.
|
|
79
|
-
*/
|
|
80
|
-
andWhereIsInTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
81
|
-
/**
|
|
82
|
-
* Adds new OR WHERE IN condition in the query builder.
|
|
83
|
-
*/
|
|
84
|
-
orWhereIsInTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
85
|
-
/**
|
|
86
|
-
* Sets WHERE NOT IN condition in the query builder.
|
|
87
|
-
* If you had previously WHERE expression defined,
|
|
88
|
-
* calling this function will override previously set WHERE conditions.
|
|
89
|
-
*/
|
|
90
|
-
whereIsNotInTyped<Type extends ObjectLiteral = Entity>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
91
|
-
/**
|
|
92
|
-
* Adds new AND WHERE NOT IN condition in the query builder.
|
|
93
|
-
*/
|
|
94
|
-
andWhereIsNotInTyped<Type extends ObjectLiteral = Entity>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
95
|
-
/**
|
|
96
|
-
* Adds new OR WHERE NOT IN condition in the query builder.
|
|
97
|
-
*/
|
|
98
|
-
orWhereIsNotInTyped<Type extends ObjectLiteral = Entity>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
44
|
+
interface UpdateQueryBuilder<Entity extends ObjectLiteral> extends TypedWhereIsInMethods<Entity> {
|
|
99
45
|
}
|
|
100
46
|
}
|
|
101
47
|
declare module 'typeorm/query-builder/DeleteQueryBuilder' {
|
|
102
|
-
interface DeleteQueryBuilder<Entity extends ObjectLiteral> {
|
|
103
|
-
/**
|
|
104
|
-
* Sets WHERE IN condition in the query builder.
|
|
105
|
-
* If you had previously WHERE expression defined,
|
|
106
|
-
* calling this function will override previously set WHERE conditions.
|
|
107
|
-
*/
|
|
108
|
-
whereIsInTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
109
|
-
/**
|
|
110
|
-
* Adds new AND WHERE IN condition in the query builder.
|
|
111
|
-
*/
|
|
112
|
-
andWhereIsInTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
113
|
-
/**
|
|
114
|
-
* Adds new OR WHERE IN condition in the query builder.
|
|
115
|
-
*/
|
|
116
|
-
orWhereIsInTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
117
|
-
/**
|
|
118
|
-
* Sets WHERE NOT IN condition in the query builder.
|
|
119
|
-
* If you had previously WHERE expression defined,
|
|
120
|
-
* calling this function will override previously set WHERE conditions.
|
|
121
|
-
*/
|
|
122
|
-
whereIsNotInTyped<Type extends ObjectLiteral = Entity>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
123
|
-
/**
|
|
124
|
-
* Adds new AND WHERE NOT IN condition in the query builder.
|
|
125
|
-
*/
|
|
126
|
-
andWhereIsNotInTyped<Type extends ObjectLiteral = Entity>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
127
|
-
/**
|
|
128
|
-
* Adds new OR WHERE NOT IN condition in the query builder.
|
|
129
|
-
*/
|
|
130
|
-
orWhereIsNotInTyped<Type extends ObjectLiteral = Entity>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, array?: ArgsType): this;
|
|
48
|
+
interface DeleteQueryBuilder<Entity extends ObjectLiteral> extends TypedWhereIsInMethods<Entity> {
|
|
131
49
|
}
|
|
132
50
|
}
|
|
@@ -4,27 +4,19 @@ require("../../where-is-in.extension");
|
|
|
4
4
|
const typeorm_1 = require("typeorm");
|
|
5
5
|
const query_builder_utils_1 = require("../../../utils/query-builder.utils");
|
|
6
6
|
const prototype_utils_1 = require("../../../utils/prototype.utils");
|
|
7
|
+
/* eslint-enable @typescript-eslint/no-empty-interface */
|
|
7
8
|
// patching
|
|
9
|
+
const createWhereIsInTypedMethod = (method) => function (where, array) {
|
|
10
|
+
return attachWhereIsIn(this, method, where, array);
|
|
11
|
+
};
|
|
8
12
|
const extension = {
|
|
9
13
|
prototype: {
|
|
10
|
-
whereIsInTyped:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
orWhereIsInTyped: function (where, array) {
|
|
17
|
-
return attachWhereIsIn(this, 'orWhereIsIn', where, array);
|
|
18
|
-
},
|
|
19
|
-
whereIsNotInTyped: function (where, array) {
|
|
20
|
-
return attachWhereIsIn(this, 'whereIsNotIn', where, array);
|
|
21
|
-
},
|
|
22
|
-
andWhereIsNotInTyped: function (where, array) {
|
|
23
|
-
return attachWhereIsIn(this, 'andWhereIsNotIn', where, array);
|
|
24
|
-
},
|
|
25
|
-
orWhereIsNotInTyped: function (where, array) {
|
|
26
|
-
return attachWhereIsIn(this, 'orWhereIsNotIn', where, array);
|
|
27
|
-
},
|
|
14
|
+
whereIsInTyped: createWhereIsInTypedMethod('whereIsIn'),
|
|
15
|
+
andWhereIsInTyped: createWhereIsInTypedMethod('andWhereIsIn'),
|
|
16
|
+
orWhereIsInTyped: createWhereIsInTypedMethod('orWhereIsIn'),
|
|
17
|
+
whereIsNotInTyped: createWhereIsInTypedMethod('whereIsNotIn'),
|
|
18
|
+
andWhereIsNotInTyped: createWhereIsInTypedMethod('andWhereIsNotIn'),
|
|
19
|
+
orWhereIsNotInTyped: createWhereIsInTypedMethod('orWhereIsNotIn'),
|
|
28
20
|
},
|
|
29
21
|
};
|
|
30
22
|
const queryBuilders = [
|
|
@@ -39,7 +31,7 @@ queryBuilders.forEach((builder) => {
|
|
|
39
31
|
function attachWhereIsIn(builder, method, where, array) {
|
|
40
32
|
if (typeof where === 'function') {
|
|
41
33
|
// several columns have no single meaning (AND? OR?), and `where…` kept only the last one
|
|
42
|
-
const key = (0, query_builder_utils_1.getTypedSingleColumnKey)(builder, where, `${method}Typed
|
|
34
|
+
const key = (0, query_builder_utils_1.getTypedSingleColumnKey)(builder, where, `${method}Typed`, { value: array });
|
|
43
35
|
// .andWhere(`"table"."column" IN (:...values)`, { values: ['value'] })
|
|
44
36
|
return builder[method](key, array);
|
|
45
37
|
}
|
|
@@ -32,7 +32,7 @@ function attachWhereJsonTyped(builder, method, where, value) {
|
|
|
32
32
|
if (typeof where !== 'function') {
|
|
33
33
|
return builder;
|
|
34
34
|
}
|
|
35
|
-
const key = (0, query_builder_utils_1.getTypedSingleColumnKey)(builder, where, `${method}Typed
|
|
35
|
+
const key = (0, query_builder_utils_1.getTypedSingleColumnKey)(builder, where, `${method}Typed`, { accessor: 'json' });
|
|
36
36
|
// .andWhereJsonContains(`"table"."column"`, { role: 'admin' }) / .andWhereJsonHasKey(`"table"."column"`, 'role')
|
|
37
37
|
// (one signature for both: `value` is the JSON value or the key, each method checks its own)
|
|
38
38
|
return builder[method](key, value);
|
|
@@ -1,87 +1,43 @@
|
|
|
1
1
|
import { ObjectLiteral } from 'typeorm';
|
|
2
2
|
import { DeepUnwrapArray, ProxyColumnValueType } from '../../../types/modules/proxy-callback.types';
|
|
3
|
-
import {
|
|
3
|
+
import { TypedWhereArgs, TypeOrDefault, UnsetType } from '../../../types/modules/typed-params.types';
|
|
4
|
+
/**
|
|
5
|
+
* Typesafe WHERE conditions: the column comes from an entity property.
|
|
6
|
+
* `Type` defaults to the query builder's entity; with the `strictParams` option (see `TypeormExtensionsConfig`)
|
|
7
|
+
* the parameter is checked against the type of the selected column.
|
|
8
|
+
*/
|
|
9
|
+
export interface TypedWhereMethods<Entity extends ObjectLiteral> {
|
|
10
|
+
/**
|
|
11
|
+
* Sets WHERE condition in the query builder.
|
|
12
|
+
* If you had previously WHERE expression defined,
|
|
13
|
+
* calling this function will override previously set WHERE conditions.
|
|
14
|
+
* Additionally you can add parameters used in where expression.
|
|
15
|
+
*/
|
|
16
|
+
whereTyped<Type extends ObjectLiteral = UnsetType, Value extends ProxyColumnValueType = ProxyColumnValueType, Operator extends string = string>(where: (proxy: DeepUnwrapArray<TypeOrDefault<Type, Entity>>) => Value, conditions: Operator, ...args: TypedWhereArgs<Type, Operator, Value>): this;
|
|
17
|
+
/**
|
|
18
|
+
* Adds new AND WHERE condition in the query builder.
|
|
19
|
+
* Additionally you can add parameters used in where expression.
|
|
20
|
+
*/
|
|
21
|
+
andWhereTyped<Type extends ObjectLiteral = UnsetType, Value extends ProxyColumnValueType = ProxyColumnValueType, Operator extends string = string>(where: (proxy: DeepUnwrapArray<TypeOrDefault<Type, Entity>>) => Value, conditions: Operator, ...args: TypedWhereArgs<Type, Operator, Value>): this;
|
|
22
|
+
/**
|
|
23
|
+
* Adds new OR WHERE condition in the query builder.
|
|
24
|
+
* Additionally you can add parameters used in where expression.
|
|
25
|
+
*/
|
|
26
|
+
orWhereTyped<Type extends ObjectLiteral = UnsetType, Value extends ProxyColumnValueType = ProxyColumnValueType, Operator extends string = string>(where: (proxy: DeepUnwrapArray<TypeOrDefault<Type, Entity>>) => Value, conditions: Operator, ...args: TypedWhereArgs<Type, Operator, Value>): this;
|
|
27
|
+
}
|
|
4
28
|
declare module 'typeorm/query-builder/WhereExpressionBuilder' {
|
|
5
|
-
interface WhereExpressionBuilder {
|
|
6
|
-
/**
|
|
7
|
-
* Sets WHERE condition in the query builder.
|
|
8
|
-
* If you had previously WHERE expression defined,
|
|
9
|
-
* calling this function will override previously set WHERE conditions.
|
|
10
|
-
* Additionally you can add parameters used in where expression.
|
|
11
|
-
*/
|
|
12
|
-
whereTyped<Type extends ObjectLiteral>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, conditions: string, parameters?: unknown, options?: TypedWhereOptions): this;
|
|
13
|
-
/**
|
|
14
|
-
* Adds new AND WHERE condition in the query builder.
|
|
15
|
-
* Additionally you can add parameters used in where expression.
|
|
16
|
-
*/
|
|
17
|
-
andWhereTyped<Type extends ObjectLiteral>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, conditions: string, parameters?: unknown, options?: TypedWhereOptions): this;
|
|
18
|
-
/**
|
|
19
|
-
* Adds new OR WHERE condition in the query builder.
|
|
20
|
-
* Additionally you can add parameters used in where expression.
|
|
21
|
-
*/
|
|
22
|
-
orWhereTyped<Type extends ObjectLiteral>(subQuery: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, conditions: string, parameters?: unknown, options?: TypedWhereOptions): this;
|
|
29
|
+
interface WhereExpressionBuilder extends TypedWhereMethods<ObjectLiteral> {
|
|
23
30
|
}
|
|
24
31
|
}
|
|
25
32
|
declare module 'typeorm/query-builder/SelectQueryBuilder' {
|
|
26
|
-
interface SelectQueryBuilder<Entity> {
|
|
27
|
-
/**
|
|
28
|
-
* Sets WHERE condition in the query builder.
|
|
29
|
-
* If you had previously WHERE expression defined,
|
|
30
|
-
* calling this function will override previously set WHERE conditions.
|
|
31
|
-
* Additionally you can add parameters used in where expression.
|
|
32
|
-
*/
|
|
33
|
-
whereTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, conditions: string, parameters?: unknown, options?: TypedWhereOptions): this;
|
|
34
|
-
/**
|
|
35
|
-
* Adds new AND WHERE condition in the query builder.
|
|
36
|
-
* Additionally you can add parameters used in where expression.
|
|
37
|
-
*/
|
|
38
|
-
andWhereTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, conditions: string, parameters?: unknown, options?: TypedWhereOptions): this;
|
|
39
|
-
/**
|
|
40
|
-
* Adds new OR WHERE condition in the query builder.
|
|
41
|
-
* Additionally you can add parameters used in where expression.
|
|
42
|
-
*/
|
|
43
|
-
orWhereTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, conditions: string, parameters?: unknown, options?: TypedWhereOptions): this;
|
|
33
|
+
interface SelectQueryBuilder<Entity extends ObjectLiteral> extends TypedWhereMethods<Entity> {
|
|
44
34
|
}
|
|
45
35
|
}
|
|
46
36
|
declare module 'typeorm/query-builder/UpdateQueryBuilder' {
|
|
47
|
-
interface UpdateQueryBuilder<Entity> {
|
|
48
|
-
/**
|
|
49
|
-
* Sets WHERE condition in the query builder.
|
|
50
|
-
* If you had previously WHERE expression defined,
|
|
51
|
-
* calling this function will override previously set WHERE conditions.
|
|
52
|
-
* Additionally you can add parameters used in where expression.
|
|
53
|
-
*/
|
|
54
|
-
whereTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, conditions: string, parameters?: unknown, options?: TypedWhereOptions): this;
|
|
55
|
-
/**
|
|
56
|
-
* Adds new AND WHERE condition in the query builder.
|
|
57
|
-
* Additionally you can add parameters used in where expression.
|
|
58
|
-
*/
|
|
59
|
-
andWhereTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, conditions: string, parameters?: unknown, options?: TypedWhereOptions): this;
|
|
60
|
-
/**
|
|
61
|
-
* Adds new OR WHERE condition in the query builder.
|
|
62
|
-
* Additionally you can add parameters used in where expression.
|
|
63
|
-
*/
|
|
64
|
-
orWhereTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, conditions: string, parameters?: unknown, options?: TypedWhereOptions): this;
|
|
37
|
+
interface UpdateQueryBuilder<Entity extends ObjectLiteral> extends TypedWhereMethods<Entity> {
|
|
65
38
|
}
|
|
66
39
|
}
|
|
67
40
|
declare module 'typeorm/query-builder/DeleteQueryBuilder' {
|
|
68
|
-
interface DeleteQueryBuilder<Entity> {
|
|
69
|
-
/**
|
|
70
|
-
* Sets WHERE condition in the query builder.
|
|
71
|
-
* If you had previously WHERE expression defined,
|
|
72
|
-
* calling this function will override previously set WHERE conditions.
|
|
73
|
-
* Additionally you can add parameters used in where expression.
|
|
74
|
-
*/
|
|
75
|
-
whereTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, conditions: string, parameters?: unknown, options?: TypedWhereOptions): this;
|
|
76
|
-
/**
|
|
77
|
-
* Adds new AND WHERE condition in the query builder.
|
|
78
|
-
* Additionally you can add parameters used in where expression.
|
|
79
|
-
*/
|
|
80
|
-
andWhereTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, conditions: string, parameters?: unknown, options?: TypedWhereOptions): this;
|
|
81
|
-
/**
|
|
82
|
-
* Adds new OR WHERE condition in the query builder.
|
|
83
|
-
* Additionally you can add parameters used in where expression.
|
|
84
|
-
*/
|
|
85
|
-
orWhereTyped<Type extends ObjectLiteral = Entity>(where: (proxy: DeepUnwrapArray<Type>) => ProxyColumnValueType, conditions: string, parameters?: unknown, options?: TypedWhereOptions): this;
|
|
41
|
+
interface DeleteQueryBuilder<Entity extends ObjectLiteral> extends TypedWhereMethods<Entity> {
|
|
86
42
|
}
|
|
87
43
|
}
|
|
@@ -4,18 +4,16 @@ const typeorm_1 = require("typeorm");
|
|
|
4
4
|
const query_builder_utils_1 = require("../../../utils/query-builder.utils");
|
|
5
5
|
const prototype_utils_1 = require("../../../utils/prototype.utils");
|
|
6
6
|
const where_utils_1 = require("../../../utils/where.utils");
|
|
7
|
+
/* eslint-enable @typescript-eslint/no-empty-interface */
|
|
7
8
|
// patching
|
|
9
|
+
const createWhereTypedMethod = (method) => function (where, conditions, parameters, options) {
|
|
10
|
+
return attachTypedWhere(this, method, where, conditions, parameters, options);
|
|
11
|
+
};
|
|
8
12
|
const extension = {
|
|
9
13
|
prototype: {
|
|
10
|
-
whereTyped:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
andWhereTyped: function (where, operator, parameters, options) {
|
|
14
|
-
return attachTypedWhere(this, 'andWhere', where, operator, parameters, options);
|
|
15
|
-
},
|
|
16
|
-
orWhereTyped: function (where, operator, parameters, options) {
|
|
17
|
-
return attachTypedWhere(this, 'orWhere', where, operator, parameters, options);
|
|
18
|
-
},
|
|
14
|
+
whereTyped: createWhereTypedMethod('where'),
|
|
15
|
+
andWhereTyped: createWhereTypedMethod('andWhere'),
|
|
16
|
+
orWhereTyped: createWhereTypedMethod('orWhere'),
|
|
19
17
|
},
|
|
20
18
|
};
|
|
21
19
|
const queryBuilders = [
|
|
@@ -31,7 +29,9 @@ function attachTypedWhere(builder, method, where, conditions, parameters, option
|
|
|
31
29
|
const { addValue } = options || {};
|
|
32
30
|
if (typeof where === 'function') {
|
|
33
31
|
// several columns have no single meaning (AND? OR?), and `where…` kept only the last one
|
|
34
|
-
|
|
32
|
+
// a path into a JSON column is cast to the type of the value it is compared with
|
|
33
|
+
const value = (0, where_utils_1.isParamsObject)(parameters) ? Object.values(parameters)[0] : parameters;
|
|
34
|
+
const key = (0, query_builder_utils_1.getTypedSingleColumnKey)(builder, where, `${method}Typed`, { value });
|
|
35
35
|
return (0, where_utils_1.attachWhere)(builder, method, key, conditions, parameters, {
|
|
36
36
|
addValue,
|
|
37
37
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './extensions';
|
|
2
2
|
export * from './types/interfaces';
|
|
3
3
|
export * from './types/extensions';
|
|
4
|
+
export type { Json } from './types/modules/proxy-callback.types';
|
|
4
5
|
export * from './utils/table.utils';
|
|
5
6
|
export { escapeLikePattern } from './utils/search.utils';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compile-time options of the library, switched on by augmenting this interface in your project:
|
|
3
|
+
*
|
|
4
|
+
* ```ts
|
|
5
|
+
* declare module 'typeorm-extensions' {
|
|
6
|
+
* interface TypeormExtensionsConfig {
|
|
7
|
+
* strictParams: true;
|
|
8
|
+
* }
|
|
9
|
+
* }
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* - `strictParams`: typed where methods check their value against the type of the column the callback
|
|
13
|
+
* selects (`whereTyped(q => q.price, '>', '10')` doesn't compile for a `number` column). Applies to calls
|
|
14
|
+
* without an explicit type argument: `whereTyped<Joins>(…)` keeps unchecked parameters.
|
|
15
|
+
*/
|
|
16
|
+
export interface TypeormExtensionsConfig {
|
|
17
|
+
}
|
|
@@ -18,3 +18,4 @@ __exportStar(require("./ordering.interface"), exports);
|
|
|
18
18
|
__exportStar(require("./pagination.interface"), exports);
|
|
19
19
|
__exportStar(require("./period.interface"), exports);
|
|
20
20
|
__exportStar(require("./cursor-pagination.interface"), exports);
|
|
21
|
+
__exportStar(require("./config.interface"), exports);
|
|
@@ -4,25 +4,49 @@ import { ColumnValueType } from "./column.types";
|
|
|
4
4
|
import { UnwrapArray } from "../util-types";
|
|
5
5
|
export type ProxyColumnValueType = ColumnValueType | ':value';
|
|
6
6
|
type ProxyPropertyType<V> = NonNullable<V> extends readonly (infer U)[] ? NonNullable<U> : NonNullable<V>;
|
|
7
|
+
/** Objects that are column values, not relations or JSON objects to go into. */
|
|
8
|
+
type ProxyLeafObject = Date | ArrayBufferView | ArrayBuffer;
|
|
9
|
+
type IsProxyBranch<V> = ProxyPropertyType<V> extends ProxyLeafObject ? false : ProxyPropertyType<V> extends object ? true : false;
|
|
10
|
+
declare const jsonColumn: unique symbol;
|
|
11
|
+
/**
|
|
12
|
+
* Marks an entity property as a JSON column for typed callbacks, which then go into it at any depth:
|
|
13
|
+
* `(e) => e.details.meta.endTs` is `"e"."details" -> 'meta' ->> 'endTs'` in where methods. Without it a typed key
|
|
14
|
+
* stops at `alias.column` (`e.details.outcome`), as it does for relations. Values are assignable both ways.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* @Column({ type: 'jsonb' })
|
|
18
|
+
* details: Json<ExecutionDetails>;
|
|
19
|
+
*/
|
|
20
|
+
export type Json<T> = T & {
|
|
21
|
+
readonly [jsonColumn]?: true;
|
|
22
|
+
};
|
|
23
|
+
type IsJsonColumn<V> = typeof jsonColumn extends keyof NonNullable<V> ? true : false;
|
|
24
|
+
type IsJsonObject<V> = NonNullable<V> extends ProxyLeafObject | readonly unknown[] ? false : NonNullable<V> extends object ? true : false;
|
|
25
|
+
/** Inside a JSON column: objects to go into at any depth, while arrays and dates are values. */
|
|
26
|
+
type JsonPathProxy<T> = {
|
|
27
|
+
[K in keyof T as K extends typeof jsonColumn ? never : K]-?: IsJsonObject<T[K]> extends true ? JsonPathProxy<NonNullable<T[K]>> : T[K];
|
|
28
|
+
};
|
|
29
|
+
type JsonColumnProxy<V> = NonNullable<V> extends readonly unknown[] ? V : JsonPathProxy<NonNullable<V>>;
|
|
7
30
|
/**
|
|
8
31
|
* End of a typed key path. Typed keys are `column` or `alias.column` (`relation.column`),
|
|
9
32
|
* so an object at the second level (a nested relation, a JSON sub-object) can be selected
|
|
10
33
|
* as a whole but not dereferenced further: `u => u.images.user.email` is a compile error.
|
|
11
|
-
* Address deeper relations by their join alias with an alias-keyed type instead
|
|
34
|
+
* Address deeper relations by their join alias with an alias-keyed type instead, and mark
|
|
35
|
+
* JSON columns with {@link Json} to go deeper into them.
|
|
12
36
|
*/
|
|
13
37
|
export interface KeyPathEnd {
|
|
14
38
|
readonly __keyPathEnd: never;
|
|
15
39
|
}
|
|
16
40
|
type ProxySecondLevel<T> = {
|
|
17
|
-
[K in keyof T]-?:
|
|
41
|
+
[K in keyof T]-?: IsJsonColumn<T[K]> extends true ? JsonColumnProxy<T[K]> : IsProxyBranch<T[K]> extends true ? KeyPathEnd : T[K];
|
|
18
42
|
};
|
|
19
43
|
/**
|
|
20
44
|
* Type of the proxy passed to typed callbacks: two levels (`column` or `alias.column`),
|
|
21
45
|
* with arrays unwrapped (`user.images.url` for `images: ImageEntity[]`) and optional
|
|
22
|
-
* properties made required.
|
|
46
|
+
* properties made required. A {@link Json} column is open at any depth.
|
|
23
47
|
*/
|
|
24
48
|
export type DeepUnwrapArray<T> = {
|
|
25
|
-
[K in keyof T]-?:
|
|
49
|
+
[K in keyof T]-?: IsJsonColumn<T[K]> extends true ? JsonColumnProxy<T[K]> : IsProxyBranch<T[K]> extends true ? ProxySecondLevel<ProxyPropertyType<T[K]>> : T[K];
|
|
26
50
|
};
|
|
27
51
|
export type KeyProxyCallback<T extends ObjectLiteral> = (proxy: DeepUnwrapArray<T>) => ProxyColumnValueType | Array<ProxyColumnValueType>;
|
|
28
52
|
export type RelationalKeyProxyCallback<T extends ObjectLiteral> = (proxy: DeepUnwrapArray<EntityOnlyWithRelations<T>>) => ProxyColumnValueType;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { TypeormExtensionsConfig } from '../interfaces/config.interface';
|
|
2
|
+
import type { TypedWhereOptions } from '../extensions/typed-where.types';
|
|
3
|
+
import type { ArgsType } from '../util-types';
|
|
4
|
+
declare const unsetType: unique symbol;
|
|
5
|
+
/**
|
|
6
|
+
* Default of the `Type` argument of typed methods. Tells a call without a type argument, whose proxy is
|
|
7
|
+
* typed by the query builder's entity, from an explicit `whereTyped<Joins>(…)`.
|
|
8
|
+
*/
|
|
9
|
+
export interface UnsetType {
|
|
10
|
+
readonly [unsetType]: true;
|
|
11
|
+
}
|
|
12
|
+
/** Blocks inference from this position, so the column type comes from the callback alone (`NoInfer` before TypeScript 5.4). */
|
|
13
|
+
type NoInferType<T> = [T][T extends unknown ? 0 : never];
|
|
14
|
+
/** Whether `Type` was left out; an explicit `<any>` is assignable to `UnsetType` but was given. */
|
|
15
|
+
type IsUnset<Type> = 0 extends 1 & Type ? false : [Type] extends [UnsetType] ? true : false;
|
|
16
|
+
export type TypeOrDefault<Type, Default> = IsUnset<Type> extends true ? Default : Type;
|
|
17
|
+
type IsStrict<Type> = TypeormExtensionsConfig extends {
|
|
18
|
+
strictParams: true;
|
|
19
|
+
} ? IsUnset<Type> : false;
|
|
20
|
+
/** A column's value as a parameter: never `null` / `undefined` (they turn `= :value` into `= NULL`); a date may be a string. */
|
|
21
|
+
export type ParamValue<Value> = NonNullable<Value> extends Date ? Date | string : NonNullable<Value>;
|
|
22
|
+
type IsValueObject<P> = [P] extends [Date | ArrayBufferView | ArrayBuffer | readonly unknown[]] ? true : false;
|
|
23
|
+
/**
|
|
24
|
+
* The value itself, or a `{ name: value }` params object. A plain object value (a JSON column) can only be
|
|
25
|
+
* passed in a params object: at runtime a plain object always is one.
|
|
26
|
+
*/
|
|
27
|
+
type DirectOrField<P> = [P] extends [object] ? IsValueObject<P> extends true ? P | Readonly<Record<string, P>> : Readonly<Record<string, P>> : P | Readonly<Record<string, P>>;
|
|
28
|
+
type Trim<S extends string> = S extends ` ${infer Rest}` ? Trim<Rest> : S extends `${infer Rest} ` ? Trim<Rest> : S;
|
|
29
|
+
type NoValueOperator = 'IS NULL' | 'IS NOT NULL' | 'IS TRUE' | 'IS NOT TRUE' | 'IS FALSE' | 'IS NOT FALSE' | 'IS UNKNOWN' | 'IS NOT UNKNOWN';
|
|
30
|
+
type ComparisonOperator = '=' | '!=' | '<>' | '>' | '<' | '>=' | '<=';
|
|
31
|
+
type DistinctOperator = 'IS DISTINCT FROM' | 'IS NOT DISTINCT FROM';
|
|
32
|
+
type NullOperator = 'IS' | 'IS NOT';
|
|
33
|
+
type ListOperator = 'IN' | 'NOT IN';
|
|
34
|
+
type PatternOperator = 'LIKE' | 'NOT LIKE' | 'ILIKE' | 'NOT ILIKE';
|
|
35
|
+
type LooseWhereArgs = [parameters?: unknown, options?: TypedWhereOptions];
|
|
36
|
+
type ValueArgs<P> = [parameters: DirectOrField<P>, options?: TypedWhereOptions];
|
|
37
|
+
type StrictWhereArgs<Operator extends string, Value> = Uppercase<Trim<Operator>> extends infer Op ? Op extends NoValueOperator ? [parameters?: undefined, options?: TypedWhereOptions] : Op extends ComparisonOperator ? ValueArgs<ParamValue<Value>> : Op extends DistinctOperator ? ValueArgs<ParamValue<Value> | null> : Op extends NullOperator ? ValueArgs<null> : Op extends ListOperator ? ValueArgs<readonly ParamValue<Value>[]> : Op extends PatternOperator ? ValueArgs<string> : LooseWhereArgs : never;
|
|
38
|
+
/**
|
|
39
|
+
* Parameters and options of `whereTyped`. With `strictParams` the parameter is checked against the column type
|
|
40
|
+
* for the operators it knows; conditions written as SQL (`'BETWEEN :from AND :to'`, `'= true'`) aren't checked.
|
|
41
|
+
*/
|
|
42
|
+
export type TypedWhereArgs<Type, Operator extends string, Value> = IsStrict<Type> extends true ? StrictWhereArgs<NoInferType<Operator>, NoInferType<Value>> : LooseWhereArgs;
|
|
43
|
+
/** Values of `whereIsInTyped` / `whereIsAnyTyped`; with `strictParams`, of the column's type. */
|
|
44
|
+
export type TypedArrayArg<Type, Value> = IsStrict<Type> extends true ? readonly ParamValue<NoInferType<Value>>[] : ArgsType;
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
|
|
2
|
+
import type { DatabaseType } from 'typeorm';
|
|
3
|
+
/** `->>` gives the value as text (as an SQL value on SQLite), `->` as JSON. */
|
|
4
|
+
export type JsonAccessor = 'text' | 'json';
|
|
5
|
+
export declare const isJsonColumn: (column: ColumnMetadata) => boolean;
|
|
6
|
+
/** `-> 'settings' ->> 'theme'`: every key but the last one with `->`, the last one with `jsonOperator`. */
|
|
7
|
+
export declare function buildJsonPath(fieldNames: readonly string[], jsonOperator: '->>' | '->'): string;
|
|
8
|
+
export interface JsonPathSqlOptions {
|
|
9
|
+
/** Defaults to `'text'`. */
|
|
10
|
+
accessor?: JsonAccessor;
|
|
11
|
+
/** The value the path is compared with: on PostgreSQL a `'text'` path is cast to its type. */
|
|
12
|
+
value?: unknown;
|
|
13
|
+
/** Compares a `'text'` path as a timestamp whatever `value` is, since a period also takes date strings. */
|
|
14
|
+
asTimestamp?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* SQL for a path inside a JSON column: `"exec"."details" -> 'meta' ->> 'endTs'`, cast on PostgreSQL to the
|
|
18
|
+
* type of the compared value (`CAST(… AS numeric)`). A `simple-json` column is text there, so it is cast to
|
|
19
|
+
* `jsonb` first. SQLite (3.38+) has the same operators, and `->>` gives SQL values, so it needs no cast, except
|
|
20
|
+
* for a timestamp: there it is rewritten in the format TypeORM stores dates and binds `Date` parameters in.
|
|
21
|
+
*/
|
|
22
|
+
export declare function toJsonPathSql(driver: DatabaseType | undefined, columnSql: string, column: ColumnMetadata, jsonPath: readonly string[], { accessor, value, asTimestamp }?: JsonPathSqlOptions): string;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toJsonPathSql = exports.buildJsonPath = exports.isJsonColumn = void 0;
|
|
4
|
+
const sql_utils_1 = require("./sql.utils");
|
|
5
|
+
const JSON_COLUMN_TYPES = ['json', 'jsonb', 'simple-json'];
|
|
6
|
+
const isJsonColumn = (column) => JSON_COLUMN_TYPES.includes(String(column.type));
|
|
7
|
+
exports.isJsonColumn = isJsonColumn;
|
|
8
|
+
/** Wraps a JSON key in single quotes, doubling any quote inside it (standard SQL string literal). */
|
|
9
|
+
const toJsonKeyLiteral = (fieldName) => `'${String(fieldName).replace(/'/g, "''")}'`;
|
|
10
|
+
/** `-> 'settings' ->> 'theme'`: every key but the last one with `->`, the last one with `jsonOperator`. */
|
|
11
|
+
function buildJsonPath(fieldNames, jsonOperator) {
|
|
12
|
+
return fieldNames
|
|
13
|
+
.map((fieldName, index) => `${index === fieldNames.length - 1 ? jsonOperator : '->'} ${toJsonKeyLiteral(fieldName)}`)
|
|
14
|
+
.join(' ');
|
|
15
|
+
}
|
|
16
|
+
exports.buildJsonPath = buildJsonPath;
|
|
17
|
+
const isDate = (value) => Object.prototype.toString.call(value) === '[object Date]';
|
|
18
|
+
/**
|
|
19
|
+
* PostgreSQL type to compare a `->>` value (text) with `value` as: text compares `'9' >= '10'` as true.
|
|
20
|
+
* An array (IN, ANY) is typed by its first value; strings and unknown values stay text.
|
|
21
|
+
*/
|
|
22
|
+
function getJsonTextCast(value) {
|
|
23
|
+
const sample = Array.isArray(value) ? value.find((item) => item !== null && item !== undefined) : value;
|
|
24
|
+
if (typeof sample === 'number' || typeof sample === 'bigint') {
|
|
25
|
+
return 'numeric';
|
|
26
|
+
}
|
|
27
|
+
if (typeof sample === 'boolean') {
|
|
28
|
+
return 'boolean';
|
|
29
|
+
}
|
|
30
|
+
if (isDate(sample)) {
|
|
31
|
+
return 'timestamptz';
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* SQL for a path inside a JSON column: `"exec"."details" -> 'meta' ->> 'endTs'`, cast on PostgreSQL to the
|
|
37
|
+
* type of the compared value (`CAST(… AS numeric)`). A `simple-json` column is text there, so it is cast to
|
|
38
|
+
* `jsonb` first. SQLite (3.38+) has the same operators, and `->>` gives SQL values, so it needs no cast, except
|
|
39
|
+
* for a timestamp: there it is rewritten in the format TypeORM stores dates and binds `Date` parameters in.
|
|
40
|
+
*/
|
|
41
|
+
function toJsonPathSql(driver, columnSql, column, jsonPath, { accessor = 'text', value, asTimestamp = false } = {}) {
|
|
42
|
+
const path = buildJsonPath(jsonPath, accessor === 'json' ? '->' : '->>');
|
|
43
|
+
const isTimestamp = asTimestamp && accessor === 'text';
|
|
44
|
+
if ((0, sql_utils_1.isSqliteLikeDriver)(driver)) {
|
|
45
|
+
const sql = `${columnSql} ${path}`;
|
|
46
|
+
return isTimestamp ? `strftime('%Y-%m-%d %H:%M:%f', ${sql})` : sql;
|
|
47
|
+
}
|
|
48
|
+
if (!(0, sql_utils_1.isPostgresLikeDriver)(driver)) {
|
|
49
|
+
throw new TypeError(`Typed keys into a JSON column (${column.propertyPath}.${jsonPath.join('.')}) are supported on PostgreSQL and SQLite, ` +
|
|
50
|
+
`not on ${driver !== null && driver !== void 0 ? driver : 'a query without a connection'}`);
|
|
51
|
+
}
|
|
52
|
+
const source = String(column.type) === 'simple-json' ? `CAST(${columnSql} AS jsonb)` : columnSql;
|
|
53
|
+
const sql = `${source} ${path}`;
|
|
54
|
+
const cast = isTimestamp ? 'timestamptz' : accessor === 'text' ? getJsonTextCast(value) : undefined;
|
|
55
|
+
return cast ? `CAST(${sql} AS ${cast})` : sql;
|
|
56
|
+
}
|
|
57
|
+
exports.toJsonPathSql = toJsonPathSql;
|
|
@@ -21,7 +21,12 @@ export declare class KeyProxy {
|
|
|
21
21
|
}
|
|
22
22
|
/** Typed keys are `column` or `alias.column`: a deeper path can't be mapped to a query alias. */
|
|
23
23
|
export declare const MAX_KEY_DEPTH = 2;
|
|
24
|
-
export declare const
|
|
24
|
+
export declare const createKeyTooDeepError: (keys: string[]) => TypeError;
|
|
25
|
+
/**
|
|
26
|
+
* Keys of a typed callback. Paths deeper than `alias.column` throw, unless `allowDeepPaths` is set by a caller
|
|
27
|
+
* that checks them against the query's metadata (paths into JSON columns).
|
|
28
|
+
*/
|
|
29
|
+
export declare const getKeyHolder: <Type extends ObjectLiteral>(callback: KeyHolder | KeyProxyCallback<Type>, allowDeepPaths?: boolean) => KeyHolder | Array<KeyHolder>;
|
|
25
30
|
export declare const getKey: <Type extends ObjectLiteral>(callback: string | KeyHolder | KeyProxyCallback<Type>) => string;
|
|
26
31
|
/**
|
|
27
32
|
* Alias to prefix a single-level key with: a string, or a function called only when it is needed,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getSqlKeyFromProxyCallback = exports.getKey = exports.getKeyHolder = exports.MAX_KEY_DEPTH = exports.KeyProxy = exports.TypedProxy = exports.KeyHolder = void 0;
|
|
3
|
+
exports.getSqlKeyFromProxyCallback = exports.getKey = exports.getKeyHolder = exports.createKeyTooDeepError = exports.MAX_KEY_DEPTH = exports.KeyProxy = exports.TypedProxy = exports.KeyHolder = void 0;
|
|
4
4
|
const sql_utils_1 = require("./sql.utils");
|
|
5
5
|
class KeyHolder {
|
|
6
6
|
constructor(_keys = []) {
|
|
@@ -71,24 +71,31 @@ KeyProxy.defaultHandler = {
|
|
|
71
71
|
};
|
|
72
72
|
/** Typed keys are `column` or `alias.column`: a deeper path can't be mapped to a query alias. */
|
|
73
73
|
exports.MAX_KEY_DEPTH = 2;
|
|
74
|
+
const createKeyTooDeepError = (keys) => new TypeError(`Typed key "${keys.join('.')}" is ${keys.length} levels deep, but typed methods support only ` +
|
|
75
|
+
`"column" or "alias.column", or a path into a JSON column in where methods. Join the nested relation and ` +
|
|
76
|
+
`address it by its alias with an alias-keyed type, e.g. type Joins = { someAlias: SomeEntity }; (j) => j.someAlias.column`);
|
|
77
|
+
exports.createKeyTooDeepError = createKeyTooDeepError;
|
|
74
78
|
const assertKeyDepth = (keyHolder) => {
|
|
75
79
|
const keys = keyHolder.getKeys();
|
|
76
80
|
if (keys.length > exports.MAX_KEY_DEPTH) {
|
|
77
|
-
throw
|
|
78
|
-
`"column" or "alias.column". Join the nested relation and address it by its alias ` +
|
|
79
|
-
`with an alias-keyed type, e.g. type Joins = { someAlias: SomeEntity }; (j) => j.someAlias.column`);
|
|
81
|
+
throw (0, exports.createKeyTooDeepError)(keys);
|
|
80
82
|
}
|
|
81
83
|
return keyHolder;
|
|
82
84
|
};
|
|
83
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Keys of a typed callback. Paths deeper than `alias.column` throw, unless `allowDeepPaths` is set by a caller
|
|
87
|
+
* that checks them against the query's metadata (paths into JSON columns).
|
|
88
|
+
*/
|
|
89
|
+
const getKeyHolder = (callback, allowDeepPaths = false) => {
|
|
90
|
+
const check = allowDeepPaths ? (keyHolder) => keyHolder : assertKeyDepth;
|
|
84
91
|
if (typeof callback !== 'function') {
|
|
85
92
|
if (callback instanceof KeyHolder) {
|
|
86
|
-
return
|
|
93
|
+
return check(callback);
|
|
87
94
|
}
|
|
88
95
|
}
|
|
89
96
|
const keyHolder = callback(KeyProxy.create());
|
|
90
97
|
// fail loudly instead of silently dropping levels beyond `alias.column`
|
|
91
|
-
return Array.isArray(keyHolder) ? keyHolder.map(
|
|
98
|
+
return Array.isArray(keyHolder) ? keyHolder.map(check) : check(keyHolder);
|
|
92
99
|
};
|
|
93
100
|
exports.getKeyHolder = getKeyHolder;
|
|
94
101
|
const getKey = (callback) => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ObjectLiteral, WhereExpressionBuilder } from 'typeorm';
|
|
2
2
|
import type { KeyProxyCallback } from '../types/modules/proxy-callback.types';
|
|
3
|
+
import { JsonPathSqlOptions } from './json-path.utils';
|
|
3
4
|
/**
|
|
4
5
|
* Database name of an entity property's column (`@Column({ name })`), looked up in the metadata of
|
|
5
6
|
* a query alias (the main alias when `aliasName` is undefined). `undefined` when the alias has no
|
|
@@ -27,15 +28,16 @@ export declare function toFieldSql(builder: WhereExpressionBuilder, field: strin
|
|
|
27
28
|
*
|
|
28
29
|
* The property is mapped to its database column name (`@Column({ name })`, embedded columns)
|
|
29
30
|
* through the metadata of the alias it belongs to (see `resolveTypedKey`). Aliases without
|
|
30
|
-
* metadata (subqueries) and unknown properties keep the property name.
|
|
31
|
+
* metadata (subqueries) and unknown properties keep the property name. A path into a JSON column
|
|
32
|
+
* gives its JSON accessor, cast on PostgreSQL to the type of `jsonOptions.value`.
|
|
31
33
|
*/
|
|
32
|
-
export declare function getTypedColumnKey<Type extends ObjectLiteral>(builder: WhereExpressionBuilder, callback: KeyProxyCallback<Type
|
|
34
|
+
export declare function getTypedColumnKey<Type extends ObjectLiteral>(builder: WhereExpressionBuilder, callback: KeyProxyCallback<Type>, jsonOptions?: JsonPathSqlOptions): string | string[];
|
|
33
35
|
/**
|
|
34
36
|
* Quoted column of a typed callback that must select exactly one column
|
|
35
37
|
* (`whereIsAnyTyped`, `whereArrayContainsTyped`, …). Throws a `TypeError` for several columns:
|
|
36
38
|
* one condition per column has no single obvious meaning (AND? OR?), so don't guess.
|
|
37
39
|
*/
|
|
38
|
-
export declare function getTypedSingleColumnKey<Type extends ObjectLiteral>(builder: WhereExpressionBuilder, callback: KeyProxyCallback<Type>, methodName: string): string;
|
|
40
|
+
export declare function getTypedSingleColumnKey<Type extends ObjectLiteral>(builder: WhereExpressionBuilder, callback: KeyProxyCallback<Type>, methodName: string, jsonOptions?: JsonPathSqlOptions): string;
|
|
39
41
|
/**
|
|
40
42
|
* Key for typed select / order / distinct on a SelectQueryBuilder.
|
|
41
43
|
*
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getTypedSelectionKey = exports.getTypedSingleColumnKey = exports.getTypedColumnKey = exports.toFieldSql = exports.getColumnDatabaseName = void 0;
|
|
4
4
|
const proxy_key_utils_1 = require("./proxy-key.utils");
|
|
5
|
+
const json_path_utils_1 = require("./json-path.utils");
|
|
5
6
|
const sql_utils_1 = require("./sql.utils");
|
|
6
7
|
/**
|
|
7
8
|
* Whether single-level typed keys are qualified with the main alias (`user.firstName`).
|
|
@@ -94,12 +95,34 @@ function toFieldSql(builder, field) {
|
|
|
94
95
|
return (0, sql_utils_1.stringToSQLIdentifier)(field, (0, sql_utils_1.getDriverType)(builder));
|
|
95
96
|
}
|
|
96
97
|
exports.toFieldSql = toFieldSql;
|
|
98
|
+
/**
|
|
99
|
+
* The column that `keys` name in an entity: the longest prefix of the keys that is a column's property path
|
|
100
|
+
* (`address.city` for an embedded entity). The keys after it are a path inside the column, allowed only in a
|
|
101
|
+
* JSON column (`details` + `['meta', 'endTs']`). `undefined` when no prefix is a column, or a column that isn't
|
|
102
|
+
* JSON is followed by more keys (a relation's join column, `user` in `user.email`).
|
|
103
|
+
*/
|
|
104
|
+
function findColumnPath(metadata, keys) {
|
|
105
|
+
for (let length = keys.length; metadata && length >= 1; length--) {
|
|
106
|
+
const propertyPath = keys.slice(0, length).join('.');
|
|
107
|
+
const column = metadata.findColumnWithPropertyPath(propertyPath);
|
|
108
|
+
if (!column) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (length === keys.length) {
|
|
112
|
+
return { propertyPath, column };
|
|
113
|
+
}
|
|
114
|
+
return (0, json_path_utils_1.isJsonColumn)(column) ? { propertyPath, column, jsonPath: keys.slice(length) } : undefined;
|
|
115
|
+
}
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
97
118
|
/**
|
|
98
119
|
* Splits typed keys into the alias and the property path they refer to:
|
|
99
120
|
* - `t => t.status` → the query's main alias + `status` (no alias on UPDATE / DELETE);
|
|
100
121
|
* - `j => j.t.status`, `u => u.images.url` → the first key, when it is an alias of the query;
|
|
101
122
|
* - `p => p.address.city` → when the first key isn't an alias but the main entity has a column
|
|
102
123
|
* with that path (an embedded entity), the main alias + `address.city`;
|
|
124
|
+
* - `e => e.details.meta.endTs`, `j => j.e.details.outcome` → a JSON column of the alias' entity
|
|
125
|
+
* followed by the keys inside it (`jsonPath`), at any depth;
|
|
103
126
|
* - anything else → the first key as the alias (an alias the query builder doesn't know yet,
|
|
104
127
|
* e.g. `q => q.base.chatRoomId` before `.from(…, 'base')`).
|
|
105
128
|
*
|
|
@@ -108,6 +131,14 @@ exports.toFieldSql = toFieldSql;
|
|
|
108
131
|
* before `from()` the property name is used as the column name.
|
|
109
132
|
*/
|
|
110
133
|
function resolveTypedKey(queryBuilder, keys) {
|
|
134
|
+
const resolved = resolveTypedKeyPath(queryBuilder, keys);
|
|
135
|
+
// deeper than `alias.column` only inside a JSON column: a nested relation can't be mapped to an alias
|
|
136
|
+
if (!resolved.jsonPath && keys.length > proxy_key_utils_1.MAX_KEY_DEPTH) {
|
|
137
|
+
throw (0, proxy_key_utils_1.createKeyTooDeepError)(keys);
|
|
138
|
+
}
|
|
139
|
+
return resolved;
|
|
140
|
+
}
|
|
141
|
+
function resolveTypedKeyPath(queryBuilder, keys) {
|
|
111
142
|
const prefixing = isAliasPrefixingEnabled(queryBuilder);
|
|
112
143
|
if (keys.length === 1) {
|
|
113
144
|
const aliasName = prefixing ? requireMainAliasName(queryBuilder, keys[0]) : undefined;
|
|
@@ -122,49 +153,63 @@ function resolveTypedKey(queryBuilder, keys) {
|
|
|
122
153
|
const mainAlias = expressionMap === null || expressionMap === void 0 ? void 0 : expressionMap.mainAlias;
|
|
123
154
|
// UPDATE / DELETE have no alias to qualify with: `u => u.user.firstName` is `"firstName"` there
|
|
124
155
|
if (!prefixing && (mainAlias === null || mainAlias === void 0 ? void 0 : mainAlias.name) === firstKey) {
|
|
156
|
+
const metadata = getAliasMetadata(queryBuilder, undefined);
|
|
125
157
|
return {
|
|
126
158
|
aliasName: undefined,
|
|
127
159
|
propertyPath: restKeys.join('.'),
|
|
128
|
-
metadata
|
|
160
|
+
metadata,
|
|
161
|
+
...findColumnPath(metadata, restKeys),
|
|
129
162
|
};
|
|
130
163
|
}
|
|
131
164
|
const queryAlias = expressionMap === null || expressionMap === void 0 ? void 0 : expressionMap.aliases.find((alias) => alias.name === firstKey);
|
|
132
165
|
if (!queryAlias && mainAlias) {
|
|
133
166
|
const mainMetadata = getAliasMetadata(queryBuilder, undefined);
|
|
134
|
-
const
|
|
135
|
-
if (
|
|
167
|
+
const columnPath = findColumnPath(mainMetadata, keys);
|
|
168
|
+
if (columnPath) {
|
|
136
169
|
return {
|
|
137
170
|
aliasName: prefixing ? mainAlias.name : undefined,
|
|
138
|
-
propertyPath: embeddedPath,
|
|
139
171
|
metadata: mainMetadata,
|
|
172
|
+
...columnPath,
|
|
140
173
|
};
|
|
141
174
|
}
|
|
142
175
|
}
|
|
176
|
+
const metadata = (queryAlias === null || queryAlias === void 0 ? void 0 : queryAlias.hasMetadata) ? queryAlias.metadata : undefined;
|
|
143
177
|
return {
|
|
144
178
|
aliasName: firstKey,
|
|
145
179
|
propertyPath: restKeys.join('.'),
|
|
146
|
-
metadata
|
|
180
|
+
metadata,
|
|
181
|
+
...findColumnPath(metadata, restKeys),
|
|
147
182
|
};
|
|
148
183
|
}
|
|
149
|
-
/**
|
|
150
|
-
|
|
184
|
+
/**
|
|
185
|
+
* `"alias"."column"` (or `"column"` without an alias) with the database column name, followed by the path
|
|
186
|
+
* inside a JSON column: `"exec"."details" -> 'meta' ->> 'endTs'` (see `toJsonPathSql`).
|
|
187
|
+
*/
|
|
188
|
+
function toQuotedColumnKey(queryBuilder, { aliasName, propertyPath, metadata, column, jsonPath }, jsonOptions) {
|
|
151
189
|
var _a, _b;
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
? queryBuilder.escape(
|
|
155
|
-
: `${queryBuilder.escape(aliasName)}.${queryBuilder.escape(
|
|
190
|
+
const columnName = (_b = (_a = (column !== null && column !== void 0 ? column : metadata === null || metadata === void 0 ? void 0 : metadata.findColumnWithPropertyPath(propertyPath))) === null || _a === void 0 ? void 0 : _a.databaseName) !== null && _b !== void 0 ? _b : propertyPath;
|
|
191
|
+
const columnSql = aliasName === undefined
|
|
192
|
+
? queryBuilder.escape(columnName)
|
|
193
|
+
: `${queryBuilder.escape(aliasName)}.${queryBuilder.escape(columnName)}`;
|
|
194
|
+
if (!column || !jsonPath) {
|
|
195
|
+
return columnSql;
|
|
196
|
+
}
|
|
197
|
+
const driver = (0, sql_utils_1.getDriverType)(queryBuilder);
|
|
198
|
+
return (0, json_path_utils_1.toJsonPathSql)(driver, columnSql, column, jsonPath, jsonOptions);
|
|
156
199
|
}
|
|
157
200
|
/**
|
|
158
201
|
* SQL key for a typed callback on `builder`: `"alias"."column"`, or `"column"` on UPDATE / DELETE.
|
|
159
202
|
*
|
|
160
203
|
* The property is mapped to its database column name (`@Column({ name })`, embedded columns)
|
|
161
204
|
* through the metadata of the alias it belongs to (see `resolveTypedKey`). Aliases without
|
|
162
|
-
* metadata (subqueries) and unknown properties keep the property name.
|
|
205
|
+
* metadata (subqueries) and unknown properties keep the property name. A path into a JSON column
|
|
206
|
+
* gives its JSON accessor, cast on PostgreSQL to the type of `jsonOptions.value`.
|
|
163
207
|
*/
|
|
164
|
-
function getTypedColumnKey(builder, callback) {
|
|
208
|
+
function getTypedColumnKey(builder, callback, jsonOptions) {
|
|
165
209
|
const queryBuilder = builder;
|
|
166
|
-
const toKey = (keyHolder) => toQuotedColumnKey(queryBuilder, resolveTypedKey(queryBuilder, keyHolder.getKeys()));
|
|
167
|
-
|
|
210
|
+
const toKey = (keyHolder) => toQuotedColumnKey(queryBuilder, resolveTypedKey(queryBuilder, keyHolder.getKeys()), jsonOptions);
|
|
211
|
+
// the depth is checked against the query's metadata, where a JSON column may be deeper
|
|
212
|
+
const keyHolder = (0, proxy_key_utils_1.getKeyHolder)(callback, true);
|
|
168
213
|
return Array.isArray(keyHolder) ? keyHolder.map(toKey) : toKey(keyHolder);
|
|
169
214
|
}
|
|
170
215
|
exports.getTypedColumnKey = getTypedColumnKey;
|
|
@@ -173,8 +218,8 @@ exports.getTypedColumnKey = getTypedColumnKey;
|
|
|
173
218
|
* (`whereIsAnyTyped`, `whereArrayContainsTyped`, …). Throws a `TypeError` for several columns:
|
|
174
219
|
* one condition per column has no single obvious meaning (AND? OR?), so don't guess.
|
|
175
220
|
*/
|
|
176
|
-
function getTypedSingleColumnKey(builder, callback, methodName) {
|
|
177
|
-
const key = getTypedColumnKey(builder, callback);
|
|
221
|
+
function getTypedSingleColumnKey(builder, callback, methodName, jsonOptions) {
|
|
222
|
+
const key = getTypedColumnKey(builder, callback, jsonOptions);
|
|
178
223
|
if (Array.isArray(key)) {
|
|
179
224
|
throw new TypeError(`${methodName} expects the callback to select a single column, got ${key.length}: ${key.join(', ')}`);
|
|
180
225
|
}
|
|
@@ -195,6 +240,10 @@ function getTypedSelectionKey(builder, selection, useQuotes) {
|
|
|
195
240
|
const queryBuilder = builder;
|
|
196
241
|
const toKey = (keyHolder) => {
|
|
197
242
|
const resolved = resolveTypedKey(queryBuilder, keyHolder.getKeys());
|
|
243
|
+
if (resolved.jsonPath) {
|
|
244
|
+
throw new TypeError(`Typed key "${keyHolder.getKeys().join('.')}" points into the JSON column "${resolved.propertyPath}": ` +
|
|
245
|
+
`select, order and distinct take columns only. For an expression use tableHelper().jsonColumn()`);
|
|
246
|
+
}
|
|
198
247
|
if (useQuotes) {
|
|
199
248
|
return toQuotedColumnKey(queryBuilder, resolved);
|
|
200
249
|
}
|
|
@@ -3,6 +3,8 @@ export declare const wrapWithDoubleQoutes: (str: string) => string;
|
|
|
3
3
|
export declare const wrapWithBackQoutes: (str: string) => string;
|
|
4
4
|
/** MySQL, MariaDB and Aurora MySQL: backtick identifiers, `<=>` null-safe comparison. */
|
|
5
5
|
export declare const isMysqlLikeDriver: (driver?: DatabaseType) => boolean;
|
|
6
|
+
/** PostgreSQL and the databases speaking its dialect. */
|
|
7
|
+
export declare const isPostgresLikeDriver: (driver?: DatabaseType) => boolean;
|
|
6
8
|
/** SQLite drivers: `IS` / `IS NOT` are null-safe comparisons. */
|
|
7
9
|
export declare const isSqliteLikeDriver: (driver?: DatabaseType) => boolean;
|
|
8
10
|
/** Database type of the query builder's connection, e.g. `'postgres'`; undefined without one. */
|
package/dist/utils/sql.utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.assertArrayType = exports.createUniqueParameterName = exports.stringToSQLValue = exports.stringToSQLIdentifier = exports.quoteIdentifierPath = exports.quoteIdentifier = exports.getDriverType = exports.isSqliteLikeDriver = exports.isMysqlLikeDriver = exports.wrapWithBackQoutes = exports.wrapWithDoubleQoutes = void 0;
|
|
3
|
+
exports.assertArrayType = exports.createUniqueParameterName = exports.stringToSQLValue = exports.stringToSQLIdentifier = exports.quoteIdentifierPath = exports.quoteIdentifier = exports.getDriverType = exports.isSqliteLikeDriver = exports.isPostgresLikeDriver = exports.isMysqlLikeDriver = exports.wrapWithBackQoutes = exports.wrapWithDoubleQoutes = void 0;
|
|
4
4
|
const common_utils_1 = require("./common.utils");
|
|
5
5
|
const wrapWithDoubleQoutes = (str) => str.includes('"') ? str : `"${str}"`;
|
|
6
6
|
exports.wrapWithDoubleQoutes = wrapWithDoubleQoutes;
|
|
@@ -29,6 +29,10 @@ const SQLITE_LIKE_DRIVERS = [
|
|
|
29
29
|
'nativescript',
|
|
30
30
|
'react-native',
|
|
31
31
|
];
|
|
32
|
+
const POSTGRES_LIKE_DRIVERS = ['postgres', 'aurora-postgres', 'cockroachdb'];
|
|
33
|
+
/** PostgreSQL and the databases speaking its dialect. */
|
|
34
|
+
const isPostgresLikeDriver = (driver) => driver !== undefined && POSTGRES_LIKE_DRIVERS.includes(driver);
|
|
35
|
+
exports.isPostgresLikeDriver = isPostgresLikeDriver;
|
|
32
36
|
/** SQLite drivers: `IS` / `IS NOT` are null-safe comparisons. */
|
|
33
37
|
const isSqliteLikeDriver = (driver) => driver !== undefined && SQLITE_LIKE_DRIVERS.includes(driver);
|
|
34
38
|
exports.isSqliteLikeDriver = isSqliteLikeDriver;
|
|
@@ -2,18 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.tableHelper = void 0;
|
|
4
4
|
const sql_utils_1 = require("./sql.utils");
|
|
5
|
-
|
|
6
|
-
function toJsonKeyLiteral(fieldName) {
|
|
7
|
-
return `'${String(fieldName).replace(/'/g, "''")}'`;
|
|
8
|
-
}
|
|
9
|
-
function buildJsonPath(fieldNames, jsonOperator) {
|
|
10
|
-
let result = '';
|
|
11
|
-
for (let i = 0; i < fieldNames.length; i++) {
|
|
12
|
-
const op = i === fieldNames.length - 1 ? jsonOperator : '->';
|
|
13
|
-
result += `${result ? ' ' : ''}${op} ${toJsonKeyLiteral(fieldNames[i])}`;
|
|
14
|
-
}
|
|
15
|
-
return result;
|
|
16
|
-
}
|
|
5
|
+
const json_path_utils_1 = require("./json-path.utils");
|
|
17
6
|
/**
|
|
18
7
|
* Creates a type-safe SQL helper for building column references, WHERE expressions,
|
|
19
8
|
* JOIN clauses, and JSONB accessors for a given entity type.
|
|
@@ -115,7 +104,7 @@ const tableHelper = (alias, options = {}) => ({
|
|
|
115
104
|
*/
|
|
116
105
|
jsonColumn(columnName, jsonOperator, ...fieldNames) {
|
|
117
106
|
const column = this.column(columnName);
|
|
118
|
-
const path = buildJsonPath(fieldNames, jsonOperator);
|
|
107
|
+
const path = (0, json_path_utils_1.buildJsonPath)(fieldNames, jsonOperator);
|
|
119
108
|
return `${column} ${path}`;
|
|
120
109
|
},
|
|
121
110
|
/**
|
|
@@ -129,7 +118,7 @@ const tableHelper = (alias, options = {}) => ({
|
|
|
129
118
|
* qb.whereTyped(u => u.metadata, `${t.jsonPath('metadata', '->>', 'role')} =`, 'admin')
|
|
130
119
|
*/
|
|
131
120
|
jsonPath(_columnName, jsonOperator, ...fieldNames) {
|
|
132
|
-
return buildJsonPath(fieldNames, jsonOperator);
|
|
121
|
+
return (0, json_path_utils_1.buildJsonPath)(fieldNames, jsonOperator);
|
|
133
122
|
}
|
|
134
123
|
});
|
|
135
124
|
exports.tableHelper = tableHelper;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typeorm-extensions",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "typeorm commonly used extensions",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
},
|
|
14
14
|
"scripts": {
|
|
15
15
|
"build": "tsc -p .",
|
|
16
|
-
"lint": "eslint . --ext .ts"
|
|
16
|
+
"lint": "eslint . --ext .ts",
|
|
17
|
+
"test:types": "tsc -p test/types"
|
|
17
18
|
},
|
|
18
19
|
"keywords": [
|
|
19
20
|
"typeorm",
|