Skip to content

Commit 6b1f8b8

Browse files
authored
Merge pull request #2568 from seefs001/feature/channel_override_trim_prefix
2 parents 22d0b73 + 817da8d commit 6b1f8b8

File tree

2 files changed

+909
-3
lines changed

2 files changed

+909
-3
lines changed

relay/common/override.go

Lines changed: 118 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ type ConditionOperation struct {
2323

2424
type 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+
372405
func 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+
425540
func 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

Comments
 (0)