metal-orm 1.0.43 → 1.0.45
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 +700 -557
- package/dist/index.cjs +896 -476
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1146 -275
- package/dist/index.d.ts +1146 -275
- package/dist/index.js +896 -474
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/ast/adapters.ts +8 -2
- package/src/core/ast/builders.ts +105 -81
- package/src/core/ast/expression-builders.ts +430 -390
- package/src/core/ast/expression-visitor.ts +47 -8
- package/src/core/ast/helpers.ts +23 -0
- package/src/core/ast/join-node.ts +17 -1
- package/src/core/ddl/dialects/base-schema-dialect.ts +7 -1
- package/src/core/ddl/dialects/index.ts +1 -0
- package/src/core/ddl/dialects/mssql-schema-dialect.ts +1 -0
- package/src/core/ddl/dialects/mysql-schema-dialect.ts +1 -0
- package/src/core/ddl/dialects/postgres-schema-dialect.ts +1 -0
- package/src/core/ddl/dialects/sqlite-schema-dialect.ts +1 -0
- package/src/core/ddl/introspect/catalogs/index.ts +1 -0
- package/src/core/ddl/introspect/catalogs/postgres.ts +2 -0
- package/src/core/ddl/introspect/context.ts +6 -0
- package/src/core/ddl/introspect/functions/postgres.ts +13 -0
- package/src/core/ddl/introspect/mssql.ts +11 -0
- package/src/core/ddl/introspect/mysql.ts +2 -0
- package/src/core/ddl/introspect/postgres.ts +14 -0
- package/src/core/ddl/introspect/registry.ts +14 -0
- package/src/core/ddl/introspect/run-select.ts +13 -0
- package/src/core/ddl/introspect/sqlite.ts +22 -0
- package/src/core/ddl/introspect/utils.ts +18 -0
- package/src/core/ddl/naming-strategy.ts +6 -0
- package/src/core/ddl/schema-dialect.ts +19 -6
- package/src/core/ddl/schema-diff.ts +22 -0
- package/src/core/ddl/schema-generator.ts +22 -0
- package/src/core/ddl/schema-plan-executor.ts +6 -0
- package/src/core/ddl/schema-types.ts +6 -0
- package/src/core/dialect/abstract.ts +2 -2
- package/src/core/execution/pooling/pool.ts +12 -7
- package/src/core/functions/datetime.ts +57 -33
- package/src/core/functions/numeric.ts +95 -30
- package/src/core/functions/standard-strategy.ts +35 -0
- package/src/core/functions/text.ts +83 -22
- package/src/core/functions/types.ts +23 -8
- package/src/decorators/bootstrap.ts +16 -4
- package/src/decorators/column.ts +17 -0
- package/src/decorators/decorator-metadata.ts +27 -0
- package/src/decorators/entity.ts +8 -0
- package/src/decorators/index.ts +3 -0
- package/src/decorators/relations.ts +32 -0
- package/src/orm/als.ts +34 -9
- package/src/orm/entity-context.ts +54 -0
- package/src/orm/entity-metadata.ts +122 -9
- package/src/orm/execute.ts +15 -0
- package/src/orm/lazy-batch.ts +158 -98
- package/src/orm/relations/has-many.ts +44 -0
- package/src/orm/save-graph.ts +45 -0
- package/src/query/index.ts +74 -0
- package/src/query/target.ts +46 -0
- package/src/query-builder/delete-query-state.ts +30 -0
- package/src/query-builder/delete.ts +64 -19
- package/src/query-builder/hydration-manager.ts +46 -0
- package/src/query-builder/insert-query-state.ts +30 -0
- package/src/query-builder/insert.ts +46 -2
- package/src/query-builder/query-ast-service.ts +5 -0
- package/src/query-builder/query-resolution.ts +78 -0
- package/src/query-builder/raw-column-parser.ts +5 -0
- package/src/query-builder/relation-alias.ts +7 -0
- package/src/query-builder/relation-conditions.ts +61 -48
- package/src/query-builder/relation-service.ts +68 -63
- package/src/query-builder/relation-utils.ts +3 -0
- package/src/query-builder/select/cte-facet.ts +40 -0
- package/src/query-builder/select/from-facet.ts +80 -0
- package/src/query-builder/select/join-facet.ts +62 -0
- package/src/query-builder/select/predicate-facet.ts +103 -0
- package/src/query-builder/select/projection-facet.ts +69 -0
- package/src/query-builder/select/relation-facet.ts +81 -0
- package/src/query-builder/select/setop-facet.ts +36 -0
- package/src/query-builder/select-helpers.ts +13 -0
- package/src/query-builder/select-query-builder-deps.ts +19 -1
- package/src/query-builder/select-query-state.ts +2 -1
- package/src/query-builder/select.ts +795 -1163
- package/src/query-builder/update-query-state.ts +52 -0
- package/src/query-builder/update.ts +69 -19
- package/src/schema/table-guards.ts +31 -0
|
@@ -4,21 +4,75 @@ import { TableDef } from '../schema/table.js';
|
|
|
4
4
|
import { RelationDef } from '../schema/relation.js';
|
|
5
5
|
import { RelationChange, RelationKey, TrackedEntity } from './runtime-types.js';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Interface for entity context providing entity tracking and management.
|
|
9
|
+
*/
|
|
7
10
|
export interface EntityContext {
|
|
11
|
+
/** The database dialect */
|
|
8
12
|
dialect: Dialect;
|
|
13
|
+
/** The database executor */
|
|
9
14
|
executor: DbExecutor;
|
|
10
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Gets an entity by table and primary key.
|
|
18
|
+
* @param table - The table definition
|
|
19
|
+
* @param pk - The primary key value
|
|
20
|
+
* @returns The entity or undefined
|
|
21
|
+
*/
|
|
11
22
|
getEntity(table: TableDef, pk: unknown): unknown;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Sets an entity in the context.
|
|
26
|
+
* @param table - The table definition
|
|
27
|
+
* @param pk - The primary key value
|
|
28
|
+
* @param entity - The entity to set
|
|
29
|
+
*/
|
|
12
30
|
setEntity(table: TableDef, pk: unknown, entity: unknown): void;
|
|
13
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Tracks a new entity.
|
|
34
|
+
* @param table - The table definition
|
|
35
|
+
* @param entity - The new entity
|
|
36
|
+
* @param pk - Optional primary key
|
|
37
|
+
*/
|
|
14
38
|
trackNew(table: TableDef, entity: unknown, pk?: unknown): void;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Tracks a managed entity.
|
|
42
|
+
* @param table - The table definition
|
|
43
|
+
* @param pk - The primary key
|
|
44
|
+
* @param entity - The managed entity
|
|
45
|
+
*/
|
|
15
46
|
trackManaged(table: TableDef, pk: unknown, entity: unknown): void;
|
|
16
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Marks an entity as dirty.
|
|
50
|
+
* @param entity - The entity to mark
|
|
51
|
+
*/
|
|
17
52
|
markDirty(entity: unknown): void;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Marks an entity as removed.
|
|
56
|
+
* @param entity - The entity to mark
|
|
57
|
+
*/
|
|
18
58
|
markRemoved(entity: unknown): void;
|
|
19
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Gets all tracked entities for a table.
|
|
62
|
+
* @param table - The table definition
|
|
63
|
+
* @returns Array of tracked entities
|
|
64
|
+
*/
|
|
20
65
|
getEntitiesForTable(table: TableDef): TrackedEntity[];
|
|
21
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Registers a relation change.
|
|
69
|
+
* @param root - The root entity
|
|
70
|
+
* @param relationKey - The relation key
|
|
71
|
+
* @param rootTable - The root table definition
|
|
72
|
+
* @param relationName - The relation name
|
|
73
|
+
* @param relation - The relation definition
|
|
74
|
+
* @param change - The relation change
|
|
75
|
+
*/
|
|
22
76
|
registerRelationChange(
|
|
23
77
|
root: unknown,
|
|
24
78
|
relationKey: RelationKey,
|
|
@@ -2,13 +2,33 @@ import { ColumnDef } from '../schema/column.js';
|
|
|
2
2
|
import { defineTable, TableDef, TableHooks } from '../schema/table.js';
|
|
3
3
|
import { CascadeMode, RelationKinds } from '../schema/relation.js';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Constructor type for entities.
|
|
7
|
+
* Supports any constructor signature for maximum flexibility with decorator-based entities.
|
|
8
|
+
* @template T - The entity type
|
|
9
|
+
*/
|
|
10
|
+
export type EntityConstructor<T = object> = new (...args: never[]) => T;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Target that can be an entity constructor or table definition.
|
|
14
|
+
*/
|
|
7
15
|
export type EntityOrTableTarget = EntityConstructor | TableDef;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Resolver for entity or table target, can be direct or function.
|
|
19
|
+
*/
|
|
8
20
|
export type EntityOrTableTargetResolver = EntityOrTableTarget | (() => EntityOrTableTarget);
|
|
9
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Simplified column definition structure used during metadata registration.
|
|
24
|
+
* @template T - Concrete column definition type being extended
|
|
25
|
+
*/
|
|
10
26
|
export type ColumnDefLike<T extends ColumnDef = ColumnDef> = Omit<T, 'name' | 'table'>;
|
|
11
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Transforms simplified column metadata into full ColumnDef objects during table building.
|
|
30
|
+
* @template TColumns - Mapping of column names to simplified definitions
|
|
31
|
+
*/
|
|
12
32
|
type MaterializeColumns<TColumns extends Record<string, ColumnDefLike>> = {
|
|
13
33
|
[K in keyof TColumns]: ColumnDef<TColumns[K]['type'], TColumns[K]['tsType']> & Omit<
|
|
14
34
|
TColumns[K],
|
|
@@ -16,62 +36,119 @@ type MaterializeColumns<TColumns extends Record<string, ColumnDefLike>> = {
|
|
|
16
36
|
> & { name: string; table: string };
|
|
17
37
|
};
|
|
18
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Common properties shared by all relation metadata types.
|
|
41
|
+
*/
|
|
19
42
|
interface BaseRelationMetadata {
|
|
43
|
+
/** The property key for the relation */
|
|
20
44
|
propertyKey: string;
|
|
45
|
+
/** The target entity or table */
|
|
21
46
|
target: EntityOrTableTargetResolver;
|
|
47
|
+
/** Optional cascade mode */
|
|
22
48
|
cascade?: CascadeMode;
|
|
23
49
|
}
|
|
24
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Metadata for has many relations.
|
|
53
|
+
*/
|
|
25
54
|
export interface HasManyRelationMetadata extends BaseRelationMetadata {
|
|
55
|
+
/** The relation kind */
|
|
26
56
|
kind: typeof RelationKinds.HasMany;
|
|
57
|
+
/** The foreign key */
|
|
27
58
|
foreignKey: string;
|
|
59
|
+
/** Optional local key */
|
|
28
60
|
localKey?: string;
|
|
29
61
|
}
|
|
30
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Metadata for has one relations.
|
|
65
|
+
*/
|
|
31
66
|
export interface HasOneRelationMetadata extends BaseRelationMetadata {
|
|
67
|
+
/** The relation kind */
|
|
32
68
|
kind: typeof RelationKinds.HasOne;
|
|
69
|
+
/** The foreign key */
|
|
33
70
|
foreignKey: string;
|
|
71
|
+
/** Optional local key */
|
|
34
72
|
localKey?: string;
|
|
35
73
|
}
|
|
36
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Metadata for belongs to relations.
|
|
77
|
+
*/
|
|
37
78
|
export interface BelongsToRelationMetadata extends BaseRelationMetadata {
|
|
79
|
+
/** The relation kind */
|
|
38
80
|
kind: typeof RelationKinds.BelongsTo;
|
|
81
|
+
/** The foreign key */
|
|
39
82
|
foreignKey: string;
|
|
83
|
+
/** Optional local key */
|
|
40
84
|
localKey?: string;
|
|
41
85
|
}
|
|
42
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Metadata for belongs to many relations.
|
|
89
|
+
*/
|
|
43
90
|
export interface BelongsToManyRelationMetadata extends BaseRelationMetadata {
|
|
91
|
+
/** The relation kind */
|
|
44
92
|
kind: typeof RelationKinds.BelongsToMany;
|
|
93
|
+
/** The pivot table */
|
|
45
94
|
pivotTable: EntityOrTableTargetResolver;
|
|
95
|
+
/** The pivot foreign key to root */
|
|
46
96
|
pivotForeignKeyToRoot: string;
|
|
97
|
+
/** The pivot foreign key to target */
|
|
47
98
|
pivotForeignKeyToTarget: string;
|
|
99
|
+
/** Optional local key */
|
|
48
100
|
localKey?: string;
|
|
101
|
+
/** Optional target key */
|
|
49
102
|
targetKey?: string;
|
|
103
|
+
/** Optional pivot primary key */
|
|
50
104
|
pivotPrimaryKey?: string;
|
|
105
|
+
/** Optional default pivot columns */
|
|
51
106
|
defaultPivotColumns?: string[];
|
|
52
107
|
}
|
|
53
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Union type for all relation metadata.
|
|
111
|
+
*/
|
|
54
112
|
export type RelationMetadata =
|
|
55
113
|
| HasManyRelationMetadata
|
|
56
114
|
| HasOneRelationMetadata
|
|
57
115
|
| BelongsToRelationMetadata
|
|
58
116
|
| BelongsToManyRelationMetadata;
|
|
59
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Metadata for entities.
|
|
120
|
+
* @template TColumns - The columns type
|
|
121
|
+
*/
|
|
60
122
|
export interface EntityMetadata<TColumns extends Record<string, ColumnDefLike> = Record<string, ColumnDefLike>> {
|
|
123
|
+
/** The entity constructor */
|
|
61
124
|
target: EntityConstructor;
|
|
125
|
+
/** The table name */
|
|
62
126
|
tableName: string;
|
|
127
|
+
/** The columns */
|
|
63
128
|
columns: TColumns;
|
|
129
|
+
/** The relations */
|
|
64
130
|
relations: Record<string, RelationMetadata>;
|
|
131
|
+
/** Optional hooks */
|
|
65
132
|
hooks?: TableHooks;
|
|
133
|
+
/** Optional table definition */
|
|
66
134
|
table?: TableDef<MaterializeColumns<TColumns>>;
|
|
67
135
|
}
|
|
68
136
|
|
|
69
137
|
const metadataMap = new Map<EntityConstructor, EntityMetadata>();
|
|
70
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Registers entity metadata.
|
|
141
|
+
* @param meta - The entity metadata to register
|
|
142
|
+
*/
|
|
71
143
|
export const registerEntityMetadata = (meta: EntityMetadata): void => {
|
|
72
144
|
metadataMap.set(meta.target, meta);
|
|
73
145
|
};
|
|
74
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Ensures entity metadata exists for the target, creating it if necessary.
|
|
149
|
+
* @param target - The entity constructor
|
|
150
|
+
* @returns The entity metadata
|
|
151
|
+
*/
|
|
75
152
|
export const ensureEntityMetadata = (target: EntityConstructor): EntityMetadata => {
|
|
76
153
|
let meta = metadataMap.get(target);
|
|
77
154
|
if (!meta) {
|
|
@@ -86,18 +163,36 @@ export const ensureEntityMetadata = (target: EntityConstructor): EntityMetadata
|
|
|
86
163
|
return meta;
|
|
87
164
|
};
|
|
88
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Gets entity metadata for the target.
|
|
168
|
+
* @param target - The entity constructor
|
|
169
|
+
* @returns The entity metadata or undefined if not found
|
|
170
|
+
*/
|
|
89
171
|
export const getEntityMetadata = (target: EntityConstructor): EntityMetadata | undefined => {
|
|
90
172
|
return metadataMap.get(target);
|
|
91
173
|
};
|
|
92
174
|
|
|
175
|
+
/**
|
|
176
|
+
* Gets all entity metadata.
|
|
177
|
+
* @returns Array of all entity metadata
|
|
178
|
+
*/
|
|
93
179
|
export const getAllEntityMetadata = (): EntityMetadata[] => {
|
|
94
180
|
return Array.from(metadataMap.values());
|
|
95
181
|
};
|
|
96
182
|
|
|
183
|
+
/**
|
|
184
|
+
* Clears all entity metadata.
|
|
185
|
+
*/
|
|
97
186
|
export const clearEntityMetadata = (): void => {
|
|
98
187
|
metadataMap.clear();
|
|
99
188
|
};
|
|
100
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Adds column metadata to an entity.
|
|
192
|
+
* @param target - The entity constructor
|
|
193
|
+
* @param propertyKey - The property key
|
|
194
|
+
* @param column - The column definition
|
|
195
|
+
*/
|
|
101
196
|
export const addColumnMetadata = (
|
|
102
197
|
target: EntityConstructor,
|
|
103
198
|
propertyKey: string,
|
|
@@ -107,6 +202,12 @@ export const addColumnMetadata = (
|
|
|
107
202
|
(meta.columns as Record<string, ColumnDefLike>)[propertyKey] = { ...column };
|
|
108
203
|
};
|
|
109
204
|
|
|
205
|
+
/**
|
|
206
|
+
* Adds relation metadata to an entity.
|
|
207
|
+
* @param target - The entity constructor
|
|
208
|
+
* @param propertyKey - The property key
|
|
209
|
+
* @param relation - The relation metadata
|
|
210
|
+
*/
|
|
110
211
|
export const addRelationMetadata = (
|
|
111
212
|
target: EntityConstructor,
|
|
112
213
|
propertyKey: string,
|
|
@@ -116,6 +217,12 @@ export const addRelationMetadata = (
|
|
|
116
217
|
meta.relations[propertyKey] = relation;
|
|
117
218
|
};
|
|
118
219
|
|
|
220
|
+
/**
|
|
221
|
+
* Sets the table name and hooks for an entity.
|
|
222
|
+
* @param target - The entity constructor
|
|
223
|
+
* @param tableName - The table name
|
|
224
|
+
* @param hooks - Optional table hooks
|
|
225
|
+
*/
|
|
119
226
|
export const setEntityTableName = (
|
|
120
227
|
target: EntityConstructor,
|
|
121
228
|
tableName: string,
|
|
@@ -130,22 +237,28 @@ export const setEntityTableName = (
|
|
|
130
237
|
}
|
|
131
238
|
};
|
|
132
239
|
|
|
240
|
+
/**
|
|
241
|
+
* Builds a table definition from entity metadata.
|
|
242
|
+
* @template TColumns - The columns type
|
|
243
|
+
* @param meta - The entity metadata
|
|
244
|
+
* @returns The table definition
|
|
245
|
+
*/
|
|
133
246
|
export const buildTableDef = <TColumns extends Record<string, ColumnDefLike>>(meta: EntityMetadata<TColumns>): TableDef<MaterializeColumns<TColumns>> => {
|
|
134
247
|
if (meta.table) {
|
|
135
248
|
return meta.table;
|
|
136
249
|
}
|
|
137
250
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
251
|
+
// Build columns using a simpler approach that avoids type assertion
|
|
252
|
+
const columns: Record<string, ColumnDef> = {};
|
|
253
|
+
for (const [key, def] of Object.entries(meta.columns)) {
|
|
254
|
+
columns[key] = {
|
|
141
255
|
...def,
|
|
142
256
|
name: key,
|
|
143
257
|
table: meta.tableName
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
}, {} as MaterializeColumns<TColumns>);
|
|
258
|
+
} as ColumnDef;
|
|
259
|
+
}
|
|
147
260
|
|
|
148
|
-
const table = defineTable(meta.tableName, columns
|
|
261
|
+
const table = defineTable(meta.tableName, columns as MaterializeColumns<TColumns>, {}, meta.hooks);
|
|
149
262
|
meta.table = table;
|
|
150
263
|
return table;
|
|
151
264
|
};
|
package/src/orm/execute.ts
CHANGED
|
@@ -42,6 +42,13 @@ const executeWithEntityContext = async <TTable extends TableDef>(
|
|
|
42
42
|
return hydrated.map(row => createEntityFromRow(entityCtx, qb.getTable(), row, qb.getLazyRelations()));
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Executes a hydrated query using the ORM session.
|
|
47
|
+
* @template TTable - The table type
|
|
48
|
+
* @param session - The ORM session
|
|
49
|
+
* @param qb - The select query builder
|
|
50
|
+
* @returns Promise resolving to array of entity instances
|
|
51
|
+
*/
|
|
45
52
|
export async function executeHydrated<TTable extends TableDef>(
|
|
46
53
|
session: OrmSession,
|
|
47
54
|
qb: SelectQueryBuilder<unknown, TTable>
|
|
@@ -49,6 +56,14 @@ export async function executeHydrated<TTable extends TableDef>(
|
|
|
49
56
|
return executeWithEntityContext(session, qb);
|
|
50
57
|
}
|
|
51
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Executes a hydrated query using execution and hydration contexts.
|
|
61
|
+
* @template TTable - The table type
|
|
62
|
+
* @param _execCtx - The execution context (unused)
|
|
63
|
+
* @param hydCtx - The hydration context
|
|
64
|
+
* @param qb - The select query builder
|
|
65
|
+
* @returns Promise resolving to array of entity instances
|
|
66
|
+
*/
|
|
52
67
|
export async function executeHydratedWithContexts<TTable extends TableDef>(
|
|
53
68
|
_execCtx: ExecutionContext,
|
|
54
69
|
hydCtx: HydrationContext,
|