@fluentity/core
Version:
Fluentity is a fluent, model-oriented, typed HTTP client for TypeScript and framework agnostic.
419 lines (418 loc) • 12.5 kB
TypeScript
import { AdapterOptions, AdapterRequest, AdapterResponse } from '../Fluentity';
import { QueryBuilder } from '../QueryBuilder';
/**
* HTTP method constants for use in requests.
* Provides type-safe HTTP method names.
*
* @example
* ```typescript
* const method: MethodType = Methods.POST;
* ```
*/
export declare const Methods: {
/** HTTP GET method */
readonly GET: "GET";
/** HTTP POST method */
readonly POST: "POST";
/** HTTP PUT method */
readonly PUT: "PUT";
/** HTTP PATCH method */
readonly PATCH: "PATCH";
/** HTTP DELETE method */
readonly DELETE: "DELETE";
/** HTTP HEAD method */
readonly HEAD: "HEAD";
/** HTTP OPTIONS method */
readonly OPTIONS: "OPTIONS";
};
/**
* Type representing valid HTTP method names.
* Derived from the Methods constant object.
*/
export type MethodType = keyof typeof Methods;
/**
* Abstract HTTP adapter class that provides base functionality for HTTP requests.
* Implements caching, interceptors, and request/response handling capabilities.
* Serves as the foundation for specific HTTP adapters like RestAdapter and GraphqlAdapter.
*
* Features:
* - Built-in response caching with TTL support
* - Request and response interceptors
* - Error handling and custom error interceptors
* - Configurable request handlers
* - Automatic JSON body serialization
*
* @abstract
* @class
* @implements {AdapterInterface}
* @example
* ```typescript
* class CustomHttpAdapter extends HttpAdapter {
* protected async fetchRequestHandler(request: HttpRequest): Promise<HttpResponse> {
* // Custom HTTP request implementation
* }
* }
*
* const adapter = new CustomHttpAdapter({
* baseUrl: 'https://api.example.com',
* cacheOptions: { enabled: true, ttl: 300000 }
* });
* ```
*/
export declare abstract class HttpAdapter<T extends HttpAdapterOptions> {
/**
* Internal cache for storing HTTP responses.
* Uses WeakMap to avoid memory leaks and automatically clean up cached responses.
* @private
*/
protected _cache: WeakMap<HttpRequest, CacheData>;
/**
* Configuration options for the HTTP adapter.
* Contains all settings for request handling, caching, and interceptors.
*/
options: HttpAdapterOptions;
/**
* The current request object being processed.
* @private
*/
private _request;
/**
* Constructor for the HttpAdapter class.
* Initializes the adapter with the provided configuration options.
*
* @param options - Partial configuration options to merge with existing options
* @throws {Error} If baseUrl is not provided
* @example
* ```typescript
* const adapter = new CustomHttpAdapter({
* baseUrl: 'https://api.example.com',
* cacheOptions: { enabled: true, ttl: 300000 },
* requestInterceptor: (request) => {
* request.options.headers['Authorization'] = 'Bearer token';
* return request;
* }
* });
* ```
*/
constructor(options: Partial<T>);
/**
* Configures the adapter with new options.
* Merges the provided options with existing configuration.
*
* @param options - Configuration options to apply
* @returns The adapter instance for method chaining
* @example
* ```typescript
* adapter.configure({
* baseUrl: 'https://new-api.example.com',
* cacheOptions: { enabled: true }
* });
* ```
*/
configure(options: Partial<T>): this;
/**
* Gets the current request object.
* Provides access to the request being processed.
*
* @returns The current HttpRequest instance
*/
get request(): HttpRequest;
/**
* Clears all cached responses.
* Resets the internal cache, forcing all subsequent requests to be made fresh.
*
* @returns The adapter instance for method chaining
* @example
* ```typescript
* // Clear cache after configuration changes
* adapter.configure({ baseUrl: 'https://new-api.example.com' });
* adapter.clearCache();
* ```
*/
clearCache(): this;
/**
* Makes an HTTP request using the adapter's configuration.
* Handles caching, interceptors, and error handling automatically.
*
* @param queryBuilder - The query builder containing request details
* @returns A promise that resolves to the response data
* @throws {Error} If baseUrl is not configured or if the request fails
* @example
* ```typescript
* const queryBuilder = new QueryBuilder()
* .where({ status: 'active' })
* .limit(10);
*
* const response = await adapter.call(queryBuilder);
* console.log(response.data);
* ```
*/
call(queryBuilder: QueryBuilder<T>): Promise<HttpResponse>;
/**
* Builds an HTTP request from a query builder.
* Abstract method that must be implemented by subclasses to provide
* adapter-specific request building logic.
*
* @param queryBuilder - The query builder containing request details
* @returns An HttpRequest instance
* @protected
* @abstract
*/
protected buildRequest(queryBuilder: QueryBuilder): HttpRequest;
/**
* Default request handler that must be implemented by subclasses.
* Provides the actual HTTP request implementation for the adapter.
*
* @param _request - The HTTP request to execute
* @returns Promise resolving to an HttpResponse
* @protected
* @abstract
*/
protected fetchRequestHandler(_request: HttpRequest): Promise<HttpResponse>;
}
/**
* Configuration options for HTTP adapters.
* Extends AdapterOptions with HTTP-specific configuration including caching,
* interceptors, and request handling options.
*
* @interface
* @extends {AdapterOptions}
* @template T - The type of response data
* @example
* ```typescript
* const options: HttpAdapterOptions = {
* baseUrl: 'https://api.example.com',
* options: {
* headers: {
* 'Authorization': 'Bearer token',
* 'Content-Type': 'application/json'
* }
* },
* cacheOptions: {
* enabled: true,
* ttl: 300000 // 5 minutes
* },
* requestInterceptor: (request) => {
* // Modify request before sending
* return request;
* },
* responseInterceptor: (response) => {
* // Modify response after receiving
* return response;
* }
* };
* ```
*/
export interface HttpAdapterOptions<T = unknown | any> extends AdapterOptions {
/** Base URL to prepend to all requests */
baseUrl?: string;
/** Default request options to apply to all requests */
options?: HttpRequestOptions;
/** Interceptor to modify requests before they are sent */
requestInterceptor?: (request: HttpRequest) => HttpRequest;
/** Interceptor to modify responses after they are received */
responseInterceptor?: (response: HttpResponse<T>) => HttpResponse<T>;
/** Handler for request errors */
errorInterceptor?: (error: Error) => void;
/** Custom request handler function */
requestHandler?: (request: HttpRequest) => Promise<HttpResponse>;
/** Cache configuration options */
cacheOptions?: CacheOptions;
}
/**
* Configuration options for response caching.
* Controls whether and how responses are cached by the adapter.
*
* @interface
* @example
* ```typescript
* const cacheOptions: CacheOptions = {
* enabled: true,
* ttl: 300000 // 5 minutes in milliseconds
* };
* ```
*/
export interface CacheOptions {
/** Whether caching is enabled */
enabled: boolean;
/** Time-to-live for cached responses in milliseconds */
ttl?: number;
}
/**
* Interface for HTTP request data.
* Defines the structure of HTTP requests used by the adapter.
*
* @interface
* @example
* ```typescript
* const request: HttpRequestInterface = {
* url: '/users/123',
* method: 'GET',
* body: { name: 'John' },
* options: {
* headers: { 'Authorization': 'Bearer token' }
* }
* };
* ```
*/
export interface HttpRequestInterface {
/** The full URL to send the request to */
url: string;
/** Request options including method, headers, body, etc. */
options?: HttpRequestOptions;
/** HTTP method to use */
method?: MethodType;
/** Request body data */
body?: string | object | object[] | undefined;
}
/**
* HTTP request class that implements HttpRequestInterface.
* Provides a structured way to represent HTTP requests with proper typing.
*
* @class
* @implements {HttpRequestInterface}
* @implements {AdapterRequest}
* @example
* ```typescript
* const request = new HttpRequest({
* url: '/users',
* method: 'POST',
* body: { name: 'John', email: 'john@example.com' },
* options: {
* headers: { 'Content-Type': 'application/json' }
* }
* });
* ```
*/
export declare class HttpRequest implements HttpRequestInterface, AdapterRequest {
/** The full URL to send the request to */
url: string;
/** Request options including headers, credentials, etc. */
options?: HttpRequestOptions;
/** HTTP method to use for the request */
method?: MethodType;
/** Request body data */
body?: string | any | any[];
/**
* Creates a new HttpRequest instance.
*
* @param options - Partial request configuration
* @example
* ```typescript
* const request = new HttpRequest({
* url: '/users/123',
* method: 'GET'
* });
* ```
*/
constructor(options?: Partial<HttpRequestInterface>);
}
/**
* Interface for HTTP response data.
* Defines the structure of HTTP responses returned by the adapter.
*
* @interface
* @example
* ```typescript
* const response: HttpResponseInterface = {
* data: { id: 123, name: 'John' }
* };
* ```
*/
export interface HttpResponseInterface {
/** The response data from the API */
data: any;
}
/**
* HTTP response class that implements HttpResponseInterface.
* Provides a structured way to represent HTTP responses with proper typing.
*
* @class
* @implements {HttpResponseInterface}
* @implements {AdapterResponse<T>}
* @template T - The type of response data
* @example
* ```typescript
* const response = new HttpResponse({
* data: { id: 123, name: 'John' }
* });
*
* console.log(response.data.name); // 'John'
* ```
*/
export declare class HttpResponse<T = any> implements HttpResponseInterface, AdapterResponse<T> {
/** The response data from the API */
data: T;
/**
* Creates a new HttpResponse instance.
*
* @param options - Partial response configuration
* @example
* ```typescript
* const response = new HttpResponse({
* data: { id: 123, name: 'John' }
* });
* ```
*/
constructor(options?: Partial<HttpResponseInterface>);
}
/**
* Interface for HTTP request options.
* Extends AdapterOptions with HTTP-specific request configuration.
*
* @interface
* @extends {AdapterOptions}
* @example
* ```typescript
* const requestOptions: HttpRequestOptions = {
* headers: {
* 'Authorization': 'Bearer token',
* 'Content-Type': 'application/json'
* },
* credentials: 'include',
* mode: 'cors',
* cache: 'default'
* };
* ```
*/
export interface HttpRequestOptions extends AdapterOptions {
/** Request headers */
headers?: Record<string, string>;
/** Request credentials mode */
credentials?: RequestCredentials;
/** Request mode */
mode?: RequestMode;
/** How to handle redirects */
redirect?: RequestRedirect;
/** Referrer URL */
referrer?: string;
/** Referrer policy */
referrerPolicy?: ReferrerPolicy;
/** Subresource integrity value */
integrity?: string;
/** Cache mode */
cache?: RequestCache;
/** Whether to keep the connection alive */
keepalive?: boolean;
/** Abort signal for cancelling the request */
signal?: AbortSignal;
}
/**
* Interface for cached response data.
* Represents a cached HTTP response with timestamp information.
*
* @interface
* @example
* ```typescript
* const cachedData: CacheData = {
* data: new HttpResponse({ data: { id: 123 } }),
* timestamp: Date.now()
* };
* ```
*/
export interface CacheData {
/** The cached response data */
data: HttpResponse;
/** Timestamp when the data was cached (milliseconds since epoch) */
timestamp: number;
}