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
@@ -8,9 +8,7 @@ import type { ValueOperandInput } from '../core/ast/expression.js';
8
8
  import type { ExpressionNode } from '../core/ast/expression-nodes.js';
9
9
  import { BulkBaseExecutor, type BulkExecutorOptions } from './bulk-executor.base.js';
10
10
  import { createBulkExecutionContext, executeCompiled } from './bulk-context.js';
11
- import { splitIntoChunks, runWithConcurrency, runChunk, maybeTransaction, aggregateOutcomes, aggregateOutcomesWithTimings } from './bulk-utils.js';
12
-
13
- const DEFAULT_CHUNK_SIZE = 1000;
11
+ import { maybeTransaction } from './bulk-utils.js';
14
12
 
15
13
  interface DeleteExecutorOptions extends BulkExecutorOptions {
16
14
  by?: string;
@@ -30,7 +28,7 @@ export class BulkDeleteExecutor extends BulkBaseExecutor<DeleteExecutorOptions>
30
28
  this.byColumnName = options.by ?? findPrimaryKey(table);
31
29
  }
32
30
 
33
- protected async executeChunk(chunk: ValueOperandInput[], chunkIndex: number): Promise<ChunkOutcome> {
31
+ protected async executeChunk(chunk: ValueOperandInput[], _chunkIndex: number): Promise<ChunkOutcome> {
34
32
  const byColumn = this.table.columns[this.byColumnName];
35
33
  if (!byColumn) {
36
34
  throw new Error(
@@ -39,7 +37,7 @@ export class BulkDeleteExecutor extends BulkBaseExecutor<DeleteExecutorOptions>
39
37
  }
40
38
 
41
39
  const extraWhere = this.options.where;
42
- const inExpr = inList(byColumn, chunk as any);
40
+ const inExpr = inList(byColumn, chunk as unknown as Parameters<typeof inList>[1]);
43
41
  const finalWhere = extraWhere ? and(inExpr, extraWhere) : inExpr;
44
42
 
45
43
  const builder = new DeleteQueryBuilder(this.table).where(finalWhere as ExpressionNode);
@@ -4,6 +4,7 @@ import type { OrmSession } from '../orm/orm-session.js';
4
4
  import type { BulkInsertOptions, ChunkOutcome, InsertRow } from './bulk-types.js';
5
5
  import { BulkBaseExecutor, type BulkExecutorOptions } from './bulk-executor.base.js';
6
6
  import { resolveReturningColumns, flattenQueryResults, executeCompiled } from './bulk-context.js';
7
+ import type { ValueOperandInput } from '../core/ast/expression.js';
7
8
 
8
9
  interface InsertExecutorOptions extends BulkExecutorOptions {
9
10
  returning?: boolean | import('../schema/column-types.js').ColumnDef[];
@@ -20,25 +21,24 @@ export class BulkInsertExecutor extends BulkBaseExecutor<InsertExecutorOptions>
20
21
  super(session, table, rows, options);
21
22
  }
22
23
 
23
- protected async executeChunk(chunk: InsertRow[], chunkIndex: number): Promise<ChunkOutcome> {
24
+ protected async executeChunk(chunk: InsertRow[], _chunkIndex: number): Promise<ChunkOutcome> {
24
25
  const returningColumns = resolveReturningColumns(this.ctx, this.table, this.options.returning);
25
26
 
26
- let builder: InsertQueryBuilder<unknown> | ConflictBuilder<unknown> =
27
- new InsertQueryBuilder(this.table).values(chunk);
27
+ let builder: InsertQueryBuilder<unknown> | ConflictBuilder<unknown> = new InsertQueryBuilder(this.table).values(chunk);
28
28
 
29
29
  if (this.options.onConflict) {
30
30
  const conflictColumns = this.options.onConflict.target?.columns ?? [];
31
- builder = (builder as InsertQueryBuilder<unknown>).onConflict(conflictColumns as any);
31
+ const conflictBuilder = (builder as InsertQueryBuilder<unknown>).onConflict(conflictColumns);
32
32
 
33
33
  if (this.options.onConflict.action.type === 'DoNothing') {
34
- builder = (builder as ConflictBuilder<unknown>).doNothing();
34
+ builder = conflictBuilder.doNothing();
35
35
  } else if (this.options.onConflict.action.type === 'DoUpdate' && this.options.onConflict.action.set) {
36
- const setMap: Record<string, unknown> = {};
36
+ const setMap: Record<string, ValueOperandInput> = {};
37
37
  for (const assignment of this.options.onConflict.action.set) {
38
38
  const colName = typeof assignment.column === 'object' ? assignment.column.name : assignment.column;
39
39
  setMap[colName] = assignment.value;
40
40
  }
41
- builder = (builder as ConflictBuilder<unknown>).doUpdate(setMap as any);
41
+ builder = conflictBuilder.doUpdate(setMap);
42
42
  }
43
43
  }
44
44
 
@@ -34,7 +34,7 @@ export class BulkUpdateExecutor extends BulkBaseExecutor<UpdateExecutorOptions>
34
34
  this.byColumns = resolveByColumns(table, options.by);
35
35
  }
36
36
 
37
- protected async executeChunk(chunk: UpdateRow[], chunkIndex: number): Promise<ChunkOutcome> {
37
+ protected async executeChunk(chunk: UpdateRow[], _chunkIndex: number): Promise<ChunkOutcome> {
38
38
  const allReturning: Record<string, unknown>[] = [];
39
39
  const returningColumns = resolveReturningColumns(this.ctx, this.table, this.options.returning);
40
40
  const extraWhere = this.options.where;
@@ -152,7 +152,7 @@ export async function bulkUpdateWhere<TTable extends TableDef>(
152
152
  const buildTask = (chunk: ValueOperandInput[], chunkIndex: number) => async (): Promise<ChunkOutcome> => {
153
153
  return runChunk(
154
154
  async () => {
155
- const inExpr = inList(byColumn, chunk as any);
155
+ const inExpr = inList(byColumn, chunk as unknown as Parameters<typeof inList>[1]);
156
156
  const finalWhere = extraWhere ? and(inExpr, extraWhere) : inExpr;
157
157
 
158
158
  let builder = new UpdateQueryBuilder(table).set(set as Record<string, unknown>).where(finalWhere);
@@ -3,12 +3,10 @@ import { findPrimaryKey } from '../query-builder/hydration-planner.js';
3
3
  import type { TableDef } from '../schema/table.js';
4
4
  import type { OrmSession } from '../orm/orm-session.js';
5
5
  import type { BulkUpsertOptions, ChunkOutcome, InsertRow } from './bulk-types.js';
6
- import type { UpsertClause } from '../core/ast/query.js';
7
6
  import type { ValueOperandInput } from '../core/ast/expression.js';
8
7
  import type { ColumnNode } from '../core/ast/expression.js';
9
8
  import { BulkBaseExecutor, type BulkExecutorOptions } from './bulk-executor.base.js';
10
- import { resolveReturningColumns, flattenQueryResults, executeCompiled, createBulkExecutionContext } from './bulk-context.js';
11
- import { splitIntoChunks, runWithConcurrency, runChunk, maybeTransaction, aggregateOutcomes, aggregateOutcomesWithTimings } from './bulk-utils.js';
9
+ import { resolveReturningColumns, flattenQueryResults, executeCompiled } from './bulk-context.js';
12
10
 
13
11
  interface UpsertExecutorOptions extends BulkExecutorOptions {
14
12
  conflictColumns?: string[];
@@ -44,22 +42,22 @@ export class BulkUpsertExecutor extends BulkBaseExecutor<UpsertExecutorOptions>
44
42
  Object.keys(rows[0] ?? {}).filter(col => !conflictSet.has(col) && col in table.columns);
45
43
  }
46
44
 
47
- protected async executeChunk(chunk: InsertRow[], chunkIndex: number): Promise<ChunkOutcome> {
45
+ protected async executeChunk(chunk: InsertRow[], _chunkIndex: number): Promise<ChunkOutcome> {
48
46
  const returningColumns = resolveReturningColumns(this.ctx, this.table, this.options.returning);
49
47
 
50
48
  const set: Record<string, ValueOperandInput> = {};
51
49
  for (const col of this.updateColumns) {
52
- set[col] = { type: 'ExcludedColumn', name: col } as any;
50
+ set[col] = { type: 'ExcludedColumn', name: col } as unknown as ValueOperandInput;
53
51
  }
54
52
 
55
53
  let builder: InsertQueryBuilder<unknown>;
56
54
 
57
55
  if (this.updateColumns.length === 0) {
58
- builder = new InsertQueryBuilder(this.table).values(chunk).onConflict(this.conflictTargetNodes as any).doNothing();
56
+ builder = new InsertQueryBuilder(this.table).values(chunk).onConflict(this.conflictTargetNodes).doNothing();
59
57
  } else {
60
58
  builder = new InsertQueryBuilder(this.table)
61
59
  .values(chunk)
62
- .onConflict(this.conflictTargetNodes as any)
60
+ .onConflict(this.conflictTargetNodes)
63
61
  .doUpdate(set);
64
62
  }
65
63
 
@@ -1,32 +1,32 @@
1
1
  import type { TableNode, FunctionTableNode, DerivedTableNode, TableSourceNode } from '../core/ast/query.js';
2
- import type { ColumnNode } from '../core/ast/expression.js';
3
-
4
- /**
5
- * Strategy interface for converting database names to TypeScript identifiers
6
- */
7
- export interface NamingStrategy {
8
- /**
9
- * Converts a table name to a TypeScript symbol name
2
+ import type { ColumnNode } from '../core/ast/expression.js';
3
+
4
+ /**
5
+ * Strategy interface for converting database names to TypeScript identifiers
6
+ */
7
+ export interface NamingStrategy {
8
+ /**
9
+ * Converts a table name to a TypeScript symbol name
10
10
  * @param table - Table node, function table node, or name
11
11
  * @returns Valid TypeScript identifier
12
12
  */
13
13
  tableToSymbol(table: TableSourceNode | string): string;
14
-
15
- /**
16
- * Converts a column reference to a property name
17
- * @param column - Column node
18
- * @returns Valid TypeScript property name
19
- */
20
- columnToProperty(column: ColumnNode): string;
21
- }
22
-
23
- /**
24
- * Default naming strategy that maintains backward compatibility
25
- * with the original capitalize() behavior
26
- */
27
- export class DefaultNamingStrategy implements NamingStrategy {
28
- /**
29
- * Converts table names to TypeScript symbols
14
+
15
+ /**
16
+ * Converts a column reference to a property name
17
+ * @param column - Column node
18
+ * @returns Valid TypeScript property name
19
+ */
20
+ columnToProperty(column: ColumnNode): string;
21
+ }
22
+
23
+ /**
24
+ * Default naming strategy that maintains backward compatibility
25
+ * with the original capitalize() behavior
26
+ */
27
+ export class DefaultNamingStrategy implements NamingStrategy {
28
+ /**
29
+ * Converts table names to TypeScript symbols
30
30
  * @param table - Table node, function table node, or string name
31
31
  * @returns Capitalized table name (handles schema-qualified names)
32
32
  */
@@ -39,33 +39,33 @@ export class DefaultNamingStrategy implements NamingStrategy {
39
39
  : table.type === 'FunctionTable'
40
40
  ? table.alias ?? table.name
41
41
  : table.name;
42
-
43
- // Handle schema-qualified names (e.g., "auth.user" → "AuthUser")
44
- if (tableName.includes('.')) {
45
- return tableName.split('.')
46
- .map(part => this.capitalize(part))
47
- .join('');
48
- }
49
-
50
- return this.capitalize(tableName);
51
- }
52
-
53
- /**
54
- * Converts column references to property names
55
- * @param column - Column node
56
- * @returns Column name as-is (for backward compatibility)
57
- */
58
- columnToProperty(column: ColumnNode): string {
59
- return column.name;
60
- }
61
-
62
- /**
63
- * Capitalizes the first letter of a string
64
- * @param s - String to capitalize
65
- * @returns Capitalized string
66
- */
67
- private capitalize(s: string): string {
68
- if (!s) return s;
69
- return s.charAt(0).toUpperCase() + s.slice(1);
70
- }
71
- }
42
+
43
+ // Handle schema-qualified names (e.g., "auth.user" → "AuthUser")
44
+ if (tableName.includes('.')) {
45
+ return tableName.split('.')
46
+ .map(part => this.capitalize(part))
47
+ .join('');
48
+ }
49
+
50
+ return this.capitalize(tableName);
51
+ }
52
+
53
+ /**
54
+ * Converts column references to property names
55
+ * @param column - Column node
56
+ * @returns Column name as-is (for backward compatibility)
57
+ */
58
+ columnToProperty(column: ColumnNode): string {
59
+ return column.name;
60
+ }
61
+
62
+ /**
63
+ * Capitalizes the first letter of a string
64
+ * @param s - String to capitalize
65
+ * @returns Capitalized string
66
+ */
67
+ private capitalize(s: string): string {
68
+ if (!s) return s;
69
+ return s.charAt(0).toUpperCase() + s.slice(1);
70
+ }
71
+ }