@@ -3,10 +3,12 @@ import Foundation
33public struct Client {
44 public let url : URL
55 public var token : String ?
6+ public var headers : [ HTTPHeader ]
67
7- public init ( url: URL , token: String ? = nil ) {
8+ public init ( url: URL , token: String ? = nil , headers : [ HTTPHeader ] = [ ] ) {
89 self . url = url
910 self . token = token
11+ self . headers = headers
1012 }
1113
1214 static let decoder : JSONDecoder = {
@@ -21,20 +23,17 @@ public struct Client {
2123 return enc
2224 } ( )
2325
24- func request < T : Encodable & Sendable > (
25- _ path: String ,
26+ private func doRequest (
27+ path: String ,
2628 method: HTTPMethod ,
27- body: T ? = nil
29+ body: Data ? = nil
2830 ) async throws ( ClientError) -> HTTPResponse {
2931 let url = self . url. appendingPathComponent ( path)
3032 var req = URLRequest ( url: url)
3133 if let token { req. addValue ( token, forHTTPHeaderField: Headers . sessionToken) }
3234 req. httpMethod = method. rawValue
33- do {
34- if let body { req. httpBody = try Client . encoder. encode ( body) }
35- } catch {
36- throw . encodeFailure
37- }
35+ for header in headers { req. addValue ( header. value, forHTTPHeaderField: header. header) }
36+ req. httpBody = body
3837 let data : Data
3938 let resp : URLResponse
4039 do {
@@ -48,25 +47,25 @@ public struct Client {
4847 return HTTPResponse ( resp: httpResponse, data: data, req: req)
4948 }
5049
51- func request(
50+ func request< T : Encodable & Sendable > (
5251 _ path: String ,
53- method: HTTPMethod
52+ method: HTTPMethod ,
53+ body: T
5454 ) async throws ( ClientError) -> HTTPResponse {
55- let url = self . url. appendingPathComponent ( path)
56- var req = URLRequest ( url: url)
57- if let token { req. addValue ( token, forHTTPHeaderField: Headers . sessionToken) }
58- req. httpMethod = method. rawValue
59- let data : Data
60- let resp : URLResponse
55+ let encodedBody : Data ?
6156 do {
62- ( data , resp ) = try await URLSession . shared . data ( for : req )
57+ encodedBody = try Client . encoder . encode ( body )
6358 } catch {
64- throw . network ( error)
59+ throw . encodeFailure ( error)
6560 }
66- guard let httpResponse = resp as? HTTPURLResponse else {
67- throw . unexpectedResponse( data)
68- }
69- return HTTPResponse ( resp: httpResponse, data: data, req: req)
61+ return try await doRequest ( path: path, method: method, body: encodedBody)
62+ }
63+
64+ func request(
65+ _ path: String ,
66+ method: HTTPMethod
67+ ) async throws ( ClientError) -> HTTPResponse {
68+ return try await doRequest ( path: path, method: method)
7069 }
7170
7271 func responseAsError( _ resp: HTTPResponse ) -> ClientError {
@@ -119,7 +118,7 @@ public enum ClientError: Error {
119118 case api( APIError )
120119 case network( any Error )
121120 case unexpectedResponse( Data )
122- case encodeFailure
121+ case encodeFailure( any Error )
123122
124123 public var description : String {
125124 switch self {
@@ -129,8 +128,8 @@ public enum ClientError: Error {
129128 return error. localizedDescription
130129 case let . unexpectedResponse( data) :
131130 return " Unexpected or non HTTP response: \( data) "
132- case . encodeFailure:
133- return " Failed to encode body "
131+ case let . encodeFailure( error ) :
132+ return " Failed to encode body: \( error ) "
134133 }
135134 }
136135}
0 commit comments