mirror of https://github.com/antonmedv/fx
Add goja
parent
b7c4bab9f1
commit
58b646c3f4
@ -0,0 +1,10 @@
|
||||
const __keys = new Set()
|
||||
|
||||
Object.prototype.__keys = function () {
|
||||
if (Array.isArray(this)) return
|
||||
if (typeof this === 'string') return
|
||||
if (this instanceof String) return
|
||||
if (typeof this === 'object' && this !== null)
|
||||
Object.keys(this).forEach(x => __keys.add(x))
|
||||
}
|
||||
|
@ -0,0 +1,108 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/dop251/goja"
|
||||
"github.com/goccy/go-yaml"
|
||||
)
|
||||
|
||||
//go:embed stdlib.js
|
||||
var Stdlib string
|
||||
|
||||
//go:embed prelude.js
|
||||
var prelude string
|
||||
|
||||
func Reduce(args []string) {
|
||||
if len(args) < 1 {
|
||||
panic("args must have at least one element")
|
||||
}
|
||||
|
||||
var (
|
||||
flagYaml bool
|
||||
flagRaw bool
|
||||
flagSlurp bool
|
||||
)
|
||||
|
||||
var src io.Reader = os.Stdin
|
||||
if isFile(args[0]) {
|
||||
src = open(args[0], &flagYaml)
|
||||
args = args[1:]
|
||||
} else if isFile(args[len(args)-1]) {
|
||||
src = open(args[len(args)-1], &flagYaml)
|
||||
args = args[:len(args)-1]
|
||||
}
|
||||
|
||||
var fns []string
|
||||
for _, arg := range args {
|
||||
switch arg {
|
||||
case "--yaml":
|
||||
flagYaml = true
|
||||
case "--raw", "-r":
|
||||
flagRaw = true
|
||||
case "--slurp", "-s":
|
||||
flagSlurp = true
|
||||
case "-rs", "-sr":
|
||||
flagRaw = true
|
||||
flagSlurp = true
|
||||
default:
|
||||
fns = append(fns, arg)
|
||||
}
|
||||
}
|
||||
|
||||
if flagSlurp {
|
||||
println("Error: Built-in JS engine does not support \"--slurp\" flag. Install Node.js or Deno to use this flag.")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(src)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if flagRaw {
|
||||
data = []byte(strconv.Quote(string(data)))
|
||||
} else if flagYaml {
|
||||
data, err = yaml.YAMLToJSON(data)
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
var code strings.Builder
|
||||
code.WriteString(prelude)
|
||||
code.WriteString(Stdlib)
|
||||
code.WriteString(fmt.Sprintf("let json = JSON.parse(%q)\n", data))
|
||||
for _, fn := range fns {
|
||||
code.WriteString(Transform(fn))
|
||||
}
|
||||
code.WriteString("JSON.stringify(json)")
|
||||
|
||||
vm := goja.New()
|
||||
vm.Set("println", func(s string) any {
|
||||
fmt.Println(s)
|
||||
return nil
|
||||
})
|
||||
|
||||
value, err := vm.RunString(code.String())
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
output, ok := value.Export().(string)
|
||||
if !ok {
|
||||
println("undefined")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(output)
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
const console = {
|
||||
log: function (...args) {
|
||||
const parts = []
|
||||
for (const arg of args) {
|
||||
parts.push(typeof arg === 'string' ? arg : JSON.stringify(arg, null, 2))
|
||||
}
|
||||
println(parts.join(' '))
|
||||
},
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package complete
|
||||
package engine
|
||||
|
||||
import (
|
||||
"fmt"
|
@ -0,0 +1,36 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func isFile(name string) bool {
|
||||
stat, err := os.Stat(name)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return !stat.IsDir()
|
||||
}
|
||||
|
||||
func open(filePath string, flagYaml *bool) *os.File {
|
||||
f, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
var pathError *fs.PathError
|
||||
if errors.As(err, &pathError) {
|
||||
println(err.Error())
|
||||
os.Exit(1)
|
||||
} else {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
fileName := path.Base(filePath)
|
||||
hasYamlExt, _ := regexp.MatchString(`(?i)\.ya?ml$`, fileName)
|
||||
if !*flagYaml && hasYamlExt {
|
||||
*flagYaml = true
|
||||
}
|
||||
return f
|
||||
}
|
Loading…
Reference in New Issue