trouble-in-terror-town/node_modules/got/source/as-promise.js
Mikolaj 2bbacbea09 did some more work on networking and removed EOS in favor of LRM
did some more work on networking and removed EOS in favor of Light Reflective Mirror
2022-05-31 15:04:31 +02:00

108 lines
2.8 KiB
JavaScript

'use strict';
const EventEmitter = require('events');
const getStream = require('get-stream');
const is = require('@sindresorhus/is');
const PCancelable = require('p-cancelable');
const requestAsEventEmitter = require('./request-as-event-emitter');
const {HTTPError, ParseError, ReadError} = require('./errors');
const {options: mergeOptions} = require('./merge');
const {reNormalize} = require('./normalize-arguments');
const asPromise = options => {
const proxy = new EventEmitter();
const promise = new PCancelable((resolve, reject, onCancel) => {
const emitter = requestAsEventEmitter(options);
onCancel(emitter.abort);
emitter.on('response', async response => {
proxy.emit('response', response);
const stream = is.null(options.encoding) ? getStream.buffer(response) : getStream(response, options);
let data;
try {
data = await stream;
} catch (error) {
reject(new ReadError(error, options));
return;
}
const limitStatusCode = options.followRedirect ? 299 : 399;
response.body = data;
try {
for (const [index, hook] of Object.entries(options.hooks.afterResponse)) {
// eslint-disable-next-line no-await-in-loop
response = await hook(response, updatedOptions => {
updatedOptions = reNormalize(mergeOptions(options, {
...updatedOptions,
retry: 0,
throwHttpErrors: false
}));
// Remove any further hooks for that request, because we we'll call them anyway.
// The loop continues. We don't want duplicates (asPromise recursion).
updatedOptions.hooks.afterResponse = options.hooks.afterResponse.slice(0, index);
return asPromise(updatedOptions);
});
}
} catch (error) {
reject(error);
return;
}
const {statusCode} = response;
if (options.json && response.body) {
try {
response.body = JSON.parse(response.body);
} catch (error) {
if (statusCode >= 200 && statusCode < 300) {
const parseError = new ParseError(error, statusCode, options, data);
Object.defineProperty(parseError, 'response', {value: response});
reject(parseError);
return;
}
}
}
if (statusCode !== 304 && (statusCode < 200 || statusCode > limitStatusCode)) {
const error = new HTTPError(response, options);
Object.defineProperty(error, 'response', {value: response});
if (emitter.retry(error) === false) {
if (options.throwHttpErrors) {
reject(error);
return;
}
resolve(response);
}
return;
}
resolve(response);
});
emitter.once('error', reject);
[
'request',
'redirect',
'uploadProgress',
'downloadProgress'
].forEach(event => emitter.on(event, (...args) => proxy.emit(event, ...args)));
});
promise.on = (name, fn) => {
proxy.on(name, fn);
return promise;
};
return promise;
};
module.exports = asPromise;