Forráskód Böngészése

fix: allow the negative number for override.go

Nekohy 6 hónapja
szülő
commit
e61c1dc738
1 módosított fájl, 46 hozzáadás és 7 törlés
  1. 46 7
      relay/common/override.go

+ 46 - 7
relay/common/override.go

@@ -5,6 +5,8 @@ import (
 	"fmt"
 	"github.com/tidwall/gjson"
 	"github.com/tidwall/sjson"
+	"regexp"
+	"strconv"
 	"strings"
 )
 
@@ -151,7 +153,9 @@ func checkConditions(jsonStr string, conditions []ConditionOperation, logic stri
 }
 
 func checkSingleCondition(jsonStr string, condition ConditionOperation) (bool, error) {
-	value := gjson.Get(jsonStr, condition.Path)
+	// 处理负数索引
+	path := processNegativeIndex(jsonStr, condition.Path)
+	value := gjson.Get(jsonStr, path)
 	if !value.Exists() {
 		if condition.PassMissingKey {
 			return true, nil
@@ -177,6 +181,37 @@ func checkSingleCondition(jsonStr string, condition ConditionOperation) (bool, e
 	return result, nil
 }
 
+func processNegativeIndex(jsonStr string, path string) string {
+	re := regexp.MustCompile(`\.(-\d+)`)
+	matches := re.FindAllStringSubmatch(path, -1)
+
+	if len(matches) == 0 {
+		return path
+	}
+
+	result := path
+	for _, match := range matches {
+		negIndex := match[1]
+		index, _ := strconv.Atoi(negIndex)
+
+		arrayPath := strings.Split(path, negIndex)[0]
+		if strings.HasSuffix(arrayPath, ".") {
+			arrayPath = arrayPath[:len(arrayPath)-1]
+		}
+
+		array := gjson.Get(jsonStr, arrayPath)
+		if array.IsArray() {
+			length := len(array.Array())
+			actualIndex := length + index
+			if actualIndex >= 0 && actualIndex < length {
+				result = strings.Replace(result, match[0], "."+strconv.Itoa(actualIndex), 1)
+			}
+		}
+	}
+
+	return result
+}
+
 // compareGjsonValues 直接比较两个gjson.Result,支持所有比较模式
 func compareGjsonValues(jsonValue, targetValue gjson.Result, mode string) (bool, error) {
 	switch mode {
@@ -274,21 +309,25 @@ func applyOperations(jsonStr string, operations []ParamOperation) (string, error
 		if !ok {
 			continue // 条件不满足,跳过当前操作
 		}
+		// 处理路径中的负数索引
+		opPath := processNegativeIndex(result, op.Path)
+		opFrom := processNegativeIndex(result, op.From)
+		opTo := processNegativeIndex(result, op.To)
 
 		switch op.Mode {
 		case "delete":
-			result, err = sjson.Delete(result, op.Path)
+			result, err = sjson.Delete(result, opPath)
 		case "set":
-			if op.KeepOrigin && gjson.Get(result, op.Path).Exists() {
+			if op.KeepOrigin && gjson.Get(result, opPath).Exists() {
 				continue
 			}
-			result, err = sjson.Set(result, op.Path, op.Value)
+			result, err = sjson.Set(result, opPath, op.Value)
 		case "move":
-			result, err = moveValue(result, op.From, op.To)
+			result, err = moveValue(result, opFrom, opTo)
 		case "prepend":
-			result, err = modifyValue(result, op.Path, op.Value, op.KeepOrigin, true)
+			result, err = modifyValue(result, opPath, op.Value, op.KeepOrigin, true)
 		case "append":
-			result, err = modifyValue(result, op.Path, op.Value, op.KeepOrigin, false)
+			result, err = modifyValue(result, opPath, op.Value, op.KeepOrigin, false)
 		default:
 			return "", fmt.Errorf("unknown operation: %s", op.Mode)
 		}