metal-orm 1.0.42 → 1.0.44

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 (122) hide show
  1. package/README.md +195 -37
  2. package/dist/index.cjs +1014 -538
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +1267 -371
  5. package/dist/index.d.ts +1267 -371
  6. package/dist/index.js +1012 -536
  7. package/dist/index.js.map +1 -1
  8. package/package.json +8 -2
  9. package/scripts/run-eslint.mjs +34 -0
  10. package/src/codegen/typescript.ts +32 -15
  11. package/src/core/ast/adapters.ts +8 -2
  12. package/src/core/ast/builders.ts +105 -76
  13. package/src/core/ast/expression-builders.ts +430 -392
  14. package/src/core/ast/expression-nodes.ts +14 -5
  15. package/src/core/ast/expression-visitor.ts +56 -14
  16. package/src/core/ast/helpers.ts +23 -0
  17. package/src/core/ast/join-node.ts +18 -2
  18. package/src/core/ast/query.ts +6 -6
  19. package/src/core/ast/window-functions.ts +10 -2
  20. package/src/core/ddl/dialects/base-schema-dialect.ts +37 -4
  21. package/src/core/ddl/dialects/index.ts +1 -0
  22. package/src/core/ddl/dialects/mssql-schema-dialect.ts +5 -0
  23. package/src/core/ddl/dialects/mysql-schema-dialect.ts +3 -0
  24. package/src/core/ddl/dialects/postgres-schema-dialect.ts +14 -1
  25. package/src/core/ddl/dialects/render-reference.test.ts +69 -0
  26. package/src/core/ddl/dialects/sqlite-schema-dialect.ts +10 -0
  27. package/src/core/ddl/introspect/catalogs/index.ts +1 -0
  28. package/src/core/ddl/introspect/catalogs/postgres.ts +2 -0
  29. package/src/core/ddl/introspect/context.ts +6 -0
  30. package/src/core/ddl/introspect/functions/postgres.ts +13 -0
  31. package/src/core/ddl/introspect/mssql.ts +53 -8
  32. package/src/core/ddl/introspect/mysql.ts +32 -6
  33. package/src/core/ddl/introspect/postgres.ts +102 -34
  34. package/src/core/ddl/introspect/registry.ts +14 -0
  35. package/src/core/ddl/introspect/run-select.ts +19 -4
  36. package/src/core/ddl/introspect/sqlite.ts +78 -11
  37. package/src/core/ddl/introspect/types.ts +0 -1
  38. package/src/core/ddl/introspect/utils.ts +21 -3
  39. package/src/core/ddl/naming-strategy.ts +6 -0
  40. package/src/core/ddl/schema-dialect.ts +20 -6
  41. package/src/core/ddl/schema-diff.ts +22 -0
  42. package/src/core/ddl/schema-generator.ts +26 -12
  43. package/src/core/ddl/schema-plan-executor.ts +6 -0
  44. package/src/core/ddl/schema-types.ts +6 -0
  45. package/src/core/ddl/sql-writing.ts +4 -4
  46. package/src/core/dialect/abstract.ts +19 -7
  47. package/src/core/dialect/base/function-table-formatter.ts +3 -2
  48. package/src/core/dialect/base/join-compiler.ts +5 -3
  49. package/src/core/dialect/base/returning-strategy.ts +1 -0
  50. package/src/core/dialect/base/sql-dialect.ts +3 -3
  51. package/src/core/dialect/mssql/functions.ts +24 -25
  52. package/src/core/dialect/mssql/index.ts +1 -4
  53. package/src/core/dialect/mysql/functions.ts +0 -1
  54. package/src/core/dialect/postgres/functions.ts +33 -34
  55. package/src/core/dialect/postgres/index.ts +1 -0
  56. package/src/core/dialect/sqlite/functions.ts +18 -19
  57. package/src/core/dialect/sqlite/index.ts +2 -0
  58. package/src/core/execution/db-executor.ts +1 -1
  59. package/src/core/execution/executors/mysql-executor.ts +2 -2
  60. package/src/core/execution/executors/postgres-executor.ts +1 -1
  61. package/src/core/execution/pooling/pool.ts +12 -5
  62. package/src/core/functions/datetime.ts +58 -34
  63. package/src/core/functions/numeric.ts +96 -31
  64. package/src/core/functions/standard-strategy.ts +35 -0
  65. package/src/core/functions/text.ts +84 -23
  66. package/src/core/functions/types.ts +23 -8
  67. package/src/decorators/bootstrap.ts +42 -11
  68. package/src/decorators/column.ts +20 -11
  69. package/src/decorators/decorator-metadata.ts +30 -9
  70. package/src/decorators/entity.ts +29 -5
  71. package/src/decorators/index.ts +3 -0
  72. package/src/decorators/relations.ts +34 -11
  73. package/src/orm/als.ts +34 -9
  74. package/src/orm/entity-context.ts +62 -8
  75. package/src/orm/entity-meta.ts +8 -8
  76. package/src/orm/entity-metadata.ts +131 -16
  77. package/src/orm/entity.ts +28 -29
  78. package/src/orm/execute.ts +19 -4
  79. package/src/orm/hydration.ts +42 -39
  80. package/src/orm/identity-map.ts +1 -1
  81. package/src/orm/lazy-batch.ts +74 -104
  82. package/src/orm/orm-session.ts +24 -23
  83. package/src/orm/orm.ts +2 -5
  84. package/src/orm/relation-change-processor.ts +12 -11
  85. package/src/orm/relations/belongs-to.ts +11 -11
  86. package/src/orm/relations/has-many.ts +54 -10
  87. package/src/orm/relations/has-one.ts +8 -7
  88. package/src/orm/relations/many-to-many.ts +13 -13
  89. package/src/orm/runtime-types.ts +4 -4
  90. package/src/orm/save-graph.ts +31 -25
  91. package/src/orm/unit-of-work.ts +17 -17
  92. package/src/query/index.ts +74 -0
  93. package/src/query/target.ts +46 -0
  94. package/src/query-builder/delete-query-state.ts +30 -0
  95. package/src/query-builder/delete.ts +64 -18
  96. package/src/query-builder/hydration-manager.ts +52 -5
  97. package/src/query-builder/insert-query-state.ts +30 -0
  98. package/src/query-builder/insert.ts +58 -10
  99. package/src/query-builder/query-ast-service.ts +7 -2
  100. package/src/query-builder/query-resolution.ts +78 -0
  101. package/src/query-builder/raw-column-parser.ts +7 -1
  102. package/src/query-builder/relation-alias.ts +7 -0
  103. package/src/query-builder/relation-conditions.ts +61 -48
  104. package/src/query-builder/relation-service.ts +68 -63
  105. package/src/query-builder/relation-utils.ts +3 -0
  106. package/src/query-builder/select/cte-facet.ts +40 -0
  107. package/src/query-builder/select/from-facet.ts +80 -0
  108. package/src/query-builder/select/join-facet.ts +62 -0
  109. package/src/query-builder/select/predicate-facet.ts +103 -0
  110. package/src/query-builder/select/projection-facet.ts +69 -0
  111. package/src/query-builder/select/relation-facet.ts +81 -0
  112. package/src/query-builder/select/setop-facet.ts +36 -0
  113. package/src/query-builder/select-helpers.ts +15 -2
  114. package/src/query-builder/select-query-builder-deps.ts +19 -1
  115. package/src/query-builder/select-query-state.ts +2 -1
  116. package/src/query-builder/select.ts +795 -1163
  117. package/src/query-builder/update-query-state.ts +52 -0
  118. package/src/query-builder/update.ts +69 -18
  119. package/src/schema/column.ts +26 -26
  120. package/src/schema/table-guards.ts +31 -0
  121. package/src/schema/table.ts +47 -18
  122. package/src/schema/types.ts +22 -22
@@ -2,6 +2,7 @@ import type { TableDef, IndexDef } from '../../schema/table.js';
2
2
  import type { ColumnDef, ForeignKeyReference } from '../../schema/column.js';
3
3
  import type { DatabaseTable, DatabaseColumn, ColumnDiff } from './schema-types.js';
4
4
 
5
+ /** The name of a database dialect. */
5
6
  export type DialectName =
6
7
  | 'postgres'
7
8
  | 'mysql'
@@ -9,33 +10,46 @@ export type DialectName =
9
10
  | 'mssql'
10
11
  | (string & {});
11
12
 
13
+ /** Interface for schema dialect implementations that handle database-specific DDL operations. */
12
14
  export interface SchemaDialect {
15
+ /** The name of the dialect. */
13
16
  readonly name: DialectName;
14
17
 
15
- // Minimal quoting surface; reusable for helpers
18
+ /** Quotes an identifier for use in SQL. */
16
19
  quoteIdentifier(id: string): string;
17
20
 
18
- // Table naming
21
+ /** Formats the table name for SQL. */
19
22
  formatTableName(table: TableDef | DatabaseTable): string;
20
23
 
21
- // Column rendering
24
+ /** Renders the column type for SQL. */
22
25
  renderColumnType(column: ColumnDef): string;
26
+ /** Renders the default value for SQL. */
23
27
  renderDefault(value: unknown, column: ColumnDef): string;
28
+ /** Renders the auto-increment clause for SQL. */
24
29
  renderAutoIncrement(column: ColumnDef, table: TableDef): string | undefined;
25
30
 
26
- // Constraints & indexes
31
+ /** Renders a foreign key reference for SQL. */
27
32
  renderReference(ref: ForeignKeyReference, table: TableDef): string;
33
+ /** Renders an index for SQL. */
28
34
  renderIndex(table: TableDef, index: IndexDef): string;
35
+ /** Renders table options for SQL. */
29
36
  renderTableOptions(table: TableDef): string | undefined;
30
37
 
31
- // Capability flags
38
+ /** Checks if the dialect supports partial indexes. */
32
39
  supportsPartialIndexes(): boolean;
40
+ /** Checks if the dialect prefers inline primary key auto-increment. */
41
+ preferInlinePkAutoincrement(column: ColumnDef, table: TableDef, pk: string[]): boolean;
33
42
 
34
- // DDL operations
43
+ /** Generates SQL to drop a column. */
35
44
  dropColumnSql?(table: DatabaseTable, column: string): string[];
45
+ /** Generates SQL to drop an index. */
36
46
  dropIndexSql?(table: DatabaseTable, index: string): string[];
47
+ /** Generates SQL to drop a table. */
37
48
  dropTableSql?(table: DatabaseTable): string[];
49
+ /** Returns a warning message for dropping a column. */
38
50
  warnDropColumn?(table: DatabaseTable, column: string): string | undefined;
51
+ /** Generates SQL to alter a column. */
39
52
  alterColumnSql?(table: TableDef, column: ColumnDef, actualColumn: DatabaseColumn, diff: ColumnDiff): string[];
53
+ /** Returns a warning message for altering a column. */
40
54
  warnAlterColumn?(table: TableDef, column: ColumnDef, actualColumn: DatabaseColumn, diff: ColumnDiff): string | undefined;
41
55
  }
@@ -6,6 +6,7 @@ import { deriveIndexName } from './naming-strategy.js';
6
6
  import { generateCreateTableSql, renderColumnDefinition } from './schema-generator.js';
7
7
  import { ColumnDiff, DatabaseColumn, DatabaseSchema, DatabaseTable } from './schema-types.js';
8
8
 
9
+ /** The kind of schema change. */
9
10
  export type SchemaChangeKind =
10
11
  | 'createTable'
11
12
  | 'dropTable'
@@ -15,6 +16,7 @@ export type SchemaChangeKind =
15
16
  | 'addIndex'
16
17
  | 'dropIndex';
17
18
 
19
+ /** Represents a single schema change. */
18
20
  export interface SchemaChange {
19
21
  kind: SchemaChangeKind;
20
22
  table: string;
@@ -23,11 +25,13 @@ export interface SchemaChange {
23
25
  safe: boolean;
24
26
  }
25
27
 
28
+ /** Represents a plan of schema changes. */
26
29
  export interface SchemaPlan {
27
30
  changes: SchemaChange[];
28
31
  warnings: string[];
29
32
  }
30
33
 
34
+ /** Options for schema diffing. */
31
35
  export interface SchemaDiffOptions {
32
36
  /** Allow destructive operations (drops) */
33
37
  allowDestructive?: boolean;
@@ -69,6 +73,14 @@ const diffColumn = (expected: ColumnDef, actual: DatabaseColumn, dialect: Schema
69
73
  };
70
74
  };
71
75
 
76
+ /**
77
+ * Computes the differences between expected and actual database schemas.
78
+ * @param expectedTables - The expected table definitions.
79
+ * @param actualSchema - The actual database schema.
80
+ * @param dialect - The schema dialect.
81
+ * @param options - Options for the diff.
82
+ * @returns The schema plan with changes and warnings.
83
+ */
72
84
  export const diffSchema = (
73
85
  expectedTables: TableDef[],
74
86
  actualSchema: DatabaseSchema,
@@ -191,10 +203,20 @@ export const diffSchema = (
191
203
  return plan;
192
204
  };
193
205
 
206
+ /** Options for schema synchronization. */
194
207
  export interface SynchronizeOptions extends SchemaDiffOptions {
195
208
  dryRun?: boolean;
196
209
  }
197
210
 
211
+ /**
212
+ * Synchronizes the database schema with the expected tables.
213
+ * @param expectedTables - The expected table definitions.
214
+ * @param actualSchema - The actual database schema.
215
+ * @param dialect - The schema dialect.
216
+ * @param executor - The database executor.
217
+ * @param options - Options for synchronization.
218
+ * @returns The schema plan with changes and warnings.
219
+ */
198
220
  export const synchronizeSchema = async (
199
221
  expectedTables: TableDef[],
200
222
  actualSchema: DatabaseSchema,
@@ -1,26 +1,28 @@
1
- import type { TableDef, IndexDef, IndexColumn } from '../../schema/table.js';
2
- import type { ColumnDef, ForeignKeyReference } from '../../schema/column.js';
1
+ import type { TableDef } from '../../schema/table.js';
2
+ import type { ColumnDef } from '../../schema/column.js';
3
3
  import type { SchemaDialect } from './schema-dialect.js';
4
- import { deriveIndexName } from './naming-strategy.js';
5
- import {
6
- formatLiteral,
7
- renderIndexColumns,
8
- quoteQualified,
9
- resolvePrimaryKey,
10
- Quoter
11
- } from './sql-writing.js';
12
- import { DatabaseTable, DatabaseColumn, ColumnDiff } from './schema-types.js';
4
+ import { resolvePrimaryKey } from './sql-writing.js';
13
5
  import { DialectName } from './schema-dialect.js';
14
6
 
7
+ /** Result of generating schema SQL. */
15
8
  export interface SchemaGenerateResult {
16
9
  tableSql: string;
17
10
  indexSql: string[];
18
11
  }
19
12
 
13
+ /** Options for rendering column definitions. */
20
14
  export interface RenderColumnOptions {
21
15
  includePrimary?: boolean;
22
16
  }
23
17
 
18
+ /**
19
+ * Renders a column definition for SQL.
20
+ * @param table - The table definition.
21
+ * @param col - The column definition.
22
+ * @param dialect - The schema dialect.
23
+ * @param options - Options for rendering.
24
+ * @returns The rendered SQL and whether primary key is inline.
25
+ */
24
26
  export const renderColumnDefinition = (
25
27
  table: TableDef,
26
28
  col: ColumnDef,
@@ -52,6 +54,12 @@ export const renderColumnDefinition = (
52
54
  return { sql: parts.join(' '), inlinePrimary: !!(options.includePrimary && col.primary) };
53
55
  };
54
56
 
57
+ /**
58
+ * Generates SQL to create a table.
59
+ * @param table - The table definition.
60
+ * @param dialect - The schema dialect.
61
+ * @returns The table SQL and index SQL.
62
+ */
55
63
  export const generateCreateTableSql = (
56
64
  table: TableDef,
57
65
  dialect: SchemaDialect
@@ -60,7 +68,7 @@ export const generateCreateTableSql = (
60
68
  const inlinePkColumns = new Set<string>();
61
69
 
62
70
  const columnLines = Object.values(table.columns).map(col => {
63
- const includePk = (dialect as any).preferInlinePkAutoincrement?.(col, table, pk) && pk.includes(col.name);
71
+ const includePk = dialect.preferInlinePkAutoincrement(col, table, pk) && pk.includes(col.name);
64
72
  if (includePk) {
65
73
  inlinePkColumns.add(col.name);
66
74
  }
@@ -99,6 +107,12 @@ export const generateCreateTableSql = (
99
107
  return { tableSql, indexSql };
100
108
  };
101
109
 
110
+ /**
111
+ * Generates SQL for creating multiple tables.
112
+ * @param tables - The table definitions.
113
+ * @param dialect - The schema dialect.
114
+ * @returns The SQL statements.
115
+ */
102
116
  export const generateSchemaSql = (
103
117
  tables: TableDef[],
104
118
  dialect: SchemaDialect
@@ -1,6 +1,12 @@
1
1
  import { DbExecutor } from '../execution/db-executor.js';
2
2
  import type { SchemaPlan, SynchronizeOptions } from './schema-diff.js';
3
3
 
4
+ /**
5
+ * Executes a schema plan by running the SQL statements.
6
+ * @param plan - The schema plan to execute.
7
+ * @param executor - The database executor.
8
+ * @param options - Options for synchronization.
9
+ */
4
10
  export const executeSchemaPlan = async (
5
11
  plan: SchemaPlan,
6
12
  executor: DbExecutor,
@@ -1,6 +1,7 @@
1
1
  import { ForeignKeyReference } from '../../schema/column.js';
2
2
  import { IndexColumn } from '../../schema/table.js';
3
3
 
4
+ /** Represents the differences detected in a database column's properties. */
4
5
  export interface ColumnDiff {
5
6
  typeChanged?: boolean;
6
7
  nullabilityChanged?: boolean;
@@ -8,6 +9,7 @@ export interface ColumnDiff {
8
9
  autoIncrementChanged?: boolean;
9
10
  }
10
11
 
12
+ /** Represents a column in the database schema. */
11
13
  export interface DatabaseColumn {
12
14
  name: string;
13
15
  type: string;
@@ -20,6 +22,7 @@ export interface DatabaseColumn {
20
22
  check?: string;
21
23
  }
22
24
 
25
+ /** Represents an index in the database schema. */
23
26
  export interface DatabaseIndex {
24
27
  name: string;
25
28
  columns: IndexColumn[];
@@ -27,11 +30,13 @@ export interface DatabaseIndex {
27
30
  where?: string;
28
31
  }
29
32
 
33
+ /** Represents a check constraint in the database schema. */
30
34
  export interface DatabaseCheck {
31
35
  name?: string;
32
36
  expression: string;
33
37
  }
34
38
 
39
+ /** Represents a table in the database schema. */
35
40
  export interface DatabaseTable {
36
41
  name: string;
37
42
  schema?: string;
@@ -41,6 +46,7 @@ export interface DatabaseTable {
41
46
  checks?: DatabaseCheck[];
42
47
  }
43
48
 
49
+ /** Represents the overall database schema. */
44
50
  export interface DatabaseSchema {
45
51
  tables: DatabaseTable[];
46
52
  }
@@ -1,5 +1,5 @@
1
1
  import type { TableDef, IndexColumn } from '../../schema/table.js';
2
- import type { RawDefaultValue } from '../../schema/column.js';
2
+ import type { ColumnDef, RawDefaultValue } from '../../schema/column.js';
3
3
 
4
4
  /**
5
5
  * Minimal surface for anything that can quote identifiers.
@@ -161,10 +161,10 @@ export const resolvePrimaryKey = (table: TableDef): string[] => {
161
161
  return table.primaryKey;
162
162
  }
163
163
 
164
- const columns = Object.values(table.columns ?? {});
164
+ const columns = Object.values(table.columns ?? {}) as ColumnDef[];
165
165
 
166
166
  // `primary` / `name` are domain-level properties of ColumnDef.
167
167
  return columns
168
- .filter((col: any) => col.primary)
169
- .map((col: any) => col.name);
168
+ .filter(col => col.primary)
169
+ .map(col => col.name);
170
170
  };
@@ -157,8 +157,9 @@ export abstract class Dialect
157
157
 
158
158
  protected compileReturning(
159
159
  returning: ColumnNode[] | undefined,
160
- ctx: CompilerContext
160
+ _ctx: CompilerContext
161
161
  ): string {
162
+ void _ctx;
162
163
  if (!returning || returning.length === 0) return '';
163
164
  throw new Error('RETURNING is not supported by this dialect.');
164
165
  }
@@ -213,7 +214,8 @@ export abstract class Dialect
213
214
  * @param index - Parameter index
214
215
  * @returns Formatted placeholder string
215
216
  */
216
- protected formatPlaceholder(index: number): string {
217
+ protected formatPlaceholder(_index: number): string {
218
+ void _index;
217
219
  return '?';
218
220
  }
219
221
 
@@ -221,7 +223,8 @@ export abstract class Dialect
221
223
  * Whether the current dialect supports a given set operation.
222
224
  * Override in concrete dialects to restrict support.
223
225
  */
224
- protected supportsSetOperation(kind: SetOperationKind): boolean {
226
+ protected supportsSetOperation(_kind: SetOperationKind): boolean {
227
+ void _kind;
225
228
  return true;
226
229
  }
227
230
 
@@ -376,7 +379,8 @@ export abstract class Dialect
376
379
  if (isOperandNode(term)) {
377
380
  return this.compileOperand(term, ctx);
378
381
  }
379
- const expr = this.compileExpression(term as any, ctx);
382
+ // At this point, term must be an ExpressionNode
383
+ const expr = this.compileExpression(term as ExpressionNode, ctx);
380
384
  return `(${expr})`;
381
385
  }
382
386
 
@@ -438,15 +442,22 @@ export abstract class Dialect
438
442
  private registerDefaultOperandCompilers(): void {
439
443
  this.registerOperandCompiler('Literal', (literal: LiteralNode, ctx) => ctx.addParameter(literal.value));
440
444
 
441
- this.registerOperandCompiler('AliasRef', (alias: AliasRefNode, _ctx) => this.quoteIdentifier(alias.name));
445
+ this.registerOperandCompiler('AliasRef', (alias: AliasRefNode, _ctx) => {
446
+ void _ctx;
447
+ return this.quoteIdentifier(alias.name);
448
+ });
442
449
 
443
450
  this.registerOperandCompiler('Column', (column: ColumnNode, _ctx) => {
451
+ void _ctx;
444
452
  return `${this.quoteIdentifier(column.table)}.${this.quoteIdentifier(column.name)}`;
445
453
  });
446
454
  this.registerOperandCompiler('Function', (fnNode: FunctionNode, ctx) =>
447
455
  this.compileFunctionOperand(fnNode, ctx)
448
456
  );
449
- this.registerOperandCompiler('JsonPath', (path: JsonPathNode, _ctx) => this.compileJsonPath(path));
457
+ this.registerOperandCompiler('JsonPath', (path: JsonPathNode, _ctx) => {
458
+ void _ctx;
459
+ return this.compileJsonPath(path);
460
+ });
450
461
 
451
462
  this.registerOperandCompiler('ScalarSubquery', (node: ScalarSubqueryNode, ctx) => {
452
463
  const sql = this.compileSelectAst(node.query, ctx).trim().replace(/;$/, '');
@@ -499,7 +510,8 @@ export abstract class Dialect
499
510
  }
500
511
 
501
512
  // Default fallback, should be overridden by dialects if supported
502
- protected compileJsonPath(node: JsonPathNode): string {
513
+ protected compileJsonPath(_node: JsonPathNode): string {
514
+ void _node;
503
515
  throw new Error("JSON Path not supported by this dialect");
504
516
  }
505
517
 
@@ -1,4 +1,5 @@
1
1
  import { CompilerContext } from '../abstract.js';
2
+ import { OperandNode } from '../../ast/expression.js';
2
3
  import { SqlDialectBase } from './sql-dialect.js';
3
4
 
4
5
  export interface FunctionTableNode {
@@ -57,9 +58,9 @@ export class FunctionTableFormatter {
57
58
  */
58
59
  private static formatArgs(fn: FunctionTableNode, ctx?: CompilerContext, dialect?: SqlDialectBase): string {
59
60
  return (fn.args || [])
60
- .map((a: any) => {
61
+ .map((a: OperandNode) => {
61
62
  if (ctx && dialect) {
62
- return (dialect as any).compileOperand(a, ctx);
63
+ return (dialect as unknown as { compileOperand(n: OperandNode, c: CompilerContext): string }).compileOperand(a, ctx);
63
64
  }
64
65
  return String(a);
65
66
  })
@@ -1,5 +1,7 @@
1
1
  import { CompilerContext } from '../abstract.js';
2
2
  import { JoinNode } from '../../ast/join.js';
3
+ import { TableSourceNode } from '../../ast/query.js';
4
+ import { ExpressionNode } from '../../ast/expression.js';
3
5
 
4
6
  /**
5
7
  * Compiler for JOIN clauses in SELECT statements.
@@ -9,12 +11,12 @@ export class JoinCompiler {
9
11
  static compileJoins(
10
12
  joins: JoinNode[] | undefined,
11
13
  ctx: CompilerContext,
12
- compileFrom: (from: any, ctx: CompilerContext) => string,
13
- compileExpression: (expr: any, ctx: CompilerContext) => string
14
+ compileFrom: (from: TableSourceNode, ctx: CompilerContext) => string,
15
+ compileExpression: (expr: ExpressionNode, ctx: CompilerContext) => string
14
16
  ): string {
15
17
  if (!joins || joins.length === 0) return '';
16
18
  const parts = joins.map(j => {
17
- const table = compileFrom(j.table as any, ctx);
19
+ const table = compileFrom(j.table, ctx);
18
20
  const cond = compileExpression(j.condition, ctx);
19
21
  return `${j.kind} JOIN ${table} ON ${cond}`;
20
22
  });
@@ -35,6 +35,7 @@ export class NoReturningStrategy implements ReturningStrategy {
35
35
  * @throws Error indicating RETURNING is not supported.
36
36
  */
37
37
  compileReturning(returning: ColumnNode[] | undefined, _ctx: CompilerContext): string {
38
+ void _ctx;
38
39
  if (!returning || returning.length === 0) return '';
39
40
  throw new Error('RETURNING is not supported by this dialect.');
40
41
  }
@@ -11,7 +11,7 @@ import {
11
11
  OrderByNode,
12
12
  TableNode
13
13
  } from '../../ast/query.js';
14
- import { ColumnNode } from '../../ast/expression.js';
14
+ import { ColumnNode, OperandNode } from '../../ast/expression.js';
15
15
  import { FunctionTableFormatter } from './function-table-formatter.js';
16
16
  import { PaginationStrategy, StandardLimitOffsetPagination } from './pagination-strategy.js';
17
17
  import { CteCompiler } from './cte-compiler.js';
@@ -134,7 +134,7 @@ export abstract class SqlDialectBase extends Dialect {
134
134
  }
135
135
 
136
136
  private compileUpdateAssignments(
137
- assignments: { column: ColumnNode; value: any }[],
137
+ assignments: { column: ColumnNode; value: OperandNode }[],
138
138
  table: TableNode,
139
139
  ctx: CompilerContext
140
140
  ): string {
@@ -190,7 +190,7 @@ export abstract class SqlDialectBase extends Dialect {
190
190
  }
191
191
 
192
192
  protected compileFrom(ast: SelectQueryNode['from'], ctx?: CompilerContext): string {
193
- const tableSource = ast as any;
193
+ const tableSource = ast;
194
194
  if (tableSource.type === 'FunctionTable') {
195
195
  return this.compileFunctionTable(tableSource, ctx);
196
196
  }
@@ -1,5 +1,4 @@
1
1
  import { StandardFunctionStrategy } from '../../functions/standard-strategy.js';
2
- import { FunctionRenderContext } from '../../functions/types.js';
3
2
  import { LiteralNode } from '../../ast/expression.js';
4
3
 
5
4
  export class MssqlFunctionStrategy extends StandardFunctionStrategy {
@@ -84,27 +83,27 @@ export class MssqlFunctionStrategy extends StandardFunctionStrategy {
84
83
  return `DATEPART(dw, ${compiledArgs[0]})`;
85
84
  });
86
85
 
87
- this.add('WEEK_OF_YEAR', ({ compiledArgs }) => {
88
- if (compiledArgs.length !== 1) throw new Error('WEEK_OF_YEAR expects 1 argument');
89
- return `DATEPART(wk, ${compiledArgs[0]})`;
90
- });
91
-
92
- this.add('DATE_TRUNC', ({ node, compiledArgs }) => {
93
- if (compiledArgs.length !== 2) throw new Error('DATE_TRUNC expects 2 arguments (part, date)');
94
- const [, date] = compiledArgs;
95
- const partArg = node.args[0] as LiteralNode;
96
- const partClean = String(partArg.value).replace(/['"]/g, '').toLowerCase();
97
- // SQL Server 2022+ has DATETRUNC
98
- return `DATETRUNC(${partClean}, ${date})`;
99
- });
100
-
101
- this.add('GROUP_CONCAT', ctx => {
102
- const arg = ctx.compiledArgs[0];
103
- const separatorOperand = this.getGroupConcatSeparatorOperand(ctx);
104
- const separator = ctx.compileOperand(separatorOperand);
105
- const orderClause = this.buildOrderByExpression(ctx);
106
- const withinGroup = orderClause ? ` WITHIN GROUP (${orderClause})` : '';
107
- return `STRING_AGG(${arg}, ${separator})${withinGroup}`;
108
- });
109
- }
110
- }
86
+ this.add('WEEK_OF_YEAR', ({ compiledArgs }) => {
87
+ if (compiledArgs.length !== 1) throw new Error('WEEK_OF_YEAR expects 1 argument');
88
+ return `DATEPART(wk, ${compiledArgs[0]})`;
89
+ });
90
+
91
+ this.add('DATE_TRUNC', ({ node, compiledArgs }) => {
92
+ if (compiledArgs.length !== 2) throw new Error('DATE_TRUNC expects 2 arguments (part, date)');
93
+ const [, date] = compiledArgs;
94
+ const partArg = node.args[0] as LiteralNode;
95
+ const partClean = String(partArg.value).replace(/['"]/g, '').toLowerCase();
96
+ // SQL Server 2022+ has DATETRUNC
97
+ return `DATETRUNC(${partClean}, ${date})`;
98
+ });
99
+
100
+ this.add('GROUP_CONCAT', ctx => {
101
+ const arg = ctx.compiledArgs[0];
102
+ const separatorOperand = this.getGroupConcatSeparatorOperand(ctx);
103
+ const separator = ctx.compileOperand(separatorOperand);
104
+ const orderClause = this.buildOrderByExpression(ctx);
105
+ const withinGroup = orderClause ? ` WITHIN GROUP (${orderClause})` : '';
106
+ return `STRING_AGG(${arg}, ${separator})${withinGroup}`;
107
+ });
108
+ }
109
+ }
@@ -1,10 +1,7 @@
1
1
  import { CompilerContext } from '../abstract.js';
2
2
  import {
3
3
  SelectQueryNode,
4
- DeleteQueryNode,
5
- TableSourceNode,
6
- DerivedTableNode,
7
- OrderByNode
4
+ DeleteQueryNode
8
5
  } from '../../ast/query.js';
9
6
  import { JsonPathNode } from '../../ast/expression.js';
10
7
  import { MssqlFunctionStrategy } from './functions.js';
@@ -1,5 +1,4 @@
1
1
  import { StandardFunctionStrategy } from '../../functions/standard-strategy.js';
2
- import { FunctionRenderContext } from '../../functions/types.js';
3
2
  import { LiteralNode } from '../../ast/expression.js';
4
3
 
5
4
  export class MysqlFunctionStrategy extends StandardFunctionStrategy {
@@ -1,5 +1,4 @@
1
1
  import { StandardFunctionStrategy } from '../../functions/standard-strategy.js';
2
- import { FunctionRenderContext } from '../../functions/types.js';
3
2
  import { LiteralNode } from '../../ast/expression.js';
4
3
 
5
4
  export class PostgresFunctionStrategy extends StandardFunctionStrategy {
@@ -69,36 +68,36 @@ export class PostgresFunctionStrategy extends StandardFunctionStrategy {
69
68
  return `TO_CHAR(${date}, ${format})`;
70
69
  });
71
70
 
72
- this.add('END_OF_MONTH', ({ compiledArgs }) => {
73
- if (compiledArgs.length !== 1) throw new Error('END_OF_MONTH expects 1 argument');
74
- return `(date_trunc('month', ${compiledArgs[0]}) + interval '1 month' - interval '1 day')::DATE`;
75
- });
76
-
77
- this.add('DAY_OF_WEEK', ({ compiledArgs }) => {
78
- if (compiledArgs.length !== 1) throw new Error('DAY_OF_WEEK expects 1 argument');
79
- return `EXTRACT(DOW FROM ${compiledArgs[0]})`;
80
- });
81
-
82
- this.add('WEEK_OF_YEAR', ({ compiledArgs }) => {
83
- if (compiledArgs.length !== 1) throw new Error('WEEK_OF_YEAR expects 1 argument');
84
- return `EXTRACT(WEEK FROM ${compiledArgs[0]})`;
85
- });
86
-
87
- this.add('DATE_TRUNC', ({ node, compiledArgs }) => {
88
- if (compiledArgs.length !== 2) throw new Error('DATE_TRUNC expects 2 arguments (part, date)');
89
- const [, date] = compiledArgs;
90
- const partArg = node.args[0] as LiteralNode;
91
- const partClean = String(partArg.value).replace(/['"]/g, '').toLowerCase();
92
- return `DATE_TRUNC('${partClean}', ${date})`;
93
- });
94
-
95
- this.add('GROUP_CONCAT', ctx => {
96
- const arg = ctx.compiledArgs[0];
97
- const orderClause = this.buildOrderByExpression(ctx);
98
- const orderSegment = orderClause ? ` ${orderClause}` : '';
99
- const separatorOperand = this.getGroupConcatSeparatorOperand(ctx);
100
- const separator = ctx.compileOperand(separatorOperand);
101
- return `STRING_AGG(${arg}, ${separator}${orderSegment})`;
102
- });
103
- }
104
- }
71
+ this.add('END_OF_MONTH', ({ compiledArgs }) => {
72
+ if (compiledArgs.length !== 1) throw new Error('END_OF_MONTH expects 1 argument');
73
+ return `(date_trunc('month', ${compiledArgs[0]}) + interval '1 month' - interval '1 day')::DATE`;
74
+ });
75
+
76
+ this.add('DAY_OF_WEEK', ({ compiledArgs }) => {
77
+ if (compiledArgs.length !== 1) throw new Error('DAY_OF_WEEK expects 1 argument');
78
+ return `EXTRACT(DOW FROM ${compiledArgs[0]})`;
79
+ });
80
+
81
+ this.add('WEEK_OF_YEAR', ({ compiledArgs }) => {
82
+ if (compiledArgs.length !== 1) throw new Error('WEEK_OF_YEAR expects 1 argument');
83
+ return `EXTRACT(WEEK FROM ${compiledArgs[0]})`;
84
+ });
85
+
86
+ this.add('DATE_TRUNC', ({ node, compiledArgs }) => {
87
+ if (compiledArgs.length !== 2) throw new Error('DATE_TRUNC expects 2 arguments (part, date)');
88
+ const [, date] = compiledArgs;
89
+ const partArg = node.args[0] as LiteralNode;
90
+ const partClean = String(partArg.value).replace(/['"]/g, '').toLowerCase();
91
+ return `DATE_TRUNC('${partClean}', ${date})`;
92
+ });
93
+
94
+ this.add('GROUP_CONCAT', ctx => {
95
+ const arg = ctx.compiledArgs[0];
96
+ const orderClause = this.buildOrderByExpression(ctx);
97
+ const orderSegment = orderClause ? ` ${orderClause}` : '';
98
+ const separatorOperand = this.getGroupConcatSeparatorOperand(ctx);
99
+ const separator = ctx.compileOperand(separatorOperand);
100
+ return `STRING_AGG(${arg}, ${separator}${orderSegment})`;
101
+ });
102
+ }
103
+ }
@@ -36,6 +36,7 @@ export class PostgresDialect extends SqlDialectBase {
36
36
  }
37
37
 
38
38
  protected compileReturning(returning: ColumnNode[] | undefined, ctx: CompilerContext): string {
39
+ void ctx;
39
40
  if (!returning || returning.length === 0) return '';
40
41
  const columns = this.formatReturningColumns(returning);
41
42
  return ` RETURNING ${columns}`;
@@ -1,12 +1,11 @@
1
- import { StandardFunctionStrategy } from '../../functions/standard-strategy.js';
2
- import { FunctionRenderContext } from '../../functions/types.js';
3
- import { LiteralNode } from '../../ast/expression.js';
4
-
5
- export class SqliteFunctionStrategy extends StandardFunctionStrategy {
6
- constructor() {
7
- super();
8
- this.registerOverrides();
9
- }
1
+ import { StandardFunctionStrategy } from '../../functions/standard-strategy.js';
2
+ import { LiteralNode } from '../../ast/expression.js';
3
+
4
+ export class SqliteFunctionStrategy extends StandardFunctionStrategy {
5
+ constructor() {
6
+ super();
7
+ this.registerOverrides();
8
+ }
10
9
 
11
10
  private registerOverrides() {
12
11
  // Override Standard/Abstract definitions with SQLite specifics
@@ -110,13 +109,13 @@ export class SqliteFunctionStrategy extends StandardFunctionStrategy {
110
109
  return `date(${date})`;
111
110
  }
112
111
  return `date(${date}, 'start of ${partClean}')`;
113
- });
114
-
115
- this.add('GROUP_CONCAT', ctx => {
116
- const arg = ctx.compiledArgs[0];
117
- const separatorOperand = this.getGroupConcatSeparatorOperand(ctx);
118
- const separator = ctx.compileOperand(separatorOperand);
119
- return `GROUP_CONCAT(${arg}, ${separator})`;
120
- });
121
- }
122
- }
112
+ });
113
+
114
+ this.add('GROUP_CONCAT', ctx => {
115
+ const arg = ctx.compiledArgs[0];
116
+ const separatorOperand = this.getGroupConcatSeparatorOperand(ctx);
117
+ const separator = ctx.compileOperand(separatorOperand);
118
+ return `GROUP_CONCAT(${arg}, ${separator})`;
119
+ });
120
+ }
121
+ }
@@ -37,10 +37,12 @@ export class SqliteDialect extends SqlDialectBase {
37
37
  }
38
38
 
39
39
  protected compileQualifiedColumn(column: ColumnNode, _table: TableNode): string {
40
+ void _table;
40
41
  return this.quoteIdentifier(column.name);
41
42
  }
42
43
 
43
44
  protected compileReturning(returning: ColumnNode[] | undefined, ctx: CompilerContext): string {
45
+ void ctx;
44
46
  if (!returning || returning.length === 0) return '';
45
47
  const columns = this.formatReturningColumns(returning);
46
48
  return ` RETURNING ${columns}`;