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.
- package/README.md +74 -20
- package/dist/index.cjs +180 -74
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +142 -96
- package/dist/index.d.ts +142 -96
- package/dist/index.js +177 -74
- package/dist/index.js.map +1 -1
- package/package.json +8 -2
- package/scripts/run-eslint.mjs +34 -0
- package/src/codegen/typescript.ts +32 -15
- package/src/core/ast/builders.ts +7 -2
- package/src/core/ast/expression-builders.ts +0 -2
- package/src/core/ast/expression-nodes.ts +14 -5
- package/src/core/ast/expression-visitor.ts +11 -8
- package/src/core/ast/expression.ts +2 -2
- package/src/core/ast/join-node.ts +1 -1
- package/src/core/ast/query.ts +6 -6
- package/src/core/ast/window-functions.ts +10 -2
- package/src/core/ddl/dialects/base-schema-dialect.ts +30 -3
- package/src/core/ddl/dialects/mssql-schema-dialect.ts +4 -0
- package/src/core/ddl/dialects/mysql-schema-dialect.ts +2 -0
- package/src/core/ddl/dialects/postgres-schema-dialect.ts +13 -1
- package/src/core/ddl/dialects/render-reference.test.ts +69 -0
- package/src/core/ddl/dialects/sqlite-schema-dialect.ts +9 -0
- package/src/core/ddl/introspect/mssql.ts +42 -8
- package/src/core/ddl/introspect/mysql.ts +30 -6
- package/src/core/ddl/introspect/postgres.ts +88 -34
- package/src/core/ddl/introspect/run-select.ts +6 -4
- package/src/core/ddl/introspect/sqlite.ts +56 -11
- package/src/core/ddl/introspect/types.ts +0 -1
- package/src/core/ddl/introspect/utils.ts +3 -3
- package/src/core/ddl/schema-dialect.ts +1 -0
- package/src/core/ddl/schema-generator.ts +4 -12
- package/src/core/ddl/sql-writing.ts +4 -4
- package/src/core/dialect/abstract.ts +18 -6
- package/src/core/dialect/base/function-table-formatter.ts +3 -2
- package/src/core/dialect/base/join-compiler.ts +5 -3
- package/src/core/dialect/base/returning-strategy.ts +1 -0
- package/src/core/dialect/base/sql-dialect.ts +3 -3
- package/src/core/dialect/mssql/functions.ts +24 -25
- package/src/core/dialect/mssql/index.ts +1 -4
- package/src/core/dialect/mysql/functions.ts +0 -1
- package/src/core/dialect/postgres/functions.ts +33 -34
- package/src/core/dialect/postgres/index.ts +1 -0
- package/src/core/dialect/sqlite/functions.ts +18 -19
- package/src/core/dialect/sqlite/index.ts +2 -0
- package/src/core/execution/db-executor.ts +1 -1
- package/src/core/execution/executors/mysql-executor.ts +2 -2
- package/src/core/execution/executors/postgres-executor.ts +1 -1
- package/src/core/execution/pooling/pool.ts +2 -0
- package/src/core/functions/datetime.ts +1 -1
- package/src/core/functions/numeric.ts +1 -1
- package/src/core/functions/text.ts +1 -1
- package/src/decorators/bootstrap.ts +27 -8
- package/src/decorators/column.ts +3 -11
- package/src/decorators/decorator-metadata.ts +3 -9
- package/src/decorators/entity.ts +21 -5
- package/src/decorators/relations.ts +2 -11
- package/src/orm/entity-context.ts +8 -8
- package/src/orm/entity-meta.ts +8 -8
- package/src/orm/entity-metadata.ts +11 -9
- package/src/orm/entity.ts +28 -29
- package/src/orm/execute.ts +4 -4
- package/src/orm/hydration.ts +42 -39
- package/src/orm/identity-map.ts +1 -1
- package/src/orm/lazy-batch.ts +9 -9
- package/src/orm/orm-session.ts +24 -23
- package/src/orm/orm.ts +2 -5
- package/src/orm/relation-change-processor.ts +12 -11
- package/src/orm/relations/belongs-to.ts +11 -11
- package/src/orm/relations/has-many.ts +10 -10
- package/src/orm/relations/has-one.ts +8 -7
- package/src/orm/relations/many-to-many.ts +13 -13
- package/src/orm/runtime-types.ts +4 -4
- package/src/orm/save-graph.ts +31 -25
- package/src/orm/unit-of-work.ts +17 -17
- package/src/query-builder/delete.ts +4 -3
- package/src/query-builder/hydration-manager.ts +6 -5
- package/src/query-builder/insert.ts +12 -8
- package/src/query-builder/query-ast-service.ts +2 -2
- package/src/query-builder/raw-column-parser.ts +2 -1
- package/src/query-builder/select-helpers.ts +2 -2
- package/src/query-builder/select.ts +31 -31
- package/src/query-builder/update.ts +4 -3
- package/src/schema/column.ts +26 -26
- package/src/schema/table.ts +239 -115
- 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
|
-
|
|
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
|
|
258
|
-
var
|
|
259
|
-
|
|
260
|
-
|
|
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
|
|
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
|
|
619
|
+
throw new Error(`Unsupported operand type "${getNodeType(node) ?? "unknown"}"`);
|
|
555
620
|
};
|
|
556
621
|
var visitExpression = (node, visitor) => {
|
|
557
|
-
const dynamic = expressionDispatchers.get(node
|
|
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
|
|
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,
|
|
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(
|
|
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(
|
|
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) =>
|
|
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) =>
|
|
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(
|
|
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
|
|
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 [
|
|
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
|
|
3004
|
-
const termType = term
|
|
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(
|
|
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
|
|
3424
|
-
const nodes = columns.map((col2) => buildColumnNode(
|
|
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,
|
|
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,
|
|
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(
|
|
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
|
-
|
|
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
|
|
4895
|
+
let currBuilder = this;
|
|
4815
4896
|
if (config.root?.length) {
|
|
4816
|
-
|
|
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
|
-
|
|
4904
|
+
currBuilder = currBuilder.selectRelationColumns(relName, ...cols);
|
|
4824
4905
|
}
|
|
4825
|
-
return
|
|
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
|
-
|
|
5500
|
+
const candidate = query;
|
|
5501
|
+
return typeof candidate.getAST === "function" && candidate.getAST ? candidate.getAST() : query;
|
|
5413
5502
|
}
|
|
5414
5503
|
compile(arg) {
|
|
5415
|
-
|
|
5416
|
-
|
|
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
|
-
|
|
5554
|
-
|
|
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
|
-
|
|
5656
|
-
|
|
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
|
|
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" },
|
|
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
|
|
6409
|
-
onUpdate: fk.on_update
|
|
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
|
|
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 (
|
|
8483
|
-
|
|
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 (
|
|
8488
|
-
|
|
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,
|