@digitalbazaar/http-client
Version:
An opinionated, isomorphic HTTP client.
54 lines (45 loc) • 1.66 kB
JavaScript
/*!
* Copyright (c) 2022 Digital Bazaar, Inc. All rights reserved.
*/
import {Agent} from 'undici';
import {versions} from 'node:process';
// as long as an agent has a reference to it, its associated dispatcher will
// be kept in this cache for reuse
const AGENT_CACHE = new WeakMap();
// can only convert agent to dispatcher option on node 18.2+
const [major, minor] = versions.node.split('.').map(v => parseInt(v, 10));
const canConvert = (major > 18) || (major === 18 && minor >= 2);
// converts `agent`/`httpsAgent` option to a dispatcher option
export function convertAgent(options) {
if(!canConvert) {
return options;
}
// do not override custom fetch function from another lib
if(options?.fetch && !options.fetch._httpClientCustomFetch) {
return options;
}
// only override if an agent option is present
const agent = options?.agent || options?.httpsAgent;
if(!agent) {
return options;
}
// use custom fetch if agent has already been converted
let fetch = AGENT_CACHE.get(agent);
if(!fetch) {
const dispatcher = new Agent({connect: agent.options});
fetch = createFetch(dispatcher);
fetch._httpClientCustomFetch = true;
AGENT_CACHE.set(agent, fetch);
}
return {...options, fetch};
}
// create fetch override uses custom `dispatcher`; since `ky` does not pass
// the dispatcher option through to `fetch`, we must use this override
function createFetch(dispatcher) {
return function fetch(...args) {
dispatcher = (args[1] && args[1].dispatcher) || dispatcher;
args[1] = {...args[1], dispatcher};
// eslint-disable-next-line no-undef
return globalThis.fetch(...args);
};
}