uql-orm 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/README.md +5 -4
  2. package/dist/bunSql/bunSqlCockroachDialect.d.ts +2 -2
  3. package/dist/bunSql/bunSqlCockroachDialect.js +4 -10
  4. package/dist/bunSql/bunSqlPostgresDialect.d.ts +2 -2
  5. package/dist/bunSql/bunSqlPostgresDialect.js +4 -10
  6. package/dist/cockroachdb/cockroachDialect.d.ts +20 -4
  7. package/dist/cockroachdb/cockroachDialect.js +33 -18
  8. package/dist/d1/d1Querier.d.ts +4 -3
  9. package/dist/d1/d1Querier.js +0 -3
  10. package/dist/d1/d1SqliteDialect.d.ts +7 -0
  11. package/dist/d1/d1SqliteDialect.js +9 -0
  12. package/dist/dialect/abstractDialect.d.ts +8 -3
  13. package/dist/dialect/abstractDialect.js +9 -4
  14. package/dist/dialect/abstractSqlDialect.d.ts +35 -7
  15. package/dist/dialect/abstractSqlDialect.js +76 -35
  16. package/dist/dialect/index.d.ts +1 -0
  17. package/dist/dialect/index.js +1 -0
  18. package/dist/dialect/indexSqlDialect.d.ts +57 -0
  19. package/dist/dialect/indexSqlDialect.js +101 -0
  20. package/dist/dialect/mysqlLikeSqlDialect.d.ts +16 -1
  21. package/dist/dialect/mysqlLikeSqlDialect.js +32 -1
  22. package/dist/dialect/pgLikeSqlDialect.d.ts +33 -15
  23. package/dist/dialect/pgLikeSqlDialect.js +90 -56
  24. package/dist/dialect/vectorCast.d.ts +21 -0
  25. package/dist/dialect/vectorCast.js +28 -0
  26. package/dist/dialect/vectorSqlDialect.d.ts +10 -3
  27. package/dist/dialect/vectorSqlDialect.js +19 -8
  28. package/dist/entity/decorator/index-decorator.d.ts +2 -9
  29. package/dist/entity/metadata/definition.d.ts +5 -4
  30. package/dist/entity/metadata/definition.js +4 -3
  31. package/dist/libsql/libsqlDialect.d.ts +12 -2
  32. package/dist/libsql/libsqlDialect.js +14 -2
  33. package/dist/libsql/libsqlQuerier.d.ts +9 -22
  34. package/dist/libsql/libsqlQuerier.js +9 -85
  35. package/dist/libsql/libsqlQuerierPool.d.ts +10 -8
  36. package/dist/libsql/libsqlQuerierPool.js +17 -15
  37. package/dist/maria/mariaDialect.d.ts +26 -4
  38. package/dist/maria/mariaDialect.js +54 -15
  39. package/dist/migrate/builder/migrationBuilder.d.ts +9 -29
  40. package/dist/migrate/builder/migrationBuilder.js +58 -76
  41. package/dist/migrate/builder/splitSqlStatements.d.ts +0 -2
  42. package/dist/migrate/builder/splitSqlStatements.js +0 -2
  43. package/dist/migrate/builder/tableBuilder.d.ts +12 -2
  44. package/dist/migrate/builder/tableBuilder.js +71 -119
  45. package/dist/migrate/builder/types.d.ts +30 -41
  46. package/dist/migrate/cli.d.ts +3 -2
  47. package/dist/migrate/cli.js +21 -48
  48. package/dist/migrate/codegen/entityCodeGenerator.d.ts +0 -4
  49. package/dist/migrate/codegen/entityCodeGenerator.js +5 -63
  50. package/dist/migrate/codegen/fieldOptionsSource.d.ts +10 -0
  51. package/dist/migrate/codegen/fieldOptionsSource.js +55 -0
  52. package/dist/migrate/codegen/index.d.ts +0 -2
  53. package/dist/migrate/codegen/index.js +0 -4
  54. package/dist/migrate/generator/indexNodeToSchema.d.ts +9 -0
  55. package/dist/migrate/generator/indexNodeToSchema.js +14 -0
  56. package/dist/migrate/generator/mongoCommand.d.ts +57 -0
  57. package/dist/migrate/generator/mongoCommand.js +26 -0
  58. package/dist/migrate/generator/mongoSchemaGenerator.d.ts +9 -20
  59. package/dist/migrate/generator/mongoSchemaGenerator.js +40 -82
  60. package/dist/migrate/index.d.ts +0 -1
  61. package/dist/migrate/index.js +0 -1
  62. package/dist/migrate/introspection/abstractSqlSchemaIntrospector.d.ts +25 -10
  63. package/dist/migrate/introspection/abstractSqlSchemaIntrospector.js +46 -32
  64. package/dist/migrate/introspection/baseSqlIntrospector.d.ts +0 -1
  65. package/dist/migrate/introspection/baseSqlIntrospector.js +3 -12
  66. package/dist/migrate/introspection/mongoIntrospector.js +2 -2
  67. package/dist/migrate/introspection/mysqlIntrospector.d.ts +5 -8
  68. package/dist/migrate/introspection/mysqlIntrospector.js +4 -10
  69. package/dist/migrate/introspection/postgresIntrospector.d.ts +5 -8
  70. package/dist/migrate/introspection/postgresIntrospector.js +4 -10
  71. package/dist/migrate/introspection/sqliteIntrospector.d.ts +6 -5
  72. package/dist/migrate/introspection/sqliteIntrospector.js +26 -18
  73. package/dist/migrate/migrator.d.ts +23 -3
  74. package/dist/migrate/migrator.js +57 -69
  75. package/dist/migrate/schemaGenerator.d.ts +26 -37
  76. package/dist/migrate/schemaGenerator.js +69 -174
  77. package/dist/migrate/schemaGeneratorAsync.d.ts +2 -2
  78. package/dist/migrate/schemaGeneratorAsync.js +3 -3
  79. package/dist/migrate/storage/databaseStorage.js +4 -4
  80. package/dist/mongo/mongoDialect.d.ts +2 -0
  81. package/dist/mongo/mongoDialect.js +14 -3
  82. package/dist/mysql/mysqlDialect.d.ts +8 -0
  83. package/dist/mysql/mysqlDialect.js +13 -0
  84. package/dist/schema/canonicalType.d.ts +14 -2
  85. package/dist/schema/canonicalType.js +41 -31
  86. package/dist/schema/index.d.ts +1 -1
  87. package/dist/schema/schemaASTBuilder.d.ts +8 -1
  88. package/dist/schema/schemaASTBuilder.js +56 -47
  89. package/dist/schema/types.d.ts +10 -37
  90. package/dist/sqlite/abstractSqliteQuerier.d.ts +39 -0
  91. package/dist/sqlite/abstractSqliteQuerier.js +44 -0
  92. package/dist/sqlite/bunSqliteAdapter.bun.d.ts +26 -0
  93. package/dist/sqlite/bunSqliteAdapter.bun.js +25 -0
  94. package/dist/sqlite/hranaQuerier.d.ts +54 -0
  95. package/dist/sqlite/hranaQuerier.js +90 -0
  96. package/dist/sqlite/hranaQuerierPool.d.ts +21 -0
  97. package/dist/sqlite/hranaQuerierPool.js +25 -0
  98. package/dist/sqlite/index.d.ts +2 -1
  99. package/dist/sqlite/index.js +2 -1
  100. package/dist/sqlite/sqliteDialect.d.ts +18 -4
  101. package/dist/sqlite/sqliteDialect.js +24 -24
  102. package/dist/sqlite/sqliteQuerier.d.ts +16 -9
  103. package/dist/sqlite/sqliteQuerier.js +4 -27
  104. package/dist/sqlite/sqliteQuerierPool.d.ts +14 -4
  105. package/dist/sqlite/sqliteQuerierPool.js +16 -5
  106. package/dist/turso/index.d.ts +3 -0
  107. package/dist/turso/index.js +3 -0
  108. package/dist/turso/local.d.ts +3 -0
  109. package/dist/turso/local.js +3 -0
  110. package/dist/turso/tursoDialect.d.ts +15 -0
  111. package/dist/turso/tursoDialect.js +18 -0
  112. package/dist/turso/tursoLocalQuerier.d.ts +25 -0
  113. package/dist/turso/tursoLocalQuerier.js +20 -0
  114. package/dist/turso/tursoLocalQuerierPool.d.ts +32 -0
  115. package/dist/turso/tursoLocalQuerierPool.js +39 -0
  116. package/dist/turso/tursoQuerier.d.ts +10 -0
  117. package/dist/turso/tursoQuerier.js +10 -0
  118. package/dist/turso/tursoQuerierPool.d.ts +39 -0
  119. package/dist/turso/tursoQuerierPool.js +38 -0
  120. package/dist/type/config.d.ts +0 -6
  121. package/dist/type/dialect.d.ts +12 -4
  122. package/dist/type/dialect.js +7 -1
  123. package/dist/type/entity.d.ts +66 -5
  124. package/dist/type/migration.d.ts +32 -23
  125. package/dist/type/vector.d.ts +5 -2
  126. package/dist/util/index.d.ts +1 -0
  127. package/dist/util/index.js +1 -0
  128. package/dist/util/indexColumn.util.d.ts +6 -0
  129. package/dist/util/indexColumn.util.js +26 -0
  130. package/package.json +16 -3
  131. package/dist/migrate/codegen/entityMerger.d.ts +0 -114
  132. package/dist/migrate/codegen/entityMerger.js +0 -293
  133. package/dist/migrate/codegen/migrationCodeGenerator.d.ts +0 -61
  134. package/dist/migrate/codegen/migrationCodeGenerator.js +0 -355
  135. package/dist/migrate/generator/index.d.ts +0 -2
  136. package/dist/migrate/generator/index.js +0 -2
  137. package/dist/migrate/sync/index.d.ts +0 -6
  138. package/dist/migrate/sync/index.js +0 -6
  139. package/dist/migrate/sync/schemaSync.d.ts +0 -131
  140. package/dist/migrate/sync/schemaSync.js +0 -259
  141. package/dist/sqlite/betterSqlite3Dialect.d.ts +0 -9
  142. package/dist/sqlite/betterSqlite3Dialect.js +0 -9
@@ -1,6 +1,5 @@
1
1
  import type { AbstractDialect } from '../dialect/abstractDialect.js';
2
2
  import type { ForeignKeyAction } from '../schema/types.js';
3
- import type { NamingStrategy } from './namingStrategy.js';
4
3
  import type { Querier } from './querier.js';
5
4
  import type { QuerierPool } from './querierPool.js';
6
5
  import type { Type } from './utility.js';
@@ -29,11 +28,6 @@ export interface Config {
29
28
  * @default 'uql_migrations'
30
29
  */
31
30
  tableName?: string;
32
- /**
33
- * The naming strategy for mapping class/property names to database table/column names.
34
- * @default DefaultNamingStrategy (camelCase -> camelCase)
35
- */
36
- namingStrategy?: NamingStrategy;
37
31
  /**
38
32
  * Default action for foreign key ON DELETE and ON UPDATE clauses.
39
33
  * @default 'NO ACTION'
@@ -74,11 +74,11 @@ export interface EngineFeatures {
74
74
  /** Whether the dialect supports inline COMMENT on columns (MySQL/MariaDB). */
75
75
  readonly columnComment: boolean;
76
76
  /**
77
- * How vector indexes are emitted: inline in CREATE TABLE (MySQL/MariaDB), a standalone
78
- * `CREATE INDEX ... USING <type> (col opclass)` (Postgres/SQLite), or a standalone
79
- * `CREATE VECTOR INDEX (col opclass)` with no access-method keyword (CockroachDB's native type).
77
+ * Whether a vector index is declared inline in `CREATE TABLE` (MySQL/MariaDB) rather than as its own
78
+ * `CREATE INDEX` statement. The statement's shape itself is the dialect's business, see
79
+ * `AbstractSqlDialect.getCreateIndexStatement`.
80
80
  */
81
- readonly vectorIndexStyle: 'inline' | 'create' | 'native';
81
+ readonly inlineVectorIndex: boolean;
82
82
  /** Whether the dialect requires/allows (n) length constraints on vector types. */
83
83
  readonly vectorSupportsLength: boolean;
84
84
  /** Whether the dialect natively supports the TIMESTAMPTZ alias/type. */
@@ -196,3 +196,11 @@ export interface SqlQueryDialect extends QueryDialect {
196
196
  */
197
197
  placeholder(index: number): string;
198
198
  }
199
+ /**
200
+ * An index capability that some engines have and others reject outright. Verified live: expression
201
+ * indexes exist everywhere but MariaDB 12.3 (which needs a generated column); prefix lengths are
202
+ * MySQL-family only and *required* there to index `TEXT`; `NULLS FIRST/LAST` and operator classes are
203
+ * Postgres-only (CockroachDB 26.2 answers "unimplemented"); `INCLUDE` is Postgres-wire only.
204
+ */
205
+ export type IndexFeature = 'expression' | 'prefixLength' | 'nullsOrder' | 'opsClass' | 'include';
206
+ export declare const INDEX_FEATURE_LABELS: Record<IndexFeature, string>;
@@ -1 +1,7 @@
1
- export {};
1
+ export const INDEX_FEATURE_LABELS = {
2
+ expression: 'expression indexes',
3
+ prefixLength: 'index prefix lengths',
4
+ nullsOrder: 'NULLS FIRST/LAST in an index',
5
+ opsClass: 'index operator classes',
6
+ include: 'covering indexes (INCLUDE)',
7
+ };
@@ -1,7 +1,7 @@
1
1
  import type { IndexType } from '../schema/types.js';
2
2
  import type { FilterOptions } from './query.js';
3
3
  import type { QueryRaw } from './queryRaw.js';
4
- import type { Json, Scalar, Type, Unpacked } from './utility.js';
4
+ import type { DistributiveOmit, Json, Scalar, Type, Unpacked } from './utility.js';
5
5
  import type { VectorDistance, VectorIndexOptions, VectorIndexType } from './vector.js';
6
6
  /**
7
7
  * Allow to customize the name of the property that identifies an entity
@@ -344,17 +344,66 @@ export type IndexTypeOptions = {
344
344
  distance?: never;
345
345
  };
346
346
  /**
347
- * Index metadata from @Index decorator.
347
+ * One entry of an index: a column name by default, `raw(...)` to index an expression, or an object
348
+ * when the entry needs more than a name.
349
+ *
350
+ * @example
351
+ * ```ts
352
+ * @Index(['tenantId', { column: 'createdAt', order: 'desc' }]) // keyset pagination
353
+ * @Index([raw('lower("email")')], { unique: true }) // case-insensitive uniqueness
354
+ * @Index([{ column: 'body', length: 64 }]) // MySQL needs a prefix on TEXT
355
+ * @Index(['data'], { type: 'gin' }) // JSONB containment
356
+ * ```
357
+ */
358
+ export type IndexColumnInput = string | QueryRaw | IndexColumnOptions;
359
+ /**
360
+ * What an index entry can carry besides the thing being indexed. Shared with the normalized
361
+ * `IndexColumnSchema`, so the authored and internal shapes cannot drift apart.
362
+ */
363
+ export type IndexColumnModifiers = {
364
+ /**
365
+ * Index only the first `n` characters. MySQL and MariaDB *require* this to index a `TEXT`/`BLOB`
366
+ * column at all ("used in key specification without a key length"); no other engine accepts it.
367
+ */
368
+ readonly length?: number;
369
+ /** Stored sort order, which lets `ORDER BY ... DESC` pagination use the index. */
370
+ readonly order?: 'asc' | 'desc';
371
+ /** Where NULLs sort. Postgres only. */
372
+ readonly nulls?: 'first' | 'last';
373
+ /** Operator class, e.g. `jsonb_path_ops` for a smaller GIN index. Postgres only. */
374
+ readonly opsClass?: string;
375
+ };
376
+ export type IndexColumnOptions = IndexColumnModifiers & {
377
+ /** The column to index, or `raw(...)` for an expression. */
378
+ readonly column: string | QueryRaw;
379
+ };
380
+ /**
381
+ * One index entry, normalized: {@link IndexColumnInput}'s three authored shapes all reduce to this
382
+ * before any dialect or generator sees them, so rendering never re-parses the sugar.
383
+ */
384
+ export type IndexColumnSchema = IndexColumnModifiers & {
385
+ /** A column name, or raw SQL when {@link expression} is set. */
386
+ readonly column: string;
387
+ /** Whether {@link column} is an expression to emit as-is rather than an identifier to quote. */
388
+ readonly expression?: boolean;
389
+ };
390
+ /**
391
+ * An index as stored in entity metadata: authored options with the columns normalized.
348
392
  */
349
393
  export type EntityIndexMeta = {
350
- /** Column names in the index */
351
- columns: string[];
394
+ /** The indexed columns, in order. */
395
+ columns: readonly IndexColumnSchema[];
352
396
  /** Custom index name */
353
397
  name?: string;
354
398
  /** Whether index is unique; omit or `false` for a non-unique index (default). */
355
399
  unique?: boolean;
356
400
  /** Partial index condition (WHERE clause) */
357
401
  where?: string;
402
+ /**
403
+ * Extra columns stored in the index but not part of its key, so a query reading only these is
404
+ * answered from the index alone. Postgres-wire only (`INCLUDE`).
405
+ */
406
+ include?: readonly string[];
358
407
  } & VectorIndexOptions & IndexTypeOptions;
359
408
  export type EntityMeta<E> = {
360
409
  readonly entity: Type<E>;
@@ -392,8 +441,20 @@ export type EntityOptions<E = unknown> = {
392
441
  /** Scalar fields; use `isId: true` on exactly one field for the primary key. */
393
442
  readonly fields?: Record<string, FieldOptions>;
394
443
  readonly relations?: Record<string, RelationOptions>;
395
- readonly indexes?: readonly EntityIndexMeta[];
444
+ readonly indexes?: readonly EntityIndexInput[];
396
445
  /** Map hook events to method names on the entity class. */
397
446
  readonly hooks?: Partial<Record<HookEvent, readonly string[]>>;
398
447
  };
448
+ /**
449
+ * Everything an index carries beyond its columns, shared by `@Index`, `defineEntity` and the
450
+ * migration builder's `table.index(...)`. `DistributiveOmit` (not plain `Omit`) keeps `type`/
451
+ * `distance` a discriminated pair: omitting `distance` on a vector index type is a compile error.
452
+ */
453
+ export type IndexOptions = DistributiveOmit<EntityIndexMeta, 'columns'>;
454
+ /**
455
+ * An index as authored, before {@link appendEntityIndex} normalizes its columns.
456
+ */
457
+ export type EntityIndexInput = IndexOptions & {
458
+ readonly columns: readonly IndexColumnInput[];
459
+ };
399
460
  export {};
@@ -1,7 +1,8 @@
1
+ import type { VectorCast } from '../dialect/vectorCast.js';
1
2
  import type { FullColumnDefinition, TableDefinition, TableForeignKeyDefinition } from '../migrate/builder/types.js';
2
3
  import type { SchemaAST } from '../schema/schemaAST.js';
3
4
  import type { ForeignKeyAction, IndexNode, IndexType, TableNode } from '../schema/types.js';
4
- import type { EntityMeta, FieldOptions, LoggingOptions, NamingStrategy, SqlQuerier, Type, VectorIndexOptions } from './index.js';
5
+ import type { EntityMeta, FieldOptions, IndexColumnSchema, LoggingOptions, SqlQuerier, Type, VectorIndexOptions } from './index.js';
5
6
  /**
6
7
  * Defines a migration using a simple object literal
7
8
  */
@@ -72,10 +73,6 @@ export interface MigratorOptions {
72
73
  * Entities to use for schema generation
73
74
  */
74
75
  readonly entities?: Type<unknown>[];
75
- /**
76
- * Naming strategy for database tables and columns
77
- */
78
- readonly namingStrategy?: NamingStrategy;
79
76
  /**
80
77
  * Default action for foreign key ON DELETE and ON UPDATE clauses.
81
78
  */
@@ -101,6 +98,13 @@ export interface MigrationResult {
101
98
  */
102
99
  export interface ColumnSchema {
103
100
  readonly name: string;
101
+ /**
102
+ * The engine's own type spelling, as introspection read it (`tinyint(1)`, `DATETIME`, `VARCHAR`).
103
+ * Deliberately not a {@link CanonicalType}: the diff has to compare what the engine would *store*,
104
+ * and several canonical types share one storage type per engine - an entity `boolean` is `TINYINT(1)`
105
+ * on MySQL and `INTEGER` on SQLite. Comparing canonical categories instead reports an alteration on
106
+ * every sync for those columns. Use `sqlToCanonical` to interpret it.
107
+ */
104
108
  readonly type: string;
105
109
  readonly nullable: boolean;
106
110
  readonly defaultValue?: unknown;
@@ -127,10 +131,20 @@ export interface TableSchema {
127
131
  */
128
132
  export interface IndexSchema extends VectorIndexOptions {
129
133
  readonly name: string;
130
- readonly columns: string[];
134
+ readonly columns: readonly IndexColumnSchema[];
131
135
  readonly unique: boolean;
132
136
  /** Index type (btree, hnsw, ivfflat, etc.) */
133
137
  readonly type?: IndexType;
138
+ /** Partial index condition (WHERE clause) */
139
+ readonly where?: string;
140
+ /** Non-key columns stored in the index (Postgres-wire `INCLUDE`). */
141
+ readonly include?: readonly string[];
142
+ /**
143
+ * The indexed column's vector type, which pgvector's operator-class names are built from
144
+ * (`halfvec_cosine_ops`). Absent for a non-vector index, and for an index whose column types are
145
+ * unknown, where `vector` is assumed.
146
+ */
147
+ readonly vectorType?: VectorCast;
134
148
  }
135
149
  /**
136
150
  * Represents a foreign key constraint
@@ -171,10 +185,11 @@ export interface SchemaGenerator {
171
185
  generateCreateTable<E>(entity: Type<E>, options?: {
172
186
  ifNotExists?: boolean;
173
187
  }): string[];
174
- /**
175
- * Generate DROP TABLE statement for an entity
176
- */
177
- generateDropTable<E>(entity: Type<E>): string;
188
+ /** Generate DROP TABLE statement. */
189
+ generateDropTable(tableName: string, options?: {
190
+ ifExists?: boolean;
191
+ cascade?: boolean;
192
+ }): string;
178
193
  /**
179
194
  * Generate ALTER TABLE statements based on schema diff
180
195
  */
@@ -215,21 +230,19 @@ export interface SchemaGenerator {
215
230
  generateCreateIndexFromNode(index: IndexNode, options?: {
216
231
  ifNotExists?: boolean;
217
232
  }): string;
218
- /** Generate DROP TABLE statement from a TableNode */
219
- generateDropTableFromNode(table: TableNode, options?: {
220
- ifExists?: boolean;
221
- }): string;
222
233
  /** DDL from a `TableDefinition`, one string per `querier.run`. */
223
234
  generateCreateTableFromDefinition(table: TableDefinition, options?: {
224
235
  ifNotExists?: boolean;
225
236
  }): string[];
226
- /** Generate DROP TABLE statement */
227
- generateDropTableSql(tableName: string, options?: {
228
- ifExists?: boolean;
229
- cascade?: boolean;
230
- }): string;
231
237
  /** Generate RENAME TABLE statement */
232
238
  generateRenameTableSql(oldName: string, newName: string): string;
239
+ }
240
+ /**
241
+ * The column and constraint DDL a migration builder emits, which only a SQL engine has. Split from
242
+ * {@link SchemaGenerator} because MongoDB used to satisfy these six by returning `''`: a document store
243
+ * has no `ADD COLUMN`, and an empty statement silently did nothing rather than saying so.
244
+ */
245
+ export interface SqlDdlGenerator extends SchemaGenerator {
233
246
  /** Generate ADD COLUMN statement */
234
247
  generateAddColumnSql(tableName: string, column: FullColumnDefinition): string;
235
248
  /** Generate ALTER COLUMN statement */
@@ -238,10 +251,6 @@ export interface SchemaGenerator {
238
251
  generateDropColumnSql(tableName: string, columnName: string): string;
239
252
  /** Generate RENAME COLUMN statement */
240
253
  generateRenameColumnSql(tableName: string, oldName: string, newName: string): string;
241
- /** Generate CREATE INDEX statement from IndexSchema */
242
- generateCreateIndexSql(tableName: string, index: IndexSchema): string;
243
- /** Generate DROP INDEX statement */
244
- generateDropIndexSql(tableName: string, indexName: string): string;
245
254
  /** Generate ADD FOREIGN KEY statement */
246
255
  generateAddForeignKeySql(tableName: string, foreignKey: TableForeignKeyDefinition): string;
247
256
  /** Generate DROP FOREIGN KEY statement */
@@ -5,9 +5,12 @@ import type { IndexType } from '../schema/types.js';
5
5
  * - `l2` - Euclidean distance
6
6
  * - `inner` - inner (dot) product
7
7
  * - `l1` - Manhattan distance
8
- * - `hamming` - for binary vectors
8
+ *
9
+ * @remarks Hamming distance is absent because no engine can express it over a float vector column:
10
+ * pgvector's `<~>`/`bit_hamming_ops` and sqlite-vec's `vec_distance_hamming` both require a *bit*
11
+ * vector, which no field type maps to. It would be a value that compiles and always throws.
9
12
  */
10
- export type VectorDistance = 'cosine' | 'l2' | 'inner' | 'l1' | 'hamming';
13
+ export type VectorDistance = 'cosine' | 'l2' | 'inner' | 'l1';
11
14
  /**
12
15
  * Vector similarity search options - used inside `$sort` on vector fields.
13
16
  *
@@ -2,6 +2,7 @@ export * from './dialect.util.js';
2
2
  export * from './field.util.js';
3
3
  export * from './filters.util.js';
4
4
  export * from './hook.util.js';
5
+ export * from './indexColumn.util.js';
5
6
  export * from './logger.js';
6
7
  export * from './object.util.js';
7
8
  export * from './raw.js';
@@ -2,6 +2,7 @@ export * from './dialect.util.js';
2
2
  export * from './field.util.js';
3
3
  export * from './filters.util.js';
4
4
  export * from './hook.util.js';
5
+ export * from './indexColumn.util.js';
5
6
  export * from './logger.js';
6
7
  export * from './object.util.js';
7
8
  export * from './raw.js';
@@ -0,0 +1,6 @@
1
+ import { type IndexColumnInput, type IndexColumnSchema } from '../type/index.js';
2
+ /**
3
+ * Reduces an authored index entry to its normalized form, so the three shapes users write - a column
4
+ * name, `raw(expression)`, or an options object - reach the dialects as one.
5
+ */
6
+ export declare function normalizeIndexColumn(entry: IndexColumnInput): IndexColumnSchema;
@@ -0,0 +1,26 @@
1
+ import { QueryRaw, RAW_VALUE } from '../type/index.js';
2
+ /**
3
+ * Reduces an authored index entry to its normalized form, so the three shapes users write - a column
4
+ * name, `raw(expression)`, or an options object - reach the dialects as one.
5
+ */
6
+ export function normalizeIndexColumn(entry) {
7
+ if (typeof entry === 'string') {
8
+ return { column: entry };
9
+ }
10
+ if (entry instanceof QueryRaw) {
11
+ return { column: rawSql(entry), expression: true };
12
+ }
13
+ const { column, ...rest } = entry;
14
+ return column instanceof QueryRaw ? { ...rest, column: rawSql(column), expression: true } : { ...rest, column };
15
+ }
16
+ /**
17
+ * An index expression is DDL, evaluated once at creation time, so it cannot take the dialect-aware
18
+ * callback form of `raw()` - there is no query context to hand it.
19
+ */
20
+ function rawSql(value) {
21
+ const sql = value[RAW_VALUE];
22
+ if (typeof sql !== 'string') {
23
+ throw new TypeError('an index expression needs raw() with a string, not a function');
24
+ }
25
+ return sql;
26
+ }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "homepage": "https://uql-orm.dev",
4
4
  "description": "Extremely fast, type-safe TypeScript ORM - one API for every database",
5
5
  "license": "MIT",
6
- "version": "0.21.0",
6
+ "version": "0.22.0",
7
7
  "type": "module",
8
8
  "engines": {
9
9
  "node": ">=20"
@@ -44,6 +44,8 @@
44
44
  "default": "./dist/browser/uql-browser.min.js"
45
45
  },
46
46
  "./libsql": "./dist/libsql/index.js",
47
+ "./turso": "./dist/turso/index.js",
48
+ "./turso/local": "./dist/turso/local.js",
47
49
  "./neon": "./dist/neon/index.js",
48
50
  "./d1": "./dist/d1/index.js",
49
51
  "./bunSql": "./dist/bunSql/index.js",
@@ -66,6 +68,8 @@
66
68
  "@neondatabase/serverless": ">=0.9.0",
67
69
  "@nestjs/common": ">=10.0.0",
68
70
  "@nestjs/core": ">=10.0.0",
71
+ "@tursodatabase/database": ">=0.7.0",
72
+ "@tursodatabase/serverless": ">=1.0.0",
69
73
  "better-sqlite3": ">=9.0.0",
70
74
  "express": ">=5.0.0",
71
75
  "jiti": ">=2.0.0",
@@ -90,6 +94,12 @@
90
94
  "@nestjs/core": {
91
95
  "optional": true
92
96
  },
97
+ "@tursodatabase/database": {
98
+ "optional": true
99
+ },
100
+ "@tursodatabase/serverless": {
101
+ "optional": true
102
+ },
93
103
  "better-sqlite3": {
94
104
  "optional": true
95
105
  },
@@ -127,9 +137,11 @@
127
137
  "@nestjs/common": "^11.1.28",
128
138
  "@nestjs/core": "^11.1.28",
129
139
  "@nestjs/testing": "^11.1.28",
140
+ "@tursodatabase/database": "^0.7.2",
141
+ "@tursodatabase/serverless": "^1.4.0",
130
142
  "@types/better-sqlite3": "^7.6.13",
131
143
  "@types/express": "^5.0.6",
132
- "@types/pg": "^8.20.0",
144
+ "@types/pg": "^8.20.1",
133
145
  "@types/ws": "^8.18.1",
134
146
  "better-sqlite3": "^13.0.2",
135
147
  "express": "^5.2.1",
@@ -141,6 +153,7 @@
141
153
  "pg-query-stream": "^4.16.0",
142
154
  "reflect-metadata": "^0.2.2",
143
155
  "rxjs": "^7.8.2",
156
+ "sqlite-vec": "^0.1.9",
144
157
  "ws": "^8.21.1"
145
158
  },
146
159
  "author": "Roger Padilla",
@@ -194,5 +207,5 @@
194
207
  "publishConfig": {
195
208
  "access": "public"
196
209
  },
197
- "gitHead": "1d056e8d5030fe70e3dc21a151db282e9e553dd9"
210
+ "gitHead": "0804fc0205c1f629e497df020835a17b63aed0e8"
198
211
  }
@@ -1,114 +0,0 @@
1
- /**
2
- * Entity Merger
3
- *
4
- * Merges generated entity code with existing TypeScript entity files.
5
- * Uses string-based parsing to add new fields with JSDoc comments.
6
- */
7
- import type { ColumnNode, RelationshipNode } from '../../schema/types.js';
8
- /**
9
- * Options for entity merging.
10
- */
11
- export interface EntityMergerOptions {
12
- /** Add JSDoc @sync-added comments to new fields */
13
- addSyncComments?: boolean;
14
- /** Mark removed fields with @deprecated instead of deleting */
15
- markRemovedAsDeprecated?: boolean;
16
- /** Custom property name transformer */
17
- propertyNameTransformer?: (columnName: string) => string;
18
- }
19
- /**
20
- * Represents a field to add to an entity.
21
- */
22
- export interface FieldToAdd {
23
- column: ColumnNode;
24
- propertyName: string;
25
- isRelation?: boolean;
26
- relation?: RelationshipNode;
27
- }
28
- /**
29
- * Represents a field to mark as deprecated.
30
- */
31
- export interface FieldToDeprecate {
32
- propertyName: string;
33
- reason: string;
34
- }
35
- /**
36
- * Result of entity merge operation.
37
- */
38
- export interface MergeResult {
39
- /** The merged source code */
40
- code: string;
41
- /** Number of fields added */
42
- fieldsAdded: number;
43
- /** Number of fields marked deprecated */
44
- fieldsDeprecated: number;
45
- /** Whether the file was modified */
46
- modified: boolean;
47
- }
48
- /**
49
- * Merges new fields from database schema into existing entity files.
50
- */
51
- export declare class EntityMerger {
52
- private readonly options;
53
- constructor(options?: EntityMergerOptions);
54
- /**
55
- * Merge new fields into existing entity source code.
56
- */
57
- merge(existingCode: string, fieldsToAdd: FieldToAdd[], fieldsToDeprecate?: FieldToDeprecate[]): MergeResult;
58
- /**
59
- * Extract existing property names from entity code.
60
- */
61
- private extractPropertyNames;
62
- /**
63
- * Find the position to insert new fields (before the last closing brace).
64
- */
65
- private findInsertPosition;
66
- /**
67
- * Count net brace depth change in a line.
68
- */
69
- private countBraces;
70
- /**
71
- * Generate code for new fields.
72
- */
73
- private generateFieldsCode;
74
- /**
75
- * Generate code for a column field.
76
- */
77
- private generateColumnField;
78
- /**
79
- * Generate code for a relation field.
80
- */
81
- private generateRelationField;
82
- /**
83
- * Mark a field as deprecated in the source code.
84
- */
85
- private markFieldAsDeprecated;
86
- /**
87
- * Build Field decorator options string.
88
- */
89
- private buildFieldOptions;
90
- /**
91
- * Format type for description.
92
- */
93
- private formatTypeDescription;
94
- /**
95
- * Get relation decorator name.
96
- */
97
- private getRelationDecoratorName;
98
- /**
99
- * Default property name transformer (delegates to shared utility).
100
- */
101
- private defaultPropertyNameTransformer;
102
- /**
103
- * Convert to PascalCase (delegates to shared utility).
104
- */
105
- private toPascalCase;
106
- /**
107
- * Singularize (delegates to shared utility).
108
- */
109
- private singularize;
110
- }
111
- /**
112
- * Create an EntityMerger instance.
113
- */
114
- export declare function createEntityMerger(options?: EntityMergerOptions): EntityMerger;