11import { SchemaError } from '$lib/errors.js' ;
22import { assertSchema } from '$lib/utils.js' ;
3+ import { merge } from 'ts-deepmerge' ;
34import type { JSONSchema } from './index.js' ;
45import { schemaInfo } from './schemaInfo.js' ;
56import type { SchemaType } from './schemaInfo.js' ;
@@ -20,8 +21,8 @@ function _defaultValues(schema: JSONSchema, isOptional: boolean, path: string[])
2021 const info = schemaInfo ( schema , isOptional , path ) ;
2122 if ( ! info ) return undefined ;
2223
23- //if (schema.type == 'object') console.log('--- OBJECT ---'); //debug
24- //else console.dir({ path, schema, isOptional }, { depth: 10 }); //debug
24+ //if (schema.type == 'object') console.log('--- OBJECT ---');
25+ //else console.dir({ path, schema, isOptional }, { depth: 10 });
2526
2627 let objectDefaults : Record < string , unknown > | undefined = undefined ;
2728
@@ -69,6 +70,8 @@ function _defaultValues(schema: JSONSchema, isOptional: boolean, path: string[])
6970 return _multiType . size > 1 ;
7071 } ;
7172
73+ let output : Record < string , unknown > = { } ;
74+
7275 // Check unions first, so default values can take precedence over nullable and optional
7376 if ( ! objectDefaults && info . union ) {
7477 const singleDefault = info . union . filter (
@@ -92,6 +95,19 @@ function _defaultValues(schema: JSONSchema, isOptional: boolean, path: string[])
9295 path
9396 ) ;
9497 }
98+
99+ // Objects must have default values to avoid setting undefined properties on nested data
100+ if ( info . types [ 0 ] == 'object' && info . union . length ) {
101+ output =
102+ info . union . length > 1
103+ ? merge . withOptions (
104+ { allowUndefinedOverrides : true } ,
105+ ...info . union . map (
106+ ( s ) => _defaultValues ( s , isOptional , path ) as Record < string , unknown >
107+ )
108+ )
109+ : ( _defaultValues ( info . union [ 0 ] , isOptional , path ) as Record < string , unknown > ) ;
110+ }
95111 }
96112 }
97113
@@ -103,14 +119,13 @@ function _defaultValues(schema: JSONSchema, isOptional: boolean, path: string[])
103119
104120 // Objects
105121 if ( info . properties ) {
106- const output : Record < string , unknown > = { } ;
107122 for ( const [ key , value ] of Object . entries ( info . properties ) ) {
108123 assertSchema ( value , [ ...path , key ] ) ;
109124
110125 const def =
111126 objectDefaults && objectDefaults [ key ] !== undefined
112127 ? objectDefaults [ key ]
113- : _defaultValues ( value , ! schema . required ?. includes ( key ) , [ ...path , key ] ) ;
128+ : _defaultValues ( value , ! info . required ?. includes ( key ) , [ ...path , key ] ) ;
114129
115130 //if (def !== undefined) output[key] = def;
116131 output [ key ] = def ;
0 commit comments