uql-orm 0.62.0 → 0.64.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/dist/bunSql/bunSql.util.d.ts +15 -15
- package/dist/bunSql/bunSql.util.js +22 -35
- package/dist/bunSql/bunSqlQuerier.d.ts +2 -2
- package/dist/bunSql/bunSqlQuerier.js +3 -3
- package/dist/bunSql/bunSqlQuerierPool.d.ts +1 -13
- package/dist/bunSql/bunSqlQuerierPool.js +3 -34
- package/dist/d1/d1Querier.d.ts +12 -4
- package/dist/d1/d1Querier.js +6 -11
- package/dist/d1/d1QuerierPool.d.ts +7 -3
- package/dist/d1/d1QuerierPool.js +5 -3
- package/dist/entity/decorator/entity.d.ts +5 -9
- package/dist/entity/decorator/entity.js +3 -7
- package/dist/entity/metadata/definition.d.ts +2 -2
- package/dist/entity/metadata/definition.js +13 -22
- package/dist/libsql/libsqlDialect.d.ts +1 -1
- package/dist/libsql/libsqlDialect.js +1 -1
- package/dist/libsql/libsqlQuerierPool.d.ts +18 -9
- package/dist/libsql/libsqlQuerierPool.js +32 -20
- package/dist/migrate/builder/expressions.js +1 -15
- package/dist/migrate/builder/migrationBuilder.d.ts +6 -28
- package/dist/migrate/builder/migrationBuilder.js +9 -83
- package/dist/migrate/builder/types.d.ts +14 -24
- package/dist/migrate/cli.d.ts +1 -6
- package/dist/migrate/cli.js +3 -10
- package/dist/migrate/codegen/index.d.ts +1 -1
- package/dist/migrate/codegen/index.js +1 -1
- package/dist/migrate/codegen/indexDecoratorSource.d.ts +1 -1
- package/dist/migrate/codegen/indexDecoratorSource.js +4 -8
- package/dist/migrate/codegen/migrationFile.d.ts +9 -5
- package/dist/migrate/codegen/migrationFile.js +2 -3
- package/dist/migrate/ddl/indexDdl.d.ts +4 -2
- package/dist/migrate/ddl/indexDdl.js +16 -15
- package/dist/migrate/generator/mongoCommand.d.ts +9 -9
- package/dist/migrate/generator/mongoCommand.js +1 -1
- package/dist/migrate/generator/mongoSchemaGenerator.d.ts +21 -26
- package/dist/migrate/generator/mongoSchemaGenerator.js +103 -80
- package/dist/migrate/index.d.ts +1 -1
- package/dist/migrate/index.js +1 -1
- package/dist/migrate/indexPredicate.d.ts +8 -0
- package/dist/migrate/indexPredicate.js +52 -0
- package/dist/migrate/migrationTarget.d.ts +23 -0
- package/dist/migrate/migrationTarget.js +48 -0
- package/dist/migrate/migrator.d.ts +17 -45
- package/dist/migrate/migrator.js +80 -179
- package/dist/migrate/schemaGenerator.d.ts +12 -13
- package/dist/migrate/schemaGenerator.js +43 -9
- package/dist/mongo/mongoDialect.d.ts +6 -1
- package/dist/querier/abstractSharedHandleQuerierPool.d.ts +5 -5
- package/dist/querier/abstractSharedHandleQuerierPool.js +5 -5
- package/dist/schema/schemaASTBuilder.d.ts +2 -0
- package/dist/schema/schemaASTBuilder.js +9 -22
- package/dist/sqlite/abstractSqliteQuerier.d.ts +11 -28
- package/dist/sqlite/abstractSqliteQuerier.js +14 -33
- package/dist/sqlite/bunSqliteAdapter.bun.d.ts +5 -4
- package/dist/sqlite/bunSqliteAdapter.bun.js +1 -1
- package/dist/sqlite/hranaQuerier.d.ts +6 -4
- package/dist/sqlite/hranaQuerier.js +4 -13
- package/dist/sqlite/index.d.ts +0 -1
- package/dist/sqlite/index.js +0 -1
- package/dist/sqlite/localSqliteQuerierPool.d.ts +14 -5
- package/dist/sqlite/nodeSqliteAdapter.d.ts +3 -4
- package/dist/sqlite/nodeSqliteAdapter.js +3 -6
- package/dist/sqlite/nodeSqliteQuerierPool.d.ts +2 -3
- package/dist/sqlite/nodeSqliteQuerierPool.js +3 -1
- package/dist/sqlite/sqliteDialect.d.ts +1 -1
- package/dist/sqlite/sqliteDialect.js +1 -1
- package/dist/sqlite/sqlitePragmas.d.ts +2 -11
- package/dist/sqlite/sqlitePragmas.js +1 -1
- package/dist/sqlite/sqliteQuerier.d.ts +29 -10
- package/dist/sqlite/sqliteQuerier.js +26 -4
- package/dist/sqlite/sqliteQuerierPool.d.ts +7 -3
- package/dist/sqlite/sqliteQuerierPool.js +12 -8
- package/dist/turso/index.d.ts +1 -0
- package/dist/turso/index.js +1 -0
- package/dist/turso/local.d.ts +1 -1
- package/dist/turso/local.js +1 -1
- package/dist/turso/tursoDialect.d.ts +4 -9
- package/dist/turso/tursoDialect.js +4 -12
- package/dist/turso/tursoLocalDialect.d.ts +10 -0
- package/dist/turso/tursoLocalDialect.js +13 -0
- package/dist/turso/tursoLocalQuerierPool.d.ts +8 -13
- package/dist/turso/tursoLocalQuerierPool.js +6 -5
- package/dist/turso/tursoQuerierPool.d.ts +15 -30
- package/dist/turso/tursoQuerierPool.js +13 -23
- package/dist/turso/tursoSessionQuerier.d.ts +57 -0
- package/dist/turso/tursoSessionQuerier.js +50 -0
- package/dist/type/entity.d.ts +37 -62
- package/dist/type/migration.d.ts +11 -40
- package/dist/type/queryRaw.d.ts +8 -0
- package/dist/type/queryRaw.js +11 -0
- package/dist/util/ddlExpression.util.d.ts +5 -3
- package/dist/util/ddlExpression.util.js +19 -12
- package/dist/util/raw.d.ts +6 -1
- package/dist/util/raw.js +11 -8
- package/dist/util/sqlLiteral.js +5 -3
- package/dist/util/wideNumber.d.ts +2 -2
- package/dist/util/wideNumber.js +2 -2
- package/package.json +2 -2
- package/dist/migrate/schemaGeneratorAsync.d.ts +0 -7
- package/dist/migrate/schemaGeneratorAsync.js +0 -12
- package/dist/sqlite/hranaQuerierPool.d.ts +0 -20
- package/dist/sqlite/hranaQuerierPool.js +0 -26
- package/dist/turso/tursoLocalQuerier.d.ts +0 -24
- package/dist/turso/tursoLocalQuerier.js +0 -20
|
@@ -1,39 +1,51 @@
|
|
|
1
1
|
import { dialectOptionsFrom } from '../dialect/abstractDialect.js';
|
|
2
|
+
import { AbstractSharedHandleQuerierPool } from '../querier/abstractSharedHandleQuerierPool.js';
|
|
2
3
|
import { HranaQuerier } from '../sqlite/hranaQuerier.js';
|
|
3
|
-
import { AbstractHranaQuerierPool } from '../sqlite/hranaQuerierPool.js';
|
|
4
4
|
import { LibsqlDialect } from './libsqlDialect.js';
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return { ...rest, url: syncUrl };
|
|
13
|
-
}
|
|
14
|
-
export class LibsqlQuerierPool extends AbstractHranaQuerierPool {
|
|
5
|
+
/**
|
|
6
|
+
* Pool for libSQL. One client serves every querier, since Hrana keeps no per-connection state: a
|
|
7
|
+
* transaction takes its own session handle. The pool builds that client from `@libsql/client`'s
|
|
8
|
+
* `Config`, or shares one the caller built (`@libsql/client/web`, `@libsql/client-wasm`), which stays
|
|
9
|
+
* theirs to close.
|
|
10
|
+
*/
|
|
11
|
+
export class LibsqlQuerierPool extends AbstractSharedHandleQuerierPool {
|
|
15
12
|
conf;
|
|
16
13
|
constructor(conf, extra) {
|
|
17
14
|
super(new LibsqlDialect(dialectOptionsFrom(extra)), extra);
|
|
18
15
|
this.conf = conf;
|
|
19
16
|
}
|
|
20
|
-
|
|
21
|
-
return this.createClient(this.conf);
|
|
17
|
+
async openDb() {
|
|
18
|
+
return 'execute' in this.conf ? this.conf : this.createClient(this.conf);
|
|
19
|
+
}
|
|
20
|
+
buildQuerier(client) {
|
|
21
|
+
return new HranaQuerier(client, this.dialect, this.extra);
|
|
22
|
+
}
|
|
23
|
+
async end() {
|
|
24
|
+
if (!('execute' in this.conf)) {
|
|
25
|
+
await super.end();
|
|
26
|
+
}
|
|
22
27
|
}
|
|
23
28
|
/**
|
|
24
|
-
* For embedded
|
|
25
|
-
*
|
|
29
|
+
* For an embedded replica - a `file:` url with a `syncUrl` - a querier on the sync url, so migrations
|
|
30
|
+
* reach sqld, its client closing with it. Anything else migrates like any other querier.
|
|
26
31
|
*/
|
|
27
32
|
async getMigrationQuerier() {
|
|
28
|
-
if (
|
|
33
|
+
if ('execute' in this.conf) {
|
|
29
34
|
return this.getQuerier();
|
|
30
35
|
}
|
|
31
|
-
const remote =
|
|
32
|
-
|
|
36
|
+
const { syncUrl, url, ...remote } = this.conf;
|
|
37
|
+
if (!syncUrl || !url.startsWith('file:')) {
|
|
38
|
+
return this.getQuerier();
|
|
39
|
+
}
|
|
40
|
+
const client = await this.createClient({ ...remote, url: syncUrl });
|
|
41
|
+
return new HranaQuerier(client, this.dialect, this.extra, { closeClientOnRelease: true });
|
|
33
42
|
}
|
|
34
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Imported on use, so `uql-orm/libsql` loads without the optional `@libsql/client` peer installed.
|
|
45
|
+
* Integers read as `bigint` whatever the config asks, so the querier decodes one past 2^53 exactly.
|
|
46
|
+
*/
|
|
35
47
|
async createClient(conf) {
|
|
36
48
|
const { createClient } = await import('@libsql/client');
|
|
37
|
-
return createClient(conf);
|
|
49
|
+
return createClient({ ...conf, intMode: 'bigint' });
|
|
38
50
|
}
|
|
39
51
|
}
|
|
@@ -99,21 +99,7 @@ function defaultLiteral(value, dialect) {
|
|
|
99
99
|
if (typeof value === 'boolean') {
|
|
100
100
|
return dialect.booleanLiteral === 'native' ? (value ? 'TRUE' : 'FALSE') : value ? '1' : '0';
|
|
101
101
|
}
|
|
102
|
-
|
|
103
|
-
return dialect.escape(ddlTimestamp(value));
|
|
104
|
-
}
|
|
105
|
-
if (typeof value === 'object') {
|
|
106
|
-
return dialect.escape(JSON.stringify(value));
|
|
107
|
-
}
|
|
108
|
-
return dialect.escape(value);
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* `YYYY-MM-DD HH:mm:ss.SSS` in UTC. Not `toISOString`, whose `T` and `Z` MySQL rejects outright
|
|
112
|
-
* ("Invalid default value"), and not `escape`'s local-time form, which would make the DDL depend on
|
|
113
|
-
* the machine that generated it.
|
|
114
|
-
*/
|
|
115
|
-
function ddlTimestamp(date) {
|
|
116
|
-
return date.toISOString().replace('T', ' ').replace('Z', '');
|
|
102
|
+
return dialect.escape(typeof value === 'object' && !(value instanceof Date) ? JSON.stringify(value) : value);
|
|
117
103
|
}
|
|
118
104
|
function expressionSql(expression, dialect) {
|
|
119
105
|
const { expressions } = DIALECT_DEFAULTS[dialect.dialectName];
|
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Migration Builder
|
|
3
|
-
*
|
|
4
|
-
* Provides type-safe migration operations with two modes:
|
|
5
|
-
* - OperationRecorder: Record operations only (for code generation)
|
|
6
|
-
* - MigrationBuilder: Execute DDL operations (for integration tests/runtime)
|
|
7
|
-
*/
|
|
8
1
|
import type { ForeignKeyAction } from '../../schema/types.js';
|
|
9
2
|
import type { IndexColumnInput, IndexOptions } from '../../type/index.js';
|
|
10
|
-
import type {
|
|
3
|
+
import type { SchemaGenerator } from '../../type/migration.js';
|
|
11
4
|
import type { AnyMigrationOperation, IAlterTableBuilder, IColumnBuilder, IColumnFactory, IMigrationBuilder, ITableBuilder } from './types.js';
|
|
12
5
|
type ForeignKeyTarget = {
|
|
13
6
|
table: string;
|
|
@@ -49,28 +42,13 @@ export declare class OperationRecorder implements IMigrationBuilder {
|
|
|
49
42
|
getOperations(): AnyMigrationOperation[];
|
|
50
43
|
}
|
|
51
44
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* @example
|
|
56
|
-
* ```typescript
|
|
57
|
-
* const builder = new MigrationBuilder(querier);
|
|
58
|
-
*
|
|
59
|
-
* await builder.createTable('users', (t) => {
|
|
60
|
-
* t.id();
|
|
61
|
-
* t.string('name');
|
|
62
|
-
* t.timestamps();
|
|
63
|
-
* });
|
|
64
|
-
* ```
|
|
45
|
+
* Records each operation, then runs the statements `generator` writes for it through `run`. Build one
|
|
46
|
+
* for a querier with `migrationBuilderFor`.
|
|
65
47
|
*/
|
|
66
48
|
export declare class MigrationBuilder extends OperationRecorder {
|
|
67
|
-
private readonly
|
|
68
|
-
private readonly
|
|
69
|
-
constructor(
|
|
70
|
-
/** The recorder's sink, plus the statements the operation turns into. */
|
|
49
|
+
private readonly generator;
|
|
50
|
+
private readonly run;
|
|
51
|
+
constructor(generator: SchemaGenerator, run: (statement: string) => Promise<unknown>);
|
|
71
52
|
protected record(operation: AnyMigrationOperation): Promise<void>;
|
|
72
|
-
private getCreateTableStatements;
|
|
73
|
-
private execute;
|
|
74
|
-
private operationToSql;
|
|
75
53
|
}
|
|
76
54
|
export {};
|
|
@@ -1,14 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Migration Builder
|
|
3
|
-
*
|
|
4
|
-
* Provides type-safe migration operations with two modes:
|
|
5
|
-
* - OperationRecorder: Record operations only (for code generation)
|
|
6
|
-
* - MigrationBuilder: Execute DDL operations (for integration tests/runtime)
|
|
7
|
-
*/
|
|
8
1
|
import { indexNameParts, normalizeIndexColumn } from '../../util/index.js';
|
|
9
2
|
import { derivedIndexName } from '../../util/sql.util.js';
|
|
10
|
-
import { createSchemaGenerator } from '../schemaGenerator.js';
|
|
11
|
-
import { splitSqlStatements } from './splitSqlStatements.js';
|
|
12
3
|
import { TableBuilder } from './tableBuilder.js';
|
|
13
4
|
/**
|
|
14
5
|
* One `createIndex` operation. Shared because the alter-table builder, the recorder and the
|
|
@@ -239,86 +230,21 @@ export class OperationRecorder {
|
|
|
239
230
|
}
|
|
240
231
|
}
|
|
241
232
|
/**
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
* @example
|
|
246
|
-
* ```typescript
|
|
247
|
-
* const builder = new MigrationBuilder(querier);
|
|
248
|
-
*
|
|
249
|
-
* await builder.createTable('users', (t) => {
|
|
250
|
-
* t.id();
|
|
251
|
-
* t.string('name');
|
|
252
|
-
* t.timestamps();
|
|
253
|
-
* });
|
|
254
|
-
* ```
|
|
233
|
+
* Records each operation, then runs the statements `generator` writes for it through `run`. Build one
|
|
234
|
+
* for a querier with `migrationBuilderFor`.
|
|
255
235
|
*/
|
|
256
236
|
export class MigrationBuilder extends OperationRecorder {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
constructor(
|
|
237
|
+
generator;
|
|
238
|
+
run;
|
|
239
|
+
constructor(generator, run) {
|
|
260
240
|
super();
|
|
261
|
-
this.
|
|
262
|
-
|
|
263
|
-
if (!generator) {
|
|
264
|
-
throw new TypeError(`Could not find a schema generator for dialect: ${querier.dialect.dialectName}`);
|
|
265
|
-
}
|
|
266
|
-
this.sqlGenerator = generator;
|
|
241
|
+
this.generator = generator;
|
|
242
|
+
this.run = run;
|
|
267
243
|
}
|
|
268
|
-
/** The recorder's sink, plus the statements the operation turns into. */
|
|
269
244
|
async record(operation) {
|
|
270
245
|
await super.record(operation);
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
getCreateTableStatements(operation) {
|
|
274
|
-
return this.sqlGenerator.generateCreateTableFromDefinition(operation.table);
|
|
275
|
-
}
|
|
276
|
-
async execute(operation) {
|
|
277
|
-
if (operation.type === 'createTable') {
|
|
278
|
-
for (const statement of this.getCreateTableStatements(operation)) {
|
|
279
|
-
await this.querier.run(statement);
|
|
280
|
-
}
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
const sql = this.operationToSql(operation);
|
|
284
|
-
if (sql) {
|
|
285
|
-
for (const statement of splitSqlStatements(sql)) {
|
|
286
|
-
await this.querier.run(statement);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
operationToSql(operation) {
|
|
291
|
-
switch (operation.type) {
|
|
292
|
-
case 'createTable':
|
|
293
|
-
// One line per statement in preview; execute() runs each separately (#87).
|
|
294
|
-
return this.getCreateTableStatements(operation).join('\n');
|
|
295
|
-
case 'dropTable':
|
|
296
|
-
return this.sqlGenerator.generateDropTable(operation.tableName, {
|
|
297
|
-
ifExists: operation.ifExists,
|
|
298
|
-
cascade: operation.cascade,
|
|
299
|
-
});
|
|
300
|
-
case 'renameTable':
|
|
301
|
-
return this.sqlGenerator.generateRenameTableSql(operation.oldName, operation.newName);
|
|
302
|
-
case 'addColumn':
|
|
303
|
-
return this.sqlGenerator.generateAddColumnSql(operation.tableName, operation.column);
|
|
304
|
-
case 'dropColumn':
|
|
305
|
-
return this.sqlGenerator.generateDropColumnSql(operation.tableName, operation.columnName);
|
|
306
|
-
case 'renameColumn':
|
|
307
|
-
return this.sqlGenerator.generateRenameColumnSql(operation.tableName, operation.oldName, operation.newName);
|
|
308
|
-
case 'alterColumn':
|
|
309
|
-
return this.sqlGenerator.generateAlterColumnSql(operation.tableName, operation.columnName, operation.changes);
|
|
310
|
-
case 'createIndex':
|
|
311
|
-
return this.sqlGenerator.generateCreateIndexFromDefinition(operation.tableName, operation.index);
|
|
312
|
-
case 'dropIndex':
|
|
313
|
-
return this.sqlGenerator.generateDropIndex(operation.tableName, operation.indexName);
|
|
314
|
-
case 'addForeignKey':
|
|
315
|
-
return this.sqlGenerator.generateAddForeignKeySql(operation.tableName, operation.foreignKey);
|
|
316
|
-
case 'dropForeignKey':
|
|
317
|
-
return this.sqlGenerator.generateDropForeignKeySql(operation.tableName, operation.constraintName);
|
|
318
|
-
case 'raw':
|
|
319
|
-
return operation.sql;
|
|
320
|
-
default:
|
|
321
|
-
return undefined;
|
|
246
|
+
for (const statement of this.generator.generateOperation(operation)) {
|
|
247
|
+
await this.run(statement);
|
|
322
248
|
}
|
|
323
249
|
}
|
|
324
250
|
}
|
|
@@ -116,20 +116,10 @@ export interface TableDefinition {
|
|
|
116
116
|
/** Table comment */
|
|
117
117
|
comment?: string;
|
|
118
118
|
}
|
|
119
|
-
/**
|
|
120
|
-
* Type of migration operation.
|
|
121
|
-
*/
|
|
122
|
-
export type MigrationOperationType = 'createTable' | 'dropTable' | 'renameTable' | 'alterTable' | 'addColumn' | 'dropColumn' | 'alterColumn' | 'renameColumn' | 'createIndex' | 'dropIndex' | 'addForeignKey' | 'dropForeignKey' | 'raw';
|
|
123
|
-
/**
|
|
124
|
-
* Base migration operation.
|
|
125
|
-
*/
|
|
126
|
-
export interface MigrationOperation {
|
|
127
|
-
type: MigrationOperationType;
|
|
128
|
-
}
|
|
129
119
|
/**
|
|
130
120
|
* Create table operation.
|
|
131
121
|
*/
|
|
132
|
-
export interface CreateTableOperation
|
|
122
|
+
export interface CreateTableOperation {
|
|
133
123
|
type: 'createTable';
|
|
134
124
|
table: TableDefinition;
|
|
135
125
|
ifNotExists?: boolean;
|
|
@@ -137,7 +127,7 @@ export interface CreateTableOperation extends MigrationOperation {
|
|
|
137
127
|
/**
|
|
138
128
|
* Drop table operation.
|
|
139
129
|
*/
|
|
140
|
-
export interface DropTableOperation
|
|
130
|
+
export interface DropTableOperation {
|
|
141
131
|
type: 'dropTable';
|
|
142
132
|
tableName: string;
|
|
143
133
|
ifExists?: boolean;
|
|
@@ -146,7 +136,7 @@ export interface DropTableOperation extends MigrationOperation {
|
|
|
146
136
|
/**
|
|
147
137
|
* Rename table operation.
|
|
148
138
|
*/
|
|
149
|
-
export interface RenameTableOperation
|
|
139
|
+
export interface RenameTableOperation {
|
|
150
140
|
type: 'renameTable';
|
|
151
141
|
oldName: string;
|
|
152
142
|
newName: string;
|
|
@@ -154,7 +144,7 @@ export interface RenameTableOperation extends MigrationOperation {
|
|
|
154
144
|
/**
|
|
155
145
|
* Add column operation.
|
|
156
146
|
*/
|
|
157
|
-
export interface AddColumnOperation
|
|
147
|
+
export interface AddColumnOperation {
|
|
158
148
|
type: 'addColumn';
|
|
159
149
|
tableName: string;
|
|
160
150
|
column: FullColumnDefinition;
|
|
@@ -162,7 +152,7 @@ export interface AddColumnOperation extends MigrationOperation {
|
|
|
162
152
|
/**
|
|
163
153
|
* Drop column operation.
|
|
164
154
|
*/
|
|
165
|
-
export interface DropColumnOperation
|
|
155
|
+
export interface DropColumnOperation {
|
|
166
156
|
type: 'dropColumn';
|
|
167
157
|
tableName: string;
|
|
168
158
|
columnName: string;
|
|
@@ -170,7 +160,7 @@ export interface DropColumnOperation extends MigrationOperation {
|
|
|
170
160
|
/**
|
|
171
161
|
* Alter column operation.
|
|
172
162
|
*/
|
|
173
|
-
export interface AlterColumnOperation
|
|
163
|
+
export interface AlterColumnOperation {
|
|
174
164
|
type: 'alterColumn';
|
|
175
165
|
tableName: string;
|
|
176
166
|
columnName: string;
|
|
@@ -179,7 +169,7 @@ export interface AlterColumnOperation extends MigrationOperation {
|
|
|
179
169
|
/**
|
|
180
170
|
* Rename column operation.
|
|
181
171
|
*/
|
|
182
|
-
export interface RenameColumnOperation
|
|
172
|
+
export interface RenameColumnOperation {
|
|
183
173
|
type: 'renameColumn';
|
|
184
174
|
tableName: string;
|
|
185
175
|
oldName: string;
|
|
@@ -188,7 +178,7 @@ export interface RenameColumnOperation extends MigrationOperation {
|
|
|
188
178
|
/**
|
|
189
179
|
* Create index operation.
|
|
190
180
|
*/
|
|
191
|
-
export interface CreateIndexOperation
|
|
181
|
+
export interface CreateIndexOperation {
|
|
192
182
|
type: 'createIndex';
|
|
193
183
|
tableName: string;
|
|
194
184
|
index: IndexDefinition;
|
|
@@ -197,7 +187,7 @@ export interface CreateIndexOperation extends MigrationOperation {
|
|
|
197
187
|
/**
|
|
198
188
|
* Drop index operation.
|
|
199
189
|
*/
|
|
200
|
-
export interface DropIndexOperation
|
|
190
|
+
export interface DropIndexOperation {
|
|
201
191
|
type: 'dropIndex';
|
|
202
192
|
tableName: string;
|
|
203
193
|
indexName: string;
|
|
@@ -206,7 +196,7 @@ export interface DropIndexOperation extends MigrationOperation {
|
|
|
206
196
|
/**
|
|
207
197
|
* Add foreign key operation.
|
|
208
198
|
*/
|
|
209
|
-
export interface AddForeignKeyOperation
|
|
199
|
+
export interface AddForeignKeyOperation {
|
|
210
200
|
type: 'addForeignKey';
|
|
211
201
|
tableName: string;
|
|
212
202
|
foreignKey: ForeignKeySchema;
|
|
@@ -214,7 +204,7 @@ export interface AddForeignKeyOperation extends MigrationOperation {
|
|
|
214
204
|
/**
|
|
215
205
|
* Drop foreign key operation.
|
|
216
206
|
*/
|
|
217
|
-
export interface DropForeignKeyOperation
|
|
207
|
+
export interface DropForeignKeyOperation {
|
|
218
208
|
type: 'dropForeignKey';
|
|
219
209
|
tableName: string;
|
|
220
210
|
constraintName: string;
|
|
@@ -222,7 +212,7 @@ export interface DropForeignKeyOperation extends MigrationOperation {
|
|
|
222
212
|
/**
|
|
223
213
|
* Raw SQL operation (escape hatch).
|
|
224
214
|
*/
|
|
225
|
-
export interface RawSqlOperation
|
|
215
|
+
export interface RawSqlOperation {
|
|
226
216
|
type: 'raw';
|
|
227
217
|
sql: string;
|
|
228
218
|
}
|
|
@@ -387,7 +377,7 @@ export interface IAlterTableBuilder {
|
|
|
387
377
|
* Interface for the main migration builder.
|
|
388
378
|
*/
|
|
389
379
|
export interface IMigrationBuilder {
|
|
390
|
-
/** Create a
|
|
380
|
+
/** Create a table as `callback` declares it; on MongoDB a collection, whose callback declares only indexes. */
|
|
391
381
|
createTable(name: string, callback: (table: ITableBuilder) => void): Promise<void>;
|
|
392
382
|
/** Drop a table */
|
|
393
383
|
dropTable(name: string, options?: {
|
|
@@ -420,6 +410,6 @@ export interface IMigrationBuilder {
|
|
|
420
410
|
}): Promise<void>;
|
|
421
411
|
/** Drop a foreign key */
|
|
422
412
|
dropForeignKey(tableName: string, constraintName: string): Promise<void>;
|
|
423
|
-
/** Execute raw SQL */
|
|
413
|
+
/** Execute raw SQL, the escape hatch for anything the builder does not model. */
|
|
424
414
|
raw(sql: string): Promise<void>;
|
|
425
415
|
}
|
package/dist/migrate/cli.d.ts
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import type {
|
|
3
|
-
import type { Config, MigratorDialect } from '../type/index.js';
|
|
2
|
+
import type { Config } from '../type/index.js';
|
|
4
3
|
import { Migrator } from './migrator.js';
|
|
5
|
-
import { createSchemaGeneratorAsync } from './schemaGeneratorAsync.js';
|
|
6
|
-
/** Sync helper for SQL dialects only; returns `undefined` for MongoDB - use {@link createSchemaGeneratorAsync}. */
|
|
7
|
-
export declare function getSchemaGenerator(dialect: MigratorDialect, defaultForeignKeyAction?: ForeignKeyAction): import("./schemaGenerator.js").SqlSchemaGenerator | undefined;
|
|
8
|
-
export { createSchemaGeneratorAsync };
|
|
9
4
|
export declare function main(args?: string[]): Promise<void>;
|
|
10
5
|
export declare function runUp(migrator: Migrator, args: string[]): Promise<void>;
|
|
11
6
|
export declare function runDown(migrator: Migrator, args: string[]): Promise<void>;
|
package/dist/migrate/cli.js
CHANGED
|
@@ -7,14 +7,8 @@ import { createEntityCodeGenerator } from './codegen/entityCodeGenerator.js';
|
|
|
7
7
|
import { entityTypesSource } from './codegen/entityTypes.js';
|
|
8
8
|
import { detectDrift } from './drift/driftDetector.js';
|
|
9
9
|
import { Migrator } from './migrator.js';
|
|
10
|
-
import { buildEntityAST
|
|
11
|
-
import { createSchemaGeneratorAsync } from './schemaGeneratorAsync.js';
|
|
10
|
+
import { buildEntityAST } from './schemaGenerator.js';
|
|
12
11
|
import { DEFAULT_MIGRATIONS_TABLE } from './storage/databaseStorage.js';
|
|
13
|
-
/** Sync helper for SQL dialects only; returns `undefined` for MongoDB - use {@link createSchemaGeneratorAsync}. */
|
|
14
|
-
export function getSchemaGenerator(dialect, defaultForeignKeyAction) {
|
|
15
|
-
return createSchemaGenerator(dialect, defaultForeignKeyAction);
|
|
16
|
-
}
|
|
17
|
-
export { createSchemaGeneratorAsync };
|
|
18
12
|
export async function main(args = process.argv.slice(2)) {
|
|
19
13
|
let customPath;
|
|
20
14
|
const filteredArgs = [];
|
|
@@ -42,7 +36,6 @@ export async function main(args = process.argv.slice(2)) {
|
|
|
42
36
|
defaultForeignKeyAction: config.defaultForeignKeyAction,
|
|
43
37
|
};
|
|
44
38
|
const migrator = new Migrator(config.pool, options);
|
|
45
|
-
await migrator.ensureSchemaGenerator();
|
|
46
39
|
switch (command) {
|
|
47
40
|
case 'up':
|
|
48
41
|
await runUp(migrator, filteredArgs.slice(1));
|
|
@@ -259,13 +252,13 @@ export async function runDriftCheck(migrator, config) {
|
|
|
259
252
|
console.error('No entities configured. Add entities to your uql config.');
|
|
260
253
|
process.exit(1);
|
|
261
254
|
}
|
|
262
|
-
else if (!migrator.schemaIntrospector
|
|
255
|
+
else if (!migrator.schemaIntrospector) {
|
|
263
256
|
console.error('No introspector available. Check your pool configuration.');
|
|
264
257
|
process.exit(1);
|
|
265
258
|
}
|
|
266
259
|
else {
|
|
267
260
|
console.log('\nChecking for schema drift...');
|
|
268
|
-
const expectedAST = buildEntityAST(migrator.
|
|
261
|
+
const expectedAST = buildEntityAST(await migrator.getSchemaGenerator(), config.entities);
|
|
269
262
|
// Build actual schema from database
|
|
270
263
|
const actualAST = await migrator.schemaIntrospector.introspect();
|
|
271
264
|
// Detect drift. The dialect renders canonical types as SQL - without it every type formats as
|
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export { createEntityCodeGenerator, EntityCodeGenerator, type EntityCodeGeneratorOptions, type GeneratedEntity, } from './entityCodeGenerator.js';
|
|
7
7
|
export { entityTypesSource } from './entityTypes.js';
|
|
8
|
-
export { buildMigrationModule,
|
|
8
|
+
export { buildMigrationModule, EMPTY_MANUAL_MIGRATION_DOWN_INNER, EMPTY_MANUAL_MIGRATION_UP_INNER, emitMongoCommandCalls, emitSqlRunCall, emitSqlRunCalls, type MigrationModuleOptions, type MigrationQuerierType, } from './migrationFile.js';
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
// Entity code generator
|
|
7
7
|
export { createEntityCodeGenerator, EntityCodeGenerator, } from './entityCodeGenerator.js';
|
|
8
8
|
export { entityTypesSource } from './entityTypes.js';
|
|
9
|
-
export { buildMigrationModule,
|
|
9
|
+
export { buildMigrationModule, EMPTY_MANUAL_MIGRATION_DOWN_INNER, EMPTY_MANUAL_MIGRATION_UP_INNER, emitMongoCommandCalls, emitSqlRunCall, emitSqlRunCalls, } from './migrationFile.js';
|
|
@@ -7,7 +7,7 @@ import type { IndexNode } from '../../schema/types.js';
|
|
|
7
7
|
export declare function isPlainFieldIndex(index: IndexNode): boolean;
|
|
8
8
|
/**
|
|
9
9
|
* One `@Index((user) => [...])` as source, for an index no `@Field` can express, its columns read off the
|
|
10
|
-
*
|
|
10
|
+
* refs `param` names. Emits `raw` for an expression entry, so callers import `raw` when
|
|
11
11
|
* {@link indexNeedsRaw} holds.
|
|
12
12
|
*/
|
|
13
13
|
export declare function buildIndexDecoratorSource(index: IndexNode, propertyName: (column: string) => string, param: string): string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isVectorIndexType } from '../../type/index.js';
|
|
1
2
|
import { isIdentifierName, quoted, rawTag } from './sourceLiteral.js';
|
|
2
3
|
/**
|
|
3
4
|
* A vector index carries its metric in the operator class pgvector names after it
|
|
@@ -54,12 +55,12 @@ export function isPlainFieldIndex(index) {
|
|
|
54
55
|
}
|
|
55
56
|
/**
|
|
56
57
|
* One `@Index((user) => [...])` as source, for an index no `@Field` can express, its columns read off the
|
|
57
|
-
*
|
|
58
|
+
* refs `param` names. Emits `raw` for an expression entry, so callers import `raw` when
|
|
58
59
|
* {@link indexNeedsRaw} holds.
|
|
59
60
|
*/
|
|
60
61
|
export function buildIndexDecoratorSource(index, propertyName, param) {
|
|
61
62
|
const entries = index.entries.map((entry) => indexEntrySource(entry, propertyName, param)).join(', ');
|
|
62
|
-
const isVector = index.type
|
|
63
|
+
const isVector = isVectorIndexType(index.type);
|
|
63
64
|
const distance = isVector ? vectorDistance(index) : undefined;
|
|
64
65
|
const options = [];
|
|
65
66
|
if (index.name)
|
|
@@ -88,12 +89,7 @@ export function indexNeedsRaw(index) {
|
|
|
88
89
|
return Boolean(index.where) || index.entries.some((entry) => entry.expression);
|
|
89
90
|
}
|
|
90
91
|
function indexEntrySource(entry, propertyName, param) {
|
|
91
|
-
|
|
92
|
-
const expression = `() => ${rawTag(entry.column)}`;
|
|
93
|
-
const modifiers = significantModifiers(entry);
|
|
94
|
-
return modifiers.length === 0 ? expression : `{ column: ${expression}, ${modifiers.join(', ')} }`;
|
|
95
|
-
}
|
|
96
|
-
const column = memberSource(param, propertyName(entry.column));
|
|
92
|
+
const column = entry.expression ? rawTag(entry.column) : memberSource(param, propertyName(entry.column));
|
|
97
93
|
const modifiers = significantModifiers(entry);
|
|
98
94
|
return modifiers.length === 0 ? column : `{ column: ${column}, ${modifiers.join(', ')} }`;
|
|
99
95
|
}
|
|
@@ -15,8 +15,6 @@ export type MigrationModuleOptions = {
|
|
|
15
15
|
/** Indented body inside `async down` (including newlines). */
|
|
16
16
|
downInner: string;
|
|
17
17
|
};
|
|
18
|
-
/** @deprecated Use {@link MigrationModuleOptions}. */
|
|
19
|
-
export type SqlMigrationModuleOptions = MigrationModuleOptions;
|
|
20
18
|
/**
|
|
21
19
|
* Emit one `await querier.run(...)` line for entity-generated migrations.
|
|
22
20
|
* Uses `JSON.stringify` so SQL with backticks (SQLite/LibSQL), quotes, `${`, etc. stays valid TS source.
|
|
@@ -30,14 +28,22 @@ export declare function emitMongoCommandCalls(statements: string[]): string;
|
|
|
30
28
|
export declare const EMPTY_MANUAL_MIGRATION_UP_INNER = " // Add your migration logic here.\n // Use one await querier.run(\"...\") per SQL statement when possible (same style as generate:entities).\n // Example (Postgres):\n // await querier.run(\"CREATE TABLE \\\"users\\\" (\\\"id\\\" SERIAL PRIMARY KEY);\");\n";
|
|
31
29
|
/** Body for `down` in a manual (empty) migration scaffold. */
|
|
32
30
|
export declare const EMPTY_MANUAL_MIGRATION_DOWN_INNER = " // Add your rollback logic here.\n // await querier.run(\"DROP TABLE IF EXISTS \\\"users\\\";\");\n";
|
|
33
|
-
/** How a migration on
|
|
31
|
+
/** How a migration on one querier is scaffolded empty, and how a generated statement is spelled in it. */
|
|
32
|
+
export type MigrationSource = {
|
|
33
|
+
readonly querier: MigrationQuerierType;
|
|
34
|
+
readonly emptyUp: string;
|
|
35
|
+
readonly emptyDown: string;
|
|
36
|
+
emit(statements: string[]): string;
|
|
37
|
+
};
|
|
34
38
|
export declare const migrationSource: {
|
|
35
39
|
SqlQuerier: {
|
|
40
|
+
querier: "SqlQuerier";
|
|
36
41
|
emptyUp: string;
|
|
37
42
|
emptyDown: string;
|
|
38
43
|
emit: typeof emitSqlRunCalls;
|
|
39
44
|
};
|
|
40
45
|
MongoQuerier: {
|
|
46
|
+
querier: "MongoQuerier";
|
|
41
47
|
emptyUp: string;
|
|
42
48
|
emptyDown: string;
|
|
43
49
|
emit: typeof emitMongoCommandCalls;
|
|
@@ -47,5 +53,3 @@ export declare const migrationSource: {
|
|
|
47
53
|
* Full contents of a `export default { async up/down(querier) { ... } }` migration module.
|
|
48
54
|
*/
|
|
49
55
|
export declare function buildMigrationModule(options: MigrationModuleOptions): string;
|
|
50
|
-
/** @deprecated Use {@link buildMigrationModule}. */
|
|
51
|
-
export declare const buildSqlQuerierMigrationModule: typeof buildMigrationModule;
|
|
@@ -24,14 +24,15 @@ export const EMPTY_MANUAL_MIGRATION_UP_INNER = ` // Add your migration logic
|
|
|
24
24
|
export const EMPTY_MANUAL_MIGRATION_DOWN_INNER = ` // Add your rollback logic here.
|
|
25
25
|
// await querier.run("DROP TABLE IF EXISTS \\"users\\";");
|
|
26
26
|
`;
|
|
27
|
-
/** How a migration on each querier is scaffolded empty, and how a generated statement is spelled in it. */
|
|
28
27
|
export const migrationSource = {
|
|
29
28
|
SqlQuerier: {
|
|
29
|
+
querier: 'SqlQuerier',
|
|
30
30
|
emptyUp: EMPTY_MANUAL_MIGRATION_UP_INNER,
|
|
31
31
|
emptyDown: EMPTY_MANUAL_MIGRATION_DOWN_INNER,
|
|
32
32
|
emit: emitSqlRunCalls,
|
|
33
33
|
},
|
|
34
34
|
MongoQuerier: {
|
|
35
|
+
querier: 'MongoQuerier',
|
|
35
36
|
emptyUp: ` // Add your migration logic here, through the database handle.
|
|
36
37
|
// await querier.db.collection('users').updateMany({}, { $set: { active: true } });
|
|
37
38
|
`,
|
|
@@ -65,5 +66,3 @@ ${options.downInner}
|
|
|
65
66
|
};
|
|
66
67
|
`;
|
|
67
68
|
}
|
|
68
|
-
/** @deprecated Use {@link buildMigrationModule}. */
|
|
69
|
-
export const buildSqlQuerierMigrationModule = buildMigrationModule;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { AbstractSqlDialect } from '../../dialect/abstractSqlDialect.js';
|
|
2
2
|
import { type IndexType } from '../../schema/types.js';
|
|
3
3
|
import { type IndexColumnSchema, type IndexFeature, type IndexJsonArray, type IndexSchema } from '../../type/index.js';
|
|
4
|
+
/** Refuses an index of a type `types` lacks, `hints` naming what to declare instead. */
|
|
5
|
+
export declare function assertIndexType(index: IndexSchema, types: ReadonlySet<IndexType>, dialectName: string, hints?: ReadonlyMap<IndexType, string>): void;
|
|
6
|
+
/** Refuses an index asking for a feature `features` lacks. */
|
|
7
|
+
export declare function assertIndexFeatures(index: IndexSchema, features: ReadonlySet<IndexFeature>, dialectName: string): void;
|
|
4
8
|
/**
|
|
5
9
|
* `CREATE INDEX` for SQL dialects: the statement and the fragments each engine spells differently.
|
|
6
10
|
* The migrator's rather than the dialect's, since {@link SqlSchemaGenerator} is the only thing that
|
|
@@ -28,8 +32,6 @@ export declare class IndexDdl<D extends AbstractSqlDialect = AbstractSqlDialect>
|
|
|
28
32
|
protected readonly indexTypes: ReadonlySet<IndexType>;
|
|
29
33
|
/** What to declare instead of a type this dialect lacks, appended to its refusal. */
|
|
30
34
|
protected readonly indexTypeHints: ReadonlyMap<IndexType, string>;
|
|
31
|
-
private assertIndexType;
|
|
32
|
-
private assertIndexFeatures;
|
|
33
35
|
/**
|
|
34
36
|
* Index types this dialect spells as a keyword of their own (`FULLTEXT INDEX`, `VECTOR INDEX`)
|
|
35
37
|
* rather than as an access method after the table. One table drives both, so a type that is a
|
|
@@ -17,6 +17,20 @@ const INDEX_FEATURE_PROBES = {
|
|
|
17
17
|
opsClass: (index) => index.entries.some((entry) => entry.opsClass !== undefined),
|
|
18
18
|
include: (index) => Boolean(index.include?.length),
|
|
19
19
|
};
|
|
20
|
+
/** Refuses an index of a type `types` lacks, `hints` naming what to declare instead. */
|
|
21
|
+
export function assertIndexType(index, types, dialectName, hints = new Map()) {
|
|
22
|
+
if (index.type && !types.has(index.type)) {
|
|
23
|
+
throw new TypeError(`${dialectName} has no ${index.type} index (index "${index.name}")` + (hints.get(index.type) ?? ''));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Refuses an index asking for a feature `features` lacks. */
|
|
27
|
+
export function assertIndexFeatures(index, features, dialectName) {
|
|
28
|
+
for (const feature of getKeys(INDEX_FEATURE_PROBES)) {
|
|
29
|
+
if (INDEX_FEATURE_PROBES[feature](index) && !features.has(feature)) {
|
|
30
|
+
throw new TypeError(`${dialectName} does not support ${INDEX_FEATURE_LABELS[feature]} (index "${index.name}")`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
20
34
|
/**
|
|
21
35
|
* `CREATE INDEX` for SQL dialects: the statement and the fragments each engine spells differently.
|
|
22
36
|
* The migrator's rather than the dialect's, since {@link SqlSchemaGenerator} is the only thing that
|
|
@@ -30,8 +44,8 @@ export class IndexDdl {
|
|
|
30
44
|
this.dialect = dialect;
|
|
31
45
|
}
|
|
32
46
|
getCreateIndexStatement(tableName, index, opts = {}) {
|
|
33
|
-
|
|
34
|
-
|
|
47
|
+
assertIndexType(index, this.indexTypes, this.dialect.dialectName, this.indexTypeHints);
|
|
48
|
+
assertIndexFeatures(index, this.indexFeatures, this.dialect.dialectName);
|
|
35
49
|
const unique = index.unique ? 'UNIQUE ' : '';
|
|
36
50
|
const ifNotExists = (opts.ifNotExists ?? this.dialect.features.indexIfNotExists) ? 'IF NOT EXISTS ' : '';
|
|
37
51
|
const columns = index.entries.map((entry) => this.indexColumn(entry, index)).join(', ');
|
|
@@ -57,19 +71,6 @@ export class IndexDdl {
|
|
|
57
71
|
indexTypes = new Set(INDEX_TYPES);
|
|
58
72
|
/** What to declare instead of a type this dialect lacks, appended to its refusal. */
|
|
59
73
|
indexTypeHints = new Map();
|
|
60
|
-
assertIndexType(index) {
|
|
61
|
-
if (index.type && !this.indexTypes.has(index.type)) {
|
|
62
|
-
throw new TypeError(`${this.dialect.dialectName} has no ${index.type} index (index "${index.name}")` +
|
|
63
|
-
(this.indexTypeHints.get(index.type) ?? ''));
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
assertIndexFeatures(index) {
|
|
67
|
-
for (const feature of getKeys(INDEX_FEATURE_PROBES)) {
|
|
68
|
-
if (INDEX_FEATURE_PROBES[feature](index) && !this.indexFeatures.has(feature)) {
|
|
69
|
-
throw new TypeError(`${this.dialect.dialectName} does not support ${INDEX_FEATURE_LABELS[feature]} (index "${index.name}")`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
74
|
/**
|
|
74
75
|
* Index types this dialect spells as a keyword of their own (`FULLTEXT INDEX`, `VECTOR INDEX`)
|
|
75
76
|
* rather than as an access method after the table. One table drives both, so a type that is a
|