typeorm-extensions 2.2.0-rc.8 → 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.
Files changed (62) hide show
  1. package/README.md +0 -8
  2. package/dist/extensions/calculated-column.extension.d.ts +3 -3
  3. package/dist/extensions/calculated-column.extension.js +3 -16
  4. package/dist/extensions/cursor-pagination.extension.js +3 -11
  5. package/dist/extensions/get-many-with-totals.extension.js +4 -20
  6. package/dist/extensions/join-lateral.extension.js +4 -6
  7. package/dist/extensions/period-filter.extension.js +1 -11
  8. package/dist/extensions/typed/index.d.ts +1 -0
  9. package/dist/extensions/typed/index.js +1 -0
  10. package/dist/extensions/typed/typed-calculated/typed-calculated-column.extension.d.ts +25 -0
  11. package/dist/extensions/typed/typed-calculated/typed-calculated-column.extension.js +24 -0
  12. package/dist/extensions/typed/typed-having/typed-having.extension.js +1 -1
  13. package/dist/extensions/typed/typed-joins/typed-join-and-map.extension.js +11 -10
  14. package/dist/extensions/typed/typed-joins/typed-joins.extension.js +11 -22
  15. package/dist/extensions/typed/typed-order-by/typed-order-by.extension.js +11 -17
  16. package/dist/extensions/typed/typed-returning/typed-returning.extension.js +1 -9
  17. package/dist/extensions/typed/typed-select/typed-select.extension.js +2 -8
  18. package/dist/extensions/typed/typed-where/typed-period-filter.extension.js +1 -11
  19. package/dist/extensions/typed/typed-where/typed-where-array.extension.js +4 -18
  20. package/dist/extensions/typed/typed-where/typed-where-ilike.extension.js +1 -11
  21. package/dist/extensions/typed/typed-where/typed-where-is-any.extension.js +3 -22
  22. package/dist/extensions/typed/typed-where/typed-where-is-distinct-from.extension.js +3 -22
  23. package/dist/extensions/typed/typed-where/typed-where-is-in.extension.js +3 -23
  24. package/dist/extensions/typed/typed-where/typed-where-json.extension.js +4 -23
  25. package/dist/extensions/typed/typed-where/typed-where-lower.extension.js +1 -11
  26. package/dist/extensions/typed/typed-where/typed-where-similar.extension.js +1 -10
  27. package/dist/extensions/typed/typed-where/typed-where.extension.js +2 -12
  28. package/dist/extensions/union.extension.js +1 -1
  29. package/dist/extensions/where-array.extension.js +1 -11
  30. package/dist/extensions/where-exists.extension.js +4 -15
  31. package/dist/extensions/where-is-any.extension.d.ts +38 -160
  32. package/dist/extensions/where-is-any.extension.js +1 -11
  33. package/dist/extensions/where-is-distinct-from.extension.js +1 -11
  34. package/dist/extensions/where-is-in.extension.d.ts +35 -145
  35. package/dist/extensions/where-is-in.extension.js +11 -29
  36. package/dist/extensions/where-json.extension.js +1 -11
  37. package/dist/extensions/where-relation-exists.extension.js +5 -25
  38. package/dist/index.d.ts +1 -6
  39. package/dist/index.js +1 -12
  40. package/dist/utils/calculated-column.utils.d.ts +8 -0
  41. package/dist/utils/calculated-column.utils.js +20 -3
  42. package/dist/utils/common.utils.d.ts +2 -0
  43. package/dist/utils/common.utils.js +4 -1
  44. package/dist/utils/cursor.utils.js +4 -6
  45. package/dist/utils/json-path.utils.js +2 -2
  46. package/dist/utils/pagination.utils.d.ts +5 -0
  47. package/dist/utils/pagination.utils.js +20 -10
  48. package/dist/utils/parameter.utils.d.ts +10 -0
  49. package/dist/utils/parameter.utils.js +22 -1
  50. package/dist/utils/period.utils.js +2 -1
  51. package/dist/utils/prototype.utils.d.ts +9 -0
  52. package/dist/utils/prototype.utils.js +12 -2
  53. package/dist/utils/query-builder.utils.d.ts +22 -2
  54. package/dist/utils/query-builder.utils.js +67 -44
  55. package/dist/utils/table.utils.js +9 -11
  56. package/dist/utils/time-zone.utils.d.ts +8 -0
  57. package/dist/utils/time-zone.utils.js +15 -5
  58. package/dist/utils/typed-where.utils.d.ts +9 -0
  59. package/dist/utils/typed-where.utils.js +17 -0
  60. package/dist/utils/where.utils.d.ts +2 -0
  61. package/dist/utils/where.utils.js +12 -14
  62. package/package.json +1 -1
@@ -1,162 +1,52 @@
1
1
  import { ObjectLiteral } from 'typeorm';
2
2
  import { ArgsType } from '../types/util-types';
3
+ export interface WhereIsInMethods {
4
+ /**
5
+ * Sets WHERE IN condition in the query builder.
6
+ * If you had previously WHERE expression defined,
7
+ * calling this function will override previously set WHERE conditions.
8
+ */
9
+ whereIsIn(field: string, array?: ArgsType): this;
10
+ /**
11
+ * Adds new AND WHERE IN condition in the query builder.
12
+ */
13
+ andWhereIsIn(field: string, array?: ArgsType): this;
14
+ /**
15
+ * Adds new OR WHERE IN condition in the query builder.
16
+ */
17
+ orWhereIsIn(field: string, array?: ArgsType): this;
18
+ /**
19
+ * Sets WHERE NOT IN condition in the query builder.
20
+ * If you had previously WHERE expression defined,
21
+ * calling this function will override previously set WHERE conditions.
22
+ */
23
+ whereIsNotIn(field: string, array?: ArgsType): this;
24
+ /**
25
+ * Adds new AND WHERE NOT IN condition in the query builder.
26
+ */
27
+ andWhereIsNotIn(field: string, array?: ArgsType): this;
28
+ /**
29
+ * Adds new OR WHERE NOT IN condition in the query builder.
30
+ */
31
+ orWhereIsNotIn(field: string, array?: ArgsType): this;
32
+ }
3
33
  declare module 'typeorm/query-builder/WhereExpressionBuilder' {
4
- interface WhereExpressionBuilder {
5
- /**
6
- * Sets WHERE IN condition in the query builder.
7
- * If you had previously WHERE expression defined,
8
- * calling this function will override previously set WHERE conditions.
9
- */
10
- whereIsIn(field: string, array?: ArgsType): this;
11
- /**
12
- * Adds new AND WHERE IN condition in the query builder.
13
- */
14
- andWhereIsIn(field: string, array?: ArgsType): this;
15
- /**
16
- * Adds new OR WHERE IN condition in the query builder.
17
- */
18
- orWhereIsIn(field: string, array?: ArgsType): this;
19
- /**
20
- * Sets WHERE NOT IN condition in the query builder.
21
- * If you had previously WHERE expression defined,
22
- * calling this function will override previously set WHERE conditions.
23
- */
24
- whereIsNotIn(field: string, array?: ArgsType): this;
25
- /**
26
- * Adds new AND WHERE NOT IN condition in the query builder.
27
- */
28
- andWhereIsNotIn(field: string, array?: ArgsType): this;
29
- /**
30
- * Adds new OR WHERE NOT IN condition in the query builder.
31
- */
32
- orWhereIsNotIn(field: string, array?: ArgsType): this;
34
+ interface WhereExpressionBuilder extends WhereIsInMethods {
33
35
  }
34
36
  }
35
37
  declare module 'typeorm/query-builder/SelectQueryBuilder' {
36
- interface SelectQueryBuilder<Entity extends ObjectLiteral> {
37
- /**
38
- * Sets WHERE IN condition in the query builder.
39
- * If you had previously WHERE expression defined,
40
- * calling this function will override previously set WHERE conditions.
41
- */
42
- whereIsIn(field: string, array?: ArgsType): this;
43
- /**
44
- * Adds new AND WHERE IN condition in the query builder.
45
- */
46
- andWhereIsIn(field: string, array?: ArgsType): this;
47
- /**
48
- * Adds new OR WHERE IN condition in the query builder.
49
- */
50
- orWhereIsIn(field: string, array?: ArgsType): this;
51
- /**
52
- * Sets WHERE NOT IN condition in the query builder.
53
- * If you had previously WHERE expression defined,
54
- * calling this function will override previously set WHERE conditions.
55
- */
56
- whereIsNotIn(field: string, array?: ArgsType): this;
57
- /**
58
- * Adds new AND WHERE NOT IN condition in the query builder.
59
- */
60
- andWhereIsNotIn(field: string, array?: ArgsType): this;
61
- /**
62
- * Adds new OR WHERE NOT IN condition in the query builder.
63
- */
64
- orWhereIsNotIn(field: string, array?: ArgsType): this;
38
+ interface SelectQueryBuilder<Entity extends ObjectLiteral> extends WhereIsInMethods {
65
39
  }
66
40
  }
67
41
  declare module 'typeorm/query-builder/UpdateQueryBuilder' {
68
- interface UpdateQueryBuilder<Entity extends ObjectLiteral> {
69
- /**
70
- * Sets WHERE IN condition in the query builder.
71
- * If you had previously WHERE expression defined,
72
- * calling this function will override previously set WHERE conditions.
73
- */
74
- whereIsIn(field: string, array?: ArgsType): UpdateQueryBuilder<Entity>;
75
- /**
76
- * Adds new AND WHERE IN condition in the query builder.
77
- */
78
- andWhereIsIn(field: string, array?: ArgsType): UpdateQueryBuilder<Entity>;
79
- /**
80
- * Adds new OR WHERE IN condition in the query builder.
81
- */
82
- orWhereIsIn(field: string, array?: ArgsType): UpdateQueryBuilder<Entity>;
83
- /**
84
- * Sets WHERE NOT IN condition in the query builder.
85
- * If you had previously WHERE expression defined,
86
- * calling this function will override previously set WHERE conditions.
87
- */
88
- whereIsNotIn(field: string, array?: ArgsType): UpdateQueryBuilder<Entity>;
89
- /**
90
- * Adds new AND WHERE NOT IN condition in the query builder.
91
- */
92
- andWhereIsNotIn(field: string, array?: ArgsType): UpdateQueryBuilder<Entity>;
93
- /**
94
- * Adds new OR WHERE NOT IN condition in the query builder.
95
- */
96
- orWhereIsNotIn(field: string, array?: ArgsType): UpdateQueryBuilder<Entity>;
42
+ interface UpdateQueryBuilder<Entity extends ObjectLiteral> extends WhereIsInMethods {
97
43
  }
98
44
  }
99
45
  declare module 'typeorm/query-builder/DeleteQueryBuilder' {
100
- interface DeleteQueryBuilder<Entity extends ObjectLiteral> {
101
- /**
102
- * Sets WHERE IN condition in the query builder.
103
- * If you had previously WHERE expression defined,
104
- * calling this function will override previously set WHERE conditions.
105
- */
106
- whereIsIn(field: string, array?: ArgsType): DeleteQueryBuilder<Entity>;
107
- /**
108
- * Adds new AND WHERE IN condition in the query builder.
109
- */
110
- andWhereIsIn(field: string, array?: ArgsType): DeleteQueryBuilder<Entity>;
111
- /**
112
- * Adds new OR WHERE IN condition in the query builder.
113
- */
114
- orWhereIsIn(field: string, array?: ArgsType): DeleteQueryBuilder<Entity>;
115
- /**
116
- * Sets WHERE NOT IN condition in the query builder.
117
- * If you had previously WHERE expression defined,
118
- * calling this function will override previously set WHERE conditions.
119
- */
120
- whereIsNotIn(field: string, array?: ArgsType): DeleteQueryBuilder<Entity>;
121
- /**
122
- * Adds new AND WHERE NOT IN condition in the query builder.
123
- */
124
- andWhereIsNotIn(field: string, array?: ArgsType): DeleteQueryBuilder<Entity>;
125
- /**
126
- * Adds new OR WHERE NOT IN condition in the query builder.
127
- */
128
- orWhereIsNotIn(field: string, array?: ArgsType): DeleteQueryBuilder<Entity>;
46
+ interface DeleteQueryBuilder<Entity extends ObjectLiteral> extends WhereIsInMethods {
129
47
  }
130
48
  }
131
49
  declare module 'typeorm/query-builder/SoftDeleteQueryBuilder' {
132
- interface SoftDeleteQueryBuilder<Entity extends ObjectLiteral> {
133
- /**
134
- * Sets WHERE IN condition in the query builder.
135
- * If you had previously WHERE expression defined,
136
- * calling this function will override previously set WHERE conditions.
137
- */
138
- whereIsIn(field: string, array?: ArgsType): SoftDeleteQueryBuilder<Entity>;
139
- /**
140
- * Adds new AND WHERE IN condition in the query builder.
141
- */
142
- andWhereIsIn(field: string, array?: ArgsType): SoftDeleteQueryBuilder<Entity>;
143
- /**
144
- * Adds new OR WHERE IN condition in the query builder.
145
- */
146
- orWhereIsIn(field: string, array?: ArgsType): SoftDeleteQueryBuilder<Entity>;
147
- /**
148
- * Sets WHERE NOT IN condition in the query builder.
149
- * If you had previously WHERE expression defined,
150
- * calling this function will override previously set WHERE conditions.
151
- */
152
- whereIsNotIn(field: string, array?: ArgsType): SoftDeleteQueryBuilder<Entity>;
153
- /**
154
- * Adds new AND WHERE NOT IN condition in the query builder.
155
- */
156
- andWhereIsNotIn(field: string, array?: ArgsType): SoftDeleteQueryBuilder<Entity>;
157
- /**
158
- * Adds new OR WHERE NOT IN condition in the query builder.
159
- */
160
- orWhereIsNotIn(field: string, array?: ArgsType): SoftDeleteQueryBuilder<Entity>;
50
+ interface SoftDeleteQueryBuilder<Entity extends ObjectLiteral> extends WhereIsInMethods {
161
51
  }
162
52
  }
@@ -1,41 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const typeorm_1 = require("typeorm");
4
- const SoftDeleteQueryBuilder_1 = require("typeorm/query-builder/SoftDeleteQueryBuilder");
5
3
  const prototype_utils_1 = require("../utils/prototype.utils");
6
4
  const where_utils_1 = require("../utils/where.utils");
5
+ /* eslint-enable @typescript-eslint/no-empty-interface, @typescript-eslint/no-unused-vars */
7
6
  // patching
7
+ const createWhereIsInMethod = (method, operator) => function (field, array) {
8
+ return attachWhereIsIn(this, method, field, operator, array);
9
+ };
8
10
  const extension = {
9
11
  prototype: {
10
- whereIsIn: function (field, array) {
11
- return attachWhereIsIn(this, 'where', field, 'IN', array);
12
- },
13
- andWhereIsIn: function (field, array) {
14
- return attachWhereIsIn(this, 'andWhere', field, 'IN', array);
15
- },
16
- orWhereIsIn: function (field, array) {
17
- return attachWhereIsIn(this, 'orWhere', field, 'IN', array);
18
- },
19
- whereIsNotIn: function (field, array) {
20
- return attachWhereIsIn(this, 'where', field, 'NOT IN', array);
21
- },
22
- andWhereIsNotIn: function (field, array) {
23
- return attachWhereIsIn(this, 'andWhere', field, 'NOT IN', array);
24
- },
25
- orWhereIsNotIn: function (field, array) {
26
- return attachWhereIsIn(this, 'orWhere', field, 'NOT IN', array);
27
- },
12
+ whereIsIn: createWhereIsInMethod('where', 'IN'),
13
+ andWhereIsIn: createWhereIsInMethod('andWhere', 'IN'),
14
+ orWhereIsIn: createWhereIsInMethod('orWhere', 'IN'),
15
+ whereIsNotIn: createWhereIsInMethod('where', 'NOT IN'),
16
+ andWhereIsNotIn: createWhereIsInMethod('andWhere', 'NOT IN'),
17
+ orWhereIsNotIn: createWhereIsInMethod('orWhere', 'NOT IN'),
28
18
  },
29
19
  };
30
- const queryBuilders = [
31
- typeorm_1.SelectQueryBuilder,
32
- typeorm_1.UpdateQueryBuilder,
33
- typeorm_1.DeleteQueryBuilder,
34
- SoftDeleteQueryBuilder_1.SoftDeleteQueryBuilder,
35
- ];
36
- queryBuilders.forEach((builder) => {
37
- (0, prototype_utils_1.patchPrototype)(builder, extension);
38
- });
20
+ (0, prototype_utils_1.patchPrototypes)(prototype_utils_1.WHERE_QUERY_BUILDERS, extension);
39
21
  // implementation
40
22
  function attachWhereIsIn(builder, method, field, operator, array) {
41
23
  if (method && typeof field === 'string' && typeof operator === 'string') {
@@ -1,7 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const typeorm_1 = require("typeorm");
4
- const SoftDeleteQueryBuilder_1 = require("typeorm/query-builder/SoftDeleteQueryBuilder");
5
3
  const prototype_utils_1 = require("../utils/prototype.utils");
6
4
  const query_builder_utils_1 = require("../utils/query-builder.utils");
7
5
  const sql_utils_1 = require("../utils/sql.utils");
@@ -23,15 +21,7 @@ const extension = {
23
21
  orWhereJsonHasKey: createWhereJsonHasKeyMethod('orWhere'),
24
22
  },
25
23
  };
26
- const queryBuilders = [
27
- typeorm_1.SelectQueryBuilder,
28
- typeorm_1.UpdateQueryBuilder,
29
- typeorm_1.DeleteQueryBuilder,
30
- SoftDeleteQueryBuilder_1.SoftDeleteQueryBuilder,
31
- ];
32
- queryBuilders.forEach((builder) => {
33
- (0, prototype_utils_1.patchPrototype)(builder, extension);
34
- });
24
+ (0, prototype_utils_1.patchPrototypes)(prototype_utils_1.WHERE_QUERY_BUILDERS, extension);
35
25
  // implementation
36
26
  /**
37
27
  * `CAST("table"."column" AS jsonb)`: makes `json` and `simple-json` (text) columns work, and is dropped by PostgreSQL
@@ -22,18 +22,12 @@ const extension = {
22
22
  // implementation
23
23
  function attachRelationExists(builder, method, negate, relationSelection, alias, where) {
24
24
  const methodName = `${method}Relation${negate ? 'Not' : ''}Exists`;
25
- const key = (0, query_builder_utils_1.getTypedSelectionKey)(builder, relationSelection);
26
- if (Array.isArray(key)) {
27
- throw new TypeError(`${methodName} expects the callback to select one relation, got ${key.length}: ${key.join(', ')}`);
28
- }
29
- const dot = key.indexOf('.');
30
- const ownerAlias = key.slice(0, dot);
31
- const propertyPath = key.slice(dot + 1);
32
- const aliases = queryAliases(builder);
25
+ const { aliasName: ownerAlias, propertyPath } = (0, query_builder_utils_1.resolveTypedProperty)(builder, relationSelection, methodName);
26
+ const aliases = (0, query_builder_utils_1.listQueryAliases)(builder);
33
27
  const owner = aliases.find((candidate) => candidate.name === ownerAlias);
34
28
  const relation = (owner === null || owner === void 0 ? void 0 : owner.hasMetadata) ? owner.metadata.findRelationWithPropertyPath(propertyPath) : undefined;
35
- if (!relation) {
36
- throw new TypeError(`${methodName}: ${key} is not a relation of an entity of the query`);
29
+ if (!owner || !relation) {
30
+ throw new TypeError(`${methodName}: ${ownerAlias}.${propertyPath} is not a relation of an entity of the query`);
37
31
  }
38
32
  // in the subquery the alias would hide the outer one the join condition refers to; SQLite matches
39
33
  // names without case, so 'USER' would hide 'user' there
@@ -45,26 +39,12 @@ function attachRelationExists(builder, method, negate, relationSelection, alias,
45
39
  .createQueryBuilder()
46
40
  .select('1')
47
41
  .from(relation.inverseEntityMetadata.target, alias);
48
- const correlation = joinCondition(relation, ownerAlias, alias, column, subQuery);
42
+ const correlation = joinCondition(relation, owner.name, alias, column, subQuery);
49
43
  where === null || where === void 0 ? void 0 : where(subQuery);
50
44
  // after the caller's conditions, so a `where` or an `orWhere` of theirs can't drop or bypass it
51
45
  (0, where_utils_1.andWhereNarrowing)(subQuery, correlation);
52
46
  return (0, where_exists_extension_1.attachExists)(builder, method, subQuery, negate);
53
47
  }
54
- /**
55
- * The aliases of the query and of the queries it is part of. Inside `Brackets` the builder has the outer
56
- * query's main alias but none of its joins: those are on its parent.
57
- */
58
- function queryAliases(builder) {
59
- const aliases = [];
60
- // parentQueryBuilder is protected in TypeORM's types
61
- let query = builder;
62
- for (; query; query = query.parentQueryBuilder) {
63
- const { aliases: own, mainAlias } = query.expressionMap;
64
- aliases.push(...own, ...(mainAlias ? [mainAlias] : []));
65
- }
66
- return aliases;
67
- }
68
48
  const equal = (left, right) => `${left} = ${right}`;
69
49
  /** The condition between the related rows (`alias`) and the outer row (`ownerAlias`); joins the junction table of a many-to-many. */
70
50
  function joinCondition(relation, ownerAlias, alias, column, subQuery) {
package/dist/index.d.ts CHANGED
@@ -4,9 +4,4 @@ export * from './types/interfaces';
4
4
  export * from './types/extensions';
5
5
  export type { Json } from './types/modules/proxy-callback.types';
6
6
  export type { TypedRoot, WithTypedRoot } from './types/modules/typed-root.types';
7
- export * from './utils/table.utils';
8
- export { escapeLikePattern } from './utils/search.utils';
9
- export { COCKROACHDB_RESERVED_KEY_WORDS, findBareReservedQualifiers, POSTGRES_RESERVED_KEY_WORDS, } from './utils/reserved-qualifier.utils';
10
- export type { ReservedQualifier } from './utils/reserved-qualifier.utils';
11
- export { disableReservedQualifierGuard, enableReservedQualifierGuard, ReservedQualifierError, } from './utils/reserved-qualifier-guard.utils';
12
- export type { ReservedQualifierGuardOptions } from './utils/reserved-qualifier-guard.utils';
7
+ export * from './helpers';
package/dist/index.js CHANGED
@@ -14,19 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.ReservedQualifierError = exports.enableReservedQualifierGuard = exports.disableReservedQualifierGuard = exports.POSTGRES_RESERVED_KEY_WORDS = exports.findBareReservedQualifiers = exports.COCKROACHDB_RESERVED_KEY_WORDS = exports.escapeLikePattern = void 0;
18
17
  __exportStar(require("./extensions"), exports);
19
18
  __exportStar(require("./decorators"), exports);
20
19
  __exportStar(require("./types/interfaces"), exports);
21
20
  __exportStar(require("./types/extensions"), exports);
22
- __exportStar(require("./utils/table.utils"), exports);
23
- var search_utils_1 = require("./utils/search.utils");
24
- Object.defineProperty(exports, "escapeLikePattern", { enumerable: true, get: function () { return search_utils_1.escapeLikePattern; } });
25
- var reserved_qualifier_utils_1 = require("./utils/reserved-qualifier.utils");
26
- Object.defineProperty(exports, "COCKROACHDB_RESERVED_KEY_WORDS", { enumerable: true, get: function () { return reserved_qualifier_utils_1.COCKROACHDB_RESERVED_KEY_WORDS; } });
27
- Object.defineProperty(exports, "findBareReservedQualifiers", { enumerable: true, get: function () { return reserved_qualifier_utils_1.findBareReservedQualifiers; } });
28
- Object.defineProperty(exports, "POSTGRES_RESERVED_KEY_WORDS", { enumerable: true, get: function () { return reserved_qualifier_utils_1.POSTGRES_RESERVED_KEY_WORDS; } });
29
- var reserved_qualifier_guard_utils_1 = require("./utils/reserved-qualifier-guard.utils");
30
- Object.defineProperty(exports, "disableReservedQualifierGuard", { enumerable: true, get: function () { return reserved_qualifier_guard_utils_1.disableReservedQualifierGuard; } });
31
- Object.defineProperty(exports, "enableReservedQualifierGuard", { enumerable: true, get: function () { return reserved_qualifier_guard_utils_1.enableReservedQualifierGuard; } });
32
- Object.defineProperty(exports, "ReservedQualifierError", { enumerable: true, get: function () { return reserved_qualifier_guard_utils_1.ReservedQualifierError; } });
21
+ __exportStar(require("./helpers"), exports);
@@ -1,10 +1,14 @@
1
1
  import { ObjectLiteral, SelectQueryBuilder } from 'typeorm';
2
+ import type { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
3
+ /** `addSelect`'s selection: an SQL expression, or a factory that builds a subquery on the builder it is given. */
4
+ export type CalculatedSelection<SubEntity extends ObjectLiteral = ObjectLiteral> = string | ((qb: SelectQueryBuilder<ObjectLiteral>) => SelectQueryBuilder<SubEntity>);
2
5
  type ResolvedCalculatedColumn = {
3
6
  /** The key TypeORM reads the column's value from when it builds the entity. */
4
7
  key: string;
5
8
  /** `Entity.property`, for error messages. */
6
9
  label: string;
7
10
  };
11
+ export declare const isCalculated: (column: ColumnMetadata | undefined) => column is ColumnMetadata;
8
12
  /** Whether `property` of the entity of `aliasName` (the main alias by default) is a `@CalculatedColumn`. */
9
13
  export declare function isCalculatedColumn<Entity extends ObjectLiteral>(builder: SelectQueryBuilder<Entity>, property: string, aliasName?: string): boolean;
10
14
  /** The `@CalculatedColumn` `property` of the entity of `aliasName`; throws a `TypeError` for anything else. */
@@ -18,4 +22,8 @@ export declare function resolveCalculatedColumn<Entity extends ObjectLiteral>(bu
18
22
  * through with `take` / `skip` and joins, which takes only select aliases it knows unquoted.
19
23
  */
20
24
  export declare function selectCalculatedForOrder<Entity extends ObjectLiteral>(builder: SelectQueryBuilder<Entity>, property: string, aliasName: string | undefined, methodName: string): string;
25
+ /** Selects `selection` into the `@CalculatedColumn` `property` of the entity of `aliasName` (the main alias by default). */
26
+ export declare function addSelectCalculatedColumn<Entity extends ObjectLiteral, SubEntity extends ObjectLiteral>(builder: SelectQueryBuilder<Entity>, selection: CalculatedSelection<SubEntity>, property: string, aliasName: string | undefined, methodName: string): SelectQueryBuilder<Entity>;
27
+ /** ORDER BY the value of a `@CalculatedColumn` selected with `addSelectCalculated`, through `orderBy` or `addOrderBy`. */
28
+ export declare function orderByCalculatedColumn<Entity extends ObjectLiteral>(builder: SelectQueryBuilder<Entity>, method: 'orderBy' | 'addOrderBy', property: string, order: 'ASC' | 'DESC' | undefined, nulls: 'NULLS FIRST' | 'NULLS LAST' | undefined, aliasName: string | undefined, methodName: string): SelectQueryBuilder<Entity>;
21
29
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.selectCalculatedForOrder = exports.resolveCalculatedColumn = exports.isCalculatedColumn = void 0;
3
+ exports.orderByCalculatedColumn = exports.addSelectCalculatedColumn = exports.selectCalculatedForOrder = exports.resolveCalculatedColumn = exports.isCalculatedColumn = exports.isCalculated = void 0;
4
4
  const DriverUtils_1 = require("typeorm/driver/DriverUtils");
5
5
  const sql_utils_1 = require("./sql.utils");
6
6
  function findCalculatedColumn(builder, property, aliasName) {
@@ -19,10 +19,11 @@ function findCalculatedColumn(builder, property, aliasName) {
19
19
  }
20
20
  // @CalculatedColumn: a virtual property without the query of TypeORM's @VirtualColumn
21
21
  const isCalculated = (column) => !!(column === null || column === void 0 ? void 0 : column.isVirtualProperty) && !column.query;
22
+ exports.isCalculated = isCalculated;
22
23
  /** Whether `property` of the entity of `aliasName` (the main alias by default) is a `@CalculatedColumn`. */
23
24
  function isCalculatedColumn(builder, property, aliasName) {
24
25
  var _a;
25
- return isCalculated((_a = findCalculatedColumn(builder, property, aliasName)) === null || _a === void 0 ? void 0 : _a.column);
26
+ return (0, exports.isCalculated)((_a = findCalculatedColumn(builder, property, aliasName)) === null || _a === void 0 ? void 0 : _a.column);
26
27
  }
27
28
  exports.isCalculatedColumn = isCalculatedColumn;
28
29
  /** The `@CalculatedColumn` `property` of the entity of `aliasName`; throws a `TypeError` for anything else. */
@@ -33,7 +34,7 @@ function resolveCalculatedColumn(builder, property, aliasName, methodName) {
33
34
  throw new TypeError(`${methodName}: the alias "${aliasName !== null && aliasName !== void 0 ? aliasName : (_a = builder.expressionMap.mainAlias) === null || _a === void 0 ? void 0 : _a.name}" has no entity with "${property}"`);
34
35
  }
35
36
  const label = `${found.entityName}.${property}`;
36
- if (!isCalculated(found.column)) {
37
+ if (!(0, exports.isCalculated)(found.column)) {
37
38
  throw new TypeError(`${methodName}: ${label} is not a @CalculatedColumn`);
38
39
  }
39
40
  // shortened past the driver's alias length limit, as TypeORM does it
@@ -61,3 +62,19 @@ function selectCalculatedForOrder(builder, property, aliasName, methodName) {
61
62
  return orderAlias;
62
63
  }
63
64
  exports.selectCalculatedForOrder = selectCalculatedForOrder;
65
+ /** Selects `selection` into the `@CalculatedColumn` `property` of the entity of `aliasName` (the main alias by default). */
66
+ function addSelectCalculatedColumn(builder, selection, property, aliasName, methodName) {
67
+ const { key } = resolveCalculatedColumn(builder, property, aliasName, methodName);
68
+ // two calls: addSelect's overloads take a string or a factory, not their union
69
+ if (typeof selection === 'function') {
70
+ return builder.addSelect(selection, key);
71
+ }
72
+ return builder.addSelect(selection, key);
73
+ }
74
+ exports.addSelectCalculatedColumn = addSelectCalculatedColumn;
75
+ /** ORDER BY the value of a `@CalculatedColumn` selected with `addSelectCalculated`, through `orderBy` or `addOrderBy`. */
76
+ function orderByCalculatedColumn(builder, method, property, order, nulls, aliasName, methodName) {
77
+ const orderAlias = selectCalculatedForOrder(builder, property, aliasName, methodName);
78
+ return builder[method](orderAlias, order, nulls);
79
+ }
80
+ exports.orderByCalculatedColumn = orderByCalculatedColumn;
@@ -1,2 +1,4 @@
1
+ /** A Date, also one from another realm (a vm context, a test runner's sandbox), where `instanceof Date` is false. */
2
+ export declare const isDate: (value: unknown) => value is Date;
1
3
  export declare const isNil: (val: unknown) => boolean;
2
4
  export declare function randomString(length?: number): string;
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.randomString = exports.isNil = void 0;
3
+ exports.randomString = exports.isNil = exports.isDate = void 0;
4
+ /** A Date, also one from another realm (a vm context, a test runner's sandbox), where `instanceof Date` is false. */
5
+ const isDate = (value) => Object.prototype.toString.call(value) === '[object Date]';
6
+ exports.isDate = isDate;
4
7
  const isNil = (val) => typeof val === 'undefined' || val === null;
5
8
  exports.isNil = isNil;
6
9
  function randomString(length = 21) {
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildKeysetCondition = exports.getTextCastType = exports.supportsRowValueComparison = exports.decodeCursor = exports.encodeCursor = exports.InvalidCursorError = void 0;
4
4
  const sql_utils_1 = require("./sql.utils");
5
+ const common_utils_1 = require("./common.utils");
5
6
  /** A cursor that can't be decoded or doesn't belong to the query's order (e.g. tampered with). */
6
7
  class InvalidCursorError extends TypeError {
7
8
  constructor(message) {
@@ -10,9 +11,8 @@ class InvalidCursorError extends TypeError {
10
11
  }
11
12
  }
12
13
  exports.InvalidCursorError = InvalidCursorError;
13
- const isDate = (value) => Object.prototype.toString.call(value) === '[object Date]';
14
14
  const toCursorValue = (value) => {
15
- if (isDate(value)) {
15
+ if ((0, common_utils_1.isDate)(value)) {
16
16
  return { $date: value.toISOString() };
17
17
  }
18
18
  if (typeof value === 'bigint') {
@@ -77,9 +77,7 @@ function decodeCursor(cursor, fields) {
77
77
  }
78
78
  exports.decodeCursor = decodeCursor;
79
79
  /** Databases that compare row values: `(a, b) < (1, 2)`. */
80
- const supportsRowValueComparison = (driver) => driver === 'postgres' ||
81
- driver === 'aurora-postgres' ||
82
- driver === 'cockroachdb' ||
80
+ const supportsRowValueComparison = (driver) => (0, sql_utils_1.isPostgresLikeDriver)(driver) ||
83
81
  (0, sql_utils_1.isMysqlLikeDriver)(driver) ||
84
82
  (0, sql_utils_1.isSqliteLikeDriver)(driver);
85
83
  exports.supportsRowValueComparison = supportsRowValueComparison;
@@ -88,7 +86,7 @@ exports.supportsRowValueComparison = supportsRowValueComparison;
88
86
  * (PostgreSQL timestamps have microseconds, a JS Date only milliseconds). `undefined` when unknown.
89
87
  */
90
88
  const getTextCastType = (driver) => {
91
- if (driver === 'postgres' || driver === 'aurora-postgres' || driver === 'cockroachdb' || (0, sql_utils_1.isSqliteLikeDriver)(driver)) {
89
+ if ((0, sql_utils_1.isPostgresLikeDriver)(driver) || (0, sql_utils_1.isSqliteLikeDriver)(driver)) {
92
90
  return 'text';
93
91
  }
94
92
  if ((0, sql_utils_1.isMysqlLikeDriver)(driver)) {
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.toJsonPathSql = exports.buildJsonPath = exports.isJsonColumn = void 0;
4
4
  const sql_utils_1 = require("./sql.utils");
5
+ const common_utils_1 = require("./common.utils");
5
6
  const JSON_COLUMN_TYPES = ['json', 'jsonb', 'simple-json'];
6
7
  const isJsonColumn = (column) => JSON_COLUMN_TYPES.includes(String(column.type));
7
8
  exports.isJsonColumn = isJsonColumn;
@@ -14,7 +15,6 @@ function buildJsonPath(fieldNames, jsonOperator) {
14
15
  .join(' ');
15
16
  }
16
17
  exports.buildJsonPath = buildJsonPath;
17
- const isDate = (value) => Object.prototype.toString.call(value) === '[object Date]';
18
18
  /**
19
19
  * PostgreSQL type to compare a `->>` value (text) with `value` as: text compares `'9' >= '10'` as true.
20
20
  * An array (IN, ANY) is typed by its first value; strings and unknown values stay text.
@@ -27,7 +27,7 @@ function getJsonTextCast(value) {
27
27
  if (typeof sample === 'boolean') {
28
28
  return 'boolean';
29
29
  }
30
- if (isDate(sample)) {
30
+ if ((0, common_utils_1.isDate)(sample)) {
31
31
  return 'timestamptz';
32
32
  }
33
33
  return undefined;
@@ -1,4 +1,9 @@
1
+ import type { ObjectLiteral, SelectQueryBuilder } from "typeorm";
1
2
  import { PaginationFilter } from "../types/interfaces/pagination.interface";
3
+ /** The page size to read: a number or a numeric string of at least 1, rounded down; `defaultPageSize` otherwise. */
4
+ export declare const normalizePageSize: (pageSize: unknown) => number;
5
+ /** Limits the rows with `take`, which counts entities rather than rows when the query joins a collection, or with `limit`. */
6
+ export declare const setPageLimit: <Entity extends ObjectLiteral>(builder: SelectQueryBuilder<Entity>, limit: number, useTakeAndSkip: boolean) => SelectQueryBuilder<Entity>;
2
7
  export declare const getLimitAndOffset: ({ page, pageSize }: PaginationFilter) => {
3
8
  limit: number;
4
9
  offset: number;
@@ -1,16 +1,26 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getLimitAndOffset = void 0;
3
+ exports.getLimitAndOffset = exports.setPageLimit = exports.normalizePageSize = void 0;
4
4
  const constants_1 = require("../constants");
5
+ // an unparsed query parameter is a string: "20" + 1 would be "201"
6
+ const toPositiveInteger = (value, fallback) => {
7
+ const number = typeof value === 'string' && value.trim() !== '' ? Number(value) : value;
8
+ return typeof number === 'number' && Number.isFinite(number) && number >= 1 ? Math.floor(number) : fallback;
9
+ };
10
+ /** The page size to read: a number or a numeric string of at least 1, rounded down; `defaultPageSize` otherwise. */
11
+ const normalizePageSize = (pageSize) => toPositiveInteger(pageSize, constants_1.defaultPageSize);
12
+ exports.normalizePageSize = normalizePageSize;
13
+ /** Limits the rows with `take`, which counts entities rather than rows when the query joins a collection, or with `limit`. */
14
+ const setPageLimit = (builder, limit, useTakeAndSkip) => (useTakeAndSkip ? builder.take(limit) : builder.limit(limit));
15
+ exports.setPageLimit = setPageLimit;
5
16
  const getLimitAndOffset = ({ page, pageSize }) => {
6
- if (!page || page < 1) {
7
- page = 1;
8
- }
9
- if (!pageSize || pageSize < 1) {
10
- pageSize = constants_1.defaultPageSize;
11
- }
12
- const offset = (page >= 1 ? page - 1 : 0) * pageSize;
13
- const limit = pageSize;
14
- return { limit, offset, page, pageSize };
17
+ const normalizedPage = toPositiveInteger(page, 1);
18
+ const normalizedPageSize = (0, exports.normalizePageSize)(pageSize);
19
+ return {
20
+ limit: normalizedPageSize,
21
+ offset: (normalizedPage - 1) * normalizedPageSize,
22
+ page: normalizedPage,
23
+ pageSize: normalizedPageSize,
24
+ };
15
25
  };
16
26
  exports.getLimitAndOffset = getLimitAndOffset;
@@ -1,7 +1,17 @@
1
1
  import type { ObjectLiteral } from 'typeorm';
2
+ /** The parameter names an SQL fragment refers to, as TypeORM reads its placeholders. */
3
+ export declare function getPlaceholderNames(sql: string): string[];
2
4
  /**
3
5
  * Renames the parameters of a subquery to unique names, in its SQL and in its parameters. A query
4
6
  * has one parameter namespace, so two subqueries with a `:status` each would otherwise both read
5
7
  * whichever value was set last. Placeholders that aren't keys of `parameters` stay as they are.
6
8
  */
7
9
  export declare function withUniqueParameterNames(sql: string, parameters: ObjectLiteral): [string, ObjectLiteral];
10
+ /**
11
+ * The SQL of a query, without the parentheses a `subQuery()` builder writes around itself, and its parameters, both
12
+ * renamed unique (see `withUniqueParameterNames`).
13
+ */
14
+ export declare function toSubQuerySql(query: {
15
+ getQuery(): string;
16
+ getParameters(): ObjectLiteral;
17
+ }): [string, ObjectLiteral];
@@ -1,9 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.withUniqueParameterNames = void 0;
3
+ exports.toSubQuerySql = exports.withUniqueParameterNames = exports.getPlaceholderNames = void 0;
4
4
  const sql_utils_1 = require("./sql.utils");
5
5
  // TypeORM's placeholder syntax, `:name` and `:...name`, as its drivers match it
6
6
  const PARAMETER_PLACEHOLDER = /:(\.\.\.)?([A-Za-z0-9_.]+)/g;
7
+ /** The parameter names an SQL fragment refers to, as TypeORM reads its placeholders. */
8
+ function getPlaceholderNames(sql) {
9
+ // a regex of its own: a global regex keeps its position between exec calls
10
+ const placeholder = new RegExp(PARAMETER_PLACEHOLDER.source, 'g');
11
+ const names = [];
12
+ for (let match = placeholder.exec(sql); match !== null; match = placeholder.exec(sql)) {
13
+ names.push(match[2]);
14
+ }
15
+ return names;
16
+ }
17
+ exports.getPlaceholderNames = getPlaceholderNames;
7
18
  /**
8
19
  * Renames the parameters of a subquery to unique names, in its SQL and in its parameters. A query
9
20
  * has one parameter namespace, so two subqueries with a `:status` each would otherwise both read
@@ -19,3 +30,13 @@ function withUniqueParameterNames(sql, parameters) {
19
30
  return [renamedSql, renamedParameters];
20
31
  }
21
32
  exports.withUniqueParameterNames = withUniqueParameterNames;
33
+ /**
34
+ * The SQL of a query, without the parentheses a `subQuery()` builder writes around itself, and its parameters, both
35
+ * renamed unique (see `withUniqueParameterNames`).
36
+ */
37
+ function toSubQuerySql(query) {
38
+ const sql = query.getQuery();
39
+ const wrapped = 'expressionMap' in query && query.expressionMap.subQuery;
40
+ return withUniqueParameterNames(wrapped ? sql.slice(1, -1) : sql, query.getParameters());
41
+ }
42
+ exports.toSubQuerySql = toSubQuerySql;
@@ -4,6 +4,7 @@ exports.attachPeriodFilter = void 0;
4
4
  const sql_utils_1 = require("./sql.utils");
5
5
  const where_utils_1 = require("./where.utils");
6
6
  const time_zone_utils_1 = require("./time-zone.utils");
7
+ const common_utils_1 = require("./common.utils");
7
8
  const DATE_ONLY = /^\d{4}-\d{2}-\d{2}$/;
8
9
  /** `'2024-01-31'` as a UTC midnight Date, or a `TypeError` if it is not a calendar date (`'2024-02-30'`). */
9
10
  function parseDateOnly(value, name) {
@@ -18,7 +19,7 @@ function normalizeBoundary(value, name) {
18
19
  if (value === undefined || value === null || value === '') {
19
20
  return undefined;
20
21
  }
21
- if (Object.prototype.toString.call(value) === '[object Date]') {
22
+ if ((0, common_utils_1.isDate)(value)) {
22
23
  if (isNaN(value.getTime())) {
23
24
  throw new TypeError(`Invalid ${name}: invalid Date`);
24
25
  }