@mikro-orm/core 7.0.0-rc.2 → 7.0.0

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 (114) hide show
  1. package/EntityManager.d.ts +4 -16
  2. package/EntityManager.js +248 -181
  3. package/MikroORM.d.ts +4 -6
  4. package/MikroORM.js +24 -24
  5. package/README.md +5 -4
  6. package/cache/FileCacheAdapter.d.ts +1 -5
  7. package/cache/FileCacheAdapter.js +22 -24
  8. package/cache/GeneratedCacheAdapter.d.ts +1 -1
  9. package/cache/GeneratedCacheAdapter.js +6 -6
  10. package/cache/MemoryCacheAdapter.d.ts +1 -2
  11. package/cache/MemoryCacheAdapter.js +8 -8
  12. package/cache/index.d.ts +1 -1
  13. package/cache/index.js +0 -1
  14. package/connections/Connection.d.ts +1 -0
  15. package/connections/Connection.js +43 -14
  16. package/drivers/DatabaseDriver.d.ts +0 -2
  17. package/drivers/DatabaseDriver.js +28 -12
  18. package/drivers/IDatabaseDriver.d.ts +43 -0
  19. package/entity/Collection.d.ts +1 -9
  20. package/entity/Collection.js +124 -108
  21. package/entity/EntityAssigner.js +23 -11
  22. package/entity/EntityFactory.d.ts +1 -8
  23. package/entity/EntityFactory.js +79 -59
  24. package/entity/EntityHelper.js +25 -16
  25. package/entity/EntityLoader.d.ts +1 -3
  26. package/entity/EntityLoader.js +90 -60
  27. package/entity/Reference.d.ts +2 -3
  28. package/entity/Reference.js +48 -19
  29. package/entity/WrappedEntity.d.ts +4 -2
  30. package/entity/WrappedEntity.js +5 -1
  31. package/entity/defineEntity.d.ts +42 -85
  32. package/entity/utils.js +28 -26
  33. package/entity/validators.js +2 -1
  34. package/enums.d.ts +2 -1
  35. package/enums.js +13 -17
  36. package/errors.d.ts +11 -11
  37. package/errors.js +8 -8
  38. package/events/EventManager.d.ts +1 -4
  39. package/events/EventManager.js +26 -23
  40. package/events/index.d.ts +1 -1
  41. package/events/index.js +0 -1
  42. package/exceptions.js +9 -2
  43. package/hydration/ObjectHydrator.d.ts +1 -2
  44. package/hydration/ObjectHydrator.js +41 -27
  45. package/index.d.ts +1 -1
  46. package/index.js +1 -1
  47. package/logging/DefaultLogger.js +6 -7
  48. package/logging/Logger.d.ts +2 -1
  49. package/logging/colors.js +2 -5
  50. package/logging/index.d.ts +1 -1
  51. package/logging/index.js +0 -1
  52. package/metadata/EntitySchema.d.ts +3 -3
  53. package/metadata/EntitySchema.js +12 -2
  54. package/metadata/MetadataDiscovery.d.ts +1 -9
  55. package/metadata/MetadataDiscovery.js +251 -179
  56. package/metadata/MetadataProvider.js +26 -1
  57. package/metadata/MetadataStorage.d.ts +1 -5
  58. package/metadata/MetadataStorage.js +37 -39
  59. package/metadata/MetadataValidator.js +20 -5
  60. package/metadata/discover-entities.js +1 -1
  61. package/metadata/index.d.ts +1 -1
  62. package/metadata/index.js +0 -1
  63. package/metadata/types.d.ts +2 -2
  64. package/naming-strategy/AbstractNamingStrategy.js +6 -3
  65. package/naming-strategy/EntityCaseNamingStrategy.js +1 -1
  66. package/naming-strategy/index.d.ts +1 -1
  67. package/naming-strategy/index.js +0 -1
  68. package/not-supported.js +5 -1
  69. package/package.json +38 -38
  70. package/platforms/Platform.d.ts +24 -1
  71. package/platforms/Platform.js +106 -27
  72. package/serialization/EntitySerializer.js +8 -4
  73. package/serialization/EntityTransformer.js +4 -1
  74. package/serialization/SerializationContext.d.ts +4 -8
  75. package/serialization/SerializationContext.js +21 -16
  76. package/types/UuidType.d.ts +2 -0
  77. package/types/UuidType.js +14 -2
  78. package/types/index.d.ts +2 -1
  79. package/typings.d.ts +35 -24
  80. package/typings.js +9 -9
  81. package/unit-of-work/ChangeSet.js +4 -4
  82. package/unit-of-work/ChangeSetComputer.d.ts +1 -6
  83. package/unit-of-work/ChangeSetComputer.js +29 -27
  84. package/unit-of-work/ChangeSetPersister.d.ts +1 -9
  85. package/unit-of-work/ChangeSetPersister.js +63 -58
  86. package/unit-of-work/CommitOrderCalculator.d.ts +1 -4
  87. package/unit-of-work/CommitOrderCalculator.js +17 -15
  88. package/unit-of-work/IdentityMap.d.ts +2 -5
  89. package/unit-of-work/IdentityMap.js +18 -18
  90. package/unit-of-work/UnitOfWork.d.ts +12 -20
  91. package/unit-of-work/UnitOfWork.js +228 -191
  92. package/utils/AbstractMigrator.d.ts +2 -2
  93. package/utils/AbstractMigrator.js +10 -12
  94. package/utils/AbstractSchemaGenerator.js +2 -1
  95. package/utils/AsyncContext.js +1 -1
  96. package/utils/Configuration.d.ts +90 -189
  97. package/utils/Configuration.js +97 -77
  98. package/utils/Cursor.d.ts +3 -3
  99. package/utils/Cursor.js +8 -6
  100. package/utils/DataloaderUtils.js +15 -12
  101. package/utils/EntityComparator.d.ts +8 -15
  102. package/utils/EntityComparator.js +100 -92
  103. package/utils/QueryHelper.d.ts +16 -1
  104. package/utils/QueryHelper.js +108 -50
  105. package/utils/RawQueryFragment.d.ts +4 -4
  106. package/utils/RawQueryFragment.js +3 -2
  107. package/utils/TransactionManager.js +3 -3
  108. package/utils/Utils.d.ts +2 -2
  109. package/utils/Utils.js +39 -32
  110. package/utils/clone.js +5 -0
  111. package/utils/env-vars.js +6 -5
  112. package/utils/fs-utils.d.ts +3 -17
  113. package/utils/fs-utils.js +2 -5
  114. package/utils/upsert-utils.js +7 -4
@@ -7,13 +7,13 @@ import { helper } from './wrap.js';
7
7
  import { expandDotPaths } from './utils.js';
8
8
  import { Raw } from '../utils/RawQueryFragment.js';
9
9
  export class EntityLoader {
10
- em;
11
- metadata;
12
- driver;
10
+ #metadata;
11
+ #driver;
12
+ #em;
13
13
  constructor(em) {
14
- this.em = em;
15
- this.metadata = this.em.getMetadata();
16
- this.driver = this.em.getDriver();
14
+ this.#em = em;
15
+ this.#metadata = this.#em.getMetadata();
16
+ this.#driver = this.#em.getDriver();
17
17
  }
18
18
  /**
19
19
  * Loads specified relations in batch.
@@ -23,13 +23,13 @@ export class EntityLoader {
23
23
  if (entities.length === 0 || Utils.isEmpty(populate)) {
24
24
  return this.setSerializationContext(entities, populate, options);
25
25
  }
26
- const meta = this.metadata.find(entityName);
26
+ const meta = this.#metadata.find(entityName);
27
27
  if (entities.some(e => !e.__helper)) {
28
28
  const entity = entities.find(e => !Utils.isEntity(e));
29
29
  throw ValidationError.notDiscoveredEntity(entity, meta, 'populate');
30
30
  }
31
31
  const references = entities.filter(e => !helper(e).isInitialized());
32
- const visited = options.visited ??= new Set();
32
+ const visited = (options.visited ??= new Set());
33
33
  options.where ??= {};
34
34
  options.orderBy ??= {};
35
35
  options.lookup ??= true;
@@ -40,7 +40,7 @@ export class EntityLoader {
40
40
  await this.populateScalar(meta, references, { ...options, populateWhere: undefined });
41
41
  }
42
42
  populate = this.normalizePopulate(entityName, populate, options.strategy, options.lookup, options.exclude);
43
- const invalid = populate.find(({ field }) => !this.em.canPopulate(entityName, field));
43
+ const invalid = populate.find(({ field }) => !this.#em.canPopulate(entityName, field));
44
44
  /* v8 ignore next */
45
45
  if (options.validate && invalid) {
46
46
  throw ValidationError.invalidPropertyName(entityName, invalid.field);
@@ -57,8 +57,9 @@ export class EntityLoader {
57
57
  }
58
58
  }
59
59
  normalizePopulate(entityName, populate, strategy, lookup = true, exclude) {
60
- const meta = this.metadata.find(entityName);
60
+ const meta = this.#metadata.find(entityName);
61
61
  let normalized = Utils.asArray(populate).map(field => {
62
+ // oxfmt-ignore
62
63
  return typeof field === 'boolean' || field.field === PopulatePath.ALL ? { all: !!field, field: meta.primaryKeys[0] } : field;
63
64
  });
64
65
  if (normalized.some(p => p.all)) {
@@ -89,6 +90,7 @@ export class EntityLoader {
89
90
  */
90
91
  mergeNestedPopulate(populate) {
91
92
  const tmp = populate.reduce((ret, item) => {
93
+ /* v8 ignore next */
92
94
  if (item.field === PopulatePath.ALL) {
93
95
  return ret;
94
96
  }
@@ -116,16 +118,17 @@ export class EntityLoader {
116
118
  */
117
119
  async populateMany(entityName, entities, populate, options) {
118
120
  const [field, ref] = populate.field.split(':', 2);
119
- const meta = this.metadata.find(entityName);
121
+ const meta = this.#metadata.find(entityName);
120
122
  const prop = meta.properties[field];
121
- if (prop.kind === ReferenceKind.MANY_TO_MANY && prop.owner && !this.driver.getPlatform().usesPivotTable()) {
123
+ if (prop.kind === ReferenceKind.MANY_TO_MANY && prop.owner && !this.#driver.getPlatform().usesPivotTable()) {
122
124
  const filtered = entities.filter(e => !e[prop.name]?.isInitialized());
123
125
  if (filtered.length > 0) {
124
126
  await this.populateScalar(meta, filtered, { ...options, fields: [prop.name] });
125
127
  }
126
128
  }
127
129
  if (prop.kind === ReferenceKind.SCALAR && prop.lazy) {
128
- const filtered = entities.filter(e => options.refresh || (prop.ref ? !e[prop.name]?.isInitialized() : e[prop.name] === undefined));
130
+ const filtered = entities.filter(e => options.refresh ||
131
+ (prop.ref ? !e[prop.name]?.isInitialized() : e[prop.name] === undefined));
129
132
  if (options.ignoreLazyScalarProperties || filtered.length === 0) {
130
133
  return entities;
131
134
  }
@@ -137,10 +140,11 @@ export class EntityLoader {
137
140
  }
138
141
  const filtered = this.filterCollections(entities, field, options, ref);
139
142
  const innerOrderBy = Utils.asArray(options.orderBy)
140
- .filter(orderBy => (Array.isArray(orderBy[prop.name]) && orderBy[prop.name].length > 0) || Utils.isObject(orderBy[prop.name]))
143
+ .filter(orderBy => (Array.isArray(orderBy[prop.name]) && orderBy[prop.name].length > 0) ||
144
+ Utils.isObject(orderBy[prop.name]))
141
145
  .flatMap(orderBy => orderBy[prop.name]);
142
146
  const where = await this.extractChildCondition(options, prop);
143
- if (prop.kind === ReferenceKind.MANY_TO_MANY && this.driver.getPlatform().usesPivotTable()) {
147
+ if (prop.kind === ReferenceKind.MANY_TO_MANY && this.#driver.getPlatform().usesPivotTable()) {
144
148
  const pivotOrderBy = QueryHelper.mergeOrderBy(innerOrderBy, prop.orderBy, prop.targetMeta?.orderBy);
145
149
  const res = await this.findChildrenFromPivotTable(filtered, prop, options, pivotOrderBy, populate, !!ref);
146
150
  return Utils.flatten(res);
@@ -160,16 +164,22 @@ export class EntityLoader {
160
164
  async populateScalar(meta, filtered, options) {
161
165
  const pk = Utils.getPrimaryKeyHash(meta.primaryKeys);
162
166
  const ids = Utils.unique(filtered.map(e => Utils.getPrimaryKeyValues(e, meta, true)));
163
- const where = this.mergePrimaryCondition(ids, pk, options, meta, this.metadata, this.driver.getPlatform());
167
+ const where = this.mergePrimaryCondition(ids, pk, options, meta, this.#metadata, this.#driver.getPlatform());
164
168
  const { filters, convertCustomTypes, lockMode, strategy, populateWhere, connectionType, logging, fields } = options;
165
- await this.em.find(meta.class, where, {
166
- filters, convertCustomTypes, lockMode, strategy, populateWhere, connectionType, logging,
169
+ await this.#em.find(meta.class, where, {
170
+ filters,
171
+ convertCustomTypes,
172
+ lockMode,
173
+ strategy,
174
+ populateWhere,
175
+ connectionType,
176
+ logging,
167
177
  fields: fields,
168
178
  populate: [],
169
179
  });
170
180
  }
171
181
  async populatePolymorphic(entities, prop, options, ref) {
172
- const ownerMeta = this.metadata.get(entities[0].constructor);
182
+ const ownerMeta = this.#metadata.get(entities[0].constructor);
173
183
  // Separate entities: those with loaded refs vs those needing FK load
174
184
  const toPopulate = [];
175
185
  const needsFkLoad = [];
@@ -220,7 +230,7 @@ export class EntityLoader {
220
230
  // Load each group concurrently - identity map handles merging with existing references
221
231
  const allItems = [];
222
232
  await Promise.all([...groups].map(async ([discriminator, children]) => {
223
- const targetMeta = this.metadata.find(prop.discriminatorMap[discriminator]);
233
+ const targetMeta = this.#metadata.find(prop.discriminatorMap[discriminator]);
224
234
  await this.populateScalar(targetMeta, children, options);
225
235
  allItems.push(...children);
226
236
  }));
@@ -230,7 +240,7 @@ export class EntityLoader {
230
240
  if (prop.kind === ReferenceKind.ONE_TO_MANY) {
231
241
  this.initializeOneToMany(filtered, children, prop, field, partial);
232
242
  }
233
- if (prop.kind === ReferenceKind.MANY_TO_MANY && !this.driver.getPlatform().usesPivotTable()) {
243
+ if (prop.kind === ReferenceKind.MANY_TO_MANY && !this.#driver.getPlatform().usesPivotTable()) {
234
244
  this.initializeManyToMany(filtered, children, prop, field, customOrder, partial);
235
245
  }
236
246
  }
@@ -244,7 +254,7 @@ export class EntityLoader {
244
254
  for (const child of children) {
245
255
  const pk = child.__helper.__data[prop.mappedBy] ?? child[prop.mappedBy];
246
256
  if (pk) {
247
- const key = helper(mapToPk ? this.em.getReference(prop.targetMeta.class, pk) : pk).getSerializedPrimaryKey();
257
+ const key = helper(mapToPk ? this.#em.getReference(prop.targetMeta.class, pk) : pk).getSerializedPrimaryKey();
248
258
  map[key]?.push(child);
249
259
  }
250
260
  }
@@ -260,7 +270,8 @@ export class EntityLoader {
260
270
  entity[field].hydrate(items, true, partial);
261
271
  }
262
272
  }
263
- else { // owning side of M:N without pivot table needs to be reordered
273
+ else {
274
+ // owning side of M:N without pivot table needs to be reordered
264
275
  for (const entity of filtered) {
265
276
  const order = !customOrder ? [...entity[prop.name].getItems(false)] : []; // copy order of references
266
277
  const items = children.filter(child => entity[prop.name].contains(child, false));
@@ -301,7 +312,7 @@ export class EntityLoader {
301
312
  if (!schema && [ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind)) {
302
313
  schema = children.find(e => e.__helper.__schema)?.__helper.__schema;
303
314
  }
304
- const ids = Utils.unique(children.map(e => prop.targetKey ? e[prop.targetKey] : e.__helper.getPrimaryKey()));
315
+ const ids = Utils.unique(children.map(e => (prop.targetKey ? e[prop.targetKey] : e.__helper.getPrimaryKey())));
305
316
  let where;
306
317
  if (polymorphicOwnerProp && Array.isArray(fk)) {
307
318
  const conditions = ids.map(id => {
@@ -311,11 +322,12 @@ export class EntityLoader {
311
322
  where = (conditions.length === 1 ? conditions[0] : { $or: conditions });
312
323
  }
313
324
  else {
314
- where = this.mergePrimaryCondition(ids, fk, options, meta, this.metadata, this.driver.getPlatform());
325
+ where = this.mergePrimaryCondition(ids, fk, options, meta, this.#metadata, this.#driver.getPlatform());
315
326
  }
316
327
  if (polymorphicOwnerProp) {
317
- const parentMeta = this.metadata.find(entities[0].constructor);
318
- const discriminatorValue = QueryHelper.findDiscriminatorValue(polymorphicOwnerProp.discriminatorMap, parentMeta.class) ?? parentMeta.tableName;
328
+ const parentMeta = this.#metadata.find(entities[0].constructor);
329
+ const discriminatorValue = QueryHelper.findDiscriminatorValue(polymorphicOwnerProp.discriminatorMap, parentMeta.class) ??
330
+ parentMeta.tableName;
319
331
  const discriminatorColumn = polymorphicOwnerProp.fieldNames[0];
320
332
  where = { $and: [where, { [discriminatorColumn]: discriminatorValue }] };
321
333
  }
@@ -330,12 +342,21 @@ export class EntityLoader {
330
342
  where = { $and: [where, prop.where] };
331
343
  }
332
344
  const orderBy = QueryHelper.mergeOrderBy(options.orderBy, prop.orderBy);
333
- const items = await this.em.find(meta.class, where, {
334
- filters, convertCustomTypes, lockMode, populateWhere, logging,
345
+ const items = await this.#em.find(meta.class, where, {
346
+ filters,
347
+ convertCustomTypes,
348
+ lockMode,
349
+ populateWhere,
350
+ logging,
335
351
  orderBy,
336
352
  populate: populate.children ?? populate.all ?? [],
337
- exclude: Array.isArray(options.exclude) ? Utils.extractChildElements(options.exclude, prop.name) : options.exclude,
338
- strategy, fields, schema, connectionType,
353
+ exclude: Array.isArray(options.exclude)
354
+ ? Utils.extractChildElements(options.exclude, prop.name)
355
+ : options.exclude,
356
+ strategy,
357
+ fields,
358
+ schema,
359
+ connectionType,
339
360
  // @ts-ignore not a public option, will be propagated to the populate call
340
361
  refresh: refresh && !children.every(item => options.visited.has(item)),
341
362
  // @ts-ignore not a public option, will be propagated to the populate call
@@ -355,6 +376,7 @@ export class EntityLoader {
355
376
  if (!ref) {
356
377
  continue;
357
378
  }
379
+ // oxfmt-ignore
358
380
  const keyValue = '' + (Reference.isReference(ref) ? ref.unwrap()[prop.targetKey] : ref[prop.targetKey]);
359
381
  const loadedItem = itemsByKey.get(keyValue);
360
382
  if (loadedItem) {
@@ -363,11 +385,11 @@ export class EntityLoader {
363
385
  }
364
386
  }
365
387
  if ([ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind) && items.length !== children.length) {
366
- const nullVal = this.em.config.get('forceUndefined') ? undefined : null;
388
+ const nullVal = this.#em.config.get('forceUndefined') ? undefined : null;
367
389
  const itemsMap = new Set();
368
390
  const childrenMap = new Set();
369
391
  // Use targetKey value if set, otherwise use serialized PK
370
- const getKey = (e) => prop.targetKey ? '' + e[prop.targetKey] : helper(e).getSerializedPrimaryKey();
392
+ const getKey = (e) => (prop.targetKey ? '' + e[prop.targetKey] : helper(e).getSerializedPrimaryKey());
371
393
  for (const item of items) {
372
394
  /* v8 ignore next */
373
395
  itemsMap.add(getKey(item));
@@ -387,23 +409,26 @@ export class EntityLoader {
387
409
  for (const item of items) {
388
410
  if (ref && !helper(item).__onLoadFired) {
389
411
  helper(item).__initialized = false;
390
- // eslint-disable-next-line dot-notation
391
- this.em.getUnitOfWork()['loadedEntities'].delete(item);
412
+ this.#em.getUnitOfWork().unmarkAsLoaded(item);
392
413
  }
393
414
  }
394
415
  return { items, partial };
395
416
  }
396
417
  mergePrimaryCondition(ids, pk, options, meta, metadata, platform) {
397
- const cond1 = QueryHelper.processWhere({ where: { [pk]: { $in: ids } }, entityName: meta.class, metadata, platform, convertCustomTypes: !options.convertCustomTypes });
418
+ const cond1 = QueryHelper.processWhere({
419
+ where: { [pk]: { $in: ids } },
420
+ entityName: meta.class,
421
+ metadata,
422
+ platform,
423
+ convertCustomTypes: !options.convertCustomTypes,
424
+ });
398
425
  const where = { ...options.where };
399
426
  Utils.dropUndefinedProperties(where);
400
- return where[pk]
401
- ? { $and: [cond1, where] }
402
- : { ...cond1, ...where };
427
+ return where[pk] ? { $and: [cond1, where] } : { ...cond1, ...where };
403
428
  }
404
429
  async populateField(entityName, entities, populate, options) {
405
430
  const field = populate.field.split(':')[0];
406
- const prop = this.metadata.find(entityName).properties[field];
431
+ const prop = this.#metadata.find(entityName).properties[field];
407
432
  if (prop.kind === ReferenceKind.SCALAR && !prop.lazy) {
408
433
  return;
409
434
  }
@@ -436,6 +461,7 @@ export class EntityLoader {
436
461
  .filter(orderBy => Utils.isObject(orderBy[prop.name]))
437
462
  .map(orderBy => orderBy[prop.name]);
438
463
  const { refresh, filters, ignoreLazyScalarProperties, populateWhere, connectionType, logging, schema } = options;
464
+ // oxfmt-ignore
439
465
  const exclude = Array.isArray(options.exclude) ? Utils.extractChildElements(options.exclude, prop.name) : options.exclude;
440
466
  const visited = options.visited;
441
467
  for (const entity of entities) {
@@ -451,7 +477,7 @@ export class EntityLoader {
451
477
  }
452
478
  const populateChildren = async (targetMeta, items) => {
453
479
  await this.populate(targetMeta.class, items, populate.children ?? populate.all, {
454
- where: await this.extractChildCondition(options, prop, false),
480
+ where: (await this.extractChildCondition(options, prop, false)),
455
481
  orderBy: innerOrderBy,
456
482
  fields,
457
483
  exclude,
@@ -489,34 +515,33 @@ export class EntityLoader {
489
515
  const refresh = options.refresh;
490
516
  let where = await this.extractChildCondition(options, prop, true);
491
517
  const fields = this.buildFields(options.fields, prop);
518
+ // oxfmt-ignore
492
519
  const exclude = Array.isArray(options.exclude) ? Utils.extractChildElements(options.exclude, prop.name) : options.exclude;
493
520
  const populateFilter = options.populateFilter?.[prop.name];
494
521
  const options2 = { ...options, fields, exclude, populateFilter };
495
522
  ['limit', 'offset', 'first', 'last', 'before', 'after', 'overfetch'].forEach(prop => delete options2[prop]);
496
- options2.populate = (populate?.children ?? []);
497
- if (prop.customType) {
498
- ids.forEach((id, idx) => ids[idx] = QueryHelper.processCustomType(prop, id, this.driver.getPlatform()));
499
- }
523
+ options2.populate = populate?.children ?? [];
500
524
  if (!Utils.isEmpty(prop.where)) {
501
525
  where = { $and: [where, prop.where] };
502
526
  }
503
- const map = await this.driver.loadFromPivotTable(prop, ids, where, orderBy, this.em.getTransactionContext(), options2, pivotJoin);
527
+ const map = await this.#driver.loadFromPivotTable(prop, ids, where, orderBy, this.#em.getTransactionContext(), options2, pivotJoin);
504
528
  const children = [];
505
- for (const entity of filtered) {
506
- const items = map[entity.__helper.getSerializedPrimaryKey()].map(item => {
529
+ for (let i = 0; i < filtered.length; i++) {
530
+ const entity = filtered[i];
531
+ const items = map[Utils.getPrimaryKeyHash(ids[i])].map(item => {
507
532
  if (pivotJoin) {
508
- return this.em.getReference(prop.targetMeta.class, item, {
533
+ return this.#em.getReference(prop.targetMeta.class, item, {
509
534
  convertCustomTypes: true,
510
- schema: options.schema ?? this.em.config.get('schema'),
535
+ schema: options.schema ?? this.#em.config.get('schema'),
511
536
  });
512
537
  }
513
- const entity = this.em.getEntityFactory().create(prop.targetMeta.class, item, {
538
+ const entity = this.#em.getEntityFactory().create(prop.targetMeta.class, item, {
514
539
  refresh,
515
540
  merge: true,
516
541
  convertCustomTypes: true,
517
- schema: options.schema ?? this.em.config.get('schema'),
542
+ schema: options.schema ?? this.#em.config.get('schema'),
518
543
  });
519
- return this.em.getUnitOfWork().register(entity, item, { refresh, loaded: true });
544
+ return this.#em.getUnitOfWork().register(entity, item, { refresh, loaded: true });
520
545
  });
521
546
  entity[prop.name].hydrate(items, true);
522
547
  children.push(items);
@@ -532,7 +557,8 @@ export class EntityLoader {
532
557
  if (where[op]) {
533
558
  const child = where[op]
534
559
  .map((cond) => cond[prop.name])
535
- .filter((sub) => sub != null && !(Utils.isPlainObject(sub) && Utils.getObjectQueryKeys(sub).every(key => Utils.isOperator(key, false))))
560
+ .filter((sub) => sub != null &&
561
+ !(Utils.isPlainObject(sub) && Utils.getObjectQueryKeys(sub).every(key => Utils.isOperator(key, false))))
536
562
  .map((cond) => {
537
563
  if (Utils.isPrimaryKey(cond)) {
538
564
  return { [pk]: cond };
@@ -553,7 +579,7 @@ export class EntityLoader {
553
579
  });
554
580
  }
555
581
  if (filters) {
556
- return this.em.applyFilters(meta2.class, subCond, options.filters, 'read', options);
582
+ return this.#em.applyFilters(meta2.class, subCond, options.filters, 'read', options);
557
583
  }
558
584
  return subCond;
559
585
  }
@@ -603,7 +629,8 @@ export class EntityLoader {
603
629
  return a;
604
630
  }, []);
605
631
  }
606
- if (prop.kind === ReferenceKind.MANY_TO_MANY) { // inverse side
632
+ if (prop.kind === ReferenceKind.MANY_TO_MANY) {
633
+ // inverse side
607
634
  return filtered;
608
635
  }
609
636
  // MANY_TO_ONE or ONE_TO_ONE
@@ -665,7 +692,7 @@ export class EntityLoader {
665
692
  }
666
693
  lookupAllRelationships(entityName) {
667
694
  const ret = [];
668
- const meta = this.metadata.find(entityName);
695
+ const meta = this.#metadata.find(entityName);
669
696
  meta.relations.forEach(prop => {
670
697
  ret.push({
671
698
  field: this.getRelationName(meta, prop),
@@ -684,7 +711,7 @@ export class EntityLoader {
684
711
  return `${this.getRelationName(meta, meta.properties[prop.embedded[0]])}.${prop.embedded[1]}`;
685
712
  }
686
713
  lookupEagerLoadedRelationships(entityName, populate, strategy, prefix = '', visited = [], exclude) {
687
- const meta = this.metadata.find(entityName);
714
+ const meta = this.#metadata.find(entityName);
688
715
  if (!meta && !prefix) {
689
716
  return populate;
690
717
  }
@@ -706,7 +733,10 @@ export class EntityLoader {
706
733
  .forEach(prop => {
707
734
  const field = this.getRelationName(meta, prop);
708
735
  const prefixed = prefix ? `${prefix}.${field}` : field;
709
- const nestedPopulate = populate.filter(p => p.field === prop.name).flatMap(p => p.children).filter(Boolean);
736
+ const nestedPopulate = populate
737
+ .filter(p => p.field === prop.name)
738
+ .flatMap(p => p.children)
739
+ .filter(Boolean);
710
740
  const nested = this.lookupEagerLoadedRelationships(prop.targetMeta.class, nestedPopulate, strategy, prefixed, visited.slice(), exclude);
711
741
  if (nested.length > 0) {
712
742
  ret.push(...nested);
@@ -716,7 +746,7 @@ export class EntityLoader {
716
746
  ret.push({
717
747
  field: prefixed,
718
748
  // enforce select-in strategy for self-referencing relations
719
- strategy: selfReferencing ? LoadStrategy.SELECT_IN : strategy ?? prop.strategy,
749
+ strategy: selfReferencing ? LoadStrategy.SELECT_IN : (strategy ?? prop.strategy),
720
750
  });
721
751
  }
722
752
  });
@@ -44,10 +44,9 @@ export declare class Reference<T extends object> {
44
44
  toJSON(...args: any[]): Dictionary;
45
45
  }
46
46
  export declare class ScalarReference<Value> {
47
+ #private;
47
48
  private value?;
48
- private initialized;
49
49
  private entity?;
50
- private property?;
51
50
  constructor(value?: Value | undefined, initialized?: boolean);
52
51
  /**
53
52
  * Ensures the underlying entity is loaded first (without reloading it if it already is loaded).
@@ -73,7 +72,7 @@ export interface LoadReferenceOrFailOptions<T extends object, P extends string =
73
72
  /**
74
73
  * shortcut for `wrap(entity).toReference()`
75
74
  */
76
- export declare function ref<I extends unknown | Ref<unknown> | undefined | null, T extends I & {}>(entity: I): Ref<T> & LoadedReference<Loaded<T, AddEager<T>>> | AddOptional<typeof entity>;
75
+ export declare function ref<I extends unknown | Ref<unknown> | undefined | null, T extends I & {}>(entity: I): (Ref<T> & LoadedReference<Loaded<T, AddEager<T>>>) | AddOptional<typeof entity>;
77
76
  /**
78
77
  * shortcut for `Reference.createFromPK(entityType, pk)`
79
78
  */
@@ -93,7 +93,8 @@ export class Reference {
93
93
  await wrapped.__em.populate(this.entity, options.populate, options);
94
94
  }
95
95
  if (!this.isInitialized() || options.refresh) {
96
- if (options.dataloader ?? [DataloaderType.ALL, DataloaderType.REFERENCE].includes(wrapped.__em.config.getDataloaderType())) {
96
+ if (options.dataloader ??
97
+ [DataloaderType.ALL, DataloaderType.REFERENCE].includes(wrapped.__em.config.getDataloaderType())) {
97
98
  const dataLoader = await wrapped.__em.getDataLoader('ref');
98
99
  return dataLoader.load([this, options]);
99
100
  }
@@ -161,12 +162,12 @@ export class Reference {
161
162
  }
162
163
  export class ScalarReference {
163
164
  value;
164
- initialized;
165
165
  entity;
166
- property;
166
+ #property;
167
+ #initialized;
167
168
  constructor(value, initialized = value != null) {
168
169
  this.value = value;
169
- this.initialized = initialized;
170
+ this.#initialized = initialized;
170
171
  }
171
172
  /**
172
173
  * Ensures the underlying entity is loaded first (without reloading it if it already is loaded).
@@ -174,11 +175,11 @@ export class ScalarReference {
174
175
  */
175
176
  async load(options) {
176
177
  const opts = typeof options === 'object' ? options : { prop: options };
177
- if (!this.initialized || opts.refresh) {
178
- if (this.entity == null || this.property == null) {
178
+ if (!this.#initialized || opts.refresh) {
179
+ if (this.entity == null || this.#property == null) {
179
180
  throw new Error('Cannot load scalar reference that is not bound to an entity property.');
180
181
  }
181
- await helper(this.entity).populate([this.property], opts);
182
+ await helper(this.entity).populate([this.#property], opts);
182
183
  }
183
184
  return this.value;
184
185
  }
@@ -192,43 +193,71 @@ export class ScalarReference {
192
193
  const wrapped = helper(this.entity);
193
194
  options.failHandler ??= wrapped.__em.config.get('findOneOrFailHandler');
194
195
  const entityName = this.entity.constructor.name;
195
- throw NotFoundError.failedToLoadProperty(entityName, this.property, wrapped.getPrimaryKey());
196
+ throw NotFoundError.failedToLoadProperty(entityName, this.#property, wrapped.getPrimaryKey());
196
197
  }
197
198
  return ret;
198
199
  }
199
200
  set(value) {
200
201
  this.value = value;
201
- this.initialized = true;
202
+ this.#initialized = true;
202
203
  }
203
204
  bind(entity, property) {
204
205
  this.entity = entity;
205
- this.property = property;
206
+ this.#property = property;
206
207
  Object.defineProperty(this, 'entity', { enumerable: false, value: entity });
207
208
  }
208
209
  unwrap() {
209
210
  return this.value;
210
211
  }
211
212
  isInitialized() {
212
- return this.initialized;
213
+ return this.#initialized;
213
214
  }
214
215
  /** @ignore */
215
216
  /* v8 ignore next */
216
217
  [Symbol.for('nodejs.util.inspect.custom')]() {
217
- return this.initialized ? `Ref<${inspect(this.value)}>` : `Ref<?>`;
218
+ return this.#initialized ? `Ref<${inspect(this.value)}>` : `Ref<?>`;
218
219
  }
219
220
  }
220
221
  Object.defineProperties(Reference.prototype, {
221
222
  __reference: { value: true, enumerable: false },
222
- __meta: { get() { return this.entity.__meta; } },
223
- __platform: { get() { return this.entity.__platform; } },
224
- __helper: { get() { return this.entity.__helper; } },
225
- $: { get() { return this.entity; } },
226
- get: { get() { return () => this.entity; } },
223
+ __meta: {
224
+ get() {
225
+ return this.entity.__meta;
226
+ },
227
+ },
228
+ __platform: {
229
+ get() {
230
+ return this.entity.__platform;
231
+ },
232
+ },
233
+ __helper: {
234
+ get() {
235
+ return this.entity.__helper;
236
+ },
237
+ },
238
+ $: {
239
+ get() {
240
+ return this.entity;
241
+ },
242
+ },
243
+ get: {
244
+ get() {
245
+ return () => this.entity;
246
+ },
247
+ },
227
248
  });
228
249
  Object.defineProperties(ScalarReference.prototype, {
229
250
  __scalarReference: { value: true, enumerable: false },
230
- $: { get() { return this.value; } },
231
- get: { get() { return () => this.value; } },
251
+ $: {
252
+ get() {
253
+ return this.value;
254
+ },
255
+ },
256
+ get: {
257
+ get() {
258
+ return () => this.value;
259
+ },
260
+ },
232
261
  });
233
262
  /**
234
263
  * shortcut for `wrap(entity).toReference()`
@@ -8,6 +8,8 @@ import type { EntityIdentifier } from './EntityIdentifier.js';
8
8
  import type { SerializationContext } from '../serialization/SerializationContext.js';
9
9
  import { type SerializeOptions } from '../serialization/EntitySerializer.js';
10
10
  import type { FindOneOptions, LoadHint } from '../drivers/IDatabaseDriver.js';
11
+ import type { Platform } from '../platforms/Platform.js';
12
+ import type { Configuration } from '../utils/Configuration.js';
11
13
  export declare class WrappedEntity<Entity extends object> {
12
14
  __initialized: boolean;
13
15
  __populated?: boolean;
@@ -58,7 +60,7 @@ export declare class WrappedEntity<Entity extends object> {
58
60
  setPrimaryKey(id: Primary<Entity> | null): void;
59
61
  getSerializedPrimaryKey(): string;
60
62
  get __meta(): EntityMetadata<Entity>;
61
- get __platform(): import("../index.js").Platform;
62
- get __config(): import("../index.js").Configuration<import("../drivers/IDatabaseDriver.js").IDatabaseDriver<import("../index.js").Connection>, EntityManager<import("../drivers/IDatabaseDriver.js").IDatabaseDriver<import("../index.js").Connection>>>;
63
+ get __platform(): Platform;
64
+ get __config(): Configuration;
63
65
  get __primaryKeys(): Primary<Entity>[];
64
66
  }
@@ -71,7 +71,11 @@ export class WrappedEntity {
71
71
  if (!this.__em) {
72
72
  throw ValidationError.entityNotManaged(this.entity);
73
73
  }
74
- return this.__em.findOne(this.entity.constructor, this.entity, { ...options, refresh: true, schema: this.__schema });
74
+ return this.__em.findOne(this.entity.constructor, this.entity, {
75
+ ...options,
76
+ refresh: true,
77
+ schema: this.__schema,
78
+ });
75
79
  }
76
80
  async populate(populate, options = {}) {
77
81
  if (!this.__em) {