@mikro-orm/core 7.0.0-dev.114 → 7.0.0-dev.116

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 (55) hide show
  1. package/EntityManager.d.ts +8 -8
  2. package/EntityManager.js +42 -62
  3. package/MikroORM.d.ts +1 -1
  4. package/MikroORM.js +2 -3
  5. package/drivers/DatabaseDriver.d.ts +11 -11
  6. package/drivers/DatabaseDriver.js +7 -8
  7. package/drivers/IDatabaseDriver.d.ts +10 -10
  8. package/entity/Collection.js +5 -5
  9. package/entity/EntityAssigner.js +9 -9
  10. package/entity/EntityFactory.js +14 -17
  11. package/entity/EntityHelper.d.ts +2 -2
  12. package/entity/EntityHelper.js +2 -2
  13. package/entity/EntityLoader.d.ts +3 -3
  14. package/entity/EntityLoader.js +17 -16
  15. package/entity/WrappedEntity.js +1 -1
  16. package/entity/defineEntity.d.ts +11 -11
  17. package/errors.d.ts +8 -8
  18. package/errors.js +14 -13
  19. package/hydration/ObjectHydrator.js +23 -16
  20. package/metadata/EntitySchema.d.ts +5 -5
  21. package/metadata/EntitySchema.js +23 -21
  22. package/metadata/MetadataDiscovery.d.ts +2 -3
  23. package/metadata/MetadataDiscovery.js +117 -90
  24. package/metadata/MetadataProvider.js +2 -0
  25. package/metadata/MetadataStorage.d.ts +13 -6
  26. package/metadata/MetadataStorage.js +64 -19
  27. package/metadata/MetadataValidator.d.ts +2 -2
  28. package/metadata/MetadataValidator.js +22 -28
  29. package/metadata/types.d.ts +3 -3
  30. package/package.json +1 -1
  31. package/serialization/EntitySerializer.d.ts +3 -0
  32. package/serialization/EntitySerializer.js +15 -13
  33. package/serialization/EntityTransformer.js +6 -6
  34. package/serialization/SerializationContext.d.ts +6 -6
  35. package/typings.d.ts +16 -14
  36. package/typings.js +15 -10
  37. package/unit-of-work/ChangeSet.d.ts +2 -3
  38. package/unit-of-work/ChangeSet.js +2 -3
  39. package/unit-of-work/ChangeSetComputer.js +3 -3
  40. package/unit-of-work/ChangeSetPersister.js +14 -14
  41. package/unit-of-work/CommitOrderCalculator.d.ts +12 -10
  42. package/unit-of-work/CommitOrderCalculator.js +13 -13
  43. package/unit-of-work/UnitOfWork.d.ts +3 -3
  44. package/unit-of-work/UnitOfWork.js +46 -45
  45. package/utils/AbstractSchemaGenerator.js +7 -7
  46. package/utils/Configuration.d.ts +0 -5
  47. package/utils/DataloaderUtils.js +13 -11
  48. package/utils/EntityComparator.d.ts +6 -6
  49. package/utils/EntityComparator.js +26 -24
  50. package/utils/QueryHelper.d.ts +5 -5
  51. package/utils/QueryHelper.js +7 -7
  52. package/utils/TransactionManager.js +1 -1
  53. package/utils/Utils.d.ts +1 -1
  54. package/utils/Utils.js +1 -2
  55. package/utils/env-vars.js +0 -1
@@ -39,7 +39,7 @@ export class ObjectHydrator extends Hydrator {
39
39
  */
40
40
  getEntityHydrator(meta, type, normalizeAccessors = false) {
41
41
  const key = `${type}~${normalizeAccessors}`;
42
- const exists = this.hydrators[key].get(meta.className);
42
+ const exists = this.hydrators[key].get(meta.class);
43
43
  if (exists) {
44
44
  return exists;
45
45
  }
@@ -59,7 +59,7 @@ export class ObjectHydrator extends Hydrator {
59
59
  });
60
60
  return convertorKey;
61
61
  };
62
- const hydrateScalar = (prop, object, path, dataKey) => {
62
+ const hydrateScalar = (prop, path, dataKey) => {
63
63
  const entityKey = path.map(k => this.wrap(k)).join('');
64
64
  const tz = this.platform.getTimezone();
65
65
  const convertorKey = path.filter(k => !k.match(/\[idx_\d+]/)).map(k => this.safeKey(k)).join('_');
@@ -135,23 +135,25 @@ export class ObjectHydrator extends Hydrator {
135
135
  ret.push(` if (data${dataKey} === null) {\n entity${entityKey} = ${nullVal};`);
136
136
  ret.push(` } else if (typeof data${dataKey} !== 'undefined') {`);
137
137
  ret.push(` if (isPrimaryKey(data${dataKey}, true)) {`);
138
+ const targetKey = this.safeKey(`${prop.targetMeta.tableName}_${this.tmpIndex++}`);
139
+ context.set(targetKey, prop.targetMeta.class);
138
140
  if (prop.ref) {
139
- ret.push(` entity${entityKey} = Reference.create(factory.createReference('${prop.type}', data${dataKey}, { merge: true, convertCustomTypes, normalizeAccessors, schema }));`);
141
+ ret.push(` entity${entityKey} = Reference.create(factory.createReference(${targetKey}, data${dataKey}, { merge: true, convertCustomTypes, normalizeAccessors, schema }));`);
140
142
  }
141
143
  else {
142
- ret.push(` entity${entityKey} = factory.createReference('${prop.type}', data${dataKey}, { merge: true, convertCustomTypes, normalizeAccessors, schema });`);
144
+ ret.push(` entity${entityKey} = factory.createReference(${targetKey}, data${dataKey}, { merge: true, convertCustomTypes, normalizeAccessors, schema });`);
143
145
  }
144
146
  ret.push(` } else if (data${dataKey} && typeof data${dataKey} === 'object') {`);
145
147
  if (prop.ref) {
146
- ret.push(` entity${entityKey} = Reference.create(factory.${method}('${prop.type}', data${dataKey}, { initialized: true, merge: true, newEntity, convertCustomTypes, normalizeAccessors, schema }));`);
148
+ ret.push(` entity${entityKey} = Reference.create(factory.${method}(${targetKey}, data${dataKey}, { initialized: true, merge: true, newEntity, convertCustomTypes, normalizeAccessors, schema }));`);
147
149
  }
148
150
  else {
149
- ret.push(` entity${entityKey} = factory.${method}('${prop.type}', data${dataKey}, { initialized: true, merge: true, newEntity, convertCustomTypes, normalizeAccessors, schema });`);
151
+ ret.push(` entity${entityKey} = factory.${method}(${targetKey}, data${dataKey}, { initialized: true, merge: true, newEntity, convertCustomTypes, normalizeAccessors, schema });`);
150
152
  }
151
153
  ret.push(` }`);
152
154
  ret.push(` }`);
153
155
  if (prop.kind === ReferenceKind.ONE_TO_ONE) {
154
- const meta2 = this.metadata.get(prop.type);
156
+ const meta2 = this.metadata.get(prop.targetMeta.class);
155
157
  const prop2 = meta2.properties[prop.inversedBy || prop.mappedBy];
156
158
  if (prop2 && !prop2.mapToPk) {
157
159
  ret.push(` if (data${dataKey} && entity${entityKey} && !entity${entityKey}.${this.safeKey(prop2.name)}) {`);
@@ -169,7 +171,7 @@ export class ObjectHydrator extends Hydrator {
169
171
  };
170
172
  const hydrateToMany = (prop, dataKey, entityKey) => {
171
173
  const ret = [];
172
- ret.push(...this.createCollectionItemMapper(prop));
174
+ ret.push(...this.createCollectionItemMapper(prop, context));
173
175
  ret.push(` if (data${dataKey} && !Array.isArray(data${dataKey}) && typeof data${dataKey} === 'object') {`);
174
176
  ret.push(` data${dataKey} = [data${dataKey}];`);
175
177
  ret.push(` }`);
@@ -252,10 +254,11 @@ export class ObjectHydrator extends Hydrator {
252
254
  prop.targetMeta.polymorphs.forEach(childMeta => {
253
255
  const childProp = prop.embeddedProps[prop.targetMeta.discriminatorColumn];
254
256
  const childDataKey = prop.object ? dataKey + this.wrap(childProp.embedded[1]) : this.wrap(childProp.name);
257
+ context.set(childMeta.className, childMeta.class);
255
258
  // weak comparison as we can have numbers that might have been converted to strings due to being object keys
256
259
  ret.push(` if (data${childDataKey} == '${childMeta.discriminatorValue}') {`);
257
260
  ret.push(` if (entity${entityKey} == null) {`);
258
- ret.push(` entity${entityKey} = factory.createEmbeddable('${childMeta.className}', embeddedData, { newEntity, convertCustomTypes, normalizeAccessors });`);
261
+ ret.push(` entity${entityKey} = factory.createEmbeddable(${childMeta.className}, embeddedData, { newEntity, convertCustomTypes, normalizeAccessors });`);
259
262
  ret.push(` }`);
260
263
  meta.props
261
264
  .filter(p => p.embedded?.[0] === prop.name)
@@ -275,8 +278,10 @@ export class ObjectHydrator extends Hydrator {
275
278
  });
276
279
  }
277
280
  else {
281
+ const targetKey = this.safeKey(`${prop.targetMeta.tableName}_${this.tmpIndex++}`);
282
+ context.set(targetKey, prop.targetMeta.class);
278
283
  ret.push(` if (entity${entityKey} == null) {`);
279
- ret.push(` entity${entityKey} = factory.createEmbeddable('${prop.targetMeta.className}', embeddedData, { newEntity, convertCustomTypes, normalizeAccessors });`);
284
+ ret.push(` entity${entityKey} = factory.createEmbeddable(${targetKey}, embeddedData, { newEntity, convertCustomTypes, normalizeAccessors });`);
280
285
  ret.push(` }`);
281
286
  meta.props
282
287
  .filter(p => p.embedded?.[0] === prop.name)
@@ -334,7 +339,7 @@ export class ObjectHydrator extends Hydrator {
334
339
  }
335
340
  }
336
341
  else { // ReferenceKind.SCALAR
337
- ret.push(...hydrateScalar(prop, object, path, dataKey));
342
+ ret.push(...hydrateScalar(prop, path, dataKey));
338
343
  }
339
344
  if (this.config.get('forceUndefined')) {
340
345
  ret.push(` if (data${dataKey} === null) entity${entityKey} = undefined;`);
@@ -348,11 +353,11 @@ export class ObjectHydrator extends Hydrator {
348
353
  + `return function(entity, data, factory, newEntity, convertCustomTypes, schema, parentSchema, normalizeAccessors) {\n`
349
354
  + `${lines.join('\n')}\n}`;
350
355
  const hydrator = Utils.createFunction(context, code);
351
- this.hydrators[key].set(meta.className, hydrator);
356
+ this.hydrators[key].set(meta.class, hydrator);
352
357
  return hydrator;
353
358
  }
354
- createCollectionItemMapper(prop) {
355
- const meta = this.metadata.get(prop.type);
359
+ createCollectionItemMapper(prop, context) {
360
+ const meta = this.metadata.get(prop.targetMeta.class);
356
361
  const lines = [];
357
362
  lines.push(` const createCollectionItem_${this.safeKey(prop.name)} = (value, entity) => {`);
358
363
  const prop2 = prop.targetMeta.properties[prop.mappedBy];
@@ -361,9 +366,11 @@ export class ObjectHydrator extends Hydrator {
361
366
  lines.push(` value = { ...value, ['${prop2.name}']: Reference.wrapReference(entity, { ref: ${prop2.ref} }) };`);
362
367
  lines.push(` }`);
363
368
  }
364
- lines.push(` if (isPrimaryKey(value, ${meta.compositePK})) return factory.createReference('${prop.type}', value, { convertCustomTypes, schema, normalizeAccessors, merge: true });`);
369
+ const targetKey = this.safeKey(`${prop.targetMeta.tableName}_${this.tmpIndex++}`);
370
+ context.set(targetKey, prop.targetMeta.class);
371
+ lines.push(` if (isPrimaryKey(value, ${meta.compositePK})) return factory.createReference(${targetKey}, value, { convertCustomTypes, schema, normalizeAccessors, merge: true });`);
365
372
  lines.push(` if (value && value.__entity) return value;`);
366
- lines.push(` return factory.create('${prop.type}', value, { newEntity, convertCustomTypes, schema, normalizeAccessors, merge: true });`);
373
+ lines.push(` return factory.create(${targetKey}, value, { newEntity, convertCustomTypes, schema, normalizeAccessors, merge: true });`);
367
374
  lines.push(` }`);
368
375
  return lines;
369
376
  }
@@ -6,12 +6,12 @@ type TypeType = string | NumberConstructor | StringConstructor | BooleanConstruc
6
6
  type TypeDef<Target> = {
7
7
  type: TypeType;
8
8
  } | {
9
- entity: string | (() => string | EntityName<Target>);
9
+ entity: () => EntityName<Target>;
10
10
  };
11
11
  type EmbeddedTypeDef<Target> = {
12
12
  type: TypeType;
13
13
  } | {
14
- entity: string | (() => string | EntityName<Target> | EntityName<Target>[]);
14
+ entity: () => EntityName<Target> | EntityName<Target>[];
15
15
  };
16
16
  export type EntitySchemaProperty<Target, Owner> = ({
17
17
  kind: ReferenceKind.MANY_TO_ONE | 'm:1';
@@ -63,10 +63,10 @@ export declare class EntitySchema<Entity = any, Base = never> {
63
63
  addIndex<Key extends string>(options: IndexOptions<Entity, Key>): void;
64
64
  addUnique<Key extends string>(options: UniqueOptions<Entity, Key>): void;
65
65
  setCustomRepository(repository: () => Constructor): void;
66
- setExtends(base: EntityName<any>): void;
67
- setClass(proto: EntityClass<Entity>): void;
66
+ setExtends(base: EntityName): void;
67
+ setClass(cls: EntityClass<Entity>): void;
68
68
  get meta(): EntityMetadata<Entity>;
69
- get name(): EntityName<Entity>;
69
+ get name(): string | EntityName<Entity>;
70
70
  get tableName(): string;
71
71
  get properties(): Record<string, any>;
72
72
  /**
@@ -10,7 +10,7 @@ export class EntitySchema {
10
10
  * so we can use the class in `entities` option just like the EntitySchema instance.
11
11
  */
12
12
  static REGISTRY = new Map();
13
- _meta = new EntityMetadata();
13
+ _meta;
14
14
  internal = false;
15
15
  initialized = false;
16
16
  constructor(meta) {
@@ -18,11 +18,14 @@ export class EntitySchema {
18
18
  if (meta.name) {
19
19
  meta.abstract ??= false;
20
20
  }
21
+ this._meta = new EntityMetadata({
22
+ className: meta.name,
23
+ ...meta,
24
+ });
25
+ this._meta.root ??= this._meta;
21
26
  if (meta.class && !meta.internal) {
22
27
  EntitySchema.REGISTRY.set(meta.class, this);
23
28
  }
24
- Object.assign(this._meta, { className: meta.name }, meta);
25
- this._meta.root ??= this._meta;
26
29
  }
27
30
  static fromMetadata(meta) {
28
31
  const schema = new EntitySchema({ ...meta, internal: true });
@@ -31,7 +34,7 @@ export class EntitySchema {
31
34
  }
32
35
  addProperty(name, type, options = {}) {
33
36
  this.renameCompositeOptions(name, options);
34
- const prop = { name, kind: ReferenceKind.SCALAR, ...options, type: this.normalizeType(options, type) };
37
+ const prop = { name, kind: ReferenceKind.SCALAR, ...options, ...this.normalizeType(options, type) };
35
38
  if (type && Type.isMappedType(type.prototype)) {
36
39
  prop.type = type;
37
40
  }
@@ -81,8 +84,8 @@ export class EntitySchema {
81
84
  }
82
85
  this._meta.properties[name] = {
83
86
  name,
84
- type: this.normalizeType(options),
85
87
  kind: ReferenceKind.EMBEDDED,
88
+ ...this.normalizeType(options),
86
89
  ...options,
87
90
  };
88
91
  }
@@ -147,19 +150,20 @@ export class EntitySchema {
147
150
  setExtends(base) {
148
151
  this._meta.extends = base;
149
152
  }
150
- setClass(proto) {
151
- const sameClass = this._meta.className === proto.name;
152
- this._meta.class = proto;
153
- this._meta.prototype = proto.prototype;
154
- this._meta.className = proto.name;
153
+ setClass(cls) {
154
+ const sameClass = this._meta.className === cls.name;
155
+ this._meta.class = cls;
156
+ this._meta.prototype = cls.prototype;
157
+ this._meta.className = this._meta.name ?? cls.name;
155
158
  if (!sameClass || !this._meta.constructorParams) {
156
- this._meta.constructorParams = Utils.getConstructorParams(proto);
159
+ this._meta.constructorParams = Utils.getConstructorParams(cls);
157
160
  }
158
161
  if (!this.internal) {
159
- EntitySchema.REGISTRY.set(proto, this);
162
+ EntitySchema.REGISTRY.set(cls, this);
160
163
  }
161
- if (Object.getPrototypeOf(proto) !== BaseEntity) {
162
- this._meta.extends = this._meta.extends || Object.getPrototypeOf(proto).name || undefined;
164
+ const base = Object.getPrototypeOf(cls);
165
+ if (base !== BaseEntity) {
166
+ this._meta.extends ??= base.name ? base : undefined;
163
167
  }
164
168
  }
165
169
  get meta() {
@@ -181,11 +185,6 @@ export class EntitySchema {
181
185
  if (this.initialized) {
182
186
  return this;
183
187
  }
184
- if (!this._meta.class) {
185
- const name = this.name;
186
- this._meta.class = ({ [name]: class {
187
- } })[name];
188
- }
189
188
  this.setClass(this._meta.class);
190
189
  if (this._meta.abstract && !this._meta.discriminatorColumn) {
191
190
  delete this._meta.name;
@@ -259,12 +258,15 @@ export class EntitySchema {
259
258
  }
260
259
  normalizeType(options, type) {
261
260
  if ('entity' in options) {
261
+ /* v8 ignore next */
262
262
  if (typeof options.entity === 'string') {
263
- type = options.type = options.entity;
263
+ throw new Error(`Relation target needs to be an entity class or EntitySchema instance, string '${options.entity}' given instead for ${this._meta.className}.${options.name}.`);
264
264
  }
265
265
  else if (options.entity) {
266
266
  const tmp = options.entity();
267
267
  type = options.type = Array.isArray(tmp) ? tmp.map(t => Utils.className(t)).sort().join(' | ') : Utils.className(tmp);
268
+ const target = tmp instanceof EntitySchema ? tmp.meta.class : tmp;
269
+ return { type, target };
268
270
  }
269
271
  }
270
272
  if (type instanceof Function) {
@@ -273,7 +275,7 @@ export class EntitySchema {
273
275
  if (['String', 'Number', 'Boolean', 'Array'].includes(type)) {
274
276
  type = type.toLowerCase();
275
277
  }
276
- return type;
278
+ return { type };
277
279
  }
278
280
  createProperty(kind, options) {
279
281
  return {
@@ -1,4 +1,4 @@
1
- import { type EntityClass, EntityMetadata } from '../typings.js';
1
+ import { type EntityClass, EntityMetadata, type EntityName } from '../typings.js';
2
2
  import type { Configuration } from '../utils/Configuration.js';
3
3
  import { MetadataStorage } from './MetadataStorage.js';
4
4
  import { EntitySchema } from './EntitySchema.js';
@@ -16,7 +16,6 @@ export declare class MetadataDiscovery {
16
16
  constructor(metadata: MetadataStorage, platform: Platform, config: Configuration);
17
17
  discover(preferTs?: boolean): Promise<MetadataStorage>;
18
18
  discoverSync(): MetadataStorage;
19
- validateDiscovered(metadata: EntityMetadata[]): void;
20
19
  private mapDiscoveredEntities;
21
20
  private initAccessors;
22
21
  processDiscoveredEntities(discovered: EntityMetadata[]): EntityMetadata[];
@@ -24,7 +23,7 @@ export declare class MetadataDiscovery {
24
23
  private discoverMissingTargets;
25
24
  private tryDiscoverTargets;
26
25
  discoverReferences<T>(refs: Iterable<EntityClass<T> | EntitySchema<T>>, validate?: boolean): EntityMetadata<T>[];
27
- reset(className: string): void;
26
+ reset<T>(entityName: EntityName<T>): void;
28
27
  private getSchema;
29
28
  private getRootEntity;
30
29
  private discoverEntity;