@@ -670,21 +670,25 @@ function applyDefaults<D extends object | ((key: string) => unknown), C extends
670670 const res : any = deepReplaceFunctionsWithObjects ( defaults , paths ) ;
671671
672672 outer: for ( const [ key , mergeValue ] of Object . entries ( config ) ) {
673- if ( mergeValue == null ) continue ;
674- if ( ! isObjectLike ( mergeValue ) ) {
673+ if ( ! isObjectLike ( mergeValue ) && mergeValue !== null ) {
675674 set ( res , key , mergeValue ) ;
676675 } else {
677676 const keyParts = key . split ( "." ) ;
678677 let baseValue : any = defaults ;
679678 for ( const [ index , part ] of keyParts . entries ( ) ) {
680- baseValue = has ( baseValue , part ) ? get ( baseValue , part ) : ( typeof baseValue === 'function' ? ( baseValue as any ) ( part ) : undefined ) ;
681- if ( baseValue === undefined || ! isObjectLike ( baseValue ) ) {
682- set ( res , key , mergeValue ) ;
679+ if ( ! isObjectLike ( baseValue ) ) {
680+ set ( res , key , mergeValue ?? null ) ;
683681 continue outer;
684682 }
683+ baseValue = has ( baseValue , part ) ? get ( baseValue , part ) : ( typeof baseValue === 'function' ? ( baseValue as any ) ( part ) : undefined ) ;
684+ }
685+ if ( ! isObjectLike ( baseValue ) ) {
686+ set ( res , key , mergeValue ?? baseValue ?? null ) ;
687+ continue outer;
688+ } else {
689+ const newPaths = paths . filter ( p => p . startsWith ( key + "." ) ) . map ( p => p . slice ( key . length + 1 ) ) ;
690+ set ( res , key , applyDefaults ( baseValue , mergeValue ?? { } , newPaths ) ) ;
685691 }
686- const newPaths = paths . filter ( p => p . startsWith ( key + "." ) ) . map ( p => p . slice ( key . length + 1 ) ) ;
687- set ( res , key , applyDefaults ( baseValue , mergeValue , newPaths ) ) ;
688692 }
689693 }
690694 return res as any ;
@@ -711,20 +715,26 @@ import.meta.vitest?.test("applyDefaults", ({ expect }) => {
711715
712716 // Dot notation
713717 expect ( applyDefaults ( { a : { b : 1 } } , { "a.c" : 2 } ) ) . toEqual ( { a : { b : 1 } , "a.c" : 2 } ) ;
714- expect ( applyDefaults ( { a : { b : 1 } } , { "a.c" : null } ) ) . toEqual ( { a : { b : 1 } } ) ;
718+ expect ( applyDefaults ( { a : { b : 1 } } , { "a.c" : null } ) ) . toEqual ( { a : { b : 1 } , "a.c" : null } ) ;
719+ expect ( applyDefaults ( { a : { b : 1 } } , { "a.b" : null } ) ) . toEqual ( { a : { b : 1 } , "a.b" : 1 } ) ;
720+ expect ( applyDefaults ( { a : { b : { c : 1 } } } , { "a.b" : null } ) ) . toEqual ( { a : { b : { c : 1 } } , "a.b" : { c : 1 } } ) ;
721+ expect ( applyDefaults ( { a : { } } , { "a.b" : null } ) ) . toEqual ( { a : { } , "a.b" : null } ) ;
722+ expect ( applyDefaults ( { a : { } } , { "a" : { b : 1 } , "a.b" : null } ) ) . toEqual ( { a : { b : 1 } , "a.b" : null } ) ;
723+ expect ( applyDefaults ( { a : 1 } , { "a.b" : null } ) ) . toEqual ( { a : 1 , "a.b" : null } ) ;
715724 expect ( applyDefaults ( { a : 1 } , { "a.b" : 2 } ) ) . toEqual ( { a : 1 , "a.b" : 2 } ) ;
716725 expect ( applyDefaults ( { a : null } , { "a.b" : 2 } ) ) . toEqual ( { a : null , "a.b" : 2 } ) ;
717726 expect ( applyDefaults ( { a : { b : { c : 1 } } } , { "a.b" : { d : 2 } } ) ) . toEqual ( { a : { b : { c : 1 } } , "a.b" : { c : 1 , d : 2 } } ) ;
718- expect ( applyDefaults ( { a : { b : { c : 1 } } } , { "a.b" : null } ) ) . toEqual ( { a : { b : { c : 1 } } } ) ;
727+ expect ( applyDefaults ( { a : { b : { c : 1 } } } , { "a.b" : null } ) ) . toEqual ( { a : { b : { c : 1 } } , "a.b" : { c : 1 } } ) ;
719728 expect ( applyDefaults ( { a : { b : { c : { d : 1 } } } } , { "a.b.c" : { } } ) ) . toEqual ( { a : { b : { c : { d : 1 } } } , "a.b.c" : { d : 1 } } ) ;
720729 expect ( applyDefaults ( { a : ( ) => ( { c : 1 } ) } , { "a.b" : { d : 2 } } ) ) . toEqual ( { a : { b : { c : 1 } } , "a.b" : { c : 1 , d : 2 } } ) ;
721- expect ( applyDefaults ( { a : ( ) => ( ) => ( { d : 1 } ) } , { "a.b" : null } ) ) . toEqual ( { a : { b : { } } } ) ;
730+ expect ( applyDefaults ( { a : ( ) => ( ) => ( { d : 1 } ) } , { "a.b" : null } ) ) . toEqual ( { a : { b : { } } , "a.b" : { } } ) ;
722731 expect ( applyDefaults ( { a : ( ) => ( ) => ( { d : 1 } ) } , { "a.b.c" : { } } ) ) . toEqual ( { a : { b : { c : { d : 1 } } } , "a.b.c" : { d : 1 } } ) ;
723732 expect ( applyDefaults ( { a : { b : ( ) => ( { c : 1 , d : 2 } ) } } , { "a.b.x-y.c" : 3 } ) ) . toEqual ( { a : { b : { "x-y" : { c : 1 , d : 2 } } } , "a.b.x-y.c" : 3 } ) ;
724733 expect ( applyDefaults ( { a : ( ) => ( { c : 1 } ) } , { "a.b.d" : 2 } ) ) . toEqual ( { a : { b : { c : 1 } } , "a.b.d" : 2 } ) ;
725734 expect ( applyDefaults ( { a : ( ) => ( { c : 1 } ) } , { "a.b.d" : 2 , "a.e.d" : 3 } ) ) . toEqual ( { a : { b : { c : 1 } , e : { c : 1 } } , "a.b.d" : 2 , "a.e.d" : 3 } ) ;
726735 expect ( applyDefaults ( { a : ( ) => ( { c : 1 } ) } , { "a.b.d" : 2 , a : { b : { d : 3 } } } ) ) . toEqual ( { a : { b : { c : 1 , d : 3 } } , "a.b.d" : 2 } ) ;
727736 expect ( applyDefaults ( { a : ( ) => ( { c : 1 } ) } , { "a.b.d" : 2 , a : { e : { d : 3 } } } ) ) . toEqual ( { a : { b : { c : 1 } , e : { c : 1 , d : 3 } } , "a.b.d" : 2 } ) ;
737+ expect ( applyDefaults ( { a : ( ) => ( { c : 1 } ) } , { "a.b" : { d : { e : 2 } } , "a.b.d" : null } ) ) . toEqual ( { a : { b : { c : 1 } } , "a.b" : { c : 1 , d : { e : 2 } } , "a.b.d" : null } ) ;
728738} ) ;
729739
730740export function applyProjectDefaults < T extends ProjectRenderedConfigBeforeDefaults > ( config : T ) {
0 commit comments