@@ -21,6 +21,7 @@ open class Client {
21
21
open var headers: [String: String] = [
22
22
"content-type": "",
23
23
"x-sdk-version": "{{spec .title | caseDash }}:{{ language .name | caseLower }}:{{ sdk .version }}"{% if spec .global .defaultHeaders | length > 0 %},{% endif %}
24
+
24
25
{% for key ,header in spec .global .defaultHeaders %}
25
26
"{{key }}": "{{header }}"{% if not loop .last %},{% endif %}
26
27
{% endfor %}
@@ -228,29 +229,17 @@ open class Client {
228
229
headers: [String: String] = [:],
229
230
params: [String: Any?] = [:],
230
231
sink: ((ByteBuffer) -> Void)? = nil,
231
- convert: (([String: Any]) -> T)? = nil,
232
- completion: ((Result<T , {{ spec .title | caseUcfirst }}Error >) -> Void)? = nil
233
- ) {
232
+ convert: (([String: Any]) -> T)? = nil
233
+ ) async throws -> T {
234
234
let validParams = params.filter { $0.value != nil }
235
235
236
236
let queryParameters = method == "GET" && !validParams.isEmpty
237
237
? "?" + parametersToQueryString(params: validParams)
238
238
: ""
239
239
240
- let targetURL = URL(string: endPoint + path + queryParameters)!
240
+ var request = HTTPClientRequest(url: endPoint + path + queryParameters)
241
+ request.method = .RAW(value: method)
241
242
242
- var request: HTTPClient.Request
243
- do {
244
- request = try HTTPClient.Request(
245
- url: targetURL,
246
- method: .RAW(value: method)
247
- )
248
- } catch {
249
- completion?(Result.failure({{ spec .title | caseUcfirst }}Error(
250
- message: error.localizedDescription
251
- )))
252
- return
253
- }
254
243
255
244
for (key, value) in self.headers.merging(headers, uniquingKeysWith: { $1 }) {
256
245
request.headers.add(name: key, value: value)
@@ -259,24 +248,16 @@ open class Client {
259
248
request.addDomainCookies()
260
249
261
250
if "GET" == method {
262
- execute(request, convert: convert, completion: completion)
263
- return
251
+ return try await execute(request, convert: convert)
264
252
}
265
253
266
- do {
267
- try buildBody(for: & request, with: validParams)
268
- } catch let error {
269
- completion?(Result.failure({{ spec .title | caseUcfirst }}Error(
270
- message: error.localizedDescription
271
- )))
272
- return
273
- }
254
+ try buildBody(for: & request, with: validParams)
274
255
275
- execute(request, withSink: sink, convert: convert, completion: completion )
256
+ return try await execute(request, withSink: sink, convert: convert)
276
257
}
277
258
278
259
private func buildBody(
279
- for request: inout HTTPClient.Request ,
260
+ for request: inout HTTPClientRequest ,
280
261
with params: [String: Any?]
281
262
) throws {
282
263
if request.headers["content-type"][0] == "multipart/form-data" {
@@ -287,96 +268,62 @@ open class Client {
287
268
}
288
269
289
270
private func execute<T >(
290
- _ request: HTTPClient.Request ,
271
+ _ request: HTTPClientRequest ,
291
272
withSink bufferSink: ((ByteBuffer) -> Void)? = nil,
292
- convert: (([String: Any]) -> T)? = nil,
293
- completion: ((Result<T , {{ spec .title | caseUcfirst }}Error >) -> Void)? = nil
294
- ) {
295
- if bufferSink == nil {
296
- http.execute(
297
- request: request,
298
- delegate: ResponseAccumulator(request: request)
299
- ).futureResult.whenComplete( { result in
300
- complete(with: result)
301
- })
302
- return
303
- }
304
-
305
- http.execute(
306
- request: request,
307
- delegate: StreamingDelegate(request: request, sink: bufferSink)
308
- ).futureResult.whenComplete { result in
309
- complete(with: result)
310
- }
311
-
312
- func complete(with result: Result<HTTPClient .Response , Swift .Error >) {
313
- guard let completion = completion else {
314
- return
315
- }
316
-
317
- switch result {
318
- case .failure(let error):
319
- completion(.failure({{ spec .title | caseUcfirst }}Error(
320
- message: error.localizedDescription
321
- )))
322
- case .success(var response):
323
- switch response.status.code {
324
- case 0..<400:
325
- if response .cookies .count > 0 {
326
- UserDefaults.standard.set(
327
- try! response.cookies.toJson(),
328
- forKey: "\(response.host)-cookies"
329
- )
330
- }
331
- switch T.self {
332
- case is Bool.Type:
333
- completion(.success(true as! T))
334
- case is ByteBuffer.Type:
335
- completion(.success(response.body! as! T))
336
- default:
337
- if response.body == nil {
338
- completion(.success(true as! T))
339
- return
340
- }
341
- let dict = try! JSONSerialization
342
- .jsonObject(with: response.body!) as? [String: Any]
343
-
344
- completion(.success(convert?(dict!) ?? dict! as! T))
345
- }
346
- default:
347
- var message = ""
348
- var type = ""
349
-
350
- if response.body == nil {
351
- completion(.failure({{ spec .title | caseUcfirst }}Error(
352
- message: "Unknown error with status code \(response.status.code)",
353
- code: Int(response.status.code)
354
- )))
355
- return
356
- }
357
-
358
- do {
359
- let dict = try JSONSerialization
360
- .jsonObject(with: response.body!) as? [String: Any]
361
-
362
- message = dict?["message"] as? String
363
- ?? response.status.reasonPhrase
364
-
365
- type = dict?["type"] as? String ?? ""
366
- } catch {
367
- message = response.body!.readString(length: response.body!.readableBytes)!
368
- }
369
-
370
- let error = {{ spec .title | caseUcfirst }}Error(
371
- message: message,
372
- code: Int(response.status.code),
373
- type: type
273
+ convert: (([String: Any]) -> T)? = nil
274
+ ) async throws -> T {
275
+ func complete(with response: HTTPClientResponse) async throws -> T {
276
+ switch response.status.code {
277
+ case 0..<400:
278
+ if response .headers [" Set-Cookie" ].count > 0 {
279
+ UserDefaults.standard.set(
280
+ response.headers["Set-Cookie"],
281
+ forKey: URL(string: request.url)!.host! + "-cookies"
374
282
)
283
+ }
284
+ switch T.self {
285
+ case is Bool.Type:
286
+ return true as! T
287
+ case is ByteBuffer.Type:
288
+ return response.body as! T
289
+ default:
290
+ let data = try await response.body.collect(upTo: Int.max)
291
+ let dict = try JSONSerialization.jsonObject(with: data) as? [String: Any]
375
292
376
- completion(.failure(error))
293
+ return convert?(dict!) ?? dict! as! T
377
294
}
295
+ default:
296
+ var message = ""
297
+ var data = try await response.body.collect(upTo: Int.max)
298
+
299
+ do {
300
+ let dict = try JSONSerialization.jsonObject(with: data) as? [String: Any]
301
+
302
+ message = dict?["message"] as? String ?? response.status.reasonPhrase
303
+ } catch {
304
+ message = data.readString(length: data.readableBytes)!
305
+ }
306
+
307
+ throw {{ spec .title | caseUcfirst }}Error(
308
+ message: message,
309
+ code: Int(response.status.code)
310
+ )
378
311
}
379
312
}
313
+
314
+ if bufferSink == nil {
315
+ let response = try await http.execute(
316
+ request,
317
+ timeout: .seconds(30)
318
+ )
319
+ return try await complete(with: response)
320
+ }
321
+
322
+ let response = try await http.execute(
323
+ request,
324
+ timeout: .seconds(30)
325
+ )
326
+ return try await complete(with: response)
380
327
}
381
328
382
329
func chunkedUpload<T >(
@@ -385,60 +332,43 @@ open class Client {
385
332
params: inout [String: Any?],
386
333
paramName: String,
387
334
convert: (([String: Any]) -> T)? = nil,
388
- onProgress: ((UploadProgress) -> Void)? = nil,
389
- completion: ((Result<T , {{ spec .title | caseUcfirst }}Error >) -> Void)? = nil
390
- ) {
335
+ onProgress: ((UploadProgress) -> Void)? = nil
336
+ ) async throws -> T {
391
337
let file = params[paramName] as! File
392
338
let size = file.buffer.readableBytes
393
339
394
340
if size < Client.chunkSize {
395
- call(
341
+ return try await call(
396
342
method: "POST",
397
343
path: path,
398
344
headers: headers,
399
345
params: params,
400
- convert: convert,
401
- completion: completion
346
+ convert: convert
402
347
)
403
- return
404
348
}
405
349
406
350
var input = file.buffer
407
351
var offset = 0
408
352
var result = [String:Any]()
409
- let group = DispatchGroup()
410
353
411
354
while offset < size {
412
355
let slice = input.readSlice(length: Client.chunkSize)
413
356
?? input.readSlice(length: Int(size - offset))
414
-
357
+
415
358
params[paramName] = File(
416
359
name: file.name,
417
360
buffer: slice!
418
361
)
419
-
420
- headers["content-range"] = "bytes \(offset)-\(min((offset + Client.chunkSize) - 1, size))/\(size)"
421
362
422
- group.enter()
363
+ headers["content-range"] = "bytes \(offset)-\(min((offset + Client.chunkSize) - 1, size))/\(size)"
423
364
424
- call(
365
+ result = try await call(
425
366
method: "POST",
426
367
path: path,
427
368
headers: headers,
428
369
params: params,
429
370
convert: { return $0 }
430
- ) { response in
431
- switch response {
432
- case let .success(map):
433
- result = map
434
- group.leave()
435
- case let .failure(error):
436
- completion?(.failure(error))
437
- return
438
- }
439
- }
440
-
441
- group.wait()
371
+ )
442
372
443
373
offset += Client.chunkSize
444
374
headers["x-{{ spec .title | caseLower }}-id"] = result["$id"] as? String
@@ -451,10 +381,9 @@ open class Client {
451
381
))
452
382
}
453
383
454
- completion?(.success( convert!(result)) )
384
+ return convert!(result)
455
385
}
456
386
457
-
458
387
private static func randomBoundary() -> String {
459
388
var string = ""
460
389
for _ in 0..<16 {
@@ -464,16 +393,16 @@ open class Client {
464
393
}
465
394
466
395
private func buildJSON (
467
- _ request: inout HTTPClient . Request ,
396
+ _ request: inout HTTPClientRequest ,
468
397
with params: [String: Any ?] = [:]
469
398
) throws {
470
399
let json = try JSONSerialization .data (withJSONObject: params , options: [])
471
400
472
- request .body = .data (json )
401
+ request .body = .bytes (json )
473
402
}
474
403
475
404
private func buildMultipart (
476
- _ request: inout HTTPClient . Request ,
405
+ _ request: inout HTTPClientRequest ,
477
406
with params: [String: Any ?] = [:],
478
407
chunked: Bool = false
479
408
) {
@@ -528,7 +457,7 @@ open class Client {
528
457
request .headers .add (name: " Content-Length" , value: bodyBuffer .readableBytes .description )
529
458
}
530
459
request .headers .add (name: " Content-Type" , value: " multipart/form-data;boundary=\" \(Client .boundary )\" " )
531
- request .body = .byteBuffer (bodyBuffer )
460
+ request .body = .bytes (bodyBuffer )
532
461
}
533
462
534
463
private func addUserAgentHeader () {
0 commit comments