import Foundation
public struct Request {
public enum Error<ApiError: Decodable & Sendable>: Swift.Error, CustomStringConvertible {
case notHttpResponse
case notFound
case apiError(_ error: ApiError)
case generalError
public var description: String {
switch self {
case .notHttpResponse: "response is not HTTP"
case .notFound: "Not found"
case .apiError(error: let error): "\(error)"
case .generalError: "General error"
}
}
}
struct EmptyError: Decodable {
}
public enum Method: String {
case get = "GET"
case post = "POST"
case put = "PUT"
case delete = "DELETE"
case patch = "PATCH"
}
public struct Config {
let method: Method
let backend: Backend
let path: String
var urlParameters: [String: String] = [:]
var headers: [String: String] = [:]
}
var session = URLSession(configuration: .ephemeral)
func makeURLRequest(config: Config, body: Data?) -> URLRequest {
let urlQuery = urlEncodedQueryString(from: config.urlParameters)
guard let url = URL(string: config.backend.baseURL + config.path + urlQuery) else {
fatalError("Couldn't create a URL")
}
var urlRequest = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData)
urlRequest.httpMethod = config.method.rawValue
urlRequest.httpBody = body
config.headers.forEach {
urlRequest.setValue($0.value, forHTTPHeaderField: $0.key)
}
return urlRequest
}
func urlEncodedQueryString(from query: [String: String]) -> String {
guard !query.isEmpty else { return "" }
var components = URLComponents()
components.queryItems = query.map { URLQueryItem(name: $0.key, value: $0.value) }
let absoluteString = components.url?.absoluteString ?? ""
let plusCorrection = absoluteString.replacingOccurrences(of: "+", with: "%2b")
return plusCorrection
}
}