-
Notifications
You must be signed in to change notification settings - Fork 246
/
request.go
97 lines (81 loc) · 2.44 KB
/
request.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//go:build wasm
// +build wasm
package main
import (
"context"
"fmt"
"syscall/js"
"github.com/authzed/spicedb/pkg/development"
devinterface "github.com/authzed/spicedb/pkg/proto/developer/v1"
"google.golang.org/protobuf/encoding/protojson"
)
// runDeveloperRequest is the function exported into the WASM environment for invoking
// one or more development operations.
//
// The arguments are:
//
// 1. Message in the form of a DeveloperRequest containing the context and the operation(s) to
// run, in JSON form.
//
// The function returns:
//
// A single JSON-encoded string of messages of type DeveloperResponse representing the errors
// encountered (if any), or the responses for each operation.
//
// See example/wasm.html for an example.
func runDeveloperRequest(this js.Value, args []js.Value) any {
if len(args) != 1 {
return respErr(fmt.Errorf("invalid number of arguments specified"))
}
// Unmarshal the developer request.
encoded := args[0].String()
devRequest := &devinterface.DeveloperRequest{}
err := protojson.Unmarshal([]byte(encoded), devRequest)
if err != nil {
return respErr(fmt.Errorf("could not decode developer request: %w", err))
}
if devRequest.Context == nil {
return respErr(fmt.Errorf("missing required context"))
}
// Construct the developer context.
devContext, devErrors, err := development.NewDevContext(context.Background(), devRequest.Context)
if err != nil {
return respErr(err)
}
if devErrors != nil && len(devErrors.InputErrors) > 0 {
return respInputErr(devErrors.InputErrors)
}
// Run operations.
results := make(map[uint64]*devinterface.OperationResult, len(devRequest.Operations))
for index, op := range devRequest.Operations {
result, err := runOperation(devContext, op)
if err != nil {
return respErr(err)
}
results[uint64(index)] = result
}
return encode(&devinterface.DeveloperResponse{
OperationsResults: &devinterface.OperationsResults{
Results: results,
},
})
}
func encode(response *devinterface.DeveloperResponse) js.Value {
encoded, err := protojson.Marshal(response)
if err != nil {
panic(err)
}
return js.ValueOf(string(encoded))
}
func respErr(err error) js.Value {
return encode(&devinterface.DeveloperResponse{
InternalError: err.Error(),
})
}
func respInputErr(inputErrors []*devinterface.DeveloperError) js.Value {
return encode(&devinterface.DeveloperResponse{
DeveloperErrors: &devinterface.DeveloperErrors{
InputErrors: inputErrors,
},
})
}