@@ -23,7 +23,7 @@ type ConditionOperation struct {
2323
2424type ParamOperation struct {
2525 Path string `json:"path"`
26- Mode string `json:"mode"` // delete, set, move, prepend, append
26+ Mode string `json:"mode"` // delete, set, move, copy, prepend, append, trim_prefix, trim_suffix, ensure_prefix, ensure_suffix, trim_space, to_lower, to_upper, replace, regex_replace
2727 Value interface {} `json:"value"`
2828 KeepOrigin bool `json:"keep_origin"`
2929 From string `json:"from,omitempty"`
@@ -330,8 +330,6 @@ func applyOperations(jsonStr string, operations []ParamOperation, conditionConte
330330 }
331331 // 处理路径中的负数索引
332332 opPath := processNegativeIndex (result , op .Path )
333- opFrom := processNegativeIndex (result , op .From )
334- opTo := processNegativeIndex (result , op .To )
335333
336334 switch op .Mode {
337335 case "delete" :
@@ -342,11 +340,38 @@ func applyOperations(jsonStr string, operations []ParamOperation, conditionConte
342340 }
343341 result , err = sjson .Set (result , opPath , op .Value )
344342 case "move" :
343+ opFrom := processNegativeIndex (result , op .From )
344+ opTo := processNegativeIndex (result , op .To )
345345 result , err = moveValue (result , opFrom , opTo )
346+ case "copy" :
347+ if op .From == "" || op .To == "" {
348+ return "" , fmt .Errorf ("copy from/to is required" )
349+ }
350+ opFrom := processNegativeIndex (result , op .From )
351+ opTo := processNegativeIndex (result , op .To )
352+ result , err = copyValue (result , opFrom , opTo )
346353 case "prepend" :
347354 result , err = modifyValue (result , opPath , op .Value , op .KeepOrigin , true )
348355 case "append" :
349356 result , err = modifyValue (result , opPath , op .Value , op .KeepOrigin , false )
357+ case "trim_prefix" :
358+ result , err = trimStringValue (result , opPath , op .Value , true )
359+ case "trim_suffix" :
360+ result , err = trimStringValue (result , opPath , op .Value , false )
361+ case "ensure_prefix" :
362+ result , err = ensureStringAffix (result , opPath , op .Value , true )
363+ case "ensure_suffix" :
364+ result , err = ensureStringAffix (result , opPath , op .Value , false )
365+ case "trim_space" :
366+ result , err = transformStringValue (result , opPath , strings .TrimSpace )
367+ case "to_lower" :
368+ result , err = transformStringValue (result , opPath , strings .ToLower )
369+ case "to_upper" :
370+ result , err = transformStringValue (result , opPath , strings .ToUpper )
371+ case "replace" :
372+ result , err = replaceStringValue (result , opPath , op .From , op .To )
373+ case "regex_replace" :
374+ result , err = regexReplaceStringValue (result , opPath , op .From , op .To )
350375 default :
351376 return "" , fmt .Errorf ("unknown operation: %s" , op .Mode )
352377 }
@@ -369,6 +394,14 @@ func moveValue(jsonStr, fromPath, toPath string) (string, error) {
369394 return sjson .Delete (result , fromPath )
370395}
371396
397+ func copyValue (jsonStr , fromPath , toPath string ) (string , error ) {
398+ sourceValue := gjson .Get (jsonStr , fromPath )
399+ if ! sourceValue .Exists () {
400+ return jsonStr , fmt .Errorf ("source path does not exist: %s" , fromPath )
401+ }
402+ return sjson .Set (jsonStr , toPath , sourceValue .Value ())
403+ }
404+
372405func modifyValue (jsonStr , path string , value interface {}, keepOrigin , isPrepend bool ) (string , error ) {
373406 current := gjson .Get (jsonStr , path )
374407 switch {
@@ -422,6 +455,88 @@ func modifyString(jsonStr, path string, value interface{}, isPrepend bool) (stri
422455 return sjson .Set (jsonStr , path , newStr )
423456}
424457
458+ func trimStringValue (jsonStr , path string , value interface {}, isPrefix bool ) (string , error ) {
459+ current := gjson .Get (jsonStr , path )
460+ if current .Type != gjson .String {
461+ return jsonStr , fmt .Errorf ("operation not supported for type: %v" , current .Type )
462+ }
463+
464+ if value == nil {
465+ return jsonStr , fmt .Errorf ("trim value is required" )
466+ }
467+ valueStr := fmt .Sprintf ("%v" , value )
468+
469+ var newStr string
470+ if isPrefix {
471+ newStr = strings .TrimPrefix (current .String (), valueStr )
472+ } else {
473+ newStr = strings .TrimSuffix (current .String (), valueStr )
474+ }
475+ return sjson .Set (jsonStr , path , newStr )
476+ }
477+
478+ func ensureStringAffix (jsonStr , path string , value interface {}, isPrefix bool ) (string , error ) {
479+ current := gjson .Get (jsonStr , path )
480+ if current .Type != gjson .String {
481+ return jsonStr , fmt .Errorf ("operation not supported for type: %v" , current .Type )
482+ }
483+
484+ if value == nil {
485+ return jsonStr , fmt .Errorf ("ensure value is required" )
486+ }
487+ valueStr := fmt .Sprintf ("%v" , value )
488+ if valueStr == "" {
489+ return jsonStr , fmt .Errorf ("ensure value is required" )
490+ }
491+
492+ currentStr := current .String ()
493+ if isPrefix {
494+ if strings .HasPrefix (currentStr , valueStr ) {
495+ return jsonStr , nil
496+ }
497+ return sjson .Set (jsonStr , path , valueStr + currentStr )
498+ }
499+
500+ if strings .HasSuffix (currentStr , valueStr ) {
501+ return jsonStr , nil
502+ }
503+ return sjson .Set (jsonStr , path , currentStr + valueStr )
504+ }
505+
506+ func transformStringValue (jsonStr , path string , transform func (string ) string ) (string , error ) {
507+ current := gjson .Get (jsonStr , path )
508+ if current .Type != gjson .String {
509+ return jsonStr , fmt .Errorf ("operation not supported for type: %v" , current .Type )
510+ }
511+ return sjson .Set (jsonStr , path , transform (current .String ()))
512+ }
513+
514+ func replaceStringValue (jsonStr , path , from , to string ) (string , error ) {
515+ current := gjson .Get (jsonStr , path )
516+ if current .Type != gjson .String {
517+ return jsonStr , fmt .Errorf ("operation not supported for type: %v" , current .Type )
518+ }
519+ if from == "" {
520+ return jsonStr , fmt .Errorf ("replace from is required" )
521+ }
522+ return sjson .Set (jsonStr , path , strings .ReplaceAll (current .String (), from , to ))
523+ }
524+
525+ func regexReplaceStringValue (jsonStr , path , pattern , replacement string ) (string , error ) {
526+ current := gjson .Get (jsonStr , path )
527+ if current .Type != gjson .String {
528+ return jsonStr , fmt .Errorf ("operation not supported for type: %v" , current .Type )
529+ }
530+ if pattern == "" {
531+ return jsonStr , fmt .Errorf ("regex pattern is required" )
532+ }
533+ re , err := regexp .Compile (pattern )
534+ if err != nil {
535+ return jsonStr , err
536+ }
537+ return sjson .Set (jsonStr , path , re .ReplaceAllString (current .String (), replacement ))
538+ }
539+
425540func mergeObjects (jsonStr , path string , value interface {}, keepOrigin bool ) (string , error ) {
426541 current := gjson .Get (jsonStr , path )
427542 var currentMap , newMap map [string ]interface {}
0 commit comments