@@ -44,7 +44,6 @@ import {
44
44
filterMutate ,
45
45
find ,
46
46
findIndex ,
47
- firstOrUndefinedIterator ,
48
47
flatten ,
49
48
forEach ,
50
49
forEachEntry ,
@@ -249,6 +248,7 @@ const libEntries: [string, string][] = [
249
248
[ "esnext.iterator" , "lib.esnext.iterator.d.ts" ] ,
250
249
[ "esnext.promise" , "lib.esnext.promise.d.ts" ] ,
251
250
[ "esnext.float16" , "lib.esnext.float16.d.ts" ] ,
251
+ [ "esnext.error" , "lib.esnext.error.d.ts" ] ,
252
252
[ "decorators" , "lib.decorators.d.ts" ] ,
253
253
[ "decorators.legacy" , "lib.decorators.legacy.d.ts" ] ,
254
254
] ;
@@ -2789,140 +2789,146 @@ function serializeOptionBaseObject(
2789
2789
return result ;
2790
2790
}
2791
2791
2792
- /**
2793
- * Generate a list of the compiler options whose value is not the default.
2794
- * @param options compilerOptions to be evaluated.
2795
- /** @internal */
2796
- export function getCompilerOptionsDiffValue ( options : CompilerOptions , newLine : string ) : string {
2797
- const compilerOptionsMap = getSerializedCompilerOption ( options ) ;
2798
- return getOverwrittenDefaultOptions ( ) ;
2799
-
2800
- function makePadding ( paddingLength : number ) : string {
2801
- return Array ( paddingLength + 1 ) . join ( " " ) ;
2802
- }
2803
-
2804
- function getOverwrittenDefaultOptions ( ) {
2805
- const result : string [ ] = [ ] ;
2806
- const tab = makePadding ( 2 ) ;
2807
- commandOptionsWithoutBuild . forEach ( cmd => {
2808
- if ( ! compilerOptionsMap . has ( cmd . name ) ) {
2809
- return ;
2810
- }
2811
-
2812
- const newValue = compilerOptionsMap . get ( cmd . name ) ;
2813
- const defaultValue = getDefaultValueForOption ( cmd ) ;
2814
- if ( newValue !== defaultValue ) {
2815
- result . push ( `${ tab } ${ cmd . name } : ${ newValue } ` ) ;
2816
- }
2817
- else if ( hasProperty ( defaultInitCompilerOptions , cmd . name ) ) {
2818
- result . push ( `${ tab } ${ cmd . name } : ${ defaultValue } ` ) ;
2819
- }
2820
- } ) ;
2821
- return result . join ( newLine ) + newLine ;
2822
- }
2823
- }
2824
-
2825
- /**
2826
- * Get the compiler options to be written into the tsconfig.json.
2827
- * @param options commandlineOptions to be included in the compileOptions.
2828
- */
2829
- function getSerializedCompilerOption ( options : CompilerOptions ) : Map < string , CompilerOptionsValue > {
2830
- const compilerOptions = extend ( options , defaultInitCompilerOptions ) ;
2831
- return serializeCompilerOptions ( compilerOptions ) ;
2832
- }
2833
2792
/**
2834
2793
* Generate tsconfig configuration when running command line "--init"
2835
2794
* @param options commandlineOptions to be generated into tsconfig.json
2836
- * @param fileNames array of filenames to be generated into tsconfig.json
2837
- *
2838
2795
* @internal
2839
2796
*/
2840
- export function generateTSConfig ( options : CompilerOptions , fileNames : readonly string [ ] , newLine : string ) : string {
2841
- const compilerOptionsMap = getSerializedCompilerOption ( options ) ;
2842
- return writeConfigurations ( ) ;
2797
+ export function generateTSConfig ( options : CompilerOptions , newLine : string ) : string {
2798
+ type PresetValue = string | number | boolean | ( string | number | boolean ) [ ] ;
2799
+
2800
+ const tab = " " ;
2801
+ const result : string [ ] = [ ] ;
2802
+ const allSetOptions = Object . keys ( options ) . filter ( k => k !== "init" && k !== "help" && k !== "watch" ) ;
2803
+
2804
+ result . push ( `{` ) ;
2805
+ result . push ( `${ tab } // ${ getLocaleSpecificMessage ( Diagnostics . Visit_https_Colon_Slash_Slashaka_ms_Slashtsconfig_to_read_more_about_this_file ) } ` ) ;
2806
+ result . push ( `${ tab } "compilerOptions": {` ) ;
2807
+
2808
+ emitHeader ( Diagnostics . File_Layout ) ;
2809
+ emitOption ( "rootDir" , "./src" , "optional" ) ;
2810
+ emitOption ( "outDir" , "./dist" , "optional" ) ;
2811
+
2812
+ newline ( ) ;
2813
+
2814
+ emitHeader ( Diagnostics . Environment_Settings ) ;
2815
+ emitHeader ( Diagnostics . See_also_https_Colon_Slash_Slashaka_ms_Slashtsconfig_Slashmodule ) ;
2816
+ emitOption ( "module" , ModuleKind . NodeNext ) ;
2817
+ emitOption ( "target" , ScriptTarget . ESNext ) ;
2818
+ emitOption ( "types" , [ ] ) ;
2819
+ if ( options . lib ) {
2820
+ emitOption ( "lib" , options . lib ) ;
2821
+ }
2822
+ emitHeader ( Diagnostics . For_nodejs_Colon ) ;
2823
+ result . push ( `${ tab } ${ tab } // "lib": ["esnext"],` ) ;
2824
+ result . push ( `${ tab } ${ tab } // "types": ["node"],` ) ;
2825
+ emitHeader ( Diagnostics . and_npm_install_D_types_Slashnode ) ;
2826
+
2827
+ newline ( ) ;
2828
+
2829
+ emitHeader ( Diagnostics . Other_Outputs ) ;
2830
+ emitOption ( "sourceMap" , /*defaultValue*/ true ) ;
2831
+ emitOption ( "declaration" , /*defaultValue*/ true ) ;
2832
+ emitOption ( "declarationMap" , /*defaultValue*/ true ) ;
2833
+
2834
+ newline ( ) ;
2835
+
2836
+ emitHeader ( Diagnostics . Stricter_Typechecking_Options ) ;
2837
+ emitOption ( "noUncheckedIndexedAccess" , /*defaultValue*/ true ) ;
2838
+ emitOption ( "exactOptionalPropertyTypes" , /*defaultValue*/ true ) ;
2839
+
2840
+ newline ( ) ;
2841
+
2842
+ emitHeader ( Diagnostics . Style_Options ) ;
2843
+ emitOption ( "noImplicitReturns" , /*defaultValue*/ true , "optional" ) ;
2844
+ emitOption ( "noImplicitOverride" , /*defaultValue*/ true , "optional" ) ;
2845
+ emitOption ( "noUnusedLocals" , /*defaultValue*/ true , "optional" ) ;
2846
+ emitOption ( "noUnusedParameters" , /*defaultValue*/ true , "optional" ) ;
2847
+ emitOption ( "noFallthroughCasesInSwitch" , /*defaultValue*/ true , "optional" ) ;
2848
+ emitOption ( "noPropertyAccessFromIndexSignature" , /*defaultValue*/ true , "optional" ) ;
2849
+
2850
+ newline ( ) ;
2851
+
2852
+ emitHeader ( Diagnostics . Recommended_Options ) ;
2853
+ emitOption ( "strict" , /*defaultValue*/ true ) ;
2854
+ emitOption ( "jsx" , JsxEmit . ReactJSX ) ;
2855
+ emitOption ( "verbatimModuleSyntax" , /*defaultValue*/ true ) ;
2856
+ emitOption ( "isolatedModules" , /*defaultValue*/ true ) ;
2857
+ emitOption ( "noUncheckedSideEffectImports" , /*defaultValue*/ true ) ;
2858
+ emitOption ( "moduleDetection" , ModuleDetectionKind . Force ) ;
2859
+ emitOption ( "skipLibCheck" , /*defaultValue*/ true ) ;
2860
+
2861
+ // Write any user-provided options we haven't already
2862
+ if ( allSetOptions . length > 0 ) {
2863
+ newline ( ) ;
2864
+ while ( allSetOptions . length > 0 ) {
2865
+ emitOption ( allSetOptions [ 0 ] , options [ allSetOptions [ 0 ] ] ) ;
2866
+ }
2867
+ }
2843
2868
2844
- function makePadding ( paddingLength : number ) : string {
2845
- return Array ( paddingLength + 1 ) . join ( " ") ;
2869
+ function newline ( ) {
2870
+ result . push ( " ") ;
2846
2871
}
2847
2872
2848
- function isAllowedOptionForOutput ( { category, name, isCommandLineOnly } : CommandLineOption ) : boolean {
2849
- // Skip options which do not have a category or have categories which are more niche
2850
- const categoriesToSkip = [ Diagnostics . Command_line_Options , Diagnostics . Editor_Support , Diagnostics . Compiler_Diagnostics , Diagnostics . Backwards_Compatibility , Diagnostics . Watch_and_Build_Modes , Diagnostics . Output_Formatting ] ;
2851
- return ! isCommandLineOnly && category !== undefined && ( ! categoriesToSkip . includes ( category ) || compilerOptionsMap . has ( name ) ) ;
2873
+ function emitHeader ( header : DiagnosticMessage ) {
2874
+ result . push ( `${ tab } ${ tab } // ${ getLocaleSpecificMessage ( header ) } ` ) ;
2852
2875
}
2853
2876
2854
- function writeConfigurations ( ) {
2855
- // Filter applicable options to place in the file
2856
- const categorizedOptions = new Map < DiagnosticMessage , CommandLineOption [ ] > ( ) ;
2857
- // Set allowed categories in order
2858
- categorizedOptions . set ( Diagnostics . Projects , [ ] ) ;
2859
- categorizedOptions . set ( Diagnostics . Language_and_Environment , [ ] ) ;
2860
- categorizedOptions . set ( Diagnostics . Modules , [ ] ) ;
2861
- categorizedOptions . set ( Diagnostics . JavaScript_Support , [ ] ) ;
2862
- categorizedOptions . set ( Diagnostics . Emit , [ ] ) ;
2863
- categorizedOptions . set ( Diagnostics . Interop_Constraints , [ ] ) ;
2864
- categorizedOptions . set ( Diagnostics . Type_Checking , [ ] ) ;
2865
- categorizedOptions . set ( Diagnostics . Completeness , [ ] ) ;
2866
- for ( const option of optionDeclarations ) {
2867
- if ( isAllowedOptionForOutput ( option ) ) {
2868
- let listForCategory = categorizedOptions . get ( option . category ! ) ;
2869
- if ( ! listForCategory ) categorizedOptions . set ( option . category ! , listForCategory = [ ] ) ;
2870
- listForCategory . push ( option ) ;
2871
- }
2877
+ // commented = 'always': Always comment this out, even if it's on commandline
2878
+ // commented = 'optional': Comment out unless it's on commandline
2879
+ // commented = 'never': Never comment this out
2880
+ function emitOption < K extends string & keyof CompilerOptions > ( setting : K , defaultValue : CompilerOptions [ K ] , commented : "always" | "optional" | "never" = "never" ) {
2881
+ const existingOptionIndex = allSetOptions . indexOf ( setting ) ;
2882
+ if ( existingOptionIndex >= 0 ) {
2883
+ allSetOptions . splice ( existingOptionIndex , 1 ) ;
2872
2884
}
2873
2885
2874
- // Serialize all options and their descriptions
2875
- let marginLength = 0 ;
2876
- let seenKnownKeys = 0 ;
2877
- const entries : { value : string ; description ?: string ; } [ ] = [ ] ;
2878
- categorizedOptions . forEach ( ( options , category ) => {
2879
- if ( entries . length !== 0 ) {
2880
- entries . push ( { value : "" } ) ;
2881
- }
2882
- entries . push ( { value : `/* ${ getLocaleSpecificMessage ( category ) } */` } ) ;
2883
- for ( const option of options ) {
2884
- let optionName ;
2885
- if ( compilerOptionsMap . has ( option . name ) ) {
2886
- optionName = `"${ option . name } ": ${ JSON . stringify ( compilerOptionsMap . get ( option . name ) ) } ${ ( seenKnownKeys += 1 ) === compilerOptionsMap . size ? "" : "," } ` ;
2887
- }
2888
- else {
2889
- optionName = `// "${ option . name } ": ${ JSON . stringify ( getDefaultValueForOption ( option ) ) } ,` ;
2890
- }
2891
- entries . push ( {
2892
- value : optionName ,
2893
- description : `/* ${ option . description && getLocaleSpecificMessage ( option . description ) || option . name } */` ,
2894
- } ) ;
2895
- marginLength = Math . max ( optionName . length , marginLength ) ;
2896
- }
2897
- } ) ;
2898
-
2899
- // Write the output
2900
- const tab = makePadding ( 2 ) ;
2901
- const result : string [ ] = [ ] ;
2902
- result . push ( `{` ) ;
2903
- result . push ( `${ tab } "compilerOptions": {` ) ;
2904
- result . push ( `${ tab } ${ tab } /* ${ getLocaleSpecificMessage ( Diagnostics . Visit_https_Colon_Slash_Slashaka_ms_Slashtsconfig_to_read_more_about_this_file ) } */` ) ;
2905
- result . push ( "" ) ;
2906
- // Print out each row, aligning all the descriptions on the same column.
2907
- for ( const entry of entries ) {
2908
- const { value, description = "" } = entry ;
2909
- result . push ( value && `${ tab } ${ tab } ${ value } ${ description && ( makePadding ( marginLength - value . length + 2 ) + description ) } ` ) ;
2886
+ let comment : boolean ;
2887
+ if ( commented === "always" ) {
2888
+ comment = true ;
2910
2889
}
2911
- if ( fileNames . length ) {
2912
- result . push ( `${ tab } },` ) ;
2913
- result . push ( `${ tab } "files": [` ) ;
2914
- for ( let i = 0 ; i < fileNames . length ; i ++ ) {
2915
- result . push ( `${ tab } ${ tab } ${ JSON . stringify ( fileNames [ i ] ) } ${ i === fileNames . length - 1 ? "" : "," } ` ) ;
2916
- }
2917
- result . push ( `${ tab } ]` ) ;
2890
+ else if ( commented === "never" ) {
2891
+ comment = false ;
2918
2892
}
2919
2893
else {
2920
- result . push ( ` ${ tab } }` ) ;
2894
+ comment = ! hasProperty ( options , setting ) ;
2921
2895
}
2922
- result . push ( `}` ) ;
2923
2896
2924
- return result . join ( newLine ) + newLine ;
2897
+ const value = ( options [ setting ] ?? defaultValue ) as PresetValue ;
2898
+ if ( comment ) {
2899
+ result . push ( `${ tab } ${ tab } // "${ setting } ": ${ formatValueOrArray ( setting , value ) } ,` ) ;
2900
+ }
2901
+ else {
2902
+ result . push ( `${ tab } ${ tab } "${ setting } ": ${ formatValueOrArray ( setting , value ) } ,` ) ;
2903
+ }
2925
2904
}
2905
+
2906
+ function formatValueOrArray ( settingName : string , value : PresetValue ) : string {
2907
+ const option = optionDeclarations . filter ( c => c . name === settingName ) [ 0 ] ;
2908
+ if ( ! option ) Debug . fail ( `No option named ${ settingName } ?` ) ;
2909
+ const map = ( option . type instanceof Map ) ? option . type : undefined ;
2910
+ if ( isArray ( value ) ) {
2911
+ // eslint-disable-next-line local/no-in-operator
2912
+ const map = ( "element" in option && ( option . element . type instanceof Map ) ) ? option . element . type : undefined ;
2913
+ return `[${ value . map ( v => formatSingleValue ( v , map ) ) . join ( ", " ) } ]` ;
2914
+ }
2915
+ else {
2916
+ return formatSingleValue ( value , map ) ;
2917
+ }
2918
+ }
2919
+
2920
+ function formatSingleValue ( value : PresetValue , map : Map < string , string | number > | undefined ) {
2921
+ if ( map ) {
2922
+ value = getNameOfCompilerOptionValue ( value as string | number , map ) ?? Debug . fail ( `No matching value of ${ value } ` ) ;
2923
+ }
2924
+ return JSON . stringify ( value ) ;
2925
+ }
2926
+
2927
+ result . push ( `${ tab } }` ) ;
2928
+ result . push ( `}` ) ;
2929
+ result . push ( `` ) ;
2930
+
2931
+ return result . join ( newLine ) ;
2926
2932
}
2927
2933
2928
2934
/** @internal */
@@ -4256,25 +4262,3 @@ function getOptionValueWithEmptyStrings(value: any, option: CommandLineOption):
4256
4262
} ) ;
4257
4263
}
4258
4264
}
4259
-
4260
- function getDefaultValueForOption ( option : CommandLineOption ) : { } {
4261
- switch ( option . type ) {
4262
- case "number" :
4263
- return 1 ;
4264
- case "boolean" :
4265
- return true ;
4266
- case "string" :
4267
- const defaultValue = option . defaultValueDescription ;
4268
- return option . isFilePath ? `./${ defaultValue && typeof defaultValue === "string" ? defaultValue : "" } ` : "" ;
4269
- case "list" :
4270
- return [ ] ;
4271
- case "listOrElement" :
4272
- return getDefaultValueForOption ( option . element ) ;
4273
- case "object" :
4274
- return { } ;
4275
- default :
4276
- const value = firstOrUndefinedIterator ( option . type . keys ( ) ) ;
4277
- if ( value !== undefined ) return value ;
4278
- return Debug . fail ( "Expected 'option.type' to have entries." ) ;
4279
- }
4280
- }
0 commit comments