import Foundation public struct TeoError: Error, LocalizedError, Decodable { public let type: String public let message: String public let errors: Dictionary? } public struct AnyCodable: Codable { public init(from: any Decoder) throws { fatalError() } public init(value: any Codable) { self.value = value } static func fromValue(_ value: Codable?) -> Self? { if let value { return Self(value: value) } else { return nil } } let value: any Codable public func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() try! container.encode(value) } } public struct Null: Codable { fileprivate init() { } public func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() try container.encodeNil() } } public let null = Null() struct FormRequestBuilder { private let boundary: String = UUID().uuidString var httpBody = Data() mutating func addTextField(named name: String, value: String) { httpBody.append(textFormField(named: name, value: value).data(using: .utf8)!) } private func textFormField(named name: String, value: String) -> String { var fieldString = "--\(boundary)\r\n" fieldString += "Content-Disposition: form-data; name=\"\(name)\"\r\n" fieldString += "Content-Type: text/plain; charset=utf8\r\n" fieldString += "Content-Transfer-Encoding: 8bit\r\n" fieldString += "\r\n" fieldString += "\(value)\r\n" return fieldString } mutating func addDataField(named name: String, filename: String, data: Data, mimeType: String? = nil) { httpBody.append(dataFormField(named: name, filename: filename, data: data, mimeType: mimeType)) } private func dataFormField(named name: String, filename: String, data: Data, mimeType: String? = nil) -> Data { var fieldData = Data() fieldData.append("--\(boundary)\r\n".data(using: .utf8)!) fieldData.append("Content-Disposition: form-data; name=\"\(name)\"; filename=\"\(filename)\"\r\n".data(using: .utf8)!) if let mimeType { fieldData.append("Content-Type: \(mimeType)\r\n".data(using: .utf8)!) } fieldData.append("\r\n".data(using: .utf8)!) fieldData.append(data) fieldData.append("\r\n".data(using: .utf8)!) return fieldData as Data } } public struct File { public let url: URL } private func formRequest(_ method: String, _ path: String, _ input: Dictionary, _ headers: Dictionary? = nil, _ query: String? = nil) async -> O { let url = URL(string: {{ conf.host.to_host_string() }} + path)! var request = URLRequest(url: url) if let headers { headers.forEach { (key, value) in request.setValue(value, forHTTPHeaderField: key) } } request.httpMethod = method var builder = FormRequestBuilder() input.forEach { (key, value) in if let value = value as? String { builder.addTextField(named: key, value: value) } else if let value = value as? File { builder.addDataField(named: key, filename: value.url.lastPathComponent, data: try! Data(contentsOf: value.url), mimeType: nil) } } request.httpBody = builder.httpBody let (data, response) = try! await URLSession.shared.data(for: request) guard response is HTTPURLResponse else { fatalError("response format is unexpected") } return try! JSONDecoder().decode(O.self, from: data) } private func jsonRequest(_ method: String, _ path: String, _ input: I, _ headers: Dictionary? = nil, _ query: String? = nil) async -> O { let url = URL(string: {{ conf.host.to_host_string() }} + path)! var request = URLRequest(url: url) request.setValue("application/json", forHTTPHeaderField: "content-type") if let headers { headers.forEach { (key, value) in request.setValue(value, forHTTPHeaderField: key) } } request.httpMethod = method request.httpBody = try! JSONEncoder().encode(input) let (data, response) = try! await URLSession.shared.data(for: request) guard response is HTTPURLResponse else { fatalError("response format is unexpected") } return try! JSONDecoder().decode(O.self, from: data) } {{ render_namespace(namespace, conf, namespace) }} public let {{ conf.object_name }} = {{ conf.object_name|capitalize_first }}()