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.
@@ -2,6 +2,8 @@
2
2
  * Expression AST nodes and builders.
3
3
  * Re-exports components for building and visiting SQL expression trees.
4
4
  */
5
+ import type { CaseExpressionNode, FunctionNode, WindowFunctionNode } from './expression-nodes.js';
6
+
5
7
  export * from './expression-nodes.js';
6
8
  export * from './expression-builders.js';
7
9
  export * from './window-functions.js';
@@ -9,3 +11,10 @@ export * from './aggregate-functions.js';
9
11
  export * from './expression-visitor.js';
10
12
  export type { ColumnRef, TableRef as AstTableRef } from './types.js';
11
13
  export * from './adapters.js';
14
+
15
+ export type TypedExpression<T> =
16
+ (FunctionNode | CaseExpressionNode | WindowFunctionNode) & { __tsType: T };
17
+
18
+ export const asType = <T>(
19
+ expr: FunctionNode | CaseExpressionNode | WindowFunctionNode
20
+ ): TypedExpression<T> => expr as TypedExpression<T>;
@@ -3,13 +3,14 @@ import { columnOperand } from './expression-builders.js';
3
3
  import { OrderDirection } from '../sql/sql.js';
4
4
  import { OrderByNode } from './query.js';
5
5
  import { ColumnRef } from './types.js';
6
+ import { TypedExpression, asType } from './expression.js';
6
7
 
7
- const buildWindowFunction = (
8
+ const buildWindowFunction = <T = any>(
8
9
  name: string,
9
10
  args: (ColumnNode | LiteralNode | JsonPathNode)[] = [],
10
11
  partitionBy?: ColumnNode[],
11
12
  orderBy?: OrderByNode[]
12
- ): WindowFunctionNode => {
13
+ ): TypedExpression<T> => {
13
14
  const node: WindowFunctionNode = {
14
15
  type: 'WindowFunction',
15
16
  name,
@@ -24,47 +25,52 @@ const buildWindowFunction = (
24
25
  node.orderBy = orderBy;
25
26
  }
26
27
 
27
- return node;
28
+ return asType<T>(node);
28
29
  };
29
30
 
30
31
  /**
31
- * Creates a ROW_NUMBER window function
32
- * @returns Window function node for ROW_NUMBER
32
+ * Creates a ROW_NUMBER window function.
33
+ *
34
+ * @returns A `TypedExpression<number>` representing the `ROW_NUMBER` window function.
33
35
  */
34
- export const rowNumber = (): WindowFunctionNode => buildWindowFunction('ROW_NUMBER');
36
+ export const rowNumber = (): TypedExpression<number> => buildWindowFunction<number>('ROW_NUMBER');
35
37
 
36
38
  /**
37
- * Creates a RANK window function
38
- * @returns Window function node for RANK
39
+ * Creates a RANK window function.
40
+ *
41
+ * @returns A `TypedExpression<number>` representing the `RANK` window function.
39
42
  */
40
- export const rank = (): WindowFunctionNode => buildWindowFunction('RANK');
43
+ export const rank = (): TypedExpression<number> => buildWindowFunction<number>('RANK');
41
44
 
42
45
  /**
43
- * Creates a DENSE_RANK window function
44
- * @returns Window function node for DENSE_RANK
46
+ * Creates a DENSE_RANK window function.
47
+ *
48
+ * @returns A `TypedExpression<number>` representing the `DENSE_RANK` window function.
45
49
  */
46
- export const denseRank = (): WindowFunctionNode => buildWindowFunction('DENSE_RANK');
50
+ export const denseRank = (): TypedExpression<number> => buildWindowFunction<number>('DENSE_RANK');
47
51
 
48
52
  /**
49
- * Creates an NTILE window function
50
- * @param n - Number of buckets
51
- * @returns Window function node for NTILE
53
+ * Creates an NTILE window function.
54
+ *
55
+ * @param n - Number of buckets.
56
+ * @returns A `TypedExpression<number>` representing the `NTILE` window function.
52
57
  */
53
- export const ntile = (n: number): WindowFunctionNode =>
54
- buildWindowFunction('NTILE', [{ type: 'Literal', value: n }]);
58
+ export const ntile = (n: number): TypedExpression<number> =>
59
+ buildWindowFunction<number>('NTILE', [{ type: 'Literal', value: n }]);
55
60
 
56
61
  /**
57
- * Creates a LAG window function
58
- * @param col - Column to lag
59
- * @param offset - Offset (defaults to 1)
60
- * @param defaultValue - Default value if no row exists
61
- * @returns Window function node for LAG
62
+ * Creates a LAG window function.
63
+ *
64
+ * @param col - Column or expression to lag.
65
+ * @param offset - Optional offset (defaults to 1).
66
+ * @param defaultValue - Optional default value.
67
+ * @returns A `TypedExpression<T>` representing the `LAG` window function.
62
68
  */
63
- export const lag = (
69
+ export const lag = <T = any>(
64
70
  col: ColumnRef | ColumnNode,
65
71
  offset: number = 1,
66
72
  defaultValue?: LiteralNode['value']
67
- ): WindowFunctionNode => {
73
+ ): TypedExpression<T> => {
68
74
  const args: (ColumnNode | LiteralNode | JsonPathNode)[] = [
69
75
  columnOperand(col),
70
76
  { type: 'Literal', value: offset }
@@ -72,21 +78,22 @@ export const lag = (
72
78
  if (defaultValue !== undefined) {
73
79
  args.push({ type: 'Literal', value: defaultValue });
74
80
  }
75
- return buildWindowFunction('LAG', args);
81
+ return buildWindowFunction<T>('LAG', args);
76
82
  };
77
83
 
78
84
  /**
79
- * Creates a LEAD window function
80
- * @param col - Column to lead
81
- * @param offset - Offset (defaults to 1)
82
- * @param defaultValue - Default value if no row exists
83
- * @returns Window function node for LEAD
85
+ * Creates a LEAD window function.
86
+ *
87
+ * @param col - Column or expression to lead.
88
+ * @param offset - Optional offset (defaults to 1).
89
+ * @param defaultValue - Optional default value.
90
+ * @returns A `TypedExpression<T>` representing the `LEAD` window function.
84
91
  */
85
- export const lead = (
92
+ export const lead = <T = any>(
86
93
  col: ColumnRef | ColumnNode,
87
94
  offset: number = 1,
88
95
  defaultValue?: LiteralNode['value']
89
- ): WindowFunctionNode => {
96
+ ): TypedExpression<T> => {
90
97
  const args: (ColumnNode | LiteralNode | JsonPathNode)[] = [
91
98
  columnOperand(col),
92
99
  { type: 'Literal', value: offset }
@@ -94,39 +101,42 @@ export const lead = (
94
101
  if (defaultValue !== undefined) {
95
102
  args.push({ type: 'Literal', value: defaultValue });
96
103
  }
97
- return buildWindowFunction('LEAD', args);
104
+ return buildWindowFunction<T>('LEAD', args);
98
105
  };
99
106
 
100
107
  /**
101
- * Creates a FIRST_VALUE window function
102
- * @param col - Column to get first value from
103
- * @returns Window function node for FIRST_VALUE
108
+ * Creates a FIRST_VALUE window function.
109
+ *
110
+ * @param col - Column or expression to get first value from.
111
+ * @returns A `TypedExpression<T>` representing the `FIRST_VALUE` window function.
104
112
  */
105
- export const firstValue = (col: ColumnRef | ColumnNode): WindowFunctionNode =>
106
- buildWindowFunction('FIRST_VALUE', [columnOperand(col)]);
113
+ export const firstValue = <T = any>(col: ColumnRef | ColumnNode): TypedExpression<T> =>
114
+ buildWindowFunction<T>('FIRST_VALUE', [columnOperand(col)]);
107
115
 
108
116
  /**
109
- * Creates a LAST_VALUE window function
110
- * @param col - Column to get last value from
111
- * @returns Window function node for LAST_VALUE
117
+ * Creates a LAST_VALUE window function.
118
+ *
119
+ * @param col - Column or expression to get last value from.
120
+ * @returns A `TypedExpression<T>` representing the `LAST_VALUE` window function.
112
121
  */
113
- export const lastValue = (col: ColumnRef | ColumnNode): WindowFunctionNode =>
114
- buildWindowFunction('LAST_VALUE', [columnOperand(col)]);
122
+ export const lastValue = <T = any>(col: ColumnRef | ColumnNode): TypedExpression<T> =>
123
+ buildWindowFunction<T>('LAST_VALUE', [columnOperand(col)]);
115
124
 
116
125
  /**
117
- * Creates a custom window function
118
- * @param name - Window function name
119
- * @param args - Function arguments
120
- * @param partitionBy - Optional PARTITION BY columns
121
- * @param orderBy - Optional ORDER BY clauses
122
- * @returns Window function node
126
+ * Creates a custom window function.
127
+ *
128
+ * @param name - Window function name.
129
+ * @param args - Function arguments.
130
+ * @param partitionBy - Optional PARTITION BY columns.
131
+ * @param orderBy - Optional ORDER BY clauses.
132
+ * @returns A `TypedExpression<T>` representing the window function.
123
133
  */
124
- export const windowFunction = (
134
+ export const windowFunction = <T = any>(
125
135
  name: string,
126
136
  args: (ColumnRef | ColumnNode | LiteralNode | JsonPathNode)[] = [],
127
137
  partitionBy?: (ColumnRef | ColumnNode)[],
128
138
  orderBy?: { column: ColumnRef | ColumnNode; direction: OrderDirection }[]
129
- ): WindowFunctionNode => {
139
+ ): TypedExpression<T> => {
130
140
  const nodeArgs = args.map(arg => {
131
141
  if (typeof (arg as LiteralNode).value !== 'undefined') {
132
142
  return arg as LiteralNode;
@@ -144,5 +154,5 @@ export const windowFunction = (
144
154
  direction: o.direction
145
155
  }));
146
156
 
147
- return buildWindowFunction(name, nodeArgs, partitionNodes, orderNodes);
157
+ return buildWindowFunction<T>(name, nodeArgs, partitionNodes, orderNodes);
148
158
  };
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { ColumnDef } from '../../schema/column-types.js';
4
4
  import { columnOperand, valueToOperand } from '../ast/expression-builders.js';
5
- import { FunctionNode, OperandNode, isOperandNode } from '../ast/expression.js';
5
+ import { FunctionNode, OperandNode, isOperandNode, TypedExpression, asType } from '../ast/expression.js';
6
6
 
7
7
  type OperandInput = OperandNode | ColumnDef | string | number | boolean | null;
8
8
 
@@ -22,5 +22,14 @@ const fn = (key: string, args: OperandInput[]): FunctionNode => ({
22
22
  args: args.map(toOperand)
23
23
  });
24
24
 
25
- export const arrayAppend = (array: OperandInput, value: OperandInput): FunctionNode =>
26
- fn('ARRAY_APPEND', [array, value]);
25
+ const afn = <T = any[]>(key: string, args: OperandInput[]): TypedExpression<T> => asType<T>(fn(key, args));
26
+
27
+ /**
28
+ * Appends a value to the end of an array.
29
+ *
30
+ * @param array - Array column or value.
31
+ * @param value - Value to append.
32
+ * @returns A `TypedExpression<any[]>` representing the `ARRAY_APPEND` SQL function.
33
+ */
34
+ export const arrayAppend = (array: OperandInput, value: OperandInput): TypedExpression<any[]> =>
35
+ afn('ARRAY_APPEND', [array, value]);
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { ColumnDef } from '../../schema/column-types.js';
4
4
  import { columnOperand, valueToOperand } from '../ast/expression-builders.js';
5
- import { FunctionNode, OperandNode, isOperandNode } from '../ast/expression.js';
5
+ import { FunctionNode, OperandNode, isOperandNode, TypedExpression, asType } from '../ast/expression.js';
6
6
 
7
7
  type OperandInput = OperandNode | ColumnDef | string | number | boolean | null;
8
8
 
@@ -22,48 +22,58 @@ const fn = (key: string, args: OperandInput[]): FunctionNode => ({
22
22
  args: args.map(toOperand)
23
23
  });
24
24
 
25
+ const afn = <T = any>(key: string, args: OperandInput[]): TypedExpression<T> => asType<T>(fn(key, args));
26
+
25
27
  /**
26
28
  * Returns the first non-null value in a list.
27
- * @param args - The list of values to check.
28
- * @returns A FunctionNode representing the COALESCE SQL function.
29
+ *
30
+ * @param args - The list of values or columns to check.
31
+ * @returns A `TypedExpression<T>` representing the `COALESCE` SQL function.
32
+ *
33
+ * @example
34
+ * coalesce(users.nickname, users.firstName, 'Guest');
29
35
  */
30
- export const coalesce = (...args: OperandInput[]): FunctionNode => {
36
+ export const coalesce = <T = any>(...args: OperandInput[]): TypedExpression<T> => {
31
37
  if (args.length < 2) throw new Error('coalesce() expects at least 2 arguments');
32
- return fn('COALESCE', args);
38
+ return afn<T>('COALESCE', args);
33
39
  };
34
40
 
35
41
  /**
36
42
  * Returns null if the two arguments are equal, otherwise returns the first argument.
43
+ *
37
44
  * @param val1 - The first value.
38
- * @param val2 - The second value.
39
- * @returns A FunctionNode representing the NULLIF SQL function.
45
+ * @param val2 - The second value to compare against.
46
+ * @returns A `TypedExpression<T>` representing the `NULLIF` SQL function.
40
47
  */
41
- export const nullif = (val1: OperandInput, val2: OperandInput): FunctionNode => fn('NULLIF', [val1, val2]);
48
+ export const nullif = <T = any>(val1: OperandInput, val2: OperandInput): TypedExpression<T> => afn<T>('NULLIF', [val1, val2]);
42
49
 
43
50
  /**
44
51
  * Returns the largest value in a list.
45
- * @param args - The list of values to compare.
46
- * @returns A FunctionNode representing the GREATEST SQL function.
52
+ *
53
+ * @param args - The list of values or columns to compare.
54
+ * @returns A `TypedExpression<T>` representing the `GREATEST` SQL function.
47
55
  */
48
- export const greatest = (...args: OperandInput[]): FunctionNode => {
56
+ export const greatest = <T = any>(...args: OperandInput[]): TypedExpression<T> => {
49
57
  if (args.length < 2) throw new Error('greatest() expects at least 2 arguments');
50
- return fn('GREATEST', args);
58
+ return afn<T>('GREATEST', args);
51
59
  };
52
60
 
53
61
  /**
54
62
  * Returns the smallest value in a list.
55
- * @param args - The list of values to compare.
56
- * @returns A FunctionNode representing the LEAST SQL function.
63
+ *
64
+ * @param args - The list of values or columns to compare.
65
+ * @returns A `TypedExpression<T>` representing the `LEAST` SQL function.
57
66
  */
58
- export const least = (...args: OperandInput[]): FunctionNode => {
67
+ export const least = <T = any>(...args: OperandInput[]): TypedExpression<T> => {
59
68
  if (args.length < 2) throw new Error('least() expects at least 2 arguments');
60
- return fn('LEAST', args);
69
+ return afn<T>('LEAST', args);
61
70
  };
62
71
 
63
72
  /**
64
73
  * Returns the first argument if it is not null, otherwise returns the second argument.
74
+ *
65
75
  * @param val - The value to check.
66
76
  * @param defaultValue - The default value to return if val is null.
67
- * @returns A FunctionNode representing the COALESCE SQL function.
77
+ * @returns A `TypedExpression<T>` representing the `COALESCE` SQL function.
68
78
  */
69
- export const ifNull = (val: OperandInput, defaultValue: OperandInput): FunctionNode => coalesce(val, defaultValue);
79
+ export const ifNull = <T = any>(val: OperandInput, defaultValue: OperandInput): TypedExpression<T> => coalesce<T>(val, defaultValue);
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { ColumnDef } from '../../schema/column-types.js';
4
4
  import { columnOperand, valueToOperand } from '../ast/expression-builders.js';
5
- import { FunctionNode, OperandNode, isOperandNode } from '../ast/expression.js';
5
+ import { FunctionNode, OperandNode, isOperandNode, TypedExpression, asType } from '../ast/expression.js';
6
6
 
7
7
  type OperandInput = OperandNode | ColumnDef | string | number | boolean | null;
8
8
 
@@ -22,187 +22,216 @@ const fn = (key: string, args: OperandInput[]): FunctionNode => ({
22
22
  args: args.map(toOperand)
23
23
  });
24
24
 
25
+ const dfn = (key: string, args: OperandInput[]): TypedExpression<Date> => asType<Date>(fn(key, args));
26
+ const nfn = (key: string, args: OperandInput[]): TypedExpression<number> => asType<number>(fn(key, args));
27
+ const sfn = (key: string, args: OperandInput[]): TypedExpression<string> => asType<string>(fn(key, args));
28
+
25
29
  // ----------------------
26
30
  // Helper Functions
27
31
  // ----------------------
28
32
 
29
33
  /**
30
34
  * Returns the current local date and time.
31
- * @returns A FunctionNode representing the NOW() SQL function.
35
+ *
36
+ * @returns A `TypedExpression<Date>` representing the `NOW()` SQL function.
32
37
  */
33
- export const now = (): FunctionNode => fn('NOW', []);
38
+ export const now = (): TypedExpression<Date> => dfn('NOW', []);
34
39
 
35
40
  /**
36
- * Returns the current date without time.
37
- * @returns A FunctionNode representing the CURRENT_DATE SQL function.
41
+ * Returns the current date (without time).
42
+ *
43
+ * @returns A `TypedExpression<Date>` representing the `CURRENT_DATE` SQL function.
38
44
  */
39
- export const currentDate = (): FunctionNode => fn('CURRENT_DATE', []);
45
+ export const currentDate = (): TypedExpression<Date> => dfn('CURRENT_DATE', []);
40
46
 
41
47
  /**
42
- * Returns the current time without date.
43
- * @returns A FunctionNode representing the CURRENT_TIME SQL function.
48
+ * Returns the current time (without date).
49
+ *
50
+ * @returns A `TypedExpression<Date>` representing the `CURRENT_TIME` SQL function.
44
51
  */
45
- export const currentTime = (): FunctionNode => fn('CURRENT_TIME', []);
52
+ export const currentTime = (): TypedExpression<Date> => dfn('CURRENT_TIME', []);
46
53
 
47
54
  /**
48
55
  * Returns the current UTC date and time.
49
- * @returns A FunctionNode representing the UTC_NOW() SQL function.
56
+ *
57
+ * @returns A `TypedExpression<Date>` representing the `UTC_NOW()` SQL function.
50
58
  */
51
- export const utcNow = (): FunctionNode => fn('UTC_NOW', []);
59
+ export const utcNow = (): TypedExpression<Date> => dfn('UTC_NOW', []);
52
60
 
53
61
  /**
54
62
  * Returns the current local time.
55
- * @returns A FunctionNode representing the LOCALTIME SQL function.
63
+ *
64
+ * @returns A `TypedExpression<Date>` representing the `LOCALTIME` SQL function.
56
65
  */
57
- export const localTime = (): FunctionNode => fn('LOCALTIME', []);
66
+ export const localTime = (): TypedExpression<Date> => dfn('LOCALTIME', []);
58
67
 
59
68
  /**
60
69
  * Returns the current local timestamp.
61
- * @returns A FunctionNode representing the LOCALTIMESTAMP SQL function.
70
+ *
71
+ * @returns A `TypedExpression<Date>` representing the `LOCALTIMESTAMP` SQL function.
62
72
  */
63
- export const localTimestamp = (): FunctionNode => fn('LOCALTIMESTAMP', []);
73
+ export const localTimestamp = (): TypedExpression<Date> => dfn('LOCALTIMESTAMP', []);
64
74
 
65
75
  /**
66
76
  * Extracts a specified part from a date or datetime value.
67
- * @param part - The date part to extract (e.g., 'YEAR', 'MONTH', 'DAY', 'HOUR', 'MINUTE', 'SECOND').
68
- * @param date - The date or datetime value to extract from.
69
- * @returns A FunctionNode representing the EXTRACT SQL function.
77
+ *
78
+ * @param part - The date part to extract (e.g., 'YEAR', 'MONTH', 'DAY').
79
+ * @param date - The date/datetime value or column.
80
+ * @returns A `TypedExpression<number>` representing the `EXTRACT` SQL function.
70
81
  */
71
- export const extract = (part: OperandInput, date: OperandInput): FunctionNode => fn('EXTRACT', [part, date]);
82
+ export const extract = (part: OperandInput, date: OperandInput): TypedExpression<number> => nfn('EXTRACT', [part, date]);
72
83
 
73
84
  /**
74
85
  * Extracts the year from a date or datetime value.
75
- * @param date - The date or datetime value.
76
- * @returns A FunctionNode representing the YEAR SQL function.
86
+ *
87
+ * @param date - The date value.
88
+ * @returns A `TypedExpression<number>` representing the `YEAR` SQL function.
77
89
  */
78
- export const year = (date: OperandInput): FunctionNode => fn('YEAR', [date]);
90
+ export const year = (date: OperandInput): TypedExpression<number> => nfn('YEAR', [date]);
79
91
 
80
92
  /**
81
93
  * Extracts the month from a date or datetime value.
82
- * @param date - The date or datetime value.
83
- * @returns A FunctionNode representing the MONTH SQL function.
94
+ *
95
+ * @param date - The date value.
96
+ * @returns A `TypedExpression<number>` representing the `MONTH` SQL function.
84
97
  */
85
- export const month = (date: OperandInput): FunctionNode => fn('MONTH', [date]);
98
+ export const month = (date: OperandInput): TypedExpression<number> => nfn('MONTH', [date]);
86
99
 
87
100
  /**
88
101
  * Extracts the day of the month from a date or datetime value.
89
- * @param date - The date or datetime value.
90
- * @returns A FunctionNode representing the DAY SQL function.
102
+ *
103
+ * @param date - The date value.
104
+ * @returns A `TypedExpression<number>` representing the `DAY` SQL function.
91
105
  */
92
- export const day = (date: OperandInput): FunctionNode => fn('DAY', [date]);
106
+ export const day = (date: OperandInput): TypedExpression<number> => nfn('DAY', [date]);
93
107
 
94
108
  /**
95
109
  * Adds a specified time interval to a date or datetime value.
96
- * @param date - The date or datetime value to add to.
97
- * @param interval - The number of units to add.
98
- * @param unit - The unit type (e.g., 'DAY', 'MONTH', 'YEAR', 'HOUR', 'MINUTE', 'SECOND').
99
- * @returns A FunctionNode representing the DATE_ADD SQL function.
110
+ *
111
+ * @param date - The base date.
112
+ * @param interval - The numeric interval to add.
113
+ * @param unit - The unit (e.g., 'DAY', 'MONTH').
114
+ * @returns A `TypedExpression<Date>` representing the `DATE_ADD` SQL function.
100
115
  */
101
- export const dateAdd = (date: OperandInput, interval: OperandInput, unit: OperandInput): FunctionNode =>
102
- fn('DATE_ADD', [date, interval, unit]);
116
+ export const dateAdd = (date: OperandInput, interval: OperandInput, unit: OperandInput): TypedExpression<Date> =>
117
+ dfn('DATE_ADD', [date, interval, unit]);
103
118
 
104
119
  /**
105
120
  * Subtracts a specified time interval from a date or datetime value.
106
- * @param date - The date or datetime value to subtract from.
107
- * @param interval - The number of units to subtract.
108
- * @param unit - The unit type (e.g., 'DAY', 'MONTH', 'YEAR', 'HOUR', 'MINUTE', 'SECOND').
109
- * @returns A FunctionNode representing the DATE_SUB SQL function.
121
+ *
122
+ * @param date - The base date.
123
+ * @param interval - The numeric interval to subtract.
124
+ * @param unit - The unit (e.g., 'DAY', 'MONTH').
125
+ * @returns A `TypedExpression<Date>` representing the `DATE_SUB` SQL function.
110
126
  */
111
- export const dateSub = (date: OperandInput, interval: OperandInput, unit: OperandInput): FunctionNode =>
112
- fn('DATE_SUB', [date, interval, unit]);
127
+ export const dateSub = (date: OperandInput, interval: OperandInput, unit: OperandInput): TypedExpression<Date> =>
128
+ dfn('DATE_SUB', [date, interval, unit]);
113
129
 
114
130
  /**
115
131
  * Returns the difference between two dates in days.
116
- * @param date1 - The end date.
117
- * @param date2 - The start date.
118
- * @returns A FunctionNode representing the DATE_DIFF SQL function.
132
+ *
133
+ * @param date1 - End date.
134
+ * @param date2 - Start date.
135
+ * @returns A `TypedExpression<number>` representing the `DATE_DIFF` SQL function.
119
136
  */
120
- export const dateDiff = (date1: OperandInput, date2: OperandInput): FunctionNode => fn('DATE_DIFF', [date1, date2]);
137
+ export const dateDiff = (date1: OperandInput, date2: OperandInput): TypedExpression<number> => nfn('DATE_DIFF', [date1, date2]);
121
138
 
122
139
  /**
123
140
  * Converts a date or datetime value to a formatted string.
124
- * @param date - The date or datetime value to format.
125
- * @param format - The format string (dialect-specific).
126
- * @returns A FunctionNode representing the DATE_FORMAT SQL function.
141
+ *
142
+ * @param date - The date value.
143
+ * @param format - Dialect-specific format string.
144
+ * @returns A `TypedExpression<string>` representing the `DATE_FORMAT` SQL function.
127
145
  */
128
- export const dateFormat = (date: OperandInput, format: OperandInput): FunctionNode => fn('DATE_FORMAT', [date, format]);
146
+ export const dateFormat = (date: OperandInput, format: OperandInput): TypedExpression<string> => sfn('DATE_FORMAT', [date, format]);
129
147
 
130
148
  /**
131
- * Returns the current Unix timestamp (seconds since 1970-01-01 00:00:00 UTC).
132
- * @returns A FunctionNode representing the UNIX_TIMESTAMP SQL function.
149
+ * Returns the current Unix timestamp (seconds since epoch).
150
+ *
151
+ * @returns A `TypedExpression<number>` representing the `UNIX_TIMESTAMP` SQL function.
133
152
  */
134
- export const unixTimestamp = (): FunctionNode => fn('UNIX_TIMESTAMP', []);
153
+ export const unixTimestamp = (): TypedExpression<number> => nfn('UNIX_TIMESTAMP', []);
135
154
 
136
155
  /**
137
- * Converts a Unix timestamp (seconds since 1970-01-01 00:00:00 UTC) to a date.
138
- * @param timestamp - Unix timestamp in seconds.
139
- * @returns A FunctionNode representing the FROM_UNIXTIME SQL function.
156
+ * Converts a Unix timestamp to a Date.
157
+ *
158
+ * @param timestamp - Seconds since epoch.
159
+ * @returns A `TypedExpression<Date>` representing the `FROM_UNIXTIME` SQL function.
140
160
  */
141
- export const fromUnixTime = (timestamp: OperandInput): FunctionNode => fn('FROM_UNIXTIME', [timestamp]);
161
+ export const fromUnixTime = (timestamp: OperandInput): TypedExpression<Date> => dfn('FROM_UNIXTIME', [timestamp]);
142
162
 
143
163
  /**
144
164
  * Returns the last day of the month for a given date.
165
+ *
145
166
  * @param date - The date value.
146
- * @returns A FunctionNode representing the END_OF_MONTH SQL function.
167
+ * @returns A `TypedExpression<Date>` representing the `END_OF_MONTH` SQL function.
147
168
  */
148
- export const endOfMonth = (date: OperandInput): FunctionNode => fn('END_OF_MONTH', [date]);
169
+ export const endOfMonth = (date: OperandInput): TypedExpression<Date> => dfn('END_OF_MONTH', [date]);
149
170
 
150
171
  /**
151
172
  * Returns the index of the weekday for a given date (1 = Sunday, 2 = Monday, etc.).
173
+ *
152
174
  * @param date - The date value.
153
- * @returns A FunctionNode representing the DAY_OF_WEEK SQL function.
175
+ * @returns A `TypedExpression<number>` representing the `DAY_OF_WEEK` SQL function.
154
176
  */
155
- export const dayOfWeek = (date: OperandInput): FunctionNode => fn('DAY_OF_WEEK', [date]);
177
+ export const dayOfWeek = (date: OperandInput): TypedExpression<number> => nfn('DAY_OF_WEEK', [date]);
156
178
 
157
179
  /**
158
180
  * Returns the week number of the year for a given date.
181
+ *
159
182
  * @param date - The date value.
160
- * @returns A FunctionNode representing the WEEK_OF_YEAR SQL function.
183
+ * @returns A `TypedExpression<number>` representing the `WEEK_OF_YEAR` SQL function.
161
184
  */
162
- export const weekOfYear = (date: OperandInput): FunctionNode => fn('WEEK_OF_YEAR', [date]);
185
+ export const weekOfYear = (date: OperandInput): TypedExpression<number> => nfn('WEEK_OF_YEAR', [date]);
163
186
 
164
187
  /**
165
- * Truncates a date or datetime value to a specified precision (e.g., first day of the month/year).
166
- * @param part - The truncation precision (e.g., 'YEAR', 'MONTH', 'DAY').
167
- * @param date - The date or datetime value to truncate.
168
- * @returns A FunctionNode representing the DATE_TRUNC SQL function.
188
+ * Truncates a date or datetime value to a specified precision.
189
+ *
190
+ * @param part - The precision (e.g., 'YEAR', 'MONTH').
191
+ * @param date - The date to truncate.
192
+ * @returns A `TypedExpression<Date>` representing the `DATE_TRUNC` SQL function.
169
193
  */
170
- export const dateTrunc = (part: OperandInput, date: OperandInput): FunctionNode => fn('DATE_TRUNC', [part, date]);
194
+ export const dateTrunc = (part: OperandInput, date: OperandInput): TypedExpression<Date> => dfn('DATE_TRUNC', [part, date]);
171
195
 
172
196
  /**
173
- * Returns the difference between two timestamps as an interval.
174
- * @param timestamp - The end timestamp.
175
- * @param baseTimestamp - The start timestamp (optional, defaults to current time).
176
- * @returns A FunctionNode representing the AGE SQL function.
197
+ * Returns the difference between two timestamps as an interval string.
198
+ *
199
+ * @param timestamp - End timestamp.
200
+ * @param baseTimestamp - Optional start timestamp.
201
+ * @returns A `TypedExpression<string>` representing the `AGE` SQL function.
177
202
  */
178
- export const age = (timestamp: OperandInput, baseTimestamp?: OperandInput): FunctionNode =>
179
- baseTimestamp === undefined ? fn('AGE', [timestamp]) : fn('AGE', [timestamp, baseTimestamp]);
203
+ export const age = (timestamp: OperandInput, baseTimestamp?: OperandInput): TypedExpression<string> =>
204
+ baseTimestamp === undefined ? sfn('AGE', [timestamp]) : sfn('AGE', [timestamp, baseTimestamp]);
180
205
 
181
206
  /**
182
207
  * Extracts the hour from a date or datetime value.
183
- * @param date - The date or datetime value.
184
- * @returns A FunctionNode representing the HOUR SQL function.
208
+ *
209
+ * @param date - The date value.
210
+ * @returns A `TypedExpression<number>` representing the `HOUR` SQL function.
185
211
  */
186
- export const hour = (date: OperandInput): FunctionNode => fn('HOUR', [date]);
212
+ export const hour = (date: OperandInput): TypedExpression<number> => nfn('HOUR', [date]);
187
213
 
188
214
  /**
189
215
  * Extracts the minute from a date or datetime value.
190
- * @param date - The date or datetime value.
191
- * @returns A FunctionNode representing the MINUTE SQL function.
216
+ *
217
+ * @param date - The date value.
218
+ * @returns A `TypedExpression<number>` representing the `MINUTE` SQL function.
192
219
  */
193
- export const minute = (date: OperandInput): FunctionNode => fn('MINUTE', [date]);
220
+ export const minute = (date: OperandInput): TypedExpression<number> => nfn('MINUTE', [date]);
194
221
 
195
222
  /**
196
223
  * Extracts the second from a date or datetime value.
197
- * @param date - The date or datetime value.
198
- * @returns A FunctionNode representing the SECOND SQL function.
224
+ *
225
+ * @param date - The date value.
226
+ * @returns A `TypedExpression<number>` representing the `SECOND` SQL function.
199
227
  */
200
- export const second = (date: OperandInput): FunctionNode => fn('SECOND', [date]);
228
+ export const second = (date: OperandInput): TypedExpression<number> => nfn('SECOND', [date]);
201
229
 
202
230
  /**
203
231
  * Extracts the quarter from a date or datetime value (1-4).
204
- * @param date - The date or datetime value.
205
- * @returns A FunctionNode representing the QUARTER SQL function.
232
+ *
233
+ * @param date - The date value.
234
+ * @returns A `TypedExpression<number>` representing the `QUARTER` SQL function.
206
235
  */
207
- export const quarter = (date: OperandInput): FunctionNode => fn('QUARTER', [date]);
236
+ export const quarter = (date: OperandInput): TypedExpression<number> => nfn('QUARTER', [date]);
208
237