feat: upgrade jsmod to support unsafeList tracking (by AI)

This commit is contained in:
AI Engineer 2026-05-30 15:33:57 +08:00
parent 056d8c6f6a
commit 57810a5553
2 changed files with 36 additions and 13 deletions

View File

@ -2,34 +2,47 @@ package jsmod
import "sync" import "sync"
type Module struct {
Exports map[string]any
UnsafeList map[string]bool
}
var ( var (
modules = make(map[string]map[string]any) modules = make(map[string]*Module)
mu sync.RWMutex mu sync.RWMutex
) )
// Register registers a Go module with its exported functions and properties. // Register registers a Go module with its exported functions and properties.
// These modules will be accessible within the JS environment. // These modules will be accessible within the JS environment.
func Register(name string, exports map[string]any) { // unsafeList identifies methods that require elevated permissions (e.g., file writing, shell execution).
func Register(name string, exports map[string]any, unsafeList ...string) {
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
if modules[name] == nil { if modules[name] == nil {
modules[name] = make(map[string]any, len(exports)) modules[name] = &Module{
Exports: make(map[string]any, len(exports)),
UnsafeList: make(map[string]bool),
}
} }
for k, v := range exports { for k, v := range exports {
modules[name][k] = v modules[name].Exports[k] = v
}
for _, method := range unsafeList {
modules[name].UnsafeList[method] = true
} }
} }
// GetModules returns all registered modules for the JS engine to inject. // GetModules returns all registered modules and their unsafe status.
func GetModules() map[string]map[string]any { func GetModules() map[string]*Module {
mu.RLock() mu.RLock()
defer mu.RUnlock() defer mu.RUnlock()
res := make(map[string]map[string]any, len(modules)) res := make(map[string]*Module, len(modules))
for name, exports := range modules { for name, mod := range modules {
res[name] = exports res[name] = mod
} }
return res return res
} }

View File

@ -1,14 +1,24 @@
package jsmod_test package jsmod_test
import ( import (
"apigo.cc/go/jsmod"
"testing" "testing"
"apigo.cc/go/jsmod"
) )
func TestRegister(t *testing.T) { func TestRegister(t *testing.T) {
jsmod.Register("test", map[string]any{"foo": "bar"}) jsmod.Register("test", map[string]any{"foo": "bar"}, "foo")
mods := jsmod.GetModules() mods := jsmod.GetModules()
if mods["test"]["foo"] != "bar" {
t.Error("Register failed") mod, ok := mods["test"]
if !ok {
t.Fatal("Module not found")
}
if mod.Exports["foo"] != "bar" {
t.Error("Export failed")
}
if !mod.UnsafeList["foo"] {
t.Error("UnsafeList tracking failed")
} }
} }