@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
@@ -12,68 +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 ? '' : `, using ${colors.cyan(this.metadataProvider.constructor.name)}`;
37
- this.logger.log('discovery', `ORM entity discovery started${suffix}`);
36
+ const suffix = this.#metadataProvider.constructor === MetadataProvider
37
+ ? ''
38
+ : `, using ${colors.cyan(this.#metadataProvider.constructor.name)}`;
39
+ this.#logger.log('discovery', `ORM entity discovery started${suffix}`);
38
40
  await this.findEntities(preferTs);
39
- for (const meta of this.discovered) {
41
+ for (const meta of this.#discovered) {
40
42
  /* v8 ignore next */
41
- await this.config.get('discovery').onMetadata?.(meta, this.platform);
43
+ await this.#config.get('discovery').onMetadata?.(meta, this.#platform);
42
44
  }
43
- this.processDiscoveredEntities(this.discovered);
45
+ this.processDiscoveredEntities(this.#discovered);
44
46
  const diff = Date.now() - startTime;
45
- 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`)}`);
46
48
  const storage = this.mapDiscoveredEntities();
47
49
  /* v8 ignore next */
48
- await this.config.get('discovery').afterDiscovered?.(storage, this.platform);
50
+ await this.#config.get('discovery').afterDiscovered?.(storage, this.#platform);
49
51
  return storage;
50
52
  }
51
53
  discoverSync() {
52
- this.discovered.length = 0;
54
+ this.#discovered.length = 0;
53
55
  const startTime = Date.now();
54
- const suffix = this.metadataProvider.constructor === MetadataProvider ? '' : `, using ${colors.cyan(this.metadataProvider.constructor.name)}`;
55
- this.logger.log('discovery', `ORM entity discovery started${suffix} in sync mode`);
56
- const refs = this.config.get('entities');
56
+ const suffix = this.#metadataProvider.constructor === MetadataProvider
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');
57
61
  this.discoverReferences(refs);
58
- for (const meta of this.discovered) {
62
+ for (const meta of this.#discovered) {
59
63
  /* v8 ignore next */
60
- void this.config.get('discovery').onMetadata?.(meta, this.platform);
64
+ void this.#config.get('discovery').onMetadata?.(meta, this.#platform);
61
65
  }
62
- this.processDiscoveredEntities(this.discovered);
66
+ this.processDiscoveredEntities(this.#discovered);
63
67
  const diff = Date.now() - startTime;
64
- 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`)}`);
65
69
  const storage = this.mapDiscoveredEntities();
66
70
  /* v8 ignore next */
67
- void this.config.get('discovery').afterDiscovered?.(storage, this.platform);
71
+ void this.#config.get('discovery').afterDiscovered?.(storage, this.#platform);
68
72
  return storage;
69
73
  }
70
74
  mapDiscoveredEntities() {
71
75
  const discovered = new MetadataStorage();
72
- this.discovered
76
+ this.#discovered
73
77
  .filter(meta => meta.root.name)
74
78
  .sort((a, b) => b.root.name.localeCompare(a.root.name))
75
79
  .forEach(meta => {
76
- this.platform.validateMetadata(meta);
80
+ this.#platform.validateMetadata(meta);
77
81
  discovered.set(meta.class, meta);
78
82
  });
79
83
  for (const meta of discovered) {
@@ -91,6 +95,7 @@ export class MetadataDiscovery {
91
95
  }
92
96
  const desc = Object.getOwnPropertyDescriptor(meta.prototype, prop.name);
93
97
  if (desc?.get || desc?.set) {
98
+ this.initRelation(prop);
94
99
  this.initFieldName(prop);
95
100
  const accessor = prop.name;
96
101
  prop.name = typeof prop.accessor === 'string' ? prop.accessor : prop.name;
@@ -106,7 +111,10 @@ export class MetadataDiscovery {
106
111
  }
107
112
  else {
108
113
  const name = prop.name;
109
- prop.name = prop.accessor;
114
+ if (prop.kind === ReferenceKind.SCALAR || prop.kind === ReferenceKind.EMBEDDED) {
115
+ prop.name = prop.accessor;
116
+ }
117
+ this.initRelation(prop);
110
118
  this.initFieldName(prop);
111
119
  prop.serializedName ??= prop.accessor;
112
120
  prop.name = name;
@@ -123,13 +131,13 @@ export class MetadataDiscovery {
123
131
  // ignore base entities (not annotated with @Entity)
124
132
  const filtered = discovered.filter(meta => meta.root.name);
125
133
  // sort so we discover entities first to get around issues with nested embeddables
126
- filtered.sort((a, b) => !a.embeddable === !b.embeddable ? 0 : (a.embeddable ? 1 : -1));
134
+ filtered.sort((a, b) => (!a.embeddable === !b.embeddable ? 0 : a.embeddable ? 1 : -1));
127
135
  filtered.forEach(meta => this.initSingleTableInheritance(meta, filtered));
128
136
  filtered.forEach(meta => this.initTPTRelationships(meta, filtered));
129
137
  filtered.forEach(meta => this.defineBaseEntityProperties(meta));
130
138
  filtered.forEach(meta => {
131
139
  const newMeta = EntitySchema.fromMetadata(meta).init().meta;
132
- return this.metadata.set(newMeta.class, newMeta);
140
+ return this.#metadata.set(newMeta.class, newMeta);
133
141
  });
134
142
  filtered.forEach(meta => this.initAutoincrement(meta));
135
143
  const forEachProp = (cb) => {
@@ -159,9 +167,9 @@ export class MetadataDiscovery {
159
167
  discovered.push(...this.processEntity(meta));
160
168
  }
161
169
  discovered.forEach(meta => meta.sync(true));
162
- this.metadataProvider.combineCache();
170
+ this.#metadataProvider.combineCache();
163
171
  return discovered.map(meta => {
164
- meta = this.metadata.get(meta.class);
172
+ meta = this.#metadata.get(meta.class);
165
173
  meta.sync(true);
166
174
  this.findReferencingProperties(meta, filtered);
167
175
  if (meta.inheritanceType === 'tpt') {
@@ -171,8 +179,8 @@ export class MetadataDiscovery {
171
179
  });
172
180
  }
173
181
  async findEntities(preferTs) {
174
- const { entities, entitiesTs, baseDir } = this.config.getAll();
175
- const targets = (preferTs && entitiesTs.length > 0) ? entitiesTs : entities;
182
+ const { entities, entitiesTs, baseDir } = this.#config.getAll();
183
+ const targets = preferTs && entitiesTs.length > 0 ? entitiesTs : entities;
176
184
  const processed = [];
177
185
  const paths = [];
178
186
  for (const entity of targets) {
@@ -185,7 +193,7 @@ export class MetadataDiscovery {
185
193
  }
186
194
  if (paths.length > 0) {
187
195
  const { discoverEntities } = await import('@mikro-orm/core/file-discovery');
188
- processed.push(...await discoverEntities(paths, { baseDir }));
196
+ processed.push(...(await discoverEntities(paths, { baseDir })));
189
197
  }
190
198
  return this.discoverReferences(processed);
191
199
  }
@@ -195,21 +203,21 @@ export class MetadataDiscovery {
195
203
  .replace(/\[]$/, '') // remove array suffix
196
204
  .replace(/\((.*)\)/, '$1'); // unwrap union types
197
205
  const missing = [];
198
- this.discovered.forEach(meta => Object.values(meta.properties).forEach(prop => {
206
+ this.#discovered.forEach(meta => Object.values(meta.properties).forEach(prop => {
199
207
  if (prop.kind === ReferenceKind.MANY_TO_MANY && prop.pivotEntity) {
200
208
  const pivotEntity = prop.pivotEntity;
201
209
  const target = typeof pivotEntity === 'function' && !pivotEntity.prototype
202
210
  ? pivotEntity()
203
211
  : pivotEntity;
204
- if (!this.discovered.find(m => m.className === Utils.className(target))) {
212
+ if (!this.#discovered.find(m => m.className === Utils.className(target))) {
205
213
  missing.push(target);
206
214
  }
207
215
  }
208
216
  if (prop.kind !== ReferenceKind.SCALAR) {
209
- const target = typeof prop.entity === 'function' && !prop.entity.prototype
210
- ? prop.entity()
211
- : prop.type;
212
- if (!unwrap(prop.type).split(/ ?\| ?/).every(type => this.discovered.find(m => m.className === type))) {
217
+ const target = typeof prop.entity === 'function' && !prop.entity.prototype ? prop.entity() : prop.type;
218
+ if (!unwrap(prop.type)
219
+ .split(/ ?\| ?/)
220
+ .every(type => this.#discovered.find(m => m.className === type))) {
213
221
  missing.push(...Utils.asArray(target));
214
222
  }
215
223
  }
@@ -225,7 +233,7 @@ export class MetadataDiscovery {
225
233
  if (isDiscoverable && target.name) {
226
234
  // Get the actual class for EntitySchema, or use target directly for classes
227
235
  const targetClass = schema ? schema.meta.class : target;
228
- if (!this.metadata.has(targetClass)) {
236
+ if (!this.#metadata.has(targetClass)) {
229
237
  this.discoverReferences([target], false);
230
238
  this.discoverMissingTargets();
231
239
  }
@@ -240,16 +248,16 @@ export class MetadataDiscovery {
240
248
  }
241
249
  const schema = this.getSchema(entity);
242
250
  const meta = schema.init().meta;
243
- this.metadata.set(meta.class, meta);
251
+ this.#metadata.set(meta.class, meta);
244
252
  found.push(schema);
245
253
  }
246
254
  // discover parents (base entities) automatically
247
- for (const meta of this.metadata) {
255
+ for (const meta of this.#metadata) {
248
256
  let parent = meta.extends;
249
- if (parent instanceof EntitySchema && !this.metadata.has(parent.init().meta.class)) {
257
+ if (parent instanceof EntitySchema && !this.#metadata.has(parent.init().meta.class)) {
250
258
  this.discoverReferences([parent], false);
251
259
  }
252
- if (typeof parent === 'function' && parent.name && !this.metadata.has(parent)) {
260
+ if (typeof parent === 'function' && parent.name && !this.#metadata.has(parent)) {
253
261
  this.discoverReferences([parent], false);
254
262
  }
255
263
  /* v8 ignore next */
@@ -258,7 +266,10 @@ export class MetadataDiscovery {
258
266
  }
259
267
  parent = Object.getPrototypeOf(meta.class);
260
268
  // Skip if parent is the auto-generated base class for the same entity (from setClass usage)
261
- 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) {
262
273
  this.discoverReferences([parent], false);
263
274
  }
264
275
  }
@@ -267,15 +278,15 @@ export class MetadataDiscovery {
267
278
  }
268
279
  this.discoverMissingTargets();
269
280
  if (validate) {
270
- this.validator.validateDiscovered(this.discovered, this.config.get('discovery'));
281
+ this.#validator.validateDiscovered(this.#discovered, this.#config.get('discovery'));
271
282
  }
272
- 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));
273
284
  }
274
285
  reset(entityName) {
275
- 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));
276
287
  if (exists !== -1) {
277
- this.metadata.reset(this.discovered[exists].class);
278
- this.discovered.splice(exists, 1);
288
+ this.#metadata.reset(this.#discovered[exists].class);
289
+ this.#discovered.splice(exists, 1);
279
290
  }
280
291
  }
281
292
  getSchema(entity) {
@@ -290,18 +301,19 @@ export class MetadataDiscovery {
290
301
  if (path) {
291
302
  const meta = Utils.copy(MetadataStorage.getMetadata(entity.name, path), false);
292
303
  meta.path = path;
293
- this.metadata.set(entity, meta);
304
+ this.#metadata.set(entity, meta);
294
305
  }
295
- const exists = this.metadata.has(entity);
296
- const meta = this.metadata.get(entity, true);
306
+ const exists = this.#metadata.has(entity);
307
+ const meta = this.#metadata.get(entity, true);
297
308
  meta.abstract ??= !(exists && meta.name);
298
309
  const schema = EntitySchema.fromMetadata(meta);
299
310
  schema.setClass(entity);
300
311
  return schema;
301
312
  }
302
313
  getRootEntity(meta) {
303
- const base = meta.extends && this.metadata.find(meta.extends);
304
- if (!base || base === meta) { // make sure we do not fall into infinite loop
314
+ const base = meta.extends && this.#metadata.find(meta.extends);
315
+ if (!base || base === meta) {
316
+ // make sure we do not fall into infinite loop
305
317
  return meta;
306
318
  }
307
319
  const root = this.getRootEntity(base);
@@ -315,13 +327,13 @@ export class MetadataDiscovery {
315
327
  discoverEntity(schema) {
316
328
  const meta = schema.meta;
317
329
  const path = meta.path;
318
- 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})` : '')}`);
319
331
  const root = this.getRootEntity(meta);
320
332
  schema.meta.path = meta.path;
321
- const cache = this.metadataProvider.getCachedMetadata(meta, root);
333
+ const cache = this.#metadataProvider.getCachedMetadata(meta, root);
322
334
  if (cache) {
323
- this.logger.log('discovery', `- using cached metadata for entity ${colors.cyan(meta.className)}`);
324
- this.discovered.push(meta);
335
+ this.#logger.log('discovery', `- using cached metadata for entity ${colors.cyan(meta.className)}`);
336
+ this.#discovered.push(meta);
325
337
  return;
326
338
  }
327
339
  // infer default value from property initializer early, as the metadata provider might use some defaults, e.g. string for reflect-metadata
@@ -329,14 +341,14 @@ export class MetadataDiscovery {
329
341
  this.inferDefaultValue(meta, prop);
330
342
  }
331
343
  // if the definition is using EntitySchema we still want it to go through the metadata provider to validate no types are missing
332
- this.metadataProvider.loadEntityMetadata(meta);
344
+ this.#metadataProvider.loadEntityMetadata(meta);
333
345
  if (!meta.tableName && meta.name) {
334
346
  const entityName = root.discriminatorColumn ? root.name : meta.name;
335
- meta.tableName = this.namingStrategy.classToTableName(entityName);
347
+ meta.tableName = this.#namingStrategy.classToTableName(entityName);
336
348
  }
337
- this.metadataProvider.saveToCache(meta);
349
+ this.#metadataProvider.saveToCache(meta);
338
350
  meta.root = root;
339
- this.discovered.push(meta);
351
+ this.#discovered.push(meta);
340
352
  }
341
353
  initNullability(prop) {
342
354
  if (prop.kind === ReferenceKind.ONE_TO_ONE) {
@@ -361,7 +373,10 @@ export class MetadataDiscovery {
361
373
  initOwnColumns(meta) {
362
374
  meta.sync();
363
375
  for (const prop of meta.props) {
364
- if (!prop.joinColumns || !prop.columnTypes || prop.ownColumns || ![ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
376
+ if (!prop.joinColumns ||
377
+ !prop.columnTypes ||
378
+ prop.ownColumns ||
379
+ ![ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
365
380
  continue;
366
381
  }
367
382
  // For polymorphic relations, ownColumns should include all fieldNames
@@ -398,7 +413,7 @@ export class MetadataDiscovery {
398
413
  return;
399
414
  }
400
415
  if (prop.kind === ReferenceKind.SCALAR || prop.kind === ReferenceKind.EMBEDDED) {
401
- prop.fieldNames = [this.namingStrategy.propertyToColumnName(prop.name, object)];
416
+ prop.fieldNames = [this.#namingStrategy.propertyToColumnName(prop.name, object)];
402
417
  }
403
418
  else if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && !prop.polymorphic) {
404
419
  prop.fieldNames = this.initManyToOneFieldName(prop, prop.name);
@@ -413,19 +428,19 @@ export class MetadataDiscovery {
413
428
  for (const primaryKey of meta2.primaryKeys) {
414
429
  this.initFieldName(meta2.properties[primaryKey]);
415
430
  for (const fieldName of meta2.properties[primaryKey].fieldNames) {
416
- ret.push(this.namingStrategy.joinKeyColumnName(name, fieldName, meta2.compositePK, tableName));
431
+ ret.push(this.#namingStrategy.joinKeyColumnName(name, fieldName, meta2.compositePK, tableName));
417
432
  }
418
433
  }
419
434
  return ret;
420
435
  }
421
436
  initManyToManyFieldName(prop, name) {
422
437
  const meta2 = prop.targetMeta;
423
- return meta2.primaryKeys.map(() => this.namingStrategy.propertyToColumnName(name));
438
+ return meta2.primaryKeys.map(() => this.#namingStrategy.propertyToColumnName(name));
424
439
  }
425
440
  initManyToManyFields(meta, prop) {
426
441
  const meta2 = prop.targetMeta;
427
442
  Utils.defaultValue(prop, 'fixedOrder', !!prop.fixedOrderColumn);
428
- const pivotMeta = this.metadata.find(prop.pivotEntity);
443
+ const pivotMeta = this.#metadata.find(prop.pivotEntity);
429
444
  const props = Object.values(pivotMeta?.properties ?? {});
430
445
  const pks = props.filter(p => p.primary);
431
446
  const fks = props.filter(p => p.kind === ReferenceKind.MANY_TO_ONE);
@@ -443,8 +458,8 @@ export class MetadataDiscovery {
443
458
  prop.joinColumns ??= first.fieldNames;
444
459
  prop.inverseJoinColumns ??= second.fieldNames;
445
460
  }
446
- if (!prop.pivotTable && prop.owner && this.platform.usesPivotTable()) {
447
- 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);
448
463
  }
449
464
  if (prop.mappedBy) {
450
465
  const prop2 = meta2.properties[prop.mappedBy];
@@ -463,22 +478,22 @@ export class MetadataDiscovery {
463
478
  prop.referencedColumnNames ??= Utils.flatten(meta.primaryKeys.map(primaryKey => meta.properties[primaryKey].fieldNames));
464
479
  // For polymorphic M:N, use discriminator base name for FK column (e.g., taggable_id instead of post_id)
465
480
  if (prop.polymorphic && prop.discriminator) {
466
- 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));
467
482
  }
468
483
  else {
469
484
  const ownerTableName = this.isExplicitTableName(meta.root) ? meta.root.tableName : undefined;
470
- 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));
471
486
  }
472
487
  const inverseTableName = this.isExplicitTableName(meta2.root) ? meta2.root.tableName : undefined;
473
488
  prop.inverseJoinColumns ??= this.initManyToOneFieldName(prop, meta2.root.className, inverseTableName);
474
489
  }
475
490
  isExplicitTableName(meta) {
476
- return meta.tableName !== this.namingStrategy.classToTableName(meta.className);
491
+ return meta.tableName !== this.#namingStrategy.classToTableName(meta.className);
477
492
  }
478
493
  initManyToOneFields(prop) {
479
494
  if (prop.polymorphic && prop.polymorphTargets) {
480
495
  const fieldNames1 = prop.targetMeta.getPrimaryProps().flatMap(pk => pk.fieldNames);
481
- 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));
482
497
  prop.fieldNames ??= [prop.discriminatorColumn, ...idColumns];
483
498
  prop.joinColumns ??= idColumns;
484
499
  prop.referencedColumnNames ??= fieldNames1;
@@ -497,7 +512,7 @@ export class MetadataDiscovery {
497
512
  }
498
513
  Utils.defaultValue(prop, 'referencedTableName', meta2.tableName);
499
514
  if (!prop.joinColumns) {
500
- 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));
501
516
  }
502
517
  if (!prop.referencedColumnNames) {
503
518
  prop.referencedColumnNames = fieldNames;
@@ -516,7 +531,7 @@ export class MetadataDiscovery {
516
531
  initOneToManyFields(prop) {
517
532
  const meta2 = prop.targetMeta;
518
533
  if (!prop.joinColumns) {
519
- prop.joinColumns = [this.namingStrategy.joinColumnName(prop.name)];
534
+ prop.joinColumns = [this.#namingStrategy.joinColumnName(prop.name)];
520
535
  }
521
536
  if (!prop.referencedColumnNames) {
522
537
  meta2.getPrimaryProps().forEach(pk => this.applyNamingStrategy(meta2, pk));
@@ -537,7 +552,7 @@ export class MetadataDiscovery {
537
552
  }
538
553
  }
539
554
  meta.forceConstructor ??= this.shouldForceConstructorUsage(meta);
540
- this.validator.validateEntityDefinition(this.metadata, meta.class, this.config.get('discovery'));
555
+ this.#validator.validateEntityDefinition(this.#metadata, meta.class, this.#config.get('discovery'));
541
556
  for (const prop of Object.values(meta.properties)) {
542
557
  this.initNullability(prop);
543
558
  this.applyNamingStrategy(meta, prop);
@@ -549,12 +564,13 @@ export class MetadataDiscovery {
549
564
  this.initRelation(prop);
550
565
  }
551
566
  this.initOwnColumns(meta);
552
- meta.simplePK = pks.length === 1 && pks[0].kind === ReferenceKind.SCALAR && !pks[0].customType && pks[0].runtimeType !== 'Date';
567
+ meta.simplePK =
568
+ pks.length === 1 && pks[0].kind === ReferenceKind.SCALAR && !pks[0].customType && pks[0].runtimeType !== 'Date';
553
569
  meta.serializedPrimaryKey ??= meta.props.find(prop => prop.serializedPrimaryKey)?.name;
554
570
  if (meta.serializedPrimaryKey && meta.serializedPrimaryKey !== meta.primaryKeys[0]) {
555
571
  meta.properties[meta.serializedPrimaryKey].persist ??= false;
556
572
  }
557
- if (this.platform.usesPivotTable()) {
573
+ if (this.#platform.usesPivotTable()) {
558
574
  return Object.values(meta.properties)
559
575
  .filter(prop => prop.kind === ReferenceKind.MANY_TO_MANY && prop.owner && prop.pivotTable)
560
576
  .map(prop => {
@@ -581,7 +597,7 @@ export class MetadataDiscovery {
581
597
  ['mappedBy', 'inversedBy', 'pivotEntity'].forEach(type => {
582
598
  const value = prop[type];
583
599
  if (value instanceof Function) {
584
- const meta2 = prop.targetMeta ?? this.metadata.get(prop.target);
600
+ const meta2 = prop.targetMeta ?? this.#metadata.get(prop.target);
585
601
  prop[type] = value(meta2.properties)?.name;
586
602
  if (type === 'pivotEntity' && value) {
587
603
  prop[type] = value(meta2.properties);
@@ -618,8 +634,8 @@ export class MetadataDiscovery {
618
634
  }
619
635
  definePivotTableEntity(meta, prop) {
620
636
  const pivotMeta = prop.pivotEntity
621
- ? this.metadata.find(prop.pivotEntity)
622
- : this.metadata.getByClassName(prop.pivotTable, false);
637
+ ? this.#metadata.find(prop.pivotEntity)
638
+ : this.#metadata.getByClassName(prop.pivotTable, false);
623
639
  // ensure inverse side exists so we can join it when populating via pivot tables
624
640
  if (!prop.inversedBy && prop.targetMeta) {
625
641
  const inverseName = `${meta.className}_${prop.name}__inverse`;
@@ -681,18 +697,19 @@ export class MetadataDiscovery {
681
697
  pivotMeta2.compositePK = true;
682
698
  }
683
699
  // handle self-referenced m:n with same default field names
684
- if (meta.className === targetType && prop.joinColumns.every((joinColumn, idx) => joinColumn === prop.inverseJoinColumns[idx])) {
700
+ if (meta.className === targetType &&
701
+ prop.joinColumns.every((joinColumn, idx) => joinColumn === prop.inverseJoinColumns[idx])) {
685
702
  // use tableName only when explicitly provided by user, otherwise use className for backwards compatibility
686
703
  const baseName = this.isExplicitTableName(meta) ? meta.tableName : meta.className;
687
- prop.joinColumns = prop.referencedColumnNames.map(name => this.namingStrategy.joinKeyColumnName(baseName + '_1', name, meta.compositePK));
688
- 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));
689
706
  if (prop.inversedBy) {
690
707
  const prop2 = targetMeta.properties[prop.inversedBy];
691
708
  prop2.inverseJoinColumns = prop.joinColumns;
692
709
  prop2.joinColumns = prop.inverseJoinColumns;
693
710
  }
694
711
  // propagate updated joinColumns to all child entities that inherit this property (STI)
695
- 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)) {
696
713
  const childProp = childMeta.properties[prop.name];
697
714
  if (childProp) {
698
715
  childProp.joinColumns = prop.joinColumns;
@@ -708,7 +725,7 @@ export class MetadataDiscovery {
708
725
  pivotMeta2.properties[meta.name + '_owner'] = this.definePivotProperty(prop, meta.name + '_owner', meta.class, targetType + '_inverse', true, meta.className === targetType);
709
726
  pivotMeta2.properties[targetType + '_inverse'] = this.definePivotProperty(prop, targetType + '_inverse', targetMeta.class, meta.name + '_owner', false, meta.className === targetType);
710
727
  }
711
- return this.metadata.set(pivotMeta2.class, EntitySchema.fromMetadata(pivotMeta2).init().meta);
728
+ return this.#metadata.set(pivotMeta2.class, EntitySchema.fromMetadata(pivotMeta2).init().meta);
712
729
  }
713
730
  /**
714
731
  * Create a scalar property for a pivot table column.
@@ -764,14 +781,16 @@ export class MetadataDiscovery {
764
781
  pivotMeta.properties[primaryProp.name] = primaryProp;
765
782
  pivotMeta.compositePK = false;
766
783
  }
767
- 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 });
768
785
  this.initFieldName(discriminatorProp);
769
786
  pivotMeta.properties[discriminatorColumn] = discriminatorProp;
770
787
  const columnTypes = this.getPrimaryKeyColumnTypes(meta);
771
788
  if (isCompositePK) {
772
789
  // Create separate properties for each PK column (nullable for other entity types)
773
790
  for (let i = 0; i < prop.joinColumns.length; i++) {
774
- pivotMeta.properties[prop.joinColumns[i]] = this.createPivotScalarProperty(prop.joinColumns[i], [columnTypes[i]]);
791
+ pivotMeta.properties[prop.joinColumns[i]] = this.createPivotScalarProperty(prop.joinColumns[i], [
792
+ columnTypes[i],
793
+ ]);
775
794
  }
776
795
  // Virtual property combining all columns (for compatibility)
777
796
  pivotMeta.properties[prop.discriminator] = this.createPivotScalarProperty(prop.discriminator, columnTypes, [...prop.joinColumns], { type: meta.className, persist: false });
@@ -815,21 +834,22 @@ export class MetadataDiscovery {
815
834
  ret.precision = pkProp.precision;
816
835
  ret.scale = pkProp.scale;
817
836
  }
818
- const schema = targetMeta.schema ?? this.config.get('schema') ?? this.platform.getDefaultSchemaName();
837
+ const schema = targetMeta.schema ?? this.#config.get('schema') ?? this.#platform.getDefaultSchemaName();
819
838
  ret.referencedTableName = schema && schema !== '*' ? schema + '.' + targetMeta.tableName : targetMeta.tableName;
820
839
  this.initColumnType(ret);
821
840
  this.initRelation(ret);
822
841
  return ret;
823
842
  }
824
843
  defineFixedOrderProperty(prop, targetMeta) {
825
- const pk = prop.fixedOrderColumn || this.namingStrategy.referenceColumnName();
844
+ const pk = prop.fixedOrderColumn || this.#namingStrategy.referenceColumnName();
826
845
  const primaryProp = {
827
846
  name: pk,
828
847
  type: 'number',
848
+ runtimeType: 'number',
829
849
  kind: ReferenceKind.SCALAR,
830
850
  primary: true,
831
851
  autoincrement: true,
832
- unsigned: this.platform.supportsUnsigned(),
852
+ unsigned: this.#platform.supportsUnsigned(),
833
853
  };
834
854
  this.initFieldName(primaryProp);
835
855
  this.initColumnType(primaryProp);
@@ -850,21 +870,21 @@ export class MetadataDiscovery {
850
870
  cascade: [Cascade.ALL],
851
871
  fixedOrder: prop.fixedOrder,
852
872
  fixedOrderColumn: prop.fixedOrderColumn,
853
- index: this.platform.indexForeignKeys(),
873
+ index: this.#platform.indexForeignKeys(),
854
874
  primary: !prop.fixedOrder,
855
875
  autoincrement: false,
856
876
  updateRule: prop.updateRule,
857
877
  deleteRule: prop.deleteRule,
858
878
  createForeignKeyConstraint: prop.createForeignKeyConstraint,
859
879
  };
860
- const defaultRule = selfReferencing && !this.platform.supportsMultipleCascadePaths() ? 'no action' : 'cascade';
880
+ const defaultRule = selfReferencing && !this.#platform.supportsMultipleCascadePaths() ? 'no action' : 'cascade';
861
881
  ret.updateRule ??= defaultRule;
862
882
  ret.deleteRule ??= defaultRule;
863
- const meta = this.metadata.get(type);
883
+ const meta = this.#metadata.get(type);
864
884
  ret.targetMeta = meta;
865
885
  ret.joinColumns = [];
866
886
  ret.inverseJoinColumns = [];
867
- const schema = meta.schema ?? this.config.get('schema') ?? this.platform.getDefaultSchemaName();
887
+ const schema = meta.schema ?? this.#config.get('schema') ?? this.#platform.getDefaultSchemaName();
868
888
  ret.referencedTableName = schema && schema !== '*' ? schema + '.' + meta.tableName : meta.tableName;
869
889
  if (owner) {
870
890
  ret.owner = true;
@@ -910,8 +930,9 @@ export class MetadataDiscovery {
910
930
  });
911
931
  }
912
932
  defineBaseEntityProperties(meta) {
913
- const base = meta.extends && this.metadata.get(meta.extends);
914
- if (!base || base === meta) { // make sure we do not fall into infinite loop
933
+ const base = meta.extends && this.#metadata.get(meta.extends);
934
+ if (!base || base === meta) {
935
+ // make sure we do not fall into infinite loop
915
936
  return 0;
916
937
  }
917
938
  let order = this.defineBaseEntityProperties(base);
@@ -923,10 +944,12 @@ export class MetadataDiscovery {
923
944
  meta.properties[prop.name] = prop;
924
945
  }
925
946
  });
926
- ownProps.forEach(prop => meta.properties[prop.name] = prop);
947
+ ownProps.forEach(prop => (meta.properties[prop.name] = prop));
927
948
  meta.filters = { ...base.filters, ...meta.filters };
928
949
  if (!meta.discriminatorValue) {
929
- Object.values(base.properties).filter(prop => !old.includes(prop.name)).forEach(prop => {
950
+ Object.values(base.properties)
951
+ .filter(prop => !old.includes(prop.name))
952
+ .forEach(prop => {
930
953
  meta.properties[prop.name] = { ...prop };
931
954
  meta.propertyOrder.set(prop.name, (order += 0.01));
932
955
  });
@@ -934,7 +957,9 @@ export class MetadataDiscovery {
934
957
  meta.indexes = Utils.unique([...base.indexes, ...meta.indexes]);
935
958
  meta.uniques = Utils.unique([...base.uniques, ...meta.uniques]);
936
959
  meta.checks = Utils.unique([...base.checks, ...meta.checks]);
937
- const pks = Object.values(meta.properties).filter(p => p.primary).map(p => p.name);
960
+ const pks = Object.values(meta.properties)
961
+ .filter(p => p.primary)
962
+ .map(p => p.name);
938
963
  if (pks.length > 0 && meta.primaryKeys.length === 0) {
939
964
  meta.primaryKeys = pks;
940
965
  }
@@ -952,8 +977,8 @@ export class MetadataDiscovery {
952
977
  }
953
978
  visited.add(embeddedProp);
954
979
  const types = embeddedProp.type.split(/ ?\| ?/);
955
- let embeddable = this.discovered.find(m => m.name === embeddedProp.type);
956
- 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));
957
982
  // create virtual polymorphic entity
958
983
  if (!embeddable && polymorphs.length > 0) {
959
984
  const properties = {};
@@ -965,13 +990,17 @@ export class MetadataDiscovery {
965
990
  if (properties[prop.name] && properties[prop.name].type !== prop.type) {
966
991
  properties[prop.name].type = `${properties[prop.name].type} | ${prop.type}`;
967
992
  properties[prop.name].runtimeType = 'any';
993
+ properties[prop.name].stiMerged = true;
968
994
  return properties[prop.name];
969
995
  }
970
- 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));
971
1000
  });
972
1001
  };
973
1002
  const processExtensions = (meta) => {
974
- const parent = this.discovered.find(m => {
1003
+ const parent = this.#discovered.find(m => {
975
1004
  return meta.extends && Utils.className(meta.extends) === m.className;
976
1005
  });
977
1006
  if (!parent) {
@@ -985,7 +1014,10 @@ export class MetadataDiscovery {
985
1014
  inlineProperties(meta);
986
1015
  processExtensions(meta);
987
1016
  });
988
- const name = polymorphs.map(t => t.className).sort().join(' | ');
1017
+ const name = polymorphs
1018
+ .map(t => t.className)
1019
+ .sort()
1020
+ .join(' | ');
989
1021
  embeddable = new EntityMetadata({
990
1022
  name,
991
1023
  className: name,
@@ -997,7 +1029,7 @@ export class MetadataDiscovery {
997
1029
  });
998
1030
  embeddable.sync();
999
1031
  discovered.push(embeddable);
1000
- polymorphs.forEach(meta => meta.root = embeddable);
1032
+ polymorphs.forEach(meta => (meta.root = embeddable));
1001
1033
  }
1002
1034
  }
1003
1035
  initPolymorphicRelation(meta, prop, discovered) {
@@ -1006,7 +1038,7 @@ export class MetadataDiscovery {
1006
1038
  }
1007
1039
  prop.polymorphic = true;
1008
1040
  prop.discriminator ??= prop.name;
1009
- prop.discriminatorColumn ??= this.namingStrategy.discriminatorColumnName(prop.discriminator);
1041
+ prop.discriminatorColumn ??= this.#namingStrategy.discriminatorColumnName(prop.discriminator);
1010
1042
  prop.createForeignKeyConstraint = false;
1011
1043
  const isToOne = [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind);
1012
1044
  if (isToOne) {
@@ -1018,7 +1050,7 @@ export class MetadataDiscovery {
1018
1050
  if (prop.discriminatorMap) {
1019
1051
  const normalizedMap = {};
1020
1052
  for (const [key, value] of Object.entries(prop.discriminatorMap)) {
1021
- const targetMeta = this.metadata.getByClassName(value, false);
1053
+ const targetMeta = this.#metadata.getByClassName(value, false);
1022
1054
  if (!targetMeta) {
1023
1055
  throw MetadataError.fromUnknownEntity(value, `${meta.className}.${prop.name} discriminatorMap`);
1024
1056
  }
@@ -1053,7 +1085,7 @@ export class MetadataDiscovery {
1053
1085
  return;
1054
1086
  }
1055
1087
  visited.add(embeddedProp);
1056
- const embeddable = this.discovered.find(m => m.name === embeddedProp.type);
1088
+ const embeddable = this.#discovered.find(m => m.name === embeddedProp.type);
1057
1089
  if (!embeddable) {
1058
1090
  throw MetadataError.fromUnknownEntity(embeddedProp.type, `${meta.className}.${embeddedProp.name}`);
1059
1091
  }
@@ -1125,7 +1157,7 @@ export class MetadataDiscovery {
1125
1157
  meta.properties[name].fieldNames = prop.fieldNames;
1126
1158
  meta.properties[name].embeddedPath = path;
1127
1159
  const targetProp = prop.targetMeta?.getPrimaryProp() ?? prop;
1128
- 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));
1129
1161
  meta.properties[name].fieldNameRaw = fieldName.sql; // for querying in SQL drivers
1130
1162
  meta.properties[name].persist = false; // only virtual as we store the whole object
1131
1163
  meta.properties[name].userDefined = false; // mark this as a generated/internal property, so we can distinguish from user-defined non-persist properties
@@ -1167,7 +1199,7 @@ export class MetadataDiscovery {
1167
1199
  const map = meta.root.discriminatorMap;
1168
1200
  Object.keys(map)
1169
1201
  .filter(key => typeof map[key] === 'string')
1170
- .forEach(key => map[key] = this.metadata.getByClassName(map[key]).class);
1202
+ .forEach(key => (map[key] = this.#metadata.getByClassName(map[key]).class));
1171
1203
  }
1172
1204
  else {
1173
1205
  meta.root.discriminatorMap = {};
@@ -1175,7 +1207,7 @@ export class MetadataDiscovery {
1175
1207
  .filter(m => m.root.class === meta.root.class && !m.abstract)
1176
1208
  .sort((a, b) => a.className.localeCompare(b.className));
1177
1209
  for (const m of children) {
1178
- const name = m.discriminatorValue ?? this.namingStrategy.classToTableName(m.className);
1210
+ const name = m.discriminatorValue ?? this.#namingStrategy.classToTableName(m.className);
1179
1211
  meta.root.discriminatorMap[name] = m.class;
1180
1212
  }
1181
1213
  }
@@ -1191,7 +1223,14 @@ export class MetadataDiscovery {
1191
1223
  Object.values(meta.properties).forEach(prop => {
1192
1224
  const newProp = { ...prop };
1193
1225
  const rootProp = meta.root.properties[prop.name];
1194
- if (rootProp && (rootProp.type !== prop.type || (rootProp.fieldNames && prop.fieldNames && !compareArrays(rootProp.fieldNames, prop.fieldNames)))) {
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;
1231
+ if (rootProp &&
1232
+ (!typesMatch ||
1233
+ (rootProp.fieldNames && prop.fieldNames && !compareArrays(rootProp.fieldNames, prop.fieldNames)))) {
1195
1234
  const name = newProp.name;
1196
1235
  this.initFieldName(newProp, newProp.object);
1197
1236
  newProp.renamedFrom = name;
@@ -1205,8 +1244,9 @@ export class MetadataDiscovery {
1205
1244
  rootProp.stiFieldNameMap = {};
1206
1245
  // Find which discriminator owns the original fieldNames
1207
1246
  for (const [discValue, childClass] of Object.entries(meta.root.discriminatorMap)) {
1208
- const childMeta = this.metadata.find(childClass);
1209
- if (childMeta?.properties[prop.name]?.fieldNames && compareArrays(childMeta.properties[prop.name].fieldNames, rootProp.fieldNames)) {
1247
+ const childMeta = this.#metadata.find(childClass);
1248
+ if (childMeta?.properties[prop.name]?.fieldNames &&
1249
+ compareArrays(childMeta.properties[prop.name].fieldNames, rootProp.fieldNames)) {
1210
1250
  rootProp.stiFieldNameMap[discValue] = rootProp.fieldNames[0];
1211
1251
  break;
1212
1252
  }
@@ -1272,11 +1312,11 @@ export class MetadataDiscovery {
1272
1312
  if (meta.tptChildren) {
1273
1313
  meta.tptChildren = meta.tptChildren.map(child => metadata.find(m => m.class === child.class) ?? child);
1274
1314
  }
1275
- const registryMeta = this.metadata.get(meta.class);
1315
+ const registryMeta = this.#metadata.get(meta.class);
1276
1316
  if (registryMeta && registryMeta !== meta) {
1277
1317
  registryMeta.inheritanceType = meta.inheritanceType;
1278
- registryMeta.tptParent = meta.tptParent ? this.metadata.get(meta.tptParent.class) : undefined;
1279
- 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));
1280
1320
  }
1281
1321
  this.initTPTDiscriminator(meta, metadata);
1282
1322
  }
@@ -1294,12 +1334,12 @@ export class MetadataDiscovery {
1294
1334
  }
1295
1335
  meta.root.discriminatorMap = {};
1296
1336
  for (const m of allDescendants) {
1297
- const name = this.namingStrategy.classToTableName(m.className);
1337
+ const name = this.#namingStrategy.classToTableName(m.className);
1298
1338
  meta.root.discriminatorMap[name] = m.class;
1299
1339
  m.discriminatorValue = name;
1300
1340
  }
1301
1341
  if (!meta.abstract) {
1302
- const name = this.namingStrategy.classToTableName(meta.className);
1342
+ const name = this.#namingStrategy.classToTableName(meta.className);
1303
1343
  meta.root.discriminatorMap[name] = meta.class;
1304
1344
  meta.discriminatorValue = name;
1305
1345
  }
@@ -1412,7 +1452,7 @@ export class MetadataDiscovery {
1412
1452
  }
1413
1453
  initAutoincrement(meta) {
1414
1454
  const pks = meta.getPrimaryProps();
1415
- if (pks.length === 1 && this.platform.isNumericProperty(pks[0])) {
1455
+ if (pks.length === 1 && this.#platform.isNumericProperty(pks[0])) {
1416
1456
  /* v8 ignore next */
1417
1457
  pks[0].autoincrement ??= true;
1418
1458
  }
@@ -1431,19 +1471,22 @@ export class MetadataDiscovery {
1431
1471
  const table = this.createSchemaTable(meta);
1432
1472
  for (const check of meta.checks) {
1433
1473
  const fieldNames = check.property ? meta.properties[check.property].fieldNames : [];
1434
- check.name ??= this.namingStrategy.indexName(meta.tableName, fieldNames, 'check');
1474
+ check.name ??= this.#namingStrategy.indexName(meta.tableName, fieldNames, 'check');
1435
1475
  if (check.expression instanceof Function) {
1436
1476
  check.expression = check.expression(columns, table);
1437
1477
  }
1438
1478
  }
1439
- if (this.platform.usesEnumCheckConstraints() && !meta.embeddable) {
1479
+ if (this.#platform.usesEnumCheckConstraints() && !meta.embeddable) {
1440
1480
  for (const prop of meta.props) {
1441
- if (prop.enum && !prop.nativeEnumName && prop.items?.every(item => typeof item === 'string')) {
1481
+ if (prop.enum &&
1482
+ prop.persist !== false &&
1483
+ !prop.nativeEnumName &&
1484
+ prop.items?.every(item => typeof item === 'string')) {
1442
1485
  this.initFieldName(prop);
1443
1486
  meta.checks.push({
1444
- name: this.namingStrategy.indexName(meta.tableName, prop.fieldNames, 'check'),
1487
+ name: this.#namingStrategy.indexName(meta.tableName, prop.fieldNames, 'check'),
1445
1488
  property: prop.name,
1446
- expression: `${this.platform.quoteIdentifier(prop.fieldNames[0])} in ('${prop.items.join("', '")}')`,
1489
+ expression: `${this.#platform.quoteIdentifier(prop.fieldNames[0])} in ('${prop.items.join("', '")}')`,
1447
1490
  });
1448
1491
  }
1449
1492
  }
@@ -1451,13 +1494,13 @@ export class MetadataDiscovery {
1451
1494
  }
1452
1495
  initGeneratedColumn(meta, prop) {
1453
1496
  if (!prop.generated && prop.columnTypes) {
1454
- const match = prop.columnTypes[0]?.match(/(.*) generated always as (.*)/i);
1497
+ const match = /(.*) generated always as (.*)/i.exec(prop.columnTypes[0]);
1455
1498
  if (match) {
1456
1499
  prop.columnTypes[0] = match[1];
1457
1500
  prop.generated = match[2];
1458
1501
  return;
1459
1502
  }
1460
- const match2 = prop.columnTypes[0]?.trim().match(/^as (.*)/i);
1503
+ const match2 = /^as (.*)/i.exec(prop.columnTypes[0]?.trim());
1461
1504
  if (match2) {
1462
1505
  prop.generated = match2[1];
1463
1506
  }
@@ -1474,13 +1517,13 @@ export class MetadataDiscovery {
1474
1517
  }
1475
1518
  /* v8 ignore next */
1476
1519
  if (prop.default != null) {
1477
- return '' + this.platform.convertVersionValue(prop.default, prop);
1520
+ return '' + this.#platform.convertVersionValue(prop.default, prop);
1478
1521
  }
1479
1522
  this.initCustomType(meta, prop, true);
1480
1523
  const type = prop.customType?.runtimeType ?? prop.runtimeType ?? prop.type;
1481
1524
  if (type === 'Date') {
1482
- prop.length ??= this.platform.getDefaultVersionLength();
1483
- return this.platform.getCurrentTimestampSQL(prop.length);
1525
+ prop.length ??= this.#platform.getDefaultVersionLength();
1526
+ return this.#platform.getCurrentTimestampSQL(prop.length);
1484
1527
  }
1485
1528
  return '1';
1486
1529
  }
@@ -1491,7 +1534,11 @@ export class MetadataDiscovery {
1491
1534
  const entity1 = new meta.class();
1492
1535
  const entity2 = new meta.class();
1493
1536
  // we compare the two values by reference, this will discard things like `new Date()` or `Date.now()`
1494
- if (this.config.get('discovery').inferDefaultValues && prop.default === undefined && entity1[prop.name] != null && entity1[prop.name] === entity2[prop.name] && entity1[prop.name] !== now) {
1537
+ if (this.#config.get('discovery').inferDefaultValues &&
1538
+ prop.default === undefined &&
1539
+ entity1[prop.name] != null &&
1540
+ entity1[prop.name] === entity2[prop.name] &&
1541
+ entity1[prop.name] !== now) {
1495
1542
  prop.default ??= entity1[prop.name];
1496
1543
  }
1497
1544
  // if the default value is null, infer nullability
@@ -1514,11 +1561,11 @@ export class MetadataDiscovery {
1514
1561
  let val = prop.default;
1515
1562
  const raw = Raw.getKnownFragment(val);
1516
1563
  if (raw) {
1517
- prop.defaultRaw = this.platform.formatQuery(raw.sql, raw.params);
1564
+ prop.defaultRaw = this.#platform.formatQuery(raw.sql, raw.params);
1518
1565
  return;
1519
1566
  }
1520
1567
  if (Array.isArray(prop.default) && prop.customType) {
1521
- val = prop.customType.convertToDatabaseValue(prop.default, this.platform);
1568
+ val = prop.customType.convertToDatabaseValue(prop.default, this.#platform);
1522
1569
  }
1523
1570
  prop.defaultRaw = typeof val === 'string' ? `'${val}'` : '' + val;
1524
1571
  }
@@ -1558,7 +1605,9 @@ export class MetadataDiscovery {
1558
1605
  prop.type = prop.customType.constructor.name;
1559
1606
  }
1560
1607
  // `prop.type` might also be custom type class (not instance), so `typeof MyType` will give us `function`, not `object`
1561
- if (typeof prop.type === 'function' && Type.isMappedType(prop.type.prototype) && !prop.customType) {
1608
+ if (typeof prop.type === 'function' &&
1609
+ Type.isMappedType(prop.type.prototype) &&
1610
+ !prop.customType) {
1562
1611
  // if the type is an ORM defined mapped type without `ensureComparable: true`,
1563
1612
  // we use just the type name, to have more performant hydration code
1564
1613
  const type = Utils.keys(t).find(type => {
@@ -1578,7 +1627,10 @@ export class MetadataDiscovery {
1578
1627
  if (!prop.customType && ['json', 'jsonb'].includes(prop.type?.toLowerCase())) {
1579
1628
  prop.customType = new t.json();
1580
1629
  }
1581
- if (prop.kind === ReferenceKind.SCALAR && !prop.customType && prop.columnTypes && ['json', 'jsonb'].includes(prop.columnTypes[0])) {
1630
+ if (prop.kind === ReferenceKind.SCALAR &&
1631
+ !prop.customType &&
1632
+ prop.columnTypes &&
1633
+ ['json', 'jsonb'].includes(prop.columnTypes[0])) {
1582
1634
  prop.customType = new t.json();
1583
1635
  }
1584
1636
  if (prop.kind === ReferenceKind.EMBEDDED && !prop.customType && (prop.object || prop.array)) {
@@ -1609,10 +1661,12 @@ export class MetadataDiscovery {
1609
1661
  if (prop.fieldNames?.length === 1 && !prop.customType) {
1610
1662
  [t.bigint, t.double, t.decimal, t.interval, t.date]
1611
1663
  .filter(type => mappedType instanceof type)
1612
- .forEach((type) => prop.customType = new type());
1664
+ .forEach((type) => (prop.customType = new type()));
1613
1665
  }
1614
1666
  if (prop.customType && !prop.columnTypes) {
1615
- const mappedType = this.getMappedType({ columnTypes: [prop.customType.getColumnType(prop, this.platform)] });
1667
+ const mappedType = this.getMappedType({
1668
+ columnTypes: [prop.customType.getColumnType(prop, this.#platform)],
1669
+ });
1616
1670
  if (prop.customType.compareAsType() === 'any' && ![t.json].some(t => prop.customType instanceof t)) {
1617
1671
  prop.runtimeType ??= mappedType.runtimeType;
1618
1672
  }
@@ -1627,27 +1681,37 @@ export class MetadataDiscovery {
1627
1681
  prop.runtimeType ??= mappedType.runtimeType;
1628
1682
  }
1629
1683
  if (prop.customType) {
1630
- prop.customType.platform = this.platform;
1684
+ prop.customType.platform = this.#platform;
1631
1685
  prop.customType.meta = meta;
1632
1686
  prop.customType.prop = prop;
1633
- prop.columnTypes ??= [prop.customType.getColumnType(prop, this.platform)];
1634
- prop.hasConvertToJSValueSQL = !!prop.customType.convertToJSValueSQL && prop.customType.convertToJSValueSQL('', this.platform) !== '';
1635
- prop.hasConvertToDatabaseValueSQL = !!prop.customType.convertToDatabaseValueSQL && prop.customType.convertToDatabaseValueSQL('', this.platform) !== '';
1636
- if (prop.customType instanceof t.bigint && ['string', 'bigint', 'number'].includes(prop.runtimeType.toLowerCase())) {
1687
+ prop.columnTypes ??= [prop.customType.getColumnType(prop, this.#platform)];
1688
+ prop.hasConvertToJSValueSQL =
1689
+ !!prop.customType.convertToJSValueSQL && prop.customType.convertToJSValueSQL('', this.#platform) !== '';
1690
+ prop.hasConvertToDatabaseValueSQL =
1691
+ !!prop.customType.convertToDatabaseValueSQL &&
1692
+ prop.customType.convertToDatabaseValueSQL('', this.#platform) !== '';
1693
+ if (prop.customType instanceof t.bigint &&
1694
+ ['string', 'bigint', 'number'].includes(prop.runtimeType.toLowerCase())) {
1637
1695
  prop.customType.mode = prop.runtimeType.toLowerCase();
1638
1696
  }
1639
1697
  }
1640
1698
  if (Type.isMappedType(prop.customType) && prop.kind === ReferenceKind.SCALAR && !isArray) {
1641
1699
  prop.type = prop.customType.name;
1642
1700
  }
1643
- if (!prop.customType && [ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind) && !prop.polymorphic && prop.targetMeta.compositePK) {
1701
+ if (!prop.customType &&
1702
+ [ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind) &&
1703
+ !prop.polymorphic &&
1704
+ prop.targetMeta.compositePK) {
1644
1705
  prop.customTypes = [];
1645
1706
  for (const pk of prop.targetMeta.getPrimaryProps()) {
1646
1707
  if (pk.customType) {
1647
1708
  prop.customTypes.push(pk.customType);
1648
- prop.hasConvertToJSValueSQL ||= !!pk.customType.convertToJSValueSQL && pk.customType.convertToJSValueSQL('', this.platform) !== '';
1709
+ prop.hasConvertToJSValueSQL ||=
1710
+ !!pk.customType.convertToJSValueSQL && pk.customType.convertToJSValueSQL('', this.#platform) !== '';
1649
1711
  /* v8 ignore next */
1650
- prop.hasConvertToDatabaseValueSQL ||= !!pk.customType.convertToDatabaseValueSQL && pk.customType.convertToDatabaseValueSQL('', this.platform) !== '';
1712
+ prop.hasConvertToDatabaseValueSQL ||=
1713
+ !!pk.customType.convertToDatabaseValueSQL &&
1714
+ pk.customType.convertToDatabaseValueSQL('', this.#platform) !== '';
1651
1715
  }
1652
1716
  else {
1653
1717
  prop.customTypes.push(undefined);
@@ -1655,11 +1719,15 @@ export class MetadataDiscovery {
1655
1719
  }
1656
1720
  }
1657
1721
  if (prop.kind === ReferenceKind.SCALAR && !(mappedType instanceof t.unknown)) {
1658
- if (!prop.columnTypes && prop.nativeEnumName && meta.schema !== this.platform.getDefaultSchemaName() && meta.schema && !prop.nativeEnumName.includes('.')) {
1722
+ if (!prop.columnTypes &&
1723
+ prop.nativeEnumName &&
1724
+ meta.schema !== this.#platform.getDefaultSchemaName() &&
1725
+ meta.schema &&
1726
+ !prop.nativeEnumName.includes('.')) {
1659
1727
  prop.columnTypes = [`${meta.schema}.${prop.nativeEnumName}`];
1660
1728
  }
1661
1729
  else {
1662
- prop.columnTypes ??= [mappedType.getColumnType(prop, this.platform)];
1730
+ prop.columnTypes ??= [mappedType.getColumnType(prop, this.#platform)];
1663
1731
  }
1664
1732
  // use only custom types provided by user, we don't need to use the ones provided by ORM,
1665
1733
  // with exception for ArrayType and JsonType, those two are handled in
@@ -1673,7 +1741,7 @@ export class MetadataDiscovery {
1673
1741
  return;
1674
1742
  }
1675
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
1676
- 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);
1677
1745
  // If targetKey is specified, use that property instead of PKs for referencedPKs
1678
1746
  prop.referencedPKs = prop.targetKey ? [prop.targetKey] : meta2.primaryKeys;
1679
1747
  prop.targetMeta = meta2;
@@ -1682,10 +1750,13 @@ export class MetadataDiscovery {
1682
1750
  }
1683
1751
  // Auto-generate formula for persist: false relations, but only for single-column FKs
1684
1752
  // Composite FK relations need standard JOIN conditions, not formula-based
1685
- if (!prop.formula && prop.persist === false && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && !prop.embedded) {
1753
+ if (!prop.formula &&
1754
+ prop.persist === false &&
1755
+ [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) &&
1756
+ !prop.embedded) {
1686
1757
  this.initFieldName(prop);
1687
1758
  if (prop.fieldNames?.length === 1) {
1688
- prop.formula = table => `${table}.${this.platform.quoteIdentifier(prop.fieldNames[0])}`;
1759
+ prop.formula = table => `${table}.${this.#platform.quoteIdentifier(prop.fieldNames[0])}`;
1689
1760
  }
1690
1761
  }
1691
1762
  }
@@ -1693,7 +1764,9 @@ export class MetadataDiscovery {
1693
1764
  this.initUnsigned(prop);
1694
1765
  // Get the target properties for FK relations - use targetKey property if specified, otherwise PKs
1695
1766
  const targetProps = prop.targetMeta
1696
- ? (prop.targetKey ? [prop.targetMeta.properties[prop.targetKey]] : prop.targetMeta.getPrimaryProps())
1767
+ ? prop.targetKey
1768
+ ? [prop.targetMeta.properties[prop.targetKey]]
1769
+ : prop.targetMeta.getPrimaryProps()
1697
1770
  : [];
1698
1771
  targetProps.map(targetProp => {
1699
1772
  prop.length ??= targetProp.length;
@@ -1705,38 +1778,36 @@ export class MetadataDiscovery {
1705
1778
  const mappedType = this.getMappedType(prop);
1706
1779
  prop.type = mappedType.compareAsType();
1707
1780
  }
1708
- if (prop.columnTypes || !this.schemaHelper) {
1781
+ if (prop.columnTypes || !this.#schemaHelper) {
1709
1782
  return;
1710
1783
  }
1711
1784
  if (prop.kind === ReferenceKind.SCALAR) {
1712
1785
  const mappedType = this.getMappedType(prop);
1713
1786
  const SCALAR_TYPES = ['string', 'number', 'boolean', 'bigint', 'Date', 'Buffer', 'RegExp', 'any', 'unknown'];
1714
- if (mappedType instanceof t.unknown
1787
+ if (mappedType instanceof t.unknown &&
1715
1788
  // it could be a runtime type from reflect-metadata
1716
- && !SCALAR_TYPES.includes(prop.type)
1789
+ !SCALAR_TYPES.includes(prop.type) &&
1717
1790
  // or it might be inferred via ts-morph to some generic type alias
1718
- && !prop.type.match(/[<>:"';{}]/)) {
1791
+ !/[<>:"';{}]/.exec(prop.type)) {
1719
1792
  const type = prop.length != null && !prop.type.endsWith(`(${prop.length})`) ? `${prop.type}(${prop.length})` : prop.type;
1720
1793
  prop.columnTypes = [type];
1721
1794
  }
1722
1795
  else {
1723
- prop.columnTypes = [mappedType.getColumnType(prop, this.platform)];
1796
+ prop.columnTypes = [mappedType.getColumnType(prop, this.#platform)];
1724
1797
  }
1725
1798
  return;
1726
1799
  }
1727
1800
  /* v8 ignore next */
1728
1801
  if (prop.kind === ReferenceKind.EMBEDDED && prop.object) {
1729
- prop.columnTypes = [this.platform.getJsonDeclarationSQL()];
1802
+ prop.columnTypes = [this.#platform.getJsonDeclarationSQL()];
1730
1803
  return;
1731
1804
  }
1732
1805
  const targetMeta = prop.targetMeta;
1733
1806
  prop.columnTypes = [];
1734
1807
  // Use targetKey property if specified, otherwise use primary key properties
1735
- const referencedProps = prop.targetKey
1736
- ? [targetMeta.properties[prop.targetKey]]
1737
- : targetMeta.getPrimaryProps();
1808
+ const referencedProps = prop.targetKey ? [targetMeta.properties[prop.targetKey]] : targetMeta.getPrimaryProps();
1738
1809
  if (prop.polymorphic && prop.polymorphTargets) {
1739
- prop.columnTypes.push(this.platform.getVarcharTypeDeclarationSQL(prop));
1810
+ prop.columnTypes.push(this.#platform.getVarcharTypeDeclarationSQL(prop));
1740
1811
  }
1741
1812
  for (const referencedProp of referencedProps) {
1742
1813
  this.initCustomType(targetMeta, referencedProp);
@@ -1744,7 +1815,7 @@ export class MetadataDiscovery {
1744
1815
  const mappedType = this.getMappedType(referencedProp);
1745
1816
  let columnTypes = referencedProp.columnTypes;
1746
1817
  if (referencedProp.autoincrement) {
1747
- columnTypes = [mappedType.getColumnType({ ...referencedProp, autoincrement: false }, this.platform)];
1818
+ columnTypes = [mappedType.getColumnType({ ...referencedProp, autoincrement: false }, this.#platform)];
1748
1819
  }
1749
1820
  prop.columnTypes.push(...columnTypes);
1750
1821
  if (!targetMeta.compositePK || prop.targetKey) {
@@ -1767,7 +1838,7 @@ export class MetadataDiscovery {
1767
1838
  if (t === 'Date') {
1768
1839
  t = 'datetime';
1769
1840
  }
1770
- return this.platform.getMappedType(t);
1841
+ return this.#platform.getMappedType(t);
1771
1842
  }
1772
1843
  getPrefix(prop, parent) {
1773
1844
  const { embeddedPath = [], fieldNames, prefix = true, prefixMode } = prop;
@@ -1778,7 +1849,7 @@ export class MetadataDiscovery {
1778
1849
  if (prefix === false) {
1779
1850
  return prefixParent;
1780
1851
  }
1781
- const mode = prefixMode ?? this.config.get('embeddables').prefixMode;
1852
+ const mode = prefixMode ?? this.#config.get('embeddables').prefixMode;
1782
1853
  return mode === 'absolute' ? prefix : prefixParent + prefix;
1783
1854
  }
1784
1855
  initUnsigned(prop) {
@@ -1792,16 +1863,17 @@ export class MetadataDiscovery {
1792
1863
  });
1793
1864
  return;
1794
1865
  }
1795
- prop.unsigned ??= (prop.primary || prop.unsigned) && this.platform.isNumericProperty(prop) && this.platform.supportsUnsigned();
1866
+ prop.unsigned ??=
1867
+ (prop.primary || prop.unsigned) && this.#platform.isNumericProperty(prop) && this.#platform.supportsUnsigned();
1796
1868
  }
1797
1869
  initIndexes(meta, prop) {
1798
1870
  const hasIndex = meta.indexes.some(idx => idx.properties?.length === 1 && idx.properties[0] === prop.name);
1799
- if (prop.kind === ReferenceKind.MANY_TO_ONE && this.platform.indexForeignKeys() && !hasIndex) {
1871
+ if (prop.kind === ReferenceKind.MANY_TO_ONE && this.#platform.indexForeignKeys() && !hasIndex) {
1800
1872
  prop.index ??= true;
1801
1873
  }
1802
1874
  }
1803
1875
  shouldForceConstructorUsage(meta) {
1804
- const forceConstructor = this.config.get('forceEntityConstructor');
1876
+ const forceConstructor = this.#config.get('forceEntityConstructor');
1805
1877
  if (Array.isArray(forceConstructor)) {
1806
1878
  return forceConstructor.some(cls => Utils.className(cls) === meta.className);
1807
1879
  }