UNPKG

@rushstack/heft-config-file

Version:

Configuration file loader for @rushstack/heft

370 lines (342 loc) 14.6 kB
/** * A library for loading config files for use with the * {@link https://rushstack.io/pages/heft/overview/ | Heft} build system. * * @packageDocumentation */ import type { IRigConfig } from '@rushstack/rig-package'; import type { ITerminal } from '@rushstack/terminal'; /** * @deprecated Use {@link ProjectConfigurationFile} instead. * @beta */ export declare const ConfigurationFile: typeof ProjectConfigurationFile; /** * @deprecated Use {@link ProjectConfigurationFile} instead. * @beta */ export declare type ConfigurationFile<TConfigurationFile> = ProjectConfigurationFile<TConfigurationFile>; /** * @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; } /** * @beta */ export declare type IConfigurationFileOptions<TConfigurationFile, TExtraOptions extends object> = IConfigurationFileOptionsWithJsonSchemaFilePath<TConfigurationFile, TExtraOptions> | IConfigurationFileOptionsWithJsonSchemaObject<TConfigurationFile, TExtraOptions>; /** * @beta */ export declare 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 declare type IConfigurationFileOptionsWithJsonSchemaFilePath<TConfigurationFile, TExtraOptions extends {}> = IConfigurationFileOptionsBase<TConfigurationFile> & TExtraOptions & { /** * The path to the schema for the configuration file. */ jsonSchemaPath: string; jsonSchemaObject?: never; }; /** * @beta */ export declare type IConfigurationFileOptionsWithJsonSchemaObject<TConfigurationFile, TExtraOptions extends {}> = IConfigurationFileOptionsBase<TConfigurationFile> & TExtraOptions & { /** * The schema for the configuration file. */ jsonSchemaObject: object; jsonSchemaPath?: never; }; /** * Used to specify how node(s) in a JSON object should be processed after being loaded. * * @beta */ export declare 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; } /** * @beta */ export declare 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 declare type IJsonPathMetadata<T> = ICustomJsonPathMetadata<T> | INonCustomJsonPathMetadata; /** * Options provided to the custom resolver specified in {@link ICustomJsonPathMetadata}. * * @beta */ export declare 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>; } /** * 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 declare interface IJsonPathsMetadata<TConfigurationFile> { [jsonPath: string]: IJsonPathMetadata<TConfigurationFile>; } /** * @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" } /** * Used to specify how node(s) in a JSON object should be processed after being loaded. * * @beta */ export declare 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 declare interface IOriginalValueOptions<TParentProperty> { parentObject: Partial<TParentProperty>; propertyName: keyof TParentProperty; } /** * @beta */ export declare interface IProjectConfigurationFileOptions { /** * A project root-relative path to the configuration file that should be loaded. */ projectRelativeFilePath: string; } /** * @beta */ export declare type IPropertiesInheritance<TConfigurationFile> = { [propertyName in keyof TConfigurationFile]?: IPropertyInheritance<InheritanceType.append | InheritanceType.merge | InheritanceType.replace> | ICustomPropertyInheritance<TConfigurationFile[propertyName]>; }; /** * @beta */ export declare interface IPropertyInheritance<TInheritanceType extends InheritanceType> { inheritanceType: TInheritanceType; } /** * @beta */ export declare interface IPropertyInheritanceDefaults { array?: IPropertyInheritance<InheritanceType.append | InheritanceType.replace>; object?: IPropertyInheritance<InheritanceType.merge | InheritanceType.replace>; } /** * @beta */ export declare class NonProjectConfigurationFile<TConfigurationFile> extends ConfigurationFileBase<TConfigurationFile, {}> { /** * Load the configuration file at the specified absolute path, automatically resolving * `extends` properties. Will throw an error if the file cannot be found. */ loadConfigurationFile(terminal: ITerminal, filePath: string): TConfigurationFile; /** * Load the configuration file at the specified absolute path, automatically resolving * `extends` properties. Will throw an error if the file cannot be found. */ loadConfigurationFileAsync(terminal: ITerminal, filePath: string): Promise<TConfigurationFile>; /** * This function is identical to {@link NonProjectConfigurationFile.loadConfigurationFile}, except * that it returns `undefined` instead of throwing an error if the configuration file cannot be found. */ tryLoadConfigurationFile(terminal: ITerminal, filePath: string): TConfigurationFile | undefined; /** * This function is identical to {@link NonProjectConfigurationFile.loadConfigurationFileAsync}, except * that it returns `undefined` instead of throwing an error if the configuration file cannot be found. */ tryLoadConfigurationFileAsync(terminal: ITerminal, filePath: string): Promise<TConfigurationFile | undefined>; protected _tryLoadConfigurationFileInRig(terminal: ITerminal, rigConfig: IRigConfig, visitedConfigurationFilePaths: Set<string>): TConfigurationFile | undefined; protected _tryLoadConfigurationFileInRigAsync(terminal: ITerminal, rigConfig: IRigConfig, visitedConfigurationFilePaths: Set<string>): Promise<TConfigurationFile | undefined>; } /** * @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" } /** * @beta */ export declare class ProjectConfigurationFile<TConfigurationFile> extends ConfigurationFileBase<TConfigurationFile, IProjectConfigurationFileOptions> { /** {@inheritDoc IProjectConfigurationFileOptions.projectRelativeFilePath} */ readonly projectRelativeFilePath: string; constructor(options: IConfigurationFileOptions<TConfigurationFile, IProjectConfigurationFileOptions>); /** * Find and return a configuration file for the specified project, automatically resolving * `extends` properties and handling rigged configuration files. Will throw an error if a configuration * file cannot be found in the rig or project config folder. */ loadConfigurationFileForProject(terminal: ITerminal, projectPath: string, rigConfig?: IRigConfig): TConfigurationFile; /** * Find and return a configuration file for the specified project, automatically resolving * `extends` properties and handling rigged configuration files. Will throw an error if a configuration * file cannot be found in the rig or project config folder. */ loadConfigurationFileForProjectAsync(terminal: ITerminal, projectPath: string, rigConfig?: IRigConfig): Promise<TConfigurationFile>; /** * This function is identical to {@link ProjectConfigurationFile.loadConfigurationFileForProject}, except * that it returns `undefined` instead of throwing an error if the configuration file cannot be found. */ tryLoadConfigurationFileForProject(terminal: ITerminal, projectPath: string, rigConfig?: IRigConfig): TConfigurationFile | undefined; /** * This function is identical to {@link ProjectConfigurationFile.loadConfigurationFileForProjectAsync}, except * that it returns `undefined` instead of throwing an error if the configuration file cannot be found. */ tryLoadConfigurationFileForProjectAsync(terminal: ITerminal, projectPath: string, rigConfig?: IRigConfig): Promise<TConfigurationFile | undefined>; protected _tryLoadConfigurationFileInRig(terminal: ITerminal, rigConfig: IRigConfig, visitedConfigurationFilePaths: Set<string>): TConfigurationFile | undefined; protected _tryLoadConfigurationFileInRigAsync(terminal: ITerminal, rigConfig: IRigConfig, visitedConfigurationFilePaths: Set<string>): Promise<TConfigurationFile | undefined>; private _getConfigurationFilePathForProject; } /** * @beta */ export declare type PropertyInheritanceCustomFunction<TObject> = (currentObject: TObject, parentObject: TObject) => TObject; /** * Returns an object with investigative annotations stripped, useful for snapshot testing. * * @beta */ declare function stripAnnotations<TObject>(obj: TObject): TObject; export declare namespace TestUtilities { export { stripAnnotations } } export { }