54 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			54 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 
 | ||
|  | 'use strict' | ||
|  | const fs = require('fs') | ||
|  | const path = require('path') | ||
|  | const YError = require('./yerror') | ||
|  | 
 | ||
|  | let previouslyVisitedConfigs = [] | ||
|  | 
 | ||
|  | function checkForCircularExtends (cfgPath) { | ||
|  |   if (previouslyVisitedConfigs.indexOf(cfgPath) > -1) { | ||
|  |     throw new YError(`Circular extended configurations: '${cfgPath}'.`) | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | function getPathToDefaultConfig (cwd, pathToExtend) { | ||
|  |   return path.resolve(cwd, pathToExtend) | ||
|  | } | ||
|  | 
 | ||
|  | function applyExtends (config, cwd) { | ||
|  |   let defaultConfig = {} | ||
|  | 
 | ||
|  |   if (config.hasOwnProperty('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) { | ||
|  |         // most likely this simply isn't a module.
 | ||
|  |       } | ||
|  |     } else { | ||
|  |       pathToDefault = getPathToDefaultConfig(cwd, config.extends) | ||
|  |     } | ||
|  |     // maybe the module uses key for some other reason,
 | ||
|  |     // err on side of caution.
 | ||
|  |     if (!pathToDefault && !isPath) return config | ||
|  | 
 | ||
|  |     checkForCircularExtends(pathToDefault) | ||
|  | 
 | ||
|  |     previouslyVisitedConfigs.push(pathToDefault) | ||
|  | 
 | ||
|  |     defaultConfig = isPath ? JSON.parse(fs.readFileSync(pathToDefault, 'utf8')) : require(config.extends) | ||
|  |     delete config.extends | ||
|  |     defaultConfig = applyExtends(defaultConfig, path.dirname(pathToDefault)) | ||
|  |   } | ||
|  | 
 | ||
|  |   previouslyVisitedConfigs = [] | ||
|  | 
 | ||
|  |   return Object.assign({}, defaultConfig, config) | ||
|  | } | ||
|  | 
 | ||
|  | module.exports = applyExtends |