UNPKG

ts-apicalypse

Version:

A Typescript client and request builder for Apicalypse

918 lines (890 loc) 32.5 kB
import { AxiosRequestConfig, AxiosPromise } from 'axios'; /** * Check whether `A1` is equal to `A2` or not. * @param A1 * @param A2 * @returns [[Boolean]] * @example * ```ts * import {A} from 'ts-toolbelt' * * type test0 = A.Equals<42 | 0, 42 | 0> // true * type test1 = A.Equals<{a: string}, {b: string}> // false * type test3 = A.Equals<{a: string}, {readonly a: string}> // false * ``` */ declare type Equals<A1 extends any, A2 extends any> = (<A>() => A extends A2 ? 1 : 0) extends (<A>() => A extends A1 ? 1 : 0) ? 1 : 0; /** * Describes index keys for any type */ declare type Key = string | number | symbol; /** * A [[List]] * @param A its type * @returns [[List]] * @example * ```ts * type list0 = [1, 2, 3] * type list1 = number[] * ``` */ declare type List<A = any> = ReadonlyArray<A>; /** * Get in `O` the type of a field of key `K` * @param O to extract from * @param K to extract at * @returns [[Any]] * @example * ```ts * import {O} from 'ts-toolbelt' * * type User = { * info: { * name: string * age: number * payment: {} * } * id: number * } * * type test0 = O.At<User, 'id'> // number * ``` */ declare type At<A extends any, K extends Key> = A extends List ? number extends A['length'] ? K extends number | `${number}` ? A[never] | undefined : undefined : K extends keyof A ? A[K] : undefined : unknown extends A ? unknown : K extends keyof A ? A[K] : undefined; /** * Ask TS to re-check that `A1` extends `A2`. * And if it fails, `A2` will be enforced anyway. * Can also be used to add constraints on parameters. * @param A1 to check against * @param A2 to cast to * @returns `A1 | A2` * @example * ```ts * import {A} from 'ts-toolbelt' * * type test0 = A.Cast<'42', string> // '42' * type test1 = A.Cast<'42', number> // number * ``` */ declare type Cast<A1 extends any, A2 extends any> = A1 extends A2 ? A1 : A2; /** * Check whether `A1` is part of `A2` or not. The difference with * `extends` is that it forces a [[Boolean]] return. * @param A1 * @param A2 * @returns [[Boolean]] * @example * ```ts * import {A} from 'ts-toolbelt' * * type test0 = A.Extends<'a' | 'b', 'b'> // Boolean * type test1 = A.Extends<'a', 'a' | 'b'> // True * * type test2 = A.Extends<{a: string}, {a: any}> // True * type test3 = A.Extends<{a: any}, {a: any, b: any}> // False * * type test4 = A.Extends<never, never> // False * /// Nothing cannot extend nothing, use `A.Equals` * ``` */ declare type Extends<A1 extends any, A2 extends any> = [ A1 ] extends [never] ? 0 : A1 extends A2 ? 1 : 0; /** * Check whether `A1` is part of `A2` or not. It works like * [[Extends]] but [[Boolean]] results are narrowed to [[False]]. * @param A1 * @param A2 * @returns [[Boolean]] * @example * ```ts * type test0 = A.Contains<'a' | 'b', 'b'> // False * type test1 = A.Contains<'a', 'a' | 'b'> // True * * type test2 = A.Contains<{a: string}, {a: string, b: number}> // False * type test3 = A.Contains<{a: string, b: number}, {a: string}> // True * * type test4 = A.Contains<never, never> // False * /// Nothing cannot contain nothing, use `A.Equals` * ``` */ declare type Contains<A1 extends any, A2 extends any> = Extends<A1, A2> extends 1 ? 1 : 0; /** * Describes the match strategy when matching types * * `default` : `extends->` * * `contains->` : X contains Y ([[Contains]]<X, Y>) * * `extends->` : X extends Y ([[Extends]]<X, Y>) * * `<-contains` : Y contains X ([[Contains]]<Y, X>) * * `<-extends` : Y extends X ([[Extends]]<Y, X>) * * `equals` : X equals Y (([[Equals]]<X, Y>)) */ declare type Match = 'default' | 'contains->' | 'extends->' | '<-contains' | '<-extends' | 'equals'; /** * Check whether `A` is similar to `A1` or not. In other words, it is a compact * type that bundles [[Equals]], [[Extends]], [[Contains]], comparison types. * @param A to be compared * @param A1 to compare to * @param match (?=`'default'`) to change precision * @returns [[Boolean]] * @example * ```ts * import {A} from 'ts-toolbelt' * * type test0 = A.Is<'a', 'a' | 'b', 'extends->'> // True * type test1 = A.Is<'a' | 'b', 'a', 'extends->'> // Boolean * * type test2 = A.Is<'a', 'a' | 'b', '<-extends'> // Boolean * type test3 = A.Is<'a' | 'b', 'a', '<-extends'> // True * * type test4 = A.Is<'a', 'a' | 'b', 'contains->'> // True * type test5 = A.Is<'a' | 'b', 'a', 'contains->'> // False * * type test6 = A.Is<'a', 'a' | 'b', '<-contains'> // False * type test7 = A.Is<'a' | 'b', 'a', '<-contains'> // True * * type test8 = A.Is<'a', 'a' | 'b', 'equals'> // False * type test9 = A.Is<'b' |'a', 'a' | 'b', 'equals'> // True * ``` */ declare type Is<A extends any, A1 extends any, match extends Match = 'default'> = { 'default': Extends<A, A1>; 'contains->': Contains<A, A1>; 'extends->': Extends<A, A1>; '<-contains': Contains<A1, A>; '<-extends': Extends<A1, A>; 'equals': Equals<A1, A>; }[match]; /** * @hidden */ declare type _UnionOf<O extends object> = O[keyof O]; /** * Transform an [[Object]] into an [[Union]] * @param O to transform * @returns [[Any]] * @example * ```ts * ``` */ declare type UnionOf<O extends object> = O extends unknown ? _UnionOf<O> : never; /** * An entry of `IterationMap` */ declare type Iteration = [ value: number, sign: '-' | '0' | '+', prev: keyof IterationMap, next: keyof IterationMap, oppo: keyof IterationMap ]; declare type IterationMap = { '__': [number, '-' | '0' | '+', '__', '__', '__']; '-100': [-100, '-', '__', '-99', '100']; '-99': [-99, '-', '-100', '-98', '99']; '-98': [-98, '-', '-99', '-97', '98']; '-97': [-97, '-', '-98', '-96', '97']; '-96': [-96, '-', '-97', '-95', '96']; '-95': [-95, '-', '-96', '-94', '95']; '-94': [-94, '-', '-95', '-93', '94']; '-93': [-93, '-', '-94', '-92', '93']; '-92': [-92, '-', '-93', '-91', '92']; '-91': [-91, '-', '-92', '-90', '91']; '-90': [-90, '-', '-91', '-89', '90']; '-89': [-89, '-', '-90', '-88', '89']; '-88': [-88, '-', '-89', '-87', '88']; '-87': [-87, '-', '-88', '-86', '87']; '-86': [-86, '-', '-87', '-85', '86']; '-85': [-85, '-', '-86', '-84', '85']; '-84': [-84, '-', '-85', '-83', '84']; '-83': [-83, '-', '-84', '-82', '83']; '-82': [-82, '-', '-83', '-81', '82']; '-81': [-81, '-', '-82', '-80', '81']; '-80': [-80, '-', '-81', '-79', '80']; '-79': [-79, '-', '-80', '-78', '79']; '-78': [-78, '-', '-79', '-77', '78']; '-77': [-77, '-', '-78', '-76', '77']; '-76': [-76, '-', '-77', '-75', '76']; '-75': [-75, '-', '-76', '-74', '75']; '-74': [-74, '-', '-75', '-73', '74']; '-73': [-73, '-', '-74', '-72', '73']; '-72': [-72, '-', '-73', '-71', '72']; '-71': [-71, '-', '-72', '-70', '71']; '-70': [-70, '-', '-71', '-69', '70']; '-69': [-69, '-', '-70', '-68', '69']; '-68': [-68, '-', '-69', '-67', '68']; '-67': [-67, '-', '-68', '-66', '67']; '-66': [-66, '-', '-67', '-65', '66']; '-65': [-65, '-', '-66', '-64', '65']; '-64': [-64, '-', '-65', '-63', '64']; '-63': [-63, '-', '-64', '-62', '63']; '-62': [-62, '-', '-63', '-61', '62']; '-61': [-61, '-', '-62', '-60', '61']; '-60': [-60, '-', '-61', '-59', '60']; '-59': [-59, '-', '-60', '-58', '59']; '-58': [-58, '-', '-59', '-57', '58']; '-57': [-57, '-', '-58', '-56', '57']; '-56': [-56, '-', '-57', '-55', '56']; '-55': [-55, '-', '-56', '-54', '55']; '-54': [-54, '-', '-55', '-53', '54']; '-53': [-53, '-', '-54', '-52', '53']; '-52': [-52, '-', '-53', '-51', '52']; '-51': [-51, '-', '-52', '-50', '51']; '-50': [-50, '-', '-51', '-49', '50']; '-49': [-49, '-', '-50', '-48', '49']; '-48': [-48, '-', '-49', '-47', '48']; '-47': [-47, '-', '-48', '-46', '47']; '-46': [-46, '-', '-47', '-45', '46']; '-45': [-45, '-', '-46', '-44', '45']; '-44': [-44, '-', '-45', '-43', '44']; '-43': [-43, '-', '-44', '-42', '43']; '-42': [-42, '-', '-43', '-41', '42']; '-41': [-41, '-', '-42', '-40', '41']; '-40': [-40, '-', '-41', '-39', '40']; '-39': [-39, '-', '-40', '-38', '39']; '-38': [-38, '-', '-39', '-37', '38']; '-37': [-37, '-', '-38', '-36', '37']; '-36': [-36, '-', '-37', '-35', '36']; '-35': [-35, '-', '-36', '-34', '35']; '-34': [-34, '-', '-35', '-33', '34']; '-33': [-33, '-', '-34', '-32', '33']; '-32': [-32, '-', '-33', '-31', '32']; '-31': [-31, '-', '-32', '-30', '31']; '-30': [-30, '-', '-31', '-29', '30']; '-29': [-29, '-', '-30', '-28', '29']; '-28': [-28, '-', '-29', '-27', '28']; '-27': [-27, '-', '-28', '-26', '27']; '-26': [-26, '-', '-27', '-25', '26']; '-25': [-25, '-', '-26', '-24', '25']; '-24': [-24, '-', '-25', '-23', '24']; '-23': [-23, '-', '-24', '-22', '23']; '-22': [-22, '-', '-23', '-21', '22']; '-21': [-21, '-', '-22', '-20', '21']; '-20': [-20, '-', '-21', '-19', '20']; '-19': [-19, '-', '-20', '-18', '19']; '-18': [-18, '-', '-19', '-17', '18']; '-17': [-17, '-', '-18', '-16', '17']; '-16': [-16, '-', '-17', '-15', '16']; '-15': [-15, '-', '-16', '-14', '15']; '-14': [-14, '-', '-15', '-13', '14']; '-13': [-13, '-', '-14', '-12', '13']; '-12': [-12, '-', '-13', '-11', '12']; '-11': [-11, '-', '-12', '-10', '11']; '-10': [-10, '-', '-11', '-9', '10']; '-9': [-9, '-', '-10', '-8', '9']; '-8': [-8, '-', '-9', '-7', '8']; '-7': [-7, '-', '-8', '-6', '7']; '-6': [-6, '-', '-7', '-5', '6']; '-5': [-5, '-', '-6', '-4', '5']; '-4': [-4, '-', '-5', '-3', '4']; '-3': [-3, '-', '-4', '-2', '3']; '-2': [-2, '-', '-3', '-1', '2']; '-1': [-1, '-', '-2', '0', '1']; '0': [0, '0', '-1', '1', '0']; '1': [1, '+', '0', '2', '-1']; '2': [2, '+', '1', '3', '-2']; '3': [3, '+', '2', '4', '-3']; '4': [4, '+', '3', '5', '-4']; '5': [5, '+', '4', '6', '-5']; '6': [6, '+', '5', '7', '-6']; '7': [7, '+', '6', '8', '-7']; '8': [8, '+', '7', '9', '-8']; '9': [9, '+', '8', '10', '-9']; '10': [10, '+', '9', '11', '-10']; '11': [11, '+', '10', '12', '-11']; '12': [12, '+', '11', '13', '-12']; '13': [13, '+', '12', '14', '-13']; '14': [14, '+', '13', '15', '-14']; '15': [15, '+', '14', '16', '-15']; '16': [16, '+', '15', '17', '-16']; '17': [17, '+', '16', '18', '-17']; '18': [18, '+', '17', '19', '-18']; '19': [19, '+', '18', '20', '-19']; '20': [20, '+', '19', '21', '-20']; '21': [21, '+', '20', '22', '-21']; '22': [22, '+', '21', '23', '-22']; '23': [23, '+', '22', '24', '-23']; '24': [24, '+', '23', '25', '-24']; '25': [25, '+', '24', '26', '-25']; '26': [26, '+', '25', '27', '-26']; '27': [27, '+', '26', '28', '-27']; '28': [28, '+', '27', '29', '-28']; '29': [29, '+', '28', '30', '-29']; '30': [30, '+', '29', '31', '-30']; '31': [31, '+', '30', '32', '-31']; '32': [32, '+', '31', '33', '-32']; '33': [33, '+', '32', '34', '-33']; '34': [34, '+', '33', '35', '-34']; '35': [35, '+', '34', '36', '-35']; '36': [36, '+', '35', '37', '-36']; '37': [37, '+', '36', '38', '-37']; '38': [38, '+', '37', '39', '-38']; '39': [39, '+', '38', '40', '-39']; '40': [40, '+', '39', '41', '-40']; '41': [41, '+', '40', '42', '-41']; '42': [42, '+', '41', '43', '-42']; '43': [43, '+', '42', '44', '-43']; '44': [44, '+', '43', '45', '-44']; '45': [45, '+', '44', '46', '-45']; '46': [46, '+', '45', '47', '-46']; '47': [47, '+', '46', '48', '-47']; '48': [48, '+', '47', '49', '-48']; '49': [49, '+', '48', '50', '-49']; '50': [50, '+', '49', '51', '-50']; '51': [51, '+', '50', '52', '-51']; '52': [52, '+', '51', '53', '-52']; '53': [53, '+', '52', '54', '-53']; '54': [54, '+', '53', '55', '-54']; '55': [55, '+', '54', '56', '-55']; '56': [56, '+', '55', '57', '-56']; '57': [57, '+', '56', '58', '-57']; '58': [58, '+', '57', '59', '-58']; '59': [59, '+', '58', '60', '-59']; '60': [60, '+', '59', '61', '-60']; '61': [61, '+', '60', '62', '-61']; '62': [62, '+', '61', '63', '-62']; '63': [63, '+', '62', '64', '-63']; '64': [64, '+', '63', '65', '-64']; '65': [65, '+', '64', '66', '-65']; '66': [66, '+', '65', '67', '-66']; '67': [67, '+', '66', '68', '-67']; '68': [68, '+', '67', '69', '-68']; '69': [69, '+', '68', '70', '-69']; '70': [70, '+', '69', '71', '-70']; '71': [71, '+', '70', '72', '-71']; '72': [72, '+', '71', '73', '-72']; '73': [73, '+', '72', '74', '-73']; '74': [74, '+', '73', '75', '-74']; '75': [75, '+', '74', '76', '-75']; '76': [76, '+', '75', '77', '-76']; '77': [77, '+', '76', '78', '-77']; '78': [78, '+', '77', '79', '-78']; '79': [79, '+', '78', '80', '-79']; '80': [80, '+', '79', '81', '-80']; '81': [81, '+', '80', '82', '-81']; '82': [82, '+', '81', '83', '-82']; '83': [83, '+', '82', '84', '-83']; '84': [84, '+', '83', '85', '-84']; '85': [85, '+', '84', '86', '-85']; '86': [86, '+', '85', '87', '-86']; '87': [87, '+', '86', '88', '-87']; '88': [88, '+', '87', '89', '-88']; '89': [89, '+', '88', '90', '-89']; '90': [90, '+', '89', '91', '-90']; '91': [91, '+', '90', '92', '-91']; '92': [92, '+', '91', '93', '-92']; '93': [93, '+', '92', '94', '-93']; '94': [94, '+', '93', '95', '-94']; '95': [95, '+', '94', '96', '-95']; '96': [96, '+', '95', '97', '-96']; '97': [97, '+', '96', '98', '-97']; '98': [98, '+', '97', '99', '-98']; '99': [99, '+', '98', '100', '-99']; '100': [100, '+', '99', '__', '-100']; }; /** * Move `I`'s position forward * @param I to move * @returns [[Iteration]] * @example * ```ts * import {I} from 'ts-toolbelt' * * type i = I.IterationOf<'20'> * * type test0 = I.Pos<i> // 20 * type test1 = I.Pos<I.Next<i>> // 21 * ``` */ declare type Next<I extends Iteration> = IterationMap[I[3]]; /** * Transform a number into an [[Iteration]] * (to use [[Prev]], [[Next]], & [[Pos]]) * @param N to transform * @returns [[Iteration]] * @example * ```ts * import {I} from 'ts-toolbelt' * * type i = I.IterationOf<0> // ["-1", "1", "0", 0, "0"] * * type next = I.Next<i> // ["0", "2", "1", 1, "+"] * type prev = I.Prev<i> // ["-2", "0", "-1", -1, "-"] * * type nnext = I.Pos<next> // +1 * type nprev = I.Pos<prev> // -1 * ``` */ declare type IterationOf<N extends number> = `${N}` extends keyof IterationMap ? IterationMap[`${N}`] : IterationMap['__']; /** * Get the position of `I` (**number**) * @param I to query * @returns `number` * @example * ```ts * import {I} from 'ts-toolbelt' * * type i = I.IterationOf<'20'> * * type test0 = I.Pos<i> // 20 * type test1 = I.Pos<I.Next<i>> // 21 * ``` */ declare type Pos<I extends Iteration> = I[0]; /** * Get the length of `L` * @param L to get length * @returns [[String]] or `number` * @example * ```ts * ``` */ declare type Length<L extends List> = L['length']; /** * Get the first entry of `L` * @param L to extract from * @returns [[Any]] * @example * ```ts * ``` */ declare type Head<L extends List> = Length<L> extends 0 ? never : L[0]; /** * Remove the last element out of `L` * @param L to remove from * @returns [[List]] * @example * ```ts * ``` */ declare type Pop<L extends List> = L extends (readonly [...infer LBody, any] | readonly [...infer LBody, any?]) ? LBody : L; /** * Remove the first item out of a [[List]] * @param L * @returns [[List]] * @example * ```ts * ``` */ declare type Tail<L extends List> = L extends readonly [] ? L : L extends readonly [any?, ...infer LTail] ? LTail : L; /** * Extract the part of `U` that matches `M` * @param U to extract from * @param M to select with * @returns [[Union]] * @example * ```ts * ``` */ declare type Select<U extends any, M extends any, match extends Match = 'default'> = U extends unknown ? { 1: U & M; 0: never; }[Is<U, M, match>] : never; declare type Literal = string | number | bigint | boolean; /** * @hidden */ declare type _Join<T extends List, D extends string> = T extends [] ? '' : T extends [Literal] ? `${T[0]}` : T extends [Literal, ...infer R] ? `${T[0]}${D}${_Join<R, D>}` : string; /** * Concat many literals together * @param T to concat * @param D to delimit */ declare type Join<T extends List<Literal>, D extends string = ''> = _Join<T, D> extends infer X ? Cast<X, string> : never; /** * @ignore */ declare type __Split<S extends string, D extends string, T extends string[] = []> = S extends `${infer BS}${D}${infer AS}` ? __Split<AS, D, [...T, BS]> : [...T, S]; /** * @hidden */ declare type _Split<S extends string, D extends string = ''> = D extends '' ? Pop<__Split<S, D>> : __Split<S, D>; /** * Split `S` by `D` into a [[List]] * @param S to split up * @param D to split at */ declare type Split<S extends string, D extends string = ''> = _Split<S, D> extends infer X ? Cast<X, string[]> : never; /** * All primitive types */ declare type Primitive = boolean | string | number | bigint | symbol | undefined | null; interface Options extends AxiosRequestConfig { queryMethod?: 'url' | 'body'; } interface Stringifiable { toApicalypseString(): string; } interface Builder<T = any> extends Stringifiable { queryFields: { fields?: string; exclude?: string; sort?: string; limit?: string; offset?: string; search?: string; where: string[]; }; queryEndpoint?: string; queryName?: string; } interface NamedBuilder<T, N extends string> extends Omit<Builder<T>, 'queryEndpoint' | 'queryName'> { queryEndpoint: string; queryName: N; } interface NarrowBuilder<T> extends Builder<T> { __narrow: true; } interface CountBuilder<T> extends Builder<T> { __count: true; } type PickWith<T, K extends keyof T, X> = X extends keyof T ? Pick<T, K | X> : Pick<T, K>; interface Pipe<T extends object, mode extends 'result' | 'count' = 'result'> { <A>(...steps: (BuilderOperator<T, T> | BuilderOperatorNarrow<T, A>)[]): Stringifiable & Executor<FallbackIfUnknown<A, PickWith<T, never, 'id'>>, mode>; } type PipeSub<T extends object, Ret extends string, mode extends 'result' | 'count' = 'result'> = { <A>(...steps: (BuilderOperator<T, T> | BuilderOperatorNarrow<T, A>)[]): NamedBuilder<FallbackIfUnknown<A, PickWith<T, never, 'id'>>, Ret> & (mode extends 'count' ? CountBuilder<any> : {}); }; interface Executor<T, mode extends 'result' | 'count' = 'result'> { execute(url: string, options?: Options): AxiosPromise<{ result: T[]; count: { count: number; }; }[mode]>; } type ResultMultiMono<T extends NamedBuilder<any, any>> = { name: T["queryName"]; } & (T extends CountBuilder<any> ? { count: number; } : { result: T extends NamedBuilder<infer S, any> ? S[] : never; }); interface ExecutorMulti<T extends Builder<any>[]> { execute(url: string, options?: Options): AxiosPromise<T extends (infer S)[] ? ResultMultiMono<S extends NamedBuilder<any, any> ? S : never>[] : never>; } interface BuilderOperator<T, R> { (builder: Builder<T>): Builder<R>; } interface BuilderOperatorNarrow<T, R> { (builder: Builder<T>): NarrowBuilder<R>; } interface NamedBuilderOperator<T, N extends string> { (builder: Builder<T>): NamedBuilder<T, N>; } type StandardOperators = '=' | '!='; type StringOperators = StandardOperators | '~'; type NumbersOperatos = StandardOperators | '>=' | '>' | '<=' | '<'; type AllowedValues = true | false | null; type GetOp<T> = T extends number ? NumbersOperatos : T extends string ? StringOperators : StandardOperators; declare enum WhereFlags { RAW = 1, NUMBER = 1, STRING = 2, STARTSWITH = 6, ENDSWITH = 10, CONTAINS = 14 } declare enum WhereInFlags { AND = 32, NAND = 48, OR = 64, NOR = 80, EXACT = 128 } type FallbackIfUnknown<T, F> = unknown extends T ? F : T; type OuterKeyCast<T, K extends string> = PickOuterKey<K> & UnionKeyOf<T>; type UnionKeyOf<T> = T extends Array<infer T> ? keyof T : T extends infer T ? keyof T : never; type DeepPick<T, P extends string> = T extends Primitive ? T : T extends Array<infer I> ? DeepPick<I, P>[] : T extends object ? string extends P ? number : PickWith<InnerPick<T, P>, OuterKeyCast<T, P>, 'id'> : never; type InnerPick<T, K extends string> = { [key in keyof T]: DeepPick<T[key], InnerKey<Extract<key, string>, K>>; }; type FlatPath<O extends any, P extends List<Key>, X = Path<O, P>> = X extends object ? number : X; type PickOuterKey<K extends string> = K extends '*' ? string : KeyHead<K>; type KeyHead<K extends string> = K extends `${infer K}.${string}` ? K : K; type InnerKey<key extends string, K> = [ Extract<K, `${key}.${string}`> ] extends [`${key}.${infer K}`] ? K : never; type FlatKey<O, K extends keyof O> = Exclude<O[K], null | undefined> extends Array<infer I> ? I : O[K]; type Flat<O> = Exclude<O, null | undefined> extends Array<infer I> ? I : O; type _ExcludePrimitiveKeys<O> = O extends Primitive ? Omit<O, keyof O> : O; type _Path<O, P extends List<Key>, It extends Iteration = IterationOf<0>> = { 0: _Path<Flat<At<_ExcludePrimitiveKeys<O>, P[Pos<It>]>>, P, Next<It>>; 1: O; }[Extends<Pos<It>, Length<P>>]; type Path<O extends any, P extends List<Key>> = _Path<O, P> extends infer X ? Cast<X, any> : never; type Index = number | string; type KeyToIndex<K extends Key, SP extends List<Index>> = number extends K ? Head<SP> : K & Index; type MetaPath<O, D extends string, St extends string, SP extends List<Index> = [], P extends List<Index> = []> = { [K in keyof Required<O>]: Exclude<MetaPath<FlatKey<O, K>, D, St, Tail<SP>, [...P, KeyToIndex<K, SP>]>, string> | Join<[...P, KeyToIndex<K, SP>], D> | ([St] extends [never] ? never : Join<[...P, St], D>); }; type NextPath<OP> = Select<UnionOf<Exclude<OP, string> & {}>, string>; type CurrentPath<OP> = Select<Exclude<OP, object>, string>; type ExecPath<A, SP extends List<Index>, D extends string, St extends string> = NextPath<Path<MetaPath<A, D, St, SP>, SP>>; type HintPath<A, P extends string, SP extends List<Index>, Exec extends string, D extends string, St extends string> = [Exec] extends [never] ? CurrentPath<Path<MetaPath<A, D, St, SP>, SP>> extends never ? ExecPath<A, Pop<SP>, D, St> : CurrentPath<Path<MetaPath<A, D, St, SP>, SP>> : Exec | P; type _AutoPath<A, P extends string, D extends string, St extends string, SP extends List<Index> = Split<P, D>> = HintPath<A, P, SP, ExecPath<A, SP, D, St>, D, St>; type AutoPath<O extends any, P extends string, D extends string = '.', St extends string = '*'> = _AutoPath<O, P, D, St>; type AllAutoPath<O extends object, P extends List<string>> = { [K in keyof P]: AutoPath<O, P[K] & string>; }; type NonEmptyStringList = [string, ...string[]]; type ChosenPaths<P extends NonEmptyStringList> = [string] extends P ? '*' : P[number]; /** * Select only given fields. * Resulting response type is narrowed to only include specified fields (including nested ones). * * @example * ```ts * request().pipe( * fields('*'), // select all fields * fields(["name", "genres.id"]), // select specific fields, incuding sub-type * fields(["name", "genres.*"]), // select specific fields, incuding all fields of sub-type * ) * ``` * @see {@link https://api-docs.igdb.com/?shell#fields} * @param f */ declare function fields<T extends Record<any, any>, P extends NonEmptyStringList>(f: AllAutoPath<T, P> | '*'): BuilderOperatorNarrow<T, DeepPick<T, ChosenPaths<P>>>; /** * Exclude given fields from selection. * Resulting response type is narrowed to exclude specified fields (not compatible with nested fields). * * @example * ```ts * request().pipe( * fields('*'), * exclude(["name", "created_at"]), // exclude specific fields * ) * ``` * @see {@link https://api-docs.igdb.com/?shell#exclude} * @param exclude */ declare function exclude<T extends Record<any, any>, K extends keyof T>(exclude: K[]): BuilderOperatorNarrow<T, Omit<T, K>>; /** * Sort results by specified field. * * @example * ```ts * request().pipe( * sort('name'), // defaults to 'asc' when direction is not specified * sort('name', 'desc'), // manually specify direction * ) * ``` * @see {@link https://api-docs.igdb.com/?shell#sorting} * @param field * @param direction */ declare function sort<T extends Record<any, any>>(field: keyof T, direction?: 'asc' | 'desc'): BuilderOperator<T, T>; /** * Limit the number of results returned by the query. * * @example * ```ts * request().pipe( * limit(42), // Only retrieve 42 elements * ) * ``` * @see {@link https://api-docs.igdb.com/?shell#pagination} * @param limit */ declare function limit<T extends Record<any, any>>(limit: number): BuilderOperator<T, T>; /** * Start results at a given offset. * * @example * ```ts * request().pipe( * offset(50), // Start he results at position 50... * limit(42), // ...and limit the number of results to 42 * ) * ``` * @see {@link https://api-docs.igdb.com/?shell#pagination} * @param offset */ declare function offset<T extends Record<any, any>>(offset: number): BuilderOperator<T, T>; /** * Search based on name, results are sorted by similarity to the given search string. * * @example * ```ts * request().pipe( * search('zelda'), * ) * ``` * @see {@link https://api-docs.igdb.com/?shell#search-1} * @param search */ declare function search<T extends Record<any, any>>(search: string): BuilderOperator<T, T>; /** * Filters results based on given parameters. All parameters are type validated if `request` is given a type. * Also see {@link whereIn}. * * @example * ```ts * request<MyType>().pipe( * where('ratings', '>', 4), // ratings greater than 4 * where('ratings', '>=', 4), // ratings greater than or equal 4 * where('ratings', '<', 4), // ratings less than 4 * where('ratings', '<=', 4), // ratings less than or equal 4 * where('name', '=', 'zelda'), // name is zelda (case sensitive) * where('name', '~', 'zelda'), // name is zelda (case insensitive) * where('name', '!=', 'zelda'), // name is not zelda * where('name', '=', 'zelda', WhereFlags.STARTSWITH), // name starts with zelda (also works with ~) * where('name', '=', 'zelda', WhereFlags.ENDSWITH), // name ends with zelda (also works with ~) * where('name', '=', 'zelda', WhereFlags.CONTAINS), // name contains zelda (also works with ~) * where('release_date', '=', null) // no release date * where('release_date', '!=', null) // release date has any value * ) * ``` * @see {@link https://api-docs.igdb.com/?shell#filters} * @param key * @param op * @param value * @param flag */ declare function where<T extends Record<any, any>, P extends string>(key: AutoPath<T, P, '.', never>, op: GetOp<Path<T, Split<P, '.'>>>, value: FlatPath<T, Split<P, '.'>> | AllowedValues, flag?: WhereFlags): BuilderOperator<T, T>; /** * Filters results based on given parameters. All parameters are type validated if `request` is given a type. * Also see {@link where}. * * @example * ```ts * request<MyType>().pipe( * whereIn('genres', [1, 2], WhereInFlags.AND), // Results whose genres includes 1 and 2 * whereIn('genres', [1, 2], WhereInFlags.OR), // Results whose genres includes 1 or 2 * whereIn('genres', [1, 2], WhereInFlags.NAND), // Results whose genres does not contain both 1 and 2, but can be 1 or 2 * whereIn('genres', [1, 2], WhereInFlags.NOR), // Results whose genres does not contain 1 or does not contain 2 * whereIn('genres', [1, 2], WhereInFlags.EXACT), // Results whose exclusive genres are 1 and 2 * ) * ``` * @see {@link https://api-docs.igdb.com/?shell#filters} * @param key * @param values * @param flag */ declare function whereIn<T extends Record<any, any>, P extends string>(key: AutoPath<T, P, '.', never>, values: FlatPath<T, Split<P, '.'>>[], flag?: WhereInFlags | WhereFlags): BuilderOperator<T, T>; /** * Combine multiple {@link where} and {@link whereIn} conditions. * * @example * ```ts * // Select results that are on platform 1 and 2, and whose name are either 'zelda' or 'link' * request<MyType>().pipe( * and( * whereIn('platforms', [1, 2], WhereInFlags.AND), * or( * where('name', '=', 'zelda'), * where('name', '=', 'link'), * ) * ) * ) * ``` * @see {@link https://api-docs.igdb.com/?shell#filters} * @param operators */ declare function and<T extends Record<any, any>>(...operators: BuilderOperator<T, T>[]): BuilderOperator<T, T>; /** * Combine multiple {@link where} and {@link whereIn} conditions. * * @example * ```ts * // Select results that are on platform 1 and 2, and whose name are either 'zelda' or 'link' * request<MyType>().pipe( * and( * whereIn('platforms', [1, 2], WhereInFlags.AND), * or( * where('name', '=', 'zelda'), * where('name', '=', 'link'), * ) * ) * ) * ``` * @see {@link https://api-docs.igdb.com/?shell#filters} * @param operators */ declare function or<T extends Record<any, any>, R>(...operators: BuilderOperator<T, R>[]): BuilderOperator<T, R>; /** * Prepare a request to an apicalypse endpoint. * * @example * ```ts * // MyType is optional but recommended, so that results are properly typed * request<MyType>().pipe( * fields(["name"]), * sort("created_at", "asc"), * where("created_at", ">", now), * ) * .execute('http:...') * .then(results => ...); * ``` */ declare function request<T extends Record<any, any>, mode extends 'result' | 'count' = 'result'>(): { pipe: Pipe<T, mode>; sub: <S extends string>(queryEndpoint: string, queryName: S) => { pipe: PipeSub<T, S, mode>; }; }; /** * Prepare a multi-query request to an apicalypse endpoint. * * @example * ```ts * multi( * // MyType is optional but recommended, so that results are properly typed * request<MyType>() * .sub('endpoint', 'alias') // mandatory for multi requests * .pipe( * fields(["name"]), * sort("created_at", "asc"), * where("created_at", ">", now), * ), * request<MyType>() * .sub('endpoint', 'alias2') // mandatory for multi requests * .pipe( * fields(["name"]), * sort("created_at", "asc"), * where("created_at", "<", now), * ) * ) * .execute('http:...') * .then(response => ...); * ``` * @see {@link https://api-docs.igdb.com/?shell#multi-query} * @param builders */ declare function multi<T extends Record<any, any>, B extends Builder<T>[]>(...builders: B): Stringifiable & ExecutorMulti<B>; /** * Narrow multi-query results types. * * @example * ```ts * interface MyType { * name: string, * created_at: number * } * * multi( * request<MyType>().sub("games", "latest-games").pipe( * fields(["name"]), * sort("created_at", "desc"), * where("created_at", "<", now), * ), * request<MyType>().sub("games", "coming-soon").pipe( * fields(["created_at"]), * sort("created_at", "desc"), * where("created_at", ">", now), * ) * ).execute('http:...').then(response => { * for (const result of response.data) { * if (isNamed(result, 'latest-games')) { * result.result.name // result is of type `{ name: string }` * } else { * result.result.created_at // result is of type `{ created_at: number }` * } * } * }); * ``` * @param builder * @param name */ declare function isNamed<T extends NamedBuilder<any, string>, S extends string>(builder: ResultMultiMono<T>, name: S): builder is ResultMultiMono<Extract<T, NamedBuilder<any, S>>>; export { AllAutoPath, AllowedValues, AutoPath, Builder, BuilderOperator, BuilderOperatorNarrow, ChosenPaths, CountBuilder, DeepPick, Executor, ExecutorMulti, FallbackIfUnknown, FlatPath, GetOp, NamedBuilder, NamedBuilderOperator, NarrowBuilder, NonEmptyStringList, NumbersOperatos, Options, Path, Pipe, PipeSub, ResultMultiMono, StandardOperators, StringOperators, Stringifiable, WhereFlags, WhereInFlags, and, exclude, fields, isNamed, limit, multi, offset, or, request, search, sort, where, whereIn };