From 6b19f721011c1728cd6a6fb328525f946877bafc Mon Sep 17 00:00:00 2001 From: AI Engineer Date: Sat, 30 May 2026 19:26:05 +0800 Subject: [PATCH] feat: inject safeMode into context in bridge --- bridge.go | 22 ++++++++++++---------- doc.go | 13 +++++++++++-- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/bridge.go b/bridge.go index b07f179..f2cee9b 100644 --- a/bridge.go +++ b/bridge.go @@ -8,6 +8,7 @@ import ( "reflect" "apigo.cc/go/cast" + "apigo.cc/go/jsmod" "github.com/dop251/goja" ) @@ -23,19 +24,18 @@ func wrapGoFunc(vm *goja.Runtime, fn any, isUnsafe bool) goja.Value { return vm.ToValue(func(call goja.FunctionCall) goja.Value { // 1. Safety Check - if isUnsafe { - safeMode := true // Default to safe mode - smVal := vm.Get("__safeMode__") - if smVal != nil && !goja.IsUndefined(smVal) { - if sm, ok := smVal.Export().(bool); ok { - safeMode = sm - } - } - if safeMode { - panic(vm.NewGoError(fmt.Errorf("unauthorized: unsafe operation blocked by safeMode"))) + safeMode := true // Default to safe mode + smVal := vm.Get("__safeMode__") + if smVal != nil && !goja.IsUndefined(smVal) { + if sm, ok := smVal.Export().(bool); ok { + safeMode = sm } } + if isUnsafe && safeMode { + panic(vm.NewGoError(fmt.Errorf("unauthorized: unsafe operation blocked by safeMode"))) + } + // 2. Prepare Arguments numIn := t.NumIn() goArgs := make([]reflect.Value, numIn) @@ -54,6 +54,8 @@ func wrapGoFunc(vm *goja.Runtime, fn any, isUnsafe bool) goja.Value { ctx = c } } + // Inject SafeMode status into context + ctx = context.WithValue(ctx, jsmod.SafeModeKey, safeMode) goArgs[i] = reflect.ValueOf(ctx) continue } diff --git a/doc.go b/doc.go index 0a0574b..c8ac3cf 100644 --- a/doc.go +++ b/doc.go @@ -69,8 +69,8 @@ func formatFunc(t reflect.Type) string { for i := 0; i < numIn; i++ { argType := t.In(i) // Skip Context and Logger in TS doc - if argType.Implements(reflect.TypeOf((*interface{ Done() <-chan struct{} })(nil)).Elem()) || - argType.String() == "*log.Logger" { + typeName := argType.String() + if typeName == "context.Context" || typeName == "*log.Logger" { continue } @@ -107,6 +107,15 @@ func goTypeToTS(t reflect.Type) string { return "any" } + // Handle known standard library types to avoid deep recursion and provide clear naming + typeName := t.String() + switch typeName { + case "time.Time", "*time.Time": + return "time.Time" + case "time.Duration", "*time.Duration": + return "time.Duration" + } + // Handle pointers for t.Kind() == reflect.Ptr { t = t.Elem()