UNPKG

60.3 kBTypeScriptView Raw
1// Originally based on contributions to DefinitelyTyped:
2// Definitions by: Qubo <https://github.com/tkQubo>
3// Pablo Rodríguez <https://github.com/MeLlamoPablo>
4// Matt R. Wilson <https://github.com/mastermatt>
5// Satana Charuwichitratana <https://github.com/micksatana>
6// Shrey Jain <https://github.com/shreyjain1994>
7// TypeScript Version: 3.2
8
9/// <reference types="node" />
10
11import events = require('events');
12import stream = require('stream');
13import ResultTypes = require('./result');
14
15// # Generic type-level utilities
16
17// If T is object then make it a partial otherwise fallback to any
18//
19// This is primarily to prevent type incompatibilities where target can be unknown.
20// While unknown can be assigned to any, Partial<unknown> can't be.
21type SafePartial<T> = T extends {} ? Partial<T> : any;
22
23type MaybeArray<T> = T | T[];
24
25type StrKey<T> = string & keyof T;
26
27// If T is unknown then convert to any, else retain original
28type UnknownToAny<T> = unknown extends T ? any : T;
29type AnyToUnknown<T> = unknown extends T ? unknown : T;
30
31// Intersection conditionally applied only when TParams is non-empty
32// This is primarily to keep the signatures more intuitive.
33type AugmentParams<TTarget, TParams> = TParams extends {}
34 ? keyof TParams extends never
35 ? TTarget
36 : {} & TTarget & TParams
37 : TTarget;
38
39// Check if provided keys (expressed as a single or union type) are members of TBase
40type AreKeysOf<TBase, TKeys> = Boxed<TKeys> extends Boxed<keyof TBase>
41 ? true
42 : false;
43
44// https://stackoverflow.com/a/50375286/476712
45type UnionToIntersection<U> = (U extends any
46 ? (k: U) => void
47 : never) extends ((k: infer I) => void)
48 ? I
49 : never;
50
51type ComparisionOperator = '=' | '>' | '>=' | '<' | '<=' | '<>';
52
53// If T is an array, get the type of member, else fall back to never
54type ArrayMember<T> = T extends (infer M)[] ? M : never;
55
56// If T is an array, get the type of member, else retain original
57type UnwrapArrayMember<T> = T extends (infer M)[] ? M : T;
58
59// Wrap a type in a container, making it an object type.
60// This is primarily useful in circumventing special handling of union/intersection in typescript
61interface Boxed<T> {
62 _value: T;
63}
64
65// If T can't be assigned to TBase fallback to an alternate type TAlt
66type IncompatibleToAlt<T, TBase, TAlt> = T extends TBase ? T : TAlt;
67
68type ArrayIfAlready<T1, T2> = T1 extends any[] ? T2[] : T2;
69
70// Boxing is necessary to prevent distribution of conditional types:
71// https://lorefnon.tech/2019/05/02/using-boxing-to-prevent-distribution-of-conditional-types/
72type PartialOrAny<TBase, TKeys> = Boxed<TKeys> extends Boxed<never>
73 ? {}
74 : Boxed<TKeys> extends Boxed<keyof TBase>
75 ? SafePick<TBase, TKeys & keyof TBase>
76 : any;
77
78// Retain the association of original keys with aliased keys at type level
79// to facilitates type-safe aliasing for object syntax
80type MappedAliasType<TBase, TAliasMapping> = {} & {
81 [K in keyof TAliasMapping]: TAliasMapping[K] extends keyof TBase
82 ? TBase[TAliasMapping[K]]
83 : any
84};
85
86// Container type for situations when we want a partial/intersection eventually
87// but the keys being selected or additional properties being augmented are not
88// all known at once and we would want to effectively build up a partial/intersection
89// over multiple steps.
90type DeferredKeySelection<
91 // The base of selection. In intermediate stages this may be unknown.
92 // If it remains unknown at the point of resolution, the selection will fall back to any
93 TBase,
94 // Union of keys to be selected
95 // In intermediate stages this may be never.
96 TKeys extends string,
97 // Changes how the resolution should behave if TKeys is never.
98 // If true, then we assume that some keys were selected, and if TKeys is never, we will fall back to any.
99 // If false, and TKeys is never, then we select TBase in its entirity
100 THasSelect extends true | false = false,
101 // Mapping of aliases <key in result> -> <key in TBase>
102 TAliasMapping extends {} = {},
103 // If enabled, then instead of extracting a partial, during resolution
104 // we will pick just a single property.
105 TSingle extends boolean = false,
106 // Extra props which will be intersected with the result
107 TIntersectProps extends {} = {},
108 // Extra props which will be unioned with the result
109 TUnionProps = never
110> = {
111 // These properties are not actually used, but exist simply because
112 // typescript doesn't end up happy when type parameters are unused
113 _base: TBase;
114 _hasSelection: THasSelect;
115 _keys: TKeys;
116 _aliases: TAliasMapping;
117 _single: TSingle;
118 _intersectProps: TIntersectProps;
119 _unionProps: TUnionProps;
120};
121
122// An companion namespace for DeferredKeySelection which provides type operators
123// to build up participants of intersection/partial over multiple invocations
124// and for final resolution.
125//
126// While the comments use wordings such as replacement and addition, it is important
127// to keep in mind that types are always immutable and all type operators return new altered types.
128declare namespace DeferredKeySelection {
129 type Any = DeferredKeySelection<any, any, any, any, any, any, any>;
130
131 // Replace the Base if already a deferred selection.
132 // If not, create a new deferred selection with specified base.
133 type SetBase<TSelection, TBase> = TSelection extends DeferredKeySelection<
134 any,
135 infer TKeys,
136 infer THasSelect,
137 infer TAliasMapping,
138 infer TSingle,
139 infer TIntersectProps,
140 infer TUnionProps
141 >
142 ? DeferredKeySelection<TBase, TKeys, THasSelect, TAliasMapping, TSingle, TIntersectProps, TUnionProps>
143 : DeferredKeySelection<TBase, never>;
144
145 // If TSelection is already a deferred selection, then replace the base with TBase
146 // If unknown, create a new deferred selection with TBase as the base
147 // Else, retain original
148 //
149 // For practical reasons applicable to current context, we always return arrays of
150 // deferred selections. So, this particular operator may not be useful in generic contexts.
151 type ReplaceBase<TSelection, TBase> = UnwrapArrayMember<
152 TSelection
153 > extends DeferredKeySelection.Any
154 ? ArrayIfAlready<TSelection, DeferredKeySelection.SetBase<UnwrapArrayMember<TSelection>, TBase>>
155 : unknown extends UnwrapArrayMember<TSelection>
156 ? ArrayIfAlready<TSelection, DeferredKeySelection.SetBase<unknown, TBase>>
157 : TSelection;
158
159 // Type operators to substitute individual type parameters:
160
161 type SetSingle<
162 TSelection,
163 TSingle extends boolean
164 > = TSelection extends DeferredKeySelection<
165 infer TBase,
166 infer TKeys,
167 infer THasSelect,
168 infer TAliasMapping,
169 any,
170 infer TIntersectProps,
171 infer TUnionProps
172 >
173 ? DeferredKeySelection<TBase, TKeys, THasSelect, TAliasMapping, TSingle, TIntersectProps, TUnionProps>
174 : never;
175
176 type AddKey<
177 TSelection,
178 TKey extends string
179 > = TSelection extends DeferredKeySelection<
180 infer TBase,
181 infer TKeys,
182 any,
183 infer TAliasMapping,
184 infer TSingle,
185 infer TIntersectProps,
186 infer TUnionProps
187 >
188 ? DeferredKeySelection<TBase, TKeys | TKey, true, TAliasMapping, TSingle, TIntersectProps, TUnionProps>
189 : DeferredKeySelection<unknown, TKey, true>;
190
191 type AddAliases<TSelection, T> = TSelection extends DeferredKeySelection<
192 infer TBase,
193 infer TKeys,
194 infer THasSelect,
195 infer TAliasMapping,
196 infer TSingle,
197 infer TIntersectProps,
198 infer TUnionProps
199 >
200 ? DeferredKeySelection<TBase, TKeys, THasSelect, TAliasMapping & T, TSingle, TIntersectProps, TUnionProps>
201 : DeferredKeySelection<unknown, never, false, T>;
202
203 type AddUnionMember<TSelection, T> = TSelection extends DeferredKeySelection<
204 infer TBase,
205 infer TKeys,
206 infer THasSelect,
207 infer TAliasMapping,
208 infer TSingle,
209 infer TIntersectProps,
210 infer TUnionProps
211 >
212 ? DeferredKeySelection<TBase, TKeys, THasSelect, TAliasMapping, TSingle, TIntersectProps, TUnionProps | T>
213 : DeferredKeySelection<TSelection, never, false, {}, false, {}, T>;
214
215 // Convenience utility to set base, keys and aliases in a single type
216 // application
217 type Augment<T, TBase, TKey extends string, TAliasMapping = {}> = AddAliases<
218 AddKey<SetBase<T, TBase>, TKey>,
219 TAliasMapping
220 >;
221
222 // Core resolution logic -- Refer to docs for DeferredKeySelection for specifics
223 type ResolveOne<TSelection> = TSelection extends DeferredKeySelection<
224 infer TBase,
225 infer TKeys,
226 infer THasSelect,
227 infer TAliasMapping,
228 infer TSingle,
229 infer TIntersectProps,
230 infer TUnionProps
231 >
232 ? UnknownToAny<
233 // ^ We convert final result to any if it is unknown for backward compatibility.
234 // Historically knex typings have been liberal with returning any and changing
235 // default return type to unknown would be a major breaking change for users.
236 //
237 // So we compromise on type safety here and return any.
238 AugmentParams<
239 AnyToUnknown<TBase> extends {}
240 // ^ Conversion of any -> unknown is needed here to prevent distribution
241 // of any over the conditional
242 ? TSingle extends true
243 ? TKeys extends keyof TBase
244 ? TBase[TKeys]
245 : any
246 : AugmentParams<
247 true extends THasSelect ? PartialOrAny<TBase, TKeys> : TBase,
248 MappedAliasType<TBase, TAliasMapping>
249 >
250 : unknown,
251 TIntersectProps
252 > | TUnionProps
253 >
254 : TSelection;
255
256 type Resolve<TSelection> = TSelection extends DeferredKeySelection.Any
257 ? ResolveOne<TSelection>
258 : TSelection extends DeferredKeySelection.Any[]
259 ? ResolveOne<TSelection[0]>[]
260 : TSelection extends (infer I)[]
261 ? UnknownToAny<I>[]
262 : UnknownToAny<TSelection>;
263}
264
265type AggregationQueryResult<TResult, TIntersectProps2> = ArrayIfAlready<
266 TResult,
267 UnwrapArrayMember<TResult> extends DeferredKeySelection<
268 infer TBase,
269 infer TKeys,
270 infer THasSelect,
271 infer TAliasMapping,
272 infer TSingle,
273 infer TIntersectProps,
274 infer TUnionProps
275 >
276 ? true extends THasSelect
277 ? DeferredKeySelection<TBase, TKeys, THasSelect, TAliasMapping, TSingle, TIntersectProps & TIntersectProps2, TUnionProps>
278 : DeferredKeySelection<{}, never, true, {}, false, TIntersectProps2>
279 : TIntersectProps2
280>;
281
282// Convenience alias and associated companion namespace for working
283// with DeferredSelection having TSingle=true.
284//
285// When TSingle=true in DeferredSelection, then we are effectively
286// deferring an index access operation (TBase[TKey]) over a potentially
287// unknown initial type of TBase and potentially never initial type of TKey
288
289type DeferredIndex<TBase, TKey extends string> = DeferredKeySelection<TBase, TKey, false, {}, true>;
290
291declare namespace DeferredIndex {
292 type Augment<
293 T,
294 TBase,
295 TKey extends string,
296 TAliasMapping = {}
297 > = DeferredKeySelection.SetSingle<
298 DeferredKeySelection.AddKey<DeferredKeySelection.SetBase<T, TBase>, TKey>,
299 true
300 >;
301}
302
303// If we have more categories of deferred selection in future,
304// this will combine all of them
305type ResolveResult<S> = DeferredKeySelection.Resolve<S>;
306
307// # Type-aliases for common type combinations
308
309type Callback = Function;
310type Client = Function;
311
312type Dict<T = any> = { [k: string]: T; };
313
314type SafePick<T, K extends keyof T> = T extends {} ? Pick<T, K> : any;
315
316interface Knex<TRecord extends {} = any, TResult = any[]>
317 extends Knex.QueryInterface<TRecord, TResult>, events.EventEmitter {
318 <TRecord2 = TRecord, TResult2 = DeferredKeySelection<TRecord2, never>[]>(
319 tableName?: Knex.TableDescriptor | Knex.AliasDict
320 ): Knex.QueryBuilder<TRecord2, TResult2>;
321 VERSION: string;
322 __knex__: string;
323
324 raw: Knex.RawBuilder<TRecord>;
325
326 transactionProvider(
327 config?: any
328 ): () => Promise<Knex.Transaction>;
329 transaction(
330 transactionScope?: null,
331 config?: any
332 ): Promise<Knex.Transaction>;
333 transaction<T>(
334 transactionScope: (trx: Knex.Transaction) => Promise<T> | Promise<T> | void,
335 config?: any
336 ): Promise<T>;
337 initialize(config?: Knex.Config): void;
338 destroy(callback: Function): void;
339 destroy(): Promise<void>;
340 batchInsert(
341 tableName: Knex.TableDescriptor,
342 data: any[],
343 chunkSize?: number
344 ): Knex.QueryBuilder<TRecord, {}>;
345 schema: Knex.SchemaBuilder;
346 queryBuilder<TRecord2 = TRecord, TResult2 = TResult>(): Knex.QueryBuilder<
347 TRecord2,
348 TResult2
349 >;
350
351 client: any;
352 migrate: Knex.Migrator;
353 seed: Knex.Seeder;
354 fn: Knex.FunctionHelper;
355 ref: Knex.RefBuilder;
356}
357
358declare function Knex<TRecord = any, TResult = unknown[]>(
359 config: Knex.Config | string
360): Knex<TRecord, TResult>;
361
362declare namespace Knex {
363 //
364 // Utility Types
365 //
366
367 type Value =
368 | string
369 | number
370 | boolean
371 | Date
372 | Array<string>
373 | Array<number>
374 | Array<Date>
375 | Array<boolean>
376 | Buffer
377 | Knex.Raw;
378
379 interface ValueDict extends Dict<Value | Knex.QueryBuilder> {}
380 interface AliasDict extends Dict<string> {}
381
382 type ColumnDescriptor<TRecord, TResult> =
383 | string
384 | Knex.Raw
385 | Knex.QueryBuilder<TRecord, TResult>
386 | Dict<string>;
387
388 type InferrableColumnDescriptor<TRecord extends {}> =
389 | keyof TRecord
390 | Knex.Ref<any, any>
391 | Dict<keyof TRecord>;
392
393 type TableDescriptor = string | Knex.Raw | Knex.QueryBuilder;
394
395 type Lookup<TRegistry extends {}, TKey extends string, TDefault = never> =
396 TKey extends keyof TRegistry ?
397 TRegistry[TKey] :
398 TDefault;
399
400 //
401 // QueryInterface
402 //
403
404 interface QueryInterface<TRecord extends {} = any, TResult = any[]> {
405 select: Select<TRecord, TResult>;
406 as: As<TRecord, TResult>;
407 columns: Select<TRecord, TResult>;
408 column: Select<TRecord, TResult>;
409 from: Table<TRecord, TResult>;
410 into: Table<TRecord, TResult>;
411 table: Table<TRecord, TResult>;
412 distinct: Distinct<TRecord, TResult>;
413
414 // Joins
415 join: Join<TRecord, TResult>;
416 joinRaw: JoinRaw<TRecord, TResult>;
417 innerJoin: Join<TRecord, TResult>;
418 leftJoin: Join<TRecord, TResult>;
419 leftOuterJoin: Join<TRecord, TResult>;
420 rightJoin: Join<TRecord, TResult>;
421 rightOuterJoin: Join<TRecord, TResult>;
422 outerJoin: Join<TRecord, TResult>;
423 fullOuterJoin: Join<TRecord, TResult>;
424 crossJoin: Join<TRecord, TResult>;
425
426 // Withs
427 with: With<TRecord, TResult>;
428 withRecursive: With<TRecord, TResult>;
429 withRaw: WithRaw<TRecord, TResult>;
430 withSchema: WithSchema<TRecord, TResult>;
431 withWrapped: WithWrapped<TRecord, TResult>;
432
433 // Wheres
434 where: Where<TRecord, TResult>;
435 andWhere: Where<TRecord, TResult>;
436 orWhere: Where<TRecord, TResult>;
437 whereNot: Where<TRecord, TResult>;
438 andWhereNot: Where<TRecord, TResult>;
439 orWhereNot: Where<TRecord, TResult>;
440 whereRaw: WhereRaw<TRecord, TResult>;
441 orWhereRaw: WhereRaw<TRecord, TResult>;
442 andWhereRaw: WhereRaw<TRecord, TResult>;
443 whereWrapped: WhereWrapped<TRecord, TResult>;
444 havingWrapped: WhereWrapped<TRecord, TResult>;
445 whereExists: WhereExists<TRecord, TResult>;
446 orWhereExists: WhereExists<TRecord, TResult>;
447 whereNotExists: WhereExists<TRecord, TResult>;
448 orWhereNotExists: WhereExists<TRecord, TResult>;
449 whereIn: WhereIn<TRecord, TResult>;
450 orWhereIn: WhereIn<TRecord, TResult>;
451 whereNotIn: WhereIn<TRecord, TResult>;
452 orWhereNotIn: WhereIn<TRecord, TResult>;
453 whereNull: WhereNull<TRecord, TResult>;
454 orWhereNull: WhereNull<TRecord, TResult>;
455 whereNotNull: WhereNull<TRecord, TResult>;
456 orWhereNotNull: WhereNull<TRecord, TResult>;
457 whereBetween: WhereBetween<TRecord, TResult>;
458 orWhereBetween: WhereBetween<TRecord, TResult>;
459 andWhereBetween: WhereBetween<TRecord, TResult>;
460 whereNotBetween: WhereBetween<TRecord, TResult>;
461 orWhereNotBetween: WhereBetween<TRecord, TResult>;
462 andWhereNotBetween: WhereBetween<TRecord, TResult>;
463
464 // Group by
465 groupBy: GroupBy<TRecord, TResult>;
466 groupByRaw: RawQueryBuilder<TRecord, TResult>;
467
468 // Order by
469 orderBy: OrderBy<TRecord, TResult>;
470 orderByRaw: RawQueryBuilder<TRecord, TResult>;
471
472 // Intersect
473 intersect: Intersect<TRecord, TResult>;
474
475 // Union
476 union: Union<TRecord, TResult>;
477 unionAll: Union<TRecord, TResult>;
478
479 // Having
480 having: Having<TRecord, TResult>;
481 andHaving: Having<TRecord, TResult>;
482 havingRaw: RawQueryBuilder<TRecord, TResult>;
483 orHaving: Having<TRecord, TResult>;
484 orHavingRaw: RawQueryBuilder<TRecord, TResult>;
485 havingIn: HavingRange<TRecord, TResult>;
486 orHavingNotBetween: HavingRange<TRecord, TResult>;
487 havingNotBetween: HavingRange<TRecord, TResult>;
488 orHavingBetween: HavingRange<TRecord, TResult>;
489 havingBetween: HavingRange<TRecord, TResult>;
490
491 // Clear
492 clearSelect(): QueryBuilder<
493 TRecord,
494 UnwrapArrayMember<TResult> extends DeferredKeySelection<
495 infer TBase,
496 infer TKeys,
497 true,
498 any,
499 any,
500 any,
501 any
502 >
503 ? DeferredKeySelection<TBase, never>[]
504 : TResult
505 >;
506 clearWhere(): QueryBuilder<TRecord, TResult>;
507 clearOrder(): QueryBuilder<TRecord, TResult>;
508 clearHaving(): QueryBuilder<TRecord, TResult>;
509 clearCounters(): QueryBuilder<TRecord, TResult>;
510
511 // Paging
512 offset(offset: number): QueryBuilder<TRecord, TResult>;
513 limit(limit: number): QueryBuilder<TRecord, TResult>;
514
515 // Aggregation
516 count: AssymetricAggregation<TRecord, TResult, Lookup<ResultTypes.Registry, "Count", number | string>>;
517 countDistinct: AssymetricAggregation<TRecord, TResult, Lookup<ResultTypes.Registry, "Count", number | string>>;
518 min: TypePreservingAggregation<TRecord, TResult>;
519 max: TypePreservingAggregation<TRecord, TResult>;
520 sum: TypePreservingAggregation<TRecord, TResult>;
521 sumDistinct: TypePreservingAggregation<TRecord, TResult>;
522 avg: TypePreservingAggregation<TRecord, TResult>;
523 avgDistinct: TypePreservingAggregation<TRecord, TResult>;
524
525 increment(
526 columnName: keyof TRecord,
527 amount?: number
528 ): QueryBuilder<TRecord, number>;
529 increment(
530 columnName: string,
531 amount?: number
532 ): QueryBuilder<TRecord, number>;
533
534 decrement(
535 columnName: keyof TRecord,
536 amount?: number
537 ): QueryBuilder<TRecord, number>;
538 decrement(
539 columnName: string,
540 amount?: number
541 ): QueryBuilder<TRecord, number>;
542
543 // Others
544 first: Select<TRecord, DeferredKeySelection.AddUnionMember<UnwrapArrayMember<TResult>, undefined>>;
545
546 pluck<K extends keyof TRecord>(
547 column: K
548 ): QueryBuilder<TRecord, TRecord[K][]>;
549 pluck<TResult2 extends {}>(column: string): QueryBuilder<TRecord, TResult2>;
550
551 insert(
552 data: MaybeArray<SafePartial<TRecord>>,
553 returning: '*'
554 ): QueryBuilder<TRecord, DeferredKeySelection<TRecord, never>[]>;
555 insert<
556 TKey extends StrKey<TRecord>,
557 TResult2 = DeferredIndex.Augment<
558 UnwrapArrayMember<TResult>,
559 TRecord,
560 TKey
561 >[]
562 >(
563 data: MaybeArray<SafePartial<TRecord>>,
564 returning: TKey
565 ): QueryBuilder<TRecord, TResult2>;
566 insert<
567 TKey extends StrKey<TRecord>,
568 TResult2 = DeferredKeySelection.Augment<
569 UnwrapArrayMember<TResult>,
570 TRecord,
571 TKey
572 >[]
573 >(
574 data: MaybeArray<SafePartial<TRecord>>,
575 returning: TKey[]
576 ): QueryBuilder<TRecord, TResult2>;
577 insert<
578 TKey extends string,
579 TResult2 = DeferredIndex.Augment<
580 UnwrapArrayMember<TResult>,
581 TRecord,
582 TKey
583 >[]
584 >(
585 data: MaybeArray<SafePartial<TRecord>>,
586 returning: TKey
587 ): QueryBuilder<TRecord, TResult2>;
588 insert<
589 TKey extends string,
590 TResult2 = DeferredIndex.Augment<
591 UnwrapArrayMember<TResult>,
592 TRecord,
593 TKey
594 >[]
595 >(
596 data: MaybeArray<SafePartial<TRecord>>,
597 returning: TKey[]
598 ): QueryBuilder<TRecord, TResult2>;
599 insert<TResult2 = number[]>(
600 data: MaybeArray<SafePartial<TRecord>>
601 ): QueryBuilder<TRecord, TResult2>;
602
603 modify<TRecord2 extends {} = any, TResult2 extends {} = any>(
604 callback: QueryCallbackWithArgs<TRecord, any>,
605 ...args: any[]
606 ): QueryBuilder<TRecord2, TResult2>;
607
608 update(
609 data: MaybeArray<SafePartial<TRecord>>,
610 returning: '*'
611 ): QueryBuilder<TRecord, DeferredKeySelection<TRecord, never>[]>;
612 update<
613 TKey extends StrKey<TRecord>,
614 TResult2 = DeferredIndex.Augment<
615 UnwrapArrayMember<TResult>,
616 TRecord,
617 TKey
618 >[]
619 >(
620 data: MaybeArray<SafePartial<TRecord>>,
621 returning: TKey
622 ): QueryBuilder<TRecord, TResult2>;
623 update<
624 TKey extends StrKey<TRecord>,
625 TResult2 = DeferredKeySelection.Augment<
626 UnwrapArrayMember<TResult>,
627 TRecord,
628 TKey
629 >[]
630 >(
631 data: MaybeArray<SafePartial<TRecord>>,
632 returning: TKey[]
633 ): QueryBuilder<TRecord, TResult2>;
634 update<
635 TKey extends string = string,
636 TResult2 extends {}[] = DeferredKeySelection.Augment<
637 UnwrapArrayMember<TResult>,
638 TRecord,
639 TKey
640 >[]
641 >(
642 data: MaybeArray<SafePartial<TRecord>>,
643 returning: TKey | TKey[]
644 ): QueryBuilder<TRecord, TResult2>;
645 update<
646 TKey extends string,
647 TResult2 extends {}[] = DeferredKeySelection.Augment<
648 UnwrapArrayMember<TResult>,
649 TRecord,
650 TKey
651 >[]
652 >(
653 data: MaybeArray<SafePartial<TRecord>>,
654 returning: TKey[]
655 ): QueryBuilder<TRecord, TResult2>;
656 update<TResult2 = number>(
657 data: MaybeArray<SafePartial<TRecord>>
658 ): QueryBuilder<TRecord, TResult2>;
659 update<
660 K1 extends StrKey<TRecord>,
661 K2 extends StrKey<TRecord>,
662 TResult2 = DeferredIndex.Augment<
663 UnwrapArrayMember<TResult>,
664 TRecord,
665 K2
666 >[]
667 >(
668 columnName: K1,
669 value: TRecord[K1],
670 returning: K1
671 ): QueryBuilder<TRecord, TResult2>;
672 update<
673 K1 extends StrKey<TRecord>,
674 K2 extends StrKey<TRecord>,
675 TResult2 = DeferredKeySelection.Augment<
676 UnwrapArrayMember<TResult>,
677 TRecord,
678 K2
679 >[]
680 >(
681 columnName: K1,
682 value: TRecord[K1],
683 returning: K1[]
684 ): QueryBuilder<TRecord, TResult2>;
685 update<K extends keyof TRecord>(
686 columnName: K,
687 value: TRecord[K]
688 ): QueryBuilder<TRecord, number>;
689 update<TResult2 = SafePartial<TRecord>[]>(
690 columnName: string,
691 value: Value,
692 returning: string | string[]
693 ): QueryBuilder<TRecord, TResult2>;
694 update<TResult2 = number>(columnName: string, value: Value): QueryBuilder<TRecord, TResult2>;
695
696 returning(column: '*'): QueryBuilder<TRecord, DeferredKeySelection<TRecord, never>[]>;
697 returning<
698 TKey extends StrKey<TRecord>,
699 TResult2 = DeferredIndex.Augment<
700 UnwrapArrayMember<TResult>,
701 TRecord,
702 TKey
703 >[]
704 >(
705 column: TKey
706 ): QueryBuilder<TRecord, TResult2>;
707 returning<
708 TKey extends StrKey<TRecord>,
709 TResult2 = DeferredKeySelection.SetSingle<
710 DeferredKeySelection.Augment<UnwrapArrayMember<TResult>, TRecord, TKey>,
711 false
712 >[]
713 >(
714 columns: TKey[]
715 ): QueryBuilder<TRecord, TResult2>;
716 returning<TResult2 = SafePartial<TRecord>[]>(
717 column: string | string[]
718 ): QueryBuilder<TRecord, TResult2>;
719
720 del(
721 returning: '*'
722 ): QueryBuilder<TRecord, DeferredKeySelection<TRecord, never>[]>;
723 del<
724 TKey extends StrKey<TRecord>,
725 TResult2 = DeferredIndex.Augment<
726 UnwrapArrayMember<TResult>,
727 TRecord,
728 TKey
729 >[]
730 >(
731 returning: TKey
732 ): QueryBuilder<TRecord, TResult2>;
733 del<
734 TKey extends StrKey<TRecord>,
735 TResult2 = DeferredKeySelection.Augment<
736 UnwrapArrayMember<TResult>,
737 TRecord,
738 TKey
739 >[]
740 >(
741 returning: TKey[]
742 ): QueryBuilder<TRecord, TResult2[]>;
743 del<TResult2 = SafePartial<TRecord>[]>(
744 returning: string | string[]
745 ): QueryBuilder<TRecord, TResult2>;
746 del<TResult2 = number>(): QueryBuilder<TRecord, TResult2>;
747
748 delete(
749 returning: '*'
750 ): QueryBuilder<TRecord, DeferredKeySelection<TRecord, never>[]>;
751 delete<
752 TKey extends StrKey<TRecord>,
753 TResult2 = DeferredIndex.Augment<
754 UnwrapArrayMember<TResult>,
755 TRecord,
756 TKey
757 >[]
758 >(
759 returning: TKey
760 ): QueryBuilder<TRecord, TResult2>;
761 delete<
762 TKey extends StrKey<TRecord>,
763 TResult2 = DeferredKeySelection.Augment<
764 UnwrapArrayMember<TResult>,
765 TRecord,
766 TKey
767 >[]
768 >(
769 returning: TKey[]
770 ): QueryBuilder<TRecord, TResult2>;
771 delete<TResult2 = any>(
772 returning: string | string[]
773 ): QueryBuilder<TRecord, TResult2>;
774 delete<TResult2 = number>(): QueryBuilder<TRecord, TResult2>;
775
776 truncate(): QueryBuilder<TRecord, void>;
777 }
778
779 interface As<TRecord, TResult> {
780 (columnName: keyof TRecord): QueryBuilder<TRecord, TResult>;
781 (columnName: string): QueryBuilder<TRecord, TResult>;
782 }
783
784 type IntersectAliases<AliasUT> =
785 UnionToIntersection<
786 IncompatibleToAlt<
787 AliasUT extends (infer I)[]
788 ? I extends Ref<any, infer TMapping>
789 ? TMapping
790 : I
791 : never,
792 Dict,
793 {}
794 >
795 >;
796
797 interface AliasQueryBuilder<TRecord extends {} = any, TResult = unknown[]> {
798 <
799 AliasUT extends InferrableColumnDescriptor<TRecord>[],
800 TResult2 = ArrayIfAlready<TResult, DeferredKeySelection.Augment<
801 UnwrapArrayMember<TResult>,
802 TRecord,
803 IncompatibleToAlt<ArrayMember<AliasUT>, string, never>,
804 IntersectAliases<AliasUT>
805 >>
806 >(
807 ...aliases: AliasUT
808 ): QueryBuilder<TRecord, TResult2>;
809
810 <
811 AliasUT extends InferrableColumnDescriptor<TRecord>[],
812 TResult2 = ArrayIfAlready<TResult, DeferredKeySelection.Augment<
813 UnwrapArrayMember<TResult>,
814 TRecord,
815 IncompatibleToAlt<ArrayMember<AliasUT>, string, never>,
816 IntersectAliases<AliasUT>
817 >>
818 >(
819 aliases: AliasUT
820 ): QueryBuilder<TRecord, TResult2>;
821
822 <
823 AliasUT extends (Dict | string)[],
824 TResult2 = ArrayIfAlready<TResult, DeferredKeySelection.Augment<
825 UnwrapArrayMember<TResult>,
826 TRecord,
827 IncompatibleToAlt<ArrayMember<AliasUT>, string, never>,
828 IntersectAliases<AliasUT>
829 >>
830 >(
831 ...aliases: AliasUT
832 ): QueryBuilder<TRecord, TResult2>;
833
834 <
835 AliasUT extends (Dict | string)[],
836 TResult2 = ArrayIfAlready<TResult, DeferredKeySelection.Augment<
837 UnwrapArrayMember<TResult>,
838 TRecord,
839 IncompatibleToAlt<ArrayMember<AliasUT>, string, never>,
840 IntersectAliases<AliasUT>
841 >>
842 >(
843 aliases: AliasUT
844 ): QueryBuilder<TRecord, TResult2>;
845 }
846
847 interface Select<TRecord extends {} = any, TResult = unknown[]>
848 extends AliasQueryBuilder<TRecord, TResult>,
849 ColumnNameQueryBuilder<TRecord, TResult> {
850 (): QueryBuilder<TRecord, TResult>;
851
852 <TResult2 = ArrayIfAlready<TResult, any>, TInnerRecord = any, TInnerResult = any>(
853 ...subQueryBuilders: QueryBuilder<TInnerRecord, TInnerResult>[]
854 ): QueryBuilder<TRecord, TResult2>;
855
856 <TResult2 = ArrayIfAlready<TResult, any>, TInnerRecord = any, TInnerResult = any>(
857 subQueryBuilders: QueryBuilder<TInnerRecord, TInnerResult>[]
858 ): QueryBuilder<TRecord, TResult2>;
859 }
860
861 interface Table<TRecord extends {} = any, TResult extends {} = any> {
862 <
863 TRecord2 = unknown,
864 TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2>
865 >(
866 tableName: TableDescriptor | AliasDict
867 ): QueryBuilder<TRecord2, TResult2>;
868 <
869 TRecord2 = unknown,
870 TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2>
871 >(
872 callback: Function
873 ): QueryBuilder<TRecord2, TResult2>;
874 <
875 TRecord2 = unknown,
876 TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2>
877 >(
878 raw: Raw
879 ): QueryBuilder<TRecord2, TResult2>;
880 }
881
882 interface Distinct<TRecord extends {}, TResult = {}[]>
883 extends ColumnNameQueryBuilder<TRecord, TResult> {}
884
885 interface JoinCallback {
886 (this: JoinClause, join: JoinClause): void;
887 }
888
889 interface Join<TRecord extends {} = any, TResult = unknown[]> {
890 <
891 TJoinTargetRecord extends {} = any,
892 TRecord2 extends {} = TRecord & TJoinTargetRecord,
893 TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2>
894 >(
895 raw: Raw
896 ): QueryBuilder<TRecord2, TResult2>;
897 <
898 TJoinTargetRecord extends {} = any,
899 TRecord2 extends {} = TRecord & TJoinTargetRecord,
900 TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2>
901 >(
902 tableName: TableDescriptor | AliasDict | QueryCallback,
903 clause: JoinCallback
904 ): QueryBuilder<TRecord2, TResult2>;
905 <
906 TJoinTargetRecord extends {} = any,
907 TRecord2 extends {} = TRecord & TJoinTargetRecord,
908 TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2>
909 >(
910 tableName: TableDescriptor | AliasDict | QueryCallback,
911 columns: { [key: string]: string | number | boolean | Raw }
912 ): QueryBuilder<TRecord2, TResult2>;
913 <
914 TJoinTargetRecord extends {} = any,
915 TRecord2 extends {} = TRecord & TJoinTargetRecord,
916 TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2>
917 >(
918 tableName: TableDescriptor | AliasDict | QueryCallback,
919 raw: Raw
920 ): QueryBuilder<TRecord2, TResult2>;
921 <
922 TJoinTargetRecord extends {} = any,
923 TRecord2 extends {} = TRecord & TJoinTargetRecord,
924 TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2>
925 >(
926 tableName: TableDescriptor | AliasDict | QueryCallback,
927 column1: string,
928 column2: string
929 ): QueryBuilder<TRecord2, TResult2>;
930 <
931 TJoinTargetRecord extends {} = any,
932 TRecord2 extends {} = TRecord & TJoinTargetRecord,
933 TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2>
934 >(
935 tableName: TableDescriptor | AliasDict | QueryCallback,
936 column1: string,
937 raw: Raw
938 ): QueryBuilder<TRecord2, TResult2>;
939 <
940 TJoinTargetRecord extends {} = any,
941 TRecord2 extends {} = TRecord & TJoinTargetRecord,
942 TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2>
943 >(
944 tableName: TableDescriptor | AliasDict | QueryCallback,
945 column1: string,
946 operator: string,
947 column2: string
948 ): QueryBuilder<TRecord2, TResult2>;
949 }
950
951 interface JoinClause {
952 on(raw: Raw): JoinClause;
953 on(callback: JoinCallback): JoinClause;
954 on(columns: { [key: string]: string | Raw }): JoinClause;
955 on(column1: string, column2: string): JoinClause;
956 on(column1: string, raw: Raw): JoinClause;
957 on(column1: string, operator: string, column2: string | Raw): JoinClause;
958 andOn(raw: Raw): JoinClause;
959 andOn(callback: JoinCallback): JoinClause;
960 andOn(columns: { [key: string]: string | Raw }): JoinClause;
961 andOn(column1: string, column2: string): JoinClause;
962 andOn(column1: string, raw: Raw): JoinClause;
963 andOn(column1: string, operator: string, column2: string | Raw): JoinClause;
964 orOn(raw: Raw): JoinClause;
965 orOn(callback: JoinCallback): JoinClause;
966 orOn(columns: { [key: string]: string | Raw }): JoinClause;
967 orOn(column1: string, column2: string): JoinClause;
968 orOn(column1: string, raw: Raw): JoinClause;
969 orOn(column1: string, operator: string, column2: string | Raw): JoinClause;
970 onIn(column1: string, values: any[]): JoinClause;
971 andOnIn(column1: string, values: any[]): JoinClause;
972 orOnIn(column1: string, values: any[]): JoinClause;
973 onNotIn(column1: string, values: any[]): JoinClause;
974 andOnNotIn(column1: string, values: any[]): JoinClause;
975 orOnNotIn(column1: string, values: any[]): JoinClause;
976 onNull(column1: string): JoinClause;
977 andOnNull(column1: string): JoinClause;
978 orOnNull(column1: string): JoinClause;
979 onNotNull(column1: string): JoinClause;
980 andOnNotNull(column1: string): JoinClause;
981 orOnNotNull(column1: string): JoinClause;
982 onExists(callback: QueryCallback): JoinClause;
983 andOnExists(callback: QueryCallback): JoinClause;
984 orOnExists(callback: QueryCallback): JoinClause;
985 onNotExists(callback: QueryCallback): JoinClause;
986 andOnNotExists(callback: QueryCallback): JoinClause;
987 orOnNotExists(callback: QueryCallback): JoinClause;
988 onBetween(column1: string, range: [any, any]): JoinClause;
989 andOnBetween(column1: string, range: [any, any]): JoinClause;
990 orOnBetween(column1: string, range: [any, any]): JoinClause;
991 onNotBetween(column1: string, range: [any, any]): JoinClause;
992 andOnNotBetween(column1: string, range: [any, any]): JoinClause;
993 orOnNotBetween(column1: string, range: [any, any]): JoinClause;
994 using(
995 column: string | string[] | Raw | { [key: string]: string | Raw }
996 ): JoinClause;
997 type(type: string): JoinClause;
998 }
999
1000 interface JoinRaw<TRecord = any, TResult = unknown[]> {
1001 (tableName: string, binding?: Value | ValueDict): QueryBuilder<
1002 TRecord,
1003 TResult
1004 >;
1005 }
1006
1007 interface With<TRecord = any, TResult = unknown[]>
1008 extends WithRaw<TRecord, TResult>,
1009 WithWrapped<TRecord, TResult> {}
1010
1011 interface WithRaw<TRecord = any, TResult = unknown[]> {
1012 (alias: string, raw: Raw | QueryBuilder): QueryBuilder<TRecord, TResult>;
1013 (alias: string, sql: string, bindings?: Value[] | Object): QueryBuilder<
1014 TRecord,
1015 TResult
1016 >;
1017 }
1018
1019 interface WithSchema<TRecord = any, TResult = unknown[]> {
1020 (schema: string): QueryBuilder<TRecord, TResult>;
1021 }
1022
1023 interface WithWrapped<TRecord = any, TResult = unknown[]> {
1024 (alias: string, queryBuilder: QueryBuilder): QueryBuilder<TRecord, TResult>;
1025 (
1026 alias: string,
1027 callback: (queryBuilder: QueryBuilder) => any
1028 ): QueryBuilder<TRecord, TResult>;
1029 }
1030
1031 interface Where<TRecord = any, TResult = unknown>
1032 extends WhereRaw<TRecord, TResult>,
1033 WhereWrapped<TRecord, TResult>,
1034 WhereNull<TRecord, TResult> {
1035 (raw: Raw): QueryBuilder<TRecord, TResult>;
1036 (callback: QueryCallback): QueryBuilder<TRecord, TResult>;
1037
1038 (object: SafePartial<TRecord>): QueryBuilder<TRecord, TResult>;
1039 (object: Object): QueryBuilder<TRecord, TResult>;
1040
1041 <T extends keyof TRecord>(
1042 columnName: T,
1043 value: TRecord[T] | null
1044 ): QueryBuilder<TRecord, TResult>;
1045 (columnName: string, value: Value | null): QueryBuilder<TRecord, TResult>;
1046
1047 <T extends keyof TRecord>(
1048 columnName: T,
1049 operator: ComparisionOperator,
1050 value: TRecord[T] | null
1051 ): QueryBuilder<TRecord, TResult>;
1052 (columnName: string, operator: string, value: Value | null): QueryBuilder<
1053 TRecord,
1054 TResult
1055 >;
1056
1057 <T extends keyof TRecord, TRecordInner, TResultInner>(
1058 columnName: T,
1059 operator: ComparisionOperator,
1060 value: QueryBuilder<TRecordInner, TResultInner>
1061 ): QueryBuilder<TRecord, TResult>;
1062 <TRecordInner, TResultInner>(
1063 columnName: string,
1064 operator: string,
1065 value: QueryBuilder<TRecordInner, TResultInner>
1066 ): QueryBuilder<TRecord, TResult>;
1067
1068 (left: Raw, operator: string, right: Value | null): QueryBuilder<
1069 TRecord,
1070 TResult
1071 >;
1072 <TRecordInner, TResultInner>(
1073 left: Raw,
1074 operator: string,
1075 right: QueryBuilder<TRecordInner, TResultInner>
1076 ): QueryBuilder<TRecord, TResult>;
1077 }
1078
1079 interface WhereRaw<TRecord = any, TResult = unknown[]>
1080 extends RawQueryBuilder<TRecord, TResult> {
1081 (condition: boolean): QueryBuilder<TRecord, TResult>;
1082 }
1083
1084 interface WhereWrapped<TRecord = any, TResult = unknown[]> {
1085 (callback: QueryCallback): QueryBuilder<TRecord, TResult>;
1086 }
1087
1088 interface WhereNull<TRecord = any, TResult = unknown[]> {
1089 (columnName: keyof TRecord): QueryBuilder<TRecord, TResult>;
1090 (columnName: string): QueryBuilder<TRecord, TResult>;
1091 }
1092
1093 interface WhereBetween<TRecord = any, TResult = unknown[]> {
1094 <K extends keyof TRecord>(
1095 columnName: K,
1096 range: [TRecord[K], TRecord[K]]
1097 ): QueryBuilder<TRecord, TResult>;
1098 (columnName: string, range: [Value, Value]): QueryBuilder<TRecord, TResult>;
1099 }
1100
1101 interface WhereExists<TRecord = any, TResult = unknown[]> {
1102 (callback: QueryCallback): QueryBuilder<TRecord, TResult>;
1103 <TRecordInner, TResultInner>(
1104 query: QueryBuilder<TRecordInner, TResultInner>
1105 ): QueryBuilder<TRecord, TResult>;
1106 }
1107
1108 interface WhereIn<TRecord = any, TResult = unknown[]> {
1109 <K extends keyof TRecord>(
1110 columnName: K,
1111 values: TRecord[K][] | QueryCallback
1112 ): QueryBuilder<TRecord, TResult>;
1113 (columnName: string, values: Value[] | QueryCallback): QueryBuilder<
1114 TRecord,
1115 TResult
1116 >;
1117 <K extends keyof TRecord>(
1118 columnNames: K[],
1119 values: TRecord[K][][] | QueryCallback
1120 ): QueryBuilder<TRecord, TResult>;
1121 (columnNames: string[], values: Value[][] | QueryCallback): QueryBuilder<
1122 TRecord,
1123 TResult
1124 >;
1125 <K extends keyof TRecord, TRecordInner, TResultInner>(
1126 columnName: K,
1127 values: QueryBuilder<TRecordInner, TRecord[K]>
1128 ): QueryBuilder<TRecord, TResult>;
1129 <TRecordInner, TResultInner>(
1130 columnName: string,
1131 values: QueryBuilder<TRecordInner, TResultInner>
1132 ): QueryBuilder<TRecord, TResult>;
1133 <K extends keyof TRecord, TRecordInner, TResultInner>(
1134 columnNames: K[],
1135 values: QueryBuilder<TRecordInner, TRecord[K]>
1136 ): QueryBuilder<TRecord, TResult>;
1137 <TRecordInner, TResultInner>(
1138 columnNames: string[],
1139 values: QueryBuilder<TRecordInner, TResultInner>
1140 ): QueryBuilder<TRecord, TResult>;
1141 }
1142
1143 // Note: Attempting to unify AssymetricAggregation & TypePreservingAggregation
1144 // by extracting out a common base interface will not work because order of overloads
1145 // is significant.
1146
1147 interface AssymetricAggregation<TRecord = any, TResult = unknown[], TValue = any> {
1148 <TResult2 = AggregationQueryResult<TResult, Dict<TValue>>>(
1149 ...columnNames: (keyof TRecord)[]
1150 ): QueryBuilder<TRecord, TResult2>;
1151 <
1152 TAliases extends {} = Record<string, string | string[] | Knex.Raw>,
1153 TResult2 = AggregationQueryResult<TResult, {[k in keyof TAliases]?: TValue}>
1154 >(aliases: TAliases): QueryBuilder<TRecord, TResult2>;
1155 <TResult2 = AggregationQueryResult<TResult, Dict<TValue>>>(
1156 ...columnNames: Array<Record<string, string | string[] | Knex.Raw> | Knex.Raw | string>
1157 ): QueryBuilder<TRecord, TResult2>;
1158 }
1159
1160 interface TypePreservingAggregation<TRecord = any, TResult = unknown[], TValue = any> {
1161 <
1162 TKey extends keyof TRecord,
1163 TResult2 = AggregationQueryResult<TResult, Dict<TRecord[TKey]>>
1164 >(
1165 ...columnNames: TKey[]
1166 ): QueryBuilder<TRecord, TResult2>;
1167 <
1168 TAliases extends {} = Record<string, string | string[] | Knex.Raw>,
1169 TResult2 = AggregationQueryResult<TResult, {
1170 // We have optional here because in most dialects aggregating by multiple keys simultaneously
1171 // causes rest of the keys to be dropped and only first to be considered
1172 [K in keyof TAliases]?: K extends keyof TRecord ?
1173 TRecord[K] :
1174 TValue
1175 }>
1176 >(aliases: TAliases): QueryBuilder<TRecord, TResult2>;
1177 <TResult2 = AggregationQueryResult<TResult, Dict<TValue>>>(
1178 ...columnNames: Array<Record<string, string | string[] | Knex.Raw> | Knex.Raw | string>
1179 ): QueryBuilder<TRecord, TResult2>;
1180 }
1181
1182 interface GroupBy<TRecord = any, TResult = unknown[]>
1183 extends RawQueryBuilder<TRecord, TResult>,
1184 ColumnNameQueryBuilder<TRecord, TResult> {}
1185
1186 interface OrderBy<TRecord = any, TResult = unknown[]> {
1187 (columnName: keyof TRecord, order?: 'asc' | 'desc'): QueryBuilder<
1188 TRecord,
1189 TResult
1190 >;
1191 (columnName: string, order?: string): QueryBuilder<TRecord, TResult>;
1192 (
1193 columnDefs: Array<
1194 keyof TRecord | { column: keyof TRecord; order?: 'asc' | 'desc' }
1195 >
1196 ): QueryBuilder<TRecord, TResult>;
1197 (
1198 columnDefs: Array<string | { column: string; order?: string }>
1199 ): QueryBuilder<TRecord, TResult>;
1200 <TRecordInner, TResultInner>(
1201 subQueryBuilder: QueryBuilder<TRecordInner, TResultInner>
1202 ): QueryBuilder<TRecord, TResult>;
1203 }
1204
1205 interface Intersect<TRecord = any, TResult = unknown[]> {
1206 (
1207 callback: MaybeArray<QueryCallback | QueryBuilder<TRecord, any> | Raw>,
1208 wrap?: boolean
1209 ): QueryBuilder<TRecord, TResult>;
1210 (
1211 ...callbacks: (QueryCallback | Raw | QueryBuilder<TRecord, any>)[]
1212 ): QueryBuilder<TRecord, TResult>;
1213 }
1214
1215 interface Union<TRecord = any, TResult = unknown[]>
1216 extends Intersect<TRecord, TResult> {}
1217
1218 interface Having<TRecord = any, TResult = unknown[]>
1219 extends RawQueryBuilder<TRecord, TResult>,
1220 WhereWrapped<TRecord, TResult> {
1221 <K1 extends keyof TRecord, K2 extends keyof TRecord>(
1222 tableName: string,
1223 column1: K1,
1224 operator: ComparisionOperator,
1225 column2: K2
1226 ): QueryBuilder<TRecord, TResult>;
1227 (
1228 tableName: string,
1229 column1: string,
1230 operator: string,
1231 column2: string
1232 ): QueryBuilder<TRecord, TResult>;
1233 }
1234
1235 interface HavingRange<TRecord = any, TResult = unknown[]> {
1236 <K extends keyof TRecord>(
1237 columnName: K,
1238 values: TRecord[K][]
1239 ): QueryBuilder<TRecord, TResult>;
1240 (columnName: string, values: Value[]): QueryBuilder<TRecord, TResult>;
1241 }
1242
1243 // commons
1244
1245 interface ColumnNameQueryBuilder<TRecord = any, TResult = unknown[]> {
1246 // When all columns are known to be keys of original record,
1247 // we can extend our selection by these columns
1248 (columnName: '*'): QueryBuilder<
1249 TRecord,
1250 DeferredKeySelection<TRecord, string>[]
1251 >;
1252
1253 <
1254 ColNameUT extends keyof TRecord,
1255 TResult2 = DeferredKeySelection.Augment<
1256 UnwrapArrayMember<TResult>,
1257 TRecord,
1258 ColNameUT & string
1259 >[]
1260 >(
1261 ...columnNames: ColNameUT[]
1262 ): QueryBuilder<TRecord, TResult2>;
1263
1264 <
1265 ColNameUT extends keyof TRecord,
1266 TResult2 = DeferredKeySelection.Augment<
1267 UnwrapArrayMember<TResult>,
1268 TRecord,
1269 ColNameUT & string
1270 >[]
1271 >(
1272 columnNames: ColNameUT[]
1273 ): QueryBuilder<TRecord, TResult2>;
1274
1275 // For non-inferrable column selection, we will allow consumer to
1276 // specify result type and if not widen the result to entire record type with any omissions permitted
1277 <
1278 TResult2 = DeferredKeySelection.Augment<
1279 UnwrapArrayMember<TResult>,
1280 SafePartial<TRecord>,
1281 keyof TRecord & string
1282 >[]
1283 >(
1284 ...columnNames: ColumnDescriptor<TRecord, TResult>[]
1285 ): QueryBuilder<TRecord, TResult2>;
1286
1287 <
1288 TResult2 = DeferredKeySelection.Augment<
1289 UnwrapArrayMember<TResult>,
1290 SafePartial<TRecord>,
1291 keyof TRecord & string
1292 >[]
1293 >(
1294 columnNames: ColumnDescriptor<TRecord, TResult>[]
1295 ): QueryBuilder<TRecord, TResult2>;
1296 }
1297
1298 type RawBinding = Value | QueryBuilder<any, any>;
1299
1300 interface RawQueryBuilder<TRecord = any, TResult = unknown[]> {
1301 <TResult2 = TResult>(
1302 sql: string,
1303 ...bindings: RawBinding[]
1304 ): QueryBuilder<TRecord, TResult2>;
1305 <TResult2 = TResult>(
1306 sql: string,
1307 bindings: RawBinding[] | ValueDict
1308 ): QueryBuilder<TRecord, TResult2>;
1309 <TResult2 = TResult>(raw: Raw<TResult2>): QueryBuilder<
1310 TRecord,
1311 TResult2
1312 >;
1313 }
1314
1315 // Raw
1316
1317 interface Raw<TResult = any>
1318 extends events.EventEmitter,
1319 ChainableInterface<ResolveResult<TResult>> {
1320 wrap<TResult2 = TResult>(before: string, after: string): Raw<TResult>;
1321 toSQL(): Sql;
1322 queryContext(context: any): Raw<TResult>;
1323 }
1324
1325 interface RawBuilder<TRecord extends {} = any, TResult = any> {
1326 <TResult2 = TResult>(value: Value): Raw<TResult2>;
1327 <TResult2 = TResult>(sql: string, ...bindings: RawBinding[]): Raw<TResult2>;
1328 <TResult2 = TResult>(sql: string, bindings: RawBinding[] | ValueDict): Raw<TResult2>;
1329 }
1330
1331 interface Ref<TSrc extends string, TMapping extends {}> extends Raw<string> {
1332 withSchema(schema: string): this;
1333 as<TAlias extends string>(alias: TAlias): Ref<TSrc, {[K in TAlias]: TSrc}>;
1334 }
1335
1336 interface RefBuilder {
1337 <TSrc extends string>(src: TSrc): Ref<TSrc, {[K in TSrc]: TSrc}>;
1338 }
1339
1340 //
1341 // QueryBuilder
1342 //
1343
1344 type QueryCallback<TRecord = any, TResult = unknown[]> = (
1345 this: QueryBuilder<TRecord, TResult>,
1346 builder: QueryBuilder<TRecord, TResult>
1347 ) => void;
1348
1349 type QueryCallbackWithArgs<TRecord = any, TResult = unknown[]> = (
1350 this: QueryBuilder<TRecord, TResult>,
1351 builder: QueryBuilder<TRecord, TResult>,
1352 ...args: any[]
1353 ) => void;
1354
1355 interface QueryBuilder<
1356 TRecord extends {} = any,
1357 TResult = SafePartial<TRecord>[]
1358 >
1359 extends QueryInterface<TRecord, TResult>,
1360 ChainableInterface<ResolveResult<TResult>> {
1361 or: QueryBuilder<TRecord, TResult>;
1362 not: QueryBuilder<TRecord, TResult>;
1363 and: QueryBuilder<TRecord, TResult>;
1364
1365 // TODO: Promise?
1366 columnInfo(column?: keyof TRecord): Promise<ColumnInfo>;
1367
1368 forUpdate(...tableNames: string[]): QueryBuilder<TRecord, TResult>;
1369 forUpdate(tableNames: string[]): QueryBuilder<TRecord, TResult>;
1370
1371 forShare(...tableNames: string[]): QueryBuilder<TRecord, TResult>;
1372 forShare(tableNames: string[]): QueryBuilder<TRecord, TResult>;
1373
1374 skipLocked(): QueryBuilder<TRecord, TResult>;
1375 noWait(): QueryBuilder<TRecord, TResult>;
1376
1377 toSQL(): Sql;
1378
1379 on(event: string, callback: Function): QueryBuilder<TRecord, TResult>;
1380
1381 queryContext(context: any): QueryBuilder<TRecord, TResult>;
1382
1383 clone(): QueryBuilder<TRecord, TResult>;
1384 timeout(ms: number, options?: {cancel?: boolean}): QueryBuilder<TRecord, TResult>;
1385 }
1386
1387 interface Sql {
1388 method: string;
1389 options: any;
1390 bindings: Value[];
1391 sql: string;
1392 toNative(): SqlNative;
1393 }
1394
1395 interface SqlNative {
1396 bindings: Value[];
1397 sql: string;
1398 }
1399
1400 //
1401 // Chainable interface
1402 //
1403
1404 interface ChainableInterface<T = any> extends Promise<T> {
1405 toQuery(): string;
1406 options(options: { [key: string]: any }): this;
1407 connection(connection: any): this;
1408 debug(enabled: boolean): this;
1409 transacting(trx: Transaction): this;
1410 stream(handler: (readable: stream.PassThrough) => any): Promise<any>;
1411 stream(
1412 options: { [key: string]: any },
1413 handler: (readable: stream.PassThrough) => any
1414 ): Promise<any>;
1415 stream(options?: { [key: string]: any }): stream.PassThrough;
1416 pipe<T extends NodeJS.WritableStream>(
1417 writable: T,
1418 options?: { [key: string]: any }
1419 ): stream.PassThrough;
1420 asCallback(callback: Function): this;
1421 }
1422
1423 interface Transaction<TRecord extends {} = any, TResult = any>
1424 extends Knex<TRecord, TResult> {
1425 executionPromise: Promise<TResult>;
1426 isCompleted: () => boolean;
1427
1428 query<TRecord extends {} = any, TResult = void>(
1429 conn: any,
1430 sql: any,
1431 status: any,
1432 value: any
1433 ): QueryBuilder<TRecord, TResult>;
1434 savepoint<T = any>(
1435 transactionScope: (trx: Transaction) => any
1436 ): Promise<T>;
1437 commit(value?: any): QueryBuilder<TRecord, TResult>;
1438 rollback(error?: any): QueryBuilder<TRecord, TResult>;
1439 }
1440
1441 //
1442 // Schema builder
1443 //
1444
1445 interface SchemaBuilder extends ChainableInterface<void> {
1446 createTable(
1447 tableName: string,
1448 callback: (tableBuilder: CreateTableBuilder) => any
1449 ): SchemaBuilder;
1450 createTableIfNotExists(
1451 tableName: string,
1452 callback: (tableBuilder: CreateTableBuilder) => any
1453 ): SchemaBuilder;
1454 alterTable(
1455 tableName: string,
1456 callback: (tableBuilder: CreateTableBuilder) => any
1457 ): SchemaBuilder;
1458 renameTable(oldTableName: string, newTableName: string): Promise<void>;
1459 dropTable(tableName: string): SchemaBuilder;
1460 hasTable(tableName: string): Promise<boolean>;
1461 hasColumn(tableName: string, columnName: string): Promise<boolean>;
1462 table(
1463 tableName: string,
1464 callback: (tableBuilder: AlterTableBuilder) => any
1465 ): Promise<void>;
1466 dropTableIfExists(tableName: string): SchemaBuilder;
1467 raw(statement: string): SchemaBuilder;
1468 withSchema(schemaName: string): SchemaBuilder;
1469 queryContext(context: any): SchemaBuilder;
1470 }
1471
1472 interface TableBuilder {
1473 increments(columnName?: string): ColumnBuilder;
1474 bigIncrements(columnName?: string): ColumnBuilder;
1475 dropColumn(columnName: string): TableBuilder;
1476 dropColumns(...columnNames: string[]): TableBuilder;
1477 renameColumn(from: string, to: string): ColumnBuilder;
1478 integer(columnName: string, length?: number): ColumnBuilder;
1479 bigInteger(columnName: string): ColumnBuilder;
1480 text(columnName: string, textType?: string): ColumnBuilder;
1481 string(columnName: string, length?: number): ColumnBuilder;
1482 float(
1483 columnName: string,
1484 precision?: number,
1485 scale?: number
1486 ): ColumnBuilder;
1487 decimal(
1488 columnName: string,
1489 precision?: number | null,
1490 scale?: number
1491 ): ColumnBuilder;
1492 boolean(columnName: string): ColumnBuilder;
1493 date(columnName: string): ColumnBuilder;
1494 dateTime(columnName: string, options?: {useTz?: boolean, precision?: number}): ColumnBuilder;
1495 time(columnName: string): ColumnBuilder;
1496 timestamp(columnName: string, options?: {useTz?: boolean, precision?: number}): ColumnBuilder;
1497 /** @deprecated */
1498 timestamp(columnName: string, withoutTz?: boolean, precision?: number): ColumnBuilder;
1499 timestamps(
1500 useTimestampType?: boolean,
1501 makeDefaultNow?: boolean
1502 ): ColumnBuilder;
1503 binary(columnName: string, length?: number): ColumnBuilder;
1504 enum(
1505 columnName: string,
1506 values: Value[],
1507 options?: EnumOptions
1508 ): ColumnBuilder;
1509 enu(
1510 columnName: string,
1511 values: Value[],
1512 options?: EnumOptions
1513 ): ColumnBuilder;
1514 json(columnName: string): ColumnBuilder;
1515 jsonb(columnName: string): ColumnBuilder;
1516 uuid(columnName: string): ColumnBuilder;
1517 comment(val: string): TableBuilder;
1518 specificType(columnName: string, type: string): ColumnBuilder;
1519 primary(columnNames: string[], constraintName?: string): TableBuilder;
1520 index(
1521 columnNames: string | (string | Raw)[],
1522 indexName?: string,
1523 indexType?: string
1524 ): TableBuilder;
1525 unique(columnNames: (string | Raw)[], indexName?: string): TableBuilder;
1526 foreign(column: string, foreignKeyName?: string): ForeignConstraintBuilder;
1527 foreign(
1528 columns: string[],
1529 foreignKeyName?: string
1530 ): MultikeyForeignConstraintBuilder;
1531 dropForeign(columnNames: string[], foreignKeyName?: string): TableBuilder;
1532 dropUnique(columnNames: (string | Raw)[], indexName?: string): TableBuilder;
1533 dropPrimary(constraintName?: string): TableBuilder;
1534 dropIndex(columnNames: string | (string | Raw)[], indexName?: string): TableBuilder;
1535 dropTimestamps(): ColumnBuilder;
1536 queryContext(context: any): TableBuilder;
1537 }
1538
1539 interface CreateTableBuilder extends TableBuilder {}
1540
1541 interface MySqlTableBuilder extends CreateTableBuilder {
1542 engine(val: string): CreateTableBuilder;
1543 charset(val: string): CreateTableBuilder;
1544 collate(val: string): CreateTableBuilder;
1545 }
1546
1547 interface PostgreSqlTableBuilder extends CreateTableBuilder {
1548 inherits(val: string): CreateTableBuilder;
1549 }
1550
1551 interface AlterTableBuilder extends TableBuilder {}
1552
1553 interface MySqlAlterTableBuilder extends AlterTableBuilder {}
1554
1555 interface PostgreSqlAlterTableBuilder extends AlterTableBuilder {}
1556
1557 interface ColumnBuilder {
1558 index(indexName?: string): ColumnBuilder;
1559 primary(constraintName?: string): ColumnBuilder;
1560 unique(indexName?: string): ColumnBuilder;
1561 references(columnName: string): ReferencingColumnBuilder;
1562 onDelete(command: string): ColumnBuilder;
1563 onUpdate(command: string): ColumnBuilder;
1564 defaultTo(value: Value | null): ColumnBuilder;
1565 unsigned(): ColumnBuilder;
1566 notNullable(): ColumnBuilder;
1567 nullable(): ColumnBuilder;
1568 comment(value: string): ColumnBuilder;
1569 alter(): ColumnBuilder;
1570 queryContext(context: any): ColumnBuilder;
1571 }
1572
1573 interface ForeignConstraintBuilder {
1574 references(columnName: string): ReferencingColumnBuilder;
1575 }
1576
1577 interface MultikeyForeignConstraintBuilder {
1578 references(columnNames: string[]): ReferencingColumnBuilder;
1579 }
1580
1581 interface PostgreSqlColumnBuilder extends ColumnBuilder {
1582 index(indexName?: string, indexType?: string): ColumnBuilder;
1583 }
1584
1585 interface ReferencingColumnBuilder extends ColumnBuilder {
1586 inTable(tableName: string): ColumnBuilder;
1587 }
1588
1589 interface AlterColumnBuilder extends ColumnBuilder {}
1590
1591 interface MySqlAlterColumnBuilder extends AlterColumnBuilder {
1592 first(): AlterColumnBuilder;
1593 after(columnName: string): AlterColumnBuilder;
1594 }
1595
1596 //
1597 // Configurations
1598 //
1599
1600 interface ColumnInfo {
1601 defaultValue: Value;
1602 type: string;
1603 maxLength: number;
1604 nullable: boolean;
1605 }
1606
1607 interface Config {
1608 debug?: boolean;
1609 client?: string | typeof Client;
1610 dialect?: string;
1611 version?: string;
1612 connection?:
1613 | string
1614 | ConnectionConfig
1615 | MariaSqlConnectionConfig
1616 | MySqlConnectionConfig
1617 | MsSqlConnectionConfig
1618 | OracleDbConnectionConfig
1619 | Sqlite3ConnectionConfig
1620 | SocketConnectionConfig;
1621 pool?: PoolConfig;
1622 migrations?: MigratorConfig;
1623 postProcessResponse?: (result: any, queryContext: any) => any;
1624 wrapIdentifier?: (
1625 value: string,
1626 origImpl: (value: string) => string,
1627 queryContext: any
1628 ) => string;
1629 seeds?: SeedsConfig;
1630 acquireConnectionTimeout?: number;
1631 useNullAsDefault?: boolean;
1632 searchPath?: string | string[];
1633 asyncStackTraces?: boolean;
1634 log?: Logger;
1635 }
1636
1637 interface ConnectionConfig {
1638 host: string;
1639 user: string;
1640 password: string;
1641 database: string;
1642 domain?: string;
1643 instanceName?: string;
1644 debug?: boolean;
1645 requestTimeout?: number;
1646 }
1647
1648 // Config object for mssql: see https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/mssql/index.d.ts
1649 interface MsSqlConnectionConfig {
1650 driver?: string;
1651 user?: string;
1652 password?: string;
1653 server: string;
1654 port?: number;
1655 domain?: string;
1656 database: string;
1657 connectionTimeout?: number;
1658 requestTimeout?: number;
1659 stream?: boolean;
1660 parseJSON?: boolean;
1661 options?: {
1662 encrypt?: boolean;
1663 instanceName?: string;
1664 useUTC?: boolean;
1665 tdsVersion?: string;
1666 appName?: string;
1667 abortTransactionOnError?: boolean;
1668 trustedConnection?: boolean;
1669 };
1670 pool?: {
1671 min?: number;
1672 max?: number;
1673 idleTimeoutMillis?: number;
1674 maxWaitingClients?: number;
1675 testOnBorrow?: boolean;
1676 acquireTimeoutMillis?: number;
1677 fifo?: boolean;
1678 priorityRange?: number;
1679 autostart?: boolean;
1680 evictionRunIntervalMillis?: number;
1681 numTestsPerRun?: number;
1682 softIdleTimeoutMillis?: number;
1683 Promise?: any;
1684 };
1685 }
1686
1687 // Config object for mariasql: https://github.com/mscdex/node-mariasql#client-methods
1688 interface MariaSqlConnectionConfig {
1689 user?: string;
1690 password?: string;
1691 host?: string;
1692 port?: number;
1693 unixSocket?: string;
1694 protocol?: string;
1695 db?: string;
1696 keepQueries?: boolean;
1697 multiStatements?: boolean;
1698 connTimeout?: number;
1699 pingInterval?: number;
1700 secureAuth?: boolean;
1701 compress?: boolean;
1702 ssl?: boolean | MariaSslConfiguration;
1703 local_infile?: boolean;
1704 read_default_file?: string;
1705 read_default_group?: string;
1706 charset?: string;
1707 streamHWM?: number;
1708 }
1709
1710 interface MariaSslConfiguration {
1711 key?: string;
1712 cert?: string;
1713 ca?: string;
1714 capath?: string;
1715 cipher?: string;
1716 rejectUnauthorized?: boolean;
1717 }
1718
1719 // Config object for mysql: https://github.com/mysqljs/mysql#connection-options
1720 interface MySqlConnectionConfig {
1721 host?: string;
1722 port?: number;
1723 localAddress?: string;
1724 socketPath?: string;
1725 user?: string;
1726 password?: string;
1727 database?: string;
1728 charset?: string;
1729 timezone?: string;
1730 connectTimeout?: number;
1731 stringifyObjects?: boolean;
1732 insecureAuth?: boolean;
1733 typeCast?: any;
1734 queryFormat?: (query: string, values: any) => string;
1735 supportBigNumbers?: boolean;
1736 bigNumberStrings?: boolean;
1737 dateStrings?: boolean;
1738 debug?: boolean;
1739 trace?: boolean;
1740 multipleStatements?: boolean;
1741 flags?: string;
1742 ssl?: string | MariaSslConfiguration;
1743 decimalNumbers?: boolean;
1744 }
1745
1746 interface OracleDbConnectionConfig {
1747 host: string;
1748 user: string;
1749 password?: string;
1750 database?: string;
1751 domain?: string;
1752 instanceName?: string;
1753 debug?: boolean;
1754 requestTimeout?: number;
1755 connectString?: string;
1756 }
1757
1758 /** Used with SQLite3 adapter */
1759 interface Sqlite3ConnectionConfig {
1760 filename: string;
1761 debug?: boolean;
1762 }
1763
1764 interface SocketConnectionConfig {
1765 socketPath: string;
1766 user: string;
1767 password: string;
1768 database: string;
1769 debug?: boolean;
1770 }
1771
1772 interface PoolConfig {
1773 name?: string;
1774 create?: Function;
1775 afterCreate?: Function;
1776 destroy?: Function;
1777 min?: number;
1778 max?: number;
1779 refreshIdle?: boolean;
1780 idleTimeoutMillis?: number;
1781 reapIntervalMillis?: number;
1782 returnToHead?: boolean;
1783 priorityRange?: number;
1784 validate?: Function;
1785 log?: boolean;
1786
1787 // generic-pool v3 configs
1788 maxWaitingClients?: number;
1789 testOnBorrow?: boolean;
1790 acquireTimeoutMillis?: number;
1791 fifo?: boolean;
1792 autostart?: boolean;
1793 evictionRunIntervalMillis?: number;
1794 numTestsPerRun?: number;
1795 softIdleTimeoutMillis?: number;
1796 Promise?: any;
1797 }
1798
1799 type LogFn = (message: string) => void;
1800
1801 interface Logger {
1802 warn?: LogFn;
1803 error?: LogFn;
1804 debug?: LogFn;
1805 deprecate?: (method: string, alternative: string) => void;
1806 }
1807
1808 interface MigratorConfig {
1809 database?: string;
1810 directory?: string | string[];
1811 extension?: string;
1812 stub?: string;
1813 tableName?: string;
1814 schemaName?: string;
1815 disableTransactions?: boolean;
1816 disableMigrationsListValidation?: boolean;
1817 sortDirsSeparately?: boolean;
1818 loadExtensions?: string[];
1819 migrationSource?: any;
1820 }
1821
1822 interface SeedsConfig {
1823 directory?: string;
1824 stub?: string;
1825 }
1826
1827 interface Migrator {
1828 make(name: string, config?: MigratorConfig): Promise<string>;
1829 latest(config?: MigratorConfig): Promise<any>;
1830 rollback(config?: MigratorConfig, all?: boolean): Promise<any>;
1831 status(config?: MigratorConfig): Promise<number>;
1832 currentVersion(config?: MigratorConfig): Promise<string>;
1833 list(config?: MigratorConfig): Promise<any>;
1834 up(config?: MigratorConfig): Promise<any>;
1835 down(config?: MigratorConfig): Promise<any>;
1836 forceFreeMigrationsLock(config?: MigratorConfig): Promise<any>;
1837 }
1838
1839 interface SeederConfig {
1840 extension?: string;
1841 directory?: string;
1842 loadExtensions?: string[];
1843 specific?: string;
1844 }
1845
1846 class Seeder {
1847 constructor(knex: Knex);
1848 setConfig(config: SeederConfig): SeederConfig;
1849 run(config?: SeederConfig): Promise<[string[]]>;
1850 make(name: string, config?: SeederConfig): Promise<string>;
1851 }
1852
1853 interface FunctionHelper {
1854 now(): Raw;
1855 }
1856
1857 interface EnumOptions {
1858 useNative: boolean;
1859 existingType?: boolean;
1860 schemaName?: string;
1861 enumName: string;
1862 }
1863
1864 //
1865 // Clients
1866 //
1867
1868 class Client extends events.EventEmitter {
1869 constructor(config: Config);
1870 config: Config;
1871 dialect: string;
1872 driverName: string;
1873 connectionSettings: object;
1874
1875 acquireRawConnection(): Promise<any>;
1876 destroyRawConnection(connection: any): Promise<void>;
1877 validateConnection(connection: any): Promise<boolean>;
1878 }
1879
1880 class QueryBuilder {
1881 static extend(
1882 methodName: string,
1883 fn: <TRecord extends {} = any, TResult = unknown[]>(
1884 this: Knex<TRecord, TResult>,
1885 ...args: any[]
1886 ) => QueryBuilder<TRecord, TResult>
1887 ): void;
1888 }
1889}
1890
1891export = Knex;