Skip to content

Commit

Permalink
Merge pull request #24 from kwhitley/23-improved-payload-type-checking
Browse files Browse the repository at this point in the history
Invert the type checking logic of the payload in order to determine whether to stringify or not
  • Loading branch information
kwhitley committed Oct 17, 2022
2 parents 06e5894 + d4dcdcd commit 387de80
Showing 1 changed file with 13 additions and 15 deletions.
28 changes: 13 additions & 15 deletions src/itty-fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ export type FetchOptions = Omit<RequestInit, 'headers'> & {
headers?: Record<string, string>
}

export type StringifyPayload = string | number | object | any[] | undefined
export type PassThroughPayload = FormData | Blob | Uint8Array

export type RequestPayload = string | number | object | any[] | PassThroughPayload | undefined
export type RequestPayload = StringifyPayload | PassThroughPayload

export interface FetcherOptions {
base?: string
Expand All @@ -36,9 +37,7 @@ export type FetcherType = FetcherOptions & {
delete: FetchyFunction
} & FetchTraps

export type FetchyOptions = {
method: string
} & FetcherOptions
export type FetchyOptions = { method: string } & FetcherOptions

const fetchy =
(options: FetchyOptions): FetchyFunction =>
Expand Down Expand Up @@ -70,23 +69,22 @@ const fetchy =
const full_url = (options.base || '') + url_or_path + search

/**
* Detect what type of incoming payload is provided. If it is FormData, Blob
* or Uint8Array, we will not attempt to stringify it. Otherwise, we will.
*
* TODO: This is a bit funky and isn't very extensible. We should probably
* find a better approach.
* If the payload is a POJO, an array or a string, we will stringify it
* automatically, otherwise we will pass it through as-is.
*/
const is_formdata = typeof FormData !== 'undefined' && payload instanceof FormData
const is_blob = typeof Blob !== 'undefined' && payload instanceof Blob
const is_arraybuffer = typeof Uint8Array !== 'undefined' && payload instanceof Uint8Array
const passthrough = is_formdata || is_blob || is_arraybuffer
const stringify =
typeof payload === 'undefined' ||
typeof payload === 'string' ||
typeof payload === 'number' ||
Array.isArray(payload) ||
Object.getPrototypeOf(payload).toString() === '[object Object]'

const jsonHeaders = !passthrough ? { 'content-type': 'application/json' } : undefined
const jsonHeaders = stringify ? { 'content-type': 'application/json' } : undefined

let req: RequestLike = {
url: full_url,
method,
body: passthrough ? (payload as PassThroughPayload) : JSON.stringify(payload),
body: stringify ? JSON.stringify(payload) : (payload as PassThroughPayload),
...fetchOptions,
headers: {
...jsonHeaders,
Expand Down

0 comments on commit 387de80

Please sign in to comment.