@mikro-orm/core 7.0.0-dev.29 → 7.0.0-dev.291

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.
Files changed (209) hide show
  1. package/EntityManager.d.ts +67 -60
  2. package/EntityManager.js +275 -257
  3. package/MikroORM.d.ts +44 -35
  4. package/MikroORM.js +109 -142
  5. package/README.md +2 -0
  6. package/cache/FileCacheAdapter.d.ts +1 -2
  7. package/cache/FileCacheAdapter.js +18 -11
  8. package/cache/GeneratedCacheAdapter.d.ts +0 -1
  9. package/cache/GeneratedCacheAdapter.js +0 -2
  10. package/cache/index.d.ts +0 -1
  11. package/cache/index.js +0 -1
  12. package/connections/Connection.d.ts +12 -5
  13. package/connections/Connection.js +21 -12
  14. package/drivers/DatabaseDriver.d.ts +25 -16
  15. package/drivers/DatabaseDriver.js +118 -35
  16. package/drivers/IDatabaseDriver.d.ts +75 -23
  17. package/entity/BaseEntity.d.ts +63 -4
  18. package/entity/BaseEntity.js +0 -3
  19. package/entity/Collection.d.ts +101 -29
  20. package/entity/Collection.js +436 -104
  21. package/entity/EntityAssigner.js +17 -17
  22. package/entity/EntityFactory.d.ts +7 -1
  23. package/entity/EntityFactory.js +87 -55
  24. package/entity/EntityHelper.d.ts +2 -2
  25. package/entity/EntityHelper.js +50 -17
  26. package/entity/EntityLoader.d.ts +11 -10
  27. package/entity/EntityLoader.js +213 -82
  28. package/entity/EntityRepository.d.ts +28 -8
  29. package/entity/EntityRepository.js +8 -2
  30. package/entity/PolymorphicRef.d.ts +12 -0
  31. package/entity/PolymorphicRef.js +18 -0
  32. package/entity/Reference.d.ts +1 -5
  33. package/entity/Reference.js +15 -11
  34. package/entity/WrappedEntity.d.ts +3 -8
  35. package/entity/WrappedEntity.js +2 -7
  36. package/entity/defineEntity.d.ts +526 -310
  37. package/entity/defineEntity.js +134 -290
  38. package/entity/index.d.ts +2 -2
  39. package/entity/index.js +2 -2
  40. package/entity/utils.d.ts +6 -1
  41. package/entity/utils.js +34 -1
  42. package/entity/validators.d.ts +11 -0
  43. package/entity/validators.js +65 -0
  44. package/enums.d.ts +8 -6
  45. package/enums.js +2 -1
  46. package/errors.d.ts +20 -10
  47. package/errors.js +55 -23
  48. package/events/EventManager.d.ts +2 -1
  49. package/events/EventManager.js +19 -11
  50. package/hydration/Hydrator.js +1 -2
  51. package/hydration/ObjectHydrator.d.ts +4 -4
  52. package/hydration/ObjectHydrator.js +79 -34
  53. package/index.d.ts +2 -2
  54. package/index.js +1 -2
  55. package/logging/DefaultLogger.d.ts +1 -1
  56. package/logging/DefaultLogger.js +1 -0
  57. package/logging/SimpleLogger.d.ts +1 -1
  58. package/logging/colors.d.ts +1 -1
  59. package/logging/colors.js +7 -6
  60. package/logging/index.d.ts +1 -0
  61. package/logging/index.js +1 -0
  62. package/logging/inspect.d.ts +2 -0
  63. package/logging/inspect.js +11 -0
  64. package/metadata/EntitySchema.d.ts +47 -23
  65. package/metadata/EntitySchema.js +92 -33
  66. package/metadata/MetadataDiscovery.d.ts +64 -9
  67. package/metadata/MetadataDiscovery.js +782 -325
  68. package/metadata/MetadataProvider.d.ts +11 -2
  69. package/metadata/MetadataProvider.js +66 -2
  70. package/metadata/MetadataStorage.d.ts +13 -11
  71. package/metadata/MetadataStorage.js +72 -39
  72. package/metadata/MetadataValidator.d.ts +32 -9
  73. package/metadata/MetadataValidator.js +196 -41
  74. package/metadata/discover-entities.d.ts +5 -0
  75. package/metadata/discover-entities.js +40 -0
  76. package/metadata/index.d.ts +1 -1
  77. package/metadata/index.js +1 -1
  78. package/metadata/types.d.ts +577 -0
  79. package/metadata/types.js +1 -0
  80. package/naming-strategy/AbstractNamingStrategy.d.ts +16 -4
  81. package/naming-strategy/AbstractNamingStrategy.js +20 -2
  82. package/naming-strategy/EntityCaseNamingStrategy.d.ts +3 -3
  83. package/naming-strategy/EntityCaseNamingStrategy.js +6 -5
  84. package/naming-strategy/MongoNamingStrategy.d.ts +3 -3
  85. package/naming-strategy/MongoNamingStrategy.js +6 -6
  86. package/naming-strategy/NamingStrategy.d.ts +28 -4
  87. package/naming-strategy/UnderscoreNamingStrategy.d.ts +3 -3
  88. package/naming-strategy/UnderscoreNamingStrategy.js +6 -6
  89. package/not-supported.d.ts +2 -0
  90. package/not-supported.js +4 -0
  91. package/package.json +22 -11
  92. package/platforms/ExceptionConverter.js +1 -1
  93. package/platforms/Platform.d.ts +10 -15
  94. package/platforms/Platform.js +21 -44
  95. package/serialization/EntitySerializer.d.ts +6 -3
  96. package/serialization/EntitySerializer.js +46 -26
  97. package/serialization/EntityTransformer.js +33 -21
  98. package/serialization/SerializationContext.d.ts +6 -6
  99. package/serialization/SerializationContext.js +3 -3
  100. package/types/ArrayType.d.ts +1 -1
  101. package/types/ArrayType.js +2 -3
  102. package/types/BigIntType.js +1 -1
  103. package/types/BlobType.d.ts +0 -1
  104. package/types/BlobType.js +0 -3
  105. package/types/BooleanType.d.ts +1 -0
  106. package/types/BooleanType.js +3 -0
  107. package/types/DecimalType.js +2 -2
  108. package/types/DoubleType.js +1 -1
  109. package/types/EnumArrayType.js +1 -2
  110. package/types/JsonType.d.ts +1 -1
  111. package/types/JsonType.js +7 -2
  112. package/types/TinyIntType.js +1 -1
  113. package/types/Type.d.ts +2 -4
  114. package/types/Type.js +3 -3
  115. package/types/Uint8ArrayType.d.ts +0 -1
  116. package/types/Uint8ArrayType.js +1 -4
  117. package/types/index.d.ts +1 -1
  118. package/typings.d.ts +412 -155
  119. package/typings.js +99 -44
  120. package/unit-of-work/ChangeSet.d.ts +4 -6
  121. package/unit-of-work/ChangeSet.js +4 -5
  122. package/unit-of-work/ChangeSetComputer.d.ts +3 -8
  123. package/unit-of-work/ChangeSetComputer.js +41 -20
  124. package/unit-of-work/ChangeSetPersister.d.ts +13 -12
  125. package/unit-of-work/ChangeSetPersister.js +94 -36
  126. package/unit-of-work/CommitOrderCalculator.d.ts +12 -10
  127. package/unit-of-work/CommitOrderCalculator.js +13 -13
  128. package/unit-of-work/IdentityMap.d.ts +12 -0
  129. package/unit-of-work/IdentityMap.js +39 -1
  130. package/unit-of-work/UnitOfWork.d.ts +27 -3
  131. package/unit-of-work/UnitOfWork.js +248 -90
  132. package/utils/AbstractMigrator.d.ts +101 -0
  133. package/utils/AbstractMigrator.js +305 -0
  134. package/utils/AbstractSchemaGenerator.d.ts +5 -5
  135. package/utils/AbstractSchemaGenerator.js +28 -17
  136. package/utils/AsyncContext.d.ts +6 -0
  137. package/utils/AsyncContext.js +42 -0
  138. package/utils/Configuration.d.ts +795 -211
  139. package/utils/Configuration.js +153 -194
  140. package/utils/ConfigurationLoader.d.ts +1 -52
  141. package/utils/ConfigurationLoader.js +1 -330
  142. package/utils/Cursor.d.ts +0 -3
  143. package/utils/Cursor.js +24 -11
  144. package/utils/DataloaderUtils.d.ts +10 -5
  145. package/utils/DataloaderUtils.js +29 -12
  146. package/utils/EntityComparator.d.ts +16 -9
  147. package/utils/EntityComparator.js +154 -56
  148. package/utils/QueryHelper.d.ts +18 -6
  149. package/utils/QueryHelper.js +76 -23
  150. package/utils/RawQueryFragment.d.ts +28 -34
  151. package/utils/RawQueryFragment.js +35 -71
  152. package/utils/RequestContext.js +2 -2
  153. package/utils/TransactionContext.js +2 -2
  154. package/utils/TransactionManager.js +9 -6
  155. package/utils/Utils.d.ts +15 -126
  156. package/utils/Utils.js +80 -382
  157. package/utils/clone.js +8 -23
  158. package/utils/env-vars.d.ts +7 -0
  159. package/utils/env-vars.js +97 -0
  160. package/utils/fs-utils.d.ts +34 -0
  161. package/utils/fs-utils.js +196 -0
  162. package/utils/index.d.ts +1 -3
  163. package/utils/index.js +1 -3
  164. package/utils/upsert-utils.d.ts +9 -4
  165. package/utils/upsert-utils.js +46 -3
  166. package/decorators/Check.d.ts +0 -3
  167. package/decorators/Check.js +0 -13
  168. package/decorators/CreateRequestContext.d.ts +0 -3
  169. package/decorators/CreateRequestContext.js +0 -32
  170. package/decorators/Embeddable.d.ts +0 -8
  171. package/decorators/Embeddable.js +0 -11
  172. package/decorators/Embedded.d.ts +0 -12
  173. package/decorators/Embedded.js +0 -18
  174. package/decorators/Entity.d.ts +0 -33
  175. package/decorators/Entity.js +0 -12
  176. package/decorators/Enum.d.ts +0 -9
  177. package/decorators/Enum.js +0 -16
  178. package/decorators/Filter.d.ts +0 -2
  179. package/decorators/Filter.js +0 -8
  180. package/decorators/Formula.d.ts +0 -4
  181. package/decorators/Formula.js +0 -15
  182. package/decorators/Indexed.d.ts +0 -19
  183. package/decorators/Indexed.js +0 -20
  184. package/decorators/ManyToMany.d.ts +0 -42
  185. package/decorators/ManyToMany.js +0 -14
  186. package/decorators/ManyToOne.d.ts +0 -34
  187. package/decorators/ManyToOne.js +0 -14
  188. package/decorators/OneToMany.d.ts +0 -28
  189. package/decorators/OneToMany.js +0 -17
  190. package/decorators/OneToOne.d.ts +0 -28
  191. package/decorators/OneToOne.js +0 -7
  192. package/decorators/PrimaryKey.d.ts +0 -8
  193. package/decorators/PrimaryKey.js +0 -20
  194. package/decorators/Property.d.ts +0 -250
  195. package/decorators/Property.js +0 -32
  196. package/decorators/Transactional.d.ts +0 -14
  197. package/decorators/Transactional.js +0 -28
  198. package/decorators/hooks.d.ts +0 -16
  199. package/decorators/hooks.js +0 -47
  200. package/decorators/index.d.ts +0 -17
  201. package/decorators/index.js +0 -17
  202. package/entity/ArrayCollection.d.ts +0 -118
  203. package/entity/ArrayCollection.js +0 -407
  204. package/entity/EntityValidator.d.ts +0 -19
  205. package/entity/EntityValidator.js +0 -150
  206. package/metadata/ReflectMetadataProvider.d.ts +0 -8
  207. package/metadata/ReflectMetadataProvider.js +0 -44
  208. package/utils/resolveContextProvider.d.ts +0 -10
  209. package/utils/resolveContextProvider.js +0 -28
@@ -1,12 +1,11 @@
1
- import { inspect } from 'node:util';
2
1
  import { Collection } from './Collection.js';
3
2
  import { Utils } from '../utils/Utils.js';
4
3
  import { Reference } from './Reference.js';
5
4
  import { ReferenceKind, SCALAR_TYPES } from '../enums.js';
6
- import { EntityValidator } from './EntityValidator.js';
5
+ import { validateProperty } from './validators.js';
7
6
  import { helper, wrap } from './wrap.js';
8
7
  import { EntityHelper } from './EntityHelper.js';
9
- const validator = new EntityValidator(false);
8
+ import { ValidationError } from '../errors.js';
10
9
  export class EntityAssigner {
11
10
  static assign(entity, data, options = {}) {
12
11
  let opts = options;
@@ -78,7 +77,7 @@ export class EntityAssigner {
78
77
  if (options.updateByPrimaryKey) {
79
78
  const pk = Utils.extractPK(value, prop.targetMeta);
80
79
  if (pk) {
81
- const ref = options.em.getReference(prop.type, pk, options);
80
+ const ref = options.em.getReference(prop.targetMeta.class, pk, options);
82
81
  // if the PK differs, we want to change the target entity, not update it
83
82
  const wrappedChild = helper(ref);
84
83
  const sameTarget = wrappedChild.getSerializedPrimaryKey() === wrapped.getSerializedPrimaryKey();
@@ -94,8 +93,9 @@ export class EntityAssigner {
94
93
  }
95
94
  return EntityAssigner.assignReference(entity, value, prop, options.em, options);
96
95
  }
97
- if (prop.kind === ReferenceKind.SCALAR && SCALAR_TYPES.includes(prop.runtimeType) && (prop.setter || !prop.getter)) {
98
- return entity[prop.name] = validator.validateProperty(prop, value, entity);
96
+ if (prop.kind === ReferenceKind.SCALAR && SCALAR_TYPES.has(prop.runtimeType) && (prop.setter || !prop.getter)) {
97
+ validateProperty(prop, value, entity);
98
+ return entity[prop.name] = value;
99
99
  }
100
100
  if (prop.kind === ReferenceKind.EMBEDDED && EntityAssigner.validateEM(options.em)) {
101
101
  return EntityAssigner.assignEmbeddable(entity, value, prop, options.em, options);
@@ -120,7 +120,7 @@ export class EntityAssigner {
120
120
  }
121
121
  const meta2 = helper(ref).__meta;
122
122
  const prop2 = meta2.properties[prop.inversedBy || prop.mappedBy];
123
- /* v8 ignore next 7 */
123
+ /* v8 ignore next */
124
124
  if (prop2 && !ref[prop2.name]) {
125
125
  if (Reference.isReference(ref)) {
126
126
  ref.unwrap()[prop2.name] = Reference.wrapReference(entity, prop2);
@@ -141,13 +141,13 @@ export class EntityAssigner {
141
141
  entity[prop.name] = Reference.wrapReference(value, prop);
142
142
  }
143
143
  else if (Utils.isPrimaryKey(value, true) && EntityAssigner.validateEM(em)) {
144
- entity[prop.name] = prop.mapToPk ? value : Reference.wrapReference(em.getReference(prop.type, value, options), prop);
144
+ entity[prop.name] = prop.mapToPk ? value : Reference.wrapReference(em.getReference(prop.targetMeta.class, value, options), prop);
145
145
  }
146
146
  else if (Utils.isPlainObject(value) && options.merge && EntityAssigner.validateEM(em)) {
147
- entity[prop.name] = Reference.wrapReference(em.merge(prop.type, value, options), prop);
147
+ entity[prop.name] = Reference.wrapReference(em.merge(prop.targetMeta.class, value, options), prop);
148
148
  }
149
149
  else if (Utils.isPlainObject(value) && EntityAssigner.validateEM(em)) {
150
- entity[prop.name] = Reference.wrapReference(em.create(prop.type, value, options), prop);
150
+ entity[prop.name] = Reference.wrapReference(em.create(prop.targetMeta.class, value, options), prop);
151
151
  }
152
152
  else {
153
153
  const name = entity.constructor.name;
@@ -166,14 +166,14 @@ export class EntityAssigner {
166
166
  if (options.updateNestedEntities && options.updateByPrimaryKey && Utils.isPlainObject(item)) {
167
167
  const pk = Utils.extractPK(item, prop.targetMeta);
168
168
  if (pk && EntityAssigner.validateEM(em)) {
169
- const ref = em.getUnitOfWork().getById(prop.type, pk, options.schema);
169
+ const ref = em.getUnitOfWork().getById(prop.targetMeta.class, pk, options.schema);
170
170
  if (ref) {
171
171
  return EntityAssigner.assign(ref, item, options);
172
172
  }
173
173
  }
174
174
  return this.createCollectionItem(item, em, prop, invalid, options);
175
175
  }
176
- /* v8 ignore next 3 */
176
+ /* v8 ignore next */
177
177
  if (options.updateNestedEntities && !options.updateByPrimaryKey && collection[idx] && helper(collection[idx])?.isInitialized()) {
178
178
  return EntityAssigner.assign(collection[idx], item, options);
179
179
  }
@@ -181,7 +181,7 @@ export class EntityAssigner {
181
181
  });
182
182
  if (invalid.length > 0) {
183
183
  const name = entity.constructor.name;
184
- throw new Error(`Invalid collection values provided for '${name}.${prop.name}' in ${name}.assign(): ${inspect(invalid)}`);
184
+ throw ValidationError.invalidCollectionValues(name, prop.name, invalid);
185
185
  }
186
186
  if (Array.isArray(value)) {
187
187
  collection.set(items);
@@ -207,7 +207,7 @@ export class EntityAssigner {
207
207
  entity[propName].push(...Object.values(tmp));
208
208
  });
209
209
  }
210
- const create = () => EntityAssigner.validateEM(em) && em.getEntityFactory().createEmbeddable(prop.type, value, {
210
+ const create = () => EntityAssigner.validateEM(em) && em.getEntityFactory().createEmbeddable(prop.targetMeta.class, value, {
211
211
  convertCustomTypes: options.convertCustomTypes,
212
212
  newEntity: options.mergeEmbeddedProperties ? !('propName' in entity) : true,
213
213
  });
@@ -221,13 +221,13 @@ export class EntityAssigner {
221
221
  return item;
222
222
  }
223
223
  if (Utils.isPrimaryKey(item) && EntityAssigner.validateEM(em)) {
224
- return em.getReference(prop.type, item, options);
224
+ return em.getReference(prop.targetMeta.class, item, options);
225
225
  }
226
226
  if (Utils.isPlainObject(item) && options.merge && EntityAssigner.validateEM(em)) {
227
- return em.merge(prop.type, item, options);
227
+ return em.merge(prop.targetMeta.class, item, options);
228
228
  }
229
229
  if (Utils.isPlainObject(item) && EntityAssigner.validateEM(em)) {
230
- return em.create(prop.type, item, options);
230
+ return em.create(prop.targetMeta.class, item, options);
231
231
  }
232
232
  invalid.push(item);
233
233
  return item;
@@ -15,6 +15,12 @@ export interface FactoryOptions {
15
15
  recomputeSnapshot?: boolean;
16
16
  schema?: string;
17
17
  parentSchema?: string;
18
+ normalizeAccessors?: boolean;
19
+ /**
20
+ * Property name to use for identity map lookup instead of the primary key.
21
+ * This is useful for creating references by unique non-PK properties.
22
+ */
23
+ key?: string;
18
24
  }
19
25
  export declare class EntityFactory {
20
26
  private readonly em;
@@ -28,7 +34,7 @@ export declare class EntityFactory {
28
34
  constructor(em: EntityManager);
29
35
  create<T extends object, P extends string = string>(entityName: EntityName<T>, data: EntityData<T>, options?: FactoryOptions): New<T, P>;
30
36
  mergeData<T extends object>(meta: EntityMetadata<T>, entity: T, data: EntityData<T>, options?: FactoryOptions): void;
31
- createReference<T extends object>(entityName: EntityName<T>, id: Primary<T> | Primary<T>[] | Record<string, Primary<T>>, options?: Pick<FactoryOptions, 'merge' | 'convertCustomTypes' | 'schema'>): T;
37
+ createReference<T extends object>(entityName: EntityName<T>, id: Primary<T> | Primary<T>[] | Record<string, Primary<T>>, options?: Pick<FactoryOptions, 'merge' | 'convertCustomTypes' | 'schema' | 'key'>): T;
32
38
  createEmbeddable<T extends object>(entityName: EntityName<T>, data: EntityData<T>, options?: Pick<FactoryOptions, 'newEntity' | 'convertCustomTypes'>): T;
33
39
  getComparator(): EntityComparator;
34
40
  private createEntity;
@@ -4,6 +4,7 @@ import { EventType, ReferenceKind } from '../enums.js';
4
4
  import { Reference } from './Reference.js';
5
5
  import { helper } from './wrap.js';
6
6
  import { EntityHelper } from './EntityHelper.js';
7
+ import { JsonType } from '../types/JsonType.js';
7
8
  export class EntityFactory {
8
9
  em;
9
10
  driver;
@@ -29,7 +30,6 @@ export class EntityFactory {
29
30
  if (data.__entity) {
30
31
  return data;
31
32
  }
32
- entityName = Utils.className(entityName);
33
33
  const meta = this.metadata.get(entityName);
34
34
  if (meta.virtual) {
35
35
  data = { ...data };
@@ -37,8 +37,8 @@ export class EntityFactory {
37
37
  this.hydrate(entity, meta, data, options);
38
38
  return entity;
39
39
  }
40
- if (this.platform.usesDifferentSerializedPrimaryKey()) {
41
- meta.primaryKeys.forEach(pk => this.denormalizePrimaryKey(data, pk, meta.properties[pk]));
40
+ if (meta.serializedPrimaryKey) {
41
+ this.denormalizePrimaryKey(meta, data);
42
42
  }
43
43
  const meta2 = this.processDiscriminatorColumn(meta, data);
44
44
  const exists = this.findEntity(data, meta2, options);
@@ -59,7 +59,7 @@ export class EntityFactory {
59
59
  wrapped.__initialized = options.initialized;
60
60
  if (options.newEntity || meta.forceConstructor || meta.virtual) {
61
61
  const tmp = { ...data };
62
- meta.constructorParams.forEach(prop => delete tmp[prop]);
62
+ meta.constructorParams?.forEach(prop => delete tmp[prop]);
63
63
  this.hydrate(entity, meta2, tmp, options);
64
64
  // since we now process only a copy of the `data` via hydrator, but later we register the state with the full snapshot,
65
65
  // we need to go through all props with custom types that have `ensureComparable: true` and ensure they are comparable
@@ -73,7 +73,9 @@ export class EntityFactory {
73
73
  if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name])) {
74
74
  data[prop.name] = Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta, true);
75
75
  }
76
- data[prop.name] = prop.customType.convertToDatabaseValue(data[prop.name], this.platform, { key: prop.name, mode: 'hydration' });
76
+ if (prop.customType instanceof JsonType && this.platform.convertsJsonAutomatically()) {
77
+ data[prop.name] = prop.customType.convertToDatabaseValue(data[prop.name], this.platform, { key: prop.name, mode: 'hydration' });
78
+ }
77
79
  }
78
80
  }
79
81
  }
@@ -81,8 +83,7 @@ export class EntityFactory {
81
83
  else {
82
84
  this.hydrate(entity, meta2, data, options);
83
85
  }
84
- wrapped.__touched = false;
85
- if (exists && meta.discriminatorColumn && !(entity instanceof meta2.class)) {
86
+ if (exists && meta.root.inheritanceType && !(entity instanceof meta2.class)) {
86
87
  Object.setPrototypeOf(entity, meta2.prototype);
87
88
  }
88
89
  if (options.merge && wrapped.hasPrimaryKey()) {
@@ -108,12 +109,12 @@ export class EntityFactory {
108
109
  data = QueryHelper.processParams(data);
109
110
  const existsData = this.comparator.prepareEntity(entity);
110
111
  const originalEntityData = helper(entity).__originalEntityData ?? {};
111
- const diff = this.comparator.diffEntities(meta.className, originalEntityData, existsData);
112
+ const diff = this.comparator.diffEntities(meta.class, originalEntityData, existsData);
112
113
  // version properties are not part of entity snapshots
113
114
  if (meta.versionProperty && data[meta.versionProperty] && data[meta.versionProperty] !== originalEntityData[meta.versionProperty]) {
114
115
  diff[meta.versionProperty] = data[meta.versionProperty];
115
116
  }
116
- const diff2 = this.comparator.diffEntities(meta.className, existsData, data, { includeInverseSides: true });
117
+ const diff2 = this.comparator.diffEntities(meta.class, existsData, data, { includeInverseSides: true });
117
118
  // do not override values changed by user
118
119
  Utils.keys(diff).forEach(key => delete diff2[key]);
119
120
  Utils.keys(diff2).filter(key => {
@@ -128,7 +129,10 @@ export class EntityFactory {
128
129
  .filter(key => meta.properties[key]?.formula || [ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(meta.properties[key]?.kind))
129
130
  .forEach(key => diff2[key] = data[key]);
130
131
  // rehydrated with the new values, skip those changed by user
131
- this.hydrate(entity, meta, diff2, options);
132
+ // use full hydration if the entity is already initialized, even if the caller used `initialized: false`
133
+ // (e.g. from createReference), otherwise scalar properties in diff2 won't be applied
134
+ const initialized = options.initialized || helper(entity).__initialized;
135
+ this.hydrate(entity, meta, diff2, initialized ? { ...options, initialized } : options);
132
136
  // we need to update the entity data only with keys that were not present before
133
137
  const nullVal = this.config.get('forceUndefined') ? undefined : null;
134
138
  Utils.keys(diff2).forEach(key => {
@@ -136,6 +140,10 @@ export class EntityFactory {
136
140
  if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name])) {
137
141
  diff2[key] = entity[prop.name] ? helper(entity[prop.name]).getPrimaryKey(options.convertCustomTypes) : null;
138
142
  }
143
+ if (!options.convertCustomTypes && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE, ReferenceKind.SCALAR].includes(prop.kind) && prop.customType?.ensureComparable(meta, prop) && diff2[key] != null) {
144
+ const converted = prop.customType.convertToJSValue(diff2[key], this.platform, { force: true });
145
+ diff2[key] = prop.customType.convertToDatabaseValue(converted, this.platform, { fromQuery: true });
146
+ }
139
147
  originalEntityData[key] = diff2[key] === null ? nullVal : diff2[key];
140
148
  helper(entity).__loadedProperties.add(key);
141
149
  });
@@ -146,20 +154,31 @@ export class EntityFactory {
146
154
  // we just create the entity from scratch, which will automatically pick the right one from the identity map and call `mergeData` on it
147
155
  data[prop.name]
148
156
  .filter(child => Utils.isPlainObject(child)) // objects with prototype can be PKs (e.g. `ObjectId`)
149
- .forEach(child => this.create(prop.type, child, options)); // we can ignore the value, we just care about the `mergeData` call
157
+ .forEach(child => this.create(prop.targetMeta.class, child, options)); // we can ignore the value, we just care about the `mergeData` call
150
158
  return;
151
159
  }
152
160
  if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name]) && entity[prop.name] && helper(entity[prop.name]).__initialized) {
153
- this.create(prop.type, data[prop.name], options); // we can ignore the value, we just care about the `mergeData` call
161
+ this.create(prop.targetMeta.class, data[prop.name], options); // we can ignore the value, we just care about the `mergeData` call
154
162
  }
155
163
  });
156
- helper(entity).__touched = false;
164
+ this.unitOfWork.normalizeEntityData(meta, originalEntityData);
157
165
  }
158
166
  createReference(entityName, id, options = {}) {
159
167
  options.convertCustomTypes ??= true;
160
- entityName = Utils.className(entityName);
161
168
  const meta = this.metadata.get(entityName);
162
169
  const schema = this.driver.getSchemaName(meta, options);
170
+ // Handle alternate key lookup
171
+ if (options.key) {
172
+ const value = '' + (Array.isArray(id) ? id[0] : Utils.isPlainObject(id) ? id[options.key] : id);
173
+ const exists = this.unitOfWork.getByKey(entityName, options.key, value, schema, options.convertCustomTypes);
174
+ if (exists) {
175
+ return exists;
176
+ }
177
+ // Create entity stub - storeByKey will set the alternate key property and store in identity map
178
+ const entity = this.create(entityName, {}, { ...options, initialized: false });
179
+ this.unitOfWork.storeByKey(entity, options.key, value, schema, options.convertCustomTypes);
180
+ return entity;
181
+ }
163
182
  if (meta.simplePK) {
164
183
  const exists = this.unitOfWork.getById(entityName, id, schema);
165
184
  if (exists) {
@@ -182,7 +201,6 @@ export class EntityFactory {
182
201
  return this.create(entityName, id, { ...options, initialized: false });
183
202
  }
184
203
  createEmbeddable(entityName, data, options = {}) {
185
- entityName = Utils.className(entityName);
186
204
  data = { ...data };
187
205
  const meta = this.metadata.get(entityName);
188
206
  const meta2 = this.processDiscriminatorColumn(meta, data);
@@ -194,7 +212,7 @@ export class EntityFactory {
194
212
  createEntity(data, meta, options) {
195
213
  const schema = this.driver.getSchemaName(meta, options);
196
214
  if (options.newEntity || meta.forceConstructor || meta.virtual) {
197
- if (!meta.class) {
215
+ if (meta.polymorphs) {
198
216
  throw new Error(`Cannot create entity ${meta.className}, class prototype is unknown`);
199
217
  }
200
218
  const params = this.extractConstructorParams(meta, data, options);
@@ -240,10 +258,10 @@ export class EntityFactory {
240
258
  }
241
259
  hydrate(entity, meta, data, options) {
242
260
  if (options.initialized) {
243
- this.hydrator.hydrate(entity, meta, data, this, 'full', options.newEntity, options.convertCustomTypes, options.schema, this.driver.getSchemaName(meta, options));
261
+ this.hydrator.hydrate(entity, meta, data, this, 'full', options.newEntity, options.convertCustomTypes, options.schema, this.driver.getSchemaName(meta, options), options.normalizeAccessors);
244
262
  }
245
263
  else {
246
- this.hydrator.hydrateReference(entity, meta, data, this, options.convertCustomTypes, options.schema, this.driver.getSchemaName(meta, options));
264
+ this.hydrator.hydrateReference(entity, meta, data, this, options.convertCustomTypes, options.schema, this.driver.getSchemaName(meta, options), options.normalizeAccessors);
247
265
  }
248
266
  Utils.keys(data).forEach(key => {
249
267
  helper(entity)?.__loadedProperties.add(key);
@@ -257,75 +275,89 @@ export class EntityFactory {
257
275
  findEntity(data, meta, options) {
258
276
  const schema = this.driver.getSchemaName(meta, options);
259
277
  if (meta.simplePK) {
260
- return this.unitOfWork.getById(meta.className, data[meta.primaryKeys[0]], schema);
278
+ return this.unitOfWork.getById(meta.class, data[meta.primaryKeys[0]], schema);
261
279
  }
262
280
  if (!Array.isArray(data) && meta.primaryKeys.some(pk => data[pk] == null)) {
263
281
  return undefined;
264
282
  }
265
283
  const pks = Utils.getOrderedPrimaryKeys(data, meta, this.platform, options.convertCustomTypes);
266
- return this.unitOfWork.getById(meta.className, pks, schema);
284
+ return this.unitOfWork.getById(meta.class, pks, schema);
267
285
  }
268
286
  processDiscriminatorColumn(meta, data) {
269
- if (!meta.root.discriminatorColumn) {
287
+ // Handle STI discriminator (persisted column)
288
+ if (meta.root.inheritanceType === 'sti') {
289
+ const prop = meta.properties[meta.root.discriminatorColumn];
290
+ const value = data[prop.name];
291
+ const type = meta.root.discriminatorMap[value];
292
+ meta = type ? this.metadata.get(type) : meta;
270
293
  return meta;
271
294
  }
272
- const prop = meta.properties[meta.root.discriminatorColumn];
273
- const value = data[prop.name];
274
- const type = meta.root.discriminatorMap[value];
275
- meta = type ? this.metadata.find(type) : meta;
295
+ // Handle TPT discriminator (computed at query time)
296
+ if (meta.root.inheritanceType === 'tpt' && meta.root.discriminatorMap) {
297
+ const value = data[meta.root.tptDiscriminatorColumn];
298
+ if (value) {
299
+ const type = meta.root.discriminatorMap[value];
300
+ meta = type ? this.metadata.get(type) : meta;
301
+ }
302
+ }
276
303
  return meta;
277
304
  }
278
305
  /**
279
306
  * denormalize PK to value required by driver (e.g. ObjectId)
280
307
  */
281
- denormalizePrimaryKey(data, primaryKey, prop) {
282
- const pk = this.platform.getSerializedPrimaryKeyField(primaryKey);
283
- if (data[pk] != null || data[primaryKey] != null) {
284
- let id = (data[pk] || data[primaryKey]);
285
- if (prop.type.toLowerCase() === 'objectid') {
286
- id = this.platform.denormalizePrimaryKey(id);
287
- }
288
- delete data[pk];
289
- data[primaryKey] = id;
308
+ denormalizePrimaryKey(meta, data) {
309
+ const pk = meta.getPrimaryProp();
310
+ const spk = meta.properties[meta.serializedPrimaryKey];
311
+ if (!spk?.serializedPrimaryKey) {
312
+ return;
313
+ }
314
+ if (pk.type === 'ObjectId' && (data[pk.name] != null || data[spk.name] != null)) {
315
+ data[pk.name] = this.platform.denormalizePrimaryKey((data[spk.name] || data[pk.name]));
316
+ delete data[spk.name];
290
317
  }
291
318
  }
292
319
  /**
293
320
  * returns parameters for entity constructor, creating references from plain ids
294
321
  */
295
322
  extractConstructorParams(meta, data, options) {
323
+ if (!meta.constructorParams) {
324
+ return [data];
325
+ }
296
326
  return meta.constructorParams.map(k => {
297
- if (meta.properties[k] && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(meta.properties[k].kind) && data[k]) {
298
- const pk = Reference.unwrapReference(data[k]);
299
- const entity = this.unitOfWork.getById(meta.properties[k].type, pk, options.schema, true);
327
+ const prop = meta.properties[k];
328
+ const value = data[k];
329
+ if (prop && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && value) {
330
+ const pk = Reference.unwrapReference(value);
331
+ const entity = this.unitOfWork.getById(prop.targetMeta.class, pk, options.schema, true);
300
332
  if (entity) {
301
333
  return entity;
302
334
  }
303
- if (Utils.isEntity(data[k])) {
304
- return data[k];
335
+ if (Utils.isEntity(value)) {
336
+ return value;
305
337
  }
306
- const nakedPk = Utils.extractPK(data[k], meta.properties[k].targetMeta, true);
307
- if (Utils.isObject(data[k]) && !nakedPk) {
308
- return this.create(meta.properties[k].type, data[k], options);
338
+ const nakedPk = Utils.extractPK(value, prop.targetMeta, true);
339
+ if (Utils.isObject(value) && !nakedPk) {
340
+ return this.create(prop.targetMeta.class, value, options);
309
341
  }
310
342
  const { newEntity, initialized, ...rest } = options;
311
- const target = this.createReference(meta.properties[k].type, nakedPk, rest);
312
- return Reference.wrapReference(target, meta.properties[k]);
343
+ const target = this.createReference(prop.targetMeta.class, nakedPk, rest);
344
+ return Reference.wrapReference(target, prop);
313
345
  }
314
- if (meta.properties[k]?.kind === ReferenceKind.EMBEDDED && data[k]) {
315
- /* v8 ignore next 3 */
316
- if (Utils.isEntity(data[k])) {
317
- return data[k];
346
+ if (prop?.kind === ReferenceKind.EMBEDDED && value) {
347
+ /* v8 ignore next */
348
+ if (Utils.isEntity(value)) {
349
+ return value;
318
350
  }
319
- return this.createEmbeddable(meta.properties[k].type, data[k], options);
351
+ return this.createEmbeddable(prop.targetMeta.class, value, options);
320
352
  }
321
- if (!meta.properties[k]) {
353
+ if (!prop) {
322
354
  const tmp = { ...data };
323
355
  for (const prop of meta.props) {
324
356
  if (!options.convertCustomTypes || !prop.customType || tmp[prop.name] == null) {
325
357
  continue;
326
358
  }
327
- if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(tmp[prop.name]) && !Utils.extractPK(tmp[prop.name], meta.properties[prop.name].targetMeta, true)) {
328
- tmp[prop.name] = Reference.wrapReference(this.create(meta.properties[prop.name].type, tmp[prop.name], options), prop);
359
+ if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(tmp[prop.name]) && !Utils.extractPK(tmp[prop.name], prop.targetMeta, true)) {
360
+ tmp[prop.name] = Reference.wrapReference(this.create(prop.targetMeta.class, tmp[prop.name], options), prop);
329
361
  }
330
362
  else if (prop.kind === ReferenceKind.SCALAR) {
331
363
  tmp[prop.name] = prop.customType.convertToJSValue(tmp[prop.name], this.platform);
@@ -333,10 +365,10 @@ export class EntityFactory {
333
365
  }
334
366
  return tmp;
335
367
  }
336
- if (options.convertCustomTypes && meta.properties[k].customType && data[k] != null) {
337
- return meta.properties[k].customType.convertToJSValue(data[k], this.platform);
368
+ if (options.convertCustomTypes && prop.customType && value != null) {
369
+ return prop.customType.convertToJSValue(value, this.platform);
338
370
  }
339
- return data[k];
371
+ return value;
340
372
  });
341
373
  }
342
374
  get unitOfWork() {
@@ -6,9 +6,9 @@ import { type EntityMetadata, type EntityProperty, type IHydrator } from '../typ
6
6
  export declare class EntityHelper {
7
7
  static decorate<T extends object>(meta: EntityMetadata<T>, em: EntityManager): void;
8
8
  /**
9
- * As a performance optimization, we create entity state methods in a lazy manner. We first add
9
+ * As a performance optimization, we create entity state methods lazily. We first add
10
10
  * the `null` value to the prototype to reserve space in memory. Then we define a setter on the
11
- * prototype, that will be executed exactly once per entity instance. There we redefine given
11
+ * prototype that will be executed exactly once per entity instance. There we redefine the given
12
12
  * property on the entity instance, so shadowing the prototype setter.
13
13
  */
14
14
  private static defineBaseProperties;
@@ -1,11 +1,12 @@
1
- import { inspect } from 'node:util';
2
- import { EagerProps, EntityRepositoryType, HiddenProps, OptionalProps, PrimaryKeyProp, } from '../typings.js';
1
+ import { EagerProps, EntityName, EntityRepositoryType, HiddenProps, OptionalProps, PrimaryKeyProp, } from '../typings.js';
3
2
  import { EntityTransformer } from '../serialization/EntityTransformer.js';
4
3
  import { Reference } from './Reference.js';
5
4
  import { Utils } from '../utils/Utils.js';
6
5
  import { WrappedEntity } from './WrappedEntity.js';
7
6
  import { ReferenceKind } from '../enums.js';
8
7
  import { helper } from './wrap.js';
8
+ import { inspect } from '../logging/inspect.js';
9
+ import { getEnv } from '../utils/env-vars.js';
9
10
  /**
10
11
  * @internal
11
12
  */
@@ -32,14 +33,19 @@ export class EntityHelper {
32
33
  const prototype = meta.prototype;
33
34
  if (!prototype.toJSON) { // toJSON can be overridden
34
35
  prototype.toJSON = function (...args) {
35
- return EntityTransformer.toObject(this, ...args.slice(meta.toJsonParams.length));
36
+ // Guard against being called on the prototype itself (e.g. by serializers
37
+ // walking the object graph and calling toJSON on prototype objects)
38
+ if (this === prototype) {
39
+ return {};
40
+ }
41
+ return EntityTransformer.toObject(this, ...args);
36
42
  };
37
43
  }
38
44
  }
39
45
  /**
40
- * As a performance optimization, we create entity state methods in a lazy manner. We first add
46
+ * As a performance optimization, we create entity state methods lazily. We first add
41
47
  * the `null` value to the prototype to reserve space in memory. Then we define a setter on the
42
- * prototype, that will be executed exactly once per entity instance. There we redefine given
48
+ * prototype that will be executed exactly once per entity instance. There we redefine the given
43
49
  * property on the entity instance, so shadowing the prototype setter.
44
50
  */
45
51
  static defineBaseProperties(meta, prototype, em) {
@@ -87,7 +93,7 @@ export class EntityHelper {
87
93
  });
88
94
  return;
89
95
  }
90
- if (prop.inherited || prop.primary || prop.persist === false || prop.trackChanges === false || prop.embedded || isCollection) {
96
+ if (prop.inherited || prop.primary || prop.accessor || prop.persist === false || prop.embedded || isCollection) {
91
97
  return;
92
98
  }
93
99
  Object.defineProperty(meta.prototype, prop.name, {
@@ -98,13 +104,11 @@ export class EntityHelper {
98
104
  },
99
105
  set(val) {
100
106
  this.__helper.__data[prop.name] = val;
101
- this.__helper.__touched = !this.__helper.hydrator.isRunning();
102
107
  },
103
108
  enumerable: true,
104
109
  configurable: true,
105
110
  });
106
111
  this.__helper.__data[prop.name] = val;
107
- this.__helper.__touched = !this.__helper.hydrator.isRunning();
108
112
  },
109
113
  configurable: true,
110
114
  });
@@ -112,16 +116,27 @@ export class EntityHelper {
112
116
  }
113
117
  static defineCustomInspect(meta) {
114
118
  // @ts-ignore
115
- meta.prototype[inspect.custom] ??= function (depth = 2) {
116
- const object = { ...this };
119
+ meta.prototype[Symbol.for('nodejs.util.inspect.custom')] ??= function (depth = 2) {
120
+ const object = {};
121
+ const keys = new Set(Utils.keys(this));
122
+ for (const prop of meta.props) {
123
+ if (keys.has(prop.name) || (prop.getter && prop.accessor === prop.name)) {
124
+ object[prop.name] = this[prop.name];
125
+ }
126
+ }
127
+ for (const key of keys) {
128
+ if (!meta.properties[key]) {
129
+ object[key] = this[key];
130
+ }
131
+ }
117
132
  // ensure we dont have internal symbols in the POJO
118
- [OptionalProps, EntityRepositoryType, PrimaryKeyProp, EagerProps, HiddenProps].forEach(sym => delete object[sym]);
133
+ [OptionalProps, EntityRepositoryType, PrimaryKeyProp, EagerProps, HiddenProps, EntityName].forEach(sym => delete object[sym]);
119
134
  meta.props
120
135
  .filter(prop => object[prop.name] === undefined)
121
136
  .forEach(prop => delete object[prop.name]);
122
137
  const ret = inspect(object, { depth });
123
- let name = (this).constructor.name;
124
- const showEM = ['true', 't', '1'].includes(process.env.MIKRO_ORM_LOG_EM_ID?.toString().toLowerCase() ?? '');
138
+ let name = this.constructor.name;
139
+ const showEM = ['true', 't', '1'].includes(getEnv('MIKRO_ORM_LOG_EM_ID')?.toLowerCase() ?? '');
125
140
  if (showEM) {
126
141
  if (helper(this).__em) {
127
142
  name += ` [managed by ${helper(this).__em.id}]`;
@@ -154,9 +169,6 @@ export class EntityHelper {
154
169
  if (val && hydrator.isRunning() && wrapped.__originalEntityData && prop.owner) {
155
170
  wrapped.__originalEntityData[prop.name] = Utils.getPrimaryKeyValues(wrapped.__data[prop.name], prop.targetMeta, true);
156
171
  }
157
- else {
158
- wrapped.__touched = !hydrator.isRunning();
159
- }
160
172
  EntityHelper.propagate(meta, entity, this, prop, Reference.unwrapReference(val), old);
161
173
  },
162
174
  enumerable: true,
@@ -164,7 +176,19 @@ export class EntityHelper {
164
176
  });
165
177
  }
166
178
  static propagate(meta, entity, owner, prop, value, old) {
167
- for (const prop2 of prop.targetMeta.bidirectionalRelations) {
179
+ // For polymorphic relations, get bidirectional relations from the actual entity's metadata
180
+ let bidirectionalRelations;
181
+ if (prop.polymorphic && prop.polymorphTargets?.length) {
182
+ // For polymorphic relations, we need to get the bidirectional relations from the actual value's metadata
183
+ if (!value) {
184
+ return; // No value means no propagation needed
185
+ }
186
+ bidirectionalRelations = helper(value).__meta.bidirectionalRelations;
187
+ }
188
+ else {
189
+ bidirectionalRelations = prop.targetMeta.bidirectionalRelations;
190
+ }
191
+ for (const prop2 of bidirectionalRelations) {
168
192
  if ((prop2.inversedBy || prop2.mappedBy) !== prop.name) {
169
193
  continue;
170
194
  }
@@ -172,6 +196,10 @@ export class EntityHelper {
172
196
  continue;
173
197
  }
174
198
  const inverse = value?.[prop2.name];
199
+ if (prop.ref && owner[prop.name]) {
200
+ // eslint-disable-next-line dot-notation
201
+ owner[prop.name]['property'] = prop;
202
+ }
175
203
  if (Utils.isCollection(inverse) && inverse.isPartial()) {
176
204
  continue;
177
205
  }
@@ -202,6 +230,11 @@ export class EntityHelper {
202
230
  helper(other).__em?.getUnitOfWork().scheduleOrphanRemoval(other);
203
231
  }
204
232
  }
233
+ // Skip setting the inverse side to null if it's a primary key - the entity will be removed via orphan removal
234
+ // Setting a primary key to null would corrupt the entity and cause validation errors
235
+ if (value == null && prop.orphanRemoval && prop2.primary) {
236
+ return;
237
+ }
205
238
  if (value == null) {
206
239
  entity[prop2.name] = value;
207
240
  }
@@ -1,26 +1,26 @@
1
- import type { AnyEntity, ConnectionType, Dictionary, EntityProperty, FilterQuery, PopulateOptions } from '../typings.js';
1
+ import type { AnyEntity, AutoPath, ConnectionType, EntityName, EntityProperty, FilterQuery, PopulateOptions } from '../typings.js';
2
2
  import type { EntityManager } from '../EntityManager.js';
3
3
  import { LoadStrategy, type LockMode, type PopulateHint, PopulatePath, type QueryOrderMap } from '../enums.js';
4
- import type { EntityField } from '../drivers/IDatabaseDriver.js';
4
+ import type { FilterOptions } from '../drivers/IDatabaseDriver.js';
5
5
  import type { LoggingOptions } from '../logging/Logger.js';
6
- export type EntityLoaderOptions<Entity, Fields extends string = PopulatePath.ALL, Excludes extends string = never> = {
6
+ export interface EntityLoaderOptions<Entity, Fields extends string = PopulatePath.ALL, Excludes extends string = never> {
7
+ fields?: readonly AutoPath<Entity, Fields, `${PopulatePath.ALL}`>[];
8
+ exclude?: readonly AutoPath<Entity, Excludes>[];
7
9
  where?: FilterQuery<Entity>;
8
10
  populateWhere?: PopulateHint | `${PopulateHint}`;
9
- fields?: readonly EntityField<Entity, Fields>[];
10
- exclude?: readonly EntityField<Entity, Excludes>[];
11
11
  orderBy?: QueryOrderMap<Entity> | QueryOrderMap<Entity>[];
12
12
  refresh?: boolean;
13
13
  validate?: boolean;
14
14
  lookup?: boolean;
15
15
  convertCustomTypes?: boolean;
16
16
  ignoreLazyScalarProperties?: boolean;
17
- filters?: Dictionary<boolean | Dictionary> | string[] | boolean;
18
- strategy?: LoadStrategy;
17
+ filters?: FilterOptions;
18
+ strategy?: LoadStrategy | `${LoadStrategy}`;
19
19
  lockMode?: Exclude<LockMode, LockMode.OPTIMISTIC>;
20
20
  schema?: string;
21
21
  connectionType?: ConnectionType;
22
22
  logging?: LoggingOptions;
23
- };
23
+ }
24
24
  export declare class EntityLoader {
25
25
  private readonly em;
26
26
  private readonly metadata;
@@ -30,8 +30,8 @@ export declare class EntityLoader {
30
30
  * Loads specified relations in batch.
31
31
  * This will execute one query for each relation, that will populate it on all the specified entities.
32
32
  */
33
- populate<Entity extends object, Fields extends string = PopulatePath.ALL>(entityName: string, entities: Entity[], populate: PopulateOptions<Entity>[] | boolean, options: EntityLoaderOptions<Entity, Fields>): Promise<void>;
34
- normalizePopulate<Entity>(entityName: string, populate: (PopulateOptions<Entity> | boolean)[] | PopulateOptions<Entity> | boolean, strategy?: LoadStrategy, lookup?: boolean): PopulateOptions<Entity>[];
33
+ populate<Entity extends object, Fields extends string = PopulatePath.ALL>(entityName: EntityName<Entity>, entities: Entity[], populate: PopulateOptions<Entity>[] | boolean, options: EntityLoaderOptions<Entity, Fields>): Promise<void>;
34
+ normalizePopulate<Entity>(entityName: EntityName<Entity>, populate: (PopulateOptions<Entity> | boolean)[] | PopulateOptions<Entity> | boolean, strategy?: LoadStrategy, lookup?: boolean, exclude?: string[]): PopulateOptions<Entity>[];
35
35
  private setSerializationContext;
36
36
  /**
37
37
  * Merge multiple populates for the same entity with different children. Also skips `*` fields, those can come from
@@ -43,6 +43,7 @@ export declare class EntityLoader {
43
43
  */
44
44
  private populateMany;
45
45
  private populateScalar;
46
+ private populatePolymorphic;
46
47
  private initializeCollections;
47
48
  private initializeOneToMany;
48
49
  private initializeManyToMany;