@@ -215,23 +215,112 @@ const DynamicJsonForm = ({
215
215
return ;
216
216
}
217
217
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 ) ;
224
225
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 ;
229
269
}
230
- current = current [ key ] as JsonObject ;
231
- }
232
270
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
+ }
235
324
} ;
236
325
237
326
return (
0 commit comments