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.
352 lines • 10.1 kB
JavaScript
"use strict";
/**
* Unified API Layer
* Integrates domain-driven architecture with existing patterns
* Following Composition over Inheritance (CoI) principles
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UnifiedApi = void 0;
exports.createUnifiedApi = createUnifiedApi;
exports.createSafeGet = createSafeGet;
exports.createSafePost = createSafePost;
exports.createSafePut = createSafePut;
exports.createSafePatch = createSafePatch;
exports.createSafeDelete = createSafeDelete;
const request_service_1 = require("../services/request-service");
const types_1 = require("../domain/types");
const axios_1 = __importDefault(require("axios"));
/**
* Axios HTTP Client Adapter
* Adapts Axios to our HttpClient interface
*/
class AxiosHttpClient {
constructor(axiosInstance) {
this.axiosInstance = axiosInstance || axios_1.default;
}
async request(config) {
return this.axiosInstance.request(config);
}
}
/**
* Console Logger Implementation
*/
class ConsoleLogger {
error(message, context) {
console.error(`[ERROR] ${message}`, context);
}
warn(message, context) {
console.warn(`[WARN] ${message}`, context);
}
info(message, context) {
console.info(`[INFO] ${message}`, context);
}
debug(message, context) {
console.debug(`[DEBUG] ${message}`, context);
}
}
/**
* Unified API Class
* Provides a clean interface combining all patterns
*/
class UnifiedApi {
constructor(config = {}) {
const httpClient = new AxiosHttpClient(config.axiosInstance);
const logger = config.logger || new ConsoleLogger();
this.requestService = new request_service_1.RequestService({
httpClient,
logger,
defaultTimeout: config.timeout || 5000,
defaultRetryConfig: config.defaultRetryConfig || {
attempts: 3,
delay: 1000,
backoff: "exponential",
},
});
this.defaultConfig = {
baseURL: config.baseURL,
headers: config.headers,
};
}
/**
* Pattern 1: Curried Functions (Functional Style)
*/
createSafeGet(guard) {
return async (url, config) => {
const fullConfig = {
...this.defaultConfig,
...config,
url,
method: "GET",
guard,
headers: config?.headers
? {
...this.defaultConfig.headers,
...config.headers,
}
: this.defaultConfig.headers,
};
return this.requestService.executeRequest(fullConfig);
};
}
createSafePost(guard) {
return async (url, data, config) => {
const fullConfig = {
...this.defaultConfig,
...config,
url,
method: "POST",
data,
guard,
headers: config?.headers
? {
...this.defaultConfig.headers,
...config.headers,
}
: this.defaultConfig.headers,
};
return this.requestService.executeRequest(fullConfig);
};
}
createSafePut(guard) {
return async (url, data, config) => {
const fullConfig = {
...this.defaultConfig,
...config,
url,
method: "PUT",
data,
guard,
};
return this.requestService.executeRequest(fullConfig);
};
}
createSafePatch(guard) {
return async (url, data, config) => {
const fullConfig = {
...this.defaultConfig,
...config,
url,
method: "PATCH",
data,
guard,
};
return this.requestService.executeRequest(fullConfig);
};
}
createSafeDelete(guard) {
return async (url, config) => {
const fullConfig = {
...this.defaultConfig,
...config,
url,
method: "DELETE",
guard,
};
return this.requestService.executeRequest(fullConfig);
};
}
/**
* Pattern 2: Configuration-first (Apollo/React Query style)
*/
async safeRequest(config) {
const fullConfig = {
...this.defaultConfig,
...config,
headers: config.headers
? {
...this.defaultConfig.headers,
...config.headers,
}
: this.defaultConfig.headers,
};
return this.requestService.executeRequest(fullConfig);
}
/**
* Pattern 3: Fluent API Builder
*/
safe() {
return new SafeRequestBuilder(this.requestService, this.defaultConfig);
}
/**
* Pattern 4: Context API (React Context style)
*/
createContext() {
return new SafeApiContext(this.requestService, this.defaultConfig);
}
/**
* Utility Methods
*/
isSuccess(result) {
return result.status === types_1.RequestStatus.SUCCESS;
}
isError(result) {
return result.status === types_1.RequestStatus.ERROR;
}
extractData(result) {
return this.isSuccess(result) ? result.data : null;
}
extractError(result) {
return this.isError(result)
? { code: result.code, message: result.message, type: result.type }
: null;
}
}
exports.UnifiedApi = UnifiedApi;
/**
* Fluent API Builder
*/
class SafeRequestBuilder {
constructor(requestService, defaultConfig) {
this.config = {};
this.requestService = requestService;
this.defaultConfig = defaultConfig;
}
get(url) {
this.config = { ...this.config, method: "GET", url };
return this;
}
post(url, data) {
this.config = { ...this.config, method: "POST", url, data };
return this;
}
put(url, data) {
this.config = { ...this.config, method: "PUT", url, data };
return this;
}
patch(url, data) {
this.config = { ...this.config, method: "PATCH", url, data };
return this;
}
delete(url) {
this.config = { ...this.config, method: "DELETE", url };
return this;
}
guard(guardFn) {
const newBuilder = this;
newBuilder.config.guard = guardFn;
return newBuilder;
}
tolerance(enabled = true) {
this.config.tolerance = enabled;
return this;
}
identifier(id) {
this.config.identifier = id;
return this;
}
timeout(ms) {
this.config.timeout = ms;
return this;
}
headers(headers) {
this.config.headers = { ...this.config.headers, ...headers };
return this;
}
retry(config) {
this.config.retry = config;
return this;
}
async execute() {
if (!this.config.guard) {
throw new Error("Guard function is required. Use .guard() method to set it.");
}
const fullConfig = {
...this.defaultConfig,
...this.config,
headers: this.config.headers
? {
...this.defaultConfig.headers,
...this.config.headers,
}
: this.defaultConfig.headers,
};
return this.requestService.executeRequest(fullConfig);
}
}
/**
* Safe API Context
*/
class SafeApiContext {
constructor(requestService, defaultConfig) {
this.requestService = requestService;
this.defaultConfig = defaultConfig;
}
async get(url, config) {
const fullConfig = {
...this.defaultConfig,
...config,
url,
method: "GET",
};
return this.requestService.executeRequest(fullConfig);
}
async post(url, data, config) {
const fullConfig = {
...this.defaultConfig,
...config,
url,
method: "POST",
data,
};
return this.requestService.executeRequest(fullConfig);
}
async put(url, data, config) {
const fullConfig = {
...this.defaultConfig,
...config,
url,
method: "PUT",
data,
};
return this.requestService.executeRequest(fullConfig);
}
async patch(url, data, config) {
const fullConfig = {
...this.defaultConfig,
...config,
url,
method: "PATCH",
data,
};
return this.requestService.executeRequest(fullConfig);
}
async delete(url, config) {
const fullConfig = {
...this.defaultConfig,
...config,
url,
method: "DELETE",
};
return this.requestService.executeRequest(fullConfig);
}
}
/**
* Factory Functions for Easy Usage
*/
function createUnifiedApi(config) {
return new UnifiedApi(config);
}
function createSafeGet(guard, config) {
const api = new UnifiedApi(config);
return api.createSafeGet(guard);
}
function createSafePost(guard, config) {
const api = new UnifiedApi(config);
return api.createSafePost(guard);
}
function createSafePut(guard, config) {
const api = new UnifiedApi(config);
return api.createSafePut(guard);
}
function createSafePatch(guard, config) {
const api = new UnifiedApi(config);
return api.createSafePatch(guard);
}
function createSafeDelete(guard, config) {
const api = new UnifiedApi(config);
return api.createSafeDelete(guard);
}
//# sourceMappingURL=unified-api.js.map