From acefaa4c2a0cb3c33b3f952be29ac0a9cb316e87 Mon Sep 17 00:00:00 2001 From: Szymon Marczak <36894700+szmarczak@users.noreply.github.com> Date: Sun, 16 Feb 2020 21:08:04 +0100 Subject: [PATCH] Fix Init hooks not being called if extended --- source/normalize-arguments.ts | 28 +++++++++++++++++----------- test/hooks.ts | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/source/normalize-arguments.ts b/source/normalize-arguments.ts index 18b79421f..1c7a68df0 100644 --- a/source/normalize-arguments.ts +++ b/source/normalize-arguments.ts @@ -270,14 +270,10 @@ export const normalizeArguments = (url: URLOrOptions, options?: Options, default throw new TypeError('Missing `url` argument'); } - if (typeof options === 'undefined') { - options = {}; - } - const runInitHooks = (hooks?: InitHook[], options?: Options): void => { - if (hooks) { + if (hooks && options) { for (const hook of hooks) { - const result = hook(options!); + const result = hook(options); if (is.promise(result)) { throw new TypeError('The `init` hook must be a synchronous function'); @@ -288,25 +284,35 @@ export const normalizeArguments = (url: URLOrOptions, options?: Options, default const hasUrl = is.urlInstance(url) || is.string(url); if (hasUrl) { - if (Reflect.has(options, 'url')) { - throw new TypeError('The `url` option cannot be used if the input is a valid URL.'); + if (options) { + if (Reflect.has(options, 'url')) { + throw new TypeError('The `url` option cannot be used if the input is a valid URL.'); + } + } else { + options = {}; } // @ts-ignore URL is not URL options.url = url; + runInitHooks(defaults?.options.hooks.init, options); runInitHooks(options.hooks?.init, options); } else if (Reflect.has(url as object, 'resolve')) { throw new Error('The legacy `url.Url` is deprecated. Use `URL` instead.'); } else { + runInitHooks(defaults?.options.hooks.init, url as Options); runInitHooks((url as Options).hooks?.init, url as Options); - runInitHooks(options.hooks?.init, options); + + if (options) { + runInitHooks(defaults?.options.hooks.init, options); + runInitHooks(options.hooks?.init, options); + } } if (hasUrl) { - options = mergeOptions(defaults?.options ?? {}, options); + options = mergeOptions(defaults?.options ?? {}, options ?? {}); } else { - options = mergeOptions(defaults?.options ?? {}, url as object, options); + options = mergeOptions(defaults?.options ?? {}, url as object, options ?? {}); } // Normalize URL diff --git a/test/hooks.ts b/test/hooks.ts index 3bfd44405..8faa68109 100644 --- a/test/hooks.ts +++ b/test/hooks.ts @@ -201,6 +201,25 @@ test('init is called with options', withServer, async (t, server, got) => { }); }); +test('init from defaults is called with options', withServer, async (t, server, got) => { + server.get('/', echoHeaders); + + const context = {}; + + const instance = got.extend({ + hooks: { + init: [ + options => { + t.is(options.url, undefined); + t.is(options.context, context); + } + ] + } + }); + + await instance({context}); +}); + test('init allows modifications', withServer, async (t, server, got) => { server.get('/', (request, response) => { response.end(request.headers.foo);