@mikro-orm/core 7.0.0-dev.43 → 7.0.0-dev.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/EntityManager.d.ts +2 -14
- package/EntityManager.js +24 -5
- package/decorators/Property.d.ts +0 -6
- package/entity/ArrayCollection.d.ts +2 -2
- package/entity/ArrayCollection.js +8 -3
- package/entity/BaseEntity.d.ts +0 -1
- package/entity/BaseEntity.js +0 -3
- package/entity/Collection.d.ts +2 -2
- package/entity/Collection.js +18 -7
- package/entity/EntityFactory.js +0 -2
- package/entity/EntityHelper.js +2 -7
- package/entity/WrappedEntity.d.ts +0 -2
- package/entity/WrappedEntity.js +0 -4
- package/entity/defineEntity.d.ts +0 -6
- package/entity/defineEntity.js +0 -8
- package/metadata/MetadataDiscovery.js +0 -5
- package/package.json +2 -2
- package/serialization/EntitySerializer.js +21 -3
- package/serialization/EntityTransformer.js +15 -5
- package/typings.d.ts +3 -8
- package/typings.js +7 -27
- package/unit-of-work/ChangeSetComputer.js +5 -2
- package/unit-of-work/UnitOfWork.js +3 -14
- package/utils/Configuration.d.ts +4 -4
- package/utils/Configuration.js +4 -9
- package/utils/ConfigurationLoader.d.ts +7 -1
- package/utils/ConfigurationLoader.js +35 -10
- package/utils/RawQueryFragment.d.ts +0 -2
- package/utils/RawQueryFragment.js +0 -13
- package/utils/TransactionManager.js +8 -3
- package/utils/Utils.d.ts +2 -2
- package/utils/Utils.js +8 -4
package/EntityManager.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { EntityLoader, type EntityLoaderOptions } from './entity/EntityLoader.js
|
|
|
10
10
|
import { Reference } from './entity/Reference.js';
|
|
11
11
|
import { UnitOfWork } from './unit-of-work/UnitOfWork.js';
|
|
12
12
|
import type { CountOptions, DeleteOptions, FilterOptions, FindAllOptions, FindByCursorOptions, FindOneOptions, FindOneOrFailOptions, FindOptions, GetReferenceOptions, IDatabaseDriver, LockOptions, NativeInsertUpdateOptions, StreamOptions, UpdateOptions, UpsertManyOptions, UpsertOptions } from './drivers/IDatabaseDriver.js';
|
|
13
|
-
import type { AnyEntity, AnyString, ArrayElement, AutoPath, ConnectionType, Dictionary, EntityData, EntityDictionary, EntityDTO, EntityMetadata, EntityName, FilterDef, FilterQuery, FromEntityType, GetRepository, IHydrator, IsSubset, Loaded,
|
|
13
|
+
import type { AnyEntity, AnyString, ArrayElement, AutoPath, ConnectionType, Dictionary, EntityData, EntityDictionary, EntityDTO, EntityMetadata, EntityName, FilterDef, FilterQuery, FromEntityType, GetRepository, IHydrator, IsSubset, Loaded, MergeLoaded, MergeSelected, NoInfer, ObjectQuery, Primary, Ref, RequiredEntityData, UnboxArray } from './typings.js';
|
|
14
14
|
import { FlushMode, LockMode, PopulatePath, type TransactionOptions } from './enums.js';
|
|
15
15
|
import type { MetadataStorage } from './metadata/MetadataStorage.js';
|
|
16
16
|
import type { Transaction } from './connections/Connection.js';
|
|
@@ -109,19 +109,7 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
|
|
|
109
109
|
/**
|
|
110
110
|
* Registers global filter to this entity manager. Global filters are enabled by default (unless disabled via last parameter).
|
|
111
111
|
*/
|
|
112
|
-
addFilter<
|
|
113
|
-
/**
|
|
114
|
-
* Registers global filter to this entity manager. Global filters are enabled by default (unless disabled via last parameter).
|
|
115
|
-
*/
|
|
116
|
-
addFilter<T1, T2>(name: string, cond: FilterQuery<T1 | T2> | ((args: Dictionary) => MaybePromise<FilterQuery<T1 | T2>>), entityName?: [EntityName<T1>, EntityName<T2>], options?: boolean | Partial<FilterDef>): void;
|
|
117
|
-
/**
|
|
118
|
-
* Registers global filter to this entity manager. Global filters are enabled by default (unless disabled via last parameter).
|
|
119
|
-
*/
|
|
120
|
-
addFilter<T1, T2, T3>(name: string, cond: FilterQuery<T1 | T2 | T3> | ((args: Dictionary) => MaybePromise<FilterQuery<T1 | T2 | T3>>), entityName?: [EntityName<T1>, EntityName<T2>, EntityName<T3>], options?: boolean | Partial<FilterDef>): void;
|
|
121
|
-
/**
|
|
122
|
-
* Registers global filter to this entity manager. Global filters are enabled by default (unless disabled via last parameter).
|
|
123
|
-
*/
|
|
124
|
-
addFilter(name: string, cond: Dictionary | ((args: Dictionary) => MaybePromise<FilterQuery<AnyEntity>>), entityName?: EntityName<AnyEntity> | EntityName<AnyEntity>[], options?: boolean | Partial<FilterDef>): void;
|
|
112
|
+
addFilter<T extends object>(options: FilterDef<T>): void;
|
|
125
113
|
/**
|
|
126
114
|
* Sets filter parameter values globally inside context defined by this entity manager.
|
|
127
115
|
* If you want to set shared value for all contexts, be sure to use the root entity manager.
|
package/EntityManager.js
CHANGED
|
@@ -256,15 +256,34 @@ export class EntityManager {
|
|
|
256
256
|
}
|
|
257
257
|
return { where: options.populateWhere };
|
|
258
258
|
}
|
|
259
|
+
// /**
|
|
260
|
+
// * Registers global filter to this entity manager. Global filters are enabled by default (unless disabled via last parameter).
|
|
261
|
+
// */
|
|
262
|
+
// addFilter<T1>(name: string, cond: FilterQuery<T1> | ((args: Dictionary) => MaybePromise<FilterQuery<T1>>), entityName?: EntityName<T1> | [EntityName<T1>], options?: boolean | Partial<FilterDef>): void;
|
|
263
|
+
//
|
|
264
|
+
// /**
|
|
265
|
+
// * Registers global filter to this entity manager. Global filters are enabled by default (unless disabled via last parameter).
|
|
266
|
+
// */
|
|
267
|
+
// addFilter<T1, T2>(name: string, cond: FilterQuery<T1 | T2> | ((args: Dictionary) => MaybePromise<FilterQuery<T1 | T2>>), entityName?: [EntityName<T1>, EntityName<T2>], options?: boolean | Partial<FilterDef>): void;
|
|
268
|
+
//
|
|
269
|
+
// /**
|
|
270
|
+
// * Registers global filter to this entity manager. Global filters are enabled by default (unless disabled via last parameter).
|
|
271
|
+
// */
|
|
272
|
+
// addFilter<T1, T2, T3>(name: string, cond: FilterQuery<T1 | T2 | T3> | ((args: Dictionary) => MaybePromise<FilterQuery<T1 | T2 | T3>>), entityName?: [EntityName<T1>, EntityName<T2>, EntityName<T3>], options?: boolean | Partial<FilterDef>): void;
|
|
273
|
+
//
|
|
274
|
+
// /**
|
|
275
|
+
// * Registers global filter to this entity manager. Global filters are enabled by default (unless disabled via last parameter).
|
|
276
|
+
// */
|
|
277
|
+
// addFilter(name: string, cond: Dictionary | ((args: Dictionary) => MaybePromise<FilterQuery<AnyEntity>>), entityName?: EntityName<AnyEntity> | EntityName<AnyEntity>[], options?: boolean | Partial<FilterDef>): void;
|
|
259
278
|
/**
|
|
260
279
|
* Registers global filter to this entity manager. Global filters are enabled by default (unless disabled via last parameter).
|
|
261
280
|
*/
|
|
262
|
-
addFilter(
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
options.entity = Utils.asArray(entityName).map(n => Utils.className(n));
|
|
281
|
+
addFilter(options) {
|
|
282
|
+
if (options.entity) {
|
|
283
|
+
options.entity = Utils.asArray(options.entity).map(n => Utils.className(n));
|
|
266
284
|
}
|
|
267
|
-
|
|
285
|
+
options.default ??= true;
|
|
286
|
+
this.getContext(false).filters[options.name] = options;
|
|
268
287
|
}
|
|
269
288
|
/**
|
|
270
289
|
* Sets filter parameter values globally inside context defined by this entity manager.
|
package/decorators/Property.d.ts
CHANGED
|
@@ -113,12 +113,6 @@ export interface PropertyOptions<Owner> {
|
|
|
113
113
|
* Enable `ScalarReference` wrapper for lazy values. Use this in combination with `lazy: true` to have a type-safe accessor object in place of the value.
|
|
114
114
|
*/
|
|
115
115
|
ref?: boolean;
|
|
116
|
-
/**
|
|
117
|
-
* Set false to disable change tracking on a property level.
|
|
118
|
-
*
|
|
119
|
-
* @see https://mikro-orm.io/docs/unit-of-work#change-tracking-and-performance-considerations
|
|
120
|
-
*/
|
|
121
|
-
trackChanges?: boolean;
|
|
122
116
|
/**
|
|
123
117
|
* Set to true to omit the property when {@link https://mikro-orm.io/docs/serializing Serializing}.
|
|
124
118
|
*/
|
|
@@ -16,7 +16,7 @@ export declare class ArrayCollection<T extends object, O extends object> {
|
|
|
16
16
|
toArray<TT extends T>(): EntityDTO<TT>[];
|
|
17
17
|
toJSON(): EntityDTO<T>[];
|
|
18
18
|
getIdentifiers<U extends IPrimaryKey = Primary<T> & IPrimaryKey>(field?: string | string[]): U[];
|
|
19
|
-
add(entity: T | Reference<T> | Iterable<T | Reference<T>>, ...entities: (T | Reference<T>)[]):
|
|
19
|
+
add(entity: T | Reference<T> | Iterable<T | Reference<T>>, ...entities: (T | Reference<T>)[]): number;
|
|
20
20
|
/**
|
|
21
21
|
* @internal
|
|
22
22
|
*/
|
|
@@ -33,7 +33,7 @@ export declare class ArrayCollection<T extends object, O extends object> {
|
|
|
33
33
|
* is not the same as `em.remove()`. If we want to delete the entity by removing it from collection, we need to enable `orphanRemoval: true`,
|
|
34
34
|
* which tells the ORM we don't want orphaned entities to exist, so we know those should be removed.
|
|
35
35
|
*/
|
|
36
|
-
remove(entity: T | Reference<T> | Iterable<T | Reference<T>>, ...entities: (T | Reference<T>)[]):
|
|
36
|
+
remove(entity: T | Reference<T> | Iterable<T | Reference<T>>, ...entities: (T | Reference<T>)[]): number;
|
|
37
37
|
/**
|
|
38
38
|
* Remove all items from the collection. Note that removing items from collection does not necessarily imply deleting the target entity,
|
|
39
39
|
* it means we are disconnecting the relation - removing items from collection, not removing entities from database - `Collection.remove()`
|
|
@@ -61,15 +61,18 @@ export class ArrayCollection {
|
|
|
61
61
|
}
|
|
62
62
|
add(entity, ...entities) {
|
|
63
63
|
entities = Utils.asArray(entity).concat(entities);
|
|
64
|
+
let added = 0;
|
|
64
65
|
for (const item of entities) {
|
|
65
66
|
const entity = Reference.unwrapReference(item);
|
|
66
67
|
if (!this.contains(entity, false)) {
|
|
67
68
|
this.incrementCount(1);
|
|
68
69
|
this[this.items.size] = entity;
|
|
69
70
|
this.items.add(entity);
|
|
71
|
+
added++;
|
|
70
72
|
this.propagate(entity, 'add');
|
|
71
73
|
}
|
|
72
74
|
}
|
|
75
|
+
return added;
|
|
73
76
|
}
|
|
74
77
|
/**
|
|
75
78
|
* @internal
|
|
@@ -127,7 +130,7 @@ export class ArrayCollection {
|
|
|
127
130
|
*/
|
|
128
131
|
remove(entity, ...entities) {
|
|
129
132
|
entities = Utils.asArray(entity).concat(entities);
|
|
130
|
-
let
|
|
133
|
+
let removed = 0;
|
|
131
134
|
for (const item of entities) {
|
|
132
135
|
if (!item) {
|
|
133
136
|
continue;
|
|
@@ -137,12 +140,13 @@ export class ArrayCollection {
|
|
|
137
140
|
this.incrementCount(-1);
|
|
138
141
|
delete this[this.items.size]; // remove last item
|
|
139
142
|
this.propagate(entity, 'remove');
|
|
140
|
-
|
|
143
|
+
removed++;
|
|
141
144
|
}
|
|
142
145
|
}
|
|
143
|
-
if (
|
|
146
|
+
if (removed > 0) {
|
|
144
147
|
Object.assign(this, [...this.items]); // reassign array access
|
|
145
148
|
}
|
|
149
|
+
return removed;
|
|
146
150
|
}
|
|
147
151
|
/**
|
|
148
152
|
* Remove all items from the collection. Note that removing items from collection does not necessarily imply deleting the target entity,
|
|
@@ -156,6 +160,7 @@ export class ArrayCollection {
|
|
|
156
160
|
this.snapshot = undefined;
|
|
157
161
|
}
|
|
158
162
|
this.remove(this.items);
|
|
163
|
+
this.setDirty();
|
|
159
164
|
}
|
|
160
165
|
/**
|
|
161
166
|
* @internal
|
package/entity/BaseEntity.d.ts
CHANGED
|
@@ -6,7 +6,6 @@ import { type SerializeOptions } from '../serialization/EntitySerializer.js';
|
|
|
6
6
|
import type { FindOneOptions } from '../drivers/IDatabaseDriver.js';
|
|
7
7
|
export declare abstract class BaseEntity {
|
|
8
8
|
isInitialized(): boolean;
|
|
9
|
-
isTouched(): boolean;
|
|
10
9
|
populated(populated?: boolean): void;
|
|
11
10
|
populate<Entity extends this = this, Hint extends string = never>(populate: AutoPath<Entity, Hint>[] | false, options?: EntityLoaderOptions<Entity>): Promise<Loaded<Entity, Hint>>;
|
|
12
11
|
toReference<Entity extends this = this>(): Ref<Entity> & LoadedReference<Loaded<Entity, AddEager<Entity>>>;
|
package/entity/BaseEntity.js
CHANGED
package/entity/Collection.d.ts
CHANGED
|
@@ -39,11 +39,11 @@ export declare class Collection<T extends object, O extends object = object> ext
|
|
|
39
39
|
*/
|
|
40
40
|
getItems(check?: boolean): T[];
|
|
41
41
|
toJSON<TT extends T>(): EntityDTO<TT>[];
|
|
42
|
-
add<TT extends T>(entity: TT | Reference<TT> | Iterable<TT | Reference<TT>>, ...entities: (TT | Reference<TT>)[]):
|
|
42
|
+
add<TT extends T>(entity: TT | Reference<TT> | Iterable<TT | Reference<TT>>, ...entities: (TT | Reference<TT>)[]): number;
|
|
43
43
|
/**
|
|
44
44
|
* @inheritDoc
|
|
45
45
|
*/
|
|
46
|
-
remove<TT extends T>(entity: TT | Reference<TT> | Iterable<TT | Reference<TT>> | ((item: TT) => boolean), ...entities: (TT | Reference<TT>)[]):
|
|
46
|
+
remove<TT extends T>(entity: TT | Reference<TT> | Iterable<TT | Reference<TT>> | ((item: TT) => boolean), ...entities: (TT | Reference<TT>)[]): number;
|
|
47
47
|
contains<TT extends T>(item: TT | Reference<TT>, check?: boolean): boolean;
|
|
48
48
|
count(): number;
|
|
49
49
|
isEmpty(): boolean;
|
package/entity/Collection.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ArrayCollection } from './ArrayCollection.js';
|
|
2
2
|
import { Utils } from '../utils/Utils.js';
|
|
3
3
|
import { ValidationError } from '../errors.js';
|
|
4
|
-
import {
|
|
4
|
+
import { DataloaderType, ReferenceKind } from '../enums.js';
|
|
5
5
|
import { Reference } from './Reference.js';
|
|
6
6
|
import { helper } from './wrap.js';
|
|
7
7
|
import { QueryHelper } from '../utils/QueryHelper.js';
|
|
@@ -117,30 +117,33 @@ export class Collection extends ArrayCollection {
|
|
|
117
117
|
entities = Utils.asArray(entity).concat(entities);
|
|
118
118
|
const unwrapped = entities.map(i => Reference.unwrapReference(i));
|
|
119
119
|
unwrapped.forEach(entity => this.validateItemType(entity));
|
|
120
|
-
this.modify('add', unwrapped);
|
|
120
|
+
const added = this.modify('add', unwrapped);
|
|
121
121
|
this.cancelOrphanRemoval(unwrapped);
|
|
122
|
+
return added;
|
|
122
123
|
}
|
|
123
124
|
/**
|
|
124
125
|
* @inheritDoc
|
|
125
126
|
*/
|
|
126
127
|
remove(entity, ...entities) {
|
|
127
128
|
if (entity instanceof Function) {
|
|
129
|
+
let removed = 0;
|
|
128
130
|
for (const item of this.items) {
|
|
129
131
|
if (entity(item)) {
|
|
130
|
-
this.remove(item);
|
|
132
|
+
removed += this.remove(item);
|
|
131
133
|
}
|
|
132
134
|
}
|
|
133
|
-
return;
|
|
135
|
+
return removed;
|
|
134
136
|
}
|
|
135
137
|
entities = Utils.asArray(entity).concat(entities);
|
|
136
138
|
const unwrapped = entities.map(i => Reference.unwrapReference(i));
|
|
137
|
-
this.modify('remove', unwrapped);
|
|
139
|
+
const removed = this.modify('remove', unwrapped);
|
|
138
140
|
const em = this.getEntityManager(unwrapped, false);
|
|
139
141
|
if (this.property.orphanRemoval && em) {
|
|
140
142
|
for (const item of unwrapped) {
|
|
141
143
|
em.getUnitOfWork().scheduleOrphanRemoval(item);
|
|
142
144
|
}
|
|
143
145
|
}
|
|
146
|
+
return removed;
|
|
144
147
|
}
|
|
145
148
|
contains(item, check = true) {
|
|
146
149
|
if (check) {
|
|
@@ -267,8 +270,10 @@ export class Collection extends ArrayCollection {
|
|
|
267
270
|
getEntityManager(items = [], required = true) {
|
|
268
271
|
const wrapped = helper(this.owner);
|
|
269
272
|
let em = wrapped.__em;
|
|
273
|
+
// console.log('wat 1', em, this.owner);
|
|
270
274
|
if (!em) {
|
|
271
275
|
for (const i of items) {
|
|
276
|
+
// console.log('wat 2', i, i && helper(i).__em);
|
|
272
277
|
if (i && helper(i).__em) {
|
|
273
278
|
em = helper(i).__em;
|
|
274
279
|
break;
|
|
@@ -325,8 +330,14 @@ export class Collection extends ArrayCollection {
|
|
|
325
330
|
this.checkInitialized();
|
|
326
331
|
}
|
|
327
332
|
this.validateModification(items);
|
|
328
|
-
super[method](items);
|
|
329
|
-
|
|
333
|
+
const modified = super[method](items);
|
|
334
|
+
if (modified > 0) {
|
|
335
|
+
this.setDirty();
|
|
336
|
+
}
|
|
337
|
+
if (this.property.kind === ReferenceKind.ONE_TO_MANY && (method === 'add' || !this.property.orphanRemoval)) {
|
|
338
|
+
this.getEntityManager(items, false)?.persist(items);
|
|
339
|
+
}
|
|
340
|
+
return modified;
|
|
330
341
|
}
|
|
331
342
|
checkInitialized() {
|
|
332
343
|
if (!this.isInitialized()) {
|
package/entity/EntityFactory.js
CHANGED
|
@@ -84,7 +84,6 @@ export class EntityFactory {
|
|
|
84
84
|
else {
|
|
85
85
|
this.hydrate(entity, meta2, data, options);
|
|
86
86
|
}
|
|
87
|
-
wrapped.__touched = false;
|
|
88
87
|
if (exists && meta.discriminatorColumn && !(entity instanceof meta2.class)) {
|
|
89
88
|
Object.setPrototypeOf(entity, meta2.prototype);
|
|
90
89
|
}
|
|
@@ -161,7 +160,6 @@ export class EntityFactory {
|
|
|
161
160
|
}
|
|
162
161
|
});
|
|
163
162
|
this.unitOfWork.normalizeEntityData(meta, originalEntityData);
|
|
164
|
-
helper(entity).__touched = false;
|
|
165
163
|
}
|
|
166
164
|
createReference(entityName, id, options = {}) {
|
|
167
165
|
options.convertCustomTypes ??= true;
|
package/entity/EntityHelper.js
CHANGED
|
@@ -87,7 +87,7 @@ export class EntityHelper {
|
|
|
87
87
|
});
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
|
-
if (prop.inherited || prop.primary || prop.accessor || prop.persist === false || prop.
|
|
90
|
+
if (prop.inherited || prop.primary || prop.accessor || prop.persist === false || prop.embedded || isCollection) {
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
93
|
Object.defineProperty(meta.prototype, prop.name, {
|
|
@@ -98,13 +98,11 @@ export class EntityHelper {
|
|
|
98
98
|
},
|
|
99
99
|
set(val) {
|
|
100
100
|
this.__helper.__data[prop.name] = val;
|
|
101
|
-
this.__helper.__touched = !this.__helper.hydrator.isRunning();
|
|
102
101
|
},
|
|
103
102
|
enumerable: true,
|
|
104
103
|
configurable: true,
|
|
105
104
|
});
|
|
106
105
|
this.__helper.__data[prop.name] = val;
|
|
107
|
-
this.__helper.__touched = !this.__helper.hydrator.isRunning();
|
|
108
106
|
},
|
|
109
107
|
configurable: true,
|
|
110
108
|
});
|
|
@@ -114,7 +112,7 @@ export class EntityHelper {
|
|
|
114
112
|
// @ts-ignore
|
|
115
113
|
meta.prototype[inspect.custom] ??= function (depth = 2) {
|
|
116
114
|
const object = {};
|
|
117
|
-
const keys = new Set(Utils.keys(this));
|
|
115
|
+
const keys = new Set(Utils.keys(this));
|
|
118
116
|
for (const prop of meta.props) {
|
|
119
117
|
if (keys.has(prop.name) || (prop.getter && prop.accessor === prop.name)) {
|
|
120
118
|
object[prop.name] = this[prop.name];
|
|
@@ -165,9 +163,6 @@ export class EntityHelper {
|
|
|
165
163
|
if (val && hydrator.isRunning() && wrapped.__originalEntityData && prop.owner) {
|
|
166
164
|
wrapped.__originalEntityData[prop.name] = Utils.getPrimaryKeyValues(wrapped.__data[prop.name], prop.targetMeta, true);
|
|
167
165
|
}
|
|
168
|
-
else {
|
|
169
|
-
wrapped.__touched = !hydrator.isRunning();
|
|
170
|
-
}
|
|
171
166
|
EntityHelper.propagate(meta, entity, this, prop, Reference.unwrapReference(val), old);
|
|
172
167
|
},
|
|
173
168
|
enumerable: true,
|
|
@@ -11,7 +11,6 @@ import { type SerializeOptions } from '../serialization/EntitySerializer.js';
|
|
|
11
11
|
import type { FindOneOptions, LoadHint } from '../drivers/IDatabaseDriver.js';
|
|
12
12
|
export declare class WrappedEntity<Entity extends object> {
|
|
13
13
|
__initialized: boolean;
|
|
14
|
-
__touched: boolean;
|
|
15
14
|
__populated?: boolean;
|
|
16
15
|
__managed?: boolean;
|
|
17
16
|
__onLoadFired?: boolean;
|
|
@@ -41,7 +40,6 @@ export declare class WrappedEntity<Entity extends object> {
|
|
|
41
40
|
private readonly pkGetterConverted?;
|
|
42
41
|
constructor(entity: Entity, hydrator: IHydrator, pkGetter?: (e: Entity) => Primary<Entity>, pkSerializer?: (e: Entity) => string, pkGetterConverted?: (e: Entity) => Primary<Entity>);
|
|
43
42
|
isInitialized(): boolean;
|
|
44
|
-
isTouched(): boolean;
|
|
45
43
|
isManaged(): boolean;
|
|
46
44
|
populated(populated?: boolean | undefined): void;
|
|
47
45
|
setSerializationContext<Hint extends string = never, Fields extends string = '*', Exclude extends string = never>(options: LoadHint<Entity, Hint, Fields, Exclude>): void;
|
package/entity/WrappedEntity.js
CHANGED
|
@@ -15,7 +15,6 @@ export class WrappedEntity {
|
|
|
15
15
|
this.pkSerializer = pkSerializer;
|
|
16
16
|
this.pkGetterConverted = pkGetterConverted;
|
|
17
17
|
this.__initialized = true;
|
|
18
|
-
this.__touched = false;
|
|
19
18
|
this.__serializationContext = {};
|
|
20
19
|
this.__loadedProperties = new Set();
|
|
21
20
|
this.__data = {};
|
|
@@ -24,9 +23,6 @@ export class WrappedEntity {
|
|
|
24
23
|
isInitialized() {
|
|
25
24
|
return this.__initialized;
|
|
26
25
|
}
|
|
27
|
-
isTouched() {
|
|
28
|
-
return this.__touched;
|
|
29
|
-
}
|
|
30
26
|
isManaged() {
|
|
31
27
|
return !!this.__managed;
|
|
32
28
|
}
|
package/entity/defineEntity.d.ts
CHANGED
|
@@ -178,12 +178,6 @@ export declare class UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys
|
|
|
178
178
|
ref<T extends boolean = true>(ref?: T): UniversalPropertyOptionsBuilder<Value, Omit<Options, 'ref'> & {
|
|
179
179
|
ref: T;
|
|
180
180
|
}, IncludeKeys>;
|
|
181
|
-
/**
|
|
182
|
-
* Set false to disable change tracking on a property level.
|
|
183
|
-
*
|
|
184
|
-
* @see https://mikro-orm.io/docs/unit-of-work#change-tracking-and-performance-considerations
|
|
185
|
-
*/
|
|
186
|
-
trackChanges(trackChanges?: boolean): UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>;
|
|
187
181
|
/**
|
|
188
182
|
* Set to true to omit the property when {@link https://mikro-orm.io/docs/serializing Serializing}.
|
|
189
183
|
*/
|
package/entity/defineEntity.js
CHANGED
|
@@ -170,14 +170,6 @@ export class UniversalPropertyOptionsBuilder {
|
|
|
170
170
|
ref(ref = true) {
|
|
171
171
|
return this.assignOptions({ ref });
|
|
172
172
|
}
|
|
173
|
-
/**
|
|
174
|
-
* Set false to disable change tracking on a property level.
|
|
175
|
-
*
|
|
176
|
-
* @see https://mikro-orm.io/docs/unit-of-work#change-tracking-and-performance-considerations
|
|
177
|
-
*/
|
|
178
|
-
trackChanges(trackChanges = true) {
|
|
179
|
-
return this.assignOptions({ trackChanges });
|
|
180
|
-
}
|
|
181
173
|
/**
|
|
182
174
|
* Set to true to omit the property when {@link https://mikro-orm.io/docs/serializing Serializing}.
|
|
183
175
|
*/
|
|
@@ -100,7 +100,6 @@ export class MetadataDiscovery {
|
|
|
100
100
|
this.initFieldName(prop);
|
|
101
101
|
prop.serializedName ??= prop.accessor;
|
|
102
102
|
prop.name = name;
|
|
103
|
-
prop.trackChanges = false;
|
|
104
103
|
}
|
|
105
104
|
}
|
|
106
105
|
}
|
|
@@ -132,10 +131,6 @@ export class MetadataDiscovery {
|
|
|
132
131
|
this.initDefaultValue(prop);
|
|
133
132
|
this.inferTypeFromDefault(prop);
|
|
134
133
|
this.initColumnType(prop);
|
|
135
|
-
// change tracking on scalars is used only for "auto" flushMode
|
|
136
|
-
if (this.config.get('flushMode') !== 'auto' && [ReferenceKind.SCALAR, ReferenceKind.EMBEDDED].includes(prop.kind)) {
|
|
137
|
-
prop.trackChanges = false;
|
|
138
|
-
}
|
|
139
134
|
}
|
|
140
135
|
}
|
|
141
136
|
filtered.forEach(meta => Object.values(meta.properties).forEach(prop => this.initIndexes(meta, prop)));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "7.0.0-dev.
|
|
4
|
+
"version": "7.0.0-dev.45",
|
|
5
5
|
"description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
|
|
6
6
|
"exports": {
|
|
7
7
|
"./package.json": "./package.json",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"dataloader": "2.2.3",
|
|
55
55
|
"dotenv": "17.2.3",
|
|
56
56
|
"esprima": "4.0.1",
|
|
57
|
-
"mikro-orm": "7.0.0-dev.
|
|
57
|
+
"mikro-orm": "7.0.0-dev.45",
|
|
58
58
|
"reflect-metadata": "0.2.2",
|
|
59
59
|
"tinyglobby": "0.2.13"
|
|
60
60
|
}
|
|
@@ -41,13 +41,31 @@ export class EntitySerializer {
|
|
|
41
41
|
}
|
|
42
42
|
const root = wrapped.__serializationContext.root;
|
|
43
43
|
const ret = {};
|
|
44
|
-
const
|
|
45
|
-
|
|
44
|
+
const props = new Set();
|
|
45
|
+
if (meta.serializedPrimaryKey && !meta.compositePK) {
|
|
46
|
+
props.add(meta.serializedPrimaryKey);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
meta.primaryKeys.forEach(pk => props.add(pk));
|
|
50
|
+
}
|
|
51
|
+
if (wrapped.isInitialized() || !wrapped.hasPrimaryKey()) {
|
|
52
|
+
const entityKeys = new Set(Object.keys(entity));
|
|
53
|
+
for (const prop of meta.props) {
|
|
54
|
+
if (entityKeys.has(prop.name) || (prop.getter && prop.accessor === prop.name)) {
|
|
55
|
+
props.add(prop.name);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
for (const key of entityKeys) {
|
|
59
|
+
if (!meta.properties[key]) {
|
|
60
|
+
props.add(key);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
46
64
|
const visited = root.visited.has(entity);
|
|
47
65
|
if (!visited) {
|
|
48
66
|
root.visited.add(entity);
|
|
49
67
|
}
|
|
50
|
-
for (const prop of
|
|
68
|
+
for (const prop of props) {
|
|
51
69
|
if (!isVisible(meta, prop, options)) {
|
|
52
70
|
continue;
|
|
53
71
|
}
|
|
@@ -27,22 +27,32 @@ export class EntityTransformer {
|
|
|
27
27
|
const root = wrapped.__serializationContext.root;
|
|
28
28
|
const meta = wrapped.__meta;
|
|
29
29
|
const ret = {};
|
|
30
|
-
const
|
|
30
|
+
const props = new Set();
|
|
31
31
|
if (meta.serializedPrimaryKey && !meta.compositePK) {
|
|
32
|
-
|
|
32
|
+
props.add(meta.serializedPrimaryKey);
|
|
33
33
|
}
|
|
34
34
|
else {
|
|
35
|
-
meta.primaryKeys.forEach(pk =>
|
|
35
|
+
meta.primaryKeys.forEach(pk => props.add(pk));
|
|
36
36
|
}
|
|
37
37
|
if (wrapped.isInitialized() || !wrapped.hasPrimaryKey()) {
|
|
38
|
-
|
|
38
|
+
const entityKeys = new Set(Object.keys(entity));
|
|
39
|
+
for (const prop of meta.props) {
|
|
40
|
+
if (entityKeys.has(prop.name) || (prop.getter && prop.accessor === prop.name)) {
|
|
41
|
+
props.add(prop.name);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
for (const key of entityKeys) {
|
|
45
|
+
if (!meta.properties[key]) {
|
|
46
|
+
props.add(key);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
39
49
|
}
|
|
40
50
|
const visited = root.visited.has(entity);
|
|
41
51
|
const includePrimaryKeys = wrapped.__config.get('serialization').includePrimaryKeys;
|
|
42
52
|
if (!visited) {
|
|
43
53
|
root.visited.add(entity);
|
|
44
54
|
}
|
|
45
|
-
for (const prop of
|
|
55
|
+
for (const prop of props) {
|
|
46
56
|
const visible = raw ? meta.properties[prop] : isVisible(meta, prop, ignoreFields);
|
|
47
57
|
if (!visible) {
|
|
48
58
|
continue;
|
package/typings.d.ts
CHANGED
|
@@ -160,7 +160,6 @@ export type FilterQuery<T> = ObjectQuery<T> | NonNullable<ExpandScalar<Primary<T
|
|
|
160
160
|
export type QBFilterQuery<T = any> = ObjectQuery<T> | Dictionary;
|
|
161
161
|
export interface IWrappedEntity<Entity extends object> {
|
|
162
162
|
isInitialized(): boolean;
|
|
163
|
-
isTouched(): boolean;
|
|
164
163
|
isManaged(): boolean;
|
|
165
164
|
populated(populated?: boolean): void;
|
|
166
165
|
populate<Hint extends string = never>(populate: AutoPath<Entity, Hint>[] | false, options?: EntityLoaderOptions<Entity>): Promise<Loaded<Entity, Hint>>;
|
|
@@ -191,7 +190,6 @@ export interface IWrappedEntityInternal<Entity extends object> extends IWrappedE
|
|
|
191
190
|
__factory: EntityFactory;
|
|
192
191
|
__hydrator: IHydrator;
|
|
193
192
|
__initialized: boolean;
|
|
194
|
-
__touched: boolean;
|
|
195
193
|
__originalEntityData?: EntityData<Entity>;
|
|
196
194
|
__loadedProperties: Set<string>;
|
|
197
195
|
__identifier?: EntityIdentifier | EntityIdentifier[];
|
|
@@ -378,7 +376,6 @@ export interface EntityProperty<Owner = any, Target = any> {
|
|
|
378
376
|
mapToPk?: boolean;
|
|
379
377
|
persist?: boolean;
|
|
380
378
|
hydrate?: boolean;
|
|
381
|
-
trackChanges?: boolean;
|
|
382
379
|
hidden?: boolean;
|
|
383
380
|
enum?: boolean;
|
|
384
381
|
items?: (number | string)[];
|
|
@@ -607,8 +604,6 @@ export interface GenerateOptions {
|
|
|
607
604
|
coreImportsPrefix?: string;
|
|
608
605
|
onInitialMetadata?: MetadataProcessor;
|
|
609
606
|
onProcessedMetadata?: MetadataProcessor;
|
|
610
|
-
/** @deprecated use `entityDefinition: 'entitySchema'` instead */
|
|
611
|
-
entitySchema?: boolean;
|
|
612
607
|
}
|
|
613
608
|
export interface IEntityGenerator {
|
|
614
609
|
generate(options?: GenerateOptions): Promise<string[]>;
|
|
@@ -722,11 +717,11 @@ export interface MigrationObject {
|
|
|
722
717
|
name: string;
|
|
723
718
|
class: Constructor<Migration>;
|
|
724
719
|
}
|
|
725
|
-
export type FilterDef = {
|
|
720
|
+
export type FilterDef<T extends object = any> = {
|
|
726
721
|
name: string;
|
|
727
|
-
cond: Dictionary | ((args: Dictionary, type: 'read' | 'update' | 'delete', em: any, options?: FindOptions<
|
|
722
|
+
cond: Dictionary | ((args: Dictionary, type: 'read' | 'update' | 'delete', em: any, options?: FindOptions<T, any, any, any> | FindOneOptions<T, any, any, any>, entityName?: EntityName<T>) => MaybePromise<Dictionary>);
|
|
728
723
|
default?: boolean;
|
|
729
|
-
entity?:
|
|
724
|
+
entity?: EntityName<T> | EntityName<T>[];
|
|
730
725
|
args?: boolean;
|
|
731
726
|
strict?: boolean;
|
|
732
727
|
};
|
package/typings.js
CHANGED
|
@@ -90,11 +90,12 @@ export class EntityMetadata {
|
|
|
90
90
|
const onlyGetter = prop.getter && !prop.setter && prop.persist === false;
|
|
91
91
|
return !prop.inherited && prop.hydrate !== false && !discriminator && !prop.embedded && !onlyGetter;
|
|
92
92
|
});
|
|
93
|
-
this.trackingProps = this.hydrateProps
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
this.trackingProps = this.hydrateProps.filter(prop => {
|
|
94
|
+
return !prop.getter && !prop.setter && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind);
|
|
95
|
+
});
|
|
96
|
+
this.selfReferencing = this.relations.some(prop => {
|
|
97
|
+
return [this.className, this.root.className].includes(prop.targetMeta?.root.className ?? prop.type);
|
|
98
|
+
});
|
|
98
99
|
this.hasUniqueProps = this.uniques.length + this.uniqueProps.length > 0;
|
|
99
100
|
this.virtual = !!this.expression;
|
|
100
101
|
if (config) {
|
|
@@ -126,8 +127,7 @@ export class EntityMetadata {
|
|
|
126
127
|
this.props.forEach(prop => this.initIndexes(prop));
|
|
127
128
|
}
|
|
128
129
|
this.definedProperties = this.trackingProps.reduce((o, prop) => {
|
|
129
|
-
const
|
|
130
|
-
const isReference = [ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind) && (prop.inversedBy || prop.mappedBy) && !prop.mapToPk;
|
|
130
|
+
const isReference = (prop.inversedBy || prop.mappedBy) && !prop.mapToPk;
|
|
131
131
|
if (isReference) {
|
|
132
132
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
133
133
|
const meta = this;
|
|
@@ -148,32 +148,12 @@ export class EntityMetadata {
|
|
|
148
148
|
if (val && hydrator.isRunning() && wrapped.__originalEntityData && prop.owner) {
|
|
149
149
|
wrapped.__originalEntityData[prop.name] = Utils.getPrimaryKeyValues(val, prop.targetMeta, true);
|
|
150
150
|
}
|
|
151
|
-
else {
|
|
152
|
-
wrapped.__touched = !hydrator.isRunning();
|
|
153
|
-
}
|
|
154
151
|
EntityHelper.propagate(meta, entity, this, prop, Reference.unwrapReference(val), old);
|
|
155
152
|
},
|
|
156
153
|
enumerable: true,
|
|
157
154
|
configurable: true,
|
|
158
155
|
};
|
|
159
156
|
}
|
|
160
|
-
if (prop.inherited || prop.primary || isCollection || prop.persist === false || prop.trackChanges === false || isReference || prop.embedded) {
|
|
161
|
-
return o;
|
|
162
|
-
}
|
|
163
|
-
o[prop.name] = {
|
|
164
|
-
get() {
|
|
165
|
-
return this.__helper.__data[prop.name];
|
|
166
|
-
},
|
|
167
|
-
set(val) {
|
|
168
|
-
if (typeof val === 'object' && !!val && '__raw' in val) {
|
|
169
|
-
val.assign();
|
|
170
|
-
}
|
|
171
|
-
this.__helper.__data[prop.name] = val;
|
|
172
|
-
this.__helper.__touched = !this.__helper.hydrator.isRunning();
|
|
173
|
-
},
|
|
174
|
-
enumerable: true,
|
|
175
|
-
configurable: true,
|
|
176
|
-
};
|
|
177
157
|
return o;
|
|
178
158
|
}, { __gettersDefined: { value: true, enumerable: false } });
|
|
179
159
|
}
|
|
@@ -34,8 +34,11 @@ export class ChangeSetComputer {
|
|
|
34
34
|
this.processPropertyInitializers(entity, prop, type, map);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
if (type === ChangeSetType.UPDATE && !wrapped.__initialized
|
|
38
|
-
|
|
37
|
+
if (type === ChangeSetType.UPDATE && !wrapped.__initialized) {
|
|
38
|
+
const data = this.comparator.prepareEntity(entity);
|
|
39
|
+
if (Utils.equals(data, wrapped.__originalEntityData)) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
39
42
|
}
|
|
40
43
|
const changeSet = new ChangeSet(entity, type, this.computePayload(entity), meta);
|
|
41
44
|
changeSet.originalEntity = wrapped.__originalEntityData;
|
|
@@ -61,7 +61,6 @@ export class UnitOfWork {
|
|
|
61
61
|
// as there can be some entity with already changed state that is not yet flushed
|
|
62
62
|
if (wrapped.__initialized && (!visited || !wrapped.__originalEntityData)) {
|
|
63
63
|
wrapped.__originalEntityData = this.comparator.prepareEntity(entity);
|
|
64
|
-
wrapped.__touched = false;
|
|
65
64
|
}
|
|
66
65
|
this.cascade(entity, Cascade.MERGE, visited ?? new Set());
|
|
67
66
|
}
|
|
@@ -124,7 +123,6 @@ export class UnitOfWork {
|
|
|
124
123
|
}
|
|
125
124
|
}
|
|
126
125
|
wrapped.__originalEntityData = data;
|
|
127
|
-
wrapped.__touched = false;
|
|
128
126
|
}
|
|
129
127
|
return entity;
|
|
130
128
|
}
|
|
@@ -215,11 +213,6 @@ export class UnitOfWork {
|
|
|
215
213
|
if (meta.discriminatorMap && Object.values(meta.discriminatorMap).some(v => this.queuedActions.has(v))) {
|
|
216
214
|
return true;
|
|
217
215
|
}
|
|
218
|
-
for (const entity of this.identityMap.getStore(meta).values()) {
|
|
219
|
-
if (helper(entity).__initialized && helper(entity).isTouched()) {
|
|
220
|
-
return true;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
216
|
return false;
|
|
224
217
|
}
|
|
225
218
|
clearActionsQueue() {
|
|
@@ -239,7 +232,6 @@ export class UnitOfWork {
|
|
|
239
232
|
this.changeSets.set(entity, cs);
|
|
240
233
|
this.persistStack.delete(entity);
|
|
241
234
|
wrapped.__originalEntityData = this.comparator.prepareEntity(entity);
|
|
242
|
-
wrapped.__touched = false;
|
|
243
235
|
}
|
|
244
236
|
recomputeSingleChangeSet(entity) {
|
|
245
237
|
const changeSet = this.changeSets.get(entity);
|
|
@@ -250,7 +242,6 @@ export class UnitOfWork {
|
|
|
250
242
|
if (cs && !this.checkUniqueProps(cs)) {
|
|
251
243
|
Object.assign(changeSet.payload, cs.payload);
|
|
252
244
|
helper(entity).__originalEntityData = this.comparator.prepareEntity(entity);
|
|
253
|
-
helper(entity).__touched = false;
|
|
254
245
|
}
|
|
255
246
|
}
|
|
256
247
|
persist(entity, visited, options = {}) {
|
|
@@ -402,7 +393,6 @@ export class UnitOfWork {
|
|
|
402
393
|
}
|
|
403
394
|
delete wrapped.__identifier;
|
|
404
395
|
delete wrapped.__originalEntityData;
|
|
405
|
-
wrapped.__touched = false;
|
|
406
396
|
wrapped.__managed = false;
|
|
407
397
|
}
|
|
408
398
|
computeChangeSets() {
|
|
@@ -412,14 +402,14 @@ export class UnitOfWork {
|
|
|
412
402
|
this.cascade(entity, Cascade.REMOVE, visited);
|
|
413
403
|
}
|
|
414
404
|
visited.clear();
|
|
415
|
-
for (const entity of this.persistStack) {
|
|
416
|
-
this.cascade(entity, Cascade.PERSIST, visited, { checkRemoveStack: true });
|
|
417
|
-
}
|
|
418
405
|
for (const entity of this.identityMap) {
|
|
419
406
|
if (!this.removeStack.has(entity) && !this.persistStack.has(entity) && !this.orphanRemoveStack.has(entity)) {
|
|
420
407
|
this.cascade(entity, Cascade.PERSIST, visited, { checkRemoveStack: true });
|
|
421
408
|
}
|
|
422
409
|
}
|
|
410
|
+
for (const entity of this.persistStack) {
|
|
411
|
+
this.cascade(entity, Cascade.PERSIST, visited, { checkRemoveStack: true });
|
|
412
|
+
}
|
|
423
413
|
visited.clear();
|
|
424
414
|
for (const entity of this.persistStack) {
|
|
425
415
|
this.findNewEntities(entity, visited);
|
|
@@ -876,7 +866,6 @@ export class UnitOfWork {
|
|
|
876
866
|
for (const changeSet of changeSets) {
|
|
877
867
|
const wrapped = helper(changeSet.entity);
|
|
878
868
|
wrapped.__originalEntityData = this.comparator.prepareEntity(changeSet.entity);
|
|
879
|
-
wrapped.__touched = false;
|
|
880
869
|
if (!wrapped.__initialized) {
|
|
881
870
|
for (const prop of changeSet.meta.relations) {
|
|
882
871
|
if ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop.kind) && changeSet.entity[prop.name] == null) {
|
package/utils/Configuration.d.ts
CHANGED
|
@@ -114,12 +114,12 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
|
|
|
114
114
|
entityGenerator: {
|
|
115
115
|
forceUndefined: true;
|
|
116
116
|
undefinedDefaults: false;
|
|
117
|
-
bidirectionalRelations: false;
|
|
118
|
-
identifiedReferences: false;
|
|
119
117
|
scalarTypeInDecorator: false;
|
|
118
|
+
bidirectionalRelations: true;
|
|
119
|
+
identifiedReferences: true;
|
|
120
120
|
scalarPropertiesForRelations: "never";
|
|
121
|
-
entityDefinition: "
|
|
122
|
-
enumMode: "
|
|
121
|
+
entityDefinition: "defineEntity";
|
|
122
|
+
enumMode: "dictionary";
|
|
123
123
|
fileName: (className: string) => string;
|
|
124
124
|
onlyPurePivotTables: false;
|
|
125
125
|
outputPurePivotTables: false;
|
package/utils/Configuration.js
CHANGED
|
@@ -104,12 +104,12 @@ export class Configuration {
|
|
|
104
104
|
entityGenerator: {
|
|
105
105
|
forceUndefined: true,
|
|
106
106
|
undefinedDefaults: false,
|
|
107
|
-
bidirectionalRelations: false,
|
|
108
|
-
identifiedReferences: false,
|
|
109
107
|
scalarTypeInDecorator: false,
|
|
108
|
+
bidirectionalRelations: true,
|
|
109
|
+
identifiedReferences: true,
|
|
110
110
|
scalarPropertiesForRelations: 'never',
|
|
111
|
-
entityDefinition: '
|
|
112
|
-
enumMode: '
|
|
111
|
+
entityDefinition: 'defineEntity',
|
|
112
|
+
enumMode: 'dictionary',
|
|
113
113
|
fileName: (className) => className,
|
|
114
114
|
onlyPurePivotTables: false,
|
|
115
115
|
outputPurePivotTables: false,
|
|
@@ -150,7 +150,6 @@ export class Configuration {
|
|
|
150
150
|
}
|
|
151
151
|
this.options = Utils.mergeConfig({}, Configuration.DEFAULTS, options);
|
|
152
152
|
this.options.baseDir = Utils.absolutePath(this.options.baseDir);
|
|
153
|
-
this.options.preferTs ??= options.preferTs;
|
|
154
153
|
if (validate) {
|
|
155
154
|
this.validateOptions();
|
|
156
155
|
}
|
|
@@ -348,10 +347,6 @@ export class Configuration {
|
|
|
348
347
|
}
|
|
349
348
|
sync() {
|
|
350
349
|
process.env.MIKRO_ORM_COLORS = '' + this.options.colors;
|
|
351
|
-
// FIXME remove `entityGenerator.entitySchema` option
|
|
352
|
-
if (this.options.entityGenerator.entitySchema) {
|
|
353
|
-
this.options.entityGenerator.entityDefinition = 'entitySchema';
|
|
354
|
-
}
|
|
355
350
|
this.logger.setDebugMode(this.options.debug);
|
|
356
351
|
}
|
|
357
352
|
/**
|
|
@@ -19,7 +19,12 @@ export declare class ConfigurationLoader {
|
|
|
19
19
|
static getSettings(): Settings;
|
|
20
20
|
static getConfigPaths(): string[];
|
|
21
21
|
static isESM(): boolean;
|
|
22
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Tries to register TS support in the following order: swc, tsx, jiti, tsimp
|
|
24
|
+
* Use `MIKRO_ORM_CLI_TS_LOADER` env var to set the loader explicitly.
|
|
25
|
+
* This method is used only in CLI context.
|
|
26
|
+
*/
|
|
27
|
+
static registerTypeScriptSupport(configPath?: string, tsLoader?: 'swc' | 'tsx' | 'jiti' | 'tsimp' | 'auto'): Promise<boolean>;
|
|
23
28
|
static registerDotenv<D extends IDatabaseDriver>(options: Options<D>): void;
|
|
24
29
|
static loadEnvironmentVars<D extends IDatabaseDriver>(): Promise<Partial<Options<D>>>;
|
|
25
30
|
static loadEnvironmentVarsSync<D extends IDatabaseDriver>(): Partial<Options<D>>;
|
|
@@ -31,6 +36,7 @@ export interface Settings {
|
|
|
31
36
|
alwaysAllowTs?: boolean;
|
|
32
37
|
verbose?: boolean;
|
|
33
38
|
preferTs?: boolean;
|
|
39
|
+
tsLoader?: 'swc' | 'tsx' | 'jiti' | 'tsimp' | 'auto';
|
|
34
40
|
tsConfigPath?: string;
|
|
35
41
|
configPaths?: string[];
|
|
36
42
|
}
|
|
@@ -110,6 +110,7 @@ export class ConfigurationLoader {
|
|
|
110
110
|
const settings = { ...config['mikro-orm'] };
|
|
111
111
|
const bool = (v) => ['true', 't', '1'].includes(v.toLowerCase());
|
|
112
112
|
settings.preferTs = process.env.MIKRO_ORM_CLI_PREFER_TS != null ? bool(process.env.MIKRO_ORM_CLI_PREFER_TS) : settings.preferTs;
|
|
113
|
+
settings.tsLoader = process.env.MIKRO_ORM_CLI_TS_LOADER ?? settings.tsLoader;
|
|
113
114
|
settings.tsConfigPath = process.env.MIKRO_ORM_CLI_TS_CONFIG_PATH ?? settings.tsConfigPath;
|
|
114
115
|
settings.alwaysAllowTs = process.env.MIKRO_ORM_CLI_ALWAYS_ALLOW_TS != null ? bool(process.env.MIKRO_ORM_CLI_ALWAYS_ALLOW_TS) : settings.alwaysAllowTs;
|
|
115
116
|
settings.verbose = process.env.MIKRO_ORM_CLI_VERBOSE != null ? bool(process.env.MIKRO_ORM_CLI_VERBOSE) : settings.verbose;
|
|
@@ -145,22 +146,46 @@ export class ConfigurationLoader {
|
|
|
145
146
|
const type = config?.type ?? '';
|
|
146
147
|
return type === 'module';
|
|
147
148
|
}
|
|
148
|
-
|
|
149
|
+
/**
|
|
150
|
+
* Tries to register TS support in the following order: swc, tsx, jiti, tsimp
|
|
151
|
+
* Use `MIKRO_ORM_CLI_TS_LOADER` env var to set the loader explicitly.
|
|
152
|
+
* This method is used only in CLI context.
|
|
153
|
+
*/
|
|
154
|
+
static async registerTypeScriptSupport(configPath = 'tsconfig.json', tsLoader) {
|
|
149
155
|
/* v8 ignore next 3 */
|
|
150
156
|
if (process.versions.bun) {
|
|
151
157
|
return true;
|
|
152
158
|
}
|
|
153
159
|
process.env.SWC_NODE_PROJECT ??= configPath;
|
|
160
|
+
process.env.TSIMP_PROJECT ??= configPath;
|
|
154
161
|
process.env.MIKRO_ORM_CLI_ALWAYS_ALLOW_TS ??= '1';
|
|
155
|
-
const
|
|
156
|
-
/* v8 ignore next
|
|
157
|
-
const importMethod =
|
|
158
|
-
const
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
162
|
+
const isEsm = this.isESM();
|
|
163
|
+
/* v8 ignore next */
|
|
164
|
+
const importMethod = isEsm ? 'tryImport' : 'tryRequire';
|
|
165
|
+
const explicitLoader = tsLoader ?? process.env.MIKRO_ORM_CLI_TS_LOADER ?? 'auto';
|
|
166
|
+
const loaders = {
|
|
167
|
+
swc: { esm: '@swc-node/register/esm-register', cjs: '@swc-node/register' },
|
|
168
|
+
tsx: { esm: 'tsx/esm/api', cjs: 'tsx/cjs/api', cb: (tsx) => tsx.register({ tsconfig: configPath }) },
|
|
169
|
+
jiti: { esm: 'jiti/register', cjs: 'jiti/register', cb: () => Utils.setDynamicImportProvider(id => import(id).then(mod => mod?.default ?? mod)) },
|
|
170
|
+
tsimp: { esm: 'tsimp/import', cjs: 'tsimp/import' },
|
|
171
|
+
};
|
|
172
|
+
for (const loader of Utils.keys(loaders)) {
|
|
173
|
+
if (explicitLoader !== 'auto' && loader !== explicitLoader) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
const { esm, cjs, cb } = loaders[loader];
|
|
177
|
+
/* v8 ignore next */
|
|
178
|
+
const module = isEsm ? esm : cjs;
|
|
179
|
+
const mod = await Utils[importMethod]({ module });
|
|
180
|
+
if (mod) {
|
|
181
|
+
cb?.(mod);
|
|
182
|
+
process.env.MIKRO_ORM_CLI_TS_LOADER = loader;
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// eslint-disable-next-line no-console
|
|
187
|
+
console.warn('Neither `swc`, `tsx`, `jiti` nor `tsimp` found in the project dependencies, support for working with TypeScript files might not work. To use `swc`, you need to install both `@swc-node/register` and `@swc/core`.');
|
|
188
|
+
return false;
|
|
164
189
|
}
|
|
165
190
|
static registerDotenv(options) {
|
|
166
191
|
const path = process.env.MIKRO_ORM_ENV ?? ((options.baseDir ?? process.cwd()) + '/.env');
|
|
@@ -8,7 +8,6 @@ export class RawQueryFragment {
|
|
|
8
8
|
static #storage = new AsyncLocalStorage();
|
|
9
9
|
static #index = 0n;
|
|
10
10
|
static cloneRegistry;
|
|
11
|
-
#assigned = false;
|
|
12
11
|
#used = 0;
|
|
13
12
|
#key;
|
|
14
13
|
constructor(sql, params = []) {
|
|
@@ -17,11 +16,6 @@ export class RawQueryFragment {
|
|
|
17
16
|
this.#key = `[raw]: ${this.sql} (#${RawQueryFragment.#index++})`;
|
|
18
17
|
}
|
|
19
18
|
as(alias) {
|
|
20
|
-
// TODO: to be removed in v7
|
|
21
|
-
/* v8 ignore next 3 */
|
|
22
|
-
if (alias.startsWith('`') || alias.startsWith('"')) {
|
|
23
|
-
return new RawQueryFragment(`${this.sql} as ${alias}`, this.params);
|
|
24
|
-
}
|
|
25
19
|
return new RawQueryFragment(`${this.sql} as ??`, [...this.params, alias]);
|
|
26
20
|
}
|
|
27
21
|
valueOf() {
|
|
@@ -35,13 +29,6 @@ export class RawQueryFragment {
|
|
|
35
29
|
this.#used++;
|
|
36
30
|
return this.#key;
|
|
37
31
|
}
|
|
38
|
-
/** @internal */
|
|
39
|
-
assign() {
|
|
40
|
-
if (this.#assigned) {
|
|
41
|
-
throw new Error(`Cannot reassign already used RawQueryFragment: '${this.sql}'`);
|
|
42
|
-
}
|
|
43
|
-
this.#assigned = true;
|
|
44
|
-
}
|
|
45
32
|
clone() {
|
|
46
33
|
RawQueryFragment.cloneRegistry?.add(this.#key);
|
|
47
34
|
return new RawQueryFragment(this.sql, this.params);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TransactionPropagation } from '../enums.js';
|
|
1
|
+
import { ReferenceKind, TransactionPropagation } from '../enums.js';
|
|
2
2
|
import { TransactionEventBroadcaster } from '../events/TransactionEventBroadcaster.js';
|
|
3
3
|
import { TransactionContext } from '../utils/TransactionContext.js';
|
|
4
4
|
import { ChangeSetType } from '../unit-of-work/ChangeSet.js';
|
|
@@ -164,8 +164,13 @@ export class TransactionManager {
|
|
|
164
164
|
const parentEntity = parentUoW.getById(meta.className, wrapped.getPrimaryKey(), parent['_schema'], true);
|
|
165
165
|
if (parentEntity && parentEntity !== entity) {
|
|
166
166
|
const parentWrapped = helper(parentEntity);
|
|
167
|
-
parentWrapped.__data =
|
|
168
|
-
parentWrapped.__originalEntityData =
|
|
167
|
+
parentWrapped.__data = wrapped.__data;
|
|
168
|
+
parentWrapped.__originalEntityData = wrapped.__originalEntityData;
|
|
169
|
+
for (const prop of meta.hydrateProps) {
|
|
170
|
+
if (prop.kind === ReferenceKind.SCALAR) {
|
|
171
|
+
parentEntity[prop.name] = entity[prop.name];
|
|
172
|
+
}
|
|
173
|
+
}
|
|
169
174
|
}
|
|
170
175
|
else {
|
|
171
176
|
parentUoW.merge(entity, new Set([entity]));
|
package/utils/Utils.d.ts
CHANGED
|
@@ -252,13 +252,13 @@ export declare class Utils {
|
|
|
252
252
|
static setPayloadProperty<T>(entity: EntityDictionary<T>, meta: EntityMetadata<T>, prop: EntityProperty<T>, value: unknown, idx: number[]): void;
|
|
253
253
|
static tryRequire<T extends Dictionary = any>({ module, from, allowError, warning }: {
|
|
254
254
|
module: string;
|
|
255
|
-
warning
|
|
255
|
+
warning?: string;
|
|
256
256
|
from?: string;
|
|
257
257
|
allowError?: string;
|
|
258
258
|
}): T | undefined;
|
|
259
259
|
static tryImport<T extends Dictionary = any>({ module, warning }: {
|
|
260
260
|
module: string;
|
|
261
|
-
warning
|
|
261
|
+
warning?: string;
|
|
262
262
|
}): Promise<T | undefined>;
|
|
263
263
|
static stripRelativePath(str: string): string;
|
|
264
264
|
static xor(a: boolean, b: boolean): boolean;
|
package/utils/Utils.js
CHANGED
|
@@ -1075,8 +1075,10 @@ export class Utils {
|
|
|
1075
1075
|
}
|
|
1076
1076
|
catch (err) {
|
|
1077
1077
|
if (err.message.includes(allowError)) {
|
|
1078
|
-
|
|
1079
|
-
|
|
1078
|
+
if (warning) {
|
|
1079
|
+
// eslint-disable-next-line no-console
|
|
1080
|
+
console.warn(warning);
|
|
1081
|
+
}
|
|
1080
1082
|
return undefined;
|
|
1081
1083
|
}
|
|
1082
1084
|
throw err;
|
|
@@ -1088,8 +1090,10 @@ export class Utils {
|
|
|
1088
1090
|
}
|
|
1089
1091
|
catch (err) {
|
|
1090
1092
|
if (err.code === 'ERR_MODULE_NOT_FOUND') {
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
+
if (warning) {
|
|
1094
|
+
// eslint-disable-next-line no-console
|
|
1095
|
+
console.warn(warning);
|
|
1096
|
+
}
|
|
1093
1097
|
return undefined;
|
|
1094
1098
|
}
|
|
1095
1099
|
throw err;
|