bun-query-builder 0.1.17 → 0.1.18

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/browser.d.ts CHANGED
@@ -62,11 +62,11 @@ export declare const browserAuth: {
62
62
  /**
63
63
  * Login and store token
64
64
  */
65
- async login: (credentials: BrowserAuthCredentials) => Promise<BrowserAuthResult>;
65
+ async login: (credentials: { email: string, password: string }) => Promise<BrowserAuthResponse>;
66
66
  /**
67
67
  * Register a new user
68
68
  */
69
- async register: (data: BrowserAuthRegistrationData) => Promise<BrowserAuthResult>;
69
+ async register: (data: { name: string, email: string, password: string }) => Promise<BrowserAuthResponse>;
70
70
  /**
71
71
  * Logout and clear token
72
72
  */
@@ -159,14 +159,15 @@ declare interface QueryState {
159
159
  selectColumns: string[]
160
160
  withRelations: string[]
161
161
  }
162
- export declare interface BrowserAuthCredentials {
163
- email: string
164
- password: string
165
- }
166
- export declare interface BrowserAuthRegistrationData extends BrowserAuthCredentials {
167
- name: string
168
- }
169
- export declare interface BrowserAuthResult {
162
+ /**
163
+ * Response shape returned by `browserAuth.login` / `browserAuth.register`.
164
+ * Lifted to a named type so the generated `.d.ts` doesn't carry a nested
165
+ * inline object literal in the return position — bun-plugin-dtsx has a
166
+ * bug where `Promise<{ ... }>` in that position emits as `Promise<;`,
167
+ * breaking downstream typecheck for any consumer that imports from
168
+ * `bun-query-builder/browser`.
169
+ */
170
+ export declare interface BrowserAuthResponse {
170
171
  user: Record<string, unknown>
171
172
  token: string
172
173
  }
package/dist/client.d.ts CHANGED
@@ -2,6 +2,7 @@ import { config } from './config';
2
2
  import { resetConnection } from './db';
3
3
  import type { DatabaseSchema } from './schema';
4
4
  import type { SchemaMeta } from './meta';
5
+ // eslint-disable-next-line pickier/no-unused-vars
5
6
  export declare function createQueryBuilder<DB extends DatabaseSchema<any>>(state?: Partial<InternalState>): QueryBuilder<DB>;
6
7
  /**
7
8
  * # `clearQueryCache()`
@@ -119,6 +120,11 @@ export declare interface BaseSelectQueryBuilder<DB extends DatabaseSchema<any>,
119
120
  whereJsonLength?: (path: string, opOrLen: WhereOperator | number, len?: number) => SelectQueryBuilder<DB, TTable, TSelected, TJoined>
120
121
  with?: (...relations: string[]) => SelectQueryBuilder<DB, TTable, TSelected, any>
121
122
  withPivot?: (relation: string, ...columns: string[]) => SelectQueryBuilder<DB, TTable, TSelected, any>
123
+ wherePivot?: (relation: string, column: string, opOrValue: any, value?: any) => SelectQueryBuilder<DB, TTable, TSelected, any>
124
+ wherePivotIn?: (relation: string, column: string, values: any[]) => SelectQueryBuilder<DB, TTable, TSelected, any>
125
+ wherePivotNotIn?: (relation: string, column: string, values: any[]) => SelectQueryBuilder<DB, TTable, TSelected, any>
126
+ wherePivotNull?: (relation: string, column: string) => SelectQueryBuilder<DB, TTable, TSelected, any>
127
+ wherePivotNotNull?: (relation: string, column: string) => SelectQueryBuilder<DB, TTable, TSelected, any>
122
128
  applyPivotColumns?: () => SelectQueryBuilder<DB, TTable, TSelected, any>
123
129
  lockForUpdate: () => SelectQueryBuilder<DB, TTable, TSelected, TJoined>
124
130
  sharedLock: () => SelectQueryBuilder<DB, TTable, TSelected, TJoined>
package/dist/db.d.ts ADDED
@@ -0,0 +1,31 @@
1
+ import { Database } from 'bun:sqlite';
2
+ import { SQL } from 'bun';
3
+ /**
4
+ * Returns a Bun SQL instance configured for the current dialect and database settings.
5
+ * For SQLite, uses bun:sqlite directly for better compiled binary support.
6
+ * Handles connection errors gracefully by falling back to in-memory SQLite.
7
+ */
8
+ export declare function getBunSql(): SQL;
9
+ export declare function getOrCreateBunSql(forceNew?: boolean): SQL;
10
+ /**
11
+ * Resets the cached database connection.
12
+ * Call this after changing config via setConfig() to ensure the new config is used.
13
+ */
14
+ export declare function resetConnection(): void;
15
+ // Wrapper that catches "Connection closed" errors and retries with a fresh connection
16
+ export declare function withFreshConnection<T>(fn: (sql: SQL) => Promise<T>): Promise<T>;
17
+ // Export a lazy proxy - no connection is made until first use
18
+ export declare const bunSql: SQL;
19
+ /**
20
+ * SQLite wrapper that provides a SQL-like tagged template literal interface
21
+ * using bun:sqlite's Database class for better compiled binary support.
22
+ */
23
+ declare class SQLiteWrapper {
24
+ constructor(filename: string);
25
+ query(sql: string, params?: any[]): any[];
26
+ run(sql: string, params?: any[]): any;
27
+ close(): void;
28
+ get database(): Database;
29
+ }
30
+ // Also export the SQL class for advanced usage
31
+ export { SQL } from 'bun';
@@ -9,7 +9,6 @@ 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
13
12
  * @defaultValue
14
13
  * ```ts
15
14
  * {
@@ -94,6 +93,25 @@ export declare interface ManyToManyPattern {
94
93
  entity: SingleTableEntity
95
94
  relation: SingleTableEntity
96
95
  }
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
+ }
97
115
  /**
98
116
  * Single Table Design Manager
99
117
  *
package/dist/index.d.ts CHANGED
@@ -15,6 +15,7 @@ export type {
15
15
  InferColumnNames,
16
16
  InferHiddenKeys,
17
17
  InferGuardedKeys,
18
+ InferPivotColumns,
18
19
  ModelRow,
19
20
  ModelRowLoose,
20
21
  ModelCreateData,
@@ -35,6 +36,7 @@ export * from './factory';
35
36
  export * from './loader';
36
37
  export * from './meta';
37
38
  export * from './migrations';
39
+ export * from './pivot';
38
40
  export * from './orm';
39
41
  export * from './schema';
40
42
  export * from './seeder';
package/dist/meta.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ModelRecord } from './schema';
1
+ import type { BelongsToManyConfig, ModelRecord } from './schema';
2
2
  export declare function buildSchemaMeta(models: ModelRecord): SchemaMeta;
3
3
  export declare interface SchemaMeta {
4
4
  modelToTable: Record<string, string>
@@ -8,7 +8,7 @@ export declare interface SchemaMeta {
8
8
  hasOne?: Record<string, string>
9
9
  hasMany?: Record<string, string>
10
10
  belongsTo?: Record<string, string>
11
- belongsToMany?: Record<string, string>
11
+ belongsToMany?: Record<string, string | BelongsToManyConfig>
12
12
  hasOneThrough?: Record<string, { through: string, target: string }>
13
13
  hasManyThrough?: Record<string, { through: string, target: string }>
14
14
  morphOne?: Record<string, string>
@@ -18,4 +18,5 @@ export declare interface SchemaMeta {
18
18
  morphedByMany?: Record<string, string>
19
19
  }>
20
20
  scopes?: Record<string, Record<string, (qb: any, value?: any) => any>>
21
+ models?: ModelRecord
21
22
  }
@@ -42,6 +42,7 @@ export declare interface IndexPlan {
42
42
  name: string
43
43
  columns: string[]
44
44
  type: 'index' | 'unique'
45
+ where?: string
45
46
  }
46
47
  export declare interface TablePlan {
47
48
  table: string
package/dist/orm.d.ts CHANGED
@@ -119,6 +119,31 @@ export declare interface ModelDefinition {
119
119
  readonly afterDelete?: (model: ModelHookInstance) => void | Promise<void>
120
120
  }
121
121
  }
122
+ /**
123
+ * Resolve a relation from its name and the parent model's definition.
124
+ * Uses the model registry to find the related model's definition.
125
+ *
126
+ * Supports both syntaxes:
127
+ * Array syntax: hasMany: ['Order'] → relation name is 'order', model is 'Order'
128
+ * Object syntax: hasMany: { orders: 'Order' } → relation name is 'orders', model is 'Order'
129
+ */
130
+ /**
131
+ * Resolved-relation shape returned by `resolveRelation`. Pivot fields are
132
+ * populated only for `belongsToMany` relations.
133
+ */
134
+ declare interface ResolvedRelation {
135
+ type: 'hasMany' | 'hasOne' | 'belongsTo' | 'belongsToMany'
136
+ relatedModelName: string
137
+ relatedTable: string
138
+ foreignKey: string
139
+ localKey: string
140
+ pivotTable?: string
141
+ pivotFkParent?: string
142
+ pivotFkRelated?: string
143
+ pivotColumns?: string[]
144
+ pivotModelName?: string
145
+ pivotTimestamps?: boolean
146
+ }
122
147
  // Binding helper type for SQL queries
123
148
  declare type Bindings = SQLQueryBindings[];
124
149
  // Primitive type mappings
@@ -237,8 +262,41 @@ declare class ModelInstance<TDef extends ModelDefinition, TSelected extends Colu
237
262
  delete(): boolean;
238
263
  refresh(): this | null;
239
264
  replicate(): ModelInstance<TDef, TSelected>;
265
+ toArray(): Record<string, unknown>;
240
266
  toJSON(): Omit<Pick<ModelAttributes<TDef>, TSelected & keyof ModelAttributes<TDef>>, HiddenKeys<TDef>>;
241
- toArray(): Omit<Pick<ModelAttributes<TDef>, TSelected & keyof ModelAttributes<TDef>>, HiddenKeys<TDef>>;
267
+ }
268
+ /**
269
+ * # `BelongsToManyRelationBuilder`
270
+ *
271
+ * Per-instance relation builder returned by callable accessors on a
272
+ * `ModelInstance`. Combines a query side (read pivot-joined related rows,
273
+ * filter by pivot columns) with a mutation side (attach/detach/sync/
274
+ * updateExistingPivot/toggle).
275
+ *
276
+ * Constructed lazily — `coach.athletes` returns a function that, when called,
277
+ * returns a fresh builder; chained methods return `this` so a single builder
278
+ * is reused per call.
279
+ */
280
+ export declare class BelongsToManyRelationBuilder<TRel extends ModelDefinition> {
281
+ constructor(parent: ModelInstance<any, any>, parentDef: ModelDefinition, resolved: ResolvedRelation, relatedDef: TRel);
282
+ where(column: string, opOrValue: unknown, value?: unknown): this;
283
+ wherePivot(column: string, opOrValue: unknown, value?: unknown): this;
284
+ wherePivotIn(column: string, values: unknown[]): this;
285
+ wherePivotNotIn(column: string, values: unknown[]): this;
286
+ wherePivotNull(column: string): this;
287
+ wherePivotNotNull(column: string): this;
288
+ orderBy(column: string, direction?: 'asc' | 'desc'): this;
289
+ limit(n: number): this;
290
+ 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[] };
242
300
  }
243
301
  /**
244
302
  * Query builder with precise type narrowing
@@ -0,0 +1,29 @@
1
+ import type { ModelRecord, PivotColumnAttribute } from './schema';
2
+ import type { SchemaMeta } from './meta';
3
+ /**
4
+ * Resolve a `belongsToMany` relation entry to a `ResolvedPivot`. Returns null
5
+ * when the relation key is absent or not a `belongsToMany` on the parent.
6
+ */
7
+ export declare function resolvePivot(meta: SchemaMeta, parentTable: string, relationKey: string, options?: ResolvePivotOptions): ResolvedPivot | null;
8
+ /**
9
+ * Iterate every declared `belongsToMany` relation across all parent tables and
10
+ * yield each as a `ResolvedPivot`. Useful for migration emission and CLI
11
+ * introspection.
12
+ */
13
+ export declare function iterateAllPivots(meta: SchemaMeta, options?: ResolvePivotOptions): Generator<{ parentTable: string, relationKey: string, resolved: ResolvedPivot }>;
14
+ export declare interface ResolvedPivot {
15
+ pivotTable: string
16
+ fkParent: string
17
+ fkRelated: string
18
+ pivotColumns: string[]
19
+ pivotColumnDefs: Record<string, PivotColumnAttribute>
20
+ pivotModelName?: string
21
+ timestamps: boolean
22
+ relatedModelName: string
23
+ relatedTable: string
24
+ hasConfig: boolean
25
+ }
26
+ export declare interface ResolvePivotOptions {
27
+ singularize?: (s: string) => string
28
+ models?: ModelRecord
29
+ }
package/dist/schema.d.ts CHANGED
@@ -75,14 +75,59 @@ export declare interface AttributesElements {
75
75
  *
76
76
  * @example
77
77
  * ```ts
78
- * { name: 'user_email_unique', columns: ['email'] }
78
+ * { name: 'user_email_unique', columns: ['email'], unique: true }
79
+ * { name: 'one_primary_per_athlete', columns: ['athlete_id'], unique: true, where: "role = 'primary'" }
79
80
  * ```
80
81
  */
81
82
  export declare interface CompositeIndex {
82
83
  name: string
83
84
  columns: string[]
85
+ unique?: boolean
86
+ where?: string
84
87
  }
85
88
  export declare interface Base {}
89
+ /**
90
+ * # `PivotColumnAttribute`
91
+ *
92
+ * Inline declaration of an extra column on the pivot table (Option A). When the
93
+ * pivot is declared via a `through` model (Option B), columns are read from
94
+ * that model's `attributes` instead.
95
+ */
96
+ export declare interface PivotColumnAttribute {
97
+ default?: string | number | boolean | Date
98
+ nullable?: boolean
99
+ validation?: {
100
+ rule: ValidationType
101
+ message?: ValidatorMessage
102
+ }
103
+ }
104
+ /**
105
+ * # `PivotConfig`
106
+ *
107
+ * Inline pivot configuration (Option A). Used when the pivot does not have its
108
+ * own model in the registry. Migrations will auto-emit a table for this pivot.
109
+ */
110
+ export declare interface PivotConfig {
111
+ columns?: Record<string, PivotColumnAttribute>
112
+ timestamps?: boolean
113
+ uniques?: string[][]
114
+ }
115
+ /**
116
+ * # `BelongsToManyConfig<T>`
117
+ *
118
+ * Object form of a `belongsToMany` relation declaration. Either `through`
119
+ * (Option B — pivot is a registered model) or `pivot.columns` (Option A —
120
+ * inline metadata) supplies the pivot column metadata. When neither is
121
+ * supplied the relation behaves exactly like the legacy string form.
122
+ */
123
+ export declare interface BelongsToManyConfig<T extends string = string> {
124
+ model: T
125
+ through?: T
126
+ table?: string
127
+ foreignKey?: string
128
+ relatedKey?: string
129
+ pivot?: PivotConfig
130
+ }
86
131
  /**
87
132
  * # `ModelOptions`
88
133
  *
@@ -156,7 +201,7 @@ export type ModelNames = string;
156
201
  export type HasOne<T extends string> = Record<string, T>;
157
202
  export type HasMany<T extends string> = Record<string, T>;
158
203
  export type BelongsTo<T extends string> = Record<string, T>;
159
- export type BelongsToMany<T extends string> = Record<string, T>;
204
+ export type BelongsToMany<T extends string> = Record<string, T | BelongsToManyConfig<T>>;
160
205
  export type HasOneThrough<T extends string> = Record<string, { through: T, target: T }>;
161
206
  export type HasManyThrough<T extends string> = Record<string, { through: T, target: T }>;
162
207
  export type MorphOne<T extends string> = Record<string, T>;