Documentation
¶
Index ¶
- Constants
- Variables
- func CheckHashPasword(hash, pwd string) bool
- func DecodeCustomBase34(s string) uint64
- func Decrypt(ciphertext, password []byte) ([]byte, error)
- func DecryptTripleDESCBC(encrypted, key []byte) ([]byte, error)
- func Decrypts(text, password string) (string, error)
- func EncodeCustomBase34(value uint64) string
- func Encrypt(plaintext, password []byte) ([]byte, error)
- func EncryptTripleDESCBC(decrypted, key []byte) ([]byte, error)
- func Encrypts(text, password string) (string, error)
- func GetLocation(vm *sim.VM) *time.Location
- func HashPassword(pwd string) string
- func IsAlphanumeric(s string) bool
- func IsAlphanumericIdent(s string) bool
- func IsDecimal(r rune) bool
- func IsIdent(s string) bool
- func IsNumeric(s string) bool
- func NewReader(r io.Reader) *reader
- func NewRoute(url string) *httpRoute
- func NewWriter(w io.Writer) *writer
- func RandString(n int) string
- func Random(n int) []byte
- func RandomAlphanumeric(size int) string
- func ReadAll(reader io.Reader, vm *sim.VM) ([]byte, error)
- func ReadNames(fs filesystem.FS, dirname string, recursive bool) ([]string, error)
- func SendMailWithTimeout(addr string, a Auth, from string, to []string, msg []byte, ...) error
- func Split(s, sep string) []string
- func ToDuration(v sim.Value) (time.Duration, error)
- func ValidateArgRange(args []sim.Value, counts ...int) error
- func ValidateArgs(args []sim.Value, t ...interface{}) error
- func ValidateOptionalArgs(args []sim.Value, t ...sim.Type) error
- func ValidateOrNilArgs(args []sim.Value, t ...interface{}) error
- func ValidatePermissions(p *sim.Program, vm *sim.VM) error
- func WithDeadline(d time.Duration, fn func(dl *Deadline) error) error
- func Write(w io.Writer, v sim.Value, vm *sim.VM) error
- func WriteAt(w io.WriterAt, v sim.Value, off int64, vm *sim.VM) error
- func ZeroPadding(ciphertext []byte, blockSize int) []byte
- func ZeroUnPadding(origData []byte) []byte
- type Addr
- type Auth
- type Buffer
- type Client
- func (c *Client) Auth(a Auth) error
- func (c *Client) Close() error
- func (c *Client) Data() (io.WriteCloser, error)
- func (c *Client) Extension(ext string) (bool, string)
- func (c *Client) Hello(localName string) error
- func (c *Client) Mail(from string) error
- func (c *Client) Quit() error
- func (c *Client) Rcpt(to string) error
- func (c *Client) Reset() error
- func (c *Client) StartTLS(config *tls.Config) error
- func (c *Client) TLSConnectionState() (state tls.ConnectionState, ok bool)
- func (c *Client) Verify(addr string) error
- type Clock
- type Deadline
- type Duration
- func (t Duration) Export(recursionLevel int) interface{}
- func (t Duration) GetField(name string, vm *sim.VM) (sim.Value, error)
- func (t Duration) GetMethod(name string) sim.NativeMethod
- func (t Duration) MarshalJSON() ([]byte, error)
- func (t Duration) Size() int
- func (t Duration) String() string
- func (t Duration) Type() string
- type FileSystemObj
- type IP
- type QueryStat
- type ResponseWriterCounter
- type SecureObject
- type ServerInfo
- type SmtMessage
- func (m *SmtMessage) AllRecipients() []string
- func (m *SmtMessage) AttachBuffer(filename string, buf []byte, inline bool) error
- func (m *SmtMessage) BccList() []string
- func (m *SmtMessage) Bytes() []byte
- func (m *SmtMessage) CcList() []string
- func (m *SmtMessage) ContentType() string
- func (m *SmtMessage) GetField(key string, vm *sim.VM) (sim.Value, error)
- func (m *SmtMessage) GetMethod(name string) sim.NativeMethod
- func (m *SmtMessage) SendWithTimeout(user, password, host string, port int, insecureSkipVerify bool, ...) error
- func (m *SmtMessage) SetField(key string, v sim.Value, vm *sim.VM) error
- func (m *SmtMessage) ToList() []string
- func (SmtMessage) Type() string
- type SqlProfiler
- type TimeObj
- func (t TimeObj) Compare(v sim.Value) int
- func (t TimeObj) Equals(v interface{}) bool
- func (t TimeObj) Export(recursionLevel int) interface{}
- func (t TimeObj) GetField(name string, vm *sim.VM) (sim.Value, error)
- func (t TimeObj) GetMethod(name string) sim.NativeMethod
- func (t TimeObj) MarshalJSON() ([]byte, error)
- func (t TimeObj) Size() int
- func (t TimeObj) String() string
- func (t TimeObj) Type() string
- type URL
- type VMNumberFormatter
Constants ¶
const MAX_PARSE_FORM_MEMORY = 10000
Variables ¶
var Assert = []sim.NativeFunction{ { Name: "assert.contains", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var msg string ln := len(args) switch ln { case 2: if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } case 3: if err := ValidateArgs(args, sim.String, sim.String, sim.String); err != nil { return sim.NullValue, err } msg = args[2].String() default: return sim.NullValue, fmt.Errorf("expected 2 or 3 args, got %d", ln) } a := args[0].String() b := args[1].String() if !strings.Contains(b, a) { if msg != "" { return sim.NullValue, errors.New(msg) } return sim.NullValue, fmt.Errorf("'%s' not contained in '%s'", a, b) } return sim.NullValue, nil }, }, { Name: "assert.equal", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var msg string ln := len(args) switch ln { case 2: case 3: a3 := args[2] if a3.Type != sim.String { return sim.NullValue, fmt.Errorf("expected error message to be a string, got %v", a3.TypeName()) } msg = a3.String() default: return sim.NullValue, fmt.Errorf("expected 2 or 3 args, got %d", ln) } a := args[0] b := args[1] if !areEqual(a, b) { if msg != "" { return sim.NullValue, errors.New(msg) } return sim.NullValue, fmt.Errorf("values are different: %v, %v", serializeOrErr(a), serializeOrErr(b)) } return sim.NullValue, nil }, }, { Name: "assert.isTrue", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var msg string ln := len(args) switch ln { case 1: case 2: if args[1].Type != sim.String { return sim.NullValue, fmt.Errorf("expected error message to be a string, got %v", args[1].TypeName()) } msg = args[1].String() default: return sim.NullValue, fmt.Errorf("expected 1 or 2 args, got %d", ln) } a := args[0] switch a.Type { case sim.Bool: if a.ToBool() { return sim.TrueValue, nil } } if msg != "" { return sim.NullValue, errors.New(msg) } return sim.NullValue, fmt.Errorf("expected true, got %v", a) }, }, { Name: "assert.isFalse", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var msg string ln := len(args) switch ln { case 1: case 2: if args[1].Type != sim.String { return sim.NullValue, fmt.Errorf("expected error message to be a string, got %v", args[1].TypeName()) } msg = args[1].String() default: return sim.NullValue, fmt.Errorf("expected 1 or 2 args, got %d", ln) } a := args[0] switch a.Type { case sim.Bool: if !a.ToBool() { return sim.TrueValue, nil } } if msg != "" { return sim.NullValue, errors.New(msg) } return sim.NullValue, fmt.Errorf("expected false, got %v", a) }, }, { Name: "assert.isNull", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var msg string ln := len(args) switch ln { case 1: case 2: if args[1].Type != sim.String { return sim.NullValue, fmt.Errorf("expected error message to be a string, got %v", args[1].TypeName()) } msg = args[1].String() default: return sim.NullValue, fmt.Errorf("expected 1 or 2 args, got %d", ln) } a := args[0] switch a.Type { case sim.Null, sim.Undefined: default: if msg != "" { return sim.NullValue, errors.New(msg) } return sim.NullValue, fmt.Errorf("expected null, got %v", a) } return sim.NullValue, nil }, }, { Name: "assert.isNotNull", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var msg string ln := len(args) switch ln { case 1: case 2: if args[1].Type != sim.String { return sim.NullValue, fmt.Errorf("expected error message to be a string, got %v", args[1].TypeName()) } msg = args[1].String() default: return sim.NullValue, fmt.Errorf("expected 1 or 2 args, got %d", ln) } a := args[0] switch a.Type { case sim.Null, sim.Undefined: if msg != "" { return sim.NullValue, errors.New(msg) } return sim.NullValue, fmt.Errorf("%v is null", a) default: } return sim.NullValue, nil }, }, { Name: "assert.exception", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] if a.Type != sim.String { return sim.NullValue, fmt.Errorf("expected argument 1 to be a string, got %s", a.TypeName()) } expected := a.String() v := args[1] err := runFuncOrClosure(vm, v) if err == nil { return sim.NullValue, fmt.Errorf("expected exception: %s", expected) } if expected != "" && !strings.Contains(err.Error(), expected) { return sim.NullValue, fmt.Errorf("invalid exception, does not contain '%s': %s", expected, err.Error()) } vm.Error = nil return sim.NullValue, nil }, }, { Name: "assert.int", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if !isStringLike(args[1]) { return sim.NullValue, fmt.Errorf("expected argument 2 to be a string, got %s", args[1].TypeName()) } a := args[0] msg := args[1].String() var v int64 var err error switch a.Type { case sim.Int: v = a.ToInt() case sim.String: v, err = strconv.ParseInt(a.String(), 0, 64) if err != nil { return sim.NullValue, fmt.Errorf(msg, showAssertMessage("%v is not int", a.TypeName())) } default: return sim.NullValue, errors.New(msg) } return sim.NewInt64(v), nil }, }, { Name: "assert.float", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if !isStringLike(args[1]) { return sim.NullValue, fmt.Errorf("expected argument 2 to be a string, got %s", args[1].TypeName()) } a := args[0] msg := args[1].String() var v int64 var err error switch a.Type { case sim.Int: v = a.ToInt() case sim.String: v, err = strconv.ParseInt(a.String(), 0, 64) if err != nil { return sim.NullValue, fmt.Errorf(msg, showAssertMessage("%v is not float", a.TypeName())) } default: return sim.NullValue, fmt.Errorf(msg, showAssertMessage("%v is not float", a.TypeName())) } return sim.NewInt64(v), nil }, }, { Name: "assert.string", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if !isStringLike(args[1]) { return sim.NullValue, fmt.Errorf("expected argument 2 to be a string, got %s", args[1].TypeName()) } a := args[0] msg := args[1].String() var v string switch a.Type { case sim.Int, sim.Float, sim.Bool, sim.String: v = a.String() default: return sim.NullValue, fmt.Errorf(msg, showAssertMessage("%v is not a string", a.TypeName())) } return sim.NewString(v), nil }, }, { Name: "assert.bool", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if !isStringLike(args[1]) { return sim.NullValue, fmt.Errorf("expected argument 2 to be a string, got %s", args[1].TypeName()) } a := args[0] msg := args[1].String() var v sim.Value switch a.Type { case sim.Bool: v = a case sim.Int: switch a.ToInt() { case 0: v = sim.FalseValue case 1: v = sim.TrueValue default: return sim.NullValue, fmt.Errorf(msg, showAssertMessage("%v is not bool", a.TypeName())) } case sim.String: s := a.String() s = strings.Trim(s, " ") switch s { case "true", "1": v = sim.TrueValue case "false", "0": v = sim.FalseValue default: return sim.NullValue, fmt.Errorf(msg, showAssertMessage("%v is not bool", a.TypeName())) } default: return sim.NullValue, fmt.Errorf(msg, showAssertMessage("%v is not bool", a.TypeName())) } return v, nil }, }, { Name: "assert.object", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if !isStringLike(args[1]) { return sim.NullValue, fmt.Errorf("expected argument 2 to be a string, got %s", args[1].TypeName()) } a := args[0] msg := args[1].String() switch a.Type { case sim.Map: default: return sim.NullValue, fmt.Errorf(msg, showAssertMessage("%v is not an object", a.TypeName())) } return a, nil }, }, }
var Async = []sim.NativeFunction{ { Name: "go", Arguments: 1, Permissions: []string{"async"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return launchGoroutine(args, vm, nil) }, }, }
var Atomic = []sim.NativeFunction{ { Name: "atomic.addInt", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int, sim.Int); err != nil { return sim.NullValue, err } i := args[0] v := args[1] // Handle both pointer and direct int64 values var ptr *int64 switch val := i.Internal.(type) { case *int64: ptr = val case int64: newVal := val + v.ToInt() i.Internal = newVal return sim.NewInt64(newVal), nil default: return sim.NullValue, fmt.Errorf("expected an int, got %T", i.Internal) } atomic.AddInt64(ptr, v.ToInt()) return i, nil }, }, { Name: "atomic.storeInt", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int, sim.Int); err != nil { return sim.NullValue, err } i := args[0] v := args[1] // Handle both pointer and direct int64 values var ptr *int64 switch val := i.Internal.(type) { case *int64: ptr = val case int64: newVal := v.ToInt() i.Internal = newVal return sim.NewInt64(newVal), nil default: return sim.NullValue, fmt.Errorf("expected an int, got %T", i.Internal) } atomic.StoreInt64(ptr, v.ToInt()) return i, nil }, }, { Name: "atomic.loadInt", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int); err != nil { return sim.NullValue, err } i := args[0] switch val := i.Internal.(type) { case *int64: v := atomic.LoadInt64(val) return sim.NewInt64(v), nil case int64: return sim.NewInt64(val), nil default: return sim.NullValue, fmt.Errorf("expected an int, got %T", i.Internal) } }, }, }
var Base64 = []sim.NativeFunction{ { Name: "base64.encode", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] switch a.Type { case sim.Null, sim.Undefined: return sim.NullValue, nil case sim.Bytes, sim.String: encoder := base64.RawStdEncoding encoded := encoder.EncodeToString(a.ToBytes()) return sim.NewString(encoded), nil default: return sim.NullValue, fmt.Errorf("expected string, got %v", a.Type) } }, }, { Name: "base64.encodeWithPadding", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] switch a.Type { case sim.Null, sim.Undefined: return sim.NullValue, nil case sim.Bytes, sim.String: encoder := base64.StdEncoding.WithPadding(base64.StdPadding) encoded := encoder.EncodeToString(a.ToBytes()) return sim.NewString(encoded), nil default: return sim.NullValue, fmt.Errorf("expected string, got %v", a.Type) } }, }, { Name: "base64.encodeURLWithPadding", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] switch a.Type { case sim.Null, sim.Undefined: return sim.NullValue, nil case sim.Bytes, sim.String: encoder := base64.RawURLEncoding.WithPadding(base64.StdPadding) encoded := encoder.EncodeToString(a.ToBytes()) return sim.NewString(encoded), nil default: return sim.NullValue, fmt.Errorf("expected string, got %v", a.Type) } }, }, { Name: "base64.decode", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] switch a.Type { case sim.Null, sim.Undefined: return sim.NullValue, nil case sim.String: encoder := base64.RawStdEncoding decoded, err := encoder.DecodeString(a.String()) if err != nil { return sim.NullValue, err } return sim.NewBytes(decoded), nil default: return sim.NullValue, fmt.Errorf("expected string, got %v", a.Type) } }, }, { Name: "base64.decodeWithPadding", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] switch a.Type { case sim.Null, sim.Undefined: return sim.NullValue, nil case sim.String: encoder := base64.StdEncoding.WithPadding(base64.StdPadding) encoded, err := encoder.DecodeString(a.String()) if err != nil { return sim.NullValue, err } return sim.NewBytes(encoded), nil default: return sim.NullValue, fmt.Errorf("expected string, got %v", a.Type) } }, }, }
var Binary = []sim.NativeFunction{ { Name: "binary.putInt16LittleEndian", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes, sim.Int); err != nil { return sim.NullValue, err } b := args[0].ToBytes() i := args[1].ToInt() binary.LittleEndian.PutUint16(b, uint16(i)) return sim.NullValue, nil }, }, { Name: "binary.putInt32LittleEndian", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes, sim.Int); err != nil { return sim.NullValue, err } b := args[0].ToBytes() i := args[1].ToInt() binary.LittleEndian.PutUint32(b, uint32(i)) return sim.NullValue, nil }, }, { Name: "binary.putInt64LittleEndian", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes, sim.Int); err != nil { return sim.NullValue, err } b := args[0].ToBytes() i := args[1].ToInt() binary.LittleEndian.PutUint64(b, uint64(i)) return sim.NullValue, nil }, }, { Name: "binary.putInt16BigEndian", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes, sim.Int); err != nil { return sim.NullValue, err } b := args[0].ToBytes() i := args[1].ToInt() binary.BigEndian.PutUint16(b, uint16(i)) return sim.NullValue, nil }, }, { Name: "binary.putInt32BigEndian", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes, sim.Int); err != nil { return sim.NullValue, err } b := args[0].ToBytes() i := args[1].ToInt() binary.BigEndian.PutUint32(b, uint32(i)) return sim.NullValue, nil }, }, { Name: "binary.putInt64BigEndian", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes, sim.Int); err != nil { return sim.NullValue, err } b := args[0].ToBytes() i := args[1].ToInt() binary.BigEndian.PutUint64(b, uint64(i)) return sim.NullValue, nil }, }, { Name: "binary.int16LittleEndian", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes); err != nil { return sim.NullValue, err } b := args[0].ToBytes() i := binary.LittleEndian.Uint16(b) return sim.NewInt64(int64(i)), nil }, }, { Name: "binary.int32LittleEndian", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes); err != nil { return sim.NullValue, err } b := args[0].ToBytes() i := binary.LittleEndian.Uint32(b) return sim.NewInt64(int64(i)), nil }, }, { Name: "binary.int64LittleEndian", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes); err != nil { return sim.NullValue, err } b := args[0].ToBytes() i := binary.LittleEndian.Uint64(b) return sim.NewInt64(int64(i)), nil }, }, { Name: "binary.int16BigEndian", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes); err != nil { return sim.NullValue, err } b := args[0].ToBytes() i := binary.BigEndian.Uint16(b) return sim.NewInt64(int64(i)), nil }, }, { Name: "binary.int32BigEndian", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes); err != nil { return sim.NullValue, err } b := args[0].ToBytes() i := binary.BigEndian.Uint32(b) return sim.NewInt64(int64(i)), nil }, }, { Name: "binary.int64BigEndian", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes); err != nil { return sim.NullValue, err } b := args[0].ToBytes() i := binary.BigEndian.Uint64(b) return sim.NewInt64(int64(i)), nil }, }, }
var Bufio = []sim.NativeFunction{ { Name: "bufio.newScanner", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } r := args[0].ToObject() reader, ok := r.(io.Reader) if !ok { return sim.NullValue, fmt.Errorf("expected a io.Reader, got %v", args[0]) } s := bufio.NewScanner(reader) return sim.NewObject(&scanner{s}), nil }, }, { Name: "bufio.newReader", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } r := args[0].ToObject() reader, ok := r.(io.Reader) if !ok { return sim.NullValue, fmt.Errorf("expected a io.Reader, got %v", args[0]) } s := bufio.NewReader(reader) return sim.NewObject(&bufioReader{s}), nil }, }, { Name: "bufio.newWriter", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } r := args[0].ToObject() w, ok := r.(io.Writer) if !ok { return sim.NullValue, fmt.Errorf("expected a io.Writer, got %v", args[0]) } s := bufio.NewWriter(w) return sim.NewObject(&bufioWriter{s}), nil }, }, }
var Bytecode = []sim.NativeFunction{ { Name: "bytecode.compile", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String, sim.Object); err != nil { return sim.NullValue, err } path := args[0].String() var fs filesystem.FS l := len(args) if l > 1 { filesystem, ok := args[1].ToObjectOrNil().(*FileSystemObj) if !ok { return sim.NullValue, fmt.Errorf("expected a filesystem, got %v", args[1]) } fs = filesystem.FS } else { fs = vm.FileSystem } p, err := sim.Compile(fs, path) if err != nil { return sim.NullValue, fmt.Errorf("compiling %s: %w", path, err) } if err := ValidatePermissions(p, vm); err != nil { return sim.NullValue, err } return sim.NewObject(&program{prog: p}), nil }, }, { Name: "bytecode.compileStr", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } code := args[0].String() p, err := sim.CompileStr(code) if err != nil { return sim.NullValue, errors.New(err.Error()) } if err := ValidatePermissions(p, vm); err != nil { return sim.NullValue, err } return sim.NewObject(&program{prog: p}), nil }, }, { Name: "bytecode.hash", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String, sim.Bool, sim.Bool, sim.Object); err != nil { return sim.NullValue, err } path := args[0].String() var fs filesystem.FS l := len(args) if l > 1 { filesystem, ok := args[1].ToObjectOrNil().(*FileSystemObj) if !ok { return sim.NullValue, fmt.Errorf("expected a filesystem, got %v", args[1]) } fs = filesystem.FS } else { fs = vm.FileSystem } hash, err := parser.Hash(fs, path) if err != nil { return sim.NullValue, fmt.Errorf("compiling %s: %w", path, err) } s := base64.StdEncoding.EncodeToString(hash) return sim.NewString(s), nil }, }, { Name: "bytecode.parseStr", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } code := args[0].String() p, err := sim.ParseStr(code) if err != nil { return sim.NullValue, errors.New(err.Error()) } return sim.NewObject(&astProgram{prog: p}), nil }, }, { Name: "bytecode.loadProgram", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes); err != nil { return sim.NullValue, err } p, err := binary.Load(args[0].ToBytes()) if err != nil { return sim.NullValue, err } return sim.NewObject(&program{prog: p}), nil }, }, { Name: "bytecode.load", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String, sim.Object); err != nil { return sim.NullValue, err } l := len(args) path := args[0].String() var fs filesystem.FS if l > 1 { filesystem, ok := args[1].ToObjectOrNil().(*FileSystemObj) if !ok { return sim.NullValue, fmt.Errorf("expected a filesystem, got %v", args[1]) } fs = filesystem.FS } else { fs = vm.FileSystem } f, err := fs.Open(path) if err != nil { return sim.NullValue, err } defer f.Close() p, err := binary.Read(f) if err != nil { return sim.NullValue, err } p.Name = strings.TrimSuffix(filepath.Base(path), filepath.Ext(path)) return sim.NewObject(&program{prog: p}), nil }, }, { Name: "bytecode.readProgram", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } r, ok := args[0].ToObjectOrNil().(io.Reader) if !ok { return sim.NullValue, fmt.Errorf("expected parameter 1 to be io.Reader, got %T", args[0].ToObjectOrNil()) } p, err := binary.Read(r) if err != nil { return sim.NullValue, err } return sim.NewObject(&program{prog: p}), nil }, }, { Name: "bytecode.writeProgram", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object, sim.Object); err != nil { return sim.NullValue, err } w, ok := args[0].ToObjectOrNil().(io.Writer) if !ok { return sim.NullValue, fmt.Errorf("expected parameter 1 to be io.Reader, got %T", args[0].ToObjectOrNil()) } p, ok := args[1].ToObjectOrNil().(*program) if !ok { return sim.NullValue, fmt.Errorf("expected parameter 2 to be a program, got %T", args[0].ToObjectOrNil()) } if err := binary.Write(w, p.prog); err != nil { return sim.NullValue, err } return sim.NullValue, nil }, }, }
var Bytes = []sim.NativeFunction{ { Name: "bytes.newReader", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes); err != nil { return sim.NullValue, err } r := args[0].ToBytes() s := bytes.NewReader(r) reader := NewReader(s) return sim.NewObject(reader), nil }, }, { Name: "bytes.replace", Arguments: 4, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes, sim.Bytes, sim.Bytes, sim.Int); err != nil { return sim.NullValue, err } b := bytes.Replace(args[0].ToBytes(), args[1].ToBytes(), args[2].ToBytes(), int(args[3].ToInt())) return sim.NewBytes(b), nil }, }, { Name: "bytes.replaceAll", Arguments: 3, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes, sim.Bytes, sim.Bytes); err != nil { return sim.NullValue, err } b := bytes.ReplaceAll(args[0].ToBytes(), args[1].ToBytes(), args[2].ToBytes()) return sim.NewBytes(b), nil }, }, { Name: "Bytes.prototype.copyAt", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if args[0].Type != sim.Int { return sim.NullValue, fmt.Errorf("expected arg 1 to be int, got %s", args[0].TypeName()) } switch args[1].Type { case sim.Bytes, sim.Array, sim.String: default: return sim.NullValue, fmt.Errorf("expected arg 2 to be bytes, got %s", args[1].TypeName()) } a := this.ToBytes() start := int(args[0].ToInt()) b := args[1].ToBytes() lenB := len(b) if lenB+start > len(a) { return sim.NullValue, fmt.Errorf("the array has not enough capacity") } for i := 0; i < lenB; i++ { a[i+start] = b[i] } return sim.NullValue, nil }, }, { Name: "Bytes.prototype.append", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if this.Type != sim.Bytes { return sim.NullValue, fmt.Errorf("expected byte array, got %s", this.TypeName()) } a := this.ToBytes() b := args[0] if b.Type != sim.Bytes { return sim.NullValue, fmt.Errorf("expected array, got %s", b.TypeName()) } c := append(a, b.ToBytes()...) return sim.NewBytes(c), nil }, }, { Name: "Bytes.prototype.indexOf", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if this.Type != sim.Bytes { return sim.NullValue, fmt.Errorf("expected byte array, got %s", this.TypeName()) } a := this.ToBytes() v := byte(args[0].ToInt()) for i, j := range a { if j == v { return sim.NewInt(i), nil } } return sim.NewInt(-1), nil }, }, { Name: "Bytes.prototype.reverse", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if this.Type != sim.Bytes { return sim.NullValue, fmt.Errorf("expected byte array, got %s", this.TypeName()) } a := this.ToBytes() l := len(a) - 1 for i, k := 0, l/2; i <= k; i++ { a[i], a[l-i] = a[l-i], a[i] } return sim.NullValue, nil }, }, { Name: "Bytes.prototype.slice", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if this.Type != sim.Bytes { return sim.NullValue, fmt.Errorf("expected string array, got %s", this.TypeName()) } a := this.ToBytes() l := len(a) switch len(args) { case 0: a = a[0:] case 1: a = a[int(args[0].ToInt()):] case 2: start := int(args[0].ToInt()) if start < 0 || start > l { return sim.NullValue, fmt.Errorf("index out of range") } end := start + int(args[1].ToInt()) if end < 0 || end > l { return sim.NullValue, fmt.Errorf("index out of range") } a = a[start:end] default: return sim.NullValue, fmt.Errorf("expected 0, 1 or 2 params, got %d", len(args)) } return sim.NewBytes(a), nil }, }, { Name: "Bytes.prototype.range", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if this.Type != sim.Bytes { return sim.NullValue, fmt.Errorf("expected array, called on %s", this.TypeName()) } a := this.ToBytes() l := len(a) switch len(args) { case 0: a = a[0:] case 1: a = a[int(args[0].ToInt()):] case 2: start := int(args[0].ToInt()) if start < 0 || start > l { return sim.NullValue, fmt.Errorf("index out of range") } end := int(args[1].ToInt()) if end < 0 || end > l { return sim.NullValue, fmt.Errorf("index out of range") } a = a[start:end] default: return sim.NullValue, fmt.Errorf("expected 0, 1 or 2 params, got %d", len(args)) } return sim.NewBytes(a), nil }, }, }
var CSV = []sim.NativeFunction{ { Name: "csv.newReader", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } r, ok := args[0].ToObject().(io.Reader) if !ok { return sim.NullValue, ErrInvalidType } reader := csv.NewReader(r) return sim.NewObject(&csvReader{reader}), nil }, }, { Name: "csv.newWriter", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } w, ok := args[0].ToObject().(io.Writer) if !ok { return sim.NullValue, ErrInvalidType } writer := csv.NewWriter(w) return sim.NewObject(&csvWriter{writer}), nil }, }, }
var Caching = []sim.NativeFunction{ { Name: "caching.newCache", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { l := len(args) var d time.Duration switch l { case 0: d = 1 * time.Minute case 1: var a = args[0] switch a.Type { case sim.Int: dd, err := ToDuration(a) if err != nil { return sim.NullValue, err } d = dd case sim.Object: dur, ok := a.ToObject().(Duration) if !ok { return sim.NullValue, fmt.Errorf("expected duration, got %s", a.TypeName()) } d = time.Duration(dur) } default: return sim.NullValue, fmt.Errorf("expected 0 or 1 arguments, got %d", l) } return sim.NewObject(newCacheObj(d)), nil }, }, }
var Console = []sim.NativeFunction{ { Name: "console.debug", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return consoleLog(true, args, vm) }, }, { Name: "console.enableDebug", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { debugEnabled = true return sim.NullValue, nil }, }, { Name: "console.disableDebug", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { debugEnabled = false return sim.NullValue, nil }, }, { Name: "console.log", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return consoleLog(false, args, vm) }, }, { Name: "console.enableTrace", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { traceEnabled = true return sim.NullValue, nil }, }, { Name: "console.disableTrace", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { traceEnabled = false return sim.NullValue, nil }, }, }
var Convert = []sim.NativeFunction{ { Name: "parseInt", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgRange(args, 0, 1, 2); err != nil { return sim.NullValue, err } if len(args) == 0 { return sim.NewFloat(math.NaN()), nil } var a sim.Value var radix int switch len(args) { case 0: return sim.NewFloat(math.NaN()), nil case 1: a = args[0] radix = 10 case 2: a = args[0] radix = int(args[1].ToInt()) } if radix == 0 { radix = 10 } if radix < 2 || radix > 36 { return sim.NewFloat(math.NaN()), nil } var str string switch a.Type { case sim.String: str = a.String() case sim.Int, sim.Float, sim.Rune: str = a.String() default: return sim.NewFloat(math.NaN()), nil } str = strings.TrimLeft(str, " \t\n\r\v\f") if str == "" { return sim.NewFloat(math.NaN()), nil } if radix == 10 && len(str) > 2 && strings.ToLower(str[:2]) == "0x" { radix = 16 str = str[2:] } sign := 1 switch str[0] { case '-': sign = -1 str = str[1:] case '+': str = str[1:] } if str == "" { return sim.NewFloat(math.NaN()), nil } result := int64(0) parsedAnyDigit := false for _, char := range str { digit := -1 if char >= '0' && char <= '9' { digit = int(char - '0') } else if char >= 'a' && char <= 'z' { digit = int(char - 'a' + 10) } else if char >= 'A' && char <= 'Z' { digit = int(char - 'A' + 10) } if digit == -1 || digit >= radix { break } parsedAnyDigit = true result = result*int64(radix) + int64(digit) } if !parsedAnyDigit { return sim.NewFloat(math.NaN()), nil } return sim.NewInt64(int64(sign) * result), nil }, }, { Name: "parseFloat", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgRange(args, 1); err != nil { return sim.NullValue, err } a := args[0] var str string switch a.Type { case sim.String: str = a.String() case sim.Int, sim.Float, sim.Rune: str = a.String() default: return sim.NewFloat(math.NaN()), nil } str = strings.TrimLeft(str, " \t\n\r\v\f") if str == "" { return sim.NewFloat(math.NaN()), nil } if str == "Infinity" || str == "+Infinity" { return sim.NewFloat(math.Inf(1)), nil } if str == "-Infinity" { return sim.NewFloat(math.Inf(-1)), nil } if str == "NaN" { return sim.NewFloat(math.NaN()), nil } sign := 1.0 if len(str) > 0 { switch str[0] { case '-': sign = -1 str = str[1:] case '+': str = str[1:] } } if str == "" { return sim.NewFloat(math.NaN()), nil } hasDecimal := false hasExponent := false result := 0.0 decimalPlaces := 0.0 exponentPart := "" inExponent := false parsedAnyDigit := false for i, char := range str { if (char == 'e' || char == 'E') && !hasExponent && i > 0 && parsedAnyDigit { hasExponent = true inExponent = true continue } if inExponent { if char == '+' || char == '-' || (char >= '0' && char <= '9') { exponentPart += string(char) continue } else { break } } if char == '.' && !hasDecimal && !inExponent { hasDecimal = true continue } if char >= '0' && char <= '9' { parsedAnyDigit = true if hasDecimal { decimalPlaces++ result = result + float64(char-'0')/math.Pow(10, decimalPlaces) } else { result = result*10 + float64(char-'0') } } else { if i == 0 { return sim.NewFloat(math.NaN()), nil } break } } if !parsedAnyDigit { return sim.NewFloat(math.NaN()), nil } if hasExponent && exponentPart != "" { if exp, err := strconv.ParseInt(exponentPart, 10, 64); err == nil { result *= math.Pow(10, float64(exp)) } } return sim.NewFloat(sign * result), nil }, }, { Name: "convert.toByte", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] var r sim.Value switch a.Type { case sim.String: default: return sim.NullValue, fmt.Errorf("can't convert %v to byte", a.Type) } s := a.String() if len(s) != 1 { return sim.NullValue, fmt.Errorf("can't convert %v to int", a.Type) } return r, nil }, }, { Name: "convert.toRune", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] switch a.Type { case sim.String: s := a.String() if len(s) != 1 { return sim.NullValue, fmt.Errorf("can't convert %v to rune", s) } return sim.NewRune(rune(s[0])), nil case sim.Int: i := a.ToInt() if i > 255 { return sim.NullValue, fmt.Errorf("can't convert %v to rune", i) } return sim.NewRune(rune(i)), nil default: return sim.NullValue, fmt.Errorf("can't convert %v to byte", a.Type) } }, }, { Name: "convert.toInt", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] var r sim.Value switch a.Type { case sim.Int: r = a case sim.Float: r = sim.NewInt64(a.ToInt()) case sim.Rune: r = sim.NewInt64(a.ToInt()) case sim.String: s := a.String() s = strings.Trim(s, " ") if len(s) > 1 { s = strings.TrimLeft(s, "0") } i, err := strconv.ParseInt(s, 0, 64) if err != nil { return sim.NullValue, err } r = sim.NewInt64(i) case sim.Func: r = sim.NewInt64(a.ToInt()) default: return sim.NullValue, fmt.Errorf("can't convert %v to int", a.Type) } return r, nil }, }, { Name: "convert.toFloat", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] switch a.Type { case sim.Int: return sim.NewFloat(a.ToFloat()), nil case sim.Float: return a, nil case sim.String: s := a.String() s = strings.Trim(s, " ") if len(s) > 1 { s = strings.TrimLeft(s, "0") } f, err := strconv.ParseFloat(s, 64) if err != nil { return sim.NullValue, err } return sim.NewFloat(f), nil default: return sim.NullValue, fmt.Errorf("can't convert %v to int", a.Type) } }, }, { Name: "convert.toBool", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] switch a.Type { case sim.Bool: return a, nil case sim.Int: switch a.ToInt() { case 0: return sim.FalseValue, nil case 1: return sim.TrueValue, nil default: return sim.NullValue, fmt.Errorf("can't convert %v to bool", a.Type) } case sim.String: s := a.String() s = strings.Trim(s, " ") switch s { case "true", "1": return sim.TrueValue, nil case "false", "0": return sim.FalseValue, nil default: return sim.NullValue, fmt.Errorf("can't convert %v to bool", s) } case sim.Null, sim.Undefined: return sim.FalseValue, nil default: return sim.NullValue, fmt.Errorf("can't convert %v to bool", a.Type) } }, }, { Name: "convert.toString", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] return sim.NewString(a.String()), nil }, }, { Name: "convert.toBytes", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] var r sim.Value switch a.Type { case sim.String: r = sim.NewBytes(a.ToBytes()) case sim.Bytes: r = a default: return sim.NullValue, fmt.Errorf("can't convert %v to int", a.Type) } return r, nil }, }, { Name: "convert.toSafeString", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] switch a.Type { case sim.Bytes: encoder := base64.RawStdEncoding encoded := encoder.EncodeToString(a.ToBytes()) return sim.NewString(encoded), nil case sim.Null, sim.Undefined: return sim.NewString(""), nil default: return sim.NewString(a.String()), nil } }, }, }
var Crypt = []sim.NativeFunction{ { Name: "crypto.signSHA1_RSA_PCKS1", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } key := args[0].ToBytes() text := args[1].String() h := sha1.New() h.Write([]byte(text)) sum := h.Sum(nil) block, _ := pem.Decode(key) if block == nil { return sim.NullValue, fmt.Errorf("error parsing private key") } privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { return sim.NullValue, fmt.Errorf("error parsing private key: %w", err) } sig, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA1, sum) if err != nil { return sim.NullValue, fmt.Errorf("error signing: %w", err) } return sim.NewBytes(sig), nil }, }, { Name: "crypto.signSHA1", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } s := args[0].String() h := sha1.New() h.Write([]byte(s)) hash := hex.EncodeToString(h.Sum(nil)) return sim.NewString(hash), nil }, }, { Name: "crypto.checkSignSHA1", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } s := args[0].String() h := sha1.New() h.Write([]byte(s)) hash := hex.EncodeToString(h.Sum(nil)) ok := hash == args[1].String() return sim.NewBool(ok), nil }, }, { Name: "crypto.signSHA1Salted", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } s := args[0].String() + getGlobalPassword() h := sha1.New() h.Write([]byte(s)) hash := hex.EncodeToString(h.Sum(nil)) return sim.NewString(hash), nil }, }, { Name: "crypto.checkSignSHA1Salted", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } s := args[0].String() + getGlobalPassword() h := sha1.New() h.Write([]byte(s)) hash := hex.EncodeToString(h.Sum(nil)) ok := hash == args[1].String() return sim.NewBool(ok), nil }, }, { Name: "crypto.signTempSHA1", Arguments: 1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } s := args[0].String() + tempSignKey h := sha1.New() h.Write([]byte(s)) hash := hex.EncodeToString(h.Sum(nil)) return sim.NewString(hash), nil }, }, { Name: "crypto.checkTempSignSHA1", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } s := args[0].String() + tempSignKey h := sha1.New() h.Write([]byte(s)) hash := hex.EncodeToString(h.Sum(nil)) ok := hash == args[1].String() return sim.NewBool(ok), nil }, }, { Name: "crypto.setGlobalPassword", Arguments: 1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } setGlobalPassword(args[0].String()) return sim.NullValue, nil }, }, { Name: "crypto.hmacSHA256", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes, sim.Bytes); err != nil { return sim.NullValue, err } msg := args[0].ToBytes() key := args[1].ToBytes() sig := hmac.New(sha256.New, key) sig.Write(msg) hash := sig.Sum(nil) return sim.NewBytes(hash), nil }, }, { Name: "crypto.hmacSHA512", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes, sim.Bytes); err != nil { return sim.NullValue, err } msg := args[0].ToBytes() key := args[1].ToBytes() sig := hmac.New(sha512.New, key) sig.Write(msg) hash := sig.Sum(nil) return sim.NewBytes(hash), nil }, }, { Name: "crypto.hashSHA", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String); err != nil { return sim.NullValue, err } h := sha1.New() h.Write([]byte(args[0].String())) hash := hex.EncodeToString(h.Sum(nil)) return sim.NewString(hash), nil }, }, { Name: "crypto.hashSHA256", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String); err != nil { return sim.NullValue, err } h := sha256.New() h.Write([]byte(args[0].String())) hash := hex.EncodeToString(h.Sum(nil)) return sim.NewString(hash), nil }, }, { Name: "crypto.hashSHA512", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String); err != nil { return sim.NullValue, err } h := sha512.New() h.Write([]byte(args[0].String())) hash := hex.EncodeToString(h.Sum(nil)) return sim.NewString(hash), nil }, }, { Name: "crypto.encryptString", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } var pwd string switch len(args) { case 0: return sim.NullValue, fmt.Errorf("expected 1 argument, got 0") case 1: pwd = getGlobalPassword() if pwd == "" { return sim.NullValue, fmt.Errorf("no password configured") } case 2: pwd = args[1].String() } s, err := Encrypts(args[0].String(), pwd) if err != nil { return sim.NullValue, err } return sim.NewString(s), nil }, }, { Name: "crypto.decryptString", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } var pwd string switch len(args) { case 0: return sim.NullValue, fmt.Errorf("expected 1 argument, got 0") case 1: pwd = getGlobalPassword() if pwd == "" { return sim.NullValue, fmt.Errorf("no password configured") } case 2: pwd = args[1].String() } s, err := Decrypts(args[0].String(), pwd) if err != nil { return sim.NullValue, err } return sim.NewString(s), nil }, }, { Name: "crypto.encrypt", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } var pwd string switch len(args) { case 0: return sim.NullValue, fmt.Errorf("expected 1 argument, got 0") case 1: pwd = getGlobalPassword() if pwd == "" { return sim.NullValue, fmt.Errorf("no password configured") } case 2: pwd = args[1].String() } b, err := Encrypt(args[0].ToBytes(), []byte(pwd)) if err != nil { return sim.NullValue, err } return sim.NewBytes(b), nil }, }, { Name: "crypto.decrypt", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } var pwd string switch len(args) { case 0: return sim.NullValue, fmt.Errorf("expected 1 argument, got 0") case 1: pwd = getGlobalPassword() if pwd == "" { return sim.NullValue, fmt.Errorf("no password configured") } case 2: pwd = args[1].String() } b, err := Decrypt(args[0].ToBytes(), []byte(pwd)) if err != nil { return sim.NullValue, err } return sim.NewBytes(b), nil }, }, { Name: "crypto.encryptTripleDES", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes, sim.Bytes); err != nil { return sim.NullValue, err } b, err := EncryptTripleDESCBC(args[0].ToBytes(), args[1].ToBytes()) if err != nil { return sim.NullValue, err } return sim.NewBytes(b), nil }, }, { Name: "crypto.decryptTripleDES", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes, sim.Bytes); err != nil { return sim.NullValue, err } b, err := DecryptTripleDESCBC(args[0].ToBytes(), args[1].ToBytes()) if err != nil { return sim.NullValue, err } return sim.NewBytes(b), nil }, }, { Name: "crypto.hashPassword", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } s := HashPassword(args[0].String()) return sim.NewString(s), nil }, }, { Name: "crypto.compareHashAndPassword", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } ok := CheckHashPasword(args[0].String(), args[1].String()) return sim.NewBool(ok), nil }, }, { Name: "crypto.rand", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int); err != nil { return sim.NullValue, err } ln := int(args[0].ToInt()) v, err := rand.Int(rand.Reader, big.NewInt(int64(ln))) if err != nil { return sim.NullValue, err } return sim.NewInt64(v.Int64()), nil }, }, { Name: "crypto.random", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int); err != nil { return sim.NullValue, err } b := Random(int(args[0].ToInt())) return sim.NewBytes(b), nil }, }, { Name: "crypto.randomAlphanumeric", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int); err != nil { return sim.NullValue, err } ln := int(args[0].ToInt()) if ln < 1 { return sim.NullValue, fmt.Errorf("invalid len: %d", ln) } s := RandomAlphanumeric(ln) return sim.NewString(s), nil }, }, }
var Encoding = []sim.NativeFunction{ { Name: "encoding.newDecoderCP850", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { d := charmap.CodePage850.NewDecoder() return sim.NewObject(&decoder{d}), nil }, }, { Name: "encoding.newEncoderCP850", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { d := charmap.CodePage850.NewEncoder() return sim.NewObject(&encoder{d}), nil }, }, { Name: "encoding.newDecoderISO8859_1", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { d := charmap.ISO8859_1.NewDecoder() return sim.NewObject(&decoder{d}), nil }, }, { Name: "encoding.newEncoderISO8859_1", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { d := charmap.ISO8859_1.NewEncoder() return sim.NewObject(&encoder{d}), nil }, }, { Name: "encoding.newDecoderWindows1252", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { d := charmap.Windows1252.NewDecoder() return sim.NewObject(&decoder{d}), nil }, }, { Name: "encoding.newEncoderWindows1252", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { d := charmap.Windows1252.NewEncoder() return sim.NewObject(&encoder{d}), nil }, }, { Name: "encoding.newDecoderUTF16_LE", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { d := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewDecoder() return sim.NewObject(&decoder{d}), nil }, }, { Name: "encoding.newEncoderUTF16_LE", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { e := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewEncoder() return sim.NewObject(&encoder{e}), nil }, }, }
var ErrFileNotFound = errors.New("file not found")
var ErrInvalidType = errors.New("invalid value type")
var ErrNoFileSystem = errors.New("there is no filesystem")
var ErrReadOnly = errors.New("readonly property")
var ErrReadOnlyOrUndefined = errors.New("undefined or readonly property")
var ErrUndefined = errors.New("undefined")
var Errors = []sim.NativeFunction{ { Name: "errors.action", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Map); err != nil { return sim.NullValue, err } var statusError int code, ok := args[0].ToMap().Map[sim.NewString("code")] if ok { if code.Type != sim.Int { return sim.NullValue, fmt.Errorf("expected code to be int, got %s", code.TypeName()) } statusError = int(code.ToInt()) } else { statusError = http.StatusBadRequest } wrap := make(map[sim.Value]sim.Value) wrap[sim.NewString("actionError")] = args[0] obj := sim.NewMapValues(wrap, false).ExportMarshal(0) buf := &bytes.Buffer{} encoder := json.NewEncoder(buf) if err := encoder.Encode(obj); err != nil { return sim.NullValue, err } buf.Truncate(buf.Len() - 1) err := sim.NewCodeError(statusError, buf.String()) err.Kind = "ActionError" return sim.NewObject(err), nil }, }, { Name: "errors.is", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object, sim.String); err != nil { return sim.NullValue, err } e, ok := args[0].ToObjectOrNil().(*sim.VMError) if !ok { return sim.FalseValue, nil } return sim.NewBool(e.Is(args[1].String())), nil }, }, { Name: "errors.wrap", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.Object); err != nil { return sim.NullValue, err } msg := args[0].String() e, ok := args[1].ToObjectOrNil().(error) if !ok { return sim.NullValue, fmt.Errorf("expected arg 2 to be an error. Got %s", args[1].TypeName()) } err := sim.Wrap(0, msg, e) return sim.NewObject(err), nil }, }, { Name: "errors.wrapCode", Arguments: 3, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int, sim.String, sim.Object); err != nil { return sim.NullValue, err } code := args[0].ToInt() msg := args[1].String() e, ok := args[2].ToObjectOrNil().(error) if !ok { return sim.NullValue, fmt.Errorf("expected arg 2 to be an error. Got %s", args[2].TypeName()) } err := sim.Wrap(int(code), msg, e) return sim.NewObject(err), nil }, }, { Name: "errors.unwrap", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } e, ok := args[0].ToObjectOrNil().(*sim.VMError) if !ok { return sim.FalseValue, nil } e = e.Wrapped if e == nil { return sim.NullValue, nil } return sim.NewObject(e), nil }, }, { Name: "errors.rethrow", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { ln := len(args) if ln == 0 { return sim.NullValue, fmt.Errorf("expected at least one argument, got 0") } e, ok := args[0].ToObjectOrNil().(*sim.VMError) if !ok { return sim.NullValue, fmt.Errorf("expected error, got %s", args[0].String()) } if ln > 1 { a := args[1] if a.Type != sim.String { return sim.NullValue, fmt.Errorf("expected parameter 1 to be a string, got %s", a.Type) } details := a.String() if ln > 2 { values := make([]interface{}, ln-2) for i, a := range args[2:] { v := a.Export(0) if t, ok := v.(*sim.VMError); ok { v = t.ErrorMessage() } values[i] = v } details = fmt.Sprintf(details, values...) } if e.Details == "" { e.Details = details } else { e.Details += "\n" + details } } e.IsRethrow = true return sim.NullValue, e }, }, { Name: "errors.newError", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { argsLen := len(args) if argsLen < 1 { return sim.NullValue, fmt.Errorf("expected at least 1 parameter, got %d", len(args)) } m := args[0] if m.Type != sim.String { return sim.NullValue, fmt.Errorf("expected parameter 1 to be a string, got %s", m.Type) } return newCodeError(0, m.String(), args[1:], vm) }, }, { Name: "errors.newCode", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { argsLen := len(args) if argsLen < 1 { return sim.NullValue, fmt.Errorf("expected at least 1 parameter, got %d", len(args)) } code := args[0] if code.Type != sim.Int { return sim.NullValue, fmt.Errorf("expected parameter 1 to be a int, got %s", code.Type) } var msg string var fmtArgs []sim.Value if argsLen > 1 { m := args[1] if m.Type != sim.String { return sim.NullValue, fmt.Errorf("expected parameter 2 to be a string, got %s", m.Type) } msg = m.ToString() fmtArgs = args[2:] } else { msg = fmt.Sprintf("Error %d", code.ToInt()) fmtArgs = args[1:] } return codeErrorf(int(code.ToInt()), msg, fmtArgs, vm) }, }, { Name: "errors.notFound", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return newHTTPCodeError(404, args, vm) }, }, { Name: "errors.badRequest", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return newHTTPCodeError(400, args, vm) }, }, { Name: "errors.unauthorized", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return newHTTPCodeError(401, args, vm) }, }, { Name: "errors.internalError", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return newHTTPCodeError(500, args, vm) }, }, }
var FSNotify = []sim.NativeFunction{ { Name: "fsnotify.newWatcher", Arguments: 1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0] switch v.Type { case sim.Func: case sim.Object: default: return sim.NullValue, fmt.Errorf("%v is not a function", v.TypeName()) } w, err := newFileWatcher(v, vm) if err != nil { return sim.NullValue, err } return sim.NewObject(w), nil }, }, }
var FilePath = []sim.NativeFunction{ { Name: "filepath.clean", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } s := args[0].String() if s == "" { return args[0], nil } if s[0] != '/' { return sim.NullValue, fmt.Errorf("relative paths are not allowed") } v := filepath.Clean(s) return sim.NewString(v), nil }, }, { Name: "filepath.join", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var parts []string for i, v := range args { if v.IsNilOrEmpty() { continue } if v.Type != sim.String { return sim.NullValue, fmt.Errorf("argument %d is not a string (%s)", i+1, v.TypeName()) } parts = append(parts, v.String()) } path := filepath.Join(parts...) return sim.NewString(path), nil }, }, { Name: "filepath.joinAbs", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var parts []string for i, v := range args { if v.IsNilOrEmpty() { continue } if v.Type != sim.String { return sim.NullValue, fmt.Errorf("argument %d is not a string (%s)", i, v.TypeName()) } s := v.String() if strings.HasPrefix(s, "/") { parts = nil } parts = append(parts, s) } path := filepath.Join(parts...) return sim.NewString(path), nil }, }, { Name: "filepath.abs", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } path, err := fs.Abs(args[0].String()) if err != nil { return sim.NullValue, fmt.Errorf("abs %s: %w", args[0].String(), err) } return sim.NewString(path), nil }, }, { Name: "filepath.ext", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } path := args[0].String() ext := filepath.Ext(path) return sim.NewString(ext), nil }, }, { Name: "filepath.base", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } path := args[0].String() name := filepath.Base(path) return sim.NewString(name), nil }, }, { Name: "filepath.baseWithoutExt", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } path := args[0].String() name := filepath.Base(path) if i := strings.LastIndexByte(name, '.'); i != -1 { name = name[:i] } return sim.NewString(name), nil }, }, { Name: "filepath.replaceExt", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } path := args[0].String() i := strings.LastIndexByte(path, '.') if i != -1 { path = path[:i] + args[1].String() } else { path += args[1].String() } return sim.NewString(path), nil }, }, { Name: "filepath.dir", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } path := args[0].String() name := filepath.Dir(path) return sim.NewString(name), nil }, }, }
var FileUtil = []sim.NativeFunction{ { Name: "fileutil.isDirEmpty", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String, sim.Object); err != nil { return sim.NullValue, err } if err := ValidateArgRange(args, 1, 2); err != nil { return sim.NullValue, err } fs, ok := args[1].ToObject().(*FileSystemObj) if !ok { return sim.NullValue, fmt.Errorf("invalid filesystem argument, got %v", args[1]) } name := args[0].String() f, err := fs.FS.Open(name) if err != nil { return sim.NullValue, err } defer f.Close() _, err = f.Readdir(1) if err != nil { if err == io.EOF { return sim.NewBool(true), nil } return sim.NullValue, err } return sim.NewBool(false), nil }, }, { Name: "fileutil.copyFile", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String, sim.String, sim.Object); err != nil { return sim.NullValue, err } if err := ValidateArgRange(args, 2, 3); err != nil { return sim.NullValue, err } src := args[0].String() dst := args[1].String() var fs filesystem.FS if len(args) == 3 { ofs, ok := args[2].ToObjectOrNil().(*FileSystemObj) if !ok { return sim.NullValue, fmt.Errorf("invalid filesystem argument, got %v", args[2]) } fs = ofs.FS } if fs == nil { fs = vm.FileSystem if fs == nil { return sim.NullValue, fmt.Errorf("no filesystem") } } r, err := fs.Open(src) if err != nil { return sim.NullValue, err } defer r.Close() w, err := fs.OpenForWrite(dst) if err != nil { return sim.NullValue, err } defer w.Close() if _, err := io.Copy(w, r); err != nil { return sim.NullValue, err } return sim.NullValue, nil }, }, }
var GZIP = []sim.NativeFunction{ { Name: "gzip.newWriter", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { w, ok := args[0].ToObjectOrNil().(io.Writer) if !ok { return sim.NullValue, fmt.Errorf("exepected a Writer, got %s", args[0].TypeName()) } g := gzip.NewWriter(w) v := &gzipWriter{g} return sim.NewObject(v), nil }, }, { Name: "gzip.newReader", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { r, ok := args[0].ToObjectOrNil().(io.Reader) if !ok { return sim.NullValue, fmt.Errorf("exepected a reader, got %s", args[0].TypeName()) } gr, err := gzip.NewReader(r) if err != nil { return sim.NullValue, err } v := &gzipReader{gr} return sim.NewObject(v), nil }, }, }
var HASH = []sim.NativeFunction{ { Name: "hash.newMD5", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { hash := md5.New() return sim.NewObject(hasher{hash}), nil }, }, { Name: "hash.newSHA256", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { hash := sha256.New() return sim.NewObject(hasher{hash}), nil }, }, }
var HEX = []sim.NativeFunction{ { Name: "hex.encodeToString", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes); err != nil { return sim.NullValue, err } b := args[0].ToBytes() s := hex.EncodeToString(b) return sim.NewString(s), nil }, }, }
var HTML = []sim.NativeFunction{ { Name: "html.encode", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] switch a.Type { case sim.Null, sim.Undefined: return sim.NullValue, nil case sim.Bytes: encoder := base64.RawStdEncoding encoded := encoder.EncodeToString(a.ToBytes()) return sim.NewString(encoded), nil case sim.String: return sim.NewString(html.EscapeString(a.String())), nil default: return sim.NewString(a.String()), nil } }, }, { Name: "html.decode", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] switch a.Type { case sim.Null, sim.Undefined: return sim.NullValue, nil case sim.String: return sim.NewString(html.UnescapeString(a.String())), nil default: return sim.NullValue, fmt.Errorf("expected string, got %v", a.Type) } }, }, }
var HTTP = []sim.NativeFunction{ { Name: "->http.OK", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(200), nil }, }, { Name: "->http.REDIRECT", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(302), nil }, }, { Name: "->http.PERMANENT_REDIRECT", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(301), nil }, }, { Name: "->http.REDIRECT", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(302), nil }, }, { Name: "->http.BAD_REQUEST", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(400), nil }, }, { Name: "->http.UNAUTHORIZED", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(401), nil }, }, { Name: "->http.NOT_FOUND", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(404), nil }, }, { Name: "->http.TIMEOUT", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(408), nil }, }, { Name: "->http.INTERNAL_ERROR", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(500), nil }, }, { Name: "->http.UNAVAILABLE", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(503), nil }, }, { Name: "->http.FORM_ERROR", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(http.StatusBadRequest), nil }, }, { Name: "->http.SameSiteDefaultMode", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(http.SameSiteDefaultMode)), nil }, }, { Name: "->http.SameSiteDefaultMode", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(http.SameSiteDefaultMode)), nil }, }, { Name: "->http.SameSiteLaxMode", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(http.SameSiteLaxMode)), nil }, }, { Name: "->http.SameSiteStrictMode", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(http.SameSiteStrictMode)), nil }, }, { Name: "->http.SameSiteNoneMode", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(http.SameSiteNoneMode)), nil }, }, { Name: "http.cacheBreaker", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { cacheMut.RLock() v := sim.NewString(cacheBreaker) cacheMut.RUnlock() return v, nil }, }, { Name: "http.resetCacheBreaker", Arguments: 0, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { cacheMut.Lock() cacheBreaker = RandString(9) lastModifiedDate = time.Now() cacheMut.Unlock() return sim.NullValue, nil }, }, { Name: "http.newServer", Arguments: 0, Permissions: []string{"netListen"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { s := &server{ vm: vm, handler: -1, readTimeout: 10 * time.Second, writeTimeout: 10 * time.Second, readHeaderTimeout: 10 * time.Second, idleTimeout: 100 * time.Second, } return sim.NewObject(s), nil }, }, { Name: "http.newResponseRecorder", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } r, ok := args[0].ToObjectOrNil().(*request) if !ok { return sim.NullValue, fmt.Errorf("expected a request, got %v", args[0].TypeName()) } w := &responseWriter{ writer: httptest.NewRecorder(), request: r.request, } return sim.NewObject(w), nil }, }, { Name: "http.newCookie", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { c := &cookie{} return sim.NewObject(c), nil }, }, { Name: "http.encodeURIComponent", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } v := args[0].String() u := url.QueryEscape(v) return sim.NewString(u), nil }, }, { Name: "http.decodeURIComponent", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } v := args[0].String() u, err := url.QueryUnescape(v) if err != nil { return sim.NullValue, err } return sim.NewString(u), nil }, }, { Name: "http.newClient", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { c := &client{client: &http.Client{}} return sim.NewObject(c), nil }, }, { Name: "http.newRequest", Arguments: -1, Permissions: []string{"networking"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgRange(args, 2, 3); err != nil { return sim.NullValue, err } if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected argument 1 to be string, got %v", args[0].Type) } if !isStringLike(args[1]) { return sim.NullValue, fmt.Errorf("expected argument 2 to be string, got %v", args[1].Type) } var method string var urlStr string var queryMap map[sim.Value]sim.Value var reader io.Reader var contentType string switch len(args) { case 2: method = args[0].String() urlStr = args[1].String() case 3: method = args[0].String() urlStr = args[1].String() form := url.Values{} v := args[2] switch v.Type { case sim.Null, sim.Undefined: case sim.String: switch method { case "POST", "PUT", "PATCH": default: return sim.NullValue, fmt.Errorf("can only pass a data string with POST, PUT or PATCH") } reader = strings.NewReader(v.String()) contentType = "application/json; charset=UTF-8" case sim.Map: m := v.ToMap() if method == "GET" { queryMap = m.Map } else { m.RLock() for k, v := range m.Map { if v.IsNilOrEmpty() { continue } vs, err := serialize(v) if err != nil { return sim.NullValue, fmt.Errorf("error serializing parameter: %v", v.Type) } form.Add(k.String(), vs) } m.RUnlock() reader = strings.NewReader(form.Encode()) contentType = "application/x-www-form-urlencoded" } case sim.Object: r, ok := v.ToObject().(io.Reader) if !ok { return sim.NullValue, fmt.Errorf("invalid argument 3 type: got %v", v.TypeName()) } reader = r default: return sim.NullValue, fmt.Errorf("expected argument 3 to be object, got %v", v.Type) } } r, err := http.NewRequest(method, urlStr, reader) if err != nil { return sim.NullValue, err } switch method { case "GET": if queryMap != nil { q := r.URL.Query() for k, v := range queryMap { if v.IsNilOrEmpty() { continue } vs, err := serialize(v) if err != nil { return sim.NullValue, fmt.Errorf("error serializing parameter: %v", v.Type) } q.Add(k.String(), vs) } r.URL.RawQuery = q.Encode() } } return sim.NewObject(&request{request: r, defaultContentType: contentType}), nil }, }, { Name: "http.get", Arguments: -1, Permissions: []string{"networking"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { client := &http.Client{} timeout := 20 * time.Second ln := len(args) if ln == 0 { return sim.NullValue, fmt.Errorf("expected 1 to 3 arguments, got %d", len(args)) } a := args[0] if a.Type != sim.String { return sim.NullValue, fmt.Errorf("expected argument 0 to be string, got %s", a.TypeName()) } url := a.String() if ln == 0 { } else if ln > 1 { a := args[1] switch a.Type { case sim.Undefined, sim.Null: case sim.Int, sim.Object: var err error timeout, err = ToDuration(args[1]) if err != nil { return sim.NullValue, err } default: return sim.NullValue, fmt.Errorf("expected argument 1 to be duration") } } if ln > 2 { b := args[2] switch b.Type { case sim.Null, sim.Undefined: case sim.Object: t, ok := args[2].ToObjectOrNil().(*tlsConfig) if !ok { return sim.NullValue, fmt.Errorf("expected argument 2 to be tls.Config") } client.Transport = getTransport(t.conf) default: return sim.NullValue, fmt.Errorf("expected argument 2 to be string, got %s", b.TypeName()) } } client.Timeout = timeout resp, err := client.Get(url) if err != nil { return sim.NullValue, err } b, err := io.ReadAll(resp.Body) err2 := resp.Body.Close() if err != nil { return sim.NullValue, err } if err2 != nil { return sim.NullValue, err2 } if !isHTTPSuccess(resp.StatusCode) { return sim.NullValue, fmt.Errorf("http Error %d: %v", resp.StatusCode, string(b)) } return sim.NewString(string(b)), nil }, }, { Name: "http.post", Arguments: -1, Permissions: []string{"networking"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgRange(args, 1, 2, 3, 4); err != nil { return sim.NullValue, err } if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected argument 0 to be string, got %s", args[0].TypeName()) } u := args[0].String() data := url.Values{} ln := len(args) if ln > 1 { a := args[1] switch a.Type { case sim.Undefined, sim.Null: case sim.Map: m := args[1].ToMap() m.RLock() for k, v := range m.Map { data.Add(k.String(), v.String()) } m.RUnlock() default: return sim.NullValue, fmt.Errorf("expected argument 1 to be an object, got %s", args[1].TypeName()) } } client := &http.Client{} timeout := 20 * time.Second if ln > 2 { a := args[2] switch a.Type { case sim.Undefined, sim.Null: case sim.Int, sim.Object: var err error timeout, err = ToDuration(args[2]) if err != nil { return sim.NullValue, err } default: return sim.NullValue, fmt.Errorf("expected argument 1 to be duration") } } if ln > 3 { b := args[3] switch b.Type { case sim.Null, sim.Undefined: case sim.Object: t, ok := args[3].ToObjectOrNil().(*tlsConfig) if !ok { return sim.NullValue, fmt.Errorf("expected argument 2 to be tls.Config") } client.Transport = getTransport(t.conf) default: return sim.NullValue, fmt.Errorf("expected argument 2 to be string, got %s", b.TypeName()) } } client.Timeout = timeout resp, err := client.PostForm(u, data) if err != nil { return sim.NullValue, err } b, err := io.ReadAll(resp.Body) resp.Body.Close() if err != nil { return sim.NullValue, err } return sim.NewString(string(b)), nil }, }, { Name: "http.sendFile", Arguments: 6, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String, sim.String, sim.String, sim.String, sim.Bytes); err != nil { return sim.NullValue, err } url := args[0].String() user := args[1].String() password := args[2].String() param := args[3].String() name := args[4].String() data := args[5].ToBytes() body := &bytes.Buffer{} w := multipart.NewWriter(body) part, err := w.CreateFormFile(param, filepath.Base(name)) if err != nil { return sim.NullValue, err } if _, err := part.Write(data); err != nil { return sim.NullValue, err } w.Close() r, err := http.NewRequest("POST", url, body) if err != nil { return sim.NullValue, err } r.SetBasicAuth(user, password) r.Header.Add("Content-Type", w.FormDataContentType()) client := &http.Client{} res, err := client.Do(r) if err != nil { return sim.NullValue, err } defer res.Body.Close() resBuf, err := io.ReadAll(res.Body) if err != nil { return sim.NullValue, err } return sim.NewBytes(resBuf), nil }, }, { Name: "http.getJSON", Arguments: 1, Permissions: []string{"networking"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } url := args[0].String() resp, err := http.Get(url) if err != nil { return sim.NullValue, err } b, err := io.ReadAll(resp.Body) resp.Body.Close() if err != nil { return sim.NullValue, err } v, err := unmarshal(b) if err != nil { return sim.NullValue, err } return v, nil }, }, { Name: "http.parseURL", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String); err != nil { return sim.NullValue, err } if len(args) == 0 { u := &url.URL{} return sim.NewObject(&URL{url: u}), nil } rawURL := args[0].String() u, err := url.Parse(rawURL) if err != nil { return sim.NullValue, err } return sim.NewObject(&URL{u}), nil }, }, { Name: "http.escapeQuery", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String); err != nil { return sim.NullValue, err } str := url.QueryEscape(args[0].String()) return sim.NewString(str), nil }, }, { Name: "http.unescapeQuery", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String); err != nil { return sim.NullValue, err } str, err := url.QueryUnescape(args[0].String()) if err != nil { return sim.NullValue, err } return sim.NewString(str), nil }, }, }
var HTTPUTIL = []sim.NativeFunction{ { Name: "httputil.newSingleHostReverseProxy", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] u, ok := a.ToObjectOrNil().(*URL) if !ok { return sim.NullValue, fmt.Errorf("invalid argument 1: expected http.URL, got %v", a.TypeName()) } p := &reverseProxy{ proxy: httputil.NewSingleHostReverseProxy(u.url), } return sim.NewObject(p), nil }, }, }
var I18N = []sim.NativeFunction{ { Name: "T", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] switch a.Type { case sim.Null, sim.Undefined: return sim.NewString(""), nil case sim.Int, sim.Float, sim.Bool: return sim.NewString(a.ToString()), nil case sim.String: default: return sim.NullValue, fmt.Errorf("expected string as fist argument, got %s", a.TypeName()) } text := a.ToString() if text == "" { return a, nil } lang := vm.Language value := text if vm.Translations != nil { value = vm.Translations.Translate(lang, text) } else { cleanText := text if strings.HasPrefix(text, "::") { cleanText = text[2:] } value = cleanText if i := strings.Index(value, "::"); i != -1 { value = value[i+2:] } } if len(args) > 1 { params := make([]interface{}, len(args)-1) for i, v := range args[1:] { params[i] = v.Export(0) } value = fmt.Sprintf(value, params...) } return sim.NewString(value), nil }, }, { Name: "i18n.createStore", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { store := sim.NewTranslationStore() wrapper := &translationStoreWrapper{store} return sim.NewObject(wrapper), nil }, }, { Name: "i18n.setCurrentStore", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if args[0].Type == sim.Null || args[0].Type == sim.Undefined { vm.Translations = nil return sim.NullValue, nil } if args[0].Type == sim.Object { if wrapper, ok := args[0].ToObjectOrNil().(*translationStoreWrapper); ok { vm.Translations = wrapper.store return sim.NullValue, nil } } return sim.NullValue, fmt.Errorf("expected TranslationStore or null, got %s", args[0].TypeName()) }, }, { Name: "i18n.getCurrentStore", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if vm.Translations == nil { return sim.NullValue, nil } wrapper := &translationStoreWrapper{vm.Translations} return sim.NewObject(wrapper), nil }, }, { Name: "i18n.set", Arguments: 3, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if vm.Translations == nil { vm.Translations = sim.NewTranslationStore() } wrapper := &translationStoreWrapper{vm.Translations} return wrapper.set(args, vm) }, }, { Name: "i18n.setBatch", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if vm.Translations == nil { vm.Translations = sim.NewTranslationStore() } wrapper := &translationStoreWrapper{vm.Translations} return wrapper.setBatch(args, vm) }, }, { Name: "i18n.get", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if vm.Translations == nil { return sim.NewString(""), nil } wrapper := &translationStoreWrapper{vm.Translations} return wrapper.get(args, vm) }, }, { Name: "i18n.clear", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if vm.Translations == nil { return sim.NullValue, nil } wrapper := &translationStoreWrapper{vm.Translations} return wrapper.clear(args, vm) }, }, { Name: "i18n.languages", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if vm.Translations == nil { return sim.NewArrayValues([]sim.Value{}), nil } wrapper := &translationStoreWrapper{vm.Translations} return wrapper.languages(args, vm) }, }, { Name: "i18n.hasLanguage", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if vm.Translations == nil { return sim.FalseValue, nil } wrapper := &translationStoreWrapper{vm.Translations} return wrapper.hasLanguage(args, vm) }, }, { Name: "i18n.getLanguageData", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if vm.Translations == nil { return sim.NullValue, nil } wrapper := &translationStoreWrapper{vm.Translations} return wrapper.getLanguageData(args, vm) }, }, }
var IO = []sim.NativeFunction{ { Name: "io.readAll", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } r := args[0].ToObject() reader, ok := r.(io.Reader) if !ok { return sim.NullValue, fmt.Errorf("expected a io.Reader, got %v", args[0]) } b, err := ReadAll(reader, vm) if err != nil { return sim.NullValue, err } return sim.NewBytes(b), nil }, }, { Name: "io.newBuffer", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewObject(NewBuffer()), nil }, }, { Name: "io.copy", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object, sim.Object); err != nil { return sim.NullValue, err } dst, ok := args[0].ToObject().(io.Writer) if !ok { return sim.NullValue, ErrInvalidType } src, ok := args[1].ToObject().(io.Reader) if !ok { return sim.NullValue, ErrInvalidType } i, err := io.Copy(dst, src) if err != nil { return sim.NullValue, err } return sim.NewInt64(i), nil }, }, { Name: "io.newRootedFS", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.Object); err != nil { return sim.NullValue, err } fs, ok := args[1].ToObject().(*FileSystemObj) if !ok { return sim.NullValue, fmt.Errorf("invalid filesystem argument, got %v", args[1]) } root := args[0].String() rFS, err := filesystem.NewRootedFS(root, fs.FS) if err != nil { return sim.NullValue, err } return sim.NewObject(NewFileSystem(rFS)), nil }, }, { Name: "io.newRestrictedFS", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Object); err != nil { return sim.NullValue, err } fs, ok := args[0].ToObject().(*FileSystemObj) if !ok { return sim.NullValue, fmt.Errorf("invalid filesystem argument, got %v", args[1]) } rFS, err := filesystem.NewRestrictedFS(fs.FS) if err != nil { return sim.NullValue, err } return sim.NewObject(NewFileSystem(rFS)), nil }, }, { Name: "io.newVirtualFS", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args); err != nil { return sim.NullValue, err } fs := filesystem.NewVirtualFS() return sim.NewObject(NewFileSystem(fs)), nil }, }, { Name: "io.newReadOnlyFS", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Object); err != nil { return sim.NullValue, err } fs, ok := args[0].ToObject().(*FileSystemObj) if !ok { return sim.NullValue, fmt.Errorf("invalid filesystem argument, got %v", args[1]) } rfs := filesystem.NewReadOnlyFS(fs.FS) return sim.NewObject(NewFileSystem(rfs)), nil }, }, }
var Image = []sim.NativeFunction{ { Name: "image.config", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgRange(args, 1); err != nil { return sim.NullValue, err } a := args[0] var r io.Reader switch a.Type { case sim.Object: var ok bool r, ok = a.ToObject().(io.Reader) if !ok { return sim.NullValue, ErrInvalidType } case sim.Bytes: r = bytes.NewBuffer(a.ToBytes()) } conf, format, err := image.DecodeConfig(r) if err != nil { return sim.NullValue, err } obj := imageConfig{ config: conf, format: format, } return sim.NewObject(obj), nil }, }, { Name: "image.decode", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgRange(args, 1); err != nil { return sim.NullValue, err } a := args[0] var r io.Reader switch a.Type { case sim.Object: var ok bool r, ok = a.ToObject().(io.Reader) if !ok { return sim.NullValue, ErrInvalidType } case sim.Bytes: r = bytes.NewBuffer(a.ToBytes()) } img, format, err := image.Decode(r) if err != nil { return sim.NullValue, err } obj := imageObj{ img: img, format: format, } return sim.NewObject(obj), nil }, }, }
var JSON = []sim.NativeFunction{ { Name: "json.marshal", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { ln := len(args) if ln == 0 || ln > 3 { return sim.NullValue, fmt.Errorf("expected 1, 2 or 3 arguments, got %d", len(args)) } var indent bool var escapeHTML bool if ln > 1 { v := args[1] if v.Type != sim.Bool { return sim.NullValue, fmt.Errorf("expected arg 2 to be boolean, got %s", v.TypeName()) } indent = v.ToBool() } if ln > 2 { v := args[2] if v.Type != sim.Bool { return sim.NullValue, fmt.Errorf("expected arg 3 to be boolean, got %s", v.TypeName()) } escapeHTML = v.ToBool() } obj := args[0].ExportMarshal(0) buf := &bytes.Buffer{} encoder := json.NewEncoder(buf) if indent { encoder.SetIndent("", " ") } encoder.SetEscapeHTML(escapeHTML) if err := encoder.Encode(obj); err != nil { return sim.NullValue, err } buf.Truncate(buf.Len() - 1) return sim.NewString(buf.String()), nil }, }, { Name: "json.unmarshal", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) != 1 { return sim.NullValue, fmt.Errorf("expected 1 argument, got %d", len(args)) } a := args[0] switch a.Type { case sim.String, sim.Bytes: default: return sim.NullValue, fmt.Errorf("expected argument to be string or byte[], got %v", args[0].Type) } if a.String() == "" { return sim.NullValue, nil } v, err := unmarshal(a.ToBytes()) if err != nil { return sim.NullValue, err } return v, nil }, }, }
var JSRegex = []sim.NativeFunction{ { Name: "jsregex.match", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } result := jsregex.Match(args[0].String(), args[1].String()) if result == nil { return sim.NullValue, nil } values := make([]sim.Value, len(result)) for i, s := range result { values[i] = sim.NewString(s) } return sim.NewArrayValues(values), nil }, }, { Name: "jsregex.matchAll", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } result := jsregex.MatchAll(args[0].String(), args[1].String()) if result == nil { return sim.NullValue, nil } values := make([]sim.Value, len(result)) for i, match := range result { matchValues := make([]sim.Value, len(match)) for j, s := range match { matchValues[j] = sim.NewString(s) } values[i] = sim.NewArrayValues(matchValues) } return sim.NewArrayValues(values), nil }, }, { Name: "jsregex.replace", Arguments: 3, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String, sim.String); err != nil { return sim.NullValue, err } result := jsregex.Replace(args[0].String(), args[1].String(), args[2].String()) return sim.NewString(result), nil }, }, { Name: "jsregex.replaceAll", Arguments: 3, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String, sim.String); err != nil { return sim.NullValue, err } result := jsregex.ReplaceAll(args[0].String(), args[1].String(), args[2].String()) return sim.NewString(result), nil }, }, { Name: "jsregex.search", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } result := jsregex.Search(args[0].String(), args[1].String()) return sim.NewInt(result), nil }, }, { Name: "jsregex.split", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgRange(args, 2, 3); err != nil { return sim.NullValue, err } if err := ValidateOptionalArgs(args, sim.String, sim.String, sim.Int); err != nil { return sim.NullValue, err } var result []string if len(args) == 3 { limit := int(args[2].ToInt()) result = jsregex.Split(args[0].String(), args[1].String(), limit) } else { result = jsregex.Split(args[0].String(), args[1].String()) } values := make([]sim.Value, len(result)) for i, s := range result { values[i] = sim.NewString(s) } return sim.NewArrayValues(values), nil }, }, { Name: "jsregex.newRegExp", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } re, err := jsregex.NewJSRegExp(args[0].String()) if err != nil { return sim.NullValue, err } wrapper := &jsRegExpWrapper{re: re} return sim.NewObject(wrapper), nil }, }, { Name: "jsregex.newJSString", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } wrapper := &jsStringWrapper{text: jsregex.JSString(args[0].String())} return sim.NewObject(wrapper), nil }, }, }
var JWT = []sim.NativeFunction{ { Name: "jwt.verify", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.Object); err != nil { return sim.NullValue, err } tokenString := args[0].String() publicKey, ok := args[1].ToObjectOrNil().(*rsaPublicKey) if !ok { return sim.NullValue, errors.New("invalid public key") } token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return publicKey.key, nil }) if err != nil { return sim.NullValue, err } return sim.NewBool(token.Valid), nil }, }, { Name: "jwt.newWithClaims", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.Map); err != nil { return sim.NullValue, err } var signMethod jwt.SigningMethod switch args[0].String() { case "HS256": signMethod = jwt.SigningMethodHS256 case "RS256": signMethod = jwt.SigningMethodRS256 default: return sim.NullValue, fmt.Errorf("invalid signing method, got %s", args[0].String()) } m := args[1].ToMap().Map claims := jwt.MapClaims{} for k, v := range m { claims[k.String()] = v.Export(0) } token := jwt.NewWithClaims(signMethod, claims) return sim.NewObject(&jwtToken{token: token}), nil }, }, }
var Locale = []sim.NativeFunction{ { Name: "->locale.currentLocalizer", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { loc := vm.Localizer if loc == nil { loc = defaultLocalizer } c := sim.NewObject(loc) return c, nil }, }, { Name: "->locale.currentLanguage", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { s := sim.NewString(vm.Language) return s, nil }, }, { Name: "->locale.defaultLocalizer", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { c := sim.NewObject(defaultLocalizer) return c, nil }, }, { Name: "locale.setDefaultLocalizer", Arguments: 1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { loc, ok := args[0].ToObjectOrNil().(*localizer) if !ok { return sim.NullValue, ErrInvalidType } defaultLocalizer = loc return sim.NullValue, nil }, }, { Name: "locale.setCurrentLocalizer", Arguments: 1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { loc, ok := args[0].ToObjectOrNil().(*localizer) if !ok { return sim.NullValue, ErrInvalidType } vm.Localizer = loc return sim.NullValue, nil }, }, { Name: "locale.setCurrentLanguage", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } vm.Language = args[0].String() return sim.NullValue, nil }, }, { Name: "locale.newCulture", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } name := args[0].String() c := sim.NewObject(&culture{culture: locale.NewCulture(name)}) return c, nil }, }, { Name: "locale.newLocalizer", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { lt := sim.NewObject(&localizer{}) return lt, nil }, }, { Name: "locale.parseNumber", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] switch a.Type { case sim.Int, sim.Float: return a, nil case sim.String: default: return sim.NullValue, fmt.Errorf("expected string, got %d", a.Type) } loc := vm.Localizer if loc == nil { loc = defaultLocalizer } v, err := loc.ParseNumber(a.String()) if err != nil { return sim.NullValue, err } if v == float64(int64(v)) { return sim.NewInt(int(v)), nil } return sim.NewFloat(v), nil }, }, { Name: "locale.parseDate", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgRange(args, 1, 2); err != nil { return sim.NullValue, err } switch args[0].Type { case sim.String: break case sim.Int: return sim.NewObject(TimeObj(time.Unix(args[0].ToInt(), 0))), nil } value := args[0].String() var format string if len(args) == 2 { switch args[1].Type { case sim.Null, sim.Undefined: format = "" case sim.String: format = args[1].String() default: return sim.NullValue, ErrInvalidType } } else { if IsNumeric(value) { i, err := strconv.ParseInt(value, 10, 64) if err != nil { panic(err) } return sim.NewObject(TimeObj(time.Unix(i, 0))), nil } format = "" } loc := vm.Localizer if loc == nil { loc = defaultLocalizer } v, err := loc.ParseDate(value, format, vm.Location) if err != nil { return sim.NullValue, err } return sim.NewObject(TimeObj(v)), nil }, }, { Name: "locale.format", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) != 2 { return sim.NullValue, fmt.Errorf("expected 2 arguments, got %d", len(args)) } a := args[0] if a.Type != sim.String { return sim.NullValue, fmt.Errorf("expected argument 1 to be a string, got %v", a.TypeName()) } loc := vm.Localizer if loc == nil { loc = defaultLocalizer } b := args[1].Export(0) s := loc.Format(vm.Language, a.String(), b, vm.Translations) return sim.NewString(s), nil }, }, }
var LockManager = []sim.NativeFunction{ { Name: "lockManager.lock", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) < 1 || len(args) > 2 { return sim.NullValue, fmt.Errorf("expected 1 or 2 arguments, got %d", len(args)) } if err := ValidateOptionalArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } key := args[0].String() contextId := "" if len(args) > 1 { contextId = args[1].String() } lock := lockStore.getLock(key) lock.Lock(contextId) return sim.NullValue, nil }, }, { Name: "lockManager.unlock", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) < 1 || len(args) > 2 { return sim.NullValue, fmt.Errorf("expected 1 or 2 arguments, got %d", len(args)) } if err := ValidateOptionalArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } key := args[0].String() contextId := "" if len(args) > 1 { contextId = args[1].String() } lock := lockStore.getLock(key) if err := lock.Unlock(contextId); err != nil { return sim.NullValue, err } return sim.NullValue, nil }, }, { Name: "lockManager.rLock", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) < 1 || len(args) > 2 { return sim.NullValue, fmt.Errorf("expected 1 or 2 arguments, got %d", len(args)) } if err := ValidateOptionalArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } key := args[0].String() contextId := "" if len(args) > 1 { contextId = args[1].String() } lock := lockStore.getLock(key) lock.RLock(contextId) return sim.NullValue, nil }, }, { Name: "lockManager.rUnlock", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) < 1 || len(args) > 2 { return sim.NullValue, fmt.Errorf("expected 1 or 2 arguments, got %d", len(args)) } if err := ValidateOptionalArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } key := args[0].String() contextId := "" if len(args) > 1 { contextId = args[1].String() } lock := lockStore.getLock(key) if err := lock.RUnlock(contextId); err != nil { return sim.NullValue, err } return sim.NullValue, nil }, }, { Name: "lockManager.exec", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args[:1], sim.String); err != nil { return sim.NullValue, err } key := args[0].String() fn := args[1] lock := lockStore.getLock(key) lock.Lock("") defer func() { if err := lock.Unlock(""); err != nil { fmt.Printf("Error unlocking in exec: %v\n", err) } }() switch fn.Type { case sim.Func: return vm.RunFuncIndex(int(fn.ToFunction())) case sim.Object: closure, ok := fn.ToObject().(*sim.Closure) if !ok { return sim.NullValue, fmt.Errorf("expected function or closure, got %v", fn.TypeName()) } return vm.RunClosure(closure) default: return sim.NullValue, fmt.Errorf("expected argument 2 to be function or closure, got %s", fn.TypeName()) } }, }, { Name: "lockManager.execReentrant", Arguments: 3, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args[:2], sim.String, sim.String); err != nil { return sim.NullValue, err } key := args[0].String() contextId := args[1].String() fn := args[2] lock := lockStore.getLock(key) lock.Lock(contextId) defer func() { if err := lock.Unlock(contextId); err != nil { fmt.Printf("Error unlocking in execReentrant: %v\n", err) } }() switch fn.Type { case sim.Func: return vm.RunFuncIndex(int(fn.ToFunction())) case sim.Object: closure, ok := fn.ToObject().(*sim.Closure) if !ok { return sim.NullValue, fmt.Errorf("expected function or closure, got %v", fn.TypeName()) } return vm.RunClosure(closure) default: return sim.NullValue, fmt.Errorf("expected argument 3 to be function or closure, got %s", fn.TypeName()) } }, }, { Name: "lockManager.freeze", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args); err != nil { return sim.NullValue, err } // Create a mutex and lock it twice, which will cause a permanent deadlock var mu sync.Mutex mu.Lock() mu.Lock() return sim.NullValue, nil }, }, }
var Markdown = []sim.NativeFunction{ { Name: "markdown.toHTML", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } text := args[0].ToString() html := parseBasicMarkdown(text) return sim.NewString(html), nil }, }, { Name: "markdown.toHTMLFull", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } text := args[0].ToString() htmlFlags := 0 htmlFlags |= blackfriday.HTML_USE_XHTML htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS htmlFlags |= blackfriday.HTML_SMARTYPANTS_FRACTIONS htmlFlags |= blackfriday.HTML_SMARTYPANTS_LATEX_DASHES extensions := 0 extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS extensions |= blackfriday.EXTENSION_TABLES extensions |= blackfriday.EXTENSION_FENCED_CODE extensions |= blackfriday.EXTENSION_AUTOLINK extensions |= blackfriday.EXTENSION_STRIKETHROUGH extensions |= blackfriday.EXTENSION_SPACE_HEADERS extensions |= blackfriday.EXTENSION_HEADER_IDS extensions |= blackfriday.EXTENSION_BACKSLASH_LINE_BREAK extensions |= blackfriday.EXTENSION_DEFINITION_LISTS renderer := blackfriday.HtmlRenderer(htmlFlags, "", "") output := blackfriday.MarkdownOptions([]byte(text), renderer, blackfriday.Options{ Extensions: extensions, }) return sim.NewString(string(output)), nil }, }, }
var Math = []sim.NativeFunction{ { Name: "math.pow", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Float, sim.Float); err != nil { return sim.NullValue, err } v := math.Pow(args[0].ToFloat(), args[1].ToFloat()) return sim.NewFloat(v), nil }, }, { Name: "math.abs", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int); err != nil { return sim.NullValue, err } v := math.Abs(args[0].ToFloat()) return sim.NewFloat(v), nil }, }, { Name: "math.floor", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int); err != nil { return sim.NullValue, err } v := math.Floor(args[0].ToFloat()) return sim.NewInt64(int64(v)), nil }, }, { Name: "math.ceil", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int); err != nil { return sim.NullValue, err } v := math.Ceil(args[0].ToFloat()) return sim.NewInt64(int64(v)), nil }, }, { Name: "math.round", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { l := len(args) if l > 2 { return sim.NullValue, fmt.Errorf("expected 1 or 2 params, got %d", l) } f := args[0] switch f.Type { case sim.Float, sim.Int: default: return sim.NullValue, fmt.Errorf("expected parameter 1 to be a number, got %s", f.TypeName()) } if l == 1 { v := math.Round(f.ToFloat()) return sim.NewInt64(int64(v)), nil } d := args[1] if d.Type != sim.Int { return sim.NullValue, fmt.Errorf("expected parameter 2 to be int, got %s", d.TypeName()) } i := math.Pow10(int(d.ToInt())) v := math.Round(f.ToFloat()*i) / i return sim.NewFloat(v), nil }, }, { Name: "math.trunc", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { l := len(args) if l > 2 { return sim.NullValue, fmt.Errorf("expected 1 or 2 params, got %d", l) } f := args[0] switch f.Type { case sim.Float, sim.Int: default: return sim.NullValue, fmt.Errorf("expected parameter 1 to be a number, got %s", f.TypeName()) } if l == 1 { v := math.Trunc(f.ToFloat()) return sim.NewInt64(int64(v)), nil } d := args[1] if d.Type != sim.Int { return sim.NullValue, fmt.Errorf("expected parameter 2 to be int, got %s", d.TypeName()) } i := math.Pow10(int(d.ToInt())) v := math.Trunc(f.ToFloat()*i) / i return sim.NewFloat(v), nil }, }, { Name: "math.rand", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int); err != nil { return sim.NullValue, err } v := rand.Intn(int(args[0].ToInt())) return sim.NewInt(v), nil }, }, { Name: "math.median", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { values := make([]float64, len(args)) for i, v := range args { switch v.Type { case sim.Int, sim.Float: values[i] = v.ToFloat() default: return sim.NullValue, fmt.Errorf("element at %d is not a number: %s", i, v.TypeName()) } } r := median(values) return sim.NewFloat(r), nil }, }, { Name: "math.min", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var min float64 var found bool for i, v := range args { switch v.Type { case sim.Null, sim.Undefined: case sim.Int, sim.Float: k := v.ToFloat() if !found { found = true min = k } else { if i == 0 { min = k } else if k < min { min = k } } default: return sim.NullValue, fmt.Errorf("element at %d is not a number: %s", i, v.TypeName()) } } if !found { return sim.UndefinedValue, nil } return sim.NewFloat(min), nil }, }, { Name: "math.max", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var max float64 var found bool for i, v := range args { switch v.Type { case sim.Null, sim.Undefined: case sim.Int, sim.Float: k := v.ToFloat() if !found { found = true max = k } else { if i == 0 { max = k } else if k > max { max = k } } default: return sim.NullValue, fmt.Errorf("element at %d is not a number: %s", i, v.TypeName()) } } if !found { return sim.UndefinedValue, nil } return sim.NewFloat(max), nil }, }, { Name: "math.standardDev", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { values := make([]float64, len(args)) for i, v := range args { switch v.Type { case sim.Int, sim.Float: values[i] = v.ToFloat() default: return sim.NullValue, fmt.Errorf("element at %d is not a number: %s", i, v.TypeName()) } } m := median(values) d := stdDev(values, m) return sim.NewFloat(d), nil }, }, }
var Multipart = []sim.NativeFunction{ { Name: "multipart.newWriter", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } r := args[0].ToObject() w, ok := r.(io.Writer) if !ok { return sim.NullValue, fmt.Errorf("expected a io.Writer, got %v", args[0]) } m := multipart.NewWriter(w) return sim.NewObject(&multipartWriter{m}), nil }, }, }
var Net = []sim.NativeFunction{ { Name: "net.inCIDR", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } cidr := args[0].String() ip := net.ParseIP(args[1].String()) _, ipnet, err := net.ParseCIDR(cidr) if err != nil { return sim.NullValue, err } v := ipnet.Contains(ip) return sim.NewBool(v), nil }, }, { Name: "net.listen", Arguments: 2, Permissions: []string{"netListen"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } listener, err := newNetListener(args[0].String(), args[1].String(), vm) if err != nil { return sim.NullValue, err } return sim.NewObject(listener), nil }, }, { Name: "net.listenTCP", Arguments: 2, Permissions: []string{"netListen"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.Object); err != nil { return sim.NullValue, err } addr, ok := args[1].ToObject().(*tcpAddr) if !ok { return sim.NullValue, fmt.Errorf("expected param 2 to be TCPAddr, got %s", args[1].TypeName()) } listener, err := newTCPListener(args[0].String(), addr.addr, vm) if err != nil { return sim.NullValue, err } return sim.NewObject(listener), nil }, }, { Name: "net.resolveTCPAddr", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } addr, err := net.ResolveTCPAddr(args[0].String(), args[1].String()) if err != nil { return sim.NullValue, err } return sim.NewObject(&tcpAddr{addr: addr}), nil }, }, { Name: "net.dialTCP", Arguments: 3, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOrNilArgs(args, sim.String, sim.Object, sim.Object); err != nil { return sim.NullValue, err } network := args[0].String() var localAddr *net.TCPAddr lArg := args[1].ToObjectOrNil() if lArg != nil { ltcpAddr, ok := lArg.(*tcpAddr) if !ok { return sim.NullValue, fmt.Errorf("expected param 2 to be TCPAddr, got %s", args[1].TypeName()) } localAddr = ltcpAddr.addr } remoteAddr, ok := args[2].ToObject().(*tcpAddr) if !ok { return sim.NullValue, fmt.Errorf("expected param 3 to be TCPAddr, got %s", args[1].TypeName()) } conn, err := net.DialTCP(network, localAddr, remoteAddr.addr) if err != nil { return sim.NullValue, err } tc := newTCPConn(conn, vm) return sim.NewObject(tc), nil }, }, { Name: "net.dial", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } conn, err := net.Dial(args[0].String(), args[1].String()) if err != nil { return sim.NullValue, err } return sim.NewObject(newNetConn(conn, vm)), nil }, }, { Name: "net.dialTimeout", Arguments: 3, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected param 1 to be string, got %s", args[0].TypeName()) } if !isStringLike(args[1]) { return sim.NullValue, fmt.Errorf("expected param 2 to be string, got %s", args[1].TypeName()) } d, err := ToDuration(args[2]) if err != nil { return sim.NullValue, err } conn, err := net.DialTimeout(args[0].String(), args[1].String(), d) if err != nil { return sim.NullValue, err } return sim.NewObject(newNetConn(conn, vm)), nil }, }, { Name: "net.getIPAddress", Arguments: 0, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { addrs, err := net.InterfaceAddrs() if err != nil { return sim.NullValue, err } for _, address := range addrs { if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { if ipnet.IP.To4() != nil { return sim.NewString(ipnet.IP.String()), nil } } } return sim.NullValue, fmt.Errorf("no IP address found") }, }, { Name: "net.getMacAddress", Arguments: 0, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { addrs, err := net.InterfaceAddrs() if err != nil { return sim.NullValue, err } var ip string for _, address := range addrs { if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { if ipnet.IP.To4() != nil { ip = ipnet.IP.String() break } } } if ip == "" { return sim.NullValue, fmt.Errorf("no IP address found") } interfaces, err := net.Interfaces() if err != nil { return sim.NullValue, err } var hardwareName string for _, interf := range interfaces { if addrs, err := interf.Addrs(); err == nil { for _, addr := range addrs { if strings.Contains(addr.String(), ip) { hardwareName = interf.Name break } } } } if hardwareName == "" { return sim.NullValue, fmt.Errorf("no network hardware found") } netInterface, err := net.InterfaceByName(hardwareName) if err != nil { return sim.NullValue, err } macAddress := netInterface.HardwareAddr hwAddr, err := net.ParseMAC(macAddress.String()) if err != nil { return sim.NullValue, err } return sim.NewString(hwAddr.String()), nil }, }, }
var Number = []sim.NativeFunction{ { Name: "->Number.MAX_VALUE", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewFloat(math.MaxFloat64), nil }, }, { Name: "->Number.MIN_VALUE", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewFloat(math.SmallestNonzeroFloat64), nil }, }, { Name: "->Number.NaN", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewFloat(math.NaN()), nil }, }, { Name: "->Number.NEGATIVE_INFINITY", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewFloat(math.Inf(-1)), nil }, }, { Name: "Number.POSITIVE_INFINITY", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewFloat(math.Inf(1)), nil }, }, { Name: "Number.prototype.format", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } switch this.Type { case sim.Int, sim.Float: break default: return sim.NullValue, fmt.Errorf("expected byte array, got %s", this.TypeName()) } format := args[0].ToString() loc := vm.Localizer if loc == nil { loc = defaultLocalizer } num := this.Export(0) s := loc.Format(vm.Language, format, num, vm.Translations) return sim.NewString(s), nil }, }, { Name: "Number.prototype.toFixed", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Int); err != nil { return sim.NullValue, err } var precision int = 0 if len(args) > 0 { precision = int(args[0].ToInt()) } if precision < 0 || precision > 100 { return sim.NullValue, fmt.Errorf("toFixed() digits argument must be between 0 and 100") } // Convert to float64 to handle both int and float var num float64 if this.Type == sim.Int { num = float64(this.ToInt()) } else { num = this.ToFloat() } s := fmt.Sprintf("%."+strconv.Itoa(precision)+"f", num) return sim.NewString(s), nil }, }, { Name: "Number.prototype.toString", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Int); err != nil { return sim.NullValue, err } radix := 10 if len(args) > 0 { radix = int(args[0].ToInt()) } if radix < 2 || radix > 36 { return sim.NullValue, fmt.Errorf("toString() radix argument must be between 2 and 36") } var result string if this.Type == sim.Int { result = strconv.FormatInt(this.ToInt(), radix) } else { if radix != 10 { return sim.NullValue, fmt.Errorf("toString() radix argument only supported for integers") } result = strconv.FormatFloat(this.ToFloat(), 'g', -1, 64) } return sim.NewString(result), nil }, }, { Name: "Number.prototype.toExponential", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Int); err != nil { return sim.NullValue, err } var precision int = -1 // -1 means use as many digits as necessary if len(args) > 0 { precision = int(args[0].ToInt()) if precision < 0 || precision > 100 { return sim.NullValue, fmt.Errorf("toExponential() fractionDigits argument must be between 0 and 100") } } // Convert to float64 var num float64 if this.Type == sim.Int { num = float64(this.ToInt()) } else { num = this.ToFloat() } var result string if precision == -1 { result = strconv.FormatFloat(num, 'e', -1, 64) } else { result = strconv.FormatFloat(num, 'e', precision, 64) } return sim.NewString(result), nil }, }, { Name: "Number.prototype.toPrecision", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Int); err != nil { return sim.NullValue, err } // Convert to float64 var num float64 if this.Type == sim.Int { num = float64(this.ToInt()) } else { num = this.ToFloat() } if len(args) == 0 { result := strconv.FormatFloat(num, 'g', -1, 64) return sim.NewString(result), nil } precision := int(args[0].ToInt()) if precision < 1 || precision > 100 { return sim.NullValue, fmt.Errorf("toPrecision() precision argument must be between 1 and 100") } result := strconv.FormatFloat(num, 'g', precision, 64) return sim.NewString(result), nil }, }, { Name: "Number.prototype.valueOf", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args); err != nil { return sim.NullValue, err } return this, nil }, }, { Name: "Number", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgRange(args, 0, 1); err != nil { return sim.NullValue, err } if len(args) == 0 { return sim.NewInt(0), nil } arg := args[0] switch arg.Type { case sim.Int, sim.Float: return arg, nil case sim.String: str := strings.TrimSpace(arg.ToString()) if str == "" { return sim.NewInt(0), nil } if str == "Infinity" || str == "+Infinity" { return sim.NewFloat(math.Inf(1)), nil } if str == "-Infinity" { return sim.NewFloat(math.Inf(-1)), nil } if str == "NaN" { return sim.NewFloat(math.NaN()), nil } str = strings.TrimLeft(str, " \t\n\r\v\f") if str == "" { return sim.NewInt(0), nil } sign := 1.0 switch str[0] { case '-': sign = -1 str = str[1:] case '+': str = str[1:] } if str == "" { return sim.NewFloat(math.NaN()), nil } hasDecimal := false result := 0.0 decimalPlaces := 0.0 for i, char := range str { if char == '.' && !hasDecimal { hasDecimal = true continue } if char >= '0' && char <= '9' { if hasDecimal { decimalPlaces++ result = result + float64(char-'0')/math.Pow(10, decimalPlaces) } else { result = result*10 + float64(char-'0') } } else { if i == 0 { return sim.NewFloat(math.NaN()), nil } break } } result *= sign if !hasDecimal && result >= math.MinInt64 && result <= math.MaxInt64 { return sim.NewInt64(int64(result)), nil } return sim.NewFloat(result), nil case sim.Bool: if arg.ToBool() { return sim.NewInt(1), nil } return sim.NewInt(0), nil case sim.Null: return sim.NewInt(0), nil case sim.Undefined: return sim.NewFloat(math.NaN()), nil default: return sim.NewFloat(math.NaN()), nil } }, }, { Name: "isNaN", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) != 1 { return sim.NullValue, fmt.Errorf("expected 1 argument, got %d", len(args)) } value := args[0] switch value.Type { case sim.Float: return sim.NewBool(math.IsNaN(value.ToFloat())), nil case sim.Int: return sim.FalseValue, nil case sim.String: s := value.String() if s == "" { return sim.FalseValue, nil } if f, err := strconv.ParseFloat(s, 64); err != nil { return sim.TrueValue, nil } else { return sim.NewBool(math.IsNaN(f)), nil } case sim.Bool: return sim.FalseValue, nil case sim.Null: return sim.FalseValue, nil case sim.Undefined: return sim.TrueValue, nil default: s := value.String() if f, err := strconv.ParseFloat(s, 64); err != nil { return sim.TrueValue, nil } else { return sim.NewBool(math.IsNaN(f)), nil } } }, }, { Name: "Number.isNaN", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) != 1 { return sim.NullValue, fmt.Errorf("expected 1 argument, got %d", len(args)) } value := args[0] if value.Type == sim.Float { return sim.NewBool(math.IsNaN(value.ToFloat())), nil } return sim.FalseValue, nil }, }, }
var OS = []sim.NativeFunction{ { Name: "->os.sharedCache", Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sharedCache, nil }, }, { Name: "->os.ErrNotExist", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewString("no such file or directory"), nil }, }, { Name: "os.hostName", Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { name, err := os.Hostname() if err != nil { return sim.NullValue, err } return sim.NewString(name), nil }, }, { Name: "->os.pathSeparator", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewString(string(os.PathSeparator)), nil }, }, { Name: "->os.userHomeDir", Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { d, err := os.UserHomeDir() if err != nil { return sim.NullValue, ErrUnauthorized } return sim.NewString(d), nil }, }, { Name: "->os.stdout", Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { f := &file{f: os.Stdout} return sim.NewObject(f), nil }, }, { Name: "->os.stdin", Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { f := &file{f: os.Stdin} return sim.NewObject(f), nil }, }, { Name: "->os.stderr", Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { f := &file{f: os.Stderr} return sim.NewObject(f), nil }, }, { Name: "os.mapPath", Arguments: 1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } p := args[0].String() if len(p) > 0 && p[0] == '~' { usr, err := user.Current() if err != nil { return sim.NullValue, err } p = filepath.Join(usr.HomeDir, p[1:]) } return sim.NewString(p), nil }, }, { Name: "os.exit", Arguments: -1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Int); err != nil { return sim.NullValue, err } var exitCode int if len(args) > 0 { exitCode = int(args[0].ToInt()) } os.Exit(exitCode) return sim.NullValue, nil }, }, { Name: "os.exec", Arguments: -1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { l := len(args) if l == 0 { return sim.NullValue, fmt.Errorf("expected at least 1 argument") } values := make([]string, l) for i, v := range args { values[i] = v.String() } cmd := exec.Command(values[0], values[1:]...) cmd.Stderr = os.Stderr cmd.Stdout = os.Stdout if err := cmd.Run(); err != nil { return sim.NullValue, err } return sim.NullValue, nil }, }, { Name: "os.newCommand", Arguments: -1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { l := len(args) if l == 0 { return sim.NullValue, fmt.Errorf("expected at least 1 argument") } values := make([]string, l) for i, v := range args { values[i] = v.String() } cmd := newCommand(values[0], values[1:]...) return sim.NewObject(cmd), nil }, }, { Name: "os.getWd", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.getWd(args, vm) }, }, { Name: "os.open", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.open(args, vm) }, }, { Name: "os.openIfExists", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.openIfExists(args, vm) }, }, { Name: "os.openForWrite", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.openForWrite(args, vm) }, }, { Name: "os.openForAppend", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.openForAppend(args, vm) }, }, { Name: "os.chdir", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.chdir(args, vm) }, }, { Name: "os.exists", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.exists(args, vm) }, }, { Name: "os.rename", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.rename(args, vm) }, }, { Name: "os.removeAll", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.removeAll(args, vm) }, }, { Name: "os.readAll", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.readAll(args, vm) }, }, { Name: "os.readAllIfExists", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.readAllIfExists(args, vm) }, }, { Name: "os.readString", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.readString(args, vm) }, }, { Name: "os.readStringIfExists", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.readStringIfExists(args, vm) }, }, { Name: "os.write", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.write(args, vm) }, }, { Name: "os.append", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.append(args, vm) }, }, { Name: "os.mkdir", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.mkdir(args, vm) }, }, { Name: "os.stat", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.stat(args, vm) }, }, { Name: "os.readDir", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.readDir(args, vm) }, }, { Name: "os.readNames", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { fs := vm.FileSystem if fs == nil { return sim.NullValue, ErrNoFileSystem } f := &FileSystemObj{fs} return f.readNames(args, vm) }, }, { Name: "os.readLine", Arguments: 0, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { r := bufio.NewReader(os.Stdin) s, err := r.ReadString('\n') if err != nil { return sim.NullValue, err } s = s[:len(s)-1] return sim.NewString(s), nil }, }, { Name: "->os.fileSystem", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if vm.FileSystem == nil { return sim.NullValue, nil } return sim.NewObject(NewFileSystem(vm.FileSystem)), nil }, }, { Name: "os.getEnv", Arguments: 1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } s := os.Getenv(args[0].String()) return sim.NewString(s), nil }, }, { Name: "os.setEnv", Arguments: 2, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } if err := os.Setenv(args[0].String(), args[1].String()); err != nil { return sim.NullValue, err } return sim.NullValue, nil }, }, { Name: "os.newFile", Arguments: 2, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int, sim.String); err != nil { return sim.NullValue, err } f := os.NewFile(uintptr(args[0].ToInt()), args[1].String()) ff := &file{f: f} return sim.NewObject(ff), nil }, }, { Name: "->os.DevNull", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewString(os.DevNull), nil }, }, }
var PDF = []sim.NativeFunction{ { Name: "pdf.newConfig", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { conf := &gopdf.Config{ PageSize: *gopdf.PageSizeA4, } return sim.NewObject(&pdfConfig{config: conf}), nil }, }, { Name: "pdf.newPDF", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Object); err != nil { return sim.NullValue, err } var conf gopdf.Config if len(args) > 0 { cn, ok := args[0].ToObjectOrNil().(*pdfConfig) if !ok { return sim.NullValue, fmt.Errorf("expected arg 1 to be config, got %s", args[0].TypeName()) } conf = *cn.config } else { conf = gopdf.Config{ PageSize: *gopdf.PageSizeA4, } } p := &pdfDoc{pdf: &gopdf.GoPdf{}, lineWidth: 1} p.pdf.Start(conf) if err := p.pdf.AddTTFFontData("roboto", pdf.RobotoRegular); err != nil { return sim.NullValue, err } if err := p.pdf.AddTTFFontData("robotoBold", pdf.RobotoBold); err != nil { return sim.NullValue, err } p.width = conf.PageSize.W p.height = conf.PageSize.H p.fontFamily = "roboto" p.fontSize = 14 p.lineHeight = lineHeight(14) if err := p.pdf.SetFont("roboto", "", p.fontSize); err != nil { return sim.NullValue, err } if p.textColor == nil { p.textColor = &pdfColor{} } if p.fillColor == nil { p.fillColor = &pdfColor{} } if p.strokeColor == nil { p.strokeColor = &pdfColor{} } return sim.NewObject(p), nil }, }, { Name: "pdf.newCellOption", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewObject(&pdfCellOption{opt: gopdf.CellOption{}}), nil }, }, { Name: "pdf.newRect", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Float, sim.Float); err != nil { return sim.NullValue, err } rect := &gopdf.Rect{ W: args[0].ToFloat(), H: args[1].ToFloat(), } return sim.NewObject(&pdfRect{rect}), nil }, }, { Name: "pdf.write", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { writer, ok := args[0].ToObjectOrNil().(io.Writer) if !ok { return sim.NullValue, fmt.Errorf("expected first parameter to be io.Writer, got %s", args[0].TypeName()) } if err := ValidateArgs(args[1:2], sim.String); err != nil { return sim.NullValue, err } xmlStr := args[1].ToString() if err := pdfWriteDirect(writer, xmlStr); err != nil { return sim.NullValue, err } return sim.NullValue, nil }, }, { Name: "pdf.writeFile", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args[0:1], sim.String); err != nil { return sim.NullValue, err } filePath := args[0].ToString() if err := ValidateArgs(args[1:2], sim.String); err != nil { return sim.NullValue, err } xmlStr := args[1].ToString() if err := pdfWriteFileDirect(filePath, xmlStr); err != nil { return sim.NullValue, err } return sim.NullValue, nil }, }, { Name: "pdf.render", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) < 2 || len(args) > 3 { return sim.NullValue, fmt.Errorf("pdf.render expects 2 or 3 parameters, got %d", len(args)) } writer, ok := args[0].ToObjectOrNil().(io.Writer) if !ok { return sim.NullValue, fmt.Errorf("expected first parameter to be io.Writer, got %s", args[0].TypeName()) } if err := ValidateArgs(args[1:2], sim.String); err != nil { return sim.NullValue, err } template := args[1].ToString() // Third parameter: optional data var data sim.Value = sim.NullValue if len(args) == 3 { data = args[2] } if err := pdfRender(writer, template, data, vm); err != nil { return sim.NullValue, err } return sim.NullValue, nil }, }, { Name: "pdf.renderFile", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) < 2 || len(args) > 3 { return sim.NullValue, fmt.Errorf("pdf.renderFile expects 2 or 3 parameters, got %d", len(args)) } if err := ValidateArgs(args[0:1], sim.String); err != nil { return sim.NullValue, err } filePath := args[0].ToString() if err := ValidateArgs(args[1:2], sim.String); err != nil { return sim.NullValue, err } template := args[1].ToString() // Third parameter: optional data var data sim.Value = sim.NullValue if len(args) == 3 { data = args[2] } if err := pdfRenderFile(filePath, template, data, vm); err != nil { return sim.NullValue, err } return sim.NullValue, nil }, }, { Name: "pdf.newRenderer", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) != 1 { return sim.NullValue, errors.New("expected 1 argument") } xmlStr := args[0].ToString() xmlDoc := etree.NewDocument() if err := xmlDoc.ReadFromString(xmlStr); err != nil { return sim.NullValue, err } document, err := pdf.Parse(xmlDoc) if err != nil { return sim.NullValue, err } formatter := createNumberFormatter(vm) doc := pdf.SetLayout(document, formatter) if doc == nil { return sim.NullValue, fmt.Errorf("failed to set layout") } _, err = pdf.NewRenderer(doc, xmlStr) if err != nil { return sim.NullValue, err } obj := sim.NewObject(map[string]interface{}{}) return obj, nil }, }, }
var Png = []sim.NativeFunction{ { Name: "png.decode", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgRange(args, 1); err != nil { return sim.NullValue, err } a := args[0] var r io.Reader switch a.Type { case sim.Object: var ok bool r, ok = a.ToObject().(io.Reader) if !ok { return sim.NullValue, ErrInvalidType } case sim.Bytes: r = bytes.NewBuffer(a.ToBytes()) } img, err := png.Decode(r) if err != nil { return sim.NullValue, err } return sim.NewObject(imageObj{img: img, format: "PNG"}), nil }, }, { Name: "png.encode", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object, sim.Object); err != nil { return sim.NullValue, err } w, ok := args[0].ToObject().(io.Writer) if !ok { return sim.NullValue, ErrInvalidType } i, ok := args[1].ToObject().(imageObj) if !ok { return sim.NullValue, ErrInvalidType } err := png.Encode(w, i.img) if err != nil { return sim.NullValue, err } return sim.NullValue, nil }, }, }
var Printing = []sim.NativeFunction{ { Name: "printing.listPrinters", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { list, err := printutil.ListPrinters() if err != nil { return sim.NullValue, err } values := make([]sim.Value, len(list)) for i, name := range list { values[i] = sim.NewString((name)) } return sim.NewArrayValues(values), nil }, }, { Name: "printing.newPrinter", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String, sim.Bool); err != nil { return sim.NullValue, err } var name string var cups bool switch len(args) { case 0: return sim.NullValue, fmt.Errorf("expected at least one argument") case 1: name = args[0].ToString() case 2: name = args[0].ToString() cups = args[1].ToBool() } p := printutil.New(name, cups) return sim.NewObject(&printerObj{p}), nil }, }, }
var Profiler = []sim.NativeFunction{}
var QRCode = []sim.NativeFunction{ { Name: "qrcode.encode", Arguments: 3, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String, sim.Int); err != nil { return sim.NullValue, err } value := args[0].ToString() var level qrcode.RecoveryLevel switch args[1].ToString() { case "low": level = qrcode.Low case "medium": level = qrcode.Medium case "high": level = qrcode.High case "highest": level = qrcode.Highest } size := int(args[2].ToInt()) png, err := qrcode.Encode(value, level, size) if err != nil { return sim.NullValue, err } return sim.NewBytes(png), nil }, }, { Name: "qrcode.encodeVersion", Arguments: 4, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String, sim.Int, sim.Int); err != nil { return sim.NullValue, err } value := args[0].ToString() var level qrcode.RecoveryLevel switch args[1].ToString() { case "low": level = qrcode.Low case "medium": level = qrcode.Medium case "high": level = qrcode.High case "highest": level = qrcode.Highest } size := int(args[2].ToInt()) version := int(args[3].ToInt()) qr, err := qrcode.NewWithForcedVersion(value, version, level) if err != nil { return sim.NullValue, err } png, err := qr.PNG(size) if err != nil { return sim.NullValue, err } return sim.NewBytes(png), nil }, }, }
var RSA = []sim.NativeFunction{ { Name: "rsa.generateKey", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Int); err != nil { return sim.NullValue, err } reader := rand.Reader var bitSize int if len(args) == 0 { bitSize = 2048 } else { bitSize = int(args[0].ToInt()) } key, err := rsa.GenerateKey(reader, bitSize) if err != nil { return sim.NullValue, err } return sim.NewObject(&rsaPrivateKey{key}), nil }, }, { Name: "rsa.decodePEMKey", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0].ToBytes() block, _ := pem.Decode(v) if block == nil { return sim.NullValue, fmt.Errorf("error decoding private key") } enc := x509.IsEncryptedPEMBlock(block) b := block.Bytes var err error if enc { b, err = x509.DecryptPEMBlock(block, nil) if err != nil { return sim.NullValue, fmt.Errorf("error decrypting private key") } } key, err := x509.ParsePKCS1PrivateKey(b) if err != nil { return sim.NullValue, fmt.Errorf("error parsing private key: %w", err) } return sim.NewObject(&rsaPrivateKey{key}), nil }, }, { Name: "rsa.decodePublicPEMKey", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0].ToBytes() block, _ := pem.Decode(v) if block == nil { return sim.NullValue, fmt.Errorf("error decoding public key") } enc := x509.IsEncryptedPEMBlock(block) b := block.Bytes var err error if enc { b, err = x509.DecryptPEMBlock(block, nil) if err != nil { return sim.NullValue, fmt.Errorf("error decrypting public key") } } parsedKey, err := x509.ParsePKIXPublicKey(b) if err != nil { if cert, err := x509.ParseCertificate(block.Bytes); err == nil { parsedKey = cert.PublicKey } else { parsedKey, err = x509.ParsePKCS1PublicKey(block.Bytes) if err != nil { return sim.NullValue, fmt.Errorf("error parsing public key (2): %v", err) } } } key, ok := parsedKey.(*rsa.PublicKey) if !ok { return sim.NullValue, fmt.Errorf("not an RSA public key") } return sim.NewObject(&rsaPublicKey{key}), nil }, }, { Name: "rsa.signPKCS1v15", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { key, ok := args[0].ToObjectOrNil().(*rsaPrivateKey) if !ok { return sim.NullValue, fmt.Errorf("expected a rsa key, got %v", args[0].TypeName()) } message := args[1].ToBytes() hashed := sha256.Sum256(message) rng := rand.Reader signature, err := rsa.SignPKCS1v15(rng, key.key, crypto.SHA256, hashed[:]) if err != nil { return sim.NullValue, err } return sim.NewBytes(signature), nil }, }, { Name: "rsa.verifyPKCS1v15", Arguments: 3, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { key, ok := args[0].ToObjectOrNil().(*rsaPublicKey) if !ok { return sim.NullValue, fmt.Errorf("expected a rsa key, got %v", args[0].TypeName()) } message := args[1].ToBytes() signature := args[2].ToBytes() hashed := sha256.Sum256(message) err := rsa.VerifyPKCS1v15(key.key, crypto.SHA256, hashed[:], signature) if err != nil { return sim.FalseValue, nil } return sim.TrueValue, err }, }, }
var Reflect = []sim.NativeFunction{ { Name: "reflect.createInstance", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) == 0 { return sim.NullValue, fmt.Errorf("expected at least 1 parameter, got %d", len(args)) } a := args[0] if a.Type != sim.String { return sim.NullValue, fmt.Errorf("argument 1 must be a string, got %s", a.TypeName()) } instance, err := sim.NewInstance(a.String(), args[1:], vm) if err != nil { return sim.NullValue, err } return sim.NewObject(instance), nil }, }, { Name: "reflect.nativeFunctions", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := getNativeFuncions(false) return v, nil }, }, { Name: "reflect.nativeProperties", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := getNativeFuncions(true) return v, nil }, }, { Name: "reflect.is", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0].TypeName() b := args[1] if b.Type != sim.String { return sim.NullValue, fmt.Errorf("argument 2 must be a string, got %s", b.TypeName()) } return sim.NewBool(a == b.String()), nil }, }, { Name: "reflect.isValue", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { switch args[0].Type { case sim.Int, sim.Float, sim.Bool, sim.String: return sim.FalseValue, nil } return sim.TrueValue, nil }, }, { Name: "reflect.isNativeObject", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0].Type == sim.Object return sim.NewBool(v), nil }, }, { Name: "reflect.isArray", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0].Type == sim.Array return sim.NewBool(v), nil }, }, { Name: "reflect.isMap", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0].Type == sim.Map return sim.NewBool(v), nil }, }, { Name: "reflect.typeOf", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0] return sim.NewString(v.TypeName()), nil }, }, { Name: "reflect.call", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) == 0 { return sim.NullValue, fmt.Errorf("expected the function name") } if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("argument must be a string, got %s", args[0].TypeName()) } return vm.RunFunc(args[0].String(), args[1:]...) }, }, { Name: "reflect.getFunction", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("argument must be a string, got %s", args[0].TypeName()) } name := args[0].String() fn, ok := vm.Program.Function(name) if !ok { return sim.NullValue, nil } v := sim.NewFunction(fn.Index) return v, nil }, }, { Name: "reflect.getFunctionInfo", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Func); err != nil { return sim.NullValue, err } i := args[0].ToFunction() if i < 0 || i > len(vm.Program.Functions)-1 { return sim.NullValue, fmt.Errorf("index out of range") } f := vm.Program.Functions[i] p := program{vm.Program} return sim.NewObject(functionInfo{f, p}), nil }, }, { Name: "reflect.findFunction", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } name := args[0].String() suffix := "/" + name for _, f := range vm.Program.Functions { if name == f.Name || strings.HasSuffix(f.Name, suffix) { p := program{vm.Program} fi := functionInfo{f, p} return sim.NewObject(fi), nil } } return sim.NullValue, nil }, }, { Name: "reflect.runFunc", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { l := len(args) if l < 1 { return sim.NullValue, fmt.Errorf("expected at least 1 parameter, got %d", l) } if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("argument must be a string, got %s", args[0].TypeName()) } name := args[0].String() v, err := vm.RunFunc(name, args[1:]...) if err != nil { return sim.NullValue, err } return v, nil }, }, }
var Regex = []sim.NativeFunction{ { Name: "regex.match", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } ok, err := regexp.MatchString(args[0].String(), args[1].String()) if err != nil { return sim.NullValue, err } return sim.NewBool(ok), nil }, }, { Name: "regex.split", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String); err != nil { return sim.NullValue, err } r, err := regexp.Compile(args[0].String()) if err != nil { return sim.NullValue, err } matches := r.Split(args[1].String(), -1) ln := len(matches) result := make([]sim.Value, ln) for i := 0; i < ln; i++ { result[i] = sim.NewString(matches[i]) } return sim.NewArrayValues(result), nil }, }, { Name: "regex.findAllStringSubmatchIndex", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgRange(args, 2, 3); err != nil { return sim.NullValue, err } if err := ValidateOptionalArgs(args, sim.String, sim.String, sim.Int); err != nil { return sim.NullValue, err } r, err := regexp.Compile(args[0].String()) if err != nil { return sim.NullValue, err } var i int if len(args) == 3 { i = int(args[2].ToInt()) } else { i = -1 } matches := r.FindAllStringSubmatchIndex(args[1].String(), i) var result []sim.Value for _, v := range matches { ln := len(v) a := make([]sim.Value, ln) for i := 0; i < ln; i++ { a[i] = sim.NewInt(v[i]) } result = append(result, sim.NewArrayValues(a)) } return sim.NewArrayValues(result), nil }, }, { Name: "regex.findAllString", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgRange(args, 2, 3); err != nil { return sim.NullValue, err } if err := ValidateOptionalArgs(args, sim.String, sim.String, sim.Int); err != nil { return sim.NullValue, err } r, err := regexp.Compile(args[0].String()) if err != nil { return sim.NullValue, err } var i int if len(args) == 3 { i = int(args[2].ToInt()) } else { i = -1 } matches := r.FindAllString(args[1].String(), i) var result []sim.Value for _, v := range matches { result = append(result, sim.NewString(v)) } return sim.NewArrayValues(result), nil }, }, { Name: "regex.findAllStringSubmatch", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgRange(args, 2, 3); err != nil { return sim.NullValue, err } if err := ValidateOptionalArgs(args, sim.String, sim.String, sim.Int); err != nil { return sim.NullValue, err } r, err := regexp.Compile(args[0].String()) if err != nil { return sim.NullValue, err } var i int if len(args) == 3 { i = int(args[2].ToInt()) } else { i = -1 } matches := r.FindAllStringSubmatch(args[1].String(), i) var result []sim.Value for _, v := range matches { var subResult []sim.Value for _, sv := range v { subResult = append(subResult, sim.NewString(sv)) } result = append(result, sim.NewArrayValues(subResult)) } return sim.NewArrayValues(result), nil }, }, { Name: "regex.replaceAllString", Arguments: 3, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.String, sim.String); err != nil { return sim.NullValue, err } r, err := regexp.Compile(args[0].String()) if err != nil { return sim.NullValue, err } result := r.ReplaceAllString(args[1].String(), args[2].String()) return sim.NewString(result), nil }, }, }
var Router = []sim.NativeFunction{ { Name: "routing.newRouter", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { r := newRouter() return sim.NewObject(r), nil }, }, }
var Runtime = []sim.NativeFunction{ { Name: "->runtime.ErrFunctionNotExist", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewString(sim.ErrFunctionNotExist.Error()), nil }, }, { Name: "runtime.numGoroutine", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { n := runtime.NumGoroutine() return sim.NewInt(n), nil }, }, { Name: "runtime.memStats", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var stats runtime.MemStats runtime.ReadMemStats(&stats) return sim.NewObject(&memStats{stats}), nil }, }, { Name: "runtime.freeDiskSpace", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { percent, err := getSystemDiskFreePercent() return sim.NewInt64(int64(percent)), err }, }, { Name: "runtime.getUsedCPUPercent", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { percent, err := getSystemCPUUsedPercent() return sim.NewInt64(int64(percent)), err }, }, { Name: "runtime.usedMemoryPercent", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { percent, err := getSystemUsedMemoryPercent() if err != nil { return sim.NullValue, err } return sim.NewInt64(int64(percent)), nil }, }, { Name: "runtime.getSystemNetworkBytes", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { rx, tx, err := getSystemNetworkBytes() if err != nil { return sim.NullValue, err } m := make(map[sim.Value]sim.Value) m[sim.NewString("rx")] = sim.NewInt64(int64(rx)) m[sim.NewString("tx")] = sim.NewInt64(int64(tx)) return sim.NewMapValues(m, true), nil }, }, { Name: "runtime.startProfiler", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if vm.Profiler == nil { vm.Profiler = sim.NewProfiler() } vm.Profiler.Start() return sim.NullValue, nil }, }, { Name: "runtime.stopProfiler", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if vm.Profiler == nil { return sim.NullValue, fmt.Errorf("there is no profiler in the current context") } vm.Profiler.Stop() return sim.NullValue, nil }, }, { Name: "runtime.resetProfiler", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if vm.Profiler == nil { return sim.NullValue, fmt.Errorf("there is no profiler in the current context") } vm.Profiler.Reset() return sim.NullValue, nil }, }, { Name: "runtime.printProfilerLines", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Int); err != nil { return sim.NullValue, err } if vm.Profiler == nil { return sim.NullValue, fmt.Errorf("there is no profiler in the current context") } var n int if len(args) == 0 { n = 50 } else { n = int(args[0].ToInt()) } vm.Profiler.PrintLines(n) return sim.NullValue, nil }, }, { Name: "runtime.printProfilerFunctions", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Int); err != nil { return sim.NullValue, err } if vm.Profiler == nil { return sim.NullValue, fmt.Errorf("there is no profiler in the current context") } var n int if len(args) == 0 { n = 50 } else { n = int(args[0].ToInt()) } vm.Profiler.PrintFunctions(n) return sim.NullValue, nil }, }, { Name: "runtime.newProfiler", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewObject(&profilerObj{sim.NewProfiler()}), nil }, }, { Name: "runtime.gc", Arguments: 0, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { runtime.GC() return sim.NullValue, nil }, }, { Name: "panic", Arguments: 1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { panic(args[0].String()) }, }, { Name: "->runtime.version", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewString(sim.VERSION), nil }, }, { Name: "runtime.typeDefs", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args); err != nil { return sim.NullValue, err } s := sim.TypeDefs() return sim.NewString(s), nil }, }, { Name: "runtime.runFunc", Arguments: -1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) == 0 { return sim.NullValue, fmt.Errorf("expected at least the function name") } a := args[0] switch a.Type { case sim.String: return vm.RunFunc(a.String(), args[1:]...) case sim.Func: return vm.RunFuncIndex(a.ToFunction(), args[1:]...) default: return sim.NullValue, fmt.Errorf("invalid function argument type, got %v", a.Type) } }, }, { Name: "->runtime.context", Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return vm.Context, nil }, }, { Name: "runtime.setContext", Arguments: 1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { vm.Context = args[0] return sim.NullValue, nil }, }, { Name: "runtime.attribute", Arguments: 1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } return programAttribute(vm.Program, args[0].String()), nil }, }, { Name: "runtime.hasAttribute", Arguments: 1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } return programHasAttribute(vm.Program, args[0].String()), nil }, }, { Name: "runtime.resources", Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { res := vm.Program.Resources if res == nil { return sim.NewArray(0), nil } a := make([]sim.Value, len(res)) i := 0 for k := range res { a[i] = sim.NewString(k) i++ } return sim.NewArrayValues(a), nil }, }, { Name: "runtime.resource", Arguments: 1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } name := args[0].String() res := vm.Program.Resources if res == nil { return sim.NullValue, nil } v, ok := res[name] if !ok { return sim.NullValue, nil } return sim.NewBytes(v), nil }, }, { Name: "->runtime.hasResources", Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { res := vm.Program.Resources if len(res) == 0 { return sim.FalseValue, nil } return sim.TrueValue, nil }, }, { Name: "runtime.setFileSystem", Arguments: 1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } fs, ok := args[0].ToObject().(*FileSystemObj) if !ok { return sim.NullValue, fmt.Errorf("expected a fileSystem, got %s", args[0].TypeName()) } vm.FileSystem = fs.FS return sim.NullValue, nil }, }, { Name: "runtime.newFinalizable", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0] fin, err := newFinalizable(v, vm) if err != nil { return sim.NullValue, err } return sim.NewObject(fin), nil }, }, { Name: "defer", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0] fin, err := newFinalizable(v, vm) if err != nil { return sim.NullValue, err } vm.SetFinalizer(fin) return sim.NullValue, nil }, }, { Name: "runtime.setFinalizer", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0] if v.Type != sim.Object { return sim.NullValue, fmt.Errorf("the value is not a finalizer") } fin, ok := v.ToObject().(sim.Finalizable) if !ok { return sim.NullValue, fmt.Errorf("the value is not a finalizer") } vm.SetFinalizer(fin) return sim.NullValue, nil }, }, { Name: "->runtime.OS", Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewString(runtime.GOOS), nil }, }, { Name: "->runtime.executable", Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewString(vm.Program.Name), nil }, }, { Name: "->runtime.entryFile", Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(vm.Program.Files) == 0 { return sim.NullValue, nil } return sim.NewString(vm.Program.Files[0]), nil }, }, { Name: "->runtime.basePath", Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewString(vm.Program.BasePath), nil }, }, { Name: "->runtime.nativeExecutable", Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { ex, err := os.Executable() if err != nil { return sim.NullValue, err } return sim.NewString(ex), nil }, }, { Name: "runtime.newVM", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { l := len(args) if l == 0 || l > 2 { return sim.NullValue, fmt.Errorf("expected 1 or 2 params, got %d", l) } if args[0].Type != sim.Object { return sim.NullValue, fmt.Errorf("argument 1 must be a program, got %s", args[0].TypeName()) } p, ok := args[0].ToObject().(*program) if !ok { return sim.NullValue, fmt.Errorf("argument 1 must be a program, got %s", args[0].TypeName()) } var m *sim.VM if l == 1 { m = sim.NewVM(p.prog) } else { switch args[1].Type { case sim.Undefined, sim.Null: m = sim.NewVM(p.prog) case sim.Array: m = sim.NewInitializedVM(p.prog, args[1].ToArray()) default: return sim.NullValue, fmt.Errorf("argument 2 must be an array, got %s", args[1].TypeName()) } } m.Parent = vm m.Stdout = vm.Stdout m.Stdin = vm.Stdin m.Stderr = vm.Stderr m.Now = vm.Now m.Profiler = vm.Profiler m.Localizer = vm.Localizer m.Language = vm.Language m.Location = vm.Location m.StatsEnabled = vm.StatsEnabled m.MaxAllocations = vm.MaxAllocations m.MaxFrames = vm.MaxFrames m.MaxSteps = vm.MaxSteps m.Translations = vm.Translations return sim.NewObject(&libVM{m}), nil }, }, { Name: "->runtime.vm", Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewObject(&libVM{vm}), nil }, }, { Name: "runtime.resetSteps", Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { vm.ResetSteps() return sim.NullValue, nil }, }, { Name: "runtime.stackTrace", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { s := strings.Join(vm.Stacktrace(), "\n") return sim.NewString(s), nil }, }, }
var SFTP = []sim.NativeFunction{ { Name: "sftp.newClient", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.Object); err != nil { return sim.NullValue, err } url := args[0].ToString() config, ok := args[1].ToObjectOrNil().(*sshConfig) if !ok { return sim.NullValue, fmt.Errorf("%v is not a ssh.Config", args[1].TypeName()) } conn, err := ssh.Dial("tcp", url, config.c) if err != nil { return sim.NullValue, errors.Wrap(err, fmt.Sprintf("dialing to %s", url)) } client, err := sftp.NewClient(conn) if err != nil { return sim.NullValue, err } return sim.NewObject(&sftpClient{conn: conn, c: client}), nil }, }, }
var SQL = []sim.NativeFunction{ { Name: "sql.open", Arguments: -1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { l := len(args) if l < 2 || l > 3 { return sim.NullValue, fmt.Errorf("expected 2 or 3 parameters, got %d", l) } if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("argument 1 must be a string, got %s", args[0].TypeName()) } if !isStringLike(args[1]) { return sim.NullValue, fmt.Errorf("argument 2 must be a string, got %s", args[1].TypeName()) } driver := args[0].String() connString := args[1].String() db, err := dbx.Open(driver, connString, vm.Clock()) if err != nil { return sim.NullValue, err } db.SetMaxOpenConns(50) db.SetMaxIdleConns(10) db.SetConnMaxLifetime(2 * time.Minute) db.SetConnMaxIdleTime(30 * time.Second) if l == 3 { if !isStringLike(args[2]) { return sim.NullValue, fmt.Errorf("argument 3 must be a string, got %s", args[2].TypeName()) } name := args[2].String() if err := validateDatabaseName(name); err != nil { return sim.NullValue, err } db = db.Open(name) } ldb := newDB(db) vm.SetGlobalFinalizer(ldb) return sim.NewObject(ldb), nil }, }, { Name: "sql.setWhitelistFuncs", Arguments: 1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Array); err != nil { return sim.NullValue, err } a := args[0].ToArray() sqx.ValidFuncs = make([]string, len(a)) for i, v := range a { if v.Type != sim.String { return sim.NullValue, fmt.Errorf("invalid value at index %d. It's a %s", i, v.TypeName()) } sqx.ValidFuncs[i] = v.String() } return sim.NullValue, nil }, }, { Name: "sql.getQueries", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } q, err := toQuery(args[0]) if err != nil { return sim.NullValue, err } queries := sqx.GetQueries(q) values := make([]sim.Value, len(queries)) for i, q := range queries { v, err := getQueryObject(q) if err != nil { return sim.NullValue, err } values[i] = v } return sim.NewArrayValues(values), nil }, }, { Name: "sql.getMainTable", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } q, err := toQuery(args[0]) if err != nil { return sim.NullValue, err } t := sqx.GetMainTable(q) if t == nil { return sim.NullValue, nil } return sim.NewObject(&sqxTable{t}), nil }, }, { Name: "sql.hasFilterColumn", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object, sim.String); err != nil { return sim.NullValue, err } q, err := toQuery(args[0]) if err != nil { return sim.NullValue, err } column := args[1].String() b := sqx.HasFilterColumn(q, column) return sim.NewBool(b), nil }, }, { Name: "sql.validateSelect", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object, sim.Map); err != nil { return sim.NullValue, err } s, ok := args[0].ToObjectOrNil().(selectQuery) if !ok { return sim.NullValue, fmt.Errorf("expected argument to be SelectQuery, got %v", args[0].TypeName()) } opt := &sqx.ValidateOptions{} optMap := args[1].ToMap().Map tablesVal, ok := optMap[sim.NewString("tables")] if !ok { return sim.NullValue, fmt.Errorf("invalid options: expected tables") } if tablesVal.Type != sim.Map { return sim.NullValue, fmt.Errorf("invalid tables value: %v", tablesVal) } for k, v := range tablesVal.ToMap().Map { if k.Type != sim.String { return sim.NullValue, fmt.Errorf("invalid table name: %v", k) } if v.Type != sim.Array { return sim.NullValue, fmt.Errorf("invalid tables value for %s: %v", k, v) } colValues := v.ToArray() cols := make([]string, len(colValues)) for i, c := range colValues { if c.Type != sim.String { return sim.NullValue, fmt.Errorf("invalid column value for %s: %v", k, c) } cols[i] = c.String() } opt.Tables = append(opt.Tables, &sqx.ValidateTable{ Name: k.String(), Columns: cols, }) } err := sqx.ValidateSelect(s.query, opt) return sim.NullValue, err }, }, { Name: "sql.newSelect", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { s := selectQuery{&sqx.SelectQuery{}} return sim.NewObject(s), nil }, }, { Name: "sql.parse", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { l := len(args) if l == 0 { return sim.NullValue, fmt.Errorf("expected at least one argument, got %d", l) } if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected argument to be a string, got %v", args[0].Type) } v := args[0].String() var params []interface{} if l > 1 { params = getSqlParams(args[1:]) } q, err := sqx.Parse(v, params...) if err != nil { return sim.NullValue, err } obj, err := getQueryObject(q) if err != nil { return sim.NullValue, err } return obj, nil }, }, { Name: "sql.select", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { l := len(args) switch l { case 0: s := selectQuery{&sqx.SelectQuery{}} return sim.NewObject(s), nil } if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected argument to be a string, got %v", args[0].Type) } v := args[0].String() var params []interface{} if l > 1 { params = getSqlParams(args[1:]) } q, err := sqx.Select(v, params...) if err != nil { return sim.NullValue, err } s := selectQuery{q} return sim.NewObject(s), nil }, }, { Name: "sql.where", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { l := len(args) switch l { case 0: s := selectQuery{&sqx.SelectQuery{}} return sim.NewObject(s), nil } if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected argument to be a string, got %v", args[0].Type) } v := args[0].String() var params []interface{} if l > 1 { params = make([]interface{}, l-1) for i, v := range args[1:] { params[i] = v.Export(0) } } q, err := sqx.Where(v, params...) if err != nil { return sim.NullValue, err } s := selectQuery{q} return sim.NewObject(s), nil }, }, { Name: "sql.newAddFKQuery", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { q := addFKQuery{&sqx.AddFKQuery{}} return sim.NewObject(q), nil }, }, { Name: "sql.parse", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) == 0 { return sim.NullValue, fmt.Errorf("expected at least 1 argument") } if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected a string, got %v", args[0]) } sQuery := args[0].String() var params []interface{} if len(args) > 1 { params = getSqlParams(args[1:]) } q, err := sqx.Parse("", "", "", sQuery, params) if err != nil { return sim.NullValue, err } obj, err := getQueryObject(q) if err != nil { return sim.NullValue, err } return obj, nil }, }, }
var SQLQuery = []sim.NativeFunction{ { Name: "sql.getQueries", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } q, err := toQuerySQLQuery(args[0]) if err != nil { return sim.NullValue, err } queries := sqx.GetQueries(q) arr := make([]sim.Value, len(queries)) for i, qq := range queries { v, err := getQueryObjectSQLQuery(qq) if err != nil { return sim.NullValue, err } arr[i] = v } return sim.NewArrayValues(arr), nil }, }, { Name: "sql.getMainTable", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgRange(args, 1, 1); err != nil { return sim.NullValue, err } q, err := toQuerySQLQuery(args[0]) if err != nil { return sim.NullValue, err } t := sqx.GetMainTable(q) if t == nil { return sim.NullValue, nil } return sim.NewObject(&sqxTableQuery{t}), nil }, }, { Name: "sql.hasFilterColumn", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object, sim.String); err != nil { return sim.NullValue, err } q, err := toQuerySQLQuery(args[0]) if err != nil { return sim.NullValue, err } column := args[1].String() b := sqx.HasFilterColumn(q, column) return sim.NewBool(b), nil }, }, { Name: "sql.validateSelect", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object, sim.Map); err != nil { return sim.NullValue, err } s, ok := args[0].ToObjectOrNil().(selectQuery) if !ok { return sim.NullValue, fmt.Errorf("expected argument to be SelectQuery, got %v", args[0].TypeName()) } opt := &sqx.ValidateOptions{} optMap := args[1].ToMap().Map tablesVal, ok := optMap[sim.NewString("tables")] if !ok { return sim.NullValue, fmt.Errorf("invalid options: expected tables") } if tablesVal.Type != sim.Map { return sim.NullValue, fmt.Errorf("invalid tables value: %v", tablesVal) } for k, v := range tablesVal.ToMap().Map { if k.Type != sim.String { return sim.NullValue, fmt.Errorf("invalid table name: %v", k) } if v.Type != sim.Array { return sim.NullValue, fmt.Errorf("invalid tables value for %s: %v", k, v) } colValues := v.ToArray() cols := make([]string, len(colValues)) for i, c := range colValues { if c.Type != sim.String { return sim.NullValue, fmt.Errorf("invalid column value for %s: %v", k, c) } cols[i] = c.String() } opt.Tables = append(opt.Tables, &sqx.ValidateTable{ Name: k.String(), Columns: cols, }) } err := sqx.ValidateSelect(s.query, opt) return sim.NullValue, err }, }, { Name: "sql.newSelect", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { s := selectQuery{&sqx.SelectQuery{}} return sim.NewObject(s), nil }, }, { Name: "sql.parse", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) == 0 { return sim.NullValue, fmt.Errorf("expected at least 1 argument") } if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected a string, got %v", args[0]) } sQuery := args[0].String() var params []interface{} if len(args) > 1 { params = getSqlParamsSQLQuery(args[1:]) } q, err := sqx.Parse("", "", "", sQuery, params) if err != nil { return sim.NullValue, err } return getQueryObjectSQLQuery(q) }, }, { Name: "sql.select", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) == 0 { return sim.NullValue, fmt.Errorf("expected at least 1 argument") } if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected a string, got %v", args[0]) } sQuery := args[0].String() var params []interface{} if len(args) > 1 { params = getSqlParamsSQLQuery(args[1:]) } q, err := sqx.Parse("", "", "", sQuery, params) if err != nil { return sim.NullValue, err } if selectQ, ok := q.(*sqx.SelectQuery); ok { return sim.NewObject(selectQuery{selectQ}), nil } return sim.NullValue, fmt.Errorf("query is not a SELECT statement") }, }, { Name: "sql.where", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) == 0 { return sim.NullValue, fmt.Errorf("expected at least 1 argument") } if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected a string, got %v", args[0]) } whereClause := args[0].String() var params []interface{} if len(args) > 1 { params = getSqlParamsSQLQuery(args[1:]) } sqlStr := "SELECT * FROM dual WHERE " + whereClause q, err := sqx.Parse("", "", "", sqlStr, params) if err != nil { return sim.NullValue, err } if selectQ, ok := q.(*sqx.SelectQuery); ok { return sim.NewObject(selectQuery{selectQ}), nil } return sim.NullValue, fmt.Errorf("failed to create WHERE query") }, }, { Name: "sql.orderBy", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) != 1 { return sim.NullValue, fmt.Errorf("expected 1 argument, got %d", len(args)) } if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected a string, got %v", args[0]) } orderByClause := args[0].String() sqlStr := "SELECT * FROM dual ORDER BY " + orderByClause q, err := sqx.Parse(sqlStr) if err != nil { return sim.NullValue, err } if selectQ, ok := q.(*sqx.SelectQuery); ok { return sim.NewObject(selectQuery{selectQ}), nil } return sim.NullValue, fmt.Errorf("failed to create ORDER BY query") }, }, { Name: "sql.newAddFKQuery", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := addFKQuery{&sqx.AddFKQuery{}} return sim.NewObject(a), nil }, }, }
var SSH = []sim.NativeFunction{ { Name: "ssh.newConfig", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { c := &ssh.ClientConfig{ Timeout: 30 * time.Second, HostKeyCallback: ssh.InsecureIgnoreHostKey(), } return sim.NewObject(&sshConfig{c}), nil }, }, { Name: "ssh.newClient", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.Object); err != nil { return sim.NullValue, err } url := args[0].ToString() config, ok := args[1].ToObjectOrNil().(*sshConfig) if !ok { return sim.NullValue, fmt.Errorf("%v is not a ssh.Config", args[1].TypeName()) } client, err := ssh.Dial("tcp", url, config.c) if err != nil { return sim.NullValue, fmt.Errorf("failed to connect to %s: %v", url, err) } return sim.NewObject(&sshClient{c: client}), nil }, }, }
var STMP = []sim.NativeFunction{ { Name: "smtp.newMessage", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewObject(&SmtMessage{}), nil }, }, { Name: "smtp.send", Arguments: -1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) < 5 || len(args) > 7 { return sim.NullValue, fmt.Errorf("expected 5-7 params, got %d", len(args)) } msg, ok := args[0].ToObject().(*SmtMessage) if !ok { return sim.NullValue, fmt.Errorf("expected a mail message, got %s", args[0].TypeName()) } user := args[1].String() password := args[2].String() host := args[3].String() port := int(args[4].ToInt()) var skipVerify bool = false var timeout time.Duration = 30 * time.Second // timeout por defecto switch len(args) { case 5: case 6: skipVerify = toBoolOrFalse(args[5]) case 7: skipVerify = toBoolOrFalse(args[5]) switch args[6].Type { case sim.Int: timeout = time.Duration(args[6].ToInt()) * time.Second case sim.Null, sim.Undefined: default: return sim.NullValue, fmt.Errorf("argument 7 must be integer (timeout in seconds)") } } err := msg.SendWithTimeout(user, password, host, port, skipVerify, timeout) return sim.NullValue, err }, }, }
var Secure = []sim.NativeFunction{ { Name: "secure.newObject", Arguments: -1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { ln := len(args) if ln < 2 || ln > 3 { return sim.NullValue, fmt.Errorf("expected 2 or 3 arguments, got %d", ln) } if args[0].Type != sim.Bool { return sim.NullValue, fmt.Errorf("expected argument 1 to be bool, got %s", args[0].Type) } if args[1].Type != sim.Bool { return sim.NullValue, fmt.Errorf("expected argument 2 to be bool, got %s", args[1].Type) } p := &SecureObject{ values: make(map[string]sim.Value), read: args[0].ToBool(), write: args[1].ToBool(), } if ln == 3 { for k, v := range args[2].ToMap().Map { p.values[k.String()] = v } } return sim.NewObject(p), nil }, }, }
var Strconv = []sim.NativeFunction{ { Name: "strconv.formatRef", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Int, sim.Int); err != nil { return sim.NullValue, err } s := EncodeCustomBase34(uint64(args[0].ToInt())) var size int if len(args) > 1 { size = int(args[1].ToInt()) } else { size = 15 } if size > 0 { s += customBase34Delimiter + RandomAlphanumeric(size) } return sim.NewString(strings.ToUpper(s)), nil }, }, { Name: "strconv.parseRef", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } s := args[0].String() i := strings.IndexRune(s, 'L') if i != -1 { s = s[:i] } v := DecodeCustomBase34(s) return sim.NewInt64(int64(v)), nil }, }, { Name: "strconv.formatInt", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int, sim.Int); err != nil { return sim.NullValue, err } v := strconv.FormatInt(args[0].ToInt(), int(args[1].ToInt())) return sim.NewString(v), nil }, }, { Name: "strconv.parseInt", Arguments: 3, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.Int, sim.Int); err != nil { return sim.NullValue, err } s := args[0].String() s = strings.Trim(s, " ") if len(s) > 1 { s = strings.TrimLeft(s, "0") } v, err := strconv.ParseInt(s, int(args[1].ToInt()), int(args[2].ToInt())) if err != nil { return sim.NullValue, err } return sim.NewInt64(v), nil }, }, { Name: "strconv.formatCustomBase34", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int); err != nil { return sim.NullValue, err } v := EncodeCustomBase34(uint64(args[0].ToInt())) return sim.NewString(v), nil }, }, { Name: "strconv.parseCustomBase34", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } v := DecodeCustomBase34(args[0].String()) return sim.NewInt64(int64(v)), nil }, }, }
var Strings = []sim.NativeFunction{ { Name: "String", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Int, sim.Float, sim.String, sim.Bool); err != nil { return sim.NullValue, err } if len(args) == 0 { return sim.NewString(""), nil } arg := args[0] switch arg.Type { case sim.String: return args[0], nil default: return sim.NewString(args[0].String()), nil } }, }, { Name: "String.fromCharCode", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var code int64 switch args[0].Type { case sim.Int: code = args[0].ToInt() case sim.Float: code = int64(args[0].ToFloat()) default: return sim.NullValue, fmt.Errorf("expected number, got %s", args[0].TypeName()) } code = code & 0xFFFF return sim.NewString(string(rune(code))), nil }, }, { Name: "strings.sanitize", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String, sim.Bool); err != nil { return sim.NullValue, err } if err := ValidateArgRange(args, 1, 2); err != nil { return sim.NullValue, err } s := args[0].String() var dashes bool if len(args) == 2 { dashes = args[1].ToBool() } var lastDash bool buf := make([]rune, 0, len(s)) for _, r := range s { if isAlphanumeric(r, 1) { buf = append(buf, r) lastDash = false } else { if dashes && !lastDash { buf = append(buf, '-') } lastDash = true } } return sim.NewString(string(buf)), nil }, }, { Name: "strings.newReader", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } r := strings.NewReader(args[0].String()) return sim.NewObject(&reader{r}), nil }, }, { Name: "String.prototype.runeAt", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] if a.Type != sim.Int { return sim.NullValue, fmt.Errorf("expected int, got %s", a.Type) } i := int(a.ToInt()) if i < 0 { return sim.NullValue, vm.NewError("Index out of range in string") } v := utf8string.NewString(this.String()) if int(i) >= v.RuneCount() { return sim.NullValue, vm.NewError("Index out of range in string") } return sim.NewRune(v.At(int(i))), nil }, }, { Name: "strings.equalFold", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] b := args[1] switch a.Type { case sim.Null, sim.Undefined: switch b.Type { case sim.Null, sim.Undefined: return sim.TrueValue, nil case sim.String: return sim.FalseValue, nil default: return sim.NullValue, fmt.Errorf("expected argument 2 to be string got %v", b.Type) } case sim.String: default: return sim.NullValue, fmt.Errorf("expected argument 1 to be string got %v", a.Type) } switch b.Type { case sim.Null, sim.Undefined: return sim.FalseValue, nil case sim.String: default: return sim.NullValue, fmt.Errorf("expected argument 2 to be string got %v", b.Type) } eq := strings.EqualFold(a.String(), b.String()) return sim.NewBool(eq), nil }, }, { Name: "strings.isIdent", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0] switch v.Type { case sim.String, sim.Rune: default: return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", v.TypeName()) } b := IsIdent(v.String()) return sim.NewBool(b), nil }, }, { Name: "strings.isAlphanumeric", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0] switch v.Type { case sim.String, sim.Rune: default: return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", v.TypeName()) } b := IsAlphanumeric(v.String()) return sim.NewBool(b), nil }, }, { Name: "strings.isAlphanumericIdent", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0] switch v.Type { case sim.String, sim.Rune: default: return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", v.TypeName()) } b := IsAlphanumericIdent(v.String()) return sim.NewBool(b), nil }, }, { Name: "strings.isNumeric", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0] switch v.Type { case sim.String, sim.Rune: case sim.Int, sim.Float: return sim.TrueValue, nil default: return sim.FalseValue, nil } b := IsNumeric(v.String()) return sim.NewBool(b), nil }, }, { Name: "strings.isEmpty", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0] switch v.Type { case sim.Null, sim.Undefined: return sim.TrueValue, nil case sim.String, sim.Rune: return sim.NewBool(v.String() == ""), nil default: return sim.FalseValue, nil } }, }, { Name: "strings.isChar", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0] switch v.Type { case sim.String, sim.Rune: default: return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", args[0].TypeName()) } s := v.String() if len(s) != 1 { return sim.FalseValue, nil } r := rune(s[0]) if 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' { return sim.TrueValue, nil } return sim.FalseValue, nil }, }, { Name: "strings.isDigit", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { v := args[0] switch v.Type { case sim.String, sim.Rune: default: return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", args[0].TypeName()) } s := v.String() if len(s) != 1 { return sim.FalseValue, nil } r := rune(s[0]) if '0' <= r && r <= '9' { return sim.TrueValue, nil } return sim.FalseValue, nil }, }, { Name: "strings.sort", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if args[0].Type != sim.Array { return sim.NullValue, fmt.Errorf("expected arg 1 to be array, got %s", args[0].TypeName()) } a := args[0].ToArray() s := make([]string, len(a)) for i, v := range a { s[i] = v.String() } sort.Strings(s) for i, v := range s { a[i] = sim.NewString(v) } return sim.NullValue, nil }, }, { Name: "strings.repeat", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String, sim.Int); err != nil { return sim.NullValue, err } a := args[0].String() b := int(args[1].ToInt()) values := make([]string, b) for i := 0; i < b; i++ { values[i] = a } s := strings.Join(values, "") return sim.NewString(s), nil }, }, { Name: "String.prototype.replaceRegex", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { exp := args[0].String() repl := args[1].String() s := this.String() r, err := regexp.Compile(exp) if err != nil { return sim.NullValue, err } return sim.NewString(r.ReplaceAllString(s, repl)), nil }, }, { Name: "String.prototype.toLowerCase", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { s := this.String() return sim.NewString(strings.ToLower(s)), nil }, }, { Name: "String.prototype.toUpperCase", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { s := this.String() return sim.NewString(strings.ToUpper(s)), nil }, }, { Name: "String.prototype.toTitle", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { s := this.String() if len(s) > 0 { s = strings.ToUpper(s[:1]) + s[1:] } return sim.NewString(s), nil }, }, { Name: "String.prototype.toUntitle", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { s := this.String() if len(s) > 0 { s = strings.ToLower(s[:1]) + s[1:] } return sim.NewString(s), nil }, }, { Name: "String.prototype.fields", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { s := this.String() parts := strings.Fields(s) res := make([]sim.Value, len(parts)) for i, v := range parts { res[i] = sim.NewString(v) } return sim.NewArrayValues(res), nil }, }, { Name: "String.prototype.trim", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var cutset string switch len(args) { case 0: cutset = " \t\r\n" case 1: cutset = args[0].String() default: return sim.NullValue, fmt.Errorf("expected 0 or 1 arguments, got %d", len(args)) } s := this.String() return sim.NewString(strings.Trim(s, cutset)), nil }, }, { Name: "String.prototype.trimLeft", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var cutset string switch len(args) { case 0: cutset = " \t\r\n" case 1: cutset = args[0].String() default: return sim.NullValue, fmt.Errorf("expected 0 or 1 arguments, got %d", len(args)) } s := this.String() return sim.NewString(strings.TrimLeft(s, cutset)), nil }, }, { Name: "String.prototype.trimRight", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var cutset string switch len(args) { case 0: cutset = " \t\r\n" case 1: cutset = args[0].String() default: return sim.NullValue, fmt.Errorf("expected 0 or 1 arguments, got %d", len(args)) } s := this.String() return sim.NewString(strings.TrimRight(s, cutset)), nil }, }, { Name: "String.prototype.trimPrefix", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", args[0].TypeName()) } s := this.String() prefix := args[0].String() s = strings.TrimPrefix(s, prefix) return sim.NewString(s), nil }, }, { Name: "String.prototype.trimSuffix", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", args[0].TypeName()) } s := this.String() prefix := args[0].String() s = strings.TrimSuffix(s, prefix) return sim.NewString(s), nil }, }, { Name: "String.prototype.substring", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { s := this.String() switch len(args) { case 1: v1 := args[0] if v1.Type != sim.Int { return sim.NullValue, fmt.Errorf("expected int, got %s", v1.Type) } a := int(v1.ToInt()) if a < 0 || a > len(s) { return sim.NullValue, fmt.Errorf("index out of range: %d of %d", a, len(s)) } return sim.NewString(s[a:]), nil case 2: v1 := args[0] if v1.Type != sim.Int { return sim.NullValue, fmt.Errorf("expected int, got %s", v1.Type) } v2 := args[1] if v2.Type != sim.Int { return sim.NullValue, fmt.Errorf("expected int, got %s", v2.Type) } l := len(s) a := int(v1.ToInt()) b := int(v2.ToInt()) if a < 0 || a > l { return sim.NullValue, fmt.Errorf("start out of range") } if b < a || b > l { return sim.NullValue, fmt.Errorf("end out of range") } return sim.NewString(s[a:b]), nil } return sim.NullValue, fmt.Errorf("expected 1 or 2 parameters") }, }, { Name: "String.prototype.runeSubstring", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { s := this.String() switch len(args) { case 1: v1 := args[0] if v1.Type != sim.Int { return sim.NullValue, fmt.Errorf("expected int, got %s", v1.Type) } a := int(v1.ToInt()) if a < 0 || a > len(s) { return sim.NullValue, fmt.Errorf("index out of range: %d of %d", a, len(s)) } return sim.NewString(substring(s, a, -1)), nil case 2: v1 := args[0] if v1.Type != sim.Int { return sim.NullValue, fmt.Errorf("expected int, got %s", v1.Type) } v2 := args[1] if v2.Type != sim.Int { return sim.NullValue, fmt.Errorf("expected int, got %s", v2.Type) } l := len(s) a := int(v1.ToInt()) b := int(v2.ToInt()) if a < 0 || a > l { return sim.NullValue, fmt.Errorf("start out of range") } if b < a || b > l { return sim.NullValue, fmt.Errorf("end out of range") } return sim.NewString(substring(s, a, b)), nil } return sim.NullValue, fmt.Errorf("expected 1 or 2 parameters") }, }, { Name: "String.prototype.take", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if args[0].Type != sim.Int { return sim.NullValue, fmt.Errorf("expected arg 1 to be int, got %s", args[0].TypeName()) } s := this.String() i := int(args[0].ToInt()) if i < 0 { return sim.NullValue, fmt.Errorf("index out of range: %d", i) } if len(s) > i { s = s[:i] } return sim.NewString(s), nil }, }, { Name: "String.prototype.startsWith", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", args[0].TypeName()) } v := args[0].String() s := this.String() return sim.NewBool(strings.HasPrefix(s, v)), nil }, }, { Name: "String.prototype.endsWith", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", args[0].TypeName()) } v := args[0].String() s := this.String() return sim.NewBool(strings.HasSuffix(s, v)), nil }, }, { Name: "String.prototype.cut", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { ln := len(args) s := this.String() var start int if len(args) > 1 { start = int(args[1].ToInt()) if start < 0 || start > len(s) { res := make([]sim.Value, 2) res[0] = sim.NewString(s) res[1] = sim.NewString("") return sim.NewArrayValues(res), nil } s = s[start:] } if ln > 1 { if args[1].Type != sim.Int { return sim.NullValue, fmt.Errorf("expected arg 2 to be int, got %s", args[1].TypeName()) } } var width int var index int switch args[0].Type { case sim.String: separator := args[0].String() width = len(separator) index = strings.Index(s, separator) + start case sim.Rune: separator := args[0].ToRune() width = runewidth.RuneWidth(separator) if width == 0 { width = 1 } index = strings.IndexRune(s, separator) + start default: return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", args[0].TypeName()) } if index == -1 { res := make([]sim.Value, 2) res[0] = sim.NewString(s) res[1] = sim.NewString("") return sim.NewArrayValues(res), nil } res := make([]sim.Value, 2) res[0] = sim.NewString(s[0:index]) res[1] = sim.NewString(s[index+width:]) return sim.NewArrayValues(res), nil }, }, { Name: "String.prototype.indexOfRelative", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { s := this.String() var i int if len(args) > 1 { vStart := args[1] if vStart.Type != sim.Int { return sim.NullValue, fmt.Errorf("expected arg 2 to be int, got %s", vStart.TypeName()) } i = int(vStart.ToInt()) if i < 0 || i > len(s) { return sim.NullValue, fmt.Errorf("index out of range") } s = s[i:] } switch args[0].Type { case sim.String: return sim.NewInt(strings.Index(s, args[0].String())), nil case sim.Rune: return sim.NewInt(strings.IndexRune(s, args[0].ToRune())), nil default: return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", args[0].TypeName()) } }, }, { Name: "String.prototype.indexOf", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { s := this.String() searchStr := "" fromIndex := 0 switch args[0].Type { case sim.String: searchStr = args[0].String() case sim.Rune: searchStr = string(args[0].ToRune()) default: return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", args[0].TypeName()) } if len(args) > 1 { vStart := args[1] if vStart.Type != sim.Int { return sim.NullValue, fmt.Errorf("expected arg 2 to be int, got %s", vStart.TypeName()) } fromIndex = int(vStart.ToInt()) if fromIndex < 0 { fromIndex = 0 } } if fromIndex >= len(s) { return sim.NewInt(-1), nil } pos := strings.Index(s[fromIndex:], searchStr) if pos == -1 { return sim.NewInt(-1), nil } return sim.NewInt(pos + fromIndex), nil }, }, { Name: "String.prototype.lastIndexOf", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { ln := len(args) if ln > 0 { if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", args[0].TypeName()) } } if ln > 1 { if args[1].Type != sim.Int { return sim.NullValue, fmt.Errorf("expected arg 2 to be int, got %s", args[1].TypeName()) } } sep := args[0].String() s := this.String() if len(args) > 1 { i := int(args[1].ToInt()) if i > len(s) { return sim.NullValue, fmt.Errorf("index out of range") } s = s[i:] } return sim.NewInt(strings.LastIndex(s, sep)), nil }, }, { Name: "String.prototype.contains", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { switch args[0].Type { case sim.String, sim.Rune: default: return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", args[0].TypeName()) } sep := args[0].String() s := this.String() return sim.NewBool(strings.Contains(s, sep)), nil }, }, { Name: "String.prototype.rightPad", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", args[0].TypeName()) } if args[1].Type != sim.Int { return sim.NullValue, fmt.Errorf("expected arg 2 to be int, got %s", args[1].TypeName()) } pad := args[0].String() if len(pad) != 1 { return sim.NullValue, fmt.Errorf("invalid pad size. Must be one character") } total := int(args[1].ToInt()) s := this.String() return sim.NewString(rightPad(s, rune(pad[0]), total)), nil }, }, { Name: "String.prototype.leftPad", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", args[0].TypeName()) } if args[1].Type != sim.Int { return sim.NullValue, fmt.Errorf("expected arg 2 to be int, got %s", args[1].TypeName()) } pad := args[0].String() if len(pad) != 1 { return sim.NullValue, fmt.Errorf("invalid pad size. Must be one character") } total := int(args[1].ToInt()) s := this.String() return sim.NewString(leftPad(s, rune(pad[0]), total)), nil }, }, { Name: "String.prototype.equalFold", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("expected arg 1 to be string, got %s", args[0].TypeName()) } eq := strings.EqualFold(this.String(), args[0].String()) return sim.NewBool(eq), nil }, }, { Name: "String.prototype.repeat", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int); err != nil { return sim.NullValue, err } s := this.String() count := int(args[0].ToInt()) if count < 0 { return sim.NullValue, fmt.Errorf("repeat count must be non-negative") } return sim.NewString(strings.Repeat(s, count)), nil }, }, { Name: "String.prototype.at", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int); err != nil { return sim.NullValue, err } s := this.String() index := int(args[0].ToInt()) runes := []rune(s) length := len(runes) if index < 0 { index = length + index } if index < 0 || index >= length { return sim.NullValue, nil } return sim.NewString(string(runes[index])), nil }, }, { Name: "String.prototype.charCodeAt", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int); err != nil { return sim.NullValue, err } s := this.String() index := int(args[0].ToInt()) if index < 0 || index >= len(s) { return sim.NewFloat(math.NaN()), nil } return sim.NewInt64(int64(s[index])), nil }, }, { Name: "String.prototype.codePointAt", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int); err != nil { return sim.NullValue, err } s := this.String() index := int(args[0].ToInt()) if index < 0 || index >= len(s) { return sim.NullValue, nil } r, _ := utf8.DecodeRuneInString(s[index:]) if r == utf8.RuneError { return sim.NullValue, nil } return sim.NewInt64(int64(r)), nil }, }, { Name: "String.prototype.includes", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) < 1 || len(args) > 2 { return sim.NullValue, fmt.Errorf("expected 1 or 2 arguments, got %d", len(args)) } s := this.String() searchString := args[0].String() // Segundo parámetro opcional: posición desde donde empezar a buscar var startPos int if len(args) == 2 { startPos = int(args[1].ToInt()) if startPos < 0 { startPos = 0 } if startPos >= len(s) { return sim.FalseValue, nil } s = s[startPos:] } return sim.NewBool(strings.Contains(s, searchString)), nil }, }, { Name: "String.prototype.slice", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) < 1 || len(args) > 2 { return sim.NullValue, fmt.Errorf("expected 1 or 2 arguments, got %d", len(args)) } s := this.String() runes := []rune(s) length := len(runes) start := int(args[0].ToInt()) if start < 0 { start = length + start } if start < 0 { start = 0 } if start > length { start = length } end := length if len(args) == 2 { end = int(args[1].ToInt()) if end < 0 { end = length + end } if end < 0 { end = 0 } if end > length { end = length } } if start >= end { return sim.NewString(""), nil } return sim.NewString(string(runes[start:end])), nil }, }, { Name: "String.prototype.concat", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { s := this.String() for _, arg := range args { s += arg.String() } return sim.NewString(s), nil }, }, { Name: "String.prototype.trimStart", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var cutset string switch len(args) { case 0: cutset = " \t\r\n" case 1: cutset = args[0].String() default: return sim.NullValue, fmt.Errorf("expected 0 or 1 arguments, got %d", len(args)) } s := this.String() return sim.NewString(strings.TrimLeft(s, cutset)), nil }, }, { Name: "String.prototype.trimEnd", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var cutset string switch len(args) { case 0: cutset = " \t\r\n" case 1: cutset = args[0].String() default: return sim.NullValue, fmt.Errorf("expected 0 or 1 arguments, got %d", len(args)) } s := this.String() return sim.NewString(strings.TrimRight(s, cutset)), nil }, }, { Name: "String.prototype.localeCompare", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) < 1 { return sim.NullValue, fmt.Errorf("expected at least 1 argument, got %d", len(args)) } s1 := this.String() s2 := args[0].String() if s1 < s2 { return sim.NewInt(-1), nil } else if s1 > s2 { return sim.NewInt(1), nil } return sim.NewInt(0), nil }, }, { Name: "String.prototype.match", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) != 1 { return sim.NullValue, fmt.Errorf("expected 1 argument, got %d", len(args)) } text := this.String() if regexWrapper, ok := args[0].ToObjectOrNil().(*jsRegExpWrapper); ok { pattern := "/" + regexWrapper.re.Source() + "/" + regexWrapper.re.Flags() result := jsregex.Match(text, pattern) if result == nil { return sim.NullValue, nil } values := make([]sim.Value, len(result)) for i, s := range result { values[i] = sim.NewString(s) } return sim.NewArrayValues(values), nil } else { pattern := args[0].String() result := jsregex.Match(text, pattern) if result == nil { return sim.NullValue, nil } values := make([]sim.Value, len(result)) for i, s := range result { values[i] = sim.NewString(s) } return sim.NewArrayValues(values), nil } }, }, { Name: "String.prototype.search", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) != 1 { return sim.NullValue, fmt.Errorf("expected 1 argument, got %d", len(args)) } text := this.String() if regexWrapper, ok := args[0].ToObjectOrNil().(*jsRegExpWrapper); ok { pattern := "/" + regexWrapper.re.Source() + "/" + regexWrapper.re.Flags() result := jsregex.Search(text, pattern) return sim.NewInt(result), nil } else { pattern := args[0].String() result := jsregex.Search(text, pattern) return sim.NewInt(result), nil } }, }, { Name: "String.prototype.replace", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) != 2 { return sim.NullValue, fmt.Errorf("expected 2 arguments, got %d", len(args)) } text := this.String() replacement := args[1].String() if regexWrapper, ok := args[0].ToObjectOrNil().(*jsRegExpWrapper); ok { pattern := "/" + regexWrapper.re.Source() + "/" + regexWrapper.re.Flags() result := jsregex.Replace(text, pattern, replacement) return sim.NewString(result), nil } else { oldStr := args[0].String() result := strings.Replace(text, oldStr, replacement, 1) return sim.NewString(result), nil } }, }, { Name: "String.prototype.replaceAll", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) != 2 { return sim.NullValue, fmt.Errorf("expected 2 arguments, got %d", len(args)) } text := this.String() replacement := args[1].String() if regexWrapper, ok := args[0].ToObjectOrNil().(*jsRegExpWrapper); ok { pattern := "/" + regexWrapper.re.Source() + "/" + regexWrapper.re.Flags() result := jsregex.ReplaceAll(text, pattern, replacement) return sim.NewString(result), nil } else { oldStr := args[0].String() result := strings.ReplaceAll(text, oldStr, replacement) return sim.NewString(result), nil } }, }, { Name: "String.prototype.splitClean", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { sep := args[0].String() s := this.String() parts := Split(s, sep) res := make([]sim.Value, len(parts)) for i, v := range parts { res[i] = sim.NewString(v) } return sim.NewArrayValues(res), nil }, }, { Name: "String.prototype.split", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) < 1 || len(args) > 2 { return sim.NullValue, fmt.Errorf("expected 1 or 2 arguments, got %d", len(args)) } text := this.String() if regexWrapper, ok := args[0].ToObjectOrNil().(*jsRegExpWrapper); ok { pattern := "/" + regexWrapper.re.Source() + "/" + regexWrapper.re.Flags() var result []string if len(args) == 2 { limit := int(args[1].ToInt()) result = jsregex.Split(text, pattern, limit) } else { result = jsregex.Split(text, pattern) } values := make([]sim.Value, len(result)) for i, s := range result { values[i] = sim.NewString(s) } return sim.NewArrayValues(values), nil } else { sep := args[0].String() if sep == "" { runes := []rune(text) values := make([]sim.Value, len(runes)) for i, r := range runes { values[i] = sim.NewString(string(r)) } return sim.NewArrayValues(values), nil } parts := strings.Split(text, sep) if len(args) == 2 { limit := int(args[1].ToInt()) if limit > 0 && len(parts) > limit { parts = parts[:limit] } } values := make([]sim.Value, len(parts)) for i, s := range parts { values[i] = sim.NewString(s) } return sim.NewArrayValues(values), nil } }, }, { Name: "String.prototype.matchAll", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) != 1 { return sim.NullValue, fmt.Errorf("expected 1 argument, got %d", len(args)) } text := this.String() if regexWrapper, ok := args[0].ToObjectOrNil().(*jsRegExpWrapper); ok { pattern := "/" + regexWrapper.re.Source() + "/" + regexWrapper.re.Flags() result := jsregex.MatchAll(text, pattern) if result == nil { return sim.NullValue, nil } values := make([]sim.Value, len(result)) for i, match := range result { matchValues := make([]sim.Value, len(match)) for j, s := range match { matchValues[j] = sim.NewString(s) } values[i] = sim.NewArrayValues(matchValues) } return sim.NewArrayValues(values), nil } else { pattern := args[0].String() result := jsregex.MatchAll(text, pattern) if result == nil { return sim.NullValue, nil } values := make([]sim.Value, len(result)) for i, match := range result { matchValues := make([]sim.Value, len(match)) for j, s := range match { matchValues[j] = sim.NewString(s) } values[i] = sim.NewArrayValues(matchValues) } return sim.NewArrayValues(values), nil } }, }, }
var Sunrise = []sim.NativeFunction{ { Name: "astro.sunRiseSet", Arguments: 3, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Float, sim.Float, sim.Object); err != nil { return sim.NullValue, err } lat := args[0].ToFloat() long := args[1].ToFloat() t, ok := args[2].ToObject().(TimeObj) if !ok { return sim.NullValue, ErrInvalidType } d := time.Time(t) rise, set := sunrise.SunriseSunset(lat, long, d.Year(), d.Month(), d.Day()) loc := GetLocation(vm) m := make(map[sim.Value]sim.Value, 2) m[sim.NewString("rise")] = sim.NewObject(TimeObj(rise.In(loc))) m[sim.NewString("set")] = sim.NewObject(TimeObj(set.In(loc))) return sim.NewMapValues(m, false), nil }, }, }
var Sync = []sim.NativeFunction{ { Name: "sync.withDeadline", Arguments: 2, Permissions: []string{"sync"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { d, err := ToDuration(args[0]) if err != nil { return sim.NullValue, err } v := args[1] switch v.Type { case sim.Func: case sim.Object: default: return sim.NullValue, fmt.Errorf("%v is not a function", v.TypeName()) } err = WithDeadline(d, func(dl *Deadline) error { obj := sim.NewObject(dl) return runAsyncFuncOrClosure(vm, v, obj) }) return sim.NullValue, err }, }, { Name: "sync.newWaitGroup", Arguments: -1, Permissions: []string{"sync"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Int); err != nil { return sim.NullValue, err } wg := &waitGroup{w: &sync.WaitGroup{}} if len(args) == 1 { concurrency := int(args[0].ToInt()) wg.limit = make(chan bool, concurrency) } return sim.NewObject(wg), nil }, }, { Name: "sync.newChannel", Arguments: -1, Permissions: []string{"sync"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Int); err != nil { return sim.NullValue, err } var ch chan sim.Value var b int if len(args) > 0 { b = int(args[0].ToInt()) ch = make(chan sim.Value, b) } else { ch = make(chan sim.Value) } c := &channel{buffer: b, c: ch} return sim.NewObject(c), nil }, }, { Name: "sync.select", Arguments: -1, Permissions: []string{"sync"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { argLen := len(args) if argLen == 0 || argLen > 2 { return sim.NullValue, fmt.Errorf("expected 1 or 2 args, got %d", argLen) } a := args[0] if a.Type != sim.Array { return sim.NullValue, fmt.Errorf("expected arg 1 to be an array of channels, got %s", a.TypeName()) } chans := a.ToArray() l := len(chans) cases := make([]reflect.SelectCase, l) for i, c := range chans { ch := c.ToObjectOrNil().(*channel) if ch == nil { return sim.NullValue, fmt.Errorf("invalid channel at index %d", i) } cases[i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch.c)} } if argLen == 2 { b := args[1] if b.Type != sim.Bool { return sim.NullValue, fmt.Errorf("expected arg 2 to be a bool, got %s", b.TypeName()) } if b.ToBool() { cases = append(cases, reflect.SelectCase{Dir: reflect.SelectDefault}) } } i, value, ok := reflect.Select(cases) m := make(map[sim.Value]sim.Value, 3) m[sim.NewString("index")] = sim.NewInt(i) if value.IsValid() { m[sim.NewString("value")] = value.Interface().(sim.Value) } m[sim.NewString("receivedOK")] = sim.NewBool(ok) return sim.NewMapValues(m, true), nil }, }, { Name: "sync.newMutex", Arguments: 0, Permissions: []string{"sync"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { m := &mutex{mutex: sync.Mutex{}} return sim.NewObject(m), nil }, }, }
var TLS = []sim.NativeFunction{ { Name: "autocert.newCertManager", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgRange(args, 2, 3); err != nil { return sim.NullValue, err } var cache *autocertCache ln := len(args) if ln < 2 || ln > 3 { return sim.NullValue, fmt.Errorf("expected 2 or 3 arguments, got %d", ln) } if !isStringLike(args[0]) { return sim.NullValue, fmt.Errorf("invalid cache directory: %s", args[0].TypeName()) } cacheDir := args[0].String() var hostPolicy autocert.HostPolicy switch args[1].Type { case sim.Array: domainValues := args[1].ToArray() domains := make([]string, len(domainValues)) for i, v := range domainValues { domains[i] = v.String() } hostPolicy = autocert.HostWhitelist(domains...) case sim.Func: hostPolicy = func(ctx context.Context, host string) error { vm = vm.CloneInitialized(vm.Program, vm.Globals()) vm.Async = true _, err := vm.RunFuncIndex(args[1].ToFunction(), sim.NewString(host)) return err } case sim.Object: c, ok := args[1].ToObjectOrNil().(*sim.Closure) if !ok { return sim.NullValue, fmt.Errorf("%v is not a function", args[1].TypeName()) } hostPolicy = func(ctx context.Context, host string) error { vm = vm.CloneInitialized(vm.Program, vm.Globals()) vm.Async = true _, err := vm.RunClosure(c, sim.NewString(host)) return err } default: return sim.NullValue, fmt.Errorf("invalid domains or hostPolicy: %s", args[1].TypeName()) } if ln == 3 { var ok bool cache, ok = args[2].ToObjectOrNil().(*autocertCache) if !ok { return sim.NullValue, fmt.Errorf("invalid cache: %s", args[2].TypeName()) } } if cache == nil { cache = &autocertCache{fs: vm.FileSystem} } cache.dir = cacheDir m := autocert.Manager{ Cache: cache, Prompt: autocert.AcceptTOS, HostPolicy: hostPolicy, } cm := &certManager{&m} return sim.NewObject(cm), nil }, }, { Name: "autocert.newFileSystemCache", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } fs, ok := args[0].ToObject().(*FileSystemObj) if !ok { return sim.NullValue, fmt.Errorf("invalid filesystem argument, got %v", args[0]) } c := &autocertCache{fs: fs.FS} return sim.NewObject(c), nil }, }, { Name: "tls.newConfig", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgRange(args, 0, 1); err != nil { return sim.NullValue, err } if err := ValidateOptionalArgs(args, sim.Bool); err != nil { return sim.NullValue, err } tc := &tlsConfig{ conf: &tls.Config{ MinVersion: tls.VersionTLS12, CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256}, PreferServerCipherSuites: true, }, } if len(args) == 1 { tc.conf.InsecureSkipVerify = args[0].ToBool() } return sim.NewObject(tc), nil }, }, { Name: "tls.generateCert", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { priv, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) if err != nil { log.Fatal(err) } template := x509.Certificate{ SerialNumber: big.NewInt(1), Subject: pkix.Name{ Organization: []string{"Acme Co"}, }, NotBefore: time.Now(), NotAfter: time.Now().Add(time.Hour * 24 * 180), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) if err != nil { return sim.Value{}, fmt.Errorf("failed to create certificate: %s", err) } pubBuf := new(bytes.Buffer) err = pem.Encode(pubBuf, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) if err != nil { return sim.Value{}, fmt.Errorf("failed to write data to cert.pem: %w", err) } privBuf := new(bytes.Buffer) privBytes, err := x509.MarshalPKCS8PrivateKey(priv) if err != nil { return sim.Value{}, fmt.Errorf("unable to marshal private key: %w", err) } err = pem.Encode(privBuf, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}) if err != nil { return sim.Value{}, fmt.Errorf("failed to write data to key.pem: %w", err) } c := &certificate{ cert: pubBuf.Bytes(), key: privBuf.Bytes(), } return sim.NewObject(c), nil }, }, }
var Templates = []sim.NativeFunction{ { Name: "templates.render", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return render("", args, vm) }, }, { Name: "templates.renderHTML", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return render("html", args, vm) }, }, { Name: "templates.renderXML", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return render("xml", args, vm) }, }, }
var Terminal = []sim.NativeFunction{}/* 118 elements not displayed */
var Time = []sim.NativeFunction{ { Name: "->time.Monday", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(time.Monday)), nil }, }, { Name: "->time.Tuesday", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(time.Tuesday)), nil }, }, { Name: "->time.Wednesday", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(time.Wednesday)), nil }, }, { Name: "->time.Thursday", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(time.Thursday)), nil }, }, { Name: "->time.Friday", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(time.Friday)), nil }, }, { Name: "->time.Saturday", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(time.Saturday)), nil }, }, { Name: "->time.Sunday", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(time.Sunday)), nil }, }, { Name: "->time.SecMillis", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(secMillis)), nil }, }, { Name: "->time.MinMillis", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(minMillis)), nil }, }, { Name: "->time.HourMillis", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(hourMillis)), nil }, }, { Name: "->time.DayMillis", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(dayMillis)), nil }, }, { Name: "->time.Nanosecond", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(time.Nanosecond)), nil }, }, { Name: "->time.Microsecond", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(time.Microsecond)), nil }, }, { Name: "->time.Millisecond", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(time.Millisecond)), nil }, }, { Name: "->time.Second", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt(int(time.Second)), nil }, }, { Name: "->time.Minute", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt64(int64(time.Minute)), nil }, }, { Name: "->time.Hour", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewInt64(int64(time.Hour)), nil }, }, { Name: "->time.RFC3339", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewString(time.RFC3339), nil }, }, { Name: "->time.DefaultDateFormat", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewString("2006-1-2"), nil }, }, { Name: "time.date", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { loc := GetLocation(vm) return getDate(args, vm, loc) }, }, { Name: "time.parseDaysOfWeek", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } s := args[0].String() values := make([]sim.Value, len(s)) for i, r := range s { values[i] = sim.NewInt(int(r - '0')) } return sim.NewArrayValues(values), nil }, }, { Name: "time.parseDuration", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] switch a.Type { case sim.Object: if _, ok := a.ToObject().(Duration); !ok { return sim.NullValue, fmt.Errorf("expected time.Duration, got %s", a.TypeName()) } return a, nil case sim.Int: return sim.NewObject(Duration(a.ToInt() * int64(time.Millisecond))), nil case sim.String: v := a.String() if IsNumeric(v) { i, err := strconv.Atoi(v) if err != nil { return sim.NullValue, sim.NewCodeError(100005, "invalid format %s. Expected an int", v) } return sim.NewObject(Duration(int64(i) * int64(time.Millisecond))), nil } if strings.ContainsRune(v, ':') { d, err := parseTime(v) if err != nil { return sim.NullValue, err } return d, nil } return parseDuration(v) default: return sim.NullValue, fmt.Errorf("expected string, got %s", a.TypeName()) } }, }, { Name: "time.parseTime", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] switch a.Type { case sim.Object: if _, ok := a.ToObject().(Duration); !ok { return sim.NullValue, fmt.Errorf("expected time.Duration, got %s", a.TypeName()) } return a, nil case sim.Int: return sim.NewObject(Duration(a.ToInt() * int64(time.Millisecond))), nil case sim.String: v := args[0].String() if IsNumeric(v) { i, err := strconv.Atoi(v) if err != nil { return sim.NullValue, sim.NewCodeError(100005, "invalid format %s. Expected an int", v) } return sim.NewObject(Duration(int64(i) * int64(time.Millisecond))), nil } parts := Split(v, ":") ln := len(parts) if ln < 2 || ln > 3 { return sim.NullValue, sim.NewCodeError(100005, "invalid time. Format is for example 18:30") } first, period, found := strings.Cut(parts[ln-1], " ") if found { switch period { case "am", "AM": parts[ln-1] = first case "pm", "PM": parts[ln-1] = first period = "pm" } } h, err := strconv.Atoi(parts[0]) if err != nil { return sim.NullValue, sim.NewCodeError(100005, "invalid hour part %s. Expected an int", parts[0]) } if period == "pm" && h < 12 { h += 12 } m, err := strconv.Atoi(parts[1]) if err != nil { return sim.NullValue, sim.NewCodeError(100005, "invalid min part %s. Expected an int", parts[1]) } var s int if ln > 2 { s, err = strconv.Atoi(parts[2]) if err != nil { return sim.NullValue, sim.NewCodeError(100005, "invalid sec part %s. Expected an int", parts[2]) } } d := time.Duration(h)*time.Hour + time.Duration(m)*time.Minute + time.Duration(s)*time.Second return sim.NewObject(Duration(d)), nil default: return sim.NullValue, fmt.Errorf("expected string, got %s", a.TypeName()) } }, }, { Name: "time.durationNS", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int); err != nil { return sim.NullValue, err } d, err := ToDuration(args[0]) if err != nil { return sim.NullValue, err } return sim.NewObject(Duration(d)), nil }, }, { Name: "time.toDuration", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Int, sim.Int, sim.Int); err != nil { return sim.NullValue, err } l := len(args) if l == 0 { return sim.NullValue, fmt.Errorf("expected at least one parameter") } d := args[0].ToInt() * int64(time.Hour) if l > 1 { d += args[1].ToInt() * int64(time.Minute) } if l > 2 { d += args[2].ToInt() * int64(time.Second) } return sim.NewObject(Duration(d)), nil }, }, { Name: "time.toMilliseconds", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Int, sim.Int, sim.Int); err != nil { return sim.NullValue, err } l := len(args) if l == 0 { return sim.NullValue, fmt.Errorf("expected at least one parameter") } m := args[0].ToInt() * 60 * 60 * 1000 if l > 1 { m += args[1].ToInt() * 60 * 1000 } if l > 2 { m += args[2].ToInt() * 1000 } return sim.NewInt64(m), nil }, }, { Name: "time.newClock", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } loc, ok := args[0].ToObjectOrNil().(location) if !ok { return sim.NullValue, fmt.Errorf("expected Location, got %s", args[0].TypeName()) } c := &clock.Clock{ Location: loc.l, Now: func() time.Time { return time.Now().In(loc.l) }, } return sim.NewObject(&Clock{c: c}), nil }, }, { Name: "time.since", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } t, ok := args[0].ToObjectOrNil().(TimeObj) if !ok { return sim.NullValue, ErrInvalidType } now := vm.Now if now.IsZero() { now = time.Now() } d := now.Sub(time.Time(t)) return sim.NewObject(Duration(d)), nil }, }, { Name: "time.unix", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Int); err != nil { return sim.NullValue, err } sec := args[0].ToInt() t := time.Unix(sec, 0) return sim.NewObject(TimeObj(t)), nil }, }, { Name: "time.setDefaultLocation", Arguments: 1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } name := args[0].String() l, err := time.LoadLocation(name) if err != nil { return sim.NullValue, fmt.Errorf("error loading timezone %s: %w", name, err) } time.Local = l return sim.NullValue, nil }, }, { Name: "time.setLocation", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } name := args[0].String() l, err := time.LoadLocation(name) if err != nil { return sim.NullValue, fmt.Errorf("error loading timezone %s: %w", name, err) } vm.Location = l return sim.NullValue, nil }, }, { Name: "time.setFixedNow", Arguments: 1, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, err } t, ok := args[0].ToObjectOrNil().(TimeObj) if !ok { return sim.NullValue, ErrInvalidType } vm.Now = time.Time(t) return sim.NullValue, nil }, }, { Name: "time.unsetFixedNow", Arguments: 0, Permissions: []string{"trusted"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { vm.Now = time.Time{} return sim.NullValue, nil }, }, { Name: "time.now", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if !vm.Now.IsZero() { return sim.NewObject(TimeObj(vm.Now)), nil } loc := GetLocation(vm) t := time.Now().In(loc) return sim.NewObject(TimeObj(t)), nil }, }, { Name: "time.nowUTC", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { n := vm.Now if !n.IsZero() { return sim.NewObject(TimeObj(n.UTC())), nil } return sim.NewObject(TimeObj(time.Now().UTC())), nil }, }, { Name: "time.unixNano", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { n := vm.Now if !n.IsZero() { return sim.NewInt64(n.UnixNano()), nil } return sim.NewInt64(time.Now().UnixNano()), nil }, }, { Name: "time.sleep", Arguments: 1, Permissions: []string{"sync"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if len(args) != 1 { return sim.NullValue, fmt.Errorf("expected 1 argument, got %d", len(args)) } d, err := ToDuration(args[0]) if err != nil { return sim.NullValue, err } time.Sleep(d) return sim.NullValue, nil }, }, { Name: "->time.utc", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { return sim.NewObject(location{time.UTC}), nil }, }, { Name: "->time.local", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { l := GetLocation(vm) return sim.NewObject(location{l}), nil }, }, { Name: "time.loadLocation", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } l, err := time.LoadLocation(args[0].String()) if err != nil { return sim.NullValue, err } return sim.NewObject(location{l}), nil }, }, { Name: "time.parse", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { l := GetLocation(vm) return parseInLocation(l, args) }, }, { Name: "time.parseInLocation", Arguments: 3, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { location, ok := args[2].ToObjectOrNil().(location) if !ok { return sim.NullValue, fmt.Errorf("invalid location, got %s", args[2].TypeName()) } return parseInLocation(location.l, args) }, }, { Name: "time.formatMinutes", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var min float64 a := args[0] switch a.Type { case sim.Int, sim.Float: min = a.ToFloat() default: return sim.NullValue, fmt.Errorf("expected a number, got %v", a.TypeName()) } negative := min < 0 min = math.Abs(min) h := int(math.Floor(min / 60)) m := int(min) % 60 s := fmt.Sprintf("%02d:%02d", h, m) if negative { s = "-" + s } return sim.NewString(s), nil }, }, { Name: "time.newTicker", Arguments: 2, Permissions: []string{"async"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { d, err := ToDuration(args[0]) if err != nil { return sim.NullValue, err } v := args[1] switch v.Type { case sim.Func: case sim.Object: if _, ok := v.ToObjectOrNil().(*sim.Closure); !ok { return sim.NullValue, fmt.Errorf("%v is not a function", v.TypeName()) } default: return sim.NullValue, fmt.Errorf("%v is not a function", v.TypeName()) } ticker := time.NewTicker(d) go func() { for range ticker.C { if err := runAsyncFuncOrClosure(vm, v); err != nil { fmt.Fprintln(vm.GetStderr(), err) } } }() return sim.NewObject(&tickerObj{ticker}), nil }, }, { Name: "time.newTimer", Arguments: 2, Permissions: []string{"async"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { d, err := ToDuration(args[0]) if err != nil { return sim.NullValue, fmt.Errorf("expected time.Duration, got: %s", args[0].TypeName()) } v := args[1] switch v.Type { case sim.Func: case sim.Object: default: return sim.NullValue, fmt.Errorf("%v is not a function", v.TypeName()) } timer := time.NewTimer(d) go func() { for range timer.C { if err := runAsyncFuncOrClosure(vm, v); err != nil { fmt.Fprintln(vm.GetStderr(), err) } } }() return sim.NewObject(&timerObj{timer}), nil }, }, { Name: "time.after", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { l := len(args) if l == 0 || l > 2 { return sim.NullValue, fmt.Errorf("expected 1 or 2 args") } d, err := ToDuration(args[0]) if err != nil { return sim.NullValue, fmt.Errorf("expected time.Duration, got: %s", args[0].TypeName()) } ch := make(chan sim.Value) timer := time.NewTimer(d) if l == 1 { go func() { t := <-timer.C ch <- sim.NewObject(TimeObj(t)) }() } else { go func() { <-timer.C ch <- args[1] }() } c := &channel{c: ch} return sim.NewObject(c), nil }, }, }
var UUID = []sim.NativeFunction{ { Name: "uuid.newID", Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { id := shortuuid.New() return sim.NewString(id), nil }, }, { Name: "uuid.newRandomID", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Int); err != nil { return sim.NullValue, err } var n int if len(args) == 0 { n = 5 } else { n = int(args[0].ToInt()/2) + 1 } id := RandomAlphanumeric(int(n)) + shortuuid.New() + RandomAlphanumeric(int(n)) return sim.NewString(id), nil }, }, }
var WebSocket = []sim.NativeFunction{ { Name: "websocket.dial", Permissions: []string{"networking"}, Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, nil } url := args[0].String() c, _, err := websocket.DefaultDialer.Dial(url, nil) if err != nil { return sim.NullValue, err } c.SetReadLimit(8192) return sim.NewObject(newWebsocketConn(c, vm)), nil }, }, { Name: "websocket.newUpgrader", Permissions: []string{"networking"}, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { u := &websocket.Upgrader{ HandshakeTimeout: 10 * time.Second, ReadBufferSize: 1024, WriteBufferSize: 1024, } return sim.NewObject(&upgrader{u}), nil }, }, { Name: "websocket.isCloseError", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object); err != nil { return sim.NullValue, nil } e, ok := args[0].ToObject().(*websocket.CloseError) if !ok { return sim.FalseValue, nil } switch e.Code { case websocket.CloseNormalClosure, websocket.CloseGoingAway, websocket.CloseProtocolError, websocket.CloseUnsupportedData, websocket.CloseNoStatusReceived, websocket.CloseAbnormalClosure, websocket.CloseInvalidFramePayloadData, websocket.ClosePolicyViolation, websocket.CloseMessageTooBig, websocket.CloseMandatoryExtension, websocket.CloseInternalServerErr, websocket.CloseServiceRestart, websocket.CloseTryAgainLater, websocket.CloseTLSHandshake: return sim.TrueValue, nil default: return sim.FalseValue, nil } }, }, }
var X509 = []sim.NativeFunction{ { Name: "x509.parsePEM", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { certPEM := args[0].ToBytes() block, _ := pem.Decode(certPEM) var certDER []byte if block != nil { certDER = block.Bytes } else { certDER = certPEM } cert, err := x509.ParseCertificate(certDER) if err != nil { return sim.NullValue, fmt.Errorf("error parsing certificate: %w", err) } return sim.NewObject(&x509Certificate{cert}), nil }, }, }
var XLSX = []sim.NativeFunction{ { Name: "xlsx.openReaderAt", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object, sim.Int); err != nil { return sim.NullValue, err } r, ok := args[0].ToObjectOrNil().(io.ReaderAt) if !ok { return sim.NullValue, fmt.Errorf("invalid argument type. Expected a io.ReaderAt, got %s", args[0].TypeName()) } size := args[1].ToInt() reader, err := xlsx.OpenReaderAt(r, size) if err != nil { return sim.NullValue, err } if vm.StatsEnabled { if err := vm.AddAllocations(int(size)); err != nil { return sim.NullValue, err } } return sim.NewObject(&xlsxFile{obj: reader}), nil }, }, { Name: "xlsx.openBinary", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes); err != nil { return sim.NullValue, err } b := args[0].ToBytes() reader, err := xlsx.OpenBinary(b) if err != nil { return sim.NullValue, err } if vm.StatsEnabled { if err := vm.AddAllocations(len(b)); err != nil { return sim.NullValue, err } } return sim.NewObject(&xlsxFile{obj: reader}), nil }, }, { Name: "xlsx.openFile", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { var r io.ReaderAt var size int64 a := args[0] switch a.Type { case sim.Object: f, ok := a.ToObject().(*file) if !ok { return sim.NullValue, fmt.Errorf("invalid argument type. Expected a io.ReaderAt, got %s", a.TypeName()) } r = f st, err := f.Stat() if err != nil { return sim.NullValue, err } size = st.Size() case sim.String: f, err := vm.FileSystem.Open(a.String()) if err != nil { return sim.NullValue, err } r = f st, err := f.Stat() if err != nil { return sim.NullValue, err } size = st.Size() default: return sim.NullValue, fmt.Errorf("invalid argument type. Expected a io.ReaderAt, got %s", a.TypeName()) } reader, err := xlsx.OpenReaderAt(r, size) if err != nil { return sim.NullValue, err } if vm.StatsEnabled { if err := vm.AddAllocations(int(size)); err != nil { return sim.NullValue, err } } return sim.NewObject(&xlsxFile{obj: reader, path: a.String()}), nil }, }, { Name: "xlsx.newFile", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args); err != nil { return sim.NullValue, err } file := xlsx.NewFile() return sim.NewObject(&xlsxFile{obj: file}), nil }, }, { Name: "xlsx.newStyle", Arguments: 0, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args); err != nil { return sim.NullValue, err } s := xlsx.NewStyle() return sim.NewObject(&xlsxStyle{obj: s}), nil }, }, }
var XML = []sim.NativeFunction{ { Name: "xml.newDocument", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.Bool, sim.String); err != nil { return sim.NullValue, err } doc := etree.NewDocument() doc.WriteSettings.CanonicalText = true doc.WriteSettings.CanonicalAttrVal = false ln := len(args) if ln == 1 && args[0].ToBool() { doc.CreateProcInst("xml", `version="1.0" encoding="UTF-8"`) } if ln == 2 { a := args[1] doc.CreateProcInst("xml", a.ToString()) if vm.StatsEnabled { if err := vm.AddAllocations(a.Size()); err != nil { return sim.NullValue, err } } } else { if vm.StatsEnabled { if err := vm.AddAllocations(1); err != nil { return sim.NullValue, err } } } return sim.NewObject(&xmlDoc{doc: doc}), nil }, }, { Name: "xml.newCharData", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String); err != nil { return sim.NullValue, err } a := args[0] d := etree.NewText(a.String()) if vm.StatsEnabled { if err := vm.AddAllocations(a.Size()); err != nil { return sim.NullValue, err } } return sim.NewObject(&xmlCharData{data: d}), nil }, }, { Name: "xml.newElement", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String); err != nil { return sim.NullValue, err } a := args[0] e := etree.NewElement(a.String()) if vm.StatsEnabled { if err := vm.AddAllocations(a.Size()); err != nil { return sim.NullValue, err } } return sim.NewObject(&xmlElement{element: e}), nil }, }, { Name: "xml.read", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Bytes); err != nil { return sim.NullValue, err } doc := etree.NewDocument() doc.WriteSettings.CanonicalText = true doc.WriteSettings.CanonicalAttrVal = false a := args[0] if err := doc.ReadFromBytes(a.ToBytes()); err != nil { return sim.NullValue, err } if vm.StatsEnabled { if err := vm.AddAllocations(a.Size()); err != nil { return sim.NullValue, err } } return sim.NewObject(&xmlDoc{doc: doc}), nil }, }, { Name: "xml.readString", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.String); err != nil { return sim.NullValue, err } doc := etree.NewDocument() doc.WriteSettings.CanonicalText = true doc.WriteSettings.CanonicalAttrVal = false a := args[0] if err := doc.ReadFromString(a.String()); err != nil { return sim.NullValue, err } if vm.StatsEnabled { if err := vm.AddAllocations(a.Size()); err != nil { return sim.NullValue, err } } return sim.NewObject(&xmlDoc{doc: doc}), nil }, }, { Name: "xml.encode", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { a := args[0] switch a.Type { case sim.Null, sim.Undefined: return sim.NullValue, nil case sim.Bytes: encoder := base64.RawStdEncoding encoded := encoder.EncodeToString(a.ToBytes()) return sim.NewString(encoded), nil default: s := encodeXML(args[0].String()) return sim.NewString(s), nil } }, }, }
var ZIP = []sim.NativeFunction{ { Name: "zip.newWriter", Arguments: 1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { w, ok := args[0].ToObjectOrNil().(io.Writer) if !ok { return sim.NullValue, fmt.Errorf("exepected a Writer, got %s", args[0].TypeName()) } g := zip.NewWriter(w) v := &zipWriter{g} return sim.NewObject(v), nil }, }, { Name: "zip.newReader", Arguments: 2, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateArgs(args, sim.Object, sim.Int); err != nil { return sim.NullValue, err } r, ok := args[0].ToObjectOrNil().(io.ReaderAt) if !ok { return sim.NullValue, fmt.Errorf("exepected a reader, got %s", args[0].TypeName()) } size := args[1].ToInt() gr, err := zip.NewReader(r, size) if err != nil { return sim.NullValue, err } v := &zipReader{r: gr} return sim.NewObject(v), nil }, }, { Name: "zip.open", Arguments: -1, Function: func(this sim.Value, args []sim.Value, vm *sim.VM) (sim.Value, error) { if err := ValidateOptionalArgs(args, sim.String, sim.Object); err != nil { return sim.NullValue, err } if err := ValidateArgRange(args, 1, 2); err != nil { return sim.NullValue, err } var fs filesystem.FS if len(args) == 2 { fsObj, ok := args[1].ToObjectOrNil().(*FileSystemObj) if !ok { return sim.NullValue, fmt.Errorf("exepected a FileSystem, got %s", args[1].TypeName()) } fs = fsObj.FS } else { fs = vm.FileSystem } f, err := fs.Open(args[0].String()) if err != nil { return sim.NullValue, err } fi, err := f.Stat() if err != nil { return sim.NullValue, err } size := fi.Size() gr, err := zip.NewReader(f, size) if err != nil { return sim.NullValue, err } v := &zipReader{gr, f} return sim.NewObject(v), nil }, }, }
Functions ¶
func CheckHashPasword ¶
func DecodeCustomBase34 ¶
DecodeCustomBase34 decodes a base34-encoded string back to uint64
func DecryptTripleDESCBC ¶
func EncodeCustomBase34 ¶
EncodeCustomBase34 encodes a uint64 value to string in base34 format
func EncryptTripleDESCBC ¶
func HashPassword ¶
func IsAlphanumeric ¶
func IsAlphanumericIdent ¶
func Random ¶
GenerateRandomBytes returns securely generated random bytes. It will return an error if the system's secure random number generator fails to function correctly, in which case the caller should not continue.
func RandomAlphanumeric ¶
func SendMailWithTimeout ¶
func SendMailWithTimeout(addr string, a Auth, from string, to []string, msg []byte, insecureSkipVerify bool, timeout time.Duration) error
SendMail connects to the server at addr, switches to TLS if possible, authenticates with the optional mechanism a if possible, and then sends an email from address from, to addresses to, with message msg. The addr must include a port, as in "mail.example.com:smtp".
The addresses in the to parameter are the SMTP RCPT addresses.
The msg parameter should be an RFC 822-style email with headers first, a blank line, and then the message body. The lines of msg should be CRLF terminated. The msg headers should usually include fields such as "From", "To", "Subject", and "Cc". Sending "Bcc" messages is accomplished by including an email address in the to parameter but not including it in the msg headers.
The SendMail function and the the net/smtp package are low-level mechanisms and provide no support for DKIM signing, MIME attachments (see the mime/multipart package), or other mail functionality. Higher-level packages exist outside of the standard library.
func ValidateArgs ¶
validate the number of args ant type
func ValidateOptionalArgs ¶
validate that if present, args are of type t
func ValidateOrNilArgs ¶
validate the number of args ant type
func ZeroPadding ¶
func ZeroUnPadding ¶
Types ¶
type Auth ¶
type Auth interface {
// Start begins an authentication with a server.
// It returns the name of the authentication protocol
// and optionally data to include in the initial AUTH message
// sent to the server. It can return proto == "" to indicate
// that the authentication should be skipped.
// If it returns a non-nil error, the SMTP client aborts
// the authentication attempt and closes the connection.
Start(server *ServerInfo) (proto string, toServer []byte, err error)
// Next continues the authentication. The server has just sent
// the fromServer data. If more is true, the server expects a
// response, which Next should return as toServer; otherwise
// Next should return toServer == nil.
// If Next returns a non-nil error, the SMTP client aborts
// the authentication attempt and closes the connection.
Next(fromServer []byte, more bool) (toServer []byte, err error)
}
Auth is implemented by an SMTP authentication mechanism.
func CRAMMD5Auth ¶
CRAMMD5Auth returns an Auth that implements the CRAM-MD5 authentication mechanism as defined in RFC 2195. The returned Auth uses the given username and secret to authenticate to the server using the challenge-response mechanism.
func LoginAuth ¶
loginAuth returns an Auth that implements the LOGIN authentication mechanism as defined in RFC 4616.
type Client ¶
func Dial ¶
Dial returns a new Client connected to an SMTP server at addr. The addr must include a port, as in "mail.example.com:smtp".
func NewClient ¶
NewClient returns a new Client using an existing connection and host as a server name to be used when authenticating.
func (*Client) Auth ¶
Auth authenticates a client using the provided authentication mechanism. A failed authentication closes the connection. Only servers that advertise the AUTH extension support this function.
func (*Client) Data ¶
func (c *Client) Data() (io.WriteCloser, error)
Data issues a DATA command to the server and returns a writer that can be used to write the mail headers and body. The caller should close the writer before calling any more methods on c. A call to Data must be preceded by one or more calls to Rcpt.
func (*Client) Extension ¶
Extension reports whether an extension is support by the server. The extension name is case-insensitive. If the extension is supported, Extension also returns a string that contains any parameters the server specifies for the extension.
func (*Client) Hello ¶
Hello sends a HELO or EHLO to the server as the given host name. Calling this method is only necessary if the client needs control over the host name used. The client will introduce itself as "localhost" automatically otherwise. If Hello is called, it must be called before any of the other methods.
func (*Client) Mail ¶
Mail issues a MAIL command to the server using the provided email address. If the server supports the 8BITMIME extension, Mail adds the BODY=8BITMIME parameter. This initiates a mail transaction and is followed by one or more Rcpt calls.
func (*Client) Rcpt ¶
Rcpt issues a RCPT command to the server using the provided email address. A call to Rcpt must be preceded by a call to Mail and may be followed by a Data call or another Rcpt call.
func (*Client) Reset ¶
Reset sends the RSET command to the server, aborting the current mail transaction.
func (*Client) StartTLS ¶
StartTLS sends the STARTTLS command and encrypts all further communication. Only servers that advertise the STARTTLS extension support this function.
func (*Client) TLSConnectionState ¶
func (c *Client) TLSConnectionState() (state tls.ConnectionState, ok bool)
TLSConnectionState returns the client's TLS connection state. The return values are their zero values if StartTLS did not succeed.
type Duration ¶
func (Duration) MarshalJSON ¶
type FileSystemObj ¶
type FileSystemObj struct {
FS filesystem.FS
}
func NewFileSystem ¶
func NewFileSystem(fs filesystem.FS) *FileSystemObj
func (*FileSystemObj) GetMethod ¶
func (f *FileSystemObj) GetMethod(name string) sim.NativeMethod
func (*FileSystemObj) Type ¶
func (f *FileSystemObj) Type() string
type ResponseWriterCounter ¶
type ResponseWriterCounter struct {
http.ResponseWriter
BytesWritten int64
}
func NewWriterCounter ¶
func NewWriterCounter(w http.ResponseWriter) *ResponseWriterCounter
func (*ResponseWriterCounter) Write ¶
func (rwc *ResponseWriterCounter) Write(data []byte) (int, error)
func (*ResponseWriterCounter) WriteHeader ¶
func (rwc *ResponseWriterCounter) WriteHeader(statusCode int)
También necesitas envolver WriteHeader si quieres interceptarlo
type SecureObject ¶
func (*SecureObject) Type ¶
func (*SecureObject) Type() string
type ServerInfo ¶
ServerInfo records information about an SMTP server.
type SmtMessage ¶
type SmtMessage struct {
Attachments map[string]*attachment
From mail.Address
To sim.Value
Bcc sim.Value
Cc sim.Value
ReplyTo string
Subject string
Body string
Html bool
}
Message represents a smtp message.
func (*SmtMessage) AllRecipients ¶
func (m *SmtMessage) AllRecipients() []string
Tolist returns all the recipients of the email
func (*SmtMessage) AttachBuffer ¶
func (m *SmtMessage) AttachBuffer(filename string, buf []byte, inline bool) error
AttachBuffer attaches a binary attachment.
func (*SmtMessage) BccList ¶
func (m *SmtMessage) BccList() []string
func (*SmtMessage) CcList ¶
func (m *SmtMessage) CcList() []string
func (*SmtMessage) ContentType ¶
func (m *SmtMessage) ContentType() string
func (*SmtMessage) GetMethod ¶
func (m *SmtMessage) GetMethod(name string) sim.NativeMethod
func (*SmtMessage) SendWithTimeout ¶
func (*SmtMessage) ToList ¶
func (m *SmtMessage) ToList() []string
func (SmtMessage) Type ¶
func (SmtMessage) Type() string
type SqlProfiler ¶
type SqlProfiler struct {
// contains filtered or unexported fields
}
func NewSQLProfiler ¶
func NewSQLProfiler() *SqlProfiler
func (*SqlProfiler) Report ¶
func (p *SqlProfiler) Report(maxLines int)
func (*SqlProfiler) ReportStats ¶
func (p *SqlProfiler) ReportStats(maxLines int) []QueryStat
func (*SqlProfiler) Reset ¶
func (p *SqlProfiler) Reset()
func (*SqlProfiler) Start ¶
func (p *SqlProfiler) Start()
func (*SqlProfiler) Stop ¶
func (p *SqlProfiler) Stop()
type TimeObj ¶
func (TimeObj) MarshalJSON ¶
type VMNumberFormatter ¶
type VMNumberFormatter struct {
// contains filtered or unexported fields
}
VMNumberFormatter implements pdf.NumberFormatter interface using VM's locale system
func (*VMNumberFormatter) FormatNumber ¶
func (f *VMNumberFormatter) FormatNumber(format string, value float64) string
FormatNumber formats a number using the VM's localizer or culture
func (*VMNumberFormatter) ParseNumber ¶
func (f *VMNumberFormatter) ParseNumber(text string) (float64, error)
ParseNumber parses a number using the VM's localizer or culture
Source Files
¶
- array.go
- assert.go
- async.go
- atomic.go
- base64.go
- binary.go
- bufio.go
- bytecode.go
- bytes.go
- cache.go
- console.go
- convert.go
- crypt.go
- csv.go
- disk_unix.go
- encoding.go
- errors.go
- filepath.go
- fileutil.go
- fmt.go
- fsnotify.go
- gzip.go
- hash.go
- hex.go
- html.go
- http.go
- httputil.go
- i18n.go
- image.go
- io.go
- json.go
- jwt.go
- locale.go
- lockManager.go
- markdown.go
- math.go
- multipart.go
- net.go
- number.go
- object.go
- os.go
- pdf.go
- png.go
- printing.go
- qrcode.go
- reflect.go
- regex.go
- regexp.go
- routing.go
- rsa.go
- runtime.go
- secure.go
- sftp.go
- smtp.go
- smtpgo.go
- sql.go
- sqlProfiler.go
- sqlQuery.go
- ssh.go
- strconv.go
- strings.go
- sunrise.go
- sync.go
- templates.go
- terminal.go
- time.go
- tls.go
- util.go
- uuid.go
- websocket.go
- x509.go
- xlsx.go
- xlsx2.go
- xml.go
- zip.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package jsregex provides JavaScript-compatible regular expression functionality for Go.
|
Package jsregex provides JavaScript-compatible regular expression functionality for Go. |
|
Package templates generates source code for templates.
|
Package templates generates source code for templates. |
|
Package etree provides XML services through an Element Tree abstraction.
|
Package etree provides XML services through an Element Tree abstraction. |