forked from cortezaproject/corteza
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added goja lib, transformer lib and jsenv pkg
- Loading branch information
1 parent
da91002
commit 0966fe9
Showing
262 changed files
with
216,125 additions
and
10,033 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package jsenv | ||
|
||
import ( | ||
"crypto/md5" | ||
"encoding/hex" | ||
"errors" | ||
"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 = errors.New("could not fetch registered value") | ||
return | ||
} | ||
|
||
fnn, ok := goja.AssertFunction(internalF) | ||
|
||
if !ok { | ||
err = errors.New("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)) | ||
} |
Oops, something went wrong.