{"version":3,"file":"index.d.ts","sources":["../src/interfaces/i-executable.ts","../src/interfaces/i-hook-result.ts","../src/interfaces/i-key-value.ts","../src/enums/e-http-method.ts","../src/lib/http/base-request.builder.ts","../src/interfaces/i-request.builder.ts","../src/request.ts"],"sourcesContent":["export interface IExecutable<TRes> {\n  execute(data?: unknown): Promise<TRes>;\n\n  abort(): void;\n}\n","export interface IHookResult {\n  retry: boolean;\n}\n","export interface IKeyValue<TKey = string, TValue = string> {\n  key: TKey;\n  value: TValue;\n}\n","export enum EHttpMethod {\n  Get = 'GET',\n  Delete = 'DELETE',\n  Head = 'HEAD',\n  Options = 'OPTIONS',\n  Post = 'POST',\n  Put = 'PUT',\n  Patch = 'PATCH',\n  Link = 'LINK',\n  Unlink = 'UNLINK',\n}\n","import {\n  CONTENT_TYPE,\n  EMPTY_STR,\n  INVALID_HEADERS_FORMAT_ERROR,\n  INVALID_NAME_TYPE_ERROR,\n  INVALID_PARAMS_FORMAT_ERROR,\n} from '../../constants';\nimport { EHttpMethod } from '../../enums';\nimport { TypeMismatchException } from '../../exceptions';\nimport { IExecutable, IHookResult, IKeyValue, IRequestBuilder } from '../../interfaces';\nimport { filter, first, isArray, isEmpty, isNil, isNilOrEmpty, isObject, map } from '../../utils';\nimport { AxiosError, AxiosInstance, AxiosResponse } from '../axios';\n\nexport abstract class BaseRequestBuilder implements IRequestBuilder {\n  protected url: string;\n  protected endpoint: string;\n  protected method: EHttpMethod;\n  protected headers: Map<string, string>;\n  protected params: Map<string, string>;\n  protected query: Map<string, string | string[]>;\n  protected body: unknown;\n  protected successHooks: ((\n    response: AxiosResponse,\n    builder: IRequestBuilder,\n  ) => Promise<IHookResult>)[];\n  protected errorHooks: ((\n    error: AxiosError,\n    builder: IRequestBuilder,\n    nextRetry?: boolean,\n  ) => Promise<IHookResult>)[];\n\n  constructor(url?: string) {\n    this.initialize();\n    this.url = url ?? null;\n  }\n\n  public getUrl(): string {\n    return this.url;\n  }\n\n  public setUrl(url: string): IRequestBuilder {\n    this.url = url;\n    return this;\n  }\n\n  public getEndpoint(): string {\n    return this.endpoint;\n  }\n\n  public setEndpoint(endpoint: string): IRequestBuilder {\n    this.endpoint = endpoint;\n    return this;\n  }\n\n  public getMethod(): EHttpMethod {\n    return this.method;\n  }\n\n  public setMethod(method: EHttpMethod): IRequestBuilder {\n    this.method = method;\n    return this;\n  }\n\n  public getContentType(): string {\n    return this.headers.get(CONTENT_TYPE);\n  }\n\n  public setContentType(mimeType: string): IRequestBuilder {\n    this.headers.set(CONTENT_TYPE, mimeType);\n    return this;\n  }\n\n  public getHeader(name: string): string {\n    return this.headers.get(name.toLowerCase());\n  }\n\n  public hasHeader(name: string): boolean {\n    return this.headers.has(name.toLowerCase());\n  }\n\n  public addHeader(name: string, value: string | number | boolean): IRequestBuilder;\n  public addHeader(name: string, value: Date, formatter?: (date: Date) => string): IRequestBuilder;\n  public addHeader(header: IKeyValue): IRequestBuilder;\n  public addHeader(\n    name: unknown,\n    value?: unknown,\n    formatter?: (date: Date) => string,\n  ): IRequestBuilder {\n    if (isObject(name)) {\n      const { key, value } = name as unknown as IKeyValue;\n      this.headers.set(key.toLowerCase(), value);\n      return this;\n    }\n    if (typeof name !== 'string') {\n      throw new TypeMismatchException(INVALID_NAME_TYPE_ERROR);\n    }\n    this.headers.set(name.toLowerCase(), this.normalizeValue(value, formatter) as string);\n    return this;\n  }\n\n  public removeHeader(name: string): IRequestBuilder;\n  public removeHeader(header: IKeyValue): IRequestBuilder;\n  public removeHeader(header: unknown): IRequestBuilder {\n    if (isObject(header)) {\n      this.headers.delete((header as unknown as IKeyValue).key.toLowerCase());\n    }\n    this.headers.delete((header as string).toLowerCase());\n    return this;\n  }\n\n  public setHeaders(headers: IKeyValue[]): IRequestBuilder;\n  public setHeaders(headers: Map<string, string>): IRequestBuilder;\n  public setHeaders(headers: Record<string, string>): IRequestBuilder;\n  public setHeaders(headers: unknown): IRequestBuilder {\n    if (isArray(headers)) {\n      for (const { key, value } of headers as IKeyValue[]) {\n        this.headers.set(key.toLowerCase(), value.toString());\n      }\n      return this;\n    }\n    if (headers instanceof Map) {\n      for (const [key, value] of headers) {\n        this.headers.set(key.toLowerCase(), value.toString());\n      }\n      return this;\n    }\n    if (isObject(headers)) {\n      for (const key in headers as Record<string, string>) {\n        const value = headers[key];\n        this.headers.set(key.toLowerCase(), value.toString());\n      }\n      return this;\n    }\n    throw new TypeMismatchException(INVALID_HEADERS_FORMAT_ERROR);\n  }\n\n  public getParam(name: string): string {\n    return this.params.get(name);\n  }\n\n  public hasParam(name: string): boolean {\n    return this.params.has(name);\n  }\n\n  // really ? do devs actually need it ???\n  public addParam(name: string, value: string | number | boolean): IRequestBuilder;\n  public addParam(name: string, date: Date, formatter?: (date: Date) => string): IRequestBuilder;\n  public addParam(param: IKeyValue): IRequestBuilder;\n  public addParam(\n    name: unknown,\n    value?: unknown,\n    formatter?: (date: Date) => string,\n  ): IRequestBuilder {\n    if (isObject(name)) {\n      const { key, value } = name as unknown as IKeyValue;\n      this.params.set(key, value);\n      return this;\n    }\n    if (typeof name !== 'string') {\n      throw new TypeMismatchException(INVALID_NAME_TYPE_ERROR);\n    }\n    this.params.set(name, this.normalizeValue(value, formatter) as string);\n    return this;\n  }\n\n  public removeParam(name: string): IRequestBuilder;\n  public removeParam(param: IKeyValue): IRequestBuilder;\n  public removeParam(param: unknown): IRequestBuilder {\n    if (isObject(param)) {\n      this.params.delete((param as unknown as IKeyValue).key);\n    }\n    this.params.delete(param as string);\n    return this;\n  }\n\n  public setParams(params: IKeyValue[]): IRequestBuilder;\n  public setParams(params: Map<string, string>): IRequestBuilder;\n  public setParams(params: Record<string, string>): IRequestBuilder;\n  public setParams(params: unknown): IRequestBuilder {\n    if (isArray(params)) {\n      for (const { key, value } of params as IKeyValue[]) {\n        this.params.set(key, value.toString());\n      }\n      return this;\n    }\n    if (params instanceof Map) {\n      for (const [key, value] of params) {\n        this.params.set(key, value.toString());\n      }\n      return this;\n    }\n    if (isObject(params)) {\n      for (const key in params as Record<string, string>) {\n        const value = params[key];\n        this.params.set(key, value.toString());\n      }\n      return this;\n    }\n    throw new TypeMismatchException(INVALID_PARAMS_FORMAT_ERROR);\n  }\n\n  public getQueryParam(name: string): string | string[] {\n    return this.query.get(name);\n  }\n\n  public hasQueryParam(name: string): boolean {\n    return !isNilOrEmpty(this.query.get(name));\n  }\n\n  public addQueryParam(\n    name: string,\n    value: string | number | boolean | string[] | number[] | boolean[],\n  ): IRequestBuilder;\n  public addQueryParam(\n    name: string,\n    value: Date | Date[],\n    formatter?: (date: Date) => string,\n  ): IRequestBuilder;\n  public addQueryParam(qp: IKeyValue<string, string | string[]>);\n  public addQueryParam(\n    name: unknown,\n    value?: unknown,\n    formatter?: (date: Date) => string,\n  ): IRequestBuilder {\n    if (isObject(name) && !isArray(name)) {\n      const { key, value } = name as unknown as IKeyValue;\n      const record = this.query.get(key);\n      this.query.set(key, this.updatedValue(record, value));\n      return this;\n    }\n    if (typeof name !== 'string') {\n      throw new TypeMismatchException(INVALID_NAME_TYPE_ERROR);\n    }\n\n    const record = this.query.get(name);\n    this.query.set(name, this.updatedValue(record, value, formatter));\n    return this;\n  }\n\n  public removeQueryParam(name: string): IRequestBuilder;\n  public removeQueryParam(qp: IKeyValue<string, string | string[]>): IRequestBuilder;\n  public removeQueryParam(name: unknown): IRequestBuilder {\n    if (isObject(name)) {\n      this.query.delete((name as unknown as IKeyValue).key);\n    }\n    this.query.delete(name as string);\n    return this;\n  }\n\n  public setQueryParams(params: IKeyValue<string, string | string[]>[]): IRequestBuilder;\n  public setQueryParams(params: Map<string, string | string[]>): IRequestBuilder;\n  public setQueryParams(params: Record<string, string | string[]>);\n  public setQueryParams(params: unknown): IRequestBuilder {\n    if (isArray(params)) {\n      for (const { key, value } of params as IKeyValue[]) {\n        this.query.set(key, value);\n      }\n      return this;\n    }\n    if (params instanceof Map) {\n      for (const [key, value] of params) {\n        this.query.set(key, value);\n      }\n      return this;\n    }\n    if (isObject(params)) {\n      for (const key in params as Record<string, string>) {\n        const value = params[key] as string;\n        this.query.set(key, value);\n      }\n      return this;\n    }\n    throw new TypeMismatchException(INVALID_PARAMS_FORMAT_ERROR);\n  }\n\n  public getBody<TBody>(): TBody {\n    return this.body as TBody;\n  }\n\n  public hasBody(): boolean {\n    return !isNilOrEmpty(this.body);\n  }\n\n  public setBody<TBody>(body: TBody): IRequestBuilder {\n    this.body = body;\n    return this;\n  }\n\n  public addOnSuccessHook(\n    fn: (response: AxiosResponse, builder?: IRequestBuilder) => Promise<IHookResult>,\n  ): IRequestBuilder {\n    this.successHooks.push(fn);\n    return this;\n  }\n\n  // TODO: use better approach for retry logic :3\n  public addOnErrorHook(\n    fn: (error: AxiosError, builder: IRequestBuilder, nextRetry?: boolean) => Promise<IHookResult>,\n  ): IRequestBuilder {\n    this.errorHooks.push(fn);\n    return this;\n  }\n\n  public abstract build<TRes = unknown>(): IExecutable<TRes>;\n  public abstract getInstance(): AxiosInstance;\n\n  protected initialize(): void {\n    this.url = null;\n    this.endpoint = EMPTY_STR;\n    this.headers = new Map<string, string>();\n    this.method = EHttpMethod.Get;\n    this.params = new Map<string, string>();\n    this.query = new Map<string, string[]>();\n    this.body = null;\n    this.successHooks = [];\n    this.errorHooks = [];\n  }\n\n  private normalizeValue(value: unknown, formatter?: (date: Date) => string): string | string[] {\n    if (value instanceof Date || (isArray(value) && first(value) instanceof Date)) {\n      formatter = formatter ?? ((date: Date): string => date.toISOString());\n      return isArray(value) ? map(value as Date[], formatter) : formatter(value);\n    }\n    if (isArray(value)) {\n      const arr = filter(\n        map(value, (v) => (!isNil(v) ? v.toString() : v)),\n        (v) => !isNil(v),\n      );\n      return isEmpty(arr) ? null : arr;\n    }\n    if (!isNilOrEmpty(value)) {\n      return value.toString();\n    }\n    return null;\n  }\n\n  private updatedValue(\n    oldValue: string | string[],\n    newValue: unknown,\n    formatter?: (date: Date) => string,\n  ): string | string[] {\n    const value: string | string[] = this.normalizeValue(newValue, formatter);\n    if (isArray(oldValue)) {\n      return isArray(value) ? [...oldValue, ...value] : [...oldValue, value];\n    } else if (!isNil(oldValue)) {\n      return isArray(value) ? [oldValue, ...value] : [oldValue, value];\n    }\n    return value;\n  }\n}\n","import { EHttpMethod } from '../enums';\nimport { AxiosError, AxiosInstance, AxiosResponse } from '../lib';\nimport { IExecutable } from './i-executable';\nimport { IHookResult } from './i-hook-result';\nimport { IKeyValue } from './i-key-value';\n\nexport interface IRequestBuilder {\n  /**\n   * Gets the current base URL of the request.\n   *\n   * @returns {string} The base URL of the request.\n   */\n  getUrl(): string;\n\n  /**\n   * Sets the base URL for the request.\n   *\n   * @param {string} url - The base URL to set.\n   * @returns {IRequestBuilder} The current instance of the request builder for chaining.\n   */\n  setUrl(url: string): IRequestBuilder;\n\n  /**\n   * Gets the current endpoint appended to the base URL.\n   *\n   * @returns {string} The endpoint of the request.\n   */\n  getEndpoint(): string;\n\n  /**\n   * Sets the endpoint to be appended to the base URL.\n   *\n   * @param {string} endpoint - The endpoint to set.\n   * @returns {IRequestBuilder} The current instance of the request builder for chaining.\n   */\n  setEndpoint(endpoint: string): IRequestBuilder;\n\n  /**\n   * Gets the HTTP method (e.g., GET, POST) of the request.\n   *\n   * @returns {EHttpMethod} The HTTP method of the request.\n   */\n  getMethod(): EHttpMethod;\n\n  /**\n   * Sets the HTTP method (e.g., GET, POST) for the request.\n   *\n   * @param {EHttpMethod} method - The HTTP method to set.\n   * @returns {IRequestBuilder} The current instance of the request builder for chaining.\n   */\n  setMethod(method: EHttpMethod): IRequestBuilder;\n\n  /**\n   * Gets the Content-Type header value of the request.\n   *\n   * @returns {string} The Content-Type header value, or null if not set.\n   */\n  getContentType(): string;\n\n  /**\n   * Sets the Content-Type header for the request.\n   *\n   * @param {string} mimeType - The MIME type to set as Content-Type header value.\n   * @returns {IRequestBuilder} The current instance of the request builder for chaining.\n   */\n  setContentType(mimeType: string): IRequestBuilder;\n\n  /**\n   * Retrieves a specific header by name from the request headers.\n   *\n   * @param {string} name - The name of the header to retrieve.\n   * @returns {string} The value of the specified header.\n   */\n  getHeader(name: string): string;\n\n  /**\n   * Checks if a specific header exists in the request headers.\n   *\n   * @param {string} name - The name of the header to check for existence.\n   * @returns {boolean} True if the header exists, false otherwise.\n   */\n  hasHeader(name: string): boolean;\n\n  /**\n   * Adds a new header or updates an existing one in the request headers.\n   *\n   * @param {string} name - Header key.\n   * @param {string | number | boolean } value - Header value.\n   * @returns {IRequestBuilder} The current instance of the builder for chaining.\n   */\n  addHeader(name: string, value: string | number | boolean): IRequestBuilder;\n\n  /**\n   * Adds a new header or updates an existing one in the request headers.\n   *\n   * @param {string} name - Header key.\n   * @param {Date} value - Header value (Date).\n   * @param {(date: Date) => string} [formatter] - Formatter function for date values. Optional if not a date value.\n   * @returns {IRequestBuilder} The current instance of the builder for chaining.\n   */\n  addHeader(name: string, value: Date, formatter?: (date: Date) => string): IRequestBuilder;\n\n  /**\n   * Adds a new header or updates an existing one in the request headers.\n   *\n   * @param {IKeyValue} header - Header key-value pair object.\n   * @returns {IRequestBuilder} The current instance of the builder for chaining.\n   */\n  addHeader(header: IKeyValue): IRequestBuilder;\n\n  /**\n   * Removes a specific header from the request headers.\n   * @param {string} name - Header key\n   * @returns {IRequestBuilder}\n   */\n  removeHeader(name: string): IRequestBuilder;\n\n  /**\n   * Removes a specific header from the request headers.\n   * @param {IKeyValue} header - Header object\n   * @returns {IRequestBuilder}\n   */\n  removeHeader(header: IKeyValue): IRequestBuilder;\n\n  /**\n   * Sets multiple headers at once using an array.\n   * @param {IKeyValue[]} headers - An array of key-value pairs.\n   * @returns {IRequestBuilder}\n   */\n  setHeaders(headers: IKeyValue[]): IRequestBuilder;\n\n  /**\n   * Sets multiple headers at once using a Map.\n   * @param {Map<string, string>} headers - A Map of headers.\n   * @returns {IRequestBuilder}\n   */\n  setHeaders(headers: Map<string, string>): IRequestBuilder;\n  setHeaders(headers: Record<string, string>): IRequestBuilder;\n\n  /**\n   * Gets a parameter value by name.\n   * @param {string} name - Parameter name.\n   * @returns {string}\n   */\n  getParam(name: string): string;\n\n  /**\n   * Checks if the param exists\n   * @param {string} name - param name\n   * @returns {boolean}\n   */\n  hasParam(name: string): boolean;\n\n  /**\n   * Adds a param to the params map.\n   * @param {string} name - The name of the param\n   * @param {string | number | boolean} value - The value of the param\n   * @returns {IRequestBuilder}\n   */\n  addParam(name: string, value: string | number | boolean): IRequestBuilder;\n\n  /**\n   * Adds a date param to the params map.\n   * @param {string} name - The name of the param\n   * @param {Date} value - The value of the param\n   * @param {(date: Date) => string} [formatter] - Formatter function for date values. Optional if not a date value.\n   * @returns {IRequestBuilder}\n   */\n  addParam(name: string, date: Date, formatter?: (date: Date) => string): IRequestBuilder;\n\n  /**\n   * Adds a param to the params map.\n   * @param {IKeyValue} param - Object that contains key value for the param\n   * @returns {IRequestBuilder}\n   */\n  addParam(param: IKeyValue): IRequestBuilder;\n\n  /**\n   * Removes a param from the params map.\n   * @param {string} name - The name of the param to be removed\n   * @returns {IRequestBuilder}\n   */\n  removeParam(name: string): IRequestBuilder;\n\n  /**\n   * Removes a param from the params map.\n   * @param {IKeyValue} param - Object that contains key value for the param\n   * @returns {IRequestBuilder}\n   */\n  removeParam(param: IKeyValue): IRequestBuilder;\n\n  /**\n   * Sets params to the params map.\n   * @param {IKeyValue[]} params - Array of key value pairs for the params\n   * @returns {IRequestBuilder}\n   */\n  setParams(params: IKeyValue[]): IRequestBuilder;\n\n  /**\n   * Sets params to the params map.\n   * @param {Map<string, string>} params - Map of key value pairs for the params\n   * @returns {IRequestBuilder}\n   */\n  setParams(params: Map<string, string>): IRequestBuilder;\n\n  /**\n   * Sets params to the params map.\n   * @param {Record<string, string>} params - Record of key value pairs for the params\n   * @returns {IRequestBuilder}\n   */\n  setParams(params: Record<string, string>): IRequestBuilder;\n\n  /**\n   * Get query param\n   * @param {string} name - query param name\n   * @returns {string | string[]}\n   */\n  getQueryParam(name: string): string | string[];\n\n  /**\n   * Checks if the query param exists\n   * @param {string} name - query param name\n   * @returns {boolean}\n   */\n  hasQueryParam(name: string): boolean;\n\n  /**\n   * Adds query param\n   * @param {string} name - the name of the query param\n   * @param {string | number | boolean | string[] | number[] | boolean[]} value - the value of the query param\n   * @returns {IRequestBuilder}\n   */\n  addQueryParam(\n    name: string,\n    value: string | number | boolean | string[] | number[] | boolean[],\n  ): IRequestBuilder;\n\n  /**\n   * Adds query param\n   * @param {string} name - the name of the query param\n   * @param {Date | Date[]} value - the value of the query param\n   * @param {(date: Date) => string} [formatter] - Formatter function for date values. Optional if not a date value.\n   * @returns {IRequestBuilder}\n   */\n  addQueryParam(\n    name: string,\n    value: Date | Date[],\n    formatter?: (date: Date) => string,\n  ): IRequestBuilder;\n\n  /**\n   * Adds query param\n   * @param {IKeyValue} qp - Object that contains key value for the query param\n   * @returns {IRequestBuilder}\n   */\n  addQueryParam(qp: IKeyValue<string, string | string[]>);\n\n  /**\n   * Removes query param\n   * @param {string} name - the name of the query param\n   * @returns {IRequestBuilder}\n   */\n  removeQueryParam(name: string): IRequestBuilder;\n\n  /**\n   * Removes query param\n   * @param {IKeyValue} qp - Object that contains key value for the query param\n   * @returns {IRequestBuilder}\n   */\n  removeQueryParam(qp: IKeyValue<string, string | string[]>): IRequestBuilder;\n\n  /**\n   * Sets query params\n   * @param {IKeyValue[]} params - Array of key value pairs for the query params\n   * @returns {IRequestBuilder}\n   */\n  setQueryParams(params: IKeyValue<string, string | string[]>[]): IRequestBuilder;\n\n  /**\n   * Sets query params\n   * @param {Map<string, string>} params - Map of key value pairs for the query params\n   * @returns {IRequestBuilder}\n   */\n  setQueryParams(params: Map<string, string | string[]>): IRequestBuilder;\n\n  /**\n   * Sets query params\n   * @param {Record<string, string>} params - Record of key value pairs for the query params\n   * @returns {IRequestBuilder}\n   */\n  setQueryParams(params: Record<string, string | string[]>);\n\n  /**\n   * Get the body\n   * @returns {TBody}\n   */\n  getBody<TBody>(): TBody;\n\n  /**\n   * Checks if the body exists\n   * @returns {boolean}\n   */\n  hasBody(): boolean;\n\n  /**\n   * Sets the body to the request\n   * @param {TBody} body - The body\n   * @returns {IRequestBuilder}\n   */\n  setBody<TBody>(body: TBody): IRequestBuilder;\n\n  /**\n   * Adds a success hook to be executed after a successful response is received.\n   *\n   * @param {(response: any, builder: IRequestBuilder) => Promise<any>} fn - A callback function to handle successful responses.\n   * @returns {IRequestBuilder} The current instance of the request builder for chaining.\n   */\n  addOnSuccessHook(\n    fn: (response: AxiosResponse, builder: IRequestBuilder) => IHookResult | Promise<IHookResult>,\n  ): IRequestBuilder;\n\n  /**\n   * Adds an error hook to be executed after an error occurs during a request.\n   *\n   * @param {(error: any, builder: IRequestBuilder, nextRetry?: boolean) => Promise<any>} fn - A callback function to handle errors during requests.\n   * @returns {IRequestBuilder} The current instance of the request builder for chaining.\n   */\n\n  addOnErrorHook(\n    fn: (error: AxiosError, builder: IRequestBuilder, nextRetry?: boolean) => Promise<IHookResult>,\n  ): IRequestBuilder;\n\n  /**\n   * method that builds and returns an executable object for making HTTP requests.\n   *\n   * @returns {IExecutable} An object with an `execute` method to perform the HTTP request.\n   */\n  build<TRes = unknown>(): IExecutable<TRes>;\n\n  /**\n   * Abstract method that retrieves an instance of Axios or another HTTP client. Must be implemented by subclasses.\n   *\n   * @abstract\n   * @returns {AxiosInstance} An instance of Axios or another HTTP client library used for making requests.\n   */\n  getInstance(): AxiosInstance;\n}\n","import { PARAM_PREFIX } from './constants';\nimport { IExecutable } from './interfaces';\nimport { axios, AxiosError, AxiosInstance, AxiosResponse, BaseRequestBuilder } from './lib';\nimport { resolveAllStrict } from './tools';\nimport { isNil, isNilOrEmpty, map, mapToObject } from './utils';\n\nexport class Request extends BaseRequestBuilder {\n  private instance: AxiosInstance;\n  private abortController: AbortController;\n\n  constructor(url?: string, instance?: AxiosInstance) {\n    super(url);\n    this.init(instance);\n  }\n\n  // todo: make retries many times as possible with default configurable max attempts config\n  public build<TRes = unknown>(): IExecutable<TRes> {\n    const execute = async (): Promise<TRes> => {\n      try {\n        const response = await this.createRequestObject();\n\n        if (await this.callSuccessHooks(response)) {\n          return await this.buildAndExecWithoutRetry<TRes>();\n        }\n\n        return response.data as TRes;\n      } catch (ex) {\n        if (await this.callErrorHooks(ex, true)) {\n          return await this.buildAndExecWithoutRetry<TRes>();\n        }\n      }\n    };\n\n    const abort = (): void => {\n      this.abortController.abort();\n    };\n\n    return { execute, abort };\n  }\n\n  //todo: remove this and make `build()` self calling for retry\n  private async buildAndExecWithoutRetry<TRes = unknown>(): Promise<TRes> {\n    let data: unknown = null;\n\n    try {\n      const response = await this.createRequestObject();\n\n      await this.callSuccessHooks(response);\n      data = response.data;\n    } catch (ex) {\n      await this.callErrorHooks(ex, false);\n    }\n    return data as TRes;\n  }\n\n  public getInstance(): AxiosInstance {\n    return this.instance;\n  }\n\n  private init(instance?: AxiosInstance): void {\n    this.instance = instance ?? axios.create();\n    this.abortController = new AbortController();\n  }\n\n  private buildUrl = (): string => {\n    let url = this.url;\n    if (!isNilOrEmpty(this.endpoint)) {\n      url += this.endpoint;\n    }\n    for (const [key, value] of this.params) {\n      url = url.replace(PARAM_PREFIX + key, value);\n    }\n    return url;\n  };\n\n  /**\n   * @returns A Promise boolean or rejects with an Error\n   */\n  private readonly callSuccessHooks = async (response: AxiosResponse): Promise<boolean> => {\n    const sRes = await resolveAllStrict(map(this.successHooks, (fn) => fn(response, this)));\n\n    return sRes.some((res) => !isNil(res) && !!res.retry);\n  };\n\n  /**\n   * @returns A Promise boolean or rejects with an Error\n   */\n  private readonly callErrorHooks = async (\n    error: AxiosError,\n    shouldRetry: boolean,\n  ): Promise<boolean> => {\n    const eRes = await resolveAllStrict(map(this.errorHooks, (fn) => fn(error, this, shouldRetry)));\n\n    return eRes.some((res) => !isNil(res) && res.retry);\n  };\n\n  private readonly buildHeaders = (): Record<string, string> => mapToObject(this.headers);\n\n  private readonly buildQueryParams = (): Record<string, string | string[]> =>\n    mapToObject(this.query);\n\n  private readonly createRequestObject = (): Promise<AxiosResponse> => {\n    return this.instance.request({\n      url: this.buildUrl(),\n      method: this.method.toString(),\n      headers: this.buildHeaders(),\n      params: this.buildQueryParams(),\n      signal: this.abortController.signal,\n      data: this.body ?? undefined,\n    });\n  };\n}\n"],"names":[],"mappings":";;AAAO;AACP;AACA;AACA;;ACHO;AACP;AACA;;ACFO;AACP;AACA;AACA;;ACHO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzDO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChSO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;"}