This commit is contained in:
2025-11-11 00:04:55 -06:00
parent a76ad41fde
commit 40538eddfd
6405 changed files with 1289756 additions and 0 deletions

3
node_modules/got/dist/source/as-promise/index.d.ts generated vendored Normal file
View 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
node_modules/got/dist/source/as-promise/index.js generated vendored Normal file
View 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
node_modules/got/dist/source/as-promise/types.d.ts generated vendored Normal file
View 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
node_modules/got/dist/source/as-promise/types.js generated vendored Normal file
View 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;
}
}

View File

@ -0,0 +1,4 @@
import type { RetryFunction } from './options.js';
type Returns<T extends (...arguments_: any) => unknown, V> = (...arguments_: Parameters<T>) => V;
declare const calculateRetryDelay: Returns<RetryFunction, number>;
export default calculateRetryDelay;

View File

@ -0,0 +1,29 @@
const calculateRetryDelay = ({ attemptCount, retryOptions, error, retryAfter, computedValue, }) => {
if (error.name === 'RetryError') {
return 1;
}
if (attemptCount > retryOptions.limit) {
return 0;
}
const hasMethod = retryOptions.methods.includes(error.options.method);
const hasErrorCode = retryOptions.errorCodes.includes(error.code);
const hasStatusCode = error.response && retryOptions.statusCodes.includes(error.response.statusCode);
if (!hasMethod || (!hasErrorCode && !hasStatusCode)) {
return 0;
}
if (error.response) {
if (retryAfter) {
// In this case `computedValue` is `options.request.timeout`
if (retryAfter > computedValue) {
return 0;
}
return retryAfter;
}
if (error.response.statusCode === 413) {
return 0;
}
}
const noise = Math.random() * retryOptions.noise;
return Math.min(((2 ** (attemptCount - 1)) * 1000), retryOptions.backoffLimit) + noise;
};
export default calculateRetryDelay;

89
node_modules/got/dist/source/core/errors.d.ts generated vendored Normal file
View File

@ -0,0 +1,89 @@
import type { Timings } from '@szmarczak/http-timer';
import type Options from './options.js';
import type { TimeoutError as TimedOutTimeoutError } from './timed-out.js';
import type { PlainResponse, Response } from './response.js';
import type Request from './index.js';
type Error = NodeJS.ErrnoException;
/**
An error to be thrown when a request fails.
Contains a `code` property with error class code, like `ECONNREFUSED`.
*/
export declare class RequestError<T = unknown> extends Error {
input?: string;
code: string;
stack: string;
readonly options: Options;
readonly response?: Response<T>;
readonly request?: Request;
readonly timings?: Timings;
constructor(message: string, error: Partial<Error & {
code?: string;
}>, self: Request | Options);
}
/**
An error to be thrown when the server redirects you more than ten times.
Includes a `response` property.
*/
export declare class MaxRedirectsError extends RequestError {
readonly response: Response;
readonly request: Request;
readonly timings: Timings;
constructor(request: Request);
}
/**
An error to be thrown when the server response code is not 2xx nor 3xx if `options.followRedirect` is `true`, but always except for 304.
Includes a `response` property.
*/
export declare class HTTPError<T = any> extends RequestError<T> {
readonly response: Response<T>;
readonly request: Request;
readonly timings: Timings;
constructor(response: PlainResponse);
}
/**
An error to be thrown when a cache method fails.
For example, if the database goes down or there's a filesystem error.
*/
export declare class CacheError extends RequestError {
readonly request: Request;
constructor(error: Error, request: Request);
}
/**
An error to be thrown when the request body is a stream and an error occurs while reading from that stream.
*/
export declare class UploadError extends RequestError {
readonly request: Request;
constructor(error: Error, request: Request);
}
/**
An error to be thrown when the request is aborted due to a timeout.
Includes an `event` and `timings` property.
*/
export declare class TimeoutError extends RequestError {
readonly request: Request;
readonly timings: Timings;
readonly event: string;
constructor(error: TimedOutTimeoutError, timings: Timings, request: Request);
}
/**
An error to be thrown when reading from response stream fails.
*/
export declare class ReadError extends RequestError {
readonly request: Request;
readonly response: Response;
readonly timings: Timings;
constructor(error: Error, request: Request);
}
/**
An error which always triggers a new retry when thrown.
*/
export declare class RetryError extends RequestError {
constructor(request: Request);
}
/**
An error to be thrown when the request is aborted by AbortController.
*/
export declare class AbortError extends RequestError {
constructor(request: Request);
}
export {};

139
node_modules/got/dist/source/core/errors.js generated vendored Normal file
View File

@ -0,0 +1,139 @@
import is from '@sindresorhus/is';
// A hacky check to prevent circular references.
function isRequest(x) {
return is.object(x) && '_onResponse' in x;
}
/**
An error to be thrown when a request fails.
Contains a `code` property with error class code, like `ECONNREFUSED`.
*/
export class RequestError extends Error {
input;
code;
stack;
response;
request;
timings;
constructor(message, error, self) {
super(message, { cause: error });
Error.captureStackTrace(this, this.constructor);
this.name = 'RequestError';
this.code = error.code ?? 'ERR_GOT_REQUEST_ERROR';
this.input = error.input;
if (isRequest(self)) {
Object.defineProperty(this, 'request', {
enumerable: false,
value: self,
});
Object.defineProperty(this, 'response', {
enumerable: false,
value: self.response,
});
this.options = self.options;
}
else {
this.options = self;
}
this.timings = this.request?.timings;
// Recover the original stacktrace
if (is.string(error.stack) && is.string(this.stack)) {
const indexOfMessage = this.stack.indexOf(this.message) + this.message.length;
const thisStackTrace = this.stack.slice(indexOfMessage).split('\n').reverse();
const errorStackTrace = error.stack.slice(error.stack.indexOf(error.message) + error.message.length).split('\n').reverse();
// Remove duplicated traces
while (errorStackTrace.length > 0 && errorStackTrace[0] === thisStackTrace[0]) {
thisStackTrace.shift();
}
this.stack = `${this.stack.slice(0, indexOfMessage)}${thisStackTrace.reverse().join('\n')}${errorStackTrace.reverse().join('\n')}`;
}
}
}
/**
An error to be thrown when the server redirects you more than ten times.
Includes a `response` property.
*/
export class MaxRedirectsError extends RequestError {
constructor(request) {
super(`Redirected ${request.options.maxRedirects} times. Aborting.`, {}, request);
this.name = 'MaxRedirectsError';
this.code = 'ERR_TOO_MANY_REDIRECTS';
}
}
/**
An error to be thrown when the server response code is not 2xx nor 3xx if `options.followRedirect` is `true`, but always except for 304.
Includes a `response` property.
*/
// TODO: Change `HTTPError<T = any>` to `HTTPError<T = unknown>` in the next major version to enforce type usage.
// eslint-disable-next-line @typescript-eslint/naming-convention
export class HTTPError extends RequestError {
constructor(response) {
super(`Response code ${response.statusCode} (${response.statusMessage})`, {}, response.request);
this.name = 'HTTPError';
this.code = 'ERR_NON_2XX_3XX_RESPONSE';
}
}
/**
An error to be thrown when a cache method fails.
For example, if the database goes down or there's a filesystem error.
*/
export class CacheError extends RequestError {
constructor(error, request) {
super(error.message, error, request);
this.name = 'CacheError';
this.code = this.code === 'ERR_GOT_REQUEST_ERROR' ? 'ERR_CACHE_ACCESS' : this.code;
}
}
/**
An error to be thrown when the request body is a stream and an error occurs while reading from that stream.
*/
export class UploadError extends RequestError {
constructor(error, request) {
super(error.message, error, request);
this.name = 'UploadError';
this.code = this.code === 'ERR_GOT_REQUEST_ERROR' ? 'ERR_UPLOAD' : this.code;
}
}
/**
An error to be thrown when the request is aborted due to a timeout.
Includes an `event` and `timings` property.
*/
export class TimeoutError extends RequestError {
timings;
event;
constructor(error, timings, request) {
super(error.message, error, request);
this.name = 'TimeoutError';
this.event = error.event;
this.timings = timings;
}
}
/**
An error to be thrown when reading from response stream fails.
*/
export class ReadError extends RequestError {
constructor(error, request) {
super(error.message, error, request);
this.name = 'ReadError';
this.code = this.code === 'ERR_GOT_REQUEST_ERROR' ? 'ERR_READING_RESPONSE_STREAM' : this.code;
}
}
/**
An error which always triggers a new retry when thrown.
*/
export class RetryError extends RequestError {
constructor(request) {
super('Retrying', {}, request);
this.name = 'RetryError';
this.code = 'ERR_RETRYING';
}
}
/**
An error to be thrown when the request is aborted by AbortController.
*/
export class AbortError extends RequestError {
constructor(request) {
super('This operation was aborted.', {}, request);
this.code = 'ERR_ABORTED';
this.name = 'AbortError';
}
}

185
node_modules/got/dist/source/core/index.d.ts generated vendored Normal file
View File

@ -0,0 +1,185 @@
import { Duplex } from 'node:stream';
import { type ClientRequest } from 'node:http';
import type { Socket } from 'node:net';
import { type Timings } from '@szmarczak/http-timer';
import Options from './options.js';
import { type PlainResponse, type Response } from './response.js';
import { RequestError } from './errors.js';
type Error = NodeJS.ErrnoException;
export type Progress = {
percent: number;
transferred: number;
total?: number;
};
export type GotEventFunction<T> =
/**
`request` event to get the request object of the request.
__Tip__: You can use `request` event to abort requests.
@example
```
import got from 'got';
got.stream('https://github.com')
.on('request', request => setTimeout(() => request.destroy(), 50));
```
*/
((name: 'request', listener: (request: ClientRequest) => void) => T)
/**
The `response` event to get the response object of the final request.
*/
& (<R extends Response>(name: 'response', listener: (response: R) => void) => T)
/**
The `redirect` event to get the response object of a redirect. The second argument is options for the next request to the redirect location.
*/
& (<R extends Response, N extends Options>(name: 'redirect', listener: (response: R, nextOptions: N) => void) => T)
/**
Progress events for uploading (sending a request) and downloading (receiving a response).
The `progress` argument is an object like:
```
{
percent: 0.1,
transferred: 1024,
total: 10240
}
```
If the `content-length` header is missing, `total` will be `undefined`.
@example
```
import got from 'got';
const response = await got('https://sindresorhus.com')
.on('downloadProgress', progress => {
// Report download progress
})
.on('uploadProgress', progress => {
// Report upload progress
});
console.log(response);
```
*/
& ((name: 'uploadProgress' | 'downloadProgress', listener: (progress: Progress) => void) => T)
/**
To enable retrying on a Got stream, it is required to have a `retry` handler attached.
When this event is emitted, you should reset the stream you were writing to and prepare the body again.
See `got.options.retry` for more information.
*/
& ((name: 'retry', listener: (retryCount: number, error: RequestError) => void) => T);
export type RequestEvents<T> = {
on: GotEventFunction<T>;
once: GotEventFunction<T>;
off: GotEventFunction<T>;
};
type UrlType = ConstructorParameters<typeof Options>[0];
type OptionsType = ConstructorParameters<typeof Options>[1];
type DefaultsType = ConstructorParameters<typeof Options>[2];
export default class Request extends Duplex implements RequestEvents<Request> {
['constructor']: typeof Request;
_noPipe?: boolean;
options: Options;
response?: PlainResponse;
requestUrl?: URL;
redirectUrls: URL[];
retryCount: number;
private _requestOptions;
private _stopRetry;
private _downloadedSize;
private _uploadedSize;
private _stopReading;
private readonly _pipedServerResponses;
private _request?;
private _responseSize?;
private _bodySize?;
private _unproxyEvents;
private _isFromCache?;
private _cannotHaveBody;
private _triggerRead;
private readonly _jobs;
private _cancelTimeouts;
private readonly _removeListeners;
private _nativeResponse?;
private _flushed;
private _aborted;
private _requestInitialized;
constructor(url: UrlType, options?: OptionsType, defaults?: DefaultsType);
flush(): Promise<void>;
_beforeError(error: Error): void;
_read(): void;
_write(chunk: unknown, encoding: BufferEncoding | undefined, callback: (error?: Error | null) => void): void;
_final(callback: (error?: Error | null) => void): void;
_destroy(error: Error | null, callback: (error: Error | null) => void): void;
pipe<T extends NodeJS.WritableStream>(destination: T, options?: {
end?: boolean;
}): T;
unpipe<T extends NodeJS.WritableStream>(destination: T): this;
private _finalizeBody;
private _onResponseBase;
private _setRawBody;
private _onResponse;
private _onRequest;
private _asyncWrite;
private _sendBody;
private _prepareCache;
private _createCacheableRequest;
private _makeRequest;
private _error;
private _writeRequest;
/**
The remote IP address.
*/
get ip(): string | undefined;
/**
Indicates whether the request has been aborted or not.
*/
get isAborted(): boolean;
get socket(): Socket | undefined;
/**
Progress event for downloading (receiving a response).
*/
get downloadProgress(): Progress;
/**
Progress event for uploading (sending a request).
*/
get uploadProgress(): Progress;
/**
The object contains the following properties:
- `start` - Time when the request started.
- `socket` - Time when a socket was assigned to the request.
- `lookup` - Time when the DNS lookup finished.
- `connect` - Time when the socket successfully connected.
- `secureConnect` - Time when the socket securely connected.
- `upload` - Time when the request finished uploading.
- `response` - Time when the request fired `response` event.
- `end` - Time when the response fired `end` event.
- `error` - Time when the request fired `error` event.
- `abort` - Time when the request fired `abort` event.
- `phases`
- `wait` - `timings.socket - timings.start`
- `dns` - `timings.lookup - timings.socket`
- `tcp` - `timings.connect - timings.lookup`
- `tls` - `timings.secureConnect - timings.connect`
- `request` - `timings.upload - (timings.secureConnect || timings.connect)`
- `firstByte` - `timings.response - timings.upload`
- `download` - `timings.end - timings.response`
- `total` - `(timings.end || timings.error || timings.abort) - timings.start`
If something has not been measured yet, it will be `undefined`.
__Note__: The time is a `number` representing the milliseconds elapsed since the UNIX epoch.
*/
get timings(): Timings | undefined;
/**
Whether the response was retrieved from the cache.
*/
get isFromCache(): boolean | undefined;
get reusedSocket(): boolean | undefined;
}
export {};

999
node_modules/got/dist/source/core/index.js generated vendored Normal file
View File

@ -0,0 +1,999 @@
import process from 'node:process';
import { Buffer } from 'node:buffer';
import { Duplex } from 'node:stream';
import http, { ServerResponse } from 'node:http';
import timer from '@szmarczak/http-timer';
import CacheableRequest, { CacheError as CacheableCacheError, } from 'cacheable-request';
import decompressResponse from 'decompress-response';
import is, { isBuffer } from '@sindresorhus/is';
import { FormDataEncoder, isFormData as isFormDataLike } from 'form-data-encoder';
import getBodySize from './utils/get-body-size.js';
import isFormData from './utils/is-form-data.js';
import proxyEvents from './utils/proxy-events.js';
import timedOut, { TimeoutError as TimedOutTimeoutError } from './timed-out.js';
import urlToOptions from './utils/url-to-options.js';
import WeakableMap from './utils/weakable-map.js';
import calculateRetryDelay from './calculate-retry-delay.js';
import Options from './options.js';
import { isResponseOk } from './response.js';
import isClientRequest from './utils/is-client-request.js';
import isUnixSocketURL from './utils/is-unix-socket-url.js';
import { RequestError, ReadError, MaxRedirectsError, HTTPError, TimeoutError, UploadError, CacheError, AbortError, } from './errors.js';
const supportsBrotli = is.string(process.versions.brotli);
const methodsWithoutBody = new Set(['GET', 'HEAD']);
const cacheableStore = new WeakableMap();
const redirectCodes = new Set([300, 301, 302, 303, 304, 307, 308]);
const proxiedRequestEvents = [
'socket',
'connect',
'continue',
'information',
'upgrade',
];
const noop = () => { };
export default class Request extends Duplex {
// @ts-expect-error - Ignoring for now.
['constructor'];
_noPipe;
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/9568
options;
response;
requestUrl;
redirectUrls;
retryCount;
_stopRetry;
_downloadedSize;
_uploadedSize;
_stopReading;
_pipedServerResponses;
_request;
_responseSize;
_bodySize;
_unproxyEvents;
_isFromCache;
_cannotHaveBody;
_triggerRead;
_cancelTimeouts;
_removeListeners;
_nativeResponse;
_flushed;
_aborted;
// We need this because `this._request` if `undefined` when using cache
_requestInitialized;
constructor(url, options, defaults) {
super({
// Don't destroy immediately, as the error may be emitted on unsuccessful retry
autoDestroy: false,
// It needs to be zero because we're just proxying the data to another stream
highWaterMark: 0,
});
this._downloadedSize = 0;
this._uploadedSize = 0;
this._stopReading = false;
this._pipedServerResponses = new Set();
this._cannotHaveBody = false;
this._unproxyEvents = noop;
this._triggerRead = false;
this._cancelTimeouts = noop;
this._removeListeners = noop;
this._jobs = [];
this._flushed = false;
this._requestInitialized = false;
this._aborted = false;
this.redirectUrls = [];
this.retryCount = 0;
this._stopRetry = noop;
this.on('pipe', (source) => {
if (source?.headers) {
Object.assign(this.options.headers, source.headers);
}
});
this.on('newListener', event => {
if (event === 'retry' && this.listenerCount('retry') > 0) {
throw new Error('A retry listener has been attached already.');
}
});
try {
this.options = new Options(url, options, defaults);
if (!this.options.url) {
if (this.options.prefixUrl === '') {
throw new TypeError('Missing `url` property');
}
this.options.url = '';
}
this.requestUrl = this.options.url;
}
catch (error) {
const { options } = error;
if (options) {
this.options = options;
}
this.flush = async () => {
this.flush = async () => { };
this.destroy(error);
};
return;
}
// Important! If you replace `body` in a handler with another stream, make sure it's readable first.
// The below is run only once.
const { body } = this.options;
if (is.nodeStream(body)) {
body.once('error', error => {
if (this._flushed) {
this._beforeError(new UploadError(error, this));
}
else {
this.flush = async () => {
this.flush = async () => { };
this._beforeError(new UploadError(error, this));
};
}
});
}
if (this.options.signal) {
const abort = () => {
this.destroy(new AbortError(this));
};
if (this.options.signal.aborted) {
abort();
}
else {
this.options.signal.addEventListener('abort', abort);
this._removeListeners = () => {
this.options.signal?.removeEventListener('abort', abort);
};
}
}
}
async flush() {
if (this._flushed) {
return;
}
this._flushed = true;
try {
await this._finalizeBody();
if (this.destroyed) {
return;
}
await this._makeRequest();
if (this.destroyed) {
this._request?.destroy();
return;
}
// Queued writes etc.
for (const job of this._jobs) {
job();
}
// Prevent memory leak
this._jobs.length = 0;
this._requestInitialized = true;
}
catch (error) {
this._beforeError(error);
}
}
_beforeError(error) {
if (this._stopReading) {
return;
}
const { response, options } = this;
const attemptCount = this.retryCount + (error.name === 'RetryError' ? 0 : 1);
this._stopReading = true;
if (!(error instanceof RequestError)) {
error = new RequestError(error.message, error, this);
}
const typedError = error;
void (async () => {
// Node.js parser is really weird.
// It emits post-request Parse Errors on the same instance as previous request. WTF.
// Therefore, we need to check if it has been destroyed as well.
//
// Furthermore, Node.js 16 `response.destroy()` doesn't immediately destroy the socket,
// but makes the response unreadable. So we additionally need to check `response.readable`.
if (response?.readable && !response.rawBody && !this._request?.socket?.destroyed) {
// @types/node has incorrect typings. `setEncoding` accepts `null` as well.
response.setEncoding(this.readableEncoding);
const success = await this._setRawBody(response);
if (success) {
response.body = response.rawBody.toString();
}
}
if (this.listenerCount('retry') !== 0) {
let backoff;
try {
let retryAfter;
if (response && 'retry-after' in response.headers) {
retryAfter = Number(response.headers['retry-after']);
if (Number.isNaN(retryAfter)) {
retryAfter = Date.parse(response.headers['retry-after']) - Date.now();
if (retryAfter <= 0) {
retryAfter = 1;
}
}
else {
retryAfter *= 1000;
}
}
const retryOptions = options.retry;
backoff = await retryOptions.calculateDelay({
attemptCount,
retryOptions,
error: typedError,
retryAfter,
computedValue: calculateRetryDelay({
attemptCount,
retryOptions,
error: typedError,
retryAfter,
computedValue: retryOptions.maxRetryAfter ?? options.timeout.request ?? Number.POSITIVE_INFINITY,
}),
});
}
catch (error_) {
void this._error(new RequestError(error_.message, error_, this));
return;
}
if (backoff) {
await new Promise(resolve => {
const timeout = setTimeout(resolve, backoff);
this._stopRetry = () => {
clearTimeout(timeout);
resolve();
};
});
// Something forced us to abort the retry
if (this.destroyed) {
return;
}
try {
for (const hook of this.options.hooks.beforeRetry) {
// eslint-disable-next-line no-await-in-loop
await hook(typedError, this.retryCount + 1);
}
}
catch (error_) {
void this._error(new RequestError(error_.message, error, this));
return;
}
// Something forced us to abort the retry
if (this.destroyed) {
return;
}
this.destroy();
this.emit('retry', this.retryCount + 1, error, (updatedOptions) => {
const request = new Request(options.url, updatedOptions, options);
request.retryCount = this.retryCount + 1;
process.nextTick(() => {
void request.flush();
});
return request;
});
return;
}
}
void this._error(typedError);
})();
}
_read() {
this._triggerRead = true;
const { response } = this;
if (response && !this._stopReading) {
// We cannot put this in the `if` above
// because `.read()` also triggers the `end` event
if (response.readableLength) {
this._triggerRead = false;
}
let data;
while ((data = response.read()) !== null) {
this._downloadedSize += data.length; // eslint-disable-line @typescript-eslint/restrict-plus-operands
const progress = this.downloadProgress;
if (progress.percent < 1) {
this.emit('downloadProgress', progress);
}
this.push(data);
}
}
}
_write(chunk, encoding, callback) {
const write = () => {
this._writeRequest(chunk, encoding, callback);
};
if (this._requestInitialized) {
write();
}
else {
this._jobs.push(write);
}
}
_final(callback) {
const endRequest = () => {
// We need to check if `this._request` is present,
// because it isn't when we use cache.
if (!this._request || this._request.destroyed) {
callback();
return;
}
this._request.end((error) => {
// The request has been destroyed before `_final` finished.
// See https://github.com/nodejs/node/issues/39356
if (this._request._writableState?.errored) {
return;
}
if (!error) {
this._bodySize = this._uploadedSize;
this.emit('uploadProgress', this.uploadProgress);
this._request.emit('upload-complete');
}
callback(error);
});
};
if (this._requestInitialized) {
endRequest();
}
else {
this._jobs.push(endRequest);
}
}
_destroy(error, callback) {
this._stopReading = true;
this.flush = async () => { };
// Prevent further retries
this._stopRetry();
this._cancelTimeouts();
this._removeListeners();
if (this.options) {
const { body } = this.options;
if (is.nodeStream(body)) {
body.destroy();
}
}
if (this._request) {
this._request.destroy();
}
if (error !== null && !is.undefined(error) && !(error instanceof RequestError)) {
error = new RequestError(error.message, error, this);
}
callback(error);
}
pipe(destination, options) {
if (destination instanceof ServerResponse) {
this._pipedServerResponses.add(destination);
}
return super.pipe(destination, options);
}
unpipe(destination) {
if (destination instanceof ServerResponse) {
this._pipedServerResponses.delete(destination);
}
super.unpipe(destination);
return this;
}
async _finalizeBody() {
const { options } = this;
const { headers } = options;
const isForm = !is.undefined(options.form);
// eslint-disable-next-line @typescript-eslint/naming-convention
const isJSON = !is.undefined(options.json);
const isBody = !is.undefined(options.body);
const cannotHaveBody = methodsWithoutBody.has(options.method) && !(options.method === 'GET' && options.allowGetBody);
this._cannotHaveBody = cannotHaveBody;
if (isForm || isJSON || isBody) {
if (cannotHaveBody) {
throw new TypeError(`The \`${options.method}\` method cannot be used with a body`);
}
// Serialize body
const noContentType = !is.string(headers['content-type']);
if (isBody) {
// Body is spec-compliant FormData
if (isFormDataLike(options.body)) {
const encoder = new FormDataEncoder(options.body);
if (noContentType) {
headers['content-type'] = encoder.headers['Content-Type'];
}
if ('Content-Length' in encoder.headers) {
headers['content-length'] = encoder.headers['Content-Length'];
}
options.body = encoder.encode();
}
// Special case for https://github.com/form-data/form-data
if (isFormData(options.body) && noContentType) {
headers['content-type'] = `multipart/form-data; boundary=${options.body.getBoundary()}`;
}
}
else if (isForm) {
if (noContentType) {
headers['content-type'] = 'application/x-www-form-urlencoded';
}
const { form } = options;
options.form = undefined;
options.body = (new URLSearchParams(form)).toString();
}
else {
if (noContentType) {
headers['content-type'] = 'application/json';
}
const { json } = options;
options.json = undefined;
options.body = options.stringifyJson(json);
}
const uploadBodySize = await getBodySize(options.body, options.headers);
// See https://tools.ietf.org/html/rfc7230#section-3.3.2
// A user agent SHOULD send a Content-Length in a request message when
// no Transfer-Encoding is sent and the request method defines a meaning
// for an enclosed payload body. For example, a Content-Length header
// field is normally sent in a POST request even when the value is 0
// (indicating an empty payload body). A user agent SHOULD NOT send a
// Content-Length header field when the request message does not contain
// a payload body and the method semantics do not anticipate such a
// body.
if (is.undefined(headers['content-length']) && is.undefined(headers['transfer-encoding']) && !cannotHaveBody && !is.undefined(uploadBodySize)) {
headers['content-length'] = String(uploadBodySize);
}
}
if (options.responseType === 'json' && !('accept' in options.headers)) {
options.headers.accept = 'application/json';
}
this._bodySize = Number(headers['content-length']) || undefined;
}
async _onResponseBase(response) {
// This will be called e.g. when using cache so we need to check if this request has been aborted.
if (this.isAborted) {
return;
}
const { options } = this;
const { url } = options;
this._nativeResponse = response;
if (options.decompress) {
response = decompressResponse(response);
}
const statusCode = response.statusCode;
const typedResponse = response;
typedResponse.statusMessage = typedResponse.statusMessage ?? http.STATUS_CODES[statusCode];
typedResponse.url = options.url.toString();
typedResponse.requestUrl = this.requestUrl;
typedResponse.redirectUrls = this.redirectUrls;
typedResponse.request = this;
typedResponse.isFromCache = this._nativeResponse.fromCache ?? false;
typedResponse.ip = this.ip;
typedResponse.retryCount = this.retryCount;
typedResponse.ok = isResponseOk(typedResponse);
this._isFromCache = typedResponse.isFromCache;
this._responseSize = Number(response.headers['content-length']) || undefined;
this.response = typedResponse;
response.once('end', () => {
this._responseSize = this._downloadedSize;
this.emit('downloadProgress', this.downloadProgress);
});
response.once('error', (error) => {
this._aborted = true;
// Force clean-up, because some packages don't do this.
// TODO: Fix decompress-response
response.destroy();
this._beforeError(new ReadError(error, this));
});
response.once('aborted', () => {
this._aborted = true;
this._beforeError(new ReadError({
name: 'Error',
message: 'The server aborted pending request',
code: 'ECONNRESET',
}, this));
});
this.emit('downloadProgress', this.downloadProgress);
const rawCookies = response.headers['set-cookie'];
if (is.object(options.cookieJar) && rawCookies) {
let promises = rawCookies.map(async (rawCookie) => options.cookieJar.setCookie(rawCookie, url.toString()));
if (options.ignoreInvalidCookies) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
promises = promises.map(async (promise) => {
try {
await promise;
}
catch { }
});
}
try {
await Promise.all(promises);
}
catch (error) {
this._beforeError(error);
return;
}
}
// The above is running a promise, therefore we need to check if this request has been aborted yet again.
if (this.isAborted) {
return;
}
if (response.headers.location && redirectCodes.has(statusCode)) {
// We're being redirected, we don't care about the response.
// It'd be best to abort the request, but we can't because
// we would have to sacrifice the TCP connection. We don't want that.
const shouldFollow = typeof options.followRedirect === 'function' ? options.followRedirect(typedResponse) : options.followRedirect;
if (shouldFollow) {
response.resume();
this._cancelTimeouts();
this._unproxyEvents();
if (this.redirectUrls.length >= options.maxRedirects) {
this._beforeError(new MaxRedirectsError(this));
return;
}
this._request = undefined;
const updatedOptions = new Options(undefined, undefined, this.options);
const serverRequestedGet = statusCode === 303 && updatedOptions.method !== 'GET' && updatedOptions.method !== 'HEAD';
const canRewrite = statusCode !== 307 && statusCode !== 308;
const userRequestedGet = updatedOptions.methodRewriting && canRewrite;
if (serverRequestedGet || userRequestedGet) {
updatedOptions.method = 'GET';
updatedOptions.body = undefined;
updatedOptions.json = undefined;
updatedOptions.form = undefined;
delete updatedOptions.headers['content-length'];
}
try {
// We need this in order to support UTF-8
const redirectBuffer = Buffer.from(response.headers.location, 'binary').toString();
const redirectUrl = new URL(redirectBuffer, url);
if (!isUnixSocketURL(url) && isUnixSocketURL(redirectUrl)) {
this._beforeError(new RequestError('Cannot redirect to UNIX socket', {}, this));
return;
}
// Redirecting to a different site, clear sensitive data.
if (redirectUrl.hostname !== url.hostname || redirectUrl.port !== url.port) {
if ('host' in updatedOptions.headers) {
delete updatedOptions.headers.host;
}
if ('cookie' in updatedOptions.headers) {
delete updatedOptions.headers.cookie;
}
if ('authorization' in updatedOptions.headers) {
delete updatedOptions.headers.authorization;
}
if (updatedOptions.username || updatedOptions.password) {
updatedOptions.username = '';
updatedOptions.password = '';
}
}
else {
redirectUrl.username = updatedOptions.username;
redirectUrl.password = updatedOptions.password;
}
this.redirectUrls.push(redirectUrl);
updatedOptions.prefixUrl = '';
updatedOptions.url = redirectUrl;
for (const hook of updatedOptions.hooks.beforeRedirect) {
// eslint-disable-next-line no-await-in-loop
await hook(updatedOptions, typedResponse);
}
this.emit('redirect', updatedOptions, typedResponse);
this.options = updatedOptions;
await this._makeRequest();
}
catch (error) {
this._beforeError(error);
return;
}
return;
}
}
// `HTTPError`s always have `error.response.body` defined.
// Therefore, we cannot retry if `options.throwHttpErrors` is false.
// On the last retry, if `options.throwHttpErrors` is false, we would need to return the body,
// but that wouldn't be possible since the body would be already read in `error.response.body`.
if (options.isStream && options.throwHttpErrors && !isResponseOk(typedResponse)) {
this._beforeError(new HTTPError(typedResponse));
return;
}
response.on('readable', () => {
if (this._triggerRead) {
this._read();
}
});
this.on('resume', () => {
response.resume();
});
this.on('pause', () => {
response.pause();
});
response.once('end', () => {
this.push(null);
});
if (this._noPipe) {
const success = await this._setRawBody();
if (success) {
this.emit('response', response);
}
return;
}
this.emit('response', response);
for (const destination of this._pipedServerResponses) {
if (destination.headersSent) {
continue;
}
// eslint-disable-next-line guard-for-in
for (const key in response.headers) {
const isAllowed = options.decompress ? key !== 'content-encoding' : true;
const value = response.headers[key];
if (isAllowed) {
destination.setHeader(key, value);
}
}
destination.statusCode = statusCode;
}
}
async _setRawBody(from = this) {
if (from.readableEnded) {
return false;
}
try {
// Errors are emitted via the `error` event
const fromArray = await from.toArray();
const rawBody = isBuffer(fromArray.at(0)) ? Buffer.concat(fromArray) : Buffer.from(fromArray.join(''));
// On retry Request is destroyed with no error, therefore the above will successfully resolve.
// So in order to check if this was really successfull, we need to check if it has been properly ended.
if (!this.isAborted) {
this.response.rawBody = rawBody;
return true;
}
}
catch { }
return false;
}
async _onResponse(response) {
try {
await this._onResponseBase(response);
}
catch (error) {
/* istanbul ignore next: better safe than sorry */
this._beforeError(error);
}
}
_onRequest(request) {
const { options } = this;
const { timeout, url } = options;
timer(request);
if (this.options.http2) {
// Unset stream timeout, as the `timeout` option was used only for connection timeout.
request.setTimeout(0);
}
this._cancelTimeouts = timedOut(request, timeout, url);
const responseEventName = options.cache ? 'cacheableResponse' : 'response';
request.once(responseEventName, (response) => {
void this._onResponse(response);
});
request.once('error', (error) => {
this._aborted = true;
// Force clean-up, because some packages (e.g. nock) don't do this.
request.destroy();
error = error instanceof TimedOutTimeoutError ? new TimeoutError(error, this.timings, this) : new RequestError(error.message, error, this);
this._beforeError(error);
});
this._unproxyEvents = proxyEvents(request, this, proxiedRequestEvents);
this._request = request;
this.emit('uploadProgress', this.uploadProgress);
this._sendBody();
this.emit('request', request);
}
async _asyncWrite(chunk) {
return new Promise((resolve, reject) => {
super.write(chunk, error => {
if (error) {
reject(error);
return;
}
resolve();
});
});
}
_sendBody() {
// Send body
const { body } = this.options;
const currentRequest = this.redirectUrls.length === 0 ? this : this._request ?? this;
if (is.nodeStream(body)) {
body.pipe(currentRequest);
}
else if (is.generator(body) || is.asyncGenerator(body)) {
(async () => {
try {
for await (const chunk of body) {
await this._asyncWrite(chunk);
}
super.end();
}
catch (error) {
this._beforeError(error);
}
})();
}
else if (!is.undefined(body)) {
this._writeRequest(body, undefined, () => { });
currentRequest.end();
}
else if (this._cannotHaveBody || this._noPipe) {
currentRequest.end();
}
}
_prepareCache(cache) {
if (!cacheableStore.has(cache)) {
const cacheableRequest = new CacheableRequest(((requestOptions, handler) => {
const result = requestOptions._request(requestOptions, handler);
// TODO: remove this when `cacheable-request` supports async request functions.
if (is.promise(result)) {
// We only need to implement the error handler in order to support HTTP2 caching.
// The result will be a promise anyway.
// @ts-expect-error ignore
result.once = (event, handler) => {
if (event === 'error') {
(async () => {
try {
await result;
}
catch (error) {
handler(error);
}
})();
}
else if (event === 'abort') {
// The empty catch is needed here in case when
// it rejects before it's `await`ed in `_makeRequest`.
(async () => {
try {
const request = (await result);
request.once('abort', handler);
}
catch { }
})();
}
else {
/* istanbul ignore next: safety check */
throw new Error(`Unknown HTTP2 promise event: ${event}`);
}
return result;
};
}
return result;
}), cache);
cacheableStore.set(cache, cacheableRequest.request());
}
}
async _createCacheableRequest(url, options) {
return new Promise((resolve, reject) => {
// TODO: Remove `utils/url-to-options.ts` when `cacheable-request` is fixed
Object.assign(options, urlToOptions(url));
let request;
// TODO: Fix `cacheable-response`. This is ugly.
const cacheRequest = cacheableStore.get(options.cache)(options, async (response) => {
response._readableState.autoDestroy = false;
if (request) {
const fix = () => {
if (response.req) {
response.complete = response.req.res.complete;
}
};
response.prependOnceListener('end', fix);
fix();
(await request).emit('cacheableResponse', response);
}
resolve(response);
});
cacheRequest.once('error', reject);
cacheRequest.once('request', async (requestOrPromise) => {
request = requestOrPromise;
resolve(request);
});
});
}
async _makeRequest() {
const { options } = this;
const { headers, username, password } = options;
const cookieJar = options.cookieJar;
for (const key in headers) {
if (is.undefined(headers[key])) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete headers[key];
}
else if (is.null(headers[key])) {
throw new TypeError(`Use \`undefined\` instead of \`null\` to delete the \`${key}\` header`);
}
}
if (options.decompress && is.undefined(headers['accept-encoding'])) {
headers['accept-encoding'] = supportsBrotli ? 'gzip, deflate, br' : 'gzip, deflate';
}
if (username || password) {
const credentials = Buffer.from(`${username}:${password}`).toString('base64');
headers.authorization = `Basic ${credentials}`;
}
// Set cookies
if (cookieJar) {
const cookieString = await cookieJar.getCookieString(options.url.toString());
if (is.nonEmptyString(cookieString)) {
headers.cookie = cookieString;
}
}
// Reset `prefixUrl`
options.prefixUrl = '';
let request;
for (const hook of options.hooks.beforeRequest) {
// eslint-disable-next-line no-await-in-loop
const result = await hook(options);
if (!is.undefined(result)) {
// @ts-expect-error Skip the type mismatch to support abstract responses
request = () => result;
break;
}
}
request ||= options.getRequestFunction();
const url = options.url;
this._requestOptions = options.createNativeRequestOptions();
if (options.cache) {
this._requestOptions._request = request;
this._requestOptions.cache = options.cache;
this._requestOptions.body = options.body;
this._prepareCache(options.cache);
}
// Cache support
const function_ = options.cache ? this._createCacheableRequest : request;
try {
// We can't do `await fn(...)`,
// because stream `error` event can be emitted before `Promise.resolve()`.
let requestOrResponse = function_(url, this._requestOptions);
if (is.promise(requestOrResponse)) {
requestOrResponse = await requestOrResponse;
}
// Fallback
if (is.undefined(requestOrResponse)) {
requestOrResponse = options.getFallbackRequestFunction()(url, this._requestOptions);
if (is.promise(requestOrResponse)) {
requestOrResponse = await requestOrResponse;
}
}
if (isClientRequest(requestOrResponse)) {
this._onRequest(requestOrResponse);
}
else if (this.writable) {
this.once('finish', () => {
void this._onResponse(requestOrResponse);
});
this._sendBody();
}
else {
void this._onResponse(requestOrResponse);
}
}
catch (error) {
if (error instanceof CacheableCacheError) {
throw new CacheError(error, this);
}
throw error;
}
}
async _error(error) {
try {
if (error instanceof HTTPError && !this.options.throwHttpErrors) {
// This branch can be reached only when using the Promise API
// Skip calling the hooks on purpose.
// See https://github.com/sindresorhus/got/issues/2103
}
else {
for (const hook of this.options.hooks.beforeError) {
// eslint-disable-next-line no-await-in-loop
error = await hook(error);
}
}
}
catch (error_) {
error = new RequestError(error_.message, error_, this);
}
this.destroy(error);
}
_writeRequest(chunk, encoding, callback) {
if (!this._request || this._request.destroyed) {
// Probably the `ClientRequest` instance will throw
return;
}
this._request.write(chunk, encoding, (error) => {
// The `!destroyed` check is required to prevent `uploadProgress` being emitted after the stream was destroyed
if (!error && !this._request.destroyed) {
this._uploadedSize += Buffer.byteLength(chunk, encoding);
const progress = this.uploadProgress;
if (progress.percent < 1) {
this.emit('uploadProgress', progress);
}
}
callback(error);
});
}
/**
The remote IP address.
*/
get ip() {
return this.socket?.remoteAddress;
}
/**
Indicates whether the request has been aborted or not.
*/
get isAborted() {
return this._aborted;
}
get socket() {
return this._request?.socket ?? undefined;
}
/**
Progress event for downloading (receiving a response).
*/
get downloadProgress() {
let percent;
if (this._responseSize) {
percent = this._downloadedSize / this._responseSize;
}
else if (this._responseSize === this._downloadedSize) {
percent = 1;
}
else {
percent = 0;
}
return {
percent,
transferred: this._downloadedSize,
total: this._responseSize,
};
}
/**
Progress event for uploading (sending a request).
*/
get uploadProgress() {
let percent;
if (this._bodySize) {
percent = this._uploadedSize / this._bodySize;
}
else if (this._bodySize === this._uploadedSize) {
percent = 1;
}
else {
percent = 0;
}
return {
percent,
transferred: this._uploadedSize,
total: this._bodySize,
};
}
/**
The object contains the following properties:
- `start` - Time when the request started.
- `socket` - Time when a socket was assigned to the request.
- `lookup` - Time when the DNS lookup finished.
- `connect` - Time when the socket successfully connected.
- `secureConnect` - Time when the socket securely connected.
- `upload` - Time when the request finished uploading.
- `response` - Time when the request fired `response` event.
- `end` - Time when the response fired `end` event.
- `error` - Time when the request fired `error` event.
- `abort` - Time when the request fired `abort` event.
- `phases`
- `wait` - `timings.socket - timings.start`
- `dns` - `timings.lookup - timings.socket`
- `tcp` - `timings.connect - timings.lookup`
- `tls` - `timings.secureConnect - timings.connect`
- `request` - `timings.upload - (timings.secureConnect || timings.connect)`
- `firstByte` - `timings.response - timings.upload`
- `download` - `timings.end - timings.response`
- `total` - `(timings.end || timings.error || timings.abort) - timings.start`
If something has not been measured yet, it will be `undefined`.
__Note__: The time is a `number` representing the milliseconds elapsed since the UNIX epoch.
*/
get timings() {
return this._request?.timings;
}
/**
Whether the response was retrieved from the cache.
*/
get isFromCache() {
return this._isFromCache;
}
get reusedSocket() {
return this._request?.reusedSocket;
}
}

1247
node_modules/got/dist/source/core/options.d.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

1635
node_modules/got/dist/source/core/options.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
export default function parseLinkHeader(link: string): {
reference: string;
parameters: Record<string, string>;
}[];

33
node_modules/got/dist/source/core/parse-link-header.js generated vendored Normal file
View File

@ -0,0 +1,33 @@
export default function parseLinkHeader(link) {
const parsed = [];
const items = link.split(',');
for (const item of items) {
// https://tools.ietf.org/html/rfc5988#section-5
const [rawUriReference, ...rawLinkParameters] = item.split(';');
const trimmedUriReference = rawUriReference.trim();
// eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
if (trimmedUriReference[0] !== '<' || trimmedUriReference.at(-1) !== '>') {
throw new Error(`Invalid format of the Link header reference: ${trimmedUriReference}`);
}
const reference = trimmedUriReference.slice(1, -1);
const parameters = {};
if (rawLinkParameters.length === 0) {
throw new Error(`Unexpected end of Link header parameters: ${rawLinkParameters.join(';')}`);
}
for (const rawParameter of rawLinkParameters) {
const trimmedRawParameter = rawParameter.trim();
const center = trimmedRawParameter.indexOf('=');
if (center === -1) {
throw new Error(`Failed to parse Link header: ${link}`);
}
const name = trimmedRawParameter.slice(0, center).trim();
const value = trimmedRawParameter.slice(center + 1).trim();
parameters[name] = value;
}
parsed.push({
reference,
parameters,
});
}
return parsed;
}

107
node_modules/got/dist/source/core/response.d.ts generated vendored Normal file
View File

@ -0,0 +1,107 @@
import type { Buffer } from 'node:buffer';
import type { IncomingMessageWithTimings, Timings } from '@szmarczak/http-timer';
import { RequestError } from './errors.js';
import type { ParseJsonFunction, ResponseType } from './options.js';
import type Request from './index.js';
export type PlainResponse = {
/**
The original request URL.
*/
requestUrl: URL;
/**
The redirect URLs.
*/
redirectUrls: URL[];
/**
- `options` - The Got options that were set on this request.
__Note__: This is not a [http.ClientRequest](https://nodejs.org/api/http.html#http_class_http_clientrequest).
*/
request: Request;
/**
The remote IP address.
This is hopefully a temporary limitation, see [lukechilds/cacheable-request#86](https://github.com/lukechilds/cacheable-request/issues/86).
__Note__: Not available when the response is cached.
*/
ip?: string;
/**
Whether the response was retrieved from the cache.
*/
isFromCache: boolean;
/**
The status code of the response.
*/
statusCode: number;
/**
The request URL or the final URL after redirects.
*/
url: string;
/**
The object contains the following properties:
- `start` - Time when the request started.
- `socket` - Time when a socket was assigned to the request.
- `lookup` - Time when the DNS lookup finished.
- `connect` - Time when the socket successfully connected.
- `secureConnect` - Time when the socket securely connected.
- `upload` - Time when the request finished uploading.
- `response` - Time when the request fired `response` event.
- `end` - Time when the response fired `end` event.
- `error` - Time when the request fired `error` event.
- `abort` - Time when the request fired `abort` event.
- `phases`
- `wait` - `timings.socket - timings.start`
- `dns` - `timings.lookup - timings.socket`
- `tcp` - `timings.connect - timings.lookup`
- `tls` - `timings.secureConnect - timings.connect`
- `request` - `timings.upload - (timings.secureConnect || timings.connect)`
- `firstByte` - `timings.response - timings.upload`
- `download` - `timings.end - timings.response`
- `total` - `(timings.end || timings.error || timings.abort) - timings.start`
If something has not been measured yet, it will be `undefined`.
__Note__: The time is a `number` representing the milliseconds elapsed since the UNIX epoch.
*/
timings: Timings;
/**
The number of times the request was retried.
*/
retryCount: number;
/**
The raw result of the request.
*/
rawBody?: Buffer;
/**
The result of the request.
*/
body?: unknown;
/**
Whether the response was successful.
__Note__: Got throws automatically when `response.ok` is `false` and `throwHttpErrors` is `true`.
*/
ok: boolean;
} & IncomingMessageWithTimings;
export type Response<T = unknown> = {
/**
The result of the request.
*/
body: T;
/**
The raw result of the request.
*/
rawBody: Buffer;
} & PlainResponse;
export declare const isResponseOk: (response: PlainResponse) => boolean;
/**
An error to be thrown when server response code is 2xx, and parsing body fails.
Includes a `response` property.
*/
export declare class ParseError extends RequestError {
readonly response: Response;
constructor(error: Error, response: Response);
}
export declare const parseBody: (response: Response, responseType: ResponseType, parseJson: ParseJsonFunction, encoding?: BufferEncoding) => unknown;

41
node_modules/got/dist/source/core/response.js generated vendored Normal file
View File

@ -0,0 +1,41 @@
import { RequestError } from './errors.js';
export const isResponseOk = (response) => {
const { statusCode } = response;
const { followRedirect } = response.request.options;
const shouldFollow = typeof followRedirect === 'function' ? followRedirect(response) : followRedirect;
const limitStatusCode = shouldFollow ? 299 : 399;
return (statusCode >= 200 && statusCode <= limitStatusCode) || statusCode === 304;
};
/**
An error to be thrown when server response code is 2xx, and parsing body fails.
Includes a `response` property.
*/
export class ParseError extends RequestError {
constructor(error, response) {
const { options } = response.request;
super(`${error.message} in "${options.url.toString()}"`, error, response.request);
this.name = 'ParseError';
this.code = 'ERR_BODY_PARSE_FAILURE';
}
}
export const parseBody = (response, responseType, parseJson, encoding) => {
const { rawBody } = response;
try {
if (responseType === 'text') {
return rawBody.toString(encoding);
}
if (responseType === 'json') {
return rawBody.length === 0 ? '' : parseJson(rawBody.toString(encoding));
}
if (responseType === 'buffer') {
return rawBody;
}
}
catch (error) {
throw new ParseError(error, response);
}
throw new ParseError({
message: `Unknown body type '${responseType}'`,
name: 'Error',
}, response);
};

30
node_modules/got/dist/source/core/timed-out.d.ts generated vendored Normal file
View File

@ -0,0 +1,30 @@
import type { ClientRequest } from 'node:http';
declare const reentry: unique symbol;
type TimedOutOptions = {
host?: string;
hostname?: string;
protocol?: string;
};
export type Delays = {
lookup?: number;
socket?: number;
connect?: number;
secureConnect?: number;
send?: number;
response?: number;
read?: number;
request?: number;
};
export type ErrorCode = 'ETIMEDOUT' | 'ECONNRESET' | 'EADDRINUSE' | 'ECONNREFUSED' | 'EPIPE' | 'ENOTFOUND' | 'ENETUNREACH' | 'EAI_AGAIN';
export declare class TimeoutError extends Error {
event: string;
code: ErrorCode;
constructor(threshold: number, event: string);
}
export default function timedOut(request: ClientRequest, delays: Delays, options: TimedOutOptions): () => void;
declare module 'http' {
interface ClientRequest {
[reentry]?: boolean;
}
}
export {};

129
node_modules/got/dist/source/core/timed-out.js generated vendored Normal file
View File

@ -0,0 +1,129 @@
import net from 'node:net';
import unhandler from './utils/unhandle.js';
const reentry = Symbol('reentry');
const noop = () => { };
export class TimeoutError extends Error {
event;
code;
constructor(threshold, event) {
super(`Timeout awaiting '${event}' for ${threshold}ms`);
this.event = event;
this.name = 'TimeoutError';
this.code = 'ETIMEDOUT';
}
}
export default function timedOut(request, delays, options) {
if (reentry in request) {
return noop;
}
request[reentry] = true;
const cancelers = [];
const { once, unhandleAll } = unhandler();
const addTimeout = (delay, callback, event) => {
const timeout = setTimeout(callback, delay, delay, event);
timeout.unref?.();
const cancel = () => {
clearTimeout(timeout);
};
cancelers.push(cancel);
return cancel;
};
const { host, hostname } = options;
const timeoutHandler = (delay, event) => {
request.destroy(new TimeoutError(delay, event));
};
const cancelTimeouts = () => {
for (const cancel of cancelers) {
cancel();
}
unhandleAll();
};
request.once('error', error => {
cancelTimeouts();
// Save original behavior
/* istanbul ignore next */
if (request.listenerCount('error') === 0) {
throw error;
}
});
if (delays.request !== undefined) {
const cancelTimeout = addTimeout(delays.request, timeoutHandler, 'request');
once(request, 'response', (response) => {
once(response, 'end', cancelTimeout);
});
}
if (delays.socket !== undefined) {
const { socket } = delays;
const socketTimeoutHandler = () => {
timeoutHandler(socket, 'socket');
};
request.setTimeout(socket, socketTimeoutHandler);
// `request.setTimeout(0)` causes a memory leak.
// We can just remove the listener and forget about the timer - it's unreffed.
// See https://github.com/sindresorhus/got/issues/690
cancelers.push(() => {
request.removeListener('timeout', socketTimeoutHandler);
});
}
const hasLookup = delays.lookup !== undefined;
const hasConnect = delays.connect !== undefined;
const hasSecureConnect = delays.secureConnect !== undefined;
const hasSend = delays.send !== undefined;
if (hasLookup || hasConnect || hasSecureConnect || hasSend) {
once(request, 'socket', (socket) => {
const { socketPath } = request;
/* istanbul ignore next: hard to test */
if (socket.connecting) {
const hasPath = Boolean(socketPath ?? net.isIP(hostname ?? host ?? '') !== 0);
if (hasLookup && !hasPath && socket.address().address === undefined) {
const cancelTimeout = addTimeout(delays.lookup, timeoutHandler, 'lookup');
once(socket, 'lookup', cancelTimeout);
}
if (hasConnect) {
const timeConnect = () => addTimeout(delays.connect, timeoutHandler, 'connect');
if (hasPath) {
once(socket, 'connect', timeConnect());
}
else {
once(socket, 'lookup', (error) => {
if (error === null) {
once(socket, 'connect', timeConnect());
}
});
}
}
if (hasSecureConnect && options.protocol === 'https:') {
once(socket, 'connect', () => {
const cancelTimeout = addTimeout(delays.secureConnect, timeoutHandler, 'secureConnect');
once(socket, 'secureConnect', cancelTimeout);
});
}
}
if (hasSend) {
const timeRequest = () => addTimeout(delays.send, timeoutHandler, 'send');
/* istanbul ignore next: hard to test */
if (socket.connecting) {
once(socket, 'connect', () => {
once(request, 'upload-complete', timeRequest());
});
}
else {
once(request, 'upload-complete', timeRequest());
}
}
});
}
if (delays.response !== undefined) {
once(request, 'upload-complete', () => {
const cancelTimeout = addTimeout(delays.response, timeoutHandler, 'response');
once(request, 'response', cancelTimeout);
});
}
if (delays.read !== undefined) {
once(request, 'response', (response) => {
const cancelTimeout = addTimeout(delays.read, timeoutHandler, 'read');
once(response, 'end', cancelTimeout);
});
}
return cancelTimeouts;
}

View File

@ -0,0 +1,2 @@
import type { ClientRequestArgs } from 'node:http';
export default function getBodySize(body: unknown, headers: ClientRequestArgs['headers']): Promise<number | undefined>;

View File

@ -0,0 +1,22 @@
import { Buffer } from 'node:buffer';
import { promisify } from 'node:util';
import is from '@sindresorhus/is';
import isFormData from './is-form-data.js';
export default async function getBodySize(body, headers) {
if (headers && 'content-length' in headers) {
return Number(headers['content-length']);
}
if (!body) {
return 0;
}
if (is.string(body)) {
return Buffer.byteLength(body);
}
if (is.buffer(body)) {
return body.length;
}
if (isFormData(body)) {
return promisify(body.getLength.bind(body))();
}
return undefined;
}

View File

@ -0,0 +1,4 @@
import type { Writable, Readable } from 'node:stream';
import type { ClientRequest } from 'node:http';
declare function isClientRequest(clientRequest: Writable | Readable): clientRequest is ClientRequest;
export default isClientRequest;

View File

@ -0,0 +1,4 @@
function isClientRequest(clientRequest) {
return clientRequest.writable && !clientRequest.writableEnded;
}
export default isClientRequest;

View File

@ -0,0 +1,7 @@
import type { Readable } from 'node:stream';
type FormData = {
getBoundary: () => string;
getLength: (callback: (error: Error | null, length: number) => void) => void;
} & Readable;
export default function isFormData(body: unknown): body is FormData;
export {};

View File

@ -0,0 +1,4 @@
import is from '@sindresorhus/is';
export default function isFormData(body) {
return is.nodeStream(body) && is.function(body.getBoundary);
}

View File

@ -0,0 +1 @@
export default function isUnixSocketURL(url: URL): boolean;

View File

@ -0,0 +1,4 @@
// eslint-disable-next-line @typescript-eslint/naming-convention
export default function isUnixSocketURL(url) {
return url.protocol === 'unix:' || url.hostname === 'unix';
}

View File

@ -0,0 +1,12 @@
export type URLOptions = {
href?: string;
protocol?: string;
host?: string;
hostname?: string;
port?: string | number;
pathname?: string;
search?: string;
searchParams?: unknown;
path?: string;
};
export default function optionsToUrl(origin: string, options: URLOptions): URL;

View File

@ -0,0 +1,48 @@
const keys = [
'protocol',
'host',
'hostname',
'port',
'pathname',
'search',
];
export default function optionsToUrl(origin, options) {
if (options.path) {
if (options.pathname) {
throw new TypeError('Parameters `path` and `pathname` are mutually exclusive.');
}
if (options.search) {
throw new TypeError('Parameters `path` and `search` are mutually exclusive.');
}
if (options.searchParams) {
throw new TypeError('Parameters `path` and `searchParams` are mutually exclusive.');
}
}
if (options.search && options.searchParams) {
throw new TypeError('Parameters `search` and `searchParams` are mutually exclusive.');
}
if (!origin) {
if (!options.protocol) {
throw new TypeError('No URL protocol specified');
}
origin = `${options.protocol}//${options.hostname ?? options.host ?? ''}`;
}
const url = new URL(origin);
if (options.path) {
const searchIndex = options.path.indexOf('?');
if (searchIndex === -1) {
options.pathname = options.path;
}
else {
options.pathname = options.path.slice(0, searchIndex);
options.search = options.path.slice(searchIndex + 1);
}
delete options.path;
}
for (const key of keys) {
if (options[key]) {
url[key] = options[key].toString();
}
}
return url;
}

View File

@ -0,0 +1,2 @@
import type { EventEmitter } from 'node:events';
export default function proxyEvents(from: EventEmitter, to: EventEmitter, events: Readonly<string[]>): () => void;

View File

@ -0,0 +1,15 @@
export default function proxyEvents(from, to, events) {
const eventFunctions = {};
for (const event of events) {
const eventFunction = (...arguments_) => {
to.emit(event, ...arguments_);
};
eventFunctions[event] = eventFunction;
from.on(event, eventFunction);
}
return () => {
for (const [event, eventFunction] of Object.entries(eventFunctions)) {
from.off(event, eventFunction);
}
};
}

10
node_modules/got/dist/source/core/utils/unhandle.d.ts generated vendored Normal file
View File

@ -0,0 +1,10 @@
import type { EventEmitter } from 'node:events';
type Origin = EventEmitter;
type Event = string | symbol;
type AnyFunction = (...arguments_: any[]) => void;
type Unhandler = {
once: (origin: Origin, event: Event, function_: AnyFunction) => void;
unhandleAll: () => void;
};
export default function unhandle(): Unhandler;
export {};

20
node_modules/got/dist/source/core/utils/unhandle.js generated vendored Normal file
View File

@ -0,0 +1,20 @@
// When attaching listeners, it's very easy to forget about them.
// Especially if you do error handling and set timeouts.
// So instead of checking if it's proper to throw an error on every timeout ever,
// use this simple tool which will remove all listeners you have attached.
export default function unhandle() {
const handlers = [];
return {
once(origin, event, function_) {
origin.once(event, function_);
handlers.push({ origin, event, fn: function_ });
},
unhandleAll() {
for (const handler of handlers) {
const { origin, event, fn } = handler;
origin.removeListener(event, fn);
}
handlers.length = 0;
},
};
}

View File

@ -0,0 +1,14 @@
import type { UrlWithStringQuery } from 'node:url';
export type LegacyUrlOptions = {
protocol: string;
hostname: string;
host: string;
hash: string | null;
search: string | null;
pathname: string;
href: string;
path: string;
port?: number;
auth?: string;
};
export default function urlToOptions(url: URL | UrlWithStringQuery): LegacyUrlOptions;

View File

@ -0,0 +1,22 @@
import is from '@sindresorhus/is';
export default function urlToOptions(url) {
// Cast to URL
url = url;
const options = {
protocol: url.protocol,
hostname: is.string(url.hostname) && url.hostname.startsWith('[') ? url.hostname.slice(1, -1) : url.hostname,
host: url.host,
hash: url.hash,
search: url.search,
pathname: url.pathname,
href: url.href,
path: `${url.pathname || ''}${url.search || ''}`,
};
if (is.string(url.port) && url.port.length > 0) {
options.port = Number(url.port);
}
if (url.username || url.password) {
options.auth = `${url.username || ''}:${url.password || ''}`;
}
return options;
}

View File

@ -0,0 +1,8 @@
export default class WeakableMap<K, V> {
weakMap: WeakMap<Record<string, unknown>, V>;
map: Map<K, V>;
constructor();
set(key: K, value: V): void;
get(key: K): V | undefined;
has(key: K): boolean;
}

View File

@ -0,0 +1,28 @@
export default class WeakableMap {
weakMap;
map;
constructor() {
this.weakMap = new WeakMap();
this.map = new Map();
}
set(key, value) {
if (typeof key === 'object') {
this.weakMap.set(key, value);
}
else {
this.map.set(key, value);
}
}
get(key) {
if (typeof key === 'object') {
return this.weakMap.get(key);
}
return this.map.get(key);
}
has(key) {
if (typeof key === 'object') {
return this.weakMap.has(key);
}
return this.map.has(key);
}
}

3
node_modules/got/dist/source/create.d.ts generated vendored Normal file
View File

@ -0,0 +1,3 @@
import type { Got, InstanceDefaults } from './types.js';
declare const create: (defaults: InstanceDefaults) => Got;
export default create;

183
node_modules/got/dist/source/create.js generated vendored Normal file
View File

@ -0,0 +1,183 @@
import is, { assert } from '@sindresorhus/is';
import asPromise from './as-promise/index.js';
import Request from './core/index.js';
import Options from './core/options.js';
// The `delay` package weighs 10KB (!)
const delay = async (ms) => new Promise(resolve => {
setTimeout(resolve, ms);
});
const isGotInstance = (value) => is.function(value);
const aliases = [
'get',
'post',
'put',
'patch',
'head',
'delete',
];
const create = (defaults) => {
defaults = {
options: new Options(undefined, undefined, defaults.options),
handlers: [...defaults.handlers],
mutableDefaults: defaults.mutableDefaults,
};
Object.defineProperty(defaults, 'mutableDefaults', {
enumerable: true,
configurable: false,
writable: false,
});
// Got interface
const got = ((url, options, defaultOptions = defaults.options) => {
const request = new Request(url, options, defaultOptions);
let promise;
const lastHandler = (normalized) => {
// Note: `options` is `undefined` when `new Options(...)` fails
request.options = normalized;
request._noPipe = !normalized?.isStream;
void request.flush();
if (normalized?.isStream) {
return request;
}
promise ||= asPromise(request);
return promise;
};
let iteration = 0;
const iterateHandlers = (newOptions) => {
const handler = defaults.handlers[iteration++] ?? lastHandler;
const result = handler(newOptions, iterateHandlers);
if (is.promise(result) && !request.options?.isStream) {
promise ||= asPromise(request);
if (result !== promise) {
const descriptors = Object.getOwnPropertyDescriptors(promise);
for (const key in descriptors) {
if (key in result) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete descriptors[key];
}
}
// eslint-disable-next-line @typescript-eslint/no-floating-promises
Object.defineProperties(result, descriptors);
result.cancel = promise.cancel;
}
}
return result;
};
return iterateHandlers(request.options);
});
got.extend = (...instancesOrOptions) => {
const options = new Options(undefined, undefined, defaults.options);
const handlers = [...defaults.handlers];
let mutableDefaults;
for (const value of instancesOrOptions) {
if (isGotInstance(value)) {
options.merge(value.defaults.options);
handlers.push(...value.defaults.handlers);
mutableDefaults = value.defaults.mutableDefaults;
}
else {
options.merge(value);
if (value.handlers) {
handlers.push(...value.handlers);
}
mutableDefaults = value.mutableDefaults;
}
}
return create({
options,
handlers,
mutableDefaults: Boolean(mutableDefaults),
});
};
// Pagination
const paginateEach = (async function* (url, options) {
let normalizedOptions = new Options(url, options, defaults.options);
normalizedOptions.resolveBodyOnly = false;
const { pagination } = normalizedOptions;
assert.function(pagination.transform);
assert.function(pagination.shouldContinue);
assert.function(pagination.filter);
assert.function(pagination.paginate);
assert.number(pagination.countLimit);
assert.number(pagination.requestLimit);
assert.number(pagination.backoff);
const allItems = [];
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);
}
// eslint-disable-next-line no-await-in-loop
const response = (await got(undefined, undefined, normalizedOptions));
// eslint-disable-next-line no-await-in-loop
const parsed = await pagination.transform(response);
const currentItems = [];
assert.array(parsed);
for (const item of parsed) {
if (pagination.filter({ item, currentItems, allItems })) {
if (!pagination.shouldContinue({ item, currentItems, allItems })) {
return;
}
yield item;
if (pagination.stackAllItems) {
allItems.push(item);
}
currentItems.push(item);
if (--countLimit <= 0) {
return;
}
}
}
const optionsToMerge = pagination.paginate({
response,
currentItems,
allItems,
});
if (optionsToMerge === false) {
return;
}
if (optionsToMerge === response.request.options) {
normalizedOptions = response.request.options;
}
else {
normalizedOptions.merge(optionsToMerge);
assert.any([is.urlInstance, is.undefined], optionsToMerge.url);
if (optionsToMerge.url !== undefined) {
normalizedOptions.prefixUrl = '';
normalizedOptions.url = optionsToMerge.url;
}
}
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) => got(url, { ...options, method, isStream: true }));
}
if (!defaults.mutableDefaults) {
Object.freeze(defaults.handlers);
defaults.options.freeze();
}
Object.defineProperty(got, 'defaults', {
value: defaults,
writable: false,
configurable: false,
enumerable: true,
});
return got;
};
export default create;

15
node_modules/got/dist/source/index.d.ts generated vendored Normal file
View File

@ -0,0 +1,15 @@
declare const got: import("./types.js").Got;
export default got;
export { got };
export { default as Options } from './core/options.js';
export * from './core/options.js';
export * from './core/response.js';
export type { default as Request } from './core/index.js';
export * from './core/index.js';
export * from './core/errors.js';
export type { Delays } from './core/timed-out.js';
export { default as calculateRetryDelay } from './core/calculate-retry-delay.js';
export * from './as-promise/types.js';
export * from './types.js';
export { default as create } from './create.js';
export { default as parseLinkHeader } from './core/parse-link-header.js';

21
node_modules/got/dist/source/index.js generated vendored Normal file
View File

@ -0,0 +1,21 @@
import create from './create.js';
import Options from './core/options.js';
const defaults = {
options: new Options(),
handlers: [],
mutableDefaults: false,
};
const got = create(defaults);
export default got;
// TODO: Remove this in the next major version.
export { got };
export { default as Options } from './core/options.js';
export * from './core/options.js';
export * from './core/response.js';
export * from './core/index.js';
export * from './core/errors.js';
export { default as calculateRetryDelay } from './core/calculate-retry-delay.js';
export * from './as-promise/types.js';
export * from './types.js';
export { default as create } from './create.js';
export { default as parseLinkHeader } from './core/parse-link-header.js';

307
node_modules/got/dist/source/types.d.ts generated vendored Normal file
View File

@ -0,0 +1,307 @@
import type { Buffer } from 'node:buffer';
import type { Spread } from 'type-fest';
import type { CancelableRequest } from './as-promise/types.js';
import type { Response } from './core/response.js';
import type Options from './core/options.js';
import { type PaginationOptions, type OptionsInit } from './core/options.js';
import type Request from './core/index.js';
type Except<ObjectType, KeysType extends keyof ObjectType> = Pick<ObjectType, Exclude<keyof ObjectType, KeysType>>;
type Merge<FirstType, SecondType> = Except<FirstType, Extract<keyof FirstType, keyof SecondType>> & SecondType;
/**
Defaults for each Got instance.
*/
export type InstanceDefaults = {
/**
An object containing the default options of Got.
*/
options: Options;
/**
An array of functions. You execute them directly by calling `got()`.
They are some sort of "global hooks" - these functions are called first.
The last handler (*it's hidden*) is either `asPromise` or `asStream`, depending on the `options.isStream` property.
@default []
*/
handlers: HandlerFunction[];
/**
A read-only boolean describing whether the defaults are mutable or not.
If set to `true`, you can update headers over time, for example, update an access token when it expires.
@default false
*/
mutableDefaults: boolean;
};
/**
A Request object returned by calling Got, or any of the Got HTTP alias request functions.
*/
export type GotReturn = Request | CancelableRequest;
/**
A function to handle options and returns a Request object.
It acts sort of like a "global hook", and will be called before any actual request is made.
*/
export type HandlerFunction = <T extends GotReturn>(options: Options, next: (options: Options) => T) => T | Promise<T>;
/**
The options available for `got.extend()`.
*/
export type ExtendOptions = {
/**
An array of functions. You execute them directly by calling `got()`.
They are some sort of "global hooks" - these functions are called first.
The last handler (*it's hidden*) is either `asPromise` or `asStream`, depending on the `options.isStream` property.
@default []
*/
handlers?: HandlerFunction[];
/**
A read-only boolean describing whether the defaults are mutable or not.
If set to `true`, you can update headers over time, for example, update an access token when it expires.
@default false
*/
mutableDefaults?: boolean;
} & OptionsInit;
export type StrictOptions = Except<OptionsInit, 'isStream' | 'responseType' | 'resolveBodyOnly'>;
export type StreamOptions = Merge<OptionsInit, {
isStream?: true;
}>;
export type OptionsWithPagination<T = unknown, R = unknown> = Merge<OptionsInit, {
pagination?: PaginationOptions<T, R>;
}>;
/**
An instance of `got.paginate`.
*/
export type GotPaginate = {
/**
Same as `GotPaginate.each`.
*/
<T, R = unknown>(url: string | URL, options?: OptionsWithPagination<T, R>): AsyncIterableIterator<T>;
/**
Same as `GotPaginate.each`.
*/
<T, R = unknown>(options?: OptionsWithPagination<T, R>): AsyncIterableIterator<T>;
/**
Returns an async iterator.
See pagination.options for more pagination options.
@example
```
import got from 'got';
const countLimit = 10;
const pagination = got.paginate('https://api.github.com/repos/sindresorhus/got/commits', {
pagination: {countLimit}
});
console.log(`Printing latest ${countLimit} Got commits (newest to oldest):`);
for await (const commitData of pagination) {
console.log(commitData.commit.message);
}
```
*/
each: (<T, R = unknown>(url: string | URL, options?: OptionsWithPagination<T, R>) => AsyncIterableIterator<T>) & (<T, R = unknown>(options?: OptionsWithPagination<T, R>) => AsyncIterableIterator<T>);
/**
Returns a Promise for an array of all results.
See pagination.options for more pagination options.
@example
```
import got from 'got';
const countLimit = 10;
const results = await got.paginate.all('https://api.github.com/repos/sindresorhus/got/commits', {
pagination: {countLimit}
});
console.log(`Printing latest ${countLimit} Got commits (newest to oldest):`);
console.log(results);
```
*/
all: (<T, R = unknown>(url: string | URL, options?: OptionsWithPagination<T, R>) => Promise<T[]>) & (<T, R = unknown>(options?: OptionsWithPagination<T, R>) => Promise<T[]>);
};
export type OptionsOfTextResponseBody = Merge<StrictOptions, {
isStream?: false;
responseType?: 'text';
}>;
export type OptionsOfTextResponseBodyOnly = Merge<StrictOptions, {
isStream?: false;
resolveBodyOnly: true;
responseType?: 'text';
}>;
export type OptionsOfTextResponseBodyWrapped = Merge<StrictOptions, {
isStream?: false;
resolveBodyOnly: false;
responseType?: 'text';
}>;
export type OptionsOfJSONResponseBody = Merge<StrictOptions, {
isStream?: false;
responseType?: 'json';
}>;
export type OptionsOfJSONResponseBodyOnly = Merge<StrictOptions, {
isStream?: false;
resolveBodyOnly: true;
responseType?: 'json';
}>;
export type OptionsOfJSONResponseBodyWrapped = Merge<StrictOptions, {
isStream?: false;
resolveBodyOnly: false;
responseType?: 'json';
}>;
export type OptionsOfBufferResponseBody = Merge<StrictOptions, {
isStream?: false;
responseType?: 'buffer';
}>;
export type OptionsOfBufferResponseBodyOnly = Merge<StrictOptions, {
isStream?: false;
resolveBodyOnly: true;
responseType?: 'buffer';
}>;
export type OptionsOfBufferResponseBodyWrapped = Merge<StrictOptions, {
isStream?: false;
resolveBodyOnly: false;
responseType?: 'buffer';
}>;
export type OptionsOfUnknownResponseBody = Merge<StrictOptions, {
isStream?: false;
}>;
export type OptionsOfUnknownResponseBodyOnly = Merge<StrictOptions, {
isStream?: false;
resolveBodyOnly: true;
}>;
export type OptionsOfUnknownResponseBodyWrapped = Merge<StrictOptions, {
isStream?: false;
resolveBodyOnly: false;
}>;
export type GotRequestFunction<U extends ExtendOptions = Record<string, unknown>> = {
(url: string | URL, options?: OptionsOfTextResponseBody): U['resolveBodyOnly'] extends true ? CancelableRequest<string> : CancelableRequest<Response<string>>;
<T>(url: string | URL, options?: OptionsOfJSONResponseBody): U['resolveBodyOnly'] extends true ? CancelableRequest<T> : CancelableRequest<Response<T>>;
(url: string | URL, options?: OptionsOfBufferResponseBody): U['resolveBodyOnly'] extends true ? CancelableRequest<Buffer> : CancelableRequest<Response<Buffer>>;
(url: string | URL, options?: OptionsOfUnknownResponseBody): U['resolveBodyOnly'] extends true ? CancelableRequest : CancelableRequest<Response>;
(url: string | URL, options?: OptionsOfTextResponseBodyWrapped): CancelableRequest<Response<string>>;
<T>(url: string | URL, options?: OptionsOfJSONResponseBodyWrapped): CancelableRequest<Response<T>>;
(url: string | URL, options?: OptionsOfBufferResponseBodyWrapped): CancelableRequest<Response<Buffer>>;
(url: string | URL, options?: OptionsOfUnknownResponseBodyWrapped): CancelableRequest<Response>;
(url: string | URL, options?: OptionsOfTextResponseBodyOnly): CancelableRequest<string>;
<T>(url: string | URL, options?: OptionsOfJSONResponseBodyOnly): CancelableRequest<T>;
(url: string | URL, options?: OptionsOfBufferResponseBodyOnly): CancelableRequest<Buffer>;
(url: string | URL, options?: OptionsOfUnknownResponseBodyOnly): CancelableRequest;
(options: OptionsOfTextResponseBody): U['resolveBodyOnly'] extends true ? CancelableRequest<string> : CancelableRequest<Response<string>>;
<T>(options: OptionsOfJSONResponseBody): U['resolveBodyOnly'] extends true ? CancelableRequest<T> : CancelableRequest<Response<T>>;
(options: OptionsOfBufferResponseBody): U['resolveBodyOnly'] extends true ? CancelableRequest<Buffer> : CancelableRequest<Response<Buffer>>;
(options: OptionsOfUnknownResponseBody): U['resolveBodyOnly'] extends true ? CancelableRequest : CancelableRequest<Response>;
(options: OptionsOfTextResponseBodyWrapped): CancelableRequest<Response<string>>;
<T>(options: OptionsOfJSONResponseBodyWrapped): CancelableRequest<Response<T>>;
(options: OptionsOfBufferResponseBodyWrapped): CancelableRequest<Response<Buffer>>;
(options: OptionsOfUnknownResponseBodyWrapped): CancelableRequest<Response>;
(options: OptionsOfTextResponseBodyOnly): CancelableRequest<string>;
<T>(options: OptionsOfJSONResponseBodyOnly): CancelableRequest<T>;
(options: OptionsOfBufferResponseBodyOnly): CancelableRequest<Buffer>;
(options: OptionsOfUnknownResponseBodyOnly): CancelableRequest;
(url: string | URL, options?: Merge<OptionsInit, {
isStream: true;
}>): Request;
(options: Merge<OptionsInit, {
isStream: true;
}>): Request;
(url: string | URL, options?: OptionsInit): CancelableRequest | Request;
(options: OptionsInit): CancelableRequest | Request;
(url: undefined, options: undefined, defaults: Options): CancelableRequest | Request;
};
/**
All available HTTP request methods provided by Got.
*/
export type HTTPAlias = 'get' | 'post' | 'put' | 'patch' | 'head' | 'delete';
type GotStreamFunction = ((url?: string | URL, options?: Merge<OptionsInit, {
isStream?: true;
}>) => Request) & ((options?: Merge<OptionsInit, {
isStream?: true;
}>) => Request);
/**
An instance of `got.stream()`.
*/
export type GotStream = GotStreamFunction & Record<HTTPAlias, GotStreamFunction>;
/**
An instance of `got`.
*/
export type Got<GotOptions extends ExtendOptions = ExtendOptions> = {
/**
Sets `options.isStream` to `true`.
Returns a [duplex stream](https://nodejs.org/api/stream.html#stream_class_stream_duplex) with additional events:
- request
- response
- redirect
- uploadProgress
- downloadProgress
- error
*/
stream: GotStream;
/**
Returns an async iterator.
See pagination.options for more pagination options.
@example
```
import got from 'got';
const countLimit = 10;
const pagination = got.paginate('https://api.github.com/repos/sindresorhus/got/commits', {
pagination: {countLimit}
});
console.log(`Printing latest ${countLimit} Got commits (newest to oldest):`);
for await (const commitData of pagination) {
console.log(commitData.commit.message);
}
```
*/
paginate: GotPaginate;
/**
The Got defaults used in that instance.
*/
defaults: InstanceDefaults;
/**
Configure a new `got` instance with default `options`.
The `options` are merged with the parent instance's `defaults.options` using `got.mergeOptions`.
You can access the resolved options with the `.defaults` property on the instance.
Additionally, `got.extend()` accepts two properties from the `defaults` object: `mutableDefaults` and `handlers`.
It is also possible to merges many instances into a single one:
- options are merged using `got.mergeOptions()` (including hooks),
- handlers are stored in an array (you can access them through `instance.defaults.handlers`).
@example
```
import got from 'got';
const client = got.extend({
prefixUrl: 'https://example.com',
headers: {
'x-unicorn': 'rainbow'
}
});
client.get('demo');
// HTTP Request =>
// GET /demo HTTP/1.1
// Host: example.com
// x-unicorn: rainbow
```
*/
extend<T extends Array<Got | ExtendOptions>>(...instancesOrOptions: T): Got<MergeExtendsConfig<T>>;
} & Record<HTTPAlias, GotRequestFunction<GotOptions>> & GotRequestFunction<GotOptions>;
export type ExtractExtendOptions<T> = T extends Got<infer GotOptions> ? GotOptions : T;
/**
Merges the options of multiple Got instances.
*/
export type MergeExtendsConfig<Value extends Array<Got | ExtendOptions>> = Value extends readonly [Value[0], ...infer NextValue] ? NextValue[0] extends undefined ? Value[0] extends infer OnlyValue ? OnlyValue extends ExtendOptions ? OnlyValue : OnlyValue extends Got<infer GotOptions> ? GotOptions : OnlyValue : never : ExtractExtendOptions<Value[0]> extends infer FirstArg extends ExtendOptions ? ExtractExtendOptions<NextValue[0] extends ExtendOptions | Got ? NextValue[0] : never> extends infer NextArg extends ExtendOptions ? Spread<FirstArg, NextArg> extends infer Merged extends ExtendOptions ? NextValue extends [NextValue[0], ...infer NextRest] ? NextRest extends Array<Got | ExtendOptions> ? MergeExtendsConfig<[Merged, ...NextRest]> : never : never : never : never : never : never;
export {};

1
node_modules/got/dist/source/types.js generated vendored Normal file
View File

@ -0,0 +1 @@
export {};