diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 0000000..4f417b1 --- /dev/null +++ b/.golangci.yaml @@ -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 diff --git a/Makefile b/Makefile index a65d210..06c2992 100644 --- a/Makefile +++ b/Makefile @@ -29,23 +29,58 @@ build.debug: go build -gcflags "all=-N -l" -o bin/gotsrpc cmd/gotsrpc/gotsrpc.go -EXAMPLES=basic nullable +## === Tools === + +EXAMPLES=basic errors nullable multi define examples .PHONY: example.$(1) example.$(1): cd example/${1} && go run ../../cmd/gotsrpc/gotsrpc.go gotsrpc.yml + cd example/${1}/client && tsc --build .PHONY: example.$(1).run example.$(1).run: example.${1} - cd example/${1}/client && tsc --build cd example/${1} && go run main.go .PHONY: example.$(1).debug example.$(1).debug: build.debug 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 $(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 === ## Show help text diff --git a/build.go b/build.go index e426adb..86d5294 100644 --- a/build.go +++ b/build.go @@ -132,6 +132,14 @@ func Build(conf *config.Config, goPath string) { 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 != "" { 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 { - goTSRPCProxiesCode, goerr := RenderGoTSRPCProxies(services, packageName, pkgName, target) + goTSRPCProxiesCode, goerr := RenderGoTSRPCProxies(services, packageName, pkgName, target, unions) if goerr != nil { fmt.Fprintln(os.Stderr, " could not generate go ts rpc proxies code in target", name, goerr) os.Exit(4) } formatAndWrite(goTSRPCProxiesCode, goTSRPCProxiesFilename) - + } + if len(target.TSRPC) > 0 && !target.SkipTSRPCClient { goTSRPCClientsCode, goerr := RenderGoTSRPCClients(services, packageName, pkgName, target) if goerr != nil { fmt.Fprintln(os.Stderr, " could not generate go ts rpc clients code in target", name, goerr) diff --git a/client.go b/client.go index 8461314..a11664d 100644 --- a/client.go +++ b/client.go @@ -75,15 +75,15 @@ func (c *bufferedClient) SetTransportHttpClient(client *http.Client) { c.client = client } -// CallClient 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) { +// 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{}) error { // Marshall args b := new(bytes.Buffer) // If no arguments are set, remove if len(args) > 0 { 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()) if errRequest != nil { - return errRequest + return NewClientError(errors.Wrap(errRequest, "failed to create request")) } resp, errDo := c.client.Do(request) if errDo != nil { - return errors.Wrap(errDo, "could not execute request") + return NewClientError(errors.Wrap(errDo, "failed to send request")) } defer resp.Body.Close() // Check status if resp.StatusCode != http.StatusOK { - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err + body := "request failed" + if value, err := ioutil.ReadAll(resp.Body); err == nil { + 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 - if err := codec.NewDecoder(resp.Body, responseHandle).Decode(reply); err != nil { - return errors.Wrap(err, "could not decode response from client") + if err := codec.NewDecoder(resp.Body, responseHandle).Decode(wrappedReply); err != nil { + return NewClientError(errors.Wrap(err, "failed to decode response")) + } + + // 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 err + return nil } diff --git a/clienterror.go b/clienterror.go new file mode 100644 index 0000000..732fd0f --- /dev/null +++ b/clienterror.go @@ -0,0 +1,11 @@ +package gotsrpc + +type ClientError struct { + error +} + +func NewClientError(err error) *ClientError { + return &ClientError{ + error: err, + } +} diff --git a/config/config.go b/config/config.go index 5bb4ace..f193e18 100644 --- a/config/config.go +++ b/config/config.go @@ -18,6 +18,7 @@ type Target struct { Out string `yaml:"out"` GoRPC []string `yaml:"gorpc"` TSRPC []string `yaml:"tsrpc"` + SkipTSRPCClient bool `yaml:"skipTSRPCClient"` } func (t *Target) IsGoRPC(service string) bool { diff --git a/error.go b/error.go new file mode 100644 index 0000000..62aaf30 --- /dev/null +++ b/error.go @@ -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 +} diff --git a/example/basic/client/src/app.ts b/example/basic/client/src/app.ts index 95f0634..92d8ed7 100644 --- a/example/basic/client/src/app.ts +++ b/example/basic/client/src/app.ts @@ -5,7 +5,7 @@ import transport from "./transport.js"; export const init = () => { const client = new ServiceClient(transport("/service")); - client.string("hello world").then((res) => { + client.boolPtr(true).then((res) => { console.log(res); }); }; diff --git a/example/basic/client/src/service-client.ts b/example/basic/client/src/service-client.ts index 3f0b318..b2dfb3c 100644 --- a/example/basic/client/src/service-client.ts +++ b/example/basic/client/src/service-client.ts @@ -10,6 +10,9 @@ export class ServiceClient { async bool(v:boolean):Promise { return (await this.transport<{0:boolean}>("Bool", [v]))[0] } + async boolPtr(v:boolean):Promise { + return (await this.transport<{0:boolean|null}>("BoolPtr", [v]))[0] + } async boolSlice(v:Array|null):Promise|null> { return (await this.transport<{0:Array|null}>("BoolSlice", [v]))[0] } diff --git a/example/basic/go.sum b/example/basic/go.sum index 6d58bba..caafc0e 100644 --- a/example/basic/go.sum +++ b/example/basic/go.sum @@ -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/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= diff --git a/example/basic/service/gorpc_gen.go b/example/basic/service/gorpc_gen.go index a398030..1643a96 100644 --- a/example/basic/service/gorpc_gen.go +++ b/example/basic/service/gorpc_gen.go @@ -28,6 +28,13 @@ type ( RetBool_0 bool } + ServiceBoolPtrRequest struct { + V bool + } + ServiceBoolPtrResponse struct { + RetBoolPtr_0 *bool + } + ServiceBoolSliceRequest struct { V []bool } @@ -438,6 +445,8 @@ type ( func init() { gob.Register(ServiceBoolRequest{}) gob.Register(ServiceBoolResponse{}) + gob.Register(ServiceBoolPtrRequest{}) + gob.Register(ServiceBoolPtrResponse{}) gob.Register(ServiceBoolSliceRequest{}) gob.Register(ServiceBoolSliceResponse{}) gob.Register(ServiceFloat32Request{}) @@ -598,6 +607,10 @@ func (p *ServiceGoRPCProxy) handler(clientAddr string, request interface{}) (res req := request.(ServiceBoolRequest) retBool_0 := p.service.Bool(req.V) 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": req := request.(ServiceBoolSliceRequest) retBoolSlice_0 := p.service.BoolSlice(req.V) diff --git a/example/basic/service/gorpcclient_gen.go b/example/basic/service/gorpcclient_gen.go index 5189d6f..6c018ce 100644 --- a/example/basic/service/gorpcclient_gen.go +++ b/example/basic/service/gorpcclient_gen.go @@ -41,6 +41,17 @@ func (tsc *ServiceGoRPCClient) Bool(v bool) (retBool_0 bool, clientErr error) { 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) { req := ServiceBoolSliceRequest{V: v} rpcCallRes, rpcCallErr := tsc.Client.Call(req) diff --git a/example/basic/service/gotsrpc_gen.go b/example/basic/service/gotsrpc_gen.go index bcc54a4..1d521b0 100644 --- a/example/basic/service/gotsrpc_gen.go +++ b/example/basic/service/gotsrpc_gen.go @@ -13,6 +13,7 @@ import ( const ( ServiceGoTSRPCProxyBool = "Bool" + ServiceGoTSRPCProxyBoolPtr = "BoolPtr" ServiceGoTSRPCProxyBoolSlice = "BoolSlice" ServiceGoTSRPCProxyFloat32 = "Float32" ServiceGoTSRPCProxyFloat32Map = "Float32Map" @@ -79,10 +80,7 @@ type ServiceGoTSRPCProxy struct { } func NewDefaultServiceGoTSRPCProxy(service Service) *ServiceGoTSRPCProxy { - return &ServiceGoTSRPCProxy{ - EndPoint: "/service", - service: service, - } + return NewServiceGoTSRPCProxy(service, "/service") } 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) 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: var ( arg_v []bool diff --git a/example/basic/service/gotsrpcclient_gen.go b/example/basic/service/gotsrpcclient_gen.go index 334238f..ca5db59 100644 --- a/example/basic/service/gotsrpcclient_gen.go +++ b/example/basic/service/gotsrpcclient_gen.go @@ -12,6 +12,7 @@ import ( type ServiceGoTSRPCClient interface { 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) 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) @@ -103,6 +104,16 @@ func (tsc *HTTPServiceGoTSRPCClient) Bool(ctx go_context.Context, v bool) (retBo 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) { args := []interface{}{v} reply := []interface{}{&retBoolSlice_0} diff --git a/example/basic/service/handler.go b/example/basic/service/handler.go index 00a541d..b97758a 100644 --- a/example/basic/service/handler.go +++ b/example/basic/service/handler.go @@ -6,6 +6,10 @@ func (h *Handler) Bool(v bool) bool { return v } +func (h *Handler) BoolPtr(v bool) *bool { + return &v +} + func (h *Handler) Int(v int) int { return v } diff --git a/example/basic/service/service.go b/example/basic/service/service.go index 2ca7faa..b1d8f7c 100644 --- a/example/basic/service/service.go +++ b/example/basic/service/service.go @@ -2,6 +2,7 @@ package service type Service interface { Bool(v bool) bool + BoolPtr(v bool) *bool Int(v int) int Int32(v int32) int32 Int64(v int64) int64 diff --git a/example/errors/call/main.go b/example/errors/call/main.go new file mode 100644 index 0000000..1d4ffef --- /dev/null +++ b/example/errors/call/main.go @@ -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") + } + } +} diff --git a/example/errors/client/index.html b/example/errors/client/index.html new file mode 100644 index 0000000..af23efc --- /dev/null +++ b/example/errors/client/index.html @@ -0,0 +1,19 @@ + + + + + + + Errors + + + +

A service test

+ +
open the console!
+
+ + \ No newline at end of file diff --git a/example/errors/client/src/app.ts b/example/errors/client/src/app.ts new file mode 100644 index 0000000..e0bd91c --- /dev/null +++ b/example/errors/client/src/app.ts @@ -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) + }) +} diff --git a/example/errors/client/src/service-client.ts b/example/errors/client/src/service-client.ts new file mode 100644 index 0000000..45a40f6 --- /dev/null +++ b/example/errors/client/src/service-client.ts @@ -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:(method: string, data?: any[]) => Promise + ) {} + async multiple():Promise { + return (await this.transport<{0:github_com_foomo_gotsrpc_v2_example_errors_service_frontend.ErrMulti|null}>("Multiple", []))[0] + } + async simple():Promise { + return (await this.transport<{0:github_com_foomo_gotsrpc_v2_example_errors_service_frontend.ErrSimple|null}>("Simple", []))[0] + } +} \ No newline at end of file diff --git a/example/errors/client/src/service-vo.ts b/example/errors/client/src/service-vo.ts new file mode 100644 index 0000000..c8fd6bc --- /dev/null +++ b/example/errors/client/src/service-vo.ts @@ -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 \ No newline at end of file diff --git a/example/errors/client/src/transport.ts b/example/errors/client/src/transport.ts new file mode 100644 index 0000000..79683ce --- /dev/null +++ b/example/errors/client/src/transport.ts @@ -0,0 +1,18 @@ +const transport = endpoint => async (method: string, args: any = []) => { + return new Promise(async (resolve, reject) => { + fetch( + `${endpoint}/${encodeURIComponent(method)}`, + { + method: 'POST', + body: JSON.stringify(args), + } + ) + .then((response) => { + return response.json() as Promise; + }) + .then((val) => resolve(val)) + .catch((err) => reject(err)) + }) +}; + +export default transport diff --git a/example/errors/client/tsconfig.json b/example/errors/client/tsconfig.json new file mode 100644 index 0000000..7729245 --- /dev/null +++ b/example/errors/client/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src", + } +} \ No newline at end of file diff --git a/example/errors/go.mod b/example/errors/go.mod new file mode 100644 index 0000000..716686d --- /dev/null +++ b/example/errors/go.mod @@ -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 => ../../ diff --git a/example/errors/go.sum b/example/errors/go.sum new file mode 100644 index 0000000..e0792df --- /dev/null +++ b/example/errors/go.sum @@ -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= diff --git a/example/errors/gotsrpc.yml b/example/errors/gotsrpc.yml new file mode 100644 index 0000000..3f1ebbd --- /dev/null +++ b/example/errors/gotsrpc.yml @@ -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 diff --git a/example/errors/handler/backend/handler.go b/example/errors/handler/backend/handler.go new file mode 100644 index 0000000..4528ca5 --- /dev/null +++ b/example/errors/handler/backend/handler.go @@ -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 +} diff --git a/example/errors/handler/frontend/handler.go b/example/errors/handler/frontend/handler.go new file mode 100644 index 0000000..534a583 --- /dev/null +++ b/example/errors/handler/frontend/handler.go @@ -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: "", + } +} diff --git a/example/errors/main.go b/example/errors/main.go new file mode 100644 index 0000000..6007fdd --- /dev/null +++ b/example/errors/main.go @@ -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) + } + }() +} diff --git a/example/errors/service/backend/gotsrpc_gen.go b/example/errors/service/backend/gotsrpc_gen.go new file mode 100644 index 0000000..4680b9c --- /dev/null +++ b/example/errors/service/backend/gotsrpc_gen.go @@ -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) + } +} diff --git a/example/errors/service/backend/gotsrpcclient_gen.go b/example/errors/service/backend/gotsrpcclient_gen.go new file mode 100644 index 0000000..a41d597 --- /dev/null +++ b/example/errors/service/backend/gotsrpcclient_gen.go @@ -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 +} diff --git a/example/errors/service/backend/service.go b/example/errors/service/backend/service.go new file mode 100644 index 0000000..7b75fb3 --- /dev/null +++ b/example/errors/service/backend/service.go @@ -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) +} diff --git a/example/errors/service/backend/vo.go b/example/errors/service/backend/vo.go new file mode 100644 index 0000000..600c442 --- /dev/null +++ b/example/errors/service/backend/vo.go @@ -0,0 +1,9 @@ +package backend + +type ( + Todo struct { + ID int + Title string + Done bool + } +) diff --git a/example/errors/service/frontend/gotsrpc_gen.go b/example/errors/service/frontend/gotsrpc_gen.go new file mode 100644 index 0000000..963d60b --- /dev/null +++ b/example/errors/service/frontend/gotsrpc_gen.go @@ -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) + } +} diff --git a/example/errors/service/frontend/service.go b/example/errors/service/frontend/service.go new file mode 100644 index 0000000..4ef7e37 --- /dev/null +++ b/example/errors/service/frontend/service.go @@ -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) +} diff --git a/example/errors/service/frontend/vo.go b/example/errors/service/frontend/vo.go new file mode 100644 index 0000000..94890bf --- /dev/null +++ b/example/errors/service/frontend/vo.go @@ -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 +) diff --git a/example/multi/client/index.html b/example/multi/client/index.html new file mode 100644 index 0000000..af23efc --- /dev/null +++ b/example/multi/client/index.html @@ -0,0 +1,19 @@ + + + + + + + Errors + + + +

A service test

+ +
open the console!
+
+ + \ No newline at end of file diff --git a/example/multi/client/src/app.ts b/example/multi/client/src/app.ts new file mode 100644 index 0000000..76db3c4 --- /dev/null +++ b/example/multi/client/src/app.ts @@ -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); +} \ No newline at end of file diff --git a/example/multi/client/src/service-client.ts b/example/multi/client/src/service-client.ts new file mode 100644 index 0000000..f472e24 --- /dev/null +++ b/example/multi/client/src/service-client.ts @@ -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:(method: string, data?: any[]) => Promise + ) {} + async inlineStruct():Promise { + return (await this.transport<{0:github_com_foomo_gotsrpc_v2_example_multi_service.InlineStruct}>("InlineStruct", []))[0] + } + async inlineStructPtr():Promise { + return (await this.transport<{0:github_com_foomo_gotsrpc_v2_example_multi_service.InlineStructPtr}>("InlineStructPtr", []))[0] + } + async unionString():Promise { + return (await this.transport<{0:github_com_foomo_gotsrpc_v2_example_multi_service.UnionString}>("UnionString", []))[0] + } + async unionStruct():Promise { + return (await this.transport<{0:github_com_foomo_gotsrpc_v2_example_multi_service.UnionStruct}>("UnionStruct", []))[0] + } +} \ No newline at end of file diff --git a/example/multi/client/src/service-vo.ts b/example/multi/client/src/service-vo.ts new file mode 100644 index 0000000..2bd95fa --- /dev/null +++ b/example/multi/client/src/service-vo.ts @@ -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 , Partial { + 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 \ No newline at end of file diff --git a/example/multi/client/src/transport.ts b/example/multi/client/src/transport.ts new file mode 100644 index 0000000..79683ce --- /dev/null +++ b/example/multi/client/src/transport.ts @@ -0,0 +1,18 @@ +const transport = endpoint => async (method: string, args: any = []) => { + return new Promise(async (resolve, reject) => { + fetch( + `${endpoint}/${encodeURIComponent(method)}`, + { + method: 'POST', + body: JSON.stringify(args), + } + ) + .then((response) => { + return response.json() as Promise; + }) + .then((val) => resolve(val)) + .catch((err) => reject(err)) + }) +}; + +export default transport diff --git a/example/multi/client/tsconfig.json b/example/multi/client/tsconfig.json new file mode 100644 index 0000000..7729245 --- /dev/null +++ b/example/multi/client/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src", + } +} \ No newline at end of file diff --git a/example/multi/go.mod b/example/multi/go.mod new file mode 100644 index 0000000..7e1cc3d --- /dev/null +++ b/example/multi/go.mod @@ -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 => ../../ diff --git a/example/multi/go.sum b/example/multi/go.sum new file mode 100644 index 0000000..84241f5 --- /dev/null +++ b/example/multi/go.sum @@ -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= diff --git a/example/multi/gotsrpc.yml b/example/multi/gotsrpc.yml new file mode 100644 index 0000000..3b80d8d --- /dev/null +++ b/example/multi/gotsrpc.yml @@ -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 diff --git a/example/multi/main.go b/example/multi/main.go new file mode 100644 index 0000000..f0bcac9 --- /dev/null +++ b/example/multi/main.go @@ -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) + } +} diff --git a/example/multi/service/gotsrpc_gen.go b/example/multi/service/gotsrpc_gen.go new file mode 100644 index 0000000..811c4e4 --- /dev/null +++ b/example/multi/service/gotsrpc_gen.go @@ -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) + } +} diff --git a/example/multi/service/gotsrpcclient_gen.go b/example/multi/service/gotsrpcclient_gen.go new file mode 100644 index 0000000..747842f --- /dev/null +++ b/example/multi/service/gotsrpcclient_gen.go @@ -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 +} diff --git a/example/multi/service/handler.go b/example/multi/service/handler.go new file mode 100644 index 0000000..e76627a --- /dev/null +++ b/example/multi/service/handler.go @@ -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}} +} diff --git a/example/multi/service/service.go b/example/multi/service/service.go new file mode 100644 index 0000000..0a45e75 --- /dev/null +++ b/example/multi/service/service.go @@ -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) +} diff --git a/example/multi/service/vo.go b/example/multi/service/vo.go new file mode 100644 index 0000000..0763df9 --- /dev/null +++ b/example/multi/service/vo.go @@ -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" +) diff --git a/example/nullable/client/src/service-client.ts b/example/nullable/client/src/service-client.ts index aaeb63e..85c8be2 100644 --- a/example/nullable/client/src/service-client.ts +++ b/example/nullable/client/src/service-client.ts @@ -29,8 +29,7 @@ export class ServiceClient { return (await this.transport<{0:Record|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|null, i4:Record|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|null; r4:Record|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|null; 3:Record|null}>("VariantH", [i1, i2, i3, i4]) - let responseObject = {r1 : response[0], r2 : response[1], r3 : response[2], r4 : response[3]}; - return responseObject; + 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|null; 3:Record|null}>("VariantH", [i1, i2, i3, i4]) + return {r1 : response[0], r2 : response[1], r3 : response[2], r4 : response[3]}; } } \ No newline at end of file diff --git a/example/nullable/go.mod b/example/nullable/go.mod index 4379104..0a9f8ea 100644 --- a/example/nullable/go.mod +++ b/example/nullable/go.mod @@ -1,4 +1,4 @@ -module github.com/foomo/gotsrpc/v2/example/basic +module github.com/foomo/gotsrpc/v2/example/nullable go 1.16 diff --git a/example/nullable/go.sum b/example/nullable/go.sum index 6d58bba..caafc0e 100644 --- a/example/nullable/go.sum +++ b/example/nullable/go.sum @@ -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/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= diff --git a/example/nullable/gotsrpc.yml b/example/nullable/gotsrpc.yml index 978c974..52963ed 100644 --- a/example/nullable/gotsrpc.yml +++ b/example/nullable/gotsrpc.yml @@ -3,7 +3,7 @@ module: path: ./ targets: - basic: + nullable: services: /service: Service package: github.com/foomo/gotsrpc/v2/example/nullable/service diff --git a/example/nullable/main.go b/example/nullable/main.go index 6569fe6..bba48f4 100644 --- a/example/nullable/main.go +++ b/example/nullable/main.go @@ -6,7 +6,7 @@ import ( "strings" "time" - "github.com/foomo/gotsrpc/v2/example/basic/service" + "github.com/foomo/gotsrpc/v2/example/nullable/service" ) func main() { diff --git a/example/nullable/service/gotsrpc_gen.go b/example/nullable/service/gotsrpc_gen.go index c212f5c..dc78782 100644 --- a/example/nullable/service/gotsrpc_gen.go +++ b/example/nullable/service/gotsrpc_gen.go @@ -28,10 +28,7 @@ type ServiceGoTSRPCProxy struct { } func NewDefaultServiceGoTSRPCProxy(service Service) *ServiceGoTSRPCProxy { - return &ServiceGoTSRPCProxy{ - EndPoint: "/service", - service: service, - } + return NewServiceGoTSRPCProxy(service, "/service") } func NewServiceGoTSRPCProxy(service Service, endpoint string) *ServiceGoTSRPCProxy { diff --git a/example/package.json b/example/package.json new file mode 100644 index 0000000..defd640 --- /dev/null +++ b/example/package.json @@ -0,0 +1,8 @@ +{ + "private": true, + "version": "0.1.0", + "name": "@foomo/gotsrpc-examples", + "devDependencies": { + "typescript": "^4.6.2" + } +} diff --git a/example/tsconfig.json b/example/tsconfig.json index b081b5e..4d0fea5 100644 --- a/example/tsconfig.json +++ b/example/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "module": "ESNext", "target": "ESNext", - "lib": ["es5", "es6", "dom"], + "lib": ["dom", "esnext"], "strictNullChecks": true, "noImplicitAny": false, "strict": true, diff --git a/example/yarn.lock b/example/yarn.lock new file mode 100644 index 0000000..2c8e0c3 --- /dev/null +++ b/example/yarn.lock @@ -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== diff --git a/go.go b/go.go index d65bfe3..6caf76c 100644 --- a/go.go +++ b/go.go @@ -143,43 +143,49 @@ func strfirst(str string, strfunc func(string) string) string { 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(".", "_", "/", "_", "-", "_") - - extractImport := func(packageName string) { - if packageName != fullPackageName { - alias, ok := aliases[packageName] - if !ok { - packageParts := strings.Split(packageName, "/") - beautifulAlias := packageParts[len(packageParts)-1] - uglyAlias := r.Replace(packageName) - alias = uglyAlias //beautifulAlias - for _, otherAlias := range aliases { - if otherAlias == beautifulAlias { - alias = uglyAlias - break - } + if packageName != fullPackageName { + alias, ok := aliases[packageName] + if !ok { + packageParts := strings.Split(packageName, "/") + beautifulAlias := packageParts[len(packageParts)-1] + uglyAlias := r.Replace(packageName) + alias = uglyAlias //beautifulAlias + for _, otherAlias := range aliases { + if otherAlias == beautifulAlias { + alias = uglyAlias + break } - aliases[packageName] = alias } + aliases[packageName] = alias } } +} +func extractImports(fields []*Field, fullPackageName string, aliases map[string]string) { for _, f := range fields { 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 { - 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 { - 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 { - 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{ "time": "time", "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)) + + renderInit(unions, aliases, packageName, g) + for _, service := range services { // Check if we should render this service as ts rcp // Note: remove once there's a separate gorcp generator @@ -226,13 +239,9 @@ func renderTSRPCServiceProxies(services ServiceList, fullPackageName string, pac } func NewDefault` + proxyName + `(service ` + servicePointer + service.Name + `) *` + proxyName + ` { - return &` + proxyName + `{ - EndPoint: "` + service.Endpoint + `", - service: service, - } + return New` + proxyName + `(service, "` + service.Endpoint + `") } - func New` + proxyName + `(service ` + servicePointer + service.Name + `, endpoint string) *` + proxyName + ` { return &` + proxyName + `{ EndPoint: endpoint, @@ -306,7 +315,7 @@ func renderTSRPCServiceProxies(services ServiceList, fullPackageName string, pac g.l("}") } } - returnValueNames := []string{} + var returnValueNames []string for retI, retField := range method.Return { retArgName := retField.Name 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.nl() - g.l("if callStats != nil {") g.ind(1).l("callStats.Execution = time.Now().Sub(executionStart)").ind(-1) g.l("}") @@ -662,6 +670,7 @@ func renderGoRPCServiceClients(services ServiceList, fullPackageName string, pac } g.l(renderImports(aliases, packageName)) + for _, service := range services { if !config.IsGoRPC(service.Name) { continue @@ -738,9 +747,9 @@ func renderGoRPCServiceClients(services ServiceList, fullPackageName string, pac 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(" ") - err = renderTSRPCServiceProxies(services, longPackageName, packageName, config, g) + err = renderTSRPCServiceProxies(services, longPackageName, packageName, config, unions, g) if err != nil { return } @@ -792,6 +801,25 @@ func goMethodArgsWithoutHTTPContextRelatedArgs(m *Method) (filteredArgs []*Field 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 { imports := "" for importPath, alias := range aliases { diff --git a/go.mod b/go.mod index 5b1dedc..eb25a52 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.15 require ( github.com/iancoleman/strcase v0.2.0 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/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.12.1 diff --git a/go.sum b/go.sum index 1809905..500ce79 100644 --- a/go.sum +++ b/go.sum @@ -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/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/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= diff --git a/gotsrpc.go b/gotsrpc.go index e127720..730cbed 100644 --- a/gotsrpc.go +++ b/gotsrpc.go @@ -11,6 +11,7 @@ import ( "os" "path" "path/filepath" + "reflect" "sort" "strings" "time" @@ -86,6 +87,15 @@ func Reply(response []interface{}, stats *CallStats, r *http.Request, w http.Res 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 { http.Error(w, "could not encode data to accepted format", http.StatusInternalServerError) return diff --git a/httperror.go b/httperror.go new file mode 100644 index 0000000..b5b059a --- /dev/null +++ b/httperror.go @@ -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()) +} diff --git a/model.go b/model.go index bb6f4f4..6e64bfb 100644 --- a/model.go +++ b/model.go @@ -12,11 +12,12 @@ const ( ) type JSONInfo struct { - Name string - Inline bool - OmitEmpty bool - ForceStringType bool - Ignore bool + Name string + Type string + Union bool + Inline bool + OmitEmpty bool + Ignore bool } type StructType struct { @@ -95,12 +96,14 @@ type Method struct { } type Struct struct { - IsError bool - Package string - Name string - Fields []*Field - Map *Map - Array *Array + IsError bool + Package string + Name string + Fields []*Field + UnionFields []*Field + InlineFields []*Field + Map *Map + Array *Array } type Scalar struct { diff --git a/servicereader.go b/servicereader.go index 1e3239d..9280a49 100644 --- a/servicereader.go +++ b/servicereader.go @@ -570,27 +570,53 @@ func (s *Struct) DepsSatisfied(missingTypes map[string]bool, structs map[string] } return false } - for _, field := range s.Fields { - var fieldStructType *StructType = nil - if field.Value.StructType != nil { - fieldStructType = field.Value.StructType - } else if field.Value.Array != nil && field.Value.Array.Value.StructType != nil { - fieldStructType = field.Value.Array.Value.StructType - } else if field.Value.Map != nil && field.Value.Map.Value.StructType != nil { - fieldStructType = field.Value.Map.Value.StructType - } else if field.Value.Scalar != nil && needsWork(field.Value.Scalar.FullName()) { - return false - } else if field.Value.Array != nil && field.Value.Array.Value.Scalar != nil && needsWork(field.Value.Array.Value.Scalar.FullName()) { - return false - } else if field.Value.Map != nil && field.Value.Map.Value.Scalar != nil && needsWork(field.Value.Map.Value.Scalar.FullName()) { - return false - } - if fieldStructType != nil { - if needsWork(fieldStructType.FullName()) { + needWorksFields := func(fields []*Field) bool { + for _, field := range fields { + var fieldStructType *StructType = nil + if field.Value.StructType != nil { + fieldStructType = field.Value.StructType + } else if field.Value.Array != nil && field.Value.Array.Value.StructType != nil { + fieldStructType = field.Value.Array.Value.StructType + } else if field.Value.Map != nil && field.Value.Map.Value.StructType != nil { + fieldStructType = field.Value.Map.Value.StructType + } else if field.Value.Scalar != nil && needsWork(field.Value.Scalar.FullName()) { + return false + } else if field.Value.Array != nil && field.Value.Array.Value.Scalar != nil && needsWork(field.Value.Array.Value.Scalar.FullName()) { + return false + } else if field.Value.Map != nil && field.Value.Map.Value.Scalar != nil && needsWork(field.Value.Map.Value.Scalar.FullName()) { return false } + if fieldStructType != nil { + if needsWork(fieldStructType.FullName()) { + return false + } + } } + 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.Value.StructType != nil { if needsWork(s.Array.Value.StructType.FullName()) { diff --git a/transport.go b/transport.go index e77a62d..01bb03e 100644 --- a/transport.go +++ b/transport.go @@ -24,10 +24,39 @@ var msgpackClientHandle = &clientHandle{ 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() { mh := new(codec.MsgpackHandle) // use map[string]interface{} instead of map[interface{}]interface{} 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 // attempting to set promoted field in literal will cause a compiler error mh.RawToString = true @@ -40,6 +69,21 @@ var jsonClientHandle = &clientHandle{ 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 { switch encoding { case EncodingMsgpack: diff --git a/typereader.go b/typereader.go index d10f85c..3a981c1 100644 --- a/typereader.go +++ b/typereader.go @@ -34,9 +34,6 @@ func readStructs(pkg *ast.Package, packageName string) (structs map[string]*Stru structType.IsError = true } } - //jsonDump(errorTypes) - //jsonDump(scalarTypes) - //jsonDump(structs) return } @@ -67,41 +64,47 @@ func extractJSONInfo(tag string) *JSONInfo { jsonTagParts := strings.Split(jsonTagString, ",") name := "" + tsType := "" omit := false + union := false inline := false ignore := false - forceStringType := false - cleanParts := []string{} + var cleanParts []string for _, jsonTagPart := range jsonTagParts { cleanParts = append(cleanParts, strings.TrimSpace(jsonTagPart)) } - switch len(cleanParts) { - case 1: + if len(cleanParts) > 0 { switch cleanParts[0] { + case "": + // do nothing case "-": ignore = true default: name = cleanParts[0] } - case 2: - if len(cleanParts[0]) > 0 { - name = cleanParts[0] - } - switch cleanParts[1] { - case "inline": - inline = true - case "omitempty": - omit = true - case "string": - forceStringType = true + } + if len(cleanParts) > 1 { + for _, cleanPart := range cleanParts[1:] { + switch { + case cleanPart == "union": + union = true + case cleanPart == "inline": + inline = true + case cleanPart == "omitempty": + omit = true + case strings.HasPrefix(cleanPart, "type:"): + tsType = strings.TrimPrefix(cleanPart, "type:") + } } } + return &JSONInfo{ - Name: name, - Inline: inline, - OmitEmpty: omit, - ForceStringType: forceStringType, - Ignore: ignore, + Name: name, + Type: tsType, + Union: union, + Inline: inline, + OmitEmpty: omit, + Ignore: ignore, } } @@ -157,6 +160,9 @@ func readAstType(v *Value, fieldIdent *ast.Ident, fileImports fileImportSpecMap, } } else { 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) { 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) { v.IsInterface = true - } func (v *Value) loadExpr(expr ast.Expr, fileImports fileImportSpecMap) { @@ -310,29 +315,32 @@ func readField(astField *ast.Field, fileImports fileImportSpecMap) (names []stri 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{} for _, field := range fieldList { - names, value, jsonInfo := readField(field, fileImports) - if value != nil { + if names, value, jsonInfo := readField(field, fileImports); value != nil { for _, name := range names { if len(name) == 0 { - if jsonInfo != nil && jsonInfo.Inline { - 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 - } - } - } + if jsonInfo == nil { + trace("i do not understand this one", field, names, value, jsonInfo) + continue + } else if jsonInfo.Inline { + inlineFields = append(inlineFields, &Field{ + Name: name, + Value: value, + JSONInfo: jsonInfo, + }) + continue } - trace("i do not understand this one", field, names, value, jsonInfo) + } else if strings.Compare(strings.ToLower(name[:1]), name[:1]) == 0 { + // this is not unicode proof continue - } - // this is not unicode proof - if strings.Compare(strings.ToLower(name[:1]), name[:1]) == 0 { + } else if jsonInfo != nil && jsonInfo.Union { + unionFields = append(unionFields, &Field{ + Name: name, + Value: value, + JSONInfo: jsonInfo, + }) continue } fields = append(fields, &Field{ @@ -394,7 +402,10 @@ func extractTypes(file *ast.File, packageName string, structs map[string]*Struct } structType := typeSpec.Type.(*ast.StructType) 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": trace("Interface", obj.Name) scalars[structName] = &Scalar{ diff --git a/typescript.go b/typescript.go index 4990dd4..3dd732c 100644 --- a/typescript.go +++ b/typescript.go @@ -14,21 +14,23 @@ import ( ) func (f *Field) tsName(camelCase bool) string { - n := f.Name + name := f.Name if camelCase { - n = strcase.ToLowerCamel(n) + name = strcase.ToLowerCamel(name) } if f.JSONInfo != nil && len(f.JSONInfo.Name) > 0 { - if camelCase && f.JSONInfo.Name != n && strcase.ToLowerCamel(f.JSONInfo.Name) == n { - 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) + 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, 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) { switch { + case jsonInfo != nil && len(jsonInfo.Type) > 0: + ts.app(jsonInfo.Type) case v.Map != nil: ts.app("Record<") if v.Map.Key != nil { @@ -39,7 +41,9 @@ func (v *Value) tsType(mappings config.TypeScriptMappings, scalars map[string]*S ts.app(",") v.Map.Value.tsType(mappings, scalars, structs, ts, nil) ts.app(">") - ts.app("|null") + if jsonInfo == nil || !jsonInfo.OmitEmpty { + ts.app("|null") + } case v.Array != nil: if v.Array.Value.ScalarType != ScalarTypeByte { ts.app("Array<") @@ -48,7 +52,9 @@ func (v *Value) tsType(mappings config.TypeScriptMappings, scalars map[string]*S if v.Array.Value.ScalarType != ScalarTypeByte { ts.app(">") } - ts.app("|null") + if jsonInfo == nil || !jsonInfo.OmitEmpty { + ts.app("|null") + } case v.Scalar != nil: if 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) { 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 } 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) ts.app(">") 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: ts.l("export interface " + str.Name + " {").ind(1) renderStructFields(str.Fields, mappings, scalars, structs, ts) diff --git a/typscriptclient.go b/typscriptclient.go index b8d1a2a..c0d874a 100644 --- a/typscriptclient.go +++ b/typscriptclient.go @@ -55,9 +55,6 @@ func renderTypescriptClient(service *Service, mappings config.TypeScriptMappings } ts.app("):") - throwLastError := false - //lastErrorName := "" - returnTypeTS := newCode(" ") returnTypeTS.app("{") innerReturnTypeTS := newCode(" ") @@ -65,9 +62,8 @@ func renderTypescriptClient(service *Service, mappings config.TypeScriptMappings firstReturnType := "" countReturns := 0 countInnerReturns := 0 - errIndex := 0 responseObjectPrefix := "" - responseObject := "let responseObject = {" + responseObject := "return {" for index, retField := range method.Return { countInnerReturns++ @@ -88,21 +84,16 @@ func renderTypescriptClient(service *Service, mappings config.TypeScriptMappings innerReturnTypeTS.app(":") 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 { - firstReturnTypeTS := newCode(" ") - retField.Value.tsType(mappings, scalars, structs, firstReturnTypeTS, retField.JSONInfo) - firstReturnType = firstReturnTypeTS.string() - } - countReturns++ - returnTypeTS.app(retArgName) - returnTypeTS.app(":") - responseObject += responseObjectPrefix + retArgName + " : response[" + strconv.Itoa(index) + "]" - retField.Value.tsType(mappings, scalars, structs, returnTypeTS, retField.JSONInfo) + if index == 0 { + firstReturnTypeTS := newCode(" ") + retField.Value.tsType(mappings, scalars, structs, firstReturnTypeTS, retField.JSONInfo) + firstReturnType = firstReturnTypeTS.string() } + countReturns++ + returnTypeTS.app(retArgName) + returnTypeTS.app(":") + responseObject += responseObjectPrefix + retArgName + " : response[" + strconv.Itoa(index) + "]" + retField.Value.tsType(mappings, scalars, structs, returnTypeTS, retField.JSONInfo) responseObjectPrefix = ", " } responseObject += "};" @@ -125,30 +116,13 @@ func renderTypescriptClient(service *Service, mappings config.TypeScriptMappings } 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;") - } + if countReturns == 0 { + ts.l("await " + call) + } else if countReturns == 1 { + ts.l("return (await " + call + ")[0]") } else { - if countReturns == 0 { - ts.l("await " + call) - } else if countReturns == 1 { - ts.l("return (await " + call + ")[0]") - } else { - ts.l("let response = await " + call) - ts.l(responseObject) - ts.l("return responseObject;") - } + ts.l("const response = await " + call) + ts.l(responseObject) } ts.ind(-1) diff --git a/unionext.go b/unionext.go new file mode 100644 index 0000000..3f39bb5 --- /dev/null +++ b/unionext.go @@ -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("") +}