metal-orm 1.0.12 → 1.0.13

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.
@@ -721,6 +721,20 @@ interface CommonTableExpressionNode {
721
721
  /** Whether the CTE is recursive */
722
722
  recursive: boolean;
723
723
  }
724
+ /**
725
+ * Supported set operation kinds for compound SELECT queries
726
+ */
727
+ type SetOperationKind = 'UNION' | 'UNION ALL' | 'INTERSECT' | 'EXCEPT';
728
+ /**
729
+ * AST node representing a set operation (UNION, INTERSECT, etc.)
730
+ */
731
+ interface SetOperationNode {
732
+ type: 'SetOperation';
733
+ /** Operator to combine queries */
734
+ operator: SetOperationKind;
735
+ /** Right-hand query in the compound expression */
736
+ query: SelectQueryNode;
737
+ }
724
738
  /**
725
739
  * AST node representing a complete SELECT query
726
740
  */
@@ -750,6 +764,8 @@ interface SelectQueryNode {
750
764
  meta?: QueryMetadata;
751
765
  /** Optional DISTINCT clause */
752
766
  distinct?: ColumnNode[];
767
+ /** Optional set operations chaining this query with others */
768
+ setOps?: SetOperationNode[];
753
769
  }
754
770
  interface InsertQueryNode {
755
771
  type: 'InsertQuery';
@@ -832,6 +848,7 @@ declare abstract class Dialect implements SelectCompiler, InsertCompiler, Update
832
848
  compileInsert(ast: InsertQueryNode): CompiledQuery;
833
849
  compileUpdate(ast: UpdateQueryNode): CompiledQuery;
834
850
  compileDelete(ast: DeleteQueryNode): CompiledQuery;
851
+ supportsReturning(): boolean;
835
852
  /**
836
853
  * Compiles SELECT query AST to SQL (to be implemented by concrete dialects)
837
854
  * @param ast - Query AST
@@ -877,6 +894,31 @@ declare abstract class Dialect implements SelectCompiler, InsertCompiler, Update
877
894
  * @returns Formatted placeholder string
878
895
  */
879
896
  protected formatPlaceholder(index: number): string;
897
+ /**
898
+ * Whether the current dialect supports a given set operation.
899
+ * Override in concrete dialects to restrict support.
900
+ */
901
+ protected supportsSetOperation(kind: SetOperationKind): boolean;
902
+ /**
903
+ * Validates set-operation semantics:
904
+ * - Ensures the dialect supports requested operators.
905
+ * - Enforces that only the outermost compound query may have ORDER/LIMIT/OFFSET.
906
+ * @param ast - Query to validate
907
+ * @param isOutermost - Whether this node is the outermost compound query
908
+ */
909
+ protected validateSetOperations(ast: SelectQueryNode, isOutermost?: boolean): void;
910
+ /**
911
+ * Hoists CTEs from set-operation operands to the outermost query so WITH appears once.
912
+ * @param ast - Query AST
913
+ * @returns Normalized AST without inner CTEs and a list of hoisted CTEs
914
+ */
915
+ private hoistCtes;
916
+ /**
917
+ * Normalizes a SELECT AST before compilation (validation + CTE hoisting).
918
+ * @param ast - Query AST
919
+ * @returns Normalized query AST
920
+ */
921
+ protected normalizeSelectAst(ast: SelectQueryNode): SelectQueryNode;
880
922
  private readonly expressionCompilers;
881
923
  private readonly operandCompilers;
882
924
  protected constructor();
@@ -999,6 +1041,12 @@ declare class SelectQueryState {
999
1041
  * @returns New SelectQueryState with CTE
1000
1042
  */
1001
1043
  withCte(cte: CommonTableExpressionNode): SelectQueryState;
1044
+ /**
1045
+ * Adds a set operation (UNION/INTERSECT/EXCEPT) to the query
1046
+ * @param op - Set operation node to add
1047
+ * @returns New SelectQueryState with set operation
1048
+ */
1049
+ withSetOperation(op: SetOperationNode): SelectQueryState;
1002
1050
  }
1003
1051
 
1004
1052
  /**
@@ -1101,6 +1149,31 @@ declare class HydrationManager {
1101
1149
  * @returns Hydration plan or undefined if none exists
1102
1150
  */
1103
1151
  getPlan(): HydrationPlan | undefined;
1152
+ /**
1153
+ * Attaches hydration metadata to a query AST node.
1154
+ */
1155
+ private attachHydrationMeta;
1156
+ /**
1157
+ * Determines whether the query needs pagination rewriting to keep LIMIT/OFFSET
1158
+ * applied to parent rows when eager-loading multiplicative relations.
1159
+ */
1160
+ private requiresParentPagination;
1161
+ private hasMultiplyingRelations;
1162
+ /**
1163
+ * Rewrites the query using CTEs so LIMIT/OFFSET target distinct parent rows
1164
+ * instead of the joined result set.
1165
+ *
1166
+ * The strategy:
1167
+ * - Hoist the original query (minus limit/offset) into a base CTE.
1168
+ * - Select distinct parent ids from that base CTE with the original ordering and pagination.
1169
+ * - Join the base CTE against the paged ids to retrieve the joined rows for just that page.
1170
+ */
1171
+ private wrapForParentPagination;
1172
+ private nextCteName;
1173
+ private getProjectionNames;
1174
+ private buildProjectionAliasMap;
1175
+ private mapOrderBy;
1176
+ private buildPagingColumns;
1104
1177
  }
1105
1178
 
1106
1179
  /**
@@ -1149,6 +1222,13 @@ declare class QueryAstService {
1149
1222
  * @returns Updated query state with CTE
1150
1223
  */
1151
1224
  withCte(name: string, query: SelectQueryNode, columns?: string[], recursive?: boolean): SelectQueryState;
1225
+ /**
1226
+ * Adds a set operation (UNION/UNION ALL/INTERSECT/EXCEPT) to the query
1227
+ * @param operator - Set operator
1228
+ * @param query - Right-hand side query
1229
+ * @returns Updated query state with set operation
1230
+ */
1231
+ withSetOperation(operator: SetOperationKind, query: SelectQueryNode): SelectQueryState;
1152
1232
  /**
1153
1233
  * Selects a subquery as a column
1154
1234
  * @param alias - Alias for the subquery
@@ -1408,6 +1488,12 @@ interface HasDomainEvents {
1408
1488
  type DomainEventHandler$1<Context> = (event: any, ctx: Context) => Promise<void> | void;
1409
1489
  declare const addDomainEvent: (entity: HasDomainEvents, event: any) => void;
1410
1490
 
1491
+ interface QueryLogEntry {
1492
+ sql: string;
1493
+ params?: unknown[];
1494
+ }
1495
+ type QueryLogger = (entry: QueryLogEntry) => void;
1496
+
1411
1497
  interface OrmInterceptor {
1412
1498
  beforeFlush?(ctx: OrmContext): Promise<void> | void;
1413
1499
  afterFlush?(ctx: OrmContext): Promise<void> | void;
@@ -1418,10 +1504,12 @@ interface OrmContextOptions {
1418
1504
  executor: DbExecutor;
1419
1505
  interceptors?: OrmInterceptor[];
1420
1506
  domainEventHandlers?: Record<string, DomainEventHandler[]>;
1507
+ queryLogger?: QueryLogger;
1421
1508
  }
1422
1509
  declare class OrmContext {
1423
1510
  private readonly options;
1424
1511
  private readonly identityMap;
1512
+ private readonly executorWithLogging;
1425
1513
  private readonly unitOfWork;
1426
1514
  private readonly relationChanges;
1427
1515
  private readonly interceptors;
@@ -1468,6 +1556,7 @@ declare class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
1468
1556
  private createChildBuilder;
1469
1557
  private applyAst;
1470
1558
  private applyJoin;
1559
+ private applySetOperation;
1471
1560
  /**
1472
1561
  * Selects specific columns for the query
1473
1562
  * @param columns - Record of column definitions, function nodes, case expressions, or window functions
@@ -1593,6 +1682,30 @@ declare class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
1593
1682
  * @returns New query builder instance with the OFFSET clause
1594
1683
  */
1595
1684
  offset(n: number): SelectQueryBuilder<T, TTable>;
1685
+ /**
1686
+ * Combines this query with another using UNION
1687
+ * @param query - Query to union with
1688
+ * @returns New query builder instance with the set operation
1689
+ */
1690
+ union(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable>;
1691
+ /**
1692
+ * Combines this query with another using UNION ALL
1693
+ * @param query - Query to union with
1694
+ * @returns New query builder instance with the set operation
1695
+ */
1696
+ unionAll(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable>;
1697
+ /**
1698
+ * Combines this query with another using INTERSECT
1699
+ * @param query - Query to intersect with
1700
+ * @returns New query builder instance with the set operation
1701
+ */
1702
+ intersect(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable>;
1703
+ /**
1704
+ * Combines this query with another using EXCEPT
1705
+ * @param query - Query to subtract
1706
+ * @returns New query builder instance with the set operation
1707
+ */
1708
+ except(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable>;
1596
1709
  /**
1597
1710
  * Adds a WHERE EXISTS condition to the query
1598
1711
  * @param subquery - Subquery to check for existence
@@ -1656,4 +1769,4 @@ declare const createColumn: (table: string, name: string) => ColumnNode;
1656
1769
  */
1657
1770
  declare const createLiteral: (val: string | number) => LiteralNode;
1658
1771
 
1659
- export { type RelationType as $, type CheckConstraint as A, type BinaryExpressionNode as B, type ColumnDef as C, type DeleteQueryNode as D, type ExpressionNode as E, type FunctionNode as F, type TableOptions as G, type HydrationPlan as H, type InExpressionNode as I, type JsonPathNode as J, type TableHooks as K, type LogicalExpressionNode as L, type ManyToManyCollection as M, type NullExpressionNode as N, type OperandNode as O, defineTable as P, type ColumnType as Q, type RelationMap as R, type SelectQueryNode as S, type TableDef as T, type UpdateQueryNode as U, type ReferentialAction as V, type WindowFunctionNode as W, type RawDefaultValue as X, type DefaultValue as Y, col as Z, RelationKinds as _, type ColumnNode as a, type CascadeMode as a0, type RelationDef as a1, hasMany as a2, belongsTo as a3, belongsToMany as a4, type ColumnToTs as a5, type InferRow as a6, createColumn as a7, createLiteral as a8, isOperandNode as a9, isFunctionNode as aa, isCaseExpressionNode as ab, isWindowFunctionNode as ac, isExpressionSelectionNode as ad, addDomainEvent as ae, EntityStatus as af, type QueryResult as ag, type RelationKey as ah, type RelationChange as ai, type HasDomainEvents as aj, type OrmInterceptor as ak, type DomainEventHandler as al, type OrmContextOptions as am, type LiteralNode as b, type BetweenExpressionNode as c, type CaseExpressionNode as d, type ExistsExpressionNode as e, type OrderDirection as f, type ScalarSubqueryNode as g, type InsertQueryNode as h, type InsertCompiler as i, type CompiledQuery as j, type UpdateCompiler as k, type DeleteCompiler as l, Dialect as m, type CompilerContext as n, type ForeignKeyReference as o, type IndexColumn as p, type IndexDef as q, type DbExecutor as r, OrmContext as s, type Entity as t, type HasManyRelation as u, type BelongsToRelation as v, type BelongsToManyRelation as w, type HasManyCollection as x, type BelongsToReference as y, SelectQueryBuilder as z };
1772
+ export { type RelationType as $, type CheckConstraint as A, type BinaryExpressionNode as B, type ColumnDef as C, type DeleteQueryNode as D, type ExpressionNode as E, type FunctionNode as F, type TableOptions as G, type HydrationPlan as H, type InExpressionNode as I, type JsonPathNode as J, type TableHooks as K, type LogicalExpressionNode as L, type ManyToManyCollection as M, type NullExpressionNode as N, type OperandNode as O, defineTable as P, type ColumnType as Q, type RelationMap as R, type SelectQueryNode as S, type TableDef as T, type UpdateQueryNode as U, type ReferentialAction as V, type WindowFunctionNode as W, type RawDefaultValue as X, type DefaultValue as Y, col as Z, RelationKinds as _, type ColumnNode as a, type CascadeMode as a0, type RelationDef as a1, hasMany as a2, belongsTo as a3, belongsToMany as a4, type ColumnToTs as a5, type InferRow as a6, createColumn as a7, createLiteral as a8, isOperandNode as a9, isFunctionNode as aa, isCaseExpressionNode as ab, isWindowFunctionNode as ac, isExpressionSelectionNode as ad, addDomainEvent as ae, EntityStatus as af, type QueryResult as ag, type RelationKey as ah, type RelationChange as ai, type HasDomainEvents as aj, type OrmInterceptor as ak, type DomainEventHandler as al, type OrmContextOptions as am, type QueryLogEntry as an, type QueryLogger as ao, type LiteralNode as b, type BetweenExpressionNode as c, type CaseExpressionNode as d, type ExistsExpressionNode as e, type OrderDirection as f, type ScalarSubqueryNode as g, type InsertQueryNode as h, type InsertCompiler as i, type CompiledQuery as j, type UpdateCompiler as k, type DeleteCompiler as l, Dialect as m, type CompilerContext as n, type ForeignKeyReference as o, type IndexColumn as p, type IndexDef as q, type DbExecutor as r, OrmContext as s, type Entity as t, type HasManyRelation as u, type BelongsToRelation as v, type BelongsToManyRelation as w, type HasManyCollection as x, type BelongsToReference as y, SelectQueryBuilder as z };
@@ -721,6 +721,20 @@ interface CommonTableExpressionNode {
721
721
  /** Whether the CTE is recursive */
722
722
  recursive: boolean;
723
723
  }
724
+ /**
725
+ * Supported set operation kinds for compound SELECT queries
726
+ */
727
+ type SetOperationKind = 'UNION' | 'UNION ALL' | 'INTERSECT' | 'EXCEPT';
728
+ /**
729
+ * AST node representing a set operation (UNION, INTERSECT, etc.)
730
+ */
731
+ interface SetOperationNode {
732
+ type: 'SetOperation';
733
+ /** Operator to combine queries */
734
+ operator: SetOperationKind;
735
+ /** Right-hand query in the compound expression */
736
+ query: SelectQueryNode;
737
+ }
724
738
  /**
725
739
  * AST node representing a complete SELECT query
726
740
  */
@@ -750,6 +764,8 @@ interface SelectQueryNode {
750
764
  meta?: QueryMetadata;
751
765
  /** Optional DISTINCT clause */
752
766
  distinct?: ColumnNode[];
767
+ /** Optional set operations chaining this query with others */
768
+ setOps?: SetOperationNode[];
753
769
  }
754
770
  interface InsertQueryNode {
755
771
  type: 'InsertQuery';
@@ -832,6 +848,7 @@ declare abstract class Dialect implements SelectCompiler, InsertCompiler, Update
832
848
  compileInsert(ast: InsertQueryNode): CompiledQuery;
833
849
  compileUpdate(ast: UpdateQueryNode): CompiledQuery;
834
850
  compileDelete(ast: DeleteQueryNode): CompiledQuery;
851
+ supportsReturning(): boolean;
835
852
  /**
836
853
  * Compiles SELECT query AST to SQL (to be implemented by concrete dialects)
837
854
  * @param ast - Query AST
@@ -877,6 +894,31 @@ declare abstract class Dialect implements SelectCompiler, InsertCompiler, Update
877
894
  * @returns Formatted placeholder string
878
895
  */
879
896
  protected formatPlaceholder(index: number): string;
897
+ /**
898
+ * Whether the current dialect supports a given set operation.
899
+ * Override in concrete dialects to restrict support.
900
+ */
901
+ protected supportsSetOperation(kind: SetOperationKind): boolean;
902
+ /**
903
+ * Validates set-operation semantics:
904
+ * - Ensures the dialect supports requested operators.
905
+ * - Enforces that only the outermost compound query may have ORDER/LIMIT/OFFSET.
906
+ * @param ast - Query to validate
907
+ * @param isOutermost - Whether this node is the outermost compound query
908
+ */
909
+ protected validateSetOperations(ast: SelectQueryNode, isOutermost?: boolean): void;
910
+ /**
911
+ * Hoists CTEs from set-operation operands to the outermost query so WITH appears once.
912
+ * @param ast - Query AST
913
+ * @returns Normalized AST without inner CTEs and a list of hoisted CTEs
914
+ */
915
+ private hoistCtes;
916
+ /**
917
+ * Normalizes a SELECT AST before compilation (validation + CTE hoisting).
918
+ * @param ast - Query AST
919
+ * @returns Normalized query AST
920
+ */
921
+ protected normalizeSelectAst(ast: SelectQueryNode): SelectQueryNode;
880
922
  private readonly expressionCompilers;
881
923
  private readonly operandCompilers;
882
924
  protected constructor();
@@ -999,6 +1041,12 @@ declare class SelectQueryState {
999
1041
  * @returns New SelectQueryState with CTE
1000
1042
  */
1001
1043
  withCte(cte: CommonTableExpressionNode): SelectQueryState;
1044
+ /**
1045
+ * Adds a set operation (UNION/INTERSECT/EXCEPT) to the query
1046
+ * @param op - Set operation node to add
1047
+ * @returns New SelectQueryState with set operation
1048
+ */
1049
+ withSetOperation(op: SetOperationNode): SelectQueryState;
1002
1050
  }
1003
1051
 
1004
1052
  /**
@@ -1101,6 +1149,31 @@ declare class HydrationManager {
1101
1149
  * @returns Hydration plan or undefined if none exists
1102
1150
  */
1103
1151
  getPlan(): HydrationPlan | undefined;
1152
+ /**
1153
+ * Attaches hydration metadata to a query AST node.
1154
+ */
1155
+ private attachHydrationMeta;
1156
+ /**
1157
+ * Determines whether the query needs pagination rewriting to keep LIMIT/OFFSET
1158
+ * applied to parent rows when eager-loading multiplicative relations.
1159
+ */
1160
+ private requiresParentPagination;
1161
+ private hasMultiplyingRelations;
1162
+ /**
1163
+ * Rewrites the query using CTEs so LIMIT/OFFSET target distinct parent rows
1164
+ * instead of the joined result set.
1165
+ *
1166
+ * The strategy:
1167
+ * - Hoist the original query (minus limit/offset) into a base CTE.
1168
+ * - Select distinct parent ids from that base CTE with the original ordering and pagination.
1169
+ * - Join the base CTE against the paged ids to retrieve the joined rows for just that page.
1170
+ */
1171
+ private wrapForParentPagination;
1172
+ private nextCteName;
1173
+ private getProjectionNames;
1174
+ private buildProjectionAliasMap;
1175
+ private mapOrderBy;
1176
+ private buildPagingColumns;
1104
1177
  }
1105
1178
 
1106
1179
  /**
@@ -1149,6 +1222,13 @@ declare class QueryAstService {
1149
1222
  * @returns Updated query state with CTE
1150
1223
  */
1151
1224
  withCte(name: string, query: SelectQueryNode, columns?: string[], recursive?: boolean): SelectQueryState;
1225
+ /**
1226
+ * Adds a set operation (UNION/UNION ALL/INTERSECT/EXCEPT) to the query
1227
+ * @param operator - Set operator
1228
+ * @param query - Right-hand side query
1229
+ * @returns Updated query state with set operation
1230
+ */
1231
+ withSetOperation(operator: SetOperationKind, query: SelectQueryNode): SelectQueryState;
1152
1232
  /**
1153
1233
  * Selects a subquery as a column
1154
1234
  * @param alias - Alias for the subquery
@@ -1408,6 +1488,12 @@ interface HasDomainEvents {
1408
1488
  type DomainEventHandler$1<Context> = (event: any, ctx: Context) => Promise<void> | void;
1409
1489
  declare const addDomainEvent: (entity: HasDomainEvents, event: any) => void;
1410
1490
 
1491
+ interface QueryLogEntry {
1492
+ sql: string;
1493
+ params?: unknown[];
1494
+ }
1495
+ type QueryLogger = (entry: QueryLogEntry) => void;
1496
+
1411
1497
  interface OrmInterceptor {
1412
1498
  beforeFlush?(ctx: OrmContext): Promise<void> | void;
1413
1499
  afterFlush?(ctx: OrmContext): Promise<void> | void;
@@ -1418,10 +1504,12 @@ interface OrmContextOptions {
1418
1504
  executor: DbExecutor;
1419
1505
  interceptors?: OrmInterceptor[];
1420
1506
  domainEventHandlers?: Record<string, DomainEventHandler[]>;
1507
+ queryLogger?: QueryLogger;
1421
1508
  }
1422
1509
  declare class OrmContext {
1423
1510
  private readonly options;
1424
1511
  private readonly identityMap;
1512
+ private readonly executorWithLogging;
1425
1513
  private readonly unitOfWork;
1426
1514
  private readonly relationChanges;
1427
1515
  private readonly interceptors;
@@ -1468,6 +1556,7 @@ declare class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
1468
1556
  private createChildBuilder;
1469
1557
  private applyAst;
1470
1558
  private applyJoin;
1559
+ private applySetOperation;
1471
1560
  /**
1472
1561
  * Selects specific columns for the query
1473
1562
  * @param columns - Record of column definitions, function nodes, case expressions, or window functions
@@ -1593,6 +1682,30 @@ declare class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
1593
1682
  * @returns New query builder instance with the OFFSET clause
1594
1683
  */
1595
1684
  offset(n: number): SelectQueryBuilder<T, TTable>;
1685
+ /**
1686
+ * Combines this query with another using UNION
1687
+ * @param query - Query to union with
1688
+ * @returns New query builder instance with the set operation
1689
+ */
1690
+ union(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable>;
1691
+ /**
1692
+ * Combines this query with another using UNION ALL
1693
+ * @param query - Query to union with
1694
+ * @returns New query builder instance with the set operation
1695
+ */
1696
+ unionAll(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable>;
1697
+ /**
1698
+ * Combines this query with another using INTERSECT
1699
+ * @param query - Query to intersect with
1700
+ * @returns New query builder instance with the set operation
1701
+ */
1702
+ intersect(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable>;
1703
+ /**
1704
+ * Combines this query with another using EXCEPT
1705
+ * @param query - Query to subtract
1706
+ * @returns New query builder instance with the set operation
1707
+ */
1708
+ except(query: SelectQueryBuilder<any, TableDef<any>> | SelectQueryNode): SelectQueryBuilder<T, TTable>;
1596
1709
  /**
1597
1710
  * Adds a WHERE EXISTS condition to the query
1598
1711
  * @param subquery - Subquery to check for existence
@@ -1656,4 +1769,4 @@ declare const createColumn: (table: string, name: string) => ColumnNode;
1656
1769
  */
1657
1770
  declare const createLiteral: (val: string | number) => LiteralNode;
1658
1771
 
1659
- export { type RelationType as $, type CheckConstraint as A, type BinaryExpressionNode as B, type ColumnDef as C, type DeleteQueryNode as D, type ExpressionNode as E, type FunctionNode as F, type TableOptions as G, type HydrationPlan as H, type InExpressionNode as I, type JsonPathNode as J, type TableHooks as K, type LogicalExpressionNode as L, type ManyToManyCollection as M, type NullExpressionNode as N, type OperandNode as O, defineTable as P, type ColumnType as Q, type RelationMap as R, type SelectQueryNode as S, type TableDef as T, type UpdateQueryNode as U, type ReferentialAction as V, type WindowFunctionNode as W, type RawDefaultValue as X, type DefaultValue as Y, col as Z, RelationKinds as _, type ColumnNode as a, type CascadeMode as a0, type RelationDef as a1, hasMany as a2, belongsTo as a3, belongsToMany as a4, type ColumnToTs as a5, type InferRow as a6, createColumn as a7, createLiteral as a8, isOperandNode as a9, isFunctionNode as aa, isCaseExpressionNode as ab, isWindowFunctionNode as ac, isExpressionSelectionNode as ad, addDomainEvent as ae, EntityStatus as af, type QueryResult as ag, type RelationKey as ah, type RelationChange as ai, type HasDomainEvents as aj, type OrmInterceptor as ak, type DomainEventHandler as al, type OrmContextOptions as am, type LiteralNode as b, type BetweenExpressionNode as c, type CaseExpressionNode as d, type ExistsExpressionNode as e, type OrderDirection as f, type ScalarSubqueryNode as g, type InsertQueryNode as h, type InsertCompiler as i, type CompiledQuery as j, type UpdateCompiler as k, type DeleteCompiler as l, Dialect as m, type CompilerContext as n, type ForeignKeyReference as o, type IndexColumn as p, type IndexDef as q, type DbExecutor as r, OrmContext as s, type Entity as t, type HasManyRelation as u, type BelongsToRelation as v, type BelongsToManyRelation as w, type HasManyCollection as x, type BelongsToReference as y, SelectQueryBuilder as z };
1772
+ export { type RelationType as $, type CheckConstraint as A, type BinaryExpressionNode as B, type ColumnDef as C, type DeleteQueryNode as D, type ExpressionNode as E, type FunctionNode as F, type TableOptions as G, type HydrationPlan as H, type InExpressionNode as I, type JsonPathNode as J, type TableHooks as K, type LogicalExpressionNode as L, type ManyToManyCollection as M, type NullExpressionNode as N, type OperandNode as O, defineTable as P, type ColumnType as Q, type RelationMap as R, type SelectQueryNode as S, type TableDef as T, type UpdateQueryNode as U, type ReferentialAction as V, type WindowFunctionNode as W, type RawDefaultValue as X, type DefaultValue as Y, col as Z, RelationKinds as _, type ColumnNode as a, type CascadeMode as a0, type RelationDef as a1, hasMany as a2, belongsTo as a3, belongsToMany as a4, type ColumnToTs as a5, type InferRow as a6, createColumn as a7, createLiteral as a8, isOperandNode as a9, isFunctionNode as aa, isCaseExpressionNode as ab, isWindowFunctionNode as ac, isExpressionSelectionNode as ad, addDomainEvent as ae, EntityStatus as af, type QueryResult as ag, type RelationKey as ah, type RelationChange as ai, type HasDomainEvents as aj, type OrmInterceptor as ak, type DomainEventHandler as al, type OrmContextOptions as am, type QueryLogEntry as an, type QueryLogger as ao, type LiteralNode as b, type BetweenExpressionNode as c, type CaseExpressionNode as d, type ExistsExpressionNode as e, type OrderDirection as f, type ScalarSubqueryNode as g, type InsertQueryNode as h, type InsertCompiler as i, type CompiledQuery as j, type UpdateCompiler as k, type DeleteCompiler as l, Dialect as m, type CompilerContext as n, type ForeignKeyReference as o, type IndexColumn as p, type IndexDef as q, type DbExecutor as r, OrmContext as s, type Entity as t, type HasManyRelation as u, type BelongsToRelation as v, type BelongsToManyRelation as w, type HasManyCollection as x, type BelongsToReference as y, SelectQueryBuilder as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metal-orm",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -21,7 +21,8 @@
21
21
  "build": "tsup",
22
22
  "check": "tsc --noEmit",
23
23
  "test": "vitest",
24
- "test:ui": "vitest --ui"
24
+ "test:ui": "vitest --ui",
25
+ "show-sql": "node scripts/show-sql.mjs"
25
26
  },
26
27
  "peerDependencies": {
27
28
  "mysql2": "^3.9.0",
@@ -94,23 +94,39 @@ export interface QueryMetadata {
94
94
  /**
95
95
  * AST node representing a Common Table Expression (CTE)
96
96
  */
97
- export interface CommonTableExpressionNode {
98
- type: 'CommonTableExpression';
99
- /** CTE name */
100
- name: string;
101
- /** Optional column names */
102
- columns?: string[];
103
- /** CTE query */
104
- query: SelectQueryNode;
105
- /** Whether the CTE is recursive */
106
- recursive: boolean;
107
- }
108
-
109
- /**
110
- * AST node representing a complete SELECT query
111
- */
112
- export interface SelectQueryNode {
113
- type: 'SelectQuery';
97
+ export interface CommonTableExpressionNode {
98
+ type: 'CommonTableExpression';
99
+ /** CTE name */
100
+ name: string;
101
+ /** Optional column names */
102
+ columns?: string[];
103
+ /** CTE query */
104
+ query: SelectQueryNode;
105
+ /** Whether the CTE is recursive */
106
+ recursive: boolean;
107
+ }
108
+
109
+ /**
110
+ * Supported set operation kinds for compound SELECT queries
111
+ */
112
+ export type SetOperationKind = 'UNION' | 'UNION ALL' | 'INTERSECT' | 'EXCEPT';
113
+
114
+ /**
115
+ * AST node representing a set operation (UNION, INTERSECT, etc.)
116
+ */
117
+ export interface SetOperationNode {
118
+ type: 'SetOperation';
119
+ /** Operator to combine queries */
120
+ operator: SetOperationKind;
121
+ /** Right-hand query in the compound expression */
122
+ query: SelectQueryNode;
123
+ }
124
+
125
+ /**
126
+ * AST node representing a complete SELECT query
127
+ */
128
+ export interface SelectQueryNode {
129
+ type: 'SelectQuery';
114
130
  /** Optional CTEs (WITH clauses) */
115
131
  ctes?: CommonTableExpressionNode[];
116
132
  /** FROM clause table */
@@ -131,11 +147,13 @@ export interface SelectQueryNode {
131
147
  limit?: number;
132
148
  /** Optional OFFSET clause */
133
149
  offset?: number;
134
- /** Optional query metadata */
135
- meta?: QueryMetadata;
136
- /** Optional DISTINCT clause */
137
- distinct?: ColumnNode[];
138
- }
150
+ /** Optional query metadata */
151
+ meta?: QueryMetadata;
152
+ /** Optional DISTINCT clause */
153
+ distinct?: ColumnNode[];
154
+ /** Optional set operations chaining this query with others */
155
+ setOps?: SetOperationNode[];
156
+ }
139
157
 
140
158
  export interface InsertQueryNode {
141
159
  type: 'InsertQuery';