typeorm-extensions 2.2.0-rc.6 → 2.2.0-rc.7

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 (66) hide show
  1. package/dist/extensions/cursor-pagination.extension.d.ts +2 -1
  2. package/dist/extensions/order.extension.d.ts +2 -2
  3. package/dist/extensions/pagination.extension.d.ts +1 -1
  4. package/dist/extensions/period-filter.extension.d.ts +4 -0
  5. package/dist/extensions/period-filter.extension.js +2 -0
  6. package/dist/extensions/typed/index.d.ts +1 -0
  7. package/dist/extensions/typed/index.js +1 -0
  8. package/dist/extensions/typed/typed-distinct/typed-distinct.extension.d.ts +2 -2
  9. package/dist/extensions/typed/typed-group-by/typed-group-by.extension.d.ts +2 -2
  10. package/dist/extensions/typed/typed-having/typed-having.extension.d.ts +4 -4
  11. package/dist/extensions/typed/typed-joins/typed-join-and-map.extension.d.ts +19 -0
  12. package/dist/extensions/typed/typed-joins/typed-join-and-map.extension.js +22 -0
  13. package/dist/extensions/typed/typed-joins/typed-joins.extension.d.ts +4 -4
  14. package/dist/extensions/typed/typed-order-by/typed-order-by-array-position.extension.d.ts +2 -2
  15. package/dist/extensions/typed/typed-order-by/typed-order-by.extension.d.ts +2 -2
  16. package/dist/extensions/typed/typed-root.extension.d.ts +26 -4
  17. package/dist/extensions/typed/typed-select/typed-select.extension.d.ts +6 -6
  18. package/dist/extensions/typed/typed-where/typed-period-filter.extension.d.ts +5 -1
  19. package/dist/extensions/typed/typed-where/typed-period-filter.extension.js +2 -0
  20. package/dist/extensions/typed/typed-where/typed-where-array.extension.d.ts +13 -9
  21. package/dist/extensions/typed/typed-where/typed-where-array.extension.js +2 -0
  22. package/dist/extensions/typed/typed-where/typed-where-ilike.extension.d.ts +10 -6
  23. package/dist/extensions/typed/typed-where/typed-where-ilike.extension.js +2 -0
  24. package/dist/extensions/typed/typed-where/typed-where-is-any.extension.d.ts +10 -6
  25. package/dist/extensions/typed/typed-where/typed-where-is-any.extension.js +2 -0
  26. package/dist/extensions/typed/typed-where/typed-where-is-distinct-from.extension.d.ts +10 -6
  27. package/dist/extensions/typed/typed-where/typed-where-is-distinct-from.extension.js +2 -0
  28. package/dist/extensions/typed/typed-where/typed-where-is-in.extension.d.ts +10 -6
  29. package/dist/extensions/typed/typed-where/typed-where-is-in.extension.js +2 -0
  30. package/dist/extensions/typed/typed-where/typed-where-json.extension.d.ts +10 -6
  31. package/dist/extensions/typed/typed-where/typed-where-json.extension.js +2 -0
  32. package/dist/extensions/typed/typed-where/typed-where-lower.extension.d.ts +10 -6
  33. package/dist/extensions/typed/typed-where/typed-where-lower.extension.js +2 -0
  34. package/dist/extensions/typed/typed-where/typed-where-similar.extension.d.ts +8 -4
  35. package/dist/extensions/typed/typed-where/typed-where-similar.extension.js +2 -0
  36. package/dist/extensions/typed/typed-where/typed-where.extension.d.ts +7 -3
  37. package/dist/extensions/typed/typed-where/typed-where.extension.js +2 -0
  38. package/dist/extensions/where-array.extension.d.ts +4 -0
  39. package/dist/extensions/where-array.extension.js +2 -0
  40. package/dist/extensions/where-is-any.extension.d.ts +41 -6
  41. package/dist/extensions/where-is-any.extension.js +2 -0
  42. package/dist/extensions/where-is-distinct-from.extension.d.ts +4 -0
  43. package/dist/extensions/where-is-distinct-from.extension.js +2 -0
  44. package/dist/extensions/where-is-in.extension.d.ts +38 -6
  45. package/dist/extensions/where-is-in.extension.js +2 -0
  46. package/dist/extensions/where-json.extension.d.ts +4 -0
  47. package/dist/extensions/where-json.extension.js +2 -0
  48. package/dist/extensions/where-relation-exists.extension.d.ts +6 -6
  49. package/dist/helpers.d.ts +4 -0
  50. package/dist/helpers.js +11 -3
  51. package/dist/index.d.ts +4 -0
  52. package/dist/index.js +9 -1
  53. package/dist/types/extensions/index.d.ts +1 -0
  54. package/dist/types/extensions/index.js +1 -0
  55. package/dist/types/extensions/typed-join-and-map.types.d.ts +6 -0
  56. package/dist/types/extensions/typed-join-and-map.types.js +2 -0
  57. package/dist/types/modules/typed-root.types.d.ts +11 -9
  58. package/dist/utils/query-builder.utils.d.ts +3 -2
  59. package/dist/utils/query-builder.utils.js +6 -4
  60. package/dist/utils/reserved-qualifier-guard.utils.d.ts +36 -0
  61. package/dist/utils/reserved-qualifier-guard.utils.js +98 -0
  62. package/dist/utils/reserved-qualifier.utils.d.ts +33 -0
  63. package/dist/utils/reserved-qualifier.utils.js +252 -0
  64. package/dist/utils/table.utils.d.ts +27 -11
  65. package/dist/utils/table.utils.js +49 -12
  66. package/package.json +2 -2
@@ -74,17 +74,7 @@ export type TableHelperTimeZone<T> = string | {
74
74
  /** The units of PostgreSQL's `date_trunc`. */
75
75
  export type DateTruncUnit = 'microseconds' | 'milliseconds' | 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year' | 'decade' | 'century' | 'millennium';
76
76
  export type JsonFieldRest<V> = [NonNullable<V>] extends [Record<string, unknown>] ? JsonFieldTuple<NonNullable<V>> : string[];
77
- /**
78
- * Creates a type-safe SQL helper for building column references, WHERE expressions,
79
- * JOIN clauses, and JSONB accessors for a given entity type.
80
- *
81
- * @example
82
- * const t = tableHelper<UserEntity>('user');
83
- * t.column('email') // → "user"."email"
84
- * t.where('id', '= :id') // → "user"."id" = :id
85
- * t.jsonColumn('metadata', '->>', 'role') // → "user"."metadata" ->> 'role'
86
- */
87
- export declare const tableHelper: <T extends ObjectLiteral>(alias?: string, options?: TableHelperOptions) => {
77
+ declare const createTableHelper: <T extends ObjectLiteral>(alias?: string, options?: TableHelperOptions, databaseNames?: ReadonlyMap<string, string>) => {
88
78
  alias: string | undefined;
89
79
  /**
90
80
  * Returns a quoted SQL column identifier, e.g. `"alias"."column"`. The column is always quoted as one
@@ -193,4 +183,30 @@ export declare const tableHelper: <T extends ObjectLiteral>(alias?: string, opti
193
183
  */
194
184
  dateTrunc(unit: DateTruncUnit, value: TableHelperExpression<T>, timeZone?: TableHelperTimeZone<T> | undefined): string;
195
185
  };
186
+ type TableHelperMemberName = keyof ReturnType<typeof createTableHelper>;
187
+ /**
188
+ * The helper `tableHelper` returns: its methods, and each column of the table as a read-only property,
189
+ * `t.email` for `t.column('email')`. A column named like a member (`alias`, `count`, …) is the member there.
190
+ */
191
+ export type TableHelper<T extends ObjectLiteral> = ReturnType<typeof createTableHelper<T>> & {
192
+ readonly [K in Exclude<ColumnName<T>, TableHelperMemberName>]: string;
193
+ };
194
+ /** An entity class, abstract ones included. */
195
+ export type EntityClass<T> = abstract new (...args: never[]) => T;
196
+ /**
197
+ * Creates a type-safe SQL helper for building column references, WHERE expressions,
198
+ * JOIN clauses, and JSONB accessors for a given entity type.
199
+ *
200
+ * Given the entity class, it takes property names and writes the column names the entity maps them to:
201
+ * `tableHelper(UserEntity, 'user').adminEmail` is `"user"."email"` for `@Column({ name: 'email' }) adminEmail`.
202
+ *
203
+ * @example
204
+ * const t = tableHelper<UserEntity>('user');
205
+ * t.column('email') // → "user"."email"
206
+ * t.email // → "user"."email", the same
207
+ * t.where('id', '= :id') // → "user"."id" = :id
208
+ * t.jsonColumn('metadata', '->>', 'role') // → "user"."metadata" ->> 'role'
209
+ */
210
+ export declare function tableHelper<T extends ObjectLiteral>(entity: EntityClass<T>, alias?: string, options?: TableHelperOptions): TableHelper<T>;
211
+ export declare function tableHelper<T extends ObjectLiteral>(alias?: string, options?: TableHelperOptions): TableHelper<T>;
196
212
  export {};
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.tableHelper = void 0;
4
+ const typeorm_1 = require("typeorm");
4
5
  const sql_utils_1 = require("./sql.utils");
5
6
  const json_path_utils_1 = require("./json-path.utils");
6
7
  /**
@@ -102,26 +103,17 @@ function jsonFunctions(driver, jsonb) {
102
103
  }
103
104
  // MySQL reads a backslash in a string as an escape (unless NO_BACKSLASH_ESCAPES): `\'` would end the literal
104
105
  const sqlString = (value, driver) => `'${((0, sql_utils_1.isMysqlLikeDriver)(driver) ? value.replace(/\\/g, '\\\\') : value).replace(/'/g, "''")}'`;
105
- /**
106
- * Creates a type-safe SQL helper for building column references, WHERE expressions,
107
- * JOIN clauses, and JSONB accessors for a given entity type.
108
- *
109
- * @example
110
- * const t = tableHelper<UserEntity>('user');
111
- * t.column('email') // → "user"."email"
112
- * t.where('id', '= :id') // → "user"."id" = :id
113
- * t.jsonColumn('metadata', '->>', 'role') // → "user"."metadata" ->> 'role'
114
- */
115
- const tableHelper = (alias, options = {}) => ({
106
+ const createTableHelper = (alias, options = {}, databaseNames) => ({
116
107
  alias,
117
108
  /**
118
109
  * Returns a quoted SQL column identifier, e.g. `"alias"."column"`. The column is always quoted as one
119
110
  * identifier, so names with other characters work too: `"user"."first-name"`.
120
111
  */
121
112
  column(columnName, alias) {
113
+ var _a;
122
114
  const { useQuotes = true, driver } = options;
123
115
  const tableAlias = alias !== null && alias !== void 0 ? alias : this.alias;
124
- const column = String(columnName);
116
+ const column = (_a = databaseNames === null || databaseNames === void 0 ? void 0 : databaseNames.get(String(columnName))) !== null && _a !== void 0 ? _a : String(columnName);
125
117
  if (!useQuotes) {
126
118
  return [tableAlias, column].filter(Boolean).join('.');
127
119
  }
@@ -316,4 +308,49 @@ const tableHelper = (alias, options = {}) => ({
316
308
  return `date_trunc('${unit}', ${toExpression(value, toColumn)}${zone})`;
317
309
  }
318
310
  });
311
+ // keys that JavaScript, Node and test tools read on any object (await, JSON.stringify, util.inspect, Jest): they
312
+ // must stay undefined, as must symbols. The members of Object.prototype are in the target already
313
+ const PROTOCOL_KEYS = new Set(['then', 'toJSON', 'inspect', 'asymmetricMatch', '$$typeof', 'nodeType']);
314
+ const columnAccess = {
315
+ get(target, key, receiver) {
316
+ if (typeof key === 'symbol' || key in target || PROTOCOL_KEYS.has(key)) {
317
+ return Reflect.get(target, key, receiver);
318
+ }
319
+ return target.column(key);
320
+ },
321
+ };
322
+ const databaseNamesByEntity = new WeakMap();
323
+ // The names set with `@Column({ name })` on the class or a parent, the nearest declaration winning. Every other
324
+ // column keeps its property name, as under TypeORM's default naming strategy. Columns of embedded entities are not read
325
+ const databaseColumnNames = (entity) => {
326
+ var _a;
327
+ const cached = databaseNamesByEntity.get(entity);
328
+ if (cached) {
329
+ return cached;
330
+ }
331
+ const lineage = [];
332
+ for (let target = entity; typeof target === 'function' && target !== Function.prototype; target = Object.getPrototypeOf(target)) {
333
+ lineage.push(target);
334
+ }
335
+ const names = new Map();
336
+ const depths = new Map();
337
+ for (const { target, propertyName, options } of (0, typeorm_1.getMetadataArgsStorage)().columns) {
338
+ const depth = lineage.indexOf(target);
339
+ if (depth !== -1 && options.name && depth < ((_a = depths.get(propertyName)) !== null && _a !== void 0 ? _a : Infinity)) {
340
+ names.set(propertyName, options.name);
341
+ depths.set(propertyName, depth);
342
+ }
343
+ }
344
+ databaseNamesByEntity.set(entity, names);
345
+ return names;
346
+ };
347
+ function tableHelper(entityOrAlias, aliasOrOptions, entityOptions) {
348
+ if (entityOrAlias === undefined && typeof aliasOrOptions === 'string') {
349
+ throw new TypeError(`tableHelper(entity, '${aliasOrOptions}'): the entity class is undefined, as a circular import leaves it at module load. Create the helper where it is used`);
350
+ }
351
+ const helper = typeof entityOrAlias === 'function'
352
+ ? createTableHelper(aliasOrOptions, entityOptions, databaseColumnNames(entityOrAlias))
353
+ : createTableHelper(entityOrAlias, aliasOrOptions);
354
+ return new Proxy(helper, columnAccess);
355
+ }
319
356
  exports.tableHelper = tableHelper;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typeorm-extensions",
3
- "version": "2.2.0-rc.6",
3
+ "version": "2.2.0-rc.7",
4
4
  "description": "typeorm commonly used extensions",
5
5
  "main": "./dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -14,7 +14,7 @@
14
14
  "scripts": {
15
15
  "build": "tsc -p .",
16
16
  "lint": "eslint . --ext .ts",
17
- "test:types": "tsc -p test/types && tsc -p test/types/tsconfig.loose.json"
17
+ "test:types": "tsc -p test/types && tsc -p test/types/tsconfig.loose.json && tsc -p test/types/typed-imports && tsc -p test/types/typed-imports/tsconfig.loose.json"
18
18
  },
19
19
  "keywords": [
20
20
  "typeorm",