Skip to content

Commit

Permalink
Support text and binary responses (#15)
Browse files Browse the repository at this point in the history
* Handle non-JSON responses

---------

Co-authored-by: Janne Enberg <[email protected]>
  • Loading branch information
fbjorn and lietu authored Oct 3, 2023
1 parent bf2269e commit 982c521
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 5 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@cocreators-ee/apity",
"description": "A typed fetch client for openapi-typescript with Svelte support",
"version": "0.0.4",
"version": "0.0.5",
"readme": "README.md",
"engines": {
"node": ">= 12.0.0",
Expand Down
29 changes: 26 additions & 3 deletions src/svelte/fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,30 @@ import type {
Method,
} from '../types.js'
import type { ApiRequest, ApiResponse, SvelteCreateFetch } from './types.js'
import { ApiError } from '../types.js'
import { ApiError, LimitedResponse } from '../types.js'

const JSON_CONTENT_TYPES = ['application/json', 'application/ld+json']

async function getResponseBody(response: LimitedResponse) {
// no content
if (response.status === 204) {
return undefined
}
const contentType = response.headers.get('content-type')
if (contentType && JSON_CONTENT_TYPES.includes(contentType)) {
return await response.json()
} else if (contentType && contentType.indexOf('text') === -1) {
// if the response is neither JSON nor text, return binary data as is
// @ts-ignore
return await response.blob()
}
const text = await response.text()
try {
return JSON.parse(text)
} catch (e) {
return text
}
}

/***
* Make an API call and compose an ApiResponse object from the result
Expand All @@ -25,7 +48,7 @@ async function fetchAndParse<R>(request: Request): Promise<ApiResponse<R>> {
try {
const response = await request.realFetch(url, init)
try {
const body = response.status === 204 ? undefined : await response.json()
const body = await getResponseBody(response)
if (response.ok) {
return {
status: response.status,
Expand All @@ -40,7 +63,7 @@ async function fetchAndParse<R>(request: Request): Promise<ApiResponse<R>> {
}
}
} catch (e) {
console.warn('Failed to parse JSON from the response body', e)
console.warn('Failed to parse the response body', e)
return {
status: -2,
data: undefined,
Expand Down
14 changes: 13 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ type OpResponseTypes<OP> = OP extends {
? S
: R[S] extends { content: { 'application/json': infer C } } // openapi 3
? C
: R[S] extends TextContentType
? string
: S extends 'default'
? R[S]
: unknown
: Blob
}
: never

Expand Down Expand Up @@ -198,3 +200,13 @@ export class ApiError extends Error {
this.data = response.data
}
}

type TextContentType = {
content:
| { 'text/css': any }
| { 'text/csv': any }
| { 'text/html': any }
| { 'text/javascript': any }
| { 'text/plain': any }
| { 'text/xml': any }
}

0 comments on commit 982c521

Please sign in to comment.