@@ -576,10 +576,10 @@ func (v *TemplateVisitor) visitObject(obj *types.JsonObject, path string) (types
576576 }
577577 if arr , ok := eval .Value .(* types.JsonArray ); ok {
578578 for i , val := range arr .Value {
579- v . pushScope ( types .AsObject ( map [ string ] interface {}{
580- eval .IndexName : types .AsNumber (i ),
581- eval .Name : val ,
582- }) )
579+ scopeObj := types .NewJsonObjectWithCapacity ( 2 )
580+ scopeObj . Put ( eval .IndexName , types .AsNumber (i ))
581+ scopeObj . Put ( eval .Name , val )
582+ v . pushScope ( scopeObj )
583583 if obj , ok := val .(* types.JsonObject ); ok {
584584 v .pushScope (obj )
585585 }
@@ -673,15 +673,36 @@ func PutValue(result *types.JsonObject, key string, r types.JsonType, path strin
673673 if r == nil || types .IsNull (r ) {
674674 result .Put (key , types .Null )
675675 } else {
676- if strings .HasPrefix (key , "$" ) && result .ContainsKey (key ) && ! types .IsReservedKey (key ) {
676+ existing , hasExisting := result .TryGet (key )
677+ if ! hasExisting || existing == nil || types .IsNull (existing ) {
677678 result .Put (key , r )
678- } else {
679- json , err := types .MergeJSON (result .Get (key ), r , true )
679+ return nil
680+ }
681+
682+ if strings .HasPrefix (key , "$" ) && ! types .IsReservedKey (key ) {
683+ result .Put (key , r )
684+ return nil
685+ }
686+
687+ if types .IsObject (existing ) && types .IsObject (r ) {
688+ merged , err := types .MergeJSON (existing , r , true )
680689 if err != nil {
681690 return utils .WrapJsonErrorf (path , err , "Failed to merge %s" , key )
682691 }
683- result .Put (key , json )
692+ result .Put (key , merged )
693+ return nil
684694 }
695+
696+ if types .IsArray (existing ) && types .IsArray (r ) {
697+ merged , err := types .MergeJSON (existing , r , true )
698+ if err != nil {
699+ return utils .WrapJsonErrorf (path , err , "Failed to merge %s" , key )
700+ }
701+ result .Put (key , merged )
702+ return nil
703+ }
704+
705+ result .Put (key , r )
685706 }
686707 return nil
687708}
@@ -723,10 +744,10 @@ func (v *TemplateVisitor) visitArrayElement(array []types.JsonType, element type
723744 case types .Iteration :
724745 if arr , ok := eval .Value .(* types.JsonArray ); ok {
725746 for i , val := range arr .Value {
726- v . pushScope ( types .AsObject ( map [ string ] interface {}{
727- eval .IndexName : types .AsNumber (i ),
728- eval .Name : val ,
729- }) )
747+ scopeObj := types .NewJsonObjectWithCapacity ( 2 )
748+ scopeObj . Put ( eval .IndexName , types .AsNumber (i ))
749+ scopeObj . Put ( eval .Name , val )
750+ v . pushScope ( scopeObj )
730751 if obj , ok := val .(* types.JsonObject ); ok {
731752 v .pushScope (obj )
732753 }
0 commit comments