@vertz/db 0.2.14 → 0.2.16
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/d1/index.d.ts +146 -11
- package/dist/d1/index.js +1 -1
- package/dist/index.d.ts +264 -209
- package/dist/index.js +246 -147
- package/dist/internals.d.ts +1 -0
- package/dist/postgres/index.d.ts +6 -0
- package/dist/postgres/index.js +1 -1
- package/dist/shared/{chunk-pxjcpnpx.js → chunk-3a9nybt2.js} +7 -2
- package/dist/shared/{chunk-pkv8w501.js → chunk-ed82s3sa.js} +8 -4
- package/dist/shared/{chunk-2gd1fqcw.js → chunk-p2x2vmg5.js} +1 -1
- package/dist/shared/{chunk-rqe0prft.js → chunk-rjry8vc2.js} +23 -0
- package/dist/shared/{chunk-ndxe1h28.js → chunk-tnaf4hbj.js} +1 -1
- package/dist/sql/index.js +1 -1
- package/dist/sqlite/index.d.ts +146 -11
- package/dist/sqlite/index.js +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -39,6 +39,19 @@ declare function formatDiagnostic(diag: DiagnosticResult): string;
|
|
|
39
39
|
*/
|
|
40
40
|
declare function explainError(message: string): string;
|
|
41
41
|
/**
|
|
42
|
+
* Query executor — wraps raw SQL execution with error mapping.
|
|
43
|
+
*
|
|
44
|
+
* Takes a query function (from the database driver) and wraps it to:
|
|
45
|
+
* 1. Execute parameterized SQL
|
|
46
|
+
* 2. Map PG errors to typed DbError subclasses
|
|
47
|
+
* 3. Return typed QueryResult
|
|
48
|
+
*/
|
|
49
|
+
interface ExecutorResult<T> {
|
|
50
|
+
readonly rows: readonly T[];
|
|
51
|
+
readonly rowCount: number;
|
|
52
|
+
}
|
|
53
|
+
type QueryFn = <T>(sql: string, params: readonly unknown[]) => Promise<ExecutorResult<T>>;
|
|
54
|
+
/**
|
|
42
55
|
* Database driver interface.
|
|
43
56
|
*
|
|
44
57
|
* Provides a unified interface for different database backends
|
|
@@ -56,6 +69,12 @@ interface DbDriver {
|
|
|
56
69
|
rowsAffected: number;
|
|
57
70
|
}>;
|
|
58
71
|
/**
|
|
72
|
+
* Execute a callback within a database transaction.
|
|
73
|
+
* The callback receives a transaction-scoped QueryFn.
|
|
74
|
+
* Optional — not all drivers support transactions (e.g., D1).
|
|
75
|
+
*/
|
|
76
|
+
beginTransaction?<T>(fn: (txQueryFn: QueryFn) => Promise<T>): Promise<T>;
|
|
77
|
+
/**
|
|
59
78
|
* Close the database connection.
|
|
60
79
|
*/
|
|
61
80
|
close(): Promise<void>;
|
|
@@ -94,6 +113,7 @@ interface ColumnBuilder<
|
|
|
94
113
|
readonly _meta: TMeta;
|
|
95
114
|
primary(options?: {
|
|
96
115
|
generate?: "cuid" | "uuid" | "nanoid";
|
|
116
|
+
generated?: boolean;
|
|
97
117
|
}): ColumnBuilder<TType, Omit<TMeta, "primary" | "hasDefault" | "generate"> & {
|
|
98
118
|
readonly primary: true;
|
|
99
119
|
readonly hasDefault: true;
|
|
@@ -290,28 +310,241 @@ interface TableOptions {
|
|
|
290
310
|
relations?: Record<string, RelationDef>;
|
|
291
311
|
indexes?: IndexDef[];
|
|
292
312
|
}
|
|
313
|
+
/** Operators available for comparable types (number, string, Date, bigint). */
|
|
314
|
+
interface ComparisonOperators<T> {
|
|
315
|
+
readonly eq?: T;
|
|
316
|
+
readonly ne?: T;
|
|
317
|
+
readonly gt?: T;
|
|
318
|
+
readonly gte?: T;
|
|
319
|
+
readonly lt?: T;
|
|
320
|
+
readonly lte?: T;
|
|
321
|
+
readonly in?: readonly T[];
|
|
322
|
+
readonly notIn?: readonly T[];
|
|
323
|
+
}
|
|
324
|
+
/** Additional operators for string columns. */
|
|
325
|
+
interface StringOperators {
|
|
326
|
+
readonly contains?: string;
|
|
327
|
+
readonly startsWith?: string;
|
|
328
|
+
readonly endsWith?: string;
|
|
329
|
+
}
|
|
330
|
+
/** The `isNull` operator — only available for nullable columns. */
|
|
331
|
+
interface NullOperator {
|
|
332
|
+
readonly isNull?: boolean;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Resolves the filter operators for a single column based on its inferred type
|
|
336
|
+
* and nullable metadata.
|
|
337
|
+
*
|
|
338
|
+
* - All types get comparison + in/notIn
|
|
339
|
+
* - String types additionally get contains, startsWith, endsWith
|
|
340
|
+
* - Nullable columns additionally get isNull
|
|
341
|
+
*
|
|
342
|
+
* Uses [T] extends [string] to prevent union distribution -- ensures that a
|
|
343
|
+
* union like 'admin' | 'editor' keeps the full union in each operator slot.
|
|
344
|
+
*/
|
|
345
|
+
type ColumnFilterOperators<
|
|
346
|
+
TType,
|
|
347
|
+
TNullable extends boolean
|
|
348
|
+
> = ([TType] extends [string] ? ComparisonOperators<TType> & StringOperators : ComparisonOperators<TType>) & (TNullable extends true ? NullOperator : unknown);
|
|
349
|
+
/** Determine whether a column is nullable from its metadata. */
|
|
350
|
+
type IsNullable<C> = C extends ColumnBuilder<unknown, infer M> ? M extends {
|
|
351
|
+
readonly nullable: true;
|
|
352
|
+
} ? true : false : false;
|
|
353
|
+
/**
|
|
354
|
+
* FilterType<TColumns> — typed where clause.
|
|
355
|
+
*
|
|
356
|
+
* Each key maps to either:
|
|
357
|
+
* - A direct value (shorthand for `{ eq: value }`)
|
|
358
|
+
* - An object with typed filter operators
|
|
359
|
+
*/
|
|
360
|
+
type FilterType<TColumns extends ColumnRecord> = { [K in keyof TColumns]? : InferColumnType<TColumns[K]> | ColumnFilterOperators<InferColumnType<TColumns[K]>, IsNullable<TColumns[K]>> };
|
|
361
|
+
type OrderByType<TColumns extends ColumnRecord> = { [K in keyof TColumns]? : "asc" | "desc" };
|
|
362
|
+
/**
|
|
363
|
+
* SelectOption<TColumns> — the `select` field in query options.
|
|
364
|
+
*
|
|
365
|
+
* Either:
|
|
366
|
+
* - `{ not: Annotation | Annotation[] }` — exclude columns by annotation(s)
|
|
367
|
+
* - `{ [column]: true }` — explicitly pick columns
|
|
368
|
+
*
|
|
369
|
+
* The two forms are mutually exclusive, enforced via `never` mapped keys.
|
|
370
|
+
*/
|
|
371
|
+
type SelectOption<TColumns extends ColumnRecord> = ({
|
|
372
|
+
readonly not: AllAnnotations<TColumns> | readonly AllAnnotations<TColumns>[];
|
|
373
|
+
} & { readonly [K in keyof TColumns]? : never }) | ({ readonly [K in keyof TColumns]? : true } & {
|
|
374
|
+
readonly not?: never;
|
|
375
|
+
});
|
|
376
|
+
/** Extract selected keys from a select map (keys set to `true`). */
|
|
377
|
+
type SelectedKeys<
|
|
378
|
+
TColumns extends ColumnRecord,
|
|
379
|
+
TSelect
|
|
380
|
+
> = { [K in keyof TSelect] : K extends keyof TColumns ? (TSelect[K] extends true ? K : never) : never }[keyof TSelect];
|
|
381
|
+
/**
|
|
382
|
+
* Normalize `not` value to a union of annotation strings.
|
|
383
|
+
* - `'annotation'` → `'annotation'`
|
|
384
|
+
* - `readonly ['a', 'b']` → `'a' | 'b'`
|
|
385
|
+
*/
|
|
386
|
+
type NormalizeAnnotations<T> = T extends readonly (infer F)[] ? F extends string ? F : never : T extends string ? T : never;
|
|
387
|
+
/**
|
|
388
|
+
* SelectNarrow<TColumns, TSelect> — applies a select clause to narrow the result type.
|
|
389
|
+
*
|
|
390
|
+
* - `{ not: 'sensitive' }` → excludes 'sensitive'-annotated AND 'hidden'-annotated columns
|
|
391
|
+
* - `{ not: ['sensitive', 'patchable'] }` → excludes columns with ANY listed annotation + 'hidden'
|
|
392
|
+
* - `{ id: true, name: true }` → picks only id and name
|
|
393
|
+
* - `undefined` → default: excludes 'hidden'-annotated columns ($infer behavior)
|
|
394
|
+
*/
|
|
395
|
+
type SelectNarrow<
|
|
396
|
+
TColumns extends ColumnRecord,
|
|
397
|
+
TSelect
|
|
398
|
+
> = TSelect extends {
|
|
399
|
+
not: infer TNot;
|
|
400
|
+
} ? { [K in ColumnKeysWithoutAnyAnnotation<TColumns, NormalizeAnnotations<TNot> | "hidden"> & keyof TColumns] : InferColumnType<TColumns[K]> } : TSelect extends Record<string, true | undefined> ? { [K in SelectedKeys<TColumns, TSelect> & keyof TColumns] : InferColumnType<TColumns[K]> } : { [K in ColumnKeysWithoutAnyAnnotation<TColumns, "hidden"> & keyof TColumns] : InferColumnType<TColumns[K]> };
|
|
401
|
+
/** Relations record — maps relation names to RelationDef. */
|
|
402
|
+
type RelationsRecord = Record<string, RelationDef>;
|
|
403
|
+
/**
|
|
404
|
+
* The shape of include options for a given relations record.
|
|
405
|
+
* Each relation can be:
|
|
406
|
+
* - `true` — include with default fields
|
|
407
|
+
* - An object with `select`, `where`, `orderBy`, `limit` constrained to target table columns
|
|
408
|
+
*/
|
|
409
|
+
type IncludeOption<TRelations extends RelationsRecord> = { [K in keyof TRelations]? : true | (RelationTarget<TRelations[K]> extends TableDef<infer TCols> ? {
|
|
410
|
+
select?: { [C in keyof TCols]? : true };
|
|
411
|
+
where?: FilterType<TCols>;
|
|
412
|
+
orderBy?: OrderByType<TCols>;
|
|
413
|
+
limit?: number;
|
|
414
|
+
/** Nested includes — untyped until full model registry is threaded through. */
|
|
415
|
+
include?: Record<string, unknown>;
|
|
416
|
+
} : never) };
|
|
417
|
+
/** Extract the target table from a RelationDef. */
|
|
418
|
+
type RelationTarget<R> = R extends RelationDef<infer TTarget, "one" | "many"> ? TTarget : never;
|
|
419
|
+
/** Extract the relation type ('one' | 'many') from a RelationDef. */
|
|
420
|
+
type RelationType<R> = R extends RelationDef<TableDef<ColumnRecord>, infer TType> ? TType : never;
|
|
421
|
+
/**
|
|
422
|
+
* Resolve a single included relation.
|
|
423
|
+
* - 'one' relations return a single object
|
|
424
|
+
* - 'many' relations return an array
|
|
425
|
+
* - When a `select` sub-clause is provided, the result is narrowed
|
|
426
|
+
*/
|
|
427
|
+
type ResolveOneInclude<
|
|
428
|
+
R extends RelationDef,
|
|
429
|
+
TIncludeValue,
|
|
430
|
+
_Depth extends readonly unknown[] = []
|
|
431
|
+
> = TIncludeValue extends {
|
|
432
|
+
select: infer TSubSelect;
|
|
433
|
+
} ? RelationTarget<R> extends TableDef<infer TCols> ? SelectNarrow<TCols, TSubSelect> : never : RelationTarget<R> extends TableDef<infer TCols> ? SelectNarrow<TCols, undefined> : never;
|
|
434
|
+
/**
|
|
435
|
+
* IncludeResolve<TRelations, TInclude, Depth> — resolves all included relations.
|
|
436
|
+
*
|
|
437
|
+
* Depth is tracked using a tuple counter. Default cap = 2.
|
|
438
|
+
*/
|
|
439
|
+
type IncludeResolve<
|
|
440
|
+
TRelations extends RelationsRecord,
|
|
441
|
+
TInclude,
|
|
442
|
+
_Depth extends readonly unknown[] = []
|
|
443
|
+
> = _Depth["length"] extends 3 ? unknown : { [K in keyof TInclude as K extends keyof TRelations ? TInclude[K] extends false | undefined ? never : K : never] : K extends keyof TRelations ? RelationType<TRelations[K]> extends "many" ? ResolveOneInclude<TRelations[K], TInclude[K], _Depth>[] : ResolveOneInclude<TRelations[K], TInclude[K], _Depth> : never };
|
|
444
|
+
/** Query options shape used by FindResult. */
|
|
445
|
+
interface FindOptions<
|
|
446
|
+
TColumns extends ColumnRecord = ColumnRecord,
|
|
447
|
+
TRelations extends RelationsRecord = RelationsRecord
|
|
448
|
+
> {
|
|
449
|
+
select?: SelectOption<TColumns>;
|
|
450
|
+
include?: IncludeOption<TRelations>;
|
|
451
|
+
where?: FilterType<TColumns>;
|
|
452
|
+
orderBy?: OrderByType<TColumns>;
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* FindResult<TTable, TOptions> — the return type of a typed query.
|
|
456
|
+
*
|
|
457
|
+
* Combines:
|
|
458
|
+
* - SelectNarrow for column selection
|
|
459
|
+
* - IncludeResolve for relation includes
|
|
460
|
+
*
|
|
461
|
+
* TOptions is structurally typed (not constrained to FindOptions) so that
|
|
462
|
+
* literal option objects flow through without widening.
|
|
463
|
+
*/
|
|
464
|
+
type FindResult<
|
|
465
|
+
TTable extends TableDef<ColumnRecord>,
|
|
466
|
+
TOptions = unknown,
|
|
467
|
+
TRelations extends RelationsRecord = RelationsRecord
|
|
468
|
+
> = TTable extends TableDef<infer TColumns> ? SelectNarrow<TColumns, TOptions extends {
|
|
469
|
+
select: infer S;
|
|
470
|
+
} ? S : undefined> & (TOptions extends {
|
|
471
|
+
include: infer I;
|
|
472
|
+
} ? IncludeResolve<TRelations, I> : unknown) : never;
|
|
473
|
+
/**
|
|
474
|
+
* InsertInput<TTable> — standalone insert type utility.
|
|
475
|
+
* Makes columns with defaults optional, all others required.
|
|
476
|
+
*/
|
|
477
|
+
type InsertInput<TTable extends TableDef<ColumnRecord>> = TTable["$insert"];
|
|
478
|
+
/**
|
|
479
|
+
* UpdateInput<TTable> — standalone update type utility.
|
|
480
|
+
* All non-PK columns, all optional.
|
|
481
|
+
*/
|
|
482
|
+
type UpdateInput<TTable extends TableDef<ColumnRecord>> = TTable["$update"];
|
|
483
|
+
/** A model entry in the database registry, pairing a table with its relations. */
|
|
484
|
+
interface ModelEntry<
|
|
485
|
+
TTable extends TableDef<ColumnRecord> = TableDef<ColumnRecord>,
|
|
486
|
+
TRelations extends RelationsRecord = RelationsRecord
|
|
487
|
+
> {
|
|
488
|
+
readonly table: TTable;
|
|
489
|
+
readonly relations: TRelations;
|
|
490
|
+
}
|
|
293
491
|
/**
|
|
294
|
-
* Database
|
|
492
|
+
* Database<TModels> — type that carries the full model registry.
|
|
295
493
|
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
494
|
+
* Used as the foundation for typed query methods (implemented in later tickets).
|
|
495
|
+
* Provides type-safe access to table definitions and their relations.
|
|
298
496
|
*/
|
|
299
|
-
interface
|
|
497
|
+
interface Database<TModels extends Record<string, ModelEntry> = Record<string, ModelEntry>> {
|
|
498
|
+
readonly _models: TModels;
|
|
499
|
+
}
|
|
500
|
+
/** A single include entry with optional query constraints. */
|
|
501
|
+
interface AdapterIncludeEntry {
|
|
502
|
+
select?: Record<string, true>;
|
|
300
503
|
where?: Record<string, unknown>;
|
|
301
504
|
orderBy?: Record<string, "asc" | "desc">;
|
|
302
505
|
limit?: number;
|
|
506
|
+
include?: Record<string, unknown>;
|
|
507
|
+
}
|
|
508
|
+
/** Include specification: maps relation names to `true` or structured entries. */
|
|
509
|
+
type AdapterIncludeSpec = Record<string, true | AdapterIncludeEntry>;
|
|
510
|
+
/**
|
|
511
|
+
* Resolves the where clause type for a given entry.
|
|
512
|
+
* When TEntry is the default (unparameterized), falls back to Record<string, unknown>.
|
|
513
|
+
*/
|
|
514
|
+
type ResolveWhere<TEntry extends ModelEntry> = TEntry extends ModelEntry<infer TTable> ? TTable extends TableDef<infer TCols> ? [ColumnRecord] extends [TCols] ? Record<string, unknown> : FilterType<TCols> : Record<string, unknown> : Record<string, unknown>;
|
|
515
|
+
/**
|
|
516
|
+
* Resolves the orderBy type for a given entry.
|
|
517
|
+
* When TEntry is the default (unparameterized), falls back to Record<string, 'asc' | 'desc'>.
|
|
518
|
+
*/
|
|
519
|
+
type ResolveOrderBy<TEntry extends ModelEntry> = TEntry extends ModelEntry<infer TTable> ? TTable extends TableDef<infer TCols> ? [ColumnRecord] extends [TCols] ? Record<string, "asc" | "desc"> : OrderByType<TCols> : Record<string, "asc" | "desc"> : Record<string, "asc" | "desc">;
|
|
520
|
+
/**
|
|
521
|
+
* Resolves the include type for a given entry.
|
|
522
|
+
* When TEntry is the default (unparameterized), falls back to AdapterIncludeSpec.
|
|
523
|
+
*/
|
|
524
|
+
type ResolveInclude<TEntry extends ModelEntry> = TEntry extends ModelEntry<TableDef<ColumnRecord>, infer TRels> ? [Record<string, never>] extends [TRels] ? AdapterIncludeSpec : IncludeOption<TRels> : AdapterIncludeSpec;
|
|
525
|
+
interface ListOptions<TEntry extends ModelEntry = ModelEntry> {
|
|
526
|
+
where?: ResolveWhere<TEntry>;
|
|
527
|
+
orderBy?: ResolveOrderBy<TEntry>;
|
|
528
|
+
limit?: number;
|
|
303
529
|
/** Cursor-based pagination: fetch records after this ID. */
|
|
304
530
|
after?: string;
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
531
|
+
/** Relation include specification for relation loading. */
|
|
532
|
+
include?: ResolveInclude<TEntry>;
|
|
533
|
+
}
|
|
534
|
+
/** Options for get-by-id operations. */
|
|
535
|
+
interface GetOptions<TEntry extends ModelEntry = ModelEntry> {
|
|
536
|
+
/** Relation include specification for relation loading. */
|
|
537
|
+
include?: ResolveInclude<TEntry>;
|
|
538
|
+
}
|
|
539
|
+
interface EntityDbAdapter<TEntry extends ModelEntry = ModelEntry> {
|
|
540
|
+
get(id: string, options?: GetOptions<TEntry>): Promise<TEntry["table"]["$response"] | null>;
|
|
541
|
+
list(options?: ListOptions<TEntry>): Promise<{
|
|
542
|
+
data: TEntry["table"]["$response"][];
|
|
310
543
|
total: number;
|
|
311
544
|
}>;
|
|
312
|
-
create(data:
|
|
313
|
-
update(id: string, data:
|
|
314
|
-
delete(id: string): Promise<
|
|
545
|
+
create(data: TEntry["table"]["$create_input"]): Promise<TEntry["table"]["$response"]>;
|
|
546
|
+
update(id: string, data: TEntry["table"]["$update_input"]): Promise<TEntry["table"]["$response"]>;
|
|
547
|
+
delete(id: string): Promise<TEntry["table"]["$response"] | null>;
|
|
315
548
|
}
|
|
316
549
|
interface D1DatabaseBinding {
|
|
317
550
|
prepare(sql: string): D1PreparedStatement;
|
|
@@ -641,201 +874,6 @@ declare function toReadError(error: unknown, query?: string): ReadError;
|
|
|
641
874
|
*/
|
|
642
875
|
declare function toWriteError(error: unknown, query?: string): WriteError;
|
|
643
876
|
/**
|
|
644
|
-
* Query executor — wraps raw SQL execution with error mapping.
|
|
645
|
-
*
|
|
646
|
-
* Takes a query function (from the database driver) and wraps it to:
|
|
647
|
-
* 1. Execute parameterized SQL
|
|
648
|
-
* 2. Map PG errors to typed DbError subclasses
|
|
649
|
-
* 3. Return typed QueryResult
|
|
650
|
-
*/
|
|
651
|
-
interface ExecutorResult<T> {
|
|
652
|
-
readonly rows: readonly T[];
|
|
653
|
-
readonly rowCount: number;
|
|
654
|
-
}
|
|
655
|
-
type QueryFn = <T>(sql: string, params: readonly unknown[]) => Promise<ExecutorResult<T>>;
|
|
656
|
-
/** Operators available for comparable types (number, string, Date, bigint). */
|
|
657
|
-
interface ComparisonOperators<T> {
|
|
658
|
-
readonly eq?: T;
|
|
659
|
-
readonly ne?: T;
|
|
660
|
-
readonly gt?: T;
|
|
661
|
-
readonly gte?: T;
|
|
662
|
-
readonly lt?: T;
|
|
663
|
-
readonly lte?: T;
|
|
664
|
-
readonly in?: readonly T[];
|
|
665
|
-
readonly notIn?: readonly T[];
|
|
666
|
-
}
|
|
667
|
-
/** Additional operators for string columns. */
|
|
668
|
-
interface StringOperators {
|
|
669
|
-
readonly contains?: string;
|
|
670
|
-
readonly startsWith?: string;
|
|
671
|
-
readonly endsWith?: string;
|
|
672
|
-
}
|
|
673
|
-
/** The `isNull` operator — only available for nullable columns. */
|
|
674
|
-
interface NullOperator {
|
|
675
|
-
readonly isNull?: boolean;
|
|
676
|
-
}
|
|
677
|
-
/**
|
|
678
|
-
* Resolves the filter operators for a single column based on its inferred type
|
|
679
|
-
* and nullable metadata.
|
|
680
|
-
*
|
|
681
|
-
* - All types get comparison + in/notIn
|
|
682
|
-
* - String types additionally get contains, startsWith, endsWith
|
|
683
|
-
* - Nullable columns additionally get isNull
|
|
684
|
-
*
|
|
685
|
-
* Uses [T] extends [string] to prevent union distribution -- ensures that a
|
|
686
|
-
* union like 'admin' | 'editor' keeps the full union in each operator slot.
|
|
687
|
-
*/
|
|
688
|
-
type ColumnFilterOperators<
|
|
689
|
-
TType,
|
|
690
|
-
TNullable extends boolean
|
|
691
|
-
> = ([TType] extends [string] ? ComparisonOperators<TType> & StringOperators : ComparisonOperators<TType>) & (TNullable extends true ? NullOperator : unknown);
|
|
692
|
-
/** Determine whether a column is nullable from its metadata. */
|
|
693
|
-
type IsNullable<C> = C extends ColumnBuilder<unknown, infer M> ? M extends {
|
|
694
|
-
readonly nullable: true;
|
|
695
|
-
} ? true : false : false;
|
|
696
|
-
/**
|
|
697
|
-
* FilterType<TColumns> — typed where clause.
|
|
698
|
-
*
|
|
699
|
-
* Each key maps to either:
|
|
700
|
-
* - A direct value (shorthand for `{ eq: value }`)
|
|
701
|
-
* - An object with typed filter operators
|
|
702
|
-
*/
|
|
703
|
-
type FilterType<TColumns extends ColumnRecord> = { [K in keyof TColumns]? : InferColumnType<TColumns[K]> | ColumnFilterOperators<InferColumnType<TColumns[K]>, IsNullable<TColumns[K]>> };
|
|
704
|
-
type OrderByType<TColumns extends ColumnRecord> = { [K in keyof TColumns]? : "asc" | "desc" };
|
|
705
|
-
/**
|
|
706
|
-
* SelectOption<TColumns> — the `select` field in query options.
|
|
707
|
-
*
|
|
708
|
-
* Either:
|
|
709
|
-
* - `{ not: Annotation | Annotation[] }` — exclude columns by annotation(s)
|
|
710
|
-
* - `{ [column]: true }` — explicitly pick columns
|
|
711
|
-
*
|
|
712
|
-
* The two forms are mutually exclusive, enforced via `never` mapped keys.
|
|
713
|
-
*/
|
|
714
|
-
type SelectOption<TColumns extends ColumnRecord> = ({
|
|
715
|
-
readonly not: AllAnnotations<TColumns> | readonly AllAnnotations<TColumns>[];
|
|
716
|
-
} & { readonly [K in keyof TColumns]? : never }) | ({ readonly [K in keyof TColumns]? : true } & {
|
|
717
|
-
readonly not?: never;
|
|
718
|
-
});
|
|
719
|
-
/** Extract selected keys from a select map (keys set to `true`). */
|
|
720
|
-
type SelectedKeys<
|
|
721
|
-
TColumns extends ColumnRecord,
|
|
722
|
-
TSelect
|
|
723
|
-
> = { [K in keyof TSelect] : K extends keyof TColumns ? (TSelect[K] extends true ? K : never) : never }[keyof TSelect];
|
|
724
|
-
/**
|
|
725
|
-
* Normalize `not` value to a union of annotation strings.
|
|
726
|
-
* - `'annotation'` → `'annotation'`
|
|
727
|
-
* - `readonly ['a', 'b']` → `'a' | 'b'`
|
|
728
|
-
*/
|
|
729
|
-
type NormalizeAnnotations<T> = T extends readonly (infer F)[] ? F extends string ? F : never : T extends string ? T : never;
|
|
730
|
-
/**
|
|
731
|
-
* SelectNarrow<TColumns, TSelect> — applies a select clause to narrow the result type.
|
|
732
|
-
*
|
|
733
|
-
* - `{ not: 'sensitive' }` → excludes 'sensitive'-annotated AND 'hidden'-annotated columns
|
|
734
|
-
* - `{ not: ['sensitive', 'patchable'] }` → excludes columns with ANY listed annotation + 'hidden'
|
|
735
|
-
* - `{ id: true, name: true }` → picks only id and name
|
|
736
|
-
* - `undefined` → default: excludes 'hidden'-annotated columns ($infer behavior)
|
|
737
|
-
*/
|
|
738
|
-
type SelectNarrow<
|
|
739
|
-
TColumns extends ColumnRecord,
|
|
740
|
-
TSelect
|
|
741
|
-
> = TSelect extends {
|
|
742
|
-
not: infer TNot;
|
|
743
|
-
} ? { [K in ColumnKeysWithoutAnyAnnotation<TColumns, NormalizeAnnotations<TNot> | "hidden"> & keyof TColumns] : InferColumnType<TColumns[K]> } : TSelect extends Record<string, true | undefined> ? { [K in SelectedKeys<TColumns, TSelect> & keyof TColumns] : InferColumnType<TColumns[K]> } : { [K in ColumnKeysWithoutAnyAnnotation<TColumns, "hidden"> & keyof TColumns] : InferColumnType<TColumns[K]> };
|
|
744
|
-
/** Relations record — maps relation names to RelationDef. */
|
|
745
|
-
type RelationsRecord = Record<string, RelationDef>;
|
|
746
|
-
/**
|
|
747
|
-
* The shape of include options for a given relations record.
|
|
748
|
-
* Each relation can be:
|
|
749
|
-
* - `true` — include with default fields
|
|
750
|
-
* - An object with optional `select` clause for narrowing
|
|
751
|
-
*/
|
|
752
|
-
type IncludeOption<TRelations extends RelationsRecord> = { [K in keyof TRelations]? : true | {
|
|
753
|
-
select?: Record<string, true>;
|
|
754
|
-
} };
|
|
755
|
-
/** Extract the target table from a RelationDef. */
|
|
756
|
-
type RelationTarget<R> = R extends RelationDef<infer TTarget, "one" | "many"> ? TTarget : never;
|
|
757
|
-
/** Extract the relation type ('one' | 'many') from a RelationDef. */
|
|
758
|
-
type RelationType<R> = R extends RelationDef<TableDef<ColumnRecord>, infer TType> ? TType : never;
|
|
759
|
-
/**
|
|
760
|
-
* Resolve a single included relation.
|
|
761
|
-
* - 'one' relations return a single object
|
|
762
|
-
* - 'many' relations return an array
|
|
763
|
-
* - When a `select` sub-clause is provided, the result is narrowed
|
|
764
|
-
*/
|
|
765
|
-
type ResolveOneInclude<
|
|
766
|
-
R extends RelationDef,
|
|
767
|
-
TIncludeValue,
|
|
768
|
-
_Depth extends readonly unknown[] = []
|
|
769
|
-
> = TIncludeValue extends {
|
|
770
|
-
select: infer TSubSelect;
|
|
771
|
-
} ? RelationTarget<R> extends TableDef<infer TCols> ? SelectNarrow<TCols, TSubSelect> : never : RelationTarget<R> extends TableDef<infer TCols> ? SelectNarrow<TCols, undefined> : never;
|
|
772
|
-
/**
|
|
773
|
-
* IncludeResolve<TRelations, TInclude, Depth> — resolves all included relations.
|
|
774
|
-
*
|
|
775
|
-
* Depth is tracked using a tuple counter. Default cap = 2.
|
|
776
|
-
*/
|
|
777
|
-
type IncludeResolve<
|
|
778
|
-
TRelations extends RelationsRecord,
|
|
779
|
-
TInclude,
|
|
780
|
-
_Depth extends readonly unknown[] = []
|
|
781
|
-
> = _Depth["length"] extends 3 ? unknown : { [K in keyof TInclude as K extends keyof TRelations ? TInclude[K] extends false | undefined ? never : K : never] : K extends keyof TRelations ? RelationType<TRelations[K]> extends "many" ? ResolveOneInclude<TRelations[K], TInclude[K], _Depth>[] : ResolveOneInclude<TRelations[K], TInclude[K], _Depth> : never };
|
|
782
|
-
/** Query options shape used by FindResult. */
|
|
783
|
-
interface FindOptions<
|
|
784
|
-
TColumns extends ColumnRecord = ColumnRecord,
|
|
785
|
-
TRelations extends RelationsRecord = RelationsRecord
|
|
786
|
-
> {
|
|
787
|
-
select?: SelectOption<TColumns>;
|
|
788
|
-
include?: IncludeOption<TRelations>;
|
|
789
|
-
where?: FilterType<TColumns>;
|
|
790
|
-
orderBy?: OrderByType<TColumns>;
|
|
791
|
-
}
|
|
792
|
-
/**
|
|
793
|
-
* FindResult<TTable, TOptions> — the return type of a typed query.
|
|
794
|
-
*
|
|
795
|
-
* Combines:
|
|
796
|
-
* - SelectNarrow for column selection
|
|
797
|
-
* - IncludeResolve for relation includes
|
|
798
|
-
*
|
|
799
|
-
* TOptions is structurally typed (not constrained to FindOptions) so that
|
|
800
|
-
* literal option objects flow through without widening.
|
|
801
|
-
*/
|
|
802
|
-
type FindResult<
|
|
803
|
-
TTable extends TableDef<ColumnRecord>,
|
|
804
|
-
TOptions = unknown,
|
|
805
|
-
TRelations extends RelationsRecord = RelationsRecord
|
|
806
|
-
> = TTable extends TableDef<infer TColumns> ? SelectNarrow<TColumns, TOptions extends {
|
|
807
|
-
select: infer S;
|
|
808
|
-
} ? S : undefined> & (TOptions extends {
|
|
809
|
-
include: infer I;
|
|
810
|
-
} ? IncludeResolve<TRelations, I> : unknown) : never;
|
|
811
|
-
/**
|
|
812
|
-
* InsertInput<TTable> — standalone insert type utility.
|
|
813
|
-
* Makes columns with defaults optional, all others required.
|
|
814
|
-
*/
|
|
815
|
-
type InsertInput<TTable extends TableDef<ColumnRecord>> = TTable["$insert"];
|
|
816
|
-
/**
|
|
817
|
-
* UpdateInput<TTable> — standalone update type utility.
|
|
818
|
-
* All non-PK columns, all optional.
|
|
819
|
-
*/
|
|
820
|
-
type UpdateInput<TTable extends TableDef<ColumnRecord>> = TTable["$update"];
|
|
821
|
-
/** A model entry in the database registry, pairing a table with its relations. */
|
|
822
|
-
interface ModelEntry<
|
|
823
|
-
TTable extends TableDef<ColumnRecord> = TableDef<ColumnRecord>,
|
|
824
|
-
TRelations extends RelationsRecord = RelationsRecord
|
|
825
|
-
> {
|
|
826
|
-
readonly table: TTable;
|
|
827
|
-
readonly relations: TRelations;
|
|
828
|
-
}
|
|
829
|
-
/**
|
|
830
|
-
* Database<TModels> — type that carries the full model registry.
|
|
831
|
-
*
|
|
832
|
-
* Used as the foundation for typed query methods (implemented in later tickets).
|
|
833
|
-
* Provides type-safe access to table definitions and their relations.
|
|
834
|
-
*/
|
|
835
|
-
interface Database<TModels extends Record<string, ModelEntry> = Record<string, ModelEntry>> {
|
|
836
|
-
readonly _models: TModels;
|
|
837
|
-
}
|
|
838
|
-
/**
|
|
839
877
|
* SQL tagged template literal and escape hatch.
|
|
840
878
|
*
|
|
841
879
|
* Provides a safe, composable way to write raw SQL with automatic parameterization.
|
|
@@ -1089,9 +1127,26 @@ interface DatabaseInternals<TModels extends Record<string, ModelEntry>> {
|
|
|
1089
1127
|
/** The computed tenant scoping graph. */
|
|
1090
1128
|
readonly tenantGraph: TenantGraph;
|
|
1091
1129
|
}
|
|
1130
|
+
/**
|
|
1131
|
+
* Scoped client for use within a transaction callback.
|
|
1132
|
+
* Provides the same model delegates and raw query as DatabaseClient —
|
|
1133
|
+
* all operations execute within a single atomic transaction.
|
|
1134
|
+
*
|
|
1135
|
+
* Auto-commits on success, auto-rolls-back on error.
|
|
1136
|
+
*/
|
|
1137
|
+
type TransactionClient<TModels extends Record<string, ModelEntry>> = { readonly [K in keyof TModels] : ModelDelegate<TModels[K]> } & {
|
|
1138
|
+
/** Execute a raw SQL query within the transaction. */
|
|
1139
|
+
query<T = Record<string, unknown>>(fragment: SqlFragment): Promise<Result<QueryResult<T>, ReadError>>;
|
|
1140
|
+
};
|
|
1092
1141
|
type DatabaseClient<TModels extends Record<string, ModelEntry>> = { readonly [K in keyof TModels] : ModelDelegate<TModels[K]> } & {
|
|
1093
1142
|
/** Execute a raw SQL query via the sql tagged template. */
|
|
1094
1143
|
query<T = Record<string, unknown>>(fragment: SqlFragment): Promise<Result<QueryResult<T>, ReadError>>;
|
|
1144
|
+
/**
|
|
1145
|
+
* Execute a callback within a database transaction.
|
|
1146
|
+
* All operations on the `tx` client are atomic — auto-commits on success,
|
|
1147
|
+
* auto-rolls-back if the callback throws.
|
|
1148
|
+
*/
|
|
1149
|
+
transaction<T>(fn: (tx: TransactionClient<TModels>) => Promise<T>): Promise<T>;
|
|
1095
1150
|
/** Close all pool connections. */
|
|
1096
1151
|
close(): Promise<void>;
|
|
1097
1152
|
/** Check if the database connection is healthy. */
|
|
@@ -1135,7 +1190,7 @@ declare function createDb<TModels extends Record<string, ModelEntry>>(options: C
|
|
|
1135
1190
|
declare function createDatabaseBridgeAdapter<
|
|
1136
1191
|
TModels extends Record<string, ModelEntry>,
|
|
1137
1192
|
TName extends keyof TModels & string
|
|
1138
|
-
>(db: DatabaseClient<TModels>, tableName: TName): EntityDbAdapter
|
|
1193
|
+
>(db: DatabaseClient<TModels>, tableName: TName): EntityDbAdapter<TModels[TName]>;
|
|
1139
1194
|
interface SqliteAdapterOptions<T extends ColumnRecord> {
|
|
1140
1195
|
/** The table schema definition */
|
|
1141
1196
|
schema: TableDef<T>;
|
|
@@ -1655,4 +1710,4 @@ type StrictKeys<
|
|
|
1655
1710
|
TAllowed extends string,
|
|
1656
1711
|
TTable extends string
|
|
1657
1712
|
> = TRecord extends Record<string, unknown> ? { [K in keyof TRecord] : K extends TAllowed ? TRecord[K] : InvalidColumn<K & string, TTable> } : TRecord;
|
|
1658
|
-
export { validateIndexes, toWriteError, toReadError, resolveErrorCode, reset, push, parsePgError, parseMigrationName, migrateStatus, migrateDev, migrateDeploy, generateId, formatDiagnostic, explainError, diagnoseError, detectSchemaDrift, defineAnnotations, defaultSqliteDialect, defaultPostgresDialect, dbErrorToHttpError, d, createSqliteDriver2 as createSqliteDriver, createSqliteAdapter, createSnapshot, createRegistry, createPostgresDriver, createEnumRegistry, createDb, createDatabaseBridgeAdapter, createD1Driver, createD1Adapter, computeTenantGraph, baseline, WriteError, VarcharMeta, ValidateKeys, UpdateInput, UniqueConstraintErrorOptions, UniqueConstraintError, TenantGraph, TableDef, StrictKeys, SqliteDialect, SqliteAdapterOptions, SelectOption, SelectNarrow, SchemaSnapshot, SchemaLike, ResetResult, ResetOptions, RenameSuggestion, RelationDef, RegisteredEnum, ReadError, QueryResult, PushResult, PushOptions, PostgresDriver, PostgresDialect, PoolConfig, PgErrorInput, PgCodeToName, OrderByType, NotNullErrorOptions, NotNullError, NotFoundError, ModelSchemas, ModelOptions, ModelEntry, ModelDelegate, ModelDef, MixedSelectError, MigrationQueryFn, MigrationInfo, MigrationFile, MigrationError2 as MigrationError, MigrateStatusResult, MigrateStatusOptions, MigrateDevResult, MigrateDevOptions, MigrateDeployResult, MigrateDeployOptions, ListOptions, JsonbValidator, InvalidRelation, InvalidFilterType, InvalidColumn, InsertInput, InferColumnType, IndexType, IndexOptions, IndexDef, IncludeResolve, IncludeOption, HttpErrorResponse, FormatMeta, ForeignKeyErrorOptions, ForeignKeyError, FindResult, FindOptions, FilterType, EnumMeta, EntityDbAdapter, DriftEntry, Dialect, DiagnosticResult, DecimalMeta, DbQueryError, DbNotFoundError, DbErrorJson, DbErrorCodeValue, DbErrorCodeName, DbErrorCode, DbErrorBase, DbError, DbDriver, DbConstraintError, DbConnectionError, DatabaseInternals, DatabaseClient, Database, D1PreparedStatement, D1DatabaseBinding, D1AdapterOptions, CreateDbOptions, ConnectionPoolExhaustedError, ConnectionError, ColumnTypeMeta, ColumnMetadata, ColumnBuilder, CodeChange, CheckConstraintErrorOptions, CheckConstraintError, BaselineResult, BaselineOptions };
|
|
1713
|
+
export { validateIndexes, toWriteError, toReadError, resolveErrorCode, reset, push, parsePgError, parseMigrationName, migrateStatus, migrateDev, migrateDeploy, generateId, formatDiagnostic, explainError, diagnoseError, detectSchemaDrift, defineAnnotations, defaultSqliteDialect, defaultPostgresDialect, dbErrorToHttpError, d, createSqliteDriver2 as createSqliteDriver, createSqliteAdapter, createSnapshot, createRegistry, createPostgresDriver, createEnumRegistry, createDb, createDatabaseBridgeAdapter, createD1Driver, createD1Adapter, computeTenantGraph, baseline, WriteError, VarcharMeta, ValidateKeys, UpdateInput, UniqueConstraintErrorOptions, UniqueConstraintError, TransactionClient, TenantGraph, TableDef, StrictKeys, SqliteDialect, SqliteAdapterOptions, SelectOption, SelectNarrow, SchemaSnapshot, SchemaLike, ResetResult, ResetOptions, RenameSuggestion, RelationDef, RegisteredEnum, ReadError, QueryResult, PushResult, PushOptions, PostgresDriver, PostgresDialect, PoolConfig, PgErrorInput, PgCodeToName, OrderByType, NotNullErrorOptions, NotNullError, NotFoundError, ModelSchemas, ModelOptions, ModelEntry, ModelDelegate, ModelDef, MixedSelectError, MigrationQueryFn, MigrationInfo, MigrationFile, MigrationError2 as MigrationError, MigrateStatusResult, MigrateStatusOptions, MigrateDevResult, MigrateDevOptions, MigrateDeployResult, MigrateDeployOptions, ListOptions, JsonbValidator, InvalidRelation, InvalidFilterType, InvalidColumn, InsertInput, InferColumnType, IndexType, IndexOptions, IndexDef, IncludeResolve, IncludeOption, HttpErrorResponse, GetOptions, FormatMeta, ForeignKeyErrorOptions, ForeignKeyError, FindResult, FindOptions, FilterType, EnumMeta, EntityDbAdapter, DriftEntry, Dialect, DiagnosticResult, DecimalMeta, DbQueryError, DbNotFoundError, DbErrorJson, DbErrorCodeValue, DbErrorCodeName, DbErrorCode, DbErrorBase, DbError, DbDriver, DbConstraintError, DbConnectionError, DatabaseInternals, DatabaseClient, Database, D1PreparedStatement, D1DatabaseBinding, D1AdapterOptions, CreateDbOptions, ConnectionPoolExhaustedError, ConnectionError, ColumnTypeMeta, ColumnMetadata, ColumnBuilder, CodeChange, CheckConstraintErrorOptions, CheckConstraintError, BaselineResult, BaselineOptions, AdapterIncludeSpec, AdapterIncludeEntry };
|