@@ -213,12 +213,13 @@ export class Config {
213
213
214
214
get serverExtraEnv ( ) : Env {
215
215
const extraEnv =
216
- this . get < { [ key : string ] : string | number } | null > ( "server.extraEnv" ) ?? { } ;
216
+ this . get < { [ key : string ] : { toString ( ) : string } | null } | null > ( "server.extraEnv" ) ??
217
+ { } ;
217
218
return substituteVariablesInEnv (
218
219
Object . fromEntries (
219
220
Object . entries ( extraEnv ) . map ( ( [ k , v ] ) => [
220
221
k ,
221
- typeof v !== "string" ? v . toString ( ) : v ,
222
+ typeof v === "string" ? v : v ?. toString ( ) ,
222
223
] ) ,
223
224
) ,
224
225
) ;
@@ -398,22 +399,24 @@ export function prepareVSCodeConfig<T>(resp: T): T {
398
399
399
400
// FIXME: Merge this with `substituteVSCodeVariables` above
400
401
export function substituteVariablesInEnv ( env : Env ) : Env {
402
+ const depRe = new RegExp ( / \$ { (?< depName > .+ ?) } / g) ;
401
403
const missingDeps = new Set < string > ( ) ;
402
404
// vscode uses `env:ENV_NAME` for env vars resolution, and it's easier
403
405
// to follow the same convention for our dependency tracking
404
406
const definedEnvKeys = new Set ( Object . keys ( env ) . map ( ( key ) => `env:${ key } ` ) ) ;
405
407
const envWithDeps = Object . fromEntries (
406
408
Object . entries ( env ) . map ( ( [ key , value ] ) => {
407
409
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
+ }
417
420
}
418
421
}
419
422
return [ `env:${ key } ` , { deps : [ ...deps ] , value } ] ;
@@ -454,11 +457,10 @@ export function substituteVariablesInEnv(env: Env): Env {
454
457
do {
455
458
leftToResolveSize = toResolve . size ;
456
459
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 ?? "" ;
462
464
} ) ;
463
465
resolved . add ( key ) ;
464
466
toResolve . delete ( key ) ;
0 commit comments