metal-orm 1.1.10 → 1.1.16

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.
Files changed (192) hide show
  1. package/README.md +758 -769
  2. package/dist/index.cjs +106 -43
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +5 -5
  5. package/dist/index.d.ts +5 -5
  6. package/dist/index.js +106 -43
  7. package/dist/index.js.map +1 -1
  8. package/package.json +100 -96
  9. package/scripts/generate-entities/render.mjs +21 -12
  10. package/scripts/generate-entities/schema.mjs +209 -195
  11. package/scripts/generate-entities/tree-detection.mjs +159 -153
  12. package/scripts/inflection/pt-br.mjs +468 -468
  13. package/scripts/run-eslint.mjs +33 -34
  14. package/scripts/show-sql-seed.sql +102 -0
  15. package/scripts/show-sql.mjs +321 -325
  16. package/src/bulk/bulk-delete-executor.ts +3 -5
  17. package/src/bulk/bulk-insert-executor.ts +7 -7
  18. package/src/bulk/bulk-update-executor.ts +2 -2
  19. package/src/bulk/bulk-upsert-executor.ts +5 -7
  20. package/src/codegen/naming-strategy.ts +54 -54
  21. package/src/codegen/typescript.ts +482 -482
  22. package/src/core/ast/adapters.ts +1 -1
  23. package/src/core/ast/builders.ts +123 -123
  24. package/src/core/ast/expression-builders.ts +745 -745
  25. package/src/core/ast/expression-nodes.ts +304 -304
  26. package/src/core/ast/expression-visitor.ts +212 -212
  27. package/src/core/ast/expression.ts +20 -20
  28. package/src/core/ast/helpers.ts +14 -14
  29. package/src/core/ast/join.ts +18 -18
  30. package/src/core/ast/query.ts +200 -200
  31. package/src/core/ddl/dialects/base-schema-dialect.ts +1 -1
  32. package/src/core/ddl/dialects/mssql-schema-dialect.ts +1 -1
  33. package/src/core/ddl/dialects/mysql-schema-dialect.ts +1 -1
  34. package/src/core/ddl/dialects/postgres-schema-dialect.ts +1 -1
  35. package/src/core/ddl/dialects/render-reference.test.ts +70 -70
  36. package/src/core/ddl/dialects/sqlite-schema-dialect.ts +1 -1
  37. package/src/core/ddl/introspect/catalogs/index.ts +5 -5
  38. package/src/core/ddl/introspect/catalogs/postgres.ts +146 -146
  39. package/src/core/ddl/introspect/context.ts +15 -15
  40. package/src/core/ddl/introspect/functions/postgres.ts +35 -35
  41. package/src/core/ddl/introspect/mysql.ts +113 -36
  42. package/src/core/ddl/introspect/registry.ts +40 -40
  43. package/src/core/ddl/introspect/run-select.ts +35 -35
  44. package/src/core/ddl/introspect/utils.ts +56 -56
  45. package/src/core/ddl/naming-strategy.ts +16 -16
  46. package/src/core/ddl/schema-dialect.ts +56 -56
  47. package/src/core/ddl/schema-diff.ts +234 -234
  48. package/src/core/ddl/schema-generator.ts +1 -1
  49. package/src/core/ddl/schema-introspect.ts +25 -25
  50. package/src/core/ddl/sql-writing.ts +171 -171
  51. package/src/core/dialect/abstract.ts +541 -541
  52. package/src/core/dialect/base/cte-compiler.ts +33 -33
  53. package/src/core/dialect/base/function-table-formatter.ts +103 -103
  54. package/src/core/dialect/base/groupby-compiler.ts +21 -21
  55. package/src/core/dialect/base/join-compiler.ts +25 -25
  56. package/src/core/dialect/base/orderby-compiler.ts +35 -35
  57. package/src/core/dialect/base/pagination-strategy.ts +32 -32
  58. package/src/core/dialect/base/returning-strategy.ts +57 -57
  59. package/src/core/dialect/base/sql-dialect.ts +294 -294
  60. package/src/core/dialect/dialect-factory.ts +91 -91
  61. package/src/core/dialect/mssql/functions.ts +120 -120
  62. package/src/core/dialect/mssql/index.ts +317 -317
  63. package/src/core/dialect/mysql/functions.ts +103 -103
  64. package/src/core/dialect/mysql/index.ts +105 -105
  65. package/src/core/dialect/postgres/functions.ts +108 -108
  66. package/src/core/dialect/postgres/index.ts +91 -91
  67. package/src/core/dialect/sqlite/functions.ts +129 -129
  68. package/src/core/dialect/sqlite/index.ts +67 -67
  69. package/src/core/driver/database-driver.ts +19 -19
  70. package/src/core/driver/mssql-driver.ts +23 -23
  71. package/src/core/driver/mysql-driver.ts +23 -23
  72. package/src/core/driver/postgres-driver.ts +23 -23
  73. package/src/core/driver/sqlite-driver.ts +23 -23
  74. package/src/core/execution/db-executor.ts +92 -92
  75. package/src/core/execution/executors/better-sqlite3-executor.ts +94 -94
  76. package/src/core/execution/executors/mssql-executor.ts +184 -184
  77. package/src/core/execution/executors/mysql-executor.ts +88 -88
  78. package/src/core/execution/executors/postgres-executor.ts +26 -26
  79. package/src/core/execution/executors/sqlite-executor.ts +42 -42
  80. package/src/core/execution/pooling/pool-types.ts +30 -30
  81. package/src/core/execution/pooling/pool.ts +275 -275
  82. package/src/core/functions/array.ts +35 -35
  83. package/src/core/functions/control-flow.ts +79 -79
  84. package/src/core/functions/datetime.ts +237 -237
  85. package/src/core/functions/json.ts +70 -70
  86. package/src/core/functions/numeric.ts +297 -297
  87. package/src/core/functions/text.ts +334 -334
  88. package/src/core/functions/types.ts +33 -33
  89. package/src/core/hydration/types.ts +51 -51
  90. package/src/core/sql/sql-operator-config.ts +39 -39
  91. package/src/core/sql/sql.ts +152 -152
  92. package/src/decorators/column-decorator.ts +87 -87
  93. package/src/decorators/decorator-metadata.ts +143 -143
  94. package/src/decorators/entity.ts +93 -93
  95. package/src/decorators/index.ts +39 -39
  96. package/src/decorators/relations.ts +231 -231
  97. package/src/decorators/transformers/built-in/string-transformers.ts +231 -231
  98. package/src/decorators/transformers/transformer-decorators.ts +134 -134
  99. package/src/decorators/transformers/transformer-executor.ts +171 -171
  100. package/src/decorators/transformers/transformer-metadata.ts +73 -73
  101. package/src/decorators/validators/built-in/br-cep-validator.ts +55 -55
  102. package/src/decorators/validators/built-in/br-cnpj-validator.ts +105 -105
  103. package/src/decorators/validators/built-in/br-cpf-validator.ts +103 -103
  104. package/src/decorators/validators/country-validator-registry.ts +64 -64
  105. package/src/decorators/validators/country-validators-decorators.ts +203 -203
  106. package/src/decorators/validators/country-validators.ts +105 -105
  107. package/src/decorators/validators/validator-metadata.ts +59 -59
  108. package/src/dto/dto-types.ts +226 -226
  109. package/src/dto/filter-types.ts +141 -141
  110. package/src/dto/index.ts +95 -95
  111. package/src/dto/openapi/generators/base.ts +29 -29
  112. package/src/dto/openapi/generators/column.ts +37 -37
  113. package/src/dto/openapi/generators/dto.ts +91 -91
  114. package/src/dto/openapi/generators/filter.ts +75 -75
  115. package/src/dto/openapi/generators/nested-dto.ts +618 -618
  116. package/src/dto/openapi/generators/pagination.ts +111 -111
  117. package/src/dto/openapi/generators/relation-filter.ts +228 -228
  118. package/src/dto/openapi/index.ts +12 -12
  119. package/src/dto/openapi/types.ts +101 -101
  120. package/src/dto/openapi/utilities.ts +95 -95
  121. package/src/dto/pagination-utils.ts +150 -150
  122. package/src/dto/transform.ts +197 -197
  123. package/src/index.ts +86 -86
  124. package/src/orm/als.ts +58 -58
  125. package/src/orm/domain-event-bus.ts +119 -119
  126. package/src/orm/entity-context.ts +86 -86
  127. package/src/orm/entity-materializer.ts +159 -159
  128. package/src/orm/entity-meta.ts +97 -97
  129. package/src/orm/entity-registry.ts +39 -39
  130. package/src/orm/entity-relation-cache.ts +39 -39
  131. package/src/orm/execute.ts +194 -194
  132. package/src/orm/execution-context.ts +18 -18
  133. package/src/orm/hydration-context.ts +26 -26
  134. package/src/orm/hydration.ts +112 -112
  135. package/src/orm/identity-map.ts +61 -61
  136. package/src/orm/interceptor-pipeline.ts +16 -16
  137. package/src/orm/lazy-batch/belongs-to-many.ts +119 -119
  138. package/src/orm/lazy-batch/belongs-to.ts +108 -108
  139. package/src/orm/lazy-batch/has-many.ts +69 -69
  140. package/src/orm/lazy-batch/has-one.ts +68 -68
  141. package/src/orm/lazy-batch/shared.ts +125 -125
  142. package/src/orm/orm-session.ts +620 -620
  143. package/src/orm/orm.ts +34 -34
  144. package/src/orm/pooled-executor-factory.ts +121 -121
  145. package/src/orm/query-logger.ts +40 -40
  146. package/src/orm/relation-change-processor.ts +420 -420
  147. package/src/orm/relations/belongs-to.ts +143 -143
  148. package/src/orm/relations/has-many.ts +204 -204
  149. package/src/orm/relations/has-one.ts +174 -174
  150. package/src/orm/relations/many-to-many.ts +288 -288
  151. package/src/orm/relations/morph-many.ts +156 -156
  152. package/src/orm/relations/morph-one.ts +151 -151
  153. package/src/orm/relations/morph-to.ts +162 -162
  154. package/src/orm/runtime-types.ts +92 -92
  155. package/src/orm/save-graph.ts +561 -561
  156. package/src/orm/transaction-runner.ts +24 -24
  157. package/src/orm/unit-of-work.ts +426 -426
  158. package/src/query/index.ts +69 -69
  159. package/src/query/target.ts +46 -46
  160. package/src/query-builder/column-selector.ts +81 -81
  161. package/src/query-builder/delete.ts +141 -141
  162. package/src/query-builder/insert-query-state.ts +149 -149
  163. package/src/query-builder/insert.ts +117 -117
  164. package/src/query-builder/query-ast-service.ts +287 -287
  165. package/src/query-builder/query-resolution.ts +78 -78
  166. package/src/query-builder/raw-column-parser.ts +38 -38
  167. package/src/query-builder/relation-filter-utils.ts +153 -153
  168. package/src/query-builder/relation-join-planner.ts +10 -10
  169. package/src/query-builder/relation-manager.ts +87 -87
  170. package/src/query-builder/relation-projection-helper.ts +102 -102
  171. package/src/query-builder/relation-types.ts +9 -9
  172. package/src/query-builder/relation-utils.ts +15 -15
  173. package/src/query-builder/select/cte-facet.ts +40 -40
  174. package/src/query-builder/select/from-facet.ts +80 -80
  175. package/src/query-builder/select/join-facet.ts +62 -62
  176. package/src/query-builder/select/predicate-facet.ts +104 -104
  177. package/src/query-builder/select/projection-facet.ts +70 -70
  178. package/src/query-builder/select/relation-facet.ts +81 -81
  179. package/src/query-builder/select/setop-facet.ts +36 -36
  180. package/src/query-builder/select-helpers.ts +1 -1
  181. package/src/query-builder/select-query-builder-deps.ts +130 -130
  182. package/src/query-builder/select-query-state.ts +207 -207
  183. package/src/query-builder/update.ts +151 -151
  184. package/src/schema/column-types.ts +322 -322
  185. package/src/schema/table-guards.ts +37 -37
  186. package/src/schema/table.ts +281 -281
  187. package/src/tree/index.ts +13 -13
  188. package/src/tree/nested-set-strategy.ts +545 -545
  189. package/src/tree/tree-decorator.ts +397 -397
  190. package/src/tree/tree-manager.ts +754 -754
  191. package/src/tree/tree-query.ts +427 -427
  192. package/src/tree/tree-types.ts +299 -299
@@ -1,334 +1,334 @@
1
- // Pure AST Builders - No Dialect Logic Here!
2
-
3
- import { ColumnDef } from '../../schema/column-types.js';
4
- import { columnOperand, valueToOperand } from '../ast/expression-builders.js';
5
- import { FunctionNode, OperandNode, isOperandNode, TypedExpression, asType } from '../ast/expression.js';
6
-
7
- type OperandInput = OperandNode | ColumnDef | string | number | boolean | null;
8
-
9
- const isColumnDef = (val: unknown): val is ColumnDef => !!val && typeof val === 'object' && 'type' in val && 'name' in val;
10
-
11
- const toOperand = (input: OperandInput): OperandNode => {
12
- if (isOperandNode(input)) return input;
13
- if (isColumnDef(input)) return columnOperand(input);
14
-
15
- return valueToOperand(input);
16
- };
17
-
18
- const fn = (key: string, args: OperandInput[]): FunctionNode => ({
19
- type: 'Function',
20
- name: key,
21
- fn: key,
22
- args: args.map(toOperand)
23
- });
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
-
28
- /**
29
- * Converts a string to lowercase.
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);
36
- */
37
- export const lower = (value: OperandInput): TypedExpression<string> => sfn('LOWER', [value]);
38
-
39
- /**
40
- * Converts a string to uppercase.
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);
47
- */
48
- export const upper = (value: OperandInput): TypedExpression<string> => sfn('UPPER', [value]);
49
-
50
- /**
51
- * Returns the ASCII code of the first character of a string.
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);
58
- */
59
- export const ascii = (value: OperandInput): TypedExpression<number> => nfn('ASCII', [value]);
60
-
61
- /**
62
- * Returns a string from one or more ASCII codes.
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'
69
- */
70
- export const char = (...codes: OperandInput[]): TypedExpression<string> => {
71
- if (codes.length === 0) throw new Error('char() expects at least 1 argument');
72
- return sfn('CHAR', codes);
73
- };
74
-
75
- /**
76
- * Returns the number of characters in a string.
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);
83
- */
84
- export const charLength = (value: OperandInput): TypedExpression<number> => nfn('CHAR_LENGTH', [value]);
85
-
86
- /**
87
- * Returns the length of a string in bytes or characters.
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);
94
- */
95
- export const length = (value: OperandInput): TypedExpression<number> => nfn('LENGTH', [value]);
96
-
97
- /**
98
- * Removes leading and trailing whitespace or specified characters from a string.
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, '/');
107
- */
108
- export const trim = (value: OperandInput, chars?: OperandInput): TypedExpression<string> =>
109
- chars === undefined ? sfn('TRIM', [value]) : sfn('TRIM', [value, chars]);
110
-
111
- /**
112
- * Removes leading whitespace from a string.
113
- *
114
- * @param value - The string value or column.
115
- * @returns A `TypedExpression<string>` representing the `LTRIM` SQL function.
116
- */
117
- export const ltrim = (value: OperandInput): TypedExpression<string> => sfn('LTRIM', [value]);
118
-
119
- /**
120
- * Removes trailing whitespace from a string.
121
- *
122
- * @param value - The string value or column.
123
- * @returns A `TypedExpression<string>` representing the `RTRIM` SQL function.
124
- */
125
- export const rtrim = (value: OperandInput): TypedExpression<string> => sfn('RTRIM', [value]);
126
-
127
- /**
128
- * Concatenates two or more strings.
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);
135
- */
136
- export const concat = (...args: OperandInput[]): TypedExpression<string> => {
137
- if (args.length < 2) throw new Error('concat() expects at least 2 arguments');
138
- return sfn('CONCAT', args);
139
- };
140
-
141
- /**
142
- * Concatenates strings with a separator.
143
- *
144
- * @param separator - The separator string.
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);
150
- */
151
- export const concatWs = (separator: OperandInput, ...args: OperandInput[]): TypedExpression<string> => {
152
- if (args.length < 1) throw new Error('concatWs() expects at least 2 arguments including the separator');
153
- return sfn('CONCAT_WS', [separator, ...args]);
154
- };
155
-
156
- /**
157
- * Extracts a substring from a string.
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);
166
- */
167
- export const substr = (value: OperandInput, start: OperandInput, length?: OperandInput): TypedExpression<string> =>
168
- length === undefined ? sfn('SUBSTR', [value, start]) : sfn('SUBSTR', [value, start, length]);
169
-
170
- /**
171
- * Returns the leftmost characters of a string.
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.
176
- */
177
- export const left = (value: OperandInput, len: OperandInput): TypedExpression<string> => sfn('LEFT', [value, len]);
178
-
179
- /**
180
- * Returns the rightmost characters of a string.
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.
185
- */
186
- export const right = (value: OperandInput, len: OperandInput): TypedExpression<string> => sfn('RIGHT', [value, len]);
187
-
188
- /**
189
- * Returns the position of a substring in a string.
190
- *
191
- * @param substring - The substring to search for.
192
- * @param value - The string or column to search within.
193
- * @returns A `TypedExpression<number>` representing the `POSITION` SQL function.
194
- */
195
- export const position = (substring: OperandInput, value: OperandInput): TypedExpression<number> => nfn('POSITION', [substring, value]);
196
-
197
- /**
198
- * Returns the position of a substring in a string.
199
- *
200
- * @param value - The string or column to search within.
201
- * @param substring - The substring to search for.
202
- * @returns A `TypedExpression<number>` representing the `INSTR` SQL function.
203
- */
204
- export const instr = (value: OperandInput, substring: OperandInput): TypedExpression<number> => nfn('INSTR', [value, substring]);
205
-
206
- /**
207
- * Returns the position of a substring in a string, optionally starting from a position.
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.
213
- */
214
- export const locate = (substring: OperandInput, value: OperandInput, start?: OperandInput): TypedExpression<number> =>
215
- start === undefined ? nfn('LOCATE', [substring, value]) : nfn('LOCATE', [substring, value, start]);
216
-
217
- /**
218
- * Replaces occurrences of a substring in a string.
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');
227
- */
228
- export const replace = (value: OperandInput, search: OperandInput, replacement: OperandInput): TypedExpression<string> =>
229
- sfn('REPLACE', [value, search, replacement]);
230
-
231
- /**
232
- * Repeats a string a specified number of times.
233
- *
234
- * @param value - The string to repeat.
235
- * @param count - How many times to repeat.
236
- * @returns A `TypedExpression<string>` representing the `REPEAT` SQL function.
237
- */
238
- export const repeat = (value: OperandInput, count: OperandInput): TypedExpression<string> => sfn('REPEAT', [value, count]);
239
-
240
- /**
241
- * Left-pads a string to a certain length with another string.
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.
247
- */
248
- export const lpad = (value: OperandInput, len: OperandInput, pad: OperandInput): TypedExpression<string> =>
249
- sfn('LPAD', [value, len, pad]);
250
-
251
- /**
252
- * Right-pads a string to a certain length with another string.
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.
258
- */
259
- export const rpad = (value: OperandInput, len: OperandInput, pad: OperandInput): TypedExpression<string> =>
260
- sfn('RPAD', [value, len, pad]);
261
-
262
- /**
263
- * Returns a string consisting of a specified number of spaces.
264
- *
265
- * @param count - Number of spaces.
266
- * @returns A `TypedExpression<string>` representing the `SPACE` SQL function.
267
- */
268
- export const space = (count: OperandInput): TypedExpression<string> => sfn('SPACE', [count]);
269
-
270
- /**
271
- * Reverses a string.
272
- *
273
- * @param value - The string value or column.
274
- * @returns A `TypedExpression<string>` representing the `REVERSE` SQL function.
275
- */
276
- export const reverse = (value: OperandInput): TypedExpression<string> => sfn('REVERSE', [value]);
277
-
278
- /**
279
- * Capitalizes the first letter of each word in a string.
280
- *
281
- * @param value - The string value or column.
282
- * @returns A `TypedExpression<string>` representing the `INITCAP` SQL function.
283
- */
284
- export const initcap = (value: OperandInput): TypedExpression<string> => sfn('INITCAP', [value]);
285
-
286
- /**
287
- * Returns the MD5 hash of a string.
288
- *
289
- * @param value - The string value or column.
290
- * @returns A `TypedExpression<string>` representing the `MD5` SQL function.
291
- */
292
- export const md5 = (value: OperandInput): TypedExpression<string> => sfn('MD5', [value]);
293
-
294
- /**
295
- * Returns the SHA-1 hash of a string.
296
- *
297
- * @param value - The string value or column.
298
- * @returns A `TypedExpression<string>` representing the `SHA1` SQL function.
299
- */
300
- export const sha1 = (value: OperandInput): TypedExpression<string> => sfn('SHA1', [value]);
301
-
302
- /**
303
- * Returns the SHA-2 hash of a string with a specified bit length.
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.
308
- */
309
- export const sha2 = (value: OperandInput, bits: OperandInput): TypedExpression<string> => sfn('SHA2', [value, bits]);
310
-
311
- /**
312
- * Returns the length of a string in bits.
313
- *
314
- * @param value - String value or column.
315
- * @returns A `TypedExpression<number>` representing the `BIT_LENGTH` SQL function.
316
- */
317
- export const bitLength = (value: OperandInput): TypedExpression<number> => nfn('BIT_LENGTH', [value]);
318
-
319
- /**
320
- * Returns the length of a string in bytes.
321
- *
322
- * @param value - String value or column.
323
- * @returns A `TypedExpression<number>` representing the `OCTET_LENGTH` SQL function.
324
- */
325
- export const octetLength = (value: OperandInput): TypedExpression<number> => nfn('OCTET_LENGTH', [value]);
326
-
327
- /**
328
- * Returns a string from an ASCII code.
329
- *
330
- * @param code - ASCII code.
331
- * @returns A `TypedExpression<string>` representing the `CHR` SQL function.
332
- */
333
- export const chr = (code: OperandInput): TypedExpression<string> => sfn('CHR', [code]);
334
-
1
+ // Pure AST Builders - No Dialect Logic Here!
2
+
3
+ import { ColumnDef } from '../../schema/column-types.js';
4
+ import { columnOperand, valueToOperand } from '../ast/expression-builders.js';
5
+ import { FunctionNode, OperandNode, isOperandNode, TypedExpression, asType } from '../ast/expression.js';
6
+
7
+ type OperandInput = OperandNode | ColumnDef | string | number | boolean | null;
8
+
9
+ const isColumnDef = (val: unknown): val is ColumnDef => !!val && typeof val === 'object' && 'type' in val && 'name' in val;
10
+
11
+ const toOperand = (input: OperandInput): OperandNode => {
12
+ if (isOperandNode(input)) return input;
13
+ if (isColumnDef(input)) return columnOperand(input);
14
+
15
+ return valueToOperand(input);
16
+ };
17
+
18
+ const fn = (key: string, args: OperandInput[]): FunctionNode => ({
19
+ type: 'Function',
20
+ name: key,
21
+ fn: key,
22
+ args: args.map(toOperand)
23
+ });
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
+
28
+ /**
29
+ * Converts a string to lowercase.
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);
36
+ */
37
+ export const lower = (value: OperandInput): TypedExpression<string> => sfn('LOWER', [value]);
38
+
39
+ /**
40
+ * Converts a string to uppercase.
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);
47
+ */
48
+ export const upper = (value: OperandInput): TypedExpression<string> => sfn('UPPER', [value]);
49
+
50
+ /**
51
+ * Returns the ASCII code of the first character of a string.
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);
58
+ */
59
+ export const ascii = (value: OperandInput): TypedExpression<number> => nfn('ASCII', [value]);
60
+
61
+ /**
62
+ * Returns a string from one or more ASCII codes.
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'
69
+ */
70
+ export const char = (...codes: OperandInput[]): TypedExpression<string> => {
71
+ if (codes.length === 0) throw new Error('char() expects at least 1 argument');
72
+ return sfn('CHAR', codes);
73
+ };
74
+
75
+ /**
76
+ * Returns the number of characters in a string.
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);
83
+ */
84
+ export const charLength = (value: OperandInput): TypedExpression<number> => nfn('CHAR_LENGTH', [value]);
85
+
86
+ /**
87
+ * Returns the length of a string in bytes or characters.
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);
94
+ */
95
+ export const length = (value: OperandInput): TypedExpression<number> => nfn('LENGTH', [value]);
96
+
97
+ /**
98
+ * Removes leading and trailing whitespace or specified characters from a string.
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, '/');
107
+ */
108
+ export const trim = (value: OperandInput, chars?: OperandInput): TypedExpression<string> =>
109
+ chars === undefined ? sfn('TRIM', [value]) : sfn('TRIM', [value, chars]);
110
+
111
+ /**
112
+ * Removes leading whitespace from a string.
113
+ *
114
+ * @param value - The string value or column.
115
+ * @returns A `TypedExpression<string>` representing the `LTRIM` SQL function.
116
+ */
117
+ export const ltrim = (value: OperandInput): TypedExpression<string> => sfn('LTRIM', [value]);
118
+
119
+ /**
120
+ * Removes trailing whitespace from a string.
121
+ *
122
+ * @param value - The string value or column.
123
+ * @returns A `TypedExpression<string>` representing the `RTRIM` SQL function.
124
+ */
125
+ export const rtrim = (value: OperandInput): TypedExpression<string> => sfn('RTRIM', [value]);
126
+
127
+ /**
128
+ * Concatenates two or more strings.
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);
135
+ */
136
+ export const concat = (...args: OperandInput[]): TypedExpression<string> => {
137
+ if (args.length < 2) throw new Error('concat() expects at least 2 arguments');
138
+ return sfn('CONCAT', args);
139
+ };
140
+
141
+ /**
142
+ * Concatenates strings with a separator.
143
+ *
144
+ * @param separator - The separator string.
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);
150
+ */
151
+ export const concatWs = (separator: OperandInput, ...args: OperandInput[]): TypedExpression<string> => {
152
+ if (args.length < 1) throw new Error('concatWs() expects at least 2 arguments including the separator');
153
+ return sfn('CONCAT_WS', [separator, ...args]);
154
+ };
155
+
156
+ /**
157
+ * Extracts a substring from a string.
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);
166
+ */
167
+ export const substr = (value: OperandInput, start: OperandInput, length?: OperandInput): TypedExpression<string> =>
168
+ length === undefined ? sfn('SUBSTR', [value, start]) : sfn('SUBSTR', [value, start, length]);
169
+
170
+ /**
171
+ * Returns the leftmost characters of a string.
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.
176
+ */
177
+ export const left = (value: OperandInput, len: OperandInput): TypedExpression<string> => sfn('LEFT', [value, len]);
178
+
179
+ /**
180
+ * Returns the rightmost characters of a string.
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.
185
+ */
186
+ export const right = (value: OperandInput, len: OperandInput): TypedExpression<string> => sfn('RIGHT', [value, len]);
187
+
188
+ /**
189
+ * Returns the position of a substring in a string.
190
+ *
191
+ * @param substring - The substring to search for.
192
+ * @param value - The string or column to search within.
193
+ * @returns A `TypedExpression<number>` representing the `POSITION` SQL function.
194
+ */
195
+ export const position = (substring: OperandInput, value: OperandInput): TypedExpression<number> => nfn('POSITION', [substring, value]);
196
+
197
+ /**
198
+ * Returns the position of a substring in a string.
199
+ *
200
+ * @param value - The string or column to search within.
201
+ * @param substring - The substring to search for.
202
+ * @returns A `TypedExpression<number>` representing the `INSTR` SQL function.
203
+ */
204
+ export const instr = (value: OperandInput, substring: OperandInput): TypedExpression<number> => nfn('INSTR', [value, substring]);
205
+
206
+ /**
207
+ * Returns the position of a substring in a string, optionally starting from a position.
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.
213
+ */
214
+ export const locate = (substring: OperandInput, value: OperandInput, start?: OperandInput): TypedExpression<number> =>
215
+ start === undefined ? nfn('LOCATE', [substring, value]) : nfn('LOCATE', [substring, value, start]);
216
+
217
+ /**
218
+ * Replaces occurrences of a substring in a string.
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');
227
+ */
228
+ export const replace = (value: OperandInput, search: OperandInput, replacement: OperandInput): TypedExpression<string> =>
229
+ sfn('REPLACE', [value, search, replacement]);
230
+
231
+ /**
232
+ * Repeats a string a specified number of times.
233
+ *
234
+ * @param value - The string to repeat.
235
+ * @param count - How many times to repeat.
236
+ * @returns A `TypedExpression<string>` representing the `REPEAT` SQL function.
237
+ */
238
+ export const repeat = (value: OperandInput, count: OperandInput): TypedExpression<string> => sfn('REPEAT', [value, count]);
239
+
240
+ /**
241
+ * Left-pads a string to a certain length with another string.
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.
247
+ */
248
+ export const lpad = (value: OperandInput, len: OperandInput, pad: OperandInput): TypedExpression<string> =>
249
+ sfn('LPAD', [value, len, pad]);
250
+
251
+ /**
252
+ * Right-pads a string to a certain length with another string.
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.
258
+ */
259
+ export const rpad = (value: OperandInput, len: OperandInput, pad: OperandInput): TypedExpression<string> =>
260
+ sfn('RPAD', [value, len, pad]);
261
+
262
+ /**
263
+ * Returns a string consisting of a specified number of spaces.
264
+ *
265
+ * @param count - Number of spaces.
266
+ * @returns A `TypedExpression<string>` representing the `SPACE` SQL function.
267
+ */
268
+ export const space = (count: OperandInput): TypedExpression<string> => sfn('SPACE', [count]);
269
+
270
+ /**
271
+ * Reverses a string.
272
+ *
273
+ * @param value - The string value or column.
274
+ * @returns A `TypedExpression<string>` representing the `REVERSE` SQL function.
275
+ */
276
+ export const reverse = (value: OperandInput): TypedExpression<string> => sfn('REVERSE', [value]);
277
+
278
+ /**
279
+ * Capitalizes the first letter of each word in a string.
280
+ *
281
+ * @param value - The string value or column.
282
+ * @returns A `TypedExpression<string>` representing the `INITCAP` SQL function.
283
+ */
284
+ export const initcap = (value: OperandInput): TypedExpression<string> => sfn('INITCAP', [value]);
285
+
286
+ /**
287
+ * Returns the MD5 hash of a string.
288
+ *
289
+ * @param value - The string value or column.
290
+ * @returns A `TypedExpression<string>` representing the `MD5` SQL function.
291
+ */
292
+ export const md5 = (value: OperandInput): TypedExpression<string> => sfn('MD5', [value]);
293
+
294
+ /**
295
+ * Returns the SHA-1 hash of a string.
296
+ *
297
+ * @param value - The string value or column.
298
+ * @returns A `TypedExpression<string>` representing the `SHA1` SQL function.
299
+ */
300
+ export const sha1 = (value: OperandInput): TypedExpression<string> => sfn('SHA1', [value]);
301
+
302
+ /**
303
+ * Returns the SHA-2 hash of a string with a specified bit length.
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.
308
+ */
309
+ export const sha2 = (value: OperandInput, bits: OperandInput): TypedExpression<string> => sfn('SHA2', [value, bits]);
310
+
311
+ /**
312
+ * Returns the length of a string in bits.
313
+ *
314
+ * @param value - String value or column.
315
+ * @returns A `TypedExpression<number>` representing the `BIT_LENGTH` SQL function.
316
+ */
317
+ export const bitLength = (value: OperandInput): TypedExpression<number> => nfn('BIT_LENGTH', [value]);
318
+
319
+ /**
320
+ * Returns the length of a string in bytes.
321
+ *
322
+ * @param value - String value or column.
323
+ * @returns A `TypedExpression<number>` representing the `OCTET_LENGTH` SQL function.
324
+ */
325
+ export const octetLength = (value: OperandInput): TypedExpression<number> => nfn('OCTET_LENGTH', [value]);
326
+
327
+ /**
328
+ * Returns a string from an ASCII code.
329
+ *
330
+ * @param code - ASCII code.
331
+ * @returns A `TypedExpression<string>` representing the `CHR` SQL function.
332
+ */
333
+ export const chr = (code: OperandInput): TypedExpression<string> => sfn('CHR', [code]);
334
+