241 lines
9.6 KiB
JavaScript
241 lines
9.6 KiB
JavaScript
|
"use strict";
|
||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||
|
}) : (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
o[k2] = m[k];
|
||
|
}));
|
||
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
exports.defaultHandler = void 0;
|
||
|
const is_1 = require("@sindresorhus/is");
|
||
|
const as_promise_1 = require("./as-promise");
|
||
|
const create_rejection_1 = require("./as-promise/create-rejection");
|
||
|
const core_1 = require("./core");
|
||
|
const deep_freeze_1 = require("./utils/deep-freeze");
|
||
|
const errors = {
|
||
|
RequestError: as_promise_1.RequestError,
|
||
|
CacheError: as_promise_1.CacheError,
|
||
|
ReadError: as_promise_1.ReadError,
|
||
|
HTTPError: as_promise_1.HTTPError,
|
||
|
MaxRedirectsError: as_promise_1.MaxRedirectsError,
|
||
|
TimeoutError: as_promise_1.TimeoutError,
|
||
|
ParseError: as_promise_1.ParseError,
|
||
|
CancelError: as_promise_1.CancelError,
|
||
|
UnsupportedProtocolError: as_promise_1.UnsupportedProtocolError,
|
||
|
UploadError: as_promise_1.UploadError
|
||
|
};
|
||
|
// The `delay` package weighs 10KB (!)
|
||
|
const delay = async (ms) => new Promise(resolve => {
|
||
|
setTimeout(resolve, ms);
|
||
|
});
|
||
|
const { normalizeArguments } = core_1.default;
|
||
|
const mergeOptions = (...sources) => {
|
||
|
let mergedOptions;
|
||
|
for (const source of sources) {
|
||
|
mergedOptions = normalizeArguments(undefined, source, mergedOptions);
|
||
|
}
|
||
|
return mergedOptions;
|
||
|
};
|
||
|
const getPromiseOrStream = (options) => options.isStream ? new core_1.default(undefined, options) : as_promise_1.default(options);
|
||
|
const isGotInstance = (value) => ('defaults' in value && 'options' in value.defaults);
|
||
|
const aliases = [
|
||
|
'get',
|
||
|
'post',
|
||
|
'put',
|
||
|
'patch',
|
||
|
'head',
|
||
|
'delete'
|
||
|
];
|
||
|
exports.defaultHandler = (options, next) => next(options);
|
||
|
const callInitHooks = (hooks, options) => {
|
||
|
if (hooks) {
|
||
|
for (const hook of hooks) {
|
||
|
hook(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;
|
||
|
}));
|
||
|
// Got interface
|
||
|
const got = ((url, options = {}, _defaults) => {
|
||
|
var _a, _b;
|
||
|
let iteration = 0;
|
||
|
const iterateHandlers = (newOptions) => {
|
||
|
return defaults.handlers[iteration++](newOptions, iteration === defaults.handlers.length ? getPromiseOrStream : iterateHandlers);
|
||
|
};
|
||
|
// TODO: Remove this in Got 12.
|
||
|
if (is_1.default.plainObject(url)) {
|
||
|
const mergedOptions = {
|
||
|
...url,
|
||
|
...options
|
||
|
};
|
||
|
core_1.setNonEnumerableProperties([url, options], mergedOptions);
|
||
|
options = mergedOptions;
|
||
|
url = undefined;
|
||
|
}
|
||
|
try {
|
||
|
// Call `init` hooks
|
||
|
let initHookError;
|
||
|
try {
|
||
|
callInitHooks(defaults.options.hooks.init, options);
|
||
|
callInitHooks((_a = options.hooks) === null || _a === void 0 ? void 0 : _a.init, options);
|
||
|
}
|
||
|
catch (error) {
|
||
|
initHookError = error;
|
||
|
}
|
||
|
// Normalize options & call handlers
|
||
|
const normalizedOptions = normalizeArguments(url, options, _defaults !== null && _defaults !== void 0 ? _defaults : defaults.options);
|
||
|
normalizedOptions[core_1.kIsNormalizedAlready] = true;
|
||
|
if (initHookError) {
|
||
|
throw new as_promise_1.RequestError(initHookError.message, initHookError, normalizedOptions);
|
||
|
}
|
||
|
return iterateHandlers(normalizedOptions);
|
||
|
}
|
||
|
catch (error) {
|
||
|
if (options.isStream) {
|
||
|
throw error;
|
||
|
}
|
||
|
else {
|
||
|
return create_rejection_1.default(error, defaults.options.hooks.beforeError, (_b = options.hooks) === null || _b === void 0 ? void 0 : _b.beforeError);
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
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 ('handlers' in value) {
|
||
|
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: mergeOptions(...optionsArray),
|
||
|
handlers,
|
||
|
mutableDefaults: Boolean(isMutableDefaults)
|
||
|
});
|
||
|
};
|
||
|
// Pagination
|
||
|
const paginateEach = (async function* (url, options) {
|
||
|
// TODO: Remove this `@ts-expect-error` when upgrading to TypeScript 4.
|
||
|
// Error: Argument of type 'Merge<Options, PaginationOptions<T, R>> | undefined' is not assignable to parameter of type 'Options | undefined'.
|
||
|
// @ts-expect-error
|
||
|
let normalizedOptions = normalizeArguments(url, options, defaults.options);
|
||
|
normalizedOptions.resolveBodyOnly = false;
|
||
|
const pagination = normalizedOptions.pagination;
|
||
|
if (!is_1.default.object(pagination)) {
|
||
|
throw new TypeError('`options.pagination` must be implemented');
|
||
|
}
|
||
|
const all = [];
|
||
|
let { countLimit } = pagination;
|
||
|
let numberOfRequests = 0;
|
||
|
while (numberOfRequests < pagination.requestLimit) {
|
||
|
if (numberOfRequests !== 0) {
|
||
|
// eslint-disable-next-line no-await-in-loop
|
||
|
await delay(pagination.backoff);
|
||
|
}
|
||
|
// @ts-expect-error FIXME!
|
||
|
// TODO: Throw when result is not an instance of Response
|
||
|
// eslint-disable-next-line no-await-in-loop
|
||
|
const result = (await got(undefined, undefined, 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;
|
||
|
if (pagination.stackAllItems) {
|
||
|
all.push(item);
|
||
|
}
|
||
|
current.push(item);
|
||
|
if (--countLimit <= 0) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
const optionsToMerge = pagination.paginate(result, all, current);
|
||
|
if (optionsToMerge === false) {
|
||
|
return;
|
||
|
}
|
||
|
if (optionsToMerge === result.request.options) {
|
||
|
normalizedOptions = result.request.options;
|
||
|
}
|
||
|
else if (optionsToMerge !== undefined) {
|
||
|
normalizedOptions = normalizeArguments(undefined, optionsToMerge, normalizedOptions);
|
||
|
}
|
||
|
numberOfRequests++;
|
||
|
}
|
||
|
});
|
||
|
got.paginate = paginateEach;
|
||
|
got.paginate.all = (async (url, options) => {
|
||
|
const results = [];
|
||
|
for await (const item of paginateEach(url, options)) {
|
||
|
results.push(item);
|
||
|
}
|
||
|
return results;
|
||
|
});
|
||
|
// For those who like very descriptive names
|
||
|
got.paginate.each = paginateEach;
|
||
|
// Stream API
|
||
|
got.stream = ((url, options) => got(url, { ...options, isStream: true }));
|
||
|
// Shortcuts
|
||
|
for (const method of aliases) {
|
||
|
got[method] = ((url, options) => got(url, { ...options, method }));
|
||
|
got.stream[method] = ((url, options) => {
|
||
|
return got(url, { ...options, method, isStream: true });
|
||
|
});
|
||
|
}
|
||
|
Object.assign(got, errors);
|
||
|
Object.defineProperty(got, 'defaults', {
|
||
|
value: defaults.mutableDefaults ? defaults : deep_freeze_1.default(defaults),
|
||
|
writable: defaults.mutableDefaults,
|
||
|
configurable: defaults.mutableDefaults,
|
||
|
enumerable: true
|
||
|
});
|
||
|
got.mergeOptions = mergeOptions;
|
||
|
return got;
|
||
|
};
|
||
|
exports.default = create;
|
||
|
__exportStar(require("./types"), exports);
|