UNPKG

@netlify/config

Version:
50 lines (49 loc) 2.21 kB
import deepmerge from 'deepmerge'; import isPlainObj from 'is-plain-obj'; import { groupBy } from './utils/group.js'; import { removeUndefined } from './utils/remove_falsy.js'; // Merge an array of configuration objects. // Last items have higher priority. // Configuration objects are deeply merged. // - By default, Arrays are overridden, not concatenated. This behavior can // be changed by setting the `concatenateArrays` property to `true`. export const mergeConfigs = function (configs, { concatenateArrays } = {}) { const cleanedConfigs = configs.map(removeUndefinedProps); return deepmerge.all(cleanedConfigs, { arrayMerge: concatenateArrays ? arrayConcatenate : arrayMerge }); }; const removeUndefinedProps = function ({ build = {}, ...config }) { return removeUndefined({ ...config, build: removeUndefined(build) }); }; // By default, `deepmerge` concatenates arrays. We use the `arrayMerge` option // to remove this behavior. Also, we merge some array properties differently, // such as `plugins`. const arrayMerge = function (arrayA, arrayB) { if (isPluginsProperty(arrayA) && isPluginsProperty(arrayB)) { return mergePlugins(arrayA, arrayB); } return arrayB; }; // Concatenate two arrays such that elements from array A come after elements // from array B. const arrayConcatenate = function (arrayA, arrayB) { return [...arrayB, ...arrayA]; }; // `deepmerge` does not allow retrieving the name of the array property being // merged, so we need to do some heuristics. const isPluginsProperty = function (array) { return Array.isArray(array) && array.every(isPluginObject); }; const isPluginObject = function (object) { return isPlainObj(object) && typeof object.package === 'string'; }; // Merge two `config.plugins`. Merge plugins with the same `plugin.package`. const mergePlugins = function (pluginsA, pluginsB) { const plugins = [...pluginsA, ...pluginsB]; return groupBy(plugins, 'package').map(mergePluginConfigs); }; const mergePluginConfigs = function (plugins) { return plugins.reduce(mergePluginsPair, {}); }; const mergePluginsPair = function (pluginA, pluginB) { return deepmerge(pluginA, pluginB, { arrayMerge }); };