import type { ITerminal } from '@rushstack/terminal';
import type { IRigConfig } from '@rushstack/rig-package';
/**
 * @beta
 */
export declare enum InheritanceType {
    /**
     * Append additional elements after elements from the parent file's property. Only applicable
     * for arrays.
     */
    append = "append",
    /**
     * Perform a shallow merge of additional elements after elements from the parent file's property.
     * Only applicable for objects.
     */
    merge = "merge",
    /**
     * Discard elements from the parent file's property
     */
    replace = "replace",
    /**
     * Custom inheritance functionality
     */
    custom = "custom"
}
/**
 * @beta
 */
export declare enum PathResolutionMethod {
    /**
     * Resolve a path relative to the configuration file
     */
    resolvePathRelativeToConfigurationFile = "resolvePathRelativeToConfigurationFile",
    /**
     * Resolve a path relative to the root of the project containing the configuration file
     */
    resolvePathRelativeToProjectRoot = "resolvePathRelativeToProjectRoot",
    /**
     * Treat the property as a NodeJS-style require/import reference and resolve using standard
     * NodeJS filesystem resolution
     *
     * @deprecated
     * Use {@link PathResolutionMethod.nodeResolve} instead
     */
    NodeResolve = "NodeResolve",
    /**
     * Treat the property as a NodeJS-style require/import reference and resolve using standard
     * NodeJS filesystem resolution
     */
    nodeResolve = "nodeResolve",
    /**
     * Resolve the property using a custom resolver.
     */
    custom = "custom"
}
export declare const CONFIGURATION_FILE_FIELD_ANNOTATION: unique symbol;
export interface IAnnotatedField<TField> {
    [CONFIGURATION_FILE_FIELD_ANNOTATION]: IConfigurationFileFieldAnnotation<TField>;
}
interface IConfigurationFileFieldAnnotation<TField> {
    configurationFilePath: string | undefined;
    originalValues: {
        [propertyName in keyof TField]: unknown;
    };
}
/**
 * Options provided to the custom resolver specified in {@link ICustomJsonPathMetadata}.
 *
 * @beta
 */
export interface IJsonPathMetadataResolverOptions<TConfigurationFile> {
    /**
     * The name of the property being resolved.
     */
    propertyName: string;
    /**
     * The value of the path property being resolved.
     */
    propertyValue: string;
    /**
     * The path to the configuration file the property was obtained from.
     */
    configurationFilePath: string;
    /**
     * The configuration file the property was obtained from.
     */
    configurationFile: Partial<TConfigurationFile>;
}
/**
 * Used to specify how node(s) in a JSON object should be processed after being loaded.
 *
 * @beta
 */
export interface ICustomJsonPathMetadata<TConfigurationFile> {
    /**
     * If `ICustomJsonPathMetadata.pathResolutionMethod` is set to `PathResolutionMethod.custom`,
     * this property be used to resolve the path.
     */
    customResolver?: (resolverOptions: IJsonPathMetadataResolverOptions<TConfigurationFile>) => string;
    /**
     * If this property describes a filesystem path, use this property to describe
     * how the path should be resolved.
     */
    pathResolutionMethod?: PathResolutionMethod.custom;
}
/**
 * Used to specify how node(s) in a JSON object should be processed after being loaded.
 *
 * @beta
 */
export interface INonCustomJsonPathMetadata {
    /**
     * If this property describes a filesystem path, use this property to describe
     * how the path should be resolved.
     */
    pathResolutionMethod?: PathResolutionMethod.NodeResolve | PathResolutionMethod.nodeResolve | PathResolutionMethod.resolvePathRelativeToConfigurationFile | PathResolutionMethod.resolvePathRelativeToProjectRoot;
}
/**
 * @beta
 */
export type PropertyInheritanceCustomFunction<TObject> = (currentObject: TObject, parentObject: TObject) => TObject;
/**
 * @beta
 */
export interface IPropertyInheritance<TInheritanceType extends InheritanceType> {
    inheritanceType: TInheritanceType;
}
/**
 * @beta
 */
export interface ICustomPropertyInheritance<TObject> extends IPropertyInheritance<InheritanceType.custom> {
    /**
     * Provides a custom inheritance function. This function takes two arguments: the first is the
     * child file's object, and the second is the parent file's object. The function should return
     * the resulting combined object.
     */
    inheritanceFunction: PropertyInheritanceCustomFunction<TObject>;
}
/**
 * @beta
 */
export type IPropertiesInheritance<TConfigurationFile> = {
    [propertyName in keyof TConfigurationFile]?: IPropertyInheritance<InheritanceType.append | InheritanceType.merge | InheritanceType.replace> | ICustomPropertyInheritance<TConfigurationFile[propertyName]>;
};
/**
 * @beta
 */
export interface IPropertyInheritanceDefaults {
    array?: IPropertyInheritance<InheritanceType.append | InheritanceType.replace>;
    object?: IPropertyInheritance<InheritanceType.merge | InheritanceType.replace>;
}
/**
 * @beta
 */
export type IJsonPathMetadata<T> = ICustomJsonPathMetadata<T> | INonCustomJsonPathMetadata;
/**
 * Keys in this object are JSONPaths {@link https://jsonpath.com/}, and values are objects
 * that describe how node(s) selected by the JSONPath are processed after loading.
 *
 * @beta
 */
export interface IJsonPathsMetadata<TConfigurationFile> {
    [jsonPath: string]: IJsonPathMetadata<TConfigurationFile>;
}
/**
 * @beta
 */
export interface IConfigurationFileOptionsBase<TConfigurationFile> {
    /**
     * Use this property to specify how JSON nodes are postprocessed.
     */
    jsonPathMetadata?: IJsonPathsMetadata<TConfigurationFile>;
    /**
     * Use this property to control how root-level properties are handled between parent and child
     * configuration files.
     */
    propertyInheritance?: IPropertiesInheritance<TConfigurationFile>;
    /**
     * Use this property to control how specific property types are handled between parent and child
     * configuration files.
     */
    propertyInheritanceDefaults?: IPropertyInheritanceDefaults;
}
/**
 * @beta
 */
export type IConfigurationFileOptionsWithJsonSchemaFilePath<TConfigurationFile, TExtraOptions extends {}> = IConfigurationFileOptionsBase<TConfigurationFile> & TExtraOptions & {
    /**
     * The path to the schema for the configuration file.
     */
    jsonSchemaPath: string;
    jsonSchemaObject?: never;
};
/**
 * @beta
 */
export type IConfigurationFileOptionsWithJsonSchemaObject<TConfigurationFile, TExtraOptions extends {}> = IConfigurationFileOptionsBase<TConfigurationFile> & TExtraOptions & {
    /**
     * The schema for the configuration file.
     */
    jsonSchemaObject: object;
    jsonSchemaPath?: never;
};
/**
 * @beta
 */
export type IConfigurationFileOptions<TConfigurationFile, TExtraOptions extends object> = IConfigurationFileOptionsWithJsonSchemaFilePath<TConfigurationFile, TExtraOptions> | IConfigurationFileOptionsWithJsonSchemaObject<TConfigurationFile, TExtraOptions>;
/**
 * @beta
 */
export interface IOriginalValueOptions<TParentProperty> {
    parentObject: Partial<TParentProperty>;
    propertyName: keyof TParentProperty;
}
/**
 * @beta
 */
export declare abstract class ConfigurationFileBase<TConfigurationFile, TExtraOptions extends {}> {
    private readonly _getSchema;
    private readonly _jsonPathMetadata;
    private readonly _propertyInheritanceTypes;
    private readonly _defaultPropertyInheritance;
    private __schema;
    private get _schema();
    private readonly _configCache;
    private readonly _configPromiseCache;
    private readonly _packageJsonLookup;
    constructor(options: IConfigurationFileOptions<TConfigurationFile, TExtraOptions>);
    /**
     * @internal
     */
    static _formatPathForLogging: (path: string) => string;
    /**
     * Get the path to the source file that the referenced property was originally
     * loaded from.
     */
    getObjectSourceFilePath<TObject extends object>(obj: TObject): string | undefined;
    /**
     * Get the value of the specified property on the specified object that was originally
     * loaded from a configuration file.
     */
    getPropertyOriginalValue<TParentProperty extends object, TValue>(options: IOriginalValueOptions<TParentProperty>): TValue | undefined;
    protected _loadConfigurationFileInnerWithCache(terminal: ITerminal, resolvedConfigurationFilePath: string, visitedConfigurationFilePaths: Set<string>, rigConfig: IRigConfig | undefined): TConfigurationFile;
    protected _loadConfigurationFileInnerWithCacheAsync(terminal: ITerminal, resolvedConfigurationFilePath: string, visitedConfigurationFilePaths: Set<string>, rigConfig: IRigConfig | undefined): Promise<TConfigurationFile>;
    protected abstract _tryLoadConfigurationFileInRig(terminal: ITerminal, rigConfig: IRigConfig, visitedConfigurationFilePaths: Set<string>): TConfigurationFile | undefined;
    protected abstract _tryLoadConfigurationFileInRigAsync(terminal: ITerminal, rigConfig: IRigConfig, visitedConfigurationFilePaths: Set<string>): Promise<TConfigurationFile | undefined>;
    private _parseAndResolveConfigurationFile;
    private _loadConfigurationFileInner;
    private _loadConfigurationFileInnerAsync;
    private _annotateProperties;
    private _annotateProperty;
    private _resolvePathProperty;
    private _mergeConfigurationFiles;
    private _mergeObjects;
}
export {};
//# sourceMappingURL=ConfigurationFileBase.d.ts.map