@@ -213,12 +213,13 @@ export class Config {
213213
214214 get serverExtraEnv ( ) : Env {
215215 const extraEnv =
216- this . get < { [ key : string ] : string | number } | null > ( "server.extraEnv" ) ?? { } ;
216+ this . get < { [ key : string ] : { toString ( ) : string } | null } | null > ( "server.extraEnv" ) ??
217+ { } ;
217218 return substituteVariablesInEnv (
218219 Object . fromEntries (
219220 Object . entries ( extraEnv ) . map ( ( [ k , v ] ) => [
220221 k ,
221- typeof v !== "string" ? v . toString ( ) : v ,
222+ typeof v === "string" ? v : v ?. toString ( ) ,
222223 ] ) ,
223224 ) ,
224225 ) ;
@@ -398,22 +399,24 @@ export function prepareVSCodeConfig<T>(resp: T): T {
398399
399400// FIXME: Merge this with `substituteVSCodeVariables` above
400401export function substituteVariablesInEnv ( env : Env ) : Env {
402+ const depRe = new RegExp ( / \$ { (?< depName > .+ ?) } / g) ;
401403 const missingDeps = new Set < string > ( ) ;
402404 // vscode uses `env:ENV_NAME` for env vars resolution, and it's easier
403405 // to follow the same convention for our dependency tracking
404406 const definedEnvKeys = new Set ( Object . keys ( env ) . map ( ( key ) => `env:${ key } ` ) ) ;
405407 const envWithDeps = Object . fromEntries (
406408 Object . entries ( env ) . map ( ( [ key , value ] ) => {
407409 const deps = new Set < string > ( ) ;
408- const depRe = new RegExp ( / \$ { (?< depName > .+ ?) } / g) ;
409- let match = undefined ;
410- while ( ( match = depRe . exec ( value ) ) ) {
411- const depName = unwrapUndefinable ( match . groups ?. [ "depName" ] ) ;
412- deps . add ( depName ) ;
413- // `depName` at this point can have a form of `expression` or
414- // `prefix:expression`
415- if ( ! definedEnvKeys . has ( depName ) ) {
416- missingDeps . add ( depName ) ;
410+ if ( value ) {
411+ let match = undefined ;
412+ while ( ( match = depRe . exec ( value ) ) ) {
413+ const depName = unwrapUndefinable ( match . groups ?. [ "depName" ] ) ;
414+ deps . add ( depName ) ;
415+ // `depName` at this point can have a form of `expression` or
416+ // `prefix:expression`
417+ if ( ! definedEnvKeys . has ( depName ) ) {
418+ missingDeps . add ( depName ) ;
419+ }
417420 }
418421 }
419422 return [ `env:${ key } ` , { deps : [ ...deps ] , value } ] ;
@@ -454,11 +457,10 @@ export function substituteVariablesInEnv(env: Env): Env {
454457 do {
455458 leftToResolveSize = toResolve . size ;
456459 for ( const key of toResolve ) {
457- const item = unwrapUndefinable ( envWithDeps [ key ] ) ;
458- if ( item . deps . every ( ( dep ) => resolved . has ( dep ) ) ) {
459- item . value = item . value . replace ( / \$ { (?< depName > .+ ?) } / g, ( _wholeMatch , depName ) => {
460- const item = unwrapUndefinable ( envWithDeps [ depName ] ) ;
461- return item . value ;
460+ const item = envWithDeps [ key ] ;
461+ if ( item && item . deps . every ( ( dep ) => resolved . has ( dep ) ) ) {
462+ item . value = item . value ?. replace ( / \$ { (?< depName > .+ ?) } / g, ( _wholeMatch , depName ) => {
463+ return envWithDeps [ depName ] ?. value ?? "" ;
462464 } ) ;
463465 resolved . add ( key ) ;
464466 toResolve . delete ( key ) ;
0 commit comments