@plyaz/db 0.4.1 → 0.5.0
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/builder/query/QueryBuilder.d.ts +850 -0
- package/dist/builder/query/QueryBuilder.d.ts.map +1 -0
- package/dist/builder/query/index.d.ts +2 -1
- package/dist/builder/query/index.d.ts.map +1 -1
- package/dist/index.cjs +1291 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1291 -7
- package/dist/index.mjs.map +1 -1
- package/dist/repository/BaseRepository.d.ts +72 -6
- package/dist/repository/BaseRepository.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,850 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Fluent Query Builder for @plyaz/db
|
|
3
|
+
*
|
|
4
|
+
* Provides a type-safe, chainable API for building database queries.
|
|
5
|
+
* Works with BaseRepository and can generate both QueryOptions and Filter arrays.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // Integrated with repository (recommended)
|
|
10
|
+
* const result = await userRepository.query()
|
|
11
|
+
* .where('status', 'eq', 'active')
|
|
12
|
+
* .orderByDesc('createdAt')
|
|
13
|
+
* .limit(20)
|
|
14
|
+
* .execute();
|
|
15
|
+
*
|
|
16
|
+
* // Standalone usage
|
|
17
|
+
* const query = QueryBuilder.create<User>()
|
|
18
|
+
* .where('status', 'eq', 'active')
|
|
19
|
+
* .orderByDesc('createdAt')
|
|
20
|
+
* .limit(20)
|
|
21
|
+
* .build();
|
|
22
|
+
*
|
|
23
|
+
* const result = await userRepository.findMany(query);
|
|
24
|
+
*
|
|
25
|
+
* // Complex query with multiple conditions
|
|
26
|
+
* const result = await orderRepository.query()
|
|
27
|
+
* .where('status', 'eq', 'pending')
|
|
28
|
+
* .andWhere('totalAmount', 'gte', 100)
|
|
29
|
+
* .orWhere('priority', 'eq', 'high')
|
|
30
|
+
* .whereIn('region', ['US', 'EU', 'APAC'])
|
|
31
|
+
* .orderBy('createdAt', 'desc')
|
|
32
|
+
* .paginate(1, 25)
|
|
33
|
+
* .execute();
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
import type { Filter, QueryOptions, SortOptions, PaginationOptions, DatabaseResult, PaginatedResult, OperationConfig, FilterOperator, RawCondition, JoinClause, GroupByClause, SelectClause, QueryBuilderResult, QueryExecutor } from "@plyaz/types/db";
|
|
37
|
+
export type { FilterOperator, RawCondition, JoinClause, GroupByClause, SelectClause, QueryBuilderResult, QueryExecutor, };
|
|
38
|
+
/**
|
|
39
|
+
* Fluent Query Builder
|
|
40
|
+
*
|
|
41
|
+
* Provides a chainable API for constructing database queries with type safety.
|
|
42
|
+
*
|
|
43
|
+
* **Design Philosophy:**
|
|
44
|
+
* - Type-safe field names derived from entity type
|
|
45
|
+
* - Chainable methods for intuitive query construction
|
|
46
|
+
* - Dual output: QueryOptions for repository, Filter[] for SQL builder
|
|
47
|
+
* - Direct repository integration via execute()
|
|
48
|
+
*
|
|
49
|
+
* **Application Flow:**
|
|
50
|
+
* ```
|
|
51
|
+
* repository.query() // or QueryBuilder.create<Entity>()
|
|
52
|
+
* ↓
|
|
53
|
+
* .where() / .orderBy() / .limit() chains
|
|
54
|
+
* ↓
|
|
55
|
+
* .execute() // or .build() → repository.findMany(options)
|
|
56
|
+
* ↓
|
|
57
|
+
* DatabaseResult<PaginatedResult<Entity>>
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @template TRecord The entity type this query operates on
|
|
61
|
+
*/
|
|
62
|
+
export declare class QueryBuilder<TRecord extends object> {
|
|
63
|
+
private _filters;
|
|
64
|
+
private _rawConditions;
|
|
65
|
+
private _sort;
|
|
66
|
+
private _pagination;
|
|
67
|
+
private _schema?;
|
|
68
|
+
private _executor?;
|
|
69
|
+
private _operationConfig?;
|
|
70
|
+
private _countExecutor?;
|
|
71
|
+
private _joins;
|
|
72
|
+
private _groupByFields;
|
|
73
|
+
private _havingConditions;
|
|
74
|
+
private _selectFields;
|
|
75
|
+
private _selectRawExpressions;
|
|
76
|
+
private _distinct;
|
|
77
|
+
/**
|
|
78
|
+
* Create a new QueryBuilder instance (standalone)
|
|
79
|
+
*
|
|
80
|
+
* @returns New QueryBuilder instance
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* const builder = QueryBuilder.create<User>();
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
static create<T extends object>(): QueryBuilder<T>;
|
|
88
|
+
/**
|
|
89
|
+
* Create a QueryBuilder bound to a repository for direct execution
|
|
90
|
+
*
|
|
91
|
+
* @param executor - Repository or object with findMany method
|
|
92
|
+
* @returns New QueryBuilder instance bound to executor
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* // Usually called via repository.query()
|
|
97
|
+
* const builder = QueryBuilder.forRepository(userRepository);
|
|
98
|
+
* const result = await builder.where('status', 'eq', 'active').execute();
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
static forRepository<T extends object>(executor: QueryExecutor<T>): QueryBuilder<T>;
|
|
102
|
+
/**
|
|
103
|
+
* Private constructor - use QueryBuilder.create() or forRepository() instead
|
|
104
|
+
*/
|
|
105
|
+
private constructor();
|
|
106
|
+
/**
|
|
107
|
+
* Add a WHERE condition with AND logical operator
|
|
108
|
+
*
|
|
109
|
+
* @param field - Field name to filter on
|
|
110
|
+
* @param operator - Comparison operator
|
|
111
|
+
* @param value - Value to compare against
|
|
112
|
+
* @returns This builder for chaining
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```typescript
|
|
116
|
+
* builder.where('status', 'eq', 'active')
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
where<K extends keyof TRecord & string>(field: K, operator: FilterOperator, value: TRecord[K]): this;
|
|
120
|
+
/**
|
|
121
|
+
* Add a WHERE condition with explicit AND logical operator
|
|
122
|
+
*
|
|
123
|
+
* @param field - Field name to filter on
|
|
124
|
+
* @param operator - Comparison operator
|
|
125
|
+
* @param value - Value to compare against
|
|
126
|
+
* @returns This builder for chaining
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* builder.where('status', 'eq', 'active')
|
|
131
|
+
* .andWhere('role', 'eq', 'admin')
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
andWhere<K extends keyof TRecord & string>(field: K, operator: FilterOperator, value: TRecord[K]): this;
|
|
135
|
+
/**
|
|
136
|
+
* Add a WHERE condition with OR logical operator
|
|
137
|
+
*
|
|
138
|
+
* @param field - Field name to filter on
|
|
139
|
+
* @param operator - Comparison operator
|
|
140
|
+
* @param value - Value to compare against
|
|
141
|
+
* @returns This builder for chaining
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```typescript
|
|
145
|
+
* builder.where('status', 'eq', 'active')
|
|
146
|
+
* .orWhere('status', 'eq', 'pending')
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
orWhere<K extends keyof TRecord & string>(field: K, operator: FilterOperator, value: TRecord[K]): this;
|
|
150
|
+
/**
|
|
151
|
+
* Add a WHERE IN condition
|
|
152
|
+
*
|
|
153
|
+
* @param field - Field name to filter on
|
|
154
|
+
* @param values - Array of values to match
|
|
155
|
+
* @returns This builder for chaining
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```typescript
|
|
159
|
+
* builder.whereIn('status', ['active', 'pending', 'review'])
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
whereIn<K extends keyof TRecord & string>(field: K, values: TRecord[K][]): this;
|
|
163
|
+
/**
|
|
164
|
+
* Add a WHERE NOT IN condition
|
|
165
|
+
*
|
|
166
|
+
* @param field - Field name to filter on
|
|
167
|
+
* @param values - Array of values to exclude
|
|
168
|
+
* @returns This builder for chaining
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```typescript
|
|
172
|
+
* builder.whereNotIn('status', ['deleted', 'archived'])
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
whereNotIn<K extends keyof TRecord & string>(field: K, values: TRecord[K][]): this;
|
|
176
|
+
/**
|
|
177
|
+
* Add a WHERE BETWEEN condition
|
|
178
|
+
*
|
|
179
|
+
* @param field - Field name to filter on
|
|
180
|
+
* @param min - Minimum value (inclusive)
|
|
181
|
+
* @param max - Maximum value (inclusive)
|
|
182
|
+
* @returns This builder for chaining
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* builder.whereBetween('price', 10, 100)
|
|
187
|
+
* builder.whereBetween('createdAt', startDate, endDate)
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
whereBetween<K extends keyof TRecord & string>(field: K, min: TRecord[K], max: TRecord[K]): this;
|
|
191
|
+
/**
|
|
192
|
+
* Add a WHERE LIKE condition (pattern matching)
|
|
193
|
+
*
|
|
194
|
+
* @param field - Field name to filter on
|
|
195
|
+
* @param pattern - LIKE pattern (use % for wildcards)
|
|
196
|
+
* @returns This builder for chaining
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```typescript
|
|
200
|
+
* builder.whereLike('email', '%@example.com')
|
|
201
|
+
* builder.whereLike('name', 'John%')
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
whereLike<K extends keyof TRecord & string>(field: K, pattern: string): this;
|
|
205
|
+
/**
|
|
206
|
+
* Add a WHERE IS NULL condition
|
|
207
|
+
*
|
|
208
|
+
* @param field - Field name to check for NULL
|
|
209
|
+
* @returns This builder for chaining
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```typescript
|
|
213
|
+
* builder.whereNull('deletedAt')
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
whereNull<K extends keyof TRecord & string>(field: K): this;
|
|
217
|
+
/**
|
|
218
|
+
* Add a WHERE IS NOT NULL condition
|
|
219
|
+
*
|
|
220
|
+
* @param field - Field name to check for non-NULL
|
|
221
|
+
* @returns This builder for chaining
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```typescript
|
|
225
|
+
* builder.whereNotNull('verifiedAt')
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
whereNotNull<K extends keyof TRecord & string>(field: K): this;
|
|
229
|
+
/**
|
|
230
|
+
* Add a raw SQL WHERE condition for complex queries
|
|
231
|
+
*
|
|
232
|
+
* Use this for conditions that cannot be expressed with the standard operators,
|
|
233
|
+
* such as subqueries, JSON operations, full-text search, or database-specific functions.
|
|
234
|
+
*
|
|
235
|
+
* @param clause - Raw SQL clause (use $1, $2, etc. for parameter placeholders)
|
|
236
|
+
* @param params - Parameter values for the clause (prevents SQL injection)
|
|
237
|
+
* @returns This builder for chaining
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* ```typescript
|
|
241
|
+
* // JSON field query (PostgreSQL)
|
|
242
|
+
* builder.whereRaw('"metadata"->\'tags\' @> $1', [JSON.stringify(['featured'])])
|
|
243
|
+
*
|
|
244
|
+
* // Full-text search
|
|
245
|
+
* builder.whereRaw('to_tsvector(name) @@ plainto_tsquery($1)', ['search term'])
|
|
246
|
+
*
|
|
247
|
+
* // Subquery
|
|
248
|
+
* builder.whereRaw('"id" IN (SELECT user_id FROM orders WHERE total > $1)', [1000])
|
|
249
|
+
*
|
|
250
|
+
* // Date functions
|
|
251
|
+
* builder.whereRaw('DATE_TRUNC(\'month\', "createdAt") = DATE_TRUNC(\'month\', $1)', [new Date()])
|
|
252
|
+
*
|
|
253
|
+
* // Complex conditions
|
|
254
|
+
* builder
|
|
255
|
+
* .where('status', 'eq', 'active')
|
|
256
|
+
* .whereRaw('("score" > $1 OR "isPremium" = $2)', [80, true])
|
|
257
|
+
* ```
|
|
258
|
+
*/
|
|
259
|
+
whereRaw(clause: string, params?: unknown[]): this;
|
|
260
|
+
/**
|
|
261
|
+
* Add a raw SQL WHERE condition with OR logical operator
|
|
262
|
+
*
|
|
263
|
+
* @param clause - Raw SQL clause (use $1, $2, etc. for parameter placeholders)
|
|
264
|
+
* @param params - Parameter values for the clause
|
|
265
|
+
* @returns This builder for chaining
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
* ```typescript
|
|
269
|
+
* builder
|
|
270
|
+
* .where('status', 'eq', 'active')
|
|
271
|
+
* .orWhereRaw('"metadata"->\'priority\' = $1', ['"high"'])
|
|
272
|
+
* ```
|
|
273
|
+
*/
|
|
274
|
+
orWhereRaw(clause: string, params?: unknown[]): this;
|
|
275
|
+
/**
|
|
276
|
+
* Select specific fields (columns) to return
|
|
277
|
+
*
|
|
278
|
+
* @param fields - Field names to select
|
|
279
|
+
* @returns This builder for chaining
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* ```typescript
|
|
283
|
+
* builder.select('id', 'name', 'email')
|
|
284
|
+
*
|
|
285
|
+
* // With table prefix for joins
|
|
286
|
+
* builder
|
|
287
|
+
* .select('users.id', 'users.name', 'orders.total')
|
|
288
|
+
* .leftJoin('orders', 'users.id = orders.user_id')
|
|
289
|
+
* ```
|
|
290
|
+
*/
|
|
291
|
+
select<K extends keyof TRecord & string>(...fields: (K | string)[]): this;
|
|
292
|
+
/**
|
|
293
|
+
* Add raw SELECT expression
|
|
294
|
+
*
|
|
295
|
+
* @param expression - Raw SQL expression
|
|
296
|
+
* @returns This builder for chaining
|
|
297
|
+
*
|
|
298
|
+
* @example
|
|
299
|
+
* ```typescript
|
|
300
|
+
* builder
|
|
301
|
+
* .select('id', 'name')
|
|
302
|
+
* .selectRaw('COUNT(*) as order_count')
|
|
303
|
+
* .selectRaw('SUM(orders.total) as total_spent')
|
|
304
|
+
* ```
|
|
305
|
+
*/
|
|
306
|
+
selectRaw(expression: string): this;
|
|
307
|
+
/**
|
|
308
|
+
* Add DISTINCT to SELECT
|
|
309
|
+
*
|
|
310
|
+
* @returns This builder for chaining
|
|
311
|
+
*
|
|
312
|
+
* @example
|
|
313
|
+
* ```typescript
|
|
314
|
+
* builder
|
|
315
|
+
* .distinct()
|
|
316
|
+
* .select('category')
|
|
317
|
+
* .orderBy('category', 'asc')
|
|
318
|
+
* ```
|
|
319
|
+
*/
|
|
320
|
+
distinct(): this;
|
|
321
|
+
/**
|
|
322
|
+
* Add INNER JOIN clause
|
|
323
|
+
*
|
|
324
|
+
* @param table - Table to join
|
|
325
|
+
* @param condition - Join condition
|
|
326
|
+
* @param alias - Optional alias for the joined table
|
|
327
|
+
* @returns This builder for chaining
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```typescript
|
|
331
|
+
* builder
|
|
332
|
+
* .join('orders', 'users.id = orders.user_id')
|
|
333
|
+
* .where('orders.status', 'eq', 'completed')
|
|
334
|
+
*
|
|
335
|
+
* // With alias
|
|
336
|
+
* builder.join('orders', 'u.id = o.user_id', 'o')
|
|
337
|
+
*
|
|
338
|
+
* // With schema
|
|
339
|
+
* builder.innerJoin('analytics.events', 'users.id = events.user_id')
|
|
340
|
+
* ```
|
|
341
|
+
*/
|
|
342
|
+
join(table: string, condition: string, alias?: string): this;
|
|
343
|
+
/**
|
|
344
|
+
* Add INNER JOIN clause (explicit)
|
|
345
|
+
*
|
|
346
|
+
* @param table - Table to join (can include schema: 'schema.table')
|
|
347
|
+
* @param condition - Join condition
|
|
348
|
+
* @param alias - Optional alias for the joined table
|
|
349
|
+
* @returns This builder for chaining
|
|
350
|
+
*/
|
|
351
|
+
innerJoin(table: string, condition: string, alias?: string): this;
|
|
352
|
+
/**
|
|
353
|
+
* Add LEFT JOIN clause
|
|
354
|
+
*
|
|
355
|
+
* @param table - Table to join (can include schema: 'schema.table')
|
|
356
|
+
* @param condition - Join condition
|
|
357
|
+
* @param alias - Optional alias for the joined table
|
|
358
|
+
* @returns This builder for chaining
|
|
359
|
+
*
|
|
360
|
+
* @example
|
|
361
|
+
* ```typescript
|
|
362
|
+
* builder
|
|
363
|
+
* .leftJoin('orders', 'users.id = orders.user_id')
|
|
364
|
+
* .select('users.*', 'orders.total')
|
|
365
|
+
* ```
|
|
366
|
+
*/
|
|
367
|
+
leftJoin(table: string, condition: string, alias?: string): this;
|
|
368
|
+
/**
|
|
369
|
+
* Add RIGHT JOIN clause
|
|
370
|
+
*
|
|
371
|
+
* @param table - Table to join (can include schema: 'schema.table')
|
|
372
|
+
* @param condition - Join condition
|
|
373
|
+
* @param alias - Optional alias for the joined table
|
|
374
|
+
* @returns This builder for chaining
|
|
375
|
+
*/
|
|
376
|
+
rightJoin(table: string, condition: string, alias?: string): this;
|
|
377
|
+
/**
|
|
378
|
+
* Add FULL OUTER JOIN clause
|
|
379
|
+
*
|
|
380
|
+
* @param table - Table to join (can include schema: 'schema.table')
|
|
381
|
+
* @param condition - Join condition
|
|
382
|
+
* @param alias - Optional alias for the joined table
|
|
383
|
+
* @returns This builder for chaining
|
|
384
|
+
*/
|
|
385
|
+
fullJoin(table: string, condition: string, alias?: string): this;
|
|
386
|
+
/**
|
|
387
|
+
* Parse table name that may include schema (schema.table)
|
|
388
|
+
*/
|
|
389
|
+
private parseTableName;
|
|
390
|
+
/**
|
|
391
|
+
* Add GROUP BY clause
|
|
392
|
+
*
|
|
393
|
+
* @param fields - Fields to group by
|
|
394
|
+
* @returns This builder for chaining
|
|
395
|
+
*
|
|
396
|
+
* @example
|
|
397
|
+
* ```typescript
|
|
398
|
+
* builder
|
|
399
|
+
* .select('status')
|
|
400
|
+
* .selectRaw('COUNT(*) as count')
|
|
401
|
+
* .groupBy('status')
|
|
402
|
+
*
|
|
403
|
+
* // Multiple fields
|
|
404
|
+
* builder
|
|
405
|
+
* .select('region', 'status')
|
|
406
|
+
* .selectRaw('SUM(amount) as total')
|
|
407
|
+
* .groupBy('region', 'status')
|
|
408
|
+
* ```
|
|
409
|
+
*/
|
|
410
|
+
groupBy<K extends keyof TRecord & string>(...fields: (K | string)[]): this;
|
|
411
|
+
/**
|
|
412
|
+
* Add HAVING condition (for use with GROUP BY)
|
|
413
|
+
*
|
|
414
|
+
* @param clause - Raw SQL HAVING condition (use $1, $2 for params)
|
|
415
|
+
* @param params - Parameter values
|
|
416
|
+
* @returns This builder for chaining
|
|
417
|
+
*
|
|
418
|
+
* @example
|
|
419
|
+
* ```typescript
|
|
420
|
+
* builder
|
|
421
|
+
* .select('status')
|
|
422
|
+
* .selectRaw('COUNT(*) as count')
|
|
423
|
+
* .groupBy('status')
|
|
424
|
+
* .having('COUNT(*) > $1', [10])
|
|
425
|
+
*
|
|
426
|
+
* // Multiple having conditions
|
|
427
|
+
* builder
|
|
428
|
+
* .groupBy('category')
|
|
429
|
+
* .selectRaw('AVG(price) as avg_price')
|
|
430
|
+
* .having('AVG(price) > $1', [100])
|
|
431
|
+
* .having('COUNT(*) >= $1', [5])
|
|
432
|
+
* ```
|
|
433
|
+
*/
|
|
434
|
+
having(clause: string, params?: unknown[]): this;
|
|
435
|
+
/**
|
|
436
|
+
* Add HAVING condition with OR
|
|
437
|
+
*
|
|
438
|
+
* @param clause - Raw SQL HAVING condition
|
|
439
|
+
* @param params - Parameter values
|
|
440
|
+
* @returns This builder for chaining
|
|
441
|
+
*/
|
|
442
|
+
orHaving(clause: string, params?: unknown[]): this;
|
|
443
|
+
/**
|
|
444
|
+
* Add ORDER BY clause
|
|
445
|
+
*
|
|
446
|
+
* @param field - Field name to sort by
|
|
447
|
+
* @param direction - Sort direction ('asc' or 'desc')
|
|
448
|
+
* @returns This builder for chaining
|
|
449
|
+
*
|
|
450
|
+
* @example
|
|
451
|
+
* ```typescript
|
|
452
|
+
* builder.orderBy('createdAt', 'desc')
|
|
453
|
+
* ```
|
|
454
|
+
*/
|
|
455
|
+
orderBy<K extends keyof TRecord & string>(field: K, direction?: "asc" | "desc"): this;
|
|
456
|
+
/**
|
|
457
|
+
* Add ORDER BY ASC clause (convenience method)
|
|
458
|
+
*
|
|
459
|
+
* @param field - Field name to sort by ascending
|
|
460
|
+
* @returns This builder for chaining
|
|
461
|
+
*
|
|
462
|
+
* @example
|
|
463
|
+
* ```typescript
|
|
464
|
+
* builder.orderByAsc('name')
|
|
465
|
+
* ```
|
|
466
|
+
*/
|
|
467
|
+
orderByAsc<K extends keyof TRecord & string>(field: K): this;
|
|
468
|
+
/**
|
|
469
|
+
* Add ORDER BY DESC clause (convenience method)
|
|
470
|
+
*
|
|
471
|
+
* @param field - Field name to sort by descending
|
|
472
|
+
* @returns This builder for chaining
|
|
473
|
+
*
|
|
474
|
+
* @example
|
|
475
|
+
* ```typescript
|
|
476
|
+
* builder.orderByDesc('createdAt')
|
|
477
|
+
* ```
|
|
478
|
+
*/
|
|
479
|
+
orderByDesc<K extends keyof TRecord & string>(field: K): this;
|
|
480
|
+
/**
|
|
481
|
+
* Set LIMIT for results
|
|
482
|
+
*
|
|
483
|
+
* @param limit - Maximum number of results to return
|
|
484
|
+
* @returns This builder for chaining
|
|
485
|
+
*
|
|
486
|
+
* @example
|
|
487
|
+
* ```typescript
|
|
488
|
+
* builder.limit(20)
|
|
489
|
+
* ```
|
|
490
|
+
*/
|
|
491
|
+
limit(limit: number): this;
|
|
492
|
+
/**
|
|
493
|
+
* Set OFFSET for results
|
|
494
|
+
*
|
|
495
|
+
* @param offset - Number of results to skip
|
|
496
|
+
* @returns This builder for chaining
|
|
497
|
+
*
|
|
498
|
+
* @example
|
|
499
|
+
* ```typescript
|
|
500
|
+
* builder.offset(40)
|
|
501
|
+
* ```
|
|
502
|
+
*/
|
|
503
|
+
offset(offset: number): this;
|
|
504
|
+
/**
|
|
505
|
+
* Set pagination by page number
|
|
506
|
+
*
|
|
507
|
+
* @param page - Page number (1-indexed)
|
|
508
|
+
* @param pageSize - Number of items per page
|
|
509
|
+
* @returns This builder for chaining
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* ```typescript
|
|
513
|
+
* builder.paginate(2, 25) // Page 2, 25 items per page
|
|
514
|
+
* ```
|
|
515
|
+
*/
|
|
516
|
+
paginate(page: number, pageSize: number): this;
|
|
517
|
+
/**
|
|
518
|
+
* Set cursor for cursor-based pagination
|
|
519
|
+
*
|
|
520
|
+
* @param cursor - Cursor string from previous query
|
|
521
|
+
* @returns This builder for chaining
|
|
522
|
+
*
|
|
523
|
+
* @example
|
|
524
|
+
* ```typescript
|
|
525
|
+
* builder.afterCursor('eyJpZCI6MTIzfQ==')
|
|
526
|
+
* ```
|
|
527
|
+
*/
|
|
528
|
+
afterCursor(cursor: string): this;
|
|
529
|
+
/**
|
|
530
|
+
* Set database schema
|
|
531
|
+
*
|
|
532
|
+
* @param schema - Schema name to query from
|
|
533
|
+
* @returns This builder for chaining
|
|
534
|
+
*
|
|
535
|
+
* @example
|
|
536
|
+
* ```typescript
|
|
537
|
+
* builder.schema('analytics')
|
|
538
|
+
* ```
|
|
539
|
+
*/
|
|
540
|
+
schema(schema: string): this;
|
|
541
|
+
/**
|
|
542
|
+
* Set operation config for execute()
|
|
543
|
+
*
|
|
544
|
+
* @param config - Operation configuration (adapter, schema override, etc.)
|
|
545
|
+
* @returns This builder for chaining
|
|
546
|
+
*
|
|
547
|
+
* @example
|
|
548
|
+
* ```typescript
|
|
549
|
+
* const result = await userRepository.query()
|
|
550
|
+
* .where('status', 'eq', 'active')
|
|
551
|
+
* .withConfig({ adapter: 'analytics' })
|
|
552
|
+
* .execute();
|
|
553
|
+
* ```
|
|
554
|
+
*/
|
|
555
|
+
withConfig(config: OperationConfig): this;
|
|
556
|
+
/**
|
|
557
|
+
* Execute the query using the bound repository
|
|
558
|
+
*
|
|
559
|
+
* Requires QueryBuilder to be created via repository.query() or forRepository()
|
|
560
|
+
*
|
|
561
|
+
* @returns Promise resolving to paginated results
|
|
562
|
+
* @throws Error if no executor is bound
|
|
563
|
+
*
|
|
564
|
+
* @example
|
|
565
|
+
* ```typescript
|
|
566
|
+
* const result = await userRepository.query()
|
|
567
|
+
* .where('status', 'eq', 'active')
|
|
568
|
+
* .orderByDesc('createdAt')
|
|
569
|
+
* .limit(20)
|
|
570
|
+
* .execute();
|
|
571
|
+
*
|
|
572
|
+
* if (result.success) {
|
|
573
|
+
* console.log('Found users:', result.value.data);
|
|
574
|
+
* }
|
|
575
|
+
* ```
|
|
576
|
+
*/
|
|
577
|
+
execute(): Promise<DatabaseResult<PaginatedResult<TRecord>>>;
|
|
578
|
+
/**
|
|
579
|
+
* Execute and return just the data array (convenience method)
|
|
580
|
+
*
|
|
581
|
+
* @returns Promise resolving to array of records
|
|
582
|
+
* @throws Error if query fails or no executor
|
|
583
|
+
*
|
|
584
|
+
* @example
|
|
585
|
+
* ```typescript
|
|
586
|
+
* const users = await userRepository.query()
|
|
587
|
+
* .where('status', 'eq', 'active')
|
|
588
|
+
* .getMany();
|
|
589
|
+
* ```
|
|
590
|
+
*/
|
|
591
|
+
getMany(): Promise<TRecord[]>;
|
|
592
|
+
/**
|
|
593
|
+
* Execute and return the first result (convenience method)
|
|
594
|
+
*
|
|
595
|
+
* @returns Promise resolving to first record or null
|
|
596
|
+
* @throws Error if query fails or no executor
|
|
597
|
+
*
|
|
598
|
+
* @example
|
|
599
|
+
* ```typescript
|
|
600
|
+
* const user = await userRepository.query()
|
|
601
|
+
* .where('email', 'eq', 'john@example.com')
|
|
602
|
+
* .getOne();
|
|
603
|
+
* ```
|
|
604
|
+
*/
|
|
605
|
+
getOne(): Promise<TRecord | null>;
|
|
606
|
+
/**
|
|
607
|
+
* Execute a count query
|
|
608
|
+
*
|
|
609
|
+
* Returns the count of records matching the filter conditions.
|
|
610
|
+
* Requires QueryBuilder to be created via repository.query() or forRepository()
|
|
611
|
+
*
|
|
612
|
+
* @returns Promise resolving to the count
|
|
613
|
+
* @throws Error if no executor or count not supported
|
|
614
|
+
*
|
|
615
|
+
* @example
|
|
616
|
+
* ```typescript
|
|
617
|
+
* const count = await userRepository.query()
|
|
618
|
+
* .where('status', 'eq', 'active')
|
|
619
|
+
* .count();
|
|
620
|
+
*
|
|
621
|
+
* // Complex count
|
|
622
|
+
* const premiumCount = await userRepository.query()
|
|
623
|
+
* .where('role', 'eq', 'premium')
|
|
624
|
+
* .andWhere('verified', 'eq', true)
|
|
625
|
+
* .count();
|
|
626
|
+
* ```
|
|
627
|
+
*/
|
|
628
|
+
count(): Promise<number>;
|
|
629
|
+
/**
|
|
630
|
+
* Check if any records exist matching the conditions
|
|
631
|
+
*
|
|
632
|
+
* @returns Promise resolving to true if at least one record exists
|
|
633
|
+
* @throws Error if query fails or no executor
|
|
634
|
+
*
|
|
635
|
+
* @example
|
|
636
|
+
* ```typescript
|
|
637
|
+
* const hasActiveUsers = await userRepository.query()
|
|
638
|
+
* .where('status', 'eq', 'active')
|
|
639
|
+
* .exists();
|
|
640
|
+
* ```
|
|
641
|
+
*/
|
|
642
|
+
exists(): Promise<boolean>;
|
|
643
|
+
/**
|
|
644
|
+
* Build QueryOptions for BaseRepository.findMany()
|
|
645
|
+
*
|
|
646
|
+
* For single filter queries, returns standard QueryOptions.
|
|
647
|
+
* For multi-filter queries, returns the first filter (use toFilters() for full array).
|
|
648
|
+
*
|
|
649
|
+
* @returns QueryOptions compatible with BaseRepository
|
|
650
|
+
*
|
|
651
|
+
* @example
|
|
652
|
+
* ```typescript
|
|
653
|
+
* const options = builder.build();
|
|
654
|
+
* const result = await repository.findMany(options);
|
|
655
|
+
* ```
|
|
656
|
+
*/
|
|
657
|
+
build(): QueryOptions<TRecord>;
|
|
658
|
+
/**
|
|
659
|
+
* Build and return full result including filters array and raw conditions
|
|
660
|
+
*
|
|
661
|
+
* Use this when you need access to all filters for direct SQL building
|
|
662
|
+
* or when using multi-condition queries with raw SQL.
|
|
663
|
+
*
|
|
664
|
+
* @returns QueryBuilderResult with options, filters, and raw conditions
|
|
665
|
+
*
|
|
666
|
+
* @example
|
|
667
|
+
* ```typescript
|
|
668
|
+
* const { options, filters, rawConditions } = builder.buildFull();
|
|
669
|
+
*
|
|
670
|
+
* // Use options for repository
|
|
671
|
+
* const result = await repository.findMany(options);
|
|
672
|
+
*
|
|
673
|
+
* // Use filters for custom SQL building
|
|
674
|
+
* const whereClause = buildWhereClause(filters);
|
|
675
|
+
*
|
|
676
|
+
* // Append raw conditions manually
|
|
677
|
+
* rawConditions.forEach(raw => {
|
|
678
|
+
* whereClause += ` ${raw.logical?.toUpperCase() ?? ''} ${raw.clause}`;
|
|
679
|
+
* });
|
|
680
|
+
* ```
|
|
681
|
+
*/
|
|
682
|
+
buildFull(): QueryBuilderResult<TRecord>;
|
|
683
|
+
/**
|
|
684
|
+
* Get array of all filters
|
|
685
|
+
*
|
|
686
|
+
* Use for direct SQL building with buildWhereClause()
|
|
687
|
+
*
|
|
688
|
+
* @returns Array of Filter objects
|
|
689
|
+
*
|
|
690
|
+
* @example
|
|
691
|
+
* ```typescript
|
|
692
|
+
* const filters = builder.toFilters();
|
|
693
|
+
* const whereClause = buildWhereClause(filters);
|
|
694
|
+
* ```
|
|
695
|
+
*/
|
|
696
|
+
toFilters(): Filter<TRecord>[];
|
|
697
|
+
/**
|
|
698
|
+
* Get array of raw SQL conditions
|
|
699
|
+
*
|
|
700
|
+
* Use for manual SQL building with complex conditions
|
|
701
|
+
*
|
|
702
|
+
* @returns Array of RawCondition objects
|
|
703
|
+
*
|
|
704
|
+
* @example
|
|
705
|
+
* ```typescript
|
|
706
|
+
* const rawConditions = builder.toRawConditions();
|
|
707
|
+
* // Manually append to WHERE clause
|
|
708
|
+
* ```
|
|
709
|
+
*/
|
|
710
|
+
toRawConditions(): RawCondition[];
|
|
711
|
+
/**
|
|
712
|
+
* Get array of sort options
|
|
713
|
+
*
|
|
714
|
+
* @returns Array of SortOptions
|
|
715
|
+
*/
|
|
716
|
+
toSortOptions(): SortOptions<TRecord>[];
|
|
717
|
+
/**
|
|
718
|
+
* Get pagination options
|
|
719
|
+
*
|
|
720
|
+
* @returns PaginationOptions
|
|
721
|
+
*/
|
|
722
|
+
toPaginationOptions(): PaginationOptions;
|
|
723
|
+
/**
|
|
724
|
+
* Check if any filters are defined (standard or raw)
|
|
725
|
+
*
|
|
726
|
+
* @returns True if filters exist
|
|
727
|
+
*/
|
|
728
|
+
hasFilters(): boolean;
|
|
729
|
+
/**
|
|
730
|
+
* Check if raw SQL conditions are defined
|
|
731
|
+
*
|
|
732
|
+
* @returns True if raw conditions exist
|
|
733
|
+
*/
|
|
734
|
+
hasRawConditions(): boolean;
|
|
735
|
+
/**
|
|
736
|
+
* Check if sorting is defined
|
|
737
|
+
*
|
|
738
|
+
* @returns True if sort options exist
|
|
739
|
+
*/
|
|
740
|
+
hasSort(): boolean;
|
|
741
|
+
/**
|
|
742
|
+
* Check if pagination is defined
|
|
743
|
+
*
|
|
744
|
+
* @returns True if pagination options exist
|
|
745
|
+
*/
|
|
746
|
+
hasPagination(): boolean;
|
|
747
|
+
/**
|
|
748
|
+
* Reset all query parameters
|
|
749
|
+
*
|
|
750
|
+
* @returns This builder for chaining
|
|
751
|
+
*/
|
|
752
|
+
reset(): this;
|
|
753
|
+
/**
|
|
754
|
+
* Clone this query builder
|
|
755
|
+
*
|
|
756
|
+
* @returns New QueryBuilder with same parameters
|
|
757
|
+
*
|
|
758
|
+
* @example
|
|
759
|
+
* ```typescript
|
|
760
|
+
* const baseQuery = QueryBuilder.create<User>()
|
|
761
|
+
* .where('status', 'eq', 'active');
|
|
762
|
+
*
|
|
763
|
+
* const adminQuery = baseQuery.clone()
|
|
764
|
+
* .andWhere('role', 'eq', 'admin');
|
|
765
|
+
*
|
|
766
|
+
* const userQuery = baseQuery.clone()
|
|
767
|
+
* .andWhere('role', 'eq', 'user');
|
|
768
|
+
* ```
|
|
769
|
+
*/
|
|
770
|
+
clone(): QueryBuilder<TRecord>;
|
|
771
|
+
/**
|
|
772
|
+
* Check if JOINs are defined
|
|
773
|
+
*
|
|
774
|
+
* @returns True if joins exist
|
|
775
|
+
*/
|
|
776
|
+
hasJoins(): boolean;
|
|
777
|
+
/**
|
|
778
|
+
* Check if GROUP BY is defined
|
|
779
|
+
*
|
|
780
|
+
* @returns True if group by fields exist
|
|
781
|
+
*/
|
|
782
|
+
hasGroupBy(): boolean;
|
|
783
|
+
/**
|
|
784
|
+
* Check if custom SELECT is defined
|
|
785
|
+
*
|
|
786
|
+
* @returns True if select fields or expressions exist
|
|
787
|
+
*/
|
|
788
|
+
hasSelect(): boolean;
|
|
789
|
+
/**
|
|
790
|
+
* Get JOIN clauses
|
|
791
|
+
*
|
|
792
|
+
* @returns Array of JoinClause objects
|
|
793
|
+
*/
|
|
794
|
+
toJoins(): JoinClause[];
|
|
795
|
+
/**
|
|
796
|
+
* Get GROUP BY fields
|
|
797
|
+
*
|
|
798
|
+
* @returns Array of field names
|
|
799
|
+
*/
|
|
800
|
+
toGroupByFields(): string[];
|
|
801
|
+
/**
|
|
802
|
+
* Get HAVING conditions
|
|
803
|
+
*
|
|
804
|
+
* @returns Array of RawCondition objects
|
|
805
|
+
*/
|
|
806
|
+
toHavingConditions(): RawCondition[];
|
|
807
|
+
/**
|
|
808
|
+
* Get SELECT fields
|
|
809
|
+
*
|
|
810
|
+
* @returns Array of field names
|
|
811
|
+
*/
|
|
812
|
+
toSelectFields(): string[];
|
|
813
|
+
/**
|
|
814
|
+
* Get SELECT raw expressions
|
|
815
|
+
*
|
|
816
|
+
* @returns Array of raw SQL expressions
|
|
817
|
+
*/
|
|
818
|
+
toSelectRawExpressions(): string[];
|
|
819
|
+
/**
|
|
820
|
+
* Check if DISTINCT is enabled
|
|
821
|
+
*
|
|
822
|
+
* @returns True if distinct is enabled
|
|
823
|
+
*/
|
|
824
|
+
isDistinct(): boolean;
|
|
825
|
+
/**
|
|
826
|
+
* Generate SQL query string (for debugging/logging)
|
|
827
|
+
*
|
|
828
|
+
* Note: This is a simplified SQL representation. The actual query
|
|
829
|
+
* execution uses the adapter's SQL generation.
|
|
830
|
+
*
|
|
831
|
+
* @param tableName - Base table name
|
|
832
|
+
* @returns SQL query string
|
|
833
|
+
*
|
|
834
|
+
* @example
|
|
835
|
+
* ```typescript
|
|
836
|
+
* const sql = builder
|
|
837
|
+
* .select('id', 'name')
|
|
838
|
+
* .leftJoin('orders', 'users.id = orders.user_id')
|
|
839
|
+
* .where('status', 'eq', 'active')
|
|
840
|
+
* .toSQL('users');
|
|
841
|
+
*
|
|
842
|
+
* console.log(sql);
|
|
843
|
+
* // SELECT "id", "name" FROM "users"
|
|
844
|
+
* // LEFT JOIN "orders" ON users.id = orders.user_id
|
|
845
|
+
* // WHERE "status" = $1
|
|
846
|
+
* ```
|
|
847
|
+
*/
|
|
848
|
+
toSQL(tableName: string): string;
|
|
849
|
+
}
|
|
850
|
+
//# sourceMappingURL=QueryBuilder.d.ts.map
|