Skip to content

Commit 1d012a5

Browse files
committed
Improve internal types
1 parent fa60b5f commit 1d012a5

13 files changed

+59
-52
lines changed

source/as-promise.ts

+8-9
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import is from '@sindresorhus/is';
55
import {ParseError, ReadError, HTTPError} from './errors';
66
import {normalizeArguments, mergeOptions} from './normalize-arguments';
77
import requestAsEventEmitter, {proxyEvents} from './request-as-event-emitter';
8-
import {CancelableRequest, GeneralError, NormalizedOptions, Response} from './utils/types';
8+
import {CancelableRequest, GeneralError, NormalizedOptions, Response} from './types';
99

1010
const parseBody = (body: Buffer, responseType: NormalizedOptions['responseType'], encoding: NormalizedOptions['encoding']): unknown => {
1111
if (responseType === 'json') {
@@ -27,7 +27,6 @@ export default function asPromise<T>(options: NormalizedOptions): CancelableRequ
2727
const proxy = new EventEmitter();
2828
let body: Buffer;
2929

30-
// @ts-ignore `.json()`, `.buffer()` and `.text()` are added later
3130
const promise = new PCancelable<Response | Response['body']>((resolve, reject, onCancel) => {
3231
const emitter = requestAsEventEmitter(options);
3332
onCancel(emitter.abort);
@@ -84,10 +83,10 @@ export default function asPromise<T>(options: NormalizedOptions): CancelableRequ
8483

8584
try {
8685
for (const [index, hook] of options.hooks.afterResponse.entries()) {
87-
// @ts-ignore Promise is not assignable to CancelableRequest
86+
// @ts-ignore TS doesn't notice that CancelableRequest is a Promise
8887
// eslint-disable-next-line no-await-in-loop
89-
response = await hook(response, async (updatedOptions: NormalizedOptions) => {
90-
updatedOptions = normalizeArguments(mergeOptions(options, {
88+
response = await hook(response, async (updatedOptions): CancelableRequest<Response> => {
89+
const typedOptions = normalizeArguments(mergeOptions(options, {
9190
...updatedOptions,
9291
retry: {
9392
calculateDelay: () => 0
@@ -98,21 +97,21 @@ export default function asPromise<T>(options: NormalizedOptions): CancelableRequ
9897

9998
// Remove any further hooks for that request, because we'll call them anyway.
10099
// The loop continues. We don't want duplicates (asPromise recursion).
101-
updatedOptions.hooks.afterResponse = options.hooks.afterResponse.slice(0, index);
100+
typedOptions.hooks.afterResponse = options.hooks.afterResponse.slice(0, index);
102101

103102
for (const hook of options.hooks.beforeRetry) {
104103
// eslint-disable-next-line no-await-in-loop
105-
await hook(updatedOptions);
104+
await hook(typedOptions);
106105
}
107106

108-
const promise = asPromise(updatedOptions);
107+
const promise = asPromise(typedOptions);
109108

110109
onCancel(() => {
111110
promise.catch(() => {});
112111
promise.cancel();
113112
});
114113

115-
return promise;
114+
return promise as unknown as CancelableRequest<Response>;
116115
});
117116
}
118117
} catch (error) {

source/as-stream.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {IncomingMessage, ServerResponse} from 'http';
44
import {Duplex as DuplexStream, PassThrough as PassThroughStream} from 'stream';
55
import {HTTPError, ReadError} from './errors';
66
import requestAsEventEmitter, {proxyEvents} from './request-as-event-emitter';
7-
import {GeneralError, GotEvents, NormalizedOptions, Response} from './utils/types';
7+
import {GeneralError, GotEvents, NormalizedOptions, Response} from './types';
88

99
export class ProxyStream<T = unknown> extends DuplexStream implements GotEvents<ProxyStream<T>> {
1010
isFromCache?: boolean;

source/calculate-retry-delay.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import is from '@sindresorhus/is';
22
import {HTTPError, ParseError, MaxRedirectsError} from './errors';
3-
import {RetryFunction, RetryObject} from './utils/types';
3+
import {RetryFunction, RetryObject} from './types';
44

55
const retryAfterStatusCodes: ReadonlySet<number> = new Set([413, 429, 503]);
66

source/create.ts

+4-8
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
Options,
1515
Response,
1616
URLOrOptions
17-
} from './utils/types';
17+
} from './types';
1818

1919
export type HTTPAlias =
2020
| 'get'
@@ -90,7 +90,6 @@ export const defaultHandler: HandlerFunction = (options, next) => next(options);
9090

9191
const create = (defaults: Defaults): Got => {
9292
// Proxy properties from next handlers
93-
// @ts-ignore Internal use only.
9493
defaults._rawHandlers = defaults.handlers;
9594
defaults.handlers = defaults.handlers.map(fn => ((options, next) => {
9695
// This will be assigned by assigning result
@@ -115,7 +114,6 @@ const create = (defaults: Defaults): Got => {
115114
const iterateHandlers = (newOptions: NormalizedOptions): GotReturn => {
116115
return defaults.handlers[iteration++](
117116
newOptions,
118-
// @ts-ignore TS doesn't know that it calls `getPromiseOrStream` at the end
119117
iteration === defaults.handlers.length ? getPromiseOrStream : iterateHandlers
120118
) as GotReturn;
121119
};
@@ -136,15 +134,13 @@ const create = (defaults: Defaults): Got => {
136134

137135
got.extend = (...instancesOrOptions) => {
138136
const optionsArray: Options[] = [defaults.options];
139-
// @ts-ignore Internal use only.
140-
let handlers: HandlerFunction[] = [...defaults._rawHandlers];
137+
let handlers: HandlerFunction[] = [...defaults._rawHandlers!];
141138
let mutableDefaults: boolean | undefined;
142139

143140
for (const value of instancesOrOptions) {
144141
if (isGotInstance(value)) {
145142
optionsArray.push(value.defaults.options);
146-
// @ts-ignore Internal use only.
147-
handlers.push(...value.defaults._rawHandlers);
143+
handlers.push(...value.defaults._rawHandlers!);
148144
mutableDefaults = value.defaults.mutableDefaults;
149145
} else {
150146
optionsArray.push(value);
@@ -174,7 +170,7 @@ const create = (defaults: Defaults): Got => {
174170
got.stream = (url, options) => got(url, {...options, isStream: true});
175171

176172
for (const method of aliases) {
177-
// @ts-ignore GotReturn<Response> does not equal GotReturn<T>
173+
// @ts-ignore Cannot properly type a function with multiple definitions yet
178174
got[method] = (url: URLOrOptions, options?: Options): GotReturn => got(url, {...options, method});
179175
got.stream[method] = (url, options) => got.stream(url, {...options, method});
180176
}

source/errors.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import is from '@sindresorhus/is';
22
import {Timings} from '@szmarczak/http-timer';
33
import {TimeoutError as TimedOutError} from './utils/timed-out';
4-
import {ErrorCode, Response, NormalizedOptions} from './utils/types';
4+
import {Response, NormalizedOptions} from './types';
55

66
export class GotError extends Error {
7-
code?: ErrorCode;
7+
code?: string;
88
stack!: string;
99
declare readonly options: NormalizedOptions;
1010

11-
constructor(message: string, error: Partial<Error & {code?: ErrorCode}>, options: NormalizedOptions) {
11+
constructor(message: string, error: Partial<Error & {code?: string}>, options: NormalizedOptions) {
1212
super(message);
1313
Error.captureStackTrace(this, this.constructor);
1414
this.name = 'GotError';

source/get-response.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import stream = require('stream');
55
import {IncomingMessage} from 'http';
66
import {promisify} from 'util';
77
import {createProgressStream} from './progress';
8-
import {NormalizedOptions} from './utils/types';
8+
import {NormalizedOptions} from './types';
99

1010
const pipeline = promisify(stream.pipeline);
1111

source/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import create, {defaultHandler} from './create';
2-
import {Defaults} from './utils/types';
2+
import {Defaults} from './types';
33

44
const defaults: Defaults = {
55
options: {
@@ -79,7 +79,7 @@ module.exports = got;
7979
module.exports.default = got;
8080

8181
// Export types
82-
export * from './utils/types';
82+
export * from './types';
8383

8484
export {
8585
Got,

source/known-hook-events.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {CancelableRequest, GeneralError, NormalizedOptions, Options, Response} from './utils/types';
1+
import {CancelableRequest, GeneralError, NormalizedOptions, Options, Response} from './types';
22

33
/**
44
Called with plain request options, right before their normalization. This is especially useful in conjunction with `got.extend()` when the input needs custom handling.

source/normalize-arguments.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
Options,
2727
RequestFunction,
2828
URLOrOptions
29-
} from './utils/types';
29+
} from './types';
3030

3131
// `preNormalizeArguments` normalizes these options: `headers`, `prefixUrl`, `hooks`, `timeout`, `retry` and `method`.
3232
// `normalizeArguments` is *only* called on `got(...)`. It normalizes the URL and performs `mergeOptions(...)`.
@@ -132,7 +132,6 @@ export const preNormalizeArguments = (options: Options, defaults?: NormalizedOpt
132132
}
133133

134134
if (options.retry.maxRetryAfter === undefined) {
135-
// @ts-ignore We assign if it is undefined, so this IS correct
136135
options.retry.maxRetryAfter = Math.min(
137136
...[options.timeout.request, options.timeout.connect].filter((n): n is number => !is.nullOrUndefined(n))
138137
);
@@ -157,7 +156,7 @@ export const preNormalizeArguments = (options: Options, defaults?: NormalizedOpt
157156
// Better memory management, so we don't have to generate a new object every time
158157
if (options.cache) {
159158
(options as NormalizedOptions).cacheableRequest = new CacheableRequest(
160-
// @ts-ignore Types broke on infer
159+
// @ts-ignore Cannot properly type a function with multiple definitions yet
161160
(requestOptions, handler) => requestOptions.request(requestOptions, handler),
162161
options.cache
163162
);
@@ -170,7 +169,7 @@ export const preNormalizeArguments = (options: Options, defaults?: NormalizedOpt
170169
// Horrible `tough-cookie` check
171170
if (setCookie.length === 4 && getCookieString.length === 0) {
172171
if (!Reflect.has(setCookie, promisify.custom)) {
173-
// @ts-ignore We check for non-promisified setCookie, so this IS correct
172+
// @ts-ignore TS is dumb.
174173
setCookie = promisify(setCookie.bind(options.cookieJar));
175174
getCookieString = promisify(getCookieString.bind(options.cookieJar));
176175
}

source/request-as-event-emitter.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import getResponse from './get-response';
1313
import {normalizeRequestArguments} from './normalize-arguments';
1414
import {createProgressStream} from './progress';
1515
import timedOut, {TimeoutError as TimedOutTimeoutError} from './utils/timed-out';
16-
import {GeneralError, NormalizedOptions, Response} from './utils/types';
16+
import {GeneralError, NormalizedOptions, Response} from './types';
1717
import urlToOptions from './utils/url-to-options';
1818

1919
const setImmediateAsync = async (): Promise<void> => new Promise(resolve => setImmediate(resolve));
@@ -82,8 +82,7 @@ export default (options: NormalizedOptions): RequestAsEventEmitter => {
8282
delete typedResponse.fromCache;
8383

8484
if (!typedResponse.isFromCache) {
85-
// @ts-ignore Node.js typings haven't been updated yet
86-
typedResponse.ip = response.socket.remoteAddress;
85+
typedResponse.ip = response.socket.remoteAddress!;
8786
}
8887

8988
const rawCookies = typedResponse.headers['set-cookie'];
@@ -226,7 +225,7 @@ export default (options: NormalizedOptions): RequestAsEventEmitter => {
226225
...urlToOptions(options.url)
227226
};
228227

229-
// @ts-ignore ResponseLike missing socket field, should be fixed upstream
228+
// @ts-ignore `cacheable-request` has got invalid types
230229
const cacheRequest = options.cacheableRequest!(httpOptions, handleResponse);
231230

232231
cacheRequest.once('error', (error: GeneralError) => {

source/utils/types.ts source/types.ts

+4-14
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import {Readable as ReadableStream} from 'stream';
99
import {Timings} from '@szmarczak/http-timer';
1010
import CacheableLookup from 'cacheable-lookup';
1111
import {Except, Merge, Promisable} from 'type-fest';
12-
import {GotReturn} from '../create';
13-
import {GotError, HTTPError, MaxRedirectsError, ParseError} from '../errors';
14-
import {Hooks} from '../known-hook-events';
15-
import {URLOptions} from './options-to-url';
12+
import {GotReturn} from './create';
13+
import {GotError, HTTPError, MaxRedirectsError, ParseError} from './errors';
14+
import {Hooks} from './known-hook-events';
15+
import {URLOptions} from './utils/options-to-url';
1616

1717
export type GeneralError = Error | GotError | HTTPError | MaxRedirectsError | ParseError;
1818

@@ -34,16 +34,6 @@ export type Method =
3434
| 'options'
3535
| 'trace';
3636

37-
export type ErrorCode =
38-
| 'ETIMEDOUT'
39-
| 'ECONNRESET'
40-
| 'EADDRINUSE'
41-
| 'ECONNREFUSED'
42-
| 'EPIPE'
43-
| 'ENOTFOUND'
44-
| 'ENETUNREACH'
45-
| 'EAI_AGAIN';
46-
4737
export type ResponseType = 'json' | 'buffer' | 'text';
4838

4939
export interface Response<BodyType = unknown> extends http.IncomingMessage {

source/utils/get-body-size.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
import {ReadStream, stat} from 'fs';
22
import {promisify} from 'util';
3+
import {ClientRequestArgs} from 'http';
34
import is from '@sindresorhus/is';
45
import isFormData from './is-form-data';
5-
import {Options} from './types';
6+
7+
interface Options {
8+
body?: unknown;
9+
headers: ClientRequestArgs['headers'];
10+
}
611

712
const statAsync = promisify(stat);
813

914
export default async (options: Options): Promise<number | undefined> => {
10-
const {body, headers, isStream} = options;
15+
const {body, headers} = options;
1116

1217
if (headers && 'content-length' in headers) {
1318
return Number(headers['content-length']);
1419
}
1520

16-
if (!body && !isStream) {
21+
if (!body) {
1722
return 0;
1823
}
1924

source/utils/timed-out.ts

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import net = require('net');
22
import {ClientRequest, IncomingMessage} from 'http';
3-
import {Delays, ErrorCode} from './types';
43
import unhandler from './unhandle';
54

65
const reentry: unique symbol = Symbol('reentry');
@@ -12,6 +11,26 @@ interface TimedOutOptions {
1211
protocol?: string;
1312
}
1413

14+
export interface Delays {
15+
lookup?: number;
16+
connect?: number;
17+
secureConnect?: number;
18+
socket?: number;
19+
response?: number;
20+
send?: number;
21+
request?: number;
22+
}
23+
24+
export type ErrorCode =
25+
| 'ETIMEDOUT'
26+
| 'ECONNRESET'
27+
| 'EADDRINUSE'
28+
| 'ECONNREFUSED'
29+
| 'EPIPE'
30+
| 'ENOTFOUND'
31+
| 'ENETUNREACH'
32+
| 'EAI_AGAIN';
33+
1534
export class TimeoutError extends Error {
1635
code: ErrorCode;
1736

0 commit comments

Comments
 (0)