guardz-axios
Version:
Type-safe HTTP client built on top of Axios with runtime validation using guardz. Part of the guardz ecosystem for comprehensive TypeScript type safety.
111 lines • 5.55 kB
TypeScript
import { AxiosInstance, AxiosRequestConfig } from "axios";
import type { TypeGuardFn } from "guardz";
import { Status } from "../types/status-types";
export type ApiResult<T> = {
status: Status.SUCCESS;
data: T;
} | {
status: Status.ERROR;
code: number;
message: string;
};
/**
* Configuration for safe requests that never throw
*/
export interface SafeRequestConfig<T> {
/** Type guard function to validate response data */
guard: TypeGuardFn<T>;
/** Enable tolerance mode (default: false) */
tolerance?: boolean;
/** Identifier for error context (default: URL) */
identifier?: string;
/** Error callback - only used in tolerance mode */
onError?: (error: string, context: ErrorContext) => void;
/** Custom axios instance */
axiosInstance?: AxiosInstance;
/** Validate response structure */
validateResponse?: boolean;
/** Timeout in milliseconds */
timeout?: number;
}
export interface ErrorContext {
type: "validation" | "network" | "timeout" | "unknown";
url: string;
method: string;
statusCode?: number;
originalError?: unknown;
}
/**
* Pattern 1: Curried Function (Google/Ramda style)
* Usage: const getUserSafely = safeGet({ guard: isUser });
* const result = await getUserSafely('https://api.example.com/users/1');
* // result is { status: Status.SUCCESS, data: User } | { status: Status.ERROR, data: AxiosError }
*/
export declare function safeGet<T>(config: SafeRequestConfig<T>): (url: string, axiosConfig?: AxiosRequestConfig) => Promise<ApiResult<T>>;
export declare function safePost<T>(config: SafeRequestConfig<T>): (url: string, data?: any, axiosConfig?: AxiosRequestConfig) => Promise<ApiResult<T>>;
export declare function safePut<T>(config: SafeRequestConfig<T>): (url: string, data?: any, axiosConfig?: AxiosRequestConfig) => Promise<ApiResult<T>>;
export declare function safePatch<T>(config: SafeRequestConfig<T>): (url: string, data?: any, axiosConfig?: AxiosRequestConfig) => Promise<ApiResult<T>>;
export declare function safeDelete<T>(config: SafeRequestConfig<T>): (url: string, axiosConfig?: AxiosRequestConfig) => Promise<ApiResult<T>>;
/**
* Pattern 2: Configuration-first (Apollo/React Query style)
* Usage: const result = await safeRequest({ url: '/users/1', method: 'GET', guard: isUser });
*/
export declare function safeRequest<T>(requestConfig: AxiosRequestConfig & {
guard: TypeGuardFn<T>;
} & Omit<SafeRequestConfig<T>, "guard">): Promise<ApiResult<T>>;
/**
* Pattern 3: Fluent API Builder
* Usage: const result = await safe().get('/users/1').guard(isUser).execute();
*/
export declare class SafeRequestBuilder<T = unknown> {
private config;
private axiosConfig;
get(url: string): SafeRequestBuilder<T>;
post(url: string, data?: any): SafeRequestBuilder<T>;
put(url: string, data?: any): SafeRequestBuilder<T>;
patch(url: string, data?: any): SafeRequestBuilder<T>;
delete(url: string): SafeRequestBuilder<T>;
guard<U>(guardFn: TypeGuardFn<U>): SafeRequestBuilder<U>;
tolerance(enabled?: boolean): SafeRequestBuilder<T>;
identifier(id: string): SafeRequestBuilder<T>;
timeout(ms: number): SafeRequestBuilder<T>;
headers(headers: Record<string, string>): SafeRequestBuilder<T>;
baseURL(url: string): SafeRequestBuilder<T>;
execute(): Promise<ApiResult<T>>;
}
export declare function safe(): SafeRequestBuilder;
/**
* Pattern 4: Context API (React Context style)
* Usage: const api = createSafeApiContext({ baseURL: 'https://api.example.com' });
* const result = await api.get('/users/1', { guard: isUser });
*/
export interface SafeApiContextConfig {
baseURL?: string;
timeout?: number;
headers?: Record<string, string>;
defaultTolerance?: boolean;
axiosInstance?: AxiosInstance;
}
export declare function createSafeApiContext(contextConfig?: SafeApiContextConfig): {
get: <T>(url: string, config: Required<Pick<SafeRequestConfig<T>, "guard">> & Omit<SafeRequestConfig<T>, "axiosInstance" | "guard">) => Promise<ApiResult<T>>;
post: <T>(url: string, config: Required<Pick<SafeRequestConfig<T>, "guard">> & Omit<SafeRequestConfig<T>, "axiosInstance" | "guard">, data?: any) => Promise<ApiResult<T>>;
put: <T>(url: string, config: Required<Pick<SafeRequestConfig<T>, "guard">> & Omit<SafeRequestConfig<T>, "axiosInstance" | "guard">, data?: any) => Promise<ApiResult<T>>;
patch: <T>(url: string, config: Required<Pick<SafeRequestConfig<T>, "guard">> & Omit<SafeRequestConfig<T>, "axiosInstance" | "guard">, data?: any) => Promise<ApiResult<T>>;
delete: <T>(url: string, config: Required<Pick<SafeRequestConfig<T>, "guard">> & Omit<SafeRequestConfig<T>, "axiosInstance" | "guard">) => Promise<ApiResult<T>>;
request: <T>(config: AxiosRequestConfig & {
guard: TypeGuardFn<T>;
} & Omit<SafeRequestConfig<T>, "axiosInstance" | "guard">) => Promise<ApiResult<T>>;
};
/**
* Type helper to extract data type from guard function
*/
export type InferDataType<T> = T extends TypeGuardFn<infer U> ? U : never;
/**
* Helper to create typed safe get function
*/
export declare function createTypedSafeGet<T>(guard: TypeGuardFn<T>): (url: string, axiosConfig?: AxiosRequestConfig) => Promise<ApiResult<T>>;
/**
* Helper to create typed safe post function
*/
export declare function createTypedSafePost<T>(guard: TypeGuardFn<T>): (url: string, data?: any, axiosConfig?: AxiosRequestConfig) => Promise<ApiResult<T>>;
//# sourceMappingURL=safe-axios-never-throws.d.ts.map