UNPKG

sync-fetch

Version:

Synchronous version of the Fetch API

98 lines (80 loc) 2.53 kB
#!/usr/bin/env node const chunks = [] process.stdin.resume() process.stdin.setEncoding('utf8') process.stdin.on('data', function (chunk) { chunks.push(chunk) }) process.stdin.on('end', function () { const [resource, init] = JSON.parse(chunks.join('')) import('node-fetch') .then(({ default: fetch, Headers, Request }) => { init.body = init.body ? Buffer.from(init.body, 'base64') : undefined init.headers = new Headers(init.headers) if (init.timeout) { const signal = timeoutSignal(init.timeout) if (init.signal) { init.signal = AbortSignal.any([init.signal, signal]) } else { init.signal = signal } } return fetch(new Request(resource, init), {}) }) .then(response => response.arrayBuffer() .then(buffer => respond(serializeResponse(Buffer.from(buffer).toString('base64'), response))) .catch(error => { if (error.name === 'AbortError' && init.signal && init.signal.reason === 'timeout') { error.type = 'body-timeout' } return respond(serializeResponse('', response, error)) }) ) .catch(error => { if (error.name === 'AbortError' && init.signal && init.signal.reason === 'timeout') { error.type = 'request-timeout' } return respondWithError(error) }) }) // Adapted from https://github.com/node-fetch/timeout-signal/blob/main/index.js function timeoutSignal (timeout) { if (!Number.isInteger(timeout)) { throw new TypeError('Expected an integer') } const controller = new AbortController() const timeoutId = setTimeout(() => { controller.abort('timeout') }, timeout) if (typeof timeoutId.unref === 'function') { timeoutId.unref() } return controller.signal } function serializeResponse (body, response, bodyError) { const init = { headers: response.headers.raw(), status: response.status, statusText: response.statusText, redirected: response.redirected, type: response.type, url: response.url } return [0, body, init, bodyError ? serializeError(bodyError) : null] } function serializeError ({ constructor, message, type, code }) { return [ constructor.name, [message, type, { code }] ] } function respond (message) { process.stdout.write(JSON.stringify(message)) } function respondWithError (error) { if (error.cause && error.message === 'fetch failed') { respondWithError(error.cause) } else { respond([1, serializeError(error)]) } }