refactor
This commit is contained in:
parent
2a561265c1
commit
8d9bf98e59
4 changed files with 276 additions and 321 deletions
70
d2js/d2wasm/api.go
Normal file
70
d2js/d2wasm/api.go
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
//go:build js && wasm
|
||||||
|
|
||||||
|
package d2wasm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"syscall/js"
|
||||||
|
)
|
||||||
|
|
||||||
|
type D2API struct {
|
||||||
|
exports map[string]js.Func
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewD2API() *D2API {
|
||||||
|
return &D2API{
|
||||||
|
exports: make(map[string]js.Func),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *D2API) Register(name string, fn func(args []js.Value) (interface{}, error)) {
|
||||||
|
api.exports[name] = wrapWASMCall(fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *D2API) ExportTo(target js.Value) {
|
||||||
|
d2Namespace := make(map[string]interface{})
|
||||||
|
for name, fn := range api.exports {
|
||||||
|
d2Namespace[name] = fn
|
||||||
|
}
|
||||||
|
target.Set("d2", js.ValueOf(d2Namespace))
|
||||||
|
}
|
||||||
|
|
||||||
|
func wrapWASMCall(fn func(args []js.Value) (interface{}, error)) js.Func {
|
||||||
|
return js.FuncOf(func(this js.Value, args []js.Value) (result any) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
resp := WASMResponse{
|
||||||
|
Error: &WASMError{
|
||||||
|
Message: fmt.Sprintf("panic recovered: %v", r),
|
||||||
|
Code: 500,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
jsonResp, _ := json.Marshal(resp)
|
||||||
|
result = string(jsonResp)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
data, err := fn(args)
|
||||||
|
if err != nil {
|
||||||
|
wasmErr, ok := err.(*WASMError)
|
||||||
|
if !ok {
|
||||||
|
wasmErr = &WASMError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Code: 500,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resp := WASMResponse{
|
||||||
|
Error: wasmErr,
|
||||||
|
}
|
||||||
|
jsonResp, _ := json.Marshal(resp)
|
||||||
|
return string(jsonResp)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := WASMResponse{
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
jsonResp, _ := json.Marshal(resp)
|
||||||
|
return string(jsonResp)
|
||||||
|
})
|
||||||
|
}
|
||||||
161
d2js/d2wasm/functions.go
Normal file
161
d2js/d2wasm/functions.go
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
//go:build js && wasm
|
||||||
|
|
||||||
|
package d2wasm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
|
"syscall/js"
|
||||||
|
|
||||||
|
"oss.terrastruct.com/d2/d2ast"
|
||||||
|
"oss.terrastruct.com/d2/d2compiler"
|
||||||
|
"oss.terrastruct.com/d2/d2format"
|
||||||
|
"oss.terrastruct.com/d2/d2lsp"
|
||||||
|
"oss.terrastruct.com/d2/d2oracle"
|
||||||
|
"oss.terrastruct.com/d2/d2parser"
|
||||||
|
"oss.terrastruct.com/d2/lib/version"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetParentID(args []js.Value) (interface{}, error) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return nil, &WASMError{Message: "missing id argument", Code: 400}
|
||||||
|
}
|
||||||
|
|
||||||
|
id := args[0].String()
|
||||||
|
mk, err := d2parser.ParseMapKey(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &WASMError{Message: err.Error(), Code: 400}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(mk.Edges) > 0 {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if mk.Key != nil {
|
||||||
|
if len(mk.Key.Path) == 1 {
|
||||||
|
return "root", nil
|
||||||
|
}
|
||||||
|
mk.Key.Path = mk.Key.Path[:len(mk.Key.Path)-1]
|
||||||
|
return strings.Join(mk.Key.StringIDA(), "."), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetObjOrder(args []js.Value) (interface{}, error) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return nil, &WASMError{Message: "missing dsl argument", Code: 400}
|
||||||
|
}
|
||||||
|
|
||||||
|
dsl := args[0].String()
|
||||||
|
g, _, err := d2compiler.Compile("", strings.NewReader(dsl), &d2compiler.CompileOptions{
|
||||||
|
UTF16Pos: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, &WASMError{Message: err.Error(), Code: 400}
|
||||||
|
}
|
||||||
|
|
||||||
|
objOrder, err := d2oracle.GetObjOrder(g, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &WASMError{Message: err.Error(), Code: 500}
|
||||||
|
}
|
||||||
|
|
||||||
|
return map[string]interface{}{
|
||||||
|
"order": objOrder,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetRefRanges(args []js.Value) (interface{}, error) {
|
||||||
|
if len(args) < 4 {
|
||||||
|
return nil, &WASMError{Message: "missing required arguments", Code: 400}
|
||||||
|
}
|
||||||
|
|
||||||
|
var fs map[string]string
|
||||||
|
if err := json.Unmarshal([]byte(args[0].String()), &fs); err != nil {
|
||||||
|
return nil, &WASMError{Message: "invalid fs argument", Code: 400}
|
||||||
|
}
|
||||||
|
|
||||||
|
file := args[1].String()
|
||||||
|
key := args[2].String()
|
||||||
|
|
||||||
|
var boardPath []string
|
||||||
|
if err := json.Unmarshal([]byte(args[3].String()), &boardPath); err != nil {
|
||||||
|
return nil, &WASMError{Message: "invalid boardPath argument", Code: 400}
|
||||||
|
}
|
||||||
|
|
||||||
|
ranges, importRanges, err := d2lsp.GetRefRanges(file, fs, boardPath, key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &WASMError{Message: err.Error(), Code: 500}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RefRangesResponse{
|
||||||
|
Ranges: ranges,
|
||||||
|
ImportRanges: importRanges,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Compile(args []js.Value) (interface{}, error) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return nil, &WASMError{Message: "missing script argument", Code: 400}
|
||||||
|
}
|
||||||
|
|
||||||
|
script := args[0].String()
|
||||||
|
g, _, err := d2compiler.Compile("", strings.NewReader(script), &d2compiler.CompileOptions{
|
||||||
|
UTF16Pos: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if pe, ok := err.(*d2parser.ParseError); ok {
|
||||||
|
return nil, &WASMError{Message: pe.Error(), Code: 400}
|
||||||
|
}
|
||||||
|
return nil, &WASMError{Message: err.Error(), Code: 500}
|
||||||
|
}
|
||||||
|
|
||||||
|
newScript := d2format.Format(g.AST)
|
||||||
|
if script != newScript {
|
||||||
|
return map[string]string{"result": newScript}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetBoardAtPosition(args []js.Value) (interface{}, error) {
|
||||||
|
if len(args) < 3 {
|
||||||
|
return nil, &WASMError{Message: "missing required arguments", Code: 400}
|
||||||
|
}
|
||||||
|
|
||||||
|
dsl := args[0].String()
|
||||||
|
line := args[1].Int()
|
||||||
|
column := args[2].Int()
|
||||||
|
|
||||||
|
boardPath, err := d2lsp.GetBoardAtPosition(dsl, d2ast.Position{
|
||||||
|
Line: line,
|
||||||
|
Column: column,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, &WASMError{Message: err.Error(), Code: 500}
|
||||||
|
}
|
||||||
|
|
||||||
|
return BoardPositionResponse{BoardPath: boardPath}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Encode(args []js.Value) (interface{}, error) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return nil, &WASMError{Message: "missing script argument", Code: 400}
|
||||||
|
}
|
||||||
|
|
||||||
|
script := args[0].String()
|
||||||
|
return map[string]string{"result": script}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Decode(args []js.Value) (interface{}, error) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return nil, &WASMError{Message: "missing script argument", Code: 400}
|
||||||
|
}
|
||||||
|
|
||||||
|
script := args[0].String()
|
||||||
|
return map[string]string{"result": script}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetVersion(args []js.Value) (interface{}, error) {
|
||||||
|
return version.Version, nil
|
||||||
|
}
|
||||||
28
d2js/d2wasm/types.go
Normal file
28
d2js/d2wasm/types.go
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
//go:build js && wasm
|
||||||
|
|
||||||
|
package d2wasm
|
||||||
|
|
||||||
|
import "oss.terrastruct.com/d2/d2ast"
|
||||||
|
|
||||||
|
type WASMResponse struct {
|
||||||
|
Data interface{} `json:"data,omitempty"`
|
||||||
|
Error *WASMError `json:"error,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WASMError struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
Code int `json:"code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *WASMError) Error() string {
|
||||||
|
return e.Message
|
||||||
|
}
|
||||||
|
|
||||||
|
type RefRangesResponse struct {
|
||||||
|
Ranges []d2ast.Range `json:"ranges"`
|
||||||
|
ImportRanges []d2ast.Range `json:"importRanges"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BoardPositionResponse struct {
|
||||||
|
BoardPath []string `json:"boardPath"`
|
||||||
|
}
|
||||||
338
d2js/js.go
338
d2js/js.go
|
|
@ -1,333 +1,29 @@
|
||||||
//go:build wasm
|
//go:build js && wasm
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"io/fs"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"syscall/js"
|
"syscall/js"
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/d2ast"
|
"oss.terrastruct.com/d2/d2js/d2wasm"
|
||||||
"oss.terrastruct.com/d2/d2compiler"
|
|
||||||
"oss.terrastruct.com/d2/d2format"
|
|
||||||
"oss.terrastruct.com/d2/d2lsp"
|
|
||||||
"oss.terrastruct.com/d2/d2oracle"
|
|
||||||
"oss.terrastruct.com/d2/d2parser"
|
|
||||||
"oss.terrastruct.com/d2/lib/urlenc"
|
|
||||||
"oss.terrastruct.com/d2/lib/version"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
js.Global().Set("d2GetParentID", js.FuncOf(jsGetParentID))
|
api := d2wasm.NewD2API()
|
||||||
js.Global().Set("d2GetObjOrder", js.FuncOf(jsGetObjOrder))
|
|
||||||
js.Global().Set("d2GetRefRanges", js.FuncOf(jsGetRefRanges))
|
api.Register("getParentID", d2wasm.GetParentID)
|
||||||
js.Global().Set("d2Compile", js.FuncOf(jsCompile))
|
api.Register("getObjOrder", d2wasm.GetObjOrder)
|
||||||
js.Global().Set("d2GetBoardAtPosition", js.FuncOf(jsGetBoardAtPosition))
|
api.Register("getRefRanges", d2wasm.GetRefRanges)
|
||||||
js.Global().Set("d2Parse", js.FuncOf(jsParse))
|
api.Register("compile", d2wasm.Compile)
|
||||||
js.Global().Set("d2Encode", js.FuncOf(jsEncode))
|
api.Register("getBoardAtPosition", d2wasm.GetBoardAtPosition)
|
||||||
js.Global().Set("d2Decode", js.FuncOf(jsDecode))
|
api.Register("encode", d2wasm.Encode)
|
||||||
js.Global().Set("d2Version", js.FuncOf(jsVersion))
|
api.Register("decode", d2wasm.Decode)
|
||||||
initCallback := js.Global().Get("onWasmInitialized")
|
api.Register("version", d2wasm.GetVersion)
|
||||||
if !initCallback.IsUndefined() {
|
|
||||||
initCallback.Invoke()
|
api.ExportTo(js.Global())
|
||||||
|
|
||||||
|
if cb := js.Global().Get("onWasmInitialized"); !cb.IsUndefined() {
|
||||||
|
cb.Invoke()
|
||||||
}
|
}
|
||||||
select {}
|
select {}
|
||||||
}
|
}
|
||||||
|
|
||||||
type jsObjOrder struct {
|
|
||||||
Order []string `json:"order"`
|
|
||||||
Error string `json:"error"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func jsGetObjOrder(this js.Value, args []js.Value) interface{} {
|
|
||||||
dsl := args[0].String()
|
|
||||||
|
|
||||||
g, _, err := d2compiler.Compile("", strings.NewReader(dsl), &d2compiler.CompileOptions{
|
|
||||||
UTF16Pos: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
ret := jsObjOrder{Error: err.Error()}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
objOrder, err := d2oracle.GetObjOrder(g, nil)
|
|
||||||
if err != nil {
|
|
||||||
ret := jsObjOrder{Error: err.Error()}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
resp := jsObjOrder{
|
|
||||||
Order: objOrder,
|
|
||||||
}
|
|
||||||
|
|
||||||
str, _ := json.Marshal(resp)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
func jsGetParentID(this js.Value, args []js.Value) interface{} {
|
|
||||||
id := args[0].String()
|
|
||||||
|
|
||||||
mk, _ := d2parser.ParseMapKey(id)
|
|
||||||
|
|
||||||
if len(mk.Edges) > 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if mk.Key != nil {
|
|
||||||
if len(mk.Key.Path) == 1 {
|
|
||||||
return "root"
|
|
||||||
}
|
|
||||||
mk.Key.Path = mk.Key.Path[:len(mk.Key.Path)-1]
|
|
||||||
return strings.Join(mk.Key.StringIDA(), ".")
|
|
||||||
}
|
|
||||||
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
type jsRefRanges struct {
|
|
||||||
Ranges []d2ast.Range `json:"ranges"`
|
|
||||||
ImportRanges []d2ast.Range `json:"importRanges"`
|
|
||||||
ParseError string `json:"parseError"`
|
|
||||||
UserError string `json:"userError"`
|
|
||||||
D2Error string `json:"d2Error"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func jsGetRefRanges(this js.Value, args []js.Value) interface{} {
|
|
||||||
fsRaw := args[0].String()
|
|
||||||
file := args[1].String()
|
|
||||||
key := args[2].String()
|
|
||||||
boardPathRaw := args[3].String()
|
|
||||||
|
|
||||||
var fs map[string]string
|
|
||||||
err := json.Unmarshal([]byte(fsRaw), &fs)
|
|
||||||
if err != nil {
|
|
||||||
ret := jsRefRanges{D2Error: err.Error()}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = d2parser.ParseMapKey(key)
|
|
||||||
if err != nil {
|
|
||||||
ret := jsRefRanges{D2Error: err.Error()}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
var boardPath []string
|
|
||||||
err = json.Unmarshal([]byte(boardPathRaw), &boardPath)
|
|
||||||
if err != nil {
|
|
||||||
ret := jsRefRanges{D2Error: err.Error()}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
ranges, importRanges, err := d2lsp.GetRefRanges(file, fs, boardPath, key)
|
|
||||||
if err != nil {
|
|
||||||
ret := jsRefRanges{D2Error: err.Error()}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := jsRefRanges{
|
|
||||||
Ranges: ranges,
|
|
||||||
ImportRanges: importRanges,
|
|
||||||
}
|
|
||||||
|
|
||||||
str, _ := json.Marshal(resp)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
type jsObject struct {
|
|
||||||
Result string `json:"result"`
|
|
||||||
UserError string `json:"userError"`
|
|
||||||
D2Error string `json:"d2Error"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type jsParseResponse struct {
|
|
||||||
DSL string `json:"dsl"`
|
|
||||||
ParseError string `json:"parseError"`
|
|
||||||
UserError string `json:"userError"`
|
|
||||||
D2Error string `json:"d2Error"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type emptyFile struct{}
|
|
||||||
|
|
||||||
func (f *emptyFile) Stat() (os.FileInfo, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *emptyFile) Read(p []byte) (int, error) {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *emptyFile) Close() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type detectFS struct {
|
|
||||||
importUsed bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (detectFS *detectFS) Open(name string) (fs.File, error) {
|
|
||||||
detectFS.importUsed = true
|
|
||||||
return &emptyFile{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func jsParse(this js.Value, args []js.Value) interface{} {
|
|
||||||
dsl := args[0].String()
|
|
||||||
themeID := args[1].Int()
|
|
||||||
|
|
||||||
detectFS := detectFS{}
|
|
||||||
|
|
||||||
g, _, err := d2compiler.Compile("", strings.NewReader(dsl), &d2compiler.CompileOptions{
|
|
||||||
UTF16Pos: true,
|
|
||||||
FS: &detectFS,
|
|
||||||
})
|
|
||||||
// If an import was used, client side D2 cannot reliably compile
|
|
||||||
// Defer to backend compilation
|
|
||||||
if !detectFS.importUsed {
|
|
||||||
var pe *d2parser.ParseError
|
|
||||||
if err != nil {
|
|
||||||
if errors.As(err, &pe) {
|
|
||||||
serialized, _ := json.Marshal(err)
|
|
||||||
ret := jsParseResponse{ParseError: string(serialized)}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
ret := jsParseResponse{D2Error: err.Error()}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, o := range g.Objects {
|
|
||||||
if (o.Attributes.Top == nil) != (o.Attributes.Left == nil) {
|
|
||||||
ret := jsParseResponse{UserError: `keywords "top" and "left" currently must be used together`}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = g.ApplyTheme(int64(themeID))
|
|
||||||
if err != nil {
|
|
||||||
ret := jsParseResponse{D2Error: err.Error()}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m, err := d2parser.Parse("", strings.NewReader(dsl), &d2parser.ParseOptions{
|
|
||||||
UTF16Pos: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := jsParseResponse{}
|
|
||||||
|
|
||||||
newDSL := d2format.Format(m)
|
|
||||||
if dsl != newDSL {
|
|
||||||
resp.DSL = newDSL
|
|
||||||
}
|
|
||||||
|
|
||||||
str, _ := json.Marshal(resp)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO error passing
|
|
||||||
// TODO recover panics
|
|
||||||
func jsCompile(this js.Value, args []js.Value) interface{} {
|
|
||||||
script := args[0].String()
|
|
||||||
|
|
||||||
g, _, err := d2compiler.Compile("", strings.NewReader(script), &d2compiler.CompileOptions{
|
|
||||||
UTF16Pos: true,
|
|
||||||
})
|
|
||||||
var pe *d2parser.ParseError
|
|
||||||
if err != nil {
|
|
||||||
if errors.As(err, &pe) {
|
|
||||||
serialized, _ := json.Marshal(err)
|
|
||||||
ret := jsObject{UserError: string(serialized)}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
ret := jsObject{D2Error: err.Error()}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
newScript := d2format.Format(g.AST)
|
|
||||||
if script != newScript {
|
|
||||||
ret := jsObject{Result: newScript}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func jsEncode(this js.Value, args []js.Value) interface{} {
|
|
||||||
script := args[0].String()
|
|
||||||
|
|
||||||
encoded, err := urlenc.Encode(script)
|
|
||||||
// should never happen
|
|
||||||
if err != nil {
|
|
||||||
ret := jsObject{D2Error: err.Error()}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := jsObject{Result: encoded}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
func jsDecode(this js.Value, args []js.Value) interface{} {
|
|
||||||
script := args[0].String()
|
|
||||||
|
|
||||||
script, err := urlenc.Decode(script)
|
|
||||||
if err != nil {
|
|
||||||
ret := jsObject{UserError: err.Error()}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := jsObject{Result: script}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
func jsVersion(this js.Value, args []js.Value) interface{} {
|
|
||||||
return version.Version
|
|
||||||
}
|
|
||||||
|
|
||||||
type jsBoardAtPosition struct {
|
|
||||||
BoardPath []string `json:"boardPath"`
|
|
||||||
Error string `json:"error"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func jsGetBoardAtPosition(this js.Value, args []js.Value) interface{} {
|
|
||||||
dsl := args[0].String()
|
|
||||||
line := args[1].Int()
|
|
||||||
column := args[2].Int()
|
|
||||||
|
|
||||||
boardPath, err := d2lsp.GetBoardAtPosition(dsl, d2ast.Position{
|
|
||||||
Line: line,
|
|
||||||
Column: column,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
ret := jsBoardAtPosition{Error: err.Error()}
|
|
||||||
str, _ := json.Marshal(ret)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := jsBoardAtPosition{
|
|
||||||
BoardPath: boardPath,
|
|
||||||
}
|
|
||||||
str, _ := json.Marshal(resp)
|
|
||||||
return string(str)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue