@waiting/fetch
Version:
HTTP fetch API for browser and Node.js. Handle 302/303 redirect correctly on Node.js
112 lines • 3.12 kB
JavaScript
import { _fetch } from './request.js';
import { handleResponseError, processResponseType } from './response.js';
import { trace } from './trace.js';
import { AttributeKey, Headers } from './types.js';
import { processParams } from './util.js';
/**
* Fetch with strict types
*
* @description generics any will be overwritten to unknown
*/
export async function fetch(options) {
const [ret] = await fetch2(options);
return ret;
}
/**
* Fetch with strict types
*
* @returns [result, response header]
* @description generics any will be overwritten to unknown
*/
export async function fetch2(options) {
trace(AttributeKey.PrepareRequestData, options.span);
const { args, requestInit } = processParams(options);
const { timeout } = args;
const timeout$ = typeof timeout === 'undefined' || timeout === Infinity || timeout < 0
? null
: new Promise(done => setTimeout(done, args.timeout));
const req$ = _fetch(options.url, args, requestInit, options.span);
const pm = [req$];
if (timeout$) {
pm.push(timeout$);
}
const data = await Promise.race(pm);
if (typeof data === 'undefined') { // timeout
abortReq(args.abortController);
trace(AttributeKey.RequestTimeout, options.span);
if (timeout) {
throw new Error(`fetch timeout in "${timeout.toString()}ms"`);
}
else {
throw new Error(`fetch timeout`);
}
}
const dataType = (args.dataType ?? 'bare');
trace(AttributeKey.ProcessResponseStart, options.span);
let resp = await handleResponseError(data, dataType === 'bare');
const respHeaders = new Headers(resp.headers);
if (typeof options.beforeProcessResponseCallback === 'function') {
resp = await options.beforeProcessResponseCallback(resp);
}
const ret = await processResponseType(resp, dataType);
trace(AttributeKey.ProcessResponseFinish, options.span);
return [ret, respHeaders];
}
/**
* Fetch Get with strict types, default response is JSON
*
* @description generics any will be overwritten to unknown
*/
export function get(url, options) {
const opts = {
...options,
url,
method: 'GET',
};
return fetch(opts);
}
/**
* Fetch Post with strict types
*
* @description generics any will be overwritten to unknown
*/
export function post(url, options) {
const opts = {
...options,
url,
method: 'POST',
};
return fetch(opts);
}
/**
* Fetch Put with strict types
*
* @description generics any will be overwritten to unknown
*/
export function put(url, options) {
const opts = {
...options,
url,
method: 'PUT',
};
return fetch(opts);
}
/**
* Fetch delete with strict types
*
* @description generics any will be overwritten to unknown
*/
export function remove(url, options) {
const opts = {
...options,
url,
method: 'DELETE',
};
return fetch(opts);
}
function abortReq(abc) {
if (abc && !abc.signal.aborted) {
abc.abort();
}
}
//# sourceMappingURL=fetch.js.map