mirror of
https://github.com/vercel/commerce.git
synced 2025-06-17 20:51:21 +00:00
97 lines
3.0 KiB
TypeScript
97 lines
3.0 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 {
|
|
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;
|