import axios from "axios";
import { z } from "zod";
import { SharedErrorHandler } from "./error-handling.mjs";
class RestClient {
  client;
  errorHandler;
  constructor({
    config,
    interceptors,
    errorHandler
  } = {}) {
    this.client = axios.create(config);
    this.errorHandler = errorHandler ?? SharedErrorHandler;
    this.attachInterceptors(interceptors);
  }
  attachInterceptors(interceptors, ...args) {
    if (interceptors != null) {
      interceptors.forEach((interceptor) => this.attachInterceptor(interceptor, ...args));
    }
  }
  attachInterceptor(interceptor, ...args) {
    interceptor.addInterceptor(this.client, ...args);
  }
  ejectInterceptor(interceptor) {
    interceptor.removeInterceptor(this.client);
  }
  async get(requestInfo, url, requestConfig) {
    return this.makeRequest(requestInfo, { ...requestConfig, method: "get", url });
  }
  async post(requestInfo, url, data, requestConfig) {
    return this.makeRequest(requestInfo, { ...requestConfig, method: "post", url, data });
  }
  async patch(requestInfo, url, data, requestConfig) {
    return this.makeRequest(requestInfo, { ...requestConfig, method: "patch", url, data });
  }
  async put(requestInfo, url, data, requestConfig) {
    return this.makeRequest(requestInfo, { ...requestConfig, method: "put", url, data });
  }
  async delete(requestInfo, url, data, requestConfig) {
    return this.makeRequest(requestInfo, { ...requestConfig, method: "delete", url, data });
  }
  async makeRequest(requestInfo, requestConfig) {
    const errorStack = new Error().stack;
    try {
      const { rawResponse, ...config } = requestConfig;
      const res = await this.client(config);
      const resData = requestInfo.resSchema.parse(res.data);
      return rawResponse ? { ...res, data: resData } : resData;
    } catch (error) {
      if (error instanceof z.ZodError) {
        error.name = "BE Response schema mismatch - ZodError";
        error.stack = [error.stack, ...errorStack?.split("\n").slice(2) ?? []].join("\n");
      }
      const errorHandler = requestInfo.errorHandler ?? this.errorHandler;
      errorHandler.rethrowError(error);
      throw error;
    }
  }
}
export {
  RestClient
};
