| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 | 'use strict';const fs = require('fs');const path = require('path');const {promisify} = require('util');const camelcase = require('camelcase');const findUp = require('find-up');const resolveFrom = require('resolve-from');const getPackageType = require('get-package-type');const readFile = promisify(fs.readFile);let loadActive = false;function isLoading() {	return loadActive;}const standardConfigFiles = [	'.nycrc',	'.nycrc.json',	'.nycrc.yml',	'.nycrc.yaml',	'nyc.config.js',	'nyc.config.cjs',	'nyc.config.mjs'];function camelcasedConfig(config) {	const results = {};	for (const [field, value] of Object.entries(config)) {		results[camelcase(field)] = value;	}	return results;}async function findPackage(options) {	const cwd = options.cwd || process.env.NYC_CWD || process.cwd();	const pkgPath = await findUp('package.json', {cwd});	if (pkgPath) {		const pkgConfig = JSON.parse(await readFile(pkgPath, 'utf8')).nyc || {};		if ('cwd' in pkgConfig) {			pkgConfig.cwd = path.resolve(path.dirname(pkgPath), pkgConfig.cwd);		}		return {			cwd: path.dirname(pkgPath),			pkgConfig		};	}	return {		cwd,		pkgConfig: {}	};}async function actualLoad(configFile) {	if (!configFile) {		return {};	}	const configExt = path.extname(configFile).toLowerCase();	switch (configExt) {		case '.js':			/* istanbul ignore next: coverage for 13.2.0+ is shown in load-esm.js */			if (await getPackageType(configFile) === 'module') {				return require('./load-esm')(configFile);			}			/* fallthrough */		case '.cjs':			return require(configFile);		/* istanbul ignore next: coverage for 13.2.0+ is shown in load-esm.js */		case '.mjs':			return require('./load-esm')(configFile);		case '.yml':		case '.yaml':			return require('js-yaml').load(await readFile(configFile, 'utf8'));		default:			return JSON.parse(await readFile(configFile, 'utf8'));	}}async function loadFile(configFile) {	/* This lets @istanbuljs/esm-loader-hook avoid circular initialization when loading	 * configuration.  This should generally only happen when the loader hook is active	 * on the main nyc process. */	loadActive = true;	try {		return await actualLoad(configFile);	} finally {		loadActive = false;	}}async function applyExtends(config, filename, loopCheck = new Set()) {	config = camelcasedConfig(config);	if ('extends' in config) {		const extConfigs = [].concat(config.extends);		if (extConfigs.some(e => typeof e !== 'string')) {			throw new TypeError(`${filename} contains an invalid 'extends' option`);		}		delete config.extends;		const filePath = path.dirname(filename);		for (const extConfig of extConfigs) {			const configFile = resolveFrom.silent(filePath, extConfig) ||				resolveFrom.silent(filePath, './' + extConfig);			if (!configFile) {				throw new Error(`Could not resolve configuration file ${extConfig} from ${path.dirname(filename)}.`);			}			if (loopCheck.has(configFile)) {				throw new Error(`Circular extended configurations: '${configFile}'.`);			}			loopCheck.add(configFile);			// eslint-disable-next-line no-await-in-loop			const configLoaded = await loadFile(configFile);			if ('cwd' in configLoaded) {				configLoaded.cwd = path.resolve(path.dirname(configFile), configLoaded.cwd);			}			Object.assign(				config,				// eslint-disable-next-line no-await-in-loop				await applyExtends(configLoaded, configFile, loopCheck)			);		}	}	return config;}async function loadNycConfig(options = {}) {	const {cwd, pkgConfig} = await findPackage(options);	const configFiles = [].concat(options.nycrcPath || standardConfigFiles);	const configFile = await findUp(configFiles, {cwd});	if (options.nycrcPath && !configFile) {		throw new Error(`Requested configuration file ${options.nycrcPath} not found`);	}	const config = {		cwd,		...(await applyExtends(pkgConfig, path.join(cwd, 'package.json'))),		...(await applyExtends(await loadFile(configFile), configFile))	};	const arrayFields = ['require', 'extension', 'exclude', 'include'];	for (const arrayField of arrayFields) {		if (config[arrayField]) {			config[arrayField] = [].concat(config[arrayField]);		}	}	return config;}module.exports = {	loadNycConfig,	isLoading};
 |