typeorm-extensions 2.2.0-rc.7 → 2.2.0-rc.9
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 +70 -39
- package/dist/decorators/generated-column.decorator.d.ts +17 -0
- package/dist/decorators/generated-column.decorator.js +15 -0
- package/dist/decorators/index.d.ts +1 -0
- package/dist/decorators/index.js +1 -0
- package/dist/extensions/calculated-column.extension.d.ts +3 -3
- package/dist/extensions/calculated-column.extension.js +3 -16
- package/dist/extensions/cursor-pagination.extension.js +7 -13
- package/dist/extensions/get-many-with-totals.extension.js +9 -32
- package/dist/extensions/join-lateral.extension.js +4 -6
- package/dist/extensions/period-filter.extension.js +1 -11
- package/dist/extensions/typed/index.d.ts +1 -0
- package/dist/extensions/typed/index.js +1 -0
- package/dist/extensions/typed/typed-calculated/typed-calculated-column.extension.d.ts +25 -0
- package/dist/extensions/typed/typed-calculated/typed-calculated-column.extension.js +24 -0
- package/dist/extensions/typed/typed-having/typed-having.extension.js +1 -1
- package/dist/extensions/typed/typed-joins/typed-join-and-map.extension.js +11 -10
- package/dist/extensions/typed/typed-joins/typed-joins.extension.js +11 -22
- package/dist/extensions/typed/typed-order-by/typed-order-by.extension.js +11 -17
- package/dist/extensions/typed/typed-returning/typed-returning.extension.js +1 -9
- package/dist/extensions/typed/typed-select/typed-select.extension.js +2 -8
- package/dist/extensions/typed/typed-where/typed-period-filter.extension.js +1 -11
- package/dist/extensions/typed/typed-where/typed-where-array.extension.js +4 -18
- package/dist/extensions/typed/typed-where/typed-where-ilike.extension.js +1 -11
- package/dist/extensions/typed/typed-where/typed-where-is-any.extension.js +3 -22
- package/dist/extensions/typed/typed-where/typed-where-is-distinct-from.extension.js +3 -22
- package/dist/extensions/typed/typed-where/typed-where-is-in.extension.js +3 -23
- package/dist/extensions/typed/typed-where/typed-where-json.extension.js +4 -23
- package/dist/extensions/typed/typed-where/typed-where-lower.extension.js +1 -11
- package/dist/extensions/typed/typed-where/typed-where-similar.extension.js +1 -10
- package/dist/extensions/typed/typed-where/typed-where.extension.js +2 -12
- package/dist/extensions/union.extension.js +1 -1
- package/dist/extensions/where-array.extension.js +1 -11
- package/dist/extensions/where-exists.extension.js +4 -15
- package/dist/extensions/where-is-any.extension.d.ts +38 -160
- package/dist/extensions/where-is-any.extension.js +1 -11
- package/dist/extensions/where-is-distinct-from.extension.js +1 -11
- package/dist/extensions/where-is-in.extension.d.ts +35 -145
- package/dist/extensions/where-is-in.extension.js +11 -29
- package/dist/extensions/where-json.extension.js +1 -11
- package/dist/extensions/where-relation-exists.extension.js +5 -25
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +2 -1
- package/dist/index.d.ts +1 -6
- package/dist/index.js +1 -12
- package/dist/types/extensions/cursor-pagination.types.d.ts +5 -0
- package/dist/types/extensions/get-many-with-totals.types.d.ts +4 -0
- package/dist/utils/calculated-column.utils.d.ts +8 -0
- package/dist/utils/calculated-column.utils.js +20 -3
- package/dist/utils/common.utils.d.ts +2 -0
- package/dist/utils/common.utils.js +4 -1
- package/dist/utils/cursor.utils.js +4 -6
- package/dist/utils/json-path.utils.js +2 -2
- package/dist/utils/pagination.utils.d.ts +7 -0
- package/dist/utils/pagination.utils.js +20 -10
- package/dist/utils/parameter.utils.d.ts +10 -0
- package/dist/utils/parameter.utils.js +22 -1
- package/dist/utils/period.utils.js +2 -1
- package/dist/utils/prototype.utils.d.ts +9 -0
- package/dist/utils/prototype.utils.js +12 -2
- package/dist/utils/query-builder.utils.d.ts +30 -2
- package/dist/utils/query-builder.utils.js +82 -44
- package/dist/utils/table.utils.js +9 -11
- package/dist/utils/time-zone.utils.d.ts +8 -0
- package/dist/utils/time-zone.utils.js +15 -5
- package/dist/utils/typed-where.utils.d.ts +9 -0
- package/dist/utils/typed-where.utils.js +17 -0
- package/dist/utils/where.utils.d.ts +2 -0
- package/dist/utils/where.utils.js +12 -14
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ exports.tableHelper = void 0;
|
|
|
4
4
|
const typeorm_1 = require("typeorm");
|
|
5
5
|
const sql_utils_1 = require("./sql.utils");
|
|
6
6
|
const json_path_utils_1 = require("./json-path.utils");
|
|
7
|
+
const time_zone_utils_1 = require("./time-zone.utils");
|
|
7
8
|
/**
|
|
8
9
|
* The argument of an aggregate and the clause after it for a `filter` written with `syntax`:
|
|
9
10
|
* `CASE WHEN filter THEN argument END`, or `argument` and ` FILTER (WHERE filter)`.
|
|
@@ -45,9 +46,9 @@ const DATE_TRUNC_UNITS = [
|
|
|
45
46
|
'century',
|
|
46
47
|
'millennium',
|
|
47
48
|
];
|
|
48
|
-
function assertPostgres(method, driver) {
|
|
49
|
+
function assertPostgres(method, driver, hint) {
|
|
49
50
|
if (driver !== undefined && !(0, sql_utils_1.isPostgresLikeDriver)(driver)) {
|
|
50
|
-
throw new TypeError(`tableHelper.${method}(): PostgreSQL only, the driver is "${driver}"`);
|
|
51
|
+
throw new TypeError(`tableHelper.${method}(): PostgreSQL only, the driver is "${driver}"${hint ? `: ${hint}` : ''}`);
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
function toExpression(value, toColumn) {
|
|
@@ -58,7 +59,7 @@ function toTimeZone(method, timeZone, toColumn) {
|
|
|
58
59
|
if (!timeZone.trim()) {
|
|
59
60
|
throw new TypeError(`tableHelper.${method}(): the time zone is empty`);
|
|
60
61
|
}
|
|
61
|
-
return sqlString(toPostgresZone(timeZone));
|
|
62
|
+
return sqlString(toPostgresZone(method, timeZone));
|
|
62
63
|
}
|
|
63
64
|
if ('sql' in timeZone) {
|
|
64
65
|
return timeZone.sql;
|
|
@@ -66,19 +67,18 @@ function toTimeZone(method, timeZone, toColumn) {
|
|
|
66
67
|
const column = toColumn(timeZone.column);
|
|
67
68
|
return timeZone.fallback === undefined
|
|
68
69
|
? column
|
|
69
|
-
: `COALESCE(${column}, ${sqlString(toPostgresZone(timeZone.fallback))})`;
|
|
70
|
+
: `COALESCE(${column}, ${sqlString(toPostgresZone(method, timeZone.fallback))})`;
|
|
70
71
|
}
|
|
71
|
-
const ISO_OFFSET = /^([+-])(\d{2}):?(\d{2})?$/;
|
|
72
72
|
/**
|
|
73
73
|
* PostgreSQL reads `'+02:00'` as a POSIX zone, whose offsets count west: UTC−2. An ISO 8601 offset is
|
|
74
74
|
* written as the POSIX zone of the same offset, `'<+0200>-02:00'`, so `'+02:00'` is UTC+2 as everywhere else.
|
|
75
75
|
*/
|
|
76
|
-
function toPostgresZone(timeZone) {
|
|
77
|
-
const offset =
|
|
76
|
+
function toPostgresZone(method, timeZone) {
|
|
77
|
+
const offset = (0, time_zone_utils_1.parseUtcOffset)(timeZone.trim(), `tableHelper.${method}(): "${timeZone}" is not a UTC offset`);
|
|
78
78
|
if (offset === null) {
|
|
79
79
|
return timeZone;
|
|
80
80
|
}
|
|
81
|
-
const
|
|
81
|
+
const { sign, hours, minutes } = offset;
|
|
82
82
|
return `<${sign}${hours}${minutes}>${sign === '+' ? '-' : '+'}${hours}:${minutes}`;
|
|
83
83
|
}
|
|
84
84
|
/** The JSON functions of a database: PostgreSQL's unless the driver is MySQL / MariaDB or SQLite. */
|
|
@@ -200,9 +200,7 @@ const createTableHelper = (alias, options = {}, databaseNames) => ({
|
|
|
200
200
|
arrayAgg(columnName, aggOptions = {}) {
|
|
201
201
|
var _a;
|
|
202
202
|
const { distinct = false, orderBy, filter } = aggOptions;
|
|
203
|
-
|
|
204
|
-
throw new TypeError(`tableHelper.arrayAgg(): arrays are PostgreSQL's, the driver is "${options.driver}": use jsonAgg`);
|
|
205
|
-
}
|
|
203
|
+
assertPostgres('arrayAgg', options.driver, 'use jsonAgg');
|
|
206
204
|
const order = orderBy ? aggregateOrder('arrayAgg', orderBy, (column) => this.column(column)) : undefined;
|
|
207
205
|
// PostgreSQL: "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list"
|
|
208
206
|
if (distinct && order && order.column !== columnName) {
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
type UtcOffset = {
|
|
2
|
+
sign: '+' | '-';
|
|
3
|
+
hours: string;
|
|
4
|
+
minutes: string;
|
|
5
|
+
};
|
|
6
|
+
/** The parts of an ISO 8601 UTC offset (`+02:00`, `-0530`, `+02`); `null` for other text, a `TypeError` past 23:59. */
|
|
7
|
+
export declare function parseUtcOffset(text: string, errorMessage: string): UtcOffset | null;
|
|
1
8
|
/** Throws a `TypeError` for a time zone the runtime doesn't know. */
|
|
2
9
|
export declare function assertTimeZone(timeZone: string): void;
|
|
3
10
|
/**
|
|
@@ -6,3 +13,4 @@ export declare function assertTimeZone(timeZone: string): void;
|
|
|
6
13
|
* instant already: it is returned as that `Date`. Any other string throws a `TypeError` naming `name`.
|
|
7
14
|
*/
|
|
8
15
|
export declare function readInTimeZone(value: string, timeZone: string, name: string): Date;
|
|
16
|
+
export {};
|
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.readInTimeZone = exports.assertTimeZone = void 0;
|
|
3
|
+
exports.readInTimeZone = exports.assertTimeZone = exports.parseUtcOffset = void 0;
|
|
4
4
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
5
5
|
const MAX_CACHED_FORMATTERS = 500;
|
|
6
6
|
const DATE_TIME = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?(Z|[+-]\d{2}(?::?\d{2})?)?)?$/i;
|
|
7
7
|
const OFFSET = /^([+-])(\d{2}):?(\d{2})?$/;
|
|
8
|
+
/** The parts of an ISO 8601 UTC offset (`+02:00`, `-0530`, `+02`); `null` for other text, a `TypeError` past 23:59. */
|
|
9
|
+
function parseUtcOffset(text, errorMessage) {
|
|
10
|
+
const offset = OFFSET.exec(text);
|
|
11
|
+
if (offset === null) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
const [, sign, hours, minutes = '00'] = offset;
|
|
15
|
+
if (Number(hours) > 23 || Number(minutes) > 59) {
|
|
16
|
+
throw new TypeError(errorMessage);
|
|
17
|
+
}
|
|
18
|
+
return { sign: sign, hours, minutes };
|
|
19
|
+
}
|
|
20
|
+
exports.parseUtcOffset = parseUtcOffset;
|
|
8
21
|
const formatters = new Map();
|
|
9
22
|
function getFormatter(timeZone) {
|
|
10
23
|
let formatter = formatters.get(timeZone);
|
|
@@ -94,9 +107,6 @@ function getOffsetMinutes(offset, value, name) {
|
|
|
94
107
|
if (offset.toUpperCase() === 'Z') {
|
|
95
108
|
return 0;
|
|
96
109
|
}
|
|
97
|
-
const
|
|
98
|
-
if (Number(hours) > 23 || Number(minutes) > 59) {
|
|
99
|
-
throw new TypeError(`Invalid ${name} "${value}": not a UTC offset`);
|
|
100
|
-
}
|
|
110
|
+
const { sign, hours, minutes } = parseUtcOffset(offset, `Invalid ${name} "${value}": not a UTC offset`);
|
|
101
111
|
return (sign === '-' ? -1 : 1) * (Number(hours) * 60 + Number(minutes));
|
|
102
112
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ObjectLiteral, WhereExpressionBuilder } from 'typeorm';
|
|
2
|
+
import type { KeyProxyCallback } from '../types/modules/proxy-callback.types';
|
|
3
|
+
import type { JsonPathSqlOptions } from './json-path.utils';
|
|
4
|
+
/**
|
|
5
|
+
* Calls the untyped where `method` with the single column a typed callback picks, followed by `args`, as the typed
|
|
6
|
+
* where methods that only add the column to their untyped counterpart do. A callback that isn't a function, from
|
|
7
|
+
* untyped code, leaves the builder as it is.
|
|
8
|
+
*/
|
|
9
|
+
export declare function attachTypedColumnWhere<Type extends ObjectLiteral, QB extends WhereExpressionBuilder, Args extends unknown[] = unknown[]>(builder: QB, method: string, where: KeyProxyCallback<Type>, jsonOptions: JsonPathSqlOptions | undefined, ...args: Args): QB;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.attachTypedColumnWhere = void 0;
|
|
4
|
+
const query_builder_utils_1 = require("./query-builder.utils");
|
|
5
|
+
/**
|
|
6
|
+
* Calls the untyped where `method` with the single column a typed callback picks, followed by `args`, as the typed
|
|
7
|
+
* where methods that only add the column to their untyped counterpart do. A callback that isn't a function, from
|
|
8
|
+
* untyped code, leaves the builder as it is.
|
|
9
|
+
*/
|
|
10
|
+
function attachTypedColumnWhere(builder, method, where, jsonOptions, ...args) {
|
|
11
|
+
if (typeof where !== 'function') {
|
|
12
|
+
return builder;
|
|
13
|
+
}
|
|
14
|
+
const key = (0, query_builder_utils_1.getTypedSingleColumnKey)(builder, where, `${method}Typed`, jsonOptions);
|
|
15
|
+
return builder[method](key, ...args);
|
|
16
|
+
}
|
|
17
|
+
exports.attachTypedColumnWhere = attachTypedColumnWhere;
|
|
@@ -5,6 +5,8 @@ export declare function getValuePlaceholder<T>(value: T, paramName?: string): st
|
|
|
5
5
|
* Whether `params` is a `{ name: value }` params object (a plain object or a class instance such
|
|
6
6
|
* as a DTO), rather than the value itself (a primitive, an array, a `Date`, a `Buffer`).
|
|
7
7
|
*/
|
|
8
|
+
/** The value a condition compares with: the value of a one-key params object, or the params themselves (a Date or a Buffer is a value too). */
|
|
9
|
+
export declare function getComparedValue(params: unknown): unknown;
|
|
8
10
|
export declare function isParamsObject(params: unknown): params is Record<string, unknown>;
|
|
9
11
|
/**
|
|
10
12
|
* Checks whether `conditions` already references a key of `params` as a TypeORM
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.andWhereNarrowing = exports.attachWhere = exports.hasParamPlaceholder = exports.isParamsObject = exports.getValuePlaceholder = void 0;
|
|
3
|
+
exports.andWhereNarrowing = exports.attachWhere = exports.hasParamPlaceholder = exports.isParamsObject = exports.getComparedValue = exports.getValuePlaceholder = void 0;
|
|
4
4
|
const sql_utils_1 = require("./sql.utils");
|
|
5
5
|
const query_builder_utils_1 = require("./query-builder.utils");
|
|
6
|
+
const parameter_utils_1 = require("./parameter.utils");
|
|
7
|
+
const common_utils_1 = require("./common.utils");
|
|
6
8
|
function getValuePlaceholder(value, paramName) {
|
|
7
9
|
if (value === undefined || value === null || paramName === undefined) {
|
|
8
10
|
return 'NULL';
|
|
@@ -18,16 +20,20 @@ exports.getValuePlaceholder = getValuePlaceholder;
|
|
|
18
20
|
* `:` or `.` is a parameter or a column (`ILIKE :like`, `= t.in`), not an operator.
|
|
19
21
|
*/
|
|
20
22
|
const OPERATOR_AT_END = /(?:[=<>!~@&|?]|(?<![\w$:.])(?:LIKE|ILIKE|IN|SIMILAR TO|DISTINCT FROM|BETWEEN|ANY|ALL))\s*$/i;
|
|
21
|
-
const isDate = (value) => Object.prototype.toString.call(value) === '[object Date]';
|
|
22
23
|
/**
|
|
23
24
|
* Objects that are parameter values themselves, not `{ name: value }` params objects:
|
|
24
25
|
* `Date`, and binary data (`Buffer`, typed arrays, `ArrayBuffer`).
|
|
25
26
|
*/
|
|
26
|
-
const isValueObject = (value) => isDate(value) || ArrayBuffer.isView(value) || value instanceof ArrayBuffer;
|
|
27
|
+
const isValueObject = (value) => (0, common_utils_1.isDate)(value) || ArrayBuffer.isView(value) || value instanceof ArrayBuffer;
|
|
27
28
|
/**
|
|
28
29
|
* Whether `params` is a `{ name: value }` params object (a plain object or a class instance such
|
|
29
30
|
* as a DTO), rather than the value itself (a primitive, an array, a `Date`, a `Buffer`).
|
|
30
31
|
*/
|
|
32
|
+
/** The value a condition compares with: the value of a one-key params object, or the params themselves (a Date or a Buffer is a value too). */
|
|
33
|
+
function getComparedValue(params) {
|
|
34
|
+
return isParamsObject(params) ? Object.values(params)[0] : params;
|
|
35
|
+
}
|
|
36
|
+
exports.getComparedValue = getComparedValue;
|
|
31
37
|
function isParamsObject(params) {
|
|
32
38
|
return (params !== null &&
|
|
33
39
|
typeof params === 'object' &&
|
|
@@ -44,14 +50,7 @@ function hasParamPlaceholder(conditions, params) {
|
|
|
44
50
|
if (!isParamsObject(params)) {
|
|
45
51
|
return false;
|
|
46
52
|
}
|
|
47
|
-
|
|
48
|
-
let match;
|
|
49
|
-
while ((match = placeholderRegex.exec(conditions)) !== null) {
|
|
50
|
-
if (Object.prototype.hasOwnProperty.call(params, match[1])) {
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return false;
|
|
53
|
+
return (0, parameter_utils_1.getPlaceholderNames)(conditions).some((name) => Object.prototype.hasOwnProperty.call(params, name));
|
|
55
54
|
}
|
|
56
55
|
exports.hasParamPlaceholder = hasParamPlaceholder;
|
|
57
56
|
/**
|
|
@@ -87,13 +86,12 @@ function attachWhere(builder, method, field, conditions, params, options) {
|
|
|
87
86
|
}
|
|
88
87
|
if (addValue && hasParams) {
|
|
89
88
|
assertSingleValueParams(fieldName, params);
|
|
90
|
-
|
|
91
|
-
const firstValue = isParamsObject(params) ? Object.values(params)[0] : params;
|
|
89
|
+
const firstValue = getComparedValue(params);
|
|
92
90
|
// 0, false, '' are valid values like any other
|
|
93
91
|
// null, undefined, NaN and invalid dates are equal to NULL
|
|
94
92
|
const valueIsValid = firstValue !== undefined &&
|
|
95
93
|
(typeof firstValue === 'number' ? !isNaN(firstValue) : true) &&
|
|
96
|
-
(isDate(firstValue) ? !isNaN(firstValue.getTime()) : true);
|
|
94
|
+
((0, common_utils_1.isDate)(firstValue) ? !isNaN(firstValue.getTime()) : true);
|
|
97
95
|
const paramName = valueIsValid
|
|
98
96
|
? (0, sql_utils_1.createUniqueParameterName)(method)
|
|
99
97
|
: undefined;
|