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
package/dist/index.cjs CHANGED
@@ -127,6 +127,7 @@ __export(index_exports, {
127
127
  diffSchema: () => diffSchema,
128
128
  div: () => div,
129
129
  endOfMonth: () => endOfMonth,
130
+ entityRef: () => entityRef,
130
131
  eq: () => eq,
131
132
  esel: () => esel,
132
133
  executeHydrated: () => executeHydrated,
@@ -139,6 +140,7 @@ __export(index_exports, {
139
140
  fromUnixTime: () => fromUnixTime,
140
141
  generateCreateTableSql: () => generateCreateTableSql,
141
142
  generateSchemaSql: () => generateSchemaSql,
143
+ getColumn: () => getColumn,
142
144
  getSchemaIntrospector: () => getSchemaIntrospector,
143
145
  getTableDefFromEntity: () => getTableDefFromEntity,
144
146
  groupConcat: () => groupConcat,
@@ -225,6 +227,7 @@ __export(index_exports, {
225
227
  substr: () => substr,
226
228
  sum: () => sum,
227
229
  synchronizeSchema: () => synchronizeSchema,
230
+ tableRef: () => tableRef,
228
231
  tan: () => tan,
229
232
  toColumnRef: () => toColumnRef,
230
233
  toTableRef: () => toTableRef,
@@ -246,7 +249,8 @@ module.exports = __toCommonJS(index_exports);
246
249
  // src/schema/table.ts
247
250
  var defineTable = (name, columns, relations = {}, hooks, options = {}) => {
248
251
  const colsWithNames = Object.entries(columns).reduce((acc, [key, def]) => {
249
- acc[key] = { ...def, name: key, table: name };
252
+ const colDef = { ...def, name: key, table: name };
253
+ acc[key] = colDef;
250
254
  return acc;
251
255
  }, {});
252
256
  return {
@@ -264,6 +268,65 @@ var defineTable = (name, columns, relations = {}, hooks, options = {}) => {
264
268
  collation: options.collation
265
269
  };
266
270
  };
271
+ var TABLE_REF_CACHE = /* @__PURE__ */ new WeakMap();
272
+ var withColumnProps = (table) => {
273
+ const cached = TABLE_REF_CACHE.get(table);
274
+ if (cached) return cached;
275
+ const proxy = new Proxy(table, {
276
+ get(target, prop, receiver) {
277
+ const t = target;
278
+ if (prop === "$") return t.columns;
279
+ if (Reflect.has(target, prop)) return Reflect.get(target, prop, receiver);
280
+ if (typeof prop === "string" && prop in t.columns) return t.columns[prop];
281
+ return void 0;
282
+ },
283
+ has(target, prop) {
284
+ const t = target;
285
+ return prop === "$" || Reflect.has(target, prop) || typeof prop === "string" && prop in t.columns;
286
+ },
287
+ ownKeys(target) {
288
+ const t = target;
289
+ const base = Reflect.ownKeys(target);
290
+ const cols = Object.keys(t.columns);
291
+ for (const k of cols) {
292
+ if (!base.includes(k)) base.push(k);
293
+ }
294
+ if (!base.includes("$")) base.push("$");
295
+ return base;
296
+ },
297
+ getOwnPropertyDescriptor(target, prop) {
298
+ if (prop === "$") {
299
+ return {
300
+ configurable: true,
301
+ enumerable: false,
302
+ get() {
303
+ return target.columns;
304
+ }
305
+ };
306
+ }
307
+ if (typeof prop === "string" && prop in target.columns && !Reflect.has(target, prop)) {
308
+ return {
309
+ configurable: true,
310
+ enumerable: true,
311
+ value: target.columns[prop],
312
+ writable: false
313
+ };
314
+ }
315
+ return Reflect.getOwnPropertyDescriptor(target, prop);
316
+ }
317
+ });
318
+ TABLE_REF_CACHE.set(table, proxy);
319
+ return proxy;
320
+ };
321
+ var tableRef = (table) => withColumnProps(table);
322
+ function getColumn(table, key) {
323
+ const col2 = table.columns[key];
324
+ if (!col2) {
325
+ const tableName = table.name || "<unknown>";
326
+ throw new Error(`Column '${key}' does not exist on table '${tableName}'`);
327
+ }
328
+ return col2;
329
+ }
267
330
 
268
331
  // src/schema/column.ts
269
332
  var col = {
@@ -468,10 +531,14 @@ var operandTypes = /* @__PURE__ */ new Set([
468
531
  "CaseExpression",
469
532
  "WindowFunction"
470
533
  ]);
471
- var isOperandNode = (node) => node && operandTypes.has(node.type);
472
- var isFunctionNode = (node) => node?.type === "Function";
473
- var isCaseExpressionNode = (node) => node?.type === "CaseExpression";
474
- var isWindowFunctionNode = (node) => node?.type === "WindowFunction";
534
+ var hasTypeProperty = (value) => typeof value === "object" && value !== null && "type" in value;
535
+ var isOperandNode = (node) => {
536
+ if (!hasTypeProperty(node)) return false;
537
+ return operandTypes.has(node.type);
538
+ };
539
+ var isFunctionNode = (node) => isOperandNode(node) && node.type === "Function";
540
+ var isCaseExpressionNode = (node) => isOperandNode(node) && node.type === "CaseExpression";
541
+ var isWindowFunctionNode = (node) => isOperandNode(node) && node.type === "WindowFunction";
475
542
  var isExpressionSelectionNode = (node) => isFunctionNode(node) || isCaseExpressionNode(node) || isWindowFunctionNode(node);
476
543
 
477
544
  // src/core/ast/expression-builders.ts
@@ -761,14 +828,15 @@ var registerOperandDispatcher = (type, dispatcher) => {
761
828
  };
762
829
  var clearExpressionDispatchers = () => expressionDispatchers.clear();
763
830
  var clearOperandDispatchers = () => operandDispatchers.clear();
831
+ var getNodeType = (node) => typeof node === "object" && node !== null && typeof node.type === "string" ? node.type : void 0;
764
832
  var unsupportedExpression = (node) => {
765
- throw new Error(`Unsupported expression type "${node?.type ?? "unknown"}"`);
833
+ throw new Error(`Unsupported expression type "${getNodeType(node) ?? "unknown"}"`);
766
834
  };
767
835
  var unsupportedOperand = (node) => {
768
- throw new Error(`Unsupported operand type "${node?.type ?? "unknown"}"`);
836
+ throw new Error(`Unsupported operand type "${getNodeType(node) ?? "unknown"}"`);
769
837
  };
770
838
  var visitExpression = (node, visitor) => {
771
- const dynamic = expressionDispatchers.get(node?.type);
839
+ const dynamic = expressionDispatchers.get(node.type);
772
840
  if (dynamic) return dynamic(node, visitor);
773
841
  switch (node.type) {
774
842
  case "BinaryExpression":
@@ -799,7 +867,7 @@ var visitExpression = (node, visitor) => {
799
867
  return unsupportedExpression(node);
800
868
  };
801
869
  var visitOperand = (node, visitor) => {
802
- const dynamic = operandDispatchers.get(node?.type);
870
+ const dynamic = operandDispatchers.get(node.type);
803
871
  if (dynamic) return dynamic(node, visitor);
804
872
  switch (node.type) {
805
873
  case "Column":
@@ -1026,7 +1094,8 @@ var Dialect = class _Dialect {
1026
1094
  if (!where) return "";
1027
1095
  return ` WHERE ${this.compileExpression(where, ctx)}`;
1028
1096
  }
1029
- compileReturning(returning, ctx) {
1097
+ compileReturning(returning, _ctx) {
1098
+ void _ctx;
1030
1099
  if (!returning || returning.length === 0) return "";
1031
1100
  throw new Error("RETURNING is not supported by this dialect.");
1032
1101
  }
@@ -1074,14 +1143,16 @@ var Dialect = class _Dialect {
1074
1143
  * @param index - Parameter index
1075
1144
  * @returns Formatted placeholder string
1076
1145
  */
1077
- formatPlaceholder(index) {
1146
+ formatPlaceholder(_index) {
1147
+ void _index;
1078
1148
  return "?";
1079
1149
  }
1080
1150
  /**
1081
1151
  * Whether the current dialect supports a given set operation.
1082
1152
  * Override in concrete dialects to restrict support.
1083
1153
  */
1084
- supportsSetOperation(kind) {
1154
+ supportsSetOperation(_kind) {
1155
+ void _kind;
1085
1156
  return true;
1086
1157
  }
1087
1158
  /**
@@ -1274,15 +1345,22 @@ var Dialect = class _Dialect {
1274
1345
  }
1275
1346
  registerDefaultOperandCompilers() {
1276
1347
  this.registerOperandCompiler("Literal", (literal, ctx) => ctx.addParameter(literal.value));
1277
- this.registerOperandCompiler("AliasRef", (alias, _ctx) => this.quoteIdentifier(alias.name));
1348
+ this.registerOperandCompiler("AliasRef", (alias, _ctx) => {
1349
+ void _ctx;
1350
+ return this.quoteIdentifier(alias.name);
1351
+ });
1278
1352
  this.registerOperandCompiler("Column", (column, _ctx) => {
1353
+ void _ctx;
1279
1354
  return `${this.quoteIdentifier(column.table)}.${this.quoteIdentifier(column.name)}`;
1280
1355
  });
1281
1356
  this.registerOperandCompiler(
1282
1357
  "Function",
1283
1358
  (fnNode, ctx) => this.compileFunctionOperand(fnNode, ctx)
1284
1359
  );
1285
- this.registerOperandCompiler("JsonPath", (path, _ctx) => this.compileJsonPath(path));
1360
+ this.registerOperandCompiler("JsonPath", (path, _ctx) => {
1361
+ void _ctx;
1362
+ return this.compileJsonPath(path);
1363
+ });
1286
1364
  this.registerOperandCompiler("ScalarSubquery", (node, ctx) => {
1287
1365
  const sql = this.compileSelectAst(node.query, ctx).trim().replace(/;$/, "");
1288
1366
  return `(${sql})`;
@@ -1326,7 +1404,8 @@ var Dialect = class _Dialect {
1326
1404
  });
1327
1405
  }
1328
1406
  // Default fallback, should be overridden by dialects if supported
1329
- compileJsonPath(node) {
1407
+ compileJsonPath(_node) {
1408
+ void _node;
1330
1409
  throw new Error("JSON Path not supported by this dialect");
1331
1410
  }
1332
1411
  /**
@@ -1492,6 +1571,7 @@ var NoReturningStrategy = class {
1492
1571
  * @throws Error indicating RETURNING is not supported.
1493
1572
  */
1494
1573
  compileReturning(returning, _ctx) {
1574
+ void _ctx;
1495
1575
  if (!returning || returning.length === 0) return "";
1496
1576
  throw new Error("RETURNING is not supported by this dialect.");
1497
1577
  }
@@ -1893,6 +1973,7 @@ var PostgresDialect = class extends SqlDialectBase {
1893
1973
  return `${col2}->>'${node.path}'`;
1894
1974
  }
1895
1975
  compileReturning(returning, ctx) {
1976
+ void ctx;
1896
1977
  if (!returning || returning.length === 0) return "";
1897
1978
  const columns = this.formatReturningColumns(returning);
1898
1979
  return ` RETURNING ${columns}`;
@@ -2143,9 +2224,11 @@ var SqliteDialect = class extends SqlDialectBase {
2143
2224
  return `json_extract(${col2}, '${node.path}')`;
2144
2225
  }
2145
2226
  compileQualifiedColumn(column, _table) {
2227
+ void _table;
2146
2228
  return this.quoteIdentifier(column.name);
2147
2229
  }
2148
2230
  compileReturning(returning, ctx) {
2231
+ void ctx;
2149
2232
  if (!returning || returning.length === 0) return "";
2150
2233
  const columns = this.formatReturningColumns(returning);
2151
2234
  return ` RETURNING ${columns}`;
@@ -2798,7 +2881,8 @@ var HydrationManager = class _HydrationManager {
2798
2881
  getProjectionNames(columns) {
2799
2882
  const names = [];
2800
2883
  for (const col2 of columns) {
2801
- const alias = col2.alias ?? col2.name;
2884
+ const node = col2;
2885
+ const alias = node.alias ?? node.name;
2802
2886
  if (!alias) return void 0;
2803
2887
  names.push(alias);
2804
2888
  }
@@ -3015,7 +3099,8 @@ var buildDefaultHydrationPlan = (table) => ({
3015
3099
  // src/query-builder/raw-column-parser.ts
3016
3100
  var parseRawColumn = (col2, tableName, ctes) => {
3017
3101
  if (col2.includes("(")) {
3018
- const [fn4, rest] = col2.split("(");
3102
+ const [_fn, rest] = col2.split("(");
3103
+ void _fn;
3019
3104
  const colName = rest.replace(")", "");
3020
3105
  const [table, name] = colName.includes(".") ? colName.split(".") : [tableName, colName];
3021
3106
  return { type: "Column", table, name, alias: col2 };
@@ -3214,8 +3299,8 @@ var QueryAstService = class {
3214
3299
  }
3215
3300
  normalizeOrderingTerm(term) {
3216
3301
  const from = this.state.ast.from;
3217
- const tableRef = from.type === "Table" && from.alias ? { ...this.table, alias: from.alias } : this.table;
3218
- const termType = term?.type;
3302
+ const tableRef2 = from.type === "Table" && from.alias ? { ...this.table, alias: from.alias } : this.table;
3303
+ const termType = term.type;
3219
3304
  if (termType === "Column") {
3220
3305
  return term;
3221
3306
  }
@@ -3228,7 +3313,7 @@ var QueryAstService = class {
3228
3313
  if (termType === "BinaryExpression" || termType === "LogicalExpression" || termType === "NullExpression" || termType === "InExpression" || termType === "ExistsExpression" || termType === "BetweenExpression" || termType === "ArithmeticExpression") {
3229
3314
  return term;
3230
3315
  }
3231
- return buildColumnNode(tableRef, term);
3316
+ return buildColumnNode(tableRef2, term);
3232
3317
  }
3233
3318
  };
3234
3319
 
@@ -3634,8 +3719,8 @@ var ColumnSelector = class {
3634
3719
  */
3635
3720
  distinct(context, columns) {
3636
3721
  const from = context.state.ast.from;
3637
- const tableRef = from.type === "Table" && from.alias ? { ...this.env.table, alias: from.alias } : this.env.table;
3638
- const nodes = columns.map((col2) => buildColumnNode(tableRef, col2));
3722
+ const tableRef2 = from.type === "Table" && from.alias ? { ...this.env.table, alias: from.alias } : this.env.table;
3723
+ const nodes = columns.map((col2) => buildColumnNode(tableRef2, col2));
3639
3724
  const astService = this.env.deps.createQueryAstService(this.env.table, context.state);
3640
3725
  const nextState = astService.withDistinct(nodes);
3641
3726
  return { state: nextState, hydration: context.hydration };
@@ -4215,7 +4300,6 @@ var DefaultManyToManyCollection = class {
4215
4300
  }
4216
4301
  async syncByIds(ids) {
4217
4302
  await this.load();
4218
- const targetKey = this.relation.targetKey || findPrimaryKey(this.relation.target);
4219
4303
  const normalized = new Set(ids.map((id) => toKey5(id)));
4220
4304
  const currentIds = new Set(this.items.map((item) => toKey5(this.extractId(item))));
4221
4305
  for (const id of normalized) {
@@ -4486,7 +4570,6 @@ var createEntityProxy = (ctx, table, row, lazyRelations = []) => {
4486
4570
  enumerable: false,
4487
4571
  writable: false
4488
4572
  });
4489
- let proxy;
4490
4573
  const handler = {
4491
4574
  get(targetObj, prop, receiver) {
4492
4575
  if (prop === ENTITY_META) {
@@ -4494,7 +4577,7 @@ var createEntityProxy = (ctx, table, row, lazyRelations = []) => {
4494
4577
  }
4495
4578
  if (prop === "$load") {
4496
4579
  return async (relationName) => {
4497
- const wrapper = getRelationWrapper(meta, relationName, proxy);
4580
+ const wrapper = getRelationWrapper(meta, relationName, receiver);
4498
4581
  if (wrapper && typeof wrapper.load === "function") {
4499
4582
  return wrapper.load();
4500
4583
  }
@@ -4502,19 +4585,19 @@ var createEntityProxy = (ctx, table, row, lazyRelations = []) => {
4502
4585
  };
4503
4586
  }
4504
4587
  if (typeof prop === "string" && table.relations[prop]) {
4505
- return getRelationWrapper(meta, prop, proxy);
4588
+ return getRelationWrapper(meta, prop, receiver);
4506
4589
  }
4507
4590
  return Reflect.get(targetObj, prop, receiver);
4508
4591
  },
4509
4592
  set(targetObj, prop, value, receiver) {
4510
4593
  const result = Reflect.set(targetObj, prop, value, receiver);
4511
4594
  if (typeof prop === "string" && table.columns[prop]) {
4512
- ctx.markDirty(proxy);
4595
+ ctx.markDirty(receiver);
4513
4596
  }
4514
4597
  return result;
4515
4598
  }
4516
4599
  };
4517
- proxy = new Proxy(target, handler);
4600
+ const proxy = new Proxy(target, handler);
4518
4601
  populateHydrationCache(proxy, row, meta);
4519
4602
  return proxy;
4520
4603
  };
@@ -4756,7 +4839,8 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
4756
4839
  return this.clone(nextContext);
4757
4840
  }
4758
4841
  resolveQueryNode(query) {
4759
- return typeof query.getAST === "function" ? query.getAST() : query;
4842
+ const candidate = query;
4843
+ return typeof candidate.getAST === "function" && candidate.getAST ? candidate.getAST() : query;
4760
4844
  }
4761
4845
  applyCorrelation(ast, correlation) {
4762
4846
  if (!correlation) return ast;
@@ -5025,18 +5109,18 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
5025
5109
  * Selects columns for the root table and relations from a single config object.
5026
5110
  */
5027
5111
  selectColumnsDeep(config) {
5028
- let qb = this;
5112
+ let currBuilder = this;
5029
5113
  if (config.root?.length) {
5030
- qb = qb.selectColumns(...config.root);
5114
+ currBuilder = currBuilder.selectColumns(...config.root);
5031
5115
  }
5032
5116
  for (const key of Object.keys(config)) {
5033
5117
  if (key === "root") continue;
5034
5118
  const relName = key;
5035
5119
  const cols = config[relName];
5036
5120
  if (!cols || !cols.length) continue;
5037
- qb = qb.selectRelationColumns(relName, ...cols);
5121
+ currBuilder = currBuilder.selectRelationColumns(relName, ...cols);
5038
5122
  }
5039
- return qb;
5123
+ return currBuilder;
5040
5124
  }
5041
5125
  getLazyRelations() {
5042
5126
  return Array.from(this.lazyRelations);
@@ -5471,6 +5555,13 @@ var selectFromEntity = (ctor) => {
5471
5555
  }
5472
5556
  return new SelectQueryBuilder(table);
5473
5557
  };
5558
+ var entityRef = (ctor) => {
5559
+ const table = getTableDefFromEntity(ctor);
5560
+ if (!table) {
5561
+ throw new Error(`Entity '${ctor.name}' is not registered with decorators or has not been bootstrapped`);
5562
+ }
5563
+ return tableRef(table);
5564
+ };
5474
5565
 
5475
5566
  // src/query-builder/select-helpers.ts
5476
5567
  function sel(table, ...cols) {
@@ -5623,11 +5714,13 @@ var InsertQueryBuilder = class _InsertQueryBuilder {
5623
5714
  return columns.map((column) => buildColumnNode(this.table, column));
5624
5715
  }
5625
5716
  resolveSelectQuery(query) {
5626
- return typeof query.getAST === "function" ? query.getAST() : query;
5717
+ const candidate = query;
5718
+ return typeof candidate.getAST === "function" && candidate.getAST ? candidate.getAST() : query;
5627
5719
  }
5628
5720
  compile(arg) {
5629
- if (typeof arg.compileInsert === "function") {
5630
- return arg.compileInsert(this.state.ast);
5721
+ const candidate = arg;
5722
+ if (typeof candidate.compileInsert === "function") {
5723
+ return candidate.compileInsert(this.state.ast);
5631
5724
  }
5632
5725
  const dialect = resolveDialectInput(arg);
5633
5726
  return dialect.compileInsert(this.state.ast);
@@ -5764,8 +5857,9 @@ var UpdateQueryBuilder = class _UpdateQueryBuilder {
5764
5857
  return this.resolveTableSource(table);
5765
5858
  }
5766
5859
  compile(arg) {
5767
- if (typeof arg.compileUpdate === "function") {
5768
- return arg.compileUpdate(this.state.ast);
5860
+ const candidate = arg;
5861
+ if (typeof candidate.compileUpdate === "function") {
5862
+ return candidate.compileUpdate(this.state.ast);
5769
5863
  }
5770
5864
  const dialect = resolveDialectInput(arg);
5771
5865
  return dialect.compileUpdate(this.state.ast);
@@ -5866,8 +5960,9 @@ var DeleteQueryBuilder = class _DeleteQueryBuilder {
5866
5960
  return this.resolveTableSource(table);
5867
5961
  }
5868
5962
  compile(arg) {
5869
- if (typeof arg.compileDelete === "function") {
5870
- return arg.compileDelete(this.state.ast);
5963
+ const candidate = arg;
5964
+ if (typeof candidate.compileDelete === "function") {
5965
+ return candidate.compileDelete(this.state.ast);
5871
5966
  }
5872
5967
  const dialect = resolveDialectInput(arg);
5873
5968
  return dialect.compileDelete(this.state.ast);
@@ -5917,7 +6012,7 @@ var generateCreateTableSql = (table, dialect) => {
5917
6012
  const pk = resolvePrimaryKey(table);
5918
6013
  const inlinePkColumns = /* @__PURE__ */ new Set();
5919
6014
  const columnLines = Object.values(table.columns).map((col2) => {
5920
- const includePk = dialect.preferInlinePkAutoincrement?.(col2, table, pk) && pk.includes(col2.name);
6015
+ const includePk = dialect.preferInlinePkAutoincrement(col2, table, pk) && pk.includes(col2.name);
5921
6016
  if (includePk) {
5922
6017
  inlinePkColumns.add(col2.name);
5923
6018
  }
@@ -6422,7 +6517,7 @@ var postgresIntrospector = {
6422
6517
  ],
6423
6518
  where: and(
6424
6519
  eq({ table: "ns", name: "nspname" }, schema),
6425
- eq({ table: "i", name: "indisprimary" }, { type: "Literal", value: false })
6520
+ eq({ table: "i", name: "indisprimary" }, false)
6426
6521
  )
6427
6522
  };
6428
6523
  const indexQueryRows = await runSelectNode(indexQuery, ctx);
@@ -6586,6 +6681,14 @@ var mysqlIntrospector = {
6586
6681
  };
6587
6682
 
6588
6683
  // src/core/ddl/introspect/sqlite.ts
6684
+ var toReferentialAction = (value) => {
6685
+ if (!value) return void 0;
6686
+ const normalized = value.toUpperCase();
6687
+ if (normalized === "NO ACTION" || normalized === "RESTRICT" || normalized === "CASCADE" || normalized === "SET NULL" || normalized === "SET DEFAULT") {
6688
+ return normalized;
6689
+ }
6690
+ return void 0;
6691
+ };
6589
6692
  var escapeSingleQuotes = (name) => name.replace(/'/g, "''");
6590
6693
  var sqliteIntrospector = {
6591
6694
  async introspect(ctx, options) {
@@ -6619,8 +6722,8 @@ var sqliteIntrospector = {
6619
6722
  col2.references = {
6620
6723
  table: fk.table,
6621
6724
  column: fk.to,
6622
- onDelete: fk.on_delete?.toUpperCase(),
6623
- onUpdate: fk.on_update?.toUpperCase()
6725
+ onDelete: toReferentialAction(fk.on_delete),
6726
+ onUpdate: toReferentialAction(fk.on_update)
6624
6727
  };
6625
6728
  }
6626
6729
  });
@@ -7030,11 +7133,7 @@ var TypeScriptGenerator = class {
7030
7133
  const lines = [];
7031
7134
  const hydration = ast.meta?.hydration;
7032
7135
  const hydratedRelations = new Set(hydration?.relations?.map((r) => r.name) ?? []);
7033
- const selections = ast.columns.filter((col2) => !(hydration && isRelationAlias(col2.alias))).map((col2) => {
7034
- const key = col2.alias || col2.name;
7035
- const operand = col2;
7036
- return `${key}: ${this.printOperand(operand)}`;
7037
- });
7136
+ const selections = ast.columns.filter((col2) => !(hydration && isRelationAlias(col2.alias))).map((col2, index) => `${this.getSelectionKey(col2, index)}: ${this.printOperand(col2)}`);
7038
7137
  lines.push(`db.select({`);
7039
7138
  selections.forEach((sel2, index) => {
7040
7139
  lines.push(` ${sel2}${index < selections.length - 1 ? "," : ""}`);
@@ -7122,7 +7221,7 @@ var TypeScriptGenerator = class {
7122
7221
  * Prints an ordering term (operand/expression/alias) to TypeScript code.
7123
7222
  */
7124
7223
  printOrderingTerm(term) {
7125
- if (!term || !term.type) {
7224
+ if (!term || !("type" in term)) {
7126
7225
  throw new Error("Unsupported ordering term");
7127
7226
  }
7128
7227
  switch (term.type) {
@@ -7141,6 +7240,18 @@ var TypeScriptGenerator = class {
7141
7240
  return this.printExpression(term);
7142
7241
  }
7143
7242
  }
7243
+ getSelectionKey(selection, index) {
7244
+ if (selection.alias) {
7245
+ return selection.alias;
7246
+ }
7247
+ if (this.isNamedSelection(selection)) {
7248
+ return selection.name;
7249
+ }
7250
+ return `selection${index + 1}`;
7251
+ }
7252
+ isNamedSelection(selection) {
7253
+ return "name" in selection;
7254
+ }
7144
7255
  visitBinaryExpression(binary) {
7145
7256
  return this.printBinaryExpression(binary);
7146
7257
  }
@@ -7924,6 +8035,7 @@ var RelationChangeProcessor = class {
7924
8035
  * @param _entry - The relation change entry (reserved for future use)
7925
8036
  */
7926
8037
  async handleBelongsToChange(_entry) {
8038
+ void _entry;
7927
8039
  }
7928
8040
  /**
7929
8041
  * Handles changes for belongs-to-many relations.
@@ -8037,7 +8149,7 @@ var RelationChangeProcessor = class {
8037
8149
  const key = findPrimaryKey(table);
8038
8150
  const value = entity[key];
8039
8151
  if (value === void 0 || value === null) return null;
8040
- return value;
8152
+ return value ?? null;
8041
8153
  }
8042
8154
  };
8043
8155
 
@@ -8629,8 +8741,6 @@ var Orm = class {
8629
8741
  const session = new OrmSession({ orm: this, executor });
8630
8742
  try {
8631
8743
  return await session.transaction(() => fn4(session));
8632
- } catch (err) {
8633
- throw err;
8634
8744
  } finally {
8635
8745
  await session.dispose();
8636
8746
  }
@@ -8661,9 +8771,6 @@ var getOrCreateMetadataBag = (context) => {
8661
8771
  var readMetadataBag = (context) => {
8662
8772
  return context.metadata?.[METADATA_KEY];
8663
8773
  };
8664
- var registerInitializer = (context, initializer) => {
8665
- context.addInitializer?.(initializer);
8666
- };
8667
8774
 
8668
8775
  // src/decorators/entity.ts
8669
8776
  var toSnakeCase = (value) => {
@@ -8693,14 +8800,24 @@ function Entity(options = {}) {
8693
8800
  if (bag) {
8694
8801
  const meta = ensureEntityMetadata(ctor);
8695
8802
  for (const entry of bag.columns) {
8696
- if (!meta.columns[entry.propertyName]) {
8697
- addColumnMetadata(ctor, entry.propertyName, { ...entry.column });
8803
+ if (meta.columns[entry.propertyName]) {
8804
+ throw new Error(
8805
+ `Column '${entry.propertyName}' is already defined on entity '${ctor.name}'.`
8806
+ );
8698
8807
  }
8808
+ addColumnMetadata(ctor, entry.propertyName, { ...entry.column });
8699
8809
  }
8700
8810
  for (const entry of bag.relations) {
8701
- if (!meta.relations[entry.propertyName]) {
8702
- addRelationMetadata(ctor, entry.propertyName, entry.relation);
8811
+ if (meta.relations[entry.propertyName]) {
8812
+ throw new Error(
8813
+ `Relation '${entry.propertyName}' is already defined on entity '${ctor.name}'.`
8814
+ );
8703
8815
  }
8816
+ const relationCopy = entry.relation.kind === RelationKinds.BelongsToMany ? {
8817
+ ...entry.relation,
8818
+ defaultPivotColumns: entry.relation.defaultPivotColumns ? [...entry.relation.defaultPivotColumns] : void 0
8819
+ } : { ...entry.relation };
8820
+ addRelationMetadata(ctor, entry.propertyName, relationCopy);
8704
8821
  }
8705
8822
  }
8706
8823
  }
@@ -8763,13 +8880,6 @@ var registerColumnFromContext = (context, column) => {
8763
8880
  if (!bag.columns.some((entry) => entry.propertyName === propertyName)) {
8764
8881
  bag.columns.push({ propertyName, column: { ...column } });
8765
8882
  }
8766
- registerInitializer(context, function() {
8767
- const ctor = resolveConstructor(this);
8768
- if (!ctor) {
8769
- return;
8770
- }
8771
- registerColumn(ctor, propertyName, column);
8772
- });
8773
8883
  };
8774
8884
  function Column(definition) {
8775
8885
  const normalized = normalizeColumnInput(definition);
@@ -8825,13 +8935,6 @@ var createFieldDecorator = (metadataFactory) => {
8825
8935
  if (!bag.relations.some((entry) => entry.propertyName === propertyName2)) {
8826
8936
  bag.relations.push({ propertyName: propertyName2, relation: relationMetadata });
8827
8937
  }
8828
- registerInitializer(ctx, function() {
8829
- const ctor2 = resolveConstructor2(this);
8830
- if (!ctor2) {
8831
- return;
8832
- }
8833
- registerRelation(ctor2, propertyName2, relationMetadata);
8834
- });
8835
8938
  return;
8836
8939
  }
8837
8940
  const propertyName = normalizePropertyName2(propertyKeyOrContext);
@@ -9497,6 +9600,7 @@ function createPooledExecutorFactory(opts) {
9497
9600
  diffSchema,
9498
9601
  div,
9499
9602
  endOfMonth,
9603
+ entityRef,
9500
9604
  eq,
9501
9605
  esel,
9502
9606
  executeHydrated,
@@ -9509,6 +9613,7 @@ function createPooledExecutorFactory(opts) {
9509
9613
  fromUnixTime,
9510
9614
  generateCreateTableSql,
9511
9615
  generateSchemaSql,
9616
+ getColumn,
9512
9617
  getSchemaIntrospector,
9513
9618
  getTableDefFromEntity,
9514
9619
  groupConcat,
@@ -9595,6 +9700,7 @@ function createPooledExecutorFactory(opts) {
9595
9700
  substr,
9596
9701
  sum,
9597
9702
  synchronizeSchema,
9703
+ tableRef,
9598
9704
  tan,
9599
9705
  toColumnRef,
9600
9706
  toTableRef,