@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.
@@ -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, MaybePromise, MergeLoaded, MergeSelected, NoInfer, ObjectQuery, Primary, Ref, RequiredEntityData, UnboxArray } from './typings.js';
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<T1>(name: string, cond: FilterQuery<T1> | ((args: Dictionary) => MaybePromise<FilterQuery<T1>>), entityName?: EntityName<T1> | [EntityName<T1>], options?: boolean | Partial<FilterDef>): void;
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(name, cond, entityName, options = true) {
263
- options = typeof options === 'object' ? { name, cond, default: true, ...options } : { name, cond, default: options };
264
- if (entityName) {
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
- this.getContext(false).filters[name] = options;
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.
@@ -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>)[]): void;
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>)[]): void;
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 modified = false;
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
- modified = true;
143
+ removed++;
141
144
  }
142
145
  }
143
- if (modified) {
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
@@ -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>>>;
@@ -6,9 +6,6 @@ export class BaseEntity {
6
6
  isInitialized() {
7
7
  return helper(this).__initialized;
8
8
  }
9
- isTouched() {
10
- return helper(this).__touched;
11
- }
12
9
  populated(populated = true) {
13
10
  helper(this).populated(populated);
14
11
  }
@@ -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>)[]): void;
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>)[]): void;
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;
@@ -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 { ReferenceKind, DataloaderType } from '../enums.js';
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
- this.setDirty();
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()) {
@@ -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;
@@ -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.trackChanges === false || prop.embedded || isCollection) {
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)); // .sort((a, b) => (meta.propertyOrder.get(a) ?? 0) - (meta.propertyOrder.get(b) ?? 0));
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;
@@ -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
  }
@@ -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
  */
@@ -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.43",
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.43",
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 keys = new Set(meta.primaryKeys);
45
- Utils.keys(entity).forEach(prop => keys.add(prop));
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 keys) {
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 keys = new Set();
30
+ const props = new Set();
31
31
  if (meta.serializedPrimaryKey && !meta.compositePK) {
32
- keys.add(meta.serializedPrimaryKey);
32
+ props.add(meta.serializedPrimaryKey);
33
33
  }
34
34
  else {
35
- meta.primaryKeys.forEach(pk => keys.add(pk));
35
+ meta.primaryKeys.forEach(pk => props.add(pk));
36
36
  }
37
37
  if (wrapped.isInitialized() || !wrapped.hasPrimaryKey()) {
38
- Utils.keys(entity).forEach(prop => keys.add(prop));
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 keys) {
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<any, any, any, any> | FindOneOptions<any, any, any, any>, entityName?: EntityName<any>) => Dictionary | Promise<Dictionary>);
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?: string[];
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
- .filter(prop => !prop.getter && !prop.setter && prop.trackChanges !== false)
95
- .filter(prop => ![ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind))
96
- .filter(prop => !prop.serializedPrimaryKey);
97
- this.selfReferencing = this.relations.some(prop => [this.className, this.root.className].includes(prop.targetMeta?.root.className ?? prop.type));
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 isCollection = [ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind);
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 && !wrapped.isTouched()) {
38
- return null;
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) {
@@ -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: "decorators";
122
- enumMode: "ts-enum";
121
+ entityDefinition: "defineEntity";
122
+ enumMode: "dictionary";
123
123
  fileName: (className: string) => string;
124
124
  onlyPurePivotTables: false;
125
125
  outputPurePivotTables: false;
@@ -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: 'decorators',
112
- enumMode: 'ts-enum',
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
- static registerTypeScriptSupport(configPath?: string): Promise<boolean>;
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
- static async registerTypeScriptSupport(configPath = 'tsconfig.json') {
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 esm = this.isESM();
156
- /* v8 ignore next 2 */
157
- const importMethod = esm ? 'tryImport' : 'tryRequire';
158
- const module = esm ? '@swc-node/register/esm-register' : '@swc-node/register';
159
- const supported = await Utils[importMethod]({
160
- module,
161
- warning: '@swc-node/register and @swc/core are not installed, support for working with TypeScript files might not work',
162
- });
163
- return !!supported;
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');
@@ -10,8 +10,6 @@ export declare class RawQueryFragment {
10
10
  valueOf(): string;
11
11
  toJSON(): string;
12
12
  toString(): string;
13
- /** @internal */
14
- assign(): void;
15
13
  clone(): RawQueryFragment;
16
14
  static run<T>(cb: (...args: any[]) => Promise<T>): Promise<T>;
17
15
  /**
@@ -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 = helper(entity).__data;
168
- parentWrapped.__originalEntityData = helper(entity).__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: string;
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: string;
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
- // eslint-disable-next-line no-console
1079
- console.warn(warning);
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
- // eslint-disable-next-line no-console
1092
- console.warn(warning);
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;