feat: clean up jsmod exports and add AddConfig for in-memory updates
This commit is contained in:
parent
6b6e191c71
commit
c0e0d7c280
11
config.go
11
config.go
@ -30,6 +30,17 @@ func SetEncryptKeys(key, iv []byte) {
|
|||||||
crypto.SetDefaultAES(key, iv)
|
crypto.SetDefaultAES(key, iv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddConfig 允许在内存中动态添加或覆盖配置,适用于从数据库或知识库加载配置的场景
|
||||||
|
func AddConfig(name string, conf map[string]any) {
|
||||||
|
configMutex.Lock()
|
||||||
|
defer configMutex.Unlock()
|
||||||
|
if GlobalConfigs[name] == nil {
|
||||||
|
GlobalConfigs[name] = conf
|
||||||
|
} else if dst, ok := GlobalConfigs[name].(map[string]any); ok {
|
||||||
|
MergeMap(dst, conf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Load 加载指定的配置文件并合并到 GlobalConfigs
|
// Load 加载指定的配置文件并合并到 GlobalConfigs
|
||||||
func Load(name string) error {
|
func Load(name string) error {
|
||||||
if name == "" {
|
if name == "" {
|
||||||
|
|||||||
42
js_export.go
42
js_export.go
@ -9,12 +9,13 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
jsmod.Register("api", map[string]any{
|
jsmod.Register("api", map[string]any{
|
||||||
"call": CallAny,
|
"call": call,
|
||||||
"load": Load,
|
"addConfig": AddConfig,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallAny(ctx context.Context, actionName string, payload any, options ...map[string]any) (any, error) {
|
// call 提供给 JS 的私有入口,避免污染 Go 公开 API
|
||||||
|
func call(ctx context.Context, actionName string, payload any, options ...map[string]any) (any, error) {
|
||||||
var opt map[string]any
|
var opt map[string]any
|
||||||
if len(options) > 0 {
|
if len(options) > 0 {
|
||||||
opt = options[0]
|
opt = options[0]
|
||||||
@ -24,7 +25,7 @@ func CallAny(ctx context.Context, actionName string, payload any, options ...map
|
|||||||
payload = make(map[string]any)
|
payload = make(map[string]any)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. Pre-fill the payload from GlobalConfigs (manually doing what api.Call does later)
|
// 1. 预填 Payload (JS 传来的 map 需要手动触发一次 fill 以获取全局配置)
|
||||||
actionConfig, safeBufs := GetActionConfig(actionName)
|
actionConfig, safeBufs := GetActionConfig(actionName)
|
||||||
defer func() {
|
defer func() {
|
||||||
for _, sb := range safeBufs {
|
for _, sb := range safeBufs {
|
||||||
@ -33,7 +34,7 @@ func CallAny(ctx context.Context, actionName string, payload any, options ...map
|
|||||||
}()
|
}()
|
||||||
fill(payload, actionConfig)
|
fill(payload, actionConfig)
|
||||||
|
|
||||||
// 2. Wrap into jsAction for interface satisfaction
|
// 2. 构造符合 Action 接口的私有包装器
|
||||||
ja := &jsAction{
|
ja := &jsAction{
|
||||||
name: actionName,
|
name: actionName,
|
||||||
payload: payload,
|
payload: payload,
|
||||||
@ -43,8 +44,6 @@ func CallAny(ctx context.Context, actionName string, payload any, options ...map
|
|||||||
return Call[any](ja)
|
return Call[any](ja)
|
||||||
}
|
}
|
||||||
|
|
||||||
// jsAction implements Action, SignerAction, URLAction, MethodAction, and ConfigurableAction.
|
|
||||||
// It redirects reflection-based 'fill' and 'json.Marshal' to its internal payload.
|
|
||||||
type jsAction struct {
|
type jsAction struct {
|
||||||
name string
|
name string
|
||||||
payload any
|
payload any
|
||||||
@ -52,40 +51,17 @@ type jsAction struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *jsAction) ActionName() string { return a.name }
|
func (a *jsAction) ActionName() string { return a.name }
|
||||||
|
|
||||||
func (a *jsAction) SignerName() string {
|
func (a *jsAction) SignerName() string {
|
||||||
if a.options != nil {
|
if a.options != nil {
|
||||||
if s := cast.String(a.options["signer"]); s != "" {
|
return cast.String(a.options["signer"])
|
||||||
return s
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
func (a *jsAction) GetURL() string { return cast.String(a.options["url"]) }
|
||||||
func (a *jsAction) GetURL() string {
|
func (a *jsAction) GetMethod() string { return cast.String(a.options["method"]) }
|
||||||
if a.options != nil {
|
|
||||||
if u := cast.String(a.options["url"]); u != "" {
|
|
||||||
return u
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *jsAction) GetMethod() string {
|
|
||||||
if a.options != nil {
|
|
||||||
if m := cast.String(a.options["method"]); m != "" {
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *jsAction) Config() map[string]any {
|
func (a *jsAction) Config() map[string]any {
|
||||||
return a.options
|
return a.options
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON ensures that when this action is sent via HTTP (as JSON),
|
|
||||||
// only the internal payload is sent, not the metadata fields.
|
|
||||||
func (a *jsAction) MarshalJSON() ([]byte, error) {
|
func (a *jsAction) MarshalJSON() ([]byte, error) {
|
||||||
return cast.ToJSONBytes(a.payload)
|
return cast.ToJSONBytes(a.payload)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user