UNPKG

@rushstack/heft-config-file

Version:

Configuration file loader for @rushstack/heft

382 lines 15 kB
import type { ITerminal } from '@rushstack/terminal'; /** * @beta * * The set of possible mechanisms for merging properties from parent configuration files. * If a child configuration file sets a property value to `null`, that will always delete the value * specified in the parent configuration file, regardless of the inheritance type. */ declare const InheritanceType: { /** * Append additional elements after elements from the parent file's property. Only applicable * for arrays. */ readonly append: "append"; /** * Perform a shallow merge of additional elements after elements from the parent file's property. * Only applicable for objects. */ readonly merge: "merge"; /** * Discard elements from the parent file's property */ readonly replace: "replace"; /** * Custom inheritance functionality */ readonly custom: "custom"; }; /** * @beta */ type InheritanceType = (typeof InheritanceType)[keyof typeof InheritanceType]; /** * @beta */ declare namespace InheritanceType { /** * Append additional elements after elements from the parent file's property. Only applicable * for arrays. */ type append = typeof InheritanceType.append; /** * Perform a shallow merge of additional elements after elements from the parent file's property. * Only applicable for objects. */ type merge = typeof InheritanceType.merge; /** * Discard elements from the parent file's property */ type replace = typeof InheritanceType.replace; /** * Custom inheritance functionality */ type custom = typeof InheritanceType.custom; } export { InheritanceType }; /** * @beta * * The set of possible resolution methods for fields that refer to paths. */ declare const PathResolutionMethod: { /** * Resolve a path relative to the configuration file */ readonly resolvePathRelativeToConfigurationFile: "resolvePathRelativeToConfigurationFile"; /** * Resolve a path relative to the root of the project containing the configuration file */ readonly resolvePathRelativeToProjectRoot: "resolvePathRelativeToProjectRoot"; /** * Treat the property as a NodeJS-style require/import reference and resolve using standard * NodeJS filesystem resolution * * @deprecated * Use {@link (PathResolutionMethod:variable).nodeResolve} instead */ readonly NodeResolve: "NodeResolve"; /** * Treat the property as a NodeJS-style require/import reference and resolve using standard * NodeJS filesystem resolution */ readonly nodeResolve: "nodeResolve"; /** * Resolve the property using a custom resolver. */ readonly custom: "custom"; }; /** * @beta */ type PathResolutionMethod = (typeof PathResolutionMethod)[keyof typeof PathResolutionMethod]; /** * @beta */ declare namespace PathResolutionMethod { /** * Resolve a path relative to the configuration file */ type resolvePathRelativeToConfigurationFile = typeof PathResolutionMethod.resolvePathRelativeToConfigurationFile; /** * Resolve a path relative to the root of the project containing the configuration file */ type resolvePathRelativeToProjectRoot = typeof PathResolutionMethod.resolvePathRelativeToProjectRoot; /** * Treat the property as a NodeJS-style require/import reference and resolve using standard * NodeJS filesystem resolution * * @deprecated * Use {@link (PathResolutionMethod:namespace).nodeResolve} instead */ type NodeResolve = typeof PathResolutionMethod.NodeResolve; /** * Treat the property as a NodeJS-style require/import reference and resolve using standard * NodeJS filesystem resolution */ type nodeResolve = typeof PathResolutionMethod.nodeResolve; /** * Resolve the property using a custom resolver. */ type custom = typeof PathResolutionMethod.custom; } export { PathResolutionMethod }; export declare const CONFIGURATION_FILE_FIELD_ANNOTATION: unique symbol; export interface IAnnotatedField<TField, TConfigurationFileFieldAnnotation extends IConfigurationFileFieldAnnotation<TField> = IConfigurationFileFieldAnnotation<TField>> { [CONFIGURATION_FILE_FIELD_ANNOTATION]: TConfigurationFileFieldAnnotation; } 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>; /** * If this is a project configuration file, the root folder of the project. */ projectFolderPath?: string; } /** * 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. * This function will not be invoked if the current value is `null`, the property will simply be deleted. */ 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>; } /** * A function to invoke after schema validation to validate the configuration file. * If this function returns any value other than `true`, the configuration file API * will throw an error indicating that custom validation failed. If the function wishes * to provide its own error message, it may use any combination of the terminal and throwing * its own error. * @beta */ export type CustomValidationFunction<TConfigurationFile> = (configurationFile: TConfigurationFile, resolvedConfigurationFilePathForLogging: string, terminal: ITerminal) => boolean; /** * @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; /** * Use this property if you need to validate the configuration file in ways beyond what JSON schema can handle. * This function will be invoked after JSON schema validation. * * If the file is valid, this function should return `true`, otherwise `ConfigurationFile` will throw an error * indicating that custom validation failed. To suppress this error, the function may itself choose to throw. */ customValidationFunction?: CustomValidationFunction<TConfigurationFile>; } /** * @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; } /** * Callback that returns a fallback configuration file path if the original configuration file was not found. * @beta */ export type IOnConfigurationFileNotFoundCallback = (resolvedConfigurationFilePathForLogging: string) => string | undefined; /** * @beta */ export declare abstract class ConfigurationFileBase<TConfigurationFile, TExtraOptions extends {}> { private readonly _getSchema; private readonly _jsonPathMetadata; private readonly _propertyInheritanceTypes; private readonly _defaultPropertyInheritance; private readonly _customValidationFunction; private __schema; private get _schema(); private readonly _configCache; private readonly _configPromiseCache; 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; /** * Get the original value of the `$schema` property from the original configuration file, it one was present. */ getSchemaPropertyOriginalValue<TObject extends object>(obj: TObject): string | undefined; protected _loadConfigurationFileInnerWithCache(terminal: ITerminal, resolvedConfigurationFilePath: string, projectFolderPath: string | undefined, onConfigurationFileNotFound?: IOnConfigurationFileNotFoundCallback): TConfigurationFile; protected _loadConfigurationFileInnerWithCacheAsync(terminal: ITerminal, resolvedConfigurationFilePath: string, projectFolderPath: string | undefined, onFileNotFound?: IOnConfigurationFileNotFoundCallback): Promise<TConfigurationFile>; private _loadConfigurationFileEntryWithCache; private _loadConfigurationFileEntryWithCacheAsync; /** * Parses the raw JSON-with-comments text of the configuration file. * @param fileText - The text of the configuration file * @param resolvedConfigurationFilePathForLogging - The path to the configuration file, formatted for logs * @returns The parsed configuration file */ private _parseConfigurationFile; /** * Resolves all path properties and annotates properties with their original values. * @param entry - The cache entry for the loaded configuration file * @param projectFolderPath - The project folder path, if applicable * @returns The configuration file with all path properties resolved */ private _contextualizeConfigurationFile; /** * Resolves all path properties and merges parent properties. * @param entry - The cache entry for the loaded configuration file * @param projectFolderPath - The project folder path, if applicable * @returns The flattened, unvalidated configuration file, with path properties resolved */ private _contextualizeAndFlattenConfigurationFile; /** * Resolves all path properties, merges parent properties, and validates the configuration file. * @param entry - The cache entry for the loaded configuration file * @param projectFolderPath - The project folder path, if applicable * @param terminal - The terminal to log validation messages to * @returns The finalized configuration file */ private _finalizeConfigurationFile; private _loadConfigurationFileEntry; private _loadConfigurationFileEntryAsync; private _annotateProperties; private _resolvePathProperty; private _mergeConfigurationFiles; private _mergeObjects; } //# sourceMappingURL=ConfigurationFileBase.d.ts.map