import { Contract, type ModuleResolver, Path, type PortablePath } from '@boost/common';
import { Event, WaterfallEvent } from '@boost/event';
import { ConfigFinder } from './ConfigFinder';
import { IgnoreFinder } from './IgnoreFinder';
import { Processor } from './Processor';
import type { ConfigFile, ConfigFinderOptions, Handler, IgnoreFile, ProcessedConfig, ProcessorOptions } from './types';
export declare abstract class Configuration<T extends object> extends Contract<T> {
    /**
     * Called after config files are loaded but before processed. Can modify config file list.
     * @category Events
     */
    readonly onLoadedConfig: WaterfallEvent<ConfigFile<T>[], string>;
    /**
     * Called after ignore files are loaded. Can modify ignore file list.
     * @category Events
     */
    readonly onLoadedIgnore: WaterfallEvent<IgnoreFile[], string>;
    /**
     * Called after config files are loaded and processed.
     * @category Events
     */
    readonly onProcessedConfig: Event<[Required<T>], string>;
    private cache;
    private configFinder;
    private ignoreFinder;
    private processor;
    constructor(name: string, resolver?: ModuleResolver);
    /**
     * Clear all cache.
     */
    clearCache(): this;
    /**
     * Clear all cached file contents.
     */
    clearFileCache(): this;
    /**
     * Clear all cached directory and file path information.
     */
    clearFinderCache(): 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.
     */
    findRootDir(fromDir?: PortablePath): Promise<Path>;
    /**
     * 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.
     */
    loadConfigFromBranchToRoot(dir: PortablePath): Promise<ProcessedConfig<T>>;
    /**
     * Load config files from the defined root. Root is determined by a relative
     * `.config` folder and `package.json` file.
     */
    loadConfigFromRoot(fromDir?: PortablePath): Promise<ProcessedConfig<T>>;
    /**
     * 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.
     */
    loadIgnoreFromBranchToRoot(dir: PortablePath): Promise<IgnoreFile[]>;
    /**
     * Load ignore file from the defined root. Root is determined by a relative
     * `.config` folder and `package.json` file.
     */
    loadIgnoreFromRoot(dir?: PortablePath): Promise<IgnoreFile[]>;
    /**
     * 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: PortablePath): 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
     */
    protected addProcessHandler<K extends keyof T, V = T[K]>(key: K, handler: Handler<V>): this;
    /**
     * Life cycle called on initialization.
     * @public
     */
    protected bootstrap(): void;
    /**
     * Configure the finder instance.
     * @public
     */
    protected configureFinder(options: Omit<ConfigFinderOptions<T>, 'name'>): this;
    /**
     * Configure the processor instance.
     * @public
     */
    protected configureProcessor(options: Omit<ProcessorOptions, 'name'>): this;
    /**
     * Return the config file finder instance.
     */
    protected getConfigFinder(): ConfigFinder<T>;
    /**
     * Return the ignore file finder instance.
     */
    protected getIgnoreFinder(): IgnoreFinder;
    /**
     * Return the processor instance.
     */
    protected getProcessor(): Processor<T>;
    /**
     * Process all loaded config objects into a single config object, and then validate.
     */
    protected processConfigs(files: ConfigFile<T>[]): Promise<ProcessedConfig<T>>;
}
//# sourceMappingURL=Configuration.d.ts.map