export type Nullable = T | null export type Keys = string | number | symbol export type JsonObject = { [key in Keys]: T } export type MiddlewareRequest = ClientRequest export type Optional = { [k in Keys]: any } export type Middleware = (next: Next) => (request: MiddlewareRequest) => Promise export type MiddlewareResponse = { resolve: Function; reject: Function; body: T; error?: HttpErrorType; statusCode: number; headers?: Record originalRequest?: MiddlewareRequest; } export type HttpErrorType = { name?: string message?: string code?: string status?: number method: MethodType statusCode: number originalRequest?: ClientRequest /** * @deprecated use `error` instead */ body?: JsonObject error?: JsonObject retryCount?: number headers?: Record [key: string]: any } export interface ClientRequest { baseUri?: string uri?: string headers?: Record method: MethodType uriTemplate?: string pathVariables?: VariableMap queryParams?: VariableMap body?: Record | string | Uint8Array; response?: ClientResponse resolve?: Function; reject?: Function; [key: string]: any } export type Next = (request: MiddlewareRequest) => Promise export type MethodType = | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE' export type QueryParam = | string | string[] | number | number[] | boolean | boolean[] | undefined export type VariableMap = { [key: string]: QueryParam } export type ClientResponse = { body?: T code?: string statusCode?: number headers?: Record error?: HttpErrorType retryCount?: number } export type ClientResult = ClientResponse export type ClientOptions = { middlewares: Array } export type Credentials = { clientId: string clientSecret: string anonymousId?: string } export type AuthMiddlewareOptions = { host: string projectKey: string credentials: Credentials scopes?: Array // For internal usage only oauthUri?: string tokenCache?: TokenCache httpClient?: Function httpClientOptions?: object } export type TokenCacheOptions = { clientId: string projectKey: string host: string } export type TokenStore = { token: string expirationTime: number refreshToken?: string tokenCacheKey?: TokenCacheOptions } export type TokenCache = { get: (tokenCacheOptions?: TokenCacheOptions) => Promise set: (cache: TokenStore, tokenCacheOptions?: TokenCacheOptions) => Promise } export type IBuiltRequestParams = { basicAuth: string url: string body: string data?: string } export type RefreshAuthMiddlewareOptions = { host: string projectKey: string credentials: { clientId: string clientSecret: string } refreshToken: string tokenCache?: TokenCache, // For internal usage only oauthUri?: string httpClient?: Function httpClientOptions?: object } /* Request */ type RequestBaseOptions = { url: string body: string basicAuth: string request: MiddlewareRequest tokenCache: TokenCache tokenCacheKey?: TokenCacheOptions tokenCacheObject?: TokenStore httpClientOptions?: object } export type ExecuteRequestOptions = RequestBaseOptions & { next: Next httpClient?: Function userOption?: AuthMiddlewareOptions | PasswordAuthMiddlewareOptions } export type AuthMiddlewareBaseOptions = RequestBaseOptions & { request: MiddlewareRequest httpClient?: Function } export type Task = { request: MiddlewareRequest next?: Next } export type UserAuthOptions = { username: string password: string } export type PasswordAuthMiddlewareOptions = { host: string projectKey: string credentials: { clientId: string clientSecret: string user: UserAuthOptions } scopes?: Array tokenCache?: TokenCache, // For internal usage only oauthUri?: string httpClient?: Function httpClientOptions?: object } export type TokenInfo = { refresh_token: string access_token: string expires_at: number expires_in: number // since this will always be used to calculate the expiration time, it shouldn't be made optional scope?: string token_type?: string } export type Dispatch = (next: Next) => (request: MiddlewareRequest) => Promise export type CredentialsMode = 'omit' | 'same-origin' | 'include' export type HttpMiddlewareOptions = { host: string credentialsMode?: CredentialsMode includeResponseHeaders?: boolean includeOriginalRequest?: boolean includeRequestInErrorResponse?: boolean maskSensitiveHeaderData?: boolean timeout?: number enableRetry?: boolean retryConfig?: RetryOptions httpClient?: Function stringBodyContentTypes?: Array httpClientOptions?: object // will be passed as a second argument to your httpClient function for configuration getAbortController?: () => AbortController } export type RetryOptions = RetryMiddlewareOptions export type HttpOptions = { url: string clientOptions: HttpClientOptions httpClient?: Function } export type LoggerMiddlewareOptions = { loggerFn?: (options: MiddlewareResponse) => void } export type RetryMiddlewareOptions = { backoff?: boolean maxRetries?: number retryDelay?: number maxDelay?: typeof Infinity retryOnAbort?: boolean retryCodes?: Array } export type CorrelationIdMiddlewareOptions = { generate?: () => string } /* HTTP User Agent */ export type HttpUserAgentOptions = { name?: string version?: string libraryName?: string libraryVersion?: string contactUrl?: string contactEmail?: string customAgent?: string } export type QueueMiddlewareOptions = { concurrency?: number } export type ExistingTokenMiddlewareOptions = { force: boolean } export type ConcurrentModificationMiddlewareOptions = { concurrentModificationHandlerFn?: ( version: number, request: MiddlewareRequest, response: MiddlewareResponse ) => Promise | string | Uint8Array>; } export type BeforeExecutionMiddlewareOptions = { [key: string]: any; middleware: (options?: Omit) => Middleware } export type AfterExecutionMiddlewareOptions = { [key: string]: any; middleware: (options?: Omit) => Middleware } export type TelemetryOptions = { apm?: Function; tracer?: Function; userAgent?: string; createTelemetryMiddleware: (options?: Omit) => Middleware } export type IClientOptions = { method: MethodType; headers: Record credentialsMode?: CredentialsMode; body?: Record | string | Uint8Array; timeout?: number abortController?: AbortController signal?: AbortSignal, getAbortController?: () => AbortController includeOriginalRequest?: boolean enableRetry?: boolean retryConfig?: RetryOptions maskSensitiveHeaderData?: boolean httpClientOptions?: object } export type HttpClientOptions = IClientOptions & Optional export type HttpClientConfig = IClientOptions & { url: string httpClient?: Function } type TResponse = { data: Record message?: string statusCode: number retryCount: number headers: Record } export type Client = { execute(request: ClientRequest): Promise> process( request: ClientRequest, fn: ProcessFn, processOpt?: ProcessOptions ): Promise | Array> } export type ProcessFn = (result: ClientResult) => Promise> export type ProcessOptions = { limit?: number; sort?: string; accumulate?: boolean; total?: number; } export type ErrorHandlerOptions = { error: HttpErrorType request: MiddlewareRequest response: MiddlewareResponse next: Next } export type ErrorMiddlewareOptions = { handler?: (args: ErrorHandlerOptions) => Promise } export type SuccessResult>> = { body: { results: Array; count: number; }; statusCode: number; headers?: JsonObject; } export type IResponse = Response & { statusCode?: number; data?: object } export type executeRequest = (request: ClientRequest) => Promise