import { HttpAdapter } from "../adapter";
import { Axios, AxiosRequestConfig } from "axios";
import { HttpConfig } from "../types";
import { AxiosFlags } from "./types";
import { Context } from "@decaf-ts/db-decorators";
import { AxiosFlavour } from "./constants";
/**
* @description Axios implementation of the HTTP adapter
* @summary Concrete implementation of HttpAdapter using Axios as the HTTP client.
* This adapter provides CRUD operations for RESTful APIs using Axios for HTTP requests.
* @template Axios - The Axios client type
* @template AxiosRequestConfig - The Axios request configuration type
* @template AxiosFlags - The flags type extending HttpFlags
* @template Context<AxiosFlags> - The context type for this adapter
* @param {Axios} native - The Axios instance
* @param {HttpConfig} config - Configuration for the HTTP adapter
* @param {string} [alias] - Optional alias for the adapter
* @class
* @example
* ```typescript
* import axios from 'axios';
* import { AxiosHttpAdapter } from '@decaf-ts/for-http';
*
* const config = { protocol: 'https', host: 'api.example.com' };
* const adapter = new AxiosHttpAdapter(axios.create(), config);
*
* // Use the adapter with a repository
* const userRepo = adapter.getRepository(User);
* const user = await userRepo.findById('123');
* ```
* @mermaid
* sequenceDiagram
* participant Client
* participant AxiosHttpAdapter
* participant Axios
* participant API
*
* Client->>AxiosHttpAdapter: create(table, id, data)
* AxiosHttpAdapter->>AxiosHttpAdapter: url(table)
* AxiosHttpAdapter->>Axios: post(url, data)
* Axios->>API: HTTP POST Request
* API-->>Axios: Response
* Axios-->>AxiosHttpAdapter: Response Data
* AxiosHttpAdapter-->>Client: Created Resource
*
* Client->>AxiosHttpAdapter: read(table, id)
* AxiosHttpAdapter->>AxiosHttpAdapter: url(table, {id})
* AxiosHttpAdapter->>Axios: get(url)
* Axios->>API: HTTP GET Request
* API-->>Axios: Response
* Axios-->>AxiosHttpAdapter: Response Data
* AxiosHttpAdapter-->>Client: Resource Data
*/
export class AxiosHttpAdapter extends HttpAdapter<
Axios,
AxiosRequestConfig,
AxiosFlags,
Context<AxiosFlags>
> {
constructor(native: Axios, config: HttpConfig, alias?: string) {
super(native as any, config, AxiosFlavour, alias);
}
/**
* @description Sends an HTTP request using Axios
* @summary Implementation of the abstract request method from HttpAdapter.
* This method uses the Axios instance to send HTTP requests with the provided configuration.
* @template V - The response value type
* @param {AxiosRequestConfig} details - The Axios request configuration
* @return {Promise<V>} A promise that resolves with the response data
*/
override async request<V>(details: AxiosRequestConfig): Promise<V> {
return this.native.request(details);
}
/**
* @description Creates a new resource via HTTP POST
* @summary Implementation of the abstract create method from HttpAdapter.
* This method sends a POST request to the specified endpoint with the model data.
* @param {string} tableName - The name of the table or endpoint
* @param {string|number} id - The identifier for the resource (not used in URL for POST)
* @param {Record<string, any>} model - The data model to create
* @return {Promise<Record<string, any>>} A promise that resolves with the created resource
*/
async create(
tableName: string,
id: string | number,
model: Record<string, any>
): Promise<Record<string, any>> {
try {
const url = this.url(tableName);
return this.native.post(url, model);
} catch (e: any) {
throw this.parseError(e);
}
}
/**
* @description Retrieves a resource by ID via HTTP GET
* @summary Implementation of the abstract read method from HttpAdapter.
* This method sends a GET request to the specified endpoint with the ID as a query parameter.
* @param {string} tableName - The name of the table or endpoint
* @param {string|number|bigint} id - The identifier for the resource to retrieve
* @return {Promise<Record<string, any>>} A promise that resolves with the retrieved resource
*/
async read(
tableName: string,
id: string | number | bigint
): Promise<Record<string, any>> {
try {
const url = this.url(tableName, { id: id as string | number });
return this.native.get(url);
} catch (e: any) {
throw this.parseError(e);
}
}
/**
* @description Updates an existing resource via HTTP PUT
* @summary Implementation of the abstract update method from HttpAdapter.
* This method sends a PUT request to the specified endpoint with the updated model data.
* @param {string} tableName - The name of the table or endpoint
* @param {string|number} id - The identifier for the resource (not used in URL for PUT)
* @param {Record<string, any>} model - The updated data model
* @return {Promise<Record<string, any>>} A promise that resolves with the updated resource
*/
async update(
tableName: string,
id: string | number,
model: Record<string, any>
): Promise<Record<string, any>> {
try {
const url = this.url(tableName);
return this.native.put(url, model);
} catch (e: any) {
throw this.parseError(e);
}
}
/**
* @description Deletes a resource by ID via HTTP DELETE
* @summary Implementation of the abstract delete method from HttpAdapter.
* This method sends a DELETE request to the specified endpoint with the ID as a query parameter.
* @param {string} tableName - The name of the table or endpoint
* @param {string|number|bigint} id - The identifier for the resource to delete
* @return {Promise<Record<string, any>>} A promise that resolves with the deletion result
*/
async delete(
tableName: string,
id: string | number | bigint
): Promise<Record<string, any>> {
try {
const url = this.url(tableName, { id: id as string | number });
return this.native.delete(url);
} catch (e: any) {
throw this.parseError(e);
}
}
/**
* @description Static decoration method for the AxiosHttpAdapter class
* @summary Placeholder method for class decoration functionality.
* This method is currently empty but can be used for decorator-based configuration.
*/
static decoration() {}
}
Source