metal-orm 1.0.39 → 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metal-orm",
3
- "version": "1.0.39",
3
+ "version": "1.0.40",
4
4
  "type": "module",
5
5
  "types": "./dist/index.d.ts",
6
6
  "engines": {
@@ -12,9 +12,11 @@ import {
12
12
  ScalarSubqueryNode,
13
13
  CaseExpressionNode,
14
14
  WindowFunctionNode,
15
+ ArithmeticExpressionNode,
15
16
  ColumnNode,
16
17
  LiteralNode,
17
18
  FunctionNode,
19
+ AliasRefNode,
18
20
  ExpressionVisitor,
19
21
  OperandVisitor,
20
22
  visitExpression,
@@ -116,7 +118,7 @@ export class TypeScriptGenerator implements ExpressionVisitor<string>, OperandVi
116
118
  }
117
119
 
118
120
  if (ast.groupBy && ast.groupBy.length) {
119
- const cols = ast.groupBy.map(c => `${this.namingStrategy.tableToSymbol(c.table)}.${c.name}`).join(', ');
121
+ const cols = ast.groupBy.map(term => this.printOrderingTerm(term)).join(', ');
120
122
  lines.push(`.groupBy(${cols})`);
121
123
  }
122
124
 
@@ -126,7 +128,16 @@ export class TypeScriptGenerator implements ExpressionVisitor<string>, OperandVi
126
128
 
127
129
  if (ast.orderBy && ast.orderBy.length) {
128
130
  ast.orderBy.forEach(o => {
129
- lines.push(`.orderBy(${this.namingStrategy.tableToSymbol(o.column.table)}.${o.column.name}, '${o.direction}')`);
131
+ const term = this.printOrderingTerm(o.term);
132
+ const opts: string[] = [`direction: '${o.direction}'`];
133
+ if (o.nulls) opts.push(`nulls: '${o.nulls}'`);
134
+ if (o.collation) opts.push(`collation: '${o.collation}'`);
135
+ const hasOpts = opts.length > 1;
136
+ if (hasOpts) {
137
+ lines.push(`.orderBy(${term}, { ${opts.join(', ')} })`);
138
+ } else {
139
+ lines.push(`.orderBy(${term}, '${o.direction}')`);
140
+ }
130
141
  });
131
142
  }
132
143
 
@@ -154,6 +165,31 @@ export class TypeScriptGenerator implements ExpressionVisitor<string>, OperandVi
154
165
  return visitOperand(node, this);
155
166
  }
156
167
 
168
+ /**
169
+ * Prints an ordering term (operand/expression/alias) to TypeScript code.
170
+ */
171
+ private printOrderingTerm(term: any): string {
172
+ if (!term || !(term as any).type) {
173
+ throw new Error('Unsupported ordering term');
174
+ }
175
+
176
+ switch ((term as any).type) {
177
+ case 'Column':
178
+ return `${this.namingStrategy.tableToSymbol((term as any).table)}.${(term as any).name}`;
179
+ case 'AliasRef':
180
+ return this.visitAliasRef(term as any);
181
+ case 'Literal':
182
+ case 'Function':
183
+ case 'JsonPath':
184
+ case 'ScalarSubquery':
185
+ case 'CaseExpression':
186
+ case 'WindowFunction':
187
+ return this.printOperand(term as OperandNode);
188
+ default:
189
+ return this.printExpression(term as ExpressionNode);
190
+ }
191
+ }
192
+
157
193
  public visitBinaryExpression(binary: BinaryExpressionNode): string {
158
194
  return this.printBinaryExpression(binary);
159
195
  }
@@ -178,6 +214,10 @@ export class TypeScriptGenerator implements ExpressionVisitor<string>, OperandVi
178
214
  return this.printBetweenExpression(betweenExpr);
179
215
  }
180
216
 
217
+ public visitArithmeticExpression(arithExpr: ArithmeticExpressionNode): string {
218
+ return this.printArithmeticExpression(arithExpr);
219
+ }
220
+
181
221
  public visitColumn(node: ColumnNode): string {
182
222
  return this.printColumnOperand(node);
183
223
  }
@@ -206,6 +246,10 @@ export class TypeScriptGenerator implements ExpressionVisitor<string>, OperandVi
206
246
  return this.printWindowFunctionOperand(node);
207
247
  }
208
248
 
249
+ public visitAliasRef(node: AliasRefNode): string {
250
+ return `aliasRef('${node.name}')`;
251
+ }
252
+
209
253
  /**
210
254
  * Prints a binary expression to TypeScript code
211
255
  * @param binary - Binary expression node
@@ -236,6 +280,12 @@ export class TypeScriptGenerator implements ExpressionVisitor<string>, OperandVi
236
280
  return `${this.mapOp(logical.operator)}(\n ${parts.join(',\n ')}\n )`;
237
281
  }
238
282
 
283
+ private printArithmeticExpression(expr: ArithmeticExpressionNode): string {
284
+ const left = this.printOperand(expr.left);
285
+ const right = this.printOperand(expr.right);
286
+ return `${left} ${expr.operator} ${right}`;
287
+ }
288
+
239
289
  /**
240
290
  * Prints an IN expression to TypeScript code
241
291
  * @param inExpr - IN expression node
@@ -366,7 +416,14 @@ export class TypeScriptGenerator implements ExpressionVisitor<string>, OperandVi
366
416
  if (node.orderBy && node.orderBy.length > 0) {
367
417
  const orderClause =
368
418
  'ORDER BY ' +
369
- node.orderBy.map(o => `${this.namingStrategy.tableToSymbol(o.column.table)}.${o.column.name} ${o.direction}`).join(', ');
419
+ node.orderBy
420
+ .map(o => {
421
+ const term = this.printOrderingTerm(o.term);
422
+ const collation = o.collation ? ` COLLATE ${o.collation}` : '';
423
+ const nulls = o.nulls ? ` NULLS ${o.nulls}` : '';
424
+ return `${term} ${o.direction}${collation}${nulls}`;
425
+ })
426
+ .join(', ');
370
427
  parts.push(orderClause);
371
428
  }
372
429
 
@@ -9,24 +9,24 @@ const buildAggregate = (name: string) => (col: ColumnRef | ColumnNode): Function
9
9
  name,
10
10
  args: [columnOperand(col)]
11
11
  });
12
-
13
- /**
14
- * Creates a COUNT function expression
15
- * @param col - Column to count
16
- * @returns Function node with COUNT
17
- */
18
- export const count = buildAggregate('COUNT');
19
-
20
- /**
21
- * Creates a SUM function expression
12
+
13
+ /**
14
+ * Creates a COUNT function expression
15
+ * @param col - Column to count
16
+ * @returns Function node with COUNT
17
+ */
18
+ export const count = buildAggregate('COUNT');
19
+
20
+ /**
21
+ * Creates a SUM function expression
22
22
  * @param col - Column to sum
23
23
  * @returns Function node with SUM
24
24
  */
25
25
  export const sum = buildAggregate('SUM');
26
-
27
- /**
28
- * Creates an AVG function expression
29
- * @param col - Column to average
26
+
27
+ /**
28
+ * Creates an AVG function expression
29
+ * @param col - Column to average
30
30
  * @returns Function node with AVG
31
31
  */
32
32
  export const avg = buildAggregate('AVG');
@@ -57,7 +57,7 @@ export type GroupConcatOptions = {
57
57
 
58
58
  const toOrderByNode = (order: GroupConcatOrderByInput): OrderByNode => ({
59
59
  type: 'OrderBy',
60
- column: columnOperand(order.column),
60
+ term: columnOperand(order.column),
61
61
  direction: order.direction ?? ORDER_DIRECTIONS.ASC
62
62
  });
63
63