60 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			60 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import { YError } from '../yerror.js';
 | 
						|
let previouslyVisitedConfigs = [];
 | 
						|
let shim;
 | 
						|
export function applyExtends(config, cwd, mergeExtends, _shim) {
 | 
						|
    shim = _shim;
 | 
						|
    let defaultConfig = {};
 | 
						|
    if (Object.prototype.hasOwnProperty.call(config, 'extends')) {
 | 
						|
        if (typeof config.extends !== 'string')
 | 
						|
            return defaultConfig;
 | 
						|
        const isPath = /\.json|\..*rc$/.test(config.extends);
 | 
						|
        let pathToDefault = null;
 | 
						|
        if (!isPath) {
 | 
						|
            try {
 | 
						|
                pathToDefault = require.resolve(config.extends);
 | 
						|
            }
 | 
						|
            catch (_err) {
 | 
						|
                return config;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            pathToDefault = getPathToDefaultConfig(cwd, config.extends);
 | 
						|
        }
 | 
						|
        checkForCircularExtends(pathToDefault);
 | 
						|
        previouslyVisitedConfigs.push(pathToDefault);
 | 
						|
        defaultConfig = isPath
 | 
						|
            ? JSON.parse(shim.readFileSync(pathToDefault, 'utf8'))
 | 
						|
            : require(config.extends);
 | 
						|
        delete config.extends;
 | 
						|
        defaultConfig = applyExtends(defaultConfig, shim.path.dirname(pathToDefault), mergeExtends, shim);
 | 
						|
    }
 | 
						|
    previouslyVisitedConfigs = [];
 | 
						|
    return mergeExtends
 | 
						|
        ? mergeDeep(defaultConfig, config)
 | 
						|
        : Object.assign({}, defaultConfig, config);
 | 
						|
}
 | 
						|
function checkForCircularExtends(cfgPath) {
 | 
						|
    if (previouslyVisitedConfigs.indexOf(cfgPath) > -1) {
 | 
						|
        throw new YError(`Circular extended configurations: '${cfgPath}'.`);
 | 
						|
    }
 | 
						|
}
 | 
						|
function getPathToDefaultConfig(cwd, pathToExtend) {
 | 
						|
    return shim.path.resolve(cwd, pathToExtend);
 | 
						|
}
 | 
						|
function mergeDeep(config1, config2) {
 | 
						|
    const target = {};
 | 
						|
    function isObject(obj) {
 | 
						|
        return obj && typeof obj === 'object' && !Array.isArray(obj);
 | 
						|
    }
 | 
						|
    Object.assign(target, config1);
 | 
						|
    for (const key of Object.keys(config2)) {
 | 
						|
        if (isObject(config2[key]) && isObject(target[key])) {
 | 
						|
            target[key] = mergeDeep(config1[key], config2[key]);
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            target[key] = config2[key];
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return target;
 | 
						|
}
 |