@web-bee-ru/openapi-axios
Version:
A TypeScript abstraction over Axios for typed requests generated from OpenAPI (Swagger) schemas using openapi-typescript.
147 lines • 6.08 kB
JavaScript
import { defaultOptions } from "./const/defaultOptions.js";
import {} from "./const/methods.js";
import { interpolateParams } from "./interpolate-params.js";
import { getQuerySerializer } from "./utils/querySerializer.js";
import { convertToAll } from "./utils/response-converters/convertToAll.js";
import { convertToAxios } from "./utils/response-converters/convertToAxios.js";
import { convertToFetch } from "./utils/response-converters/convertToFetch.js";
/**
* @description OpenApiAxios class is a wrapper around Axios that provides methods to handle API requests
* and responses based on OpenAPI specifications.
*
* @template Schema - The OpenAPI schema type.
* @template ClassValidStatus - The type that configures the error handling strategy.
*/
export class OpenApiAxios {
axios;
opt;
/**
* @description Creates an instance of OpenApiAxios.
*
* @param axios - The Axios instance to use for requests.
* @param options - Configuration options for the OpenApiAxios instance.
*/
constructor(axios, options) {
this.axios = axios;
this.opt = Object.assign({}, defaultOptions, options);
}
// HTTP methods without a request body
get = this.factoryWithoutBody("get");
head = this.factoryWithoutBody("head");
delete = this.factoryWithoutBody("delete");
options = this.factoryWithoutBody("options");
// HTTP methods with a request body
put = this.factoryWithBody("put");
post = this.factoryWithBody("post");
patch = this.factoryWithBody("patch");
/**
* @description Generates a URI for a given API endpoint, including query parameters.
*
* @param method - The HTTP method to use.
* @param path - The API route.
* @param options - Additional options for the request.
* @returns The generated URI as a string.
*/
async getUri(method, path, options) {
const { urlString, newOptions } = this.prepareOptions(path, options);
const { paramsSerializer, params, ...axios } = this.optionsToAxiosOptions(newOptions);
// Axios getUri doesn't support serializers
const queryUri = Object.keys(params || {}).length > 0
? `?${paramsSerializer(params)}`
: "";
return this.axios.getUri({
url: `${urlString}${queryUri}`,
method,
...axios,
});
}
/**
* @description Prepares the options and URL for an API request.
*
* @param path - The API route.
* @param options - Additional options for the request.
* @returns An object containing the prepared URL string and new options.
*/
prepareOptions(path, options) {
let urlString = path;
// Assign ValidStatus from class if not provided in request options
const newOptions = Object.assign({}, options, {
validStatus: this.opt.validStatus,
});
// Create URL by interpolating parameters based on the OpenAPI pattern
// @ts-expect-error; @TODO See issue #2 - https://github.com/web-bee-ru/openapi-axios/issues/2
if (newOptions?.params)
urlString = interpolateParams(urlString,
// @ts-expect-error; @TODO See issue #2 - https://github.com/web-bee-ru/openapi-axios/issues/2
newOptions.params);
// Assign query serializer to Axios
const querySerializationParams = options?.querySerializationParams || this.opt.querySerializationParams;
if (!options?.axios?.paramsSerializer && querySerializationParams) {
newOptions.axios = Object.assign({}, newOptions.axios, {
paramsSerializer: getQuerySerializer(querySerializationParams),
});
}
return {
urlString,
newOptions,
};
}
/**
* @description Prepares the API response based on the valid status type.
*
* @param response - The Axios response promise.
* @param options - Options for the request.
* @returns A promise that resolves to the processed API response.
*/
async prepareResponse(response, options) {
switch (options.validStatus) {
case "all":
return convertToAll(response);
case "fetch":
return convertToFetch(response);
case "axios":
default:
return convertToAxios(response);
}
}
/**
* @description Converts OpenAPI options to Axios request options.
*
* @param options - The options to convert.
* @returns The converted Axios request configuration.
*/
optionsToAxiosOptions(options) {
return {
// @ts-expect-error; @TODO See issue #2 - https://github.com/web-bee-ru/openapi-axios/issues/2
params: options?.query,
...options.axios,
};
}
/**
* @description Creates a fetcher method for HTTP methods that do not have a request body (e.g., GET, DELETE).
*
* @param method - The HTTP method to create a fetcher for.
* @returns A function that performs the API request.
*/
factoryWithoutBody(method) {
return (...args) => {
const [path, options] = args;
const { urlString, newOptions } = this.prepareOptions(path, options);
return this.prepareResponse(this.axios[method](urlString, this.optionsToAxiosOptions(newOptions)), newOptions);
};
}
/**
* @description Creates a fetcher method for HTTP methods that have a request body (e.g., POST, PUT).
*
* @param method - The HTTP method to create a fetcher for.
* @returns A function that performs the API request.
*/
factoryWithBody(method) {
return (...args) => {
const [path, body, options] = args;
const { urlString, newOptions } = this.prepareOptions(path, options);
return this.prepareResponse(this.axios[method](urlString, body, this.optionsToAxiosOptions(newOptions)), newOptions);
};
}
}
//# sourceMappingURL=index.js.map