Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve types #946

Merged
merged 24 commits into from
Dec 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
1d476f3
Fix types for CookieJar / Request / HandlerFunction
pmmmwh Nov 26, 2019
5999af4
Address PR comments in #928 and fix force casting in source
pmmmwh Nov 26, 2019
7b896d6
Enhance type definitions for tests
pmmmwh Nov 26, 2019
d0bbd93
Fix most force casting and use of any in tests
pmmmwh Nov 26, 2019
a473d03
Update calculateDelay example in readme
pmmmwh Nov 26, 2019
62ca5b0
Fix linting errors
pmmmwh Nov 26, 2019
a741e75
Lint project to fully comply with XO rules
pmmmwh Nov 26, 2019
db1febb
Augment global scope to fix missing types for URL
pmmmwh Nov 27, 2019
e3836eb
Fix linting errors
pmmmwh Nov 27, 2019
be04a57
More cleanup on ts-ignore and eslint-disable comments
pmmmwh Nov 28, 2019
d95edc6
Cleanup one last missed ts-ignore
pmmmwh Nov 28, 2019
a665f0c
Update index.d.ts
sindresorhus Nov 29, 2019
077c2bc
Fixes according to comments
pmmmwh Nov 29, 2019
96d6087
Annotate as-stream piped type
pmmmwh Nov 29, 2019
1f294a0
Merge remote-tracking branch 'origin/types-follow-up' into types-foll…
pmmmwh Nov 29, 2019
a4a27f8
Pull in type enhancements from #833
pmmmwh Nov 29, 2019
1e3028b
Fix more review comments
pmmmwh Nov 29, 2019
55676ea
Fix linting error
pmmmwh Nov 29, 2019
53e3fd9
Pull in more type enhancements from #833
pmmmwh Nov 29, 2019
701d17a
Fix types & increase coverage
szmarczak Nov 29, 2019
f7bbd9f
Update source/normalize-arguments.ts
szmarczak Nov 29, 2019
85712d7
Fix types & increase coverage (#1)
pmmmwh Nov 30, 2019
ff3ab99
Merge remote-tracking branch 'origin/types-follow-up' into types-foll…
pmmmwh Nov 30, 2019
a8b54ba
Fix merge conflicts
pmmmwh Nov 30, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,6 @@
"extensions": [
"ts"
],
"rules": {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/promise-function-async": "off"
},
"ignores": [
"documentation/examples/*"
]
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -1310,7 +1310,7 @@ test('retry function gets iteration count', withServer, async (t, server, got) =
retry: {
calculateDelay: ({attemptCount}) => {
t.true(is.number(attemptCount));
return attemptCount < 2;
return attemptCount < 2 ? 1 : 0;
}
}
});
Expand Down
11 changes: 5 additions & 6 deletions source/as-promise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {normalizeArguments, mergeOptions} from './normalize-arguments';
import requestAsEventEmitter, {proxyEvents} from './request-as-event-emitter';
import {CancelableRequest, GeneralError, NormalizedOptions, Response} from './utils/types';

const parseBody = (body: Response['body'], responseType: NormalizedOptions['responseType'], statusCode: Response['statusCode']) => {
const parseBody = (body: Response['body'], responseType: NormalizedOptions['responseType'], statusCode: Response['statusCode']): unknown => {
if (responseType === 'json' && is.string(body)) {
return statusCode === 204 ? '' : JSON.parse(body);
}
Expand All @@ -24,7 +24,7 @@ const parseBody = (body: Response['body'], responseType: NormalizedOptions['resp
return body;
}

throw new Error(`Failed to parse body of type '${typeof body}' as '${responseType}'`);
throw new Error(`Failed to parse body of type '${typeof body}' as '${responseType!}'`);
};

export default function asPromise<T>(options: NormalizedOptions): CancelableRequest<T> {
Expand Down Expand Up @@ -66,7 +66,7 @@ export default function asPromise<T>(options: NormalizedOptions): CancelableRequ

try {
for (const [index, hook] of options.hooks.afterResponse.entries()) {
// @ts-ignore
// @ts-ignore Promise is not assignable to CancelableRequest
// eslint-disable-next-line no-await-in-loop
response = await hook(response, async (updatedOptions: NormalizedOptions) => {
updatedOptions = normalizeArguments(mergeOptions(options, {
Expand Down Expand Up @@ -141,7 +141,7 @@ export default function asPromise<T>(options: NormalizedOptions): CancelableRequ
emitter.once('error', reject);

proxyEvents(proxy, emitter);
}) as CancelableRequest<any>;
}) as CancelableRequest<T>;

promise.on = (name: string, fn: (...args: any[]) => void) => {
proxy.on(name, fn);
Expand All @@ -154,8 +154,7 @@ export default function asPromise<T>(options: NormalizedOptions): CancelableRequ

Object.defineProperties(newPromise, Object.getOwnPropertyDescriptors(promise));

// @ts-ignore The missing properties are added above
return newPromise;
return newPromise as CancelableRequest<T>;
};

promise.json = () => {
Expand Down
10 changes: 5 additions & 5 deletions source/as-stream.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import duplexer3 = require('duplexer3');
import stream = require('stream');
import {IncomingMessage} from 'http';
import {IncomingMessage, ServerResponse} from 'http';
import {Duplex as DuplexStream, PassThrough as PassThroughStream} from 'stream';
import {HTTPError, ReadError} from './errors';
import requestAsEventEmitter, {proxyEvents} from './request-as-event-emitter';
Expand All @@ -14,7 +14,7 @@ export default function asStream<T>(options: NormalizedOptions): ProxyStream<T>
const input = new PassThroughStream();
const output = new PassThroughStream();
const proxy = duplexer3(input, output) as ProxyStream;
const piped = new Set<any>(); // TODO: Should be `new Set<stream.Writable>();`.
const piped = new Set<ServerResponse>();
let isFinished = false;

options.retry.calculateDelay = () => 0;
Expand Down Expand Up @@ -91,7 +91,7 @@ export default function asStream<T>(options: NormalizedOptions): ProxyStream<T>
// It's not possible to decompress already decompressed data, is it?
const isAllowed = options.decompress ? key !== 'content-encoding' : true;
if (isAllowed) {
destination.setHeader(key, value);
destination.setHeader(key, value!);
}
}

Expand All @@ -114,15 +114,15 @@ export default function asStream<T>(options: NormalizedOptions): ProxyStream<T>

pipe(destination, options);

if (Reflect.has(destination, 'setHeader')) {
if (destination instanceof ServerResponse) {
piped.add(destination);
}

return destination;
};

proxy.unpipe = stream => {
piped.delete(stream);
piped.delete(stream as ServerResponse);
return unpipe(stream);
};

Expand Down
4 changes: 2 additions & 2 deletions source/calculate-retry-delay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const calculateRetryDelay: RetryFunction = ({attemptCount, retryOptions, error})

const hasMethod = retryOptions.methods.includes(error.options.method);
const hasErrorCode = Reflect.has(error, 'code') && retryOptions.errorCodes.includes(error.code);
const hasStatusCode = isErrorWithResponse(error) && Reflect.has(error, 'response') && retryOptions.statusCodes.includes(error.response?.statusCode);
const hasStatusCode = isErrorWithResponse(error) && retryOptions.statusCodes.includes(error.response.statusCode);
if (!hasMethod || (!hasErrorCode && !hasStatusCode)) {
return 0;
}
Expand All @@ -37,7 +37,7 @@ const calculateRetryDelay: RetryFunction = ({attemptCount, retryOptions, error})
return after;
}

if (response?.statusCode === 413) {
if (response.statusCode === 413) {
return 0;
}
}
Expand Down
28 changes: 16 additions & 12 deletions source/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import {normalizeArguments, mergeOptions} from './normalize-arguments';
import deepFreeze from './utils/deep-freeze';
import {
CancelableRequest,
Defaults,
DefaultOptions,
ExtendOptions,
HandlerFunction,
NormalizedDefaults,
NormalizedOptions,
Options,
Response,
Expand All @@ -28,7 +29,7 @@ export type GotReturn<T = unknown> = CancelableRequest<T> | ProxyStream<T>;

const getPromiseOrStream = (options: NormalizedOptions): GotReturn => options.isStream ? asStream(options) : asPromise(options);

const isGotInstance = (value: any): value is Got => (
const isGotInstance = (value: Got | ExtendOptions): value is Got => (
Reflect.has(value, 'defaults') && Reflect.has(value.defaults, 'options')
);

Expand All @@ -55,7 +56,7 @@ interface GotFunctions {

export interface Got extends Record<HTTPAlias, GotFunctions>, GotFunctions {
stream: GotStream;
defaults: NormalizedDefaults | Readonly<NormalizedDefaults>;
defaults: Defaults | Readonly<Defaults>;
GotError: typeof errors.GotError;
CacheError: typeof errors.CacheError;
RequestError: typeof errors.RequestError;
Expand Down Expand Up @@ -87,12 +88,13 @@ const aliases: readonly HTTPAlias[] = [

export const defaultHandler: HandlerFunction = (options, next) => next(options);

const create = (defaults: NormalizedDefaults & {_rawHandlers?: HandlerFunction[]}): Got => {
const create = (defaults: Defaults): Got => {
// Proxy properties from next handlers
// @ts-ignore Internal use only.
defaults._rawHandlers = defaults.handlers;
defaults.handlers = defaults.handlers.map(fn => ((options, next) => {
// This will be assigned by assigning result
let root!: GotReturn;
let root!: ReturnType<typeof next>;

const result = fn(options, newOptions => {
root = next(newOptions);
Expand All @@ -105,17 +107,17 @@ const create = (defaults: NormalizedDefaults & {_rawHandlers?: HandlerFunction[]
}

return result;
}) as HandlerFunction);
}));

// @ts-ignore Because the for loop handles it for us, as well as the other Object.defines
const got: Got = (url: URLOrOptions, options?: Options): GotReturn => {
let iteration = 0;
const iterateHandlers = (newOptions: Parameters<HandlerFunction>[0]): ReturnType<HandlerFunction> => {
const iterateHandlers = (newOptions: NormalizedOptions): GotReturn => {
return defaults.handlers[iteration++](
newOptions,
// @ts-ignore TS doesn't know that it calls `getPromiseOrStream` at the end
iteration === defaults.handlers.length ? getPromiseOrStream : iterateHandlers
);
) as GotReturn;
};

/* eslint-disable @typescript-eslint/return-await */
Expand All @@ -134,13 +136,15 @@ const create = (defaults: NormalizedDefaults & {_rawHandlers?: HandlerFunction[]

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

for (const value of instancesOrOptions) {
if (isGotInstance(value)) {
optionsArray.push(value.defaults.options);
handlers.push(...value.defaults._rawHandlers!);
// @ts-ignore Internal use only.
handlers.push(...value.defaults._rawHandlers);
mutableDefaults = value.defaults.mutableDefaults;
} else {
optionsArray.push(value);
Expand All @@ -160,7 +164,7 @@ const create = (defaults: NormalizedDefaults & {_rawHandlers?: HandlerFunction[]
}

return create({
options: mergeOptions(...optionsArray),
options: mergeOptions(...optionsArray) as DefaultOptions,
handlers,
mutableDefaults: Boolean(mutableDefaults)
});
Expand All @@ -170,7 +174,7 @@ const create = (defaults: NormalizedDefaults & {_rawHandlers?: HandlerFunction[]
got.stream = (url, options) => got(url, {...options, isStream: true});

for (const method of aliases) {
// @ts-ignore
// @ts-ignore GotReturn<Response> does not equal GotReturn<T>
got[method] = (url: URLOrOptions, options?: Options): GotReturn => got(url, {...options, method});
got.stream[method] = (url, options) => got.stream(url, {...options, method});
}
Expand Down
2 changes: 1 addition & 1 deletion source/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export class HTTPError extends GotError {
declare readonly response: Response;

constructor(response: Response, options: NormalizedOptions) {
super(`Response code ${response.statusCode} (${response.statusMessage ?? ''})`, {}, options);
super(`Response code ${response.statusCode} (${response.statusMessage!})`, {}, options);
this.name = 'HTTPError';

Object.defineProperty(this, 'response', {
Expand Down
2 changes: 1 addition & 1 deletion source/get-response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {NormalizedOptions} from './utils/types';

const pipeline = promisify(stream.pipeline);

export default async (response: IncomingMessage, options: NormalizedOptions, emitter: EventEmitter) => {
export default async (response: IncomingMessage, options: NormalizedOptions, emitter: EventEmitter): Promise<void> => {
const downloadBodySize = Number(response.headers['content-length']) || undefined;
const progressStream = createProgressStream('downloadProgress', emitter, downloadBodySize);

Expand Down
4 changes: 3 additions & 1 deletion source/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ const defaults: Defaults = {
resolveBodyOnly: false,
maxRedirects: 10,
prefixUrl: '',
methodRewriting: true
methodRewriting: true,
ignoreInvalidCookies: false,
context: {}
},
handlers: [defaultHandler],
mutableDefaults: false
Expand Down
Loading