commerce/framework/spree/utils/create-customized-fetch-fetcher.ts
2022-01-17 09:12:55 -03:00

110 lines
3.1 KiB
TypeScript

import {
errors,
request as spreeSdkRequestHelpers,
} from '@spree/storefront-api-v2-sdk'
import type { CreateCustomizedFetchFetcher } from '@spree/storefront-api-v2-sdk/types/interfaces/CreateCustomizedFetchFetcher'
import isJsonContentType from './is-json-content-type'
export const fetchResponseKey = Symbol('fetch-response-key')
const createCustomizedFetchFetcher: CreateCustomizedFetchFetcher = (
fetcherOptions
) => {
const { FetchError } = errors
const sharedHeaders = {
'Content-Type': 'application/json',
}
const { host, fetch, requestConstructor } = fetcherOptions
return {
fetch: async (fetchOptions) => {
// This fetcher always returns request equal null,
// because @vercel/fetch doesn't accept a Request object as argument
// and it's not used by NJC anyway.
try {
const { url, params, method, headers, responseParsing } = fetchOptions
const absoluteUrl = new URL(url, host)
let payload
switch (method.toUpperCase()) {
case 'PUT':
case 'POST':
case 'DELETE':
case 'PATCH':
payload = { body: JSON.stringify(params) }
break
default:
payload = null
absoluteUrl.search =
spreeSdkRequestHelpers.objectToQuerystring(params)
}
const request: Request = new requestConstructor(
absoluteUrl.toString(),
{
method: method.toUpperCase(),
headers: { ...sharedHeaders, ...headers },
...payload,
}
)
try {
console.info(
`Calling the Spree API: ${request.method} ${request.url}`
)
const response: Response = await fetch(request)
const responseContentType = response.headers.get('content-type')
let data
if (responseParsing === 'automatic') {
if (responseContentType && isJsonContentType(responseContentType)) {
data = await response.json()
} else {
data = await response.text()
}
} else if (responseParsing === 'text') {
data = await response.text()
} else if (responseParsing === 'json') {
data = await response.json()
} else if (responseParsing === 'stream') {
data = await response.body
}
if (!response.ok) {
// Use the "traditional" approach and reject non 2xx responses.
throw new FetchError(response, request, data)
}
data[fetchResponseKey] = response
return { data }
} catch (error) {
if (error instanceof FetchError) {
throw error
}
if (!(error instanceof Error)) {
throw error
}
throw new FetchError(null, request, null, error.message)
}
} catch (error) {
if (error instanceof FetchError) {
throw error
}
if (!(error instanceof Error)) {
throw error
}
throw new FetchError(null, null, null, error.message)
}
},
}
}
export default createCustomizedFetchFetcher