Skip to content

Commit

Permalink
Merge hooks on got.extend() (#608)
Browse files Browse the repository at this point in the history
  • Loading branch information
szmarczak authored and sindresorhus committed Sep 10, 2018
1 parent 7ae6939 commit 292f78a
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 41 deletions.
8 changes: 3 additions & 5 deletions source/create.js
Expand Up @@ -5,10 +5,8 @@ const asPromise = require('./as-promise');
const normalizeArguments = require('./normalize-arguments');
const merge = require('./merge');
const deepFreeze = require('./deep-freeze');
const mergeInstances = require('./merge-instances');

const getPromiseOrStream = options => options.stream ? asStream(options) : asPromise(options);
const mergeOptions = (defaults, options = {}) => merge({}, defaults, options);

const aliases = [
'get',
Expand Down Expand Up @@ -42,11 +40,11 @@ const create = defaults => {

got.create = create;
got.extend = options => create({
options: mergeOptions(defaults.options, options),
options: merge.options(defaults.options, options),
handler: defaults.handler
});

got.mergeInstances = (...args) => create(mergeInstances(args));
got.mergeInstances = (...args) => create(merge.instances(args));

got.stream = (url, options) => got(url, {...options, stream: true});

Expand All @@ -55,7 +53,7 @@ const create = defaults => {
got.stream[method] = (url, options) => got.stream(url, {...options, method});
}

Object.assign(got, {...errors, mergeOptions});
Object.assign(got, {...errors, mergeOptions: merge.options});
Object.defineProperty(got, 'defaults', {
value: deepFreeze(defaults),
writable: false,
Expand Down
36 changes: 0 additions & 36 deletions source/merge-instances.js

This file was deleted.

45 changes: 45 additions & 0 deletions source/merge.js
@@ -1,6 +1,7 @@
'use strict';
const {URL} = require('url');
const is = require('@sindresorhus/is');
const knownHookEvents = require('./known-hook-events');

const merge = (target, ...sources) => {
for (const source of sources) {
Expand Down Expand Up @@ -29,4 +30,48 @@ const merge = (target, ...sources) => {
return target;
};

const mergeOptions = (...sources) => {
sources = sources.map(source => source || {});
const merged = merge({}, ...sources);

const hooks = {};
for (const hook of knownHookEvents) {
hooks[hook] = [];
}

for (const source of sources) {
if (source.hooks) {
for (const hook of knownHookEvents) {
if (hooks[hook]) {
hooks[hook] = hooks[hook].concat(source.hooks[hook]);
}
}
}
}

if (!is.empty(hooks)) {
merged.hooks = hooks;
}

return merged;
};

const mergeInstances = (instances, methods) => {
const handlers = instances.map(instance => instance.defaults.handler);
const size = instances.length - 1;

return {
methods,
options: mergeOptions(...instances.map(instance => instance.defaults.options)),
handler: (options, next) => {
let iteration = -1;
const iterate = options => handlers[++iteration](options, iteration === size ? next : iterate);

return iterate(options);
}
};
};

module.exports = merge;
module.exports.options = mergeOptions;
module.exports.instances = mergeInstances;
10 changes: 10 additions & 0 deletions test/create.js
Expand Up @@ -115,6 +115,16 @@ test('create', async t => {
t.is(headers['user-agent'], undefined);
});

test('hooks are merged on got.extend()', t => {
const hooksA = [() => {}];
const hooksB = [() => {}];

const instanceA = got.create({options: {hooks: {beforeRequest: hooksA}}});

const extended = instanceA.extend({hooks: {beforeRequest: hooksB}});
t.deepEqual(extended.defaults.options.hooks.beforeRequest, hooksA.concat(hooksB));
});

test('custom endpoint with custom headers (extend)', async t => {
const instance = got.extend({headers: {unicorn: 'rainbow'}, baseUrl: s.url});
const headers = (await instance('/', {
Expand Down

0 comments on commit 292f78a

Please sign in to comment.