thedesk/app/node_modules/got/source/merge.js
2019-09-12 23:38:13 +09:00

74 lines
1.8 KiB
JavaScript

'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) {
for (const [key, sourceValue] of Object.entries(source)) {
if (is.undefined(sourceValue)) {
continue;
}
const targetValue = target[key];
if (is.urlInstance(targetValue) && (is.urlInstance(sourceValue) || is.string(sourceValue))) {
target[key] = new URL(sourceValue, targetValue);
} else if (is.plainObject(sourceValue)) {
if (is.plainObject(targetValue)) {
target[key] = merge({}, targetValue, sourceValue);
} else {
target[key] = merge({}, sourceValue);
}
} else if (is.array(sourceValue)) {
target[key] = merge([], sourceValue);
} else {
target[key] = sourceValue;
}
}
}
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) {
hooks[hook] = hooks[hook].concat(source.hooks[hook]);
}
}
}
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;