154 lines
6.4 KiB
JavaScript
154 lines
6.4 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const is_1 = require("@sindresorhus/is");
|
|
const as_promise_1 = require("./as-promise");
|
|
const as_stream_1 = require("./as-stream");
|
|
const errors = require("./errors");
|
|
const normalize_arguments_1 = require("./normalize-arguments");
|
|
const deep_freeze_1 = require("./utils/deep-freeze");
|
|
const getPromiseOrStream = (options) => options.isStream ? as_stream_1.default(options) : as_promise_1.default(options);
|
|
const isGotInstance = (value) => (Reflect.has(value, 'defaults') && Reflect.has(value.defaults, 'options'));
|
|
const aliases = [
|
|
'get',
|
|
'post',
|
|
'put',
|
|
'patch',
|
|
'head',
|
|
'delete'
|
|
];
|
|
exports.defaultHandler = (options, next) => next(options);
|
|
const create = (defaults) => {
|
|
// Proxy properties from next handlers
|
|
defaults._rawHandlers = defaults.handlers;
|
|
defaults.handlers = defaults.handlers.map(fn => ((options, next) => {
|
|
// This will be assigned by assigning result
|
|
let root;
|
|
const result = fn(options, newOptions => {
|
|
root = next(newOptions);
|
|
return root;
|
|
});
|
|
if (result !== root && !options.isStream && root) {
|
|
const typedResult = result;
|
|
const { then: promiseThen, catch: promiseCatch, finally: promiseFianlly } = typedResult;
|
|
Object.setPrototypeOf(typedResult, Object.getPrototypeOf(root));
|
|
Object.defineProperties(typedResult, Object.getOwnPropertyDescriptors(root));
|
|
// These should point to the new promise
|
|
// eslint-disable-next-line promise/prefer-await-to-then
|
|
typedResult.then = promiseThen;
|
|
typedResult.catch = promiseCatch;
|
|
typedResult.finally = promiseFianlly;
|
|
}
|
|
return result;
|
|
}));
|
|
// @ts-ignore Because the for loop handles it for us, as well as the other Object.defines
|
|
const got = (url, options) => {
|
|
var _a;
|
|
let iteration = 0;
|
|
const iterateHandlers = (newOptions) => {
|
|
return defaults.handlers[iteration++](newOptions, iteration === defaults.handlers.length ? getPromiseOrStream : iterateHandlers);
|
|
};
|
|
/* eslint-disable @typescript-eslint/return-await */
|
|
try {
|
|
return iterateHandlers(normalize_arguments_1.normalizeArguments(url, options, defaults));
|
|
}
|
|
catch (error) {
|
|
if ((_a = options) === null || _a === void 0 ? void 0 : _a.isStream) {
|
|
throw error;
|
|
}
|
|
else {
|
|
// @ts-ignore It's an Error not a response, but TS thinks it's calling .resolve
|
|
return as_promise_1.createRejection(error);
|
|
}
|
|
}
|
|
/* eslint-enable @typescript-eslint/return-await */
|
|
};
|
|
got.extend = (...instancesOrOptions) => {
|
|
const optionsArray = [defaults.options];
|
|
let handlers = [...defaults._rawHandlers];
|
|
let isMutableDefaults;
|
|
for (const value of instancesOrOptions) {
|
|
if (isGotInstance(value)) {
|
|
optionsArray.push(value.defaults.options);
|
|
handlers.push(...value.defaults._rawHandlers);
|
|
isMutableDefaults = value.defaults.mutableDefaults;
|
|
}
|
|
else {
|
|
optionsArray.push(value);
|
|
if (Reflect.has(value, 'handlers')) {
|
|
handlers.push(...value.handlers);
|
|
}
|
|
isMutableDefaults = value.mutableDefaults;
|
|
}
|
|
}
|
|
handlers = handlers.filter(handler => handler !== exports.defaultHandler);
|
|
if (handlers.length === 0) {
|
|
handlers.push(exports.defaultHandler);
|
|
}
|
|
return create({
|
|
options: normalize_arguments_1.mergeOptions(...optionsArray),
|
|
handlers,
|
|
mutableDefaults: Boolean(isMutableDefaults)
|
|
});
|
|
};
|
|
// @ts-ignore The missing methods because the for-loop handles it for us
|
|
got.stream = (url, options) => got(url, { ...options, isStream: true });
|
|
for (const method of aliases) {
|
|
// @ts-ignore Cannot properly type a function with multiple definitions yet
|
|
got[method] = (url, options) => got(url, { ...options, method });
|
|
got.stream[method] = (url, options) => got.stream(url, { ...options, method });
|
|
}
|
|
// @ts-ignore The missing property is added below
|
|
got.paginate = async function* (url, options) {
|
|
let normalizedOptions = normalize_arguments_1.normalizeArguments(url, options, defaults);
|
|
const pagination = normalizedOptions._pagination;
|
|
if (!is_1.default.object(pagination)) {
|
|
throw new Error('`options._pagination` must be implemented');
|
|
}
|
|
const all = [];
|
|
while (true) {
|
|
// @ts-ignore See https://github.com/sindresorhus/got/issues/954
|
|
// eslint-disable-next-line no-await-in-loop
|
|
const result = await got(normalizedOptions);
|
|
// eslint-disable-next-line no-await-in-loop
|
|
const parsed = await pagination.transform(result);
|
|
const current = [];
|
|
for (const item of parsed) {
|
|
if (pagination.filter(item, all, current)) {
|
|
if (!pagination.shouldContinue(item, all, current)) {
|
|
return;
|
|
}
|
|
yield item;
|
|
all.push(item);
|
|
current.push(item);
|
|
if (all.length === pagination.countLimit) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
const optionsToMerge = pagination.paginate(result, all, current);
|
|
if (optionsToMerge === false) {
|
|
return;
|
|
}
|
|
if (optionsToMerge !== undefined) {
|
|
normalizedOptions = normalize_arguments_1.normalizeArguments(normalizedOptions, optionsToMerge);
|
|
}
|
|
}
|
|
};
|
|
got.paginate.all = async (url, options) => {
|
|
const results = [];
|
|
for await (const item of got.paginate(url, options)) {
|
|
results.push(item);
|
|
}
|
|
return results;
|
|
};
|
|
Object.assign(got, { ...errors, mergeOptions: normalize_arguments_1.mergeOptions });
|
|
Object.defineProperty(got, 'defaults', {
|
|
value: defaults.mutableDefaults ? defaults : deep_freeze_1.default(defaults),
|
|
writable: defaults.mutableDefaults,
|
|
configurable: defaults.mutableDefaults,
|
|
enumerable: true
|
|
});
|
|
return got;
|
|
};
|
|
exports.default = create;
|