metal-orm 1.0.62 → 1.0.64

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.62",
3
+ "version": "1.0.64",
4
4
  "type": "module",
5
5
  "types": "./dist/index.d.ts",
6
6
  "engines": {
@@ -2,9 +2,10 @@ import { ColumnNode, FunctionNode } from './expression-nodes.js';
2
2
  import { columnOperand, valueToOperand, ValueOperandInput } from './expression-builders.js';
3
3
  import { ColumnRef } from './types.js';
4
4
  import { OrderByNode } from './query.js';
5
+ import { TypedExpression, asType } from './expression.js';
5
6
  import { ORDER_DIRECTIONS, OrderDirection } from '../sql/sql.js';
6
7
 
7
- const buildAggregate = (name: string) => (col: ColumnRef | ColumnNode): FunctionNode => ({
8
+ const buildAggregate = (name: string) => (col: ColumnRef | ColumnNode): TypedExpression<number> => asType<number>({
8
9
  type: 'Function',
9
10
  name,
10
11
  args: [columnOperand(col)]
@@ -47,9 +48,10 @@ export const max = buildAggregate('MAX');
47
48
 
48
49
  /**
49
50
  * Creates a COUNT(*) function expression.
50
- * @returns Function node with COUNT(*)
51
+ *
52
+ * @returns A `TypedExpression<number>` representing the `COUNT(*)` SQL function.
51
53
  */
52
- export const countAll = (): FunctionNode => ({
54
+ export const countAll = (): TypedExpression<number> => asType<number>({
53
55
  type: 'Function',
54
56
  name: 'COUNT',
55
57
  args: []
@@ -73,11 +75,18 @@ const toOrderByNode = (order: GroupConcatOrderByInput): OrderByNode => ({
73
75
 
74
76
  /**
75
77
  * Aggregates grouped strings into a single value.
78
+ *
79
+ * @param col - Column or expression to aggregate.
80
+ * @param options - Optional separator and ordering.
81
+ * @returns A `TypedExpression<string>` representing the `GROUP_CONCAT` SQL function.
82
+ *
83
+ * @example
84
+ * groupConcat(users.name, { separator: ', ', orderBy: [{ column: users.name }] });
76
85
  */
77
86
  export const groupConcat = (
78
87
  col: ColumnRef | ColumnNode,
79
88
  options?: GroupConcatOptions
80
- ): FunctionNode => ({
89
+ ): TypedExpression<string> => asType<string>({
81
90
  type: 'Function',
82
91
  name: 'GROUP_CONCAT',
83
92
  args: [columnOperand(col)],
@@ -27,6 +27,8 @@ import {
27
27
  export type LiteralValue = LiteralNode['value'];
28
28
  export type ValueOperandInput = OperandNode | LiteralValue;
29
29
 
30
+ export type TypedLike<T> = { tsType?: T } | { __tsType: T };
31
+
30
32
  /**
31
33
  * Type guard to check if a value is a literal value
32
34
  */
@@ -165,76 +167,149 @@ const createBinaryExpression = (
165
167
  };
166
168
 
167
169
  /**
168
- * Creates an equality expression (left = right)
169
- * @param left - Left operand
170
- * @param right - Right operand
171
- * @returns Binary expression node with equality operator
172
- */
173
- export const eq = (left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number | boolean): BinaryExpressionNode =>
174
- createBinaryExpression('=', left, right);
175
-
176
- /**
177
- * Creates a not equal expression (left != right)
178
- */
179
- export const neq = (
180
- left: OperandNode | ColumnRef,
181
- right: OperandNode | ColumnRef | string | number | boolean
182
- ): BinaryExpressionNode => createBinaryExpression('!=', left, right);
183
-
184
- /**
185
- * Creates a greater-than expression (left > right)
186
- * @param left - Left operand
187
- * @param right - Right operand
188
- * @returns Binary expression node with greater-than operator
189
- */
190
- export const gt = (left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number): BinaryExpressionNode =>
191
- createBinaryExpression('>', left, right);
192
-
193
- /**
194
- * Creates a greater than or equal expression (left >= right)
195
- */
196
- export const gte = (left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number): BinaryExpressionNode =>
197
- createBinaryExpression('>=', left, right);
198
-
199
- /**
200
- * Creates a less-than expression (left < right)
201
- * @param left - Left operand
202
- * @param right - Right operand
203
- * @returns Binary expression node with less-than operator
204
- */
205
- export const lt = (left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number): BinaryExpressionNode =>
206
- createBinaryExpression('<', left, right);
207
-
208
- /**
209
- * Creates a less than or equal expression (left <= right)
210
- */
211
- export const lte = (left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number): BinaryExpressionNode =>
212
- createBinaryExpression('<=', left, right);
213
-
214
- /**
215
- * Creates a LIKE pattern matching expression
216
- * @param left - Left operand
217
- * @param pattern - Pattern to match
218
- * @param escape - Optional escape character
219
- * @returns Binary expression node with LIKE operator
170
+ * Creates an equality expression (`left = right`).
171
+ *
172
+ * Supports type safety when used with `ColumnDef` objects containing strict type information.
173
+ *
174
+ * @param left - The left operand (column or value).
175
+ * @param right - The right operand (column or value).
176
+ * @returns A `BinaryExpressionNode` representing the equality check.
177
+ *
178
+ * @example
179
+ * // Basic usage
180
+ * eq(users.id, 1);
181
+ *
182
+ * // With strict typing (typescript will error if types mismatch)
183
+ * eq(users.firstName, 'Ada');
184
+ */
185
+ export function eq<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
186
+ export function eq(left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number | boolean): BinaryExpressionNode;
187
+ export function eq(left: OperandNode | ColumnRef | TypedLike<unknown>, right: OperandNode | ColumnRef | string | number | boolean | TypedLike<unknown>): BinaryExpressionNode {
188
+ return createBinaryExpression('=', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | string | number | boolean);
189
+ }
190
+
191
+ /**
192
+ * Creates a not equal expression (`left != right`).
193
+ *
194
+ * @param left - The left operand (column or value).
195
+ * @param right - The right operand (column or value).
196
+ * @returns A `BinaryExpressionNode` representing the inequality check.
197
+ *
198
+ * @example
199
+ * neq(users.status, 'inactive');
200
+ */
201
+ export function neq<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
202
+ export function neq(left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number | boolean): BinaryExpressionNode;
203
+ export function neq(
204
+ left: OperandNode | ColumnRef | TypedLike<unknown>,
205
+ right: OperandNode | ColumnRef | string | number | boolean | TypedLike<unknown>
206
+ ): BinaryExpressionNode {
207
+ return createBinaryExpression('!=', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | string | number | boolean);
208
+ }
209
+
210
+ /**
211
+ * Creates a greater-than expression (`left > right`).
212
+ *
213
+ * @param left - The left operand.
214
+ * @param right - The right operand.
215
+ * @returns A `BinaryExpressionNode`.
216
+ *
217
+ * @example
218
+ * gt(users.age, 18);
219
+ */
220
+ export function gt<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
221
+ export function gt(left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number): BinaryExpressionNode;
222
+ export function gt(left: OperandNode | ColumnRef | TypedLike<unknown>, right: OperandNode | ColumnRef | string | number | TypedLike<unknown>): BinaryExpressionNode {
223
+ return createBinaryExpression('>', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | string | number);
224
+ }
225
+
226
+ /**
227
+ * Creates a greater-than-or-equal expression (`left >= right`).
228
+ *
229
+ * @param left - The left operand.
230
+ * @param right - The right operand.
231
+ * @returns A `BinaryExpressionNode`.
232
+ *
233
+ * @example
234
+ * gte(users.score, 100);
235
+ */
236
+ export function gte<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
237
+ export function gte(left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number): BinaryExpressionNode;
238
+ export function gte(left: OperandNode | ColumnRef | TypedLike<unknown>, right: OperandNode | ColumnRef | string | number | TypedLike<unknown>): BinaryExpressionNode {
239
+ return createBinaryExpression('>=', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | string | number);
240
+ }
241
+
242
+ /**
243
+ * Creates a less-than expression (`left < right`).
244
+ *
245
+ * @param left - The left operand.
246
+ * @param right - The right operand.
247
+ * @returns A `BinaryExpressionNode`.
248
+ *
249
+ * @example
250
+ * lt(inventory.stock, 5);
251
+ */
252
+ export function lt<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
253
+ export function lt(left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number): BinaryExpressionNode;
254
+ export function lt(left: OperandNode | ColumnRef | TypedLike<unknown>, right: OperandNode | ColumnRef | string | number | TypedLike<unknown>): BinaryExpressionNode {
255
+ return createBinaryExpression('<', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | string | number);
256
+ }
257
+
258
+ /**
259
+ * Creates a less-than-or-equal expression (`left <= right`).
260
+ *
261
+ * @param left - The left operand.
262
+ * @param right - The right operand.
263
+ * @returns A `BinaryExpressionNode`.
264
+ *
265
+ * @example
266
+ * lte(products.price, 50.00);
267
+ */
268
+ export function lte<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
269
+ export function lte(left: OperandNode | ColumnRef, right: OperandNode | ColumnRef | string | number): BinaryExpressionNode;
270
+ export function lte(left: OperandNode | ColumnRef | TypedLike<unknown>, right: OperandNode | ColumnRef | string | number | TypedLike<unknown>): BinaryExpressionNode {
271
+ return createBinaryExpression('<=', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | string | number);
272
+ }
273
+
274
+ /**
275
+ * Creates a `LIKE` pattern matching expression.
276
+ *
277
+ * @param left - The column or expression to check.
278
+ * @param pattern - The pattern string (e.g., 'A%').
279
+ * @param escape - Optional escape character.
280
+ * @returns A `BinaryExpressionNode`.
281
+ *
282
+ * @example
283
+ * like(users.email, '%@gmail.com');
220
284
  */
221
285
  export const like = (left: OperandNode | ColumnRef, pattern: string, escape?: string): BinaryExpressionNode =>
222
286
  createBinaryExpression('LIKE', left, pattern, escape);
223
287
 
224
288
  /**
225
- * Creates a NOT LIKE pattern matching expression
226
- * @param left - Left operand
227
- * @param pattern - Pattern to match
228
- * @param escape - Optional escape character
229
- * @returns Binary expression node with NOT LIKE operator
289
+ * Creates a `NOT LIKE` pattern matching expression.
290
+ *
291
+ * @param left - The column or expression to check.
292
+ * @param pattern - The pattern string.
293
+ * @param escape - Optional escape character.
294
+ * @returns A `BinaryExpressionNode`.
295
+ *
296
+ * @example
297
+ * notLike(users.email, 'test%');
230
298
  */
231
299
  export const notLike = (left: OperandNode | ColumnRef, pattern: string, escape?: string): BinaryExpressionNode =>
232
300
  createBinaryExpression('NOT LIKE', left, pattern, escape);
233
301
 
234
302
  /**
235
- * Creates a logical AND expression
236
- * @param operands - Expressions to combine with AND
237
- * @returns Logical expression node with AND operator
303
+ * Creates a logical AND expression to combine multiple conditions.
304
+ *
305
+ * @param operands - One or more conditions to combine.
306
+ * @returns A `LogicalExpressionNode`.
307
+ *
308
+ * @example
309
+ * and(
310
+ * eq(users.isActive, true),
311
+ * gt(users.age, 18)
312
+ * );
238
313
  */
239
314
  export const and = (...operands: ExpressionNode[]): LogicalExpressionNode => ({
240
315
  type: 'LogicalExpression',
@@ -243,9 +318,16 @@ export const and = (...operands: ExpressionNode[]): LogicalExpressionNode => ({
243
318
  });
244
319
 
245
320
  /**
246
- * Creates a logical OR expression
247
- * @param operands - Expressions to combine with OR
248
- * @returns Logical expression node with OR operator
321
+ * Creates a logical OR expression to combine multiple conditions.
322
+ *
323
+ * @param operands - One or more conditions to combine.
324
+ * @returns A `LogicalExpressionNode`.
325
+ *
326
+ * @example
327
+ * or(
328
+ * eq(users.role, 'admin'),
329
+ * eq(users.role, 'moderator')
330
+ * );
249
331
  */
250
332
  export const or = (...operands: ExpressionNode[]): LogicalExpressionNode => ({
251
333
  type: 'LogicalExpression',
@@ -254,9 +336,13 @@ export const or = (...operands: ExpressionNode[]): LogicalExpressionNode => ({
254
336
  });
255
337
 
256
338
  /**
257
- * Creates an IS NULL expression
258
- * @param left - Operand to check for null
259
- * @returns Null expression node with IS NULL operator
339
+ * Creates an IS NULL check (`left IS NULL`).
340
+ *
341
+ * @param left - The operand to check.
342
+ * @returns A `NullExpressionNode`.
343
+ *
344
+ * @example
345
+ * isNull(users.deletedAt);
260
346
  */
261
347
  export const isNull = (left: OperandNode | ColumnRef): NullExpressionNode => ({
262
348
  type: 'NullExpression',
@@ -265,9 +351,13 @@ export const isNull = (left: OperandNode | ColumnRef): NullExpressionNode => ({
265
351
  });
266
352
 
267
353
  /**
268
- * Creates an IS NOT NULL expression
269
- * @param left - Operand to check for non-null
270
- * @returns Null expression node with IS NOT NULL operator
354
+ * Creates an IS NOT NULL check (`left IS NOT NULL`).
355
+ *
356
+ * @param left - The operand to check.
357
+ * @returns A `NullExpressionNode`.
358
+ *
359
+ * @example
360
+ * isNotNull(users.email);
271
361
  */
272
362
  export const isNotNull = (left: OperandNode | ColumnRef): NullExpressionNode => ({
273
363
  type: 'NullExpression',
@@ -287,26 +377,60 @@ const createInExpression = (
287
377
  });
288
378
 
289
379
  /**
290
- * Creates an IN expression (value IN list)
291
- * @param left - Operand to check
292
- * @param values - Values to check against
293
- * @returns IN expression node
380
+ * Creates an IN list check (`left IN (v1, v2, ...)`).
381
+ *
382
+ * @param left - The operand to check.
383
+ * @param values - An array of values to check against.
384
+ * @returns An `InExpressionNode`.
385
+ *
386
+ * @example
387
+ * inList(users.status, ['active', 'pending']);
294
388
  */
295
389
  export const inList = (left: OperandNode | ColumnRef, values: (string | number | LiteralNode)[]): InExpressionNode =>
296
390
  createInExpression('IN', left, values.map(v => toOperand(v)));
297
391
 
298
392
  /**
299
- * Creates a NOT IN expression (value NOT IN list)
300
- * @param left - Operand to check
301
- * @param values - Values to check against
302
- * @returns NOT IN expression node
393
+ * Creates a NOT IN list check (`left NOT IN (v1, v2, ...)`).
394
+ *
395
+ * @param left - The operand to check.
396
+ * @param values - An array of values to check against.
397
+ * @returns An `InExpressionNode`.
398
+ *
399
+ * @example
400
+ * notInList(users.id, [1, 2, 3]);
303
401
  */
304
402
  export const notInList = (left: OperandNode | ColumnRef, values: (string | number | LiteralNode)[]): InExpressionNode =>
305
403
  createInExpression('NOT IN', left, values.map(v => toOperand(v)));
306
404
 
405
+ /**
406
+ * Creates an IN subquery check (`left IN (SELECT ...)`).
407
+ *
408
+ * @param left - The operand to check.
409
+ * @param subquery - The subquery to run.
410
+ * @returns An `InExpressionNode`.
411
+ *
412
+ * @example
413
+ * inSubquery(
414
+ * posts.authorId,
415
+ * selectFromEntity(User).select({ id: users.id }).where(eq(users.isActive, true))
416
+ * );
417
+ */
307
418
  export const inSubquery = (left: OperandNode | ColumnRef, subquery: SelectQueryInput): InExpressionNode =>
308
419
  createInExpression('IN', left, toScalarSubqueryNode(subquery));
309
420
 
421
+ /**
422
+ * Creates a NOT IN subquery check (`left NOT IN (SELECT ...)`).
423
+ *
424
+ * @param left - The operand to check.
425
+ * @param subquery - The subquery to run.
426
+ * @returns An `InExpressionNode`.
427
+ *
428
+ * @example
429
+ * notInSubquery(
430
+ * users.id,
431
+ * selectFromEntity(Blacklist).select({ userId: blacklist.userId })
432
+ * );
433
+ */
310
434
  export const notInSubquery = (left: OperandNode | ColumnRef, subquery: SelectQueryInput): InExpressionNode =>
311
435
  createInExpression('NOT IN', left, toScalarSubqueryNode(subquery));
312
436
 
@@ -324,11 +448,15 @@ const createBetweenExpression = (
324
448
  });
325
449
 
326
450
  /**
327
- * Creates a BETWEEN expression (value BETWEEN lower AND upper)
328
- * @param left - Operand to check
329
- * @param lower - Lower bound
330
- * @param upper - Upper bound
331
- * @returns BETWEEN expression node
451
+ * Creates a BETWEEN check (`left BETWEEN lower AND upper`).
452
+ *
453
+ * @param left - The operand to check.
454
+ * @param lower - The lower bound (inclusive).
455
+ * @param upper - The upper bound (inclusive).
456
+ * @returns A `BetweenExpressionNode`.
457
+ *
458
+ * @example
459
+ * between(products.price, 10, 100);
332
460
  */
333
461
  export const between = (
334
462
  left: OperandNode | ColumnRef,
@@ -337,11 +465,15 @@ export const between = (
337
465
  ): BetweenExpressionNode => createBetweenExpression('BETWEEN', left, lower, upper);
338
466
 
339
467
  /**
340
- * Creates a NOT BETWEEN expression (value NOT BETWEEN lower AND upper)
341
- * @param left - Operand to check
342
- * @param lower - Lower bound
343
- * @param upper - Upper bound
344
- * @returns NOT BETWEEN expression node
468
+ * Creates a NOT BETWEEN check (`left NOT BETWEEN lower AND upper`).
469
+ *
470
+ * @param left - The operand to check.
471
+ * @param lower - The lower bound (inclusive).
472
+ * @param upper - The upper bound (inclusive).
473
+ * @returns A `BetweenExpressionNode`.
474
+ *
475
+ * @example
476
+ * notBetween(users.age, 20, 30);
345
477
  */
346
478
  export const notBetween = (
347
479
  left: OperandNode | ColumnRef,
@@ -360,21 +492,49 @@ const createArithmeticExpression = (
360
492
  right: toOperand(right)
361
493
  });
362
494
 
495
+ /**
496
+ * Creates an addition expression (`left + right`).
497
+ *
498
+ * @param left - The left operand.
499
+ * @param right - The right operand.
500
+ * @returns An `ArithmeticExpressionNode`.
501
+ */
363
502
  export const add = (
364
503
  left: OperandNode | ColumnRef,
365
504
  right: OperandNode | ColumnRef | string | number
366
505
  ): ArithmeticExpressionNode => createArithmeticExpression('+', left, right);
367
506
 
507
+ /**
508
+ * Creates a subtraction expression (`left - right`).
509
+ *
510
+ * @param left - The left operand.
511
+ * @param right - The right operand.
512
+ * @returns An `ArithmeticExpressionNode`.
513
+ */
368
514
  export const sub = (
369
515
  left: OperandNode | ColumnRef,
370
516
  right: OperandNode | ColumnRef | string | number
371
517
  ): ArithmeticExpressionNode => createArithmeticExpression('-', left, right);
372
518
 
519
+ /**
520
+ * Creates a multiplication expression (`left * right`).
521
+ *
522
+ * @param left - The left operand.
523
+ * @param right - The right operand.
524
+ * @returns An `ArithmeticExpressionNode`.
525
+ */
373
526
  export const mul = (
374
527
  left: OperandNode | ColumnRef,
375
528
  right: OperandNode | ColumnRef | string | number
376
529
  ): ArithmeticExpressionNode => createArithmeticExpression('*', left, right);
377
530
 
531
+ /**
532
+ * Creates a division expression (`left / right`).
533
+ *
534
+ * @param left - The left operand.
535
+ * @param right - The right operand.
536
+ * @returns An `ArithmeticExpressionNode`.
537
+ */
378
538
  export const div = (
379
539
  left: OperandNode | ColumnRef,
380
540
  right: OperandNode | ColumnRef | string | number
@@ -392,7 +552,11 @@ const createBitwiseExpression = (
392
552
  });
393
553
 
394
554
  /**
395
- * Creates a bitwise AND expression (left & right)
555
+ * Creates a bitwise AND expression (`left & right`).
556
+ *
557
+ * @param left - The left operand.
558
+ * @param right - The right operand.
559
+ * @returns A `BitwiseExpressionNode`.
396
560
  */
397
561
  export const bitAnd = (
398
562
  left: OperandNode | ColumnRef,
@@ -400,7 +564,11 @@ export const bitAnd = (
400
564
  ): BitwiseExpressionNode => createBitwiseExpression('&', left, right);
401
565
 
402
566
  /**
403
- * Creates a bitwise OR expression (left | right)
567
+ * Creates a bitwise OR expression (`left | right`).
568
+ *
569
+ * @param left - The left operand.
570
+ * @param right - The right operand.
571
+ * @returns A `BitwiseExpressionNode`.
404
572
  */
405
573
  export const bitOr = (
406
574
  left: OperandNode | ColumnRef,
@@ -408,7 +576,11 @@ export const bitOr = (
408
576
  ): BitwiseExpressionNode => createBitwiseExpression('|', left, right);
409
577
 
410
578
  /**
411
- * Creates a bitwise XOR expression (left ^ right)
579
+ * Creates a bitwise XOR expression (`left ^ right`).
580
+ *
581
+ * @param left - The left operand.
582
+ * @param right - The right operand.
583
+ * @returns A `BitwiseExpressionNode`.
412
584
  */
413
585
  export const bitXor = (
414
586
  left: OperandNode | ColumnRef,
@@ -416,7 +588,11 @@ export const bitXor = (
416
588
  ): BitwiseExpressionNode => createBitwiseExpression('^', left, right);
417
589
 
418
590
  /**
419
- * Creates a bitwise shift left expression (left << right)
591
+ * Creates a bitwise left-shift expression (`left << right`).
592
+ *
593
+ * @param left - The left operand.
594
+ * @param right - The right operand (number of bits).
595
+ * @returns A `BitwiseExpressionNode`.
420
596
  */
421
597
  export const shiftLeft = (
422
598
  left: OperandNode | ColumnRef,
@@ -424,7 +600,11 @@ export const shiftLeft = (
424
600
  ): BitwiseExpressionNode => createBitwiseExpression('<<', left, right);
425
601
 
426
602
  /**
427
- * Creates a bitwise shift right expression (left >> right)
603
+ * Creates a bitwise right-shift expression (`left >> right`).
604
+ *
605
+ * @param left - The left operand.
606
+ * @param right - The right operand (number of bits).
607
+ * @returns A `BitwiseExpressionNode`.
428
608
  */
429
609
  export const shiftRight = (
430
610
  left: OperandNode | ColumnRef,
@@ -432,10 +612,14 @@ export const shiftRight = (
432
612
  ): BitwiseExpressionNode => createBitwiseExpression('>>', left, right);
433
613
 
434
614
  /**
435
- * Creates a JSON path expression
436
- * @param col - Source column
437
- * @param path - JSON path expression
438
- * @returns JSON path node
615
+ * Creates a JSON path extraction expression.
616
+ *
617
+ * @param col - The source column (should be a JSON/JSONB column).
618
+ * @param path - The JSON path expression (e.g., '$.address.city').
619
+ * @returns A `JsonPathNode`.
620
+ *
621
+ * @example
622
+ * jsonPath(users.profile, '$.settings.theme');
439
623
  */
440
624
  export const jsonPath = (col: ColumnRef | ColumnNode, path: string): JsonPathNode => ({
441
625
  type: 'JsonPath',
@@ -444,10 +628,17 @@ export const jsonPath = (col: ColumnRef | ColumnNode, path: string): JsonPathNod
444
628
  });
445
629
 
446
630
  /**
447
- * Creates a CASE expression
448
- * @param conditions - Array of WHEN-THEN conditions
449
- * @param elseValue - Optional ELSE value
450
- * @returns CASE expression node
631
+ * Creates a CASE expression (`CASE WHEN ... THEN ... ELSE ... END`).
632
+ *
633
+ * @param conditions - An array of `{ when, then }` objects.
634
+ * @param elseValue - Optional value for the `ELSE` clause.
635
+ * @returns A `CaseExpressionNode`.
636
+ *
637
+ * @example
638
+ * caseWhen([
639
+ * { when: gt(users.age, 65), then: 'Senior' },
640
+ * { when: gt(users.age, 18), then: 'Adult' }
641
+ * ], 'Minor');
451
642
  */
452
643
  export const caseWhen = (
453
644
  conditions: { when: ExpressionNode; then: OperandNode | ColumnRef | string | number | boolean | null }[],
@@ -462,7 +653,14 @@ export const caseWhen = (
462
653
  });
463
654
 
464
655
  /**
465
- * Builds a CAST expression node for casting values to SQL types.
656
+ * Creates a CAST expression (`CAST(expression AS type)`).
657
+ *
658
+ * @param expression - The expression to cast.
659
+ * @param castType - The target SQL type (e.g., 'VARCHAR', 'INTEGER').
660
+ * @returns A `CastExpressionNode`.
661
+ *
662
+ * @example
663
+ * cast(users.age, 'VARCHAR');
466
664
  */
467
665
  export const cast = (
468
666
  expression: OperandNode | ColumnRef | string | number | boolean | null,
@@ -474,9 +672,15 @@ export const cast = (
474
672
  });
475
673
 
476
674
  /**
477
- * Creates an EXISTS expression
478
- * @param subquery - Subquery to check for existence
479
- * @returns EXISTS expression node
675
+ * Creates an EXISTS check (`EXISTS (SELECT ...)`).
676
+ *
677
+ * @param subquery - The subquery to check.
678
+ * @returns An `ExistsExpressionNode`.
679
+ *
680
+ * @example
681
+ * exists(
682
+ * selectFromEntity(Order).where(eq(orders.userId, users.id))
683
+ * );
480
684
  */
481
685
  export const exists = (subquery: SelectQueryNode): ExistsExpressionNode => ({
482
686
  type: 'ExistsExpression',
@@ -485,9 +689,15 @@ export const exists = (subquery: SelectQueryNode): ExistsExpressionNode => ({
485
689
  });
486
690
 
487
691
  /**
488
- * Creates a NOT EXISTS expression
489
- * @param subquery - Subquery to check for non-existence
490
- * @returns NOT EXISTS expression node
692
+ * Creates a NOT EXISTS check (`NOT EXISTS (SELECT ...)`).
693
+ *
694
+ * @param subquery - The subquery to check.
695
+ * @returns An `ExistsExpressionNode`.
696
+ *
697
+ * @example
698
+ * notExists(
699
+ * selectFromEntity(Subscription).where(eq(subscriptions.userId, users.id))
700
+ * );
491
701
  */
492
702
  export const notExists = (subquery: SelectQueryNode): ExistsExpressionNode => ({
493
703
  type: 'ExistsExpression',
@@ -496,10 +706,14 @@ export const notExists = (subquery: SelectQueryNode): ExistsExpressionNode => ({
496
706
  });
497
707
 
498
708
  /**
499
- * Creates a COLLATE expression (expression COLLATE collationName)
500
- * @param expression - Expression to be collated
501
- * @param collation - Collation name
502
- * @returns COLLATE expression node
709
+ * Creates a COLLATE expression (`expression COLLATE collation`).
710
+ *
711
+ * @param expression - The expression string.
712
+ * @param collation - The collation name (e.g., 'nocase').
713
+ * @returns A `CollateExpressionNode`.
714
+ *
715
+ * @example
716
+ * collate(users.email, 'nocase');
503
717
  */
504
718
  export const collate = (
505
719
  expression: OperandNode | ColumnRef | string | number | boolean | null,