@@ -160,15 +160,32 @@ export const CONFIGURATION_FILE_FIELD_ANNOTATION: unique symbol = Symbol(
160160 'configuration-file-field-annotation'
161161) ;
162162
163- export interface IAnnotatedField < TField > {
164- [ CONFIGURATION_FILE_FIELD_ANNOTATION ] : IConfigurationFileFieldAnnotation < TField > ;
163+ export interface IAnnotatedField <
164+ TField ,
165+ TConfigurationFileFieldAnnotation extends
166+ IConfigurationFileFieldAnnotation < TField > = IConfigurationFileFieldAnnotation < TField >
167+ > {
168+ [ CONFIGURATION_FILE_FIELD_ANNOTATION ] : TConfigurationFileFieldAnnotation ;
165169}
166170
171+ type IAnnotatedObject < TParentProperty > = Partial < IAnnotatedField < TParentProperty > > ;
172+ type IRootAnnotatedObject < TParentProperty > = Partial <
173+ IAnnotatedField < TParentProperty , IRootConfigurationFileFieldAnnotation < TParentProperty > >
174+ > ;
175+
167176interface IConfigurationFileFieldAnnotation < TField > {
168177 configurationFilePath : string | undefined ;
169178 originalValues : { [ propertyName in keyof TField ] : unknown } ;
170179}
171180
181+ interface IRootConfigurationFileFieldAnnotation < TField > extends IConfigurationFileFieldAnnotation < TField > {
182+ schemaPropertyOriginalValue ?: string ;
183+ }
184+
185+ interface IObjectWithSchema {
186+ $schema ?: string ;
187+ }
188+
172189/**
173190 * Options provided to the custom resolver specified in {@link ICustomJsonPathMetadata}.
174191 *
@@ -453,15 +470,8 @@ export abstract class ConfigurationFileBase<TConfigurationFile, TExtraOptions ex
453470 * loaded from.
454471 */
455472 public getObjectSourceFilePath < TObject extends object > ( obj : TObject ) : string | undefined {
456- // eslint-disable-next-line @typescript-eslint/no-explicit-any
457- const annotation : IConfigurationFileFieldAnnotation < TObject > | undefined = ( obj as any ) [
458- CONFIGURATION_FILE_FIELD_ANNOTATION
459- ] ;
460- if ( annotation ) {
461- return annotation . configurationFilePath ;
462- }
463-
464- return undefined ;
473+ const { [ CONFIGURATION_FILE_FIELD_ANNOTATION ] : annotation } : IAnnotatedObject < TObject > = obj ;
474+ return annotation ?. configurationFilePath ;
465475 }
466476
467477 /**
@@ -471,15 +481,22 @@ export abstract class ConfigurationFileBase<TConfigurationFile, TExtraOptions ex
471481 public getPropertyOriginalValue < TParentProperty extends object , TValue > (
472482 options : IOriginalValueOptions < TParentProperty >
473483 ) : TValue | undefined {
474- const {
475- [ CONFIGURATION_FILE_FIELD_ANNOTATION ] : annotation
476- } : { [ CONFIGURATION_FILE_FIELD_ANNOTATION ] ?: IConfigurationFileFieldAnnotation < TParentProperty > } =
477- options . parentObject ;
478- if ( annotation ?. originalValues . hasOwnProperty ( options . propertyName ) ) {
479- return annotation . originalValues [ options . propertyName ] as TValue ;
484+ const { parentObject, propertyName } = options ;
485+ const { [ CONFIGURATION_FILE_FIELD_ANNOTATION ] : annotation } : IAnnotatedObject < TParentProperty > =
486+ parentObject ;
487+ if ( annotation ?. originalValues . hasOwnProperty ( propertyName ) ) {
488+ return annotation . originalValues [ propertyName ] as TValue ;
480489 }
481490 }
482491
492+ /**
493+ * Get the original value of the `$schema` property from the original configuration file, it one was present.
494+ */
495+ public getSchemaPropertyOriginalValue < TObject extends object > ( obj : TObject ) : string | undefined {
496+ const { [ CONFIGURATION_FILE_FIELD_ANNOTATION ] : annotation } : IRootAnnotatedObject < TObject > = obj ;
497+ return annotation ?. schemaPropertyOriginalValue ;
498+ }
499+
483500 protected _loadConfigurationFileInnerWithCache (
484501 terminal : ITerminal ,
485502 resolvedConfigurationFilePath : string ,
@@ -979,14 +996,21 @@ export abstract class ConfigurationFileBase<TConfigurationFile, TExtraOptions ex
979996
980997 // Need to do a dance with the casting here because while we know that JSON keys are always
981998 // strings, TypeScript doesn't.
982- return this . _mergeObjects (
999+ const result : Partial < TConfigurationFile > = this . _mergeObjects (
9831000 parentConfiguration as { [ key : string ] : unknown } ,
9841001 configurationJson as { [ key : string ] : unknown } ,
9851002 resolvedConfigurationFilePath ,
9861003 this . _defaultPropertyInheritance ,
9871004 this . _propertyInheritanceTypes as IPropertiesInheritance < { [ key : string ] : unknown } > ,
9881005 ignoreProperties
9891006 ) as Partial < TConfigurationFile > ;
1007+
1008+ const schemaPropertyOriginalValue : string | undefined = ( configurationJson as IObjectWithSchema ) . $schema ;
1009+ ( result as unknown as Required < IRootAnnotatedObject < { } > > ) [
1010+ CONFIGURATION_FILE_FIELD_ANNOTATION
1011+ ] . schemaPropertyOriginalValue = schemaPropertyOriginalValue ;
1012+
1013+ return result ;
9901014 }
9911015
9921016 private _mergeObjects < TField extends { [ key : string ] : unknown } > (
0 commit comments