UNPKG

@boost/config

Version:

Powerful convention based finder, loader, and manager of both configuration and ignore files.

196 lines (178 loc) 5.3 kB
import { Contract } from '@boost/common'; import { schemas } from '@boost/common/optimal'; import { WaterfallEvent, Event } from '@boost/event'; import { Cache } from './Cache.mjs'; import { ConfigFinder } from './ConfigFinder.mjs'; import { IgnoreFinder } from './IgnoreFinder.mjs'; import { Processor } from './Processor.mjs'; class Configuration extends Contract { constructor(name, resolver) { super(); /** * Called after config files are loaded but before processed. Can modify config file list. * @category Events */ this.onLoadedConfig = new WaterfallEvent('loaded-config'); /** * Called after ignore files are loaded. Can modify ignore file list. * @category Events */ this.onLoadedIgnore = new WaterfallEvent('loaded-ignore'); /** * Called after config files are loaded and processed. * @category Events */ this.onProcessedConfig = new Event('processed-config'); this.cache = void 0; this.configFinder = void 0; this.ignoreFinder = void 0; this.processor = void 0; this.cache = new Cache(); this.configFinder = new ConfigFinder({ name, resolver }, this.cache); this.ignoreFinder = new IgnoreFinder({ name }, this.cache); this.processor = new Processor({ name }); this.bootstrap(); } /** * Clear all cache. */ clearCache() { this.clearFileCache(); this.clearFinderCache(); return this; } /** * Clear all cached file contents. */ clearFileCache() { this.cache.clearFileCache(); return this; } /** * Clear all cached directory and file path information. */ clearFinderCache() { this.cache.clearFinderCache(); return this; } /** * Attempt to find the root directory starting from the provided directory. * Once the root is found, it will be cached for further lookups, * otherwise an error is thrown based on current configuration. */ async findRootDir(fromDir = process.cwd()) { return this.getConfigFinder().findRootDir(fromDir); } /** * Traverse upwards from the branch directory, until the root directory is found, * or we reach to top of the file system. While traversing, find all config files * within each branch directory, and the root. */ async loadConfigFromBranchToRoot(dir) { const configs = await this.getConfigFinder().loadFromBranchToRoot(dir); return this.processConfigs(this.onLoadedConfig.emit(configs)); } /** * Load config files from the defined root. Root is determined by a relative * `.config` folder and `package.json` file. */ async loadConfigFromRoot(fromDir = process.cwd()) { const configs = await this.getConfigFinder().loadFromRoot(fromDir); return this.processConfigs(this.onLoadedConfig.emit(configs)); } /** * Traverse upwards from the branch directory, until the root directory is found, * or we reach to top of the file system. While traversing, find all ignore files * within each branch directory, and the root. */ async loadIgnoreFromBranchToRoot(dir) { const ignores = await this.getIgnoreFinder().loadFromBranchToRoot(dir); return this.onLoadedIgnore.emit(ignores); } /** * Load ignore file from the defined root. Root is determined by a relative * `.config` folder and `package.json` file. */ async loadIgnoreFromRoot(dir = process.cwd()) { const ignores = await this.getIgnoreFinder().loadFromRoot(dir); return this.onLoadedIgnore.emit(ignores); } /** * Explicitly set the root directory to stop traversal at. This should only be set * manually when you want full control, and know file boundaries up front. * * This *does not* check for the existence of the root config file or folder. */ setRootDir(dir) { this.cache.setRootDir(dir); return this; } /** * Add a process handler to customize the processing of key-value setting pairs. * May only run a processor on settings found in the root of the configuration object. * @public */ addProcessHandler(key, handler) { this.getProcessor().addHandler(key, handler); return this; } /** * Life cycle called on initialization. * @public */ bootstrap() {} /** * Configure the finder instance. * @public */ configureFinder(options) { this.getConfigFinder().configure(options); return this; } /** * Configure the processor instance. * @public */ configureProcessor(options) { this.getProcessor().configure(options); return this; } /** * Return the config file finder instance. */ getConfigFinder() { return this.configFinder; } /** * Return the ignore file finder instance. */ getIgnoreFinder() { return this.ignoreFinder; } /** * Return the processor instance. */ getProcessor() { return this.processor; } /** * Process all loaded config objects into a single config object, and then validate. */ async processConfigs(files) { const config = await this.getProcessor().process(this.options, files, this.blueprint(schemas)); this.onProcessedConfig.emit([config]); return { config, files }; } } export { Configuration }; //# sourceMappingURL=Configuration.mjs.map