@mikro-orm/sql 7.2.0-dev.0 → 7.2.0-dev.1
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.
- package/AbstractSqlDriver.d.ts +1 -1
- package/AbstractSqlDriver.js +3 -1
- package/AbstractSqlPlatform.d.ts +7 -0
- package/AbstractSqlPlatform.js +23 -2
- package/dialects/mysql/BaseMySqlPlatform.js +1 -1
- package/dialects/mysql/MySqlSchemaHelper.js +3 -2
- package/dialects/postgresql/PostgreSqlSchemaHelper.js +3 -1
- package/dialects/sqlite/SqliteSchemaHelper.js +1 -1
- package/package.json +4 -4
- package/query/QueryBuilder.d.ts +23 -15
- package/query/QueryBuilder.js +3 -1
package/AbstractSqlDriver.d.ts
CHANGED
|
@@ -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 ...)`.
|
package/AbstractSqlDriver.js
CHANGED
|
@@ -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
|
-
|
|
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/AbstractSqlPlatform.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { NativeQueryBuilder } from './query/NativeQueryBuilder.js';
|
|
|
6
6
|
/** Base class for SQL database platforms, providing SQL generation and quoting utilities. */
|
|
7
7
|
export declare abstract class AbstractSqlPlatform extends Platform {
|
|
8
8
|
#private;
|
|
9
|
+
private static readonly ORDER_BY_DIRECTIONS;
|
|
9
10
|
protected readonly schemaHelper?: SchemaHelper;
|
|
10
11
|
usesPivotTable(): boolean;
|
|
11
12
|
indexForeignKeys(): boolean;
|
|
@@ -46,6 +47,12 @@ export declare abstract class AbstractSqlPlatform extends Platform {
|
|
|
46
47
|
* @internal
|
|
47
48
|
*/
|
|
48
49
|
getOrderByExpression(column: string, direction: string, collation?: string): string[];
|
|
50
|
+
/**
|
|
51
|
+
* `toLowerCase()` folds every `QueryOrder` enum member (and the normalized `QueryOrderNumeric`
|
|
52
|
+
* values) onto the six allow-listed directions, so only unknown values are rejected.
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
validateOrderByDirection(direction: string): string;
|
|
49
56
|
/**
|
|
50
57
|
* Quotes a collation name for use in COLLATE clauses.
|
|
51
58
|
* @internal
|
package/AbstractSqlPlatform.js
CHANGED
|
@@ -5,6 +5,14 @@ import { NativeQueryBuilder } from './query/NativeQueryBuilder.js';
|
|
|
5
5
|
/** Base class for SQL database platforms, providing SQL generation and quoting utilities. */
|
|
6
6
|
export class AbstractSqlPlatform extends Platform {
|
|
7
7
|
static #JSON_PROPERTY_NAME_RE = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
8
|
+
static ORDER_BY_DIRECTIONS = new Set([
|
|
9
|
+
'asc',
|
|
10
|
+
'desc',
|
|
11
|
+
'asc nulls first',
|
|
12
|
+
'asc nulls last',
|
|
13
|
+
'desc nulls first',
|
|
14
|
+
'desc nulls last',
|
|
15
|
+
]);
|
|
8
16
|
schemaHelper;
|
|
9
17
|
usesPivotTable() {
|
|
10
18
|
return true;
|
|
@@ -115,10 +123,23 @@ export class AbstractSqlPlatform extends Platform {
|
|
|
115
123
|
* @internal
|
|
116
124
|
*/
|
|
117
125
|
getOrderByExpression(column, direction, collation) {
|
|
126
|
+
const dir = this.validateOrderByDirection(direction);
|
|
118
127
|
if (collation) {
|
|
119
|
-
return [`${column} collate ${this.quoteCollation(collation)} ${
|
|
128
|
+
return [`${column} collate ${this.quoteCollation(collation)} ${dir}`];
|
|
120
129
|
}
|
|
121
|
-
return [`${column} ${
|
|
130
|
+
return [`${column} ${dir}`];
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* `toLowerCase()` folds every `QueryOrder` enum member (and the normalized `QueryOrderNumeric`
|
|
134
|
+
* values) onto the six allow-listed directions, so only unknown values are rejected.
|
|
135
|
+
* @internal
|
|
136
|
+
*/
|
|
137
|
+
validateOrderByDirection(direction) {
|
|
138
|
+
const dir = ('' + direction).toLowerCase().trim();
|
|
139
|
+
if (!AbstractSqlPlatform.ORDER_BY_DIRECTIONS.has(dir)) {
|
|
140
|
+
throw new Error(`Invalid order direction: '${direction}'`);
|
|
141
|
+
}
|
|
142
|
+
return dir;
|
|
122
143
|
}
|
|
123
144
|
/**
|
|
124
145
|
* Quotes a collation name for use in COLLATE clauses.
|
|
@@ -114,7 +114,7 @@ export class BaseMySqlPlatform extends AbstractSqlPlatform {
|
|
|
114
114
|
}
|
|
115
115
|
getOrderByExpression(column, direction, collation) {
|
|
116
116
|
const ret = [];
|
|
117
|
-
const dir =
|
|
117
|
+
const dir = this.validateOrderByDirection(direction);
|
|
118
118
|
const col = collation ? `${column} collate ${this.quoteCollation(collation)}` : column;
|
|
119
119
|
if (dir in this.ORDER_BY_NULLS_TRANSLATE) {
|
|
120
120
|
ret.push(`${col} ${this.ORDER_BY_NULLS_TRANSLATE[dir]}`);
|
|
@@ -54,10 +54,10 @@ export class MySqlSchemaHelper extends SchemaHelper {
|
|
|
54
54
|
return sql;
|
|
55
55
|
}
|
|
56
56
|
getListTablesSQL() {
|
|
57
|
-
return `select table_name as table_name, nullif(table_schema, schema()) as schema_name, table_comment as table_comment, table_collation as table_collation from information_schema.tables where table_type = 'BASE TABLE' and table_schema = schema()`;
|
|
57
|
+
return `select table_name as table_name, nullif(table_schema, schema()) as schema_name, table_comment as table_comment, table_collation as table_collation from information_schema.tables where table_type = 'BASE TABLE' and table_schema = schema() order by table_name`;
|
|
58
58
|
}
|
|
59
59
|
getListViewsSQL() {
|
|
60
|
-
return `select table_name as view_name, nullif(table_schema, schema()) as schema_name, view_definition from information_schema.views where table_schema = schema()`;
|
|
60
|
+
return `select table_name as view_name, nullif(table_schema, schema()) as schema_name, view_definition from information_schema.views where table_schema = schema() order by table_name`;
|
|
61
61
|
}
|
|
62
62
|
async loadViews(schema, connection, schemaName, ctx) {
|
|
63
63
|
const views = await connection.execute(this.getListViewsSQL(), [], 'all', ctx);
|
|
@@ -372,6 +372,7 @@ export class MySqlSchemaHelper extends SchemaHelper {
|
|
|
372
372
|
from information_schema.routines r
|
|
373
373
|
where r.routine_schema = database()
|
|
374
374
|
and r.routine_type in ('PROCEDURE', 'FUNCTION')
|
|
375
|
+
order by r.routine_name
|
|
375
376
|
`;
|
|
376
377
|
const [rows, params] = await Promise.all([
|
|
377
378
|
connection.execute(sql),
|
|
@@ -579,6 +579,7 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
|
|
|
579
579
|
)
|
|
580
580
|
-- exclude trigger-helper functions; they're managed alongside their owning trigger.
|
|
581
581
|
and p.prorettype <> 'trigger'::regtype
|
|
582
|
+
order by n.nspname, p.proname
|
|
582
583
|
`;
|
|
583
584
|
const rows = await connection.execute(sql);
|
|
584
585
|
return rows.map(row => {
|
|
@@ -775,7 +776,8 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
|
|
|
775
776
|
left join pg_enum e on t.oid = e.enumtypid
|
|
776
777
|
join pg_catalog.pg_namespace n on n.oid = t.typnamespace
|
|
777
778
|
where t.typtype = 'e' and n.nspname in (${Array(uniqueSchemas.length).fill('?').join(', ')})
|
|
778
|
-
group by t.typname, n.nspname
|
|
779
|
+
group by t.typname, n.nspname
|
|
780
|
+
order by n.nspname, t.typname`, uniqueSchemas, 'all', ctx);
|
|
779
781
|
return res.reduce((o, row) => {
|
|
780
782
|
let name = row.enum_name;
|
|
781
783
|
if (row.schema_name && row.schema_name !== this.platform.getDefaultSchemaName()) {
|
|
@@ -52,7 +52,7 @@ export class SqliteSchemaHelper extends SchemaHelper {
|
|
|
52
52
|
for (const dbName of targetSchemas) {
|
|
53
53
|
const prefix = this.getSchemaPrefix(dbName);
|
|
54
54
|
const tables = await connection.execute(`select name from ${prefix}sqlite_master where type = 'table' ` +
|
|
55
|
-
`and name != 'sqlite_sequence' and name != 'geometry_columns' and name != 'spatial_ref_sys'`, [], 'all', ctx);
|
|
55
|
+
`and name != 'sqlite_sequence' and name != 'geometry_columns' and name != 'spatial_ref_sys' order by name`, [], 'all', ctx);
|
|
56
56
|
for (const t of tables) {
|
|
57
57
|
allTables.push({ table_name: t.name, schema_name: dbName });
|
|
58
58
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/sql",
|
|
3
|
-
"version": "7.2.0-dev.
|
|
3
|
+
"version": "7.2.0-dev.1",
|
|
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",
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
"copy": "node ../../scripts/copy.mjs"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"kysely": "0.29.
|
|
50
|
+
"kysely": "0.29.4"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@mikro-orm/core": "^7.1.
|
|
53
|
+
"@mikro-orm/core": "^7.1.7"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@mikro-orm/core": "7.2.0-dev.
|
|
56
|
+
"@mikro-orm/core": "7.2.0-dev.1"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
59
|
"node": ">= 22.17.0"
|
package/query/QueryBuilder.d.ts
CHANGED
|
@@ -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>}.*`) | '*' |
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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:
|
|
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,
|
|
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
|
|
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
|
|
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.
|
package/query/QueryBuilder.js
CHANGED
|
@@ -782,7 +782,9 @@ export class QueryBuilder {
|
|
|
782
782
|
this.fromRawTable(target, aliasName);
|
|
783
783
|
}
|
|
784
784
|
else {
|
|
785
|
-
if (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);
|