UNPKG

got

Version:

Human-friendly and powerful HTTP request library for Node.js

154 lines (153 loc) 6.57 kB
"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;