snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
This commit is contained in:
23
server/pkg/jsenv/func.go
Normal file
23
server/pkg/jsenv/func.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package jsenv
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/dop251/goja"
|
||||
)
|
||||
|
||||
type (
|
||||
Fn struct {
|
||||
f goja.Callable
|
||||
}
|
||||
)
|
||||
|
||||
func (f Fn) Exec(i ...goja.Value) (interface{}, error) {
|
||||
ret, err := f.f(goja.Undefined(), i...)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not run function: %s", err)
|
||||
}
|
||||
|
||||
return ret.Export(), nil
|
||||
}
|
||||
17
server/pkg/jsenv/scope.go
Normal file
17
server/pkg/jsenv/scope.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package jsenv
|
||||
|
||||
type (
|
||||
globalScope map[string]interface{}
|
||||
)
|
||||
|
||||
func (gs globalScope) Set(k string, i interface{}) {
|
||||
gs[k] = i
|
||||
}
|
||||
|
||||
func (gs globalScope) Get(k string) interface{} {
|
||||
if v, ok := gs[k]; ok {
|
||||
return v
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
64
server/pkg/jsenv/transformer.go
Normal file
64
server/pkg/jsenv/transformer.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package jsenv
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/evanw/esbuild/pkg/api"
|
||||
)
|
||||
|
||||
const (
|
||||
// limiting the support for loaders and targets
|
||||
LoaderJS TransformLoader = TransformLoader(api.LoaderJS)
|
||||
LoaderJSX TransformLoader = TransformLoader(api.LoaderJSX)
|
||||
LoaderTS TransformLoader = TransformLoader(api.LoaderTS)
|
||||
|
||||
TargetNoop TransformTarget = 0
|
||||
TargetES5 TransformTarget = TransformTarget(api.ES5)
|
||||
TargetES2016 TransformTarget = TransformTarget(api.ES2016)
|
||||
)
|
||||
|
||||
type (
|
||||
TransformLoader uint8
|
||||
TransformTarget uint8
|
||||
|
||||
t struct {
|
||||
ldr TransformLoader
|
||||
tr TransformTarget
|
||||
}
|
||||
|
||||
noop struct{}
|
||||
|
||||
Transformer interface {
|
||||
Transform(string) ([]byte, error)
|
||||
}
|
||||
)
|
||||
|
||||
func NewTransformer(loader TransformLoader, target TransformTarget) Transformer {
|
||||
if target == TargetNoop {
|
||||
return &noop{}
|
||||
}
|
||||
|
||||
return &t{
|
||||
ldr: loader,
|
||||
tr: target,
|
||||
}
|
||||
}
|
||||
|
||||
// Transform uses the loaders and targets and transpiles
|
||||
func (tt t) Transform(p string) (b []byte, err error) {
|
||||
result := api.Transform(p, api.TransformOptions{
|
||||
Loader: api.Loader(tt.ldr),
|
||||
Target: api.Target(tt.tr),
|
||||
})
|
||||
|
||||
if len(result.Errors) > 0 {
|
||||
return []byte{}, fmt.Errorf("could not transform payload: %s", result.Errors[0].Text)
|
||||
}
|
||||
|
||||
return result.Code, nil
|
||||
}
|
||||
|
||||
// Fallback transform that keeps the original intact
|
||||
func (tt noop) Transform(p string) ([]byte, error) {
|
||||
return []byte(p), nil
|
||||
}
|
||||
111
server/pkg/jsenv/vm.go
Normal file
111
server/pkg/jsenv/vm.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package jsenv
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/dop251/goja"
|
||||
)
|
||||
|
||||
const (
|
||||
// placeholder for functions in js env
|
||||
exportFuncDescriptor = "_expFunc_"
|
||||
)
|
||||
|
||||
type (
|
||||
Vm struct {
|
||||
g *goja.Runtime
|
||||
t Transformer
|
||||
}
|
||||
)
|
||||
|
||||
func New(t Transformer) Vm {
|
||||
return Vm{
|
||||
g: goja.New(),
|
||||
t: t,
|
||||
}
|
||||
}
|
||||
|
||||
// New creates a goja internal type
|
||||
func (ss Vm) New(i interface{}) goja.Value {
|
||||
return ss.g.ToValue(i)
|
||||
}
|
||||
|
||||
// Register the value in vm
|
||||
func (ss Vm) Register(key string, i interface{}) error {
|
||||
return ss.g.Set(key, i)
|
||||
}
|
||||
|
||||
// Fetch value from vm
|
||||
func (ss Vm) Fetch(key string) goja.Value {
|
||||
return ss.g.Get(key)
|
||||
}
|
||||
|
||||
// RegisterFunction registers the function to the vm and returns the
|
||||
// function that can be used in go
|
||||
func (ss Vm) RegisterFunction(s string, wrapperFn ...func() string) (f *Fn, err error) {
|
||||
if len(wrapperFn) > 0 {
|
||||
for _, wfn := range wrapperFn {
|
||||
s = fmt.Sprintf(wfn(), s)
|
||||
}
|
||||
} else {
|
||||
s = fmt.Sprintf("function (input) { %s }", s)
|
||||
}
|
||||
|
||||
desc := ss.funcDescriptor(s)
|
||||
run := fmt.Sprintf("var %s=%s;", desc, s)
|
||||
|
||||
err = ss.Eval(run)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
internalF := ss.Fetch(desc)
|
||||
|
||||
if internalF == nil {
|
||||
err = fmt.Errorf("could not fetch registered value")
|
||||
return
|
||||
}
|
||||
|
||||
fnn, ok := goja.AssertFunction(internalF)
|
||||
|
||||
if !ok {
|
||||
err = fmt.Errorf("could not assert function")
|
||||
return
|
||||
}
|
||||
|
||||
return &Fn{
|
||||
f: fnn,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Eval transforms the input js to the specified
|
||||
// version and evals in vm
|
||||
func (ss Vm) Eval(p string) (err error) {
|
||||
tr, err := ss.t.Transform(p)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = ss.g.RunString(string(tr))
|
||||
return
|
||||
}
|
||||
|
||||
// Compile is used only when parsing the
|
||||
// input evaluation without actually running it
|
||||
func (ss Vm) Compile(p string) (err error) {
|
||||
_, err = goja.Parse("", p)
|
||||
return
|
||||
}
|
||||
|
||||
func (ss Vm) genID(s string) string {
|
||||
h := md5.Sum([]byte(s))
|
||||
return hex.EncodeToString(h[:])
|
||||
}
|
||||
|
||||
func (ss Vm) funcDescriptor(s string) string {
|
||||
return fmt.Sprintf("%s%s", exportFuncDescriptor, ss.genID(s))
|
||||
}
|
||||
101
server/pkg/jsenv/vm_test.go
Normal file
101
server/pkg/jsenv/vm_test.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package jsenv
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_registerFunction(t *testing.T) {
|
||||
type (
|
||||
tf struct {
|
||||
name string
|
||||
err string
|
||||
fn string
|
||||
wrapperFn func() string
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
tcc = []tf{
|
||||
{
|
||||
name: "register js func",
|
||||
fn: "return 1;",
|
||||
},
|
||||
{
|
||||
name: "register js custom wrapper fn",
|
||||
fn: "return second;",
|
||||
wrapperFn: func() string { return "function (first, second, third) { %s }" },
|
||||
},
|
||||
{
|
||||
name: "register js func error",
|
||||
fn: "function () {return 1",
|
||||
err: "SyntaxError: SyntaxError: (anonymous): Line 1:69 Unexpected end of input (and 1 more errors)",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
for _, tc := range tcc {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
var (
|
||||
f *Fn
|
||||
err error
|
||||
|
||||
req = require.New(t)
|
||||
tr = NewTransformer(LoaderJS, TargetNoop)
|
||||
vm = New(tr)
|
||||
)
|
||||
|
||||
if tc.wrapperFn != nil {
|
||||
f, err = vm.RegisterFunction(tc.fn, tc.wrapperFn)
|
||||
} else {
|
||||
f, err = vm.RegisterFunction(tc.fn)
|
||||
}
|
||||
|
||||
if tc.err == "" {
|
||||
req.NoError(err)
|
||||
req.Equal(reflect.Func, reflect.TypeOf(f.f).Kind())
|
||||
req.Equal("Callable", reflect.TypeOf(f.f).Name())
|
||||
} else {
|
||||
req.Errorf(err, tc.err)
|
||||
req.Nil(f)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_compile(t *testing.T) {
|
||||
var (
|
||||
req = require.New(t)
|
||||
tr = NewTransformer(LoaderJS, TargetNoop)
|
||||
vm = New(tr)
|
||||
)
|
||||
|
||||
err := vm.Compile(`function () {return 1`)
|
||||
|
||||
req.Errorf(err, "SyntaxError: SyntaxError: (anonymous): Line 1:69 Unexpected end of input (and 1 more errors)")
|
||||
}
|
||||
|
||||
func Test_funcDescriptor(t *testing.T) {
|
||||
var (
|
||||
req = require.New(t)
|
||||
tr = NewTransformer(LoaderJS, TargetNoop)
|
||||
vm = New(tr)
|
||||
)
|
||||
|
||||
req.Equal("_expFunc_1a6126e35863d2e16ba8e40f40668fdb", vm.funcDescriptor(`function () {return 1}`))
|
||||
}
|
||||
|
||||
func Test_fetchEval(t *testing.T) {
|
||||
var (
|
||||
req = require.New(t)
|
||||
tr = NewTransformer(LoaderJS, TargetNoop)
|
||||
vm = New(tr)
|
||||
)
|
||||
|
||||
req.NoError(vm.Eval(`foo = 'bar'`))
|
||||
req.Equal("bar", vm.Fetch("foo").Export())
|
||||
req.Nil(vm.Fetch("bar"))
|
||||
}
|
||||
Reference in New Issue
Block a user