2023-02-03 00:16:38 -06:00
|
|
|
import { type AxiosResponse } from 'axios';
|
2023-02-16 16:57:52 -06:00
|
|
|
import { type Readable } from 'stream';
|
2023-02-21 13:23:07 -06:00
|
|
|
import { HttpStatusCode } from '../enums/HttpStatusCode.js';
|
|
|
|
|
import { ApiResponse } from './ApiResponse.js';
|
2023-01-27 15:00:34 -06:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @class ApiResponseFactory - Factory class for creating ApiResponse objects
|
|
|
|
|
*/
|
|
|
|
|
export class ApiResponseFactory {
|
|
|
|
|
/**
|
|
|
|
|
* @method getApiResponse - Creates an ApiResponse object from an AxiosResponse object
|
|
|
|
|
* @param {AxiosResponse} response - The AxiosResponse object that will be used to create the ApiResponse object
|
2023-02-16 16:57:52 -06:00
|
|
|
* @returns {Promise<ApiResponse<T>>} - A promise that resolves to an ApiResponse object
|
2023-01-27 15:00:34 -06:00
|
|
|
*/
|
2023-02-16 16:57:52 -06:00
|
|
|
public static async getApiResponse<T>(
|
|
|
|
|
response: AxiosResponse
|
|
|
|
|
): Promise<ApiResponse<T>> {
|
|
|
|
|
const message = await this.TryToGetMessage(response);
|
2023-01-27 18:09:14 -06:00
|
|
|
|
|
|
|
|
if (this.isSuccessStatusCode(response.status) === true) {
|
2023-02-01 21:21:39 -06:00
|
|
|
return new ApiResponse<T>(response.status, message, response.data);
|
2023-01-27 15:00:34 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new ApiResponse<T>(response.status, message, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @method TryToGetMessage - Attempts to get the message from the response data
|
|
|
|
|
* @param {AxiosResponse} response - The AxiosResponse object that will be used to get the message
|
2023-02-16 16:57:52 -06:00
|
|
|
* @returns {Promise<string>} - A promise that resolves to the message
|
2023-01-27 15:00:34 -06:00
|
|
|
*/
|
2023-02-16 16:57:52 -06:00
|
|
|
private static async TryToGetMessage(
|
|
|
|
|
response: AxiosResponse
|
|
|
|
|
): Promise<string> {
|
2023-01-27 15:00:34 -06:00
|
|
|
if (
|
2023-01-27 22:21:38 -06:00
|
|
|
response.status === HttpStatusCode.Unauthorized ||
|
|
|
|
|
response.status === HttpStatusCode.Forbidden ||
|
|
|
|
|
response.status === HttpStatusCode.NotFound
|
2023-01-27 18:09:14 -06:00
|
|
|
) {
|
2023-02-16 16:57:52 -06:00
|
|
|
if (response.config.responseType === 'stream') {
|
|
|
|
|
const dataString = await this.getStreamDataAsString(response.data);
|
|
|
|
|
const dataObject =
|
|
|
|
|
dataString.length > 0 ? JSON.parse(dataString) : '{}';
|
|
|
|
|
return dataObject.message;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-27 15:00:34 -06:00
|
|
|
return response.data?.message;
|
|
|
|
|
}
|
2023-01-27 18:09:14 -06:00
|
|
|
|
|
|
|
|
if (this.isSuccessStatusCode(response.status) === false) {
|
2023-02-16 16:57:52 -06:00
|
|
|
if (response.config.responseType === 'stream') {
|
|
|
|
|
const data = response.data as Readable;
|
|
|
|
|
return await this.getStreamDataAsString(data);
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-27 15:00:34 -06:00
|
|
|
return JSON.stringify(response.data);
|
|
|
|
|
}
|
2023-01-27 18:09:14 -06:00
|
|
|
|
|
|
|
|
return '';
|
2023-01-27 15:00:34 -06:00
|
|
|
}
|
|
|
|
|
|
2023-02-16 16:57:52 -06:00
|
|
|
/**
|
2023-02-20 21:08:22 -06:00
|
|
|
* @method getStreamDataAsString - Gets the data from a stream as a string
|
|
|
|
|
* @param {Readable} stream - The stream that will be used to get the data
|
|
|
|
|
* @returns {Promise<string>} - A promise that resolves to the data from the stream as a string
|
2023-02-16 16:57:52 -06:00
|
|
|
*/
|
|
|
|
|
private static async getStreamDataAsString(
|
|
|
|
|
stream: Readable
|
|
|
|
|
): Promise<string> {
|
|
|
|
|
const chunks = [] as Buffer[];
|
|
|
|
|
|
|
|
|
|
for await (const chunk of stream) {
|
|
|
|
|
chunks.push(chunk);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Buffer.concat(chunks).toString('utf-8');
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-27 15:00:34 -06:00
|
|
|
/**
|
|
|
|
|
* @method isSuccessStatusCode - Determines if the specified status code is a success status code
|
|
|
|
|
* @param {number} statusCode - The status code that will be used to determine if it is a success status code
|
|
|
|
|
* @returns {boolean} - A boolean indicating if the specified status code is a success status code
|
|
|
|
|
*/
|
|
|
|
|
private static isSuccessStatusCode(statusCode: number): boolean {
|
|
|
|
|
return statusCode >= HttpStatusCode.OK && statusCode <= 299;
|
|
|
|
|
}
|
|
|
|
|
}
|