uql-orm 0.21.0 → 0.23.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/browser/uql-browser.min.js.map +3 -3
- 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 +49 -8
- package/dist/dialect/abstractSqlDialect.js +95 -47
- 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 +26 -1
- package/dist/dialect/mysqlLikeSqlDialect.js +57 -1
- package/dist/dialect/pgLikeSqlDialect.d.ts +37 -22
- package/dist/dialect/pgLikeSqlDialect.js +97 -68
- 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/bag.d.ts +35 -0
- package/dist/entity/decorator/bag.js +54 -0
- package/dist/entity/decorator/entity.d.ts +28 -2
- package/dist/entity/decorator/entity.js +40 -2
- package/dist/entity/decorator/members.d.ts +51 -0
- package/dist/entity/decorator/members.js +51 -0
- package/dist/entity/index.d.ts +3 -1
- package/dist/entity/index.js +3 -1
- package/dist/entity/metadata/definition.d.ts +23 -8
- package/dist/entity/metadata/definition.js +56 -100
- package/dist/http/contract.js +1 -2
- package/dist/http/handler.js +5 -26
- package/dist/http/query.js +1 -1
- 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/acquireQuerierForMigrations.d.ts +13 -1
- package/dist/migrate/acquireQuerierForMigrations.js +28 -0
- 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-config.js +24 -8
- package/dist/migrate/cli.d.ts +3 -2
- package/dist/migrate/cli.js +26 -49
- package/dist/migrate/codegen/entityCodeGenerator.d.ts +0 -4
- package/dist/migrate/codegen/entityCodeGenerator.js +8 -67
- 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 -3
- package/dist/migrate/codegen/index.js +0 -6
- package/dist/migrate/drift/driftDetector.d.ts +10 -1
- package/dist/migrate/drift/driftDetector.js +22 -5
- 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 +30 -11
- package/dist/migrate/introspection/abstractSqlSchemaIntrospector.js +61 -57
- package/dist/migrate/introspection/baseSqlIntrospector.d.ts +0 -1
- package/dist/migrate/introspection/baseSqlIntrospector.js +3 -12
- package/dist/migrate/introspection/mongoIntrospector.js +9 -15
- 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 +101 -150
- 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.d.ts +2 -0
- package/dist/migrate/storage/databaseStorage.js +12 -27
- package/dist/mongo/mongoDialect.d.ts +2 -0
- package/dist/mongo/mongoDialect.js +14 -3
- package/dist/mongo/mongodbQuerier.js +171 -229
- package/dist/mysql/mysqlDialect.d.ts +8 -0
- package/dist/mysql/mysqlDialect.js +13 -0
- package/dist/nestjs/uqlContextInterceptor.js +58 -22
- package/dist/nestjs/uqlModule.d.ts +2 -11
- package/dist/nestjs/uqlModule.js +93 -44
- package/dist/postgres/postgresDialect.js +2 -2
- package/dist/querier/abstractQuerier.d.ts +28 -0
- package/dist/querier/abstractQuerier.js +47 -22
- package/dist/querier/abstractQuerierPool.d.ts +3 -0
- package/dist/querier/abstractQuerierPool.js +5 -3
- package/dist/querier/abstractSqlQuerier.d.ts +1 -3
- package/dist/querier/abstractSqlQuerier.js +48 -96
- package/dist/querier/index.d.ts +3 -1
- package/dist/querier/index.js +3 -1
- package/dist/querier/querierContext.browser.d.ts +12 -0
- package/dist/querier/querierContext.browser.js +18 -0
- package/dist/querier/querierContext.d.ts +22 -0
- package/dist/querier/querierContext.js +42 -0
- package/dist/querier/queryError.d.ts +22 -0
- package/dist/querier/queryError.js +20 -0
- package/dist/querier/transactional.d.ts +26 -0
- package/dist/querier/transactional.js +43 -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 +9 -2
- package/dist/schema/schemaASTBuilder.js +58 -49
- package/dist/schema/types.d.ts +10 -58
- package/dist/sqlite/abstractSqliteQuerier.d.ts +46 -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 +68 -0
- package/dist/sqlite/hranaQuerierPool.d.ts +21 -0
- package/dist/sqlite/hranaQuerierPool.js +25 -0
- package/dist/sqlite/index.d.ts +3 -1
- package/dist/sqlite/index.js +3 -1
- package/dist/sqlite/localSqliteQuerierPool.d.ts +31 -0
- package/dist/sqlite/localSqliteQuerierPool.js +34 -0
- package/dist/sqlite/nodeSqliteAdapter.d.ts +35 -0
- package/dist/sqlite/nodeSqliteAdapter.js +28 -0
- package/dist/sqlite/nodeSqliteQuerierPool.d.ts +28 -0
- package/dist/sqlite/nodeSqliteQuerierPool.js +29 -0
- package/dist/sqlite/sqliteDialect.d.ts +18 -5
- package/dist/sqlite/sqliteDialect.js +23 -36
- package/dist/sqlite/sqliteQuerier.d.ts +16 -9
- package/dist/sqlite/sqliteQuerier.js +4 -27
- package/dist/sqlite/sqliteQuerierPool.d.ts +11 -14
- package/dist/sqlite/sqliteQuerierPool.js +16 -24
- 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 +154 -26
- package/dist/type/migration.d.ts +32 -23
- package/dist/type/querier.d.ts +6 -0
- package/dist/type/vector.d.ts +5 -2
- package/dist/util/hook.util.js +1 -1
- 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 +21 -16
- package/dist/entity/decorator/field.d.ts +0 -2
- package/dist/entity/decorator/field.js +0 -7
- package/dist/entity/decorator/filter.d.ts +0 -7
- package/dist/entity/decorator/filter.js +0 -11
- package/dist/entity/decorator/hook.d.ts +0 -7
- package/dist/entity/decorator/hook.js +0 -14
- package/dist/entity/decorator/id.d.ts +0 -2
- package/dist/entity/decorator/id.js +0 -7
- package/dist/entity/decorator/index-decorator.d.ts +0 -29
- package/dist/entity/decorator/index-decorator.js +0 -26
- package/dist/entity/decorator/index.d.ts +0 -8
- package/dist/entity/decorator/index.js +0 -8
- package/dist/entity/decorator/relation.d.ts +0 -8
- package/dist/entity/decorator/relation.js +0 -19
- 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/codegen/smartRelationDetector.d.ts +0 -47
- package/dist/migrate/codegen/smartRelationDetector.js +0 -134
- 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/querier/decorator/index.d.ts +0 -4
- package/dist/querier/decorator/index.js +0 -4
- package/dist/querier/decorator/injectQuerier.d.ts +0 -3
- package/dist/querier/decorator/injectQuerier.js +0 -33
- package/dist/querier/decorator/log.d.ts +0 -32
- package/dist/querier/decorator/log.js +0 -52
- package/dist/querier/decorator/serialized.d.ts +0 -6
- package/dist/querier/decorator/serialized.js +0 -13
- package/dist/querier/decorator/transactional.d.ts +0 -6
- package/dist/querier/decorator/transactional.js +0 -48
- package/dist/sqlite/betterSqlite3Dialect.d.ts +0 -9
- package/dist/sqlite/betterSqlite3Dialect.js +0 -9
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Fluent API for defining tables in migrations.
|
|
5
5
|
*/
|
|
6
|
+
import { normalizeIndexColumn } from '../../util/index.js';
|
|
6
7
|
import { ColumnBuilder } from './columnBuilder.js';
|
|
7
8
|
import { t } from './expressions.js';
|
|
8
9
|
/**
|
|
@@ -68,137 +69,83 @@ export class TableBuilder {
|
|
|
68
69
|
// Numeric Types
|
|
69
70
|
// ============================================================================
|
|
70
71
|
id(name = 'id', options = {}) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
this.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
this._columnBuilders.push(col);
|
|
88
|
-
return col;
|
|
89
|
-
}
|
|
90
|
-
float(name, options = {}) {
|
|
91
|
-
const col = new ColumnBuilder(name, { category: 'float' }, options);
|
|
92
|
-
this._columnBuilders.push(col);
|
|
93
|
-
return col;
|
|
94
|
-
}
|
|
95
|
-
double(name, options = {}) {
|
|
96
|
-
const col = new ColumnBuilder(name, { category: 'float', size: 'big' }, options);
|
|
97
|
-
this._columnBuilders.push(col);
|
|
98
|
-
return col;
|
|
72
|
+
return this.add(name, { category: 'integer' }, { ...options, primaryKey: true, autoIncrement: true });
|
|
73
|
+
}
|
|
74
|
+
integer(name, options) {
|
|
75
|
+
return this.add(name, { category: 'integer' }, options);
|
|
76
|
+
}
|
|
77
|
+
smallint(name, options) {
|
|
78
|
+
return this.add(name, { category: 'integer', size: 'small' }, options);
|
|
79
|
+
}
|
|
80
|
+
bigint(name, options) {
|
|
81
|
+
return this.add(name, { category: 'integer', size: 'big' }, options);
|
|
82
|
+
}
|
|
83
|
+
float(name, options) {
|
|
84
|
+
return this.add(name, { category: 'float' }, options);
|
|
85
|
+
}
|
|
86
|
+
double(name, options) {
|
|
87
|
+
return this.add(name, { category: 'float', size: 'big' }, options);
|
|
99
88
|
}
|
|
100
89
|
decimal(name, options = {}) {
|
|
101
90
|
const { precision, scale, ...rest } = options;
|
|
102
|
-
|
|
103
|
-
this._columnBuilders.push(col);
|
|
104
|
-
return col;
|
|
91
|
+
return this.add(name, { category: 'decimal', precision, scale }, rest);
|
|
105
92
|
}
|
|
106
|
-
// ============================================================================
|
|
107
|
-
// String Types
|
|
108
|
-
// ============================================================================
|
|
109
93
|
string(name, options = {}) {
|
|
110
94
|
const { length = 255, ...rest } = options;
|
|
111
|
-
|
|
112
|
-
this._columnBuilders.push(col);
|
|
113
|
-
return col;
|
|
95
|
+
return this.add(name, { category: 'string', length }, rest);
|
|
114
96
|
}
|
|
115
97
|
char(name, options = {}) {
|
|
116
98
|
const { length = 1, ...rest } = options;
|
|
117
|
-
|
|
118
|
-
this._columnBuilders.push(col);
|
|
119
|
-
return col;
|
|
99
|
+
return this.add(name, { category: 'string', length }, rest);
|
|
120
100
|
}
|
|
121
|
-
text(name, options
|
|
122
|
-
|
|
123
|
-
this._columnBuilders.push(col);
|
|
124
|
-
return col;
|
|
101
|
+
text(name, options) {
|
|
102
|
+
return this.add(name, { category: 'string' }, options);
|
|
125
103
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
// ============================================================================
|
|
129
|
-
boolean(name, options = {}) {
|
|
130
|
-
const col = new ColumnBuilder(name, { category: 'boolean' }, options);
|
|
131
|
-
this._columnBuilders.push(col);
|
|
132
|
-
return col;
|
|
104
|
+
boolean(name, options) {
|
|
105
|
+
return this.add(name, { category: 'boolean' }, options);
|
|
133
106
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
// ============================================================================
|
|
137
|
-
date(name, options = {}) {
|
|
138
|
-
const col = new ColumnBuilder(name, { category: 'date' }, options);
|
|
139
|
-
this._columnBuilders.push(col);
|
|
140
|
-
return col;
|
|
141
|
-
}
|
|
142
|
-
time(name, options = {}) {
|
|
143
|
-
const col = new ColumnBuilder(name, { category: 'time' }, options);
|
|
144
|
-
this._columnBuilders.push(col);
|
|
145
|
-
return col;
|
|
146
|
-
}
|
|
147
|
-
timestamp(name, options = {}) {
|
|
148
|
-
const col = new ColumnBuilder(name, { category: 'timestamp' }, options);
|
|
149
|
-
this._columnBuilders.push(col);
|
|
150
|
-
return col;
|
|
151
|
-
}
|
|
152
|
-
timestamptz(name, options = {}) {
|
|
153
|
-
const col = new ColumnBuilder(name, { category: 'timestamp', withTimezone: true }, options);
|
|
154
|
-
this._columnBuilders.push(col);
|
|
155
|
-
return col;
|
|
107
|
+
date(name, options) {
|
|
108
|
+
return this.add(name, { category: 'date' }, options);
|
|
156
109
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
// ============================================================================
|
|
160
|
-
json(name, options = {}) {
|
|
161
|
-
const col = new ColumnBuilder(name, { category: 'json' }, options);
|
|
162
|
-
this._columnBuilders.push(col);
|
|
163
|
-
return col;
|
|
110
|
+
time(name, options) {
|
|
111
|
+
return this.add(name, { category: 'time' }, options);
|
|
164
112
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
const col = new ColumnBuilder(name, { category: 'json' }, options);
|
|
168
|
-
this._columnBuilders.push(col);
|
|
169
|
-
return col;
|
|
113
|
+
timestamp(name, options) {
|
|
114
|
+
return this.add(name, { category: 'timestamp' }, options);
|
|
170
115
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
116
|
+
timestamptz(name, options) {
|
|
117
|
+
return this.add(name, { category: 'timestamp', withTimezone: true }, options);
|
|
118
|
+
}
|
|
119
|
+
json(name, options) {
|
|
120
|
+
return this.add(name, { category: 'json' }, options);
|
|
121
|
+
}
|
|
122
|
+
/** One canonical json category; the dialect decides between `JSON` and `JSONB`. */
|
|
123
|
+
jsonb(name, options) {
|
|
124
|
+
return this.add(name, { category: 'json' }, options);
|
|
125
|
+
}
|
|
126
|
+
uuid(name, options) {
|
|
127
|
+
return this.add(name, { category: 'uuid' }, options);
|
|
178
128
|
}
|
|
179
|
-
blob(name, options
|
|
180
|
-
|
|
181
|
-
this._columnBuilders.push(col);
|
|
182
|
-
return col;
|
|
129
|
+
blob(name, options) {
|
|
130
|
+
return this.add(name, { category: 'blob' }, options);
|
|
183
131
|
}
|
|
184
132
|
vector(name, options = {}) {
|
|
185
133
|
const { dimensions, ...rest } = options;
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
134
|
+
return this.add(name, { category: 'vector', length: dimensions }, rest);
|
|
135
|
+
}
|
|
136
|
+
add(name, type, options = {}) {
|
|
137
|
+
const column = new ColumnBuilder(name, type, options);
|
|
138
|
+
this._columnBuilders.push(column);
|
|
139
|
+
return column;
|
|
189
140
|
}
|
|
190
141
|
// ============================================================================
|
|
191
142
|
// Convenience Methods
|
|
192
143
|
// ============================================================================
|
|
193
144
|
createdAt() {
|
|
194
|
-
|
|
195
|
-
this._columnBuilders.push(col);
|
|
196
|
-
return col;
|
|
145
|
+
return this.add('createdAt', { category: 'timestamp' }, { defaultValue: t.now() });
|
|
197
146
|
}
|
|
198
147
|
updatedAt() {
|
|
199
|
-
|
|
200
|
-
this._columnBuilders.push(col);
|
|
201
|
-
return col;
|
|
148
|
+
return this.add('updatedAt', { category: 'timestamp' }, { defaultValue: t.now() });
|
|
202
149
|
}
|
|
203
150
|
timestamps() {
|
|
204
151
|
this.createdAt();
|
|
@@ -211,21 +158,26 @@ export class TableBuilder {
|
|
|
211
158
|
this._primaryKey = columns;
|
|
212
159
|
return this;
|
|
213
160
|
}
|
|
214
|
-
unique(columns,
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
unique: true,
|
|
220
|
-
});
|
|
221
|
-
return this;
|
|
161
|
+
unique(columns, options) {
|
|
162
|
+
return this.addIndex('uq', columns, options, true);
|
|
163
|
+
}
|
|
164
|
+
index(columns, options) {
|
|
165
|
+
return this.addIndex('idx', columns, options, false);
|
|
222
166
|
}
|
|
223
|
-
|
|
224
|
-
|
|
167
|
+
/**
|
|
168
|
+
* `@Index` and `table.index(...)` differ only in how the name is defaulted, so both normalize their
|
|
169
|
+
* entries here: the generator renders expressions and per-column modifiers from the normalized
|
|
170
|
+
* form, and anything left as a bare string would reach it as a column literally named `[object
|
|
171
|
+
* Object]`.
|
|
172
|
+
*/
|
|
173
|
+
addIndex(prefix, columns, options, unique) {
|
|
174
|
+
const { name, ...rest } = typeof options === 'string' ? { name: options } : (options ?? {});
|
|
175
|
+
const entries = columns.map(normalizeIndexColumn);
|
|
225
176
|
this._indexes.push({
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
177
|
+
...rest,
|
|
178
|
+
name: name ?? `${prefix}_${this._name}_${entries.map((entry) => entry.column).join('_')}`,
|
|
179
|
+
columns: entries,
|
|
180
|
+
unique,
|
|
229
181
|
});
|
|
230
182
|
return this;
|
|
231
183
|
}
|
|
@@ -255,7 +207,7 @@ export class TableBuilder {
|
|
|
255
207
|
if (!this._indexes.some((idx) => idx.name === indexName)) {
|
|
256
208
|
this._indexes.push({
|
|
257
209
|
name: indexName,
|
|
258
|
-
columns: [col.name],
|
|
210
|
+
columns: [{ column: col.name }],
|
|
259
211
|
unique: col.unique,
|
|
260
212
|
});
|
|
261
213
|
}
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* Type definitions for the fluent migration builder API.
|
|
5
5
|
* Enables type-safe migrations without raw SQL.
|
|
6
6
|
*/
|
|
7
|
-
import type { CanonicalType, ForeignKeyAction
|
|
7
|
+
import type { CanonicalType, ForeignKeyAction } from '../../schema/types.js';
|
|
8
|
+
import type { IndexColumnInput, IndexOptions, IndexSchema } from '../../type/index.js';
|
|
8
9
|
/**
|
|
9
10
|
* Foreign key reference options.
|
|
10
11
|
*/
|
|
@@ -110,21 +111,6 @@ export interface FullColumnDefinition extends ColumnDefinition {
|
|
|
110
111
|
/** Index name (if indexed) */
|
|
111
112
|
index?: string | boolean;
|
|
112
113
|
}
|
|
113
|
-
/**
|
|
114
|
-
* Index definition.
|
|
115
|
-
*/
|
|
116
|
-
export interface IndexDefinition {
|
|
117
|
-
/** Index name */
|
|
118
|
-
name: string;
|
|
119
|
-
/** Column names */
|
|
120
|
-
columns: string[];
|
|
121
|
-
/** Whether unique */
|
|
122
|
-
unique: boolean;
|
|
123
|
-
/** Index type (btree, hash, etc.) */
|
|
124
|
-
type?: IndexType;
|
|
125
|
-
/** Partial index WHERE clause */
|
|
126
|
-
where?: string;
|
|
127
|
-
}
|
|
128
114
|
/**
|
|
129
115
|
* Complete table definition.
|
|
130
116
|
*/
|
|
@@ -136,7 +122,7 @@ export interface TableDefinition {
|
|
|
136
122
|
/** Primary key columns (for composite keys) */
|
|
137
123
|
primaryKey?: string[];
|
|
138
124
|
/** Index definitions */
|
|
139
|
-
indexes:
|
|
125
|
+
indexes: IndexSchema[];
|
|
140
126
|
/** Foreign key definitions at table level */
|
|
141
127
|
foreignKeys: TableForeignKeyDefinition[];
|
|
142
128
|
/** Table comment */
|
|
@@ -234,7 +220,7 @@ export interface RenameColumnOperation extends MigrationOperation {
|
|
|
234
220
|
export interface CreateIndexOperation extends MigrationOperation {
|
|
235
221
|
type: 'createIndex';
|
|
236
222
|
tableName: string;
|
|
237
|
-
index:
|
|
223
|
+
index: IndexSchema;
|
|
238
224
|
ifNotExists?: boolean;
|
|
239
225
|
}
|
|
240
226
|
/**
|
|
@@ -310,9 +296,13 @@ export interface IForeignKeyBuilder extends IColumnBuilder {
|
|
|
310
296
|
onUpdate(action: ForeignKeyAction): this;
|
|
311
297
|
}
|
|
312
298
|
/**
|
|
313
|
-
*
|
|
299
|
+
* The column vocabulary: every column type the builder can declare, name first.
|
|
300
|
+
*
|
|
301
|
+
* Split out of {@link ITableBuilder} so `addColumn`/`alterColumn` can hand it to their callback. They
|
|
302
|
+
* used to take an {@link IColumnBuilder}, which has no way to say what type a column is - so the
|
|
303
|
+
* builder hard-coded `VARCHAR`, and every column a generated migration added or altered was a string.
|
|
314
304
|
*/
|
|
315
|
-
export interface
|
|
305
|
+
export interface IColumnFactory {
|
|
316
306
|
/** Add an auto-incrementing primary key */
|
|
317
307
|
id(name?: string, options?: BaseColumnOptions): IColumnBuilder;
|
|
318
308
|
/** Add an integer column */
|
|
@@ -353,6 +343,11 @@ export interface ITableBuilder {
|
|
|
353
343
|
blob(name: string, options?: BaseColumnOptions): IColumnBuilder;
|
|
354
344
|
/** Add a vector column (for embeddings) */
|
|
355
345
|
vector(name: string, options?: VectorColumnOptions): IColumnBuilder;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Interface for table builder (fluent API).
|
|
349
|
+
*/
|
|
350
|
+
export interface ITableBuilder extends IColumnFactory {
|
|
356
351
|
/** Add createdAt timestamp column */
|
|
357
352
|
createdAt(): IColumnBuilder;
|
|
358
353
|
/** Add updatedAt timestamp column */
|
|
@@ -361,10 +356,10 @@ export interface ITableBuilder {
|
|
|
361
356
|
timestamps(): void;
|
|
362
357
|
/** Add composite primary key */
|
|
363
358
|
primaryKey(columns: string[]): this;
|
|
364
|
-
/** Add composite unique
|
|
365
|
-
unique(columns:
|
|
366
|
-
/** Add composite index */
|
|
367
|
-
index(columns:
|
|
359
|
+
/** Add a composite unique index; takes the same options as `@Index`, or just its name. */
|
|
360
|
+
unique(columns: readonly IndexColumnInput[], options?: string | IndexOptions): this;
|
|
361
|
+
/** Add a composite index; takes the same options as `@Index`, or just its name. */
|
|
362
|
+
index(columns: readonly IndexColumnInput[], options?: string | IndexOptions): this;
|
|
368
363
|
/** Add table-level foreign key */
|
|
369
364
|
foreignKey(columns: string[]): ITableForeignKeyBuilder;
|
|
370
365
|
/** Add a comment to the table */
|
|
@@ -389,19 +384,16 @@ export interface ITableForeignKeyBuilder {
|
|
|
389
384
|
* Interface for altering a table.
|
|
390
385
|
*/
|
|
391
386
|
export interface IAlterTableBuilder {
|
|
392
|
-
/** Add a column
|
|
393
|
-
addColumn(
|
|
387
|
+
/** Add a column, declared exactly as in `createTable`: `addColumn((c) => c.timestamp('createdAt'))`. */
|
|
388
|
+
addColumn(callback: (columns: IColumnFactory) => IColumnBuilder): this;
|
|
394
389
|
/** Drop a column from the table */
|
|
395
390
|
dropColumn(name: string): this;
|
|
396
391
|
/** Rename a column */
|
|
397
392
|
renameColumn(oldName: string, newName: string): this;
|
|
398
|
-
/**
|
|
399
|
-
alterColumn(
|
|
393
|
+
/** Redeclare a column, named and typed as it should end up. */
|
|
394
|
+
alterColumn(callback: (columns: IColumnFactory) => IColumnBuilder): this;
|
|
400
395
|
/** Add an index to the table */
|
|
401
|
-
addIndex(columns:
|
|
402
|
-
name?: string;
|
|
403
|
-
unique?: boolean;
|
|
404
|
-
}): this;
|
|
396
|
+
addIndex(columns: readonly IndexColumnInput[], options?: IndexOptions): this;
|
|
405
397
|
/** Drop an index from the table */
|
|
406
398
|
dropIndex(name: string): this;
|
|
407
399
|
/** Add a foreign key to the table */
|
|
@@ -431,19 +423,16 @@ export interface IMigrationBuilder {
|
|
|
431
423
|
renameTable(oldName: string, newName: string): Promise<void>;
|
|
432
424
|
/** Alter an existing table */
|
|
433
425
|
alterTable(name: string, callback: (table: IAlterTableBuilder) => void): Promise<void>;
|
|
434
|
-
/** Add a column
|
|
435
|
-
addColumn(tableName: string,
|
|
426
|
+
/** Add a column, declared exactly as in `createTable`: `addColumn('t', (c) => c.timestamp('at'))`. */
|
|
427
|
+
addColumn(tableName: string, callback: (columns: IColumnFactory) => IColumnBuilder): Promise<void>;
|
|
436
428
|
/** Drop a column from a table */
|
|
437
429
|
dropColumn(tableName: string, columnName: string): Promise<void>;
|
|
438
|
-
/**
|
|
439
|
-
alterColumn(tableName: string,
|
|
430
|
+
/** Redeclare a column, named and typed as it should end up. */
|
|
431
|
+
alterColumn(tableName: string, callback: (columns: IColumnFactory) => IColumnBuilder): Promise<void>;
|
|
440
432
|
/** Rename a column */
|
|
441
433
|
renameColumn(tableName: string, oldName: string, newName: string): Promise<void>;
|
|
442
|
-
/** Create an index */
|
|
443
|
-
createIndex(tableName: string, columns:
|
|
444
|
-
name?: string;
|
|
445
|
-
unique?: boolean;
|
|
446
|
-
}): Promise<void>;
|
|
434
|
+
/** Create an index; takes the same options as `@Index`, so a generated migration can restate them. */
|
|
435
|
+
createIndex(tableName: string, columns: readonly IndexColumnInput[], options?: IndexOptions): Promise<void>;
|
|
447
436
|
/** Drop an index */
|
|
448
437
|
dropIndex(tableName: string, indexName: string): Promise<void>;
|
|
449
438
|
/** Add a foreign key */
|
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
import { stat } from 'node:fs/promises';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
|
-
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
/**
|
|
5
|
+
* Loads the config with a plain `import()`, leaving TypeScript to whatever runs the CLI.
|
|
6
|
+
*
|
|
7
|
+
* @remarks uql deliberately bundles no transpiler. The config imports the entity classes, so whoever
|
|
8
|
+
* loads it decides which decorator spec their decorators are invoked with, and only the runtime knows
|
|
9
|
+
* the project's `tsconfig.json`. Bun and `node --import tsx` both get it right; a bundled loader would
|
|
10
|
+
* be guessing, and `jiti` guessed wrong (it hardcodes the legacy transform, so standard decorators were
|
|
11
|
+
* called as `(prototype, key)` and every field was silently dropped).
|
|
12
|
+
*
|
|
13
|
+
* Node's own type stripping covers a config that is only types plus a plain object, which is why the
|
|
14
|
+
* error below distinguishes the two cases: decorators are not erasable syntax, so a config that reaches
|
|
15
|
+
* decorated entity classes needs a runtime that actually transforms them.
|
|
16
|
+
*/
|
|
4
17
|
async function importConfig(path) {
|
|
5
|
-
const
|
|
6
|
-
throw new
|
|
7
|
-
|
|
8
|
-
|
|
18
|
+
const mod = (await import(pathToFileURL(path).href).catch((cause) => {
|
|
19
|
+
throw new TypeError(`Could not import ${path}: ${cause?.message}\n` +
|
|
20
|
+
'If it reaches entity classes, their decorators need a runtime that transforms TypeScript, not ' +
|
|
21
|
+
'just one that strips its types. Run the CLI with `bun`, or with `node --import tsx` ' +
|
|
22
|
+
'(`npm i -D tsx`). A JavaScript config, or passing the config inline, needs neither.', { cause });
|
|
23
|
+
}));
|
|
24
|
+
return mod.default ?? mod;
|
|
9
25
|
}
|
|
10
26
|
export async function loadConfig(customPath) {
|
|
11
27
|
if (customPath) {
|
|
@@ -14,14 +30,14 @@ export async function loadConfig(customPath) {
|
|
|
14
30
|
.then(() => true)
|
|
15
31
|
.catch(() => false);
|
|
16
32
|
if (!exists) {
|
|
17
|
-
throw new
|
|
33
|
+
throw new TypeError(`Could not find uql configuration file at ${customPath}`);
|
|
18
34
|
}
|
|
19
35
|
try {
|
|
20
36
|
const config = await importConfig(fullPath);
|
|
21
37
|
return config;
|
|
22
38
|
}
|
|
23
39
|
catch (error) {
|
|
24
|
-
throw new
|
|
40
|
+
throw new TypeError(`Could not load configuration file at ${customPath}: ${error.message}`);
|
|
25
41
|
}
|
|
26
42
|
}
|
|
27
43
|
const configPaths = ['uql.config.ts', 'uql.config.js', 'uql.config.mjs', '.uqlrc.ts', '.uqlrc.js'];
|
|
@@ -35,5 +51,5 @@ export async function loadConfig(customPath) {
|
|
|
35
51
|
return config;
|
|
36
52
|
}
|
|
37
53
|
}
|
|
38
|
-
throw new
|
|
54
|
+
throw new TypeError('Could not find uql configuration file. Create a uql.config.ts or uql.config.js file in your project root.');
|
|
39
55
|
}
|
package/dist/migrate/cli.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import type { AbstractDialect } from '../dialect/index.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { ForeignKeyAction } from '../schema/types.js';
|
|
4
|
+
import type { Config } from '../type/index.js';
|
|
4
5
|
import { Migrator } from './migrator.js';
|
|
5
6
|
import { createSchemaGeneratorAsync } from './schemaGeneratorAsync.js';
|
|
6
7
|
/** Sync helper for SQL dialects only; returns `undefined` for MongoDB - use {@link createSchemaGeneratorAsync}. */
|
|
7
|
-
export declare function getSchemaGenerator(dialect: AbstractDialect,
|
|
8
|
+
export declare function getSchemaGenerator(dialect: AbstractDialect, defaultForeignKeyAction?: ForeignKeyAction): import("./schemaGenerator.js").SqlSchemaGenerator | undefined;
|
|
8
9
|
export { createSchemaGeneratorAsync };
|
|
9
10
|
export declare function main(args?: string[]): Promise<void>;
|
|
10
11
|
export declare function runUp(migrator: Migrator, args: string[]): Promise<void>;
|
package/dist/migrate/cli.js
CHANGED
|
@@ -9,10 +9,10 @@ import { detectDrift } from './drift/driftDetector.js';
|
|
|
9
9
|
import { Migrator } from './migrator.js';
|
|
10
10
|
import { createSchemaGenerator } from './schemaGenerator.js';
|
|
11
11
|
import { createSchemaGeneratorAsync } from './schemaGeneratorAsync.js';
|
|
12
|
-
import {
|
|
12
|
+
import { DEFAULT_MIGRATIONS_TABLE } from './storage/databaseStorage.js';
|
|
13
13
|
/** Sync helper for SQL dialects only; returns `undefined` for MongoDB - use {@link createSchemaGeneratorAsync}. */
|
|
14
|
-
export function getSchemaGenerator(dialect,
|
|
15
|
-
return createSchemaGenerator(dialect,
|
|
14
|
+
export function getSchemaGenerator(dialect, defaultForeignKeyAction) {
|
|
15
|
+
return createSchemaGenerator(dialect, defaultForeignKeyAction);
|
|
16
16
|
}
|
|
17
17
|
export { createSchemaGeneratorAsync };
|
|
18
18
|
export async function main(args = process.argv.slice(2)) {
|
|
@@ -40,11 +40,11 @@ export async function main(args = process.argv.slice(2)) {
|
|
|
40
40
|
tableName: config.tableName,
|
|
41
41
|
logger: console.log,
|
|
42
42
|
entities: config.entities,
|
|
43
|
-
|
|
43
|
+
defaultForeignKeyAction: config.defaultForeignKeyAction,
|
|
44
44
|
};
|
|
45
45
|
const migrator = new Migrator(config.pool, options);
|
|
46
46
|
if (!migrator.schemaGenerator) {
|
|
47
|
-
const generator = await createSchemaGeneratorAsync(config.pool.dialect, config.
|
|
47
|
+
const generator = await createSchemaGeneratorAsync(config.pool.dialect, config.defaultForeignKeyAction);
|
|
48
48
|
if (!generator) {
|
|
49
49
|
throw new TypeError(`Could not find a schema generator for dialect: ${dialectName}`);
|
|
50
50
|
}
|
|
@@ -191,49 +191,25 @@ export async function runGenerateFromEntities(migrator, args) {
|
|
|
191
191
|
console.log(`\nCreated migration from entities: ${filePath}`);
|
|
192
192
|
}
|
|
193
193
|
export async function runSync(migrator, args, config) {
|
|
194
|
-
|
|
195
|
-
const push = args.includes('--push');
|
|
196
|
-
const pull = args.includes('--pull');
|
|
197
|
-
const dryRun = args.includes('--dry-run');
|
|
198
|
-
// Parse direction
|
|
199
|
-
let direction = 'bidirectional';
|
|
200
|
-
for (let i = 0; i < args.length; i++) {
|
|
201
|
-
if (args[i] === '--direction' && args[i + 1]) {
|
|
202
|
-
direction = args[++i];
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
// Shorthand flags
|
|
206
|
-
if (push)
|
|
207
|
-
direction = 'entity-to-db';
|
|
208
|
-
if (pull)
|
|
209
|
-
direction = 'db-to-entity';
|
|
210
|
-
if (force) {
|
|
194
|
+
if (args.includes('--force')) {
|
|
211
195
|
console.log('\n⚠️ WARNING: This will drop and recreate all tables!');
|
|
212
196
|
console.log(' All data will be lost. This should only be used in development.\n');
|
|
213
|
-
await migrator.sync({ force });
|
|
197
|
+
await migrator.sync({ force: true });
|
|
214
198
|
console.log('\nSchema sync completed.');
|
|
215
199
|
return;
|
|
216
200
|
}
|
|
217
|
-
//
|
|
218
|
-
if (
|
|
219
|
-
|
|
220
|
-
entities: config.entities,
|
|
221
|
-
introspector: migrator.schemaIntrospector,
|
|
222
|
-
direction,
|
|
223
|
-
safe: !args.includes('--unsafe'),
|
|
224
|
-
dryRun,
|
|
225
|
-
});
|
|
226
|
-
const result = await schemaSync.sync();
|
|
227
|
-
console.log('\n' + result.summary);
|
|
228
|
-
if (result.conflicts.length > 0) {
|
|
229
|
-
console.log('\n⚠️ Conflicts require manual resolution.');
|
|
230
|
-
process.exit(1);
|
|
231
|
-
}
|
|
201
|
+
// Pulling the database into entity files is what `generate:from-db` does; one implementation.
|
|
202
|
+
if (args.includes('--pull')) {
|
|
203
|
+
return runGenerateFromDb(migrator, args, config);
|
|
232
204
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
205
|
+
const safe = !args.includes('--unsafe');
|
|
206
|
+
if (args.includes('--dry-run')) {
|
|
207
|
+
const statements = await migrator.planSync({ safe, drop: !safe });
|
|
208
|
+
console.log(statements.length ? `\n${statements.join('\n')}` : '\nSchema is already in sync.');
|
|
209
|
+
return;
|
|
236
210
|
}
|
|
211
|
+
await migrator.autoSync({ safe, drop: !safe, logging: true });
|
|
212
|
+
console.log('\nSchema sync completed.');
|
|
237
213
|
}
|
|
238
214
|
export async function runGenerateFromDb(migrator, args, config) {
|
|
239
215
|
// Parse output directory
|
|
@@ -290,7 +266,10 @@ export async function runDriftCheck(migrator, config) {
|
|
|
290
266
|
const actualAST = await migrator.schemaIntrospector.introspect();
|
|
291
267
|
// Detect drift. The dialect renders canonical types as SQL - without it every type formats as
|
|
292
268
|
// `unknown` and type drift compares equal, silently reporting a mismatched column as in sync.
|
|
293
|
-
const report = detectDrift(expectedAST, actualAST, {
|
|
269
|
+
const report = detectDrift(expectedAST, actualAST, {
|
|
270
|
+
dialect: config.pool?.dialect,
|
|
271
|
+
excludeTables: [config.tableName ?? DEFAULT_MIGRATIONS_TABLE],
|
|
272
|
+
});
|
|
294
273
|
printDriftReport(report);
|
|
295
274
|
}
|
|
296
275
|
}
|
|
@@ -359,13 +338,11 @@ Commands:
|
|
|
359
338
|
generate:from-db Generate TypeScript entities from database
|
|
360
339
|
--output, -o <dir> Output directory (default: ./src/entities)
|
|
361
340
|
|
|
362
|
-
sync
|
|
341
|
+
sync Apply the entity schema to the database
|
|
342
|
+
--dry-run Print the statements instead of running them
|
|
343
|
+
--unsafe Allow destructive changes (drops, column alterations)
|
|
344
|
+
--pull Go the other way: generate entities from the database
|
|
363
345
|
--force Drop and recreate all tables (dangerous!)
|
|
364
|
-
--direction <mode> Sync direction: bidirectional, entity-to-db, db-to-entity
|
|
365
|
-
--push Shorthand for --direction entity-to-db
|
|
366
|
-
--pull Shorthand for --direction db-to-entity
|
|
367
|
-
--dry-run Preview changes without applying
|
|
368
|
-
--unsafe Allow destructive changes
|
|
369
346
|
|
|
370
347
|
drift:check Check for schema drift between entities and database
|
|
371
348
|
|
|
@@ -391,7 +368,7 @@ Examples:
|
|
|
391
368
|
uql-orm/migrate generate add_users_table
|
|
392
369
|
uql-orm/migrate generate:entities initial_schema
|
|
393
370
|
uql-orm/migrate generate:from-db --output ./src/entities
|
|
394
|
-
uql-orm/migrate sync --
|
|
371
|
+
uql-orm/migrate sync --dry-run
|
|
395
372
|
uql-orm/migrate sync --pull
|
|
396
373
|
uql-orm/migrate drift:check
|
|
397
374
|
`);
|
|
@@ -105,10 +105,6 @@ export declare class EntityCodeGenerator {
|
|
|
105
105
|
* Format type for description.
|
|
106
106
|
*/
|
|
107
107
|
private formatTypeDescription;
|
|
108
|
-
/**
|
|
109
|
-
* Format default value for code.
|
|
110
|
-
*/
|
|
111
|
-
private formatDefaultValue;
|
|
112
108
|
/**
|
|
113
109
|
* Default class name transformer: table_name -> TableName (PascalCase, singular).
|
|
114
110
|
*/
|