mirror of
https://github.com/black-ant/Ant-Browser.git
synced 2026-07-14 18:48:55 +08:00
289 lines
8.2 KiB
Go
289 lines
8.2 KiB
Go
package automation
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func stringifyImportJSONValue(value any) string {
|
|
if value == nil {
|
|
return ""
|
|
}
|
|
if text, ok := value.(string); ok {
|
|
return strings.TrimSpace(text)
|
|
}
|
|
encoded, err := json.MarshalIndent(value, "", " ")
|
|
if err != nil {
|
|
return strings.TrimSpace(fmt.Sprint(value))
|
|
}
|
|
return string(bytes.TrimSpace(encoded))
|
|
}
|
|
|
|
func mergeDescriptorValue(target map[string]any, key string, value string) {
|
|
if strings.TrimSpace(value) == "" {
|
|
return
|
|
}
|
|
if _, exists := target[key]; exists {
|
|
return
|
|
}
|
|
target[key] = strings.TrimSpace(value)
|
|
}
|
|
|
|
func mapStringSliceValue(payload map[string]any, key string) []string {
|
|
raw, exists := payload[key]
|
|
if !exists || raw == nil {
|
|
return nil
|
|
}
|
|
items, ok := raw.([]any)
|
|
if !ok {
|
|
if stringsValue, ok := raw.([]string); ok {
|
|
return normalizeScriptTags(stringsValue)
|
|
}
|
|
return nil
|
|
}
|
|
result := make([]string, 0, len(items))
|
|
for _, item := range items {
|
|
value := strings.TrimSpace(fmt.Sprint(item))
|
|
if value != "" {
|
|
result = append(result, value)
|
|
}
|
|
}
|
|
return normalizeScriptTags(result)
|
|
}
|
|
|
|
func mapStringValueAny(payload map[string]any, key string) string {
|
|
if payload == nil {
|
|
return ""
|
|
}
|
|
value, exists := payload[key]
|
|
if !exists || value == nil {
|
|
return ""
|
|
}
|
|
return strings.TrimSpace(fmt.Sprint(value))
|
|
}
|
|
|
|
func mapIntValueAny(payload map[string]any, key string) int {
|
|
if payload == nil {
|
|
return 0
|
|
}
|
|
value, exists := payload[key]
|
|
if !exists || value == nil {
|
|
return 0
|
|
}
|
|
switch typed := value.(type) {
|
|
case int:
|
|
return typed
|
|
case int32:
|
|
return int(typed)
|
|
case int64:
|
|
return int(typed)
|
|
case float64:
|
|
return int(typed)
|
|
case json.Number:
|
|
if parsed, err := typed.Int64(); err == nil {
|
|
return int(parsed)
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func mapObjectValue(payload map[string]any, key string) map[string]any {
|
|
if payload == nil {
|
|
return nil
|
|
}
|
|
value, exists := payload[key]
|
|
if !exists || value == nil {
|
|
return nil
|
|
}
|
|
if object, ok := value.(map[string]any); ok {
|
|
return object
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func inferImportSource(sourceLabel string) ScriptSource {
|
|
now := time.Now().Format(time.RFC3339)
|
|
trimmed := strings.TrimSpace(sourceLabel)
|
|
source := ScriptSource{
|
|
ImportedAt: now,
|
|
}
|
|
switch {
|
|
case strings.HasPrefix(trimmed, "本地文件 "):
|
|
source.Type = "local-file"
|
|
source.URI = strings.TrimSpace(strings.TrimPrefix(trimmed, "本地文件 "))
|
|
case strings.HasPrefix(trimmed, "本地目录 "):
|
|
source.Type = "local-dir"
|
|
source.URI = strings.TrimSpace(strings.TrimPrefix(trimmed, "本地目录 "))
|
|
case strings.HasPrefix(trimmed, "远程地址 "):
|
|
source.Type = "remote-url"
|
|
source.URI = strings.TrimSpace(strings.TrimPrefix(trimmed, "远程地址 "))
|
|
case strings.HasPrefix(trimmed, "Git "):
|
|
source.Type = "git"
|
|
rest := strings.TrimSpace(strings.TrimPrefix(trimmed, "Git "))
|
|
repo := rest
|
|
if index := strings.Index(rest, " : "); index >= 0 {
|
|
source.Path = strings.TrimSpace(rest[index+3:])
|
|
repo = strings.TrimSpace(rest[:index])
|
|
}
|
|
if index := strings.Index(repo, " @ "); index >= 0 {
|
|
source.Ref = strings.TrimSpace(repo[index+3:])
|
|
repo = strings.TrimSpace(repo[:index])
|
|
}
|
|
source.URI = repo
|
|
default:
|
|
if trimmed != "" {
|
|
source.Type = "manual"
|
|
source.URI = trimmed
|
|
}
|
|
}
|
|
return source
|
|
}
|
|
|
|
func mergeImportedSource(base ScriptSource, override map[string]any) ScriptSource {
|
|
if override == nil {
|
|
return base
|
|
}
|
|
next := base
|
|
if value := mapStringValueAny(override, "type"); value != "" {
|
|
next.Type = value
|
|
}
|
|
if value := firstNonEmpty(mapStringValueAny(override, "uri"), mapStringValueAny(override, "url")); value != "" {
|
|
next.URI = value
|
|
}
|
|
if value := mapStringValueAny(override, "ref"); value != "" {
|
|
next.Ref = value
|
|
}
|
|
if value := mapStringValueAny(override, "path"); value != "" {
|
|
next.Path = value
|
|
}
|
|
if value := mapStringValueAny(override, "importedAt"); value != "" {
|
|
next.ImportedAt = value
|
|
}
|
|
return next
|
|
}
|
|
|
|
func mapScriptTargetConfigValue(value any) ScriptTargetConfig {
|
|
object, ok := value.(map[string]any)
|
|
if !ok || object == nil {
|
|
return ScriptTargetConfig{}
|
|
}
|
|
|
|
return ScriptTargetConfig{
|
|
Mode: mapStringValueAny(object, "mode"),
|
|
Selector: mapScriptTargetSelectorValue(object["selector"]),
|
|
TemplateSelector: mapScriptTargetSelectorValue(object["templateSelector"]),
|
|
CreateNameTemplate: mapStringValueAny(object, "createNameTemplate"),
|
|
}
|
|
}
|
|
|
|
func mapScriptPublicAPIValue(value any) ScriptPublicAPIConfig {
|
|
object, ok := value.(map[string]any)
|
|
if !ok || object == nil {
|
|
return ScriptPublicAPIConfig{}
|
|
}
|
|
|
|
return ScriptPublicAPIConfig{
|
|
Enabled: mapBoolValueAny(object, "enabled"),
|
|
Method: mapStringValueAny(object, "method"),
|
|
Path: firstNonEmpty(mapStringValueAny(object, "path"), mapStringValueAny(object, "route")),
|
|
RequestMode: mapStringValueAny(object, "requestMode"),
|
|
ResponseMode: mapStringValueAny(object, "responseMode"),
|
|
TimeoutMs: mapIntValueAny(object, "timeoutMs"),
|
|
RequestBodyText: stringifyImportJSONValue(firstNonNil(object["requestBodyText"], object["requestBody"], object["requestExample"])),
|
|
ResponseBodyText: stringifyImportJSONValue(firstNonNil(object["responseBodyText"], object["responseBody"], object["responseExample"])),
|
|
Variables: mapScriptPublicAPIVariablesValue(object["variables"]),
|
|
}
|
|
}
|
|
|
|
func mapScriptPublicAPIVariablesValue(value any) []ScriptPublicAPIVariable {
|
|
switch typed := value.(type) {
|
|
case []ScriptPublicAPIVariable:
|
|
return normalizeScriptPublicAPIVariables(typed)
|
|
case []any:
|
|
variables := make([]ScriptPublicAPIVariable, 0, len(typed))
|
|
for _, item := range typed {
|
|
object, ok := item.(map[string]any)
|
|
if !ok || object == nil {
|
|
continue
|
|
}
|
|
variables = append(variables, ScriptPublicAPIVariable{
|
|
Name: firstNonEmpty(mapStringValueAny(object, "name"), mapStringValueAny(object, "key")),
|
|
DefaultValue: firstNonEmpty(mapStringValueAny(object, "defaultValue"), mapStringValueAny(object, "default"), mapStringValueAny(object, "value")),
|
|
Description: firstNonEmpty(mapStringValueAny(object, "description"), mapStringValueAny(object, "label"), mapStringValueAny(object, "note")),
|
|
Required: mapBoolValueAny(object, "required"),
|
|
})
|
|
}
|
|
return normalizeScriptPublicAPIVariables(variables)
|
|
case map[string]any:
|
|
variables := make([]ScriptPublicAPIVariable, 0, len(typed))
|
|
for key, rawValue := range typed {
|
|
variable := ScriptPublicAPIVariable{Name: key}
|
|
if object, ok := rawValue.(map[string]any); ok && object != nil {
|
|
variable.DefaultValue = firstNonEmpty(mapStringValueAny(object, "defaultValue"), mapStringValueAny(object, "default"), mapStringValueAny(object, "value"))
|
|
variable.Description = firstNonEmpty(mapStringValueAny(object, "description"), mapStringValueAny(object, "label"), mapStringValueAny(object, "note"))
|
|
variable.Required = mapBoolValueAny(object, "required")
|
|
} else if rawValue != nil {
|
|
variable.DefaultValue = strings.TrimSpace(fmt.Sprint(rawValue))
|
|
}
|
|
variables = append(variables, variable)
|
|
}
|
|
return normalizeScriptPublicAPIVariables(variables)
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func mapScriptTargetSelectorValue(value any) ScriptTargetSelector {
|
|
object, ok := value.(map[string]any)
|
|
if !ok || object == nil {
|
|
return ScriptTargetSelector{}
|
|
}
|
|
|
|
return ScriptTargetSelector{
|
|
Code: firstNonEmpty(mapStringValueAny(object, "code"), mapStringValueAny(object, "launchCode")),
|
|
ProfileID: mapStringValueAny(object, "profileId"),
|
|
ProfileName: mapStringValueAny(object, "profileName"),
|
|
GroupID: mapStringValueAny(object, "groupId"),
|
|
Keywords: mapStringSliceValue(object, "keywords"),
|
|
Tags: mapStringSliceValue(object, "tags"),
|
|
}
|
|
}
|
|
|
|
func mapBoolValueAny(payload map[string]any, key string) bool {
|
|
if payload == nil {
|
|
return false
|
|
}
|
|
value, exists := payload[key]
|
|
if !exists || value == nil {
|
|
return false
|
|
}
|
|
switch typed := value.(type) {
|
|
case bool:
|
|
return typed
|
|
case string:
|
|
switch strings.ToLower(strings.TrimSpace(typed)) {
|
|
case "true", "1", "yes", "enabled", "on":
|
|
return true
|
|
}
|
|
case float64:
|
|
return typed != 0
|
|
case int:
|
|
return typed != 0
|
|
case int64:
|
|
return typed != 0
|
|
}
|
|
return false
|
|
}
|
|
|
|
func firstNonNil(values ...any) any {
|
|
for _, value := range values {
|
|
if value != nil {
|
|
return value
|
|
}
|
|
}
|
|
return nil
|
|
}
|