@mikro-orm/core 7.0.0-dev.321 → 7.0.0-dev.323

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 (53) hide show
  1. package/EntityManager.d.ts +2 -15
  2. package/EntityManager.js +155 -152
  3. package/MikroORM.d.ts +1 -3
  4. package/MikroORM.js +20 -20
  5. package/cache/FileCacheAdapter.d.ts +1 -5
  6. package/cache/FileCacheAdapter.js +22 -22
  7. package/cache/GeneratedCacheAdapter.d.ts +1 -1
  8. package/cache/GeneratedCacheAdapter.js +6 -6
  9. package/cache/MemoryCacheAdapter.d.ts +1 -2
  10. package/cache/MemoryCacheAdapter.js +8 -8
  11. package/entity/Collection.d.ts +2 -10
  12. package/entity/Collection.js +95 -105
  13. package/entity/EntityFactory.d.ts +1 -8
  14. package/entity/EntityFactory.js +48 -48
  15. package/entity/EntityLoader.d.ts +1 -3
  16. package/entity/EntityLoader.js +33 -34
  17. package/entity/Reference.d.ts +1 -2
  18. package/entity/Reference.js +11 -11
  19. package/events/EventManager.d.ts +1 -4
  20. package/events/EventManager.js +21 -21
  21. package/hydration/ObjectHydrator.d.ts +1 -2
  22. package/hydration/ObjectHydrator.js +11 -11
  23. package/metadata/MetadataDiscovery.d.ts +1 -9
  24. package/metadata/MetadataDiscovery.js +147 -144
  25. package/metadata/MetadataStorage.d.ts +1 -5
  26. package/metadata/MetadataStorage.js +36 -36
  27. package/naming-strategy/EntityCaseNamingStrategy.js +1 -1
  28. package/package.json +1 -1
  29. package/serialization/EntitySerializer.js +1 -1
  30. package/serialization/EntityTransformer.js +4 -1
  31. package/serialization/SerializationContext.d.ts +3 -7
  32. package/serialization/SerializationContext.js +20 -15
  33. package/unit-of-work/ChangeSetComputer.d.ts +1 -6
  34. package/unit-of-work/ChangeSetComputer.js +21 -21
  35. package/unit-of-work/ChangeSetPersister.d.ts +1 -9
  36. package/unit-of-work/ChangeSetPersister.js +51 -51
  37. package/unit-of-work/CommitOrderCalculator.d.ts +1 -4
  38. package/unit-of-work/CommitOrderCalculator.js +13 -13
  39. package/unit-of-work/IdentityMap.d.ts +2 -5
  40. package/unit-of-work/IdentityMap.js +18 -18
  41. package/unit-of-work/UnitOfWork.d.ts +5 -19
  42. package/unit-of-work/UnitOfWork.js +181 -173
  43. package/utils/AbstractMigrator.d.ts +1 -1
  44. package/utils/AbstractMigrator.js +6 -6
  45. package/utils/Configuration.d.ts +1 -6
  46. package/utils/Configuration.js +78 -78
  47. package/utils/Cursor.d.ts +1 -1
  48. package/utils/Cursor.js +3 -3
  49. package/utils/EntityComparator.d.ts +2 -11
  50. package/utils/EntityComparator.js +44 -44
  51. package/utils/TransactionManager.js +1 -2
  52. package/utils/Utils.js +1 -1
  53. package/utils/clone.js +1 -1
@@ -1,12 +1,8 @@
1
1
  import { type Dictionary, EntityMetadata, type EntityName } from '../typings.js';
2
2
  import type { EntityManager } from '../EntityManager.js';
3
3
  export declare class MetadataStorage {
4
+ #private;
4
5
  static readonly PATH_SYMBOL: unique symbol;
5
- private static readonly metadata;
6
- private readonly metadata;
7
- private readonly idMap;
8
- private readonly classNameMap;
9
- private readonly uniqueNameMap;
10
6
  constructor(metadata?: Dictionary<EntityMetadata>);
11
7
  static getMetadata(): Dictionary<EntityMetadata>;
12
8
  static getMetadata<T = any>(entity: string, path: string): EntityMetadata<T>;
@@ -10,39 +10,39 @@ function getGlobalStorage(namespace) {
10
10
  }
11
11
  export class MetadataStorage {
12
12
  static PATH_SYMBOL = Symbol.for('@mikro-orm/core/MetadataStorage.PATH_SYMBOL');
13
- static metadata = getGlobalStorage('metadata');
14
- metadata = new Map();
15
- idMap;
16
- classNameMap;
17
- uniqueNameMap;
13
+ static #metadata = getGlobalStorage('metadata');
14
+ #metadataMap = new Map();
15
+ #idMap;
16
+ #classNameMap;
17
+ #uniqueNameMap;
18
18
  constructor(metadata = {}) {
19
- this.idMap = {};
20
- this.uniqueNameMap = {};
21
- this.classNameMap = Utils.copy(metadata, false);
22
- for (const meta of Object.values(this.classNameMap)) {
23
- this.idMap[meta._id] = meta;
24
- this.uniqueNameMap[meta.uniqueName] = meta;
25
- this.metadata.set(meta.class, meta);
19
+ this.#idMap = {};
20
+ this.#uniqueNameMap = {};
21
+ this.#classNameMap = Utils.copy(metadata, false);
22
+ for (const meta of Object.values(this.#classNameMap)) {
23
+ this.#idMap[meta._id] = meta;
24
+ this.#uniqueNameMap[meta.uniqueName] = meta;
25
+ this.#metadataMap.set(meta.class, meta);
26
26
  }
27
27
  }
28
28
  static getMetadata(entity, path) {
29
29
  const key = entity && path ? entity + '-' + Utils.hash(path) : null;
30
- if (key && !MetadataStorage.metadata[key]) {
31
- MetadataStorage.metadata[key] = new EntityMetadata({ className: entity, path });
30
+ if (key && !MetadataStorage.#metadata[key]) {
31
+ MetadataStorage.#metadata[key] = new EntityMetadata({ className: entity, path });
32
32
  }
33
33
  if (key) {
34
- return MetadataStorage.metadata[key];
34
+ return MetadataStorage.#metadata[key];
35
35
  }
36
- return MetadataStorage.metadata;
36
+ return MetadataStorage.#metadata;
37
37
  }
38
38
  static isKnownEntity(name) {
39
- return !!Object.values(this.metadata).find(meta => meta.className === name);
39
+ return !!Object.values(this.#metadata).find(meta => meta.className === name);
40
40
  }
41
41
  static clear() {
42
- Object.keys(this.metadata).forEach(k => delete this.metadata[k]);
42
+ Object.keys(this.#metadata).forEach(k => delete this.#metadata[k]);
43
43
  }
44
44
  getAll() {
45
- return this.metadata;
45
+ return this.#metadataMap;
46
46
  }
47
47
  get(entityName, init = false) {
48
48
  const exists = this.find(entityName);
@@ -61,50 +61,50 @@ export class MetadataStorage {
61
61
  if (!entityName) {
62
62
  return;
63
63
  }
64
- const meta = this.metadata.get(entityName);
64
+ const meta = this.#metadataMap.get(entityName);
65
65
  if (meta) {
66
66
  return meta;
67
67
  }
68
68
  if (entityName instanceof EntitySchema) {
69
- return this.metadata.get(entityName.meta.class) ?? entityName.meta;
69
+ return this.#metadataMap.get(entityName.meta.class) ?? entityName.meta;
70
70
  }
71
- return this.classNameMap[Utils.className(entityName)];
71
+ return this.#classNameMap[Utils.className(entityName)];
72
72
  }
73
73
  has(entityName) {
74
- return this.metadata.has(entityName);
74
+ return this.#metadataMap.has(entityName);
75
75
  }
76
76
  set(entityName, meta) {
77
- this.metadata.set(entityName, meta);
78
- this.idMap[meta._id] = meta;
79
- this.uniqueNameMap[meta.uniqueName] = meta;
80
- this.classNameMap[Utils.className(entityName)] = meta;
77
+ this.#metadataMap.set(entityName, meta);
78
+ this.#idMap[meta._id] = meta;
79
+ this.#uniqueNameMap[meta.uniqueName] = meta;
80
+ this.#classNameMap[Utils.className(entityName)] = meta;
81
81
  return meta;
82
82
  }
83
83
  reset(entityName) {
84
84
  const meta = this.find(entityName);
85
85
  if (meta) {
86
- this.metadata.delete(meta.class);
87
- delete this.idMap[meta._id];
88
- delete this.uniqueNameMap[meta.uniqueName];
89
- delete this.classNameMap[meta.className];
86
+ this.#metadataMap.delete(meta.class);
87
+ delete this.#idMap[meta._id];
88
+ delete this.#uniqueNameMap[meta.uniqueName];
89
+ delete this.#classNameMap[meta.className];
90
90
  }
91
91
  }
92
92
  decorate(em) {
93
- [...this.metadata.values()].filter(meta => meta.prototype).forEach(meta => EntityHelper.decorate(meta, em));
93
+ [...this.#metadataMap.values()].filter(meta => meta.prototype).forEach(meta => EntityHelper.decorate(meta, em));
94
94
  }
95
95
  *[Symbol.iterator]() {
96
- for (const meta of this.metadata.values()) {
96
+ for (const meta of this.#metadataMap.values()) {
97
97
  yield meta;
98
98
  }
99
99
  }
100
100
  getById(id) {
101
- return this.idMap[id];
101
+ return this.#idMap[id];
102
102
  }
103
103
  getByClassName(className, validate = true) {
104
- return this.validate(this.classNameMap[className], className, validate);
104
+ return this.validate(this.#classNameMap[className], className, validate);
105
105
  }
106
106
  getByUniqueName(uniqueName, validate = true) {
107
- return this.validate(this.uniqueNameMap[uniqueName], uniqueName, validate);
107
+ return this.validate(this.#uniqueNameMap[uniqueName], uniqueName, validate);
108
108
  }
109
109
  validate(meta, id, validate) {
110
110
  if (!meta && validate) {
@@ -11,7 +11,7 @@ export class EntityCaseNamingStrategy extends AbstractNamingStrategy {
11
11
  }
12
12
  joinKeyColumnName(entityName, referencedColumnName, composite, tableName) {
13
13
  entityName = this.classToTableName(entityName, tableName);
14
- const name = entityName.substr(0, 1).toLowerCase() + entityName.substr(1);
14
+ const name = entityName.substring(0, 1).toLowerCase() + entityName.substring(1);
15
15
  if (composite && referencedColumnName) {
16
16
  return name + '_' + referencedColumnName;
17
17
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "7.0.0-dev.321",
3
+ "version": "7.0.0-dev.323",
4
4
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
5
5
  "keywords": [
6
6
  "data-mapper",
@@ -36,7 +36,7 @@ export class EntitySerializer {
36
36
  const meta = wrapped.__meta;
37
37
  let contextCreated = false;
38
38
  if (!wrapped.__serializationContext.root) {
39
- const root = new SerializationContext(wrapped.__config);
39
+ const root = new SerializationContext();
40
40
  SerializationContext.propagate(root, entity, (meta, prop) => meta.properties[prop]?.kind !== ReferenceKind.SCALAR);
41
41
  options.populate = (options.populate ? Utils.asArray(options.populate) : options.populate);
42
42
  contextCreated = true;
@@ -20,7 +20,7 @@ export class EntityTransformer {
20
20
  return entity;
21
21
  }
22
22
  if (!wrapped.__serializationContext.root) {
23
- const root = new SerializationContext(wrapped.__config, wrapped.__serializationContext.populate, wrapped.__serializationContext.fields, wrapped.__serializationContext.exclude);
23
+ const root = new SerializationContext(wrapped.__serializationContext.populate, wrapped.__serializationContext.fields, wrapped.__serializationContext.exclude);
24
24
  SerializationContext.propagate(root, entity, isVisible);
25
25
  contextCreated = true;
26
26
  }
@@ -64,6 +64,9 @@ export class EntityTransformer {
64
64
  if (!partiallyLoaded && !populated && !isPrimary) {
65
65
  continue;
66
66
  }
67
+ if (root.isExcluded(meta.class, prop) && !populated) {
68
+ continue;
69
+ }
67
70
  }
68
71
  const cycle = root.visit(meta.class, prop);
69
72
  if (cycle && visited) {
@@ -1,19 +1,14 @@
1
1
  import type { AnyEntity, EntityMetadata, EntityName, PopulateOptions } from '../typings.js';
2
- import type { Configuration } from '../utils/Configuration.js';
3
2
  /**
4
3
  * Helper that allows to keep track of where we are currently at when serializing complex entity graph with cycles.
5
4
  * Before we process a property, we call `visit` that checks if it is not a cycle path (but allows to pass cycles that
6
5
  * are defined in populate hint). If not, we proceed and call `leave` afterwards.
7
6
  */
8
7
  export declare class SerializationContext<T extends object> {
9
- private readonly config;
10
- private readonly populate;
11
- private readonly fields?;
12
- private readonly exclude?;
8
+ #private;
13
9
  readonly path: [EntityName, string][];
14
10
  readonly visited: Set<Partial<any>>;
15
- private entities;
16
- constructor(config: Configuration, populate?: PopulateOptions<T>[], fields?: Set<string> | undefined, exclude?: string[] | undefined);
11
+ constructor(populate?: PopulateOptions<T>[], fields?: Set<string>, exclude?: readonly string[]);
17
12
  /**
18
13
  * Returns true when there is a cycle detected.
19
14
  */
@@ -25,6 +20,7 @@ export declare class SerializationContext<T extends object> {
25
20
  */
26
21
  static propagate(root: SerializationContext<any>, entity: AnyEntity, isVisible: (meta: EntityMetadata, prop: string) => boolean): void;
27
22
  isMarkedAsPopulated(entityName: EntityName, prop: string): boolean;
23
+ isExcluded(entityName: EntityName, prop: string): boolean;
28
24
  isPartiallyLoaded(entityName: EntityName, prop: string): boolean;
29
25
  private register;
30
26
  }
@@ -6,18 +6,16 @@ import { helper } from '../entity/wrap.js';
6
6
  * are defined in populate hint). If not, we proceed and call `leave` afterwards.
7
7
  */
8
8
  export class SerializationContext {
9
- config;
10
- populate;
11
- fields;
12
- exclude;
13
9
  path = [];
14
10
  visited = new Set();
15
- entities = new Set();
16
- constructor(config, populate = [], fields, exclude) {
17
- this.config = config;
18
- this.populate = populate;
19
- this.fields = fields;
20
- this.exclude = exclude;
11
+ #entities = new Set();
12
+ #populate;
13
+ #fields;
14
+ #exclude;
15
+ constructor(populate = [], fields, exclude) {
16
+ this.#populate = populate;
17
+ this.#fields = fields;
18
+ this.#exclude = exclude;
21
19
  }
22
20
  /**
23
21
  * Returns true when there is a cycle detected.
@@ -42,7 +40,7 @@ export class SerializationContext {
42
40
  }
43
41
  }
44
42
  close() {
45
- for (const entity of this.entities) {
43
+ for (const entity of this.#entities) {
46
44
  delete helper(entity).__serializationContext.root;
47
45
  }
48
46
  }
@@ -73,7 +71,7 @@ export class SerializationContext {
73
71
  }
74
72
  }
75
73
  isMarkedAsPopulated(entityName, prop) {
76
- let populate = this.populate ?? [];
74
+ let populate = this.#populate ?? [];
77
75
  for (const segment of this.path) {
78
76
  const hints = populate.filter(p => p.field === segment[1]);
79
77
  if (hints.length > 0) {
@@ -92,11 +90,18 @@ export class SerializationContext {
92
90
  }
93
91
  return !!populate?.some(p => p.field === prop);
94
92
  }
93
+ isExcluded(entityName, prop) {
94
+ if (!this.#exclude || this.#exclude.length === 0) {
95
+ return false;
96
+ }
97
+ const fullPath = this.path.map(segment => segment[1] + '.').join('') + prop;
98
+ return this.#exclude.includes(fullPath);
99
+ }
95
100
  isPartiallyLoaded(entityName, prop) {
96
- if (!this.fields) {
101
+ if (!this.#fields) {
97
102
  return true;
98
103
  }
99
- let fields = [...this.fields];
104
+ let fields = [...this.#fields];
100
105
  for (const segment of this.path) {
101
106
  /* v8 ignore next */
102
107
  if (fields.length === 0) {
@@ -110,6 +115,6 @@ export class SerializationContext {
110
115
  }
111
116
  register(entity) {
112
117
  helper(entity).__serializationContext.root = this;
113
- this.entities.add(entity);
118
+ this.#entities.add(entity);
114
119
  }
115
120
  }
@@ -3,12 +3,7 @@ import { ChangeSet } from './ChangeSet.js';
3
3
  import { type Collection } from '../entity/Collection.js';
4
4
  import type { EntityManager } from '../EntityManager.js';
5
5
  export declare class ChangeSetComputer {
6
- private readonly em;
7
- private readonly collectionUpdates;
8
- private readonly comparator;
9
- private readonly metadata;
10
- private readonly platform;
11
- private readonly config;
6
+ #private;
12
7
  constructor(em: EntityManager, collectionUpdates: Set<Collection<AnyEntity>>);
13
8
  computeChangeSet<T extends object>(entity: T): ChangeSet<T> | null;
14
9
  /**
@@ -7,22 +7,22 @@ import { Reference } from '../entity/Reference.js';
7
7
  import { PolymorphicRef } from '../entity/PolymorphicRef.js';
8
8
  import { ReferenceKind } from '../enums.js';
9
9
  export class ChangeSetComputer {
10
- em;
11
- collectionUpdates;
12
- comparator;
13
- metadata;
14
- platform;
15
- config;
10
+ #comparator;
11
+ #metadata;
12
+ #platform;
13
+ #config;
14
+ #em;
15
+ #collectionUpdates;
16
16
  constructor(em, collectionUpdates) {
17
- this.em = em;
18
- this.collectionUpdates = collectionUpdates;
19
- this.config = this.em.config;
20
- this.metadata = this.em.getMetadata();
21
- this.platform = this.em.getPlatform();
22
- this.comparator = this.config.getComparator(this.metadata);
17
+ this.#em = em;
18
+ this.#collectionUpdates = collectionUpdates;
19
+ this.#config = this.#em.config;
20
+ this.#metadata = this.#em.getMetadata();
21
+ this.#platform = this.#em.getPlatform();
22
+ this.#comparator = this.#config.getComparator(this.#metadata);
23
23
  }
24
24
  computeChangeSet(entity) {
25
- const meta = this.metadata.get(entity.constructor);
25
+ const meta = this.#metadata.get(entity.constructor);
26
26
  if (meta.readonly) {
27
27
  return null;
28
28
  }
@@ -38,7 +38,7 @@ export class ChangeSetComputer {
38
38
  }
39
39
  }
40
40
  if (type === ChangeSetType.UPDATE && !wrapped.__initialized) {
41
- const data = this.comparator.prepareEntity(entity);
41
+ const data = this.#comparator.prepareEntity(entity);
42
42
  if (Utils.equals(data, wrapped.__originalEntityData)) {
43
43
  return null;
44
44
  }
@@ -79,11 +79,11 @@ export class ChangeSetComputer {
79
79
  type === ChangeSetType.CREATE &&
80
80
  (entity[prop.name] == null ||
81
81
  (Utils.isScalarReference(entity[prop.name]) && entity[prop.name].unwrap() == null))) {
82
- entity[prop.name] = prop.onCreate(entity, this.em);
82
+ entity[prop.name] = prop.onCreate(entity, this.#em);
83
83
  }
84
84
  if (prop.onUpdate && type === ChangeSetType.UPDATE) {
85
85
  const pairs = map.get(entity) ?? [];
86
- pairs.push([prop.name, prop.onUpdate(entity, this.em)]);
86
+ pairs.push([prop.name, prop.onUpdate(entity, this.#em)]);
87
87
  map.set(entity, pairs);
88
88
  }
89
89
  if (prop.kind === ReferenceKind.EMBEDDED && entity[prop.name]) {
@@ -93,7 +93,7 @@ export class ChangeSetComputer {
93
93
  }
94
94
  }
95
95
  computePayload(entity, ignoreUndefined = false) {
96
- const data = this.comparator.prepareEntity(entity);
96
+ const data = this.#comparator.prepareEntity(entity);
97
97
  const wrapped = helper(entity);
98
98
  const entityName = wrapped.__meta.class;
99
99
  const originalEntityData = wrapped.__originalEntityData;
@@ -104,7 +104,7 @@ export class ChangeSetComputer {
104
104
  return data;
105
105
  }
106
106
  if (originalEntityData) {
107
- const comparator = this.comparator.getEntityComparator(entityName);
107
+ const comparator = this.#comparator.getEntityComparator(entityName);
108
108
  const diff = comparator(originalEntityData, data);
109
109
  if (ignoreUndefined) {
110
110
  Utils.keys(diff)
@@ -144,7 +144,7 @@ export class ChangeSetComputer {
144
144
  if (prop.targetKey && prop.targetMeta) {
145
145
  const targetProp = prop.targetMeta.properties[prop.targetKey];
146
146
  if (targetProp?.customType) {
147
- value = targetProp.customType.convertToDatabaseValue(value, this.platform, { mode: 'serialization' });
147
+ value = targetProp.customType.convertToDatabaseValue(value, this.#platform, { mode: 'serialization' });
148
148
  }
149
149
  }
150
150
  if (prop.polymorphic) {
@@ -163,9 +163,9 @@ export class ChangeSetComputer {
163
163
  return;
164
164
  }
165
165
  if (target.isDirty()) {
166
- this.collectionUpdates.add(target);
166
+ this.#collectionUpdates.add(target);
167
167
  }
168
- if (prop.owner && !this.platform.usesPivotTable()) {
168
+ if (prop.owner && !this.#platform.usesPivotTable()) {
169
169
  changeSet.payload[prop.name] = target.getItems(false).map((item) => {
170
170
  return item.__helper.__identifier ?? item.__helper.getPrimaryKey();
171
171
  });
@@ -3,15 +3,7 @@ import { type ChangeSet } from './ChangeSet.js';
3
3
  import type { DriverMethodOptions } from '../drivers/IDatabaseDriver.js';
4
4
  import type { EntityManager } from '../EntityManager.js';
5
5
  export declare class ChangeSetPersister {
6
- private readonly em;
7
- private readonly platform;
8
- private readonly comparator;
9
- private readonly usesReturningStatement;
10
- private readonly driver;
11
- private readonly metadata;
12
- private readonly hydrator;
13
- private readonly factory;
14
- private readonly config;
6
+ #private;
15
7
  constructor(em: EntityManager);
16
8
  executeInserts<T extends object>(changeSets: ChangeSet<T>[], options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
17
9
  executeUpdates<T extends object>(changeSets: ChangeSet<T>[], batched: boolean, options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;