@mikro-orm/core 7.0.0-dev.179 → 7.0.0-dev.180

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.
@@ -515,7 +515,7 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
515
515
  private lockAndPopulate;
516
516
  private buildFields;
517
517
  /** @internal */
518
- preparePopulate<Entity extends object>(entityName: EntityName<Entity>, options: Pick<FindOptions<Entity, any, any>, 'populate' | 'strategy' | 'fields' | 'flags' | 'filters'>, validate?: boolean): Promise<PopulateOptions<Entity>[]>;
518
+ preparePopulate<Entity extends object>(entityName: EntityName<Entity>, options: Pick<FindOptions<Entity, any, any, any>, 'populate' | 'strategy' | 'fields' | 'flags' | 'filters' | 'exclude'>, validate?: boolean): Promise<PopulateOptions<Entity>[]>;
519
519
  /**
520
520
  * when the entity is found in identity map, we check if it was partially loaded or we are trying to populate
521
521
  * some additional lazy properties, if so, we reload and merge the data from database
package/EntityManager.js CHANGED
@@ -1642,7 +1642,7 @@ export class EntityManager {
1642
1642
  options.populate = pruneToOneRelations(meta, this.buildFields(options.fields));
1643
1643
  }
1644
1644
  if (!options.populate) {
1645
- const populate = this.entityLoader.normalizePopulate(entityName, [], options.strategy);
1645
+ const populate = this.entityLoader.normalizePopulate(entityName, [], options.strategy, true, options.exclude);
1646
1646
  await this.autoJoinRefsForFilters(meta, { ...options, populate });
1647
1647
  return populate;
1648
1648
  }
@@ -1664,7 +1664,7 @@ export class EntityManager {
1664
1664
  return [field];
1665
1665
  }).flat();
1666
1666
  }
1667
- const populate = this.entityLoader.normalizePopulate(entityName, options.populate, options.strategy);
1667
+ const populate = this.entityLoader.normalizePopulate(entityName, options.populate, options.strategy, true, options.exclude);
1668
1668
  const invalid = populate.find(({ field }) => !this.canPopulate(entityName, field));
1669
1669
  if (validate && invalid) {
1670
1670
  throw ValidationError.invalidPropertyName(entityName, invalid.field);
@@ -31,7 +31,7 @@ export declare class EntityLoader {
31
31
  * This will execute one query for each relation, that will populate it on all the specified entities.
32
32
  */
33
33
  populate<Entity extends object, Fields extends string = PopulatePath.ALL>(entityName: EntityName<Entity>, entities: Entity[], populate: PopulateOptions<Entity>[] | boolean, options: EntityLoaderOptions<Entity, Fields>): Promise<void>;
34
- normalizePopulate<Entity>(entityName: EntityName<Entity>, populate: (PopulateOptions<Entity> | boolean)[] | PopulateOptions<Entity> | boolean, strategy?: LoadStrategy, lookup?: boolean): PopulateOptions<Entity>[];
34
+ normalizePopulate<Entity>(entityName: EntityName<Entity>, populate: (PopulateOptions<Entity> | boolean)[] | PopulateOptions<Entity> | boolean, strategy?: LoadStrategy, lookup?: boolean, exclude?: string[]): PopulateOptions<Entity>[];
35
35
  private setSerializationContext;
36
36
  /**
37
37
  * Merge multiple populates for the same entity with different children. Also skips `*` fields, those can come from
@@ -39,7 +39,7 @@ export class EntityLoader {
39
39
  if (references.length > 0) {
40
40
  await this.populateScalar(meta, references, { ...options, populateWhere: undefined });
41
41
  }
42
- populate = this.normalizePopulate(entityName, populate, options.strategy, options.lookup);
42
+ populate = this.normalizePopulate(entityName, populate, options.strategy, options.lookup, options.exclude);
43
43
  const invalid = populate.find(({ field }) => !this.em.canPopulate(entityName, field));
44
44
  /* v8 ignore next */
45
45
  if (options.validate && invalid) {
@@ -56,7 +56,7 @@ export class EntityLoader {
56
56
  visited.delete(entity);
57
57
  }
58
58
  }
59
- normalizePopulate(entityName, populate, strategy, lookup = true) {
59
+ normalizePopulate(entityName, populate, strategy, lookup = true, exclude) {
60
60
  const meta = this.metadata.find(entityName);
61
61
  let normalized = Utils.asArray(populate).map(field => {
62
62
  return typeof field === 'boolean' || field.field === PopulatePath.ALL ? { all: !!field, field: meta.primaryKeys[0] } : field;
@@ -67,7 +67,7 @@ export class EntityLoader {
67
67
  // convert nested `field` with dot syntax to PopulateOptions with `children` array
68
68
  expandDotPaths(meta, normalized, true);
69
69
  if (lookup && populate !== false) {
70
- normalized = this.lookupEagerLoadedRelationships(entityName, normalized, strategy);
70
+ normalized = this.lookupEagerLoadedRelationships(entityName, normalized, strategy, '', [], exclude);
71
71
  // convert nested `field` with dot syntax produced by eager relations
72
72
  expandDotPaths(meta, normalized, true);
73
73
  }
@@ -587,7 +587,7 @@ export class EntityLoader {
587
587
  }
588
588
  return `${this.getRelationName(meta, meta.properties[prop.embedded[0]])}.${prop.embedded[1]}`;
589
589
  }
590
- lookupEagerLoadedRelationships(entityName, populate, strategy, prefix = '', visited = []) {
590
+ lookupEagerLoadedRelationships(entityName, populate, strategy, prefix = '', visited = [], exclude) {
591
591
  const meta = this.metadata.find(entityName);
592
592
  if (!meta && !prefix) {
593
593
  return populate;
@@ -599,16 +599,19 @@ export class EntityLoader {
599
599
  const ret = prefix === '' ? [...populate] : [];
600
600
  meta.relations
601
601
  .filter(prop => {
602
+ const field = this.getRelationName(meta, prop);
603
+ const prefixed = prefix ? `${prefix}.${field}` : field;
604
+ const isExcluded = exclude?.includes(prefixed);
602
605
  const eager = prop.eager && !populate.some(p => p.field === `${prop.name}:ref`);
603
606
  const populated = populate.some(p => p.field === prop.name);
604
607
  const disabled = populate.some(p => p.field === prop.name && p.all === false);
605
- return !disabled && (eager || populated);
608
+ return !disabled && !isExcluded && (eager || populated);
606
609
  })
607
610
  .forEach(prop => {
608
611
  const field = this.getRelationName(meta, prop);
609
612
  const prefixed = prefix ? `${prefix}.${field}` : field;
610
613
  const nestedPopulate = populate.filter(p => p.field === prop.name).flatMap(p => p.children).filter(Boolean);
611
- const nested = this.lookupEagerLoadedRelationships(prop.targetMeta.class, nestedPopulate, strategy, prefixed, visited.slice());
614
+ const nested = this.lookupEagerLoadedRelationships(prop.targetMeta.class, nestedPopulate, strategy, prefixed, visited.slice(), exclude);
612
615
  if (nested.length > 0) {
613
616
  ret.push(...nested);
614
617
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
3
  "type": "module",
4
- "version": "7.0.0-dev.179",
4
+ "version": "7.0.0-dev.180",
5
5
  "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.",
6
6
  "exports": {
7
7
  "./package.json": "./package.json",
package/utils/Utils.js CHANGED
@@ -123,7 +123,7 @@ export function parseJsonSafe(value) {
123
123
  }
124
124
  export class Utils {
125
125
  static PK_SEPARATOR = '~~~';
126
- static #ORM_VERSION = '7.0.0-dev.179';
126
+ static #ORM_VERSION = '7.0.0-dev.180';
127
127
  /**
128
128
  * Checks if the argument is instance of `Object`. Returns false for arrays.
129
129
  */