bun-query-builder 0.1.41 → 0.1.45
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/actions/migrate-rollback.d.ts +2 -1
- package/dist/bin/cli.js +211 -84
- package/dist/browser.d.ts +4 -16
- package/dist/config.d.ts +10 -1
- package/dist/db.d.ts +1 -0
- package/dist/drivers/index.d.ts +2 -0
- package/dist/drivers/mysql.d.ts +6 -0
- package/dist/drivers/singlestore.d.ts +28 -0
- package/dist/drivers/sqlite.d.ts +6 -0
- package/dist/dynamodb-single-table.d.ts +11 -23
- package/dist/index.d.ts +4 -1
- package/dist/migrations.d.ts +5 -0
- package/dist/orm.d.ts +122 -16
- package/dist/sqlite-pragmas.d.ts +30 -0
- package/dist/src/index.js +215 -83
- package/dist/types.d.ts +27 -1
- package/package.json +1 -1
package/dist/browser.d.ts
CHANGED
|
@@ -59,9 +59,9 @@ export declare function createBrowserModel<const TDef extends BrowserModelDefini
|
|
|
59
59
|
* @defaultValue
|
|
60
60
|
* ```ts
|
|
61
61
|
* {
|
|
62
|
-
* login: (credentials?: { email: string, password: string }): Promise<
|
|
62
|
+
* login: (credentials?: { email: string, password: string }): Promise<{ user: Record<string, unknown>, token: string }> {
|
|
63
63
|
* const response) => Promise<unknown>,
|
|
64
|
-
* register: (data?: { name: string, email: string, password: string }): Promise<
|
|
64
|
+
* register: (data?: { name: string, email: string, password: string }): Promise<{ user: Record<string, unknown>, token: string }> {
|
|
65
65
|
* const response) => Promise<unknown>,
|
|
66
66
|
* logout: () => unknown,
|
|
67
67
|
* user: () => unknown,
|
|
@@ -73,11 +73,11 @@ export declare const browserAuth: {
|
|
|
73
73
|
/**
|
|
74
74
|
* Login and store token
|
|
75
75
|
*/
|
|
76
|
-
login: (credentials: { email: string, password: string }) => Promise
|
|
76
|
+
login: (credentials: { email: string, password: string }) => Promise<;
|
|
77
77
|
/**
|
|
78
78
|
* Register a new user
|
|
79
79
|
*/
|
|
80
|
-
register: (data: { name: string, email: string, password: string }) => Promise
|
|
80
|
+
register: (data: { name: string, email: string, password: string }) => Promise<;
|
|
81
81
|
/**
|
|
82
82
|
* Logout and clear token
|
|
83
83
|
*/
|
|
@@ -170,18 +170,6 @@ declare interface QueryState {
|
|
|
170
170
|
selectColumns: string[]
|
|
171
171
|
withRelations: string[]
|
|
172
172
|
}
|
|
173
|
-
/**
|
|
174
|
-
* Response shape returned by `browserAuth.login` / `browserAuth.register`.
|
|
175
|
-
* Lifted to a named type so the generated `.d.ts` doesn't carry a nested
|
|
176
|
-
* inline object literal in the return position — bun-plugin-dtsx has a
|
|
177
|
-
* bug where `Promise<{ ... }>` in that position emits as `Promise<;`,
|
|
178
|
-
* breaking downstream typecheck for any consumer that imports from
|
|
179
|
-
* `bun-query-builder/browser`.
|
|
180
|
-
*/
|
|
181
|
-
export declare interface BrowserAuthResponse {
|
|
182
|
-
user: Record<string, unknown>
|
|
183
|
-
token: string
|
|
184
|
-
}
|
|
185
173
|
// Primitive type mappings
|
|
186
174
|
declare type PrimitiveTypeMap = {
|
|
187
175
|
string: string
|
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import type { QueryBuilderConfig } from './types';
|
|
1
|
+
import type { QueryBuilderConfig, SupportedDialect } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Whether a dialect belongs to the MySQL wire-protocol family (MySQL itself or
|
|
4
|
+
* SingleStore). These share `?` placeholders, backtick identifier quoting,
|
|
5
|
+
* `ON DUPLICATE KEY UPDATE` upserts, `LAST_INSERT_ID()` id recovery, and the
|
|
6
|
+
* `YYYY-MM-DD HH:MM:SS` datetime literal shape. Runtime DML branches should key
|
|
7
|
+
* off this helper rather than `dialect === 'mysql'` so SingleStore inherits the
|
|
8
|
+
* same behavior; only DDL (see `SingleStoreDriver`) diverges.
|
|
9
|
+
*/
|
|
10
|
+
export declare function isMysqlLike(dialect?: SupportedDialect): boolean;
|
|
2
11
|
/**
|
|
3
12
|
* Get the placeholder format for the current dialect.
|
|
4
13
|
* PostgreSQL uses $1, $2, $3... while MySQL and SQLite use ?
|
package/dist/db.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Database } from 'bun:sqlite';
|
|
2
2
|
import { SQL } from 'bun';
|
|
3
3
|
import type { PoolConfig } from './types';
|
|
4
|
+
export declare function splitSqlStatements(sql: string): string[];
|
|
4
5
|
/**
|
|
5
6
|
* Map the qb-level `pool` config (ms-based, ergonomic) onto the Bun SQL
|
|
6
7
|
* driver's native option names (second resolution). Only the knobs Bun's
|
package/dist/drivers/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MySQLDriver } from './mysql';
|
|
2
2
|
import { PostgresDriver } from './postgres';
|
|
3
|
+
import { SingleStoreDriver } from './singlestore';
|
|
3
4
|
import { SQLiteDriver } from './sqlite';
|
|
4
5
|
import type { DialectDriver } from './postgres';
|
|
5
6
|
import type { SupportedDialect } from '../types';
|
|
@@ -29,6 +30,7 @@ export type {
|
|
|
29
30
|
export declare function getDialectDriver(dialect: SupportedDialect): DialectDriver;
|
|
30
31
|
export { MySQLDriver } from './mysql';
|
|
31
32
|
export { PostgresDriver } from './postgres';
|
|
33
|
+
export { SingleStoreDriver } from './singlestore';
|
|
32
34
|
export { SQLiteDriver } from './sqlite';
|
|
33
35
|
// DynamoDB driver (NoSQL)
|
|
34
36
|
export {
|
package/dist/drivers/mysql.d.ts
CHANGED
|
@@ -18,6 +18,11 @@ export declare interface DialectDriver {
|
|
|
18
18
|
recordMigrationQuery: () => string
|
|
19
19
|
}
|
|
20
20
|
export declare class MySQLDriver implements DialectDriver {
|
|
21
|
+
protected quoteIdentifier(id: string): string;
|
|
22
|
+
protected getColumnType(column: ColumnPlan): string;
|
|
23
|
+
protected getPrimaryKeyType(column: ColumnPlan): string;
|
|
24
|
+
protected getAutoIncrementClause(column: ColumnPlan): string;
|
|
25
|
+
protected getDefaultValue(column: ColumnPlan): string;
|
|
21
26
|
createEnumType(_enumTypeName: string, _values: string[]): string;
|
|
22
27
|
createTable(table: TablePlan): string;
|
|
23
28
|
createIndex(tableName: string, index: IndexPlan): string;
|
|
@@ -34,4 +39,5 @@ export declare class MySQLDriver implements DialectDriver {
|
|
|
34
39
|
createMigrationsTable(): string;
|
|
35
40
|
getExecutedMigrationsQuery(): string;
|
|
36
41
|
recordMigrationQuery(): string;
|
|
42
|
+
protected renderColumn(column: ColumnPlan): string;
|
|
37
43
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { MySQLDriver } from './mysql';
|
|
2
|
+
import type { IndexPlan, TablePlan } from '../migrations';
|
|
3
|
+
/**
|
|
4
|
+
* SingleStore DDL driver.
|
|
5
|
+
*
|
|
6
|
+
* SingleStore (formerly MemSQL) speaks the MySQL wire protocol, so runtime DML
|
|
7
|
+
* (placeholders, backtick quoting, `ON DUPLICATE KEY UPDATE`, `LAST_INSERT_ID`)
|
|
8
|
+
* is identical — see `isMysqlLike` in `config.ts`. Only the DDL diverges, which
|
|
9
|
+
* is what this driver customizes:
|
|
10
|
+
*
|
|
11
|
+
* - **Distributed tables.** Rows are hash-partitioned across leaf nodes by a
|
|
12
|
+
* `SHARD KEY`. When a model declares `shardKey`, we emit it; otherwise
|
|
13
|
+
* SingleStore shards on the primary key (or a random key for columnstore),
|
|
14
|
+
* so a plain MySQL-shaped `CREATE TABLE` still works.
|
|
15
|
+
* - **Storage engine.** `tableKind: 'columnstore'` (default for analytics
|
|
16
|
+
* workloads) emits `SORT KEY (...)`; `'rowstore'` emits `ROWSTORE`;
|
|
17
|
+
* `'reference'` emits a `REFERENCE` table (fully replicated, no shard key —
|
|
18
|
+
* ideal for small dimension tables that get JOINed everywhere).
|
|
19
|
+
* - **No foreign keys.** SingleStore does not support `FOREIGN KEY`
|
|
20
|
+
* constraints, so `addForeignKey` is a no-op (referential integrity is an
|
|
21
|
+
* application concern). This mirrors how the MySQL driver already treats
|
|
22
|
+
* enums (`createEnumType` → '').
|
|
23
|
+
*/
|
|
24
|
+
export declare class SingleStoreDriver extends MySQLDriver {
|
|
25
|
+
createTable(table: TablePlan): string;
|
|
26
|
+
addForeignKey(): string;
|
|
27
|
+
createIndex(tableName: string, index: IndexPlan): string;
|
|
28
|
+
}
|
package/dist/drivers/sqlite.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import type { ColumnPlan, IndexPlan, RebuildTableSpec, TablePlan } from '../migrations';
|
|
2
|
+
/**
|
|
3
|
+
* Whether a plan type belongs to the numeric family. Used by the `_id`
|
|
4
|
+
* safety net (numeric ids must store as INTEGER on SQLite) — non-numeric
|
|
5
|
+
* declared types must never be coerced by the name heuristic.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isNumericPlanType(type: string | undefined): boolean;
|
|
2
8
|
export declare interface DialectDriver {
|
|
3
9
|
createEnumType: (enumTypeName: string, values: string[]) => string
|
|
4
10
|
createTable: (table: TablePlan) => string
|
|
@@ -9,6 +9,7 @@ export declare function createSingleTableManager(config: SingleTableConfig): Sin
|
|
|
9
9
|
*/
|
|
10
10
|
export declare function createRepository<T extends Record<string, any>>(manager: SingleTableManager, entityName: string, options: DynamoDBQueryBuilderOptions): SingleTableRepository<T>;
|
|
11
11
|
/**
|
|
12
|
+
* Common single table design patterns
|
|
12
13
|
* @defaultValue
|
|
13
14
|
* ```ts
|
|
14
15
|
* {
|
|
@@ -16,11 +17,11 @@ export declare function createRepository<T extends Record<string, any>>(manager:
|
|
|
16
17
|
* oneToMany: (parentEntity: string,
|
|
17
18
|
* childEntity: string,
|
|
18
19
|
* parentIdField?: string,
|
|
19
|
-
* childIdField?: string,) =>
|
|
20
|
+
* childIdField?: string,) => { parent: SingleTableEntity, child: SingleTableEntity },
|
|
20
21
|
* manyToMany: (entityName: string,
|
|
21
22
|
* relationName: string,
|
|
22
23
|
* idField?: string,
|
|
23
|
-
* relatedIdField?: string,) =>
|
|
24
|
+
* relatedIdField?: string,) => { entity: SingleTableEntity, relation: SingleTableEntity },
|
|
24
25
|
* hierarchical: (entityName: string, rootIdField?: string, pathField?: string) => SingleTableEntity
|
|
25
26
|
* }
|
|
26
27
|
* ```
|
|
@@ -37,14 +38,20 @@ export declare const SingleTablePatterns: {
|
|
|
37
38
|
* Parent: PK=PARENT#<parentId>, SK=METADATA
|
|
38
39
|
* Child: PK=PARENT#<parentId>, SK=CHILD#<childId>
|
|
39
40
|
*/
|
|
40
|
-
oneToMany: (parentEntity: string,
|
|
41
|
+
oneToMany: (parentEntity: string,
|
|
42
|
+
childEntity: string,
|
|
43
|
+
parentIdField?: string,
|
|
44
|
+
childIdField?: string,) => ;
|
|
41
45
|
/**
|
|
42
46
|
* Many-to-many relationship pattern using adjacency list
|
|
43
47
|
* Entity: PK=ENTITY#<entityId>, SK=METADATA
|
|
44
48
|
* Relationship: PK=ENTITY#<entityId>, SK=RELATED#<relatedId>
|
|
45
49
|
* Inverse: PK=ENTITY#<relatedId>, SK=RELATED#<entityId> (via GSI)
|
|
46
50
|
*/
|
|
47
|
-
manyToMany: (entityName: string,
|
|
51
|
+
manyToMany: (entityName: string,
|
|
52
|
+
relationName: string,
|
|
53
|
+
idField?: string,
|
|
54
|
+
relatedIdField?: string,) => ;
|
|
48
55
|
/**
|
|
49
56
|
* Hierarchical data pattern (e.g., org chart, file system)
|
|
50
57
|
* PK: ROOT#<rootId>
|
|
@@ -93,25 +100,6 @@ export declare interface ManyToManyPattern {
|
|
|
93
100
|
entity: SingleTableEntity
|
|
94
101
|
relation: SingleTableEntity
|
|
95
102
|
}
|
|
96
|
-
/**
|
|
97
|
-
* Common single table design patterns
|
|
98
|
-
*/
|
|
99
|
-
/**
|
|
100
|
-
* Result shapes for relationship pattern helpers. Lifted to named
|
|
101
|
-
* interfaces so the generated `.d.ts` doesn't carry an inline object
|
|
102
|
-
* literal in the return position — bun-plugin-dtsx has a bug where
|
|
103
|
-
* `(...) => { ... }` in that position emits as `=> ;`, breaking
|
|
104
|
-
* downstream typecheck for any consumer importing from
|
|
105
|
-
* `bun-query-builder/dynamodb-single-table`.
|
|
106
|
-
*/
|
|
107
|
-
export declare interface OneToManyPattern {
|
|
108
|
-
parent: SingleTableEntity
|
|
109
|
-
child: SingleTableEntity
|
|
110
|
-
}
|
|
111
|
-
export declare interface ManyToManyPattern {
|
|
112
|
-
entity: SingleTableEntity
|
|
113
|
-
relation: SingleTableEntity
|
|
114
|
-
}
|
|
115
103
|
/**
|
|
116
104
|
* Single Table Design Manager
|
|
117
105
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// Resolve ambiguous re-exports by explicitly choosing which module's version to use
|
|
2
2
|
export type { WhereOperator } from './browser';
|
|
3
3
|
export type { ModelQueryBuilder } from './dynamodb/index';
|
|
4
|
-
export type { ColumnName } from './client';
|
|
4
|
+
export type { ColumnName, QueryBuilder } from './client';
|
|
5
|
+
export type { ModelRecord } from './schema';
|
|
6
|
+
export type { ModelDefinition as OrmModelDefinition, ModelStatic as OrmModelStatic } from './orm';
|
|
5
7
|
// Re-export the type-inference version of InferRelationNames (supports wrapped models)
|
|
6
8
|
// to resolve the ambiguity with orm.ts's InferRelationNames (which takes raw definitions)
|
|
7
9
|
export type { InferRelationNames } from './type-inference';
|
|
@@ -40,6 +42,7 @@ export * from './pivot';
|
|
|
40
42
|
export * from './orm';
|
|
41
43
|
export * from './schema';
|
|
42
44
|
export * from './seeder';
|
|
45
|
+
export * from './sqlite-pragmas';
|
|
43
46
|
export * from './type-inference';
|
|
44
47
|
export * from './types';
|
|
45
48
|
export { type ModelDefinition, defineModel } from './model';
|
package/dist/migrations.d.ts
CHANGED
|
@@ -61,6 +61,8 @@ export declare interface ColumnPlan {
|
|
|
61
61
|
defaultValue?: PrimitiveDefault
|
|
62
62
|
references?: { table: string, column: string, onDelete?: OnForeignKeyAction, onUpdate?: OnForeignKeyAction }
|
|
63
63
|
enumValues?: string[]
|
|
64
|
+
maxLength?: number
|
|
65
|
+
enumTypeName?: string
|
|
64
66
|
}
|
|
65
67
|
export declare interface IndexPlan {
|
|
66
68
|
name: string
|
|
@@ -72,6 +74,9 @@ export declare interface TablePlan {
|
|
|
72
74
|
table: string
|
|
73
75
|
columns: ColumnPlan[]
|
|
74
76
|
indexes: IndexPlan[]
|
|
77
|
+
shardKey?: string[]
|
|
78
|
+
sortKey?: string[]
|
|
79
|
+
tableKind?: 'rowstore' | 'columnstore' | 'reference'
|
|
75
80
|
}
|
|
76
81
|
export declare interface MigrationPlan {
|
|
77
82
|
dialect: SupportedDialect
|
package/dist/orm.d.ts
CHANGED
|
@@ -37,10 +37,8 @@ export declare function configureOrm(options: { database?: string | Database; ve
|
|
|
37
37
|
* low-level table setup).
|
|
38
38
|
*/
|
|
39
39
|
export declare function getDatabase(): Database;
|
|
40
|
-
/**
|
|
41
|
-
|
|
42
|
-
*/
|
|
43
|
-
export declare function createModel<const TDef extends ModelDefinition>(definition: TDef): void;
|
|
40
|
+
/** Create a model class from a definition with full type inference. */
|
|
41
|
+
export declare function createModel<const TDef extends ModelDefinition>(definition: TDef): ModelStatic<TDef>;
|
|
44
42
|
export declare function createTableFromModel(definition: ModelDefinition): Promise<void>;
|
|
45
43
|
export declare function seedModel(definition: ModelDefinition, count?: number, faker?: Record<string, unknown>): Promise<void>;
|
|
46
44
|
// Attribute definition with explicit type
|
|
@@ -111,6 +109,7 @@ export declare interface ModelDefinition {
|
|
|
111
109
|
readonly taggable?: boolean
|
|
112
110
|
readonly categorizable?: boolean
|
|
113
111
|
readonly commentables?: boolean
|
|
112
|
+
readonly commentable?: boolean
|
|
114
113
|
readonly useActivityLog?: boolean | object
|
|
115
114
|
readonly useSocials?: readonly string[]
|
|
116
115
|
}
|
|
@@ -128,11 +127,11 @@ export declare interface ModelDefinition {
|
|
|
128
127
|
readonly attributes: {
|
|
129
128
|
readonly [key: string]: TypedAttribute<unknown>
|
|
130
129
|
}
|
|
131
|
-
readonly get?: Record<string, (attributes:
|
|
132
|
-
readonly set?: Record<string, (attributes:
|
|
130
|
+
readonly get?: Record<string, (attributes: any) => unknown>
|
|
131
|
+
readonly set?: Record<string, (attributes: any) => unknown>
|
|
133
132
|
readonly scopes?: Record<string, (value: unknown) => unknown>
|
|
134
133
|
readonly indexes?: readonly object[]
|
|
135
|
-
readonly dashboard?: { readonly highlight?: boolean | number }
|
|
134
|
+
readonly dashboard?: { readonly enabled?: boolean; readonly highlight?: boolean | number }
|
|
136
135
|
readonly hooks?: {
|
|
137
136
|
readonly beforeCreate?: (data: Record<string, unknown>) => void | Promise<void>
|
|
138
137
|
readonly afterCreate?: (model: ModelHookInstance) => void | Promise<void>
|
|
@@ -179,6 +178,31 @@ declare interface ResolvedRelation {
|
|
|
179
178
|
pivotModelName?: string
|
|
180
179
|
pivotTimestamps?: boolean
|
|
181
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* Overloaded where/orWhere signatures for static model methods.
|
|
183
|
+
* Object literals cannot have overloaded methods, so we express them as an interface
|
|
184
|
+
* and intersect with the concrete model object via a type assertion.
|
|
185
|
+
*/
|
|
186
|
+
declare interface StaticWhereOverloads<TDef extends ModelDefinition> {
|
|
187
|
+
where<K extends ColumnName<TDef>>(
|
|
188
|
+
column: K,
|
|
189
|
+
value: K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown
|
|
190
|
+
): ModelQueryBuilder<TDef>
|
|
191
|
+
where<K extends ColumnName<TDef>>(
|
|
192
|
+
column: K,
|
|
193
|
+
operator: WhereOperator,
|
|
194
|
+
value: K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown
|
|
195
|
+
): ModelQueryBuilder<TDef>
|
|
196
|
+
orWhere<K extends ColumnName<TDef>>(
|
|
197
|
+
column: K,
|
|
198
|
+
value: K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown
|
|
199
|
+
): ModelQueryBuilder<TDef>
|
|
200
|
+
orWhere<K extends ColumnName<TDef>>(
|
|
201
|
+
column: K,
|
|
202
|
+
operator: WhereOperator,
|
|
203
|
+
value: K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown
|
|
204
|
+
): ModelQueryBuilder<TDef>
|
|
205
|
+
}
|
|
182
206
|
// Binding helper type for SQL queries
|
|
183
207
|
declare type Bindings = SQLQueryBindings[];
|
|
184
208
|
// Primitive type mappings
|
|
@@ -193,12 +217,17 @@ declare type PrimitiveTypeMap = {
|
|
|
193
217
|
declare type InferType<T> = T extends keyof PrimitiveTypeMap ? PrimitiveTypeMap[T] :
|
|
194
218
|
T extends readonly (infer U)[] ? U :
|
|
195
219
|
T extends (infer U)[] ? U :
|
|
220
|
+
T extends { validate: (value: infer U) => any } ? U :
|
|
196
221
|
unknown;
|
|
197
222
|
// Extract attribute keys from definition
|
|
198
223
|
declare type AttributeKeys<TDef extends ModelDefinition> = keyof TDef['attributes'] & string;
|
|
199
224
|
// Infer single attribute type
|
|
200
225
|
declare type InferAttributeType<TAttr> = TAttr extends { type: infer T } ? InferType<T> :
|
|
201
|
-
TAttr extends { factory: (faker: Faker) => infer R }
|
|
226
|
+
TAttr extends { factory: (faker: Faker) => infer R }
|
|
227
|
+
? [Exclude<R, null | undefined>] extends [never]
|
|
228
|
+
? TAttr extends { validation: { rule: infer V } } ? InferType<V> | Extract<R, null | undefined> : R
|
|
229
|
+
: R
|
|
230
|
+
: TAttr extends { validation: { rule: infer R } } ? InferType<R> :
|
|
202
231
|
unknown;
|
|
203
232
|
// Build the full attributes type from definition. Columns declared
|
|
204
233
|
// `nullable: true` admit null — mirrors InferAttributes in type-inference.ts.
|
|
@@ -207,6 +236,14 @@ declare type InferModelAttributes<TDef extends ModelDefinition> = {
|
|
|
207
236
|
? InferAttributeType<TDef['attributes'][K]> | null
|
|
208
237
|
: InferAttributeType<TDef['attributes'][K]>
|
|
209
238
|
}
|
|
239
|
+
declare type SnakeCase<S extends string> = S extends `${infer C}${infer Rest}`
|
|
240
|
+
? C extends Lowercase<C>
|
|
241
|
+
? `${C}${SnakeCase<Rest>}`
|
|
242
|
+
: `_${Lowercase<C>}${SnakeCase<Rest>}`
|
|
243
|
+
: S;
|
|
244
|
+
declare type SnakeCaseAttributes<TDef extends ModelDefinition> = {
|
|
245
|
+
[K in keyof InferModelAttributes<TDef> & string as SnakeCase<K>]: InferModelAttributes<TDef>[K]
|
|
246
|
+
}
|
|
210
247
|
// System fields added by traits. The primary-key column honors the model's
|
|
211
248
|
// declared `primaryKey` (default 'id') — a custom-pk model exposes THAT
|
|
212
249
|
// column, not a phantom 'id'. Mirrors InferAttributes in type-inference.ts.
|
|
@@ -219,9 +256,10 @@ declare type SystemFields<TDef extends ModelDefinition> = { [K in TDef extends {
|
|
|
219
256
|
(TDef['traits'] extends { useAuth: true | object } ? { two_factor_secret: string | null; public_key: string | null } : {}) &
|
|
220
257
|
(TDef['traits'] extends { billable: true | object } ? { stripe_id: string | null } : {});
|
|
221
258
|
// Complete model type
|
|
222
|
-
declare type ModelAttributes<TDef extends ModelDefinition> = InferModelAttributes<TDef> & SystemFields<TDef>;
|
|
259
|
+
declare type ModelAttributes<TDef extends ModelDefinition> = InferModelAttributes<TDef> & SnakeCaseAttributes<TDef> & SystemFields<TDef>;
|
|
223
260
|
// All valid column names
|
|
224
261
|
declare type ColumnName<TDef extends ModelDefinition> = | AttributeKeys<TDef>
|
|
262
|
+
| SnakeCase<AttributeKeys<TDef>>
|
|
225
263
|
| (TDef extends { primaryKey: infer PK extends string } ? PK : 'id')
|
|
226
264
|
| (TDef['traits'] extends { useUuid: true } ? 'uuid' : never)
|
|
227
265
|
| (TDef['traits'] extends { useTimestamps: true } ? 'created_at' | 'updated_at' : never)
|
|
@@ -238,6 +276,10 @@ declare type HiddenKeys<TDef extends ModelDefinition> = {
|
|
|
238
276
|
declare type FillableKeys<TDef extends ModelDefinition> = {
|
|
239
277
|
[K in AttributeKeys<TDef>]: TDef['attributes'][K] extends { fillable: true } ? K : never
|
|
240
278
|
}[AttributeKeys<TDef>];
|
|
279
|
+
declare type FillableAttributes<TDef extends ModelDefinition> = Partial<Pick<
|
|
280
|
+
ModelAttributes<TDef>,
|
|
281
|
+
FillableKeys<TDef> | SnakeCase<FillableKeys<TDef>>
|
|
282
|
+
>>;
|
|
241
283
|
// Numeric attribute columns — constrains aggregate methods (sum, avg, etc.)
|
|
242
284
|
declare type NumericColumns<TDef extends ModelDefinition> = {
|
|
243
285
|
[K in AttributeKeys<TDef>]: TDef['attributes'][K] extends { type: 'number' } ? K : never
|
|
@@ -280,6 +322,10 @@ declare type LoadedRelationValue<TDef, R extends string> = 'one' extends Relatio
|
|
|
280
322
|
: 'many' extends RelationCardinality<TDef, R>
|
|
281
323
|
? ModelInstance<any, any>[] | undefined
|
|
282
324
|
: ModelInstance<any, any>[] | ModelInstance<any, any> | null | undefined;
|
|
325
|
+
/** A hydrated model instance with its selected columns exposed as proxy properties. */
|
|
326
|
+
export type ModelRecord<TDef extends ModelDefinition, TSelected extends ColumnName<TDef> = ColumnName<TDef>,> = ModelInstance<TDef, TSelected>
|
|
327
|
+
& Pick<ModelAttributes<TDef>, Extract<TSelected, keyof ModelAttributes<TDef>>>
|
|
328
|
+
& { [R in InferRelationNames<TDef>]?: LoadedRelationValue<TDef, R> }
|
|
283
329
|
declare type WhereOperator = '=' | '!=' | '<' | '>' | '<=' | '>=' | 'like' | 'not like' | 'in' | 'not in';
|
|
284
330
|
// --- Dialect-aware execution layer -------------------------------------------
|
|
285
331
|
//
|
|
@@ -295,6 +341,66 @@ declare type WhereOperator = '=' | '!=' | '<' | '>' | '<=' | '>=' | 'like' | 'no
|
|
|
295
341
|
// `selectFrom(...)` builder already uses. Because the network drivers are
|
|
296
342
|
// async-only, every model read/write method now returns a Promise.
|
|
297
343
|
declare type RunResult = { changes: number, lastInsertId: number | bigint | null }
|
|
344
|
+
/** The fully inferred static model API produced from a model definition. */
|
|
345
|
+
export type ModelStatic<TDef extends ModelDefinition> = StaticWhereOverloads<TDef> & {
|
|
346
|
+
query: () => ModelQueryBuilder<TDef>
|
|
347
|
+
whereIn: <K extends ColumnName<TDef>>(column: K, values: (K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown)[]) => ModelQueryBuilder<TDef>
|
|
348
|
+
whereNotIn: <K extends ColumnName<TDef>>(column: K, values: (K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown)[]) => ModelQueryBuilder<TDef>
|
|
349
|
+
whereNull: <K extends ColumnName<TDef>>(column: K) => ModelQueryBuilder<TDef>
|
|
350
|
+
whereNotNull: <K extends ColumnName<TDef>>(column: K) => ModelQueryBuilder<TDef>
|
|
351
|
+
whereLike: <K extends ColumnName<TDef>>(column: K, pattern: string) => ModelQueryBuilder<TDef>
|
|
352
|
+
orderBy: <K extends ColumnName<TDef>>(column: K, direction?: 'asc' | 'desc') => ModelQueryBuilder<TDef>
|
|
353
|
+
orderByDesc: <K extends ColumnName<TDef>>(column: K) => ModelQueryBuilder<TDef>
|
|
354
|
+
select: <K extends ColumnName<TDef>>(...columns: K[]) => ModelQueryBuilder<TDef, K>
|
|
355
|
+
with: <R extends InferRelationNames<TDef>>(...relations: R[]) => ModelQueryBuilder<TDef>
|
|
356
|
+
limit: (count: number) => ModelQueryBuilder<TDef>
|
|
357
|
+
take: (count: number) => ModelQueryBuilder<TDef>
|
|
358
|
+
skip: (count: number) => ModelQueryBuilder<TDef>
|
|
359
|
+
withTrashed: () => ModelQueryBuilder<TDef>
|
|
360
|
+
onlyTrashed: () => ModelQueryBuilder<TDef>
|
|
361
|
+
find: (id: number | string) => Promise<ModelRecord<TDef> | undefined>
|
|
362
|
+
findOrFail: (id: number | string) => Promise<ModelRecord<TDef>>
|
|
363
|
+
findMany: (ids: (number | string)[]) => Promise<ModelRecord<TDef>[]>
|
|
364
|
+
all: () => Promise<ModelRecord<TDef>[]>
|
|
365
|
+
first: () => Promise<ModelRecord<TDef> | undefined>
|
|
366
|
+
firstOrFail: () => Promise<ModelRecord<TDef>>
|
|
367
|
+
last: () => Promise<ModelRecord<TDef> | undefined>
|
|
368
|
+
count: () => Promise<number>
|
|
369
|
+
exists: () => Promise<boolean>
|
|
370
|
+
doesntExist: () => Promise<boolean>
|
|
371
|
+
paginate: (page?: number, perPage?: number) => Promise<{
|
|
372
|
+
data: ModelRecord<TDef>[]
|
|
373
|
+
total: number
|
|
374
|
+
page: number
|
|
375
|
+
perPage: number
|
|
376
|
+
lastPage: number
|
|
377
|
+
hasMorePages: boolean
|
|
378
|
+
isEmpty: boolean
|
|
379
|
+
from: number | null
|
|
380
|
+
to: number | null
|
|
381
|
+
}>
|
|
382
|
+
whereBetween: <K extends ColumnName<TDef>>(column: K, range: [min: K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown, max: K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown]) => ModelQueryBuilder<TDef>
|
|
383
|
+
whereNotBetween: <K extends ColumnName<TDef>>(column: K, range: [min: K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown, max: K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown]) => ModelQueryBuilder<TDef>
|
|
384
|
+
create: (data: FillableAttributes<TDef>) => Promise<ModelRecord<TDef>>
|
|
385
|
+
createMany: (items: FillableAttributes<TDef>[]) => Promise<ModelRecord<TDef>[]>
|
|
386
|
+
updateOrCreate: (search: Partial<ModelAttributes<TDef>>, data: FillableAttributes<TDef>) => Promise<ModelRecord<TDef>>
|
|
387
|
+
firstOrCreate: (search: Partial<ModelAttributes<TDef>>, data?: FillableAttributes<TDef>) => Promise<ModelRecord<TDef>>
|
|
388
|
+
destroy: (id: number | string) => Promise<boolean>
|
|
389
|
+
remove: (id: number | string) => Promise<boolean>
|
|
390
|
+
truncate: () => Promise<void>
|
|
391
|
+
getDefinition: () => TDef
|
|
392
|
+
getTable: () => string
|
|
393
|
+
make: (data?: Partial<ModelAttributes<TDef>>) => ModelInstance<TDef>
|
|
394
|
+
latest: (column?: ColumnName<TDef>) => ModelQueryBuilder<TDef>
|
|
395
|
+
oldest: (column?: ColumnName<TDef>) => ModelQueryBuilder<TDef>
|
|
396
|
+
max: <K extends ColumnName<TDef>>(column: K) => Promise<(K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown) | null>
|
|
397
|
+
min: <K extends ColumnName<TDef>>(column: K) => Promise<(K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown) | null>
|
|
398
|
+
avg: <K extends NumericColumns<TDef>>(column: K) => Promise<number>
|
|
399
|
+
sum: <K extends NumericColumns<TDef>>(column: K) => Promise<number>
|
|
400
|
+
pluck: <K extends ColumnName<TDef>>(column: K) => Promise<(K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown)[]>
|
|
401
|
+
} & {
|
|
402
|
+
[K in AttributeKeys<TDef> as `where${Capitalize<K>}`]: (value: K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown) => ModelQueryBuilder<TDef>
|
|
403
|
+
}
|
|
298
404
|
declare class SqliteExecutor implements OrmExecutor {
|
|
299
405
|
readonly dialect: unknown;
|
|
300
406
|
public readonly sqliteDb: Database;
|
|
@@ -332,10 +438,10 @@ declare class ModelInstance<TDef extends ModelDefinition, TSelected extends Colu
|
|
|
332
438
|
isClean(column?: ColumnName<TDef>): boolean;
|
|
333
439
|
getOriginal<K extends ColumnName<TDef>>(column: K): K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown;
|
|
334
440
|
getChanges(): Partial<InferModelAttributes<TDef>>;
|
|
335
|
-
fill(data:
|
|
441
|
+
fill(data: FillableAttributes<TDef>): this;
|
|
336
442
|
forceFill(data: Partial<InferModelAttributes<TDef>>): this;
|
|
337
443
|
save(): Promise<this>;
|
|
338
|
-
update(data:
|
|
444
|
+
update(data: FillableAttributes<TDef>): Promise<this>;
|
|
339
445
|
fresh(): Promise<ModelInstance<TDef, TSelected> | null>;
|
|
340
446
|
delete(): Promise<boolean>;
|
|
341
447
|
restore(): Promise<this>;
|
|
@@ -421,14 +527,14 @@ declare class ModelQueryBuilder<TDef extends ModelDefinition, TSelected extends
|
|
|
421
527
|
with<R extends InferRelationNames<TDef>>(...relations: R[]): ModelQueryBuilder<TDef, TSelected>;
|
|
422
528
|
getWithRelations(): string[];
|
|
423
529
|
toSql(): { sql: string; params: unknown[] };
|
|
424
|
-
get(): Promise<
|
|
425
|
-
first(): Promise<
|
|
426
|
-
firstOrFail(): Promise<
|
|
427
|
-
last(): Promise<
|
|
530
|
+
get(): Promise<ModelRecord<TDef, TSelected>[]>;
|
|
531
|
+
first(): Promise<ModelRecord<TDef, TSelected> | undefined>;
|
|
532
|
+
firstOrFail(): Promise<ModelRecord<TDef, TSelected>>;
|
|
533
|
+
last(): Promise<ModelRecord<TDef, TSelected> | undefined>;
|
|
428
534
|
count(): Promise<number>;
|
|
429
535
|
exists(): Promise<boolean>;
|
|
430
536
|
doesntExist(): Promise<boolean>;
|
|
431
|
-
sole(): Promise<
|
|
537
|
+
sole(): Promise<ModelRecord<TDef, TSelected>>;
|
|
432
538
|
increment<K extends NumericColumns<TDef>>(column: K, amount?: number): Promise<number>;
|
|
433
539
|
decrement<K extends NumericColumns<TDef>>(column: K, amount?: number): Promise<number>;
|
|
434
540
|
chunk(size: number, callback: (items: ModelInstance<TDef, TSelected>[]) => void | false | Promise<void | false>): Promise<void>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Database } from 'bun:sqlite';
|
|
2
|
+
/** The pragma list currently in effect: the config override, or the defaults. */
|
|
3
|
+
export declare function resolveSqlitePragmas(): readonly string[];
|
|
4
|
+
/**
|
|
5
|
+
* Apply the bootstrap pragmas to a freshly-opened `bun:sqlite` Database.
|
|
6
|
+
*
|
|
7
|
+
* Fail-open per pragma: a single rejected pragma (e.g. a dialect-specific
|
|
8
|
+
* one in a custom list) must not take down connection creation — matching
|
|
9
|
+
* the long-standing behavior of the WAL pragma this generalizes.
|
|
10
|
+
*/
|
|
11
|
+
export declare function applySqliteBootstrapPragmas(db: Database): void;
|
|
12
|
+
/**
|
|
13
|
+
* Bootstrap pragmas applied to every sqlite connection the library opens.
|
|
14
|
+
*
|
|
15
|
+
* SQLite scopes these settings to the CONNECTION, not the database file, and
|
|
16
|
+
* ships with unsafe defaults on every fresh connection: `foreign_keys` is OFF
|
|
17
|
+
* (so `REFERENCES ... ON DELETE CASCADE` in the schema is silently inert and
|
|
18
|
+
* orphan rows insert without error) and there is no busy timeout (concurrent
|
|
19
|
+
* writers surface as immediate `SQLITE_BUSY` failures). They therefore have
|
|
20
|
+
* to be re-applied on every connection the library creates — historically
|
|
21
|
+
* only the query-builder connection got `journal_mode = WAL` while the
|
|
22
|
+
* model-layer executor (the connection `Model.create()/save()/delete()`
|
|
23
|
+
* writes through) got nothing at all, leaving FK enforcement off on the
|
|
24
|
+
* exact connection performing the writes.
|
|
25
|
+
*
|
|
26
|
+
* Override via `setConfig({ sqlite: { pragmas: [...] } })` — the custom list
|
|
27
|
+
* REPLACES this one. Caller-supplied `Database` instances
|
|
28
|
+
* (`configureOrm({ database: db })`) are never touched.
|
|
29
|
+
*/
|
|
30
|
+
export declare const DEFAULT_SQLITE_PRAGMAS: readonly string[];
|