uql-orm 0.66.0 → 0.67.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/browser/querier/httpQuerier.js +1 -8
- package/dist/browser/uql-browser.min.js.map +5 -5
- package/dist/bunSql/bunSql.util.d.ts +2 -6
- package/dist/bunSql/bunSql.util.js +2 -6
- package/dist/bunSql/bunSqlQuerier.d.ts +2 -5
- package/dist/bunSql/bunSqlQuerier.js +2 -5
- package/dist/cockroachdb/cockroachDialect.d.ts +4 -13
- package/dist/cockroachdb/cockroachDialect.js +4 -13
- package/dist/context/context.browser.js +2 -10
- package/dist/context/context.d.ts +4 -17
- package/dist/context/context.js +4 -17
- package/dist/dialect/abstractDialect.d.ts +4 -19
- package/dist/dialect/abstractDialect.js +2 -20
- package/dist/dialect/abstractSqlDialect.d.ts +47 -212
- package/dist/dialect/abstractSqlDialect.js +68 -222
- package/dist/dialect/aliases.d.ts +2 -12
- package/dist/dialect/aliases.js +4 -12
- package/dist/dialect/hydrateColumn.d.ts +2 -6
- package/dist/dialect/hydrateColumn.js +3 -13
- package/dist/dialect/jsonArrayElemMatchUtils.d.ts +1 -7
- package/dist/dialect/jsonArrayElemMatchUtils.js +1 -7
- package/dist/dialect/jsonSql.d.ts +6 -27
- package/dist/dialect/jsonSql.js +6 -27
- package/dist/dialect/mergeSqlDialect.d.ts +4 -22
- package/dist/dialect/mergeSqlDialect.js +4 -22
- package/dist/dialect/mysqlLikeSqlDialect.d.ts +11 -37
- package/dist/dialect/mysqlLikeSqlDialect.js +35 -51
- package/dist/dialect/pgLikeSqlDialect.d.ts +8 -22
- package/dist/dialect/pgLikeSqlDialect.js +36 -39
- package/dist/dialect/queryContext.d.ts +4 -22
- package/dist/dialect/queryContext.js +4 -22
- package/dist/dialect/queryJoins.d.ts +3 -12
- package/dist/dialect/queryJoins.js +3 -12
- package/dist/dialect/vectorCast.d.ts +2 -12
- package/dist/dialect/vectorCast.js +3 -19
- package/dist/dialect/vectorSqlDialect.d.ts +8 -38
- package/dist/dialect/vectorSqlDialect.js +7 -38
- package/dist/entity/decorator/bag.d.ts +6 -19
- package/dist/entity/decorator/bag.js +6 -22
- package/dist/entity/decorator/entity.d.ts +2 -7
- package/dist/entity/decorator/entity.js +2 -7
- package/dist/entity/decorator/members.d.ts +7 -30
- package/dist/entity/decorator/members.js +3 -12
- package/dist/entity/metadata/definition.d.ts +2 -18
- package/dist/entity/metadata/definition.js +6 -28
- package/dist/http/handler.d.ts +2 -14
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/libsql/libsqlDialect.d.ts +1 -8
- package/dist/libsql/libsqlDialect.js +1 -8
- package/dist/maria/mariaDialect.d.ts +3 -5
- package/dist/maria/mariaDialect.js +5 -5
- package/dist/maria/mariadbQuerier.js +2 -2
- package/dist/maria/mariadbQuerierPool.js +1 -6
- package/dist/migrate/builder/migrationBuilder.js +3 -19
- package/dist/migrate/builder/splitSqlStatements.d.ts +1 -14
- package/dist/migrate/builder/splitSqlStatements.js +2 -22
- package/dist/migrate/builder/types.d.ts +2 -15
- package/dist/migrate/cli-config.js +2 -11
- package/dist/migrate/cli.js +2 -7
- package/dist/migrate/codegen/entityCodeGenerator.d.ts +0 -15
- package/dist/migrate/codegen/entityCodeGenerator.js +15 -44
- package/dist/migrate/codegen/fieldOptionsSource.d.ts +1 -8
- package/dist/migrate/codegen/fieldOptionsSource.js +3 -22
- package/dist/migrate/ddl/indexDdl.d.ts +2 -5
- package/dist/migrate/ddl/indexDdl.js +2 -5
- package/dist/migrate/ddl/pgIndexDdl.d.ts +3 -13
- package/dist/migrate/ddl/pgIndexDdl.js +3 -13
- package/dist/migrate/generator/definitionToNode.d.ts +2 -9
- package/dist/migrate/generator/definitionToNode.js +3 -17
- package/dist/migrate/generator/indexNodeToSchema.d.ts +2 -3
- package/dist/migrate/generator/indexNodeToSchema.js +2 -3
- package/dist/migrate/generator/mongoCommand.d.ts +1 -8
- package/dist/migrate/generator/mongoSchemaGenerator.d.ts +1 -8
- package/dist/migrate/generator/mongoSchemaGenerator.js +1 -8
- package/dist/migrate/introspection/abstractSqlSchemaIntrospector.d.ts +6 -26
- package/dist/migrate/introspection/abstractSqlSchemaIntrospector.js +9 -41
- package/dist/migrate/introspection/baseSqlIntrospector.js +0 -1
- package/dist/migrate/introspection/mongoIntrospector.d.ts +3 -1
- package/dist/migrate/introspection/mongoIntrospector.js +48 -46
- package/dist/migrate/introspection/mssqlIntrospector.d.ts +4 -4
- package/dist/migrate/introspection/mssqlIntrospector.js +18 -27
- package/dist/migrate/introspection/mysqlIntrospector.d.ts +7 -2
- package/dist/migrate/introspection/mysqlIntrospector.js +16 -14
- package/dist/migrate/introspection/postgresIntrospector.d.ts +24 -9
- package/dist/migrate/introspection/postgresIntrospector.js +68 -59
- package/dist/migrate/introspection/sqliteIntrospector.d.ts +1 -1
- package/dist/migrate/introspection/sqliteIntrospector.js +8 -10
- package/dist/migrate/migrator.d.ts +9 -53
- package/dist/migrate/migrator.js +32 -65
- package/dist/migrate/schemaGenerator.d.ts +16 -66
- package/dist/migrate/schemaGenerator.js +21 -74
- package/dist/mongo/mongoDialect.d.ts +21 -53
- package/dist/mongo/mongoDialect.js +25 -70
- package/dist/mongo/mongodbQuerier.d.ts +5 -8
- package/dist/mongo/mongodbQuerier.js +31 -65
- package/dist/mssql/mssqlDialect.d.ts +8 -34
- package/dist/mssql/mssqlDialect.js +37 -51
- package/dist/mssql/mssqlQuerier.d.ts +37 -4
- package/dist/mssql/mssqlQuerier.js +2 -2
- package/dist/mssql/mssqlWireTypes.d.ts +2 -14
- package/dist/mssql/mssqlWireTypes.js +2 -14
- package/dist/nestjs/uqlModule.js +2 -7
- package/dist/pglite/pgliteQuerier.d.ts +1 -9
- package/dist/pglite/pgliteQuerierPool.d.ts +4 -26
- package/dist/pglite/pgliteQuerierPool.js +3 -18
- package/dist/postgres/abstractPgQuerierPool.d.ts +1 -8
- package/dist/postgres/abstractPgQuerierPool.js +1 -8
- package/dist/postgres/pgNumericTypes.d.ts +3 -26
- package/dist/postgres/pgNumericTypes.js +3 -26
- package/dist/postgres/postgresDialect.d.ts +4 -10
- package/dist/postgres/postgresDialect.js +4 -10
- package/dist/querier/abstractQuerier.d.ts +35 -103
- package/dist/querier/abstractQuerier.js +105 -201
- package/dist/querier/abstractSharedHandleQuerierPool.d.ts +3 -17
- package/dist/querier/abstractSharedHandleQuerierPool.js +3 -17
- package/dist/querier/abstractSqlQuerier.d.ts +15 -36
- package/dist/querier/abstractSqlQuerier.js +49 -131
- package/dist/schema/canonicalType.d.ts +3 -21
- package/dist/schema/canonicalType.js +22 -67
- package/dist/schema/dependencyGraph.d.ts +2 -8
- package/dist/schema/dependencyGraph.js +2 -32
- package/dist/schema/index.d.ts +1 -25
- package/dist/schema/index.js +0 -26
- package/dist/schema/indexColumns.d.ts +1 -8
- package/dist/schema/indexColumns.js +1 -8
- package/dist/schema/indexDifferences.d.ts +7 -40
- package/dist/schema/indexDifferences.js +6 -31
- package/dist/schema/schemaAST.d.ts +8 -175
- package/dist/schema/schemaAST.js +13 -365
- package/dist/schema/schemaASTBuilder.d.ts +2 -24
- package/dist/schema/schemaASTBuilder.js +2 -30
- package/dist/schema/schemaASTDiffer.d.ts +6 -46
- package/dist/schema/schemaASTDiffer.js +8 -56
- package/dist/schema/types.d.ts +5 -61
- package/dist/schema/types.js +3 -6
- package/dist/sqlite/abstractSqliteQuerier.d.ts +1 -8
- package/dist/sqlite/localSqliteQuerierPool.d.ts +1 -7
- package/dist/sqlite/localSqliteQuerierPool.js +1 -7
- package/dist/sqlite/nodeSqliteQuerierPool.d.ts +2 -7
- package/dist/sqlite/nodeSqliteQuerierPool.js +2 -7
- package/dist/sqlite/sqliteDialect.d.ts +5 -20
- package/dist/sqlite/sqliteDialect.js +29 -35
- package/dist/turso/tursoDialect.d.ts +4 -6
- package/dist/turso/tursoDialect.js +4 -6
- package/dist/turso/tursoLocalQuerierPool.d.ts +1 -7
- package/dist/turso/tursoLocalQuerierPool.js +1 -7
- package/dist/turso/tursoQuerierPool.d.ts +2 -6
- package/dist/turso/tursoQuerierPool.js +2 -6
- package/dist/turso/tursoSessionQuerier.d.ts +1 -7
- package/dist/turso/tursoSessionQuerier.js +1 -7
- package/dist/type/dialect.d.ts +42 -94
- package/dist/type/dialect.js +3 -13
- package/dist/type/entity.d.ts +163 -534
- package/dist/type/entity.js +26 -9
- package/dist/type/logger.d.ts +2 -14
- package/dist/type/migration.d.ts +9 -38
- package/dist/type/querier.d.ts +9 -28
- package/dist/type/querierPool.d.ts +4 -26
- package/dist/type/query.d.ts +19 -73
- package/dist/type/query.js +2 -7
- package/dist/type/queryAggregate.d.ts +18 -98
- package/dist/type/queryRaw.d.ts +1 -8
- package/dist/type/queryRaw.js +1 -8
- package/dist/type/queryWhere.d.ts +13 -61
- package/dist/type/universalQuerier.d.ts +18 -105
- package/dist/type/utility.d.ts +12 -24
- package/dist/type/vector.d.ts +8 -38
- package/dist/type/vector.js +1 -1
- package/dist/type/wire.d.ts +2 -5
- package/dist/util/dialect.util.d.ts +9 -27
- package/dist/util/dialect.util.js +10 -27
- package/dist/util/field.util.d.ts +2 -31
- package/dist/util/field.util.js +3 -43
- package/dist/util/fieldOption.util.d.ts +7 -15
- package/dist/util/fieldOption.util.js +1 -1
- package/dist/util/filters.util.d.ts +2 -5
- package/dist/util/filters.util.js +2 -5
- package/dist/util/logger.d.ts +2 -6
- package/dist/util/logger.js +2 -6
- package/dist/util/object.util.d.ts +2 -6
- package/dist/util/object.util.js +1 -5
- package/dist/util/raw.d.ts +3 -23
- package/dist/util/relationQuery.util.d.ts +3 -14
- package/dist/util/relationQuery.util.js +3 -14
- package/dist/util/rowKey.util.d.ts +2 -10
- package/dist/util/rowKey.util.js +2 -10
- package/dist/util/sql.util.d.ts +6 -37
- package/dist/util/sql.util.js +13 -73
- package/dist/util/sqlLiteral.d.ts +2 -13
- package/dist/util/sqlLiteral.js +8 -13
- package/dist/util/string.util.js +0 -2
- package/package.json +4 -4
|
@@ -175,11 +175,8 @@ export function defineEntity(entity, opts = {}) {
|
|
|
175
175
|
if (!hasKeys(meta.fields)) {
|
|
176
176
|
throw TypeError(`'${entity.name}' must have fields`);
|
|
177
177
|
}
|
|
178
|
-
// A later call composes onto the entity, so
|
|
179
|
-
//
|
|
180
|
-
// It records that the class name stood in, telling a naming strategy there is something to derive;
|
|
181
|
-
// comparing the two cannot, since an entity may name its table exactly what its class is called and
|
|
182
|
-
// a spec's minted class is named after its table.
|
|
178
|
+
// A later call composes onto the entity, so a name is only ever set, and `derivedName` records that
|
|
179
|
+
// the class name stood in, which is what a naming strategy derives from.
|
|
183
180
|
if (opts.name !== undefined) {
|
|
184
181
|
meta.name = opts.name;
|
|
185
182
|
meta.derivedName = false;
|
|
@@ -251,27 +248,11 @@ export function relationOf(meta, key) {
|
|
|
251
248
|
}
|
|
252
249
|
return relation;
|
|
253
250
|
}
|
|
254
|
-
/**
|
|
255
|
-
* Whether the caller named every column of the row's primary key, so {@link idOf} can name the row.
|
|
256
|
-
*
|
|
257
|
-
* `!= null` rather than falsiness: `0` and an empty string are ids a row can legitimately carry, and
|
|
258
|
-
* reading them as "no id" is how a write of that row turned into a second insert. Distinct from
|
|
259
|
-
* "does the row carry this column", which an insert asks of `undefined` alone because that is what
|
|
260
|
-
* decides whether the column appears in its `VALUES` list at all.
|
|
261
|
-
*/
|
|
251
|
+
/** Whether the row names every column of its primary key, `0` and `''` included. */
|
|
262
252
|
export function namesKey(meta, row) {
|
|
263
253
|
return meta.ids.every((key) => row[key] != null);
|
|
264
254
|
}
|
|
265
|
-
/**
|
|
266
|
-
* A row's primary key: the value itself for a single key, an object carrying every key for a
|
|
267
|
-
* composite - which is {@link WrittenId}, and reads as the {@link EntityId} a `$where` takes.
|
|
268
|
-
*
|
|
269
|
-
* What a settled write names its rows by, and what a write hands back. Naming a composite row by one
|
|
270
|
-
* of its columns would address every row agreeing on that one.
|
|
271
|
-
*
|
|
272
|
-
* `WrittenId` does not reduce for an unresolved `E`, so which branch this entity is in cannot be
|
|
273
|
-
* proven here, only checked - which is what `ids.length` does.
|
|
274
|
-
*/
|
|
255
|
+
/** A row's primary key: its value, or a map of every column on a composite, checked at run time. */
|
|
275
256
|
export function idOf(meta, row) {
|
|
276
257
|
const { ids } = meta;
|
|
277
258
|
const id = ids.length === 1 ? row[ids[0]] : Object.fromEntries(ids.map((key) => [key, row[key]]));
|
|
@@ -503,11 +484,8 @@ function getIdKeys(meta) {
|
|
|
503
484
|
return getKeys(meta.fields).filter((key) => meta.fields[key]?.isId);
|
|
504
485
|
}
|
|
505
486
|
/**
|
|
506
|
-
* Merges `ancestor` and its
|
|
507
|
-
*
|
|
508
|
-
* its registrations, so do it here. Walking the *class* prototype chain rather than the metadata
|
|
509
|
-
* object's is what makes this work on every transformer: tsc and esbuild chain metadata across
|
|
510
|
-
* `extends`, SWC does not.
|
|
487
|
+
* Merges `ancestor` and its ancestors into `meta`, nearest first, draining an undecorated base's
|
|
488
|
+
* registrations. Walks the class chain, since not every compiler chains decorator metadata.
|
|
511
489
|
*/
|
|
512
490
|
function inheritFrom(meta, ancestor) {
|
|
513
491
|
for (let parent = ancestor; parent && parent !== Object; parent = parentOf(parent)) {
|
package/dist/http/handler.d.ts
CHANGED
|
@@ -29,13 +29,7 @@ export type HookContext<E extends object, Ctx = unknown> = {
|
|
|
29
29
|
readonly meta: EntityMeta<E>;
|
|
30
30
|
readonly op: CrudOperation;
|
|
31
31
|
readonly method: HttpMethod;
|
|
32
|
-
/**
|
|
33
|
-
* parsed query - mutate in place or reassign to shape it (e.g. force a `$select`, inject a
|
|
34
|
-
* `$sort`). For actual tenant/row-level scoping, prefer `@Filter(..., { security: true })` on
|
|
35
|
-
* the entity instead: unlike a hook mutation, it is AND-merged (a client `$where` on the same
|
|
36
|
-
* key cannot silently win), fails closed when its context is missing, and applies uniformly
|
|
37
|
-
* across every query path including joined relations.
|
|
38
|
-
*/
|
|
32
|
+
/** The parsed query, to reshape in place. Scope rows with a `security` filter instead, which a client cannot override. */
|
|
39
33
|
query: Query<E>;
|
|
40
34
|
/**
|
|
41
35
|
* request payload - reassignable for sanitization or field injection.
|
|
@@ -51,13 +45,7 @@ export type ResponseHook<Ctx = unknown> = <E extends object>(ctx: HookContext<E,
|
|
|
51
45
|
export type RequestHandlerOptions<Ctx = unknown> = {
|
|
52
46
|
include?: Type<object>[];
|
|
53
47
|
exclude?: Type<object>[];
|
|
54
|
-
/**
|
|
55
|
-
* The URL segment an entity is addressed by, defaulting to its kebab-cased class name.
|
|
56
|
-
*
|
|
57
|
-
* State it where the default cannot serve: a build that minifies class names renames every route,
|
|
58
|
-
* and two entities mapping one table in different schemas collide on one. The browser client takes
|
|
59
|
-
* the same option, so both ends can read one map.
|
|
60
|
-
*/
|
|
48
|
+
/** The URL segment an entity is addressed by, its kebab-cased class name by default; the browser client takes the same option. */
|
|
61
49
|
entityPath?: (entity: Type<unknown>) => string;
|
|
62
50
|
/**
|
|
63
51
|
* Allow augment any kind of request before it runs. Hooks may be async
|
package/dist/index.d.ts
CHANGED
|
@@ -4,4 +4,6 @@ export * from './entity/index.js';
|
|
|
4
4
|
export * from './namingStrategy/index.js';
|
|
5
5
|
export * from './querier/index.js';
|
|
6
6
|
export * from './type/index.js';
|
|
7
|
-
export
|
|
7
|
+
export { withDeleted } from './util/filters.util.js';
|
|
8
|
+
export { DefaultLogger } from './util/logger.js';
|
|
9
|
+
export { raw, refs } from './util/raw.js';
|
package/dist/index.js
CHANGED
|
@@ -4,4 +4,6 @@ export * from './entity/index.js';
|
|
|
4
4
|
export * from './namingStrategy/index.js';
|
|
5
5
|
export * from './querier/index.js';
|
|
6
6
|
export * from './type/index.js';
|
|
7
|
-
export
|
|
7
|
+
export { withDeleted } from './util/filters.util.js';
|
|
8
|
+
export { DefaultLogger } from './util/logger.js';
|
|
9
|
+
export { raw, refs } from './util/raw.js';
|
|
@@ -7,13 +7,6 @@ import type { VectorDistance, VectorMetric } from '../type/index.js';
|
|
|
7
7
|
* functions, which `TursoDialect` inherits.
|
|
8
8
|
*/
|
|
9
9
|
export declare class LibsqlDialect extends SqliteDialect {
|
|
10
|
-
/**
|
|
11
|
-
* libSQL has vector search built in, under its own names, so the sqlite-vec `vec_distance_*`
|
|
12
|
-
* functions this dialect would otherwise inherit are never present.
|
|
13
|
-
*
|
|
14
|
-
* @remarks `inner` and `l1` are left out: `vector_distance_dot` only exists in the newer Rust
|
|
15
|
-
* engine (see `TursoLocalDialect`) and no libSQL build has an L1 metric. Both raise the same
|
|
16
|
-
* "does not support vector distance metric" error as any other unsupported metric.
|
|
17
|
-
*/
|
|
10
|
+
/** libSQL's built-in vector functions; no `inner` (only the Rust engine has it) and no `l1`. */
|
|
18
11
|
readonly vectorMetrics: ReadonlyMap<VectorDistance, VectorMetric>;
|
|
19
12
|
}
|
|
@@ -6,14 +6,7 @@ import { SqliteDialect } from '../sqlite/sqliteDialect.js';
|
|
|
6
6
|
* functions, which `TursoDialect` inherits.
|
|
7
7
|
*/
|
|
8
8
|
export class LibsqlDialect extends SqliteDialect {
|
|
9
|
-
/**
|
|
10
|
-
* libSQL has vector search built in, under its own names, so the sqlite-vec `vec_distance_*`
|
|
11
|
-
* functions this dialect would otherwise inherit are never present.
|
|
12
|
-
*
|
|
13
|
-
* @remarks `inner` and `l1` are left out: `vector_distance_dot` only exists in the newer Rust
|
|
14
|
-
* engine (see `TursoLocalDialect`) and no libSQL build has an L1 metric. Both raise the same
|
|
15
|
-
* "does not support vector distance metric" error as any other unsupported metric.
|
|
16
|
-
*/
|
|
9
|
+
/** libSQL's built-in vector functions; no `inner` (only the Rust engine has it) and no `l1`. */
|
|
17
10
|
vectorMetrics = new Map([
|
|
18
11
|
['cosine', { fn: 'vector_distance_cos' }],
|
|
19
12
|
['l2', { fn: 'vector_distance_l2' }],
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { type RelationRows } from '../dialect/abstractSqlDialect.js';
|
|
2
2
|
import { MysqlLikeSqlDialect } from '../dialect/mysqlLikeSqlDialect.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { EntityMeta, FieldOptions, Query, QueryContext, SqlDialectFeatures, Type, VectorDistance, VectorMetric } from '../type/index.js';
|
|
4
4
|
export declare class MariaDialect extends MysqlLikeSqlDialect {
|
|
5
5
|
readonly dialectName = "mariadb";
|
|
6
6
|
readonly insertIdSource = "returning";
|
|
7
|
-
/** MariaDB has no `FOR ... OF`, so a lock cannot be narrowed to one table of a join. */
|
|
8
|
-
readonly supportsLockOf = false;
|
|
9
7
|
/**
|
|
10
8
|
* Unlike MySQL: `VECTOR(n)` takes its dimension, every column of a vector index has to be NOT NULL,
|
|
11
|
-
*
|
|
9
|
+
* `CREATE INDEX` takes `IF NOT EXISTS`, and a lock cannot be narrowed to one table of a join.
|
|
12
10
|
*/
|
|
13
|
-
|
|
11
|
+
readonly features: SqlDialectFeatures;
|
|
14
12
|
/**
|
|
15
13
|
* A derived table here reads no column of the statement around it, so the aggregate reads the
|
|
16
14
|
* related table itself, and orders and pages inside `JSON_ARRAYAGG`, which takes both.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { relationTermKey } from '../dialect/abstractSqlDialect.js';
|
|
2
2
|
import { jsonPath } from '../dialect/jsonSql.js';
|
|
3
|
-
import { MysqlLikeSqlDialect } from '../dialect/mysqlLikeSqlDialect.js';
|
|
3
|
+
import { MYSQL_FEATURES, MysqlLikeSqlDialect } from '../dialect/mysqlLikeSqlDialect.js';
|
|
4
4
|
import { getMeta } from '../entity/index.js';
|
|
5
5
|
import { columnFamily } from '../util/field.util.js';
|
|
6
6
|
import { MARIA_VECTOR_METRICS } from './mariaVectorMetrics.js';
|
|
@@ -8,16 +8,16 @@ export class MariaDialect extends MysqlLikeSqlDialect {
|
|
|
8
8
|
dialectName = 'mariadb';
|
|
9
9
|
// MariaDB 10.5+ has `INSERT ... RETURNING`, so ids come back exact per row - the upsert's too.
|
|
10
10
|
insertIdSource = 'returning';
|
|
11
|
-
/** MariaDB has no `FOR ... OF`, so a lock cannot be narrowed to one table of a join. */
|
|
12
|
-
supportsLockOf = false;
|
|
13
11
|
/**
|
|
14
12
|
* Unlike MySQL: `VECTOR(n)` takes its dimension, every column of a vector index has to be NOT NULL,
|
|
15
|
-
*
|
|
13
|
+
* `CREATE INDEX` takes `IF NOT EXISTS`, and a lock cannot be narrowed to one table of a join.
|
|
16
14
|
*/
|
|
17
|
-
|
|
15
|
+
features = {
|
|
16
|
+
...MYSQL_FEATURES,
|
|
18
17
|
vectorSupportsLength: true,
|
|
19
18
|
vectorIndexRequiresNotNull: true,
|
|
20
19
|
indexIfNotExists: true,
|
|
20
|
+
rowLockOf: false,
|
|
21
21
|
};
|
|
22
22
|
/**
|
|
23
23
|
* A derived table here reads no column of the statement around it, so the aggregate reads the
|
|
@@ -7,8 +7,8 @@ export class MariadbQuerier extends AbstractPoolQuerier {
|
|
|
7
7
|
}
|
|
8
8
|
async internalRun(query, values) {
|
|
9
9
|
const res = await this.getConn().query(query, values);
|
|
10
|
-
//
|
|
11
|
-
const changes = res.affectedRows ?? res.length
|
|
10
|
+
// An OK packet reports `affectedRows`; a `RETURNING` statement answers rows instead, and counts by them.
|
|
11
|
+
const changes = res.affectedRows ?? res.length;
|
|
12
12
|
const rows = res.length ? Array.from(res, decodeBigInts) : [];
|
|
13
13
|
return this.buildUpdateResult({ rows, changes, upsertStatus: res.affectedRows });
|
|
14
14
|
}
|
|
@@ -11,12 +11,7 @@ export class MariadbQuerierPool extends AbstractSqlQuerierPool {
|
|
|
11
11
|
// BIGINT stays the driver's `bigint`, which `MariadbQuerier` decodes by the rule every driver here
|
|
12
12
|
// shares (`decodeWideNumber`) - not `bigIntAsNumber`, which rounds past 2^53 without a word.
|
|
13
13
|
this.pool = createPool(opts);
|
|
14
|
-
// `mariadb`'
|
|
15
|
-
// listener (so a dropped connection can't crash the process), but its
|
|
16
|
-
// `Pool` type only declares `on` for 'acquire' | 'connection' | 'enqueue'
|
|
17
|
-
// | 'release' - 'error' genuinely fires at runtime (see `lib/pool.js`)
|
|
18
|
-
// but isn't in the declaration, hence the cast. Re-attaching our own
|
|
19
|
-
// listener here just makes the error visible instead of a silent no-op.
|
|
14
|
+
// `mariadb` fires 'error' at runtime without declaring it, hence the cast; this makes it visible.
|
|
20
15
|
attachPoolErrorHandler(this.pool, 'Idle MariaDB pool connection encountered an error', extra?.logger);
|
|
21
16
|
}
|
|
22
17
|
async getQuerier() {
|
|
@@ -20,13 +20,7 @@ function createIndexOperation(tableName, columns, options = {}) {
|
|
|
20
20
|
},
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
|
-
/**
|
|
24
|
-
* The one shape of an `addForeignKey` operation, `NO ACTION` defaults included.
|
|
25
|
-
*
|
|
26
|
-
* Three callers build it and differ only in what they do with the result: the table builder records
|
|
27
|
-
* it through its parent, the recorder records it directly, and the executing builder also runs it.
|
|
28
|
-
* Spelled out three times, a changed default would have had to be found in all three.
|
|
29
|
-
*/
|
|
23
|
+
/** An `addForeignKey` operation, `NO ACTION` defaults included, for the three builders that record one. */
|
|
30
24
|
function addForeignKeyOperation(tableName, columns, target, options = {}) {
|
|
31
25
|
return {
|
|
32
26
|
type: 'addForeignKey',
|
|
@@ -40,21 +34,11 @@ function addForeignKeyOperation(tableName, columns, target, options = {}) {
|
|
|
40
34
|
},
|
|
41
35
|
};
|
|
42
36
|
}
|
|
43
|
-
/**
|
|
44
|
-
* Declare one column through the same vocabulary `createTable` uses. A throwaway {@link TableBuilder}
|
|
45
|
-
* is that vocabulary: `addColumn`/`alterColumn` used to take a bare {@link IColumnBuilder}, which
|
|
46
|
-
* cannot express a type, so every column they recorded was hard-coded `VARCHAR`.
|
|
47
|
-
*/
|
|
37
|
+
/** One column declared through `createTable`'s vocabulary, a throwaway {@link TableBuilder}, so its type is stated. */
|
|
48
38
|
function buildOneColumn(callback) {
|
|
49
39
|
return callback(new TableBuilder('')).build();
|
|
50
40
|
}
|
|
51
|
-
/**
|
|
52
|
-
* Collects the operations one `alterTable` callback declares, in the order it declared them.
|
|
53
|
-
*
|
|
54
|
-
* Collected rather than dispatched to the parent as they are made: the chaining methods are
|
|
55
|
-
* synchronous by contract, so a builder that executes could only fire and forget, which returned from
|
|
56
|
-
* `alterTable` with the statements still in flight and turned a failure into an unhandled rejection.
|
|
57
|
-
*/
|
|
41
|
+
/** The operations one `alterTable` callback declares, collected in order, since its methods are synchronous. */
|
|
58
42
|
class AlterTableBuilder {
|
|
59
43
|
tableName;
|
|
60
44
|
operations = [];
|
|
@@ -1,15 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Splits a SQL blob on semicolons into separate statements.
|
|
3
|
-
*
|
|
4
|
-
* Uses a declarative Master-Regex scanner to rapidly
|
|
5
|
-
* identify and skip "non-splittable" blocks (strings, comments, dollar-quotes) in a single pass.
|
|
6
|
-
* This approach is $O(n)$, leverages native regex speed, and is trivially easy to audit.
|
|
7
|
-
*
|
|
8
|
-
* Handles:
|
|
9
|
-
* - Single quotes: '...' (standard SQL, respects '' and \')
|
|
10
|
-
* - Double quotes: "..." (identifiers or MySQL strings)
|
|
11
|
-
* - Backticks: `...` (MySQL identifiers)
|
|
12
|
-
* - Postgres Dollar quotes: $tag$...$tag$ or $$...$$
|
|
13
|
-
* - Comments: -- and /* ... *\/
|
|
14
|
-
*/
|
|
1
|
+
/** Splits SQL on semicolons, skipping strings, quoted identifiers, dollar-quoted blocks and comments in one regex pass. */
|
|
15
2
|
export declare function splitSqlStatements(sql: string): string[];
|
|
@@ -1,28 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Splits a SQL blob on semicolons into separate statements.
|
|
3
|
-
*
|
|
4
|
-
* Uses a declarative Master-Regex scanner to rapidly
|
|
5
|
-
* identify and skip "non-splittable" blocks (strings, comments, dollar-quotes) in a single pass.
|
|
6
|
-
* This approach is $O(n)$, leverages native regex speed, and is trivially easy to audit.
|
|
7
|
-
*
|
|
8
|
-
* Handles:
|
|
9
|
-
* - Single quotes: '...' (standard SQL, respects '' and \')
|
|
10
|
-
* - Double quotes: "..." (identifiers or MySQL strings)
|
|
11
|
-
* - Backticks: `...` (MySQL identifiers)
|
|
12
|
-
* - Postgres Dollar quotes: $tag$...$tag$ or $$...$$
|
|
13
|
-
* - Comments: -- and /* ... *\/
|
|
14
|
-
*/
|
|
1
|
+
/** Splits SQL on semicolons, skipping strings, quoted identifiers, dollar-quoted blocks and comments in one regex pass. */
|
|
15
2
|
export function splitSqlStatements(sql) {
|
|
16
3
|
const statements = [];
|
|
17
4
|
let lastIndex = 0;
|
|
18
|
-
//
|
|
19
|
-
// 1. Single quoted strings: '(?:''|\\['\\]|[^'])*(?:'|(?=$))
|
|
20
|
-
// 2. Double quoted identifiers: "(?:""|\\["\\]|[^"])*(?:"|(?=$))
|
|
21
|
-
// 3. Backticked identifiers: `(?:``|\\[`\\]|[^`])*(?:`|(?=$))
|
|
22
|
-
// 4. Postgres Dollar quoted blocks: \$(?<tag>[a-zA-Z0-9_]*)\$[\s\S]*?(?:\$\k<tag>|(?=$))
|
|
23
|
-
// 5. Single-line comments: --.*
|
|
24
|
-
// 6. Multi-line comments: \/\*[\s\S]*?(?:\*\/|(?=$))
|
|
25
|
-
// 7. Statement terminator: ;
|
|
5
|
+
// Quoted strings and identifiers, dollar quotes, comments, or a `;`: the one regex scanning them all.
|
|
26
6
|
const masterRegex = /'(?:''|\\['\\]|[^'])*(?:'|(?=$))|"(?:""|\\["\\]|[^"])*(?:"|(?=$))|`(?:``|\\[`\\]|[^`])*(?:`|(?=$))|\$(?<tag>[a-zA-Z0-9_]*)\$[\s\S]*?(?:\$\k<tag>|(?=$))|--.*|\/\*[\s\S]*?(?:\*\/|(?=$))|;/g;
|
|
27
7
|
for (const match of sql.matchAll(masterRegex)) {
|
|
28
8
|
if (match[0] === ';') {
|
|
@@ -67,14 +67,7 @@ export interface VectorColumnOptions extends BaseColumnOptions {
|
|
|
67
67
|
/** Number of dimensions */
|
|
68
68
|
dimensions?: number;
|
|
69
69
|
}
|
|
70
|
-
/**
|
|
71
|
-
* A column as the builder describes one: {@link ColumnNode} without the graph links a DTO cannot carry.
|
|
72
|
-
*
|
|
73
|
-
* Derived rather than restated, so the two cannot drift. A column gained `enum` and this shape was
|
|
74
|
-
* simply missing it, which is why a hand-written `createTable` could never constrain one. A field
|
|
75
|
-
* added to the node now reaches here, and failing to render it is a compile error rather than a
|
|
76
|
-
* column that quietly loses half its declaration.
|
|
77
|
-
*/
|
|
70
|
+
/** A column as the builder describes one: a {@link ColumnNode} without its graph links. */
|
|
78
71
|
export type ColumnDefinition = Omit<ColumnNode, 'table' | 'referencedBy' | 'references'>;
|
|
79
72
|
/**
|
|
80
73
|
* The foreign key a single column declares: {@link ForeignKeySchema} without the local columns, which
|
|
@@ -260,13 +253,7 @@ export interface IForeignKeyBuilder extends IColumnBuilder {
|
|
|
260
253
|
/** Set ON UPDATE action */
|
|
261
254
|
onUpdate(action: ForeignKeyAction): this;
|
|
262
255
|
}
|
|
263
|
-
/**
|
|
264
|
-
* The column vocabulary: every column type the builder can declare, name first.
|
|
265
|
-
*
|
|
266
|
-
* Split out of {@link ITableBuilder} so `addColumn`/`alterColumn` can hand it to their callback. They
|
|
267
|
-
* used to take an {@link IColumnBuilder}, which has no way to say what type a column is - so the
|
|
268
|
-
* builder hard-coded `VARCHAR`, and every column a generated migration added or altered was a string.
|
|
269
|
-
*/
|
|
256
|
+
/** Every column type the builder can declare, name first, handed to `addColumn`/`alterColumn` callbacks too. */
|
|
270
257
|
export interface IColumnFactory {
|
|
271
258
|
/** Add an auto-incrementing primary key */
|
|
272
259
|
id(name?: string, options?: BaseColumnOptions): IColumnBuilder;
|
|
@@ -2,17 +2,8 @@ import { stat } from 'node:fs/promises';
|
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
4
|
/**
|
|
5
|
-
* Loads the config with a plain `import()`, leaving TypeScript to
|
|
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.
|
|
5
|
+
* Loads the config with a plain `import()`, leaving TypeScript to the runtime: uql bundles no transpiler,
|
|
6
|
+
* since only the project knows its decorator spec. Node's type stripping handles no decorators.
|
|
16
7
|
*/
|
|
17
8
|
async function importConfig(path) {
|
|
18
9
|
const mod = (await import(pathToFileURL(path).href).catch((cause) => {
|
package/dist/migrate/cli.js
CHANGED
|
@@ -76,11 +76,7 @@ export async function main(args = process.argv.slice(2)) {
|
|
|
76
76
|
printHelp();
|
|
77
77
|
process.exit(1);
|
|
78
78
|
}
|
|
79
|
-
|
|
80
|
-
const pool = config.pool;
|
|
81
|
-
if (pool.end) {
|
|
82
|
-
await pool.end();
|
|
83
|
-
}
|
|
79
|
+
await config.pool.end();
|
|
84
80
|
}
|
|
85
81
|
catch (error) {
|
|
86
82
|
console.error('Error:', error.message);
|
|
@@ -202,8 +198,7 @@ export async function runSync(migrator, args, config) {
|
|
|
202
198
|
const force = args.includes('--force');
|
|
203
199
|
const safe = !args.includes('--unsafe');
|
|
204
200
|
const options = { force, safe, drop: !safe };
|
|
205
|
-
// Ahead of the warning
|
|
206
|
-
// asked for, and it used to be ignored beside `--force`.
|
|
201
|
+
// Ahead of the warning and the run: `--dry-run` means the same whatever else was asked for, `--force` included.
|
|
207
202
|
if (args.includes('--dry-run')) {
|
|
208
203
|
const statements = await migrator.planSync(options);
|
|
209
204
|
console.log(statements.length ? `\n${statements.join('\n')}` : '\nSchema is already in sync.');
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Entity Code Generator
|
|
3
|
-
*
|
|
4
|
-
* Generates TypeScript entity files from SchemaAST.
|
|
5
|
-
* Supports:
|
|
6
|
-
* - ES Module syntax
|
|
7
|
-
* - TypeScript types
|
|
8
|
-
* - Relations with proper decorators
|
|
9
|
-
* - Indexes
|
|
10
|
-
* - JSDoc comments for sync-added fields
|
|
11
|
-
*/
|
|
12
1
|
import type { SchemaAST } from '../../schema/schemaAST.js';
|
|
13
2
|
/**
|
|
14
3
|
* Options for entity code generation.
|
|
@@ -107,10 +96,6 @@ export declare class EntityCodeGenerator {
|
|
|
107
96
|
* Build incoming relation (OneToMany where other tables have FK to this).
|
|
108
97
|
*/
|
|
109
98
|
private buildIncomingRelation;
|
|
110
|
-
/**
|
|
111
|
-
* Get decorator name for relation type.
|
|
112
|
-
*/
|
|
113
|
-
private getRelationDecoratorName;
|
|
114
99
|
/**
|
|
115
100
|
* Format type for description.
|
|
116
101
|
*/
|
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Entity Code Generator
|
|
3
|
-
*
|
|
4
|
-
* Generates TypeScript entity files from SchemaAST.
|
|
5
|
-
* Supports:
|
|
6
|
-
* - ES Module syntax
|
|
7
|
-
* - TypeScript types
|
|
8
|
-
* - Relations with proper decorators
|
|
9
|
-
* - Indexes
|
|
10
|
-
* - JSDoc comments for sync-added fields
|
|
11
|
-
*/
|
|
12
1
|
import { canonicalToTypeScript } from '../../schema/canonicalType.js';
|
|
13
2
|
import { DEFAULT_FOREIGN_KEY_ACTION, } from '../../schema/types.js';
|
|
14
3
|
import { camelCase, lowerFirst, pascalCase, singularize } from '../../util/string.util.js';
|
|
15
4
|
import { buildFieldOptionsSource, fieldNeedsRaw } from './fieldOptionsSource.js';
|
|
16
5
|
import { buildIndexDecoratorSource, indexNeedsRaw, isPlainFieldIndex } from './indexDecoratorSource.js';
|
|
17
6
|
import { memberSource } from './sourceLiteral.js';
|
|
7
|
+
/** The decorator on the other side of a relation. */
|
|
8
|
+
const INVERSE_RELATION = {
|
|
9
|
+
OneToOne: 'OneToOne',
|
|
10
|
+
OneToMany: 'ManyToOne',
|
|
11
|
+
ManyToOne: 'OneToMany',
|
|
12
|
+
ManyToMany: 'ManyToMany',
|
|
13
|
+
};
|
|
18
14
|
/**
|
|
19
15
|
* Generates TypeScript entity code from SchemaAST.
|
|
20
16
|
*/
|
|
@@ -87,7 +83,7 @@ export class EntityCodeGenerator {
|
|
|
87
83
|
// Check for relation decorators
|
|
88
84
|
if (this.options.includeRelations) {
|
|
89
85
|
for (const rel of [...table.incomingRelations, ...table.outgoingRelations]) {
|
|
90
|
-
uqlImports.add(
|
|
86
|
+
uqlImports.add(rel.type);
|
|
91
87
|
const relatedTable = rel.from.table === table ? rel.to.table : rel.from.table;
|
|
92
88
|
const relatedClassName = this.options.classNameTransformer(relatedTable.name);
|
|
93
89
|
if (!relatedImports.includes(relatedClassName)) {
|
|
@@ -175,7 +171,7 @@ export class EntityCodeGenerator {
|
|
|
175
171
|
* Build Field decorator options.
|
|
176
172
|
*/
|
|
177
173
|
buildFieldOptions(col, propertyName) {
|
|
178
|
-
const indexes = this.options.includeIndexes ?
|
|
174
|
+
const indexes = this.options.includeIndexes ? col.table.indexes : [];
|
|
179
175
|
const fieldIndex = indexes.find((idx) => isPlainFieldIndex(idx) && idx.entries[0]?.column === col.name);
|
|
180
176
|
return buildFieldOptionsSource(col, propertyName, fieldIndex?.name);
|
|
181
177
|
}
|
|
@@ -184,7 +180,7 @@ export class EntityCodeGenerator {
|
|
|
184
180
|
* carry on its own.
|
|
185
181
|
*/
|
|
186
182
|
declaredIndexes(table) {
|
|
187
|
-
return
|
|
183
|
+
return table.indexes.filter((index) => !isPlainFieldIndex(index));
|
|
188
184
|
}
|
|
189
185
|
/**
|
|
190
186
|
* Build relation definitions.
|
|
@@ -222,15 +218,11 @@ export class EntityCodeGenerator {
|
|
|
222
218
|
else {
|
|
223
219
|
propertyName = this.options.propertyNameTransformer(this.options.singularize(rel.to.table.name));
|
|
224
220
|
}
|
|
225
|
-
const decoratorName = this.getRelationDecoratorName(rel.type);
|
|
226
221
|
// JSDoc
|
|
227
222
|
if (this.options.addSyncComments) {
|
|
228
223
|
lines.push(' /**');
|
|
229
224
|
lines.push(` * @sync-added ${new Date().toISOString().split('T')[0]}`);
|
|
230
225
|
lines.push(` * Relation to ${rel.to.table.name} via ${rel.from.columns.map((c) => c.name).join(', ')}`);
|
|
231
|
-
if (rel.confidence !== undefined && rel.confidence < 1.0) {
|
|
232
|
-
lines.push(` * Inferred (${(rel.confidence * 100).toFixed(0)}% confidence)`);
|
|
233
|
-
}
|
|
234
226
|
lines.push(' */');
|
|
235
227
|
}
|
|
236
228
|
// Decorator. `onDelete`/`onUpdate` only when introspection found a real referential action, so a
|
|
@@ -243,7 +235,7 @@ export class EntityCodeGenerator {
|
|
|
243
235
|
options.push(`onDelete: '${rel.onDelete}'`);
|
|
244
236
|
if (rel.onUpdate && rel.onUpdate !== DEFAULT_FOREIGN_KEY_ACTION)
|
|
245
237
|
options.push(`onUpdate: '${rel.onUpdate}'`);
|
|
246
|
-
lines.push(` @${
|
|
238
|
+
lines.push(` @${rel.type}({ ${options.join(', ')} })`);
|
|
247
239
|
// Property
|
|
248
240
|
lines.push(` ${propertyName}?: ${relatedClassName};`);
|
|
249
241
|
return lines.join('\n');
|
|
@@ -274,8 +266,6 @@ export class EntityCodeGenerator {
|
|
|
274
266
|
const lines = [];
|
|
275
267
|
const relatedClassName = this.options.classNameTransformer(rel.from.table.name);
|
|
276
268
|
const propertyName = this.options.propertyNameTransformer(rel.from.table.name);
|
|
277
|
-
const inverseType = this.ast.getInverseRelationType(rel.type);
|
|
278
|
-
const decoratorName = this.getRelationDecoratorName(inverseType);
|
|
279
269
|
// JSDoc
|
|
280
270
|
if (this.options.addSyncComments) {
|
|
281
271
|
lines.push(' /**');
|
|
@@ -286,31 +276,12 @@ export class EntityCodeGenerator {
|
|
|
286
276
|
// The inverse side, mapped by the related class's property that points back at this one.
|
|
287
277
|
const param = lowerFirst(relatedClassName);
|
|
288
278
|
const inverse = memberSource(param, this.options.propertyNameTransformer(this.options.singularize(table.name)));
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
294
|
-
else {
|
|
295
|
-
lines.push(` ${propertyName}?: ${relatedClassName};`);
|
|
296
|
-
}
|
|
279
|
+
const inverseType = INVERSE_RELATION[rel.type];
|
|
280
|
+
lines.push(` @${inverseType}({ entity: () => ${relatedClassName}, mappedBy: (${param}) => ${inverse} })`);
|
|
281
|
+
const many = inverseType === 'OneToMany' || inverseType === 'ManyToMany';
|
|
282
|
+
lines.push(` ${propertyName}?: ${relatedClassName}${many ? '[]' : ''};`);
|
|
297
283
|
return lines.join('\n');
|
|
298
284
|
}
|
|
299
|
-
/**
|
|
300
|
-
* Get decorator name for relation type.
|
|
301
|
-
*/
|
|
302
|
-
getRelationDecoratorName(type) {
|
|
303
|
-
switch (type) {
|
|
304
|
-
case 'OneToOne':
|
|
305
|
-
return 'OneToOne';
|
|
306
|
-
case 'OneToMany':
|
|
307
|
-
return 'OneToMany';
|
|
308
|
-
case 'ManyToOne':
|
|
309
|
-
return 'ManyToOne';
|
|
310
|
-
case 'ManyToMany':
|
|
311
|
-
return 'ManyToMany';
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
285
|
/**
|
|
315
286
|
* Format type for description.
|
|
316
287
|
*/
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
import type { ColumnNode } from '../../schema/types.js';
|
|
2
|
-
/**
|
|
3
|
-
* A column's `@Field({ ... })` options as source, or `''` when it needs none.
|
|
4
|
-
*
|
|
5
|
-
* Shared by the entity generator and the merger because they emit the same decorator. They each had
|
|
6
|
-
* their own copy, and the copies had drifted: the merger's dropped `unique` and `defaultValue`, so
|
|
7
|
-
* merging a column into an existing entity file quietly produced a weaker field than generating the
|
|
8
|
-
* file from scratch.
|
|
9
|
-
*/
|
|
2
|
+
/** A column's `@Field({ ... })` options as source, `''` where it needs none: shared by the generator and the merger. */
|
|
10
3
|
export declare function buildFieldOptionsSource(col: ColumnNode, propertyName: string, indexName?: string): string;
|
|
11
4
|
/** Whether the field's decorator needs `raw` imported, the way {@link indexNeedsRaw} does for an index. */
|
|
12
5
|
export declare function fieldNeedsRaw(col: ColumnNode): boolean;
|
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
import { canonicalToColumnType } from '../../schema/canonicalType.js';
|
|
2
2
|
import { quoted, rawTag } from './sourceLiteral.js';
|
|
3
|
-
/**
|
|
4
|
-
* What each field of a {@link ColumnNode} contributes to `@Field({ ... })`, in emit order, and `null`
|
|
5
|
-
* where nothing does.
|
|
6
|
-
*
|
|
7
|
-
* The `satisfies` is the point: a field the node gains cannot reach here without someone answering
|
|
8
|
-
* whether an entity generated from a database keeps it. Written as a hand-rolled `if` chain, this had
|
|
9
|
-
* already dropped `comment` - introspection reads one on Postgres and MySQL, and regenerating an
|
|
10
|
-
* entity threw it away.
|
|
11
|
-
*/
|
|
3
|
+
/** What each field of a {@link ColumnNode} contributes to `@Field({ ... })`, in emit order; `satisfies` makes a new field answer. */
|
|
12
4
|
const OPTION_SOURCE = {
|
|
13
5
|
// Without this the entity maps to a column named after the property, which for anything the
|
|
14
6
|
// transformer rewrote - every `user_id` - is a column the database does not have.
|
|
@@ -36,14 +28,7 @@ const OPTION_SOURCE = {
|
|
|
36
28
|
references: null,
|
|
37
29
|
referencedBy: null,
|
|
38
30
|
};
|
|
39
|
-
/**
|
|
40
|
-
* A column's `@Field({ ... })` options as source, or `''` when it needs none.
|
|
41
|
-
*
|
|
42
|
-
* Shared by the entity generator and the merger because they emit the same decorator. They each had
|
|
43
|
-
* their own copy, and the copies had drifted: the merger's dropped `unique` and `defaultValue`, so
|
|
44
|
-
* merging a column into an existing entity file quietly produced a weaker field than generating the
|
|
45
|
-
* file from scratch.
|
|
46
|
-
*/
|
|
31
|
+
/** A column's `@Field({ ... })` options as source, `''` where it needs none: shared by the generator and the merger. */
|
|
47
32
|
export function buildFieldOptionsSource(col, propertyName, indexName) {
|
|
48
33
|
const context = { propertyName, indexName };
|
|
49
34
|
const options = [
|
|
@@ -57,11 +42,7 @@ export function buildFieldOptionsSource(col, propertyName, indexName) {
|
|
|
57
42
|
export function fieldNeedsRaw(col) {
|
|
58
43
|
return col.generatedAs !== undefined;
|
|
59
44
|
}
|
|
60
|
-
/**
|
|
61
|
-
* A default value as source. Strings stay single-quoted, expressions included: `defaultValue: 'now()'`
|
|
62
|
-
* is what reaches the DDL. The generator used to branch on `CURRENT_TIMESTAMP`/`NEXTVAL`/`(` first, but
|
|
63
|
-
* both branches emitted a quoted string and only the fallthrough escaped embedded quotes.
|
|
64
|
-
*/
|
|
45
|
+
/** A default value as source, a string single-quoted and escaped, an expression included: `defaultValue: 'now()'`. */
|
|
65
46
|
function defaultValueSource(value) {
|
|
66
47
|
if (typeof value === 'string') {
|
|
67
48
|
return quoted(value);
|
|
@@ -6,11 +6,8 @@ export declare function assertIndexType(index: IndexSchema, types: ReadonlySet<I
|
|
|
6
6
|
/** Refuses an index asking for a feature `features` lacks. */
|
|
7
7
|
export declare function assertIndexFeatures(index: IndexSchema, features: ReadonlySet<IndexFeature>, dialectName: string): void;
|
|
8
8
|
/**
|
|
9
|
-
* `CREATE INDEX`
|
|
10
|
-
* The migrator's
|
|
11
|
-
* emits DDL - which is what keeps a `CAST(... ARRAY)` table out of every runtime consumer's entry.
|
|
12
|
-
* The form here is the portable one, which SQLite (and so libSQL, Turso and D1) takes verbatim: no
|
|
13
|
-
* access-method clause, no operator classes, no tuning parameters.
|
|
9
|
+
* `CREATE INDEX` in its portable form, which the SQLite family takes as is; the engines with more override
|
|
10
|
+
* the fragments. The migrator's own, so no runtime entry carries it.
|
|
14
11
|
*/
|
|
15
12
|
export declare class IndexDdl<D extends AbstractSqlDialect = AbstractSqlDialect> {
|
|
16
13
|
protected readonly dialect: D;
|
|
@@ -32,11 +32,8 @@ export function assertIndexFeatures(index, features, dialectName) {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
-
* `CREATE INDEX`
|
|
36
|
-
* The migrator's
|
|
37
|
-
* emits DDL - which is what keeps a `CAST(... ARRAY)` table out of every runtime consumer's entry.
|
|
38
|
-
* The form here is the portable one, which SQLite (and so libSQL, Turso and D1) takes verbatim: no
|
|
39
|
-
* access-method clause, no operator classes, no tuning parameters.
|
|
35
|
+
* `CREATE INDEX` in its portable form, which the SQLite family takes as is; the engines with more override
|
|
36
|
+
* the fragments. The migrator's own, so no runtime entry carries it.
|
|
40
37
|
*/
|
|
41
38
|
export class IndexDdl {
|
|
42
39
|
dialect;
|