UNPKG

9.69 kBJavaScriptView Raw
1"use strict";
2var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 if (k2 === undefined) k2 = k;
4 Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5}) : (function(o, m, k, k2) {
6 if (k2 === undefined) k2 = k;
7 o[k2] = m[k];
8}));
9var __exportStar = (this && this.__exportStar) || function(m, exports) {
10 for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
11};
12Object.defineProperty(exports, "__esModule", { value: true });
13exports.defaultHandler = void 0;
14const p_cancelable_1 = require("p-cancelable");
15const is_1 = require("@sindresorhus/is");
16const as_promise_1 = require("./as-promise");
17const create_rejection_1 = require("./as-promise/create-rejection");
18const core_1 = require("./core");
19const deep_freeze_1 = require("./utils/deep-freeze");
20const errors = {
21 RequestError: as_promise_1.RequestError,
22 CacheError: as_promise_1.CacheError,
23 ReadError: as_promise_1.ReadError,
24 HTTPError: as_promise_1.HTTPError,
25 MaxRedirectsError: as_promise_1.MaxRedirectsError,
26 TimeoutError: as_promise_1.TimeoutError,
27 ParseError: as_promise_1.ParseError,
28 CancelError: p_cancelable_1.CancelError,
29 UnsupportedProtocolError: as_promise_1.UnsupportedProtocolError,
30 UploadError: as_promise_1.UploadError
31};
32// The `delay` package weighs 10KB (!)
33const delay = async (ms) => new Promise(resolve => setTimeout(resolve, ms));
34const { normalizeArguments, mergeOptions } = as_promise_1.PromisableRequest;
35const getPromiseOrStream = (options) => options.isStream ? new core_1.default(options.url, options) : as_promise_1.default(options);
36const isGotInstance = (value) => ('defaults' in value && 'options' in value.defaults);
37const aliases = [
38 'get',
39 'post',
40 'put',
41 'patch',
42 'head',
43 'delete'
44];
45exports.defaultHandler = (options, next) => next(options);
46const callInitHooks = (hooks, options) => {
47 if (hooks) {
48 for (const hook of hooks) {
49 hook(options);
50 }
51 }
52};
53const create = (defaults) => {
54 // Proxy properties from next handlers
55 defaults._rawHandlers = defaults.handlers;
56 defaults.handlers = defaults.handlers.map(fn => ((options, next) => {
57 // This will be assigned by assigning result
58 let root;
59 const result = fn(options, newOptions => {
60 root = next(newOptions);
61 return root;
62 });
63 if (result !== root && !options.isStream && root) {
64 const typedResult = result;
65 const { then: promiseThen, catch: promiseCatch, finally: promiseFianlly } = typedResult;
66 Object.setPrototypeOf(typedResult, Object.getPrototypeOf(root));
67 Object.defineProperties(typedResult, Object.getOwnPropertyDescriptors(root));
68 // These should point to the new promise
69 // eslint-disable-next-line promise/prefer-await-to-then
70 typedResult.then = promiseThen;
71 typedResult.catch = promiseCatch;
72 typedResult.finally = promiseFianlly;
73 }
74 return result;
75 }));
76 // Got interface
77 const got = ((url, options) => {
78 var _a, _b;
79 let iteration = 0;
80 const iterateHandlers = (newOptions) => {
81 return defaults.handlers[iteration++](newOptions, iteration === defaults.handlers.length ? getPromiseOrStream : iterateHandlers);
82 };
83 // TODO: Remove this in Got 12.
84 if (is_1.default.plainObject(url)) {
85 const mergedOptions = {
86 ...url,
87 ...options
88 };
89 core_1.setNonEnumerableProperties([url, options], mergedOptions);
90 options = mergedOptions;
91 url = undefined;
92 }
93 try {
94 // Call `init` hooks
95 let initHookError;
96 try {
97 callInitHooks(defaults.options.hooks.init, options);
98 callInitHooks((_a = options === null || options === void 0 ? void 0 : options.hooks) === null || _a === void 0 ? void 0 : _a.init, options);
99 }
100 catch (error) {
101 initHookError = error;
102 }
103 // Normalize options & call handlers
104 const normalizedOptions = normalizeArguments(url, options, defaults.options);
105 normalizedOptions[core_1.kIsNormalizedAlready] = true;
106 if (initHookError) {
107 throw new as_promise_1.RequestError(initHookError.message, initHookError, normalizedOptions);
108 }
109 return iterateHandlers(normalizedOptions);
110 }
111 catch (error) {
112 if (options === null || options === void 0 ? void 0 : options.isStream) {
113 throw error;
114 }
115 else {
116 return create_rejection_1.default(error, defaults.options.hooks.beforeError, (_b = options === null || options === void 0 ? void 0 : options.hooks) === null || _b === void 0 ? void 0 : _b.beforeError);
117 }
118 }
119 });
120 got.extend = (...instancesOrOptions) => {
121 const optionsArray = [defaults.options];
122 let handlers = [...defaults._rawHandlers];
123 let isMutableDefaults;
124 for (const value of instancesOrOptions) {
125 if (isGotInstance(value)) {
126 optionsArray.push(value.defaults.options);
127 handlers.push(...value.defaults._rawHandlers);
128 isMutableDefaults = value.defaults.mutableDefaults;
129 }
130 else {
131 optionsArray.push(value);
132 if ('handlers' in value) {
133 handlers.push(...value.handlers);
134 }
135 isMutableDefaults = value.mutableDefaults;
136 }
137 }
138 handlers = handlers.filter(handler => handler !== exports.defaultHandler);
139 if (handlers.length === 0) {
140 handlers.push(exports.defaultHandler);
141 }
142 return create({
143 options: mergeOptions(...optionsArray),
144 handlers,
145 mutableDefaults: Boolean(isMutableDefaults)
146 });
147 };
148 // Pagination
149 const paginateEach = (async function* (url, options) {
150 // TODO: Remove this `@ts-expect-error` when upgrading to TypeScript 4.
151 // Error: Argument of type 'Merge<Options, PaginationOptions<T, R>> | undefined' is not assignable to parameter of type 'Options | undefined'.
152 // @ts-expect-error
153 let normalizedOptions = normalizeArguments(url, options, defaults.options);
154 normalizedOptions.resolveBodyOnly = false;
155 const pagination = normalizedOptions.pagination;
156 if (!is_1.default.object(pagination)) {
157 throw new TypeError('`options.pagination` must be implemented');
158 }
159 const all = [];
160 let { countLimit } = pagination;
161 let numberOfRequests = 0;
162 while (numberOfRequests < pagination.requestLimit) {
163 if (numberOfRequests !== 0) {
164 // eslint-disable-next-line no-await-in-loop
165 await delay(pagination.backoff);
166 }
167 // TODO: Throw when result is not an instance of Response
168 // eslint-disable-next-line no-await-in-loop
169 const result = (await got(normalizedOptions));
170 // eslint-disable-next-line no-await-in-loop
171 const parsed = await pagination.transform(result);
172 const current = [];
173 for (const item of parsed) {
174 if (pagination.filter(item, all, current)) {
175 if (!pagination.shouldContinue(item, all, current)) {
176 return;
177 }
178 yield item;
179 if (pagination.stackAllItems) {
180 all.push(item);
181 }
182 current.push(item);
183 if (--countLimit <= 0) {
184 return;
185 }
186 }
187 }
188 const optionsToMerge = pagination.paginate(result, all, current);
189 if (optionsToMerge === false) {
190 return;
191 }
192 if (optionsToMerge === result.request.options) {
193 normalizedOptions = result.request.options;
194 }
195 else if (optionsToMerge !== undefined) {
196 normalizedOptions = normalizeArguments(undefined, optionsToMerge, normalizedOptions);
197 }
198 numberOfRequests++;
199 }
200 });
201 got.paginate = ((url, options) => {
202 return paginateEach(url, options);
203 });
204 got.paginate.all = (async (url, options) => {
205 const results = [];
206 for await (const item of got.paginate(url, options)) {
207 results.push(item);
208 }
209 return results;
210 });
211 // For those who like very descriptive names
212 got.paginate.each = paginateEach;
213 // Stream API
214 got.stream = ((url, options) => got(url, { ...options, isStream: true }));
215 // Shortcuts
216 for (const method of aliases) {
217 got[method] = ((url, options) => got(url, { ...options, method }));
218 got.stream[method] = ((url, options) => {
219 return got(url, { ...options, method, isStream: true });
220 });
221 }
222 Object.assign(got, { ...errors, mergeOptions });
223 Object.defineProperty(got, 'defaults', {
224 value: defaults.mutableDefaults ? defaults : deep_freeze_1.default(defaults),
225 writable: defaults.mutableDefaults,
226 configurable: defaults.mutableDefaults,
227 enumerable: true
228 });
229 return got;
230};
231exports.default = create;
232__exportStar(require("./types"), exports);