package gojs import ( "apigo.cc/apigo/gojs/dop251/goja" "errors" "github.com/ssgo/log" "github.com/ssgo/u" "path/filepath" ) type Args struct { This goja.Value Arguments []goja.Value VM *goja.Runtime Logger *log.Logger } type Obj struct { This goja.Value VM *goja.Runtime Logger *log.Logger O *goja.Object } func GetLogger(vm *goja.Runtime) *log.Logger { var logger *log.Logger if vm.GoData["logger"] != nil { if logger1, ok := vm.GoData["logger"].(*log.Logger); ok { logger = logger1 } } if logger == nil { logger = log.DefaultLogger } return logger } func MakeArgs(args *goja.FunctionCall, vm *goja.Runtime) *Args { return &Args{ This: args.This, Arguments: args.Arguments, VM: vm, Logger: GetLogger(vm), } } func (args *Args) Check(num int) *Args { if len(args.Arguments) < num { panic(args.VM.NewGoError(errors.New("arguments need " + u.String(num) + ", but given " + u.String(len(args.Arguments))))) } return args } func (args *Args) Int(index int) int { if len(args.Arguments) > index { return u.Int(args.Arguments[index].Export()) } return 0 } func (args *Args) Int64(index int) int64 { if len(args.Arguments) > index { return u.Int64(args.Arguments[index].Export()) } return 0 } func (args *Args) Any(index int) any { if len(args.Arguments) > index { return args.Arguments[index].Export() } return nil } func (args *Args) Str(index int) string { if len(args.Arguments) > index { return u.String(args.Arguments[index].Export()) } return "" } func (args *Args) Bytes(index int) []byte { if len(args.Arguments) > index { return u.Bytes(args.Arguments[index].Export()) } return []byte{} } func (args *Args) Bool(index int) bool { if len(args.Arguments) > index { return u.Bool(args.Arguments[index].Export()) } return false } func (args *Args) Map(index int) map[string]any { out := map[string]any{} if len(args.Arguments) > index { u.Convert(args.Arguments[index].Export(), &out) } return out } func (args *Args) StrArr(startIndex int) []string { if len(args.Arguments) > startIndex { a := make([]string, len(args.Arguments)-startIndex) for index := startIndex; index < len(args.Arguments); index++ { a[index-startIndex] = u.String(args.Arguments[index].Export()) } return a } return make([]string, 0) } func (args *Args) Arr(startIndex int) []any { if len(args.Arguments) > startIndex { a := make([]any, len(args.Arguments)-startIndex) for index := startIndex; index < len(args.Arguments); index++ { a[index-startIndex] = u.String(args.Arguments[index].Export()) } return a } return make([]any, 0) } func (args *Args) Map2StrArr(index int) []string { headerMap := args.Map(index) headers := make([]string, len(headerMap)*2) i := 0 for k, v := range headerMap { headers[i] = k headers[i+1] = u.String(v) i += 2 } return headers } func (args *Args) Map2Arr(index int) []any { arrMap := args.Map(index) arr := make([]any, len(arrMap)*2) i := 0 for k, v := range arrMap { arr[i] = k arr[i+1] = u.String(v) i += 2 } return arr } func FindPath(vm *goja.Runtime, filename string) string { if u.FileExists(filename) { return filename } if !filepath.IsAbs(filename) { startPath := u.String(vm.GoData["startPath"]) if startPath != "" { tryFilename := filepath.Join(startPath, filename) if u.FileExists(tryFilename) { return tryFilename } } } return filename } func (args *Args) Path(index int) string { return FindPath(args.VM, args.Str(index)) } func GetFunc(v goja.Value) goja.Callable { if cb, ok := goja.AssertFunction(v); ok { return cb } return nil } func (args *Args) Func(index int) goja.Callable { if len(args.Arguments) > index { return GetFunc(args.Arguments[index]) } return nil } func (args *Args) Obj(index int) *Obj { if len(args.Arguments) > index { return &Obj{ This: args.This, VM: args.VM, Logger: args.Logger, O: args.Arguments[index].ToObject(args.VM), } } return nil } func (args *Args) Object(index int) *goja.Object { if len(args.Arguments) > index { return args.Arguments[index].ToObject(args.VM) } return nil } // -------- Object func (obj *Obj) Get(name string) goja.Value { return obj.O.Get(name) } func (obj *Obj) Int(name string) int { v := obj.O.Get(name) if v != nil { return u.Int(v.Export()) } return 0 } func (obj *Obj) Int64(name string) int64 { v := obj.O.Get(name) if v != nil { return u.Int64(v.Export()) } return 0 } func (obj *Obj) Any(name string) any { v := obj.O.Get(name) if v != nil { return v.Export() } return nil } func (obj *Obj) Str(name string) string { v := obj.O.Get(name) if v != nil { return u.String(v.Export()) } return "" } func (obj *Obj) Bytes(name string) []byte { v := obj.O.Get(name) if v != nil { return u.Bytes(v.Export()) } return []byte{} } func (obj *Obj) Bool(name string) bool { v := obj.O.Get(name) if v != nil { return u.Bool(v.Export()) } return false } func (obj *Obj) Map(name string) map[string]any { v := obj.O.Get(name) out := map[string]any{} if v != nil { u.Convert(v.Export(), &out) } return out } func (obj *Obj) Path(name string) string { return FindPath(obj.VM, obj.Str(name)) } func (obj *Obj) Func(name string) goja.Callable { v := obj.O.Get(name) if v != nil { return GetFunc(v) } return nil } func (obj *Obj) Object(name string) *goja.Object { v := obj.O.Get(name) if v != nil { return v.ToObject(obj.VM) } return nil } func (obj *Obj) Arr(name string) []any { v := obj.O.Get(name) if v != nil { arr := make([]any, 0) obj.VM.ForOf(v, func(v goja.Value) bool { arr = append(arr, v.Export()) return true }) return arr } return nil }