mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-03 04:50:52 +08:00
refactor(gemini): optimize removeExtensionFields with post-order traversal and DeleteBytes
Amp-Thread-ID: https://ampcode.com/threads/T-019c0d09-330d-7399-b794-652b94847df1 Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -4,6 +4,7 @@ package util
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
@@ -441,32 +442,43 @@ func removeUnsupportedKeywords(jsonStr string) string {
|
|||||||
func removeExtensionFields(jsonStr string) string {
|
func removeExtensionFields(jsonStr string) string {
|
||||||
var paths []string
|
var paths []string
|
||||||
walkForExtensions(gjson.Parse(jsonStr), "", &paths)
|
walkForExtensions(gjson.Parse(jsonStr), "", &paths)
|
||||||
sortByDepth(paths)
|
// walkForExtensions returns paths in a way that deeper paths are added before their ancestors
|
||||||
|
// when they are not deleted wholesale, but since we skip children of deleted x-* nodes,
|
||||||
|
// any collected path is safe to delete. We still use DeleteBytes for efficiency.
|
||||||
|
|
||||||
|
b := []byte(jsonStr)
|
||||||
for _, p := range paths {
|
for _, p := range paths {
|
||||||
jsonStr, _ = sjson.Delete(jsonStr, p)
|
b, _ = sjson.DeleteBytes(b, p)
|
||||||
}
|
}
|
||||||
return jsonStr
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func walkForExtensions(value gjson.Result, path string, paths *[]string) {
|
func walkForExtensions(value gjson.Result, path string, paths *[]string) {
|
||||||
if !value.IsObject() && !value.IsArray() {
|
if value.IsArray() {
|
||||||
|
arr := value.Array()
|
||||||
|
for i := len(arr) - 1; i >= 0; i-- {
|
||||||
|
walkForExtensions(arr[i], joinPath(path, strconv.Itoa(i)), paths)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if value.IsObject() {
|
||||||
value.ForEach(func(key, val gjson.Result) bool {
|
value.ForEach(func(key, val gjson.Result) bool {
|
||||||
keyStr := key.String()
|
keyStr := key.String()
|
||||||
safeKey := escapeGJSONPathKey(keyStr)
|
safeKey := escapeGJSONPathKey(keyStr)
|
||||||
childPath := joinPath(path, safeKey)
|
childPath := joinPath(path, safeKey)
|
||||||
|
|
||||||
// Only remove x-* extension fields, but protect them if they are property definitions.
|
// If it's an extension field, we delete it and don't need to look at its children.
|
||||||
if strings.HasPrefix(keyStr, "x-") && !isPropertyDefinition(path) {
|
if strings.HasPrefix(keyStr, "x-") && !isPropertyDefinition(path) {
|
||||||
*paths = append(*paths, childPath)
|
*paths = append(*paths, childPath)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
walkForExtensions(val, childPath, paths)
|
walkForExtensions(val, childPath, paths)
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func cleanupRequiredFields(jsonStr string) string {
|
func cleanupRequiredFields(jsonStr string) string {
|
||||||
for _, p := range findPaths(jsonStr, "required") {
|
for _, p := range findPaths(jsonStr, "required") {
|
||||||
|
|||||||
Reference in New Issue
Block a user