@@ -17,6 +17,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrl
1717import okhttp3.MediaType.Companion.toMediaType
1818import okhttp3.RequestBody.Companion.asRequestBody
1919import okhttp3.RequestBody.Companion.toRequestBody
20+ import java.io.BufferedInputStream
2021import java.io.BufferedReader
2122import java.io.File
2223import java.io.IOException
@@ -44,6 +45,8 @@ class Client @JvmOverloads constructor(
4445
4546 private val job = Job()
4647
48+ private val gson = Gson()
49+
4750 lateinit var http: OkHttpClient
4851
4952 private val headers: MutableMap<String , String >
@@ -203,13 +206,14 @@ class Client @JvmOverloads constructor(
203206 * @return [Response]
204207 */
205208 @Throws({{ spec .title | caseUcfirst }}Exception::class)
206- suspend fun call(
209+ suspend fun < T > call(
207210 method: String,
208211 path: String,
209212 headers: Map<String , String > = mapOf(),
210- params: Map<String , Any ?> = mapOf()
211- ): Response {
212-
213+ params: Map<String , Any ?> = mapOf(),
214+ responseType: Class<T >,
215+ convert: ((Map<String , Any ,>) -> T)? = null
216+ ): T {
213217 val filteredParams = params.filterValues { it != null }
214218
215219 val requestHeaders = this.headers.toHeaders().newBuilder()
@@ -244,7 +248,7 @@ class Client @JvmOverloads constructor(
244248 .get()
245249 .build()
246250
247- return awaitResponse(request)
251+ return awaitResponse(request, responseType, convert )
248252 }
249253
250254 val body = if (MultipartBody.FORM.toString() == headers["content-type"]) {
@@ -272,7 +276,7 @@ class Client @JvmOverloads constructor(
272276 }
273277 builder.build()
274278 } else {
275- Gson() .toJson(filteredParams)
279+ gson .toJson(filteredParams)
276280 .toRequestBody("application/json".toMediaType())
277281 }
278282
@@ -282,21 +286,25 @@ class Client @JvmOverloads constructor(
282286 .method(method, body)
283287 .build()
284288
285- return awaitResponse(request)
289+ return awaitResponse(request, responseType, convert )
286290 }
287291
288292 /**
289293 * Await Response
290- *
294+ *
291295 * @param method
292296 * @param path
293297 * @param headers
294298 * @param params
295299 *
296- * @return [Response]
300+ * @return [T]
297301 */
298302 @Throws({{ spec .title | caseUcfirst }}Exception::class)
299- private suspend fun awaitResponse(request: Request) = suspendCancellableCoroutine<Response > {
303+ private suspend fun <T > awaitResponse(
304+ request: Request,
305+ responseType: Class<T >,
306+ convert: ((Map<String , Any ,>) -> T)? = null
307+ ) = suspendCancellableCoroutine<T > {
300308 http.newCall(request).enqueue(object : Callback {
301309 override fun onFailure(call: Call, e: IOException) {
302310 if (it.isCancelled) {
@@ -306,26 +314,52 @@ class Client @JvmOverloads constructor(
306314 }
307315
308316 override fun onResponse(call: Call, response: Response) {
309- if (response.code >= 400) {
310- val bodyString = response.body
311- ?.charStream()
312- ?.buffered()
313- ?.use(BufferedReader::readText) ?: ""
314-
315- val contentType: String = response.headers["content-type"] ?: ""
316- val error = if (contentType.contains("application/json", ignoreCase = true)) {
317- bodyString.fromJson< {{ spec .title | caseUcfirst }}Exception>()
317+ if (!response.isSuccessful) {
318+ val body = response.body!!
319+ .charStream()
320+ .buffered()
321+ .use(BufferedReader::readText)
322+ val error = if (response.headers["content-type"]?.contains("application/json") == true) {
323+ body.fromJson()
318324 } else {
319- {{ spec .title | caseUcfirst }}Exception(bodyString , response.code)
325+ {{ spec .title | caseUcfirst }}Exception(body , response.code)
320326 }
321-
322- it.cancel(AppwriteException(
323- error.message,
324- error.code,
325- bodyString
326- ))
327+ it.cancel(error)
328+ return
329+ }
330+ when {
331+ responseType == Boolean::class.java -> {
332+ it.resume(true as T)
333+ return
334+ }
335+ responseType == ByteArray::class.java -> {
336+ it.resume(response.body!!
337+ .byteStream()
338+ .buffered()
339+ .use(BufferedInputStream::readBytes) as T
340+ )
341+ return
342+ }
343+ response.body == null -> {
344+ it.resume(true as T)
345+ return
346+ }
347+ }
348+ val body = response.body!!
349+ .charStream()
350+ .buffered()
351+ .use(BufferedReader::readText)
352+ if (body.isEmpty()) {
353+ it.resume(true as T)
354+ return
327355 }
328- it.resume(response)
356+ val map = gson.fromJson<Map <String , Any >>(
357+ body,
358+ HashMap::class.java
359+ )
360+ it.resume(
361+ convert?.invoke(map) ?: map as T
362+ )
329363 }
330364 })
331365 }
0 commit comments