feat: support union types

This commit is contained in:
Kevin Franklin Kim 2022-03-02 15:18:09 +01:00
parent 40c94dab59
commit b1eeafc427
72 changed files with 3261 additions and 193 deletions

56
.golangci.yaml Normal file
View File

@ -0,0 +1,56 @@
# Minimum golangci-lint version required: v1.42.0
run:
timeout: 3m
skip-dirs:
- tmp
linters-settings:
gci:
local-prefixes: github.com/foomo/keel
revive:
rules:
- name: indent-error-flow
disabled: true
gocritic:
enabled-tags:
- diagnostic
- performance
- style
disabled-tags:
- experimental
- opinionated
disabled-checks:
- ifElseChain
settings:
hugeParam:
sizeThreshold: 512
linters:
enable:
- bodyclose
- exhaustive
- dogsled
- dupl
- exportloopref
- goconst
- gocritic
- gocyclo
- gofmt
- goprintffuncname
- gosec
- ifshort
- misspell
- nakedret
- noctx
- nolintlint
- prealloc
- revive
- promlinter
- rowserrcheck
- sqlclosecheck
- stylecheck
- thelper
- tparallel
- unconvert
- unparam
- whitespace

View File

@ -29,23 +29,58 @@ build.debug:
go build -gcflags "all=-N -l" -o bin/gotsrpc cmd/gotsrpc/gotsrpc.go go build -gcflags "all=-N -l" -o bin/gotsrpc cmd/gotsrpc/gotsrpc.go
EXAMPLES=basic nullable ## === Tools ===
EXAMPLES=basic errors nullable multi
define examples define examples
.PHONY: example.$(1) .PHONY: example.$(1)
example.$(1): example.$(1):
cd example/${1} && go run ../../cmd/gotsrpc/gotsrpc.go gotsrpc.yml cd example/${1} && go run ../../cmd/gotsrpc/gotsrpc.go gotsrpc.yml
cd example/${1}/client && tsc --build
.PHONY: example.$(1).run .PHONY: example.$(1).run
example.$(1).run: example.${1} example.$(1).run: example.${1}
cd example/${1}/client && tsc --build
cd example/${1} && go run main.go cd example/${1} && go run main.go
.PHONY: example.$(1).debug .PHONY: example.$(1).debug
example.$(1).debug: build.debug example.$(1).debug: build.debug
cd example/${1} && dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ../../bin/gotsrpc gotsrpc.yml cd example/${1} && dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ../../bin/gotsrpc gotsrpc.yml
.PHONY: example.$(1).lint
example.$(1).lint:
cd example/${1} && golangci-lint run
endef endef
$(foreach p,$(EXAMPLES),$(eval $(call examples,$(p)))) $(foreach p,$(EXAMPLES),$(eval $(call examples,$(p))))
## Run go mod tidy recursive
.PHONY: lint
lint:
# @golangci-lint run
@for name in example/*/; do\
echo "-------- $${name} ------------";\
sh -c "cd $$(pwd)/$${name} && golangci-lint run";\
done
## Run go mod tidy recursive
.PHONY: gomod
gomod:
@go mod tidy
@for name in example/*/; do\
echo "-------- $${name} ------------";\
sh -c "cd $$(pwd)/$${name} && go mod tidy";\
done
## === Examples ===
.PHONY: examples
## Build examples
examples:
@for name in example/*/; do\
echo "-------- $${name} ------------";\
$(MAKE) example.`basename $${name}`;\
done
.PHONY: examples
## === Utils === ## === Utils ===
## Show help text ## Show help text

View File

@ -132,6 +132,14 @@ func Build(conf *config.Config, goPath string) {
os.Exit(2) os.Exit(2)
} }
// collect all union structs
unions := map[string][]string{}
for _, s := range structs {
if len(s.Fields) == 0 && len(s.UnionFields) > 0 {
unions[s.Package] = append(unions[s.Package], s.Name)
}
}
if target.Out != "" { if target.Out != "" {
ts, err := RenderTypeScriptServices(services, conf.Mappings, scalars, structs, target) ts, err := RenderTypeScriptServices(services, conf.Mappings, scalars, structs, target)
@ -192,13 +200,14 @@ func Build(conf *config.Config, goPath string) {
} }
} }
if len(target.TSRPC) > 0 { if len(target.TSRPC) > 0 {
goTSRPCProxiesCode, goerr := RenderGoTSRPCProxies(services, packageName, pkgName, target) goTSRPCProxiesCode, goerr := RenderGoTSRPCProxies(services, packageName, pkgName, target, unions)
if goerr != nil { if goerr != nil {
fmt.Fprintln(os.Stderr, " could not generate go ts rpc proxies code in target", name, goerr) fmt.Fprintln(os.Stderr, " could not generate go ts rpc proxies code in target", name, goerr)
os.Exit(4) os.Exit(4)
} }
formatAndWrite(goTSRPCProxiesCode, goTSRPCProxiesFilename) formatAndWrite(goTSRPCProxiesCode, goTSRPCProxiesFilename)
}
if len(target.TSRPC) > 0 && !target.SkipTSRPCClient {
goTSRPCClientsCode, goerr := RenderGoTSRPCClients(services, packageName, pkgName, target) goTSRPCClientsCode, goerr := RenderGoTSRPCClients(services, packageName, pkgName, target)
if goerr != nil { if goerr != nil {
fmt.Fprintln(os.Stderr, " could not generate go ts rpc clients code in target", name, goerr) fmt.Fprintln(os.Stderr, " could not generate go ts rpc clients code in target", name, goerr)

View File

@ -75,15 +75,15 @@ func (c *bufferedClient) SetTransportHttpClient(client *http.Client) {
c.client = client c.client = client
} }
// CallClient calls a method on the remove service // Call calls a method on the remove service
func (c *bufferedClient) Call(ctx context.Context, url string, endpoint string, method string, args []interface{}, reply []interface{}) (err error) { func (c *bufferedClient) Call(ctx context.Context, url string, endpoint string, method string, args []interface{}, reply []interface{}) error {
// Marshall args // Marshall args
b := new(bytes.Buffer) b := new(bytes.Buffer)
// If no arguments are set, remove // If no arguments are set, remove
if len(args) > 0 { if len(args) > 0 {
if err := codec.NewEncoder(b, c.handle.handle).Encode(args); err != nil { if err := codec.NewEncoder(b, c.handle.handle).Encode(args); err != nil {
return errors.Wrap(err, "could not encode argument") return NewClientError(errors.Wrap(err, "failed to encode arguments"))
} }
} }
@ -93,28 +93,47 @@ func (c *bufferedClient) Call(ctx context.Context, url string, endpoint string,
request, errRequest := newRequest(ctx, postURL, c.handle.contentType, b, c.headers.Clone()) request, errRequest := newRequest(ctx, postURL, c.handle.contentType, b, c.headers.Clone())
if errRequest != nil { if errRequest != nil {
return errRequest return NewClientError(errors.Wrap(errRequest, "failed to create request"))
} }
resp, errDo := c.client.Do(request) resp, errDo := c.client.Do(request)
if errDo != nil { if errDo != nil {
return errors.Wrap(errDo, "could not execute request") return NewClientError(errors.Wrap(errDo, "failed to send request"))
} }
defer resp.Body.Close() defer resp.Body.Close()
// Check status // Check status
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
body, err := ioutil.ReadAll(resp.Body) body := "request failed"
if err != nil { if value, err := ioutil.ReadAll(resp.Body); err == nil {
return err body = string(value)
}
return NewClientError(NewHTTPError(body, resp.StatusCode))
}
wrappedReply := make([]interface{}, len(reply))
for k, v := range reply {
if _, ok := v.(*error); ok {
var e *Error
wrappedReply[k] = e
} else {
wrappedReply[k] = v
} }
return fmt.Errorf("[%d] %s", resp.StatusCode, string(body))
} }
responseHandle := getHandlerForContentType(resp.Header.Get("Content-Type")).handle responseHandle := getHandlerForContentType(resp.Header.Get("Content-Type")).handle
if err := codec.NewDecoder(resp.Body, responseHandle).Decode(reply); err != nil { if err := codec.NewDecoder(resp.Body, responseHandle).Decode(wrappedReply); err != nil {
return errors.Wrap(err, "could not decode response from client") return NewClientError(errors.Wrap(err, "failed to decode response"))
} }
return err // replace error
for k, v := range wrappedReply {
if x, ok := v.(*Error); ok && x != nil {
if y, ok := reply[k].(*error); ok {
*y = x
}
}
}
return nil
} }

11
clienterror.go Normal file
View File

@ -0,0 +1,11 @@
package gotsrpc
type ClientError struct {
error
}
func NewClientError(err error) *ClientError {
return &ClientError{
error: err,
}
}

View File

@ -18,6 +18,7 @@ type Target struct {
Out string `yaml:"out"` Out string `yaml:"out"`
GoRPC []string `yaml:"gorpc"` GoRPC []string `yaml:"gorpc"`
TSRPC []string `yaml:"tsrpc"` TSRPC []string `yaml:"tsrpc"`
SkipTSRPCClient bool `yaml:"skipTSRPCClient"`
} }
func (t *Target) IsGoRPC(service string) bool { func (t *Target) IsGoRPC(service string) bool {

126
error.go Normal file
View File

@ -0,0 +1,126 @@
package gotsrpc
import (
"fmt"
"io"
"reflect"
"strings"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
)
type Error struct {
Msg string `json:"m"`
Pkg string `json:"p"`
Type string `json:"t"`
Data interface{} `json:"d,omitempty"`
ErrCause *Error `json:"c,omitempty"`
}
// NewError returns a new instance
func NewError(err error) *Error {
// check if already transformed
if v, ok := err.(*Error); ok {
return v
}
// skip *withStack error type
if _, ok := err.(interface {
StackTrace() errors.StackTrace
}); ok && errors.Unwrap(err) != nil {
err = errors.Unwrap(err)
}
// retrieve error details
errType := reflect.TypeOf(err)
inst := &Error{
Msg: err.Error(),
Type: errType.String(),
Pkg: errType.Elem().PkgPath(),
Data: err,
}
// unwrap error
if unwrappedErr := errors.Unwrap(err); unwrappedErr != nil {
inst.ErrCause = NewError(unwrappedErr)
inst.Msg = strings.TrimSuffix(inst.Msg, ": "+unwrappedErr.Error())
}
return inst
}
// As interface
func (e *Error) As(err interface{}) bool {
if e == nil || err == nil {
return false
}
if reflect.TypeOf(err).Elem().String() == e.Type {
if decodeErr := mapstructure.Decode(e.Data, &err); decodeErr != nil {
fmt.Printf("ERROR: failed to decode error data\n%+v", decodeErr)
return false
} else {
return true
}
}
return false
}
// Cause interface
func (e *Error) Cause() error {
if e.ErrCause != nil {
return e.ErrCause
}
return e
}
// Format interface
func (e *Error) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
if s.Flag('+') {
fmt.Fprintf(s, "%s.(%s)\n", e.Pkg, e.Type)
if e.Data != nil {
fmt.Fprintf(s, "Data: %v\n", e.Data)
}
}
fallthrough
case 's', 'q':
io.WriteString(s, e.Error())
}
}
// Unwrap interface
func (e *Error) Unwrap() error {
if e != nil && e.ErrCause != nil {
return e.ErrCause
}
return nil
}
// Is interface
func (e *Error) Is(err error) bool {
if e == nil || err == nil {
return false
}
errType := reflect.TypeOf(err)
if e.Msg == err.Error() &&
errType.String() == e.Type &&
errType.Elem().PkgPath() == e.Pkg {
return true
}
return false
}
// Error interface
func (e *Error) Error() string {
msg := e.Msg
if e.ErrCause != nil {
msg += ": " + e.ErrCause.Error()
}
return msg
}

View File

@ -5,7 +5,7 @@ import transport from "./transport.js";
export const init = () => { export const init = () => {
const client = new ServiceClient(transport("/service")); const client = new ServiceClient(transport("/service"));
client.string("hello world").then((res) => { client.boolPtr(true).then((res) => {
console.log(res); console.log(res);
}); });
}; };

View File

@ -10,6 +10,9 @@ export class ServiceClient {
async bool(v:boolean):Promise<boolean> { async bool(v:boolean):Promise<boolean> {
return (await this.transport<{0:boolean}>("Bool", [v]))[0] return (await this.transport<{0:boolean}>("Bool", [v]))[0]
} }
async boolPtr(v:boolean):Promise<boolean|null> {
return (await this.transport<{0:boolean|null}>("BoolPtr", [v]))[0]
}
async boolSlice(v:Array<boolean>|null):Promise<Array<boolean>|null> { async boolSlice(v:Array<boolean>|null):Promise<Array<boolean>|null> {
return (await this.transport<{0:Array<boolean>|null}>("BoolSlice", [v]))[0] return (await this.transport<{0:Array<boolean>|null}>("BoolSlice", [v]))[0]
} }

View File

@ -143,6 +143,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=

View File

@ -28,6 +28,13 @@ type (
RetBool_0 bool RetBool_0 bool
} }
ServiceBoolPtrRequest struct {
V bool
}
ServiceBoolPtrResponse struct {
RetBoolPtr_0 *bool
}
ServiceBoolSliceRequest struct { ServiceBoolSliceRequest struct {
V []bool V []bool
} }
@ -438,6 +445,8 @@ type (
func init() { func init() {
gob.Register(ServiceBoolRequest{}) gob.Register(ServiceBoolRequest{})
gob.Register(ServiceBoolResponse{}) gob.Register(ServiceBoolResponse{})
gob.Register(ServiceBoolPtrRequest{})
gob.Register(ServiceBoolPtrResponse{})
gob.Register(ServiceBoolSliceRequest{}) gob.Register(ServiceBoolSliceRequest{})
gob.Register(ServiceBoolSliceResponse{}) gob.Register(ServiceBoolSliceResponse{})
gob.Register(ServiceFloat32Request{}) gob.Register(ServiceFloat32Request{})
@ -598,6 +607,10 @@ func (p *ServiceGoRPCProxy) handler(clientAddr string, request interface{}) (res
req := request.(ServiceBoolRequest) req := request.(ServiceBoolRequest)
retBool_0 := p.service.Bool(req.V) retBool_0 := p.service.Bool(req.V)
response = ServiceBoolResponse{RetBool_0: retBool_0} response = ServiceBoolResponse{RetBool_0: retBool_0}
case "ServiceBoolPtrRequest":
req := request.(ServiceBoolPtrRequest)
retBoolPtr_0 := p.service.BoolPtr(req.V)
response = ServiceBoolPtrResponse{RetBoolPtr_0: retBoolPtr_0}
case "ServiceBoolSliceRequest": case "ServiceBoolSliceRequest":
req := request.(ServiceBoolSliceRequest) req := request.(ServiceBoolSliceRequest)
retBoolSlice_0 := p.service.BoolSlice(req.V) retBoolSlice_0 := p.service.BoolSlice(req.V)

View File

@ -41,6 +41,17 @@ func (tsc *ServiceGoRPCClient) Bool(v bool) (retBool_0 bool, clientErr error) {
return response.RetBool_0, nil return response.RetBool_0, nil
} }
func (tsc *ServiceGoRPCClient) BoolPtr(v bool) (retBoolPtr_0 *bool, clientErr error) {
req := ServiceBoolPtrRequest{V: v}
rpcCallRes, rpcCallErr := tsc.Client.Call(req)
if rpcCallErr != nil {
clientErr = rpcCallErr
return
}
response := rpcCallRes.(ServiceBoolPtrResponse)
return response.RetBoolPtr_0, nil
}
func (tsc *ServiceGoRPCClient) BoolSlice(v []bool) (retBoolSlice_0 []bool, clientErr error) { func (tsc *ServiceGoRPCClient) BoolSlice(v []bool) (retBoolSlice_0 []bool, clientErr error) {
req := ServiceBoolSliceRequest{V: v} req := ServiceBoolSliceRequest{V: v}
rpcCallRes, rpcCallErr := tsc.Client.Call(req) rpcCallRes, rpcCallErr := tsc.Client.Call(req)

View File

@ -13,6 +13,7 @@ import (
const ( const (
ServiceGoTSRPCProxyBool = "Bool" ServiceGoTSRPCProxyBool = "Bool"
ServiceGoTSRPCProxyBoolPtr = "BoolPtr"
ServiceGoTSRPCProxyBoolSlice = "BoolSlice" ServiceGoTSRPCProxyBoolSlice = "BoolSlice"
ServiceGoTSRPCProxyFloat32 = "Float32" ServiceGoTSRPCProxyFloat32 = "Float32"
ServiceGoTSRPCProxyFloat32Map = "Float32Map" ServiceGoTSRPCProxyFloat32Map = "Float32Map"
@ -79,10 +80,7 @@ type ServiceGoTSRPCProxy struct {
} }
func NewDefaultServiceGoTSRPCProxy(service Service) *ServiceGoTSRPCProxy { func NewDefaultServiceGoTSRPCProxy(service Service) *ServiceGoTSRPCProxy {
return &ServiceGoTSRPCProxy{ return NewServiceGoTSRPCProxy(service, "/service")
EndPoint: "/service",
service: service,
}
} }
func NewServiceGoTSRPCProxy(service Service, endpoint string) *ServiceGoTSRPCProxy { func NewServiceGoTSRPCProxy(service Service, endpoint string) *ServiceGoTSRPCProxy {
@ -128,6 +126,23 @@ func (p *ServiceGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request)
} }
gotsrpc.Reply([]interface{}{boolRet}, callStats, r, w) gotsrpc.Reply([]interface{}{boolRet}, callStats, r, w)
return return
case ServiceGoTSRPCProxyBoolPtr:
var (
arg_v bool
)
args := []interface{}{&arg_v}
err := gotsrpc.LoadArgs(&args, callStats, r)
if err != nil {
gotsrpc.ErrorCouldNotLoadArgs(w)
return
}
executionStart := time.Now()
boolPtrRet := p.service.BoolPtr(arg_v)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
gotsrpc.Reply([]interface{}{boolPtrRet}, callStats, r, w)
return
case ServiceGoTSRPCProxyBoolSlice: case ServiceGoTSRPCProxyBoolSlice:
var ( var (
arg_v []bool arg_v []bool

View File

@ -12,6 +12,7 @@ import (
type ServiceGoTSRPCClient interface { type ServiceGoTSRPCClient interface {
Bool(ctx go_context.Context, v bool) (retBool_0 bool, clientErr error) Bool(ctx go_context.Context, v bool) (retBool_0 bool, clientErr error)
BoolPtr(ctx go_context.Context, v bool) (retBoolPtr_0 *bool, clientErr error)
BoolSlice(ctx go_context.Context, v []bool) (retBoolSlice_0 []bool, clientErr error) BoolSlice(ctx go_context.Context, v []bool) (retBoolSlice_0 []bool, clientErr error)
Float32(ctx go_context.Context, v float32) (retFloat32_0 float32, clientErr error) Float32(ctx go_context.Context, v float32) (retFloat32_0 float32, clientErr error)
Float32Map(ctx go_context.Context, v map[float32]interface{}) (retFloat32Map_0 map[float32]interface{}, clientErr error) Float32Map(ctx go_context.Context, v map[float32]interface{}) (retFloat32Map_0 map[float32]interface{}, clientErr error)
@ -103,6 +104,16 @@ func (tsc *HTTPServiceGoTSRPCClient) Bool(ctx go_context.Context, v bool) (retBo
return return
} }
func (tsc *HTTPServiceGoTSRPCClient) BoolPtr(ctx go_context.Context, v bool) (retBoolPtr_0 *bool, clientErr error) {
args := []interface{}{v}
reply := []interface{}{&retBoolPtr_0}
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "BoolPtr", args, reply)
if clientErr != nil {
clientErr = pkg_errors.WithMessage(clientErr, "failed to call service.ServiceGoTSRPCProxy BoolPtr")
}
return
}
func (tsc *HTTPServiceGoTSRPCClient) BoolSlice(ctx go_context.Context, v []bool) (retBoolSlice_0 []bool, clientErr error) { func (tsc *HTTPServiceGoTSRPCClient) BoolSlice(ctx go_context.Context, v []bool) (retBoolSlice_0 []bool, clientErr error) {
args := []interface{}{v} args := []interface{}{v}
reply := []interface{}{&retBoolSlice_0} reply := []interface{}{&retBoolSlice_0}

View File

@ -6,6 +6,10 @@ func (h *Handler) Bool(v bool) bool {
return v return v
} }
func (h *Handler) BoolPtr(v bool) *bool {
return &v
}
func (h *Handler) Int(v int) int { func (h *Handler) Int(v int) int {
return v return v
} }

View File

@ -2,6 +2,7 @@ package service
type Service interface { type Service interface {
Bool(v bool) bool Bool(v bool) bool
BoolPtr(v bool) *bool
Int(v int) int Int(v int) int
Int32(v int32) int32 Int32(v int32) int32
Int64(v int64) int64 Int64(v int64) int64

167
example/errors/call/main.go Normal file
View File

@ -0,0 +1,167 @@
package main
import (
"context"
"fmt"
"github.com/pkg/errors"
"github.com/foomo/gotsrpc/v2"
"github.com/foomo/gotsrpc/v2/example/errors/handler/backend"
backendsvs "github.com/foomo/gotsrpc/v2/example/errors/service/backend"
)
func main() {
ctx := context.Background()
c := backendsvs.NewDefaultServiceGoTSRPCClient("http://localhost:3000")
{
fmt.Println("-------------------------")
var gotsrpcErr *gotsrpc.Error
serviceErr, err := c.Error(ctx)
if err != nil {
panic("client error should be nil")
} else if serviceErr == nil {
panic("service error should not be nil")
} else if serviceErr != nil {
fmt.Println("OK")
}
if errors.As(serviceErr, &gotsrpcErr) {
fmt.Printf("%s\n", gotsrpcErr)
fmt.Printf("%q\n", gotsrpcErr)
fmt.Printf("%+v\n", gotsrpcErr)
}
}
{
fmt.Println("-------------------------")
scalar, err := c.Scalar(ctx)
if err != nil {
panic("client error should be nil")
} else if scalar == nil {
panic("service error should not be nil")
} else if scalar != nil {
fmt.Println("OK")
}
}
{
fmt.Println("-------------------------")
scalar, err := c.MultiScalar(ctx)
if err != nil {
panic("client error should be nil")
} else if scalar == nil {
panic("service error should not be nil")
} else if scalar != nil {
fmt.Println("OK")
}
}
{
fmt.Println("-------------------------")
var gotsrpcErr *gotsrpc.Error
serviceErr, err := c.WrappedError(ctx)
if err != nil {
panic("client error should be nil")
} else if serviceErr == nil {
panic("service error should not be nil")
} else if serviceErr != nil {
fmt.Println("OK")
}
if errors.As(serviceErr, &gotsrpcErr) {
fmt.Println(gotsrpcErr.Error())
fmt.Printf("%+v\n", gotsrpcErr)
}
if errors.As(errors.Unwrap(serviceErr), &gotsrpcErr) {
fmt.Println(gotsrpcErr.Error())
}
}
{
fmt.Println("-------------------------")
var scalarErr *backend.ScalarError
var gotsrpcErr *gotsrpc.Error
serviceErr, err := c.ScalarError(ctx)
if err != nil {
panic("client error should be nil")
} else if serviceErr == nil {
panic("service error should not be nil")
} else if serviceErr != nil {
fmt.Printf("%s\n", serviceErr)
fmt.Printf("%q\n", serviceErr)
fmt.Printf("%+v\n", serviceErr)
}
if errors.As(serviceErr, &gotsrpcErr) {
fmt.Println(gotsrpcErr)
}
if errors.As(serviceErr, &scalarErr) {
fmt.Println(scalarErr)
}
}
{
fmt.Println("-------------------------")
var customErr *backend.CustomError
var gotsrpcErr *gotsrpc.Error
serviceErr, err := c.CustomError(ctx)
if err != nil {
panic("client error should be nil")
} else if serviceErr == nil {
panic("service error should not be nil")
} else if serviceErr != nil {
fmt.Printf("%s\n", serviceErr)
fmt.Printf("%q\n", serviceErr)
fmt.Printf("%+v\n", serviceErr)
}
if errors.As(serviceErr, &gotsrpcErr) {
fmt.Println(gotsrpcErr)
}
if errors.As(serviceErr, &customErr) {
fmt.Println(customErr)
}
}
{
fmt.Println("-------------------------")
serviceErr, err := c.TypedError(ctx)
if err != nil {
panic("client error should be nil")
} else if serviceErr == nil {
panic("service error should not be nil")
} else if serviceErr != nil {
fmt.Println("OK")
}
if errors.Is(serviceErr, backend.ErrTyped) {
fmt.Println("OK")
}
}
{
fmt.Println("-------------------------")
serviceErr, err := c.TypedWrappedError(ctx)
if err != nil {
panic("client error should be nil")
} else if serviceErr == nil {
panic("service error should not be nil")
} else if serviceErr != nil {
fmt.Println("OK")
}
if errors.Is(serviceErr, backend.ErrTyped) {
fmt.Println("OK")
}
}
{
fmt.Println("-------------------------")
serviceErr, err := c.TypedCustomError(ctx)
if err != nil {
panic("client error should be nil")
} else if serviceErr == nil {
panic("service error should not be nil")
} else if serviceErr != nil {
fmt.Println("OK")
}
if errors.Is(serviceErr, backend.ErrCustom) {
fmt.Println("OK")
}
}
}

View File

@ -0,0 +1,19 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Errors</title>
<script type="module">
import { init } from './dist/app.js'
init()
</script>
</head>
<body>
<h1>A service test</h1>
<code>
<pre>open the console!</pre>
</code>
</body>
</html>

View File

@ -0,0 +1,14 @@
import {ServiceClient} from "./service-client.js";
import transport from "./transport.js";
export const init = () => {
const client = new ServiceClient(transport("/service/frontend"))
client.simple().then((ret) => {
console.log(ret)
})
client.multiple().then(ret => {
console.log(ret)
})
}

View File

@ -0,0 +1,16 @@
/* eslint:disable */
// hello commonjs - we need some imports - sorted in alphabetical order, by go package
import * as github_com_foomo_gotsrpc_v2_example_errors_service_frontend from './service-vo'; // ./client/src/service-client.ts to ./client/src/service-vo.ts
export class ServiceClient {
public static defaultEndpoint = "/service/frontend";
constructor(
public transport:<T>(method: string, data?: any[]) => Promise<T>
) {}
async multiple():Promise<github_com_foomo_gotsrpc_v2_example_errors_service_frontend.ErrMulti|null> {
return (await this.transport<{0:github_com_foomo_gotsrpc_v2_example_errors_service_frontend.ErrMulti|null}>("Multiple", []))[0]
}
async simple():Promise<github_com_foomo_gotsrpc_v2_example_errors_service_frontend.ErrSimple|null> {
return (await this.transport<{0:github_com_foomo_gotsrpc_v2_example_errors_service_frontend.ErrSimple|null}>("Simple", []))[0]
}
}

View File

@ -0,0 +1,21 @@
/* eslint:disable */
// hello commonjs - we need some imports - sorted in alphabetical order, by go package
import * as github_com_foomo_gotsrpc_v2_example_errors_service_frontend from './service-vo'; // ./client/src/service-vo.ts to ./client/src/service-vo.ts
// github.com/foomo/gotsrpc/v2/example/errors/service/frontend.ErrMulti
export type ErrMulti = (typeof github_com_foomo_gotsrpc_v2_example_errors_service_frontend.ErrMultiA) & (typeof github_com_foomo_gotsrpc_v2_example_errors_service_frontend.ErrMultiB)
// github.com/foomo/gotsrpc/v2/example/errors/service/frontend.ErrMultiA
export enum ErrMultiA {
One = "one",
Two = "two",
}
// github.com/foomo/gotsrpc/v2/example/errors/service/frontend.ErrMultiB
export enum ErrMultiB {
Four = "four",
Three = "three",
}
// github.com/foomo/gotsrpc/v2/example/errors/service/frontend.ErrSimple
export enum ErrSimple {
One = "one",
Two = "two",
}
// end of common js

View File

@ -0,0 +1,18 @@
const transport = endpoint => async <T>(method: string, args: any = []) => {
return new Promise<T>(async (resolve, reject) => {
fetch(
`${endpoint}/${encodeURIComponent(method)}`,
{
method: 'POST',
body: JSON.stringify(args),
}
)
.then((response) => {
return response.json() as Promise<T>;
})
.then((val) => resolve(val))
.catch((err) => reject(err))
})
};
export default transport

View File

@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
}
}

14
example/errors/go.mod Normal file
View File

@ -0,0 +1,14 @@
module github.com/foomo/gotsrpc/v2/example/errors
go 1.16
require (
github.com/foomo/gotsrpc/v2 v2.0.10
github.com/kr/pretty v0.3.0 // indirect
github.com/pkg/errors v0.9.1
github.com/rogpeppe/go-internal v1.8.1 // indirect
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
)
replace github.com/foomo/gotsrpc/v2 => ../../

494
example/errors/go.sum Normal file
View File

@ -0,0 +1,494 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E=
github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0=
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

View File

@ -0,0 +1,23 @@
module:
name: github.com/foomo/gotsrpc/v2/example/errors
path: ./
targets:
frontend:
services:
/service/frontend: Service
package: github.com/foomo/gotsrpc/v2/example/errors/service/frontend
out: ./client/src/service-client.ts
skipTSRPCClient: true
tsrpc:
- Service
backend:
services:
/service/backend: Service
package: github.com/foomo/gotsrpc/v2/example/errors/service/backend
tsrpc:
- Service
mappings:
github.com/foomo/gotsrpc/v2/example/errors/service/frontend:
out: ./client/src/service-vo.ts

View File

@ -0,0 +1,104 @@
package backend
import (
"net/http"
"github.com/pkg/errors"
"github.com/foomo/gotsrpc/v2/example/errors/service/backend"
)
type (
ScalarError string
CustomError struct {
Msg string
Map map[string]string
Slice []string
Struct struct {
A string
}
}
)
const (
ScalarErrorOne ScalarError = "scalar error one"
ScalarErrorTwo ScalarError = "scalar error two"
)
func NewScalarError(e ScalarError) *ScalarError {
return &e
}
func (e *ScalarError) Error() string {
return string(*e)
}
func NewCustomError(msg string) *CustomError {
return &CustomError{
Msg: msg,
Map: map[string]string{"a": "b"},
Slice: []string{"a", "b"},
Struct: struct{ A string }{A: "b"},
}
}
func (e *CustomError) Error() string {
return e.Msg
}
var (
ErrTyped = errors.New("typed error")
ErrCustom = NewCustomError("typed custom error")
ErrScalarOne = NewScalarError(ScalarErrorOne)
ErrScalarTwo = NewScalarError(ScalarErrorTwo)
)
type Handler struct {
}
func New() *Handler {
return &Handler{}
}
func (h *Handler) Error(w http.ResponseWriter, r *http.Request) (e error) {
return errors.New("error")
}
func (h *Handler) Scalar(w http.ResponseWriter, r *http.Request) (e *backend.Scalar) {
s := backend.ScalarOne
return &s
}
func (h *Handler) MultiScalar(w http.ResponseWriter, r *http.Request) (e *backend.MultiScalar) {
return &backend.MultiScalar{
ScalarA: backend.ScalarAOne,
}
}
func (h *Handler) TypedError(w http.ResponseWriter, r *http.Request) (e error) {
return ErrTyped
}
func (h *Handler) ScalarError(w http.ResponseWriter, r *http.Request) (e error) {
return NewScalarError(ScalarErrorOne)
}
func (h *Handler) CustomError(w http.ResponseWriter, r *http.Request) (e error) {
return NewCustomError("custom error")
}
func (h *Handler) WrappedError(w http.ResponseWriter, r *http.Request) (e error) {
return errors.Wrap(errors.New("error"), "wrapped")
}
func (h *Handler) TypedWrappedError(w http.ResponseWriter, r *http.Request) (e error) {
return errors.Wrap(ErrTyped, "wrapped")
}
func (h *Handler) TypedScalarError(w http.ResponseWriter, r *http.Request) (e error) {
return ErrScalarTwo
}
func (h *Handler) TypedCustomError(w http.ResponseWriter, r *http.Request) (e error) {
return ErrCustom
}

View File

@ -0,0 +1,29 @@
package frontend
import (
"net/http"
"github.com/foomo/gotsrpc/v2/example/errors/service/backend"
"github.com/foomo/gotsrpc/v2/example/errors/service/frontend"
)
type Handler struct {
client backend.ServiceGoTSRPCClient
}
func New(client backend.ServiceGoTSRPCClient) *Handler {
return &Handler{
client: client,
}
}
func (h *Handler) Simple(w http.ResponseWriter, r *http.Request) (e *frontend.ErrSimple) {
return
}
func (h *Handler) Multiple(w http.ResponseWriter, r *http.Request) (e *frontend.ErrMulti) {
return &frontend.ErrMulti{
ErrMultiA: frontend.ErrMultiAOne,
ErrMultiB: "",
}
}

42
example/errors/main.go Normal file
View File

@ -0,0 +1,42 @@
package main
import (
"net/http"
"os/exec"
"strings"
"time"
"github.com/foomo/gotsrpc/v2/example/errors/handler/backend"
"github.com/foomo/gotsrpc/v2/example/errors/handler/frontend"
backendsvs "github.com/foomo/gotsrpc/v2/example/errors/service/backend"
frontendsvs "github.com/foomo/gotsrpc/v2/example/errors/service/frontend"
)
func main() {
fs := http.FileServer(http.Dir("./client"))
fh := frontendsvs.NewDefaultServiceGoTSRPCProxy(frontend.New(backendsvs.NewDefaultServiceGoTSRPCClient("http://localhost:3000")))
bh := backendsvs.NewDefaultServiceGoTSRPCProxy(backend.New())
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
switch {
case strings.HasPrefix(r.URL.Path, "/service/frontend"):
fh.ServeHTTP(w, r)
case strings.HasPrefix(r.URL.Path, "/service/backend"):
bh.ServeHTTP(w, r)
default:
fs.ServeHTTP(w, r)
}
})
go func() {
time.Sleep(time.Second)
_ = exec.Command("open", "http://127.0.0.1:3000").Run()
}()
go func() {
if err := http.ListenAndServe("localhost:3000", mux); err != nil {
panic(err)
}
}()
}

View File

@ -0,0 +1,176 @@
// Code generated by gotsrpc https://github.com/foomo/gotsrpc/v2 - DO NOT EDIT.
package backend
import (
io "io"
ioutil "io/ioutil"
http "net/http"
time "time"
gotsrpc "github.com/foomo/gotsrpc/v2"
)
const (
ServiceGoTSRPCProxyCustomError = "CustomError"
ServiceGoTSRPCProxyError = "Error"
ServiceGoTSRPCProxyMultiScalar = "MultiScalar"
ServiceGoTSRPCProxyScalar = "Scalar"
ServiceGoTSRPCProxyScalarError = "ScalarError"
ServiceGoTSRPCProxyTypedCustomError = "TypedCustomError"
ServiceGoTSRPCProxyTypedError = "TypedError"
ServiceGoTSRPCProxyTypedScalarError = "TypedScalarError"
ServiceGoTSRPCProxyTypedWrappedError = "TypedWrappedError"
ServiceGoTSRPCProxyWrappedError = "WrappedError"
)
type ServiceGoTSRPCProxy struct {
EndPoint string
service Service
}
func NewDefaultServiceGoTSRPCProxy(service Service) *ServiceGoTSRPCProxy {
return NewServiceGoTSRPCProxy(service, "/service/backend")
}
func NewServiceGoTSRPCProxy(service Service, endpoint string) *ServiceGoTSRPCProxy {
return &ServiceGoTSRPCProxy{
EndPoint: endpoint,
service: service,
}
}
// ServeHTTP exposes your service
func (p *ServiceGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
if r.Method == http.MethodOptions {
return
}
gotsrpc.ErrorMethodNotAllowed(w)
return
}
defer io.Copy(ioutil.Discard, r.Body) // Drain Request Body
funcName := gotsrpc.GetCalledFunc(r, p.EndPoint)
callStats := gotsrpc.GetStatsForRequest(r)
if callStats != nil {
callStats.Func = funcName
callStats.Package = "github.com/foomo/gotsrpc/v2/example/errors/service/backend"
callStats.Service = "Service"
}
switch funcName {
case ServiceGoTSRPCProxyCustomError:
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
customErrorE := p.service.CustomError(&rw, r)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
if rw.Status() == http.StatusOK {
gotsrpc.Reply([]interface{}{customErrorE}, callStats, r, w)
}
return
case ServiceGoTSRPCProxyError:
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
errorE := p.service.Error(&rw, r)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
if rw.Status() == http.StatusOK {
gotsrpc.Reply([]interface{}{errorE}, callStats, r, w)
}
return
case ServiceGoTSRPCProxyMultiScalar:
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
multiScalarE := p.service.MultiScalar(&rw, r)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
if rw.Status() == http.StatusOK {
gotsrpc.Reply([]interface{}{multiScalarE}, callStats, r, w)
}
return
case ServiceGoTSRPCProxyScalar:
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
scalarE := p.service.Scalar(&rw, r)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
if rw.Status() == http.StatusOK {
gotsrpc.Reply([]interface{}{scalarE}, callStats, r, w)
}
return
case ServiceGoTSRPCProxyScalarError:
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
scalarErrorE := p.service.ScalarError(&rw, r)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
if rw.Status() == http.StatusOK {
gotsrpc.Reply([]interface{}{scalarErrorE}, callStats, r, w)
}
return
case ServiceGoTSRPCProxyTypedCustomError:
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
typedCustomErrorE := p.service.TypedCustomError(&rw, r)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
if rw.Status() == http.StatusOK {
gotsrpc.Reply([]interface{}{typedCustomErrorE}, callStats, r, w)
}
return
case ServiceGoTSRPCProxyTypedError:
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
typedErrorE := p.service.TypedError(&rw, r)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
if rw.Status() == http.StatusOK {
gotsrpc.Reply([]interface{}{typedErrorE}, callStats, r, w)
}
return
case ServiceGoTSRPCProxyTypedScalarError:
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
typedScalarErrorE := p.service.TypedScalarError(&rw, r)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
if rw.Status() == http.StatusOK {
gotsrpc.Reply([]interface{}{typedScalarErrorE}, callStats, r, w)
}
return
case ServiceGoTSRPCProxyTypedWrappedError:
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
typedWrappedErrorE := p.service.TypedWrappedError(&rw, r)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
if rw.Status() == http.StatusOK {
gotsrpc.Reply([]interface{}{typedWrappedErrorE}, callStats, r, w)
}
return
case ServiceGoTSRPCProxyWrappedError:
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
wrappedErrorE := p.service.WrappedError(&rw, r)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
if rw.Status() == http.StatusOK {
gotsrpc.Reply([]interface{}{wrappedErrorE}, callStats, r, w)
}
return
default:
gotsrpc.ClearStats(r)
http.Error(w, "404 - not found "+r.URL.Path, http.StatusNotFound)
}
}

View File

@ -0,0 +1,145 @@
// Code generated by gotsrpc https://github.com/foomo/gotsrpc/v2 - DO NOT EDIT.
package backend
import (
go_context "context"
go_net_http "net/http"
gotsrpc "github.com/foomo/gotsrpc/v2"
pkg_errors "github.com/pkg/errors"
)
type ServiceGoTSRPCClient interface {
CustomError(ctx go_context.Context) (e error, clientErr error)
Error(ctx go_context.Context) (e error, clientErr error)
MultiScalar(ctx go_context.Context) (e *MultiScalar, clientErr error)
Scalar(ctx go_context.Context) (e *Scalar, clientErr error)
ScalarError(ctx go_context.Context) (e error, clientErr error)
TypedCustomError(ctx go_context.Context) (e error, clientErr error)
TypedError(ctx go_context.Context) (e error, clientErr error)
TypedScalarError(ctx go_context.Context) (e error, clientErr error)
TypedWrappedError(ctx go_context.Context) (e error, clientErr error)
WrappedError(ctx go_context.Context) (e error, clientErr error)
}
type HTTPServiceGoTSRPCClient struct {
URL string
EndPoint string
Client gotsrpc.Client
}
func NewDefaultServiceGoTSRPCClient(url string) *HTTPServiceGoTSRPCClient {
return NewServiceGoTSRPCClient(url, "/service/backend")
}
func NewServiceGoTSRPCClient(url string, endpoint string) *HTTPServiceGoTSRPCClient {
return NewServiceGoTSRPCClientWithClient(url, endpoint, nil)
}
func NewServiceGoTSRPCClientWithClient(url string, endpoint string, client *go_net_http.Client) *HTTPServiceGoTSRPCClient {
return &HTTPServiceGoTSRPCClient{
URL: url,
EndPoint: endpoint,
Client: gotsrpc.NewClientWithHttpClient(client),
}
}
func (tsc *HTTPServiceGoTSRPCClient) CustomError(ctx go_context.Context) (e error, clientErr error) {
args := []interface{}{}
reply := []interface{}{&e}
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "CustomError", args, reply)
if clientErr != nil {
clientErr = pkg_errors.WithMessage(clientErr, "failed to call backend.ServiceGoTSRPCProxy CustomError")
}
return
}
func (tsc *HTTPServiceGoTSRPCClient) Error(ctx go_context.Context) (e error, clientErr error) {
args := []interface{}{}
reply := []interface{}{&e}
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "Error", args, reply)
if clientErr != nil {
clientErr = pkg_errors.WithMessage(clientErr, "failed to call backend.ServiceGoTSRPCProxy Error")
}
return
}
func (tsc *HTTPServiceGoTSRPCClient) MultiScalar(ctx go_context.Context) (e *MultiScalar, clientErr error) {
args := []interface{}{}
reply := []interface{}{&e}
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "MultiScalar", args, reply)
if clientErr != nil {
clientErr = pkg_errors.WithMessage(clientErr, "failed to call backend.ServiceGoTSRPCProxy MultiScalar")
}
return
}
func (tsc *HTTPServiceGoTSRPCClient) Scalar(ctx go_context.Context) (e *Scalar, clientErr error) {
args := []interface{}{}
reply := []interface{}{&e}
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "Scalar", args, reply)
if clientErr != nil {
clientErr = pkg_errors.WithMessage(clientErr, "failed to call backend.ServiceGoTSRPCProxy Scalar")
}
return
}
func (tsc *HTTPServiceGoTSRPCClient) ScalarError(ctx go_context.Context) (e error, clientErr error) {
args := []interface{}{}
reply := []interface{}{&e}
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "ScalarError", args, reply)
if clientErr != nil {
clientErr = pkg_errors.WithMessage(clientErr, "failed to call backend.ServiceGoTSRPCProxy ScalarError")
}
return
}
func (tsc *HTTPServiceGoTSRPCClient) TypedCustomError(ctx go_context.Context) (e error, clientErr error) {
args := []interface{}{}
reply := []interface{}{&e}
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "TypedCustomError", args, reply)
if clientErr != nil {
clientErr = pkg_errors.WithMessage(clientErr, "failed to call backend.ServiceGoTSRPCProxy TypedCustomError")
}
return
}
func (tsc *HTTPServiceGoTSRPCClient) TypedError(ctx go_context.Context) (e error, clientErr error) {
args := []interface{}{}
reply := []interface{}{&e}
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "TypedError", args, reply)
if clientErr != nil {
clientErr = pkg_errors.WithMessage(clientErr, "failed to call backend.ServiceGoTSRPCProxy TypedError")
}
return
}
func (tsc *HTTPServiceGoTSRPCClient) TypedScalarError(ctx go_context.Context) (e error, clientErr error) {
args := []interface{}{}
reply := []interface{}{&e}
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "TypedScalarError", args, reply)
if clientErr != nil {
clientErr = pkg_errors.WithMessage(clientErr, "failed to call backend.ServiceGoTSRPCProxy TypedScalarError")
}
return
}
func (tsc *HTTPServiceGoTSRPCClient) TypedWrappedError(ctx go_context.Context) (e error, clientErr error) {
args := []interface{}{}
reply := []interface{}{&e}
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "TypedWrappedError", args, reply)
if clientErr != nil {
clientErr = pkg_errors.WithMessage(clientErr, "failed to call backend.ServiceGoTSRPCProxy TypedWrappedError")
}
return
}
func (tsc *HTTPServiceGoTSRPCClient) WrappedError(ctx go_context.Context) (e error, clientErr error) {
args := []interface{}{}
reply := []interface{}{&e}
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "WrappedError", args, reply)
if clientErr != nil {
clientErr = pkg_errors.WithMessage(clientErr, "failed to call backend.ServiceGoTSRPCProxy WrappedError")
}
return
}

View File

@ -0,0 +1,46 @@
package backend
import (
"net/http"
)
type ErrService string
const (
ErrUnauthorized ErrService = "unauthorized"
)
type Scalar string
type (
ScalarA string
ScalarB string
MultiScalar struct {
ScalarA `json:",inline"`
ScalarB `json:",inline"`
}
)
const (
ScalarOne Scalar = "one"
ScalarTwo Scalar = "two"
ScalarAOne ScalarA = "one"
ScalarATwo ScalarA = "two"
ScalarBThree ScalarB = "three"
ScalarBFour ScalarB = "four"
)
type Service interface {
Error(w http.ResponseWriter, r *http.Request) (e error)
Scalar(w http.ResponseWriter, r *http.Request) (e *Scalar)
MultiScalar(w http.ResponseWriter, r *http.Request) (e *MultiScalar)
TypedError(w http.ResponseWriter, r *http.Request) (e error)
ScalarError(w http.ResponseWriter, r *http.Request) (e error)
CustomError(w http.ResponseWriter, r *http.Request) (e error)
WrappedError(w http.ResponseWriter, r *http.Request) (e error)
TypedWrappedError(w http.ResponseWriter, r *http.Request) (e error)
TypedScalarError(w http.ResponseWriter, r *http.Request) (e error)
TypedCustomError(w http.ResponseWriter, r *http.Request) (e error)
}

View File

@ -0,0 +1,9 @@
package backend
type (
Todo struct {
ID int
Title string
Done bool
}
)

View File

@ -0,0 +1,84 @@
// Code generated by gotsrpc https://github.com/foomo/gotsrpc/v2 - DO NOT EDIT.
package frontend
import (
io "io"
ioutil "io/ioutil"
http "net/http"
time "time"
gotsrpc "github.com/foomo/gotsrpc/v2"
)
func init() {
gotsrpc.MustRegisterUnionExt(ErrMulti{})
}
const (
ServiceGoTSRPCProxyMultiple = "Multiple"
ServiceGoTSRPCProxySimple = "Simple"
)
type ServiceGoTSRPCProxy struct {
EndPoint string
service Service
}
func NewDefaultServiceGoTSRPCProxy(service Service) *ServiceGoTSRPCProxy {
return NewServiceGoTSRPCProxy(service, "/service/frontend")
}
func NewServiceGoTSRPCProxy(service Service, endpoint string) *ServiceGoTSRPCProxy {
return &ServiceGoTSRPCProxy{
EndPoint: endpoint,
service: service,
}
}
// ServeHTTP exposes your service
func (p *ServiceGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
if r.Method == http.MethodOptions {
return
}
gotsrpc.ErrorMethodNotAllowed(w)
return
}
defer io.Copy(ioutil.Discard, r.Body) // Drain Request Body
funcName := gotsrpc.GetCalledFunc(r, p.EndPoint)
callStats := gotsrpc.GetStatsForRequest(r)
if callStats != nil {
callStats.Func = funcName
callStats.Package = "github.com/foomo/gotsrpc/v2/example/errors/service/frontend"
callStats.Service = "Service"
}
switch funcName {
case ServiceGoTSRPCProxyMultiple:
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
multipleE := p.service.Multiple(&rw, r)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
if rw.Status() == http.StatusOK {
gotsrpc.Reply([]interface{}{multipleE}, callStats, r, w)
}
return
case ServiceGoTSRPCProxySimple:
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
simpleE := p.service.Simple(&rw, r)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
if rw.Status() == http.StatusOK {
gotsrpc.Reply([]interface{}{simpleE}, callStats, r, w)
}
return
default:
gotsrpc.ClearStats(r)
http.Error(w, "404 - not found "+r.URL.Path, http.StatusNotFound)
}
}

View File

@ -0,0 +1,21 @@
package frontend
import (
"net/http"
)
const (
ErrSimpleOne ErrSimple = "one"
ErrSimpleTwo ErrSimple = "two"
ErrMultiAOne ErrMultiA = "one"
ErrMultiATwo ErrMultiA = "two"
ErrMultiBThree ErrMultiB = "three"
ErrMultiBFour ErrMultiB = "four"
)
type Service interface {
Simple(w http.ResponseWriter, r *http.Request) (e *ErrSimple)
Multiple(w http.ResponseWriter, r *http.Request) (e *ErrMulti)
}

View File

@ -0,0 +1,12 @@
package frontend
type ErrSimple string
type (
ErrMulti struct {
A ErrMultiA `json:"a,union"`
B ErrMultiB `json:"b,union"`
}
ErrMultiA string
ErrMultiB string
)

View File

@ -0,0 +1,19 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Errors</title>
<script type="module">
import { init } from './dist/app.js'
init()
</script>
</head>
<body>
<h1>A service test</h1>
<code>
<pre>open the console!</pre>
</code>
</body>
</html>

View File

@ -0,0 +1,50 @@
import {ServiceClient} from "./service-client.js";
import transport from "./transport.js";
export const init = () => {
const client = new ServiceClient(transport(ServiceClient.defaultEndpoint))
client.inlineStruct().then((ret) => {
console.log(ret.valueA)
})
client.inlineStructPtr().then(ret => {
console.log(ret.valueA)
})
client.unionString().then(ret => {
console.log(ret.One)
console.log(ret.Two)
console.log(ret.Three)
console.log(ret.Four)
})
client.unionStruct().then(ret => {
if (ret) {
switch (ret.kind) {
case "UnionStructA":
console.log(ret.value)
console.log(ret.bar)
break
case "UnionStructB":
console.log(ret.value)
console.log(ret.foo)
break;
default:
assertExhaustive(ret, "unhandled")
}
if (ret.kind === "UnionStructA") {
console.log(ret.value)
console.log(ret.bar)
}
}
})
}
function assertExhaustive(
value: never,
message: string = 'msg'
): never {
throw new Error(message);
}

View File

@ -0,0 +1,22 @@
/* eslint:disable */
// hello commonjs - we need some imports - sorted in alphabetical order, by go package
import * as github_com_foomo_gotsrpc_v2_example_multi_service from './service-vo'; // ./client/src/service-client.ts to ./client/src/service-vo.ts
export class ServiceClient {
public static defaultEndpoint = "/service";
constructor(
public transport:<T>(method: string, data?: any[]) => Promise<T>
) {}
async inlineStruct():Promise<github_com_foomo_gotsrpc_v2_example_multi_service.InlineStruct> {
return (await this.transport<{0:github_com_foomo_gotsrpc_v2_example_multi_service.InlineStruct}>("InlineStruct", []))[0]
}
async inlineStructPtr():Promise<github_com_foomo_gotsrpc_v2_example_multi_service.InlineStructPtr> {
return (await this.transport<{0:github_com_foomo_gotsrpc_v2_example_multi_service.InlineStructPtr}>("InlineStructPtr", []))[0]
}
async unionString():Promise<github_com_foomo_gotsrpc_v2_example_multi_service.UnionString> {
return (await this.transport<{0:github_com_foomo_gotsrpc_v2_example_multi_service.UnionString}>("UnionString", []))[0]
}
async unionStruct():Promise<github_com_foomo_gotsrpc_v2_example_multi_service.UnionStruct> {
return (await this.transport<{0:github_com_foomo_gotsrpc_v2_example_multi_service.UnionStruct}>("UnionStruct", []))[0]
}
}

View File

@ -0,0 +1,59 @@
/* eslint:disable */
// hello commonjs - we need some imports - sorted in alphabetical order, by go package
import * as github_com_foomo_gotsrpc_v2_example_multi_service from './service-vo'; // ./client/src/service-vo.ts to ./client/src/service-vo.ts
// github.com/foomo/gotsrpc/v2/example/multi/service.InlineStruct
export interface InlineStruct extends github_com_foomo_gotsrpc_v2_example_multi_service.InlineStructA , github_com_foomo_gotsrpc_v2_example_multi_service.InlineStructB {
value:string;
}
// github.com/foomo/gotsrpc/v2/example/multi/service.InlineStructA
export interface InlineStructA {
valueA:string;
}
// github.com/foomo/gotsrpc/v2/example/multi/service.InlineStructB
export interface InlineStructB {
valueB:string;
}
// github.com/foomo/gotsrpc/v2/example/multi/service.InlineStructPtr
export interface InlineStructPtr extends Partial<github_com_foomo_gotsrpc_v2_example_multi_service.InlineStructA> , Partial<github_com_foomo_gotsrpc_v2_example_multi_service.InlineStructB> {
bug?:github_com_foomo_gotsrpc_v2_example_multi_service.InlineStructB;
value:string;
}
// github.com/foomo/gotsrpc/v2/example/multi/service.UnionString
export type UnionString = (typeof github_com_foomo_gotsrpc_v2_example_multi_service.UnionStringA) & (typeof github_com_foomo_gotsrpc_v2_example_multi_service.UnionStringB)
// github.com/foomo/gotsrpc/v2/example/multi/service.UnionStringA
export enum UnionStringA {
One = "one",
Two = "two",
}
// github.com/foomo/gotsrpc/v2/example/multi/service.UnionStringB
export enum UnionStringB {
Four = "four",
Three = "three",
}
// github.com/foomo/gotsrpc/v2/example/multi/service.UnionStruct
export type UnionStruct = github_com_foomo_gotsrpc_v2_example_multi_service.UnionStructA | github_com_foomo_gotsrpc_v2_example_multi_service.UnionStructB | undefined
// github.com/foomo/gotsrpc/v2/example/multi/service.UnionStructA
export interface UnionStructA {
kind:'UnionStructA';
value:github_com_foomo_gotsrpc_v2_example_multi_service.UnionStructAValueA;
bar:string;
}
// github.com/foomo/gotsrpc/v2/example/multi/service.UnionStructAValueA
export enum UnionStructAValueA {
One = "one",
Three = "three",
Two = "two",
}
// github.com/foomo/gotsrpc/v2/example/multi/service.UnionStructAValueB
export enum UnionStructAValueB {
One = "one",
Three = "three",
Two = "two",
}
// github.com/foomo/gotsrpc/v2/example/multi/service.UnionStructB
export interface UnionStructB {
kind:'UnionStructB';
value:github_com_foomo_gotsrpc_v2_example_multi_service.UnionStructAValueB;
foo:string;
}
// end of common js

View File

@ -0,0 +1,18 @@
const transport = endpoint => async <T>(method: string, args: any = []) => {
return new Promise<T>(async (resolve, reject) => {
fetch(
`${endpoint}/${encodeURIComponent(method)}`,
{
method: 'POST',
body: JSON.stringify(args),
}
)
.then((response) => {
return response.json() as Promise<T>;
})
.then((val) => resolve(val))
.catch((err) => reject(err))
})
};
export default transport

View File

@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
}
}

11
example/multi/go.mod Normal file
View File

@ -0,0 +1,11 @@
module github.com/foomo/gotsrpc/v2/example/multi
go 1.16
require (
github.com/davecgh/go-spew v1.1.1
github.com/foomo/gotsrpc/v2 v2.0.0
github.com/pkg/errors v0.9.1
)
replace github.com/foomo/gotsrpc/v2 => ../../

486
example/multi/go.sum Normal file
View File

@ -0,0 +1,486 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E=
github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0=
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

16
example/multi/gotsrpc.yml Normal file
View File

@ -0,0 +1,16 @@
module:
name: github.com/foomo/gotsrpc/v2/example/multi
path: ./
targets:
multi:
services:
/service: Service
package: github.com/foomo/gotsrpc/v2/example/multi/service
out: ./client/src/service-client.ts
tsrpc:
- Service
mappings:
github.com/foomo/gotsrpc/v2/example/multi/service:
out: ./client/src/service-vo.ts

59
example/multi/main.go Normal file
View File

@ -0,0 +1,59 @@
package main
import (
"context"
"net/http"
"os/exec"
"strings"
"time"
"github.com/davecgh/go-spew/spew"
"github.com/foomo/gotsrpc/v2/example/multi/service"
)
func main() {
fs := http.FileServer(http.Dir("./client"))
ws := service.NewDefaultServiceGoTSRPCProxy(&service.Handler{})
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
switch {
case strings.HasPrefix(r.URL.Path, "/service/"):
ws.ServeHTTP(w, r)
default:
fs.ServeHTTP(w, r)
}
})
go exec.Command("open", "http://127.0.0.1:3000").Run()
go call()
http.ListenAndServe("localhost:3000", mux)
}
func call() {
time.Sleep(time.Second)
c := service.NewDefaultServiceGoTSRPCClient("http://127.0.0.1:3000")
{
res, _ := c.InlineStruct(context.Background())
spew.Dump(res)
}
{
res, _ := c.InlineStructPtr(context.Background())
spew.Dump(res) // TODO this should have nil for InlineStructB as for Bug
}
{
res, _ := c.UnionString(context.Background())
spew.Dump(res)
}
{
res, _ := c.UnionStruct(context.Background())
spew.Dump(res)
}
}

View File

@ -0,0 +1,109 @@
// Code generated by gotsrpc https://github.com/foomo/gotsrpc/v2 - DO NOT EDIT.
package service
import (
io "io"
ioutil "io/ioutil"
http "net/http"
time "time"
gotsrpc "github.com/foomo/gotsrpc/v2"
)
func init() {
gotsrpc.MustRegisterUnionExt(UnionStruct{})
gotsrpc.MustRegisterUnionExt(UnionString{})
}
const (
ServiceGoTSRPCProxyInlineStruct = "InlineStruct"
ServiceGoTSRPCProxyInlineStructPtr = "InlineStructPtr"
ServiceGoTSRPCProxyUnionString = "UnionString"
ServiceGoTSRPCProxyUnionStruct = "UnionStruct"
)
type ServiceGoTSRPCProxy struct {
EndPoint string
service Service
}
func NewDefaultServiceGoTSRPCProxy(service Service) *ServiceGoTSRPCProxy {
return NewServiceGoTSRPCProxy(service, "/service")
}
func NewServiceGoTSRPCProxy(service Service, endpoint string) *ServiceGoTSRPCProxy {
return &ServiceGoTSRPCProxy{
EndPoint: endpoint,
service: service,
}
}
// ServeHTTP exposes your service
func (p *ServiceGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
if r.Method == http.MethodOptions {
return
}
gotsrpc.ErrorMethodNotAllowed(w)
return
}
defer io.Copy(ioutil.Discard, r.Body) // Drain Request Body
funcName := gotsrpc.GetCalledFunc(r, p.EndPoint)
callStats := gotsrpc.GetStatsForRequest(r)
if callStats != nil {
callStats.Func = funcName
callStats.Package = "github.com/foomo/gotsrpc/v2/example/multi/service"
callStats.Service = "Service"
}
switch funcName {
case ServiceGoTSRPCProxyInlineStruct:
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
inlineStructE := p.service.InlineStruct(&rw, r)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
if rw.Status() == http.StatusOK {
gotsrpc.Reply([]interface{}{inlineStructE}, callStats, r, w)
}
return
case ServiceGoTSRPCProxyInlineStructPtr:
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
inlineStructPtrE := p.service.InlineStructPtr(&rw, r)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
if rw.Status() == http.StatusOK {
gotsrpc.Reply([]interface{}{inlineStructPtrE}, callStats, r, w)
}
return
case ServiceGoTSRPCProxyUnionString:
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
unionStringE := p.service.UnionString(&rw, r)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
if rw.Status() == http.StatusOK {
gotsrpc.Reply([]interface{}{unionStringE}, callStats, r, w)
}
return
case ServiceGoTSRPCProxyUnionStruct:
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
unionStructE := p.service.UnionStruct(&rw, r)
if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart)
}
if rw.Status() == http.StatusOK {
gotsrpc.Reply([]interface{}{unionStructE}, callStats, r, w)
}
return
default:
gotsrpc.ClearStats(r)
http.Error(w, "404 - not found "+r.URL.Path, http.StatusNotFound)
}
}

View File

@ -0,0 +1,79 @@
// Code generated by gotsrpc https://github.com/foomo/gotsrpc/v2 - DO NOT EDIT.
package service
import (
go_context "context"
go_net_http "net/http"
gotsrpc "github.com/foomo/gotsrpc/v2"
pkg_errors "github.com/pkg/errors"
)
type ServiceGoTSRPCClient interface {
InlineStruct(ctx go_context.Context) (e InlineStruct, clientErr error)
InlineStructPtr(ctx go_context.Context) (e InlineStructPtr, clientErr error)
UnionString(ctx go_context.Context) (e UnionString, clientErr error)
UnionStruct(ctx go_context.Context) (e UnionStruct, clientErr error)
}
type HTTPServiceGoTSRPCClient struct {
URL string
EndPoint string
Client gotsrpc.Client
}
func NewDefaultServiceGoTSRPCClient(url string) *HTTPServiceGoTSRPCClient {
return NewServiceGoTSRPCClient(url, "/service")
}
func NewServiceGoTSRPCClient(url string, endpoint string) *HTTPServiceGoTSRPCClient {
return NewServiceGoTSRPCClientWithClient(url, endpoint, nil)
}
func NewServiceGoTSRPCClientWithClient(url string, endpoint string, client *go_net_http.Client) *HTTPServiceGoTSRPCClient {
return &HTTPServiceGoTSRPCClient{
URL: url,
EndPoint: endpoint,
Client: gotsrpc.NewClientWithHttpClient(client),
}
}
func (tsc *HTTPServiceGoTSRPCClient) InlineStruct(ctx go_context.Context) (e InlineStruct, clientErr error) {
args := []interface{}{}
reply := []interface{}{&e}
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "InlineStruct", args, reply)
if clientErr != nil {
clientErr = pkg_errors.WithMessage(clientErr, "failed to call service.ServiceGoTSRPCProxy InlineStruct")
}
return
}
func (tsc *HTTPServiceGoTSRPCClient) InlineStructPtr(ctx go_context.Context) (e InlineStructPtr, clientErr error) {
args := []interface{}{}
reply := []interface{}{&e}
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "InlineStructPtr", args, reply)
if clientErr != nil {
clientErr = pkg_errors.WithMessage(clientErr, "failed to call service.ServiceGoTSRPCProxy InlineStructPtr")
}
return
}
func (tsc *HTTPServiceGoTSRPCClient) UnionString(ctx go_context.Context) (e UnionString, clientErr error) {
args := []interface{}{}
reply := []interface{}{&e}
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "UnionString", args, reply)
if clientErr != nil {
clientErr = pkg_errors.WithMessage(clientErr, "failed to call service.ServiceGoTSRPCProxy UnionString")
}
return
}
func (tsc *HTTPServiceGoTSRPCClient) UnionStruct(ctx go_context.Context) (e UnionStruct, clientErr error) {
args := []interface{}{}
reply := []interface{}{&e}
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "UnionStruct", args, reply)
if clientErr != nil {
clientErr = pkg_errors.WithMessage(clientErr, "failed to call service.ServiceGoTSRPCProxy UnionStruct")
}
return
}

View File

@ -0,0 +1,25 @@
package service
import (
"net/http"
)
type Handler struct{}
func (h *Handler) InlineStruct(w http.ResponseWriter, r *http.Request) (e InlineStruct) {
return InlineStruct{InlineStructA: InlineStructA{ValueA: "a"}}
}
func (h *Handler) InlineStructPtr(w http.ResponseWriter, r *http.Request) (e InlineStructPtr) {
return InlineStructPtr{InlineStructA: &InlineStructA{ValueA: "a"}}
}
func (h *Handler) UnionString(w http.ResponseWriter, r *http.Request) (e UnionString) {
v := UnionStringBThree
return UnionString{B: &v}
}
func (h *Handler) UnionStruct(w http.ResponseWriter, r *http.Request) (e UnionStruct) {
//return UnionStruct{UnionStructA: UnionStructA{Kind: "UnionStructA", Value: UnionStructAValueAOne}}
return UnionStruct{B: &UnionStructB{Kind: "UnionStructB", Value: UnionStructAValueBOne}}
}

View File

@ -0,0 +1,12 @@
package service
import (
"net/http"
)
type Service interface {
InlineStruct(w http.ResponseWriter, r *http.Request) (e InlineStruct)
InlineStructPtr(w http.ResponseWriter, r *http.Request) (e InlineStructPtr)
UnionString(w http.ResponseWriter, r *http.Request) (e UnionString)
UnionStruct(w http.ResponseWriter, r *http.Request) (e UnionStruct)
}

View File

@ -0,0 +1,76 @@
package service
import (
"github.com/foomo/gotsrpc/v2"
)
func init() {
gotsrpc.MustRegisterUnionExt(UnionString{}, UnionStruct{})
}
type (
InlineStructA struct {
ValueA string `json:"valueA"`
}
InlineStructB struct {
ValueB string `json:"valueB"`
}
InlineStruct struct {
InlineStructA `json:",inline"`
InlineStructB `json:",inline"`
Value string `json:"value"`
}
InlineStructPtr struct {
*InlineStructA `json:",inline,omitempty"`
*InlineStructB `json:",inline,omitempty"` // TODO this should have nil for InlineStructB as for Bug
Bug *InlineStructB `json:"bug,omitempty"`
Value string `json:"value"`
}
)
type (
UnionString struct {
A *UnionStringA `json:"a,omitempty,union"`
B *UnionStringB `json:"b,omitempty,union"`
}
UnionStringA string
UnionStringB string
)
const (
UnionStringAOne UnionStringA = "one"
UnionStringATwo UnionStringA = "two"
UnionStringBThree UnionStringB = "three"
UnionStringBFour UnionStringB = "four"
)
type (
UnionStructA struct {
Kind string `json:"kind,type:'UnionStructA'"`
Value UnionStructAValueA `json:"value"`
Bar string `json:"bar"`
}
UnionStructAValueA string
UnionStructB struct {
Kind string `json:"kind,type:'UnionStructB'"`
Value UnionStructAValueB `json:"value"`
Foo string `json:"foo"`
}
UnionStructAValueB string
UnionStruct struct {
A *UnionStructA `json:"a,omitempty,union"`
B *UnionStructB `json:"b,omitempty,union"`
}
)
const (
UnionStructAValueAOne UnionStructAValueA = "one"
UnionStructAValueATwo UnionStructAValueA = "two"
UnionStructAValueAThree UnionStructAValueA = "three"
UnionStructAValueBOne UnionStructAValueB = "one"
UnionStructAValueBTwo UnionStructAValueB = "two"
UnionStructAValueBThree UnionStructAValueB = "three"
)

View File

@ -29,8 +29,7 @@ export class ServiceClient {
return (await this.transport<{0:Record<string,github_com_foomo_gotsrpc_v2_example_nullable_service.Base|null>|null}>("VariantG", [i1]))[0] return (await this.transport<{0:Record<string,github_com_foomo_gotsrpc_v2_example_nullable_service.Base|null>|null}>("VariantG", [i1]))[0]
} }
async variantH(i1:github_com_foomo_gotsrpc_v2_example_nullable_service.Base, i2:github_com_foomo_gotsrpc_v2_example_nullable_service.Base|null, i3:Array<github_com_foomo_gotsrpc_v2_example_nullable_service.Base|null>|null, i4:Record<string,github_com_foomo_gotsrpc_v2_example_nullable_service.Base>|null):Promise<{r1:github_com_foomo_gotsrpc_v2_example_nullable_service.Base; r2:github_com_foomo_gotsrpc_v2_example_nullable_service.Base|null; r3:Array<github_com_foomo_gotsrpc_v2_example_nullable_service.Base|null>|null; r4:Record<string,github_com_foomo_gotsrpc_v2_example_nullable_service.Base>|null}> { async variantH(i1:github_com_foomo_gotsrpc_v2_example_nullable_service.Base, i2:github_com_foomo_gotsrpc_v2_example_nullable_service.Base|null, i3:Array<github_com_foomo_gotsrpc_v2_example_nullable_service.Base|null>|null, i4:Record<string,github_com_foomo_gotsrpc_v2_example_nullable_service.Base>|null):Promise<{r1:github_com_foomo_gotsrpc_v2_example_nullable_service.Base; r2:github_com_foomo_gotsrpc_v2_example_nullable_service.Base|null; r3:Array<github_com_foomo_gotsrpc_v2_example_nullable_service.Base|null>|null; r4:Record<string,github_com_foomo_gotsrpc_v2_example_nullable_service.Base>|null}> {
let response = await this.transport<{0:github_com_foomo_gotsrpc_v2_example_nullable_service.Base; 1:github_com_foomo_gotsrpc_v2_example_nullable_service.Base|null; 2:Array<github_com_foomo_gotsrpc_v2_example_nullable_service.Base|null>|null; 3:Record<string,github_com_foomo_gotsrpc_v2_example_nullable_service.Base>|null}>("VariantH", [i1, i2, i3, i4]) const response = await this.transport<{0:github_com_foomo_gotsrpc_v2_example_nullable_service.Base; 1:github_com_foomo_gotsrpc_v2_example_nullable_service.Base|null; 2:Array<github_com_foomo_gotsrpc_v2_example_nullable_service.Base|null>|null; 3:Record<string,github_com_foomo_gotsrpc_v2_example_nullable_service.Base>|null}>("VariantH", [i1, i2, i3, i4])
let responseObject = {r1 : response[0], r2 : response[1], r3 : response[2], r4 : response[3]}; return {r1 : response[0], r2 : response[1], r3 : response[2], r4 : response[3]};
return responseObject;
} }
} }

View File

@ -1,4 +1,4 @@
module github.com/foomo/gotsrpc/v2/example/basic module github.com/foomo/gotsrpc/v2/example/nullable
go 1.16 go 1.16

View File

@ -143,6 +143,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=

View File

@ -3,7 +3,7 @@ module:
path: ./ path: ./
targets: targets:
basic: nullable:
services: services:
/service: Service /service: Service
package: github.com/foomo/gotsrpc/v2/example/nullable/service package: github.com/foomo/gotsrpc/v2/example/nullable/service

View File

@ -6,7 +6,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/foomo/gotsrpc/v2/example/basic/service" "github.com/foomo/gotsrpc/v2/example/nullable/service"
) )
func main() { func main() {

View File

@ -28,10 +28,7 @@ type ServiceGoTSRPCProxy struct {
} }
func NewDefaultServiceGoTSRPCProxy(service Service) *ServiceGoTSRPCProxy { func NewDefaultServiceGoTSRPCProxy(service Service) *ServiceGoTSRPCProxy {
return &ServiceGoTSRPCProxy{ return NewServiceGoTSRPCProxy(service, "/service")
EndPoint: "/service",
service: service,
}
} }
func NewServiceGoTSRPCProxy(service Service, endpoint string) *ServiceGoTSRPCProxy { func NewServiceGoTSRPCProxy(service Service, endpoint string) *ServiceGoTSRPCProxy {

8
example/package.json Normal file
View File

@ -0,0 +1,8 @@
{
"private": true,
"version": "0.1.0",
"name": "@foomo/gotsrpc-examples",
"devDependencies": {
"typescript": "^4.6.2"
}
}

View File

@ -2,7 +2,7 @@
"compilerOptions": { "compilerOptions": {
"module": "ESNext", "module": "ESNext",
"target": "ESNext", "target": "ESNext",
"lib": ["es5", "es6", "dom"], "lib": ["dom", "esnext"],
"strictNullChecks": true, "strictNullChecks": true,
"noImplicitAny": false, "noImplicitAny": false,
"strict": true, "strict": true,

8
example/yarn.lock Normal file
View File

@ -0,0 +1,8 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
typescript@^4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.2.tgz#fe12d2727b708f4eef40f51598b3398baa9611d4"
integrity sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==

64
go.go
View File

@ -143,11 +143,8 @@ func strfirst(str string, strfunc func(string) string) string {
return res return res
} }
func extractImports(fields []*Field, fullPackageName string, aliases map[string]string) { func extractImport(packageName string, fullPackageName string, aliases map[string]string) {
r := strings.NewReplacer(".", "_", "/", "_", "-", "_") r := strings.NewReplacer(".", "_", "/", "_", "-", "_")
extractImport := func(packageName string) {
if packageName != fullPackageName { if packageName != fullPackageName {
alias, ok := aliases[packageName] alias, ok := aliases[packageName]
if !ok { if !ok {
@ -166,20 +163,29 @@ func extractImports(fields []*Field, fullPackageName string, aliases map[string]
} }
} }
func extractImports(fields []*Field, fullPackageName string, aliases map[string]string) {
for _, f := range fields { for _, f := range fields {
if f.Value.StructType != nil { if f.Value.StructType != nil {
extractImport(f.Value.StructType.Package) extractImport(f.Value.StructType.Package, fullPackageName, aliases)
} else if f.Value.Array != nil && f.Value.Array.Value.StructType != nil { } else if f.Value.Array != nil && f.Value.Array.Value.StructType != nil {
extractImport(f.Value.Array.Value.StructType.Package) extractImport(f.Value.Array.Value.StructType.Package, fullPackageName, aliases)
} else if f.Value.Map != nil && f.Value.Map.Value.StructType != nil {
extractImport(f.Value.Map.Value.StructType.Package, fullPackageName, aliases)
} else if f.Value.Map != nil && f.Value.Map.Key.StructType != nil {
extractImport(f.Value.Map.Key.StructType.Package, fullPackageName, aliases)
} else if f.Value.Array != nil && f.Value.Array.Value.Scalar != nil { } else if f.Value.Array != nil && f.Value.Array.Value.Scalar != nil {
extractImport(f.Value.Array.Value.Scalar.Package) extractImport(f.Value.Array.Value.Scalar.Package, fullPackageName, aliases)
} else if f.Value.Map != nil && f.Value.Map.Value.Scalar != nil {
extractImport(f.Value.Map.Value.Scalar.Package, fullPackageName, aliases)
} else if f.Value.Map != nil && f.Value.Map.Key.Scalar != nil {
extractImport(f.Value.Map.Key.Scalar.Package, fullPackageName, aliases)
} else if f.Value.Scalar != nil { } else if f.Value.Scalar != nil {
extractImport(f.Value.Scalar.Package) extractImport(f.Value.Scalar.Package, fullPackageName, aliases)
} }
} }
} }
func renderTSRPCServiceProxies(services ServiceList, fullPackageName string, packageName string, config *config.Target, g *code) error { func renderTSRPCServiceProxies(services ServiceList, fullPackageName string, packageName string, config *config.Target, unions map[string][]string, g *code) error {
aliases := map[string]string{ aliases := map[string]string{
"time": "time", "time": "time",
"net/http": "http", "net/http": "http",
@ -198,7 +204,14 @@ func renderTSRPCServiceProxies(services ServiceList, fullPackageName string, pac
} }
} }
for pkg := range unions {
extractImport(pkg, fullPackageName, aliases)
}
g.l(renderImports(aliases, packageName)) g.l(renderImports(aliases, packageName))
renderInit(unions, aliases, packageName, g)
for _, service := range services { for _, service := range services {
// Check if we should render this service as ts rcp // Check if we should render this service as ts rcp
// Note: remove once there's a separate gorcp generator // Note: remove once there's a separate gorcp generator
@ -226,12 +239,8 @@ func renderTSRPCServiceProxies(services ServiceList, fullPackageName string, pac
} }
func NewDefault` + proxyName + `(service ` + servicePointer + service.Name + `) *` + proxyName + ` { func NewDefault` + proxyName + `(service ` + servicePointer + service.Name + `) *` + proxyName + ` {
return &` + proxyName + `{ return New` + proxyName + `(service, "` + service.Endpoint + `")
EndPoint: "` + service.Endpoint + `",
service: service,
} }
}
func New` + proxyName + `(service ` + servicePointer + service.Name + `, endpoint string) *` + proxyName + ` { func New` + proxyName + `(service ` + servicePointer + service.Name + `, endpoint string) *` + proxyName + ` {
return &` + proxyName + `{ return &` + proxyName + `{
@ -306,7 +315,7 @@ func renderTSRPCServiceProxies(services ServiceList, fullPackageName string, pac
g.l("}") g.l("}")
} }
} }
returnValueNames := []string{} var returnValueNames []string
for retI, retField := range method.Return { for retI, retField := range method.Return {
retArgName := retField.Name retArgName := retField.Name
if len(retArgName) == 0 { if len(retArgName) == 0 {
@ -327,7 +336,6 @@ func renderTSRPCServiceProxies(services ServiceList, fullPackageName string, pac
} }
g.app("p.service." + method.Name + "(" + strings.Join(callArgs, ", ") + ")") g.app("p.service." + method.Name + "(" + strings.Join(callArgs, ", ") + ")")
g.nl() g.nl()
g.l("if callStats != nil {") g.l("if callStats != nil {")
g.ind(1).l("callStats.Execution = time.Now().Sub(executionStart)").ind(-1) g.ind(1).l("callStats.Execution = time.Now().Sub(executionStart)").ind(-1)
g.l("}") g.l("}")
@ -662,6 +670,7 @@ func renderGoRPCServiceClients(services ServiceList, fullPackageName string, pac
} }
g.l(renderImports(aliases, packageName)) g.l(renderImports(aliases, packageName))
for _, service := range services { for _, service := range services {
if !config.IsGoRPC(service.Name) { if !config.IsGoRPC(service.Name) {
continue continue
@ -738,9 +747,9 @@ func renderGoRPCServiceClients(services ServiceList, fullPackageName string, pac
return nil return nil
} }
func RenderGoTSRPCProxies(services ServiceList, longPackageName, packageName string, config *config.Target) (gocode string, err error) { func RenderGoTSRPCProxies(services ServiceList, longPackageName, packageName string, config *config.Target, unions map[string][]string) (gocode string, err error) {
g := newCode(" ") g := newCode(" ")
err = renderTSRPCServiceProxies(services, longPackageName, packageName, config, g) err = renderTSRPCServiceProxies(services, longPackageName, packageName, config, unions, g)
if err != nil { if err != nil {
return return
} }
@ -792,6 +801,25 @@ func goMethodArgsWithoutHTTPContextRelatedArgs(m *Method) (filteredArgs []*Field
return return
} }
func renderInit(unions map[string][]string, aliases map[string]string, packageName string, g *code) {
if len(unions) > 0 {
g.l("func init() {")
g.ind(1)
for pkg, us := range unions {
for _, name := range us {
var t string
if packageName != pkg && aliases[pkg] != "" {
t += aliases[pkg] + "."
}
t += name
g.l("gotsrpc.MustRegisterUnionExt(" + t + "{})")
}
}
g.ind(-1)
g.l("}")
}
}
func renderImports(aliases map[string]string, packageName string) string { func renderImports(aliases map[string]string, packageName string) string {
imports := "" imports := ""
for importPath, alias := range aliases { for importPath, alias := range aliases {

1
go.mod
View File

@ -5,6 +5,7 @@ go 1.15
require ( require (
github.com/iancoleman/strcase v0.2.0 github.com/iancoleman/strcase v0.2.0
github.com/kr/text v0.2.0 // indirect github.com/kr/text v0.2.0 // indirect
github.com/mitchellh/mapstructure v1.4.3
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.12.1 github.com/prometheus/client_golang v1.12.1

2
go.sum
View File

@ -148,6 +148,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=

View File

@ -11,6 +11,7 @@ import (
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"reflect"
"sort" "sort"
"strings" "strings"
"time" "time"
@ -86,6 +87,15 @@ func Reply(response []interface{}, stats *CallStats, r *http.Request, w http.Res
writer.Header().Set("Content-Type", clientHandle.contentType) writer.Header().Set("Content-Type", clientHandle.contentType)
// transform error type to sth that is transportable
for k, v := range response {
if e, ok := v.(error); ok {
if !reflect.ValueOf(e).IsNil() {
response[k] = NewError(e)
}
}
}
if errEncode := codec.NewEncoder(writer, clientHandle.handle).Encode(response); errEncode != nil { if errEncode := codec.NewEncoder(writer, clientHandle.handle).Encode(response); errEncode != nil {
http.Error(w, "could not encode data to accepted format", http.StatusInternalServerError) http.Error(w, "could not encode data to accepted format", http.StatusInternalServerError)
return return

23
httperror.go Normal file
View File

@ -0,0 +1,23 @@
package gotsrpc
import (
"errors"
"fmt"
)
type HTTPError struct {
StatusCode int
Body string
error
}
func NewHTTPError(msg string, code int) *HTTPError {
return &HTTPError{
error: errors.New(msg),
StatusCode: code,
}
}
func (e *HTTPError) Error() string {
return fmt.Sprintf("[%d] %s", e.StatusCode, e.error.Error())
}

View File

@ -13,9 +13,10 @@ const (
type JSONInfo struct { type JSONInfo struct {
Name string Name string
Type string
Union bool
Inline bool Inline bool
OmitEmpty bool OmitEmpty bool
ForceStringType bool
Ignore bool Ignore bool
} }
@ -99,6 +100,8 @@ type Struct struct {
Package string Package string
Name string Name string
Fields []*Field Fields []*Field
UnionFields []*Field
InlineFields []*Field
Map *Map Map *Map
Array *Array Array *Array
} }

View File

@ -570,7 +570,8 @@ func (s *Struct) DepsSatisfied(missingTypes map[string]bool, structs map[string]
} }
return false return false
} }
for _, field := range s.Fields { needWorksFields := func(fields []*Field) bool {
for _, field := range fields {
var fieldStructType *StructType = nil var fieldStructType *StructType = nil
if field.Value.StructType != nil { if field.Value.StructType != nil {
fieldStructType = field.Value.StructType fieldStructType = field.Value.StructType
@ -591,6 +592,31 @@ func (s *Struct) DepsSatisfied(missingTypes map[string]bool, structs map[string]
} }
} }
} }
return true
}
if ok := needWorksFields(s.Fields); !ok {
return false
} else if ok := needWorksFields(s.InlineFields); !ok {
return false
} else if ok := needWorksFields(s.UnionFields); !ok {
return false
}
//// special handling of union only structs
//if len(s.Fields) == 0 {
// for _, field := range s.UnionFields {
// var fieldStructType *StructType = nil
// if field.Value.StructType != nil {
// fieldStructType = field.Value.StructType
// } else if field.Value.Scalar != nil && needsWork(field.Value.Scalar.FullName()) {
// return false
// }
// if fieldStructType != nil {
// if needsWork(fieldStructType.FullName()) {
// return false
// }
// }
// }
//}
if s.Array != nil && s.Array.Value != nil { if s.Array != nil && s.Array.Value != nil {
if s.Array.Value.StructType != nil { if s.Array.Value.StructType != nil {
if needsWork(s.Array.Value.StructType.FullName()) { if needsWork(s.Array.Value.StructType.FullName()) {

View File

@ -24,10 +24,39 @@ var msgpackClientHandle = &clientHandle{
contentType: "application/msgpack; charset=utf-8", contentType: "application/msgpack; charset=utf-8",
} }
//type TimeExt struct{}
//
//func (x TimeExt) WriteExt(v interface{}) []byte {
// b := make([]byte, binary.MaxVarintLen64)
// switch t := v.(type) {
// case time.Time:
// binary.PutVarint(b, t.UnixNano())
// return b
// case *time.Time:
// binary.PutVarint(b, t.UnixNano())
// return b
// default:
// panic("Bug")
// }
//}
//func (x TimeExt) ReadExt(dest interface{}, src []byte) {
// tt := dest.(*time.Time)
// r := bytes.NewBuffer(src)
// v, err := binary.ReadVarint(r)
// if err != nil {
// panic("BUG")
// }
// *tt = time.Unix(0, v).UTC()
//}
func init() { func init() {
mh := new(codec.MsgpackHandle) mh := new(codec.MsgpackHandle)
// use map[string]interface{} instead of map[interface{}]interface{} // use map[string]interface{} instead of map[interface{}]interface{}
mh.MapType = reflect.TypeOf(map[string]interface{}(nil)) mh.MapType = reflect.TypeOf(map[string]interface{}(nil))
//if err := mh.SetBytesExt(reflect.TypeOf(time.Time{}), 1, TimeExt{}); err != nil {
// panic("2")
//}
//mh.TimeNotBuiltin = true
msgpackClientHandle.handle = mh msgpackClientHandle.handle = mh
// attempting to set promoted field in literal will cause a compiler error // attempting to set promoted field in literal will cause a compiler error
mh.RawToString = true mh.RawToString = true
@ -40,6 +69,21 @@ var jsonClientHandle = &clientHandle{
contentType: "application/json; charset=utf-8", contentType: "application/json; charset=utf-8",
} }
func NewMSGPackEncoderBytes(b *[]byte) *codec.Encoder {
return codec.NewEncoderBytes(b, msgpackClientHandle.handle)
}
func NewMSGPackDecoderBytes(b []byte) *codec.Decoder {
return codec.NewDecoderBytes(b, msgpackClientHandle.handle)
}
func SetJSONExt(rt interface{}, tag uint64, ext codec.InterfaceExt) error {
return jsonClientHandle.handle.(*codec.JsonHandle).SetInterfaceExt(reflect.TypeOf(rt), tag, ext)
}
func SetMSGPackExt(rt interface{}, tag uint64, ext codec.BytesExt) error {
return msgpackClientHandle.handle.(*codec.MsgpackHandle).SetBytesExt(reflect.TypeOf(rt), tag, ext)
}
func getHandleForEncoding(encoding ClientEncoding) *clientHandle { func getHandleForEncoding(encoding ClientEncoding) *clientHandle {
switch encoding { switch encoding {
case EncodingMsgpack: case EncodingMsgpack:

View File

@ -34,9 +34,6 @@ func readStructs(pkg *ast.Package, packageName string) (structs map[string]*Stru
structType.IsError = true structType.IsError = true
} }
} }
//jsonDump(errorTypes)
//jsonDump(scalarTypes)
//jsonDump(structs)
return return
} }
@ -67,40 +64,46 @@ func extractJSONInfo(tag string) *JSONInfo {
jsonTagParts := strings.Split(jsonTagString, ",") jsonTagParts := strings.Split(jsonTagString, ",")
name := "" name := ""
tsType := ""
omit := false omit := false
union := false
inline := false inline := false
ignore := false ignore := false
forceStringType := false var cleanParts []string
cleanParts := []string{}
for _, jsonTagPart := range jsonTagParts { for _, jsonTagPart := range jsonTagParts {
cleanParts = append(cleanParts, strings.TrimSpace(jsonTagPart)) cleanParts = append(cleanParts, strings.TrimSpace(jsonTagPart))
} }
switch len(cleanParts) { if len(cleanParts) > 0 {
case 1:
switch cleanParts[0] { switch cleanParts[0] {
case "":
// do nothing
case "-": case "-":
ignore = true ignore = true
default: default:
name = cleanParts[0] name = cleanParts[0]
} }
case 2:
if len(cleanParts[0]) > 0 {
name = cleanParts[0]
} }
switch cleanParts[1] { if len(cleanParts) > 1 {
case "inline": for _, cleanPart := range cleanParts[1:] {
switch {
case cleanPart == "union":
union = true
case cleanPart == "inline":
inline = true inline = true
case "omitempty": case cleanPart == "omitempty":
omit = true omit = true
case "string": case strings.HasPrefix(cleanPart, "type:"):
forceStringType = true tsType = strings.TrimPrefix(cleanPart, "type:")
} }
} }
}
return &JSONInfo{ return &JSONInfo{
Name: name, Name: name,
Type: tsType,
Union: union,
Inline: inline, Inline: inline,
OmitEmpty: omit, OmitEmpty: omit,
ForceStringType: forceStringType,
Ignore: ignore, Ignore: ignore,
} }
} }
@ -157,6 +160,9 @@ func readAstType(v *Value, fieldIdent *ast.Ident, fileImports fileImportSpecMap,
} }
} else { } else {
v.GoScalarType = fieldIdent.Name v.GoScalarType = fieldIdent.Name
if fieldIdent.Name == "error" {
v.IsError = true
}
} }
} }
@ -235,12 +241,11 @@ func readAstSelectorExpr(v *Value, selectorExpr *ast.SelectorExpr, fileImports f
func readAstStructType(v *Value, structType *ast.StructType, fileImports fileImportSpecMap) { func readAstStructType(v *Value, structType *ast.StructType, fileImports fileImportSpecMap) {
v.Struct = &Struct{} v.Struct = &Struct{}
v.Struct.Fields = readFieldList(structType.Fields.List, fileImports) v.Struct.Fields, v.Struct.InlineFields, v.Struct.UnionFields = readFieldList(structType.Fields.List, fileImports)
} }
func readAstInterfaceType(v *Value, interfaceType *ast.InterfaceType, fileImports fileImportSpecMap) { func readAstInterfaceType(v *Value, interfaceType *ast.InterfaceType, fileImports fileImportSpecMap) {
v.IsInterface = true v.IsInterface = true
} }
func (v *Value) loadExpr(expr ast.Expr, fileImports fileImportSpecMap) { func (v *Value) loadExpr(expr ast.Expr, fileImports fileImportSpecMap) {
@ -310,29 +315,32 @@ func readField(astField *ast.Field, fileImports fileImportSpecMap) (names []stri
return return
} }
func readFieldList(fieldList []*ast.Field, fileImports fileImportSpecMap) (fields []*Field) { func readFieldList(fieldList []*ast.Field, fileImports fileImportSpecMap) (fields []*Field, inlineFields []*Field, unionFields []*Field) {
fields = []*Field{} fields = []*Field{}
for _, field := range fieldList { for _, field := range fieldList {
names, value, jsonInfo := readField(field, fileImports) if names, value, jsonInfo := readField(field, fileImports); value != nil {
if value != nil {
for _, name := range names { for _, name := range names {
if len(name) == 0 { if len(name) == 0 {
if jsonInfo != nil && jsonInfo.Inline { if jsonInfo == nil {
if identType, ok := field.Type.(*ast.Ident); ok {
if typeSpec, ok := identType.Obj.Decl.(*ast.TypeSpec); ok {
if structType, ok := typeSpec.Type.(*ast.StructType); ok {
trace("Inline IdentType", identType.Name)
fields = append(fields, readFieldList(structType.Fields.List, fileImports)...)
continue
}
}
}
}
trace("i do not understand this one", field, names, value, jsonInfo) trace("i do not understand this one", field, names, value, jsonInfo)
continue continue
} else if jsonInfo.Inline {
inlineFields = append(inlineFields, &Field{
Name: name,
Value: value,
JSONInfo: jsonInfo,
})
continue
} }
} else if strings.Compare(strings.ToLower(name[:1]), name[:1]) == 0 {
// this is not unicode proof // this is not unicode proof
if strings.Compare(strings.ToLower(name[:1]), name[:1]) == 0 { continue
} else if jsonInfo != nil && jsonInfo.Union {
unionFields = append(unionFields, &Field{
Name: name,
Value: value,
JSONInfo: jsonInfo,
})
continue continue
} }
fields = append(fields, &Field{ fields = append(fields, &Field{
@ -394,7 +402,10 @@ func extractTypes(file *ast.File, packageName string, structs map[string]*Struct
} }
structType := typeSpec.Type.(*ast.StructType) structType := typeSpec.Type.(*ast.StructType)
trace("StructType", obj.Name) trace("StructType", obj.Name)
structs[structName].Fields = readFieldList(structType.Fields.List, fileImports) fields, inlineFields, unionFields := readFieldList(structType.Fields.List, fileImports)
structs[structName].Fields = fields
structs[structName].InlineFields = inlineFields
structs[structName].UnionFields = unionFields
case "*ast.InterfaceType": case "*ast.InterfaceType":
trace("Interface", obj.Name) trace("Interface", obj.Name)
scalars[structName] = &Scalar{ scalars[structName] = &Scalar{

View File

@ -14,21 +14,23 @@ import (
) )
func (f *Field) tsName(camelCase bool) string { func (f *Field) tsName(camelCase bool) string {
n := f.Name name := f.Name
if camelCase { if camelCase {
n = strcase.ToLowerCamel(n) name = strcase.ToLowerCamel(name)
} }
if f.JSONInfo != nil && len(f.JSONInfo.Name) > 0 { if f.JSONInfo != nil && len(f.JSONInfo.Name) > 0 {
if camelCase && f.JSONInfo.Name != n && strcase.ToLowerCamel(f.JSONInfo.Name) == n { if camelCase && f.JSONInfo.Name != name && strcase.ToLowerCamel(f.JSONInfo.Name) == name {
fmt.Fprintf(os.Stderr, "WARN: json struct field annotation for `%s` does not match the camelCase pattern (expected: `%s`, got: `%s`)\n", f.Name, n, f.JSONInfo.Name) fmt.Fprintf(os.Stderr, "WARN: json struct field annotation for `%s` does not match the camelCase pattern (expected: `%s`, got: `%s`)\n", f.Name, name, f.JSONInfo.Name)
} }
n = f.JSONInfo.Name name = f.JSONInfo.Name
} }
return n return name
} }
func (v *Value) tsType(mappings config.TypeScriptMappings, scalars map[string]*Scalar, structs map[string]*Struct, ts *code, jsonInfo *JSONInfo) { func (v *Value) tsType(mappings config.TypeScriptMappings, scalars map[string]*Scalar, structs map[string]*Struct, ts *code, jsonInfo *JSONInfo) {
switch { switch {
case jsonInfo != nil && len(jsonInfo.Type) > 0:
ts.app(jsonInfo.Type)
case v.Map != nil: case v.Map != nil:
ts.app("Record<") ts.app("Record<")
if v.Map.Key != nil { if v.Map.Key != nil {
@ -39,7 +41,9 @@ func (v *Value) tsType(mappings config.TypeScriptMappings, scalars map[string]*S
ts.app(",") ts.app(",")
v.Map.Value.tsType(mappings, scalars, structs, ts, nil) v.Map.Value.tsType(mappings, scalars, structs, ts, nil)
ts.app(">") ts.app(">")
if jsonInfo == nil || !jsonInfo.OmitEmpty {
ts.app("|null") ts.app("|null")
}
case v.Array != nil: case v.Array != nil:
if v.Array.Value.ScalarType != ScalarTypeByte { if v.Array.Value.ScalarType != ScalarTypeByte {
ts.app("Array<") ts.app("Array<")
@ -48,7 +52,9 @@ func (v *Value) tsType(mappings config.TypeScriptMappings, scalars map[string]*S
if v.Array.Value.ScalarType != ScalarTypeByte { if v.Array.Value.ScalarType != ScalarTypeByte {
ts.app(">") ts.app(">")
} }
if jsonInfo == nil || !jsonInfo.OmitEmpty {
ts.app("|null") ts.app("|null")
}
case v.Scalar != nil: case v.Scalar != nil:
if v.Scalar.Package != "" { if v.Scalar.Package != "" {
mapping, ok := mappings[v.Scalar.Package] mapping, ok := mappings[v.Scalar.Package]
@ -111,7 +117,9 @@ func tsTypeFromScalarType(scalarType ScalarType) string {
func renderStructFields(fields []*Field, mappings config.TypeScriptMappings, scalars map[string]*Scalar, structs map[string]*Struct, ts *code) { func renderStructFields(fields []*Field, mappings config.TypeScriptMappings, scalars map[string]*Scalar, structs map[string]*Struct, ts *code) {
for _, f := range fields { for _, f := range fields {
if f.JSONInfo != nil && f.JSONInfo.Ignore { if len(f.Name) == 0 {
continue
} else if f.JSONInfo != nil && f.JSONInfo.Ignore {
continue continue
} }
ts.app(f.tsName(true)) ts.app(f.tsName(true))
@ -144,6 +152,62 @@ func renderTypescriptStruct(str *Struct, mappings config.TypeScriptMappings, sca
str.Map.Value.tsType(mappings, scalars, structs, ts, nil) str.Map.Value.tsType(mappings, scalars, structs, ts, nil)
ts.app(">") ts.app(">")
ts.nl() ts.nl()
// special handling of inline only structs
case len(str.UnionFields) > 0:
if len(str.Fields) > 0 || len(str.InlineFields) > 0 {
return errors.New("no fields or inline fields are supported when using union")
}
switch {
case str.UnionFields[0].Value.StructType != nil:
ts.app("export type " + str.Name + " = ")
var isUndefined bool
for i, unionField := range str.UnionFields {
if i > 0 {
ts.app(" | ")
}
unionField.Value.tsType(mappings, scalars, structs, ts, &JSONInfo{OmitEmpty: true})
if unionField.Value.IsPtr {
isUndefined = true
}
}
if isUndefined {
ts.app(" | undefined")
}
ts.nl()
case str.UnionFields[0].Value.Scalar != nil:
ts.app("export type " + str.Name + " = ")
for i, field := range str.UnionFields {
if i > 0 {
ts.app(" & ")
}
ts.app("(typeof ")
field.Value.tsType(mappings, scalars, structs, ts, &JSONInfo{OmitEmpty: true})
ts.app(")")
}
ts.nl()
default:
return errors.New("could not resolve this union type")
}
case len(str.InlineFields) > 0:
ts.app("export interface " + str.Name + " extends ")
for i, inlineField := range str.InlineFields {
if i > 0 {
ts.app(", ")
}
if inlineField.Value.IsPtr {
ts.app("Partial<")
}
inlineField.Value.tsType(mappings, scalars, structs, ts, &JSONInfo{OmitEmpty: true})
if inlineField.Value.IsPtr {
ts.app(">")
}
ts.app(" ")
}
ts.app("{")
ts.nl()
ts.ind(1)
renderStructFields(str.Fields, mappings, scalars, structs, ts)
ts.ind(-1).l("}")
default: default:
ts.l("export interface " + str.Name + " {").ind(1) ts.l("export interface " + str.Name + " {").ind(1)
renderStructFields(str.Fields, mappings, scalars, structs, ts) renderStructFields(str.Fields, mappings, scalars, structs, ts)

View File

@ -55,9 +55,6 @@ func renderTypescriptClient(service *Service, mappings config.TypeScriptMappings
} }
ts.app("):") ts.app("):")
throwLastError := false
//lastErrorName := ""
returnTypeTS := newCode(" ") returnTypeTS := newCode(" ")
returnTypeTS.app("{") returnTypeTS.app("{")
innerReturnTypeTS := newCode(" ") innerReturnTypeTS := newCode(" ")
@ -65,9 +62,8 @@ func renderTypescriptClient(service *Service, mappings config.TypeScriptMappings
firstReturnType := "" firstReturnType := ""
countReturns := 0 countReturns := 0
countInnerReturns := 0 countInnerReturns := 0
errIndex := 0
responseObjectPrefix := "" responseObjectPrefix := ""
responseObject := "let responseObject = {" responseObject := "return {"
for index, retField := range method.Return { for index, retField := range method.Return {
countInnerReturns++ countInnerReturns++
@ -88,10 +84,6 @@ func renderTypescriptClient(service *Service, mappings config.TypeScriptMappings
innerReturnTypeTS.app(":") innerReturnTypeTS.app(":")
retField.Value.tsType(mappings, scalars, structs, innerReturnTypeTS, retField.JSONInfo) retField.Value.tsType(mappings, scalars, structs, innerReturnTypeTS, retField.JSONInfo)
if index == len(method.Return)-1 && retField.Value.IsError {
throwLastError = true
errIndex = index
} else {
if index == 0 { if index == 0 {
firstReturnTypeTS := newCode(" ") firstReturnTypeTS := newCode(" ")
retField.Value.tsType(mappings, scalars, structs, firstReturnTypeTS, retField.JSONInfo) retField.Value.tsType(mappings, scalars, structs, firstReturnTypeTS, retField.JSONInfo)
@ -102,7 +94,6 @@ func renderTypescriptClient(service *Service, mappings config.TypeScriptMappings
returnTypeTS.app(":") returnTypeTS.app(":")
responseObject += responseObjectPrefix + retArgName + " : response[" + strconv.Itoa(index) + "]" responseObject += responseObjectPrefix + retArgName + " : response[" + strconv.Itoa(index) + "]"
retField.Value.tsType(mappings, scalars, structs, returnTypeTS, retField.JSONInfo) retField.Value.tsType(mappings, scalars, structs, returnTypeTS, retField.JSONInfo)
}
responseObjectPrefix = ", " responseObjectPrefix = ", "
} }
responseObject += "};" responseObject += "};"
@ -125,30 +116,13 @@ func renderTypescriptClient(service *Service, mappings config.TypeScriptMappings
} }
call := "this.transport<" + innerCallTypeString + ">(\"" + method.Name + "\", [" + strings.Join(callArgs, ", ") + "])" call := "this.transport<" + innerCallTypeString + ">(\"" + method.Name + "\", [" + strings.Join(callArgs, ", ") + "])"
if throwLastError {
ts.l("let response = await " + call)
ts.l("let err = response[" + strconv.Itoa(errIndex) + "];")
//ts.l("delete response." + lastErrorName + ";")
ts.l("if(err) { throw err }")
if countReturns == 1 {
ts.l("return response[0]")
} else if countReturns == 0 {
//ts.l("return response;")
} else {
ts.l(responseObject)
ts.l("return responseObject;")
}
} else {
if countReturns == 0 { if countReturns == 0 {
ts.l("await " + call) ts.l("await " + call)
} else if countReturns == 1 { } else if countReturns == 1 {
ts.l("return (await " + call + ")[0]") ts.l("return (await " + call + ")[0]")
} else { } else {
ts.l("let response = await " + call) ts.l("const response = await " + call)
ts.l(responseObject) ts.l(responseObject)
ts.l("return responseObject;")
}
} }
ts.ind(-1) ts.ind(-1)

42
unionext.go Normal file
View File

@ -0,0 +1,42 @@
package gotsrpc
import (
"fmt"
"reflect"
)
type UnionExt struct{}
var unionExt = &UnionExt{}
func RegisterUnionExt(v ...interface{}) error {
for _, i := range v {
if err := SetJSONExt(i, 1, unionExt); err != nil {
return err
}
}
return nil
}
func MustRegisterUnionExt(v ...interface{}) {
if err := RegisterUnionExt(v...); err != nil {
panic(err)
}
}
func (x *UnionExt) ConvertExt(v interface{}) interface{} {
val := reflect.ValueOf(v)
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
for i := 0; i < val.NumField(); i++ {
if field := val.Field(i); !field.IsZero() {
return field.Interface()
}
}
return nil
}
func (x *UnionExt) UpdateExt(dst interface{}, src interface{}) {
fmt.Println("")
}