bun-query-builder 0.1.24 → 0.1.26
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/index.d.ts +1 -0
- package/dist/actions/introspect-db.d.ts +32 -0
- package/dist/actions/migrate-rollback.d.ts +14 -0
- package/dist/bin/cli.js +1084 -391
- package/dist/client.d.ts +3 -3
- package/dist/config.d.ts +1 -15
- package/dist/db.d.ts +54 -0
- package/dist/orm.d.ts +100 -35
- package/dist/relation-utils.d.ts +27 -0
- package/dist/src/index.js +1075 -385
- package/dist/types.d.ts +21 -0
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -103,8 +103,8 @@ export declare interface BaseSelectQueryBuilder<DB extends DatabaseSchema<any>,
|
|
|
103
103
|
groupByRaw: (fragment: SqlFragment) => SelectQueryBuilder<DB, TTable, TSelected, TJoined>
|
|
104
104
|
having: (expr: WhereExpression<any>) => SelectQueryBuilder<DB, TTable, TSelected, TJoined>
|
|
105
105
|
havingRaw: (fragment: SqlFragment) => SelectQueryBuilder<DB, TTable, TSelected, TJoined>
|
|
106
|
-
addSelect: (...columns: (keyof DB[TTable]['columns'] & string | string)[]) => SelectQueryBuilder<DB, TTable, TSelected, TJoined>
|
|
107
|
-
select?: (columns: (keyof DB[TTable]['columns'] & string | string)[]) => SelectQueryBuilder<DB, TTable, TSelected, TJoined>
|
|
106
|
+
addSelect: (...columns: ((keyof DB[TTable]['columns'] & string) | string | SqlFragment)[]) => SelectQueryBuilder<DB, TTable, TSelected, TJoined>
|
|
107
|
+
select?: (columns: string | SqlFragment | ((keyof DB[TTable]['columns'] & string) | string | SqlFragment)[]) => SelectQueryBuilder<DB, TTable, TSelected, TJoined>
|
|
108
108
|
selectAll?: () => SelectQueryBuilder<DB, TTable, TSelected, TJoined>
|
|
109
109
|
orderByRaw: (fragment: SqlFragment) => SelectQueryBuilder<DB, TTable, TSelected, TJoined>
|
|
110
110
|
union: (other: { toSQL: () => any }) => SelectQueryBuilder<DB, TTable, TSelected, TJoined>
|
|
@@ -148,7 +148,7 @@ export declare interface BaseSelectQueryBuilder<DB extends DatabaseSchema<any>,
|
|
|
148
148
|
explain: () => Promise<any[]>
|
|
149
149
|
simple: () => any
|
|
150
150
|
toText?: () => string
|
|
151
|
-
paginate: (perPage: number, page?: number) => Promise<{ data: SelectedRow<DB, TTable, TSelected>[], meta: { perPage: number, page: number, total: number, lastPage: number } }>
|
|
151
|
+
paginate: (perPage: number, page?: number, opts?: { tx?: { unsafe: (sql: string, params?: any[]) => any } }) => Promise<{ data: SelectedRow<DB, TTable, TSelected>[], meta: { perPage: number, page: number, total: number, lastPage: number } }>
|
|
152
152
|
simplePaginate: (perPage: number, page?: number) => Promise<{ data: SelectedRow<DB, TTable, TSelected>[], meta: { perPage: number, page: number, hasMore: boolean } }>
|
|
153
153
|
toSQL: () => string
|
|
154
154
|
execute: () => Promise<SelectedRow<DB, TTable, TSelected>[]>
|
package/dist/config.d.ts
CHANGED
|
@@ -13,18 +13,4 @@ export declare function getPlaceholders(count: number, startIndex?: number): str
|
|
|
13
13
|
export declare function getConfig(): Promise<QueryBuilderConfig>;
|
|
14
14
|
export declare function setConfig(userConfig: Partial<QueryBuilderConfig>): void;
|
|
15
15
|
export declare const defaultConfig: QueryBuilderConfig;
|
|
16
|
-
|
|
17
|
-
//
|
|
18
|
-
// Why `let` + an explicit `Object.assign(config, defaultConfig)` instead of
|
|
19
|
-
// the obvious `export const config = defaultConfig`: when downstream code
|
|
20
|
-
// (e.g. `bunfig`, our config loader) introduces a top-level `await`, Bun's
|
|
21
|
-
// bundler may wrap this module's initializer in `__esm(async () => {...})`.
|
|
22
|
-
// Static `const x = y` exports inside such a wrapper are reassigned only
|
|
23
|
-
// once the async init runs, so callers that reach `setConfig(...)` before
|
|
24
|
-
// that init (e.g. another module's top-level `setConfig` call mid-graph)
|
|
25
|
-
// see `config` as `undefined` and `Object.assign(undefined, ...)` throws.
|
|
26
|
-
// Initializing as `let config = {...defaultConfig}` outside the wrapper, and
|
|
27
|
-
// having `setConfig` re-hydrate from defaults if it's somehow still empty,
|
|
28
|
-
// keeps the surface synchronous for every consumer regardless of how the
|
|
29
|
-
// module ends up bundled.
|
|
30
|
-
export declare let config: QueryBuilderConfig;
|
|
16
|
+
export declare const config: QueryBuilderConfig;
|
package/dist/db.d.ts
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import { Database } from 'bun:sqlite';
|
|
2
2
|
import { SQL } from 'bun';
|
|
3
|
+
import type { PoolConfig } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Map the qb-level `pool` config (ms-based, ergonomic) onto the Bun SQL
|
|
6
|
+
* driver's native option names (second resolution). Only the knobs Bun's
|
|
7
|
+
* `SQL` actually honors are emitted — `min`/`autoReconnect` are accepted on
|
|
8
|
+
* `PoolConfig` for forward-compatibility but the driver manages them itself,
|
|
9
|
+
* so they are intentionally not passed through. See
|
|
10
|
+
* stacksjs/bun-query-builder#1014.
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolvePoolOptions(pool?: PoolConfig): {
|
|
13
|
+
max?: number
|
|
14
|
+
idleTimeout?: number
|
|
15
|
+
connectionTimeout?: number
|
|
16
|
+
maxLifetime?: number
|
|
17
|
+
};
|
|
3
18
|
/**
|
|
4
19
|
* Returns a Bun SQL instance configured for the current dialect and database settings.
|
|
5
20
|
* For SQLite, uses bun:sqlite directly for better compiled binary support.
|
|
@@ -16,6 +31,37 @@ export declare function resetConnection(): void;
|
|
|
16
31
|
export declare function withFreshConnection<T>(fn: (sql: SQL) => Promise<T>): Promise<T>;
|
|
17
32
|
// Export a lazy proxy - no connection is made until first use
|
|
18
33
|
export declare const bunSql: SQL;
|
|
34
|
+
/**
|
|
35
|
+
* The query object returned by `connection.unsafe(...)` / a tagged template.
|
|
36
|
+
* Both Bun's native `SQL` query and our `createSQLiteSQL` wrapper satisfy this.
|
|
37
|
+
* See stacksjs/bun-query-builder#1044.
|
|
38
|
+
*/
|
|
39
|
+
export declare interface DriverQuery {
|
|
40
|
+
execute: () => Promise<any>
|
|
41
|
+
values?: () => any
|
|
42
|
+
raw?: () => any
|
|
43
|
+
toString: () => string
|
|
44
|
+
cancel?: () => void
|
|
45
|
+
readonly sql?: string
|
|
46
|
+
[key: string]: any
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The shared connection surface used across the dispatch path — both the
|
|
50
|
+
* `bun:sqlite` wrapper and Bun's native `SQL` satisfy it. Typing `_sql` against
|
|
51
|
+
* this (instead of `any`) is what lets the ~hundreds of `(_sql as any).unsafe`
|
|
52
|
+
* casts be dropped. See stacksjs/bun-query-builder#1044.
|
|
53
|
+
*/
|
|
54
|
+
export declare interface DriverConnection {
|
|
55
|
+
(strings: TemplateStringsArray, ...values: any[]): DriverQuery
|
|
56
|
+
(value: any): any
|
|
57
|
+
unsafe: (sql: string, values?: any[]) => AwaitableDriverQuery
|
|
58
|
+
query?: (sql: string, params?: any[]) => any
|
|
59
|
+
close?: () => Promise<void> | void
|
|
60
|
+
_prepareStatement?: (sql: string) => any
|
|
61
|
+
[key: string]: any
|
|
62
|
+
}
|
|
63
|
+
/** An `unsafe(...)` result: a query object that is ALSO directly awaitable. */
|
|
64
|
+
export type AwaitableDriverQuery = DriverQuery & PromiseLike<any>;
|
|
19
65
|
/**
|
|
20
66
|
* SQLite wrapper that provides a SQL-like tagged template literal interface
|
|
21
67
|
* using bun:sqlite's Database class for better compiled binary support.
|
|
@@ -27,5 +73,13 @@ declare class SQLiteWrapper {
|
|
|
27
73
|
close(): void;
|
|
28
74
|
get database(): Database;
|
|
29
75
|
}
|
|
76
|
+
// NOTE: this module no longer installs a process-wide `unhandledRejection`
|
|
77
|
+
// handler. A library has no business doing so: ANY such listener suppresses the
|
|
78
|
+
// runtime's default crash for EVERY unhandled rejection in the consumer's
|
|
79
|
+
// process (the old handler's body matched only DB errors but silently swallowed
|
|
80
|
+
// the rest), masking genuine production bugs. Expected "database does not exist"
|
|
81
|
+
// errors during tests are surfaced/awaited at query time now (#1022); a test
|
|
82
|
+
// harness that needs to tolerate a missing DB should install its own handler.
|
|
83
|
+
// See stacksjs/bun-query-builder#1040.
|
|
30
84
|
// Also export the SQL class for advanced usage
|
|
31
85
|
export { SQL } from 'bun';
|
package/dist/orm.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Database, type SQLQueryBindings } from 'bun:sqlite';
|
|
2
2
|
import type { Faker } from '@stacksjs/ts-faker';
|
|
3
|
+
import type { SupportedDialect } from './types';
|
|
3
4
|
export type {
|
|
4
5
|
ModelInstance,
|
|
5
6
|
ModelQueryBuilder,
|
|
@@ -12,13 +13,34 @@ export type {
|
|
|
12
13
|
FillableKeys,
|
|
13
14
|
HiddenKeys,
|
|
14
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Extract an affected-row count from a Bun SQL driver result.
|
|
18
|
+
*
|
|
19
|
+
* Verified against live Postgres (Bun 1.3): a non-RETURNING `UPDATE`/`DELETE`
|
|
20
|
+
* returns an empty array carrying `{ count: <affected>, affectedRows: null,
|
|
21
|
+
* command: 'UPDATE' }`. So `count` must be checked BEFORE the `Array.length`
|
|
22
|
+
* fallback (which would be 0) — see stacksjs/bun-query-builder#1032. MySQL
|
|
23
|
+
* surfaces `affectedRows` instead.
|
|
24
|
+
*/
|
|
25
|
+
export declare function extractChanges(res: any): number;
|
|
26
|
+
/** Extract a generated primary key from a Bun SQL driver result. */
|
|
27
|
+
export declare function extractInsertId(res: any): number | bigint | null;
|
|
15
28
|
export declare function configureOrm(options: { database?: string | Database; verbose?: boolean }): void;
|
|
29
|
+
/**
|
|
30
|
+
* Return the underlying `bun:sqlite` Database backing the model layer.
|
|
31
|
+
*
|
|
32
|
+
* Only meaningful when the active dialect is sqlite (or a sqlite Database was
|
|
33
|
+
* supplied via `configureOrm`). For mysql/postgres there is no `Database`
|
|
34
|
+
* object — use the async model API instead. Retained for backwards
|
|
35
|
+
* compatibility with callers that reach for the raw sqlite handle (tests,
|
|
36
|
+
* low-level table setup).
|
|
37
|
+
*/
|
|
16
38
|
export declare function getDatabase(): Database;
|
|
17
39
|
/**
|
|
18
40
|
* Create a model class from a definition with full type inference
|
|
19
41
|
*/
|
|
20
42
|
export declare function createModel<const TDef extends ModelDefinition>(definition: TDef): void;
|
|
21
|
-
export declare function createTableFromModel(definition: ModelDefinition): void
|
|
43
|
+
export declare function createTableFromModel(definition: ModelDefinition): Promise<void>;
|
|
22
44
|
export declare function seedModel(definition: ModelDefinition, count?: number, faker?: Record<string, unknown>): Promise<void>;
|
|
23
45
|
// Attribute definition with explicit type
|
|
24
46
|
export declare interface TypedAttribute<T = unknown> {
|
|
@@ -119,6 +141,14 @@ export declare interface ModelDefinition {
|
|
|
119
141
|
readonly afterDelete?: (model: ModelHookInstance) => void | Promise<void>
|
|
120
142
|
}
|
|
121
143
|
}
|
|
144
|
+
declare interface OrmExecutor {
|
|
145
|
+
readonly dialect: SupportedDialect
|
|
146
|
+
all: (sql: string, params: unknown[]) => Promise<Record<string, unknown>[]>
|
|
147
|
+
get: (sql: string, params: unknown[]) => Promise<Record<string, unknown> | undefined>
|
|
148
|
+
run: (sql: string, params: unknown[]) => Promise<RunResult>
|
|
149
|
+
insert: (sql: string, params: unknown[], primaryKey: string) => Promise<RunResult>
|
|
150
|
+
readonly sqliteDb?: Database
|
|
151
|
+
}
|
|
122
152
|
/**
|
|
123
153
|
* Resolve a relation from its name and the parent model's definition.
|
|
124
154
|
* Uses the model registry to find the related model's definition.
|
|
@@ -234,6 +264,37 @@ export type InferRelationNames<TDef> = | InferBelongsToNames<TDef>
|
|
|
234
264
|
| InferHasOneThroughNames<TDef>
|
|
235
265
|
| InferHasManyThroughNames<TDef>;
|
|
236
266
|
declare type WhereOperator = '=' | '!=' | '<' | '>' | '<=' | '>=' | 'like' | 'not like' | 'in' | 'not in';
|
|
267
|
+
// --- Dialect-aware execution layer -------------------------------------------
|
|
268
|
+
//
|
|
269
|
+
// The model API historically ran every query through a hardcoded in-memory
|
|
270
|
+
// `bun:sqlite` Database, so projects configured for MySQL/Postgres had their
|
|
271
|
+
// model calls silently routed to a fresh, empty SQLite database — every query
|
|
272
|
+
// returned "no such table" (stacksjs/bun-query-builder#1021).
|
|
273
|
+
//
|
|
274
|
+
// All model queries now go through an `OrmExecutor` chosen from the configured
|
|
275
|
+
// dialect. SQLite keeps its synchronous `bun:sqlite` engine (wrapped in
|
|
276
|
+
// resolved Promises); MySQL/Postgres route through Bun's async `SQL` driver via
|
|
277
|
+
// the shared `getOrCreateBunSql()` connection — the same path the direct
|
|
278
|
+
// `selectFrom(...)` builder already uses. Because the network drivers are
|
|
279
|
+
// async-only, every model read/write method now returns a Promise.
|
|
280
|
+
declare type RunResult = { changes: number, lastInsertId: number | bigint | null }
|
|
281
|
+
declare class SqliteExecutor implements OrmExecutor {
|
|
282
|
+
readonly dialect: unknown;
|
|
283
|
+
public readonly sqliteDb: Database;
|
|
284
|
+
constructor(sqliteDb: Database);
|
|
285
|
+
all(sql: string, params: unknown[]): Promise<Record<string, unknown>[]>;
|
|
286
|
+
get(sql: string, params: unknown[]): Promise<Record<string, unknown> | undefined>;
|
|
287
|
+
run(sql: string, params: unknown[]): Promise<RunResult>;
|
|
288
|
+
insert(sql: string, params: unknown[]): Promise<RunResult>;
|
|
289
|
+
}
|
|
290
|
+
declare class DriverExecutor implements OrmExecutor {
|
|
291
|
+
public readonly dialect: SupportedDialect;
|
|
292
|
+
constructor(dialect: SupportedDialect);
|
|
293
|
+
all(sql: string, params: unknown[]): Promise<Record<string, unknown>[]>;
|
|
294
|
+
get(sql: string, params: unknown[]): Promise<Record<string, unknown> | undefined>;
|
|
295
|
+
run(sql: string, params: unknown[]): Promise<RunResult>;
|
|
296
|
+
insert(sql: string, params: unknown[], primaryKey: string): Promise<RunResult>;
|
|
297
|
+
}
|
|
237
298
|
/**
|
|
238
299
|
* Model instance - represents a single database record
|
|
239
300
|
*/
|
|
@@ -256,11 +317,13 @@ declare class ModelInstance<TDef extends ModelDefinition, TSelected extends Colu
|
|
|
256
317
|
getChanges(): Partial<InferModelAttributes<TDef>>;
|
|
257
318
|
fill(data: Partial<Pick<InferModelAttributes<TDef>, FillableKeys<TDef>>>): this;
|
|
258
319
|
forceFill(data: Partial<InferModelAttributes<TDef>>): this;
|
|
259
|
-
save(): this
|
|
260
|
-
update(data: Partial<Pick<InferModelAttributes<TDef>, FillableKeys<TDef>>>): this
|
|
261
|
-
fresh(): ModelInstance<TDef, TSelected> | null
|
|
262
|
-
delete(): boolean
|
|
263
|
-
|
|
320
|
+
save(): Promise<this>;
|
|
321
|
+
update(data: Partial<Pick<InferModelAttributes<TDef>, FillableKeys<TDef>>>): Promise<this>;
|
|
322
|
+
fresh(): Promise<ModelInstance<TDef, TSelected> | null>;
|
|
323
|
+
delete(): Promise<boolean>;
|
|
324
|
+
restore(): Promise<this>;
|
|
325
|
+
trashed(): boolean;
|
|
326
|
+
refresh(): Promise<this | null>;
|
|
264
327
|
replicate(): ModelInstance<TDef, TSelected>;
|
|
265
328
|
toArray(): Record<string, unknown>;
|
|
266
329
|
toJSON(): Omit<Pick<ModelAttributes<TDef>, TSelected & keyof ModelAttributes<TDef>>, HiddenKeys<TDef>>;
|
|
@@ -288,21 +351,23 @@ export declare class BelongsToManyRelationBuilder<TRel extends ModelDefinition>
|
|
|
288
351
|
orderBy(column: string, direction?: 'asc' | 'desc'): this;
|
|
289
352
|
limit(n: number): this;
|
|
290
353
|
offset(n: number): this;
|
|
291
|
-
get(): ModelInstance<TRel, any>[]
|
|
292
|
-
first(): ModelInstance<TRel, any> | undefined
|
|
293
|
-
count(): number
|
|
294
|
-
exists(): boolean
|
|
295
|
-
attach(idOrIds: unknown | unknown[], extras?: Record<string, unknown>): number
|
|
296
|
-
detach(idOrIds?: unknown | unknown[]): number
|
|
297
|
-
updateExistingPivot(relatedId: unknown, extras: Record<string, unknown>): number
|
|
298
|
-
sync(items: Array<unknown | { id: unknown, [key: string]: unknown }>): { attached: unknown[], detached: unknown[], updated: unknown[] }
|
|
299
|
-
toggle(idOrIds: unknown | unknown[]): { attached: unknown[], detached: unknown[] }
|
|
354
|
+
get(): Promise<ModelInstance<TRel, any>[]>;
|
|
355
|
+
first(): Promise<ModelInstance<TRel, any> | undefined>;
|
|
356
|
+
count(): Promise<number>;
|
|
357
|
+
exists(): Promise<boolean>;
|
|
358
|
+
attach(idOrIds: unknown | unknown[], extras?: Record<string, unknown>): Promise<number>;
|
|
359
|
+
detach(idOrIds?: unknown | unknown[]): Promise<number>;
|
|
360
|
+
updateExistingPivot(relatedId: unknown, extras: Record<string, unknown>): Promise<number>;
|
|
361
|
+
sync(items: Array<unknown | { id: unknown, [key: string]: unknown }>): Promise<{ attached: unknown[], detached: unknown[], updated: unknown[] }>;
|
|
362
|
+
toggle(idOrIds: unknown | unknown[]): Promise<{ attached: unknown[], detached: unknown[] }>;
|
|
300
363
|
}
|
|
301
364
|
/**
|
|
302
365
|
* Query builder with precise type narrowing
|
|
303
366
|
*/
|
|
304
367
|
declare class ModelQueryBuilder<TDef extends ModelDefinition, TSelected extends ColumnName<TDef> = ColumnName<TDef>> {
|
|
305
368
|
constructor(definition: TDef);
|
|
369
|
+
withTrashed(): ModelQueryBuilder<TDef, TSelected>;
|
|
370
|
+
onlyTrashed(): ModelQueryBuilder<TDef, TSelected>;
|
|
306
371
|
where<K extends ColumnName<TDef>>(column: K, value: K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown): ModelQueryBuilder<TDef, TSelected>;
|
|
307
372
|
where<K extends ColumnName<TDef>>(column: K, operator: WhereOperator, value: K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown): ModelQueryBuilder<TDef, TSelected>;
|
|
308
373
|
where<K extends ColumnName<TDef>>(column: K, operatorOrValue: WhereOperator | unknown, value?: unknown): ModelQueryBuilder<TDef, TSelected>;
|
|
@@ -339,18 +404,18 @@ declare class ModelQueryBuilder<TDef extends ModelDefinition, TSelected extends
|
|
|
339
404
|
with<R extends InferRelationNames<TDef>>(...relations: R[]): ModelQueryBuilder<TDef, TSelected>;
|
|
340
405
|
getWithRelations(): string[];
|
|
341
406
|
toSql(): { sql: string; params: unknown[] };
|
|
342
|
-
get(): ModelInstance<TDef, TSelected>[]
|
|
343
|
-
first(): ModelInstance<TDef, TSelected> | undefined
|
|
344
|
-
firstOrFail(): ModelInstance<TDef, TSelected
|
|
345
|
-
last(): ModelInstance<TDef, TSelected> | undefined
|
|
346
|
-
count(): number
|
|
347
|
-
exists(): boolean
|
|
348
|
-
doesntExist(): boolean
|
|
349
|
-
sole(): ModelInstance<TDef, TSelected
|
|
350
|
-
increment<K extends NumericColumns<TDef>>(column: K, amount?: number): number
|
|
351
|
-
decrement<K extends NumericColumns<TDef>>(column: K, amount?: number): number
|
|
352
|
-
chunk(size: number, callback: (items: ModelInstance<TDef, TSelected>[]) => void | false): void
|
|
353
|
-
paginate(page?: number, perPage?: number): {
|
|
407
|
+
get(): Promise<ModelInstance<TDef, TSelected>[]>;
|
|
408
|
+
first(): Promise<ModelInstance<TDef, TSelected> | undefined>;
|
|
409
|
+
firstOrFail(): Promise<ModelInstance<TDef, TSelected>>;
|
|
410
|
+
last(): Promise<ModelInstance<TDef, TSelected> | undefined>;
|
|
411
|
+
count(): Promise<number>;
|
|
412
|
+
exists(): Promise<boolean>;
|
|
413
|
+
doesntExist(): Promise<boolean>;
|
|
414
|
+
sole(): Promise<ModelInstance<TDef, TSelected>>;
|
|
415
|
+
increment<K extends NumericColumns<TDef>>(column: K, amount?: number): Promise<number>;
|
|
416
|
+
decrement<K extends NumericColumns<TDef>>(column: K, amount?: number): Promise<number>;
|
|
417
|
+
chunk(size: number, callback: (items: ModelInstance<TDef, TSelected>[]) => void | false | Promise<void | false>): Promise<void>;
|
|
418
|
+
paginate(page?: number, perPage?: number): Promise<{
|
|
354
419
|
data: ModelInstance<TDef, TSelected>[]
|
|
355
420
|
total: number
|
|
356
421
|
page: number
|
|
@@ -360,12 +425,12 @@ declare class ModelQueryBuilder<TDef extends ModelDefinition, TSelected extends
|
|
|
360
425
|
isEmpty: boolean
|
|
361
426
|
from: number | null
|
|
362
427
|
to: number | null
|
|
363
|
-
}
|
|
364
|
-
pluck<K extends ColumnName<TDef>>(column: K): (K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown)[]
|
|
365
|
-
max<K extends ColumnName<TDef>>(column: K): number | null
|
|
366
|
-
min<K extends ColumnName<TDef>>(column: K): number | null
|
|
367
|
-
avg<K extends NumericColumns<TDef>>(column: K): number
|
|
368
|
-
sum<K extends NumericColumns<TDef>>(column: K): number
|
|
369
|
-
delete(): number
|
|
370
|
-
update(data: Partial<Pick<InferModelAttributes<TDef>, FillableKeys<TDef>>>): number
|
|
428
|
+
}>;
|
|
429
|
+
pluck<K extends ColumnName<TDef>>(column: K): Promise<(K extends keyof ModelAttributes<TDef> ? ModelAttributes<TDef>[K] : unknown)[]>;
|
|
430
|
+
max<K extends ColumnName<TDef>>(column: K): Promise<number | null>;
|
|
431
|
+
min<K extends ColumnName<TDef>>(column: K): Promise<number | null>;
|
|
432
|
+
avg<K extends NumericColumns<TDef>>(column: K): Promise<number>;
|
|
433
|
+
sum<K extends NumericColumns<TDef>>(column: K): Promise<number>;
|
|
434
|
+
delete(): Promise<number>;
|
|
435
|
+
update(data: Partial<Pick<InferModelAttributes<TDef>, FillableKeys<TDef>>>): Promise<number>;
|
|
371
436
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { OnForeignKeyAction } from './schema';
|
|
2
|
+
/**
|
|
3
|
+
* Unwrap a single relation entry to a descriptor, or null if it isn't a valid
|
|
4
|
+
* relation entry. Accepts:
|
|
5
|
+
* - `'Model'`
|
|
6
|
+
* - `{ model: 'Model', foreignKey?, onDelete? }`
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizeRelationEntry(entry: unknown): NormalizedRelation | null;
|
|
9
|
+
/**
|
|
10
|
+
* Flatten a relation declaration into descriptors. Accepts every supported
|
|
11
|
+
* shape: string array, object-in-array, record (name->Model) and record
|
|
12
|
+
* (name->config). Invalid entries are dropped.
|
|
13
|
+
*/
|
|
14
|
+
export declare function normalizeRelationList(rel: unknown): NormalizedRelation[];
|
|
15
|
+
/**
|
|
16
|
+
* A relation entry reduced to the fields the schema/migration layers need.
|
|
17
|
+
*
|
|
18
|
+
* Single source of truth for unwrapping the supported relation-declaration
|
|
19
|
+
* shapes. Previously `meta.ts` (toRecord) and `migrations.ts`
|
|
20
|
+
* (normalizeBelongsTo) each re-implemented this — the exact shape that caused
|
|
21
|
+
* stacksjs/bun-query-builder#1023, and the fix had to be applied twice. See #1042.
|
|
22
|
+
*/
|
|
23
|
+
export declare interface NormalizedRelation {
|
|
24
|
+
model: string
|
|
25
|
+
foreignKey?: string
|
|
26
|
+
onDelete?: OnForeignKeyAction
|
|
27
|
+
}
|