fix
This commit is contained in:
3
book/node_modules/got/dist/source/as-promise/index.d.ts
generated
vendored
Normal file
3
book/node_modules/got/dist/source/as-promise/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
import Request from '../core/index.js';
|
||||
import { type CancelableRequest } from './types.js';
|
||||
export default function asPromise<T>(firstRequest?: Request): CancelableRequest<T>;
|
164
book/node_modules/got/dist/source/as-promise/index.js
generated
vendored
Normal file
164
book/node_modules/got/dist/source/as-promise/index.js
generated
vendored
Normal file
@ -0,0 +1,164 @@
|
||||
import { EventEmitter } from 'node:events';
|
||||
import is from '@sindresorhus/is';
|
||||
import PCancelable from 'p-cancelable';
|
||||
import { HTTPError, RetryError, } from '../core/errors.js';
|
||||
import Request from '../core/index.js';
|
||||
import { parseBody, isResponseOk, ParseError, } from '../core/response.js';
|
||||
import proxyEvents from '../core/utils/proxy-events.js';
|
||||
import { CancelError } from './types.js';
|
||||
const proxiedRequestEvents = [
|
||||
'request',
|
||||
'response',
|
||||
'redirect',
|
||||
'uploadProgress',
|
||||
'downloadProgress',
|
||||
];
|
||||
export default function asPromise(firstRequest) {
|
||||
let globalRequest;
|
||||
let globalResponse;
|
||||
let normalizedOptions;
|
||||
const emitter = new EventEmitter();
|
||||
const promise = new PCancelable((resolve, reject, onCancel) => {
|
||||
onCancel(() => {
|
||||
globalRequest.destroy();
|
||||
});
|
||||
onCancel.shouldReject = false;
|
||||
onCancel(() => {
|
||||
reject(new CancelError(globalRequest));
|
||||
});
|
||||
const makeRequest = (retryCount) => {
|
||||
// Errors when a new request is made after the promise settles.
|
||||
// Used to detect a race condition.
|
||||
// See https://github.com/sindresorhus/got/issues/1489
|
||||
onCancel(() => { });
|
||||
const request = firstRequest ?? new Request(undefined, undefined, normalizedOptions);
|
||||
request.retryCount = retryCount;
|
||||
request._noPipe = true;
|
||||
globalRequest = request;
|
||||
request.once('response', async (response) => {
|
||||
// Parse body
|
||||
const contentEncoding = (response.headers['content-encoding'] ?? '').toLowerCase();
|
||||
const isCompressed = contentEncoding === 'gzip' || contentEncoding === 'deflate' || contentEncoding === 'br';
|
||||
const { options } = request;
|
||||
if (isCompressed && !options.decompress) {
|
||||
response.body = response.rawBody;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
response.body = parseBody(response, options.responseType, options.parseJson, options.encoding);
|
||||
}
|
||||
catch (error) {
|
||||
// Fall back to `utf8`
|
||||
try {
|
||||
response.body = response.rawBody.toString();
|
||||
}
|
||||
catch (error) {
|
||||
request._beforeError(new ParseError(error, response));
|
||||
return;
|
||||
}
|
||||
if (isResponseOk(response)) {
|
||||
request._beforeError(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
const hooks = options.hooks.afterResponse;
|
||||
for (const [index, hook] of hooks.entries()) {
|
||||
// @ts-expect-error TS doesn't notice that CancelableRequest is a Promise
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
response = await hook(response, async (updatedOptions) => {
|
||||
options.merge(updatedOptions);
|
||||
options.prefixUrl = '';
|
||||
if (updatedOptions.url) {
|
||||
options.url = updatedOptions.url;
|
||||
}
|
||||
// Remove any further hooks for that request, because we'll call them anyway.
|
||||
// The loop continues. We don't want duplicates (asPromise recursion).
|
||||
options.hooks.afterResponse = options.hooks.afterResponse.slice(0, index);
|
||||
throw new RetryError(request);
|
||||
});
|
||||
if (!(is.object(response) && is.number(response.statusCode) && !is.nullOrUndefined(response.body))) {
|
||||
throw new TypeError('The `afterResponse` hook returned an invalid value');
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
request._beforeError(error);
|
||||
return;
|
||||
}
|
||||
globalResponse = response;
|
||||
if (!isResponseOk(response)) {
|
||||
request._beforeError(new HTTPError(response));
|
||||
return;
|
||||
}
|
||||
request.destroy();
|
||||
resolve(request.options.resolveBodyOnly ? response.body : response);
|
||||
});
|
||||
const onError = (error) => {
|
||||
if (promise.isCanceled) {
|
||||
return;
|
||||
}
|
||||
const { options } = request;
|
||||
if (error instanceof HTTPError && !options.throwHttpErrors) {
|
||||
const { response } = error;
|
||||
request.destroy();
|
||||
resolve(request.options.resolveBodyOnly ? response.body : response);
|
||||
return;
|
||||
}
|
||||
reject(error);
|
||||
};
|
||||
request.once('error', onError);
|
||||
const previousBody = request.options?.body;
|
||||
request.once('retry', (newRetryCount, error) => {
|
||||
firstRequest = undefined;
|
||||
const newBody = request.options.body;
|
||||
if (previousBody === newBody && is.nodeStream(newBody)) {
|
||||
error.message = 'Cannot retry with consumed body stream';
|
||||
onError(error);
|
||||
return;
|
||||
}
|
||||
// This is needed! We need to reuse `request.options` because they can get modified!
|
||||
// For example, by calling `promise.json()`.
|
||||
normalizedOptions = request.options;
|
||||
makeRequest(newRetryCount);
|
||||
});
|
||||
proxyEvents(request, emitter, proxiedRequestEvents);
|
||||
if (is.undefined(firstRequest)) {
|
||||
void request.flush();
|
||||
}
|
||||
};
|
||||
makeRequest(0);
|
||||
});
|
||||
promise.on = (event, function_) => {
|
||||
emitter.on(event, function_);
|
||||
return promise;
|
||||
};
|
||||
promise.off = (event, function_) => {
|
||||
emitter.off(event, function_);
|
||||
return promise;
|
||||
};
|
||||
const shortcut = (responseType) => {
|
||||
const newPromise = (async () => {
|
||||
// Wait until downloading has ended
|
||||
await promise;
|
||||
const { options } = globalResponse.request;
|
||||
return parseBody(globalResponse, responseType, options.parseJson, options.encoding);
|
||||
})();
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
Object.defineProperties(newPromise, Object.getOwnPropertyDescriptors(promise));
|
||||
return newPromise;
|
||||
};
|
||||
promise.json = () => {
|
||||
if (globalRequest.options) {
|
||||
const { headers } = globalRequest.options;
|
||||
if (!globalRequest.writableFinished && !('accept' in headers)) {
|
||||
headers.accept = 'application/json';
|
||||
}
|
||||
}
|
||||
return shortcut('json');
|
||||
};
|
||||
promise.buffer = () => shortcut('buffer');
|
||||
promise.text = () => shortcut('text');
|
||||
return promise;
|
||||
}
|
37
book/node_modules/got/dist/source/as-promise/types.d.ts
generated
vendored
Normal file
37
book/node_modules/got/dist/source/as-promise/types.d.ts
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
import type { Buffer } from 'node:buffer';
|
||||
import type PCancelable from 'p-cancelable';
|
||||
import { RequestError } from '../core/errors.js';
|
||||
import type Request from '../core/index.js';
|
||||
import { type RequestEvents } from '../core/index.js';
|
||||
import type { Response } from '../core/response.js';
|
||||
/**
|
||||
An error to be thrown when the request is aborted with `.cancel()`.
|
||||
*/
|
||||
export declare class CancelError extends RequestError {
|
||||
readonly response: Response;
|
||||
constructor(request: Request);
|
||||
/**
|
||||
Whether the promise is canceled.
|
||||
*/
|
||||
get isCanceled(): boolean;
|
||||
}
|
||||
export interface CancelableRequest<T extends Response | Response['body'] = Response['body']> extends PCancelable<T>, RequestEvents<CancelableRequest<T>> {
|
||||
/**
|
||||
A shortcut method that gives a Promise returning a JSON object.
|
||||
|
||||
It is semantically the same as settings `options.resolveBodyOnly` to `true` and `options.responseType` to `'json'`.
|
||||
*/
|
||||
json: <ReturnType>() => CancelableRequest<ReturnType>;
|
||||
/**
|
||||
A shortcut method that gives a Promise returning a [Buffer](https://nodejs.org/api/buffer.html).
|
||||
|
||||
It is semantically the same as settings `options.resolveBodyOnly` to `true` and `options.responseType` to `'buffer'`.
|
||||
*/
|
||||
buffer: () => CancelableRequest<Buffer>;
|
||||
/**
|
||||
A shortcut method that gives a Promise returning a string.
|
||||
|
||||
It is semantically the same as settings `options.resolveBodyOnly` to `true` and `options.responseType` to `'text'`.
|
||||
*/
|
||||
text: () => CancelableRequest<string>;
|
||||
}
|
17
book/node_modules/got/dist/source/as-promise/types.js
generated
vendored
Normal file
17
book/node_modules/got/dist/source/as-promise/types.js
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
import { RequestError } from '../core/errors.js';
|
||||
/**
|
||||
An error to be thrown when the request is aborted with `.cancel()`.
|
||||
*/
|
||||
export class CancelError extends RequestError {
|
||||
constructor(request) {
|
||||
super('Promise was canceled', {}, request);
|
||||
this.name = 'CancelError';
|
||||
this.code = 'ERR_CANCELED';
|
||||
}
|
||||
/**
|
||||
Whether the promise is canceled.
|
||||
*/
|
||||
get isCanceled() {
|
||||
return true;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user