metal-orm 1.0.40 → 1.0.42
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 +53 -14
- package/dist/index.cjs +1298 -126
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +676 -30
- package/dist/index.d.ts +676 -30
- package/dist/index.js +1293 -126
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/codegen/typescript.ts +6 -2
- package/src/core/ast/expression-builders.ts +25 -4
- package/src/core/ast/expression-nodes.ts +3 -1
- package/src/core/ast/expression.ts +2 -2
- package/src/core/ast/query.ts +24 -2
- package/src/core/dialect/abstract.ts +6 -2
- package/src/core/dialect/base/join-compiler.ts +9 -12
- package/src/core/dialect/base/sql-dialect.ts +98 -17
- package/src/core/dialect/mssql/index.ts +30 -62
- package/src/core/dialect/sqlite/index.ts +39 -34
- package/src/core/execution/db-executor.ts +46 -6
- package/src/core/execution/executors/mssql-executor.ts +39 -22
- package/src/core/execution/executors/mysql-executor.ts +23 -6
- package/src/core/execution/executors/sqlite-executor.ts +29 -3
- package/src/core/execution/pooling/pool-types.ts +30 -0
- package/src/core/execution/pooling/pool.ts +268 -0
- package/src/decorators/bootstrap.ts +7 -7
- package/src/index.ts +6 -0
- package/src/orm/domain-event-bus.ts +49 -0
- package/src/orm/entity-metadata.ts +9 -9
- package/src/orm/entity.ts +58 -0
- package/src/orm/orm-session.ts +465 -270
- package/src/orm/orm.ts +61 -11
- package/src/orm/pooled-executor-factory.ts +131 -0
- package/src/orm/query-logger.ts +6 -12
- package/src/orm/relation-change-processor.ts +75 -0
- package/src/orm/relations/many-to-many.ts +4 -2
- package/src/orm/save-graph.ts +303 -0
- package/src/orm/transaction-runner.ts +3 -3
- package/src/orm/unit-of-work.ts +128 -0
- package/src/query-builder/delete-query-state.ts +67 -38
- package/src/query-builder/delete.ts +37 -1
- package/src/query-builder/insert-query-state.ts +131 -61
- package/src/query-builder/insert.ts +27 -1
- package/src/query-builder/update-query-state.ts +114 -77
- package/src/query-builder/update.ts +38 -1
- package/src/schema/table.ts +210 -115
|
@@ -1,18 +1,44 @@
|
|
|
1
1
|
import type { DomainEvent, HasDomainEvents, TrackedEntity } from './runtime-types.js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Extracts domain events of a specific type.
|
|
5
|
+
* @template E - The domain event type
|
|
6
|
+
* @template TType - The specific event type
|
|
7
|
+
*/
|
|
3
8
|
type EventOfType<E extends DomainEvent, TType extends E['type']> =
|
|
4
9
|
Extract<E, { type: TType }>;
|
|
5
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Domain event handler function.
|
|
13
|
+
* @template E - The domain event type
|
|
14
|
+
* @template Context - The context type
|
|
15
|
+
* @param event - The domain event
|
|
16
|
+
* @param ctx - The context
|
|
17
|
+
*/
|
|
6
18
|
export type DomainEventHandler<E extends DomainEvent, Context> =
|
|
7
19
|
(event: E, ctx: Context) => Promise<void> | void;
|
|
8
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Initial handlers for domain events.
|
|
23
|
+
* @template E - The domain event type
|
|
24
|
+
* @template Context - The context type
|
|
25
|
+
*/
|
|
9
26
|
export type InitialHandlers<E extends DomainEvent, Context> = {
|
|
10
27
|
[K in E['type']]?: DomainEventHandler<EventOfType<E, K>, Context>[];
|
|
11
28
|
};
|
|
12
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Domain event bus for managing and dispatching domain events.
|
|
32
|
+
* @template E - The domain event type
|
|
33
|
+
* @template Context - The context type
|
|
34
|
+
*/
|
|
13
35
|
export class DomainEventBus<E extends DomainEvent, Context> {
|
|
14
36
|
private readonly handlers = new Map<E['type'], DomainEventHandler<E, Context>[]>();
|
|
15
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Creates a new DomainEventBus instance.
|
|
40
|
+
* @param initialHandlers - Optional initial event handlers
|
|
41
|
+
*/
|
|
16
42
|
constructor(initialHandlers?: InitialHandlers<E, Context>) {
|
|
17
43
|
if (initialHandlers) {
|
|
18
44
|
for (const key in initialHandlers) {
|
|
@@ -23,6 +49,12 @@ export class DomainEventBus<E extends DomainEvent, Context> {
|
|
|
23
49
|
}
|
|
24
50
|
}
|
|
25
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Registers an event handler for a specific event type.
|
|
54
|
+
* @template TType - The event type
|
|
55
|
+
* @param type - The event type
|
|
56
|
+
* @param handler - The event handler
|
|
57
|
+
*/
|
|
26
58
|
on<TType extends E['type']>(
|
|
27
59
|
type: TType,
|
|
28
60
|
handler: DomainEventHandler<EventOfType<E, TType>, Context>
|
|
@@ -33,6 +65,12 @@ export class DomainEventBus<E extends DomainEvent, Context> {
|
|
|
33
65
|
this.handlers.set(key, existing);
|
|
34
66
|
}
|
|
35
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Registers an event handler for a specific event type (alias for on).
|
|
70
|
+
* @template TType - The event type
|
|
71
|
+
* @param type - The event type
|
|
72
|
+
* @param handler - The event handler
|
|
73
|
+
*/
|
|
36
74
|
register<TType extends E['type']>(
|
|
37
75
|
type: TType,
|
|
38
76
|
handler: DomainEventHandler<EventOfType<E, TType>, Context>
|
|
@@ -40,6 +78,11 @@ export class DomainEventBus<E extends DomainEvent, Context> {
|
|
|
40
78
|
this.on(type, handler);
|
|
41
79
|
}
|
|
42
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Dispatches domain events for tracked entities.
|
|
83
|
+
* @param trackedEntities - Iterable of tracked entities
|
|
84
|
+
* @param ctx - The context to pass to handlers
|
|
85
|
+
*/
|
|
43
86
|
async dispatch(trackedEntities: Iterable<TrackedEntity>, ctx: Context): Promise<void> {
|
|
44
87
|
for (const tracked of trackedEntities) {
|
|
45
88
|
const entity = tracked.entity as HasDomainEvents<E>;
|
|
@@ -59,6 +102,12 @@ export class DomainEventBus<E extends DomainEvent, Context> {
|
|
|
59
102
|
}
|
|
60
103
|
}
|
|
61
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Adds a domain event to an entity.
|
|
107
|
+
* @template E - The domain event type
|
|
108
|
+
* @param entity - The entity to add the event to
|
|
109
|
+
* @param event - The domain event to add
|
|
110
|
+
*/
|
|
62
111
|
export const addDomainEvent = <E extends DomainEvent>(
|
|
63
112
|
entity: HasDomainEvents<E>,
|
|
64
113
|
event: E
|
|
@@ -2,8 +2,8 @@ import { ColumnType, 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
|
-
export type EntityConstructor = new (...args: any[]) =>
|
|
6
|
-
export type EntityOrTableTarget = EntityConstructor | TableDef;
|
|
5
|
+
export type EntityConstructor<T = object> = new (...args: any[]) => T;
|
|
6
|
+
export type EntityOrTableTarget = EntityConstructor<any> | TableDef;
|
|
7
7
|
export type EntityOrTableTargetResolver = EntityOrTableTarget | (() => EntityOrTableTarget);
|
|
8
8
|
|
|
9
9
|
export type ColumnDefLike<T extends ColumnDef = ColumnDef> = Omit<T, 'name' | 'table'>;
|
|
@@ -57,7 +57,7 @@ export type RelationMetadata =
|
|
|
57
57
|
| BelongsToManyRelationMetadata;
|
|
58
58
|
|
|
59
59
|
export interface EntityMetadata<TColumns extends Record<string, ColumnDefLike> = Record<string, ColumnDefLike>> {
|
|
60
|
-
target: EntityConstructor
|
|
60
|
+
target: EntityConstructor<any>;
|
|
61
61
|
tableName: string;
|
|
62
62
|
columns: TColumns;
|
|
63
63
|
relations: Record<string, RelationMetadata>;
|
|
@@ -65,13 +65,13 @@ export interface EntityMetadata<TColumns extends Record<string, ColumnDefLike> =
|
|
|
65
65
|
table?: TableDef<MaterializeColumns<TColumns>>;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
const metadataMap = new Map<EntityConstructor
|
|
68
|
+
const metadataMap = new Map<EntityConstructor<any>, EntityMetadata>();
|
|
69
69
|
|
|
70
70
|
export const registerEntityMetadata = (meta: EntityMetadata): void => {
|
|
71
71
|
metadataMap.set(meta.target, meta);
|
|
72
72
|
};
|
|
73
73
|
|
|
74
|
-
export const ensureEntityMetadata = (target: EntityConstructor): EntityMetadata => {
|
|
74
|
+
export const ensureEntityMetadata = (target: EntityConstructor<any>): EntityMetadata => {
|
|
75
75
|
let meta = metadataMap.get(target);
|
|
76
76
|
if (!meta) {
|
|
77
77
|
meta = {
|
|
@@ -85,7 +85,7 @@ export const ensureEntityMetadata = (target: EntityConstructor): EntityMetadata
|
|
|
85
85
|
return meta;
|
|
86
86
|
};
|
|
87
87
|
|
|
88
|
-
export const getEntityMetadata = (target: EntityConstructor): EntityMetadata | undefined => {
|
|
88
|
+
export const getEntityMetadata = (target: EntityConstructor<any>): EntityMetadata | undefined => {
|
|
89
89
|
return metadataMap.get(target);
|
|
90
90
|
};
|
|
91
91
|
|
|
@@ -98,7 +98,7 @@ export const clearEntityMetadata = (): void => {
|
|
|
98
98
|
};
|
|
99
99
|
|
|
100
100
|
export const addColumnMetadata = (
|
|
101
|
-
target: EntityConstructor
|
|
101
|
+
target: EntityConstructor<any>,
|
|
102
102
|
propertyKey: string,
|
|
103
103
|
column: ColumnDefLike
|
|
104
104
|
): void => {
|
|
@@ -107,7 +107,7 @@ export const addColumnMetadata = (
|
|
|
107
107
|
};
|
|
108
108
|
|
|
109
109
|
export const addRelationMetadata = (
|
|
110
|
-
target: EntityConstructor
|
|
110
|
+
target: EntityConstructor<any>,
|
|
111
111
|
propertyKey: string,
|
|
112
112
|
relation: RelationMetadata
|
|
113
113
|
): void => {
|
|
@@ -116,7 +116,7 @@ export const addRelationMetadata = (
|
|
|
116
116
|
};
|
|
117
117
|
|
|
118
118
|
export const setEntityTableName = (
|
|
119
|
-
target: EntityConstructor
|
|
119
|
+
target: EntityConstructor<any>,
|
|
120
120
|
tableName: string,
|
|
121
121
|
hooks?: TableHooks
|
|
122
122
|
): void => {
|
package/src/orm/entity.ts
CHANGED
|
@@ -10,8 +10,19 @@ import { HasManyRelation, HasOneRelation, BelongsToRelation, BelongsToManyRelati
|
|
|
10
10
|
import { loadHasManyRelation, loadHasOneRelation, loadBelongsToRelation, loadBelongsToManyRelation } from './lazy-batch.js';
|
|
11
11
|
import { findPrimaryKey } from '../query-builder/hydration-planner.js';
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Type representing an array of database rows.
|
|
15
|
+
*/
|
|
13
16
|
type Rows = Record<string, any>[];
|
|
14
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Caches relation loader results across entities of the same type.
|
|
20
|
+
* @template T - The cache type
|
|
21
|
+
* @param meta - The entity metadata
|
|
22
|
+
* @param relationName - The relation name
|
|
23
|
+
* @param factory - The factory function to create the cache
|
|
24
|
+
* @returns Promise with the cached relation data
|
|
25
|
+
*/
|
|
15
26
|
const relationLoaderCache = <T extends Map<string, any>>(
|
|
16
27
|
meta: EntityMeta<any>,
|
|
17
28
|
relationName: string,
|
|
@@ -41,6 +52,16 @@ const relationLoaderCache = <T extends Map<string, any>>(
|
|
|
41
52
|
return promise;
|
|
42
53
|
};
|
|
43
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Creates an entity proxy with lazy loading capabilities.
|
|
57
|
+
* @template TTable - The table type
|
|
58
|
+
* @template TLazy - The lazy relation keys
|
|
59
|
+
* @param ctx - The entity context
|
|
60
|
+
* @param table - The table definition
|
|
61
|
+
* @param row - The database row
|
|
62
|
+
* @param lazyRelations - Optional lazy relations
|
|
63
|
+
* @returns The entity instance
|
|
64
|
+
*/
|
|
44
65
|
export const createEntityProxy = <
|
|
45
66
|
TTable extends TableDef,
|
|
46
67
|
TLazy extends keyof RelationMap<TTable> = keyof RelationMap<TTable>
|
|
@@ -104,6 +125,16 @@ export const createEntityProxy = <
|
|
|
104
125
|
return proxy;
|
|
105
126
|
};
|
|
106
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Creates an entity instance from a database row.
|
|
130
|
+
* @template TTable - The table type
|
|
131
|
+
* @template TResult - The result type
|
|
132
|
+
* @param ctx - The entity context
|
|
133
|
+
* @param table - The table definition
|
|
134
|
+
* @param row - The database row
|
|
135
|
+
* @param lazyRelations - Optional lazy relations
|
|
136
|
+
* @returns The entity instance
|
|
137
|
+
*/
|
|
107
138
|
export const createEntityFromRow = <
|
|
108
139
|
TTable extends TableDef,
|
|
109
140
|
TResult extends EntityInstance<TTable> = EntityInstance<TTable>
|
|
@@ -130,8 +161,20 @@ export const createEntityFromRow = <
|
|
|
130
161
|
return entity as TResult;
|
|
131
162
|
};
|
|
132
163
|
|
|
164
|
+
/**
|
|
165
|
+
* Converts a value to a string key.
|
|
166
|
+
* @param value - The value to convert
|
|
167
|
+
* @returns String representation of the value
|
|
168
|
+
*/
|
|
133
169
|
const toKey = (value: unknown): string => (value === null || value === undefined ? '' : String(value));
|
|
134
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Populates the hydration cache with relation data from the database row.
|
|
173
|
+
* @template TTable - The table type
|
|
174
|
+
* @param entity - The entity instance
|
|
175
|
+
* @param row - The database row
|
|
176
|
+
* @param meta - The entity metadata
|
|
177
|
+
*/
|
|
135
178
|
const populateHydrationCache = <TTable extends TableDef>(
|
|
136
179
|
entity: any,
|
|
137
180
|
row: Record<string, any>,
|
|
@@ -181,6 +224,13 @@ const populateHydrationCache = <TTable extends TableDef>(
|
|
|
181
224
|
}
|
|
182
225
|
};
|
|
183
226
|
|
|
227
|
+
/**
|
|
228
|
+
* Gets a relation wrapper for an entity.
|
|
229
|
+
* @param meta - The entity metadata
|
|
230
|
+
* @param relationName - The relation name
|
|
231
|
+
* @param owner - The owner entity
|
|
232
|
+
* @returns The relation wrapper or undefined
|
|
233
|
+
*/
|
|
184
234
|
const getRelationWrapper = (
|
|
185
235
|
meta: EntityMeta<any>,
|
|
186
236
|
relationName: string,
|
|
@@ -201,6 +251,14 @@ const getRelationWrapper = (
|
|
|
201
251
|
return wrapper;
|
|
202
252
|
};
|
|
203
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Instantiates the appropriate relation wrapper based on relation type.
|
|
256
|
+
* @param meta - The entity metadata
|
|
257
|
+
* @param relationName - The relation name
|
|
258
|
+
* @param relation - The relation definition
|
|
259
|
+
* @param owner - The owner entity
|
|
260
|
+
* @returns The relation wrapper or undefined
|
|
261
|
+
*/
|
|
204
262
|
const instantiateWrapper = (
|
|
205
263
|
meta: EntityMeta<any>,
|
|
206
264
|
relationName: string,
|