metal-orm 1.0.41 → 1.0.43

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 (87) hide show
  1. package/README.md +74 -20
  2. package/dist/index.cjs +180 -74
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +142 -96
  5. package/dist/index.d.ts +142 -96
  6. package/dist/index.js +177 -74
  7. package/dist/index.js.map +1 -1
  8. package/package.json +8 -2
  9. package/scripts/run-eslint.mjs +34 -0
  10. package/src/codegen/typescript.ts +32 -15
  11. package/src/core/ast/builders.ts +7 -2
  12. package/src/core/ast/expression-builders.ts +0 -2
  13. package/src/core/ast/expression-nodes.ts +14 -5
  14. package/src/core/ast/expression-visitor.ts +11 -8
  15. package/src/core/ast/expression.ts +2 -2
  16. package/src/core/ast/join-node.ts +1 -1
  17. package/src/core/ast/query.ts +6 -6
  18. package/src/core/ast/window-functions.ts +10 -2
  19. package/src/core/ddl/dialects/base-schema-dialect.ts +30 -3
  20. package/src/core/ddl/dialects/mssql-schema-dialect.ts +4 -0
  21. package/src/core/ddl/dialects/mysql-schema-dialect.ts +2 -0
  22. package/src/core/ddl/dialects/postgres-schema-dialect.ts +13 -1
  23. package/src/core/ddl/dialects/render-reference.test.ts +69 -0
  24. package/src/core/ddl/dialects/sqlite-schema-dialect.ts +9 -0
  25. package/src/core/ddl/introspect/mssql.ts +42 -8
  26. package/src/core/ddl/introspect/mysql.ts +30 -6
  27. package/src/core/ddl/introspect/postgres.ts +88 -34
  28. package/src/core/ddl/introspect/run-select.ts +6 -4
  29. package/src/core/ddl/introspect/sqlite.ts +56 -11
  30. package/src/core/ddl/introspect/types.ts +0 -1
  31. package/src/core/ddl/introspect/utils.ts +3 -3
  32. package/src/core/ddl/schema-dialect.ts +1 -0
  33. package/src/core/ddl/schema-generator.ts +4 -12
  34. package/src/core/ddl/sql-writing.ts +4 -4
  35. package/src/core/dialect/abstract.ts +18 -6
  36. package/src/core/dialect/base/function-table-formatter.ts +3 -2
  37. package/src/core/dialect/base/join-compiler.ts +5 -3
  38. package/src/core/dialect/base/returning-strategy.ts +1 -0
  39. package/src/core/dialect/base/sql-dialect.ts +3 -3
  40. package/src/core/dialect/mssql/functions.ts +24 -25
  41. package/src/core/dialect/mssql/index.ts +1 -4
  42. package/src/core/dialect/mysql/functions.ts +0 -1
  43. package/src/core/dialect/postgres/functions.ts +33 -34
  44. package/src/core/dialect/postgres/index.ts +1 -0
  45. package/src/core/dialect/sqlite/functions.ts +18 -19
  46. package/src/core/dialect/sqlite/index.ts +2 -0
  47. package/src/core/execution/db-executor.ts +1 -1
  48. package/src/core/execution/executors/mysql-executor.ts +2 -2
  49. package/src/core/execution/executors/postgres-executor.ts +1 -1
  50. package/src/core/execution/pooling/pool.ts +2 -0
  51. package/src/core/functions/datetime.ts +1 -1
  52. package/src/core/functions/numeric.ts +1 -1
  53. package/src/core/functions/text.ts +1 -1
  54. package/src/decorators/bootstrap.ts +27 -8
  55. package/src/decorators/column.ts +3 -11
  56. package/src/decorators/decorator-metadata.ts +3 -9
  57. package/src/decorators/entity.ts +21 -5
  58. package/src/decorators/relations.ts +2 -11
  59. package/src/orm/entity-context.ts +8 -8
  60. package/src/orm/entity-meta.ts +8 -8
  61. package/src/orm/entity-metadata.ts +11 -9
  62. package/src/orm/entity.ts +28 -29
  63. package/src/orm/execute.ts +4 -4
  64. package/src/orm/hydration.ts +42 -39
  65. package/src/orm/identity-map.ts +1 -1
  66. package/src/orm/lazy-batch.ts +9 -9
  67. package/src/orm/orm-session.ts +24 -23
  68. package/src/orm/orm.ts +2 -5
  69. package/src/orm/relation-change-processor.ts +12 -11
  70. package/src/orm/relations/belongs-to.ts +11 -11
  71. package/src/orm/relations/has-many.ts +10 -10
  72. package/src/orm/relations/has-one.ts +8 -7
  73. package/src/orm/relations/many-to-many.ts +13 -13
  74. package/src/orm/runtime-types.ts +4 -4
  75. package/src/orm/save-graph.ts +31 -25
  76. package/src/orm/unit-of-work.ts +17 -17
  77. package/src/query-builder/delete.ts +4 -3
  78. package/src/query-builder/hydration-manager.ts +6 -5
  79. package/src/query-builder/insert.ts +12 -8
  80. package/src/query-builder/query-ast-service.ts +2 -2
  81. package/src/query-builder/raw-column-parser.ts +2 -1
  82. package/src/query-builder/select-helpers.ts +2 -2
  83. package/src/query-builder/select.ts +31 -31
  84. package/src/query-builder/update.ts +4 -3
  85. package/src/schema/column.ts +26 -26
  86. package/src/schema/table.ts +239 -115
  87. package/src/schema/types.ts +22 -22
@@ -1,4 +1,10 @@
1
- import type { EntityInstance } from '../schema/types.js';
1
+ import type {
2
+ EntityInstance,
3
+ HasManyCollection,
4
+ HasOneReference,
5
+ BelongsToReference,
6
+ ManyToManyCollection
7
+ } from '../schema/types.js';
2
8
  import {
3
9
  RelationKinds,
4
10
  type BelongsToManyRelation,
@@ -19,12 +25,12 @@ export interface SaveGraphOptions {
19
25
  pruneMissing?: boolean;
20
26
  }
21
27
 
22
- type AnyEntity = Record<string, any>;
28
+ type AnyEntity = Record<string, unknown>;
23
29
 
24
30
  const toKey = (value: unknown): string => (value === null || value === undefined ? '' : String(value));
25
31
 
26
- const pickColumns = (table: TableDef, payload: AnyEntity): Record<string, any> => {
27
- const columns: Record<string, any> = {};
32
+ const pickColumns = (table: TableDef, payload: AnyEntity): Record<string, unknown> => {
33
+ const columns: Record<string, unknown> = {};
28
34
  for (const key of Object.keys(table.columns)) {
29
35
  if (payload[key] !== undefined) {
30
36
  columns[key] = payload[key];
@@ -71,7 +77,7 @@ const isEntityInCollection = (items: AnyEntity[], pkName: string, entity: AnyEnt
71
77
  return items.some(item => toKey(item[pkName]) === toKey(entityPk));
72
78
  };
73
79
 
74
- const findInCollectionByPk = (items: AnyEntity[], pkName: string, pkValue: any): AnyEntity | undefined => {
80
+ const findInCollectionByPk = (items: AnyEntity[], pkName: string, pkValue: unknown): AnyEntity | undefined => {
75
81
  if (pkValue === undefined || pkValue === null) return undefined;
76
82
  return items.find(item => toKey(item[pkName]) === toKey(pkValue));
77
83
  };
@@ -85,12 +91,12 @@ const handleHasMany = async (
85
91
  options: SaveGraphOptions
86
92
  ): Promise<void> => {
87
93
  if (!Array.isArray(payload)) return;
88
- const collection = root[relationName];
94
+ const collection = root[relationName] as unknown as HasManyCollection<unknown>;
89
95
  await collection.load();
90
96
 
91
97
  const targetTable = relation.target;
92
98
  const targetPk = findPrimaryKey(targetTable);
93
- const existing = collection.getItems();
99
+ const existing = collection.getItems() as unknown as AnyEntity[];
94
100
  const seen = new Set<string>();
95
101
 
96
102
  for (const item of payload) {
@@ -103,10 +109,10 @@ const handleHasMany = async (
103
109
  (pkValue !== undefined && pkValue !== null ? session.getEntity(targetTable, pkValue) : undefined);
104
110
 
105
111
  const entity = current ?? ensureEntity(session, targetTable, asObj);
106
- assignColumns(targetTable, entity, asObj);
107
- await applyGraphToEntity(session, targetTable, entity, asObj, options);
112
+ assignColumns(targetTable, entity as AnyEntity, asObj);
113
+ await applyGraphToEntity(session, targetTable, entity as AnyEntity, asObj, options);
108
114
 
109
- if (!isEntityInCollection(collection.getItems(), targetPk, entity)) {
115
+ if (!isEntityInCollection(collection.getItems() as unknown as AnyEntity[], targetPk, entity as unknown as AnyEntity)) {
110
116
  collection.attach(entity);
111
117
  }
112
118
 
@@ -133,7 +139,7 @@ const handleHasOne = async (
133
139
  payload: unknown,
134
140
  options: SaveGraphOptions
135
141
  ): Promise<void> => {
136
- const ref = root[relationName];
142
+ const ref = root[relationName] as unknown as HasOneReference<unknown>;
137
143
  if (payload === undefined) return;
138
144
  if (payload === null) {
139
145
  ref.set(null);
@@ -143,13 +149,13 @@ const handleHasOne = async (
143
149
  if (typeof payload === 'number' || typeof payload === 'string') {
144
150
  const entity = ref.set({ [pk]: payload });
145
151
  if (entity) {
146
- await applyGraphToEntity(session, relation.target, entity, { [pk]: payload }, options);
152
+ await applyGraphToEntity(session, relation.target, entity as AnyEntity, { [pk]: payload }, options);
147
153
  }
148
154
  return;
149
155
  }
150
156
  const attached = ref.set(payload as AnyEntity);
151
157
  if (attached) {
152
- await applyGraphToEntity(session, relation.target, attached, payload as AnyEntity, options);
158
+ await applyGraphToEntity(session, relation.target, attached as AnyEntity, payload as AnyEntity, options);
153
159
  }
154
160
  };
155
161
 
@@ -161,7 +167,7 @@ const handleBelongsTo = async (
161
167
  payload: unknown,
162
168
  options: SaveGraphOptions
163
169
  ): Promise<void> => {
164
- const ref = root[relationName];
170
+ const ref = root[relationName] as unknown as BelongsToReference<unknown>;
165
171
  if (payload === undefined) return;
166
172
  if (payload === null) {
167
173
  ref.set(null);
@@ -171,13 +177,13 @@ const handleBelongsTo = async (
171
177
  if (typeof payload === 'number' || typeof payload === 'string') {
172
178
  const entity = ref.set({ [pk]: payload });
173
179
  if (entity) {
174
- await applyGraphToEntity(session, relation.target, entity, { [pk]: payload }, options);
180
+ await applyGraphToEntity(session, relation.target, entity as AnyEntity, { [pk]: payload }, options);
175
181
  }
176
182
  return;
177
183
  }
178
184
  const attached = ref.set(payload as AnyEntity);
179
185
  if (attached) {
180
- await applyGraphToEntity(session, relation.target, attached, payload as AnyEntity, options);
186
+ await applyGraphToEntity(session, relation.target, attached as AnyEntity, payload as AnyEntity, options);
181
187
  }
182
188
  };
183
189
 
@@ -190,7 +196,7 @@ const handleBelongsToMany = async (
190
196
  options: SaveGraphOptions
191
197
  ): Promise<void> => {
192
198
  if (!Array.isArray(payload)) return;
193
- const collection = root[relationName];
199
+ const collection = root[relationName] as unknown as ManyToManyCollection<unknown>;
194
200
  await collection.load();
195
201
 
196
202
  const targetTable = relation.target;
@@ -212,10 +218,10 @@ const handleBelongsToMany = async (
212
218
  ? session.getEntity(targetTable, pkValue) ?? ensureEntity(session, targetTable, asObj)
213
219
  : ensureEntity(session, targetTable, asObj);
214
220
 
215
- assignColumns(targetTable, entity, asObj);
216
- await applyGraphToEntity(session, targetTable, entity, asObj, options);
221
+ assignColumns(targetTable, entity as AnyEntity, asObj);
222
+ await applyGraphToEntity(session, targetTable, entity as AnyEntity, asObj, options);
217
223
 
218
- if (!isEntityInCollection(collection.getItems(), targetPk, entity)) {
224
+ if (!isEntityInCollection(collection.getItems() as unknown as AnyEntity[], targetPk, entity as unknown as AnyEntity)) {
219
225
  collection.attach(entity);
220
226
  }
221
227
 
@@ -225,7 +231,7 @@ const handleBelongsToMany = async (
225
231
  }
226
232
 
227
233
  if (options.pruneMissing) {
228
- for (const item of [...collection.getItems()]) {
234
+ for (const item of [...collection.getItems()] as unknown as AnyEntity[]) {
229
235
  const pkValue = item[targetPk];
230
236
  if (pkValue !== undefined && pkValue !== null && !seen.has(toKey(pkValue))) {
231
237
  collection.detach(item);
@@ -272,7 +278,7 @@ const applyGraphToEntity = async (
272
278
 
273
279
  export const saveGraph = async <TTable extends TableDef>(
274
280
  session: OrmSession,
275
- entityClass: EntityConstructor<any>,
281
+ entityClass: EntityConstructor,
276
282
  payload: AnyEntity,
277
283
  options: SaveGraphOptions = {}
278
284
  ): Promise<EntityInstance<TTable>> => {
@@ -282,11 +288,11 @@ export const saveGraph = async <TTable extends TableDef>(
282
288
  }
283
289
 
284
290
  const root = ensureEntity<TTable>(session, table as TTable, payload);
285
- await applyGraphToEntity(session, table, root, payload, options);
291
+ await applyGraphToEntity(session, table, root as AnyEntity, payload, options);
286
292
  return root;
287
293
  };
288
294
 
289
- export const saveGraphInternal = async <TCtor extends EntityConstructor<any>>(
295
+ export const saveGraphInternal = async <TCtor extends EntityConstructor>(
290
296
  session: OrmSession,
291
297
  entityClass: TCtor,
292
298
  payload: AnyEntity,
@@ -298,6 +304,6 @@ export const saveGraphInternal = async <TCtor extends EntityConstructor<any>>(
298
304
  }
299
305
 
300
306
  const root = ensureEntity(session, table, payload);
301
- await applyGraphToEntity(session, table, root, payload, options);
307
+ await applyGraphToEntity(session, table, root as AnyEntity, payload, options);
302
308
  return root as unknown as InstanceType<TCtor>;
303
309
  };
@@ -14,7 +14,7 @@ import type { TrackedEntity } from './runtime-types.js';
14
14
  * Unit of Work pattern implementation for tracking entity changes.
15
15
  */
16
16
  export class UnitOfWork {
17
- private readonly trackedEntities = new Map<any, TrackedEntity>();
17
+ private readonly trackedEntities = new Map<unknown, TrackedEntity>();
18
18
 
19
19
  /**
20
20
  * Creates a new UnitOfWork instance.
@@ -51,7 +51,7 @@ export class UnitOfWork {
51
51
  * @param pk - The primary key value
52
52
  * @returns The entity or undefined if not found
53
53
  */
54
- getEntity(table: TableDef, pk: string | number): any | undefined {
54
+ getEntity(table: TableDef, pk: string | number): unknown | undefined {
55
55
  return this.identityMap.getEntity(table, pk);
56
56
  }
57
57
 
@@ -69,7 +69,7 @@ export class UnitOfWork {
69
69
  * @param entity - The entity to find
70
70
  * @returns The tracked entity or undefined if not found
71
71
  */
72
- findTracked(entity: any): TrackedEntity | undefined {
72
+ findTracked(entity: unknown): TrackedEntity | undefined {
73
73
  return this.trackedEntities.get(entity);
74
74
  }
75
75
 
@@ -79,7 +79,7 @@ export class UnitOfWork {
79
79
  * @param pk - The primary key value
80
80
  * @param entity - The entity instance
81
81
  */
82
- setEntity(table: TableDef, pk: string | number, entity: any): void {
82
+ setEntity(table: TableDef, pk: string | number, entity: unknown): void {
83
83
  if (pk === null || pk === undefined) return;
84
84
  let tracked = this.trackedEntities.get(entity);
85
85
  if (!tracked) {
@@ -88,7 +88,7 @@ export class UnitOfWork {
88
88
  entity,
89
89
  pk,
90
90
  status: EntityStatus.Managed,
91
- original: this.createSnapshot(table, entity)
91
+ original: this.createSnapshot(table, entity as Record<string, unknown>)
92
92
  };
93
93
  this.trackedEntities.set(entity, tracked);
94
94
  } else {
@@ -104,7 +104,7 @@ export class UnitOfWork {
104
104
  * @param entity - The entity instance
105
105
  * @param pk - Optional primary key value
106
106
  */
107
- trackNew(table: TableDef, entity: any, pk?: string | number): void {
107
+ trackNew(table: TableDef, entity: unknown, pk?: string | number): void {
108
108
  const tracked: TrackedEntity = {
109
109
  table,
110
110
  entity,
@@ -124,13 +124,13 @@ export class UnitOfWork {
124
124
  * @param pk - The primary key value
125
125
  * @param entity - The entity instance
126
126
  */
127
- trackManaged(table: TableDef, pk: string | number, entity: any): void {
127
+ trackManaged(table: TableDef, pk: string | number, entity: unknown): void {
128
128
  const tracked: TrackedEntity = {
129
129
  table,
130
130
  entity,
131
131
  pk,
132
132
  status: EntityStatus.Managed,
133
- original: this.createSnapshot(table, entity)
133
+ original: this.createSnapshot(table, entity as Record<string, unknown>)
134
134
  };
135
135
  this.trackedEntities.set(entity, tracked);
136
136
  this.registerIdentity(tracked);
@@ -140,7 +140,7 @@ export class UnitOfWork {
140
140
  * Marks an entity as dirty (modified).
141
141
  * @param entity - The entity to mark as dirty
142
142
  */
143
- markDirty(entity: any): void {
143
+ markDirty(entity: unknown): void {
144
144
  const tracked = this.trackedEntities.get(entity);
145
145
  if (!tracked) return;
146
146
  if (tracked.status === EntityStatus.New || tracked.status === EntityStatus.Removed) return;
@@ -151,7 +151,7 @@ export class UnitOfWork {
151
151
  * Marks an entity as removed.
152
152
  * @param entity - The entity to mark as removed
153
153
  */
154
- markRemoved(entity: any): void {
154
+ markRemoved(entity: unknown): void {
155
155
  const tracked = this.trackedEntities.get(entity);
156
156
  if (!tracked) return;
157
157
  tracked.status = EntityStatus.Removed;
@@ -194,7 +194,7 @@ export class UnitOfWork {
194
194
  private async flushInsert(tracked: TrackedEntity): Promise<void> {
195
195
  await this.runHook(tracked.table.hooks?.beforeInsert, tracked);
196
196
 
197
- const payload = this.extractColumns(tracked.table, tracked.entity);
197
+ const payload = this.extractColumns(tracked.table, tracked.entity as Record<string, unknown>);
198
198
  let builder = new InsertQueryBuilder(tracked.table).values(payload);
199
199
  if (this.dialect.supportsReturning()) {
200
200
  builder = builder.returning(...this.getReturningColumns(tracked.table));
@@ -204,7 +204,7 @@ export class UnitOfWork {
204
204
  this.applyReturningResults(tracked, results);
205
205
 
206
206
  tracked.status = EntityStatus.Managed;
207
- tracked.original = this.createSnapshot(tracked.table, tracked.entity);
207
+ tracked.original = this.createSnapshot(tracked.table, tracked.entity as Record<string, unknown>);
208
208
  tracked.pk = this.getPrimaryKeyValue(tracked);
209
209
  this.registerIdentity(tracked);
210
210
 
@@ -241,7 +241,7 @@ export class UnitOfWork {
241
241
  this.applyReturningResults(tracked, results);
242
242
 
243
243
  tracked.status = EntityStatus.Managed;
244
- tracked.original = this.createSnapshot(tracked.table, tracked.entity);
244
+ tracked.original = this.createSnapshot(tracked.table, tracked.entity as Record<string, unknown>);
245
245
  this.registerIdentity(tracked);
246
246
 
247
247
  await this.runHook(tracked.table.hooks?.afterUpdate, tracked);
@@ -279,7 +279,7 @@ export class UnitOfWork {
279
279
  tracked: TrackedEntity
280
280
  ): Promise<void> {
281
281
  if (!hook) return;
282
- await hook(this.hookContext() as any, tracked.entity);
282
+ await hook(this.hookContext(), tracked.entity);
283
283
  }
284
284
 
285
285
  /**
@@ -305,7 +305,7 @@ export class UnitOfWork {
305
305
  * @param entity - The entity instance
306
306
  * @returns Object with column values
307
307
  */
308
- private extractColumns(table: TableDef, entity: any): Record<string, unknown> {
308
+ private extractColumns(table: TableDef, entity: Record<string, unknown>): Record<string, unknown> {
309
309
  const payload: Record<string, unknown> = {};
310
310
  for (const column of Object.keys(table.columns)) {
311
311
  if (entity[column] === undefined) continue;
@@ -381,8 +381,8 @@ export class UnitOfWork {
381
381
  * @param entity - The entity instance
382
382
  * @returns Object with entity state
383
383
  */
384
- private createSnapshot(table: TableDef, entity: any): Record<string, any> {
385
- const snapshot: Record<string, any> = {};
384
+ private createSnapshot(table: TableDef, entity: Record<string, unknown>): Record<string, unknown> {
385
+ const snapshot: Record<string, unknown> = {};
386
386
  for (const column of Object.keys(table.columns)) {
387
387
  snapshot[column] = entity[column];
388
388
  }
@@ -76,9 +76,10 @@ export class DeleteQueryBuilder<T> {
76
76
  compile(dialect: DeleteDialectInput): CompiledQuery;
77
77
 
78
78
  compile(arg: DeleteCompiler | DeleteDialectInput): CompiledQuery {
79
- if (typeof (arg as any).compileDelete === 'function') {
79
+ const candidate = arg as { compileDelete?: (ast: DeleteQueryNode) => CompiledQuery };
80
+ if (typeof candidate.compileDelete === 'function') {
80
81
  // DeleteCompiler path – old behavior
81
- return (arg as DeleteCompiler).compileDelete(this.state.ast);
82
+ return candidate.compileDelete(this.state.ast);
82
83
  }
83
84
 
84
85
  // Dialect | string path – new behavior
@@ -87,7 +88,7 @@ export class DeleteQueryBuilder<T> {
87
88
  }
88
89
 
89
90
  toSql(arg: DeleteCompiler | DeleteDialectInput): string {
90
- return this.compile(arg as any).sql;
91
+ return this.compile(arg as DeleteCompiler).sql;
91
92
  }
92
93
 
93
94
  getAST(): DeleteQueryNode {
@@ -20,7 +20,7 @@ export class HydrationManager {
20
20
  constructor(
21
21
  private readonly table: TableDef,
22
22
  private readonly planner: HydrationPlanner
23
- ) {}
23
+ ) { }
24
24
 
25
25
  /**
26
26
  * Creates a new HydrationManager with updated planner
@@ -219,7 +219,8 @@ export class HydrationManager {
219
219
  private getProjectionNames(columns: ProjectionNode[]): string[] | undefined {
220
220
  const names: string[] = [];
221
221
  for (const col of columns) {
222
- const alias = (col as any).alias ?? (col as any).name;
222
+ const node = col as { alias?: string; name?: string };
223
+ const alias = node.alias ?? node.name;
223
224
  if (!alias) return undefined;
224
225
  names.push(alias);
225
226
  }
@@ -267,7 +268,7 @@ export class HydrationManager {
267
268
  baseAlias: string,
268
269
  availableColumns: Set<string>
269
270
  ): OrderByNode['term'] | null {
270
- if ((term as any).type === 'Column') {
271
+ if (term.type === 'Column') {
271
272
  const col = term as ColumnNode;
272
273
  if (col.table !== plan.rootTable) return null;
273
274
  const alias = projectionAliases.get(`${col.table}.${col.name}`) ?? col.name;
@@ -275,8 +276,8 @@ export class HydrationManager {
275
276
  return { type: 'Column', table: baseAlias, name: alias };
276
277
  }
277
278
 
278
- if ((term as any).type === 'AliasRef') {
279
- const aliasName = (term as any).name;
279
+ if (term.type === 'AliasRef') {
280
+ const aliasName = term.name;
280
281
  if (!availableColumns.has(aliasName)) return null;
281
282
  return { type: 'Column', table: baseAlias, name: aliasName };
282
283
  }
@@ -37,8 +37,8 @@ export class InsertQueryBuilder<T> {
37
37
  return this.clone(this.state.withColumns(this.resolveColumnNodes(columns)));
38
38
  }
39
39
 
40
- fromSelect(
41
- query: SelectQueryNode | SelectQueryBuilder<any, TableDef<any>>,
40
+ fromSelect<TSource extends TableDef>(
41
+ query: SelectQueryNode | SelectQueryBuilder<unknown, TSource>,
42
42
  columns: (ColumnDef | ColumnNode)[] = []
43
43
  ): InsertQueryBuilder<T> {
44
44
  const ast = this.resolveSelectQuery(query);
@@ -57,9 +57,12 @@ export class InsertQueryBuilder<T> {
57
57
  return columns.map(column => buildColumnNode(this.table, column));
58
58
  }
59
59
 
60
- private resolveSelectQuery(query: SelectQueryNode | SelectQueryBuilder<any>): SelectQueryNode {
61
- return typeof (query as any).getAST === 'function'
62
- ? (query as SelectQueryBuilder<any>).getAST()
60
+ private resolveSelectQuery<TSource extends TableDef>(
61
+ query: SelectQueryNode | SelectQueryBuilder<unknown, TSource>
62
+ ): SelectQueryNode {
63
+ const candidate = query as { getAST?: () => SelectQueryNode };
64
+ return typeof candidate.getAST === 'function' && candidate.getAST
65
+ ? candidate.getAST()
63
66
  : (query as SelectQueryNode);
64
67
  }
65
68
 
@@ -71,9 +74,10 @@ export class InsertQueryBuilder<T> {
71
74
  compile(dialect: InsertDialectInput): CompiledQuery;
72
75
 
73
76
  compile(arg: InsertCompiler | InsertDialectInput): CompiledQuery {
74
- if (typeof (arg as any).compileInsert === 'function') {
77
+ const candidate = arg as { compileInsert?: (ast: InsertQueryNode) => CompiledQuery };
78
+ if (typeof candidate.compileInsert === 'function') {
75
79
  // InsertCompiler path – old behavior
76
- return (arg as InsertCompiler).compileInsert(this.state.ast);
80
+ return candidate.compileInsert(this.state.ast);
77
81
  }
78
82
 
79
83
  // Dialect | string path – new behavior
@@ -82,7 +86,7 @@ export class InsertQueryBuilder<T> {
82
86
  }
83
87
 
84
88
  toSql(arg: InsertCompiler | InsertDialectInput): string {
85
- return this.compile(arg as any).sql;
89
+ return this.compile(arg as InsertCompiler).sql;
86
90
  }
87
91
 
88
92
  getAST(): InsertQueryNode {
@@ -49,7 +49,7 @@ export class QueryAstService {
49
49
  * @param table - Table definition
50
50
  * @param state - Current query state
51
51
  */
52
- constructor(private readonly table: TableDef, private readonly state: SelectQueryState) {}
52
+ constructor(private readonly table: TableDef, private readonly state: SelectQueryState) { }
53
53
 
54
54
  /**
55
55
  * Selects columns for the query
@@ -254,7 +254,7 @@ export class QueryAstService {
254
254
  private normalizeOrderingTerm(term: ColumnDef | OrderingTerm): OrderingTerm {
255
255
  const from = this.state.ast.from;
256
256
  const tableRef = from.type === 'Table' && from.alias ? { ...this.table, alias: from.alias } : this.table;
257
- const termType = (term as any)?.type;
257
+ const termType = (term as { type?: string }).type;
258
258
  if (termType === 'Column') {
259
259
  return term as ColumnNode;
260
260
  }
@@ -11,7 +11,8 @@ export const parseRawColumn = (
11
11
  ctes?: CommonTableExpressionNode[]
12
12
  ): ColumnNode => {
13
13
  if (col.includes('(')) {
14
- const [fn, rest] = col.split('(');
14
+ const [_fn, rest] = col.split('(');
15
+ void _fn;
15
16
  const colName = rest.replace(')', '');
16
17
  const [table, name] = colName.includes('.') ? colName.split('.') : [tableName, colName];
17
18
  return { type: 'Column', table, name, alias: col };
@@ -22,12 +22,12 @@ export function sel<
22
22
  return selection;
23
23
  }
24
24
 
25
- type Ctor<T> = { new (...args: any[]): T };
25
+ type Ctor<T> = { new(...args: unknown[]): T };
26
26
 
27
27
  /**
28
28
  * Build a typed selection map from an entity constructor.
29
29
  */
30
- export function esel<TEntity, K extends keyof TEntity & string>(
30
+ export function esel<TEntity extends object, K extends keyof TEntity & string>(
31
31
  entity: Ctor<TEntity>,
32
32
  ...props: K[]
33
33
  ): Record<K, ColumnDef> {
@@ -95,8 +95,8 @@ type WhereHasOptions = {
95
95
  };
96
96
 
97
97
  type RelationCallback = <TChildTable extends TableDef>(
98
- qb: SelectQueryBuilder<any, TChildTable>
99
- ) => SelectQueryBuilder<any, TChildTable>;
98
+ qb: SelectQueryBuilder<unknown, TChildTable>
99
+ ) => SelectQueryBuilder<unknown, TChildTable>;
100
100
 
101
101
 
102
102
  /**
@@ -109,7 +109,7 @@ type RelationCallback = <TChildTable extends TableDef>(
109
109
 
110
110
  */
111
111
 
112
- export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
112
+ export class SelectQueryBuilder<T = unknown, TTable extends TableDef = TableDef> {
113
113
 
114
114
  private readonly env: SelectQueryBuilderEnvironment;
115
115
 
@@ -205,12 +205,11 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
205
205
 
206
206
 
207
207
 
208
- private resolveQueryNode(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryNode {
209
-
210
- return typeof (query as any).getAST === 'function'
211
-
212
- ? (query as SelectQueryBuilder<any, TableDef<any>>).getAST()
208
+ private resolveQueryNode<TSub extends TableDef>(query: SelectQueryBuilder<unknown, TSub> | SelectQueryNode): SelectQueryNode {
213
209
 
210
+ const candidate = query as { getAST?: () => SelectQueryNode };
211
+ return typeof candidate.getAST === 'function' && candidate.getAST
212
+ ? candidate.getAST()
214
213
  : (query as SelectQueryNode);
215
214
 
216
215
  }
@@ -272,11 +271,11 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
272
271
 
273
272
 
274
273
 
275
- private applySetOperation(
274
+ private applySetOperation<TSub extends TableDef>(
276
275
 
277
276
  operator: SetOperationKind,
278
277
 
279
- query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode
278
+ query: SelectQueryBuilder<unknown, TSub> | SelectQueryNode
280
279
 
281
280
  ): SelectQueryBuilderContext {
282
281
 
@@ -357,7 +356,7 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
357
356
 
358
357
  */
359
358
 
360
- with(name: string, query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode, columns?: string[]): SelectQueryBuilder<T, TTable> {
359
+ with<TSub extends TableDef>(name: string, query: SelectQueryBuilder<unknown, TSub> | SelectQueryNode, columns?: string[]): SelectQueryBuilder<T, TTable> {
361
360
 
362
361
  const subAst = this.resolveQueryNode(query);
363
362
 
@@ -383,7 +382,7 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
383
382
 
384
383
  */
385
384
 
386
- withRecursive(name: string, query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode, columns?: string[]): SelectQueryBuilder<T, TTable> {
385
+ withRecursive<TSub extends TableDef>(name: string, query: SelectQueryBuilder<unknown, TSub> | SelectQueryNode, columns?: string[]): SelectQueryBuilder<T, TTable> {
387
386
 
388
387
  const subAst = this.resolveQueryNode(query);
389
388
 
@@ -401,8 +400,8 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
401
400
  * @param columnAliases - Optional column alias list
402
401
  * @returns New query builder instance with updated FROM
403
402
  */
404
- fromSubquery(
405
- subquery: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode,
403
+ fromSubquery<TSub extends TableDef>(
404
+ subquery: SelectQueryBuilder<unknown, TSub> | SelectQueryNode,
406
405
  alias: string,
407
406
  columnAliases?: string[]
408
407
  ): SelectQueryBuilder<T, TTable> {
@@ -426,7 +425,7 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
426
425
 
427
426
  */
428
427
 
429
- selectSubquery(alias: string, sub: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
428
+ selectSubquery<TSub extends TableDef>(alias: string, sub: SelectQueryBuilder<unknown, TSub> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
430
429
 
431
430
  const query = this.resolveQueryNode(sub);
432
431
 
@@ -444,8 +443,8 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
444
443
  * @param columnAliases - Optional column alias list for the derived table
445
444
  * @returns New query builder instance with the derived-table join
446
445
  */
447
- joinSubquery(
448
- subquery: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode,
446
+ joinSubquery<TSub extends TableDef>(
447
+ subquery: SelectQueryBuilder<unknown, TSub> | SelectQueryNode,
449
448
  alias: string,
450
449
  condition: BinaryExpressionNode,
451
450
  joinKind: JoinKind = JOIN_KINDS.INNER,
@@ -655,10 +654,11 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
655
654
  * Selects columns for the root table and relations from a single config object.
656
655
  */
657
656
  selectColumnsDeep(config: DeepSelectConfig<TTable>): SelectQueryBuilder<T, TTable> {
658
- let qb: SelectQueryBuilder<T, TTable> = this;
657
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
658
+ let currBuilder: SelectQueryBuilder<T, TTable> = this;
659
659
 
660
660
  if (config.root?.length) {
661
- qb = qb.selectColumns(...config.root);
661
+ currBuilder = currBuilder.selectColumns(...config.root);
662
662
  }
663
663
 
664
664
  for (const key of Object.keys(config) as (keyof typeof config)[]) {
@@ -666,10 +666,10 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
666
666
  const relName = key as keyof TTable['relations'] & string;
667
667
  const cols = config[relName as keyof DeepSelectConfig<TTable>] as string[] | undefined;
668
668
  if (!cols || !cols.length) continue;
669
- qb = qb.selectRelationColumns(relName, ...(cols as string[]));
669
+ currBuilder = currBuilder.selectRelationColumns(relName, ...(cols as string[]));
670
670
  }
671
671
 
672
- return qb;
672
+ return currBuilder;
673
673
  }
674
674
 
675
675
 
@@ -848,7 +848,7 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
848
848
 
849
849
  */
850
850
 
851
- union(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
851
+ union<TSub extends TableDef>(query: SelectQueryBuilder<unknown, TSub> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
852
852
 
853
853
  return this.clone(this.applySetOperation('UNION', query));
854
854
 
@@ -866,7 +866,7 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
866
866
 
867
867
  */
868
868
 
869
- unionAll(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
869
+ unionAll<TSub extends TableDef>(query: SelectQueryBuilder<unknown, TSub> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
870
870
 
871
871
  return this.clone(this.applySetOperation('UNION ALL', query));
872
872
 
@@ -884,7 +884,7 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
884
884
 
885
885
  */
886
886
 
887
- intersect(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
887
+ intersect<TSub extends TableDef>(query: SelectQueryBuilder<unknown, TSub> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
888
888
 
889
889
  return this.clone(this.applySetOperation('INTERSECT', query));
890
890
 
@@ -902,7 +902,7 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
902
902
 
903
903
  */
904
904
 
905
- except(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
905
+ except<TSub extends TableDef>(query: SelectQueryBuilder<unknown, TSub> | SelectQueryNode): SelectQueryBuilder<T, TTable> {
906
906
 
907
907
  return this.clone(this.applySetOperation('EXCEPT', query));
908
908
 
@@ -920,8 +920,8 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
920
920
 
921
921
  */
922
922
 
923
- whereExists(
924
- subquery: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode,
923
+ whereExists<TSub extends TableDef>(
924
+ subquery: SelectQueryBuilder<unknown, TSub> | SelectQueryNode,
925
925
  correlate?: ExpressionNode
926
926
  ): SelectQueryBuilder<T, TTable> {
927
927
  const subAst = this.resolveQueryNode(subquery);
@@ -941,8 +941,8 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
941
941
 
942
942
  */
943
943
 
944
- whereNotExists(
945
- subquery: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode,
944
+ whereNotExists<TSub extends TableDef>(
945
+ subquery: SelectQueryBuilder<unknown, TSub> | SelectQueryNode,
946
946
  correlate?: ExpressionNode
947
947
  ): SelectQueryBuilder<T, TTable> {
948
948
  const subAst = this.resolveQueryNode(subquery);
@@ -987,7 +987,7 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
987
987
  const callback = typeof callbackOrOptions === 'function' ? callbackOrOptions as RelationCallback : undefined;
988
988
  const options = (typeof callbackOrOptions === 'function' ? maybeOptions : callbackOrOptions) as WhereHasOptions | undefined;
989
989
 
990
- let subQb = this.createChildBuilder<any, typeof relation.target>(relation.target);
990
+ let subQb = this.createChildBuilder<unknown, typeof relation.target>(relation.target);
991
991
 
992
992
  if (callback) {
993
993
 
@@ -1042,7 +1042,7 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
1042
1042
  const callback = typeof callbackOrOptions === 'function' ? callbackOrOptions as RelationCallback : undefined;
1043
1043
  const options = (typeof callbackOrOptions === 'function' ? maybeOptions : callbackOrOptions) as WhereHasOptions | undefined;
1044
1044
 
1045
- let subQb = this.createChildBuilder<any, typeof relation.target>(relation.target);
1045
+ let subQb = this.createChildBuilder<unknown, typeof relation.target>(relation.target);
1046
1046
 
1047
1047
  if (callback) {
1048
1048