@mikro-orm/sql 7.1.8-dev.5 → 7.1.8-dev.7

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.
@@ -168,7 +168,7 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
168
168
  protected extractManyToMany<T>(meta: EntityMetadata<T>, data: EntityDictionary<T>): EntityData<T>;
169
169
  protected processManyToMany<T extends object>(meta: EntityMetadata<T>, pks: Primary<T>[], collections: EntityData<T>, clear: boolean, options?: DriverMethodOptions): Promise<void>;
170
170
  lockPessimistic<T extends object>(entity: T, options: LockOptions): Promise<void>;
171
- protected buildPopulateWhere<T extends object>(meta: EntityMetadata<T>, joinedProps: PopulateOptions<T>[], options: Pick<FindOptions<any>, 'populateWhere'>): ObjectQuery<T>;
171
+ protected buildPopulateWhere<T extends object>(meta: EntityMetadata<T>, joinedProps: PopulateOptions<T>[], options: Pick<FindOptions<any>, 'populateWhere' | 'strategy'>): ObjectQuery<T>;
172
172
  /**
173
173
  * Builds a UNION ALL (or UNION) subquery from `unionWhere` branches and merges it
174
174
  * into the main WHERE as `pk IN (branch_1 UNION ALL branch_2 ...)`.
@@ -2124,7 +2124,9 @@ export class AbstractSqlDriver extends DatabaseDriver {
2124
2124
  if (hint.children) {
2125
2125
  const targetMeta = prop.targetMeta;
2126
2126
  if (targetMeta) {
2127
- const inner = this.buildPopulateWhere(targetMeta, hint.children, {});
2127
+ // only joined children contribute to the ON conditions, the rest is handled by the entity loader
2128
+ const children = this.joinedProps(targetMeta, hint.children, options);
2129
+ const inner = this.buildPopulateWhere(targetMeta, children, { strategy: options.strategy });
2128
2130
  if (!Utils.isEmpty(inner) || RawQueryFragment.hasObjectFragments(inner)) {
2129
2131
  where[prop.name] ??= {};
2130
2132
  Object.assign(where[prop.name], inner);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/sql",
3
- "version": "7.1.8-dev.5",
3
+ "version": "7.1.8-dev.7",
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",
@@ -53,7 +53,7 @@
53
53
  "@mikro-orm/core": "^7.1.7"
54
54
  },
55
55
  "peerDependencies": {
56
- "@mikro-orm/core": "7.1.8-dev.5"
56
+ "@mikro-orm/core": "7.1.8-dev.7"
57
57
  },
58
58
  "engines": {
59
59
  "node": ">= 22.17.0"
@@ -52,6 +52,12 @@ type IsNever<T, True = true, False = false> = [T] extends [never] ? True : False
52
52
  type GetAlias<T extends string> = T extends `${infer A}.${string}` ? A : never;
53
53
  type GetPropName<T extends string> = T extends `${string}.${infer P}` ? P : T;
54
54
  type AppendToHint<Parent extends string, Child extends string> = `${Parent}.${Child}`;
55
+ /**
56
+ * Extracts the entity type from a query builder via its main alias. Matching against
57
+ * `QueryBuilder<infer T>` is unreliable once another generic, such as selected fields,
58
+ * differs from its default.
59
+ */
60
+ type QueryBuilderEntity<Q extends QueryBuilder<any>> = Q['mainAlias'] extends Alias<infer T extends object> ? T : object;
55
61
  /**
56
62
  * Context tuple format: [Path, Alias, Type, Select]
57
63
  * - Path: The relation path from root entity (e.g., 'books', 'books.author')
@@ -85,7 +91,7 @@ type ContextRelationKeys<Context> = Context[keyof Context] extends infer Join ?
85
91
  export type QBField<Entity, RootAlias extends string, Context> = EntityRelations<Entity> | `${RootAlias}.${EntityRelations<Entity>}` | ([Context] extends [never] ? never : ContextRelationKeys<Context>);
86
92
  type ContextFieldKeys<Context> = Context[keyof Context] extends infer Join ? Join extends any ? Join extends [string, infer Alias, infer Type, any] ? `${Alias & string}.${keyof Type & string}` : never : never : never;
87
93
  type WithAlias<T extends string> = T | `${T} as ${string}`;
88
- export type Field<Entity, RootAlias extends string = never, Context = never> = WithAlias<EntityKey<Entity>> | (IsNever<RootAlias> extends true ? never : WithAlias<`${RootAlias}.${EntityKey<Entity>}`> | `${RootAlias}.*`) | ([Context] extends [never] ? never : WithAlias<ContextFieldKeys<Context>> | `${AliasNames<Context>}.*`) | '*' | QueryBuilder<any> | NativeQueryBuilder | RawQueryFragment<any> | (RawQueryFragment & symbol);
94
+ export type Field<Entity, RootAlias extends string = never, Context = never> = WithAlias<EntityKey<Entity>> | (IsNever<RootAlias> extends true ? never : WithAlias<`${RootAlias}.${EntityKey<Entity>}`> | `${RootAlias}.*`) | ([Context] extends [never] ? never : WithAlias<ContextFieldKeys<Context>> | `${AliasNames<Context>}.*`) | '*' | AnyQueryBuilder | NativeQueryBuilder | RawQueryFragment<any> | (RawQueryFragment & symbol);
89
95
  type RootAliasOrderKeys<RootAlias extends string, Entity> = {
90
96
  [K in `${RootAlias}.${EntityKey<Entity>}`]?: QueryOrderKeysFlat;
91
97
  };
@@ -432,29 +438,29 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
432
438
  * .where({ 'a.name': 'John' });
433
439
  * ```
434
440
  */
435
- join<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field, alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, type?: JoinType, path?: string, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field> & {}, ModifyContext<Entity, Context, Field, Alias>, RawAliases, '*', CTEs>;
441
+ join<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field, alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, type?: JoinType, path?: string, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field> & {}, ModifyContext<Entity, Context, Field, Alias>, RawAliases, Fields, CTEs>;
436
442
  /**
437
443
  * Adds a JOIN clause to the query for a subquery.
438
444
  */
439
- join<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, type?: JoinType, path?: string, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
445
+ join<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, type?: JoinType, path?: string, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, Fields, CTEs>;
440
446
  /**
441
447
  * Adds an INNER JOIN clause to the query for an entity relation.
442
448
  */
443
- innerJoin<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field, alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field> & {}, ModifyContext<Entity, Context, Field, Alias>, RawAliases, '*', CTEs>;
449
+ innerJoin<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field, alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field> & {}, ModifyContext<Entity, Context, Field, Alias>, RawAliases, Fields, CTEs>;
444
450
  /**
445
451
  * Adds an INNER JOIN clause to the query for a subquery.
446
452
  */
447
- innerJoin<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
448
- innerJoinLateral<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
453
+ innerJoin<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, Fields, CTEs>;
454
+ innerJoinLateral<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, Fields, CTEs>;
449
455
  /**
450
456
  * Adds a LEFT JOIN clause to the query for an entity relation.
451
457
  */
452
- leftJoin<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field, alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field> & {}, ModifyContext<Entity, Context, Field, Alias>, RawAliases, '*', CTEs>;
458
+ leftJoin<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field, alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field> & {}, ModifyContext<Entity, Context, Field, Alias>, RawAliases, Fields, CTEs>;
453
459
  /**
454
460
  * Adds a LEFT JOIN clause to the query for a subquery.
455
461
  */
456
- leftJoin<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
457
- leftJoinLateral<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
462
+ leftJoin<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, Fields, CTEs>;
463
+ leftJoinLateral<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, Fields, CTEs>;
458
464
  /**
459
465
  * Adds a JOIN clause and automatically selects the joined entity's fields.
460
466
  * This is useful for eager loading related entities.
@@ -723,7 +729,9 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
723
729
  * Specifies FROM which entity's table select/update/delete will be executed, removing all previously set FROM-s.
724
730
  * Allows setting a main string alias of the selection data.
725
731
  */
726
- from<Entity extends object>(target: QueryBuilder<Entity>, aliasName?: string): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
732
+ from<Entity extends object>(target: Subquery & {
733
+ readonly mainAlias: Alias<Entity>;
734
+ }, aliasName?: string): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
727
735
  /**
728
736
  * Specifies FROM which entity's table select/update/delete will be executed, removing all previously set FROM-s.
729
737
  * Allows setting a main string alias of the selection data.
@@ -733,7 +741,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
733
741
  * Specifies a CTE name as the FROM source, with full type safety.
734
742
  * The entity type is inferred from the CTE definition passed to `.with()`.
735
743
  */
736
- from<Name extends string & keyof CTEs, Alias extends string = Name>(target: Name, aliasName?: Alias): SelectQueryBuilder<CTEs[Name], Alias, never, never, never, '*', CTEs>;
744
+ from<Name extends string & keyof CTEs, Alias extends string = Name>(target: Name, aliasName?: Alias): SelectQueryBuilder<CTEs[Name], Alias, never, never, never, Fields, CTEs>;
737
745
  getNativeQuery(processVirtualEntity?: boolean): NativeQueryBuilder;
738
746
  protected processReturningStatement(qb: NativeQueryBuilder, meta?: EntityMetadata, data?: Dictionary, returning?: Field<any>[]): void;
739
747
  /**
@@ -849,7 +857,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
849
857
  * const results = await em.find(Employee, { id: { $in: subquery } });
850
858
  * ```
851
859
  */
852
- unionAll(...others: (QueryBuilder<any> | NativeQueryBuilder)[]): QueryBuilder<Entity>;
860
+ unionAll(...others: (QueryBuilder<any> | NativeQueryBuilder)[]): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
853
861
  /**
854
862
  * Combines the current query with one or more other queries using `UNION` (with deduplication).
855
863
  * All queries must select the same columns. Returns a `QueryBuilder` that
@@ -864,7 +872,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
864
872
  * const results = await em.find(Employee, { id: { $in: subquery } });
865
873
  * ```
866
874
  */
867
- union(...others: (QueryBuilder<any> | NativeQueryBuilder)[]): QueryBuilder<Entity>;
875
+ union(...others: (QueryBuilder<any> | NativeQueryBuilder)[]): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
868
876
  private buildUnionQuery;
869
877
  /**
870
878
  * Adds a Common Table Expression (CTE) to the query.
@@ -879,7 +887,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
879
887
  * .from('recent_books', 'rb'); // entity type inferred as Book
880
888
  * ```
881
889
  */
882
- with<Name extends string, Q extends QueryBuilder<any>>(name: Name, query: Q, options?: CteOptions): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs & Record<Name, Q extends QueryBuilder<infer T> ? T : object>>;
890
+ with<Name extends string, Q extends QueryBuilder<any>>(name: Name, query: Q, options?: CteOptions): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs & Record<Name, QueryBuilderEntity<Q>>>;
883
891
  /**
884
892
  * Adds a Common Table Expression (CTE) to the query using a `NativeQueryBuilder` or raw SQL fragment.
885
893
  * The CTE name is tracked but without entity type inference — use `from()` to query from it.
@@ -900,7 +908,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
900
908
  * .from('category_tree', 'ct'); // entity type inferred as Category
901
909
  * ```
902
910
  */
903
- withRecursive<Name extends string, Q extends QueryBuilder<any>>(name: Name, query: Q, options?: CteOptions): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs & Record<Name, Q extends QueryBuilder<infer T> ? T : object>>;
911
+ withRecursive<Name extends string, Q extends QueryBuilder<any>>(name: Name, query: Q, options?: CteOptions): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs & Record<Name, QueryBuilderEntity<Q>>>;
904
912
  /**
905
913
  * Adds a recursive Common Table Expression (CTE) to the query using a `NativeQueryBuilder` or raw SQL fragment.
906
914
  * The CTE name is tracked but without entity type inference — use `from()` to query from it.
@@ -782,7 +782,9 @@ export class QueryBuilder {
782
782
  this.fromRawTable(target, aliasName);
783
783
  }
784
784
  else {
785
- if (aliasName && this.#state.mainAlias && Utils.className(target) !== this.#state.mainAlias.aliasName) {
785
+ if (aliasName &&
786
+ this.#state.mainAlias &&
787
+ Utils.className(target) !== this.#state.mainAlias.aliasName) {
786
788
  throw new Error(`Cannot override the alias to '${aliasName}' since a query already contains references to '${this.#state.mainAlias.aliasName}'`);
787
789
  }
788
790
  this.fromEntityName(target, aliasName);