UNPKG

knex

Version:

A batteries-included SQL query & schema builder for Postgres, MySQL and SQLite3 and the Browser

1,515 lines (1,363 loc) 57 kB
// Originally based on contributions to DefinitelyTyped: // Definitions by: Qubo <https://github.com/tkQubo> // Pablo Rodríguez <https://github.com/MeLlamoPablo> // Matt R. Wilson <https://github.com/mastermatt> // Satana Charuwichitratana <https://github.com/micksatana> // Shrey Jain <https://github.com/shreyjain1994> // TypeScript Version: 3.2 /// <reference types="node" /> import events = require('events'); import stream = require('stream'); import Bluebird = require('bluebird'); // # Generic type-level utilities // If T is object then make it a partial otherwise fallback to any // // This is primarily to prevent type incompatibilities where target can be unknown. // While unknown can be assigned to any, Partial<unknown> can't be. type SafePartial<T> = T extends {} ? Partial<T> : any; type MaybeArray<T> = T | T[]; type StrKey<T> = string & keyof T; // If T is unknown then convert to any, else retain original type UnknownToAny<T> = ArrayIfAlready<T, unknown extends UnwrapArrayMember<T> ? any : UnwrapArrayMember<T>>; // Intersection conditionally applied only when TParams is non-empty // This is primarily to keep the signatures more intuitive. type AugmentParams<TTarget, TParams> = TParams extends {} ? keyof TParams extends never ? TTarget : {} & TTarget & TParams : TTarget; // Check if provided keys (expressed as a single or union type) are members of TBase type AreKeysOf<TBase, TKeys> = Boxed<TKeys> extends Boxed<keyof TBase> ? true : false; // https://stackoverflow.com/a/50375286/476712 type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never; type ComparisionOperator = '=' | '>' | '>=' | '<' | '<=' | '<>'; // If T is an array, get the type of member, else fall back to never type ArrayMember<T> = T extends (infer M)[] ? M : never; // If T is an array, get the type of member, else retain original type UnwrapArrayMember<T> = T extends (infer M)[] ? M : T; // Wrap a type in a container, making it an object type. // This is primarily useful in circumventing special handling of union/intersection in typescript interface Boxed<T> { _value: T; } // If T can't be assigned to TBase fallback to an alternate type TAlt type IncompatibleToAlt<T, TBase, TAlt> = T extends TBase ? T : TAlt; type ArrayIfAlready<T1, T2> = T1 extends any[] ? T2[] : T2; // Boxing is necessary to prevent distribution of conditional types: // https://lorefnon.tech/2019/05/02/using-boxing-to-prevent-distribution-of-conditional-types/ type PartialOrAny<TBase, TKeys> = Boxed<TKeys> extends Boxed<never> ? {} : Boxed<TKeys> extends Boxed<keyof TBase> ? Pick<TBase, TKeys & keyof TBase> : any; // Retain the association of original keys with aliased keys at type level // to facilitates type-safe aliasing for object syntax type MappedAliasType<TBase, TAliasMapping> = {} & { [K in keyof TAliasMapping]: TAliasMapping[K] extends keyof TBase ? TBase[TAliasMapping[K]] : any }; // Container type for situations when we want a partial/intersection eventually // but the keys being selected or additional properties being augmented are not // all known at once and we would want to effectively build up a partial/intersection // over multiple steps. interface DeferredKeySelection< // The base of selection. In intermediate stages this may be unknown. // If it remains unknown at the point of resolution, the selection will fall back to any TBase, // Union of keys to be selected // In intermediate stages this may be never. TKeys extends string, // Changes how the resolution should behave if TKeys is never. // If true, then we assume that some keys were selected, and if TKeys is never, we will fall back to any. // If false, and TKeys is never, then we select TBase in its entirity THasSelect extends true | false = false, // Mapping of aliases <key in result> -> <key in TBase> TAliasMapping extends {} = {}, // If enabled, then instead of extracting a partial, during resolution // we will pick just a single property. TSingle extends boolean = false, // Extra props which will be intersected with the result TIntersectProps extends {} = {}, // Extra props which will be unioned with the result TUnionProps = never > { // These properties are not actually used, but exist simply because // typescript doesn't end up happy when type parameters are unused _base: TBase; _hasSelection: THasSelect; _keys: TKeys; _aliases: TAliasMapping; _single: TSingle; _intersectProps: TIntersectProps; _unionProps: TUnionProps; } // An companion namespace for DeferredKeySelection which provides type operators // to build up participants of intersection/partial over multiple invocations // and for final resolution. // // While the comments use wordings such as replacement and addition, it is important // to keep in mind that types are always immutable and all type operators return new altered types. declare namespace DeferredKeySelection { type Any = DeferredKeySelection<any, any, any, any, any, any, any>; // Replace the Base if already a deferred selection. // If not, create a new deferred selection with specified base. type SetBase<TSelection, TBase> = TSelection extends DeferredKeySelection< any, infer TKeys, infer THasSelect, infer TAliasMapping, infer TSingle, infer TIntersectProps, infer TUnionProps > ? DeferredKeySelection<TBase, TKeys, THasSelect, TAliasMapping, TSingle, TIntersectProps, TUnionProps> : DeferredKeySelection<TBase, never>; // If TSelection is already a deferred selection, then replace the base with TBase // If unknown, create a new deferred selection with TBase as the base // Else, retain original // // For practical reasons applicable to current context, we always return arrays of // deferred selections. So, this particular operator may not be useful in generic contexts. type ReplaceBase<TSelection, TBase> = UnwrapArrayMember< TSelection > extends DeferredKeySelection.Any ? ArrayIfAlready<TSelection, DeferredKeySelection.SetBase<UnwrapArrayMember<TSelection>, TBase>> : unknown extends UnwrapArrayMember<TSelection> ? ArrayIfAlready<TSelection, DeferredKeySelection.SetBase<unknown, TBase>> : TSelection; // Type operators to substitute individual type parameters: type SetSingle< TSelection, TSingle extends boolean > = TSelection extends DeferredKeySelection< infer TBase, infer TKeys, infer THasSelect, infer TAliasMapping, any, infer TIntersectProps, infer TUnionProps > ? DeferredKeySelection<TBase, TKeys, THasSelect, TAliasMapping, TSingle, TIntersectProps, TUnionProps> : never; type AddKey< TSelection, TKey extends string > = TSelection extends DeferredKeySelection< infer TBase, infer TKeys, any, infer TAliasMapping, infer TSingle, infer TIntersectProps, infer TUnionProps > ? DeferredKeySelection<TBase, TKeys | TKey, true, TAliasMapping, TSingle, TIntersectProps, TUnionProps> : DeferredKeySelection<unknown, TKey, true>; type AddAliases<TSelection, T> = TSelection extends DeferredKeySelection< infer TBase, infer TKeys, infer THasSelect, infer TAliasMapping, infer TSingle, infer TIntersectProps, infer TUnionProps > ? DeferredKeySelection<TBase, TKeys, THasSelect, TAliasMapping & T, TSingle, TIntersectProps, TUnionProps> : DeferredKeySelection<unknown, never, false, T>; type AddUnionMember<TSelection, T> = TSelection extends DeferredKeySelection< infer TBase, infer TKeys, infer THasSelect, infer TAliasMapping, infer TSingle, infer TIntersectProps, infer TUnionProps > ? DeferredKeySelection<TBase, TKeys, THasSelect, TAliasMapping, TSingle, TIntersectProps, TUnionProps | T> : DeferredKeySelection<TSelection, never, false, {}, false, {}, T>; // Convenience utility to set base, keys and aliases in a single type // application type Augment<T, TBase, TKey extends string, TAliasMapping = {}> = AddAliases< AddKey<SetBase<T, TBase>, TKey>, TAliasMapping >; // Core resolution logic -- Refer to docs for DeferredKeySelection for specifics type ResolveOne<TSelection> = TSelection extends DeferredKeySelection< infer TBase, infer TKeys, infer THasSelect, infer TAliasMapping, infer TSingle, infer TIntersectProps, infer TUnionProps > ? AugmentParams< TBase extends {} ? TSingle extends true ? TKeys extends keyof TBase ? TBase[TKeys] : any : AugmentParams< true extends THasSelect ? PartialOrAny<TBase, TKeys> : TBase, MappedAliasType<TBase, TAliasMapping> > : unknown, TIntersectProps > | TUnionProps : TSelection; // Resolution logic lifted over arrays of deferred selections type Resolve<TSelection> = UnknownToAny< ArrayIfAlready<TSelection, ResolveOne<UnwrapArrayMember<TSelection>>> >; } type AggregationQueryResult<TResult, TIntersectProps2> = ArrayIfAlready< TResult, UnwrapArrayMember<TResult> extends DeferredKeySelection< infer TBase, infer TKeys, infer THasSelect, infer TAliasMapping, infer TSingle, infer TIntersectProps, infer TUnionProps > ? true extends THasSelect ? DeferredKeySelection<TBase, TKeys, THasSelect, TAliasMapping, TSingle, TIntersectProps & TIntersectProps2, TUnionProps> : DeferredKeySelection<{}, never, true, {}, false, TIntersectProps2> : TIntersectProps2 >; // Convenience alias and associated companion namespace for working // with DeferredSelection having TSingle=true. // // When TSingle=true in DeferredSelection, then we are effectively // deferring an index access operation (TBase[TKey]) over a potentially // unknown initial type of TBase and potentially never initial type of TKey interface DeferredIndex<TBase, TKey extends string> extends DeferredKeySelection<TBase, TKey, false, {}, true> {} declare namespace DeferredIndex { type Augment< T, TBase, TKey extends string, TAliasMapping = {} > = DeferredKeySelection.SetSingle< DeferredKeySelection.AddKey<DeferredKeySelection.SetBase<T, TBase>, TKey>, true >; } // If we have more categories of deferred selection in future, // this will combine all of them type ResolveResult<S> = DeferredKeySelection.Resolve<S>; // # Type-aliases for common type combinations type Callback = Function; type Client = Function; interface Dict<T = any> { [k: string]: T; } type SafePick<T, K extends keyof T> = T extends {} ? Pick<T, K> : any; interface Knex<TRecord extends {} = any, TResult = any[]> extends Knex.QueryInterface<TRecord, TResult>, events.EventEmitter { <TRecord2 = TRecord, TResult2 = DeferredKeySelection<TRecord2, never>[]>( tableName?: Knex.TableDescriptor | Knex.AliasDict ): Knex.QueryBuilder<TRecord2, TResult2>; VERSION: string; __knex__: string; raw: Knex.RawBuilder<TRecord, TResult>; transactionProvider( config?: any ): () => Promise<Knex.Transaction>; transaction( transactionScope?: undefined | null, config?: any ): Promise<Knex.Transaction>; transaction<T>( transactionScope: (trx: Knex.Transaction) => Promise<T> | Bluebird<T> | void, config?: any ): Bluebird<T>; initialize(config?: Knex.Config): void; destroy(callback: Function): void; destroy(): Bluebird<void>; batchInsert( tableName: Knex.TableDescriptor, data: any[], chunkSize?: number ): Knex.QueryBuilder<TRecord, {}>; schema: Knex.SchemaBuilder; queryBuilder<TRecord2 = TRecord, TResult2 = TResult>(): Knex.QueryBuilder< TRecord2, TResult2 >; client: any; migrate: Knex.Migrator; seed: Knex.Seeder; fn: Knex.FunctionHelper; ref: Knex.RefBuilder; } declare function Knex<TRecord = any, TResult = unknown[]>( config: Knex.Config | string ): Knex<TRecord, TResult>; declare namespace Knex { // // Utility Types // type Value = | string | number | boolean | Date | Array<string> | Array<number> | Array<Date> | Array<boolean> | Buffer | Knex.Raw; interface ValueDict extends Dict<Value | Knex.QueryBuilder> {} interface AliasDict extends Dict<string> {} type ColumnDescriptor<TRecord, TResult> = | string | Knex.Raw | Knex.QueryBuilder<TRecord, TResult> | Dict<string>; type InferrableColumnDescriptor<TRecord extends {}> = | keyof TRecord | Knex.Ref<any, any> | Dict<keyof TRecord>; type TableDescriptor = string | Knex.Raw | Knex.QueryBuilder; // // QueryInterface // interface QueryInterface<TRecord extends {} = any, TResult = any[]> { select: Select<TRecord, TResult>; as: As<TRecord, TResult>; columns: Select<TRecord, TResult>; column: Select<TRecord, TResult>; from: Table<TRecord, TResult>; into: Table<TRecord, TResult>; table: Table<TRecord, TResult>; distinct: Distinct<TRecord, TResult>; // Joins join: Join<TRecord, TResult>; joinRaw: JoinRaw<TRecord, TResult>; innerJoin: Join<TRecord, TResult>; leftJoin: Join<TRecord, TResult>; leftOuterJoin: Join<TRecord, TResult>; rightJoin: Join<TRecord, TResult>; rightOuterJoin: Join<TRecord, TResult>; outerJoin: Join<TRecord, TResult>; fullOuterJoin: Join<TRecord, TResult>; crossJoin: Join<TRecord, TResult>; // Withs with: With<TRecord, TResult>; withRecursive: With<TRecord, TResult>; withRaw: WithRaw<TRecord, TResult>; withSchema: WithSchema<TRecord, TResult>; withWrapped: WithWrapped<TRecord, TResult>; // Wheres where: Where<TRecord, TResult>; andWhere: Where<TRecord, TResult>; orWhere: Where<TRecord, TResult>; whereNot: Where<TRecord, TResult>; andWhereNot: Where<TRecord, TResult>; orWhereNot: Where<TRecord, TResult>; whereRaw: WhereRaw<TRecord, TResult>; orWhereRaw: WhereRaw<TRecord, TResult>; andWhereRaw: WhereRaw<TRecord, TResult>; whereWrapped: WhereWrapped<TRecord, TResult>; havingWrapped: WhereWrapped<TRecord, TResult>; whereExists: WhereExists<TRecord, TResult>; orWhereExists: WhereExists<TRecord, TResult>; whereNotExists: WhereExists<TRecord, TResult>; orWhereNotExists: WhereExists<TRecord, TResult>; whereIn: WhereIn<TRecord, TResult>; orWhereIn: WhereIn<TRecord, TResult>; whereNotIn: WhereIn<TRecord, TResult>; orWhereNotIn: WhereIn<TRecord, TResult>; whereNull: WhereNull<TRecord, TResult>; orWhereNull: WhereNull<TRecord, TResult>; whereNotNull: WhereNull<TRecord, TResult>; orWhereNotNull: WhereNull<TRecord, TResult>; whereBetween: WhereBetween<TRecord, TResult>; orWhereBetween: WhereBetween<TRecord, TResult>; andWhereBetween: WhereBetween<TRecord, TResult>; whereNotBetween: WhereBetween<TRecord, TResult>; orWhereNotBetween: WhereBetween<TRecord, TResult>; andWhereNotBetween: WhereBetween<TRecord, TResult>; // Group by groupBy: GroupBy<TRecord, TResult>; groupByRaw: RawQueryBuilder<TRecord, TResult>; // Order by orderBy: OrderBy<TRecord, TResult>; orderByRaw: RawQueryBuilder<TRecord, TResult>; // Intersect intersect: Intersect<TRecord, TResult>; // Union union: Union<TRecord, TResult>; unionAll: Union<TRecord, TResult>; // Having having: Having<TRecord, TResult>; andHaving: Having<TRecord, TResult>; havingRaw: RawQueryBuilder<TRecord, TResult>; orHaving: Having<TRecord, TResult>; orHavingRaw: RawQueryBuilder<TRecord, TResult>; havingIn: HavingRange<TRecord, TResult>; orHavingNotBetween: HavingRange<TRecord, TResult>; havingNotBetween: HavingRange<TRecord, TResult>; orHavingBetween: HavingRange<TRecord, TResult>; havingBetween: HavingRange<TRecord, TResult>; // Clear clearSelect(): QueryBuilder< TRecord, UnwrapArrayMember<TResult> extends DeferredKeySelection< infer TBase, infer TKeys, true, any, any, any, any > ? DeferredKeySelection<TBase, never>[] : TResult >; clearWhere(): QueryBuilder<TRecord, TResult>; clearOrder(): QueryBuilder<TRecord, TResult>; clearHaving(): QueryBuilder<TRecord, TResult>; clearCounters(): QueryBuilder<TRecord, TResult>; // Paging offset(offset: number): QueryBuilder<TRecord, TResult>; limit(limit: number): QueryBuilder<TRecord, TResult>; // Aggregation count: AssymetricAggregation<TRecord, TResult, number | string>; countDistinct: AssymetricAggregation<TRecord, TResult, number | string>; min: TypePreservingAggregation<TRecord, TResult>; max: TypePreservingAggregation<TRecord, TResult>; sum: TypePreservingAggregation<TRecord, TResult>; sumDistinct: TypePreservingAggregation<TRecord, TResult>; avg: TypePreservingAggregation<TRecord, TResult>; avgDistinct: TypePreservingAggregation<TRecord, TResult>; increment( columnName: keyof TRecord, amount?: number ): QueryBuilder<TRecord, number>; increment( columnName: string, amount?: number ): QueryBuilder<TRecord, number>; decrement( columnName: keyof TRecord, amount?: number ): QueryBuilder<TRecord, number>; decrement( columnName: string, amount?: number ): QueryBuilder<TRecord, number>; // Others first: Select<TRecord, DeferredKeySelection.AddUnionMember<UnwrapArrayMember<TResult>, undefined>>; pluck<K extends keyof TRecord>( column: K ): QueryBuilder<TRecord, TRecord[K][]>; pluck<TResult2 extends {}>(column: string): QueryBuilder<TRecord, TResult2>; insert< TKey extends StrKey<TRecord>, TResult2 = DeferredIndex.Augment< UnwrapArrayMember<TResult>, TRecord, TKey >[] >( data: MaybeArray<SafePartial<TRecord>>, returning: TKey ): QueryBuilder<TRecord, TResult2>; insert< TKey extends StrKey<TRecord>, TResult2 = DeferredKeySelection.Augment< UnwrapArrayMember<TResult>, TRecord, TKey >[] >( data: MaybeArray<SafePartial<TRecord>>, returning: TKey[] ): QueryBuilder<TRecord, TResult2>; insert< TKey extends string, TResult2 = DeferredIndex.Augment< UnwrapArrayMember<TResult>, TRecord, TKey >[] >( data: MaybeArray<SafePartial<TRecord>>, returning: TKey ): QueryBuilder<TRecord, TResult2>; insert< TKey extends string, TResult2 = DeferredIndex.Augment< UnwrapArrayMember<TResult>, TRecord, TKey >[] >( data: MaybeArray<SafePartial<TRecord>>, returning: TKey[] ): QueryBuilder<TRecord, TResult2>; insert<TResult2 = number[]>( data: MaybeArray<SafePartial<TRecord>> ): QueryBuilder<TRecord, TResult2>; modify<TRecord2 extends {} = any, TResult2 extends {} = any>( callback: QueryCallbackWithArgs<TRecord, any>, ...args: any[] ): QueryBuilder<TRecord2, TResult2>; update< TKey extends StrKey<TRecord>, TResult2 = DeferredIndex.Augment< UnwrapArrayMember<TResult>, TRecord, TKey >[] >( data: MaybeArray<SafePartial<TRecord>>, returning: TKey ): QueryBuilder<TRecord, TResult2>; update< TKey extends StrKey<TRecord>, TResult2 = DeferredKeySelection.Augment< UnwrapArrayMember<TResult>, TRecord, TKey >[] >( data: MaybeArray<SafePartial<TRecord>>, returning: TKey[] ): QueryBuilder<TRecord, TResult2>; update< TKey extends string = string, TResult2 extends {}[] = DeferredKeySelection.Augment< UnwrapArrayMember<TResult>, TRecord, TKey >[] >( data: MaybeArray<SafePartial<TRecord>>, returning: TKey | TKey[] ): QueryBuilder<TRecord, TResult2>; update< TKey extends string, TResult2 extends {}[] = DeferredKeySelection.Augment< UnwrapArrayMember<TResult>, TRecord, TKey >[] >( data: MaybeArray<SafePartial<TRecord>>, returning: TKey[] ): QueryBuilder<TRecord, TResult2>; update<TResult2 = number>( data: MaybeArray<SafePartial<TRecord>> ): QueryBuilder<TRecord, TResult2>; update< K1 extends StrKey<TRecord>, K2 extends StrKey<TRecord>, TResult2 = DeferredIndex.Augment< UnwrapArrayMember<TResult>, TRecord, K2 >[] >( columnName: K1, value: TRecord[K1], returning: K1 ): QueryBuilder<TRecord, TResult2>; update< K1 extends StrKey<TRecord>, K2 extends StrKey<TRecord>, TResult2 = DeferredKeySelection.Augment< UnwrapArrayMember<TResult>, TRecord, K2 >[] >( columnName: K1, value: TRecord[K1], returning: K1[] ): QueryBuilder<TRecord, TResult2>; update<K extends keyof TRecord>( columnName: K, value: TRecord[K] ): QueryBuilder<TRecord, number>; update<TResult2 = SafePartial<TRecord>[]>( columnName: string, value: Value, returning: string | string[] ): QueryBuilder<TRecord, TResult2>; update<TResult2 = number>(columnName: string, value: Value): QueryBuilder<TRecord, TResult2>; returning< TKey extends StrKey<TRecord>, TResult2 = DeferredIndex.Augment< UnwrapArrayMember<TResult>, TRecord, TKey >[] >( column: TKey ): QueryBuilder<TRecord, TResult2>; returning< TKey extends StrKey<TRecord>, TResult2 = DeferredKeySelection.SetSingle< DeferredKeySelection.Augment<UnwrapArrayMember<TResult>, TRecord, TKey>, false >[] >( columns: TKey[] ): QueryBuilder<TRecord, TResult2>; returning<TResult2 = SafePartial<TRecord>[]>( column: string | string[] ): QueryBuilder<TRecord, TResult2>; del< TKey extends StrKey<TRecord>, TResult2 = DeferredIndex.Augment< UnwrapArrayMember<TResult>, TRecord, TKey >[] >( returning: TKey ): QueryBuilder<TRecord, TResult2>; del< TKey extends StrKey<TRecord>, TResult2 = DeferredKeySelection.Augment< UnwrapArrayMember<TResult>, TRecord, TKey >[] >( returning: TKey[] ): QueryBuilder<TRecord, TResult2[]>; del<TResult2 = SafePartial<TRecord>[]>( returning: string | string[] ): QueryBuilder<TRecord, TResult2>; del<TResult2 = number>(): QueryBuilder<TRecord, TResult2>; delete< TKey extends StrKey<TRecord>, TResult2 = DeferredIndex.Augment< UnwrapArrayMember<TResult>, TRecord, TKey >[] >( returning: TKey ): QueryBuilder<TRecord, TResult2>; delete< TKey extends StrKey<TRecord>, TResult2 = DeferredKeySelection.Augment< UnwrapArrayMember<TResult>, TRecord, TKey >[] >( returning: TKey[] ): QueryBuilder<TRecord, TResult2>; delete<TResult2 = any>( returning: string | string[] ): QueryBuilder<TRecord, TResult2>; delete<TResult2 = number>(): QueryBuilder<TRecord, TResult2>; truncate(): QueryBuilder<TRecord, void>; clone(): QueryBuilder<TRecord, TResult>; } interface As<TRecord, TResult> { (columnName: keyof TRecord): QueryBuilder<TRecord, TResult>; (columnName: string): QueryBuilder<TRecord, TResult>; } type IntersectAliases<AliasUT> = UnionToIntersection< IncompatibleToAlt< AliasUT extends (infer I)[] ? I extends Ref<any, infer TMapping> ? TMapping : I : never, Dict, {} > >; interface AliasQueryBuilder<TRecord extends {} = any, TResult = unknown[]> { < AliasUT extends InferrableColumnDescriptor<TRecord>[], TResult2 = ArrayIfAlready<TResult, DeferredKeySelection.Augment< UnwrapArrayMember<TResult>, TRecord, IncompatibleToAlt<ArrayMember<AliasUT>, string, never>, IntersectAliases<AliasUT> >> >( ...aliases: AliasUT ): QueryBuilder<TRecord, TResult2>; < AliasUT extends InferrableColumnDescriptor<TRecord>[], TResult2 = ArrayIfAlready<TResult, DeferredKeySelection.Augment< UnwrapArrayMember<TResult>, TRecord, IncompatibleToAlt<ArrayMember<AliasUT>, string, never>, IntersectAliases<AliasUT> >> >( aliases: AliasUT ): QueryBuilder<TRecord, TResult2>; < AliasUT extends (Dict | string)[], TResult2 = ArrayIfAlready<TResult, DeferredKeySelection.Augment< UnwrapArrayMember<TResult>, TRecord, IncompatibleToAlt<ArrayMember<AliasUT>, string, never>, IntersectAliases<AliasUT> >> >( ...aliases: AliasUT ): QueryBuilder<TRecord, TResult2>; < AliasUT extends (Dict | string)[], TResult2 = ArrayIfAlready<TResult, DeferredKeySelection.Augment< UnwrapArrayMember<TResult>, TRecord, IncompatibleToAlt<ArrayMember<AliasUT>, string, never>, IntersectAliases<AliasUT> >> >( aliases: AliasUT ): QueryBuilder<TRecord, TResult2>; } interface Select<TRecord extends {} = any, TResult = unknown[]> extends AliasQueryBuilder<TRecord, TResult>, ColumnNameQueryBuilder<TRecord, TResult> { (): QueryBuilder<TRecord, TResult>; <TResult2 = ArrayIfAlready<TResult, any>, TInnerRecord = any, TInnerResult = any>( ...subQueryBuilders: QueryBuilder<TInnerRecord, TInnerResult>[] ): QueryBuilder<TRecord, TResult2>; <TResult2 = ArrayIfAlready<TResult, any>, TInnerRecord = any, TInnerResult = any>( subQueryBuilders: QueryBuilder<TInnerRecord, TInnerResult>[] ): QueryBuilder<TRecord, TResult2>; } interface Table<TRecord extends {} = any, TResult extends {} = any> { < TRecord2 = unknown, TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2> >( tableName: TableDescriptor | AliasDict ): QueryBuilder<TRecord2, TResult2>; < TRecord2 = unknown, TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2> >( callback: Function ): QueryBuilder<TRecord2, TResult2>; < TRecord2 = unknown, TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2> >( raw: Raw ): QueryBuilder<TRecord2, TResult2>; } interface Distinct<TRecord extends {}, TResult = {}[]> extends ColumnNameQueryBuilder<TRecord, TResult> {} interface JoinCallback { (this: JoinClause, join: JoinClause): void; } interface Join<TRecord extends {} = any, TResult = unknown[]> { < TJoinTargetRecord extends {} = any, TRecord2 extends {} = TRecord & TJoinTargetRecord, TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2> >( raw: Raw ): QueryBuilder<TRecord2, TResult2>; < TJoinTargetRecord extends {} = any, TRecord2 extends {} = TRecord & TJoinTargetRecord, TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2> >( tableName: TableDescriptor | AliasDict | QueryCallback, clause: JoinCallback ): QueryBuilder<TRecord2, TResult2>; < TJoinTargetRecord extends {} = any, TRecord2 extends {} = TRecord & TJoinTargetRecord, TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2> >( tableName: TableDescriptor | AliasDict | QueryCallback, columns: { [key: string]: string | number | boolean | Raw } ): QueryBuilder<TRecord2, TResult2>; < TJoinTargetRecord extends {} = any, TRecord2 extends {} = TRecord & TJoinTargetRecord, TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2> >( tableName: TableDescriptor | AliasDict | QueryCallback, raw: Raw ): QueryBuilder<TRecord2, TResult2>; < TJoinTargetRecord extends {} = any, TRecord2 extends {} = TRecord & TJoinTargetRecord, TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2> >( tableName: TableDescriptor | AliasDict | QueryCallback, column1: string, column2: string ): QueryBuilder<TRecord2, TResult2>; < TJoinTargetRecord extends {} = any, TRecord2 extends {} = TRecord & TJoinTargetRecord, TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2> >( tableName: TableDescriptor | AliasDict | QueryCallback, column1: string, raw: Raw ): QueryBuilder<TRecord2, TResult2>; < TJoinTargetRecord extends {} = any, TRecord2 extends {} = TRecord & TJoinTargetRecord, TResult2 = DeferredKeySelection.ReplaceBase<TResult, TRecord2> >( tableName: TableDescriptor | AliasDict | QueryCallback, column1: string, operator: string, column2: string ): QueryBuilder<TRecord2, TResult2>; } interface JoinClause { on(raw: Raw): JoinClause; on(callback: JoinCallback): JoinClause; on(columns: { [key: string]: string | Raw }): JoinClause; on(column1: string, column2: string): JoinClause; on(column1: string, raw: Raw): JoinClause; on(column1: string, operator: string, column2: string | Raw): JoinClause; andOn(raw: Raw): JoinClause; andOn(callback: JoinCallback): JoinClause; andOn(columns: { [key: string]: string | Raw }): JoinClause; andOn(column1: string, column2: string): JoinClause; andOn(column1: string, raw: Raw): JoinClause; andOn(column1: string, operator: string, column2: string | Raw): JoinClause; orOn(raw: Raw): JoinClause; orOn(callback: JoinCallback): JoinClause; orOn(columns: { [key: string]: string | Raw }): JoinClause; orOn(column1: string, column2: string): JoinClause; orOn(column1: string, raw: Raw): JoinClause; orOn(column1: string, operator: string, column2: string | Raw): JoinClause; onIn(column1: string, values: any[]): JoinClause; andOnIn(column1: string, values: any[]): JoinClause; orOnIn(column1: string, values: any[]): JoinClause; onNotIn(column1: string, values: any[]): JoinClause; andOnNotIn(column1: string, values: any[]): JoinClause; orOnNotIn(column1: string, values: any[]): JoinClause; onNull(column1: string): JoinClause; andOnNull(column1: string): JoinClause; orOnNull(column1: string): JoinClause; onNotNull(column1: string): JoinClause; andOnNotNull(column1: string): JoinClause; orOnNotNull(column1: string): JoinClause; onExists(callback: QueryCallback): JoinClause; andOnExists(callback: QueryCallback): JoinClause; orOnExists(callback: QueryCallback): JoinClause; onNotExists(callback: QueryCallback): JoinClause; andOnNotExists(callback: QueryCallback): JoinClause; orOnNotExists(callback: QueryCallback): JoinClause; onBetween(column1: string, range: [any, any]): JoinClause; andOnBetween(column1: string, range: [any, any]): JoinClause; orOnBetween(column1: string, range: [any, any]): JoinClause; onNotBetween(column1: string, range: [any, any]): JoinClause; andOnNotBetween(column1: string, range: [any, any]): JoinClause; orOnNotBetween(column1: string, range: [any, any]): JoinClause; using( column: string | string[] | Raw | { [key: string]: string | Raw } ): JoinClause; type(type: string): JoinClause; } interface JoinRaw<TRecord = any, TResult = unknown[]> { (tableName: string, binding?: Value | ValueDict): QueryBuilder< TRecord, TResult >; } interface With<TRecord = any, TResult = unknown[]> extends WithRaw<TRecord, TResult>, WithWrapped<TRecord, TResult> {} interface WithRaw<TRecord = any, TResult = unknown[]> { (alias: string, raw: Raw | QueryBuilder): QueryBuilder<TRecord, TResult>; (alias: string, sql: string, bindings?: Value[] | Object): QueryBuilder< TRecord, TResult >; } interface WithSchema<TRecord = any, TResult = unknown[]> { (schema: string): QueryBuilder<TRecord, TResult>; } interface WithWrapped<TRecord = any, TResult = unknown[]> { (alias: string, queryBuilder: QueryBuilder): QueryBuilder<TRecord, TResult>; ( alias: string, callback: (queryBuilder: QueryBuilder) => any ): QueryBuilder<TRecord, TResult>; } interface Where<TRecord = any, TResult = unknown> extends WhereRaw<TRecord, TResult>, WhereWrapped<TRecord, TResult>, WhereNull<TRecord, TResult> { (raw: Raw): QueryBuilder<TRecord, TResult>; (callback: QueryCallback): QueryBuilder<TRecord, TResult>; (object: SafePartial<TRecord>): QueryBuilder<TRecord, TResult>; (object: Object): QueryBuilder<TRecord, TResult>; <T extends keyof TRecord>( columnName: T, value: TRecord[T] | null ): QueryBuilder<TRecord, TResult>; (columnName: string, value: Value | null): QueryBuilder<TRecord, TResult>; <T extends keyof TRecord>( columnName: T, operator: ComparisionOperator, value: TRecord[T] | null ): QueryBuilder<TRecord, TResult>; (columnName: string, operator: string, value: Value | null): QueryBuilder< TRecord, TResult >; <T extends keyof TRecord, TRecordInner, TResultInner>( columnName: T, operator: ComparisionOperator, value: QueryBuilder<TRecordInner, TResultInner> ): QueryBuilder<TRecord, TResult>; <TRecordInner, TResultInner>( columnName: string, operator: string, value: QueryBuilder<TRecordInner, TResultInner> ): QueryBuilder<TRecord, TResult>; (left: Raw, operator: string, right: Value | null): QueryBuilder< TRecord, TResult >; <TRecordInner, TResultInner>( left: Raw, operator: string, right: QueryBuilder<TRecordInner, TResultInner> ): QueryBuilder<TRecord, TResult>; } interface WhereRaw<TRecord = any, TResult = unknown[]> extends RawQueryBuilder<TRecord, TResult> { (condition: boolean): QueryBuilder<TRecord, TResult>; } interface WhereWrapped<TRecord = any, TResult = unknown[]> { (callback: QueryCallback): QueryBuilder<TRecord, TResult>; } interface WhereNull<TRecord = any, TResult = unknown[]> { (columnName: keyof TRecord): QueryBuilder<TRecord, TResult>; (columnName: string): QueryBuilder<TRecord, TResult>; } interface WhereBetween<TRecord = any, TResult = unknown[]> { <K extends keyof TRecord>( columnName: K, range: [TRecord[K], TRecord[K]] ): QueryBuilder<TRecord, TResult>; (columnName: string, range: [Value, Value]): QueryBuilder<TRecord, TResult>; } interface WhereExists<TRecord = any, TResult = unknown[]> { (callback: QueryCallback): QueryBuilder<TRecord, TResult>; <TRecordInner, TResultInner>( query: QueryBuilder<TRecordInner, TResultInner> ): QueryBuilder<TRecord, TResult>; } interface WhereIn<TRecord = any, TResult = unknown[]> { <K extends keyof TRecord>( columnName: K, values: TRecord[K][] | QueryCallback ): QueryBuilder<TRecord, TResult>; (columnName: string, values: Value[] | QueryCallback): QueryBuilder< TRecord, TResult >; <K extends keyof TRecord>( columnNames: K[], values: TRecord[K][][] | QueryCallback ): QueryBuilder<TRecord, TResult>; (columnNames: string[], values: Value[][] | QueryCallback): QueryBuilder< TRecord, TResult >; <K extends keyof TRecord, TRecordInner, TResultInner>( columnName: K, values: QueryBuilder<TRecordInner, TRecord[K]> ): QueryBuilder<TRecord, TResult>; <TRecordInner, TResultInner>( columnName: string, values: QueryBuilder<TRecordInner, TResultInner> ): QueryBuilder<TRecord, TResult>; <K extends keyof TRecord, TRecordInner, TResultInner>( columnNames: K[], values: QueryBuilder<TRecordInner, TRecord[K]> ): QueryBuilder<TRecord, TResult>; <TRecordInner, TResultInner>( columnNames: string[], values: QueryBuilder<TRecordInner, TResultInner> ): QueryBuilder<TRecord, TResult>; } // Note: Attempting to unify AssymetricAggregation & TypePreservingAggregation // by extracting out a common base interface will not work because order of overloads // is significant. interface AssymetricAggregation<TRecord = any, TResult = unknown[], TValue = any> { <TResult2 = AggregationQueryResult<TResult, Dict<TValue>>>( ...columnNames: (keyof TRecord)[] ): QueryBuilder<TRecord, TResult2>; < TAliases extends {} = Record<string, string | string[] | Knex.Raw>, TResult2 = AggregationQueryResult<TResult, {[k in keyof TAliases]?: TValue}> >(aliases: TAliases): QueryBuilder<TRecord, TResult2>; <TResult2 = AggregationQueryResult<TResult, Dict<TValue>>>( ...columnNames: Array<Record<string, string | string[] | Knex.Raw> | Knex.Raw | string> ): QueryBuilder<TRecord, TResult2>; } interface TypePreservingAggregation<TRecord = any, TResult = unknown[], TValue = any> { < TKey extends keyof TRecord, TResult2 = AggregationQueryResult<TResult, Dict<TRecord[TKey]>> >( ...columnNames: TKey[] ): QueryBuilder<TRecord, TResult2>; < TAliases extends {} = Record<string, string | string[] | Knex.Raw>, TResult2 = AggregationQueryResult<TResult, { // We have optional here because in most dialects aggregating by multiple keys simultaneously // causes rest of the keys to be dropped and only first to be considered [K in keyof TAliases]?: K extends keyof TRecord ? TRecord[K] : TValue }> >(aliases: TAliases): QueryBuilder<TRecord, TResult2>; <TResult2 = AggregationQueryResult<TResult, Dict<TValue>>>( ...columnNames: Array<Record<string, string | string[] | Knex.Raw> | Knex.Raw | string> ): QueryBuilder<TRecord, TResult2>; } interface GroupBy<TRecord = any, TResult = unknown[]> extends RawQueryBuilder<TRecord, TResult>, ColumnNameQueryBuilder<TRecord, TResult> {} interface OrderBy<TRecord = any, TResult = unknown[]> { (columnName: keyof TRecord, order?: 'asc' | 'desc'): QueryBuilder< TRecord, TResult >; (columnName: string, order?: string): QueryBuilder<TRecord, TResult>; ( columnDefs: Array< keyof TRecord | { column: keyof TRecord; order?: 'asc' | 'desc' } > ): QueryBuilder<TRecord, TResult>; ( columnDefs: Array<string | { column: string; order?: string }> ): QueryBuilder<TRecord, TResult>; } interface Intersect<TRecord = any, TResult = unknown[]> { ( callback: MaybeArray<QueryCallback | QueryBuilder<TRecord, any> | Raw>, wrap?: boolean ): QueryBuilder<TRecord, TResult>; ( ...callbacks: (QueryCallback | Raw | QueryBuilder<TRecord, any>)[] ): QueryBuilder<TRecord, TResult>; } interface Union<TRecord = any, TResult = unknown[]> extends Intersect<TRecord, TResult> {} interface Having<TRecord = any, TResult = unknown[]> extends RawQueryBuilder<TRecord, TResult>, WhereWrapped<TRecord, TResult> { <K1 extends keyof TRecord, K2 extends keyof TRecord>( tableName: string, column1: K1, operator: ComparisionOperator, column2: K2 ): QueryBuilder<TRecord, TResult>; ( tableName: string, column1: string, operator: string, column2: string ): QueryBuilder<TRecord, TResult>; } interface HavingRange<TRecord = any, TResult = unknown[]> { <K extends keyof TRecord>( columnName: K, values: TRecord[K][] ): QueryBuilder<TRecord, TResult>; (columnName: string, values: Value[]): QueryBuilder<TRecord, TResult>; } // commons interface ColumnNameQueryBuilder<TRecord = any, TResult = unknown[]> { // When all columns are known to be keys of original record, // we can extend our selection by these columns (columnName: '*'): QueryBuilder< TRecord, DeferredKeySelection<TRecord, string>[] >; < ColNameUT extends keyof TRecord, TResult2 = DeferredKeySelection.Augment< UnwrapArrayMember<TResult>, TRecord, ColNameUT & string >[] >( ...columnNames: ColNameUT[] ): QueryBuilder<TRecord, TResult2>; < ColNameUT extends keyof TRecord, TResult2 = DeferredKeySelection.Augment< UnwrapArrayMember<TResult>, TRecord, ColNameUT & string >[] >( columnNames: ColNameUT[] ): QueryBuilder<TRecord, TResult2>; // For non-inferrable column selection, we will allow consumer to // specify result type and if not widen the result to entire record type with any omissions permitted < TResult2 = DeferredKeySelection.Augment< UnwrapArrayMember<TResult>, SafePartial<TRecord>, keyof TRecord & string >[] >( ...columnNames: ColumnDescriptor<TRecord, TResult>[] ): QueryBuilder<TRecord, TResult2>; < TResult2 = DeferredKeySelection.Augment< UnwrapArrayMember<TResult>, SafePartial<TRecord>, keyof TRecord & string >[] >( columnNames: ColumnDescriptor<TRecord, TResult>[] ): QueryBuilder<TRecord, TResult2>; } type RawBinding = Value | QueryBuilder<any, any>; interface RawQueryBuilder<TRecord = any, TResult = unknown[]> { <TResult2 = UnknownToAny<TResult>>( sql: string, ...bindings: RawBinding[] ): QueryBuilder<TRecord, TResult2>; <TResult2 = UnknownToAny<TResult>>( sql: string, bindings: RawBinding[] | ValueDict ): QueryBuilder<TRecord, TResult2>; <TResult2 = UnknownToAny<TResult>>(raw: Raw<TResult2>): QueryBuilder< TRecord, TResult2 >; } // Raw interface Raw<TResult = any> extends events.EventEmitter, ChainableInterface<ResolveResult<TResult>> { wrap<TResult2 = TResult>(before: string, after: string): Raw<TResult>; toSQL(): Sql; queryContext(context: any): Raw<TResult>; } interface RawBuilder<TRecord extends {} = any, TResult = unknown[]> { <TResult2 = UnknownToAny<TResult>>(value: Value): Raw<TResult2>; <TResult2 = UnknownToAny<TResult>>(sql: string, ...bindings: RawBinding[]): Raw<TResult2>; <TResult2 = UnknownToAny<TResult>>(sql: string, bindings: RawBinding[] | ValueDict): Raw<TResult2>; } interface Ref<TSrc extends string, TMapping extends {}> extends Raw<string> { withSchema(schema: string): this; as<TAlias extends string>(alias: TAlias): Ref<TSrc, {[K in TAlias]: TSrc}>; } interface RefBuilder { <TSrc extends string>(src: TSrc): Ref<TSrc, {[K in TSrc]: TSrc}>; } // // QueryBuilder // type QueryCallback<TRecord = any, TResult = unknown[]> = ( this: QueryBuilder<TRecord, TResult>, builder: QueryBuilder<TRecord, TResult> ) => void; type QueryCallbackWithArgs<TRecord = any, TResult = unknown[]> = ( this: QueryBuilder<TRecord, TResult>, builder: QueryBuilder<TRecord, TResult>, ...args: any[] ) => void; interface QueryBuilder< TRecord extends {} = any, TResult = SafePartial<TRecord>[] > extends QueryInterface<TRecord, TResult>, ChainableInterface<ResolveResult<TResult>> { // [TODO] Doesn't seem to be available // or: QueryBuilder; and: QueryBuilder<TRecord, TResult>; // TODO: Promise? columnInfo(column?: keyof TRecord): Bluebird<ColumnInfo>; forUpdate(...tableNames: string[]): QueryBuilder<TRecord, TResult>; forUpdate(tableNames: string[]): QueryBuilder<TRecord, TResult>; forShare(...tableNames: string[]): QueryBuilder<TRecord, TResult>; forShare(tableNames: string[]): QueryBuilder<TRecord, TResult>; toSQL(): Sql; on(event: string, callback: Function): QueryBuilder<TRecord, TResult>; queryContext(context: any): QueryBuilder<TRecord, TResult>; } interface Sql { method: string; options: any; bindings: Value[]; sql: string; toNative(): SqlNative; } interface SqlNative { bindings: Value[]; sql: string; } // // Chainable interface // interface ChainableInterface<T = any> extends Bluebird<T> { toQuery(): string; options(options: { [key: string]: any }): this; connection(connection: any): this; debug(enabled: boolean): this; transacting(trx: Transaction): this; stream(handler: (readable: stream.PassThrough) => any): Bluebird<any>; stream( options: { [key: string]: any }, handler: (readable: stream.PassThrough) => any ): Bluebird<any>; stream(options?: { [key: string]: any }): stream.PassThrough; pipe<T extends NodeJS.WritableStream>( writable: T, options?: { [key: string]: any } ): stream.PassThrough; asCallback(callback: Function): this; } interface Transaction<TRecord extends {} = any, TResult = any> extends Knex<TRecord, TResult> { query<TRecord extends {} = any, TResult = void>( conn: any, sql: any, status: any, value: any ): QueryBuilder<TRecord, TResult>; savepoint<T = any>( transactionScope: (trx: Transaction) => any ): Bluebird<T>; commit(value?: any): QueryBuilder<TRecord, TResult>; rollback(error?: any): QueryBuilder<TRecord, TResult>; } // // Schema builder // interface SchemaBuilder extends ChainableInterface<void> { createTable( tableName: string, callback: (tableBuilder: CreateTableBuilder) => any ): SchemaBuilder; createTableIfNotExists( tableName: string, callback: (tableBuilder: CreateTableBuilder) => any ): SchemaBuilder; alterTable( tableName: string, callback: (tableBuilder: CreateTableBuilder) => any ): SchemaBuilder; renameTable(oldTableName: string, newTableName: string): Bluebird<void>; dropTable(tableName: string): SchemaBuilder; hasTable(tableName: string): Bluebird<boolean>; hasColumn(tableName: string, columnName: string): Bluebird<boolean>; table( tableName: string, callback: (tableBuilder: AlterTableBuilder) => any ): Bluebird<void>; dropTableIfExists(tableName: string): SchemaBuilder; raw(statement: string): SchemaBuilder; withSchema(schemaName: string): SchemaBuilder; queryContext(context: any): SchemaBuilder; } interface TableBuilder { increments(columnName?: string): ColumnBuilder; bigIncrements(columnName?: string): ColumnBuilder; dropColumn(columnName: string): TableBuilder; dropColumns(...columnNames: string[]): TableBuilder; renameColumn(from: string, to: string): ColumnBuilder; integer(columnName: string, length?: number): ColumnBuilder; bigInteger(columnName: string): ColumnBuilder; text(columnName: string, textType?: string): ColumnBuilder; string(columnName: string, length?: number): ColumnBuilder; float( columnName: string, precision?: number, scale?: number ): ColumnBuilder; decimal( columnName: string, precision?: number | null, scale?: number ): ColumnBuilder; boolean(columnName: string): ColumnBuilder; date(columnName: string): ColumnBuilder; dateTime(columnName: string, options?: {useTz?: boolean, precision?: number}): ColumnBuilder; time(columnName: string): ColumnBuilder; timestamp(columnName: string, options?: {useTz?: boolean, precision?: number}): ColumnBuilder; /** @deprecated */ timestamp(columnName: string, withoutTz?: boolean, precision?: number): ColumnBuilder; timestamps( useTimestampType?: boolean, makeDefaultNow?: boolean ): ColumnBuilder; binary(columnName: string, length?: number): ColumnBuilder; enum( columnName: string, values: Value[], options?: EnumOptions ): ColumnBuilder; enu( columnName: string, values: Value[], options?: EnumOptions ): ColumnBuilder; json(columnName: string): ColumnBuilder; jsonb(columnName: string): ColumnBuilder; uuid(columnName: string): ColumnBuilder; comment(val: string): TableBuilder; specificType(columnName: string, type: string): ColumnBuilder; primary(columnNames: string[], constraintName?: string): TableBuilder; index( columnNames: (string | Raw)[], indexName?: string, indexType?: string ): TableBuilder; unique(columnNames: (string | Raw)[], indexName?: string): TableBuilder; foreign(column: string, foreignKeyName?: string): ForeignConstraintBuilder; foreign( columns: string[], foreignKeyName?: string ): MultikeyForeignConstraintBuilder; dropForeign(columnNames: string[], foreignKeyName?: string): TableBuilder; dropUnique(columnNames: (string | Raw)[], indexName?: string): TableBuilder; dropPrimary(constraintName?: string): TableBuilder; dropIndex(columnNames: (string | Raw)[], indexName?: string): TableBuilder; dropTimestamps(): ColumnBuilder; queryContext(context: any): TableBuilder; } interface CreateTableBuilder extends TableBuilder {} interface MySqlTableBuilder extends CreateTableBuilder { engine(val: string): CreateTableBuilder; charset(val: string): CreateTableBuilder; collate(val: string): CreateTableBuilder; } interface AlterTableBuilder extends TableBuilder {} interface MySqlAlterTableBuilder extends AlterTableBuilder {} interface ColumnBuilder { index(indexName?: string): ColumnBuilder; primary(constraintName?: string): ColumnBuilder; unique(indexName?: str