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.js CHANGED
@@ -32,7 +32,8 @@ var init_schema_plan_executor = __esm({
32
32
  // src/schema/table.ts
33
33
  var defineTable = (name, columns, relations = {}, hooks, options = {}) => {
34
34
  const colsWithNames = Object.entries(columns).reduce((acc, [key, def]) => {
35
- acc[key] = { ...def, name: key, table: name };
35
+ const colDef = { ...def, name: key, table: name };
36
+ acc[key] = colDef;
36
37
  return acc;
37
38
  }, {});
38
39
  return {
@@ -50,6 +51,65 @@ var defineTable = (name, columns, relations = {}, hooks, options = {}) => {
50
51
  collation: options.collation
51
52
  };
52
53
  };
54
+ var TABLE_REF_CACHE = /* @__PURE__ */ new WeakMap();
55
+ var withColumnProps = (table) => {
56
+ const cached = TABLE_REF_CACHE.get(table);
57
+ if (cached) return cached;
58
+ const proxy = new Proxy(table, {
59
+ get(target, prop, receiver) {
60
+ const t = target;
61
+ if (prop === "$") return t.columns;
62
+ if (Reflect.has(target, prop)) return Reflect.get(target, prop, receiver);
63
+ if (typeof prop === "string" && prop in t.columns) return t.columns[prop];
64
+ return void 0;
65
+ },
66
+ has(target, prop) {
67
+ const t = target;
68
+ return prop === "$" || Reflect.has(target, prop) || typeof prop === "string" && prop in t.columns;
69
+ },
70
+ ownKeys(target) {
71
+ const t = target;
72
+ const base = Reflect.ownKeys(target);
73
+ const cols = Object.keys(t.columns);
74
+ for (const k of cols) {
75
+ if (!base.includes(k)) base.push(k);
76
+ }
77
+ if (!base.includes("$")) base.push("$");
78
+ return base;
79
+ },
80
+ getOwnPropertyDescriptor(target, prop) {
81
+ if (prop === "$") {
82
+ return {
83
+ configurable: true,
84
+ enumerable: false,
85
+ get() {
86
+ return target.columns;
87
+ }
88
+ };
89
+ }
90
+ if (typeof prop === "string" && prop in target.columns && !Reflect.has(target, prop)) {
91
+ return {
92
+ configurable: true,
93
+ enumerable: true,
94
+ value: target.columns[prop],
95
+ writable: false
96
+ };
97
+ }
98
+ return Reflect.getOwnPropertyDescriptor(target, prop);
99
+ }
100
+ });
101
+ TABLE_REF_CACHE.set(table, proxy);
102
+ return proxy;
103
+ };
104
+ var tableRef = (table) => withColumnProps(table);
105
+ function getColumn(table, key) {
106
+ const col2 = table.columns[key];
107
+ if (!col2) {
108
+ const tableName = table.name || "<unknown>";
109
+ throw new Error(`Column '${key}' does not exist on table '${tableName}'`);
110
+ }
111
+ return col2;
112
+ }
53
113
 
54
114
  // src/schema/column.ts
55
115
  var col = {
@@ -254,10 +314,14 @@ var operandTypes = /* @__PURE__ */ new Set([
254
314
  "CaseExpression",
255
315
  "WindowFunction"
256
316
  ]);
257
- var isOperandNode = (node) => node && operandTypes.has(node.type);
258
- var isFunctionNode = (node) => node?.type === "Function";
259
- var isCaseExpressionNode = (node) => node?.type === "CaseExpression";
260
- var isWindowFunctionNode = (node) => node?.type === "WindowFunction";
317
+ var hasTypeProperty = (value) => typeof value === "object" && value !== null && "type" in value;
318
+ var isOperandNode = (node) => {
319
+ if (!hasTypeProperty(node)) return false;
320
+ return operandTypes.has(node.type);
321
+ };
322
+ var isFunctionNode = (node) => isOperandNode(node) && node.type === "Function";
323
+ var isCaseExpressionNode = (node) => isOperandNode(node) && node.type === "CaseExpression";
324
+ var isWindowFunctionNode = (node) => isOperandNode(node) && node.type === "WindowFunction";
261
325
  var isExpressionSelectionNode = (node) => isFunctionNode(node) || isCaseExpressionNode(node) || isWindowFunctionNode(node);
262
326
 
263
327
  // src/core/ast/expression-builders.ts
@@ -547,14 +611,15 @@ var registerOperandDispatcher = (type, dispatcher) => {
547
611
  };
548
612
  var clearExpressionDispatchers = () => expressionDispatchers.clear();
549
613
  var clearOperandDispatchers = () => operandDispatchers.clear();
614
+ var getNodeType = (node) => typeof node === "object" && node !== null && typeof node.type === "string" ? node.type : void 0;
550
615
  var unsupportedExpression = (node) => {
551
- throw new Error(`Unsupported expression type "${node?.type ?? "unknown"}"`);
616
+ throw new Error(`Unsupported expression type "${getNodeType(node) ?? "unknown"}"`);
552
617
  };
553
618
  var unsupportedOperand = (node) => {
554
- throw new Error(`Unsupported operand type "${node?.type ?? "unknown"}"`);
619
+ throw new Error(`Unsupported operand type "${getNodeType(node) ?? "unknown"}"`);
555
620
  };
556
621
  var visitExpression = (node, visitor) => {
557
- const dynamic = expressionDispatchers.get(node?.type);
622
+ const dynamic = expressionDispatchers.get(node.type);
558
623
  if (dynamic) return dynamic(node, visitor);
559
624
  switch (node.type) {
560
625
  case "BinaryExpression":
@@ -585,7 +650,7 @@ var visitExpression = (node, visitor) => {
585
650
  return unsupportedExpression(node);
586
651
  };
587
652
  var visitOperand = (node, visitor) => {
588
- const dynamic = operandDispatchers.get(node?.type);
653
+ const dynamic = operandDispatchers.get(node.type);
589
654
  if (dynamic) return dynamic(node, visitor);
590
655
  switch (node.type) {
591
656
  case "Column":
@@ -812,7 +877,8 @@ var Dialect = class _Dialect {
812
877
  if (!where) return "";
813
878
  return ` WHERE ${this.compileExpression(where, ctx)}`;
814
879
  }
815
- compileReturning(returning, ctx) {
880
+ compileReturning(returning, _ctx) {
881
+ void _ctx;
816
882
  if (!returning || returning.length === 0) return "";
817
883
  throw new Error("RETURNING is not supported by this dialect.");
818
884
  }
@@ -860,14 +926,16 @@ var Dialect = class _Dialect {
860
926
  * @param index - Parameter index
861
927
  * @returns Formatted placeholder string
862
928
  */
863
- formatPlaceholder(index) {
929
+ formatPlaceholder(_index) {
930
+ void _index;
864
931
  return "?";
865
932
  }
866
933
  /**
867
934
  * Whether the current dialect supports a given set operation.
868
935
  * Override in concrete dialects to restrict support.
869
936
  */
870
- supportsSetOperation(kind) {
937
+ supportsSetOperation(_kind) {
938
+ void _kind;
871
939
  return true;
872
940
  }
873
941
  /**
@@ -1060,15 +1128,22 @@ var Dialect = class _Dialect {
1060
1128
  }
1061
1129
  registerDefaultOperandCompilers() {
1062
1130
  this.registerOperandCompiler("Literal", (literal, ctx) => ctx.addParameter(literal.value));
1063
- this.registerOperandCompiler("AliasRef", (alias, _ctx) => this.quoteIdentifier(alias.name));
1131
+ this.registerOperandCompiler("AliasRef", (alias, _ctx) => {
1132
+ void _ctx;
1133
+ return this.quoteIdentifier(alias.name);
1134
+ });
1064
1135
  this.registerOperandCompiler("Column", (column, _ctx) => {
1136
+ void _ctx;
1065
1137
  return `${this.quoteIdentifier(column.table)}.${this.quoteIdentifier(column.name)}`;
1066
1138
  });
1067
1139
  this.registerOperandCompiler(
1068
1140
  "Function",
1069
1141
  (fnNode, ctx) => this.compileFunctionOperand(fnNode, ctx)
1070
1142
  );
1071
- this.registerOperandCompiler("JsonPath", (path, _ctx) => this.compileJsonPath(path));
1143
+ this.registerOperandCompiler("JsonPath", (path, _ctx) => {
1144
+ void _ctx;
1145
+ return this.compileJsonPath(path);
1146
+ });
1072
1147
  this.registerOperandCompiler("ScalarSubquery", (node, ctx) => {
1073
1148
  const sql = this.compileSelectAst(node.query, ctx).trim().replace(/;$/, "");
1074
1149
  return `(${sql})`;
@@ -1112,7 +1187,8 @@ var Dialect = class _Dialect {
1112
1187
  });
1113
1188
  }
1114
1189
  // Default fallback, should be overridden by dialects if supported
1115
- compileJsonPath(node) {
1190
+ compileJsonPath(_node) {
1191
+ void _node;
1116
1192
  throw new Error("JSON Path not supported by this dialect");
1117
1193
  }
1118
1194
  /**
@@ -1278,6 +1354,7 @@ var NoReturningStrategy = class {
1278
1354
  * @throws Error indicating RETURNING is not supported.
1279
1355
  */
1280
1356
  compileReturning(returning, _ctx) {
1357
+ void _ctx;
1281
1358
  if (!returning || returning.length === 0) return "";
1282
1359
  throw new Error("RETURNING is not supported by this dialect.");
1283
1360
  }
@@ -1679,6 +1756,7 @@ var PostgresDialect = class extends SqlDialectBase {
1679
1756
  return `${col2}->>'${node.path}'`;
1680
1757
  }
1681
1758
  compileReturning(returning, ctx) {
1759
+ void ctx;
1682
1760
  if (!returning || returning.length === 0) return "";
1683
1761
  const columns = this.formatReturningColumns(returning);
1684
1762
  return ` RETURNING ${columns}`;
@@ -1929,9 +2007,11 @@ var SqliteDialect = class extends SqlDialectBase {
1929
2007
  return `json_extract(${col2}, '${node.path}')`;
1930
2008
  }
1931
2009
  compileQualifiedColumn(column, _table) {
2010
+ void _table;
1932
2011
  return this.quoteIdentifier(column.name);
1933
2012
  }
1934
2013
  compileReturning(returning, ctx) {
2014
+ void ctx;
1935
2015
  if (!returning || returning.length === 0) return "";
1936
2016
  const columns = this.formatReturningColumns(returning);
1937
2017
  return ` RETURNING ${columns}`;
@@ -2584,7 +2664,8 @@ var HydrationManager = class _HydrationManager {
2584
2664
  getProjectionNames(columns) {
2585
2665
  const names = [];
2586
2666
  for (const col2 of columns) {
2587
- const alias = col2.alias ?? col2.name;
2667
+ const node = col2;
2668
+ const alias = node.alias ?? node.name;
2588
2669
  if (!alias) return void 0;
2589
2670
  names.push(alias);
2590
2671
  }
@@ -2801,7 +2882,8 @@ var buildDefaultHydrationPlan = (table) => ({
2801
2882
  // src/query-builder/raw-column-parser.ts
2802
2883
  var parseRawColumn = (col2, tableName, ctes) => {
2803
2884
  if (col2.includes("(")) {
2804
- const [fn4, rest] = col2.split("(");
2885
+ const [_fn, rest] = col2.split("(");
2886
+ void _fn;
2805
2887
  const colName = rest.replace(")", "");
2806
2888
  const [table, name] = colName.includes(".") ? colName.split(".") : [tableName, colName];
2807
2889
  return { type: "Column", table, name, alias: col2 };
@@ -3000,8 +3082,8 @@ var QueryAstService = class {
3000
3082
  }
3001
3083
  normalizeOrderingTerm(term) {
3002
3084
  const from = this.state.ast.from;
3003
- const tableRef = from.type === "Table" && from.alias ? { ...this.table, alias: from.alias } : this.table;
3004
- const termType = term?.type;
3085
+ const tableRef2 = from.type === "Table" && from.alias ? { ...this.table, alias: from.alias } : this.table;
3086
+ const termType = term.type;
3005
3087
  if (termType === "Column") {
3006
3088
  return term;
3007
3089
  }
@@ -3014,7 +3096,7 @@ var QueryAstService = class {
3014
3096
  if (termType === "BinaryExpression" || termType === "LogicalExpression" || termType === "NullExpression" || termType === "InExpression" || termType === "ExistsExpression" || termType === "BetweenExpression" || termType === "ArithmeticExpression") {
3015
3097
  return term;
3016
3098
  }
3017
- return buildColumnNode(tableRef, term);
3099
+ return buildColumnNode(tableRef2, term);
3018
3100
  }
3019
3101
  };
3020
3102
 
@@ -3420,8 +3502,8 @@ var ColumnSelector = class {
3420
3502
  */
3421
3503
  distinct(context, columns) {
3422
3504
  const from = context.state.ast.from;
3423
- const tableRef = from.type === "Table" && from.alias ? { ...this.env.table, alias: from.alias } : this.env.table;
3424
- const nodes = columns.map((col2) => buildColumnNode(tableRef, col2));
3505
+ const tableRef2 = from.type === "Table" && from.alias ? { ...this.env.table, alias: from.alias } : this.env.table;
3506
+ const nodes = columns.map((col2) => buildColumnNode(tableRef2, col2));
3425
3507
  const astService = this.env.deps.createQueryAstService(this.env.table, context.state);
3426
3508
  const nextState = astService.withDistinct(nodes);
3427
3509
  return { state: nextState, hydration: context.hydration };
@@ -4001,7 +4083,6 @@ var DefaultManyToManyCollection = class {
4001
4083
  }
4002
4084
  async syncByIds(ids) {
4003
4085
  await this.load();
4004
- const targetKey = this.relation.targetKey || findPrimaryKey(this.relation.target);
4005
4086
  const normalized = new Set(ids.map((id) => toKey5(id)));
4006
4087
  const currentIds = new Set(this.items.map((item) => toKey5(this.extractId(item))));
4007
4088
  for (const id of normalized) {
@@ -4272,7 +4353,6 @@ var createEntityProxy = (ctx, table, row, lazyRelations = []) => {
4272
4353
  enumerable: false,
4273
4354
  writable: false
4274
4355
  });
4275
- let proxy;
4276
4356
  const handler = {
4277
4357
  get(targetObj, prop, receiver) {
4278
4358
  if (prop === ENTITY_META) {
@@ -4280,7 +4360,7 @@ var createEntityProxy = (ctx, table, row, lazyRelations = []) => {
4280
4360
  }
4281
4361
  if (prop === "$load") {
4282
4362
  return async (relationName) => {
4283
- const wrapper = getRelationWrapper(meta, relationName, proxy);
4363
+ const wrapper = getRelationWrapper(meta, relationName, receiver);
4284
4364
  if (wrapper && typeof wrapper.load === "function") {
4285
4365
  return wrapper.load();
4286
4366
  }
@@ -4288,19 +4368,19 @@ var createEntityProxy = (ctx, table, row, lazyRelations = []) => {
4288
4368
  };
4289
4369
  }
4290
4370
  if (typeof prop === "string" && table.relations[prop]) {
4291
- return getRelationWrapper(meta, prop, proxy);
4371
+ return getRelationWrapper(meta, prop, receiver);
4292
4372
  }
4293
4373
  return Reflect.get(targetObj, prop, receiver);
4294
4374
  },
4295
4375
  set(targetObj, prop, value, receiver) {
4296
4376
  const result = Reflect.set(targetObj, prop, value, receiver);
4297
4377
  if (typeof prop === "string" && table.columns[prop]) {
4298
- ctx.markDirty(proxy);
4378
+ ctx.markDirty(receiver);
4299
4379
  }
4300
4380
  return result;
4301
4381
  }
4302
4382
  };
4303
- proxy = new Proxy(target, handler);
4383
+ const proxy = new Proxy(target, handler);
4304
4384
  populateHydrationCache(proxy, row, meta);
4305
4385
  return proxy;
4306
4386
  };
@@ -4542,7 +4622,8 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
4542
4622
  return this.clone(nextContext);
4543
4623
  }
4544
4624
  resolveQueryNode(query) {
4545
- return typeof query.getAST === "function" ? query.getAST() : query;
4625
+ const candidate = query;
4626
+ return typeof candidate.getAST === "function" && candidate.getAST ? candidate.getAST() : query;
4546
4627
  }
4547
4628
  applyCorrelation(ast, correlation) {
4548
4629
  if (!correlation) return ast;
@@ -4811,18 +4892,18 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
4811
4892
  * Selects columns for the root table and relations from a single config object.
4812
4893
  */
4813
4894
  selectColumnsDeep(config) {
4814
- let qb = this;
4895
+ let currBuilder = this;
4815
4896
  if (config.root?.length) {
4816
- qb = qb.selectColumns(...config.root);
4897
+ currBuilder = currBuilder.selectColumns(...config.root);
4817
4898
  }
4818
4899
  for (const key of Object.keys(config)) {
4819
4900
  if (key === "root") continue;
4820
4901
  const relName = key;
4821
4902
  const cols = config[relName];
4822
4903
  if (!cols || !cols.length) continue;
4823
- qb = qb.selectRelationColumns(relName, ...cols);
4904
+ currBuilder = currBuilder.selectRelationColumns(relName, ...cols);
4824
4905
  }
4825
- return qb;
4906
+ return currBuilder;
4826
4907
  }
4827
4908
  getLazyRelations() {
4828
4909
  return Array.from(this.lazyRelations);
@@ -5257,6 +5338,13 @@ var selectFromEntity = (ctor) => {
5257
5338
  }
5258
5339
  return new SelectQueryBuilder(table);
5259
5340
  };
5341
+ var entityRef = (ctor) => {
5342
+ const table = getTableDefFromEntity(ctor);
5343
+ if (!table) {
5344
+ throw new Error(`Entity '${ctor.name}' is not registered with decorators or has not been bootstrapped`);
5345
+ }
5346
+ return tableRef(table);
5347
+ };
5260
5348
 
5261
5349
  // src/query-builder/select-helpers.ts
5262
5350
  function sel(table, ...cols) {
@@ -5409,11 +5497,13 @@ var InsertQueryBuilder = class _InsertQueryBuilder {
5409
5497
  return columns.map((column) => buildColumnNode(this.table, column));
5410
5498
  }
5411
5499
  resolveSelectQuery(query) {
5412
- return typeof query.getAST === "function" ? query.getAST() : query;
5500
+ const candidate = query;
5501
+ return typeof candidate.getAST === "function" && candidate.getAST ? candidate.getAST() : query;
5413
5502
  }
5414
5503
  compile(arg) {
5415
- if (typeof arg.compileInsert === "function") {
5416
- return arg.compileInsert(this.state.ast);
5504
+ const candidate = arg;
5505
+ if (typeof candidate.compileInsert === "function") {
5506
+ return candidate.compileInsert(this.state.ast);
5417
5507
  }
5418
5508
  const dialect = resolveDialectInput(arg);
5419
5509
  return dialect.compileInsert(this.state.ast);
@@ -5550,8 +5640,9 @@ var UpdateQueryBuilder = class _UpdateQueryBuilder {
5550
5640
  return this.resolveTableSource(table);
5551
5641
  }
5552
5642
  compile(arg) {
5553
- if (typeof arg.compileUpdate === "function") {
5554
- return arg.compileUpdate(this.state.ast);
5643
+ const candidate = arg;
5644
+ if (typeof candidate.compileUpdate === "function") {
5645
+ return candidate.compileUpdate(this.state.ast);
5555
5646
  }
5556
5647
  const dialect = resolveDialectInput(arg);
5557
5648
  return dialect.compileUpdate(this.state.ast);
@@ -5652,8 +5743,9 @@ var DeleteQueryBuilder = class _DeleteQueryBuilder {
5652
5743
  return this.resolveTableSource(table);
5653
5744
  }
5654
5745
  compile(arg) {
5655
- if (typeof arg.compileDelete === "function") {
5656
- return arg.compileDelete(this.state.ast);
5746
+ const candidate = arg;
5747
+ if (typeof candidate.compileDelete === "function") {
5748
+ return candidate.compileDelete(this.state.ast);
5657
5749
  }
5658
5750
  const dialect = resolveDialectInput(arg);
5659
5751
  return dialect.compileDelete(this.state.ast);
@@ -5703,7 +5795,7 @@ var generateCreateTableSql = (table, dialect) => {
5703
5795
  const pk = resolvePrimaryKey(table);
5704
5796
  const inlinePkColumns = /* @__PURE__ */ new Set();
5705
5797
  const columnLines = Object.values(table.columns).map((col2) => {
5706
- const includePk = dialect.preferInlinePkAutoincrement?.(col2, table, pk) && pk.includes(col2.name);
5798
+ const includePk = dialect.preferInlinePkAutoincrement(col2, table, pk) && pk.includes(col2.name);
5707
5799
  if (includePk) {
5708
5800
  inlinePkColumns.add(col2.name);
5709
5801
  }
@@ -6208,7 +6300,7 @@ var postgresIntrospector = {
6208
6300
  ],
6209
6301
  where: and(
6210
6302
  eq({ table: "ns", name: "nspname" }, schema),
6211
- eq({ table: "i", name: "indisprimary" }, { type: "Literal", value: false })
6303
+ eq({ table: "i", name: "indisprimary" }, false)
6212
6304
  )
6213
6305
  };
6214
6306
  const indexQueryRows = await runSelectNode(indexQuery, ctx);
@@ -6372,6 +6464,14 @@ var mysqlIntrospector = {
6372
6464
  };
6373
6465
 
6374
6466
  // src/core/ddl/introspect/sqlite.ts
6467
+ var toReferentialAction = (value) => {
6468
+ if (!value) return void 0;
6469
+ const normalized = value.toUpperCase();
6470
+ if (normalized === "NO ACTION" || normalized === "RESTRICT" || normalized === "CASCADE" || normalized === "SET NULL" || normalized === "SET DEFAULT") {
6471
+ return normalized;
6472
+ }
6473
+ return void 0;
6474
+ };
6375
6475
  var escapeSingleQuotes = (name) => name.replace(/'/g, "''");
6376
6476
  var sqliteIntrospector = {
6377
6477
  async introspect(ctx, options) {
@@ -6405,8 +6505,8 @@ var sqliteIntrospector = {
6405
6505
  col2.references = {
6406
6506
  table: fk.table,
6407
6507
  column: fk.to,
6408
- onDelete: fk.on_delete?.toUpperCase(),
6409
- onUpdate: fk.on_update?.toUpperCase()
6508
+ onDelete: toReferentialAction(fk.on_delete),
6509
+ onUpdate: toReferentialAction(fk.on_update)
6410
6510
  };
6411
6511
  }
6412
6512
  });
@@ -6816,11 +6916,7 @@ var TypeScriptGenerator = class {
6816
6916
  const lines = [];
6817
6917
  const hydration = ast.meta?.hydration;
6818
6918
  const hydratedRelations = new Set(hydration?.relations?.map((r) => r.name) ?? []);
6819
- const selections = ast.columns.filter((col2) => !(hydration && isRelationAlias(col2.alias))).map((col2) => {
6820
- const key = col2.alias || col2.name;
6821
- const operand = col2;
6822
- return `${key}: ${this.printOperand(operand)}`;
6823
- });
6919
+ const selections = ast.columns.filter((col2) => !(hydration && isRelationAlias(col2.alias))).map((col2, index) => `${this.getSelectionKey(col2, index)}: ${this.printOperand(col2)}`);
6824
6920
  lines.push(`db.select({`);
6825
6921
  selections.forEach((sel2, index) => {
6826
6922
  lines.push(` ${sel2}${index < selections.length - 1 ? "," : ""}`);
@@ -6908,7 +7004,7 @@ var TypeScriptGenerator = class {
6908
7004
  * Prints an ordering term (operand/expression/alias) to TypeScript code.
6909
7005
  */
6910
7006
  printOrderingTerm(term) {
6911
- if (!term || !term.type) {
7007
+ if (!term || !("type" in term)) {
6912
7008
  throw new Error("Unsupported ordering term");
6913
7009
  }
6914
7010
  switch (term.type) {
@@ -6927,6 +7023,18 @@ var TypeScriptGenerator = class {
6927
7023
  return this.printExpression(term);
6928
7024
  }
6929
7025
  }
7026
+ getSelectionKey(selection, index) {
7027
+ if (selection.alias) {
7028
+ return selection.alias;
7029
+ }
7030
+ if (this.isNamedSelection(selection)) {
7031
+ return selection.name;
7032
+ }
7033
+ return `selection${index + 1}`;
7034
+ }
7035
+ isNamedSelection(selection) {
7036
+ return "name" in selection;
7037
+ }
6930
7038
  visitBinaryExpression(binary) {
6931
7039
  return this.printBinaryExpression(binary);
6932
7040
  }
@@ -7710,6 +7818,7 @@ var RelationChangeProcessor = class {
7710
7818
  * @param _entry - The relation change entry (reserved for future use)
7711
7819
  */
7712
7820
  async handleBelongsToChange(_entry) {
7821
+ void _entry;
7713
7822
  }
7714
7823
  /**
7715
7824
  * Handles changes for belongs-to-many relations.
@@ -7823,7 +7932,7 @@ var RelationChangeProcessor = class {
7823
7932
  const key = findPrimaryKey(table);
7824
7933
  const value = entity[key];
7825
7934
  if (value === void 0 || value === null) return null;
7826
- return value;
7935
+ return value ?? null;
7827
7936
  }
7828
7937
  };
7829
7938
 
@@ -8415,8 +8524,6 @@ var Orm = class {
8415
8524
  const session = new OrmSession({ orm: this, executor });
8416
8525
  try {
8417
8526
  return await session.transaction(() => fn4(session));
8418
- } catch (err) {
8419
- throw err;
8420
8527
  } finally {
8421
8528
  await session.dispose();
8422
8529
  }
@@ -8447,9 +8554,6 @@ var getOrCreateMetadataBag = (context) => {
8447
8554
  var readMetadataBag = (context) => {
8448
8555
  return context.metadata?.[METADATA_KEY];
8449
8556
  };
8450
- var registerInitializer = (context, initializer) => {
8451
- context.addInitializer?.(initializer);
8452
- };
8453
8557
 
8454
8558
  // src/decorators/entity.ts
8455
8559
  var toSnakeCase = (value) => {
@@ -8479,14 +8583,24 @@ function Entity(options = {}) {
8479
8583
  if (bag) {
8480
8584
  const meta = ensureEntityMetadata(ctor);
8481
8585
  for (const entry of bag.columns) {
8482
- if (!meta.columns[entry.propertyName]) {
8483
- addColumnMetadata(ctor, entry.propertyName, { ...entry.column });
8586
+ if (meta.columns[entry.propertyName]) {
8587
+ throw new Error(
8588
+ `Column '${entry.propertyName}' is already defined on entity '${ctor.name}'.`
8589
+ );
8484
8590
  }
8591
+ addColumnMetadata(ctor, entry.propertyName, { ...entry.column });
8485
8592
  }
8486
8593
  for (const entry of bag.relations) {
8487
- if (!meta.relations[entry.propertyName]) {
8488
- addRelationMetadata(ctor, entry.propertyName, entry.relation);
8594
+ if (meta.relations[entry.propertyName]) {
8595
+ throw new Error(
8596
+ `Relation '${entry.propertyName}' is already defined on entity '${ctor.name}'.`
8597
+ );
8489
8598
  }
8599
+ const relationCopy = entry.relation.kind === RelationKinds.BelongsToMany ? {
8600
+ ...entry.relation,
8601
+ defaultPivotColumns: entry.relation.defaultPivotColumns ? [...entry.relation.defaultPivotColumns] : void 0
8602
+ } : { ...entry.relation };
8603
+ addRelationMetadata(ctor, entry.propertyName, relationCopy);
8490
8604
  }
8491
8605
  }
8492
8606
  }
@@ -8549,13 +8663,6 @@ var registerColumnFromContext = (context, column) => {
8549
8663
  if (!bag.columns.some((entry) => entry.propertyName === propertyName)) {
8550
8664
  bag.columns.push({ propertyName, column: { ...column } });
8551
8665
  }
8552
- registerInitializer(context, function() {
8553
- const ctor = resolveConstructor(this);
8554
- if (!ctor) {
8555
- return;
8556
- }
8557
- registerColumn(ctor, propertyName, column);
8558
- });
8559
8666
  };
8560
8667
  function Column(definition) {
8561
8668
  const normalized = normalizeColumnInput(definition);
@@ -8611,13 +8718,6 @@ var createFieldDecorator = (metadataFactory) => {
8611
8718
  if (!bag.relations.some((entry) => entry.propertyName === propertyName2)) {
8612
8719
  bag.relations.push({ propertyName: propertyName2, relation: relationMetadata });
8613
8720
  }
8614
- registerInitializer(ctx, function() {
8615
- const ctor2 = resolveConstructor2(this);
8616
- if (!ctor2) {
8617
- return;
8618
- }
8619
- registerRelation(ctor2, propertyName2, relationMetadata);
8620
- });
8621
8721
  return;
8622
8722
  }
8623
8723
  const propertyName = normalizePropertyName2(propertyKeyOrContext);
@@ -9282,6 +9382,7 @@ export {
9282
9382
  diffSchema,
9283
9383
  div,
9284
9384
  endOfMonth,
9385
+ entityRef,
9285
9386
  eq,
9286
9387
  esel,
9287
9388
  executeHydrated,
@@ -9294,6 +9395,7 @@ export {
9294
9395
  fromUnixTime,
9295
9396
  generateCreateTableSql,
9296
9397
  generateSchemaSql,
9398
+ getColumn,
9297
9399
  getSchemaIntrospector,
9298
9400
  getTableDefFromEntity,
9299
9401
  groupConcat,
@@ -9380,6 +9482,7 @@ export {
9380
9482
  substr,
9381
9483
  sum,
9382
9484
  synchronizeSchema,
9485
+ tableRef,
9383
9486
  tan,
9384
9487
  toColumnRef,
9385
9488
  toTableRef,