@mikro-orm/core 6.6.6-dev.1 → 6.6.6-dev.3

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.
@@ -507,7 +507,7 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
507
507
  private lockAndPopulate;
508
508
  private buildFields;
509
509
  /** @internal */
510
- preparePopulate<Entity extends object>(entityName: string, options: Pick<FindOptions<Entity, any, any>, 'populate' | 'strategy' | 'fields' | 'flags' | 'filters'>, validate?: boolean): Promise<PopulateOptions<Entity>[]>;
510
+ preparePopulate<Entity extends object>(entityName: string, options: Pick<FindOptions<Entity, any, any, any>, 'populate' | 'strategy' | 'fields' | 'flags' | 'filters' | 'exclude'>, validate?: boolean): Promise<PopulateOptions<Entity>[]>;
511
511
  /**
512
512
  * when the entity is found in identity map, we check if it was partially loaded or we are trying to populate
513
513
  * some additional lazy properties, if so, we reload and merge the data from database
package/EntityManager.js CHANGED
@@ -1624,7 +1624,7 @@ class EntityManager {
1624
1624
  options.populate = pruneToOneRelations(meta, this.buildFields(options.fields));
1625
1625
  }
1626
1626
  if (!options.populate) {
1627
- const populate = this.entityLoader.normalizePopulate(entityName, [], options.strategy);
1627
+ const populate = this.entityLoader.normalizePopulate(entityName, [], options.strategy, true, options.exclude);
1628
1628
  await this.autoJoinRefsForFilters(meta, { ...options, populate });
1629
1629
  return populate;
1630
1630
  }
@@ -1646,7 +1646,7 @@ class EntityManager {
1646
1646
  return [field];
1647
1647
  }).flat();
1648
1648
  }
1649
- const populate = this.entityLoader.normalizePopulate(entityName, options.populate, options.strategy);
1649
+ const populate = this.entityLoader.normalizePopulate(entityName, options.populate, options.strategy, true, options.exclude);
1650
1650
  const invalid = populate.find(({ field }) => !this.canPopulate(entityName, field));
1651
1651
  if (validate && invalid) {
1652
1652
  throw errors_1.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: string, entities: Entity[], populate: PopulateOptions<Entity>[] | boolean, options: EntityLoaderOptions<Entity, Fields>): Promise<void>;
34
- normalizePopulate<Entity>(entityName: string, populate: (PopulateOptions<Entity> | boolean)[] | PopulateOptions<Entity> | boolean, strategy?: LoadStrategy, lookup?: boolean): PopulateOptions<Entity>[];
34
+ normalizePopulate<Entity>(entityName: string, 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
@@ -42,7 +42,7 @@ class EntityLoader {
42
42
  if (references.length > 0) {
43
43
  await this.populateScalar(meta, references, { ...options, populateWhere: undefined });
44
44
  }
45
- populate = this.normalizePopulate(entityName, populate, options.strategy, options.lookup);
45
+ populate = this.normalizePopulate(entityName, populate, options.strategy, options.lookup, options.exclude);
46
46
  const invalid = populate.find(({ field }) => !this.em.canPopulate(entityName, field));
47
47
  /* istanbul ignore next */
48
48
  if (options.validate && invalid) {
@@ -59,7 +59,7 @@ class EntityLoader {
59
59
  visited.delete(entity);
60
60
  }
61
61
  }
62
- normalizePopulate(entityName, populate, strategy, lookup = true) {
62
+ normalizePopulate(entityName, populate, strategy, lookup = true, exclude) {
63
63
  const meta = this.metadata.find(entityName);
64
64
  let normalized = Utils_1.Utils.asArray(populate).map(field => {
65
65
  return typeof field === 'boolean' || field.field === enums_1.PopulatePath.ALL ? { all: !!field, field: meta.primaryKeys[0] } : field;
@@ -70,7 +70,7 @@ class EntityLoader {
70
70
  // convert nested `field` with dot syntax to PopulateOptions with `children` array
71
71
  (0, utils_1.expandDotPaths)(meta, normalized, true);
72
72
  if (lookup && populate !== false) {
73
- normalized = this.lookupEagerLoadedRelationships(entityName, normalized, strategy);
73
+ normalized = this.lookupEagerLoadedRelationships(entityName, normalized, strategy, '', [], exclude);
74
74
  // convert nested `field` with dot syntax produced by eager relations
75
75
  (0, utils_1.expandDotPaths)(meta, normalized, true);
76
76
  }
@@ -572,7 +572,7 @@ class EntityLoader {
572
572
  }
573
573
  return `${this.getRelationName(meta, meta.properties[prop.embedded[0]])}.${prop.embedded[1]}`;
574
574
  }
575
- lookupEagerLoadedRelationships(entityName, populate, strategy, prefix = '', visited = []) {
575
+ lookupEagerLoadedRelationships(entityName, populate, strategy, prefix = '', visited = [], exclude) {
576
576
  const meta = this.metadata.find(entityName);
577
577
  if (!meta && !prefix) {
578
578
  return populate;
@@ -584,16 +584,19 @@ class EntityLoader {
584
584
  const ret = prefix === '' ? [...populate] : [];
585
585
  meta.relations
586
586
  .filter(prop => {
587
+ const field = this.getRelationName(meta, prop);
588
+ const prefixed = prefix ? `${prefix}.${field}` : field;
589
+ const isExcluded = exclude?.includes(prefixed);
587
590
  const eager = prop.eager && !populate.some(p => p.field === `${prop.name}:ref`);
588
591
  const populated = populate.some(p => p.field === prop.name);
589
592
  const disabled = populate.some(p => p.field === prop.name && p.all === false);
590
- return !disabled && (eager || populated);
593
+ return !disabled && !isExcluded && (eager || populated);
591
594
  })
592
595
  .forEach(prop => {
593
596
  const field = this.getRelationName(meta, prop);
594
597
  const prefixed = prefix ? `${prefix}.${field}` : field;
595
598
  const nestedPopulate = populate.filter(p => p.field === prop.name).flatMap(p => p.children).filter(Boolean);
596
- const nested = this.lookupEagerLoadedRelationships(prop.type, nestedPopulate, strategy, prefixed, visited.slice());
599
+ const nested = this.lookupEagerLoadedRelationships(prop.type, nestedPopulate, strategy, prefixed, visited.slice(), exclude);
597
600
  if (nested.length > 0) {
598
601
  ret.push(...nested);
599
602
  }
@@ -416,12 +416,13 @@ declare const propertyBuilders: {
416
416
  interval: () => UniversalPropertyOptionsBuilder<string, EmptyOptions, IncludeKeysForProperty>;
417
417
  unknown: () => UniversalPropertyOptionsBuilder<{}, EmptyOptions, IncludeKeysForProperty>;
418
418
  };
419
- export interface EntityMetadataWithProperties<TProperties extends Record<string, any>, TPK extends (keyof TProperties)[] | undefined = undefined, TBase = never> extends Omit<Partial<EntityMetadata<InferEntityFromProperties<TProperties, TPK>>>, 'properties' | 'extends' | 'primaryKeys' | 'hooks' | 'discriminatorColumn' | 'versionProperty' | 'concurrencyCheckKeys' | 'serializedPrimaryKey' | 'indexes' | 'uniques'> {
419
+ export interface EntityMetadataWithProperties<TProperties extends Record<string, any>, TPK extends (keyof TProperties)[] | undefined = undefined, TBase = never> extends Omit<Partial<EntityMetadata<InferEntityFromProperties<TProperties, TPK>>>, 'properties' | 'extends' | 'primaryKeys' | 'hooks' | 'discriminatorColumn' | 'versionProperty' | 'concurrencyCheckKeys' | 'serializedPrimaryKey' | 'indexes' | 'uniques' | 'repository'> {
420
420
  name: string;
421
421
  extends?: EntityName<TBase>;
422
422
  properties: TProperties | ((properties: typeof propertyBuilders) => TProperties);
423
423
  primaryKeys?: TPK & InferPrimaryKey<TProperties>[];
424
424
  hooks?: DefineEntityHooks<InferEntityFromProperties<TProperties, TPK>>;
425
+ repository?: (() => Constructor) | (() => unknown);
425
426
  discriminatorColumn?: keyof TProperties;
426
427
  versionProperty?: keyof TProperties;
427
428
  concurrencyCheckKeys?: Set<keyof TProperties>;
@@ -654,6 +654,12 @@ class MetadataDiscovery {
654
654
  prop2.inverseJoinColumns = prop.joinColumns;
655
655
  prop2.joinColumns = prop.inverseJoinColumns;
656
656
  }
657
+ // propagate updated joinColumns to all child entities that inherit this property (STI)
658
+ for (const childMeta of this.discovered.filter(m => m.root === meta && m !== meta)) {
659
+ const childProp = childMeta.properties[prop.name];
660
+ childProp.joinColumns = prop.joinColumns;
661
+ childProp.inverseJoinColumns = prop.inverseJoinColumns;
662
+ }
657
663
  }
658
664
  data.properties[meta.name + '_owner'] = this.definePivotProperty(prop, meta.name + '_owner', meta.className, targetType + '_inverse', true, meta.className === targetType);
659
665
  data.properties[targetType + '_inverse'] = this.definePivotProperty(prop, targetType + '_inverse', targetType, meta.name + '_owner', false, meta.className === targetType);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "6.6.6-dev.1",
3
+ "version": "6.6.6-dev.3",
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
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -64,7 +64,7 @@
64
64
  "esprima": "4.0.1",
65
65
  "fs-extra": "11.3.3",
66
66
  "globby": "11.1.0",
67
- "mikro-orm": "6.6.6-dev.1",
67
+ "mikro-orm": "6.6.6-dev.3",
68
68
  "reflect-metadata": "0.2.2"
69
69
  }
70
70
  }