@vertz/db 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +412 -694
- package/dist/d1/index.d.ts +241 -0
- package/dist/d1/index.js +8 -0
- package/dist/diagnostic/index.js +1 -1
- package/dist/index.d.ts +932 -626
- package/dist/index.js +1753 -533
- package/dist/internals.d.ts +96 -31
- package/dist/internals.js +8 -7
- package/dist/plugin/index.d.ts +1 -1
- package/dist/plugin/index.js +7 -3
- package/dist/postgres/index.d.ts +77 -0
- package/dist/postgres/index.js +7 -0
- package/dist/shared/{chunk-3f2grpak.js → chunk-0e1vy9qd.js} +147 -52
- package/dist/shared/chunk-2gd1fqcw.js +7 -0
- package/dist/shared/{chunk-xp022dyp.js → chunk-agyds4jw.js} +25 -19
- package/dist/shared/chunk-dvwe5jsq.js +7 -0
- package/dist/shared/chunk-fwk49jvg.js +302 -0
- package/dist/shared/chunk-j4kwq1gh.js +5 -0
- package/dist/shared/{chunk-wj026daz.js → chunk-k04v1jjx.js} +2 -2
- package/dist/shared/chunk-kb4tnn2k.js +26 -0
- package/dist/shared/chunk-ktbebkz5.js +48 -0
- package/dist/shared/chunk-rqe0prft.js +100 -0
- package/dist/shared/chunk-ssga2xea.js +9 -0
- package/dist/shared/{chunk-hrfdj0rr.js → chunk-v2qm94qp.js} +12 -2
- package/dist/sql/index.d.ts +61 -61
- package/dist/sql/index.js +2 -2
- package/dist/sqlite/index.d.ts +221 -0
- package/dist/sqlite/index.js +845 -0
- package/package.json +31 -4
package/dist/sql/index.d.ts
CHANGED
|
@@ -5,33 +5,69 @@
|
|
|
5
5
|
* to PostgreSQL column names (snake_case) and vice versa.
|
|
6
6
|
*/
|
|
7
7
|
/**
|
|
8
|
+
* Override map for custom casing conversions.
|
|
9
|
+
* Keys are camelCase, values are snake_case.
|
|
10
|
+
* Example: { 'oAuth': 'oauth', 'userID': 'user_id' }
|
|
11
|
+
*/
|
|
12
|
+
type CasingOverrides = Record<string, string>;
|
|
13
|
+
/**
|
|
8
14
|
* Convert a camelCase string to snake_case.
|
|
9
15
|
*
|
|
10
16
|
* Handles acronyms correctly:
|
|
11
17
|
* - "parseJSON" -> "parse_json"
|
|
12
18
|
* - "getHTTPSUrl" -> "get_https_url"
|
|
13
19
|
* - "htmlParser" -> "html_parser"
|
|
20
|
+
*
|
|
21
|
+
* @param str - The camelCase string to convert
|
|
22
|
+
* @param overrides - Optional map of camelCase -> snake_case overrides that take precedence
|
|
14
23
|
*/
|
|
15
|
-
declare function camelToSnake(str: string): string;
|
|
24
|
+
declare function camelToSnake(str: string, overrides?: CasingOverrides): string;
|
|
16
25
|
/**
|
|
17
26
|
* Convert a snake_case string to camelCase.
|
|
18
27
|
*
|
|
19
28
|
* - "first_name" -> "firstName"
|
|
20
29
|
* - "created_at_timestamp" -> "createdAtTimestamp"
|
|
21
|
-
*/
|
|
22
|
-
declare function snakeToCamel(str: string): string;
|
|
23
|
-
/**
|
|
24
|
-
* DELETE statement builder.
|
|
25
30
|
*
|
|
26
|
-
*
|
|
27
|
-
* -
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
* @param str - The snake_case string to convert
|
|
32
|
+
* @param overrides - Optional map of camelCase -> snake_case overrides (reverse lookup)
|
|
33
|
+
*/
|
|
34
|
+
declare function snakeToCamel(str: string, overrides?: CasingOverrides): string;
|
|
35
|
+
interface Dialect {
|
|
36
|
+
/** Dialect name. */
|
|
37
|
+
readonly name: "postgres" | "sqlite";
|
|
38
|
+
/**
|
|
39
|
+
* Parameter placeholder: $1, $2 (postgres) or ? (sqlite).
|
|
40
|
+
* @param index - 1-based parameter index
|
|
41
|
+
*/
|
|
42
|
+
param(index: number): string;
|
|
43
|
+
/** SQL function for current timestamp. */
|
|
44
|
+
now(): string;
|
|
45
|
+
/**
|
|
46
|
+
* Map a vertz column sqlType to the dialect's SQL type.
|
|
47
|
+
* @param sqlType - The generic sqlType from column metadata
|
|
48
|
+
* @param meta - Additional metadata (enum values, length, precision)
|
|
49
|
+
*/
|
|
50
|
+
mapColumnType(sqlType: string, meta?: ColumnTypeMeta): string;
|
|
51
|
+
/** Whether the dialect supports RETURNING clause. */
|
|
52
|
+
readonly supportsReturning: boolean;
|
|
53
|
+
/** Whether the dialect supports array operators (@>, <@, &&). */
|
|
54
|
+
readonly supportsArrayOps: boolean;
|
|
55
|
+
/** Whether the dialect supports JSONB path operators (->>, ->). */
|
|
56
|
+
readonly supportsJsonbPath: boolean;
|
|
57
|
+
}
|
|
58
|
+
interface ColumnTypeMeta {
|
|
59
|
+
readonly enumName?: string;
|
|
60
|
+
readonly enumValues?: readonly string[];
|
|
61
|
+
readonly length?: number;
|
|
62
|
+
readonly precision?: number;
|
|
63
|
+
readonly scale?: number;
|
|
64
|
+
}
|
|
31
65
|
interface DeleteOptions {
|
|
32
66
|
readonly table: string;
|
|
33
67
|
readonly where?: Record<string, unknown>;
|
|
34
68
|
readonly returning?: "*" | readonly string[];
|
|
69
|
+
/** SQL dialect to use. Defaults to postgres. */
|
|
70
|
+
readonly dialect?: Dialect;
|
|
35
71
|
}
|
|
36
72
|
interface DeleteResult {
|
|
37
73
|
readonly sql: string;
|
|
@@ -40,17 +76,7 @@ interface DeleteResult {
|
|
|
40
76
|
/**
|
|
41
77
|
* Build a DELETE statement from the given options.
|
|
42
78
|
*/
|
|
43
|
-
declare function buildDelete(options: DeleteOptions): DeleteResult;
|
|
44
|
-
/**
|
|
45
|
-
* INSERT statement builder.
|
|
46
|
-
*
|
|
47
|
-
* Generates parameterized INSERT queries with support for:
|
|
48
|
-
* - Single row and batch (multi-row VALUES) inserts
|
|
49
|
-
* - RETURNING clause with column aliasing
|
|
50
|
-
* - ON CONFLICT (upsert) — DO NOTHING or DO UPDATE SET
|
|
51
|
-
* - camelCase -> snake_case column conversion
|
|
52
|
-
* - "now" sentinel handling for timestamp defaults
|
|
53
|
-
*/
|
|
79
|
+
declare function buildDelete(options: DeleteOptions, dialect?: Dialect): DeleteResult;
|
|
54
80
|
interface OnConflictOptions {
|
|
55
81
|
readonly columns: readonly string[];
|
|
56
82
|
readonly action: "nothing" | "update";
|
|
@@ -65,6 +91,8 @@ interface InsertOptions {
|
|
|
65
91
|
readonly onConflict?: OnConflictOptions;
|
|
66
92
|
/** Column names (camelCase) that should use NOW() instead of a parameterized value when the value is "now". */
|
|
67
93
|
readonly nowColumns?: readonly string[];
|
|
94
|
+
/** SQL dialect to use. Defaults to postgres. */
|
|
95
|
+
readonly dialect?: Dialect;
|
|
68
96
|
}
|
|
69
97
|
interface InsertResult {
|
|
70
98
|
readonly sql: string;
|
|
@@ -73,18 +101,7 @@ interface InsertResult {
|
|
|
73
101
|
/**
|
|
74
102
|
* Build an INSERT statement from the given options.
|
|
75
103
|
*/
|
|
76
|
-
declare function buildInsert(options: InsertOptions): InsertResult;
|
|
77
|
-
/**
|
|
78
|
-
* SELECT statement builder.
|
|
79
|
-
*
|
|
80
|
-
* Generates parameterized SELECT queries with support for:
|
|
81
|
-
* - Column selection with camelCase -> snake_case conversion and aliasing
|
|
82
|
-
* - WHERE clause via the where builder
|
|
83
|
-
* - ORDER BY with direction
|
|
84
|
-
* - LIMIT / OFFSET pagination (parameterized)
|
|
85
|
-
* - Cursor-based pagination (cursor + take)
|
|
86
|
-
* - COUNT(*) OVER() for listAndCount
|
|
87
|
-
*/
|
|
104
|
+
declare function buildInsert(options: InsertOptions, dialect?: Dialect): InsertResult;
|
|
88
105
|
interface SelectOptions {
|
|
89
106
|
readonly table: string;
|
|
90
107
|
readonly columns?: readonly string[];
|
|
@@ -97,6 +114,10 @@ interface SelectOptions {
|
|
|
97
114
|
readonly cursor?: Record<string, unknown>;
|
|
98
115
|
/** Number of rows to take (used with cursor). Aliases `limit` when cursor is present. */
|
|
99
116
|
readonly take?: number;
|
|
117
|
+
/** Custom casing overrides for camelCase -> snake_case conversion. */
|
|
118
|
+
readonly casingOverrides?: CasingOverrides;
|
|
119
|
+
/** SQL dialect to use. Defaults to postgres. */
|
|
120
|
+
readonly dialect?: Dialect;
|
|
100
121
|
}
|
|
101
122
|
interface SelectResult {
|
|
102
123
|
readonly sql: string;
|
|
@@ -105,7 +126,7 @@ interface SelectResult {
|
|
|
105
126
|
/**
|
|
106
127
|
* Build a SELECT statement from the given options.
|
|
107
128
|
*/
|
|
108
|
-
declare function buildSelect(options: SelectOptions): SelectResult;
|
|
129
|
+
declare function buildSelect(options: SelectOptions, dialect?: Dialect): SelectResult;
|
|
109
130
|
/**
|
|
110
131
|
* SQL tagged template literal and escape hatch.
|
|
111
132
|
*
|
|
@@ -151,16 +172,6 @@ declare const sql: {
|
|
|
151
172
|
(strings: TemplateStringsArray, ...values: unknown[]): SqlFragment;
|
|
152
173
|
raw(value: string): SqlFragment;
|
|
153
174
|
};
|
|
154
|
-
/**
|
|
155
|
-
* UPDATE statement builder.
|
|
156
|
-
*
|
|
157
|
-
* Generates parameterized UPDATE queries with support for:
|
|
158
|
-
* - SET clause from a data object
|
|
159
|
-
* - WHERE clause via the where builder
|
|
160
|
-
* - RETURNING clause with column aliasing
|
|
161
|
-
* - camelCase -> snake_case column conversion
|
|
162
|
-
* - "now" sentinel handling for timestamp defaults
|
|
163
|
-
*/
|
|
164
175
|
interface UpdateOptions {
|
|
165
176
|
readonly table: string;
|
|
166
177
|
readonly data: Record<string, unknown>;
|
|
@@ -168,6 +179,8 @@ interface UpdateOptions {
|
|
|
168
179
|
readonly returning?: "*" | readonly string[];
|
|
169
180
|
/** Column names (camelCase) that should use NOW() instead of a parameterized value when the value is "now". */
|
|
170
181
|
readonly nowColumns?: readonly string[];
|
|
182
|
+
/** SQL dialect to use. Defaults to postgres. */
|
|
183
|
+
readonly dialect?: Dialect;
|
|
171
184
|
}
|
|
172
185
|
interface UpdateResult {
|
|
173
186
|
readonly sql: string;
|
|
@@ -176,22 +189,7 @@ interface UpdateResult {
|
|
|
176
189
|
/**
|
|
177
190
|
* Build an UPDATE statement from the given options.
|
|
178
191
|
*/
|
|
179
|
-
declare function buildUpdate(options: UpdateOptions): UpdateResult;
|
|
180
|
-
/**
|
|
181
|
-
* WHERE clause builder with parameterized queries.
|
|
182
|
-
*
|
|
183
|
-
* Supports all filter operators from the schema layer:
|
|
184
|
-
* - Comparison: eq, ne, gt, gte, lt, lte
|
|
185
|
-
* - String: contains, startsWith, endsWith
|
|
186
|
-
* - Set: in, notIn
|
|
187
|
-
* - Null: isNull (true/false)
|
|
188
|
-
* - Logical: AND, OR, NOT
|
|
189
|
-
* - PostgreSQL array: arrayContains (@>), arrayContainedBy (<@), arrayOverlaps (&&)
|
|
190
|
-
* - JSONB path: metadata->key syntax
|
|
191
|
-
*
|
|
192
|
-
* All values are parameterized ($1, $2, ...) to prevent SQL injection.
|
|
193
|
-
* Column names are converted from camelCase to snake_case.
|
|
194
|
-
*/
|
|
192
|
+
declare function buildUpdate(options: UpdateOptions, dialect?: Dialect): UpdateResult;
|
|
195
193
|
interface WhereResult {
|
|
196
194
|
readonly sql: string;
|
|
197
195
|
readonly params: readonly unknown[];
|
|
@@ -207,7 +205,9 @@ interface WhereFilter {
|
|
|
207
205
|
*
|
|
208
206
|
* @param filter - The filter object with column conditions
|
|
209
207
|
* @param paramOffset - Starting parameter offset (0-based, params start at $offset+1)
|
|
208
|
+
* @param overrides - Optional casing overrides for camelCase -> snake_case conversion
|
|
209
|
+
* @param dialect - SQL dialect for parameter placeholders and feature checks
|
|
210
210
|
* @returns WhereResult with the SQL string (without WHERE keyword) and parameter values
|
|
211
211
|
*/
|
|
212
|
-
declare function buildWhere(filter: WhereFilter | undefined, paramOffset?: number): WhereResult;
|
|
212
|
+
declare function buildWhere(filter: WhereFilter | undefined, paramOffset?: number, overrides?: CasingOverrides, dialect?: Dialect): WhereResult;
|
|
213
213
|
export { sql, snakeToCamel, camelToSnake, buildWhere, buildUpdate, buildSelect, buildInsert, buildDelete, WhereResult, UpdateResult, UpdateOptions, SqlFragment, SelectResult, SelectOptions, OnConflictOptions, InsertResult, InsertOptions, DeleteResult, DeleteOptions };
|
package/dist/sql/index.js
CHANGED
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
buildSelect,
|
|
5
5
|
buildUpdate,
|
|
6
6
|
buildWhere
|
|
7
|
-
} from "../shared/chunk-
|
|
7
|
+
} from "../shared/chunk-0e1vy9qd.js";
|
|
8
8
|
import {
|
|
9
9
|
camelToSnake,
|
|
10
10
|
snakeToCamel
|
|
11
|
-
} from "../shared/chunk-
|
|
11
|
+
} from "../shared/chunk-v2qm94qp.js";
|
|
12
12
|
// src/sql/tagged.ts
|
|
13
13
|
function isSqlFragment(value) {
|
|
14
14
|
return typeof value === "object" && value !== null && "_tag" in value && value._tag === "SqlFragment";
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database driver interface.
|
|
3
|
+
*
|
|
4
|
+
* Provides a unified interface for different database backends
|
|
5
|
+
* (PostgreSQL, SQLite/D1, etc.) with query and execute methods.
|
|
6
|
+
*/
|
|
7
|
+
interface DbDriver {
|
|
8
|
+
/**
|
|
9
|
+
* Execute a read query and return results.
|
|
10
|
+
*/
|
|
11
|
+
query<T = unknown>(sql: string, params?: unknown[]): Promise<T[]>;
|
|
12
|
+
/**
|
|
13
|
+
* Execute a write query and return affected row count.
|
|
14
|
+
*/
|
|
15
|
+
execute(sql: string, params?: unknown[]): Promise<{
|
|
16
|
+
rowsAffected: number;
|
|
17
|
+
}>;
|
|
18
|
+
/**
|
|
19
|
+
* Close the database connection.
|
|
20
|
+
*/
|
|
21
|
+
close(): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
interface JsonbValidator<T> {
|
|
24
|
+
parse(value: unknown): T;
|
|
25
|
+
}
|
|
26
|
+
interface ColumnMetadata {
|
|
27
|
+
readonly sqlType: string;
|
|
28
|
+
readonly primary: boolean;
|
|
29
|
+
readonly unique: boolean;
|
|
30
|
+
readonly nullable: boolean;
|
|
31
|
+
readonly hasDefault: boolean;
|
|
32
|
+
readonly _annotations: Record<string, true>;
|
|
33
|
+
readonly isReadOnly: boolean;
|
|
34
|
+
readonly isAutoUpdate: boolean;
|
|
35
|
+
readonly isTenant: boolean;
|
|
36
|
+
readonly references: {
|
|
37
|
+
readonly table: string;
|
|
38
|
+
readonly column: string;
|
|
39
|
+
} | null;
|
|
40
|
+
readonly check: string | null;
|
|
41
|
+
readonly defaultValue?: unknown;
|
|
42
|
+
readonly format?: string;
|
|
43
|
+
readonly length?: number;
|
|
44
|
+
readonly precision?: number;
|
|
45
|
+
readonly scale?: number;
|
|
46
|
+
readonly enumName?: string;
|
|
47
|
+
readonly enumValues?: readonly string[];
|
|
48
|
+
readonly validator?: JsonbValidator<unknown>;
|
|
49
|
+
readonly generate?: "cuid" | "uuid" | "nanoid";
|
|
50
|
+
}
|
|
51
|
+
/** Phantom symbol to carry the TypeScript type without a runtime value. */
|
|
52
|
+
declare const PhantomType: unique symbol;
|
|
53
|
+
interface ColumnBuilder<
|
|
54
|
+
TType,
|
|
55
|
+
TMeta extends ColumnMetadata = ColumnMetadata
|
|
56
|
+
> {
|
|
57
|
+
/** Phantom field -- only exists at the type level for inference. Do not access at runtime. */
|
|
58
|
+
readonly [PhantomType]: TType;
|
|
59
|
+
readonly _meta: TMeta;
|
|
60
|
+
primary(options?: {
|
|
61
|
+
generate?: "cuid" | "uuid" | "nanoid";
|
|
62
|
+
}): ColumnBuilder<TType, Omit<TMeta, "primary" | "hasDefault" | "generate"> & {
|
|
63
|
+
readonly primary: true;
|
|
64
|
+
readonly hasDefault: true;
|
|
65
|
+
readonly generate?: "cuid" | "uuid" | "nanoid";
|
|
66
|
+
}>;
|
|
67
|
+
unique(): ColumnBuilder<TType, Omit<TMeta, "unique"> & {
|
|
68
|
+
readonly unique: true;
|
|
69
|
+
}>;
|
|
70
|
+
nullable(): ColumnBuilder<TType | null, Omit<TMeta, "nullable"> & {
|
|
71
|
+
readonly nullable: true;
|
|
72
|
+
}>;
|
|
73
|
+
default(value: TType | "now"): ColumnBuilder<TType, Omit<TMeta, "hasDefault"> & {
|
|
74
|
+
readonly hasDefault: true;
|
|
75
|
+
readonly defaultValue: TType | "now";
|
|
76
|
+
}>;
|
|
77
|
+
is<TFlag extends string>(flag: TFlag): ColumnBuilder<TType, Omit<TMeta, "_annotations"> & {
|
|
78
|
+
readonly _annotations: TMeta["_annotations"] & { readonly [K in TFlag] : true };
|
|
79
|
+
}>;
|
|
80
|
+
readOnly(): ColumnBuilder<TType, Omit<TMeta, "isReadOnly"> & {
|
|
81
|
+
readonly isReadOnly: true;
|
|
82
|
+
}>;
|
|
83
|
+
autoUpdate(): ColumnBuilder<TType, Omit<TMeta, "isAutoUpdate" | "isReadOnly"> & {
|
|
84
|
+
readonly isAutoUpdate: true;
|
|
85
|
+
readonly isReadOnly: true;
|
|
86
|
+
}>;
|
|
87
|
+
check(sql: string): ColumnBuilder<TType, Omit<TMeta, "check"> & {
|
|
88
|
+
readonly check: string;
|
|
89
|
+
}>;
|
|
90
|
+
references(table: string, column?: string): ColumnBuilder<TType, Omit<TMeta, "references"> & {
|
|
91
|
+
readonly references: {
|
|
92
|
+
readonly table: string;
|
|
93
|
+
readonly column: string;
|
|
94
|
+
};
|
|
95
|
+
}>;
|
|
96
|
+
}
|
|
97
|
+
type InferColumnType<C> = C extends ColumnBuilder<infer T, ColumnMetadata> ? T : never;
|
|
98
|
+
interface IndexDef {
|
|
99
|
+
readonly columns: readonly string[];
|
|
100
|
+
readonly name?: string;
|
|
101
|
+
readonly unique?: boolean;
|
|
102
|
+
}
|
|
103
|
+
/** A record of column builders -- the shape passed to d.table(). */
|
|
104
|
+
type ColumnRecord = Record<string, ColumnBuilder<unknown, ColumnMetadata>>;
|
|
105
|
+
/** Extract the TypeScript type from every column in a record. */
|
|
106
|
+
type InferColumns<T extends ColumnRecord> = { [K in keyof T] : InferColumnType<T[K]> };
|
|
107
|
+
/** Keys of columns where a given metadata property is `true`. */
|
|
108
|
+
type ColumnKeysWhere<
|
|
109
|
+
T extends ColumnRecord,
|
|
110
|
+
Flag extends keyof ColumnMetadata
|
|
111
|
+
> = { [K in keyof T] : T[K] extends ColumnBuilder<unknown, infer M> ? M extends Record<Flag, true> ? K : never : never }[keyof T];
|
|
112
|
+
/** Keys of columns where a given metadata property is NOT `true` (i.e., false). */
|
|
113
|
+
type ColumnKeysWhereNot<
|
|
114
|
+
T extends ColumnRecord,
|
|
115
|
+
Flag extends keyof ColumnMetadata
|
|
116
|
+
> = { [K in keyof T] : T[K] extends ColumnBuilder<unknown, infer M> ? M extends Record<Flag, true> ? never : K : never }[keyof T];
|
|
117
|
+
/** Keys of columns that do NOT have ANY of the specified annotations in `_annotations`. */
|
|
118
|
+
type ColumnKeysWithoutAnyAnnotation<
|
|
119
|
+
T extends ColumnRecord,
|
|
120
|
+
Annotations extends string
|
|
121
|
+
> = { [K in keyof T] : T[K] extends ColumnBuilder<unknown, infer M> ? M["_annotations"] extends Record<Annotations, true> ? never : K : never }[keyof T];
|
|
122
|
+
/**
|
|
123
|
+
* $infer -- default SELECT type.
|
|
124
|
+
* Excludes columns annotated 'hidden'. Includes everything else.
|
|
125
|
+
*/
|
|
126
|
+
type Infer<T extends ColumnRecord> = { [K in ColumnKeysWithoutAnyAnnotation<T, "hidden">] : InferColumnType<T[K]> };
|
|
127
|
+
/**
|
|
128
|
+
* $infer_all -- all columns including hidden.
|
|
129
|
+
*/
|
|
130
|
+
type InferAll<T extends ColumnRecord> = InferColumns<T>;
|
|
131
|
+
/**
|
|
132
|
+
* $insert -- write type. ALL columns included (visibility is read-side only).
|
|
133
|
+
* Columns with hasDefault: true become optional.
|
|
134
|
+
*/
|
|
135
|
+
type Insert<T extends ColumnRecord> = { [K in ColumnKeysWhereNot<T, "hasDefault">] : InferColumnType<T[K]> } & { [K in ColumnKeysWhere<T, "hasDefault">]? : InferColumnType<T[K]> };
|
|
136
|
+
/**
|
|
137
|
+
* $update -- write type. ALL non-primary-key columns, all optional.
|
|
138
|
+
* Primary key excluded (you don't update a PK).
|
|
139
|
+
*/
|
|
140
|
+
type Update<T extends ColumnRecord> = { [K in ColumnKeysWhereNot<T, "primary">]? : InferColumnType<T[K]> };
|
|
141
|
+
/**
|
|
142
|
+
* $response -- API response shape. Excludes columns annotated 'hidden'.
|
|
143
|
+
*/
|
|
144
|
+
type Response<T extends ColumnRecord> = { [K in ColumnKeysWithoutAnyAnnotation<T, "hidden">] : InferColumnType<T[K]> };
|
|
145
|
+
/**
|
|
146
|
+
* $create_input -- API create input shape.
|
|
147
|
+
* Excludes readOnly and primary key columns.
|
|
148
|
+
* Columns with defaults are optional.
|
|
149
|
+
*/
|
|
150
|
+
type ApiCreateInput<T extends ColumnRecord> = { [K in ColumnKeysWhereNot<T, "isReadOnly"> & ColumnKeysWhereNot<T, "primary"> & ColumnKeysWhereNot<T, "hasDefault"> & string] : InferColumnType<T[K]> } & { [K in ColumnKeysWhereNot<T, "isReadOnly"> & ColumnKeysWhereNot<T, "primary"> & ColumnKeysWhere<T, "hasDefault"> & string]? : InferColumnType<T[K]> };
|
|
151
|
+
/**
|
|
152
|
+
* $update_input -- API update input shape.
|
|
153
|
+
* Excludes readOnly and primary key columns. All fields optional (partial update).
|
|
154
|
+
*/
|
|
155
|
+
type ApiUpdateInput<T extends ColumnRecord> = { [K in ColumnKeysWhereNot<T, "isReadOnly"> & ColumnKeysWhereNot<T, "primary"> & string]? : InferColumnType<T[K]> };
|
|
156
|
+
interface TableDef<TColumns extends ColumnRecord = ColumnRecord> {
|
|
157
|
+
readonly _name: string;
|
|
158
|
+
readonly _columns: TColumns;
|
|
159
|
+
readonly _indexes: readonly IndexDef[];
|
|
160
|
+
readonly _shared: boolean;
|
|
161
|
+
/** Default SELECT type -- excludes columns annotated 'hidden'. */
|
|
162
|
+
readonly $infer: Infer<TColumns>;
|
|
163
|
+
/** All columns including hidden. */
|
|
164
|
+
readonly $infer_all: InferAll<TColumns>;
|
|
165
|
+
/** Insert type -- defaulted columns optional. ALL columns included. */
|
|
166
|
+
readonly $insert: Insert<TColumns>;
|
|
167
|
+
/** Update type -- all non-PK columns optional. ALL columns included. */
|
|
168
|
+
readonly $update: Update<TColumns>;
|
|
169
|
+
/** API response shape — excludes columns annotated 'hidden'. */
|
|
170
|
+
readonly $response: Response<TColumns>;
|
|
171
|
+
/** API create input — excludes readOnly + PK; defaulted columns optional. */
|
|
172
|
+
readonly $create_input: ApiCreateInput<TColumns>;
|
|
173
|
+
/** API update input — excludes readOnly + PK; all fields optional. */
|
|
174
|
+
readonly $update_input: ApiUpdateInput<TColumns>;
|
|
175
|
+
/** Mark this table as shared / cross-tenant. */
|
|
176
|
+
shared(): TableDef<TColumns>;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Database Adapter Types for @vertz/db
|
|
180
|
+
*
|
|
181
|
+
* Generic adapter interface that abstracts database operations.
|
|
182
|
+
* Implemented by SQLite, D1, and other database adapters.
|
|
183
|
+
*/
|
|
184
|
+
interface ListOptions {
|
|
185
|
+
where?: Record<string, unknown>;
|
|
186
|
+
orderBy?: Record<string, "asc" | "desc">;
|
|
187
|
+
limit?: number;
|
|
188
|
+
/** Cursor-based pagination: fetch records after this ID. */
|
|
189
|
+
after?: string;
|
|
190
|
+
}
|
|
191
|
+
interface EntityDbAdapter {
|
|
192
|
+
get(id: string): Promise<Record<string, unknown> | null>;
|
|
193
|
+
list(options?: ListOptions): Promise<{
|
|
194
|
+
data: Record<string, unknown>[];
|
|
195
|
+
total: number;
|
|
196
|
+
}>;
|
|
197
|
+
create(data: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
198
|
+
update(id: string, data: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
199
|
+
delete(id: string): Promise<Record<string, unknown> | null>;
|
|
200
|
+
}
|
|
201
|
+
interface SqliteAdapterOptions<T extends ColumnRecord> {
|
|
202
|
+
/** The table schema definition */
|
|
203
|
+
schema: TableDef<T>;
|
|
204
|
+
/** Path to the SQLite database file */
|
|
205
|
+
dbPath?: string;
|
|
206
|
+
/** Directory to store the database file (alternative to dbPath) */
|
|
207
|
+
dataDir?: string;
|
|
208
|
+
/** Auto-apply migrations on startup */
|
|
209
|
+
migrations?: {
|
|
210
|
+
autoApply?: boolean;
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Create a SQLite driver using bun:sqlite or better-sqlite3.
|
|
215
|
+
*/
|
|
216
|
+
declare function createSqliteDriver(dbPath: string): DbDriver;
|
|
217
|
+
/**
|
|
218
|
+
* Create a SQLite EntityDbAdapter from a schema.
|
|
219
|
+
*/
|
|
220
|
+
declare function createSqliteAdapter<T extends ColumnRecord>(options: SqliteAdapterOptions<T>): Promise<EntityDbAdapter>;
|
|
221
|
+
export { createSqliteDriver, createSqliteAdapter, SqliteAdapterOptions };
|