@@ -6,7 +6,6 @@ import * as yaml from 'js-yaml';
66import { getMessage } from "./messages" ;
77import { toAbsolutePath } from "./utils"
88import { SeverityLevel } from "./rules" ;
9- import { getMessageFromCatalog , SHARED_MESSAGE_CATALOG , ValueValidator } from "@salesforce/code-analyzer-engine-api" ;
109
1110export const FIELDS = {
1211 CONFIG_ROOT : 'config_root' ,
@@ -27,15 +26,6 @@ export type RuleOverride = {
2726 severity ?: SeverityLevel
2827 tags ?: string [ ]
2928}
30- export const TOP_LEVEL_CONFIG_DESCRIPTION : ConfigDescription = {
31- overview : getMessage ( 'ConfigOverview' ) ,
32- fieldDescriptions : {
33- config_root : getMessage ( 'ConfigFieldDescription_config_root' ) ,
34- log_folder : getMessage ( 'ConfigFieldDescription_log_folder' ) ,
35- rules : getMessage ( 'ConfigFieldDescription_rules' ) ,
36- engines : getMessage ( 'ConfigFieldDescription_engines' ) ,
37- }
38- }
3929
4030type TopLevelConfig = {
4131 config_root : string
@@ -53,7 +43,20 @@ export const DEFAULT_CONFIG: TopLevelConfig = {
5343 custom_engine_plugin_modules : [ ] , // INTERNAL USE ONLY
5444} ;
5545
56- export type ConfigDescription = engApi . ConfigDescription ;
46+ export type ConfigDescription = {
47+ // A brief overview of this specific configuration object. It is recommended to include a link to documentation when possible.
48+ overview : string
49+
50+ // Description objects for the primary fields in the configuration
51+ fieldDescriptions : Record < string , ConfigFieldDescription >
52+ }
53+
54+ export type ConfigFieldDescription = engApi . ConfigFieldDescription & {
55+ // Whether or not the user has supplied a value for the field in their configuration file
56+ // Note: Unlike the Engine API's ConfigFieldDescription, core has the ability to determine if the user supplied
57+ // the field value (as we create a CodeAnalyzerConfig object), which is why "wasSuppliedByUser" is here only.
58+ wasSuppliedByUser : boolean
59+ }
5760
5861export class CodeAnalyzerConfig {
5962 private readonly config : TopLevelConfig ;
@@ -99,16 +102,44 @@ export class CodeAnalyzerConfig {
99102 config_root : configRoot ,
100103 log_folder : configExtractor . extractFolder ( FIELDS . LOG_FOLDER , DEFAULT_CONFIG . log_folder ) ! ,
101104 custom_engine_plugin_modules : configExtractor . extractArray ( FIELDS . CUSTOM_ENGINE_PLUGIN_MODULES ,
102- ValueValidator . validateString ,
105+ engApi . ValueValidator . validateString ,
103106 DEFAULT_CONFIG . custom_engine_plugin_modules ) ! ,
104107 rules : extractRulesValue ( configExtractor ) ,
105108 engines : extractEnginesValue ( configExtractor )
106109 }
107110 return new CodeAnalyzerConfig ( config ) ;
108111 }
109112
110- public static getConfigDescription ( ) : ConfigDescription {
111- return TOP_LEVEL_CONFIG_DESCRIPTION ;
113+ public getConfigDescription ( ) : ConfigDescription {
114+ return {
115+ overview : getMessage ( 'ConfigOverview' ) ,
116+ fieldDescriptions : {
117+ config_root : {
118+ descriptionText : getMessage ( 'ConfigFieldDescription_config_root' ) ,
119+ valueType : 'string' ,
120+ defaultValue : null , // Using null for doc and since it indicates that the value is calculated based on the environment
121+ wasSuppliedByUser : this . config . config_root !== DEFAULT_CONFIG . config_root
122+ } ,
123+ log_folder : {
124+ descriptionText : getMessage ( 'ConfigFieldDescription_log_folder' ) ,
125+ valueType : 'string' ,
126+ defaultValue : null , // Using null for doc and since it indicates that the value is calculated based on the environment
127+ wasSuppliedByUser : this . config . log_folder !== DEFAULT_CONFIG . log_folder
128+ } ,
129+ rules : {
130+ descriptionText : getMessage ( 'ConfigFieldDescription_rules' ) ,
131+ valueType : 'object' ,
132+ defaultValue : { } ,
133+ wasSuppliedByUser : this . config . rules !== DEFAULT_CONFIG . rules
134+ } ,
135+ engines : {
136+ descriptionText : getMessage ( 'ConfigFieldDescription_engines' ) ,
137+ valueType : 'object' ,
138+ defaultValue : { } ,
139+ wasSuppliedByUser : this . config . engines !== DEFAULT_CONFIG . engines
140+ }
141+ }
142+ } ;
112143 }
113144
114145 private constructor ( config : TopLevelConfig ) {
@@ -160,7 +191,7 @@ function extractRuleOverridesFrom(engineRuleOverridesExtractor: engApi.ConfigVal
160191function extractRuleOverrideFrom ( ruleOverrideExtractor : engApi . ConfigValueExtractor ) : RuleOverride {
161192 const engSeverity : engApi . SeverityLevel | undefined = ruleOverrideExtractor . extractSeverityLevel ( FIELDS . SEVERITY ) ;
162193 return {
163- tags : ruleOverrideExtractor . extractArray ( FIELDS . TAGS , ValueValidator . validateString ) ,
194+ tags : ruleOverrideExtractor . extractArray ( FIELDS . TAGS , engApi . ValueValidator . validateString ) ,
164195 severity : engSeverity === undefined ? undefined : engSeverity as SeverityLevel
165196 }
166197}
@@ -194,17 +225,19 @@ function parseAndValidate(parseFcn: () => unknown): object {
194225function validateAbsoluteFolder ( value : unknown , fieldPath : string ) : string {
195226 const folderValue : string = validateAbsolutePath ( value , fieldPath ) ;
196227 if ( ! fs . statSync ( folderValue ) . isDirectory ( ) ) {
197- throw new Error ( getMessageFromCatalog ( SHARED_MESSAGE_CATALOG , 'ConfigFolderValueMustNotBeFile' , fieldPath , folderValue ) ) ;
228+ throw new Error ( engApi . getMessageFromCatalog ( engApi . SHARED_MESSAGE_CATALOG ,
229+ 'ConfigFolderValueMustNotBeFile' , fieldPath , folderValue ) ) ;
198230 }
199231 return folderValue ;
200232}
201233
202234function validateAbsolutePath ( value : unknown , fieldPath : string ) : string {
203- const pathValue : string = ValueValidator . validateString ( value , fieldPath ) ;
235+ const pathValue : string = engApi . ValueValidator . validateString ( value , fieldPath ) ;
204236 if ( pathValue !== toAbsolutePath ( pathValue ) ) {
205237 throw new Error ( getMessage ( 'ConfigPathValueMustBeAbsolute' , fieldPath , pathValue , toAbsolutePath ( pathValue ) ) ) ;
206238 } else if ( ! fs . existsSync ( pathValue ) ) {
207- throw new Error ( getMessageFromCatalog ( SHARED_MESSAGE_CATALOG , 'ConfigPathValueDoesNotExist' , fieldPath , pathValue ) ) ;
239+ throw new Error ( engApi . getMessageFromCatalog ( engApi . SHARED_MESSAGE_CATALOG ,
240+ 'ConfigPathValueDoesNotExist' , fieldPath , pathValue ) ) ;
208241 }
209242 return pathValue ;
210243}
0 commit comments