@@ -215,23 +215,112 @@ const DynamicJsonForm = ({
215215 return ;
216216 }
217217
218- const newValue = {
219- ...( typeof value === "object" && value !== null && ! Array . isArray ( value )
220- ? value
221- : { } ) ,
222- } as JsonObject ;
223- let current : JsonObject = newValue ;
218+ const updateArray = (
219+ array : JsonValue [ ] ,
220+ path : string [ ] ,
221+ value : JsonValue ,
222+ ) : JsonValue [ ] => {
223+ const [ index , ...restPath ] = path ;
224+ const arrayIndex = Number ( index ) ;
224225
225- for ( let i = 0 ; i < path . length - 1 ; i ++ ) {
226- const key = path [ i ] ;
227- if ( ! ( key in current ) ) {
228- current [ key ] = { } ;
226+ // Validate array index
227+ if ( isNaN ( arrayIndex ) ) {
228+ console . error ( `Invalid array index: ${ index } ` ) ;
229+ return array ;
230+ }
231+
232+ // Check array bounds
233+ if ( arrayIndex < 0 ) {
234+ console . error ( `Array index out of bounds: ${ arrayIndex } < 0` ) ;
235+ return array ;
236+ }
237+
238+ const newArray = [ ...array ] ;
239+
240+ if ( restPath . length === 0 ) {
241+ newArray [ arrayIndex ] = value ;
242+ } else {
243+ // Ensure index position exists
244+ if ( arrayIndex >= array . length ) {
245+ console . warn ( `Extending array to index ${ arrayIndex } ` ) ;
246+ newArray . length = arrayIndex + 1 ;
247+ newArray . fill ( null , array . length , arrayIndex ) ;
248+ }
249+ newArray [ arrayIndex ] = updateValue (
250+ newArray [ arrayIndex ] ,
251+ restPath ,
252+ value ,
253+ ) ;
254+ }
255+ return newArray ;
256+ } ;
257+
258+ const updateObject = (
259+ obj : JsonObject ,
260+ path : string [ ] ,
261+ value : JsonValue ,
262+ ) : JsonObject => {
263+ const [ key , ...restPath ] = path ;
264+
265+ // Validate object key
266+ if ( typeof key !== "string" ) {
267+ console . error ( `Invalid object key: ${ key } ` ) ;
268+ return obj ;
229269 }
230- current = current [ key ] as JsonObject ;
231- }
232270
233- current [ path [ path . length - 1 ] ] = fieldValue ;
234- onChange ( newValue ) ;
271+ const newObj = { ...obj } ;
272+
273+ if ( restPath . length === 0 ) {
274+ newObj [ key ] = value ;
275+ } else {
276+ // Ensure key exists
277+ if ( ! ( key in newObj ) ) {
278+ console . warn ( `Creating new key in object: ${ key } ` ) ;
279+ newObj [ key ] = { } ;
280+ }
281+ newObj [ key ] = updateValue ( newObj [ key ] , restPath , value ) ;
282+ }
283+ return newObj ;
284+ } ;
285+
286+ const updateValue = (
287+ current : JsonValue ,
288+ path : string [ ] ,
289+ value : JsonValue ,
290+ ) : JsonValue => {
291+ if ( path . length === 0 ) return value ;
292+
293+ try {
294+ if ( ! current ) {
295+ current = ! isNaN ( Number ( path [ 0 ] ) ) ? [ ] : { } ;
296+ }
297+
298+ // Type checking
299+ if ( Array . isArray ( current ) ) {
300+ return updateArray ( current , path , value ) ;
301+ } else if ( typeof current === "object" && current !== null ) {
302+ return updateObject ( current , path , value ) ;
303+ } else {
304+ console . error (
305+ `Cannot update path ${ path . join ( "." ) } in non-object/array value:` ,
306+ current ,
307+ ) ;
308+ return current ;
309+ }
310+ } catch ( error ) {
311+ console . error ( `Error updating value at path ${ path . join ( "." ) } :` , error ) ;
312+ return current ;
313+ }
314+ } ;
315+
316+ try {
317+ const newValue = updateValue ( value , path , fieldValue ) ;
318+ onChange ( newValue ) ;
319+ } catch ( error ) {
320+ console . error ( "Failed to update form value:" , error ) ;
321+ // Keep the original value unchanged
322+ onChange ( value ) ;
323+ }
235324 } ;
236325
237326 return (
0 commit comments