UNPKG

@data-client/endpoint

Version:

Declarative Network Interface Definitions

201 lines (176 loc) 6.03 kB
/* eslint-disable @typescript-eslint/no-unsafe-function-type */ import type { EndpointInterface, Schema } from './interface.js'; import type { EndpointExtraOptions, FetchFunction, PartialParameters, } from './types.js'; export interface EndpointOptions< F extends FetchFunction = FetchFunction, S extends Schema | undefined = undefined, M extends boolean | undefined = false, > extends EndpointExtraOptions<F> { key?: (...args: Parameters<F>) => string; sideEffect?: M; schema?: S; [k: string]: any; } export interface EndpointExtendOptions< F extends FetchFunction = FetchFunction, S extends Schema | undefined = Schema | undefined, M extends boolean | undefined = boolean | undefined, > extends EndpointOptions<F, S, M> { fetch?: FetchFunction; } export type ParamFromFetch<F> = F extends (params: infer P, body?: any) => Promise<any> ? P : never; //type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U; TODO: should we use this? export type KeyofEndpointInstance = keyof EndpointInstance<FetchFunction>; export type ExtendedEndpoint< O extends EndpointExtendOptions<F>, E extends EndpointInstance< FetchFunction, Schema | undefined, boolean | undefined >, F extends FetchFunction, > = EndpointInstance< 'fetch' extends keyof O ? Exclude<O['fetch'], undefined> : E['fetch'], 'schema' extends keyof O ? O['schema'] : E['schema'], 'sideEffect' extends keyof O ? O['sideEffect'] : E['sideEffect'] > & Omit<O, KeyofEndpointInstance> & Omit<E, KeyofEndpointInstance>; /** * Defines an async data source. * @see https://dataclient.io/docs/api/Endpoint */ export interface EndpointInstance< F extends (...args: any) => Promise<any> = FetchFunction, S extends Schema | undefined = Schema | undefined, M extends boolean | undefined = boolean | undefined, > extends EndpointInstanceInterface<F, S, M> { extend< E extends EndpointInstance< (...args: any) => Promise<any>, Schema | undefined, boolean | undefined >, O extends EndpointExtendOptions<F> & Partial<Omit<E, keyof EndpointInstance<FetchFunction>>> & Record<string, unknown>, >( this: E, options: Readonly<O>, ): ExtendedEndpoint<typeof options, E, F>; } /** * Defines an async data source. * @see https://dataclient.io/docs/api/Endpoint */ export interface EndpointInstanceInterface< F extends FetchFunction = FetchFunction, S extends Schema | undefined = Schema | undefined, M extends boolean | undefined = boolean | undefined, > extends EndpointInterface<F, S, M> { constructor: EndpointConstructor; /** * Calls the function, substituting the specified object for the this value of the function, and the specified array for the arguments of the function. * @param thisArg The object to be used as the this object. * @param argArray A set of arguments to be passed to the function. */ apply<E extends FetchFunction>( this: E, thisArg: ThisParameterType<E>, argArray?: Parameters<E>, ): ReturnType<E>; /** * Calls a method of an object, substituting another object for the current object. * @param thisArg The object to be used as the current object. * @param argArray A list of arguments to be passed to the method. */ call<E extends FetchFunction>( this: E, thisArg: ThisParameterType<E>, ...argArray: Parameters<E> ): ReturnType<E>; /** * For a given function, creates a bound function that has the same body as the original function. * The this object of the bound function is associated with the specified object, and has the specified initial parameters. * @param thisArg An object to which the this keyword can refer inside the new function. * @param argArray A list of arguments to be passed to the new function. */ bind<E extends FetchFunction, P extends PartialParameters<E>>( this: E, thisArg: ThisParameterType<E>, ...args: readonly [...P] ): EndpointInstance< (...args: readonly [...RemoveArray<Parameters<E>, P>]) => ReturnType<E>, S, M > & Omit<E, keyof EndpointInstance<FetchFunction>>; /** Returns a string representation of a function. */ toString(): string; prototype: any; readonly length: number; // Non-standard extensions arguments: any; caller: F; key(...args: Parameters<F>): string; readonly sideEffect: M; readonly schema: S; fetch: F; /* utilities */ /** @see https://dataclient.io/rest/api/Endpoint#testKey */ testKey(key: string): boolean; } export interface EndpointConstructor { /** * Defines an async data source. * @see https://dataclient.io/docs/api/Endpoint */ new < F extends ( this: EndpointInstance<FetchFunction> & E, params?: any, body?: any, ) => Promise<any>, S extends Schema | undefined = undefined, M extends boolean | undefined = false, E extends Record<string, any> = {}, >( fetchFunction: F, options?: EndpointOptions<F, S, M> & E, ): EndpointInstance<F, S, M> & E; readonly prototype: Function; } export interface ExtendableEndpointConstructor { /** * Defines an async data source. * @see https://dataclient.io/docs/api/Endpoint */ new < F extends ( this: EndpointInstanceInterface<FetchFunction> & E, params?: any, body?: any, ) => Promise<any>, S extends Schema | undefined = undefined, M extends boolean | undefined = false, E extends Record<string, any> = {}, >( RestFetch: F, options?: Readonly<EndpointOptions<F, S, M>> & E, ): EndpointInstanceInterface<F, S, M> & E; readonly prototype: Function; } type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N; type IfTypeScriptLooseNull<Y, N> = 1 | undefined extends 1 ? Y : N; type OnlyFirst<A extends unknown[]> = A extends [] ? [] : [A[0]]; type RemoveArray<Orig extends any[], Rem extends any[]> = Rem extends [any, ...infer RestRem] ? Orig extends [any, ...infer RestOrig] ? RemoveArray<RestOrig, RestRem> : never : Orig;