metal-orm 1.0.42 → 1.0.43

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 (86) hide show
  1. package/README.md +22 -7
  2. package/dist/index.cjs +130 -74
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +121 -96
  5. package/dist/index.d.ts +121 -96
  6. package/dist/index.js +128 -74
  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/builders.ts +7 -2
  12. package/src/core/ast/expression-builders.ts +0 -2
  13. package/src/core/ast/expression-nodes.ts +14 -5
  14. package/src/core/ast/expression-visitor.ts +11 -8
  15. package/src/core/ast/join-node.ts +1 -1
  16. package/src/core/ast/query.ts +6 -6
  17. package/src/core/ast/window-functions.ts +10 -2
  18. package/src/core/ddl/dialects/base-schema-dialect.ts +30 -3
  19. package/src/core/ddl/dialects/mssql-schema-dialect.ts +4 -0
  20. package/src/core/ddl/dialects/mysql-schema-dialect.ts +2 -0
  21. package/src/core/ddl/dialects/postgres-schema-dialect.ts +13 -1
  22. package/src/core/ddl/dialects/render-reference.test.ts +69 -0
  23. package/src/core/ddl/dialects/sqlite-schema-dialect.ts +9 -0
  24. package/src/core/ddl/introspect/mssql.ts +42 -8
  25. package/src/core/ddl/introspect/mysql.ts +30 -6
  26. package/src/core/ddl/introspect/postgres.ts +88 -34
  27. package/src/core/ddl/introspect/run-select.ts +6 -4
  28. package/src/core/ddl/introspect/sqlite.ts +56 -11
  29. package/src/core/ddl/introspect/types.ts +0 -1
  30. package/src/core/ddl/introspect/utils.ts +3 -3
  31. package/src/core/ddl/schema-dialect.ts +1 -0
  32. package/src/core/ddl/schema-generator.ts +4 -12
  33. package/src/core/ddl/sql-writing.ts +4 -4
  34. package/src/core/dialect/abstract.ts +18 -6
  35. package/src/core/dialect/base/function-table-formatter.ts +3 -2
  36. package/src/core/dialect/base/join-compiler.ts +5 -3
  37. package/src/core/dialect/base/returning-strategy.ts +1 -0
  38. package/src/core/dialect/base/sql-dialect.ts +3 -3
  39. package/src/core/dialect/mssql/functions.ts +24 -25
  40. package/src/core/dialect/mssql/index.ts +1 -4
  41. package/src/core/dialect/mysql/functions.ts +0 -1
  42. package/src/core/dialect/postgres/functions.ts +33 -34
  43. package/src/core/dialect/postgres/index.ts +1 -0
  44. package/src/core/dialect/sqlite/functions.ts +18 -19
  45. package/src/core/dialect/sqlite/index.ts +2 -0
  46. package/src/core/execution/db-executor.ts +1 -1
  47. package/src/core/execution/executors/mysql-executor.ts +2 -2
  48. package/src/core/execution/executors/postgres-executor.ts +1 -1
  49. package/src/core/execution/pooling/pool.ts +2 -0
  50. package/src/core/functions/datetime.ts +1 -1
  51. package/src/core/functions/numeric.ts +1 -1
  52. package/src/core/functions/text.ts +1 -1
  53. package/src/decorators/bootstrap.ts +27 -8
  54. package/src/decorators/column.ts +3 -11
  55. package/src/decorators/decorator-metadata.ts +3 -9
  56. package/src/decorators/entity.ts +21 -5
  57. package/src/decorators/relations.ts +2 -11
  58. package/src/orm/entity-context.ts +8 -8
  59. package/src/orm/entity-meta.ts +8 -8
  60. package/src/orm/entity-metadata.ts +11 -9
  61. package/src/orm/entity.ts +28 -29
  62. package/src/orm/execute.ts +4 -4
  63. package/src/orm/hydration.ts +42 -39
  64. package/src/orm/identity-map.ts +1 -1
  65. package/src/orm/lazy-batch.ts +9 -9
  66. package/src/orm/orm-session.ts +24 -23
  67. package/src/orm/orm.ts +2 -5
  68. package/src/orm/relation-change-processor.ts +12 -11
  69. package/src/orm/relations/belongs-to.ts +11 -11
  70. package/src/orm/relations/has-many.ts +10 -10
  71. package/src/orm/relations/has-one.ts +8 -7
  72. package/src/orm/relations/many-to-many.ts +13 -13
  73. package/src/orm/runtime-types.ts +4 -4
  74. package/src/orm/save-graph.ts +31 -25
  75. package/src/orm/unit-of-work.ts +17 -17
  76. package/src/query-builder/delete.ts +4 -3
  77. package/src/query-builder/hydration-manager.ts +6 -5
  78. package/src/query-builder/insert.ts +12 -8
  79. package/src/query-builder/query-ast-service.ts +2 -2
  80. package/src/query-builder/raw-column-parser.ts +2 -1
  81. package/src/query-builder/select-helpers.ts +2 -2
  82. package/src/query-builder/select.ts +31 -31
  83. package/src/query-builder/update.ts +4 -3
  84. package/src/schema/column.ts +26 -26
  85. package/src/schema/table.ts +47 -18
  86. package/src/schema/types.ts +22 -22
@@ -3,13 +3,37 @@ import { queryRows, shouldIncludeTable } from './utils.js';
3
3
  import { DatabaseSchema, DatabaseTable, DatabaseIndex, DatabaseColumn } from '../schema-types.js';
4
4
  import { DbExecutor } from '../../execution/db-executor.js';
5
5
 
6
+ type MysqlColumnRow = {
7
+ table_schema: string;
8
+ table_name: string;
9
+ column_name: string;
10
+ data_type: string;
11
+ is_nullable: string;
12
+ column_default: string | null;
13
+ extra: string | null;
14
+ };
15
+
16
+ type MysqlPrimaryKeyRow = {
17
+ table_schema: string;
18
+ table_name: string;
19
+ column_name: string;
20
+ };
21
+
22
+ type MysqlIndexRow = {
23
+ table_schema: string;
24
+ table_name: string;
25
+ index_name: string;
26
+ non_unique: number;
27
+ cols: string | null;
28
+ };
29
+
6
30
  export const mysqlIntrospector: SchemaIntrospector = {
7
31
  async introspect(ctx: { executor: DbExecutor }, options: IntrospectOptions): Promise<DatabaseSchema> {
8
32
  const schema = options.schema;
9
33
  const filterClause = schema ? 'table_schema = ?' : 'table_schema = database()';
10
34
  const params = schema ? [schema] : [];
11
35
 
12
- const columnRows = await queryRows(
36
+ const columnRows = (await queryRows(
13
37
  ctx.executor,
14
38
  `
15
39
  SELECT table_schema, table_name, column_name, data_type, is_nullable, column_default, extra
@@ -18,9 +42,9 @@ export const mysqlIntrospector: SchemaIntrospector = {
18
42
  ORDER BY table_name, ordinal_position
19
43
  `,
20
44
  params
21
- );
45
+ )) as MysqlColumnRow[];
22
46
 
23
- const pkRows = await queryRows(
47
+ const pkRows = (await queryRows(
24
48
  ctx.executor,
25
49
  `
26
50
  SELECT table_schema, table_name, column_name
@@ -29,7 +53,7 @@ export const mysqlIntrospector: SchemaIntrospector = {
29
53
  ORDER BY ordinal_position
30
54
  `,
31
55
  params
32
- );
56
+ )) as MysqlPrimaryKeyRow[];
33
57
 
34
58
  const pkMap = new Map<string, string[]>();
35
59
  pkRows.forEach(r => {
@@ -39,7 +63,7 @@ export const mysqlIntrospector: SchemaIntrospector = {
39
63
  pkMap.set(key, list);
40
64
  });
41
65
 
42
- const indexRows = await queryRows(
66
+ const indexRows = (await queryRows(
43
67
  ctx.executor,
44
68
  `
45
69
  SELECT
@@ -53,7 +77,7 @@ export const mysqlIntrospector: SchemaIntrospector = {
53
77
  GROUP BY table_schema, table_name, index_name, non_unique
54
78
  `,
55
79
  params
56
- );
80
+ )) as MysqlIndexRow[];
57
81
 
58
82
  const tablesByKey = new Map<string, DatabaseTable>();
59
83
 
@@ -1,10 +1,10 @@
1
1
  import type { SchemaIntrospector, IntrospectOptions } from './types.js';
2
- import { queryRows, shouldIncludeTable } from './utils.js';
2
+ import { shouldIncludeTable } from './utils.js';
3
3
  import { DatabaseSchema, DatabaseTable, DatabaseIndex, DatabaseColumn } from '../schema-types.js';
4
- import type { DbExecutor } from '../../execution/db-executor.js';
4
+ import type { ReferentialAction } from '../../../schema/column.js';
5
5
  import type { IntrospectContext } from './context.js';
6
6
  import { PgInformationSchemaColumns } from './catalogs/postgres.js';
7
- import { PgKeyColumnUsage, PgTableConstraints, PgConstraintColumnUsage, PgReferentialConstraints, PgIndex, PgClass, PgNamespace, PgAttribute } from './catalogs/postgres.js';
7
+ import { PgKeyColumnUsage, PgTableConstraints, PgConstraintColumnUsage, PgReferentialConstraints } from './catalogs/postgres.js';
8
8
  import { SelectQueryBuilder } from '../../../query-builder/select.js';
9
9
  import { eq, and } from '../../ast/expression-builders.js';
10
10
  import type { SelectQueryNode, TableNode } from '../../ast/query.js';
@@ -13,13 +13,67 @@ import type { ColumnNode, ExpressionNode } from '../../ast/expression-nodes.js';
13
13
  import { fnTable } from '../../ast/builders.js';
14
14
  import { runSelect, runSelectNode } from './run-select.js';
15
15
 
16
+ type ColumnIntrospectRow = {
17
+ table_schema: string;
18
+ table_name: string;
19
+ column_name: string;
20
+ data_type: string;
21
+ is_nullable: string;
22
+ column_default: string | null;
23
+ ordinal_position: number | null;
24
+ };
25
+
26
+ type PrimaryKeyIntrospectRow = {
27
+ table_schema: string;
28
+ table_name: string;
29
+ column_name: string;
30
+ ordinal_position: number | null;
31
+ constraint_name: string;
32
+ };
33
+
34
+ type ForeignKeyIntrospectRow = {
35
+ table_schema: string;
36
+ table_name: string;
37
+ column_name: string;
38
+ constraint_name: string;
39
+ foreign_table_schema: string;
40
+ foreign_table_name: string;
41
+ foreign_column_name: string;
42
+ };
43
+
44
+ type ForeignKeyEntry = {
45
+ table: string;
46
+ column: string;
47
+ onDelete?: ReferentialAction;
48
+ onUpdate?: ReferentialAction;
49
+ };
50
+
51
+ type IndexQueryRow = {
52
+ table_schema: string;
53
+ table_name: string;
54
+ index_name: string;
55
+ is_unique: boolean;
56
+ predicate: string | null;
57
+ attname: string | null;
58
+ ord: number | null;
59
+ };
60
+
61
+ type IndexGroup = {
62
+ table_schema: string;
63
+ table_name: string;
64
+ index_name: string;
65
+ is_unique: boolean;
66
+ predicate: string | null;
67
+ cols: { ord: number; att: string | null }[];
68
+ };
69
+
16
70
  export const postgresIntrospector: SchemaIntrospector = {
17
71
  async introspect(ctx: IntrospectContext, options: IntrospectOptions): Promise<DatabaseSchema> {
18
72
  const schema = options.schema || 'public';
19
73
  const tables: DatabaseTable[] = [];
20
74
 
21
75
  // Columns query
22
- const qbColumns = new SelectQueryBuilder(PgInformationSchemaColumns as any)
76
+ const qbColumns = new SelectQueryBuilder(PgInformationSchemaColumns)
23
77
  .select({
24
78
  table_schema: PgInformationSchemaColumns.columns.table_schema,
25
79
  table_name: PgInformationSchemaColumns.columns.table_name,
@@ -33,10 +87,10 @@ export const postgresIntrospector: SchemaIntrospector = {
33
87
  .orderBy(PgInformationSchemaColumns.columns.table_name)
34
88
  .orderBy(PgInformationSchemaColumns.columns.ordinal_position);
35
89
 
36
- const columnRows = await runSelect(qbColumns, ctx);
90
+ const columnRows = await runSelect<ColumnIntrospectRow>(qbColumns, ctx);
37
91
 
38
92
  // Primary key columns query
39
- const qbPk = new SelectQueryBuilder(PgKeyColumnUsage as any)
93
+ const qbPk = new SelectQueryBuilder(PgKeyColumnUsage)
40
94
  .select({
41
95
  table_schema: PgKeyColumnUsage.columns.table_schema,
42
96
  table_name: PgKeyColumnUsage.columns.table_name,
@@ -44,13 +98,13 @@ export const postgresIntrospector: SchemaIntrospector = {
44
98
  ordinal_position: PgKeyColumnUsage.columns.ordinal_position,
45
99
  constraint_name: PgKeyColumnUsage.columns.constraint_name
46
100
  })
47
- .innerJoin(PgTableConstraints as any, eq(PgTableConstraints.columns.constraint_name, PgKeyColumnUsage.columns.constraint_name))
101
+ .innerJoin(PgTableConstraints, eq(PgTableConstraints.columns.constraint_name, PgKeyColumnUsage.columns.constraint_name))
48
102
  .where(eq(PgTableConstraints.columns.constraint_type, 'PRIMARY KEY'))
49
103
  .where(eq(PgKeyColumnUsage.columns.table_schema, schema))
50
104
  .orderBy(PgKeyColumnUsage.columns.table_name)
51
105
  .orderBy(PgKeyColumnUsage.columns.ordinal_position);
52
106
 
53
- const pkRows = await runSelect(qbPk, ctx);
107
+ const pkRows = await runSelect<PrimaryKeyIntrospectRow>(qbPk, ctx);
54
108
 
55
109
  // Build primary key map (grouped by table, ordered by ordinal_position)
56
110
  const pkMap = new Map<string, string[]>();
@@ -67,7 +121,7 @@ export const postgresIntrospector: SchemaIntrospector = {
67
121
  }
68
122
 
69
123
  // Foreign key columns query
70
- const qbFk = new SelectQueryBuilder(PgKeyColumnUsage as any)
124
+ const qbFk = new SelectQueryBuilder(PgKeyColumnUsage)
71
125
  .select({
72
126
  table_schema: PgKeyColumnUsage.columns.table_schema,
73
127
  table_name: PgKeyColumnUsage.columns.table_name,
@@ -77,16 +131,16 @@ export const postgresIntrospector: SchemaIntrospector = {
77
131
  foreign_table_name: PgConstraintColumnUsage.columns.table_name,
78
132
  foreign_column_name: PgConstraintColumnUsage.columns.column_name
79
133
  })
80
- .innerJoin(PgTableConstraints as any, eq(PgTableConstraints.columns.constraint_name, PgKeyColumnUsage.columns.constraint_name))
81
- .innerJoin(PgConstraintColumnUsage as any, eq(PgConstraintColumnUsage.columns.constraint_name, PgTableConstraints.columns.constraint_name))
82
- .innerJoin(PgReferentialConstraints as any, eq(PgReferentialConstraints.columns.constraint_name, PgTableConstraints.columns.constraint_name))
134
+ .innerJoin(PgTableConstraints, eq(PgTableConstraints.columns.constraint_name, PgKeyColumnUsage.columns.constraint_name))
135
+ .innerJoin(PgConstraintColumnUsage, eq(PgConstraintColumnUsage.columns.constraint_name, PgTableConstraints.columns.constraint_name))
136
+ .innerJoin(PgReferentialConstraints, eq(PgReferentialConstraints.columns.constraint_name, PgTableConstraints.columns.constraint_name))
83
137
  .where(eq(PgTableConstraints.columns.constraint_type, 'FOREIGN KEY'))
84
138
  .where(eq(PgKeyColumnUsage.columns.table_schema, schema));
85
139
 
86
- const fkRows = await runSelect(qbFk, ctx);
140
+ const fkRows = await runSelect<ForeignKeyIntrospectRow>(qbFk, ctx);
87
141
 
88
142
  // Build foreign key map
89
- const fkMap = new Map<string, any[]>();
143
+ const fkMap = new Map<string, ForeignKeyEntry[]>();
90
144
  for (const r of fkRows) {
91
145
  const key = `${r.table_schema}.${r.table_name}.${r.column_name}`;
92
146
  const existing = fkMap.get(key) ?? [];
@@ -138,10 +192,10 @@ export const postgresIntrospector: SchemaIntrospector = {
138
192
  {
139
193
  type: 'Join',
140
194
  kind: 'INNER',
141
- table: fnTable('unnest', [{ type: 'Column', table: 'i', name: 'indkey' } as ColumnNode], 'arr', {
142
- lateral: true,
143
- withOrdinality: true,
144
- columnAliases: ['attnum', 'idx']
195
+ table: fnTable('unnest', [{ type: 'Column', table: 'i', name: 'indkey' } as ColumnNode], 'arr', {
196
+ lateral: true,
197
+ withOrdinality: true,
198
+ columnAliases: ['attnum', 'idx']
145
199
  }),
146
200
  condition: { type: 'BinaryExpression', left: { type: 'Literal', value: 1 }, operator: '=', right: { type: 'Literal', value: 1 } } as unknown as ExpressionNode
147
201
  } as JoinNode,
@@ -158,23 +212,23 @@ export const postgresIntrospector: SchemaIntrospector = {
158
212
  ],
159
213
  where: and(
160
214
  eq({ table: 'ns', name: 'nspname' }, schema) as ExpressionNode,
161
- eq({ table: 'i', name: 'indisprimary' }, { type: 'Literal', value: false } as any) as ExpressionNode
215
+ eq({ table: 'i', name: 'indisprimary' }, false) as ExpressionNode
162
216
  ) as ExpressionNode
163
217
  };
164
218
 
165
- const indexQueryRows = await runSelectNode(indexQuery, ctx);
166
-
219
+ const indexQueryRows = await runSelectNode<IndexQueryRow>(indexQuery, ctx);
220
+
167
221
  // Aggregate index rows by table/index to build final index list
168
- const indexGrouped = new Map<string, { table_schema: string; table_name: string; index_name: string; is_unique: any; predicate: any; cols: { ord: number; att: string | null }[] }>();
222
+ const indexGrouped = new Map<string, IndexGroup>();
169
223
  for (const r of indexQueryRows) {
170
224
  const key = `${r.table_schema}.${r.table_name}.${r.index_name}`;
171
- const entry = indexGrouped.get(key) ?? {
172
- table_schema: r.table_schema,
173
- table_name: r.table_name,
174
- index_name: r.index_name,
175
- is_unique: r.is_unique,
176
- predicate: r.predicate,
177
- cols: []
225
+ const entry = indexGrouped.get(key) ?? {
226
+ table_schema: r.table_schema,
227
+ table_name: r.table_name,
228
+ index_name: r.index_name,
229
+ is_unique: r.is_unique,
230
+ predicate: r.predicate,
231
+ cols: []
178
232
  };
179
233
  entry.cols.push({ ord: r.ord ?? 0, att: r.attname ?? null });
180
234
  indexGrouped.set(key, entry);
@@ -215,11 +269,11 @@ export const postgresIntrospector: SchemaIntrospector = {
215
269
  default: r.column_default ?? undefined,
216
270
  references: fk
217
271
  ? {
218
- table: fk.table,
219
- column: fk.column,
220
- onDelete: fk.onDelete,
221
- onUpdate: fk.onUpdate
222
- }
272
+ table: fk.table,
273
+ column: fk.column,
274
+ onDelete: fk.onDelete,
275
+ onUpdate: fk.onUpdate
276
+ }
223
277
  : undefined
224
278
  };
225
279
  cols.columns.push(column);
@@ -1,10 +1,12 @@
1
- import type { SelectQueryBuilder } from '../../../query-builder/select.js';
2
1
  import type { IntrospectContext } from './context.js';
2
+ import type { SelectQueryNode } from '../../ast/query.js';
3
3
 
4
4
  import { toRows } from './utils.js';
5
5
 
6
- export async function runSelect<T = Record<string, any>>(
7
- qb: SelectQueryBuilder<any, any>,
6
+ type SelectQuerySource = { getAST(): SelectQueryNode };
7
+
8
+ export async function runSelect<T = Record<string, unknown>>(
9
+ qb: SelectQuerySource,
8
10
  ctx: IntrospectContext
9
11
  ): Promise<T[]> {
10
12
  const ast = qb.getAST();
@@ -17,7 +19,7 @@ export async function runSelect<T = Record<string, any>>(
17
19
 
18
20
  export default runSelect;
19
21
 
20
- export async function runSelectNode<T = Record<string, any>>(ast: any, ctx: IntrospectContext): Promise<T[]> {
22
+ export async function runSelectNode<T = Record<string, unknown>>(ast: SelectQueryNode, ctx: IntrospectContext): Promise<T[]> {
21
23
  const compiled = ctx.dialect.compileSelect(ast);
22
24
  const results = await ctx.executor.executeSql(compiled.sql, compiled.params);
23
25
  const [first] = results;
@@ -1,24 +1,69 @@
1
1
  import { SchemaIntrospector, IntrospectOptions } from './types.js';
2
2
  import { queryRows, shouldIncludeTable } from './utils.js';
3
3
  import { DatabaseSchema, DatabaseTable, DatabaseIndex } from '../schema-types.js';
4
+ import { ReferentialAction } from '../../../schema/column.js';
4
5
  import { DbExecutor } from '../../execution/db-executor.js';
5
6
 
7
+ type SqliteTableRow = {
8
+ name: string;
9
+ };
10
+
11
+ type SqliteTableInfoRow = {
12
+ name: string;
13
+ type: string;
14
+ notnull: number;
15
+ dflt_value: string | null;
16
+ pk: number;
17
+ };
18
+
19
+ type SqliteForeignKeyRow = {
20
+ table: string;
21
+ from: string;
22
+ to: string;
23
+ on_delete: string | null;
24
+ on_update: string | null;
25
+ };
26
+
27
+ type SqliteIndexListRow = {
28
+ name: string;
29
+ unique: number;
30
+ };
31
+
32
+ type SqliteIndexInfoRow = {
33
+ name: string;
34
+ };
35
+
36
+ const toReferentialAction = (value: string | null | undefined): ReferentialAction | undefined => {
37
+ if (!value) return undefined;
38
+ const normalized = value.toUpperCase();
39
+ if (
40
+ normalized === 'NO ACTION' ||
41
+ normalized === 'RESTRICT' ||
42
+ normalized === 'CASCADE' ||
43
+ normalized === 'SET NULL' ||
44
+ normalized === 'SET DEFAULT'
45
+ ) {
46
+ return normalized as ReferentialAction;
47
+ }
48
+ return undefined;
49
+ };
50
+
6
51
  const escapeSingleQuotes = (name: string) => name.replace(/'/g, "''");
7
52
 
8
53
  export const sqliteIntrospector: SchemaIntrospector = {
9
54
  async introspect(ctx: { executor: DbExecutor }, options: IntrospectOptions): Promise<DatabaseSchema> {
10
55
  const tables: DatabaseTable[] = [];
11
- const tableRows = await queryRows(
56
+ const tableRows = (await queryRows(
12
57
  ctx.executor,
13
58
  `SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%';`
14
- );
59
+ )) as SqliteTableRow[];
15
60
 
16
61
  for (const row of tableRows) {
17
- const name = row.name as string;
62
+ const name = row.name;
18
63
  if (!shouldIncludeTable(name, options)) continue;
19
64
  const table: DatabaseTable = { name, columns: [], primaryKey: [], indexes: [] };
20
65
 
21
- const cols = await queryRows(ctx.executor, `PRAGMA table_info('${escapeSingleQuotes(name)}');`);
66
+ const cols = (await queryRows(ctx.executor, `PRAGMA table_info('${escapeSingleQuotes(name)}');`)) as SqliteTableInfoRow[];
22
67
  cols.forEach(c => {
23
68
  table.columns.push({
24
69
  name: c.name,
@@ -33,26 +78,26 @@ export const sqliteIntrospector: SchemaIntrospector = {
33
78
  }
34
79
  });
35
80
 
36
- const fkRows = await queryRows(ctx.executor, `PRAGMA foreign_key_list('${escapeSingleQuotes(name)}');`);
81
+ const fkRows = (await queryRows(ctx.executor, `PRAGMA foreign_key_list('${escapeSingleQuotes(name)}');`)) as SqliteForeignKeyRow[];
37
82
  fkRows.forEach(fk => {
38
83
  const col = table.columns.find(c => c.name === fk.from);
39
84
  if (col) {
40
85
  col.references = {
41
86
  table: fk.table,
42
87
  column: fk.to,
43
- onDelete: fk.on_delete?.toUpperCase(),
44
- onUpdate: fk.on_update?.toUpperCase()
88
+ onDelete: toReferentialAction(fk.on_delete),
89
+ onUpdate: toReferentialAction(fk.on_update)
45
90
  };
46
91
  }
47
92
  });
48
93
 
49
- const idxList = await queryRows(ctx.executor, `PRAGMA index_list('${escapeSingleQuotes(name)}');`);
94
+ const idxList = (await queryRows(ctx.executor, `PRAGMA index_list('${escapeSingleQuotes(name)}');`)) as SqliteIndexListRow[];
50
95
  for (const idx of idxList) {
51
- const idxName = idx.name as string;
52
- const columnsInfo = await queryRows(ctx.executor, `PRAGMA index_info('${escapeSingleQuotes(idxName)}');`);
96
+ const idxName = idx.name;
97
+ const columnsInfo = (await queryRows(ctx.executor, `PRAGMA index_info('${escapeSingleQuotes(idxName)}');`)) as SqliteIndexInfoRow[];
53
98
  const idxEntry: DatabaseIndex = {
54
99
  name: idxName,
55
- columns: columnsInfo.map(ci => ({ column: ci.name as string })),
100
+ columns: columnsInfo.map(ci => ({ column: ci.name })),
56
101
  unique: idx.unique === 1
57
102
  };
58
103
  table.indexes!.push(idxEntry);
@@ -1,4 +1,3 @@
1
- import type { DbExecutor } from '../../execution/db-executor.js';
2
1
  import { DatabaseSchema } from '../schema-types.js';
3
2
  import type { IntrospectContext } from './context.js';
4
3
 
@@ -1,10 +1,10 @@
1
1
  import { DbExecutor, QueryResult } from '../../execution/db-executor.js';
2
2
  import { IntrospectOptions } from './types.js';
3
3
 
4
- export const toRows = (result: QueryResult | undefined): Record<string, any>[] => {
4
+ export const toRows = (result: QueryResult | undefined): Record<string, unknown>[] => {
5
5
  if (!result) return [];
6
6
  return result.values.map(row =>
7
- result.columns.reduce<Record<string, any>>((acc, col, idx) => {
7
+ result.columns.reduce<Record<string, unknown>>((acc, col, idx) => {
8
8
  acc[col] = row[idx];
9
9
  return acc;
10
10
  }, {})
@@ -15,7 +15,7 @@ export const queryRows = async (
15
15
  executor: DbExecutor,
16
16
  sql: string,
17
17
  params: unknown[] = []
18
- ): Promise<Record<string, any>[]> => {
18
+ ): Promise<Record<string, unknown>[]> => {
19
19
  const [first] = await executor.executeSql(sql, params);
20
20
  return toRows(first);
21
21
  };
@@ -30,6 +30,7 @@ export interface SchemaDialect {
30
30
 
31
31
  // Capability flags
32
32
  supportsPartialIndexes(): boolean;
33
+ preferInlinePkAutoincrement(column: ColumnDef, table: TableDef, pk: string[]): boolean;
33
34
 
34
35
  // DDL operations
35
36
  dropColumnSql?(table: DatabaseTable, column: string): string[];
@@ -1,15 +1,7 @@
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
 
15
7
  export interface SchemaGenerateResult {
@@ -60,7 +52,7 @@ export const generateCreateTableSql = (
60
52
  const inlinePkColumns = new Set<string>();
61
53
 
62
54
  const columnLines = Object.values(table.columns).map(col => {
63
- const includePk = (dialect as any).preferInlinePkAutoincrement?.(col, table, pk) && pk.includes(col.name);
55
+ const includePk = dialect.preferInlinePkAutoincrement(col, table, pk) && pk.includes(col.name);
64
56
  if (includePk) {
65
57
  inlinePkColumns.add(col.name);
66
58
  }
@@ -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,6 +379,7 @@ export abstract class Dialect
376
379
  if (isOperandNode(term)) {
377
380
  return this.compileOperand(term, ctx);
378
381
  }
382
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
379
383
  const expr = this.compileExpression(term as any, ctx);
380
384
  return `(${expr})`;
381
385
  }
@@ -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
  }