metal-orm 1.0.38 → 1.0.40

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.
@@ -1,79 +1,86 @@
1
- import { TableDef } from '../schema/table.js';
2
- import { SelectQueryNode, CommonTableExpressionNode, OrderByNode, SetOperationNode, TableSourceNode } from '../core/ast/query.js';
3
- import {
4
- ColumnNode,
5
- ExpressionNode,
6
- FunctionNode,
7
- ScalarSubqueryNode,
8
- CaseExpressionNode,
9
- WindowFunctionNode
10
- } from '../core/ast/expression.js';
11
- import { JoinNode } from '../core/ast/join.js';
12
-
13
- /**
14
- * Node types that can be used in query projections
15
- */
16
- export type ProjectionNode =
17
- | ColumnNode
18
- | FunctionNode
19
- | ScalarSubqueryNode
20
- | CaseExpressionNode
21
- | WindowFunctionNode;
22
-
23
- /**
24
- * Manages the state of a SELECT query being built
25
- */
26
- export class SelectQueryState {
27
- /**
28
- * Table definition for the query
29
- */
30
- public readonly table: TableDef;
31
- /**
32
- * Abstract Syntax Tree (AST) representation of the query
33
- */
34
- public readonly ast: SelectQueryNode;
35
-
36
- /**
37
- * Creates a new SelectQueryState instance
38
- * @param table - Table definition
39
- * @param ast - Optional existing AST
40
- */
41
- constructor(table: TableDef, ast?: SelectQueryNode) {
42
- this.table = table;
43
- this.ast = ast ?? {
44
- type: 'SelectQuery',
45
- from: { type: 'Table', name: table.name },
46
- columns: [],
47
- joins: []
48
- };
49
- }
50
-
51
- /**
52
- * Creates a new SelectQueryState with updated AST
53
- * @param nextAst - Updated AST
54
- * @returns New SelectQueryState instance
55
- */
56
- private clone(nextAst: SelectQueryNode): SelectQueryState {
57
- return new SelectQueryState(this.table, nextAst);
58
- }
59
-
60
- /**
61
- * Adds columns to the query
62
- * @param newCols - Columns to add
63
- * @returns New SelectQueryState with added columns
64
- */
65
- withColumns(newCols: ProjectionNode[]): SelectQueryState {
66
- return this.clone({
67
- ...this.ast,
68
- columns: [...(this.ast.columns ?? []), ...newCols]
69
- });
70
- }
71
-
72
- /**
73
- * Adds a join to the query
74
- * @param join - Join node to add
75
- * @returns New SelectQueryState with added join
76
- */
1
+ import { TableDef } from '../schema/table.js';
2
+ import {
3
+ SelectQueryNode,
4
+ CommonTableExpressionNode,
5
+ OrderByNode,
6
+ SetOperationNode,
7
+ TableSourceNode,
8
+ OrderingTerm
9
+ } from '../core/ast/query.js';
10
+ import {
11
+ ColumnNode,
12
+ ExpressionNode,
13
+ FunctionNode,
14
+ ScalarSubqueryNode,
15
+ CaseExpressionNode,
16
+ WindowFunctionNode
17
+ } from '../core/ast/expression.js';
18
+ import { JoinNode } from '../core/ast/join.js';
19
+
20
+ /**
21
+ * Node types that can be used in query projections
22
+ */
23
+ export type ProjectionNode =
24
+ | ColumnNode
25
+ | FunctionNode
26
+ | ScalarSubqueryNode
27
+ | CaseExpressionNode
28
+ | WindowFunctionNode;
29
+
30
+ /**
31
+ * Manages the state of a SELECT query being built
32
+ */
33
+ export class SelectQueryState {
34
+ /**
35
+ * Table definition for the query
36
+ */
37
+ public readonly table: TableDef;
38
+ /**
39
+ * Abstract Syntax Tree (AST) representation of the query
40
+ */
41
+ public readonly ast: SelectQueryNode;
42
+
43
+ /**
44
+ * Creates a new SelectQueryState instance
45
+ * @param table - Table definition
46
+ * @param ast - Optional existing AST
47
+ */
48
+ constructor(table: TableDef, ast?: SelectQueryNode) {
49
+ this.table = table;
50
+ this.ast = ast ?? {
51
+ type: 'SelectQuery',
52
+ from: { type: 'Table', name: table.name },
53
+ columns: [],
54
+ joins: []
55
+ };
56
+ }
57
+
58
+ /**
59
+ * Creates a new SelectQueryState with updated AST
60
+ * @param nextAst - Updated AST
61
+ * @returns New SelectQueryState instance
62
+ */
63
+ private clone(nextAst: SelectQueryNode): SelectQueryState {
64
+ return new SelectQueryState(this.table, nextAst);
65
+ }
66
+
67
+ /**
68
+ * Adds columns to the query
69
+ * @param newCols - Columns to add
70
+ * @returns New SelectQueryState with added columns
71
+ */
72
+ withColumns(newCols: ProjectionNode[]): SelectQueryState {
73
+ return this.clone({
74
+ ...this.ast,
75
+ columns: [...(this.ast.columns ?? []), ...newCols]
76
+ });
77
+ }
78
+
79
+ /**
80
+ * Adds a join to the query
81
+ * @param join - Join node to add
82
+ * @returns New SelectQueryState with added join
83
+ */
77
84
  withJoin(join: JoinNode): SelectQueryState {
78
85
  return this.clone({
79
86
  ...this.ast,
@@ -92,92 +99,92 @@ export class SelectQueryState {
92
99
  from
93
100
  });
94
101
  }
95
-
96
- /**
97
- * Adds a WHERE clause to the query
98
- * @param predicate - WHERE predicate expression
99
- * @returns New SelectQueryState with WHERE clause
100
- */
101
- withWhere(predicate: ExpressionNode): SelectQueryState {
102
- return this.clone({
103
- ...this.ast,
104
- where: predicate
105
- });
106
- }
107
-
108
- /**
109
- * Adds a HAVING clause to the query
110
- * @param predicate - HAVING predicate expression
111
- * @returns New SelectQueryState with HAVING clause
112
- */
113
- withHaving(predicate: ExpressionNode): SelectQueryState {
114
- return this.clone({
115
- ...this.ast,
116
- having: predicate
117
- });
118
- }
119
-
120
- /**
121
- * Adds GROUP BY columns to the query
122
- * @param columns - Columns to group by
123
- * @returns New SelectQueryState with GROUP BY clause
124
- */
125
- withGroupBy(columns: ColumnNode[]): SelectQueryState {
126
- return this.clone({
127
- ...this.ast,
128
- groupBy: [...(this.ast.groupBy ?? []), ...columns]
129
- });
130
- }
131
-
132
- /**
133
- * Adds ORDER BY clauses to the query
134
- * @param orderBy - ORDER BY nodes
135
- * @returns New SelectQueryState with ORDER BY clause
136
- */
137
- withOrderBy(orderBy: OrderByNode[]): SelectQueryState {
138
- return this.clone({
139
- ...this.ast,
140
- orderBy: [...(this.ast.orderBy ?? []), ...orderBy]
141
- });
142
- }
143
-
144
- /**
145
- * Adds DISTINCT columns to the query
146
- * @param columns - Columns to make distinct
147
- * @returns New SelectQueryState with DISTINCT clause
148
- */
149
- withDistinct(columns: ColumnNode[]): SelectQueryState {
150
- return this.clone({
151
- ...this.ast,
152
- distinct: [...(this.ast.distinct ?? []), ...columns]
153
- });
154
- }
155
-
156
- /**
157
- * Adds a LIMIT clause to the query
158
- * @param limit - Maximum number of rows to return
159
- * @returns New SelectQueryState with LIMIT clause
160
- */
161
- withLimit(limit: number): SelectQueryState {
162
- return this.clone({
163
- ...this.ast,
164
- limit
165
- });
166
- }
167
-
168
- /**
169
- * Adds an OFFSET clause to the query
170
- * @param offset - Number of rows to skip
171
- * @returns New SelectQueryState with OFFSET clause
172
- */
173
- withOffset(offset: number): SelectQueryState {
174
- return this.clone({
175
- ...this.ast,
176
- offset
177
- });
178
- }
179
-
180
- /**
102
+
103
+ /**
104
+ * Adds a WHERE clause to the query
105
+ * @param predicate - WHERE predicate expression
106
+ * @returns New SelectQueryState with WHERE clause
107
+ */
108
+ withWhere(predicate: ExpressionNode): SelectQueryState {
109
+ return this.clone({
110
+ ...this.ast,
111
+ where: predicate
112
+ });
113
+ }
114
+
115
+ /**
116
+ * Adds a HAVING clause to the query
117
+ * @param predicate - HAVING predicate expression
118
+ * @returns New SelectQueryState with HAVING clause
119
+ */
120
+ withHaving(predicate: ExpressionNode): SelectQueryState {
121
+ return this.clone({
122
+ ...this.ast,
123
+ having: predicate
124
+ });
125
+ }
126
+
127
+ /**
128
+ * Adds GROUP BY columns to the query
129
+ * @param columns - Terms to group by
130
+ * @returns New SelectQueryState with GROUP BY clause
131
+ */
132
+ withGroupBy(columns: OrderingTerm[]): SelectQueryState {
133
+ return this.clone({
134
+ ...this.ast,
135
+ groupBy: [...(this.ast.groupBy ?? []), ...columns]
136
+ });
137
+ }
138
+
139
+ /**
140
+ * Adds ORDER BY clauses to the query
141
+ * @param orderBy - ORDER BY nodes
142
+ * @returns New SelectQueryState with ORDER BY clause
143
+ */
144
+ withOrderBy(orderBy: OrderByNode[]): SelectQueryState {
145
+ return this.clone({
146
+ ...this.ast,
147
+ orderBy: [...(this.ast.orderBy ?? []), ...orderBy]
148
+ });
149
+ }
150
+
151
+ /**
152
+ * Adds DISTINCT columns to the query
153
+ * @param columns - Columns to make distinct
154
+ * @returns New SelectQueryState with DISTINCT clause
155
+ */
156
+ withDistinct(columns: ColumnNode[]): SelectQueryState {
157
+ return this.clone({
158
+ ...this.ast,
159
+ distinct: [...(this.ast.distinct ?? []), ...columns]
160
+ });
161
+ }
162
+
163
+ /**
164
+ * Adds a LIMIT clause to the query
165
+ * @param limit - Maximum number of rows to return
166
+ * @returns New SelectQueryState with LIMIT clause
167
+ */
168
+ withLimit(limit: number): SelectQueryState {
169
+ return this.clone({
170
+ ...this.ast,
171
+ limit
172
+ });
173
+ }
174
+
175
+ /**
176
+ * Adds an OFFSET clause to the query
177
+ * @param offset - Number of rows to skip
178
+ * @returns New SelectQueryState with OFFSET clause
179
+ */
180
+ withOffset(offset: number): SelectQueryState {
181
+ return this.clone({
182
+ ...this.ast,
183
+ offset
184
+ });
185
+ }
186
+
187
+ /**
181
188
  * Adds a Common Table Expression (CTE) to the query
182
189
  * @param cte - CTE node to add
183
190
  * @returns New SelectQueryState with CTE
@@ -2,7 +2,7 @@ import { TableDef } from '../schema/table.js';
2
2
 
3
3
  import { ColumnDef } from '../schema/column.js';
4
4
 
5
- import { SelectQueryNode, SetOperationKind } from '../core/ast/query.js';
5
+ import { OrderingTerm, SelectQueryNode, SetOperationKind } from '../core/ast/query.js';
6
6
 
7
7
  import { HydrationPlan } from '../core/hydration/types.js';
8
8
 
@@ -727,21 +727,13 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
727
727
 
728
728
 
729
729
  /**
730
-
731
730
  * Adds a GROUP BY clause to the query
732
-
733
- * @param col - Column definition or column node to group by
734
-
731
+ * @param term - Column definition or ordering term to group by
735
732
  * @returns New query builder instance with the GROUP BY clause
736
-
737
733
  */
738
-
739
- groupBy(col: ColumnDef | ColumnNode): SelectQueryBuilder<T, TTable> {
740
-
741
- const nextContext = this.applyAst(this.context, service => service.withGroupBy(col));
742
-
734
+ groupBy(term: ColumnDef | OrderingTerm): SelectQueryBuilder<T, TTable> {
735
+ const nextContext = this.applyAst(this.context, service => service.withGroupBy(term));
743
736
  return this.clone(nextContext);
744
-
745
737
  }
746
738
 
747
739
 
@@ -767,23 +759,23 @@ export class SelectQueryBuilder<T = any, TTable extends TableDef = TableDef> {
767
759
 
768
760
 
769
761
  /**
770
-
771
762
  * Adds an ORDER BY clause to the query
772
-
773
- * @param col - Column definition or column node to order by
774
-
775
- * @param direction - Order direction (defaults to ASC)
776
-
763
+ * @param term - Column definition or ordering term to order by
764
+ * @param directionOrOptions - Order direction or options (defaults to ASC)
777
765
  * @returns New query builder instance with the ORDER BY clause
778
-
779
766
  */
767
+ orderBy(
768
+ term: ColumnDef | OrderingTerm,
769
+ directionOrOptions: OrderDirection | { direction?: OrderDirection; nulls?: 'FIRST' | 'LAST'; collation?: string } = ORDER_DIRECTIONS.ASC
770
+ ): SelectQueryBuilder<T, TTable> {
771
+ const options = typeof directionOrOptions === 'string' ? { direction: directionOrOptions } : directionOrOptions;
772
+ const dir = options.direction ?? ORDER_DIRECTIONS.ASC;
780
773
 
781
- orderBy(col: ColumnDef | ColumnNode, direction: OrderDirection = ORDER_DIRECTIONS.ASC): SelectQueryBuilder<T, TTable> {
782
-
783
- const nextContext = this.applyAst(this.context, service => service.withOrderBy(col, direction));
774
+ const nextContext = this.applyAst(this.context, service =>
775
+ service.withOrderBy(term, dir, options.nulls, options.collation)
776
+ );
784
777
 
785
778
  return this.clone(nextContext);
786
-
787
779
  }
788
780
 
789
781