metal-orm 1.1.11 → 1.1.18
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 +758 -769
- package/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +100 -96
- package/scripts/generate-entities/schema.mjs +122 -122
- package/scripts/generate-entities/tree-detection.mjs +92 -92
- package/scripts/inflection/pt-br.mjs +468 -468
- package/scripts/run-eslint.mjs +33 -34
- package/scripts/show-sql-seed.sql +102 -0
- package/scripts/show-sql.mjs +321 -325
- package/src/codegen/naming-strategy.ts +54 -54
- package/src/codegen/typescript.ts +482 -482
- package/src/core/ast/adapters.ts +1 -1
- package/src/core/ast/builders.ts +123 -123
- package/src/core/ast/expression-builders.ts +745 -745
- package/src/core/ast/expression-nodes.ts +304 -304
- package/src/core/ast/expression-visitor.ts +212 -212
- package/src/core/ast/expression.ts +20 -20
- package/src/core/ast/helpers.ts +14 -14
- package/src/core/ast/join.ts +18 -18
- package/src/core/ast/query.ts +200 -200
- package/src/core/ddl/dialects/base-schema-dialect.ts +1 -1
- package/src/core/ddl/dialects/mssql-schema-dialect.ts +1 -1
- package/src/core/ddl/dialects/mysql-schema-dialect.ts +1 -1
- package/src/core/ddl/dialects/postgres-schema-dialect.ts +1 -1
- package/src/core/ddl/dialects/render-reference.test.ts +70 -70
- package/src/core/ddl/dialects/sqlite-schema-dialect.ts +1 -1
- package/src/core/ddl/introspect/catalogs/index.ts +5 -5
- package/src/core/ddl/introspect/catalogs/postgres.ts +146 -146
- package/src/core/ddl/introspect/context.ts +15 -15
- package/src/core/ddl/introspect/functions/postgres.ts +35 -35
- package/src/core/ddl/introspect/registry.ts +40 -40
- package/src/core/ddl/introspect/run-select.ts +35 -35
- package/src/core/ddl/introspect/utils.ts +56 -56
- package/src/core/ddl/naming-strategy.ts +16 -16
- package/src/core/ddl/schema-dialect.ts +56 -56
- package/src/core/ddl/schema-diff.ts +234 -234
- package/src/core/ddl/schema-generator.ts +1 -1
- package/src/core/ddl/schema-introspect.ts +25 -25
- package/src/core/ddl/sql-writing.ts +171 -171
- package/src/core/dialect/abstract.ts +541 -541
- package/src/core/dialect/base/cte-compiler.ts +33 -33
- package/src/core/dialect/base/function-table-formatter.ts +103 -103
- package/src/core/dialect/base/groupby-compiler.ts +21 -21
- package/src/core/dialect/base/join-compiler.ts +25 -25
- package/src/core/dialect/base/orderby-compiler.ts +35 -35
- package/src/core/dialect/base/pagination-strategy.ts +32 -32
- package/src/core/dialect/base/returning-strategy.ts +57 -57
- package/src/core/dialect/base/sql-dialect.ts +294 -294
- package/src/core/dialect/dialect-factory.ts +91 -91
- package/src/core/dialect/mssql/functions.ts +120 -120
- package/src/core/dialect/mssql/index.ts +317 -317
- package/src/core/dialect/mysql/functions.ts +103 -103
- package/src/core/dialect/mysql/index.ts +105 -105
- package/src/core/dialect/postgres/functions.ts +108 -108
- package/src/core/dialect/postgres/index.ts +91 -91
- package/src/core/dialect/sqlite/functions.ts +129 -129
- package/src/core/dialect/sqlite/index.ts +67 -67
- package/src/core/driver/database-driver.ts +19 -19
- package/src/core/driver/mssql-driver.ts +23 -23
- package/src/core/driver/mysql-driver.ts +23 -23
- package/src/core/driver/postgres-driver.ts +23 -23
- package/src/core/driver/sqlite-driver.ts +23 -23
- package/src/core/execution/db-executor.ts +92 -92
- package/src/core/execution/executors/better-sqlite3-executor.ts +90 -90
- package/src/core/execution/executors/mssql-executor.ts +184 -184
- package/src/core/execution/executors/mysql-executor.ts +88 -88
- package/src/core/execution/executors/postgres-executor.ts +26 -26
- package/src/core/execution/executors/sqlite-executor.ts +42 -42
- package/src/core/execution/pooling/pool-types.ts +30 -30
- package/src/core/execution/pooling/pool.ts +275 -275
- package/src/core/functions/array.ts +35 -35
- package/src/core/functions/control-flow.ts +79 -79
- package/src/core/functions/datetime.ts +237 -237
- package/src/core/functions/json.ts +70 -70
- package/src/core/functions/numeric.ts +297 -297
- package/src/core/functions/text.ts +334 -334
- package/src/core/functions/types.ts +33 -33
- package/src/core/hydration/types.ts +51 -51
- package/src/core/sql/sql-operator-config.ts +39 -39
- package/src/core/sql/sql.ts +152 -152
- package/src/decorators/column-decorator.ts +87 -87
- package/src/decorators/decorator-metadata.ts +143 -143
- package/src/decorators/entity.ts +93 -93
- package/src/decorators/index.ts +39 -39
- package/src/decorators/relations.ts +231 -231
- package/src/decorators/transformers/built-in/string-transformers.ts +231 -231
- package/src/decorators/transformers/transformer-decorators.ts +134 -134
- package/src/decorators/transformers/transformer-executor.ts +171 -171
- package/src/decorators/transformers/transformer-metadata.ts +73 -73
- package/src/decorators/validators/built-in/br-cep-validator.ts +55 -55
- package/src/decorators/validators/built-in/br-cnpj-validator.ts +105 -105
- package/src/decorators/validators/built-in/br-cpf-validator.ts +103 -103
- package/src/decorators/validators/country-validator-registry.ts +64 -64
- package/src/decorators/validators/country-validators-decorators.ts +203 -203
- package/src/decorators/validators/country-validators.ts +105 -105
- package/src/decorators/validators/validator-metadata.ts +59 -59
- package/src/dto/dto-types.ts +226 -226
- package/src/dto/filter-types.ts +141 -141
- package/src/dto/index.ts +95 -95
- package/src/dto/openapi/generators/base.ts +29 -29
- package/src/dto/openapi/generators/column.ts +37 -37
- package/src/dto/openapi/generators/dto.ts +91 -91
- package/src/dto/openapi/generators/filter.ts +75 -75
- package/src/dto/openapi/generators/nested-dto.ts +618 -618
- package/src/dto/openapi/generators/pagination.ts +111 -111
- package/src/dto/openapi/generators/relation-filter.ts +228 -228
- package/src/dto/openapi/index.ts +12 -12
- package/src/dto/openapi/types.ts +101 -101
- package/src/dto/openapi/utilities.ts +95 -95
- package/src/dto/pagination-utils.ts +150 -150
- package/src/dto/transform.ts +197 -197
- package/src/index.ts +86 -86
- package/src/orm/als.ts +58 -58
- package/src/orm/domain-event-bus.ts +119 -119
- package/src/orm/entity-context.ts +86 -86
- package/src/orm/entity-materializer.ts +159 -159
- package/src/orm/entity-meta.ts +97 -97
- package/src/orm/entity-registry.ts +39 -39
- package/src/orm/entity-relation-cache.ts +39 -39
- package/src/orm/execute.ts +194 -194
- package/src/orm/execution-context.ts +18 -18
- package/src/orm/hydration-context.ts +26 -26
- package/src/orm/hydration.ts +112 -112
- package/src/orm/identity-map.ts +61 -61
- package/src/orm/interceptor-pipeline.ts +16 -16
- package/src/orm/lazy-batch/belongs-to-many.ts +119 -119
- package/src/orm/lazy-batch/belongs-to.ts +108 -108
- package/src/orm/lazy-batch/has-many.ts +69 -69
- package/src/orm/lazy-batch/has-one.ts +68 -68
- package/src/orm/lazy-batch/shared.ts +125 -125
- package/src/orm/orm-session.ts +620 -620
- package/src/orm/orm.ts +34 -34
- package/src/orm/pooled-executor-factory.ts +121 -121
- package/src/orm/query-logger.ts +40 -40
- package/src/orm/relation-change-processor.ts +420 -420
- package/src/orm/relations/belongs-to.ts +143 -143
- package/src/orm/relations/has-many.ts +204 -204
- package/src/orm/relations/has-one.ts +174 -174
- package/src/orm/relations/many-to-many.ts +288 -288
- package/src/orm/relations/morph-many.ts +156 -156
- package/src/orm/relations/morph-one.ts +151 -151
- package/src/orm/relations/morph-to.ts +162 -162
- package/src/orm/runtime-types.ts +92 -92
- package/src/orm/save-graph.ts +561 -561
- package/src/orm/transaction-runner.ts +24 -24
- package/src/orm/unit-of-work.ts +426 -426
- package/src/query/index.ts +69 -69
- package/src/query/target.ts +46 -46
- package/src/query-builder/column-selector.ts +81 -81
- package/src/query-builder/delete.ts +141 -141
- package/src/query-builder/insert-query-state.ts +149 -149
- package/src/query-builder/insert.ts +117 -117
- package/src/query-builder/query-ast-service.ts +287 -287
- package/src/query-builder/query-resolution.ts +78 -78
- package/src/query-builder/raw-column-parser.ts +38 -38
- package/src/query-builder/relation-filter-utils.ts +153 -153
- package/src/query-builder/relation-join-planner.ts +10 -10
- package/src/query-builder/relation-manager.ts +87 -87
- package/src/query-builder/relation-projection-helper.ts +102 -102
- package/src/query-builder/relation-types.ts +9 -9
- package/src/query-builder/relation-utils.ts +15 -15
- package/src/query-builder/select/cte-facet.ts +40 -40
- package/src/query-builder/select/from-facet.ts +80 -80
- package/src/query-builder/select/join-facet.ts +62 -62
- package/src/query-builder/select/predicate-facet.ts +104 -104
- package/src/query-builder/select/projection-facet.ts +70 -70
- package/src/query-builder/select/relation-facet.ts +81 -81
- package/src/query-builder/select/setop-facet.ts +36 -36
- package/src/query-builder/select-helpers.ts +1 -1
- package/src/query-builder/select-query-builder-deps.ts +130 -130
- package/src/query-builder/select-query-state.ts +207 -207
- package/src/query-builder/update.ts +151 -151
- package/src/schema/column-types.ts +322 -322
- package/src/schema/table-guards.ts +37 -37
- package/src/schema/table.ts +281 -281
- package/src/tree/index.ts +13 -13
- package/src/tree/nested-set-strategy.ts +545 -545
- package/src/tree/tree-decorator.ts +397 -397
- package/src/tree/tree-manager.ts +754 -754
- package/src/tree/tree-query.ts +427 -427
- package/src/tree/tree-types.ts +299 -299
|
@@ -1,125 +1,125 @@
|
|
|
1
|
-
import { TableDef } from '../../schema/table.js';
|
|
2
|
-
import { SelectQueryBuilder } from '../../query-builder/select.js';
|
|
3
|
-
import { ExpressionNode, inList, LiteralNode } from '../../core/ast/expression.js';
|
|
4
|
-
import type { QueryResult } from '../../core/execution/db-executor.js';
|
|
5
|
-
import { ColumnDef } from '../../schema/column-types.js';
|
|
6
|
-
import { EntityContext } from '../entity-context.js';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* An array of database rows, each represented as a record of string keys to unknown values.
|
|
10
|
-
*/
|
|
11
|
-
export type Rows = Record<string, unknown>[];
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Represents a single tracked entity from the EntityContext for a table.
|
|
15
|
-
*/
|
|
16
|
-
export type EntityTracker = ReturnType<EntityContext['getEntitiesForTable']>[number];
|
|
17
|
-
|
|
18
|
-
export const hasColumns = (columns?: readonly string[]): columns is readonly string[] =>
|
|
19
|
-
Boolean(columns && columns.length > 0);
|
|
20
|
-
|
|
21
|
-
export const buildColumnSelection = (
|
|
22
|
-
table: TableDef,
|
|
23
|
-
columns: string[],
|
|
24
|
-
missingMsg: (col: string) => string
|
|
25
|
-
): Record<string, ColumnDef> => {
|
|
26
|
-
return columns.reduce((acc, column) => {
|
|
27
|
-
const def = table.columns[column];
|
|
28
|
-
if (!def) {
|
|
29
|
-
throw new Error(missingMsg(column));
|
|
30
|
-
}
|
|
31
|
-
acc[column] = def;
|
|
32
|
-
return acc;
|
|
33
|
-
}, {} as Record<string, ColumnDef>);
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export const filterRow = (row: Record<string, unknown>, columns: Set<string>): Record<string, unknown> => {
|
|
37
|
-
const filtered: Record<string, unknown> = {};
|
|
38
|
-
for (const column of columns) {
|
|
39
|
-
if (column in row) {
|
|
40
|
-
filtered[column] = row[column];
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return filtered;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export const filterRows = (rows: Rows, columns: Set<string>): Rows => rows.map(row => filterRow(row, columns));
|
|
47
|
-
|
|
48
|
-
const rowsFromResults = (results: QueryResult[]): Rows => {
|
|
49
|
-
const rows: Rows = [];
|
|
50
|
-
for (const result of results) {
|
|
51
|
-
const { columns, values } = result;
|
|
52
|
-
for (const valueRow of values) {
|
|
53
|
-
const row: Record<string, unknown> = {};
|
|
54
|
-
columns.forEach((column, idx) => {
|
|
55
|
-
row[column] = valueRow[idx];
|
|
56
|
-
});
|
|
57
|
-
rows.push(row);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return rows;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const executeQuery = async (ctx: EntityContext, qb: SelectQueryBuilder<unknown, TableDef>): Promise<Rows> => {
|
|
64
|
-
const compiled = ctx.dialect.compileSelect(qb.getAST());
|
|
65
|
-
const results = await ctx.executor.executeSql(compiled.sql, compiled.params);
|
|
66
|
-
return rowsFromResults(results);
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
export const toKey = (value: unknown): string => (value === null || value === undefined ? '' : String(value));
|
|
70
|
-
|
|
71
|
-
export const collectKeysFromRoots = (roots: EntityTracker[], key: string): Set<unknown> => {
|
|
72
|
-
const collected = new Set<unknown>();
|
|
73
|
-
for (const tracked of roots) {
|
|
74
|
-
const value = (tracked.entity as Record<string, unknown>)[key];
|
|
75
|
-
if (value !== null && value !== undefined) {
|
|
76
|
-
collected.add(value);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return collected;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
const buildInListValues = (keys: Set<unknown>): (string | number | LiteralNode)[] =>
|
|
83
|
-
Array.from(keys) as (string | number | LiteralNode)[];
|
|
84
|
-
|
|
85
|
-
export const fetchRowsForKeys = async (
|
|
86
|
-
ctx: EntityContext,
|
|
87
|
-
table: TableDef,
|
|
88
|
-
column: ColumnDef,
|
|
89
|
-
keys: Set<unknown>,
|
|
90
|
-
selection: Record<string, ColumnDef>,
|
|
91
|
-
filter?: ExpressionNode
|
|
92
|
-
): Promise<Rows> => {
|
|
93
|
-
let qb = new SelectQueryBuilder(table).select(selection);
|
|
94
|
-
qb = qb.where(inList(column, buildInListValues(keys)));
|
|
95
|
-
if (filter) {
|
|
96
|
-
qb = qb.where(filter);
|
|
97
|
-
}
|
|
98
|
-
return executeQuery(ctx, qb);
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
export const groupRowsByMany = (rows: Rows, keyColumn: string): Map<string, Rows> => {
|
|
102
|
-
const grouped = new Map<string, Rows>();
|
|
103
|
-
for (const row of rows) {
|
|
104
|
-
const value = row[keyColumn];
|
|
105
|
-
if (value === null || value === undefined) continue;
|
|
106
|
-
const key = toKey(value);
|
|
107
|
-
const bucket = grouped.get(key) ?? [];
|
|
108
|
-
bucket.push(row);
|
|
109
|
-
grouped.set(key, bucket);
|
|
110
|
-
}
|
|
111
|
-
return grouped;
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
export const groupRowsByUnique = (rows: Rows, keyColumn: string): Map<string, Record<string, unknown>> => {
|
|
115
|
-
const lookup = new Map<string, Record<string, unknown>>();
|
|
116
|
-
for (const row of rows) {
|
|
117
|
-
const value = row[keyColumn];
|
|
118
|
-
if (value === null || value === undefined) continue;
|
|
119
|
-
const key = toKey(value);
|
|
120
|
-
if (!lookup.has(key)) {
|
|
121
|
-
lookup.set(key, row);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return lookup;
|
|
125
|
-
};
|
|
1
|
+
import { TableDef } from '../../schema/table.js';
|
|
2
|
+
import { SelectQueryBuilder } from '../../query-builder/select.js';
|
|
3
|
+
import { ExpressionNode, inList, LiteralNode } from '../../core/ast/expression.js';
|
|
4
|
+
import type { QueryResult } from '../../core/execution/db-executor.js';
|
|
5
|
+
import { ColumnDef } from '../../schema/column-types.js';
|
|
6
|
+
import { EntityContext } from '../entity-context.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* An array of database rows, each represented as a record of string keys to unknown values.
|
|
10
|
+
*/
|
|
11
|
+
export type Rows = Record<string, unknown>[];
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Represents a single tracked entity from the EntityContext for a table.
|
|
15
|
+
*/
|
|
16
|
+
export type EntityTracker = ReturnType<EntityContext['getEntitiesForTable']>[number];
|
|
17
|
+
|
|
18
|
+
export const hasColumns = (columns?: readonly string[]): columns is readonly string[] =>
|
|
19
|
+
Boolean(columns && columns.length > 0);
|
|
20
|
+
|
|
21
|
+
export const buildColumnSelection = (
|
|
22
|
+
table: TableDef,
|
|
23
|
+
columns: string[],
|
|
24
|
+
missingMsg: (col: string) => string
|
|
25
|
+
): Record<string, ColumnDef> => {
|
|
26
|
+
return columns.reduce((acc, column) => {
|
|
27
|
+
const def = table.columns[column];
|
|
28
|
+
if (!def) {
|
|
29
|
+
throw new Error(missingMsg(column));
|
|
30
|
+
}
|
|
31
|
+
acc[column] = def;
|
|
32
|
+
return acc;
|
|
33
|
+
}, {} as Record<string, ColumnDef>);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const filterRow = (row: Record<string, unknown>, columns: Set<string>): Record<string, unknown> => {
|
|
37
|
+
const filtered: Record<string, unknown> = {};
|
|
38
|
+
for (const column of columns) {
|
|
39
|
+
if (column in row) {
|
|
40
|
+
filtered[column] = row[column];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return filtered;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const filterRows = (rows: Rows, columns: Set<string>): Rows => rows.map(row => filterRow(row, columns));
|
|
47
|
+
|
|
48
|
+
const rowsFromResults = (results: QueryResult[]): Rows => {
|
|
49
|
+
const rows: Rows = [];
|
|
50
|
+
for (const result of results) {
|
|
51
|
+
const { columns, values } = result;
|
|
52
|
+
for (const valueRow of values) {
|
|
53
|
+
const row: Record<string, unknown> = {};
|
|
54
|
+
columns.forEach((column, idx) => {
|
|
55
|
+
row[column] = valueRow[idx];
|
|
56
|
+
});
|
|
57
|
+
rows.push(row);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return rows;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const executeQuery = async (ctx: EntityContext, qb: SelectQueryBuilder<unknown, TableDef>): Promise<Rows> => {
|
|
64
|
+
const compiled = ctx.dialect.compileSelect(qb.getAST());
|
|
65
|
+
const results = await ctx.executor.executeSql(compiled.sql, compiled.params);
|
|
66
|
+
return rowsFromResults(results);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const toKey = (value: unknown): string => (value === null || value === undefined ? '' : String(value));
|
|
70
|
+
|
|
71
|
+
export const collectKeysFromRoots = (roots: EntityTracker[], key: string): Set<unknown> => {
|
|
72
|
+
const collected = new Set<unknown>();
|
|
73
|
+
for (const tracked of roots) {
|
|
74
|
+
const value = (tracked.entity as Record<string, unknown>)[key];
|
|
75
|
+
if (value !== null && value !== undefined) {
|
|
76
|
+
collected.add(value);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return collected;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const buildInListValues = (keys: Set<unknown>): (string | number | LiteralNode)[] =>
|
|
83
|
+
Array.from(keys) as (string | number | LiteralNode)[];
|
|
84
|
+
|
|
85
|
+
export const fetchRowsForKeys = async (
|
|
86
|
+
ctx: EntityContext,
|
|
87
|
+
table: TableDef,
|
|
88
|
+
column: ColumnDef,
|
|
89
|
+
keys: Set<unknown>,
|
|
90
|
+
selection: Record<string, ColumnDef>,
|
|
91
|
+
filter?: ExpressionNode
|
|
92
|
+
): Promise<Rows> => {
|
|
93
|
+
let qb = new SelectQueryBuilder(table).select(selection);
|
|
94
|
+
qb = qb.where(inList(column, buildInListValues(keys)));
|
|
95
|
+
if (filter) {
|
|
96
|
+
qb = qb.where(filter);
|
|
97
|
+
}
|
|
98
|
+
return executeQuery(ctx, qb);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const groupRowsByMany = (rows: Rows, keyColumn: string): Map<string, Rows> => {
|
|
102
|
+
const grouped = new Map<string, Rows>();
|
|
103
|
+
for (const row of rows) {
|
|
104
|
+
const value = row[keyColumn];
|
|
105
|
+
if (value === null || value === undefined) continue;
|
|
106
|
+
const key = toKey(value);
|
|
107
|
+
const bucket = grouped.get(key) ?? [];
|
|
108
|
+
bucket.push(row);
|
|
109
|
+
grouped.set(key, bucket);
|
|
110
|
+
}
|
|
111
|
+
return grouped;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export const groupRowsByUnique = (rows: Rows, keyColumn: string): Map<string, Record<string, unknown>> => {
|
|
115
|
+
const lookup = new Map<string, Record<string, unknown>>();
|
|
116
|
+
for (const row of rows) {
|
|
117
|
+
const value = row[keyColumn];
|
|
118
|
+
if (value === null || value === undefined) continue;
|
|
119
|
+
const key = toKey(value);
|
|
120
|
+
if (!lookup.has(key)) {
|
|
121
|
+
lookup.set(key, row);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return lookup;
|
|
125
|
+
};
|