@mikro-orm/core 7.0.0-rc.3 → 7.0.1-dev.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 (94) hide show
  1. package/EntityManager.d.ts +2 -15
  2. package/EntityManager.js +155 -152
  3. package/MikroORM.d.ts +4 -6
  4. package/MikroORM.js +20 -20
  5. package/README.md +5 -4
  6. package/cache/FileCacheAdapter.d.ts +1 -5
  7. package/cache/FileCacheAdapter.js +22 -22
  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 +27 -11
  16. package/drivers/DatabaseDriver.d.ts +0 -2
  17. package/drivers/DatabaseDriver.js +2 -4
  18. package/entity/Collection.d.ts +1 -9
  19. package/entity/Collection.js +95 -105
  20. package/entity/EntityFactory.d.ts +1 -8
  21. package/entity/EntityFactory.js +48 -48
  22. package/entity/EntityLoader.d.ts +1 -3
  23. package/entity/EntityLoader.js +36 -39
  24. package/entity/Reference.d.ts +1 -2
  25. package/entity/Reference.js +11 -11
  26. package/entity/WrappedEntity.d.ts +4 -2
  27. package/entity/defineEntity.d.ts +18 -73
  28. package/enums.d.ts +2 -1
  29. package/enums.js +1 -0
  30. package/errors.d.ts +11 -11
  31. package/errors.js +3 -13
  32. package/events/EventManager.d.ts +1 -4
  33. package/events/EventManager.js +25 -22
  34. package/events/index.d.ts +1 -1
  35. package/events/index.js +0 -1
  36. package/exceptions.js +8 -6
  37. package/hydration/ObjectHydrator.d.ts +1 -2
  38. package/hydration/ObjectHydrator.js +16 -16
  39. package/logging/DefaultLogger.js +3 -2
  40. package/logging/Logger.d.ts +2 -1
  41. package/logging/colors.js +1 -1
  42. package/logging/index.d.ts +1 -1
  43. package/logging/index.js +0 -1
  44. package/metadata/EntitySchema.d.ts +1 -1
  45. package/metadata/MetadataDiscovery.d.ts +1 -9
  46. package/metadata/MetadataDiscovery.js +162 -149
  47. package/metadata/MetadataStorage.d.ts +1 -5
  48. package/metadata/MetadataStorage.js +36 -36
  49. package/metadata/discover-entities.js +1 -1
  50. package/metadata/index.d.ts +1 -1
  51. package/metadata/index.js +0 -1
  52. package/naming-strategy/AbstractNamingStrategy.js +1 -1
  53. package/naming-strategy/EntityCaseNamingStrategy.js +1 -1
  54. package/naming-strategy/index.d.ts +1 -1
  55. package/naming-strategy/index.js +0 -1
  56. package/package.json +1 -1
  57. package/platforms/Platform.d.ts +23 -1
  58. package/platforms/Platform.js +57 -4
  59. package/serialization/EntitySerializer.js +1 -1
  60. package/serialization/EntityTransformer.js +4 -1
  61. package/serialization/SerializationContext.d.ts +4 -8
  62. package/serialization/SerializationContext.js +20 -15
  63. package/types/UuidType.d.ts +2 -0
  64. package/types/UuidType.js +14 -2
  65. package/types/index.d.ts +2 -1
  66. package/typings.d.ts +12 -1
  67. package/unit-of-work/ChangeSetComputer.d.ts +1 -6
  68. package/unit-of-work/ChangeSetComputer.js +21 -21
  69. package/unit-of-work/ChangeSetPersister.d.ts +1 -9
  70. package/unit-of-work/ChangeSetPersister.js +52 -52
  71. package/unit-of-work/CommitOrderCalculator.d.ts +1 -4
  72. package/unit-of-work/CommitOrderCalculator.js +13 -13
  73. package/unit-of-work/IdentityMap.d.ts +2 -5
  74. package/unit-of-work/IdentityMap.js +18 -18
  75. package/unit-of-work/UnitOfWork.d.ts +5 -19
  76. package/unit-of-work/UnitOfWork.js +182 -174
  77. package/utils/AbstractMigrator.d.ts +1 -1
  78. package/utils/AbstractMigrator.js +7 -7
  79. package/utils/Configuration.d.ts +90 -189
  80. package/utils/Configuration.js +94 -78
  81. package/utils/Cursor.d.ts +3 -3
  82. package/utils/Cursor.js +4 -4
  83. package/utils/EntityComparator.d.ts +8 -15
  84. package/utils/EntityComparator.js +49 -49
  85. package/utils/QueryHelper.d.ts +16 -1
  86. package/utils/QueryHelper.js +70 -24
  87. package/utils/RawQueryFragment.d.ts +4 -4
  88. package/utils/TransactionManager.js +1 -2
  89. package/utils/Utils.d.ts +1 -1
  90. package/utils/Utils.js +5 -4
  91. package/utils/clone.js +5 -0
  92. package/utils/fs-utils.d.ts +3 -17
  93. package/utils/fs-utils.js +1 -1
  94. package/utils/upsert-utils.js +1 -1
@@ -12,72 +12,72 @@ import { colors } from '../logging/colors.js';
12
12
  import { raw, Raw } from '../utils/RawQueryFragment.js';
13
13
  import { BaseEntity } from '../entity/BaseEntity.js';
14
14
  export class MetadataDiscovery {
15
- metadata;
16
- platform;
17
- config;
18
- namingStrategy;
19
- metadataProvider;
20
- logger;
21
- schemaHelper;
22
- validator = new MetadataValidator();
23
- discovered = [];
15
+ #namingStrategy;
16
+ #metadataProvider;
17
+ #logger;
18
+ #schemaHelper;
19
+ #validator = new MetadataValidator();
20
+ #discovered = [];
21
+ #metadata;
22
+ #platform;
23
+ #config;
24
24
  constructor(metadata, platform, config) {
25
- this.metadata = metadata;
26
- this.platform = platform;
27
- this.config = config;
28
- this.namingStrategy = this.config.getNamingStrategy();
29
- this.metadataProvider = this.config.getMetadataProvider();
30
- this.logger = this.config.getLogger();
31
- this.schemaHelper = this.platform.getSchemaHelper();
25
+ this.#metadata = metadata;
26
+ this.#platform = platform;
27
+ this.#config = config;
28
+ this.#namingStrategy = this.#config.getNamingStrategy();
29
+ this.#metadataProvider = this.#config.getMetadataProvider();
30
+ this.#logger = this.#config.getLogger();
31
+ this.#schemaHelper = this.#platform.getSchemaHelper();
32
32
  }
33
33
  async discover(preferTs = true) {
34
- this.discovered.length = 0;
34
+ this.#discovered.length = 0;
35
35
  const startTime = Date.now();
36
- const suffix = this.metadataProvider.constructor === MetadataProvider
36
+ const suffix = this.#metadataProvider.constructor === MetadataProvider
37
37
  ? ''
38
- : `, using ${colors.cyan(this.metadataProvider.constructor.name)}`;
39
- this.logger.log('discovery', `ORM entity discovery started${suffix}`);
38
+ : `, using ${colors.cyan(this.#metadataProvider.constructor.name)}`;
39
+ this.#logger.log('discovery', `ORM entity discovery started${suffix}`);
40
40
  await this.findEntities(preferTs);
41
- for (const meta of this.discovered) {
41
+ for (const meta of this.#discovered) {
42
42
  /* v8 ignore next */
43
- await this.config.get('discovery').onMetadata?.(meta, this.platform);
43
+ await this.#config.get('discovery').onMetadata?.(meta, this.#platform);
44
44
  }
45
- this.processDiscoveredEntities(this.discovered);
45
+ this.processDiscoveredEntities(this.#discovered);
46
46
  const diff = Date.now() - startTime;
47
- this.logger.log('discovery', `- entity discovery finished, found ${colors.green('' + this.discovered.length)} entities, took ${colors.green(`${diff} ms`)}`);
47
+ this.#logger.log('discovery', `- entity discovery finished, found ${colors.green('' + this.#discovered.length)} entities, took ${colors.green(`${diff} ms`)}`);
48
48
  const storage = this.mapDiscoveredEntities();
49
49
  /* v8 ignore next */
50
- await this.config.get('discovery').afterDiscovered?.(storage, this.platform);
50
+ await this.#config.get('discovery').afterDiscovered?.(storage, this.#platform);
51
51
  return storage;
52
52
  }
53
53
  discoverSync() {
54
- this.discovered.length = 0;
54
+ this.#discovered.length = 0;
55
55
  const startTime = Date.now();
56
- const suffix = this.metadataProvider.constructor === MetadataProvider
56
+ const suffix = this.#metadataProvider.constructor === MetadataProvider
57
57
  ? ''
58
- : `, using ${colors.cyan(this.metadataProvider.constructor.name)}`;
59
- this.logger.log('discovery', `ORM entity discovery started${suffix} in sync mode`);
60
- const refs = this.config.get('entities');
58
+ : `, using ${colors.cyan(this.#metadataProvider.constructor.name)}`;
59
+ this.#logger.log('discovery', `ORM entity discovery started${suffix} in sync mode`);
60
+ const refs = this.#config.get('entities');
61
61
  this.discoverReferences(refs);
62
- for (const meta of this.discovered) {
62
+ for (const meta of this.#discovered) {
63
63
  /* v8 ignore next */
64
- void this.config.get('discovery').onMetadata?.(meta, this.platform);
64
+ void this.#config.get('discovery').onMetadata?.(meta, this.#platform);
65
65
  }
66
- this.processDiscoveredEntities(this.discovered);
66
+ this.processDiscoveredEntities(this.#discovered);
67
67
  const diff = Date.now() - startTime;
68
- this.logger.log('discovery', `- entity discovery finished, found ${colors.green('' + this.discovered.length)} entities, took ${colors.green(`${diff} ms`)}`);
68
+ this.#logger.log('discovery', `- entity discovery finished, found ${colors.green('' + this.#discovered.length)} entities, took ${colors.green(`${diff} ms`)}`);
69
69
  const storage = this.mapDiscoveredEntities();
70
70
  /* v8 ignore next */
71
- void this.config.get('discovery').afterDiscovered?.(storage, this.platform);
71
+ void this.#config.get('discovery').afterDiscovered?.(storage, this.#platform);
72
72
  return storage;
73
73
  }
74
74
  mapDiscoveredEntities() {
75
75
  const discovered = new MetadataStorage();
76
- this.discovered
76
+ this.#discovered
77
77
  .filter(meta => meta.root.name)
78
78
  .sort((a, b) => b.root.name.localeCompare(a.root.name))
79
79
  .forEach(meta => {
80
- this.platform.validateMetadata(meta);
80
+ this.#platform.validateMetadata(meta);
81
81
  discovered.set(meta.class, meta);
82
82
  });
83
83
  for (const meta of discovered) {
@@ -137,7 +137,7 @@ export class MetadataDiscovery {
137
137
  filtered.forEach(meta => this.defineBaseEntityProperties(meta));
138
138
  filtered.forEach(meta => {
139
139
  const newMeta = EntitySchema.fromMetadata(meta).init().meta;
140
- return this.metadata.set(newMeta.class, newMeta);
140
+ return this.#metadata.set(newMeta.class, newMeta);
141
141
  });
142
142
  filtered.forEach(meta => this.initAutoincrement(meta));
143
143
  const forEachProp = (cb) => {
@@ -167,9 +167,9 @@ export class MetadataDiscovery {
167
167
  discovered.push(...this.processEntity(meta));
168
168
  }
169
169
  discovered.forEach(meta => meta.sync(true));
170
- this.metadataProvider.combineCache();
170
+ this.#metadataProvider.combineCache();
171
171
  return discovered.map(meta => {
172
- meta = this.metadata.get(meta.class);
172
+ meta = this.#metadata.get(meta.class);
173
173
  meta.sync(true);
174
174
  this.findReferencingProperties(meta, filtered);
175
175
  if (meta.inheritanceType === 'tpt') {
@@ -179,7 +179,7 @@ export class MetadataDiscovery {
179
179
  });
180
180
  }
181
181
  async findEntities(preferTs) {
182
- const { entities, entitiesTs, baseDir } = this.config.getAll();
182
+ const { entities, entitiesTs, baseDir } = this.#config.getAll();
183
183
  const targets = preferTs && entitiesTs.length > 0 ? entitiesTs : entities;
184
184
  const processed = [];
185
185
  const paths = [];
@@ -203,13 +203,13 @@ export class MetadataDiscovery {
203
203
  .replace(/\[]$/, '') // remove array suffix
204
204
  .replace(/\((.*)\)/, '$1'); // unwrap union types
205
205
  const missing = [];
206
- this.discovered.forEach(meta => Object.values(meta.properties).forEach(prop => {
206
+ this.#discovered.forEach(meta => Object.values(meta.properties).forEach(prop => {
207
207
  if (prop.kind === ReferenceKind.MANY_TO_MANY && prop.pivotEntity) {
208
208
  const pivotEntity = prop.pivotEntity;
209
209
  const target = typeof pivotEntity === 'function' && !pivotEntity.prototype
210
210
  ? pivotEntity()
211
211
  : pivotEntity;
212
- if (!this.discovered.find(m => m.className === Utils.className(target))) {
212
+ if (!this.#discovered.find(m => m.className === Utils.className(target))) {
213
213
  missing.push(target);
214
214
  }
215
215
  }
@@ -217,7 +217,7 @@ export class MetadataDiscovery {
217
217
  const target = typeof prop.entity === 'function' && !prop.entity.prototype ? prop.entity() : prop.type;
218
218
  if (!unwrap(prop.type)
219
219
  .split(/ ?\| ?/)
220
- .every(type => this.discovered.find(m => m.className === type))) {
220
+ .every(type => this.#discovered.find(m => m.className === type))) {
221
221
  missing.push(...Utils.asArray(target));
222
222
  }
223
223
  }
@@ -233,7 +233,7 @@ export class MetadataDiscovery {
233
233
  if (isDiscoverable && target.name) {
234
234
  // Get the actual class for EntitySchema, or use target directly for classes
235
235
  const targetClass = schema ? schema.meta.class : target;
236
- if (!this.metadata.has(targetClass)) {
236
+ if (!this.#metadata.has(targetClass)) {
237
237
  this.discoverReferences([target], false);
238
238
  this.discoverMissingTargets();
239
239
  }
@@ -248,16 +248,16 @@ export class MetadataDiscovery {
248
248
  }
249
249
  const schema = this.getSchema(entity);
250
250
  const meta = schema.init().meta;
251
- this.metadata.set(meta.class, meta);
251
+ this.#metadata.set(meta.class, meta);
252
252
  found.push(schema);
253
253
  }
254
254
  // discover parents (base entities) automatically
255
- for (const meta of this.metadata) {
255
+ for (const meta of this.#metadata) {
256
256
  let parent = meta.extends;
257
- if (parent instanceof EntitySchema && !this.metadata.has(parent.init().meta.class)) {
257
+ if (parent instanceof EntitySchema && !this.#metadata.has(parent.init().meta.class)) {
258
258
  this.discoverReferences([parent], false);
259
259
  }
260
- if (typeof parent === 'function' && parent.name && !this.metadata.has(parent)) {
260
+ if (typeof parent === 'function' && parent.name && !this.#metadata.has(parent)) {
261
261
  this.discoverReferences([parent], false);
262
262
  }
263
263
  /* v8 ignore next */
@@ -266,7 +266,10 @@ export class MetadataDiscovery {
266
266
  }
267
267
  parent = Object.getPrototypeOf(meta.class);
268
268
  // Skip if parent is the auto-generated base class for the same entity (from setClass usage)
269
- if (parent.name !== '' && parent.name !== meta.className && !this.metadata.has(parent) && parent !== BaseEntity) {
269
+ if (parent.name !== '' &&
270
+ parent.name !== meta.className &&
271
+ !this.#metadata.has(parent) &&
272
+ parent !== BaseEntity) {
270
273
  this.discoverReferences([parent], false);
271
274
  }
272
275
  }
@@ -275,15 +278,15 @@ export class MetadataDiscovery {
275
278
  }
276
279
  this.discoverMissingTargets();
277
280
  if (validate) {
278
- this.validator.validateDiscovered(this.discovered, this.config.get('discovery'));
281
+ this.#validator.validateDiscovered(this.#discovered, this.#config.get('discovery'));
279
282
  }
280
- return this.discovered.filter(meta => found.find(m => m.name === meta.className));
283
+ return this.#discovered.filter(meta => found.find(m => m.name === meta.className));
281
284
  }
282
285
  reset(entityName) {
283
- const exists = this.discovered.findIndex(m => m.class === entityName || m.className === Utils.className(entityName));
286
+ const exists = this.#discovered.findIndex(m => m.class === entityName || m.className === Utils.className(entityName));
284
287
  if (exists !== -1) {
285
- this.metadata.reset(this.discovered[exists].class);
286
- this.discovered.splice(exists, 1);
288
+ this.#metadata.reset(this.#discovered[exists].class);
289
+ this.#discovered.splice(exists, 1);
287
290
  }
288
291
  }
289
292
  getSchema(entity) {
@@ -298,17 +301,17 @@ export class MetadataDiscovery {
298
301
  if (path) {
299
302
  const meta = Utils.copy(MetadataStorage.getMetadata(entity.name, path), false);
300
303
  meta.path = path;
301
- this.metadata.set(entity, meta);
304
+ this.#metadata.set(entity, meta);
302
305
  }
303
- const exists = this.metadata.has(entity);
304
- const meta = this.metadata.get(entity, true);
306
+ const exists = this.#metadata.has(entity);
307
+ const meta = this.#metadata.get(entity, true);
305
308
  meta.abstract ??= !(exists && meta.name);
306
309
  const schema = EntitySchema.fromMetadata(meta);
307
310
  schema.setClass(entity);
308
311
  return schema;
309
312
  }
310
313
  getRootEntity(meta) {
311
- const base = meta.extends && this.metadata.find(meta.extends);
314
+ const base = meta.extends && this.#metadata.find(meta.extends);
312
315
  if (!base || base === meta) {
313
316
  // make sure we do not fall into infinite loop
314
317
  return meta;
@@ -324,13 +327,13 @@ export class MetadataDiscovery {
324
327
  discoverEntity(schema) {
325
328
  const meta = schema.meta;
326
329
  const path = meta.path;
327
- this.logger.log('discovery', `- processing entity ${colors.cyan(meta.className)}${colors.grey(path ? ` (${path})` : '')}`);
330
+ this.#logger.log('discovery', `- processing entity ${colors.cyan(meta.className)}${colors.grey(path ? ` (${path})` : '')}`);
328
331
  const root = this.getRootEntity(meta);
329
332
  schema.meta.path = meta.path;
330
- const cache = this.metadataProvider.getCachedMetadata(meta, root);
333
+ const cache = this.#metadataProvider.getCachedMetadata(meta, root);
331
334
  if (cache) {
332
- this.logger.log('discovery', `- using cached metadata for entity ${colors.cyan(meta.className)}`);
333
- this.discovered.push(meta);
335
+ this.#logger.log('discovery', `- using cached metadata for entity ${colors.cyan(meta.className)}`);
336
+ this.#discovered.push(meta);
334
337
  return;
335
338
  }
336
339
  // infer default value from property initializer early, as the metadata provider might use some defaults, e.g. string for reflect-metadata
@@ -338,14 +341,14 @@ export class MetadataDiscovery {
338
341
  this.inferDefaultValue(meta, prop);
339
342
  }
340
343
  // if the definition is using EntitySchema we still want it to go through the metadata provider to validate no types are missing
341
- this.metadataProvider.loadEntityMetadata(meta);
344
+ this.#metadataProvider.loadEntityMetadata(meta);
342
345
  if (!meta.tableName && meta.name) {
343
346
  const entityName = root.discriminatorColumn ? root.name : meta.name;
344
- meta.tableName = this.namingStrategy.classToTableName(entityName);
347
+ meta.tableName = this.#namingStrategy.classToTableName(entityName);
345
348
  }
346
- this.metadataProvider.saveToCache(meta);
349
+ this.#metadataProvider.saveToCache(meta);
347
350
  meta.root = root;
348
- this.discovered.push(meta);
351
+ this.#discovered.push(meta);
349
352
  }
350
353
  initNullability(prop) {
351
354
  if (prop.kind === ReferenceKind.ONE_TO_ONE) {
@@ -410,7 +413,7 @@ export class MetadataDiscovery {
410
413
  return;
411
414
  }
412
415
  if (prop.kind === ReferenceKind.SCALAR || prop.kind === ReferenceKind.EMBEDDED) {
413
- prop.fieldNames = [this.namingStrategy.propertyToColumnName(prop.name, object)];
416
+ prop.fieldNames = [this.#namingStrategy.propertyToColumnName(prop.name, object)];
414
417
  }
415
418
  else if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && !prop.polymorphic) {
416
419
  prop.fieldNames = this.initManyToOneFieldName(prop, prop.name);
@@ -425,19 +428,19 @@ export class MetadataDiscovery {
425
428
  for (const primaryKey of meta2.primaryKeys) {
426
429
  this.initFieldName(meta2.properties[primaryKey]);
427
430
  for (const fieldName of meta2.properties[primaryKey].fieldNames) {
428
- ret.push(this.namingStrategy.joinKeyColumnName(name, fieldName, meta2.compositePK, tableName));
431
+ ret.push(this.#namingStrategy.joinKeyColumnName(name, fieldName, meta2.compositePK, tableName));
429
432
  }
430
433
  }
431
434
  return ret;
432
435
  }
433
436
  initManyToManyFieldName(prop, name) {
434
437
  const meta2 = prop.targetMeta;
435
- return meta2.primaryKeys.map(() => this.namingStrategy.propertyToColumnName(name));
438
+ return meta2.primaryKeys.map(() => this.#namingStrategy.propertyToColumnName(name));
436
439
  }
437
440
  initManyToManyFields(meta, prop) {
438
441
  const meta2 = prop.targetMeta;
439
442
  Utils.defaultValue(prop, 'fixedOrder', !!prop.fixedOrderColumn);
440
- const pivotMeta = this.metadata.find(prop.pivotEntity);
443
+ const pivotMeta = this.#metadata.find(prop.pivotEntity);
441
444
  const props = Object.values(pivotMeta?.properties ?? {});
442
445
  const pks = props.filter(p => p.primary);
443
446
  const fks = props.filter(p => p.kind === ReferenceKind.MANY_TO_ONE);
@@ -455,8 +458,8 @@ export class MetadataDiscovery {
455
458
  prop.joinColumns ??= first.fieldNames;
456
459
  prop.inverseJoinColumns ??= second.fieldNames;
457
460
  }
458
- if (!prop.pivotTable && prop.owner && this.platform.usesPivotTable()) {
459
- prop.pivotTable = this.namingStrategy.joinTableName(meta.className, meta2.tableName, prop.name, meta.tableName);
461
+ if (!prop.pivotTable && prop.owner && this.#platform.usesPivotTable()) {
462
+ prop.pivotTable = this.#namingStrategy.joinTableName(meta.className, meta2.tableName, prop.name, meta.tableName);
460
463
  }
461
464
  if (prop.mappedBy) {
462
465
  const prop2 = meta2.properties[prop.mappedBy];
@@ -475,22 +478,22 @@ export class MetadataDiscovery {
475
478
  prop.referencedColumnNames ??= Utils.flatten(meta.primaryKeys.map(primaryKey => meta.properties[primaryKey].fieldNames));
476
479
  // For polymorphic M:N, use discriminator base name for FK column (e.g., taggable_id instead of post_id)
477
480
  if (prop.polymorphic && prop.discriminator) {
478
- prop.joinColumns ??= prop.referencedColumnNames.map(referencedColumnName => this.namingStrategy.joinKeyColumnName(prop.discriminator, referencedColumnName, prop.referencedColumnNames.length > 1));
481
+ prop.joinColumns ??= prop.referencedColumnNames.map(referencedColumnName => this.#namingStrategy.joinKeyColumnName(prop.discriminator, referencedColumnName, prop.referencedColumnNames.length > 1));
479
482
  }
480
483
  else {
481
484
  const ownerTableName = this.isExplicitTableName(meta.root) ? meta.root.tableName : undefined;
482
- prop.joinColumns ??= prop.referencedColumnNames.map(referencedColumnName => this.namingStrategy.joinKeyColumnName(meta.root.className, referencedColumnName, meta.compositePK, ownerTableName));
485
+ prop.joinColumns ??= prop.referencedColumnNames.map(referencedColumnName => this.#namingStrategy.joinKeyColumnName(meta.root.className, referencedColumnName, meta.compositePK, ownerTableName));
483
486
  }
484
487
  const inverseTableName = this.isExplicitTableName(meta2.root) ? meta2.root.tableName : undefined;
485
488
  prop.inverseJoinColumns ??= this.initManyToOneFieldName(prop, meta2.root.className, inverseTableName);
486
489
  }
487
490
  isExplicitTableName(meta) {
488
- return meta.tableName !== this.namingStrategy.classToTableName(meta.className);
491
+ return meta.tableName !== this.#namingStrategy.classToTableName(meta.className);
489
492
  }
490
493
  initManyToOneFields(prop) {
491
494
  if (prop.polymorphic && prop.polymorphTargets) {
492
495
  const fieldNames1 = prop.targetMeta.getPrimaryProps().flatMap(pk => pk.fieldNames);
493
- const idColumns = fieldNames1.map(fieldName => this.namingStrategy.joinKeyColumnName(prop.discriminator, fieldName, fieldNames1.length > 1));
496
+ const idColumns = fieldNames1.map(fieldName => this.#namingStrategy.joinKeyColumnName(prop.discriminator, fieldName, fieldNames1.length > 1));
494
497
  prop.fieldNames ??= [prop.discriminatorColumn, ...idColumns];
495
498
  prop.joinColumns ??= idColumns;
496
499
  prop.referencedColumnNames ??= fieldNames1;
@@ -509,7 +512,7 @@ export class MetadataDiscovery {
509
512
  }
510
513
  Utils.defaultValue(prop, 'referencedTableName', meta2.tableName);
511
514
  if (!prop.joinColumns) {
512
- prop.joinColumns = fieldNames.map(fieldName => this.namingStrategy.joinKeyColumnName(prop.name, fieldName, fieldNames.length > 1));
515
+ prop.joinColumns = fieldNames.map(fieldName => this.#namingStrategy.joinKeyColumnName(prop.name, fieldName, fieldNames.length > 1));
513
516
  }
514
517
  if (!prop.referencedColumnNames) {
515
518
  prop.referencedColumnNames = fieldNames;
@@ -528,7 +531,7 @@ export class MetadataDiscovery {
528
531
  initOneToManyFields(prop) {
529
532
  const meta2 = prop.targetMeta;
530
533
  if (!prop.joinColumns) {
531
- prop.joinColumns = [this.namingStrategy.joinColumnName(prop.name)];
534
+ prop.joinColumns = [this.#namingStrategy.joinColumnName(prop.name)];
532
535
  }
533
536
  if (!prop.referencedColumnNames) {
534
537
  meta2.getPrimaryProps().forEach(pk => this.applyNamingStrategy(meta2, pk));
@@ -549,7 +552,7 @@ export class MetadataDiscovery {
549
552
  }
550
553
  }
551
554
  meta.forceConstructor ??= this.shouldForceConstructorUsage(meta);
552
- this.validator.validateEntityDefinition(this.metadata, meta.class, this.config.get('discovery'));
555
+ this.#validator.validateEntityDefinition(this.#metadata, meta.class, this.#config.get('discovery'));
553
556
  for (const prop of Object.values(meta.properties)) {
554
557
  this.initNullability(prop);
555
558
  this.applyNamingStrategy(meta, prop);
@@ -567,7 +570,7 @@ export class MetadataDiscovery {
567
570
  if (meta.serializedPrimaryKey && meta.serializedPrimaryKey !== meta.primaryKeys[0]) {
568
571
  meta.properties[meta.serializedPrimaryKey].persist ??= false;
569
572
  }
570
- if (this.platform.usesPivotTable()) {
573
+ if (this.#platform.usesPivotTable()) {
571
574
  return Object.values(meta.properties)
572
575
  .filter(prop => prop.kind === ReferenceKind.MANY_TO_MANY && prop.owner && prop.pivotTable)
573
576
  .map(prop => {
@@ -594,7 +597,7 @@ export class MetadataDiscovery {
594
597
  ['mappedBy', 'inversedBy', 'pivotEntity'].forEach(type => {
595
598
  const value = prop[type];
596
599
  if (value instanceof Function) {
597
- const meta2 = prop.targetMeta ?? this.metadata.get(prop.target);
600
+ const meta2 = prop.targetMeta ?? this.#metadata.get(prop.target);
598
601
  prop[type] = value(meta2.properties)?.name;
599
602
  if (type === 'pivotEntity' && value) {
600
603
  prop[type] = value(meta2.properties);
@@ -631,8 +634,8 @@ export class MetadataDiscovery {
631
634
  }
632
635
  definePivotTableEntity(meta, prop) {
633
636
  const pivotMeta = prop.pivotEntity
634
- ? this.metadata.find(prop.pivotEntity)
635
- : this.metadata.getByClassName(prop.pivotTable, false);
637
+ ? this.#metadata.find(prop.pivotEntity)
638
+ : this.#metadata.getByClassName(prop.pivotTable, false);
636
639
  // ensure inverse side exists so we can join it when populating via pivot tables
637
640
  if (!prop.inversedBy && prop.targetMeta) {
638
641
  const inverseName = `${meta.className}_${prop.name}__inverse`;
@@ -698,15 +701,15 @@ export class MetadataDiscovery {
698
701
  prop.joinColumns.every((joinColumn, idx) => joinColumn === prop.inverseJoinColumns[idx])) {
699
702
  // use tableName only when explicitly provided by user, otherwise use className for backwards compatibility
700
703
  const baseName = this.isExplicitTableName(meta) ? meta.tableName : meta.className;
701
- prop.joinColumns = prop.referencedColumnNames.map(name => this.namingStrategy.joinKeyColumnName(baseName + '_1', name, meta.compositePK));
702
- prop.inverseJoinColumns = prop.referencedColumnNames.map(name => this.namingStrategy.joinKeyColumnName(baseName + '_2', name, meta.compositePK));
704
+ prop.joinColumns = prop.referencedColumnNames.map(name => this.#namingStrategy.joinKeyColumnName(baseName + '_1', name, meta.compositePK));
705
+ prop.inverseJoinColumns = prop.referencedColumnNames.map(name => this.#namingStrategy.joinKeyColumnName(baseName + '_2', name, meta.compositePK));
703
706
  if (prop.inversedBy) {
704
707
  const prop2 = targetMeta.properties[prop.inversedBy];
705
708
  prop2.inverseJoinColumns = prop.joinColumns;
706
709
  prop2.joinColumns = prop.inverseJoinColumns;
707
710
  }
708
711
  // propagate updated joinColumns to all child entities that inherit this property (STI)
709
- for (const childMeta of this.discovered.filter(m => m.root === meta && m !== meta)) {
712
+ for (const childMeta of this.#discovered.filter(m => m.root === meta && m !== meta)) {
710
713
  const childProp = childMeta.properties[prop.name];
711
714
  if (childProp) {
712
715
  childProp.joinColumns = prop.joinColumns;
@@ -722,7 +725,7 @@ export class MetadataDiscovery {
722
725
  pivotMeta2.properties[meta.name + '_owner'] = this.definePivotProperty(prop, meta.name + '_owner', meta.class, targetType + '_inverse', true, meta.className === targetType);
723
726
  pivotMeta2.properties[targetType + '_inverse'] = this.definePivotProperty(prop, targetType + '_inverse', targetMeta.class, meta.name + '_owner', false, meta.className === targetType);
724
727
  }
725
- return this.metadata.set(pivotMeta2.class, EntitySchema.fromMetadata(pivotMeta2).init().meta);
728
+ return this.#metadata.set(pivotMeta2.class, EntitySchema.fromMetadata(pivotMeta2).init().meta);
726
729
  }
727
730
  /**
728
731
  * Create a scalar property for a pivot table column.
@@ -778,7 +781,7 @@ export class MetadataDiscovery {
778
781
  pivotMeta.properties[primaryProp.name] = primaryProp;
779
782
  pivotMeta.compositePK = false;
780
783
  }
781
- const discriminatorProp = this.createPivotScalarProperty(discriminatorColumn, [this.platform.getVarcharTypeDeclarationSQL(prop)], [discriminatorColumn], { type: 'string', primary: !isCompositePK, nullable: false });
784
+ const discriminatorProp = this.createPivotScalarProperty(discriminatorColumn, [this.#platform.getVarcharTypeDeclarationSQL(prop)], [discriminatorColumn], { type: 'string', primary: !isCompositePK, nullable: false });
782
785
  this.initFieldName(discriminatorProp);
783
786
  pivotMeta.properties[discriminatorColumn] = discriminatorProp;
784
787
  const columnTypes = this.getPrimaryKeyColumnTypes(meta);
@@ -831,21 +834,22 @@ export class MetadataDiscovery {
831
834
  ret.precision = pkProp.precision;
832
835
  ret.scale = pkProp.scale;
833
836
  }
834
- const schema = targetMeta.schema ?? this.config.get('schema') ?? this.platform.getDefaultSchemaName();
837
+ const schema = targetMeta.schema ?? this.#config.get('schema') ?? this.#platform.getDefaultSchemaName();
835
838
  ret.referencedTableName = schema && schema !== '*' ? schema + '.' + targetMeta.tableName : targetMeta.tableName;
836
839
  this.initColumnType(ret);
837
840
  this.initRelation(ret);
838
841
  return ret;
839
842
  }
840
843
  defineFixedOrderProperty(prop, targetMeta) {
841
- const pk = prop.fixedOrderColumn || this.namingStrategy.referenceColumnName();
844
+ const pk = prop.fixedOrderColumn || this.#namingStrategy.referenceColumnName();
842
845
  const primaryProp = {
843
846
  name: pk,
844
847
  type: 'number',
848
+ runtimeType: 'number',
845
849
  kind: ReferenceKind.SCALAR,
846
850
  primary: true,
847
851
  autoincrement: true,
848
- unsigned: this.platform.supportsUnsigned(),
852
+ unsigned: this.#platform.supportsUnsigned(),
849
853
  };
850
854
  this.initFieldName(primaryProp);
851
855
  this.initColumnType(primaryProp);
@@ -866,21 +870,21 @@ export class MetadataDiscovery {
866
870
  cascade: [Cascade.ALL],
867
871
  fixedOrder: prop.fixedOrder,
868
872
  fixedOrderColumn: prop.fixedOrderColumn,
869
- index: this.platform.indexForeignKeys(),
873
+ index: this.#platform.indexForeignKeys(),
870
874
  primary: !prop.fixedOrder,
871
875
  autoincrement: false,
872
876
  updateRule: prop.updateRule,
873
877
  deleteRule: prop.deleteRule,
874
878
  createForeignKeyConstraint: prop.createForeignKeyConstraint,
875
879
  };
876
- const defaultRule = selfReferencing && !this.platform.supportsMultipleCascadePaths() ? 'no action' : 'cascade';
880
+ const defaultRule = selfReferencing && !this.#platform.supportsMultipleCascadePaths() ? 'no action' : 'cascade';
877
881
  ret.updateRule ??= defaultRule;
878
882
  ret.deleteRule ??= defaultRule;
879
- const meta = this.metadata.get(type);
883
+ const meta = this.#metadata.get(type);
880
884
  ret.targetMeta = meta;
881
885
  ret.joinColumns = [];
882
886
  ret.inverseJoinColumns = [];
883
- const schema = meta.schema ?? this.config.get('schema') ?? this.platform.getDefaultSchemaName();
887
+ const schema = meta.schema ?? this.#config.get('schema') ?? this.#platform.getDefaultSchemaName();
884
888
  ret.referencedTableName = schema && schema !== '*' ? schema + '.' + meta.tableName : meta.tableName;
885
889
  if (owner) {
886
890
  ret.owner = true;
@@ -926,7 +930,7 @@ export class MetadataDiscovery {
926
930
  });
927
931
  }
928
932
  defineBaseEntityProperties(meta) {
929
- const base = meta.extends && this.metadata.get(meta.extends);
933
+ const base = meta.extends && this.#metadata.get(meta.extends);
930
934
  if (!base || base === meta) {
931
935
  // make sure we do not fall into infinite loop
932
936
  return 0;
@@ -973,8 +977,8 @@ export class MetadataDiscovery {
973
977
  }
974
978
  visited.add(embeddedProp);
975
979
  const types = embeddedProp.type.split(/ ?\| ?/);
976
- let embeddable = this.discovered.find(m => m.name === embeddedProp.type);
977
- const polymorphs = this.discovered.filter(m => types.includes(m.name));
980
+ let embeddable = this.#discovered.find(m => m.name === embeddedProp.type);
981
+ const polymorphs = this.#discovered.filter(m => types.includes(m.name));
978
982
  // create virtual polymorphic entity
979
983
  if (!embeddable && polymorphs.length > 0) {
980
984
  const properties = {};
@@ -986,13 +990,17 @@ export class MetadataDiscovery {
986
990
  if (properties[prop.name] && properties[prop.name].type !== prop.type) {
987
991
  properties[prop.name].type = `${properties[prop.name].type} | ${prop.type}`;
988
992
  properties[prop.name].runtimeType = 'any';
993
+ properties[prop.name].stiMerged = true;
989
994
  return properties[prop.name];
990
995
  }
991
- return (properties[prop.name] = prop);
996
+ // Deep copy to prevent mutating the original entity's property —
997
+ // both from the merge path above (GH #6522/#6523) and from
998
+ // downstream code that mutates nested arrays like fieldNames.
999
+ return (properties[prop.name] = Utils.copy(prop));
992
1000
  });
993
1001
  };
994
1002
  const processExtensions = (meta) => {
995
- const parent = this.discovered.find(m => {
1003
+ const parent = this.#discovered.find(m => {
996
1004
  return meta.extends && Utils.className(meta.extends) === m.className;
997
1005
  });
998
1006
  if (!parent) {
@@ -1030,7 +1038,7 @@ export class MetadataDiscovery {
1030
1038
  }
1031
1039
  prop.polymorphic = true;
1032
1040
  prop.discriminator ??= prop.name;
1033
- prop.discriminatorColumn ??= this.namingStrategy.discriminatorColumnName(prop.discriminator);
1041
+ prop.discriminatorColumn ??= this.#namingStrategy.discriminatorColumnName(prop.discriminator);
1034
1042
  prop.createForeignKeyConstraint = false;
1035
1043
  const isToOne = [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind);
1036
1044
  if (isToOne) {
@@ -1042,7 +1050,7 @@ export class MetadataDiscovery {
1042
1050
  if (prop.discriminatorMap) {
1043
1051
  const normalizedMap = {};
1044
1052
  for (const [key, value] of Object.entries(prop.discriminatorMap)) {
1045
- const targetMeta = this.metadata.getByClassName(value, false);
1053
+ const targetMeta = this.#metadata.getByClassName(value, false);
1046
1054
  if (!targetMeta) {
1047
1055
  throw MetadataError.fromUnknownEntity(value, `${meta.className}.${prop.name} discriminatorMap`);
1048
1056
  }
@@ -1077,7 +1085,7 @@ export class MetadataDiscovery {
1077
1085
  return;
1078
1086
  }
1079
1087
  visited.add(embeddedProp);
1080
- const embeddable = this.discovered.find(m => m.name === embeddedProp.type);
1088
+ const embeddable = this.#discovered.find(m => m.name === embeddedProp.type);
1081
1089
  if (!embeddable) {
1082
1090
  throw MetadataError.fromUnknownEntity(embeddedProp.type, `${meta.className}.${embeddedProp.name}`);
1083
1091
  }
@@ -1149,7 +1157,7 @@ export class MetadataDiscovery {
1149
1157
  meta.properties[name].fieldNames = prop.fieldNames;
1150
1158
  meta.properties[name].embeddedPath = path;
1151
1159
  const targetProp = prop.targetMeta?.getPrimaryProp() ?? prop;
1152
- const fieldName = raw(this.platform.getSearchJsonPropertySQL(path.join('->'), targetProp.runtimeType ?? targetProp.type, true));
1160
+ const fieldName = raw(this.#platform.getSearchJsonPropertySQL(path.join('->'), targetProp.runtimeType ?? targetProp.type, true));
1153
1161
  meta.properties[name].fieldNameRaw = fieldName.sql; // for querying in SQL drivers
1154
1162
  meta.properties[name].persist = false; // only virtual as we store the whole object
1155
1163
  meta.properties[name].userDefined = false; // mark this as a generated/internal property, so we can distinguish from user-defined non-persist properties
@@ -1191,7 +1199,7 @@ export class MetadataDiscovery {
1191
1199
  const map = meta.root.discriminatorMap;
1192
1200
  Object.keys(map)
1193
1201
  .filter(key => typeof map[key] === 'string')
1194
- .forEach(key => (map[key] = this.metadata.getByClassName(map[key]).class));
1202
+ .forEach(key => (map[key] = this.#metadata.getByClassName(map[key]).class));
1195
1203
  }
1196
1204
  else {
1197
1205
  meta.root.discriminatorMap = {};
@@ -1199,7 +1207,7 @@ export class MetadataDiscovery {
1199
1207
  .filter(m => m.root.class === meta.root.class && !m.abstract)
1200
1208
  .sort((a, b) => a.className.localeCompare(b.className));
1201
1209
  for (const m of children) {
1202
- const name = m.discriminatorValue ?? this.namingStrategy.classToTableName(m.className);
1210
+ const name = m.discriminatorValue ?? this.#namingStrategy.classToTableName(m.className);
1203
1211
  meta.root.discriminatorMap[name] = m.class;
1204
1212
  }
1205
1213
  }
@@ -1215,8 +1223,13 @@ export class MetadataDiscovery {
1215
1223
  Object.values(meta.properties).forEach(prop => {
1216
1224
  const newProp = { ...prop };
1217
1225
  const rootProp = meta.root.properties[prop.name];
1226
+ // stiMerged is set during inlineProperties when a property was merged
1227
+ // from multiple polymorphic variants with different types. The flag is
1228
+ // cleared implicitly when the first child claims the root property via
1229
+ // addProperty below, so subsequent children correctly trigger renaming.
1230
+ const typesMatch = rootProp?.type === prop.type || rootProp?.stiMerged === true;
1218
1231
  if (rootProp &&
1219
- (rootProp.type !== prop.type ||
1232
+ (!typesMatch ||
1220
1233
  (rootProp.fieldNames && prop.fieldNames && !compareArrays(rootProp.fieldNames, prop.fieldNames)))) {
1221
1234
  const name = newProp.name;
1222
1235
  this.initFieldName(newProp, newProp.object);
@@ -1231,7 +1244,7 @@ export class MetadataDiscovery {
1231
1244
  rootProp.stiFieldNameMap = {};
1232
1245
  // Find which discriminator owns the original fieldNames
1233
1246
  for (const [discValue, childClass] of Object.entries(meta.root.discriminatorMap)) {
1234
- const childMeta = this.metadata.find(childClass);
1247
+ const childMeta = this.#metadata.find(childClass);
1235
1248
  if (childMeta?.properties[prop.name]?.fieldNames &&
1236
1249
  compareArrays(childMeta.properties[prop.name].fieldNames, rootProp.fieldNames)) {
1237
1250
  rootProp.stiFieldNameMap[discValue] = rootProp.fieldNames[0];
@@ -1299,11 +1312,11 @@ export class MetadataDiscovery {
1299
1312
  if (meta.tptChildren) {
1300
1313
  meta.tptChildren = meta.tptChildren.map(child => metadata.find(m => m.class === child.class) ?? child);
1301
1314
  }
1302
- const registryMeta = this.metadata.get(meta.class);
1315
+ const registryMeta = this.#metadata.get(meta.class);
1303
1316
  if (registryMeta && registryMeta !== meta) {
1304
1317
  registryMeta.inheritanceType = meta.inheritanceType;
1305
- registryMeta.tptParent = meta.tptParent ? this.metadata.get(meta.tptParent.class) : undefined;
1306
- registryMeta.tptChildren = meta.tptChildren?.map(child => this.metadata.get(child.class));
1318
+ registryMeta.tptParent = meta.tptParent ? this.#metadata.get(meta.tptParent.class) : undefined;
1319
+ registryMeta.tptChildren = meta.tptChildren?.map(child => this.#metadata.get(child.class));
1307
1320
  }
1308
1321
  this.initTPTDiscriminator(meta, metadata);
1309
1322
  }
@@ -1321,12 +1334,12 @@ export class MetadataDiscovery {
1321
1334
  }
1322
1335
  meta.root.discriminatorMap = {};
1323
1336
  for (const m of allDescendants) {
1324
- const name = this.namingStrategy.classToTableName(m.className);
1337
+ const name = this.#namingStrategy.classToTableName(m.className);
1325
1338
  meta.root.discriminatorMap[name] = m.class;
1326
1339
  m.discriminatorValue = name;
1327
1340
  }
1328
1341
  if (!meta.abstract) {
1329
- const name = this.namingStrategy.classToTableName(meta.className);
1342
+ const name = this.#namingStrategy.classToTableName(meta.className);
1330
1343
  meta.root.discriminatorMap[name] = meta.class;
1331
1344
  meta.discriminatorValue = name;
1332
1345
  }
@@ -1439,7 +1452,7 @@ export class MetadataDiscovery {
1439
1452
  }
1440
1453
  initAutoincrement(meta) {
1441
1454
  const pks = meta.getPrimaryProps();
1442
- if (pks.length === 1 && this.platform.isNumericProperty(pks[0])) {
1455
+ if (pks.length === 1 && this.#platform.isNumericProperty(pks[0])) {
1443
1456
  /* v8 ignore next */
1444
1457
  pks[0].autoincrement ??= true;
1445
1458
  }
@@ -1458,12 +1471,12 @@ export class MetadataDiscovery {
1458
1471
  const table = this.createSchemaTable(meta);
1459
1472
  for (const check of meta.checks) {
1460
1473
  const fieldNames = check.property ? meta.properties[check.property].fieldNames : [];
1461
- check.name ??= this.namingStrategy.indexName(meta.tableName, fieldNames, 'check');
1474
+ check.name ??= this.#namingStrategy.indexName(meta.tableName, fieldNames, 'check');
1462
1475
  if (check.expression instanceof Function) {
1463
1476
  check.expression = check.expression(columns, table);
1464
1477
  }
1465
1478
  }
1466
- if (this.platform.usesEnumCheckConstraints() && !meta.embeddable) {
1479
+ if (this.#platform.usesEnumCheckConstraints() && !meta.embeddable) {
1467
1480
  for (const prop of meta.props) {
1468
1481
  if (prop.enum &&
1469
1482
  prop.persist !== false &&
@@ -1471,9 +1484,9 @@ export class MetadataDiscovery {
1471
1484
  prop.items?.every(item => typeof item === 'string')) {
1472
1485
  this.initFieldName(prop);
1473
1486
  meta.checks.push({
1474
- name: this.namingStrategy.indexName(meta.tableName, prop.fieldNames, 'check'),
1487
+ name: this.#namingStrategy.indexName(meta.tableName, prop.fieldNames, 'check'),
1475
1488
  property: prop.name,
1476
- expression: `${this.platform.quoteIdentifier(prop.fieldNames[0])} in ('${prop.items.join("', '")}')`,
1489
+ expression: `${this.#platform.quoteIdentifier(prop.fieldNames[0])} in ('${prop.items.join("', '")}')`,
1477
1490
  });
1478
1491
  }
1479
1492
  }
@@ -1481,13 +1494,13 @@ export class MetadataDiscovery {
1481
1494
  }
1482
1495
  initGeneratedColumn(meta, prop) {
1483
1496
  if (!prop.generated && prop.columnTypes) {
1484
- const match = prop.columnTypes[0]?.match(/(.*) generated always as (.*)/i);
1497
+ const match = /(.*) generated always as (.*)/i.exec(prop.columnTypes[0]);
1485
1498
  if (match) {
1486
1499
  prop.columnTypes[0] = match[1];
1487
1500
  prop.generated = match[2];
1488
1501
  return;
1489
1502
  }
1490
- const match2 = prop.columnTypes[0]?.trim().match(/^as (.*)/i);
1503
+ const match2 = /^as (.*)/i.exec(prop.columnTypes[0]?.trim());
1491
1504
  if (match2) {
1492
1505
  prop.generated = match2[1];
1493
1506
  }
@@ -1504,13 +1517,13 @@ export class MetadataDiscovery {
1504
1517
  }
1505
1518
  /* v8 ignore next */
1506
1519
  if (prop.default != null) {
1507
- return '' + this.platform.convertVersionValue(prop.default, prop);
1520
+ return '' + this.#platform.convertVersionValue(prop.default, prop);
1508
1521
  }
1509
1522
  this.initCustomType(meta, prop, true);
1510
1523
  const type = prop.customType?.runtimeType ?? prop.runtimeType ?? prop.type;
1511
1524
  if (type === 'Date') {
1512
- prop.length ??= this.platform.getDefaultVersionLength();
1513
- return this.platform.getCurrentTimestampSQL(prop.length);
1525
+ prop.length ??= this.#platform.getDefaultVersionLength();
1526
+ return this.#platform.getCurrentTimestampSQL(prop.length);
1514
1527
  }
1515
1528
  return '1';
1516
1529
  }
@@ -1521,7 +1534,7 @@ export class MetadataDiscovery {
1521
1534
  const entity1 = new meta.class();
1522
1535
  const entity2 = new meta.class();
1523
1536
  // we compare the two values by reference, this will discard things like `new Date()` or `Date.now()`
1524
- if (this.config.get('discovery').inferDefaultValues &&
1537
+ if (this.#config.get('discovery').inferDefaultValues &&
1525
1538
  prop.default === undefined &&
1526
1539
  entity1[prop.name] != null &&
1527
1540
  entity1[prop.name] === entity2[prop.name] &&
@@ -1548,11 +1561,11 @@ export class MetadataDiscovery {
1548
1561
  let val = prop.default;
1549
1562
  const raw = Raw.getKnownFragment(val);
1550
1563
  if (raw) {
1551
- prop.defaultRaw = this.platform.formatQuery(raw.sql, raw.params);
1564
+ prop.defaultRaw = this.#platform.formatQuery(raw.sql, raw.params);
1552
1565
  return;
1553
1566
  }
1554
1567
  if (Array.isArray(prop.default) && prop.customType) {
1555
- val = prop.customType.convertToDatabaseValue(prop.default, this.platform);
1568
+ val = prop.customType.convertToDatabaseValue(prop.default, this.#platform);
1556
1569
  }
1557
1570
  prop.defaultRaw = typeof val === 'string' ? `'${val}'` : '' + val;
1558
1571
  }
@@ -1652,7 +1665,7 @@ export class MetadataDiscovery {
1652
1665
  }
1653
1666
  if (prop.customType && !prop.columnTypes) {
1654
1667
  const mappedType = this.getMappedType({
1655
- columnTypes: [prop.customType.getColumnType(prop, this.platform)],
1668
+ columnTypes: [prop.customType.getColumnType(prop, this.#platform)],
1656
1669
  });
1657
1670
  if (prop.customType.compareAsType() === 'any' && ![t.json].some(t => prop.customType instanceof t)) {
1658
1671
  prop.runtimeType ??= mappedType.runtimeType;
@@ -1668,15 +1681,15 @@ export class MetadataDiscovery {
1668
1681
  prop.runtimeType ??= mappedType.runtimeType;
1669
1682
  }
1670
1683
  if (prop.customType) {
1671
- prop.customType.platform = this.platform;
1684
+ prop.customType.platform = this.#platform;
1672
1685
  prop.customType.meta = meta;
1673
1686
  prop.customType.prop = prop;
1674
- prop.columnTypes ??= [prop.customType.getColumnType(prop, this.platform)];
1687
+ prop.columnTypes ??= [prop.customType.getColumnType(prop, this.#platform)];
1675
1688
  prop.hasConvertToJSValueSQL =
1676
- !!prop.customType.convertToJSValueSQL && prop.customType.convertToJSValueSQL('', this.platform) !== '';
1689
+ !!prop.customType.convertToJSValueSQL && prop.customType.convertToJSValueSQL('', this.#platform) !== '';
1677
1690
  prop.hasConvertToDatabaseValueSQL =
1678
1691
  !!prop.customType.convertToDatabaseValueSQL &&
1679
- prop.customType.convertToDatabaseValueSQL('', this.platform) !== '';
1692
+ prop.customType.convertToDatabaseValueSQL('', this.#platform) !== '';
1680
1693
  if (prop.customType instanceof t.bigint &&
1681
1694
  ['string', 'bigint', 'number'].includes(prop.runtimeType.toLowerCase())) {
1682
1695
  prop.customType.mode = prop.runtimeType.toLowerCase();
@@ -1694,11 +1707,11 @@ export class MetadataDiscovery {
1694
1707
  if (pk.customType) {
1695
1708
  prop.customTypes.push(pk.customType);
1696
1709
  prop.hasConvertToJSValueSQL ||=
1697
- !!pk.customType.convertToJSValueSQL && pk.customType.convertToJSValueSQL('', this.platform) !== '';
1710
+ !!pk.customType.convertToJSValueSQL && pk.customType.convertToJSValueSQL('', this.#platform) !== '';
1698
1711
  /* v8 ignore next */
1699
1712
  prop.hasConvertToDatabaseValueSQL ||=
1700
1713
  !!pk.customType.convertToDatabaseValueSQL &&
1701
- pk.customType.convertToDatabaseValueSQL('', this.platform) !== '';
1714
+ pk.customType.convertToDatabaseValueSQL('', this.#platform) !== '';
1702
1715
  }
1703
1716
  else {
1704
1717
  prop.customTypes.push(undefined);
@@ -1708,13 +1721,13 @@ export class MetadataDiscovery {
1708
1721
  if (prop.kind === ReferenceKind.SCALAR && !(mappedType instanceof t.unknown)) {
1709
1722
  if (!prop.columnTypes &&
1710
1723
  prop.nativeEnumName &&
1711
- meta.schema !== this.platform.getDefaultSchemaName() &&
1724
+ meta.schema !== this.#platform.getDefaultSchemaName() &&
1712
1725
  meta.schema &&
1713
1726
  !prop.nativeEnumName.includes('.')) {
1714
1727
  prop.columnTypes = [`${meta.schema}.${prop.nativeEnumName}`];
1715
1728
  }
1716
1729
  else {
1717
- prop.columnTypes ??= [mappedType.getColumnType(prop, this.platform)];
1730
+ prop.columnTypes ??= [mappedType.getColumnType(prop, this.#platform)];
1718
1731
  }
1719
1732
  // use only custom types provided by user, we don't need to use the ones provided by ORM,
1720
1733
  // with exception for ArrayType and JsonType, those two are handled in
@@ -1728,7 +1741,7 @@ export class MetadataDiscovery {
1728
1741
  return;
1729
1742
  }
1730
1743
  // when the target is a polymorphic embedded entity, `prop.target` is an array of classes, we need to get the metadata by the type name instead
1731
- const meta2 = this.metadata.find(prop.target) ?? this.metadata.getByClassName(prop.type);
1744
+ const meta2 = this.#metadata.find(prop.target) ?? this.#metadata.getByClassName(prop.type);
1732
1745
  // If targetKey is specified, use that property instead of PKs for referencedPKs
1733
1746
  prop.referencedPKs = prop.targetKey ? [prop.targetKey] : meta2.primaryKeys;
1734
1747
  prop.targetMeta = meta2;
@@ -1743,7 +1756,7 @@ export class MetadataDiscovery {
1743
1756
  !prop.embedded) {
1744
1757
  this.initFieldName(prop);
1745
1758
  if (prop.fieldNames?.length === 1) {
1746
- prop.formula = table => `${table}.${this.platform.quoteIdentifier(prop.fieldNames[0])}`;
1759
+ prop.formula = table => `${table}.${this.#platform.quoteIdentifier(prop.fieldNames[0])}`;
1747
1760
  }
1748
1761
  }
1749
1762
  }
@@ -1765,7 +1778,7 @@ export class MetadataDiscovery {
1765
1778
  const mappedType = this.getMappedType(prop);
1766
1779
  prop.type = mappedType.compareAsType();
1767
1780
  }
1768
- if (prop.columnTypes || !this.schemaHelper) {
1781
+ if (prop.columnTypes || !this.#schemaHelper) {
1769
1782
  return;
1770
1783
  }
1771
1784
  if (prop.kind === ReferenceKind.SCALAR) {
@@ -1775,18 +1788,18 @@ export class MetadataDiscovery {
1775
1788
  // it could be a runtime type from reflect-metadata
1776
1789
  !SCALAR_TYPES.includes(prop.type) &&
1777
1790
  // or it might be inferred via ts-morph to some generic type alias
1778
- !prop.type.match(/[<>:"';{}]/)) {
1791
+ !/[<>:"';{}]/.exec(prop.type)) {
1779
1792
  const type = prop.length != null && !prop.type.endsWith(`(${prop.length})`) ? `${prop.type}(${prop.length})` : prop.type;
1780
1793
  prop.columnTypes = [type];
1781
1794
  }
1782
1795
  else {
1783
- prop.columnTypes = [mappedType.getColumnType(prop, this.platform)];
1796
+ prop.columnTypes = [mappedType.getColumnType(prop, this.#platform)];
1784
1797
  }
1785
1798
  return;
1786
1799
  }
1787
1800
  /* v8 ignore next */
1788
1801
  if (prop.kind === ReferenceKind.EMBEDDED && prop.object) {
1789
- prop.columnTypes = [this.platform.getJsonDeclarationSQL()];
1802
+ prop.columnTypes = [this.#platform.getJsonDeclarationSQL()];
1790
1803
  return;
1791
1804
  }
1792
1805
  const targetMeta = prop.targetMeta;
@@ -1794,7 +1807,7 @@ export class MetadataDiscovery {
1794
1807
  // Use targetKey property if specified, otherwise use primary key properties
1795
1808
  const referencedProps = prop.targetKey ? [targetMeta.properties[prop.targetKey]] : targetMeta.getPrimaryProps();
1796
1809
  if (prop.polymorphic && prop.polymorphTargets) {
1797
- prop.columnTypes.push(this.platform.getVarcharTypeDeclarationSQL(prop));
1810
+ prop.columnTypes.push(this.#platform.getVarcharTypeDeclarationSQL(prop));
1798
1811
  }
1799
1812
  for (const referencedProp of referencedProps) {
1800
1813
  this.initCustomType(targetMeta, referencedProp);
@@ -1802,7 +1815,7 @@ export class MetadataDiscovery {
1802
1815
  const mappedType = this.getMappedType(referencedProp);
1803
1816
  let columnTypes = referencedProp.columnTypes;
1804
1817
  if (referencedProp.autoincrement) {
1805
- columnTypes = [mappedType.getColumnType({ ...referencedProp, autoincrement: false }, this.platform)];
1818
+ columnTypes = [mappedType.getColumnType({ ...referencedProp, autoincrement: false }, this.#platform)];
1806
1819
  }
1807
1820
  prop.columnTypes.push(...columnTypes);
1808
1821
  if (!targetMeta.compositePK || prop.targetKey) {
@@ -1825,7 +1838,7 @@ export class MetadataDiscovery {
1825
1838
  if (t === 'Date') {
1826
1839
  t = 'datetime';
1827
1840
  }
1828
- return this.platform.getMappedType(t);
1841
+ return this.#platform.getMappedType(t);
1829
1842
  }
1830
1843
  getPrefix(prop, parent) {
1831
1844
  const { embeddedPath = [], fieldNames, prefix = true, prefixMode } = prop;
@@ -1836,7 +1849,7 @@ export class MetadataDiscovery {
1836
1849
  if (prefix === false) {
1837
1850
  return prefixParent;
1838
1851
  }
1839
- const mode = prefixMode ?? this.config.get('embeddables').prefixMode;
1852
+ const mode = prefixMode ?? this.#config.get('embeddables').prefixMode;
1840
1853
  return mode === 'absolute' ? prefix : prefixParent + prefix;
1841
1854
  }
1842
1855
  initUnsigned(prop) {
@@ -1851,16 +1864,16 @@ export class MetadataDiscovery {
1851
1864
  return;
1852
1865
  }
1853
1866
  prop.unsigned ??=
1854
- (prop.primary || prop.unsigned) && this.platform.isNumericProperty(prop) && this.platform.supportsUnsigned();
1867
+ (prop.primary || prop.unsigned) && this.#platform.isNumericProperty(prop) && this.#platform.supportsUnsigned();
1855
1868
  }
1856
1869
  initIndexes(meta, prop) {
1857
1870
  const hasIndex = meta.indexes.some(idx => idx.properties?.length === 1 && idx.properties[0] === prop.name);
1858
- if (prop.kind === ReferenceKind.MANY_TO_ONE && this.platform.indexForeignKeys() && !hasIndex) {
1871
+ if (prop.kind === ReferenceKind.MANY_TO_ONE && this.#platform.indexForeignKeys() && !hasIndex) {
1859
1872
  prop.index ??= true;
1860
1873
  }
1861
1874
  }
1862
1875
  shouldForceConstructorUsage(meta) {
1863
- const forceConstructor = this.config.get('forceEntityConstructor');
1876
+ const forceConstructor = this.#config.get('forceEntityConstructor');
1864
1877
  if (Array.isArray(forceConstructor)) {
1865
1878
  return forceConstructor.some(cls => Utils.className(cls) === meta.className);
1866
1879
  }