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/README.md +10 -8
- package/dist/index.cjs +187 -119
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +844 -422
- package/dist/index.d.ts +844 -422
- package/dist/index.js +184 -119
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/ast/aggregate-functions.ts +13 -4
- package/src/core/ast/expression-builders.ts +325 -111
- package/src/core/ast/expression.ts +9 -0
- package/src/core/ast/window-functions.ts +62 -52
- package/src/core/functions/array.ts +12 -3
- package/src/core/functions/control-flow.ts +28 -18
- package/src/core/functions/datetime.ts +113 -84
- package/src/core/functions/json.ts +40 -8
- package/src/core/functions/numeric.ts +116 -79
- package/src/core/functions/text.ts +181 -114
- package/src/decorators/bootstrap.ts +23 -19
- package/src/query-builder/hydration-planner.ts +14 -16
- package/src/query-builder/select.ts +91 -55
|
@@ -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,246 +22,313 @@ const fn = (key: string, args: OperandInput[]): FunctionNode => ({
|
|
|
22
22
|
args: args.map(toOperand)
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
+
const sfn = (key: string, args: OperandInput[]): TypedExpression<string> => asType<string>(fn(key, args));
|
|
26
|
+
const nfn = (key: string, args: OperandInput[]): TypedExpression<number> => asType<number>(fn(key, args));
|
|
27
|
+
|
|
25
28
|
/**
|
|
26
29
|
* Converts a string to lowercase.
|
|
27
|
-
*
|
|
28
|
-
* @
|
|
30
|
+
*
|
|
31
|
+
* @param value - The string value or column.
|
|
32
|
+
* @returns A `TypedExpression<string>` representing the `LOWER` SQL function.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* lower(users.email);
|
|
29
36
|
*/
|
|
30
|
-
export const lower = (value: OperandInput):
|
|
37
|
+
export const lower = (value: OperandInput): TypedExpression<string> => sfn('LOWER', [value]);
|
|
31
38
|
|
|
32
39
|
/**
|
|
33
40
|
* Converts a string to uppercase.
|
|
34
|
-
*
|
|
35
|
-
* @
|
|
41
|
+
*
|
|
42
|
+
* @param value - The string value or column.
|
|
43
|
+
* @returns A `TypedExpression<string>` representing the `UPPER` SQL function.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* upper(users.firstName);
|
|
36
47
|
*/
|
|
37
|
-
export const upper = (value: OperandInput):
|
|
48
|
+
export const upper = (value: OperandInput): TypedExpression<string> => sfn('UPPER', [value]);
|
|
38
49
|
|
|
39
50
|
/**
|
|
40
51
|
* Returns the ASCII code of the first character of a string.
|
|
41
|
-
*
|
|
42
|
-
* @
|
|
52
|
+
*
|
|
53
|
+
* @param value - The string value or column.
|
|
54
|
+
* @returns A `TypedExpression<number>` representing the `ASCII` SQL function.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ascii(users.initial);
|
|
43
58
|
*/
|
|
44
|
-
export const ascii = (value: OperandInput):
|
|
59
|
+
export const ascii = (value: OperandInput): TypedExpression<number> => nfn('ASCII', [value]);
|
|
45
60
|
|
|
46
61
|
/**
|
|
47
62
|
* Returns a string from one or more ASCII codes.
|
|
48
|
-
*
|
|
49
|
-
* @
|
|
63
|
+
*
|
|
64
|
+
* @param codes - One or more ASCII codes.
|
|
65
|
+
* @returns A `TypedExpression<string>` representing the `CHAR` SQL function.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* char(65, 66, 67); // 'ABC'
|
|
50
69
|
*/
|
|
51
|
-
export const char = (...codes: OperandInput[]):
|
|
70
|
+
export const char = (...codes: OperandInput[]): TypedExpression<string> => {
|
|
52
71
|
if (codes.length === 0) throw new Error('char() expects at least 1 argument');
|
|
53
|
-
return
|
|
72
|
+
return sfn('CHAR', codes);
|
|
54
73
|
};
|
|
55
74
|
|
|
56
75
|
/**
|
|
57
76
|
* Returns the number of characters in a string.
|
|
58
|
-
*
|
|
59
|
-
* @
|
|
77
|
+
*
|
|
78
|
+
* @param value - The string value or column.
|
|
79
|
+
* @returns A `TypedExpression<number>` representing the `CHAR_LENGTH` SQL function.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* charLength(users.bio);
|
|
60
83
|
*/
|
|
61
|
-
export const charLength = (value: OperandInput):
|
|
84
|
+
export const charLength = (value: OperandInput): TypedExpression<number> => nfn('CHAR_LENGTH', [value]);
|
|
62
85
|
|
|
63
86
|
/**
|
|
64
87
|
* Returns the length of a string in bytes or characters.
|
|
65
|
-
*
|
|
66
|
-
* @
|
|
88
|
+
*
|
|
89
|
+
* @param value - The string value or column.
|
|
90
|
+
* @returns A `TypedExpression<number>` representing the `LENGTH` SQL function.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* length(users.password);
|
|
67
94
|
*/
|
|
68
|
-
export const length = (value: OperandInput):
|
|
95
|
+
export const length = (value: OperandInput): TypedExpression<number> => nfn('LENGTH', [value]);
|
|
69
96
|
|
|
70
97
|
/**
|
|
71
98
|
* Removes leading and trailing whitespace or specified characters from a string.
|
|
72
|
-
*
|
|
73
|
-
* @param
|
|
74
|
-
* @
|
|
99
|
+
*
|
|
100
|
+
* @param value - The string value or column.
|
|
101
|
+
* @param chars - Optional characters to trim.
|
|
102
|
+
* @returns A `TypedExpression<string>` representing the `TRIM` SQL function.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* trim(users.name);
|
|
106
|
+
* trim(users.path, '/');
|
|
75
107
|
*/
|
|
76
|
-
export const trim = (value: OperandInput, chars?: OperandInput):
|
|
77
|
-
chars === undefined ?
|
|
108
|
+
export const trim = (value: OperandInput, chars?: OperandInput): TypedExpression<string> =>
|
|
109
|
+
chars === undefined ? sfn('TRIM', [value]) : sfn('TRIM', [value, chars]);
|
|
78
110
|
|
|
79
111
|
/**
|
|
80
112
|
* Removes leading whitespace from a string.
|
|
81
|
-
*
|
|
82
|
-
* @
|
|
113
|
+
*
|
|
114
|
+
* @param value - The string value or column.
|
|
115
|
+
* @returns A `TypedExpression<string>` representing the `LTRIM` SQL function.
|
|
83
116
|
*/
|
|
84
|
-
export const ltrim = (value: OperandInput):
|
|
117
|
+
export const ltrim = (value: OperandInput): TypedExpression<string> => sfn('LTRIM', [value]);
|
|
85
118
|
|
|
86
119
|
/**
|
|
87
120
|
* Removes trailing whitespace from a string.
|
|
88
|
-
*
|
|
89
|
-
* @
|
|
121
|
+
*
|
|
122
|
+
* @param value - The string value or column.
|
|
123
|
+
* @returns A `TypedExpression<string>` representing the `RTRIM` SQL function.
|
|
90
124
|
*/
|
|
91
|
-
export const rtrim = (value: OperandInput):
|
|
125
|
+
export const rtrim = (value: OperandInput): TypedExpression<string> => sfn('RTRIM', [value]);
|
|
92
126
|
|
|
93
127
|
/**
|
|
94
128
|
* Concatenates two or more strings.
|
|
95
|
-
*
|
|
96
|
-
* @
|
|
129
|
+
*
|
|
130
|
+
* @param args - The strings or columns to concatenate.
|
|
131
|
+
* @returns A `TypedExpression<string>` representing the `CONCAT` SQL function.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* concat(users.firstName, ' ', users.lastName);
|
|
97
135
|
*/
|
|
98
|
-
export const concat = (...args: OperandInput[]):
|
|
136
|
+
export const concat = (...args: OperandInput[]): TypedExpression<string> => {
|
|
99
137
|
if (args.length < 2) throw new Error('concat() expects at least 2 arguments');
|
|
100
|
-
return
|
|
138
|
+
return sfn('CONCAT', args);
|
|
101
139
|
};
|
|
102
140
|
|
|
103
141
|
/**
|
|
104
142
|
* Concatenates strings with a separator.
|
|
143
|
+
*
|
|
105
144
|
* @param separator - The separator string.
|
|
106
|
-
* @param args - The strings to concatenate.
|
|
107
|
-
* @returns A
|
|
145
|
+
* @param args - The strings or columns to concatenate.
|
|
146
|
+
* @returns A `TypedExpression<string>` representing the `CONCAT_WS` SQL function.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* concatWs(', ', users.lastName, users.firstName);
|
|
108
150
|
*/
|
|
109
|
-
export const concatWs = (separator: OperandInput, ...args: OperandInput[]):
|
|
151
|
+
export const concatWs = (separator: OperandInput, ...args: OperandInput[]): TypedExpression<string> => {
|
|
110
152
|
if (args.length < 1) throw new Error('concatWs() expects at least 2 arguments including the separator');
|
|
111
|
-
return
|
|
153
|
+
return sfn('CONCAT_WS', [separator, ...args]);
|
|
112
154
|
};
|
|
113
155
|
|
|
114
156
|
/**
|
|
115
157
|
* Extracts a substring from a string.
|
|
116
|
-
*
|
|
117
|
-
* @param
|
|
118
|
-
* @param
|
|
119
|
-
* @
|
|
158
|
+
*
|
|
159
|
+
* @param value - The input string or column.
|
|
160
|
+
* @param start - The starting position (1-indexed).
|
|
161
|
+
* @param length - Optional length of the substring.
|
|
162
|
+
* @returns A `TypedExpression<string>` representing the `SUBSTR` SQL function.
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* substr(users.token, 1, 8);
|
|
120
166
|
*/
|
|
121
|
-
export const substr = (value: OperandInput, start: OperandInput, length?: OperandInput):
|
|
122
|
-
length === undefined ?
|
|
167
|
+
export const substr = (value: OperandInput, start: OperandInput, length?: OperandInput): TypedExpression<string> =>
|
|
168
|
+
length === undefined ? sfn('SUBSTR', [value, start]) : sfn('SUBSTR', [value, start, length]);
|
|
123
169
|
|
|
124
170
|
/**
|
|
125
171
|
* Returns the leftmost characters of a string.
|
|
126
|
-
*
|
|
127
|
-
* @param
|
|
128
|
-
* @
|
|
172
|
+
*
|
|
173
|
+
* @param value - The string value or column.
|
|
174
|
+
* @param len - Number of characters to return.
|
|
175
|
+
* @returns A `TypedExpression<string>` representing the `LEFT` SQL function.
|
|
129
176
|
*/
|
|
130
|
-
export const left = (value: OperandInput, len: OperandInput):
|
|
177
|
+
export const left = (value: OperandInput, len: OperandInput): TypedExpression<string> => sfn('LEFT', [value, len]);
|
|
131
178
|
|
|
132
179
|
/**
|
|
133
180
|
* Returns the rightmost characters of a string.
|
|
134
|
-
*
|
|
135
|
-
* @param
|
|
136
|
-
* @
|
|
181
|
+
*
|
|
182
|
+
* @param value - The string value or column.
|
|
183
|
+
* @param len - Number of characters to return.
|
|
184
|
+
* @returns A `TypedExpression<string>` representing the `RIGHT` SQL function.
|
|
137
185
|
*/
|
|
138
|
-
export const right = (value: OperandInput, len: OperandInput):
|
|
186
|
+
export const right = (value: OperandInput, len: OperandInput): TypedExpression<string> => sfn('RIGHT', [value, len]);
|
|
139
187
|
|
|
140
188
|
/**
|
|
141
189
|
* Returns the position of a substring in a string.
|
|
190
|
+
*
|
|
142
191
|
* @param substring - The substring to search for.
|
|
143
|
-
* @param value - The string to search
|
|
144
|
-
* @returns A
|
|
192
|
+
* @param value - The string or column to search within.
|
|
193
|
+
* @returns A `TypedExpression<number>` representing the `POSITION` SQL function.
|
|
145
194
|
*/
|
|
146
|
-
export const position = (substring: OperandInput, value: OperandInput):
|
|
195
|
+
export const position = (substring: OperandInput, value: OperandInput): TypedExpression<number> => nfn('POSITION', [substring, value]);
|
|
147
196
|
|
|
148
197
|
/**
|
|
149
198
|
* Returns the position of a substring in a string.
|
|
150
|
-
*
|
|
199
|
+
*
|
|
200
|
+
* @param value - The string or column to search within.
|
|
151
201
|
* @param substring - The substring to search for.
|
|
152
|
-
* @returns A
|
|
202
|
+
* @returns A `TypedExpression<number>` representing the `INSTR` SQL function.
|
|
153
203
|
*/
|
|
154
|
-
export const instr = (value: OperandInput, substring: OperandInput):
|
|
204
|
+
export const instr = (value: OperandInput, substring: OperandInput): TypedExpression<number> => nfn('INSTR', [value, substring]);
|
|
155
205
|
|
|
156
206
|
/**
|
|
157
207
|
* Returns the position of a substring in a string, optionally starting from a position.
|
|
158
|
-
*
|
|
159
|
-
* @param
|
|
160
|
-
* @param
|
|
161
|
-
* @
|
|
208
|
+
*
|
|
209
|
+
* @param substring - Substring to find.
|
|
210
|
+
* @param value - String/column to search.
|
|
211
|
+
* @param start - Optional starting position.
|
|
212
|
+
* @returns A `TypedExpression<number>` representing the `LOCATE` SQL function.
|
|
162
213
|
*/
|
|
163
|
-
export const locate = (substring: OperandInput, value: OperandInput, start?: OperandInput):
|
|
164
|
-
start === undefined ?
|
|
214
|
+
export const locate = (substring: OperandInput, value: OperandInput, start?: OperandInput): TypedExpression<number> =>
|
|
215
|
+
start === undefined ? nfn('LOCATE', [substring, value]) : nfn('LOCATE', [substring, value, start]);
|
|
165
216
|
|
|
166
217
|
/**
|
|
167
218
|
* Replaces occurrences of a substring in a string.
|
|
168
|
-
*
|
|
169
|
-
* @param
|
|
170
|
-
* @param
|
|
171
|
-
* @
|
|
219
|
+
*
|
|
220
|
+
* @param value - The original string or column.
|
|
221
|
+
* @param search - Substring to search for.
|
|
222
|
+
* @param replacement - Replacement string.
|
|
223
|
+
* @returns A `TypedExpression<string>` representing the `REPLACE` SQL function.
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* replace(users.email, 'old.com', 'new.com');
|
|
172
227
|
*/
|
|
173
|
-
export const replace = (value: OperandInput, search: OperandInput, replacement: OperandInput):
|
|
174
|
-
|
|
228
|
+
export const replace = (value: OperandInput, search: OperandInput, replacement: OperandInput): TypedExpression<string> =>
|
|
229
|
+
sfn('REPLACE', [value, search, replacement]);
|
|
175
230
|
|
|
176
231
|
/**
|
|
177
232
|
* Repeats a string a specified number of times.
|
|
233
|
+
*
|
|
178
234
|
* @param value - The string to repeat.
|
|
179
|
-
* @param count -
|
|
180
|
-
* @returns A
|
|
235
|
+
* @param count - How many times to repeat.
|
|
236
|
+
* @returns A `TypedExpression<string>` representing the `REPEAT` SQL function.
|
|
181
237
|
*/
|
|
182
|
-
export const repeat = (value: OperandInput, count: OperandInput):
|
|
238
|
+
export const repeat = (value: OperandInput, count: OperandInput): TypedExpression<string> => sfn('REPEAT', [value, count]);
|
|
183
239
|
|
|
184
240
|
/**
|
|
185
241
|
* Left-pads a string to a certain length with another string.
|
|
186
|
-
*
|
|
187
|
-
* @param
|
|
188
|
-
* @param
|
|
189
|
-
* @
|
|
242
|
+
*
|
|
243
|
+
* @param value - The string/column to pad.
|
|
244
|
+
* @param len - Target length.
|
|
245
|
+
* @param pad - Padding string.
|
|
246
|
+
* @returns A `TypedExpression<string>` representing the `LPAD` SQL function.
|
|
190
247
|
*/
|
|
191
|
-
export const lpad = (value: OperandInput, len: OperandInput, pad: OperandInput):
|
|
192
|
-
|
|
248
|
+
export const lpad = (value: OperandInput, len: OperandInput, pad: OperandInput): TypedExpression<string> =>
|
|
249
|
+
sfn('LPAD', [value, len, pad]);
|
|
193
250
|
|
|
194
251
|
/**
|
|
195
252
|
* Right-pads a string to a certain length with another string.
|
|
196
|
-
*
|
|
197
|
-
* @param
|
|
198
|
-
* @param
|
|
199
|
-
* @
|
|
253
|
+
*
|
|
254
|
+
* @param value - The string/column to pad.
|
|
255
|
+
* @param len - Target length.
|
|
256
|
+
* @param pad - Padding string.
|
|
257
|
+
* @returns A `TypedExpression<string>` representing the `RPAD` SQL function.
|
|
200
258
|
*/
|
|
201
|
-
export const rpad = (value: OperandInput, len: OperandInput, pad: OperandInput):
|
|
202
|
-
|
|
259
|
+
export const rpad = (value: OperandInput, len: OperandInput, pad: OperandInput): TypedExpression<string> =>
|
|
260
|
+
sfn('RPAD', [value, len, pad]);
|
|
203
261
|
|
|
204
262
|
/**
|
|
205
263
|
* Returns a string consisting of a specified number of spaces.
|
|
206
|
-
*
|
|
207
|
-
* @
|
|
264
|
+
*
|
|
265
|
+
* @param count - Number of spaces.
|
|
266
|
+
* @returns A `TypedExpression<string>` representing the `SPACE` SQL function.
|
|
208
267
|
*/
|
|
209
|
-
export const space = (count: OperandInput):
|
|
268
|
+
export const space = (count: OperandInput): TypedExpression<string> => sfn('SPACE', [count]);
|
|
210
269
|
|
|
211
270
|
/**
|
|
212
271
|
* Reverses a string.
|
|
213
|
-
*
|
|
214
|
-
* @
|
|
272
|
+
*
|
|
273
|
+
* @param value - The string value or column.
|
|
274
|
+
* @returns A `TypedExpression<string>` representing the `REVERSE` SQL function.
|
|
215
275
|
*/
|
|
216
|
-
export const reverse = (value: OperandInput):
|
|
276
|
+
export const reverse = (value: OperandInput): TypedExpression<string> => sfn('REVERSE', [value]);
|
|
217
277
|
|
|
218
278
|
/**
|
|
219
279
|
* Capitalizes the first letter of each word in a string.
|
|
220
|
-
*
|
|
221
|
-
* @
|
|
280
|
+
*
|
|
281
|
+
* @param value - The string value or column.
|
|
282
|
+
* @returns A `TypedExpression<string>` representing the `INITCAP` SQL function.
|
|
222
283
|
*/
|
|
223
|
-
export const initcap = (value: OperandInput):
|
|
284
|
+
export const initcap = (value: OperandInput): TypedExpression<string> => sfn('INITCAP', [value]);
|
|
224
285
|
|
|
225
286
|
/**
|
|
226
287
|
* Returns the MD5 hash of a string.
|
|
227
|
-
*
|
|
228
|
-
* @
|
|
288
|
+
*
|
|
289
|
+
* @param value - The string value or column.
|
|
290
|
+
* @returns A `TypedExpression<string>` representing the `MD5` SQL function.
|
|
229
291
|
*/
|
|
230
|
-
export const md5 = (value: OperandInput):
|
|
292
|
+
export const md5 = (value: OperandInput): TypedExpression<string> => sfn('MD5', [value]);
|
|
231
293
|
|
|
232
294
|
/**
|
|
233
295
|
* Returns the SHA-1 hash of a string.
|
|
234
|
-
*
|
|
235
|
-
* @
|
|
296
|
+
*
|
|
297
|
+
* @param value - The string value or column.
|
|
298
|
+
* @returns A `TypedExpression<string>` representing the `SHA1` SQL function.
|
|
236
299
|
*/
|
|
237
|
-
export const sha1 = (value: OperandInput):
|
|
300
|
+
export const sha1 = (value: OperandInput): TypedExpression<string> => sfn('SHA1', [value]);
|
|
238
301
|
|
|
239
302
|
/**
|
|
240
303
|
* Returns the SHA-2 hash of a string with a specified bit length.
|
|
241
|
-
*
|
|
242
|
-
* @param
|
|
243
|
-
* @
|
|
304
|
+
*
|
|
305
|
+
* @param value - The input.
|
|
306
|
+
* @param bits - Bit length (e.g., 256, 512).
|
|
307
|
+
* @returns A `TypedExpression<string>` representing the `SHA2` SQL function.
|
|
244
308
|
*/
|
|
245
|
-
export const sha2 = (value: OperandInput, bits: OperandInput):
|
|
309
|
+
export const sha2 = (value: OperandInput, bits: OperandInput): TypedExpression<string> => sfn('SHA2', [value, bits]);
|
|
246
310
|
|
|
247
311
|
/**
|
|
248
312
|
* Returns the length of a string in bits.
|
|
249
|
-
*
|
|
250
|
-
* @
|
|
313
|
+
*
|
|
314
|
+
* @param value - String value or column.
|
|
315
|
+
* @returns A `TypedExpression<number>` representing the `BIT_LENGTH` SQL function.
|
|
251
316
|
*/
|
|
252
|
-
export const bitLength = (value: OperandInput):
|
|
317
|
+
export const bitLength = (value: OperandInput): TypedExpression<number> => nfn('BIT_LENGTH', [value]);
|
|
253
318
|
|
|
254
319
|
/**
|
|
255
320
|
* Returns the length of a string in bytes.
|
|
256
|
-
*
|
|
257
|
-
* @
|
|
321
|
+
*
|
|
322
|
+
* @param value - String value or column.
|
|
323
|
+
* @returns A `TypedExpression<number>` representing the `OCTET_LENGTH` SQL function.
|
|
258
324
|
*/
|
|
259
|
-
export const octetLength = (value: OperandInput):
|
|
325
|
+
export const octetLength = (value: OperandInput): TypedExpression<number> => nfn('OCTET_LENGTH', [value]);
|
|
260
326
|
|
|
261
327
|
/**
|
|
262
328
|
* Returns a string from an ASCII code.
|
|
263
|
-
*
|
|
264
|
-
* @
|
|
329
|
+
*
|
|
330
|
+
* @param code - ASCII code.
|
|
331
|
+
* @returns A `TypedExpression<string>` representing the `CHR` SQL function.
|
|
265
332
|
*/
|
|
266
|
-
export const chr = (code: OperandInput):
|
|
333
|
+
export const chr = (code: OperandInput): TypedExpression<string> => sfn('CHR', [code]);
|
|
267
334
|
|
|
@@ -25,13 +25,14 @@ import {
|
|
|
25
25
|
|
|
26
26
|
import { tableRef, type TableRef } from '../schema/table.js';
|
|
27
27
|
import {
|
|
28
|
-
SelectableKeys,
|
|
29
|
-
ColumnDef,
|
|
30
|
-
HasManyCollection,
|
|
31
|
-
HasOneReference,
|
|
32
|
-
BelongsToReference,
|
|
33
|
-
ManyToManyCollection
|
|
34
|
-
|
|
28
|
+
SelectableKeys,
|
|
29
|
+
ColumnDef,
|
|
30
|
+
HasManyCollection,
|
|
31
|
+
HasOneReference,
|
|
32
|
+
BelongsToReference,
|
|
33
|
+
ManyToManyCollection,
|
|
34
|
+
EntityInstance
|
|
35
|
+
} from '../schema/types.js';
|
|
35
36
|
|
|
36
37
|
const unwrapTarget = (target: EntityOrTableTargetResolver): EntityOrTableTarget => {
|
|
37
38
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
@@ -196,9 +197,9 @@ type NonFunctionKeys<T> = {
|
|
|
196
197
|
type RelationKeys<TEntity extends object> =
|
|
197
198
|
Exclude<NonFunctionKeys<TEntity>, SelectableKeys<TEntity>> & string;
|
|
198
199
|
|
|
199
|
-
type EntityTable<TEntity extends object> =
|
|
200
|
-
Omit<TableDef<{ [K in SelectableKeys<TEntity>]: ColumnDef }>, 'relations'> & {
|
|
201
|
-
relations: {
|
|
200
|
+
type EntityTable<TEntity extends object> =
|
|
201
|
+
Omit<TableDef<{ [K in SelectableKeys<TEntity>]: ColumnDef }>, 'relations'> & {
|
|
202
|
+
relations: {
|
|
202
203
|
[K in RelationKeys<TEntity>]:
|
|
203
204
|
NonNullable<TEntity[K]> extends HasManyCollection<infer TChild>
|
|
204
205
|
? HasManyRelation<EntityTable<NonNullable<TChild> & object>>
|
|
@@ -214,15 +215,18 @@ type EntityTable<TEntity extends object> =
|
|
|
214
215
|
: NonNullable<TEntity[K]> extends object
|
|
215
216
|
? BelongsToRelation<EntityTable<NonNullable<TEntity[K]> & object>>
|
|
216
217
|
: never;
|
|
217
|
-
};
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
export
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
218
|
+
};
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
export type DecoratedEntityInstance<TEntity extends object> =
|
|
222
|
+
TEntity & EntityInstance<EntityTable<TEntity>>;
|
|
223
|
+
|
|
224
|
+
export const selectFromEntity = <TEntity extends object>(
|
|
225
|
+
ctor: EntityConstructor<TEntity>
|
|
226
|
+
): SelectQueryBuilder<DecoratedEntityInstance<TEntity>, EntityTable<TEntity>> => {
|
|
227
|
+
const table = getTableDefFromEntity(ctor);
|
|
228
|
+
if (!table) {
|
|
229
|
+
throw new Error(`Entity '${ctor.name}' is not registered with decorators or has not been bootstrapped`);
|
|
226
230
|
}
|
|
227
231
|
return new SelectQueryBuilder(
|
|
228
232
|
table as unknown as EntityTable<TEntity>,
|
|
@@ -31,22 +31,20 @@ export class HydrationPlanner {
|
|
|
31
31
|
* @param columns - Columns to capture
|
|
32
32
|
* @returns Updated HydrationPlanner with captured columns
|
|
33
33
|
*/
|
|
34
|
-
captureRootColumns(columns: ProjectionNode[]): HydrationPlanner {
|
|
35
|
-
const currentPlan = this.getPlanOrDefault();
|
|
36
|
-
const rootCols = new Set(currentPlan.rootColumns);
|
|
37
|
-
let changed = false;
|
|
38
|
-
|
|
39
|
-
columns.forEach(node => {
|
|
40
|
-
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
});
|
|
34
|
+
captureRootColumns(columns: ProjectionNode[]): HydrationPlanner {
|
|
35
|
+
const currentPlan = this.getPlanOrDefault();
|
|
36
|
+
const rootCols = new Set(currentPlan.rootColumns);
|
|
37
|
+
let changed = false;
|
|
38
|
+
|
|
39
|
+
columns.forEach(node => {
|
|
40
|
+
const alias = node.type === 'Column' ? (node.alias || node.name) : node.alias;
|
|
41
|
+
if (!alias || isRelationAlias(alias)) return;
|
|
42
|
+
if (node.type === 'Column' && node.table !== this.table.name) return;
|
|
43
|
+
if (!rootCols.has(alias)) {
|
|
44
|
+
rootCols.add(alias);
|
|
45
|
+
changed = true;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
50
48
|
|
|
51
49
|
if (!changed) return this;
|
|
52
50
|
return new HydrationPlanner(this.table, {
|