Skip to content

Commit ef53bb9

Browse files
committed
Validation of zip using javascript
1 parent 1e13380 commit ef53bb9

File tree

5 files changed

+102
-0
lines changed

5 files changed

+102
-0
lines changed

code/go-wasm/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.wasm

code/go-wasm/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
build:
2+
GOOS=js GOARCH=wasm go build -o validator.wasm .
3+
4+
test:
5+
GOOS=js GOARCH=wasm go test -v -exec="`go env GOROOT`/misc/wasm/go_js_wasm_exec" . ../go/...

code/go-wasm/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
* Build wasm with `make build`.
2+
* Run `./validate.js /path/to/package.zip` (or `node validate.js /path/to/package.zip`).
3+
4+
Node.js and Go are required.

code/go-wasm/main.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"syscall/js"
6+
7+
"github.com/elastic/package-spec/code/go/pkg/validator"
8+
)
9+
10+
const moduleName = "elasticPackageSpec"
11+
12+
// asyncFunc helps creating functions that return a promise.
13+
//
14+
// Calling async JavaScript APIs causes deadlocks in the JS event loop. Not sure
15+
// how to find if a Go code does it, but for example ValidateFromZip does, so
16+
// we need to run this code in a goroutine and return the result as a promise.
17+
// Related: https://github.com/golang/go/issues/41310
18+
func asyncFunc(fn func(this js.Value, args []js.Value) interface{}) js.Func {
19+
return js.FuncOf(func(this js.Value, args []js.Value) interface{} {
20+
handler := js.FuncOf(func(_ js.Value, handlerArgs []js.Value) interface{} {
21+
resolve := handlerArgs[0]
22+
reject := handlerArgs[1]
23+
24+
go func() {
25+
result := fn(this, args)
26+
if err, ok := result.(error); ok {
27+
reject.Invoke(err.Error())
28+
return
29+
}
30+
resolve.Invoke(result)
31+
}()
32+
33+
return nil
34+
})
35+
36+
return js.Global().Get("Promise").New(handler)
37+
})
38+
}
39+
40+
func main() {
41+
// It doesn't seem to be possible yet to export values as part of the compiled instance.
42+
// So we have to expose it by setting a global value. It may worth to explore tynigo for this.
43+
// Related: https://github.com/golang/go/issues/42372
44+
js.Global().Set(moduleName, make(map[string]interface{}))
45+
module := js.Global().Get(moduleName)
46+
module.Set("validateFromZip", asyncFunc(
47+
func(this js.Value, args []js.Value) interface{} {
48+
if len(args) == 0 || args[0].IsNull() || args[0].IsUndefined() {
49+
return fmt.Errorf("package path expected")
50+
}
51+
52+
pkgPath := args[0].String()
53+
return validator.ValidateFromZip(pkgPath)
54+
},
55+
))
56+
57+
// Go runtime must be always available at any moment where exported functionality
58+
// can be executed, so keep it running till done.
59+
done := make(chan struct{})
60+
module.Set("stop", js.FuncOf(func(_ js.Value, _ []js.Value) interface{} {
61+
close(done)
62+
return nil
63+
}))
64+
<-done
65+
}

code/go-wasm/validate.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env node
2+
3+
if (process.argv.length < 3) {
4+
console.error("usage: " + process.argv[1] + " [package path]");
5+
process.exit(1);
6+
}
7+
8+
const path = require('path')
9+
const fs = require('fs');
10+
11+
require(path.join(process.env.GOROOT, "misc/wasm/wasm_exec.js"));
12+
const go = new Go();
13+
14+
const wasmBuffer = fs.readFileSync('validator.wasm');
15+
WebAssembly.instantiate(wasmBuffer, go.importObject).then((validator) => {
16+
go.run(validator.instance);
17+
18+
elasticPackageSpec.validateFromZip(process.argv[2]).then(() =>
19+
console.log("OK")
20+
).catch((err) =>
21+
console.error(err)
22+
).finally(() =>
23+
elasticPackageSpec.stop()
24+
)
25+
}).catch((err) => {
26+
console.error(err);
27+
});

0 commit comments

Comments
 (0)