rest-envelop
Version:
Wrapper for working with REST API using well-known axios and native fetch modules, with pluggable caching, retry with backoff, and TypeScript typings
144 lines (122 loc) • 4.01 kB
TypeScript
/**
* Type definitions for rest-envelop.
*/
export interface Logger {
info?(...args: unknown[]): void;
warn?(...args: unknown[]): void;
error?(...args: unknown[]): void;
}
export interface CustomCacheAdapter {
get(key: string): Promise<string | null | undefined>;
set(key: string, value: string, ttl: number): Promise<unknown>;
}
export interface RedisCacheOptions {
[key: string]: unknown;
}
export interface MemcachedCacheOptions {
servers?: string | string[];
options?: Record<string, unknown>;
}
export interface CacheServiceOptions {
/** List of HTTP statuses eligible for caching. Defaults to `[200]`. */
cachedStatuses?: number[];
/** Use a custom cache client instead of redis/memcached. */
adapter?: CustomCacheAdapter;
/** ioredis connection options/string. Mutually exclusive with `memcached`. */
redis?: RedisCacheOptions;
/** memcached connection options. Mutually exclusive with `redis`. */
memcached?: MemcachedCacheOptions;
}
export interface BackoffOptions {
/** Base delay in ms for the first retry. Default: 200. */
baseMs?: number;
/** Maximum delay in ms between retries. Default: 5000. */
maxMs?: number;
/** Exponential growth factor. Default: 2. */
factor?: number;
/** Randomize the delay (full jitter). Default: true. */
jitter?: boolean;
}
export interface RetryOptions {
/** Number of retry attempts after the first try. */
attempts?: number;
/** HTTP statuses that are considered successful and won't trigger a retry. */
expectedStatuses?: number[];
/** Backoff configuration between attempts, or `false` to retry immediately. */
backoff?: BackoffOptions | false;
}
export interface CacheRequestOptions {
/** Custom cache key. Defaults to the request URL. */
key?: string;
/** Time-to-live in seconds. Caching is only active when `ttl` is set. */
ttl?: number;
/** Override the instance-level cached statuses for this request only. */
cachedStatuses?: number[];
}
export interface RequestOptions {
method?: string;
params?: Record<string, unknown>;
headers?: Record<string, string>;
timeout?: number;
signal?: AbortSignal;
requestLog?: boolean;
cache?: CacheRequestOptions;
retry?: RetryOptions;
body?: BodyInit | unknown;
[key: string]: unknown;
}
export interface RestEnvelopResponse<T = unknown> {
data: T;
status: number;
headers?: Record<string, unknown> | Headers;
}
export interface ClientOptionalConfig {
environment?: string;
requestLog?: boolean;
createInstance?: boolean;
logger?: Logger | false;
cacheService?: CacheServiceOptions;
}
export interface ClientConfig {
baseURL?: string;
timeout?: number;
headers?: Record<string, string>;
optional?: ClientOptionalConfig;
[key: string]: unknown;
}
declare class BaseClient {
constructor(config: ClientConfig);
readonly timeout: number;
readonly environment: string | undefined;
readonly requestLog: boolean;
readonly enableRequestLog: boolean;
readonly logger: Required<Logger>;
readonly cachedStatuses: number[];
static absoluteUrl(url: string): boolean;
}
export class Axios extends BaseClient {
request<T = unknown>(url: string, options?: RequestOptions): Promise<RestEnvelopResponse<T>>;
}
export class Fetch extends BaseClient {
request<T = unknown>(url: string, options?: RequestOptions): Promise<RestEnvelopResponse<T>>;
}
export class RestEnvelopError extends Error {
constructor(message: string, meta?: Record<string, unknown>);
}
export class RequestTimeoutError extends RestEnvelopError {
url: string;
timeout: number;
constructor(url: string, timeout: number);
}
export class UnexpectedStatusError extends RestEnvelopError {
url: string;
status: number;
expectedStatuses: number[];
constructor(url: string, status: number, expectedStatuses?: number[]);
}
export class CacheError extends RestEnvelopError {
operation: 'get' | 'set';
key: string;
cause: Error;
constructor(operation: 'get' | 'set', key: string, cause: Error);
}