uql-orm 0.21.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -4
- package/dist/bunSql/bunSqlCockroachDialect.d.ts +2 -2
- package/dist/bunSql/bunSqlCockroachDialect.js +4 -10
- package/dist/bunSql/bunSqlPostgresDialect.d.ts +2 -2
- package/dist/bunSql/bunSqlPostgresDialect.js +4 -10
- package/dist/cockroachdb/cockroachDialect.d.ts +20 -4
- package/dist/cockroachdb/cockroachDialect.js +33 -18
- package/dist/d1/d1Querier.d.ts +4 -3
- package/dist/d1/d1Querier.js +0 -3
- package/dist/d1/d1SqliteDialect.d.ts +7 -0
- package/dist/d1/d1SqliteDialect.js +9 -0
- package/dist/dialect/abstractDialect.d.ts +8 -3
- package/dist/dialect/abstractDialect.js +9 -4
- package/dist/dialect/abstractSqlDialect.d.ts +35 -7
- package/dist/dialect/abstractSqlDialect.js +76 -35
- package/dist/dialect/index.d.ts +1 -0
- package/dist/dialect/index.js +1 -0
- package/dist/dialect/indexSqlDialect.d.ts +57 -0
- package/dist/dialect/indexSqlDialect.js +101 -0
- package/dist/dialect/mysqlLikeSqlDialect.d.ts +16 -1
- package/dist/dialect/mysqlLikeSqlDialect.js +32 -1
- package/dist/dialect/pgLikeSqlDialect.d.ts +33 -15
- package/dist/dialect/pgLikeSqlDialect.js +90 -56
- package/dist/dialect/vectorCast.d.ts +21 -0
- package/dist/dialect/vectorCast.js +28 -0
- package/dist/dialect/vectorSqlDialect.d.ts +10 -3
- package/dist/dialect/vectorSqlDialect.js +19 -8
- package/dist/entity/decorator/index-decorator.d.ts +2 -9
- package/dist/entity/metadata/definition.d.ts +5 -4
- package/dist/entity/metadata/definition.js +4 -3
- package/dist/libsql/libsqlDialect.d.ts +12 -2
- package/dist/libsql/libsqlDialect.js +14 -2
- package/dist/libsql/libsqlQuerier.d.ts +9 -22
- package/dist/libsql/libsqlQuerier.js +9 -85
- package/dist/libsql/libsqlQuerierPool.d.ts +10 -8
- package/dist/libsql/libsqlQuerierPool.js +17 -15
- package/dist/maria/mariaDialect.d.ts +26 -4
- package/dist/maria/mariaDialect.js +54 -15
- package/dist/migrate/builder/migrationBuilder.d.ts +9 -29
- package/dist/migrate/builder/migrationBuilder.js +58 -76
- package/dist/migrate/builder/splitSqlStatements.d.ts +0 -2
- package/dist/migrate/builder/splitSqlStatements.js +0 -2
- package/dist/migrate/builder/tableBuilder.d.ts +12 -2
- package/dist/migrate/builder/tableBuilder.js +71 -119
- package/dist/migrate/builder/types.d.ts +30 -41
- package/dist/migrate/cli.d.ts +3 -2
- package/dist/migrate/cli.js +21 -48
- package/dist/migrate/codegen/entityCodeGenerator.d.ts +0 -4
- package/dist/migrate/codegen/entityCodeGenerator.js +5 -63
- package/dist/migrate/codegen/fieldOptionsSource.d.ts +10 -0
- package/dist/migrate/codegen/fieldOptionsSource.js +55 -0
- package/dist/migrate/codegen/index.d.ts +0 -2
- package/dist/migrate/codegen/index.js +0 -4
- package/dist/migrate/generator/indexNodeToSchema.d.ts +9 -0
- package/dist/migrate/generator/indexNodeToSchema.js +14 -0
- package/dist/migrate/generator/mongoCommand.d.ts +57 -0
- package/dist/migrate/generator/mongoCommand.js +26 -0
- package/dist/migrate/generator/mongoSchemaGenerator.d.ts +9 -20
- package/dist/migrate/generator/mongoSchemaGenerator.js +40 -82
- package/dist/migrate/index.d.ts +0 -1
- package/dist/migrate/index.js +0 -1
- package/dist/migrate/introspection/abstractSqlSchemaIntrospector.d.ts +25 -10
- package/dist/migrate/introspection/abstractSqlSchemaIntrospector.js +46 -32
- package/dist/migrate/introspection/baseSqlIntrospector.d.ts +0 -1
- package/dist/migrate/introspection/baseSqlIntrospector.js +3 -12
- package/dist/migrate/introspection/mongoIntrospector.js +2 -2
- package/dist/migrate/introspection/mysqlIntrospector.d.ts +5 -8
- package/dist/migrate/introspection/mysqlIntrospector.js +4 -10
- package/dist/migrate/introspection/postgresIntrospector.d.ts +5 -8
- package/dist/migrate/introspection/postgresIntrospector.js +4 -10
- package/dist/migrate/introspection/sqliteIntrospector.d.ts +6 -5
- package/dist/migrate/introspection/sqliteIntrospector.js +26 -18
- package/dist/migrate/migrator.d.ts +23 -3
- package/dist/migrate/migrator.js +57 -69
- package/dist/migrate/schemaGenerator.d.ts +26 -37
- package/dist/migrate/schemaGenerator.js +69 -174
- package/dist/migrate/schemaGeneratorAsync.d.ts +2 -2
- package/dist/migrate/schemaGeneratorAsync.js +3 -3
- package/dist/migrate/storage/databaseStorage.js +4 -4
- package/dist/mongo/mongoDialect.d.ts +2 -0
- package/dist/mongo/mongoDialect.js +14 -3
- package/dist/mysql/mysqlDialect.d.ts +8 -0
- package/dist/mysql/mysqlDialect.js +13 -0
- package/dist/schema/canonicalType.d.ts +14 -2
- package/dist/schema/canonicalType.js +41 -31
- package/dist/schema/index.d.ts +1 -1
- package/dist/schema/schemaASTBuilder.d.ts +8 -1
- package/dist/schema/schemaASTBuilder.js +56 -47
- package/dist/schema/types.d.ts +10 -37
- package/dist/sqlite/abstractSqliteQuerier.d.ts +39 -0
- package/dist/sqlite/abstractSqliteQuerier.js +44 -0
- package/dist/sqlite/bunSqliteAdapter.bun.d.ts +26 -0
- package/dist/sqlite/bunSqliteAdapter.bun.js +25 -0
- package/dist/sqlite/hranaQuerier.d.ts +54 -0
- package/dist/sqlite/hranaQuerier.js +90 -0
- package/dist/sqlite/hranaQuerierPool.d.ts +21 -0
- package/dist/sqlite/hranaQuerierPool.js +25 -0
- package/dist/sqlite/index.d.ts +2 -1
- package/dist/sqlite/index.js +2 -1
- package/dist/sqlite/sqliteDialect.d.ts +18 -4
- package/dist/sqlite/sqliteDialect.js +24 -24
- package/dist/sqlite/sqliteQuerier.d.ts +16 -9
- package/dist/sqlite/sqliteQuerier.js +4 -27
- package/dist/sqlite/sqliteQuerierPool.d.ts +14 -4
- package/dist/sqlite/sqliteQuerierPool.js +16 -5
- package/dist/turso/index.d.ts +3 -0
- package/dist/turso/index.js +3 -0
- package/dist/turso/local.d.ts +3 -0
- package/dist/turso/local.js +3 -0
- package/dist/turso/tursoDialect.d.ts +15 -0
- package/dist/turso/tursoDialect.js +18 -0
- package/dist/turso/tursoLocalQuerier.d.ts +25 -0
- package/dist/turso/tursoLocalQuerier.js +20 -0
- package/dist/turso/tursoLocalQuerierPool.d.ts +32 -0
- package/dist/turso/tursoLocalQuerierPool.js +39 -0
- package/dist/turso/tursoQuerier.d.ts +10 -0
- package/dist/turso/tursoQuerier.js +10 -0
- package/dist/turso/tursoQuerierPool.d.ts +39 -0
- package/dist/turso/tursoQuerierPool.js +38 -0
- package/dist/type/config.d.ts +0 -6
- package/dist/type/dialect.d.ts +12 -4
- package/dist/type/dialect.js +7 -1
- package/dist/type/entity.d.ts +66 -5
- package/dist/type/migration.d.ts +32 -23
- package/dist/type/vector.d.ts +5 -2
- package/dist/util/index.d.ts +1 -0
- package/dist/util/index.js +1 -0
- package/dist/util/indexColumn.util.d.ts +6 -0
- package/dist/util/indexColumn.util.js +26 -0
- package/package.json +16 -3
- package/dist/migrate/codegen/entityMerger.d.ts +0 -114
- package/dist/migrate/codegen/entityMerger.js +0 -293
- package/dist/migrate/codegen/migrationCodeGenerator.d.ts +0 -61
- package/dist/migrate/codegen/migrationCodeGenerator.js +0 -355
- package/dist/migrate/generator/index.d.ts +0 -2
- package/dist/migrate/generator/index.js +0 -2
- package/dist/migrate/sync/index.d.ts +0 -6
- package/dist/migrate/sync/index.js +0 -6
- package/dist/migrate/sync/schemaSync.d.ts +0 -131
- package/dist/migrate/sync/schemaSync.js +0 -259
- package/dist/sqlite/betterSqlite3Dialect.d.ts +0 -9
- package/dist/sqlite/betterSqlite3Dialect.js +0 -9
|
@@ -1,355 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Migration Code Generator
|
|
3
|
-
*
|
|
4
|
-
* Generates TypeScript migration code from SchemaDiff.
|
|
5
|
-
* This enables auto-generating migrations from entity changes.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Generates TypeScript migration code from schema diffs.
|
|
9
|
-
*/
|
|
10
|
-
export class MigrationCodeGenerator {
|
|
11
|
-
indent;
|
|
12
|
-
includeComments;
|
|
13
|
-
constructor(options = {}) {
|
|
14
|
-
this.indent = options.indent ?? ' ';
|
|
15
|
-
this.includeComments = options.includeComments ?? true;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Generate migration code from a single SchemaDiff.
|
|
19
|
-
*/
|
|
20
|
-
generate(diff) {
|
|
21
|
-
const description = this.generateDescription(diff);
|
|
22
|
-
if (diff.type === 'create') {
|
|
23
|
-
return {
|
|
24
|
-
up: this.generateCreateTable(diff),
|
|
25
|
-
down: this.generateDropTable(diff.tableName),
|
|
26
|
-
description,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
if (diff.type === 'drop') {
|
|
30
|
-
return {
|
|
31
|
-
up: this.generateDropTable(diff.tableName),
|
|
32
|
-
down: '// Cannot auto-generate: original table structure unknown',
|
|
33
|
-
description,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
// alter
|
|
37
|
-
return {
|
|
38
|
-
up: this.generateAlterUp(diff),
|
|
39
|
-
down: this.generateAlterDown(diff),
|
|
40
|
-
description,
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Generate migration code from multiple diffs.
|
|
45
|
-
*/
|
|
46
|
-
generateAll(diffs) {
|
|
47
|
-
const ups = [];
|
|
48
|
-
const downs = [];
|
|
49
|
-
const descriptions = [];
|
|
50
|
-
for (const diff of diffs) {
|
|
51
|
-
const result = this.generate(diff);
|
|
52
|
-
ups.push(result.up);
|
|
53
|
-
downs.push(result.down);
|
|
54
|
-
descriptions.push(result.description);
|
|
55
|
-
}
|
|
56
|
-
return {
|
|
57
|
-
up: ups.join('\n\n'),
|
|
58
|
-
down: downs.reverse().join('\n\n'), // Reverse for correct rollback order
|
|
59
|
-
description: descriptions.join('; '),
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Generate a complete migration file template.
|
|
64
|
-
*/
|
|
65
|
-
generateFile(diffs, name) {
|
|
66
|
-
const { up, down, description } = this.generateAll(diffs);
|
|
67
|
-
const timestamp = new Date()
|
|
68
|
-
.toISOString()
|
|
69
|
-
.replace(/[-:T.Z]/g, '')
|
|
70
|
-
.slice(0, 14);
|
|
71
|
-
const migrationName = name ?? `migration_${timestamp}`;
|
|
72
|
-
return `/**
|
|
73
|
-
* Migration: ${migrationName}
|
|
74
|
-
* ${description}
|
|
75
|
-
*
|
|
76
|
-
* Generated at: ${new Date().toISOString()}
|
|
77
|
-
*/
|
|
78
|
-
|
|
79
|
-
import type { IMigrationBuilder } from 'uql-orm';
|
|
80
|
-
|
|
81
|
-
export async function up(builder: IMigrationBuilder): Promise<void> {
|
|
82
|
-
${this.indentBlock(up, 1)}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export async function down(builder: IMigrationBuilder): Promise<void> {
|
|
86
|
-
${this.indentBlock(down, 1)}
|
|
87
|
-
}
|
|
88
|
-
`;
|
|
89
|
-
}
|
|
90
|
-
// ===========================================================================
|
|
91
|
-
// Private: Code Generation
|
|
92
|
-
// ===========================================================================
|
|
93
|
-
generateCreateTable(diff) {
|
|
94
|
-
const columns = diff.columnsToAdd ?? [];
|
|
95
|
-
const lines = [];
|
|
96
|
-
lines.push(`await builder.createTable('${diff.tableName}', (table) => {`);
|
|
97
|
-
for (const col of columns) {
|
|
98
|
-
lines.push(`${this.indent}${this.generateColumnCall(col)};`);
|
|
99
|
-
}
|
|
100
|
-
// Add indexes if any
|
|
101
|
-
for (const idx of diff.indexesToAdd ?? []) {
|
|
102
|
-
lines.push(`${this.indent}${this.generateIndexCall(idx)};`);
|
|
103
|
-
}
|
|
104
|
-
lines.push('});');
|
|
105
|
-
return lines.join('\n');
|
|
106
|
-
}
|
|
107
|
-
generateDropTable(tableName) {
|
|
108
|
-
return `await builder.dropTable('${tableName}');`;
|
|
109
|
-
}
|
|
110
|
-
generateAlterUp(diff) {
|
|
111
|
-
const lines = [];
|
|
112
|
-
// Add columns
|
|
113
|
-
for (const col of diff.columnsToAdd ?? []) {
|
|
114
|
-
lines.push(this.generateAddColumn(diff.tableName, col));
|
|
115
|
-
}
|
|
116
|
-
// Alter columns
|
|
117
|
-
for (const { to } of diff.columnsToAlter ?? []) {
|
|
118
|
-
lines.push(this.generateAlterColumn(diff.tableName, to));
|
|
119
|
-
}
|
|
120
|
-
// Drop columns
|
|
121
|
-
for (const colName of diff.columnsToDrop ?? []) {
|
|
122
|
-
lines.push(`await builder.dropColumn('${diff.tableName}', '${colName}');`);
|
|
123
|
-
}
|
|
124
|
-
// Add indexes
|
|
125
|
-
for (const idx of diff.indexesToAdd ?? []) {
|
|
126
|
-
lines.push(this.generateCreateIndex(diff.tableName, idx));
|
|
127
|
-
}
|
|
128
|
-
// Drop indexes
|
|
129
|
-
for (const idxName of diff.indexesToDrop ?? []) {
|
|
130
|
-
lines.push(`await builder.dropIndex('${diff.tableName}', '${idxName}');`);
|
|
131
|
-
}
|
|
132
|
-
// Add foreign keys
|
|
133
|
-
for (const fk of diff.foreignKeysToAdd ?? []) {
|
|
134
|
-
lines.push(this.generateAddForeignKey(diff.tableName, fk));
|
|
135
|
-
}
|
|
136
|
-
// Drop foreign keys
|
|
137
|
-
for (const fkName of diff.foreignKeysToDrop ?? []) {
|
|
138
|
-
lines.push(`await builder.dropForeignKey('${diff.tableName}', '${fkName}');`);
|
|
139
|
-
}
|
|
140
|
-
return lines.join('\n');
|
|
141
|
-
}
|
|
142
|
-
generateAlterDown(diff) {
|
|
143
|
-
const lines = [];
|
|
144
|
-
// Reverse: drop added columns
|
|
145
|
-
for (const col of diff.columnsToAdd ?? []) {
|
|
146
|
-
lines.push(`await builder.dropColumn('${diff.tableName}', '${col.name}');`);
|
|
147
|
-
}
|
|
148
|
-
// Reverse: restore altered columns
|
|
149
|
-
for (const { from } of diff.columnsToAlter ?? []) {
|
|
150
|
-
lines.push(this.generateAlterColumn(diff.tableName, from));
|
|
151
|
-
}
|
|
152
|
-
// Reverse: re-add dropped columns (if we have the schema)
|
|
153
|
-
// Note: This requires the original column definition
|
|
154
|
-
if (diff.columnsToDrop?.length) {
|
|
155
|
-
lines.push(`// TODO: Re-add dropped columns: ${diff.columnsToDrop.join(', ')}`);
|
|
156
|
-
}
|
|
157
|
-
// Reverse: drop added indexes
|
|
158
|
-
for (const idx of diff.indexesToAdd ?? []) {
|
|
159
|
-
lines.push(`await builder.dropIndex('${diff.tableName}', '${idx.name}');`);
|
|
160
|
-
}
|
|
161
|
-
// Reverse: re-add dropped indexes
|
|
162
|
-
if (diff.indexesToDrop?.length) {
|
|
163
|
-
lines.push(`// TODO: Re-add dropped indexes: ${diff.indexesToDrop.join(', ')}`);
|
|
164
|
-
}
|
|
165
|
-
// Reverse: drop added foreign keys
|
|
166
|
-
for (const fk of diff.foreignKeysToAdd ?? []) {
|
|
167
|
-
if (fk.name) {
|
|
168
|
-
lines.push(`await builder.dropForeignKey('${diff.tableName}', '${fk.name}');`);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
// Reverse: re-add dropped foreign keys
|
|
172
|
-
if (diff.foreignKeysToDrop?.length) {
|
|
173
|
-
lines.push(`// TODO: Re-add dropped foreign keys: ${diff.foreignKeysToDrop.join(', ')}`);
|
|
174
|
-
}
|
|
175
|
-
return lines.join('\n');
|
|
176
|
-
}
|
|
177
|
-
generateAddColumn(tableName, col) {
|
|
178
|
-
const options = this.generateColumnOptions(col);
|
|
179
|
-
return `await builder.addColumn('${tableName}', '${col.name}', (col) => col${options});`;
|
|
180
|
-
}
|
|
181
|
-
generateAlterColumn(tableName, col) {
|
|
182
|
-
const options = this.generateColumnOptions(col);
|
|
183
|
-
return `await builder.alterColumn('${tableName}', '${col.name}', (col) => col${options});`;
|
|
184
|
-
}
|
|
185
|
-
generateCreateIndex(tableName, idx) {
|
|
186
|
-
const cols = idx.columns.map((c) => `'${c}'`).join(', ');
|
|
187
|
-
const opts = [];
|
|
188
|
-
if (idx.name)
|
|
189
|
-
opts.push(`name: '${idx.name}'`);
|
|
190
|
-
if (idx.unique)
|
|
191
|
-
opts.push('unique: true');
|
|
192
|
-
const optsStr = opts.length ? `, { ${opts.join(', ')} }` : '';
|
|
193
|
-
return `await builder.createIndex('${tableName}', [${cols}]${optsStr});`;
|
|
194
|
-
}
|
|
195
|
-
generateAddForeignKey(tableName, fk) {
|
|
196
|
-
const cols = fk.columns.map((c) => `'${c}'`).join(', ');
|
|
197
|
-
const refCols = fk.referencedColumns.map((c) => `'${c}'`).join(', ');
|
|
198
|
-
const opts = [];
|
|
199
|
-
if (fk.name)
|
|
200
|
-
opts.push(`name: '${fk.name}'`);
|
|
201
|
-
if (fk.onDelete && fk.onDelete !== 'NO ACTION')
|
|
202
|
-
opts.push(`onDelete: '${fk.onDelete}'`);
|
|
203
|
-
if (fk.onUpdate && fk.onUpdate !== 'NO ACTION')
|
|
204
|
-
opts.push(`onUpdate: '${fk.onUpdate}'`);
|
|
205
|
-
const optsStr = opts.length ? `, { ${opts.join(', ')} }` : '';
|
|
206
|
-
return `await builder.addForeignKey('${tableName}', [${cols}], { table: '${fk.referencedTable}', columns: [${refCols}] }${optsStr});`;
|
|
207
|
-
}
|
|
208
|
-
// ===========================================================================
|
|
209
|
-
// Private: Column Call Generation
|
|
210
|
-
// ===========================================================================
|
|
211
|
-
generateColumnCall(col) {
|
|
212
|
-
const method = this.getColumnMethod(col);
|
|
213
|
-
const options = this.generateColumnOptionsObject(col);
|
|
214
|
-
return `table.${method}('${col.name}'${options})`;
|
|
215
|
-
}
|
|
216
|
-
generateIndexCall(idx) {
|
|
217
|
-
const cols = idx.columns.map((c) => `'${c}'`).join(', ');
|
|
218
|
-
if (idx.unique) {
|
|
219
|
-
return `table.unique([${cols}], '${idx.name}')`;
|
|
220
|
-
}
|
|
221
|
-
return `table.index([${cols}], '${idx.name}')`;
|
|
222
|
-
}
|
|
223
|
-
getColumnMethod(col) {
|
|
224
|
-
const type = col.type;
|
|
225
|
-
// Check for auto-increment primary key → id()
|
|
226
|
-
if (col.isPrimaryKey && col.isAutoIncrement) {
|
|
227
|
-
return 'id';
|
|
228
|
-
}
|
|
229
|
-
// Map type string to method name
|
|
230
|
-
const typeMap = {
|
|
231
|
-
integer: 'integer',
|
|
232
|
-
int: 'integer',
|
|
233
|
-
bigint: 'bigint',
|
|
234
|
-
smallint: 'smallint',
|
|
235
|
-
float: 'float',
|
|
236
|
-
double: 'double',
|
|
237
|
-
decimal: 'decimal',
|
|
238
|
-
numeric: 'decimal',
|
|
239
|
-
varchar: 'string',
|
|
240
|
-
char: 'char',
|
|
241
|
-
text: 'text',
|
|
242
|
-
boolean: 'boolean',
|
|
243
|
-
bool: 'boolean',
|
|
244
|
-
date: 'date',
|
|
245
|
-
time: 'time',
|
|
246
|
-
timestamp: 'timestamp',
|
|
247
|
-
timestamptz: 'timestamptz',
|
|
248
|
-
json: 'json',
|
|
249
|
-
jsonb: 'jsonb',
|
|
250
|
-
uuid: 'uuid',
|
|
251
|
-
blob: 'blob',
|
|
252
|
-
bytea: 'blob',
|
|
253
|
-
vector: 'vector',
|
|
254
|
-
};
|
|
255
|
-
const lowerType = type.toLowerCase().replace(/\(.*\)/, ''); // Remove (255) etc
|
|
256
|
-
return typeMap[lowerType] ?? 'string';
|
|
257
|
-
}
|
|
258
|
-
generateColumnOptionsObject(col) {
|
|
259
|
-
const opts = [];
|
|
260
|
-
// Type-specific options
|
|
261
|
-
if (col.length !== undefined && col.length !== 255) {
|
|
262
|
-
opts.push(`length: ${col.length}`);
|
|
263
|
-
}
|
|
264
|
-
if (col.precision !== undefined) {
|
|
265
|
-
opts.push(`precision: ${col.precision}`);
|
|
266
|
-
}
|
|
267
|
-
if (col.scale !== undefined) {
|
|
268
|
-
opts.push(`scale: ${col.scale}`);
|
|
269
|
-
}
|
|
270
|
-
// Common options (only include non-defaults)
|
|
271
|
-
if (col.nullable) {
|
|
272
|
-
opts.push('nullable: true');
|
|
273
|
-
}
|
|
274
|
-
if (col.isUnique && !col.isPrimaryKey) {
|
|
275
|
-
opts.push('unique: true');
|
|
276
|
-
}
|
|
277
|
-
if (col.isPrimaryKey && !col.isAutoIncrement) {
|
|
278
|
-
opts.push('primaryKey: true');
|
|
279
|
-
}
|
|
280
|
-
if (col.defaultValue !== undefined) {
|
|
281
|
-
opts.push(`defaultValue: ${this.formatValue(col.defaultValue)}`);
|
|
282
|
-
}
|
|
283
|
-
if (opts.length === 0)
|
|
284
|
-
return '';
|
|
285
|
-
return `, { ${opts.join(', ')} }`;
|
|
286
|
-
}
|
|
287
|
-
generateColumnOptions(col) {
|
|
288
|
-
const parts = [];
|
|
289
|
-
if (!col.nullable) {
|
|
290
|
-
parts.push('.notNullable()');
|
|
291
|
-
}
|
|
292
|
-
if (col.isUnique) {
|
|
293
|
-
parts.push('.unique()');
|
|
294
|
-
}
|
|
295
|
-
if (col.defaultValue !== undefined) {
|
|
296
|
-
parts.push(`.defaultValue(${this.formatValue(col.defaultValue)})`);
|
|
297
|
-
}
|
|
298
|
-
return parts.join('');
|
|
299
|
-
}
|
|
300
|
-
formatValue(value) {
|
|
301
|
-
if (value === null)
|
|
302
|
-
return 'null';
|
|
303
|
-
if (typeof value === 'string') {
|
|
304
|
-
// Check for SQL expressions
|
|
305
|
-
if (value.toUpperCase().includes('CURRENT_TIMESTAMP') ||
|
|
306
|
-
value.includes('()') ||
|
|
307
|
-
value.toUpperCase().includes('NOW')) {
|
|
308
|
-
return `t.raw('${value}')`;
|
|
309
|
-
}
|
|
310
|
-
return `'${value.replace(/'/g, "\\'")}'`;
|
|
311
|
-
}
|
|
312
|
-
if (typeof value === 'boolean')
|
|
313
|
-
return String(value);
|
|
314
|
-
if (typeof value === 'number')
|
|
315
|
-
return String(value);
|
|
316
|
-
return JSON.stringify(value);
|
|
317
|
-
}
|
|
318
|
-
// ===========================================================================
|
|
319
|
-
// Private: Utilities
|
|
320
|
-
// ===========================================================================
|
|
321
|
-
generateDescription(diff) {
|
|
322
|
-
const parts = [];
|
|
323
|
-
if (diff.type === 'create') {
|
|
324
|
-
parts.push(`Create table '${diff.tableName}'`);
|
|
325
|
-
}
|
|
326
|
-
else if (diff.type === 'drop') {
|
|
327
|
-
parts.push(`Drop table '${diff.tableName}'`);
|
|
328
|
-
}
|
|
329
|
-
else {
|
|
330
|
-
if (diff.columnsToAdd?.length) {
|
|
331
|
-
parts.push(`Add ${diff.columnsToAdd.length} column(s)`);
|
|
332
|
-
}
|
|
333
|
-
if (diff.columnsToAlter?.length) {
|
|
334
|
-
parts.push(`Alter ${diff.columnsToAlter.length} column(s)`);
|
|
335
|
-
}
|
|
336
|
-
if (diff.columnsToDrop?.length) {
|
|
337
|
-
parts.push(`Drop ${diff.columnsToDrop.length} column(s)`);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
return parts.join(', ') || `Alter table '${diff.tableName}'`;
|
|
341
|
-
}
|
|
342
|
-
indentBlock(code, level) {
|
|
343
|
-
const prefix = this.indent.repeat(level);
|
|
344
|
-
return code
|
|
345
|
-
.split('\n')
|
|
346
|
-
.map((line) => (line.trim() ? prefix + line : line))
|
|
347
|
-
.join('\n');
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Factory function to create a MigrationCodeGenerator.
|
|
352
|
-
*/
|
|
353
|
-
export function createMigrationCodeGenerator(options) {
|
|
354
|
-
return new MigrationCodeGenerator(options);
|
|
355
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Schema Sync
|
|
3
|
-
*
|
|
4
|
-
* Orchestrates schema synchronization between entities and database
|
|
5
|
-
* with configurable direction modes.
|
|
6
|
-
*/
|
|
7
|
-
import type { SchemaDiffResult, SyncDirection, SyncOptions } from '../../schema/types.js';
|
|
8
|
-
import type { SchemaIntrospector, Type } from '../../type/index.js';
|
|
9
|
-
/**
|
|
10
|
-
* Result of a schema sync operation.
|
|
11
|
-
*/
|
|
12
|
-
export interface SchemaSyncResult {
|
|
13
|
-
/** Direction of the sync */
|
|
14
|
-
direction: SyncDirection;
|
|
15
|
-
/** Whether the sync was successful */
|
|
16
|
-
success: boolean;
|
|
17
|
-
/** Changes applied to database */
|
|
18
|
-
dbChanges: SchemaDiffResult | undefined;
|
|
19
|
-
/** Changes applied to entities */
|
|
20
|
-
entityChanges: SchemaDiffResult | undefined;
|
|
21
|
-
/** Conflicts that need manual resolution */
|
|
22
|
-
conflicts: SyncConflict[];
|
|
23
|
-
/** Human-readable summary */
|
|
24
|
-
summary: string;
|
|
25
|
-
/** Structured summary of changes */
|
|
26
|
-
details: {
|
|
27
|
-
db: {
|
|
28
|
-
created: number;
|
|
29
|
-
dropped: number;
|
|
30
|
-
altered: number;
|
|
31
|
-
};
|
|
32
|
-
entity: {
|
|
33
|
-
created: number;
|
|
34
|
-
dropped: number;
|
|
35
|
-
altered: number;
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* A conflict between entity and database schemas.
|
|
41
|
-
*/
|
|
42
|
-
export interface SyncConflict {
|
|
43
|
-
/** Type of conflict */
|
|
44
|
-
type: 'type_mismatch' | 'constraint_mismatch' | 'column_mismatch' | 'relation_mismatch';
|
|
45
|
-
/** Table name */
|
|
46
|
-
table: string;
|
|
47
|
-
/** Column name (if applicable) */
|
|
48
|
-
column?: string;
|
|
49
|
-
/** What entity expects */
|
|
50
|
-
entityValue: unknown;
|
|
51
|
-
/** What database has */
|
|
52
|
-
dbValue: unknown;
|
|
53
|
-
/** Suggested resolution */
|
|
54
|
-
suggestion: string;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Options for schema sync operation.
|
|
58
|
-
*/
|
|
59
|
-
export interface SchemaSyncOptions extends SyncOptions {
|
|
60
|
-
/** Entities to sync */
|
|
61
|
-
entities: Type<unknown>[];
|
|
62
|
-
/** Schema introspector for database */
|
|
63
|
-
introspector: SchemaIntrospector;
|
|
64
|
-
/** Output directory for generated entities (db-to-entity mode) */
|
|
65
|
-
entityOutputDir?: string;
|
|
66
|
-
/** Dry run - don't apply changes */
|
|
67
|
-
dryRun?: boolean;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Service for synchronizing schemas between entities and database.
|
|
71
|
-
*/
|
|
72
|
-
export declare class SchemaSync {
|
|
73
|
-
private readonly options;
|
|
74
|
-
constructor(options: SchemaSyncOptions);
|
|
75
|
-
/**
|
|
76
|
-
* Execute schema synchronization.
|
|
77
|
-
*/
|
|
78
|
-
sync(): Promise<SchemaSyncResult>;
|
|
79
|
-
/**
|
|
80
|
-
* Sync from entities to database (push).
|
|
81
|
-
*/
|
|
82
|
-
private syncEntityToDb;
|
|
83
|
-
/**
|
|
84
|
-
* Sync from database to entities (pull).
|
|
85
|
-
*/
|
|
86
|
-
private syncDbToEntity;
|
|
87
|
-
/**
|
|
88
|
-
* Bidirectional sync with conflict detection.
|
|
89
|
-
*/
|
|
90
|
-
private syncBidirectional;
|
|
91
|
-
/**
|
|
92
|
-
* Build SchemaAST from entities.
|
|
93
|
-
*/
|
|
94
|
-
private buildEntityAST;
|
|
95
|
-
/**
|
|
96
|
-
* Build SchemaAST from database.
|
|
97
|
-
*/
|
|
98
|
-
private buildDatabaseAST;
|
|
99
|
-
/**
|
|
100
|
-
* Filter destructive changes for safe mode.
|
|
101
|
-
*/
|
|
102
|
-
private filterDestructiveChanges;
|
|
103
|
-
/**
|
|
104
|
-
* Detect conflicts between bidirectional changes.
|
|
105
|
-
*/
|
|
106
|
-
private detectConflicts;
|
|
107
|
-
/**
|
|
108
|
-
* Filter out conflicting changes.
|
|
109
|
-
*/
|
|
110
|
-
private filterConflictingChanges;
|
|
111
|
-
/**
|
|
112
|
-
* Get counts of changes from a diff.
|
|
113
|
-
*/
|
|
114
|
-
private getDiffCounts;
|
|
115
|
-
/**
|
|
116
|
-
* Format summary for single-direction sync.
|
|
117
|
-
*/
|
|
118
|
-
private formatSummary;
|
|
119
|
-
/**
|
|
120
|
-
* Format summary for bidirectional sync.
|
|
121
|
-
*/
|
|
122
|
-
private formatBidirectionalSummary;
|
|
123
|
-
/**
|
|
124
|
-
* Format type for display.
|
|
125
|
-
*/
|
|
126
|
-
private formatType;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Create a SchemaSync instance.
|
|
130
|
-
*/
|
|
131
|
-
export declare function createSchemaSync(options: SchemaSyncOptions): SchemaSync;
|