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
package/dist/type/entity.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { EnumValues, ForeignKeyAction, IndexType } from '../schema/types.js';
|
|
2
2
|
import type { FilterOptions } from './query.js';
|
|
3
|
-
import type { QueryRaw } from './queryRaw.js';
|
|
3
|
+
import type { ColumnRef, QueryRaw } from './queryRaw.js';
|
|
4
4
|
import type { QueryWhere } from './queryWhere.js';
|
|
5
5
|
import type { Except, IsMany, Json, Scalar, Type, Unpacked } from './utility.js';
|
|
6
6
|
import type { VectorDistance, VectorIndexOptions, VectorIndexType } from './vector.js';
|
|
@@ -595,14 +595,6 @@ type RelationOptionsThroughOwner<E, O> = Pick<RelationOptions<E, O>, 'entity' |
|
|
|
595
595
|
export type KeyMap<E> = {
|
|
596
596
|
readonly [K in keyof E]-?: K;
|
|
597
597
|
};
|
|
598
|
-
declare const COLUMN_KEY: unique symbol;
|
|
599
|
-
/**
|
|
600
|
-
* A field of an entity as SQL, read off a {@link RefMap}: interpolated into `raw`, it renders as that
|
|
601
|
-
* field's column. A `QueryRaw` like any other fragment, branded with the field `K` it names.
|
|
602
|
-
*/
|
|
603
|
-
export type ColumnRef<K extends string = string> = QueryRaw & {
|
|
604
|
-
readonly [COLUMN_KEY]?: K;
|
|
605
|
-
};
|
|
606
598
|
/**
|
|
607
599
|
* The fields of `E` as {@link ColumnRef}s, for SQL that names them: `refs(User)` in a statement, the
|
|
608
600
|
* callback's parameter in a definition. Keyed over a type parameter constrained to `keyof E`, as
|
|
@@ -612,15 +604,13 @@ export type RefMap<E, F extends keyof E = FieldKey<E>> = {
|
|
|
612
604
|
readonly [K in F]-?: ColumnRef<K & string>;
|
|
613
605
|
};
|
|
614
606
|
/**
|
|
615
|
-
*
|
|
616
|
-
* method, bivariant in its refs, so one typed for its entity still fits where the entity is
|
|
617
|
-
* registry, which resolves it.
|
|
607
|
+
* SQL a definition writes: `raw`, or a callback reading the entity's fields off its refs. The callback is
|
|
608
|
+
* declared as a method, bivariant in its refs, so one typed for its entity still fits where the entity is
|
|
609
|
+
* erased: the registry, which resolves it.
|
|
618
610
|
*/
|
|
619
|
-
export type
|
|
620
|
-
sql(
|
|
611
|
+
export type EntitySql<E> = QueryRaw | {
|
|
612
|
+
sql(refs: RefMap<E>): QueryRaw;
|
|
621
613
|
}['sql'];
|
|
622
|
-
/** SQL a definition writes: `raw`, or a {@link SqlCallback} for SQL that names the entity's fields. */
|
|
623
|
-
export type EntitySql<E> = QueryRaw | SqlCallback<E>;
|
|
624
614
|
/**
|
|
625
615
|
* A predicate DDL carries, over the entity's own fields: a relation, full-text search and a sub-query
|
|
626
616
|
* have nothing a `CHECK` or a partial index can hold. An intersection rather than `Except`, which would
|
|
@@ -677,41 +667,24 @@ export type IndexTypeOptions = {
|
|
|
677
667
|
distance?: never;
|
|
678
668
|
};
|
|
679
669
|
/**
|
|
680
|
-
* One entry
|
|
681
|
-
* when the entry needs more
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
*
|
|
686
|
-
*
|
|
687
|
-
* @Index((post) => [{ column: post.
|
|
688
|
-
* @Index((post) => [post.data], { type: 'gin' }) // JSONB containment
|
|
689
|
-
* ```
|
|
690
|
-
*
|
|
691
|
-
* `C` is the entity's `FieldKey` on the `@Index`/`defineEntity` paths, where the decorated class says
|
|
692
|
-
* which columns exist, and `E` the entity itself, which is what checks a JSON entry's path. Both
|
|
693
|
-
* default to the unchecked form for the migration builder's `table.index(...)`, which names raw
|
|
694
|
-
* table columns with no entity in scope.
|
|
695
|
-
*/
|
|
696
|
-
export type IndexColumnInput<C extends string = string, E = unknown> = C | SqlCallback<E> | IndexColumnOptions<C, E> | IndexJsonColumnOptions<C, E>;
|
|
697
|
-
/**
|
|
698
|
-
* The JSON entries, whose `path` is checked against the payload of the column the same entry names -
|
|
699
|
-
* a mapped union, one arm per JSON field, so `{ column: 'kind', jsonPath: { path: 'thema.color' } }`
|
|
700
|
-
* cannot compile. It matters more here than anywhere else in the index API: a path that is merely
|
|
701
|
-
* *misspelled* still builds a perfectly valid index, one no query will ever match, and nothing at
|
|
702
|
-
* runtime can tell that from the index you meant.
|
|
703
|
-
*
|
|
704
|
-
* `jsonArray`'s path is the array's own, so on a column that *is* the array (`Json<string[]>`) it
|
|
705
|
-
* resolves to `never` and the property can only be omitted, which is exactly the truth.
|
|
706
|
-
*
|
|
707
|
-
* Falls back to the unchecked shape only where there is no entity to check against - the migration
|
|
708
|
-
* builder. An entity with no JSON field at all offers no arm, which is also the truth.
|
|
670
|
+
* One index entry as the migration builder takes it: a column name, `raw` for an expression, or an object
|
|
671
|
+
* when the entry needs more. An entity's entries are this too, which is what `normalizeIndexColumn` reads.
|
|
672
|
+
*/
|
|
673
|
+
export type IndexColumnInput = string | QueryRaw | EntityIndexColumn;
|
|
674
|
+
/**
|
|
675
|
+
* One entry of an entity's index, read off its refs: a column, `raw` for an expression, or an object when
|
|
676
|
+
* the entry needs more, a JSON entry's path checked against its column.
|
|
677
|
+
* @example `@Index((post) => [post.tenantId, { column: post.createdAt, order: 'desc' }, raw`lower(${post.email})`])`
|
|
709
678
|
*/
|
|
710
|
-
type
|
|
711
|
-
|
|
712
|
-
|
|
679
|
+
export type EntityIndexColumnInput<E> = QueryRaw | IndexColumnOptions | IndexJsonColumnOptions<E>;
|
|
680
|
+
/**
|
|
681
|
+
* The JSON entries, one arm per JSON field, each `path` checked against the payload of the column its own
|
|
682
|
+
* entry names: a misspelled path still builds a valid index that no query matches. On a column that is
|
|
683
|
+
* the array (`Json<string[]>`), `jsonArray`'s path resolves to `never`, so it can only be omitted.
|
|
684
|
+
*/
|
|
685
|
+
type IndexJsonColumnOptions<E> = {
|
|
713
686
|
[K in JsonColumnKey<E>]: IndexColumnPlainModifiers & {
|
|
714
|
-
readonly column: K
|
|
687
|
+
readonly column: ColumnRef<K & string>;
|
|
715
688
|
} & ({
|
|
716
689
|
readonly jsonPath: WithCheckedPath<IndexJsonPath, E, K>;
|
|
717
690
|
readonly jsonArray?: never;
|
|
@@ -727,7 +700,7 @@ type IndexJsonColumnOptions<C extends string, E> = unknown extends E ? IndexColu
|
|
|
727
700
|
* subject is that column.
|
|
728
701
|
*/
|
|
729
702
|
type JsonColumnKey<E> = {
|
|
730
|
-
readonly [K in keyof E]-?:
|
|
703
|
+
readonly [K in keyof E]-?: IsJsonColumn<NonNullable<E[K]>> extends true ? K : never;
|
|
731
704
|
}[Key<E>];
|
|
732
705
|
/** The payload a path is checked against: the column's own brand, or that of the documents it holds. */
|
|
733
706
|
type JsonColumnPayload<V> = IsJson<NonNullable<V>> extends true ? UnwrapJson<NonNullable<V>> : JsonPayload<V>;
|
|
@@ -807,15 +780,19 @@ export type IndexJsonArray = {
|
|
|
807
780
|
};
|
|
808
781
|
/** The modifiers that do not name a JSON path, and so need no entity to be checked against. */
|
|
809
782
|
type IndexColumnPlainModifiers = Except<IndexColumnModifiers, 'jsonPath' | 'jsonArray'>;
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
783
|
+
/**
|
|
784
|
+
* An entity's entry with plain modifiers. `jsonPath` and `jsonArray` are `never` here, since a JSON entry
|
|
785
|
+
* would otherwise match this shape too, its path unchecked.
|
|
786
|
+
*/
|
|
787
|
+
type IndexColumnOptions = IndexColumnPlainModifiers & {
|
|
788
|
+
/** A column read off the refs, or `raw` for an expression. */
|
|
789
|
+
readonly column: QueryRaw;
|
|
813
790
|
readonly jsonPath?: never;
|
|
814
791
|
readonly jsonArray?: never;
|
|
815
792
|
};
|
|
816
793
|
/**
|
|
817
|
-
* One index entry, normalized:
|
|
818
|
-
*
|
|
794
|
+
* One index entry, normalized: every authored shape reduces to this before any dialect or generator sees
|
|
795
|
+
* it, so rendering never re-parses the sugar.
|
|
819
796
|
*/
|
|
820
797
|
export type IndexColumnSchema = IndexColumnModifiers & {
|
|
821
798
|
/** A column name, or raw SQL when {@link expression} is set. */
|
|
@@ -967,27 +944,25 @@ export type EntityOptions<E = unknown> = {
|
|
|
967
944
|
* and through {@link EntityIndexOptions} `@Index` and `defineEntity`. `Except` (not plain `Omit`) keeps
|
|
968
945
|
* `type`/`distance` a discriminated pair: omitting `distance` on a vector index type is a compile error.
|
|
969
946
|
*/
|
|
970
|
-
export type IndexOptions = Except<EntityIndexMeta, 'columns' | '
|
|
971
|
-
/** Non-key columns stored in the index, by column name; a typo builds nothing, the server refusing it. */
|
|
972
|
-
readonly include?: readonly string[];
|
|
947
|
+
export type IndexOptions = Except<EntityIndexMeta, 'columns' | 'where'> & {
|
|
973
948
|
/** Partial-index predicate, as `raw` with no interpolation: the migration builder has no entity to compile one against. */
|
|
974
949
|
readonly where?: QueryRaw;
|
|
975
950
|
};
|
|
976
951
|
/**
|
|
977
|
-
* {@link IndexOptions} on an entity, whose stored columns are read off its
|
|
952
|
+
* {@link IndexOptions} on an entity, whose stored columns are read off its refs, `(post) => [post.slug]`,
|
|
978
953
|
* so they are checked against it and follow a rename. The migration builder names raw columns instead.
|
|
979
954
|
*/
|
|
980
955
|
export type EntityIndexOptions<E> = Except<IndexOptions, 'include' | 'where'> & {
|
|
981
|
-
readonly include?: (
|
|
956
|
+
readonly include?: (refs: RefMap<E>) => readonly ColumnRef<FieldKey<E>>[];
|
|
982
957
|
/** Partial-index predicate. See {@link EntityWhere}. */
|
|
983
958
|
readonly where?: EntityWhere<E>;
|
|
984
959
|
};
|
|
985
960
|
/**
|
|
986
|
-
* An index as authored on an entity, before `defineIndex` reads its columns off the
|
|
961
|
+
* An index as authored on an entity, before `defineIndex` reads its columns off the refs. Only the
|
|
987
962
|
* member lists are callbacks: TypeScript never checks a callback's returned literal for excess properties,
|
|
988
963
|
* so the options stay a literal of their own, where `uniqe: true` is a compile error.
|
|
989
964
|
*/
|
|
990
965
|
export type EntityIndexInput<E> = EntityIndexOptions<E> & {
|
|
991
|
-
readonly columns: (
|
|
966
|
+
readonly columns: (refs: RefMap<E>) => readonly EntityIndexColumnInput<E>[];
|
|
992
967
|
};
|
|
993
968
|
export {};
|
package/dist/type/migration.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { VectorCast } from '../dialect/vectorCast.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { AnyMigrationOperation } from '../migrate/builder/types.js';
|
|
3
3
|
import type { IndexFacet } from '../schema/indexDifferences.js';
|
|
4
4
|
import type { SchemaAST } from '../schema/schemaAST.js';
|
|
5
|
-
import type { ColumnNode, ForeignKeyAction,
|
|
5
|
+
import type { ColumnNode, ForeignKeyAction, IndexType, TableNode } from '../schema/types.js';
|
|
6
6
|
import type { EntityMeta, EntityWhereMeta, FieldOptions, IndexColumnSchema, LoggingOptions, Querier, SqlQuerier, Type, VectorIndexOptions } from './index.js';
|
|
7
7
|
/**
|
|
8
8
|
* Defines a migration using a simple object literal. `Q` is `MongoQuerier` for a MongoDB migration.
|
|
@@ -148,7 +148,7 @@ export interface IndexSchema extends VectorIndexOptions {
|
|
|
148
148
|
readonly unique: boolean;
|
|
149
149
|
/** Index type (btree, hnsw, ivfflat, etc.) */
|
|
150
150
|
readonly type?: IndexType;
|
|
151
|
-
/** Partial index
|
|
151
|
+
/** Partial index predicate as its engine writes it: SQL, or on MongoDB the JSON of its filter document. */
|
|
152
152
|
readonly where?: string;
|
|
153
153
|
/** Non-key columns stored in the index (Postgres-wire `INCLUDE`). */
|
|
154
154
|
readonly include?: readonly string[];
|
|
@@ -292,14 +292,20 @@ export interface SchemaGenerator {
|
|
|
292
292
|
*/
|
|
293
293
|
generateDropIndex(tableName: string, indexName: string): string;
|
|
294
294
|
/**
|
|
295
|
-
*
|
|
295
|
+
* The statements one migration builder operation runs as, one string each. An operation the engine
|
|
296
|
+
* has no form for throws: MongoDB has no columns, constraints or SQL.
|
|
296
297
|
*/
|
|
297
|
-
|
|
298
|
+
generateOperation(operation: AnyMigrationOperation): string[];
|
|
298
299
|
/**
|
|
299
300
|
* The text of SQL an entity declares - a check, a stored computed column, an index expression or
|
|
300
301
|
* predicate - rendered for this engine, which is what building an entity's schema needs from it.
|
|
301
302
|
*/
|
|
302
303
|
compileDdl(sql: EntityWhereMeta<object>, entity: Type<object>): string;
|
|
304
|
+
/**
|
|
305
|
+
* A partial index's `$where` as this engine writes it into {@link IndexSchema.where}, refused where its
|
|
306
|
+
* index takes less of a predicate than a query does: SQL Server's filter has no `OR`.
|
|
307
|
+
*/
|
|
308
|
+
compileIndexPredicate(where: EntityWhereMeta<object>, entity: Type<object>, indexName: string): string;
|
|
303
309
|
/**
|
|
304
310
|
* Compare an entity with a database table node and return the differences.
|
|
305
311
|
*
|
|
@@ -333,41 +339,6 @@ export interface SchemaGenerator {
|
|
|
333
339
|
* Resolve column name using field options and naming strategy
|
|
334
340
|
*/
|
|
335
341
|
resolveColumnName(key: string, field: FieldOptions): string;
|
|
336
|
-
/** DDL from a `TableNode`, one string per `querier.run`. */
|
|
337
|
-
generateCreateTableFromNode(table: TableNode, options?: {
|
|
338
|
-
ifNotExists?: boolean;
|
|
339
|
-
}): string[];
|
|
340
|
-
/** Generate CREATE INDEX statement from an IndexNode */
|
|
341
|
-
generateCreateIndexFromNode(index: IndexNode, options?: {
|
|
342
|
-
ifNotExists?: boolean;
|
|
343
|
-
}): string;
|
|
344
|
-
/** DDL from a `TableDefinition`, one string per `querier.run`. */
|
|
345
|
-
generateCreateTableFromDefinition(table: TableDefinition, options?: {
|
|
346
|
-
ifNotExists?: boolean;
|
|
347
|
-
}): string[];
|
|
348
|
-
/** Generate RENAME TABLE statement */
|
|
349
|
-
generateRenameTableSql(oldName: string, newName: string): string;
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* The column and constraint DDL a migration builder emits, which only a SQL engine has. Split from
|
|
353
|
-
* {@link SchemaGenerator} because MongoDB used to satisfy these six by returning `''`: a document store
|
|
354
|
-
* has no `ADD COLUMN`, and an empty statement silently did nothing rather than saying so.
|
|
355
|
-
*/
|
|
356
|
-
export interface SqlDdlGenerator extends SchemaGenerator {
|
|
357
|
-
/** Generate ADD COLUMN statement */
|
|
358
|
-
generateAddColumnSql(tableName: string, column: FullColumnDefinition): string;
|
|
359
|
-
/** Generate ALTER COLUMN statement */
|
|
360
|
-
generateAlterColumnSql(tableName: string, columnName: string, column: FullColumnDefinition): string;
|
|
361
|
-
/** Generate DROP COLUMN statement */
|
|
362
|
-
generateDropColumnSql(tableName: string, columnName: string): string;
|
|
363
|
-
/** Generate RENAME COLUMN statement */
|
|
364
|
-
generateRenameColumnSql(tableName: string, oldName: string, newName: string): string;
|
|
365
|
-
/** Generate ADD FOREIGN KEY statement */
|
|
366
|
-
generateAddForeignKeySql(tableName: string, foreignKey: ForeignKeySchema): string;
|
|
367
|
-
/** Generate DROP FOREIGN KEY statement */
|
|
368
|
-
generateDropForeignKeySql(tableName: string, constraintName: string): string;
|
|
369
|
-
/** CREATE INDEX from a builder's {@link IndexDefinition}, its SQL rendered for this engine. */
|
|
370
|
-
generateCreateIndexFromDefinition(tableName: string, index: IndexDefinition): string;
|
|
371
342
|
}
|
|
372
343
|
/**
|
|
373
344
|
* Interface for introspecting the current database schema
|
package/dist/type/queryRaw.d.ts
CHANGED
|
@@ -43,3 +43,11 @@ export declare class QueryRaw {
|
|
|
43
43
|
*/
|
|
44
44
|
render(opts: QueryRawRenderOptions): void;
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* A field of an entity as SQL, read off `refs(Entity)` or a definition's refs: interpolated into `raw`, it
|
|
48
|
+
* renders as the field's column. Its `key` is how an index tells a column from an expression.
|
|
49
|
+
*/
|
|
50
|
+
export declare class ColumnRef<K extends string = string> extends QueryRaw {
|
|
51
|
+
readonly key: K;
|
|
52
|
+
constructor(key: K, value: QueryRawFn);
|
|
53
|
+
}
|
package/dist/type/queryRaw.js
CHANGED
|
@@ -26,3 +26,14 @@ export class QueryRaw {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* A field of an entity as SQL, read off `refs(Entity)` or a definition's refs: interpolated into `raw`, it
|
|
31
|
+
* renders as the field's column. Its `key` is how an index tells a column from an expression.
|
|
32
|
+
*/
|
|
33
|
+
export class ColumnRef extends QueryRaw {
|
|
34
|
+
key;
|
|
35
|
+
constructor(key, value) {
|
|
36
|
+
super(value);
|
|
37
|
+
this.key = key;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { type EntityIndexColumn, type IndexColumnInput, type IndexColumnSchema, QueryRaw } from '../type/index.js';
|
|
1
|
+
import { type EntityIndexColumn, type EntityIndexMeta, type EntityMeta, type IndexColumnInput, type IndexColumnSchema, QueryRaw } from '../type/index.js';
|
|
2
2
|
/**
|
|
3
|
-
* Reduces an authored index entry to the form metadata keeps, so
|
|
4
|
-
*
|
|
3
|
+
* Reduces an authored index entry to the form metadata keeps, so a column, an expression and an options
|
|
4
|
+
* object reach the schema as one: a column read off the refs as its key, any other `raw` as it is.
|
|
5
5
|
*/
|
|
6
6
|
export declare function normalizeIndexColumn(entry: IndexColumnInput): EntityIndexColumn;
|
|
7
|
+
/** Every index an entity declares: each `@Field({ index })` as the one-column `@Index` it is, then its `@Index`es. */
|
|
8
|
+
export declare function declaredIndexes<E>(meta: EntityMeta<E>): EntityIndexMeta<E>[];
|
|
7
9
|
/** An index entry as the schema holds it, its expression rendered to text by `render`. */
|
|
8
10
|
export declare function renderIndexColumn(entry: EntityIndexColumn, render: (sql: QueryRaw) => string): IndexColumnSchema;
|
|
9
11
|
/** What an unnamed index's name is built from: each entry's column, or `expr<n>` for an expression, which has none. */
|
|
@@ -1,18 +1,25 @@
|
|
|
1
|
-
import { QueryRaw } from '../type/index.js';
|
|
2
|
-
import {
|
|
1
|
+
import { ColumnRef, QueryRaw, } from '../type/index.js';
|
|
2
|
+
import { definedEntries } from './object.util.js';
|
|
3
3
|
/**
|
|
4
|
-
* Reduces an authored index entry to the form metadata keeps, so
|
|
5
|
-
*
|
|
4
|
+
* Reduces an authored index entry to the form metadata keeps, so a column, an expression and an options
|
|
5
|
+
* object reach the schema as one: a column read off the refs as its key, any other `raw` as it is.
|
|
6
6
|
*/
|
|
7
7
|
export function normalizeIndexColumn(entry) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
const { column, ...modifiers } = typeof entry === 'string' || entry instanceof QueryRaw ? { column: entry } : entry;
|
|
9
|
+
return { ...modifiers, column: column instanceof ColumnRef ? column.key : column };
|
|
10
|
+
}
|
|
11
|
+
/** Every index an entity declares: each `@Field({ index })` as the one-column `@Index` it is, then its `@Index`es. */
|
|
12
|
+
export function declaredIndexes(meta) {
|
|
13
|
+
const fieldIndexes = definedEntries(meta.fields).flatMap(([key, field]) => field.index
|
|
14
|
+
? [
|
|
15
|
+
{
|
|
16
|
+
columns: [{ column: key }],
|
|
17
|
+
name: typeof field.index === 'string' ? field.index : undefined,
|
|
18
|
+
unique: field.unique,
|
|
19
|
+
},
|
|
20
|
+
]
|
|
21
|
+
: []);
|
|
22
|
+
return [...fieldIndexes, ...(meta.indexes ?? [])];
|
|
16
23
|
}
|
|
17
24
|
/** An index entry as the schema holds it, its expression rendered to text by `render`. */
|
|
18
25
|
export function renderIndexColumn(entry, render) {
|
package/dist/util/raw.d.ts
CHANGED
|
@@ -32,7 +32,12 @@ export declare function raw(value: QueryRawFn): QueryRaw;
|
|
|
32
32
|
* in scope. Metadata is read when a ref renders, so the map serves before the fields are registered.
|
|
33
33
|
*/
|
|
34
34
|
export declare function refs<E>(entity: Type<E>): RefMap<E>;
|
|
35
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* The refs a definition's callbacks read: an index's, a check's, a computed field's. A member decorator
|
|
37
|
+
* sees no class, so these name no entity and resolve against the one rendering them.
|
|
38
|
+
*/
|
|
39
|
+
export declare function memberRefs<E>(): RefMap<E>;
|
|
40
|
+
/** SQL a definition writes, a callback's refs read off {@link memberRefs}. */
|
|
36
41
|
export declare function entitySql<E>(sql: EntitySql<E>): QueryRaw;
|
|
37
42
|
/** A definition's predicate, its callback resolved the way {@link entitySql} resolves one. */
|
|
38
43
|
export declare function entityWhere<E>(where: EntityWhere<E>): EntityWhereMeta<E>;
|
package/dist/util/raw.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getMeta } from '../entity/metadata/definition.js';
|
|
2
|
-
import { QueryRaw, } from '../type/index.js';
|
|
2
|
+
import { ColumnRef, QueryRaw, } from '../type/index.js';
|
|
3
3
|
import { isInlinedExpression } from './field.util.js';
|
|
4
4
|
export function raw(value, ...rest) {
|
|
5
5
|
if (!isTemplateStrings(value)) {
|
|
@@ -27,22 +27,25 @@ export function raw(value, ...rest) {
|
|
|
27
27
|
export function refs(entity) {
|
|
28
28
|
return new Proxy({}, { get: (_, key) => columnRef(entity, String(key)) });
|
|
29
29
|
}
|
|
30
|
+
const MEMBER_REFS = new Proxy({}, { get: (_, key) => columnRef(undefined, String(key)) });
|
|
30
31
|
/**
|
|
31
|
-
* The refs a definition's
|
|
32
|
-
*
|
|
32
|
+
* The refs a definition's callbacks read: an index's, a check's, a computed field's. A member decorator
|
|
33
|
+
* sees no class, so these name no entity and resolve against the one rendering them.
|
|
33
34
|
*/
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
export function memberRefs() {
|
|
36
|
+
return MEMBER_REFS;
|
|
37
|
+
}
|
|
38
|
+
/** SQL a definition writes, a callback's refs read off {@link memberRefs}. */
|
|
36
39
|
export function entitySql(sql) {
|
|
37
|
-
return sql instanceof QueryRaw ? sql : sql(
|
|
40
|
+
return sql instanceof QueryRaw ? sql : sql(memberRefs());
|
|
38
41
|
}
|
|
39
42
|
/** A definition's predicate, its callback resolved the way {@link entitySql} resolves one. */
|
|
40
43
|
export function entityWhere(where) {
|
|
41
|
-
return typeof where === 'function' ? where(
|
|
44
|
+
return typeof where === 'function' ? where(memberRefs()) : where;
|
|
42
45
|
}
|
|
43
46
|
/** One field as SQL, against its own entity or, read off a definition, the entity rendering it. */
|
|
44
47
|
function columnRef(entity, key) {
|
|
45
|
-
return new
|
|
48
|
+
return new ColumnRef(key, (opts) => {
|
|
46
49
|
const owner = entity ?? opts.entity;
|
|
47
50
|
if (!owner) {
|
|
48
51
|
throw new TypeError(`'${key}' was read off a definition's refs, so it renders only inside its entity's SQL`);
|
package/dist/util/sqlLiteral.js
CHANGED
|
@@ -32,7 +32,6 @@ const MYSQL_ESCAPES = {
|
|
|
32
32
|
'\\': '\\\\',
|
|
33
33
|
};
|
|
34
34
|
const mysqlStringLiteral = (val) => `'${val.replace(MYSQL_SPECIALS, (char) => MYSQL_ESCAPES[char])}'`;
|
|
35
|
-
const pad = (value, len) => String(value).padStart(len, '0');
|
|
36
35
|
const HEX_BYTES = Array.from({ length: 256 }, (_, byte) => byte.toString(16).padStart(2, '0'));
|
|
37
36
|
/** Native hex encoder where available (~130x faster on 4 KB); lookup table for browsers. */
|
|
38
37
|
function bytesToHexLiteral(bytes) {
|
|
@@ -49,8 +48,11 @@ function bytesToHexLiteral(bytes) {
|
|
|
49
48
|
* measured 1.1-1.5x slower. Rejects unsupported types rather than stringifying them into SQL.
|
|
50
49
|
*/
|
|
51
50
|
function createEscaper(escapeString) {
|
|
52
|
-
/**
|
|
53
|
-
|
|
51
|
+
/**
|
|
52
|
+
* `YYYY-MM-DD HH:mm:ss.SSS` in UTC, so the SQL is the same whichever machine wrote it. Not `toISOString`
|
|
53
|
+
* as it is, whose `T` and `Z` MySQL rejects outright ("Invalid default value").
|
|
54
|
+
*/
|
|
55
|
+
const dateLiteral = (date) => escapeString(date.toISOString().replace('T', ' ').replace('Z', ''));
|
|
54
56
|
const sqlList = (arr) => {
|
|
55
57
|
let sql = '';
|
|
56
58
|
for (let i = 0; i < arr.length; i++) {
|
|
@@ -8,7 +8,7 @@ import type { RawRow } from '../type/index.js';
|
|
|
8
8
|
export declare function decodeWideNumber(value: string | bigint): number | string;
|
|
9
9
|
/**
|
|
10
10
|
* {@link decodeWideNumber} over every `bigint` cell of a row, for the drivers that hand a BIGINT back
|
|
11
|
-
* as one (`bun:sql`
|
|
12
|
-
* a copy per row cost more than the decode it carried.
|
|
11
|
+
* as one (`bun:sql`, `mariadb`, and every SQLite driver but D1). In place: the row is the driver's fresh
|
|
12
|
+
* object, and a copy per row cost more than the decode it carried.
|
|
13
13
|
*/
|
|
14
14
|
export declare function decodeBigInts(row: RawRow): RawRow;
|
package/dist/util/wideNumber.js
CHANGED
|
@@ -10,8 +10,8 @@ export function decodeWideNumber(value) {
|
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* {@link decodeWideNumber} over every `bigint` cell of a row, for the drivers that hand a BIGINT back
|
|
13
|
-
* as one (`bun:sql`
|
|
14
|
-
* a copy per row cost more than the decode it carried.
|
|
13
|
+
* as one (`bun:sql`, `mariadb`, and every SQLite driver but D1). In place: the row is the driver's fresh
|
|
14
|
+
* object, and a copy per row cost more than the decode it carried.
|
|
15
15
|
*/
|
|
16
16
|
export function decodeBigInts(row) {
|
|
17
17
|
for (const key in row) {
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"homepage": "https://uql-orm.dev",
|
|
4
4
|
"description": "The JSON-native TypeScript ORM for Bun, Browsers, Edge, Deno, Node, Workers. Supports PostgreSQL, PGlite, MySQL, MariaDB, SQLite, CockroachDB, SQL Server, Turso, Neon, Cloudflare D1 and MongoDB. Queries are plain JSON, typed to the leaf.",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.64.0",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"engines": {
|
|
9
9
|
"node": ">=24"
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"@nestjs/common": ">=10.0.0",
|
|
72
72
|
"@nestjs/core": ">=10.0.0",
|
|
73
73
|
"@tursodatabase/database": ">=0.7.0",
|
|
74
|
-
"@tursodatabase/serverless": ">=1.
|
|
74
|
+
"@tursodatabase/serverless": ">=1.3.0",
|
|
75
75
|
"better-sqlite3": ">=9.0.0",
|
|
76
76
|
"express": ">=5.0.0",
|
|
77
77
|
"mariadb": ">=3.0.0",
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { ForeignKeyAction } from '../schema/types.js';
|
|
2
|
-
import type { MigratorDialect, SchemaGenerator } from '../type/index.js';
|
|
3
|
-
/**
|
|
4
|
-
* Async factory for schema generators. Use this for MongoDB so the optional peer
|
|
5
|
-
* `mongodb` is only loaded when this path runs. SQL dialects delegate to {@link createSchemaGenerator}.
|
|
6
|
-
*/
|
|
7
|
-
export declare function createSchemaGeneratorAsync(dialect: MigratorDialect, defaultForeignKeyAction?: ForeignKeyAction): Promise<SchemaGenerator | undefined>;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { createSchemaGenerator } from './schemaGenerator.js';
|
|
2
|
-
/**
|
|
3
|
-
* Async factory for schema generators. Use this for MongoDB so the optional peer
|
|
4
|
-
* `mongodb` is only loaded when this path runs. SQL dialects delegate to {@link createSchemaGenerator}.
|
|
5
|
-
*/
|
|
6
|
-
export async function createSchemaGeneratorAsync(dialect, defaultForeignKeyAction) {
|
|
7
|
-
if (dialect.dialectName === 'mongodb') {
|
|
8
|
-
const { MongoSchemaGenerator } = await import('./generator/mongoSchemaGenerator.js');
|
|
9
|
-
return new MongoSchemaGenerator(dialect.namingStrategy, defaultForeignKeyAction);
|
|
10
|
-
}
|
|
11
|
-
return createSchemaGenerator(dialect, defaultForeignKeyAction);
|
|
12
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { AbstractSqlQuerierPool } from '../querier/index.js';
|
|
2
|
-
import { type HranaClient, HranaQuerier } from './hranaQuerier.js';
|
|
3
|
-
import type { SqliteDialect } from './sqliteDialect.js';
|
|
4
|
-
/**
|
|
5
|
-
* Pool for SQLite databases reached over the Hrana wire protocol (`@libsql/client`,
|
|
6
|
-
* `@tursodatabase/serverless/compat`).
|
|
7
|
-
*
|
|
8
|
-
* @remarks The client is shared by every querier, since Hrana keeps no per-connection state: a
|
|
9
|
-
* transaction takes its own session handle. It is resolved on first use rather than in the
|
|
10
|
-
* constructor, so building a pool never throws when the optional driver peer is absent, which is what
|
|
11
|
-
* lets a Workers bundle construct one at module scope.
|
|
12
|
-
*/
|
|
13
|
-
export declare abstract class AbstractHranaQuerierPool<D extends SqliteDialect> extends AbstractSqlQuerierPool<HranaQuerier, D> {
|
|
14
|
-
private client?;
|
|
15
|
-
/** False when the caller injected their own client, in which case they own its lifecycle. */
|
|
16
|
-
protected readonly ownsClient: boolean;
|
|
17
|
-
protected abstract openClient(): Promise<HranaClient>;
|
|
18
|
-
getQuerier(): Promise<HranaQuerier>;
|
|
19
|
-
end(): Promise<void>;
|
|
20
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { AbstractSqlQuerierPool } from '../querier/index.js';
|
|
2
|
-
import { HranaQuerier } from './hranaQuerier.js';
|
|
3
|
-
/**
|
|
4
|
-
* Pool for SQLite databases reached over the Hrana wire protocol (`@libsql/client`,
|
|
5
|
-
* `@tursodatabase/serverless/compat`).
|
|
6
|
-
*
|
|
7
|
-
* @remarks The client is shared by every querier, since Hrana keeps no per-connection state: a
|
|
8
|
-
* transaction takes its own session handle. It is resolved on first use rather than in the
|
|
9
|
-
* constructor, so building a pool never throws when the optional driver peer is absent, which is what
|
|
10
|
-
* lets a Workers bundle construct one at module scope.
|
|
11
|
-
*/
|
|
12
|
-
export class AbstractHranaQuerierPool extends AbstractSqlQuerierPool {
|
|
13
|
-
client;
|
|
14
|
-
/** False when the caller injected their own client, in which case they own its lifecycle. */
|
|
15
|
-
ownsClient = true;
|
|
16
|
-
async getQuerier() {
|
|
17
|
-
this.client ??= await this.openClient();
|
|
18
|
-
return new HranaQuerier(this.client, this.dialect, this.extra);
|
|
19
|
-
}
|
|
20
|
-
async end() {
|
|
21
|
-
if (this.ownsClient) {
|
|
22
|
-
this.client?.close();
|
|
23
|
-
}
|
|
24
|
-
this.client = undefined;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { PreparedSqliteQuerier, type SqlitePreparedStatement } from '../sqlite/abstractSqliteQuerier.js';
|
|
2
|
-
import type { SqliteDialect } from '../sqlite/sqliteDialect.js';
|
|
3
|
-
import type { ExtraOptions } from '../type/index.js';
|
|
4
|
-
/**
|
|
5
|
-
* Structural subset of the `@tursodatabase/database` API actually used here, declared locally so
|
|
6
|
-
* this package does not couple its published types to a pre-1.0 dependency.
|
|
7
|
-
*/
|
|
8
|
-
export type TursoDatabase = {
|
|
9
|
-
prepare(sql: string): Promise<SqlitePreparedStatement>;
|
|
10
|
-
close(): Promise<void>;
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* Querier for the embedded Turso engine.
|
|
14
|
-
*
|
|
15
|
-
* @remarks The engine exposes better-sqlite3 semantics (`reader`, `{changes, lastInsertRowid}`,
|
|
16
|
-
* array-bound values) over an async API, so all it supplies is the awaited `prepare`.
|
|
17
|
-
* `BEGIN`/`COMMIT` work as plain statements, leaving transactions to the base class.
|
|
18
|
-
*/
|
|
19
|
-
export declare class TursoLocalQuerier extends PreparedSqliteQuerier {
|
|
20
|
-
readonly db: TursoDatabase;
|
|
21
|
-
readonly extra?: ExtraOptions | undefined;
|
|
22
|
-
constructor(db: TursoDatabase, dialect: SqliteDialect, extra?: ExtraOptions | undefined);
|
|
23
|
-
protected prepare(query: string): Promise<SqlitePreparedStatement>;
|
|
24
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { PreparedSqliteQuerier } from '../sqlite/abstractSqliteQuerier.js';
|
|
2
|
-
/**
|
|
3
|
-
* Querier for the embedded Turso engine.
|
|
4
|
-
*
|
|
5
|
-
* @remarks The engine exposes better-sqlite3 semantics (`reader`, `{changes, lastInsertRowid}`,
|
|
6
|
-
* array-bound values) over an async API, so all it supplies is the awaited `prepare`.
|
|
7
|
-
* `BEGIN`/`COMMIT` work as plain statements, leaving transactions to the base class.
|
|
8
|
-
*/
|
|
9
|
-
export class TursoLocalQuerier extends PreparedSqliteQuerier {
|
|
10
|
-
db;
|
|
11
|
-
extra;
|
|
12
|
-
constructor(db, dialect, extra) {
|
|
13
|
-
super(dialect, extra);
|
|
14
|
-
this.db = db;
|
|
15
|
-
this.extra = extra;
|
|
16
|
-
}
|
|
17
|
-
prepare(query) {
|
|
18
|
-
return this.db.prepare(query);
|
|
19
|
-
}
|
|
20
|
-
}
|