* 'master' of https://github.com/foomo/gotsrpc:
  merged slice-args and added test for arg loading
  implemented ServiceList to get determistically sorted code
  reverted code sorting attempts
  yet another codegen reference point
  sorting next iteration
  added target test
  reomved old tests
  alphabeitc order ensured
  code gen demo update
  docs aond demo update
  codegen update
  inline testyaml fixed
  skipping private constants
  removed r and w from php client generator
  next arg handling iteration, by passing in pointers
  back to number casting
  handling of string params
  finetuning slice argument unmarshalling

# Conflicts:
#	Makefile
This commit is contained in:
Stefan Martinov 2017-07-07 14:08:08 +02:00
commit 83962012ea
21 changed files with 327 additions and 449 deletions

View File

@ -10,9 +10,11 @@ install:
build: goreleaser build: goreleaser
goreleaser goreleaser
goreleaser: goreleaser:
@go get github.com/goreleaser/goreleaser && go install github.com/goreleaser/goreleaser @go get github.com/goreleaser/goreleaser && go install github.com/goreleaser/goreleaser
glide: glide:
@go get github.com/Masterminds/glide && glide install @go get github.com/Masterminds/glide && glide install
test: demo
go test $(glide nv)

View File

@ -1,23 +1,69 @@
# Go TypeScript RPC # Go / TypeScript and Go / Go RPC
Where to define this ?!
```bash ```bash
gotsrpc -ts-target path/to/local/whatever.ts -ts-module My.Module.Foo my/package/path ServiceStructA [ServiceStructB ...] gotsrpc gotsrpc.yml
gotsrpc build gotsrpc.yml
``` ```
Will generate client and server side go and TypeScript code. Have fun!
## config expamples
### commonjs
[demo/config.yml](demo/config-commonjs.yml)
```yaml ```yaml
--- ---
# gotsrpc.yml modulekind: commonjs
targets: targets:
- demo:
package: my/package/path services:
expose: /service/foo: Foo
- ServiceStructA /service/demo: Demo
- ServiceStructB package: github.com/foomo/gotsrpc/demo
ts: out: /tmp/test.ts
module: My.Module.Foo gorpc:
target: path/to/local/whatever.ts - Foo
- Demo
tsrpc:
- Foo
- Demo
mappings:
github.com/foomo/gotsrpc/demo:
out: /tmp/test-files-demo.ts
github.com/foomo/gotsrpc/demo/nested:
out: /tmp/test-files-demo-nested.ts
...
```
### oldschool TypeScript
[demo/config.yml](demo/config.yml)
```yaml
---
targets:
demo:
module: GoTSRPC.Demo
services:
/service/foo: Foo
/service/demo: Demo
package: github.com/foomo/gotsrpc/demo
out: /tmp/test.ts
gorpc:
- Foo
- Demo
tsrpc:
- Foo
- Demo
mappings:
github.com/foomo/gotsrpc/demo:
module: GoTSRPC.Demo
out: /tmp/test-files-demo.ts
github.com/foomo/gotsrpc/demo/nested:
module: GoTSRPC.Demo.Nested
out: /tmp/test-files-demo-nested.ts
...
``` ```

View File

@ -53,6 +53,14 @@ func Build(conf *config.Config, goPath string) {
} }
mappedTypeScript := map[string]map[string]*code{} mappedTypeScript := map[string]map[string]*code{}
// preserve alphabetic order
names := []string{}
for name := range conf.Targets {
names = append(names, name)
}
sort.Strings(names)
for name, target := range conf.Targets { for name, target := range conf.Targets {
fmt.Fprintln(os.Stderr, "building target", name) fmt.Fprintln(os.Stderr, "building target", name)
@ -179,6 +187,7 @@ func Build(conf *config.Config, goPath string) {
} }
// spew.Dump(mappedTypeScript) // spew.Dump(mappedTypeScript)
for goPackage, mappedStructsMap := range mappedTypeScript { for goPackage, mappedStructsMap := range mappedTypeScript {
mapping, ok := conf.Mappings[goPackage] mapping, ok := conf.Mappings[goPackage]
if !ok { if !ok {

View File

@ -10,7 +10,7 @@ import (
) )
type Demo struct { type Demo struct {
proxy *demo.ServiceGoTSRPCProxy proxy *demo.DemoGoTSRPCProxy
} }
func (d *Demo) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (d *Demo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
@ -39,7 +39,7 @@ func serveFile(name string, w http.ResponseWriter) {
func main() { func main() {
d := &Demo{ d := &Demo{
proxy: demo.NewServiceGoTSRPCProxy(&demo.Demo{}, "/service"), proxy: demo.NewDefaultDemoGoTSRPCProxy(&demo.Demo{}, []string{}),
} }
fmt.Println(http.ListenAndServe(":8080", d)) fmt.Println(http.ListenAndServe(":8080", d))
} }

View File

@ -9,7 +9,7 @@ targets:
/service/demo: Service /service/demo: Service
package: github.com/foomo/gotsrpc/demo package: github.com/foomo/gotsrpc/demo
module: My.Service module: My.Service
modulekind: commonjs modulekind: commonjs
out: /tmp/my-service.ts out: /tmp/my-service.ts
mappings: mappings:
foo/bar: foo/bar:

22
demo/config-commonjs.yml Normal file
View File

@ -0,0 +1,22 @@
---
modulekind: commonjs
targets:
demo:
services:
/service/foo: Foo
/service/demo: Demo
package: github.com/foomo/gotsrpc/demo
out: /tmp/test.ts
gorpc:
- Foo
- Demo
tsrpc:
- Foo
- Demo
mappings:
github.com/foomo/gotsrpc/demo:
out: /tmp/test-files-demo.ts
github.com/foomo/gotsrpc/demo/nested:
out: /tmp/test-files-demo-nested.ts
...

View File

@ -10,6 +10,9 @@ targets:
gorpc: gorpc:
- Foo - Foo
- Demo - Demo
tsrpc:
- Foo
- Demo
mappings: mappings:
github.com/foomo/gotsrpc/demo: github.com/foomo/gotsrpc/demo:
@ -18,3 +21,4 @@ mappings:
github.com/foomo/gotsrpc/demo/nested: github.com/foomo/gotsrpc/demo/nested:
module: GoTSRPC.Demo.Nested module: GoTSRPC.Demo.Nested
out: /tmp/test-files-demo-nested.ts out: /tmp/test-files-demo-nested.ts
...

View File

@ -10,7 +10,7 @@ type Demo struct {
Bla bool Bla bool
} }
func (d *Demo) Hello(name string) (reply string, err *Err) { func (d *Demo) Hello(name string) (string, *Err) {
if name == "Peter" { if name == "Peter" {
return "", &Err{"fuck you Peter I do not like you"} return "", &Err{"fuck you Peter I do not like you"}
} }

View File

@ -20,17 +20,17 @@ type (
callStatsHandler gotsrpc.GoRPCCallStatsHandlerFun callStatsHandler gotsrpc.GoRPCCallStatsHandlerFun
} }
HelloRequest struct { FooHelloRequest struct {
Number int64 Number int64
} }
HelloResponse struct { FooHelloResponse struct {
RetHello_0 int RetHello_0 int
} }
) )
func init() { func init() {
gob.Register(HelloRequest{}) gob.Register(FooHelloRequest{})
gob.Register(HelloResponse{}) gob.Register(FooHelloResponse{})
} }
func NewFooGoRPCProxy(addr string, service *Foo, tlsConfig *tls.Config) *FooGoRPCProxy { func NewFooGoRPCProxy(addr string, service *Foo, tlsConfig *tls.Config) *FooGoRPCProxy {
@ -51,6 +51,10 @@ func (p *FooGoRPCProxy) Start() error {
return p.server.Start() return p.server.Start()
} }
func (p *FooGoRPCProxy) Serve() error {
return p.server.Serve()
}
func (p *FooGoRPCProxy) Stop() { func (p *FooGoRPCProxy) Stop() {
p.server.Stop() p.server.Stop()
} }
@ -67,10 +71,10 @@ func (p *FooGoRPCProxy) handler(clientAddr string, request interface{}) (respons
funcName := funcNameParts[len(funcNameParts)-1] funcName := funcNameParts[len(funcNameParts)-1]
switch funcName { switch funcName {
case "HelloRequest": case "FooHelloRequest":
req := request.(HelloRequest) req := request.(FooHelloRequest)
retHello_0 := p.service.Hello(req.Number) retHello_0 := p.service.Hello(req.Number)
response = HelloResponse{RetHello_0: retHello_0} response = FooHelloResponse{RetHello_0: retHello_0}
default: default:
fmt.Println("Unkown request type", reflect.TypeOf(request).String()) fmt.Println("Unkown request type", reflect.TypeOf(request).String())
} }
@ -94,62 +98,62 @@ type (
callStatsHandler gotsrpc.GoRPCCallStatsHandlerFun callStatsHandler gotsrpc.GoRPCCallStatsHandlerFun
} }
ExtractAddressRequest struct { DemoExtractAddressRequest struct {
Person *Person Person *Person
} }
ExtractAddressResponse struct { DemoExtractAddressResponse struct {
Addr *Address Addr *Address
E *Err E *Err
} }
GiveMeAScalarRequest struct { DemoGiveMeAScalarRequest struct {
} }
GiveMeAScalarResponse struct { DemoGiveMeAScalarResponse struct {
Amount nested.Amount Amount nested.Amount
Wahr nested.True Wahr nested.True
Hier ScalarInPlace Hier ScalarInPlace
} }
HelloRequest struct { DemoHelloRequest struct {
Name string Name string
} }
HelloResponse struct { DemoHelloResponse struct {
Reply string RetHello_0 string
Err *Err RetHello_1 *Err
} }
MapCrapRequest struct { DemoMapCrapRequest struct {
} }
MapCrapResponse struct { DemoMapCrapResponse struct {
Crap map[string][]int Crap map[string][]int
} }
NestRequest struct { DemoNestRequest struct {
} }
NestResponse struct { DemoNestResponse struct {
RetNest_0 *nested.Nested RetNest_0 *nested.Nested
} }
TestScalarInPlaceRequest struct { DemoTestScalarInPlaceRequest struct {
} }
TestScalarInPlaceResponse struct { DemoTestScalarInPlaceResponse struct {
RetTestScalarInPlace_0 ScalarInPlace RetTestScalarInPlace_0 ScalarInPlace
} }
) )
func init() { func init() {
gob.Register(ExtractAddressRequest{}) gob.Register(DemoExtractAddressRequest{})
gob.Register(ExtractAddressResponse{}) gob.Register(DemoExtractAddressResponse{})
gob.Register(GiveMeAScalarRequest{}) gob.Register(DemoGiveMeAScalarRequest{})
gob.Register(GiveMeAScalarResponse{}) gob.Register(DemoGiveMeAScalarResponse{})
gob.Register(HelloRequest{}) gob.Register(DemoHelloRequest{})
gob.Register(HelloResponse{}) gob.Register(DemoHelloResponse{})
gob.Register(MapCrapRequest{}) gob.Register(DemoMapCrapRequest{})
gob.Register(MapCrapResponse{}) gob.Register(DemoMapCrapResponse{})
gob.Register(NestRequest{}) gob.Register(DemoNestRequest{})
gob.Register(NestResponse{}) gob.Register(DemoNestResponse{})
gob.Register(TestScalarInPlaceRequest{}) gob.Register(DemoTestScalarInPlaceRequest{})
gob.Register(TestScalarInPlaceResponse{}) gob.Register(DemoTestScalarInPlaceResponse{})
} }
func NewDemoGoRPCProxy(addr string, service *Demo, tlsConfig *tls.Config) *DemoGoRPCProxy { func NewDemoGoRPCProxy(addr string, service *Demo, tlsConfig *tls.Config) *DemoGoRPCProxy {
@ -170,6 +174,10 @@ func (p *DemoGoRPCProxy) Start() error {
return p.server.Start() return p.server.Start()
} }
func (p *DemoGoRPCProxy) Serve() error {
return p.server.Serve()
}
func (p *DemoGoRPCProxy) Stop() { func (p *DemoGoRPCProxy) Stop() {
p.server.Stop() p.server.Stop()
} }
@ -186,26 +194,26 @@ func (p *DemoGoRPCProxy) handler(clientAddr string, request interface{}) (respon
funcName := funcNameParts[len(funcNameParts)-1] funcName := funcNameParts[len(funcNameParts)-1]
switch funcName { switch funcName {
case "ExtractAddressRequest": case "DemoExtractAddressRequest":
req := request.(ExtractAddressRequest) req := request.(DemoExtractAddressRequest)
addr, e := p.service.ExtractAddress(req.Person) addr, e := p.service.ExtractAddress(req.Person)
response = ExtractAddressResponse{Addr: addr, E: e} response = DemoExtractAddressResponse{Addr: addr, E: e}
case "GiveMeAScalarRequest": case "DemoGiveMeAScalarRequest":
amount, wahr, hier := p.service.GiveMeAScalar() amount, wahr, hier := p.service.GiveMeAScalar()
response = GiveMeAScalarResponse{Amount: amount, Wahr: wahr, Hier: hier} response = DemoGiveMeAScalarResponse{Amount: amount, Wahr: wahr, Hier: hier}
case "HelloRequest": case "DemoHelloRequest":
req := request.(HelloRequest) req := request.(DemoHelloRequest)
reply, err := p.service.Hello(req.Name) retHello_0, retHello_1 := p.service.Hello(req.Name)
response = HelloResponse{Reply: reply, Err: err} response = DemoHelloResponse{RetHello_0: retHello_0, RetHello_1: retHello_1}
case "MapCrapRequest": case "DemoMapCrapRequest":
crap := p.service.MapCrap() crap := p.service.MapCrap()
response = MapCrapResponse{Crap: crap} response = DemoMapCrapResponse{Crap: crap}
case "NestRequest": case "DemoNestRequest":
retNest_0 := p.service.Nest() retNest_0 := p.service.Nest()
response = NestResponse{RetNest_0: retNest_0} response = DemoNestResponse{RetNest_0: retNest_0}
case "TestScalarInPlaceRequest": case "DemoTestScalarInPlaceRequest":
retTestScalarInPlace_0 := p.service.TestScalarInPlace() retTestScalarInPlace_0 := p.service.TestScalarInPlace()
response = TestScalarInPlaceResponse{RetTestScalarInPlace_0: retTestScalarInPlace_0} response = DemoTestScalarInPlaceResponse{RetTestScalarInPlace_0: retTestScalarInPlace_0}
default: default:
fmt.Println("Unkown request type", reflect.TypeOf(request).String()) fmt.Println("Unkown request type", reflect.TypeOf(request).String())
} }

View File

@ -8,124 +8,122 @@ import (
) )
type FooGoRPCClient struct { type FooGoRPCClient struct {
client *gorpc.Client Client *gorpc.Client
} }
func NewFooGoRPCClient(addr string, tlsConfig *tls.Config) *FooGoRPCClient { func NewFooGoRPCClient(addr string, tlsConfig *tls.Config) *FooGoRPCClient {
client := &FooGoRPCClient{} client := &FooGoRPCClient{}
if tlsConfig == nil { if tlsConfig == nil {
client.client = gorpc.NewTCPClient(addr) client.Client = gorpc.NewTCPClient(addr)
} else { } else {
client.client = gorpc.NewTLSClient(addr, tlsConfig) client.Client = gorpc.NewTLSClient(addr, tlsConfig)
} }
client.Start()
return client return client
} }
func (c *FooGoRPCClient) Start() { func (c *FooGoRPCClient) Start() {
c.client.Start() c.Client.Start()
} }
func (c *FooGoRPCClient) Stop() { func (c *FooGoRPCClient) Stop() {
c.client.Stop() c.Client.Stop()
} }
func (c *FooGoRPCClient) Hello(number int64) (retHello_0 int, clientErr error) { func (c *FooGoRPCClient) Hello(number int64) (retHello_0 int, clientErr error) {
req := HelloRequest{Number: number} req := FooHelloRequest{Number: number}
res, err := c.client.Call(req) rpcCallRes, rpcCallErr := c.Client.Call(req)
if err != nil { if rpcCallErr != nil {
clientErr = err clientErr = rpcCallErr
return return
} }
response := res.(HelloResponse) response := rpcCallRes.(FooHelloResponse)
return response.RetHello_0, nil return response.RetHello_0, nil
} }
type DemoGoRPCClient struct { type DemoGoRPCClient struct {
client *gorpc.Client Client *gorpc.Client
} }
func NewDemoGoRPCClient(addr string, tlsConfig *tls.Config) *DemoGoRPCClient { func NewDemoGoRPCClient(addr string, tlsConfig *tls.Config) *DemoGoRPCClient {
client := &DemoGoRPCClient{} client := &DemoGoRPCClient{}
if tlsConfig == nil { if tlsConfig == nil {
client.client = gorpc.NewTCPClient(addr) client.Client = gorpc.NewTCPClient(addr)
} else { } else {
client.client = gorpc.NewTLSClient(addr, tlsConfig) client.Client = gorpc.NewTLSClient(addr, tlsConfig)
} }
client.Start()
return client return client
} }
func (c *DemoGoRPCClient) Start() { func (c *DemoGoRPCClient) Start() {
c.client.Start() c.Client.Start()
} }
func (c *DemoGoRPCClient) Stop() { func (c *DemoGoRPCClient) Stop() {
c.client.Stop() c.Client.Stop()
} }
func (c *DemoGoRPCClient) ExtractAddress(person *Person) (addr *Address, e *Err, clientErr error) { func (c *DemoGoRPCClient) ExtractAddress(person *Person) (addr *Address, e *Err, clientErr error) {
req := ExtractAddressRequest{Person: person} req := DemoExtractAddressRequest{Person: person}
res, err := c.client.Call(req) rpcCallRes, rpcCallErr := c.Client.Call(req)
if err != nil { if rpcCallErr != nil {
clientErr = err clientErr = rpcCallErr
return return
} }
response := res.(ExtractAddressResponse) response := rpcCallRes.(DemoExtractAddressResponse)
return response.Addr, response.E, nil return response.Addr, response.E, nil
} }
func (c *DemoGoRPCClient) GiveMeAScalar() (amount nested.Amount, wahr nested.True, hier ScalarInPlace, clientErr error) { func (c *DemoGoRPCClient) GiveMeAScalar() (amount nested.Amount, wahr nested.True, hier ScalarInPlace, clientErr error) {
req := GiveMeAScalarRequest{} req := DemoGiveMeAScalarRequest{}
res, err := c.client.Call(req) rpcCallRes, rpcCallErr := c.Client.Call(req)
if err != nil { if rpcCallErr != nil {
clientErr = err clientErr = rpcCallErr
return return
} }
response := res.(GiveMeAScalarResponse) response := rpcCallRes.(DemoGiveMeAScalarResponse)
return response.Amount, response.Wahr, response.Hier, nil return response.Amount, response.Wahr, response.Hier, nil
} }
func (c *DemoGoRPCClient) Hello(name string) (reply string, err *Err, clientErr error) { func (c *DemoGoRPCClient) Hello(name string) (retHello_0 string, retHello_1 *Err, clientErr error) {
req := HelloRequest{Name: name} req := DemoHelloRequest{Name: name}
res, err := c.client.Call(req) rpcCallRes, rpcCallErr := c.Client.Call(req)
if err != nil { if rpcCallErr != nil {
clientErr = err clientErr = rpcCallErr
return return
} }
response := res.(HelloResponse) response := rpcCallRes.(DemoHelloResponse)
return response.Reply, response.Err, nil return response.RetHello_0, response.RetHello_1, nil
} }
func (c *DemoGoRPCClient) MapCrap() (crap map[string][]int, clientErr error) { func (c *DemoGoRPCClient) MapCrap() (crap map[string][]int, clientErr error) {
req := MapCrapRequest{} req := DemoMapCrapRequest{}
res, err := c.client.Call(req) rpcCallRes, rpcCallErr := c.Client.Call(req)
if err != nil { if rpcCallErr != nil {
clientErr = err clientErr = rpcCallErr
return return
} }
response := res.(MapCrapResponse) response := rpcCallRes.(DemoMapCrapResponse)
return response.Crap, nil return response.Crap, nil
} }
func (c *DemoGoRPCClient) Nest() (retNest_0 *nested.Nested, clientErr error) { func (c *DemoGoRPCClient) Nest() (retNest_0 *nested.Nested, clientErr error) {
req := NestRequest{} req := DemoNestRequest{}
res, err := c.client.Call(req) rpcCallRes, rpcCallErr := c.Client.Call(req)
if err != nil { if rpcCallErr != nil {
clientErr = err clientErr = rpcCallErr
return return
} }
response := res.(NestResponse) response := rpcCallRes.(DemoNestResponse)
return response.RetNest_0, nil return response.RetNest_0, nil
} }
func (c *DemoGoRPCClient) TestScalarInPlace() (retTestScalarInPlace_0 ScalarInPlace, clientErr error) { func (c *DemoGoRPCClient) TestScalarInPlace() (retTestScalarInPlace_0 ScalarInPlace, clientErr error) {
req := TestScalarInPlaceRequest{} req := DemoTestScalarInPlaceRequest{}
res, err := c.client.Call(req) rpcCallRes, rpcCallErr := c.Client.Call(req)
if err != nil { if rpcCallErr != nil {
clientErr = err clientErr = rpcCallErr
return return
} }
response := res.(TestScalarInPlaceResponse) response := rpcCallRes.(DemoTestScalarInPlaceResponse)
return response.RetTestScalarInPlace_0, nil return response.RetTestScalarInPlace_0, nil
} }

View File

@ -55,14 +55,15 @@ func (p *FooGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
switch funcName { switch funcName {
case "Hello": case "Hello":
args = []interface{}{int64(0)} arg_number := int64(0)
err := gotsrpc.LoadArgs(args, callStats, r) args = []interface{}{&arg_number}
err := gotsrpc.LoadArgs(&args, callStats, r)
if err != nil { if err != nil {
gotsrpc.ErrorCouldNotLoadArgs(w) gotsrpc.ErrorCouldNotLoadArgs(w)
return return
} }
executionStart := time.Now() executionStart := time.Now()
helloRet := p.service.Hello(int64(args[0].(float64))) helloRet := p.service.Hello(arg_number)
if callStats != nil { if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart) callStats.Execution = time.Now().Sub(executionStart)
} }
@ -121,14 +122,15 @@ func (p *DemoGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
switch funcName { switch funcName {
case "ExtractAddress": case "ExtractAddress":
args = []interface{}{&Person{}} arg_person := &Person{}
err := gotsrpc.LoadArgs(args, callStats, r) args = []interface{}{&arg_person}
err := gotsrpc.LoadArgs(&args, callStats, r)
if err != nil { if err != nil {
gotsrpc.ErrorCouldNotLoadArgs(w) gotsrpc.ErrorCouldNotLoadArgs(w)
return return
} }
executionStart := time.Now() executionStart := time.Now()
extractAddressAddr, extractAddressE := p.service.ExtractAddress(args[0].(*Person)) extractAddressAddr, extractAddressE := p.service.ExtractAddress(arg_person)
if callStats != nil { if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart) callStats.Execution = time.Now().Sub(executionStart)
} }
@ -143,18 +145,19 @@ func (p *DemoGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
gotsrpc.Reply([]interface{}{giveMeAScalarAmount, giveMeAScalarWahr, giveMeAScalarHier}, callStats, r, w) gotsrpc.Reply([]interface{}{giveMeAScalarAmount, giveMeAScalarWahr, giveMeAScalarHier}, callStats, r, w)
return return
case "Hello": case "Hello":
args = []interface{}{""} arg_name := ""
err := gotsrpc.LoadArgs(args, callStats, r) args = []interface{}{&arg_name}
err := gotsrpc.LoadArgs(&args, callStats, r)
if err != nil { if err != nil {
gotsrpc.ErrorCouldNotLoadArgs(w) gotsrpc.ErrorCouldNotLoadArgs(w)
return return
} }
executionStart := time.Now() executionStart := time.Now()
helloReply, helloErr := p.service.Hello(args[0].(string)) helloRet, helloRet_1 := p.service.Hello(arg_name)
if callStats != nil { if callStats != nil {
callStats.Execution = time.Now().Sub(executionStart) callStats.Execution = time.Now().Sub(executionStart)
} }
gotsrpc.Reply([]interface{}{helloReply, helloErr}, callStats, r, w) gotsrpc.Reply([]interface{}{helloRet, helloRet_1}, callStats, r, w)
return return
case "MapCrap": case "MapCrap":
executionStart := time.Now() executionStart := time.Now()

View File

@ -59,9 +59,9 @@ func (c *DemoGoTSRPCClient) GiveMeAScalar() (amount nested.Amount, wahr nested.T
return return
} }
func (c *DemoGoTSRPCClient) Hello(name string) (reply string, err *Err, clientErr error) { func (c *DemoGoTSRPCClient) Hello(name string) (retHello_0 string, retHello_1 *Err, clientErr error) {
args := []interface{}{name} args := []interface{}{name}
reply := []interface{}{&reply, &err} reply := []interface{}{&retHello_0, &retHello_1}
clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "Hello", args, reply) clientErr = gotsrpc.CallClient(c.URL, c.EndPoint, "Hello", args, reply)
return return
} }

46
go.go
View File

@ -163,7 +163,7 @@ func extractImports(fields []*Field, fullPackageName string, aliases map[string]
} }
} }
func renderTSRPCServiceProxies(services map[string]*Service, fullPackageName string, packageName string, config *config.Target, g *code) error { func renderTSRPCServiceProxies(services ServiceList, fullPackageName string, packageName string, config *config.Target, g *code) error {
aliases := map[string]string{ aliases := map[string]string{
"time": "time", "time": "time",
"net/http": "http", "net/http": "http",
@ -171,7 +171,7 @@ func renderTSRPCServiceProxies(services map[string]*Service, fullPackageName str
} }
for _, service := range services { for _, service := range services {
// Check if we should render this service as ts rcp // Check if we should render this service as ts rpc
// Note: remove once there's a separate gorcp generator // Note: remove once there's a separate gorcp generator
if !config.IsTSRPC(service.Name) { if !config.IsTSRPC(service.Name) {
continue continue
@ -193,7 +193,7 @@ func renderTSRPCServiceProxies(services map[string]*Service, fullPackageName str
` + imports + ` ` + imports + `
) )
`) `)
for endpoint, service := range services { for _, service := range services {
// Check if we should render this service as ts rcp // Check if we should render this service as ts rcp
// Note: remove once there's a separate gorcp generator // Note: remove once there's a separate gorcp generator
if !config.IsTSRPC(service.Name) { if !config.IsTSRPC(service.Name) {
@ -210,7 +210,7 @@ func renderTSRPCServiceProxies(services map[string]*Service, fullPackageName str
func NewDefault` + proxyName + `(service *` + service.Name + `, allowOrigin []string) *` + proxyName + ` { func NewDefault` + proxyName + `(service *` + service.Name + `, allowOrigin []string) *` + proxyName + ` {
return &` + proxyName + `{ return &` + proxyName + `{
EndPoint: "` + endpoint + `", EndPoint: "` + service.Endpoint + `",
allowOrigin : allowOrigin, allowOrigin : allowOrigin,
service: service, service: service,
} }
@ -274,11 +274,14 @@ func renderTSRPCServiceProxies(services map[string]*Service, fullPackageName str
if len(method.Args) > 0 { if len(method.Args) > 0 {
args := []string{} args := []string{}
argsDecls := []string{}
skipArgI := 0 skipArgI := 0
for argI, arg := range method.Args { for argI, arg := range method.Args {
argName := "arg_" + arg.Name //strconv.Itoa(argI)
if argI == 0 && arg.Value.isHTTPResponseWriter() { if argI == 0 && arg.Value.isHTTPResponseWriter() {
continue continue
} }
@ -287,19 +290,16 @@ func renderTSRPCServiceProxies(services map[string]*Service, fullPackageName str
continue continue
} }
args = append(args, arg.Value.emptyLiteral(aliases)) argsDecls = append(argsDecls, argName+" := "+arg.Value.emptyLiteral(aliases))
switch arg.Value.GoScalarType { args = append(args, "&"+argName)
case "int", "int8", "int16", "int32", "int64", callArgs = append(callArgs, argName)
"uint", "uint8", "uint16", "uint32", "uint64":
callArgs = append(callArgs, fmt.Sprint(arg.Value.GoScalarType+"(args[", skipArgI, "].(float64))"))
default:
// assert
callArgs = append(callArgs, fmt.Sprint("args[", skipArgI, "].("+arg.Value.goType(aliases, fullPackageName)+")"))
}
skipArgI++ skipArgI++
} }
for _, argDecl := range argsDecls {
g.l(argDecl)
}
g.l("args = []interface{}{" + strings.Join(args, ", ") + "}") g.l("args = []interface{}{" + strings.Join(args, ", ") + "}")
g.l("err := gotsrpc.LoadArgs(args, callStats, r)") g.l("err := gotsrpc.LoadArgs(&args, callStats, r)")
g.l("if err != nil {") g.l("if err != nil {")
g.ind(1) g.ind(1)
g.l("gotsrpc.ErrorCouldNotLoadArgs(w)") g.l("gotsrpc.ErrorCouldNotLoadArgs(w)")
@ -344,7 +344,7 @@ func renderTSRPCServiceProxies(services map[string]*Service, fullPackageName str
return nil return nil
} }
func renderTSRPCServiceClients(services map[string]*Service, fullPackageName string, packageName string, config *config.Target, g *code) error { func renderTSRPCServiceClients(services ServiceList, fullPackageName string, packageName string, config *config.Target, g *code) error {
aliases := map[string]string{ aliases := map[string]string{
"github.com/foomo/gotsrpc": "gotsrpc", "github.com/foomo/gotsrpc": "gotsrpc",
} }
@ -373,7 +373,7 @@ func renderTSRPCServiceClients(services map[string]*Service, fullPackageName str
` + imports + ` ` + imports + `
) )
`) `)
for endpoint, service := range services { for _, service := range services {
// Check if we should render this service as ts rcp // Check if we should render this service as ts rcp
// Note: remove once there's a separate gorcp generator // Note: remove once there's a separate gorcp generator
if !config.IsTSRPC(service.Name) { if !config.IsTSRPC(service.Name) {
@ -388,7 +388,7 @@ func renderTSRPCServiceClients(services map[string]*Service, fullPackageName str
} }
func NewDefault` + clientName + `(url string) *` + clientName + ` { func NewDefault` + clientName + `(url string) *` + clientName + ` {
return New` + clientName + `(url, "` + endpoint + `") return New` + clientName + `(url, "` + service.Endpoint + `")
} }
func New` + clientName + `(url string, endpoint string) *` + clientName + ` { func New` + clientName + `(url string, endpoint string) *` + clientName + ` {
@ -428,7 +428,7 @@ func renderTSRPCServiceClients(services map[string]*Service, fullPackageName str
return nil return nil
} }
func renderGoRPCServiceProxies(services map[string]*Service, fullPackageName string, packageName string, config *config.Target, g *code) error { func renderGoRPCServiceProxies(services ServiceList, fullPackageName string, packageName string, config *config.Target, g *code) error {
aliases := map[string]string{ aliases := map[string]string{
"fmt": "fmt", "fmt": "fmt",
"time": "time", "time": "time",
@ -596,7 +596,7 @@ func renderGoRPCServiceProxies(services map[string]*Service, fullPackageName str
return nil return nil
} }
func renderGoRPCServiceClients(services map[string]*Service, fullPackageName string, packageName string, config *config.Target, g *code) error { func renderGoRPCServiceClients(services ServiceList, fullPackageName string, packageName string, config *config.Target, g *code) error {
aliases := map[string]string{ aliases := map[string]string{
"crypto/tls": "tls", "crypto/tls": "tls",
"github.com/valyala/gorpc": "gorpc", "github.com/valyala/gorpc": "gorpc",
@ -699,7 +699,7 @@ func renderGoRPCServiceClients(services map[string]*Service, fullPackageName str
return nil return nil
} }
func RenderGoTSRPCProxies(services map[string]*Service, longPackageName, packageName string, config *config.Target) (gocode string, err error) { func RenderGoTSRPCProxies(services ServiceList, longPackageName, packageName string, config *config.Target) (gocode string, err error) {
g := newCode(" ") g := newCode(" ")
err = renderTSRPCServiceProxies(services, longPackageName, packageName, config, g) err = renderTSRPCServiceProxies(services, longPackageName, packageName, config, g)
if err != nil { if err != nil {
@ -709,7 +709,7 @@ func RenderGoTSRPCProxies(services map[string]*Service, longPackageName, package
return return
} }
func RenderGoTSRPCClients(services map[string]*Service, longPackageName, packageName string, config *config.Target) (gocode string, err error) { func RenderGoTSRPCClients(services ServiceList, longPackageName, packageName string, config *config.Target) (gocode string, err error) {
g := newCode(" ") g := newCode(" ")
err = renderTSRPCServiceClients(services, longPackageName, packageName, config, g) err = renderTSRPCServiceClients(services, longPackageName, packageName, config, g)
if err != nil { if err != nil {
@ -719,7 +719,7 @@ func RenderGoTSRPCClients(services map[string]*Service, longPackageName, package
return return
} }
func RenderGoRPCProxies(services map[string]*Service, longPackageName, packageName string, config *config.Target) (gocode string, err error) { func RenderGoRPCProxies(services ServiceList, longPackageName, packageName string, config *config.Target) (gocode string, err error) {
g := newCode(" ") g := newCode(" ")
err = renderGoRPCServiceProxies(services, longPackageName, packageName, config, g) err = renderGoRPCServiceProxies(services, longPackageName, packageName, config, g)
if err != nil { if err != nil {
@ -729,7 +729,7 @@ func RenderGoRPCProxies(services map[string]*Service, longPackageName, packageNa
return return
} }
func RenderGoRPCClients(services map[string]*Service, longPackageName, packageName string, config *config.Target) (gocode string, err error) { func RenderGoRPCClients(services ServiceList, longPackageName, packageName string, config *config.Target) (gocode string, err error) {
g := newCode(" ") g := newCode(" ")
err = renderGoRPCServiceClients(services, longPackageName, packageName, config, g) err = renderGoRPCServiceClients(services, longPackageName, packageName, config, g)
if err != nil { if err != nil {

View File

@ -36,15 +36,16 @@ func ErrorMethodNotAllowed(w http.ResponseWriter) {
w.Write([]byte("you gotta POST")) w.Write([]byte("you gotta POST"))
} }
func LoadArgs(args []interface{}, callStats *CallStats, r *http.Request) error { func LoadArgs(args interface{}, callStats *CallStats, r *http.Request) error {
start := time.Now() start := time.Now()
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
return err return err
} }
if err := json.Unmarshal(body, &args); err != nil { errLoad := loadArgs(&args, body)
return err if errLoad != nil {
return errLoad
} }
if callStats != nil { if callStats != nil {
callStats.Unmarshalling = time.Now().Sub(start) callStats.Unmarshalling = time.Now().Sub(start)
@ -53,6 +54,13 @@ func LoadArgs(args []interface{}, callStats *CallStats, r *http.Request) error {
return nil return nil
} }
func loadArgs(args interface{}, jsonBytes []byte) error {
if err := json.Unmarshal(jsonBytes, &args); err != nil {
return err
}
return nil
}
func RequestWithStatsContext(r *http.Request) *http.Request { func RequestWithStatsContext(r *http.Request) *http.Request {
stats := &CallStats{} stats := &CallStats{}
return r.WithContext(context.WithValue(r.Context(), contextStatsKey, stats)) return r.WithContext(context.WithValue(r.Context(), contextStatsKey, stats))
@ -100,7 +108,7 @@ func parseDir(goPaths []string, packageName string) (map[string]*ast.Package, er
fset := token.NewFileSet() fset := token.NewFileSet()
var dir string var dir string
if strings.HasSuffix(goPath, "vendor") { if strings.HasSuffix(goPath, "vendor") {
dir = path.Join(goPath,packageName) dir = path.Join(goPath, packageName)
} else { } else {
dir = path.Join(goPath, "src", packageName) dir = path.Join(goPath, "src", packageName)
} }

25
gotsrpc_test.go Normal file
View File

@ -0,0 +1,25 @@
package gotsrpc
import (
"testing"
)
func TestLoadArgs(t *testing.T) {
jsonBytes := []byte(`["a", ["a", "b", "c"]]`)
foo := ""
bar := []string{}
args := []interface{}{&foo, &bar}
errLoad := loadArgs(&args, jsonBytes)
if errLoad != nil {
t.Fatal(errLoad)
}
if foo != "a" {
t.Fatal("foo should have been a")
}
if len(bar) != 3 {
t.Fatal("bar len wrong", len(bar), "!=", len(bar))
}
if bar[1] != "b" {
t.Fatal("bar[1] (", bar[1], ") != b")
}
}

View File

@ -48,12 +48,15 @@ type Field struct {
} }
type Service struct { type Service struct {
Name string Name string
Methods ServiceMethods Methods ServiceMethods
Endpoint string
} }
type ServiceMethods []*Method type ServiceMethods []*Method
type ServiceList []*Service
func (sm ServiceMethods) Len() int { return len(sm) } func (sm ServiceMethods) Len() int { return len(sm) }
func (sm ServiceMethods) Swap(i, j int) { sm[i], sm[j] = sm[j], sm[i] } func (sm ServiceMethods) Swap(i, j int) { sm[i], sm[j] = sm[j], sm[i] }
func (sm ServiceMethods) Less(i, j int) bool { return sm[i].Name < sm[j].Name } func (sm ServiceMethods) Less(i, j int) bool { return sm[i].Name < sm[j].Name }

15
php.go
View File

@ -1,8 +1,9 @@
package gotsrpc package gotsrpc
import ( import (
"github.com/foomo/gotsrpc/config"
"strings" "strings"
"github.com/foomo/gotsrpc/config"
) )
func renderPHPRPCServiceClients(service *Service, namespce string, g *code) error { func renderPHPRPCServiceClients(service *Service, namespce string, g *code) error {
@ -39,12 +40,16 @@ func renderPHPRPCServiceClients(service *Service, namespce string, g *code) erro
// Service methods // Service methods
for _, method := range service.Methods { for _, method := range service.Methods {
args := []string{}
params := []string{} params := []string{}
g.l(`/**`) g.l(`/**`)
for _, a := range method.Args { for i, a := range method.Args {
args = append(args, "$"+a.Name) if i == 0 && a.Value.isHTTPResponseWriter() {
continue
}
if i == 1 && a.Value.isHTTPRequest() {
continue
}
params = append(params, "$"+a.Name) params = append(params, "$"+a.Name)
g.l(` * @param $` + a.Name) g.l(` * @param $` + a.Name)
} }
@ -88,7 +93,7 @@ func renderPHPRPCServiceClients(service *Service, namespce string, g *code) erro
return nil return nil
} }
func RenderPHPRPCClients(services map[string]*Service, config *config.Target) (code map[string]string, err error) { func RenderPHPRPCClients(services ServiceList, config *config.Target) (code map[string]string, err error) {
code = map[string]string{} code = map[string]string{}
for _, service := range services { for _, service := range services {
// Check if we should render this service as ts rcp // Check if we should render this service as ts rcp

View File

@ -10,7 +10,11 @@ import (
"strings" "strings"
) )
func readServiceFile(file *ast.File, packageName string, services map[string]*Service) error { func (sl ServiceList) Len() int { return len(sl) }
func (sl ServiceList) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] }
func (sl ServiceList) Less(i, j int) bool { return strings.Compare(sl[i].Name, sl[j].Name) > 0 }
func readServiceFile(file *ast.File, packageName string, services ServiceList) error {
findService := func(serviceName string) (service *Service, ok bool) { findService := func(serviceName string) (service *Service, ok bool) {
for _, service := range services { for _, service := range services {
if service.Name == serviceName { if service.Name == serviceName {
@ -132,13 +136,14 @@ func readFields(fieldList *ast.FieldList, fileImports fileImportSpecMap) (fields
} }
func readServicesInPackage(pkg *ast.Package, packageName string, serviceMap map[string]string) (services map[string]*Service, err error) { func readServicesInPackage(pkg *ast.Package, packageName string, serviceMap map[string]string) (services ServiceList, err error) {
services = map[string]*Service{} services = ServiceList{}
for endpoint, serviceName := range serviceMap { for endpoint, serviceName := range serviceMap {
services[endpoint] = &Service{ services = append(services, &Service{
Name: serviceName, Name: serviceName,
Methods: []*Method{}, Methods: []*Method{},
} Endpoint: endpoint,
})
} }
for _, file := range pkg.Files { for _, file := range pkg.Files {
err = readServiceFile(file, packageName, services) err = readServiceFile(file, packageName, services)
@ -147,6 +152,7 @@ func readServicesInPackage(pkg *ast.Package, packageName string, serviceMap map[
} }
} }
sort.Sort(services)
return return
} }
@ -163,13 +169,17 @@ func loadConstants(pkg *ast.Package) map[string]*ast.BasicLit {
spec := spec.(*ast.ValueSpec) spec := spec.(*ast.ValueSpec)
for _, val := range spec.Values { for _, val := range spec.Values {
if reflect.ValueOf(val).Type().String() == "*ast.BasicLit" { if reflect.ValueOf(val).Type().String() == "*ast.BasicLit" {
firstValueLit := val.(*ast.BasicLit) firstValueLit := val.(*ast.BasicLit)
//fmt.Println("a value spec", spec.Names[0], firstValueLit.Kind, firstValueLit.Value) constName := spec.Names[0].String()
constants[spec.Names[0].String()] = firstValueLit //.Value for indexRune, r := range constName {
if indexRune == 0 {
if string(r) == strings.ToUpper(string(r)) {
constants[constName] = firstValueLit
}
break
}
}
} }
} }
} }
} }
@ -181,7 +191,7 @@ func loadConstants(pkg *ast.Package) map[string]*ast.BasicLit {
} }
func Read(goPaths []string, packageName string, serviceMap map[string]string) (services map[string]*Service, structs map[string]*Struct, scalars map[string]*Scalar, constants map[string]map[string]*ast.BasicLit, err error) { func Read(goPaths []string, packageName string, serviceMap map[string]string) (services ServiceList, structs map[string]*Struct, scalars map[string]*Scalar, constants map[string]map[string]*ast.BasicLit, err error) {
if len(serviceMap) == 0 { if len(serviceMap) == 0 {
err = errors.New("nothing to do service names are empty") err = errors.New("nothing to do service names are empty")
return return

122
test.js
View File

@ -1,122 +0,0 @@
var GoTSRPC;
(function (GoTSRPC) {
function call(endPoint, method, args, success, err) {
var request = new XMLHttpRequest();
request.withCredentials = true;
request.open('POST', endPoint + "/" + encodeURIComponent(method), true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.send(JSON.stringify(args));
request.onload = function () {
if (request.status == 200) {
try {
var data = JSON.parse(request.responseText);
success.apply(null, data);
}
catch (e) {
err(request);
}
}
else {
err(request);
}
};
request.onerror = function () {
err(request);
};
}
GoTSRPC.call = call;
})(GoTSRPC || (GoTSRPC = {}));
var MZG;
(function (MZG) {
var Services;
(function (Services) {
var Order;
(function (Order) {
var ServiceClient = (function () {
function ServiceClient(endPoint) {
if (endPoint === void 0) { endPoint = "/service"; }
this.endPoint = endPoint;
}
ServiceClient.prototype.validateOrder = function (success, err) {
GoTSRPC.call(this.endPoint, "ValidateOrder", [], success, err);
};
ServiceClient.prototype.confirmOrder = function (success, err) {
GoTSRPC.call(this.endPoint, "ConfirmOrder", [], success, err);
};
ServiceClient.prototype.flushPaymentInfo = function (success, err) {
GoTSRPC.call(this.endPoint, "FlushPaymentInfo", [], success, err);
};
ServiceClient.prototype.setPositionSize = function (oldItemID, newItemID, success, err) {
GoTSRPC.call(this.endPoint, "SetPositionSize", [oldItemID, newItemID], success, err);
};
ServiceClient.prototype.setPositionCount = function (itemID, count, success, err) {
GoTSRPC.call(this.endPoint, "SetPositionCount", [itemID, count], success, err);
};
ServiceClient.prototype.getOrder = function (success, err) {
GoTSRPC.call(this.endPoint, "GetOrder", [], success, err);
};
ServiceClient.prototype.setBillingAddress = function (addressId, success, err) {
GoTSRPC.call(this.endPoint, "SetBillingAddress", [addressId], success, err);
};
ServiceClient.prototype.setShippingAddress = function (addressId, success, err) {
GoTSRPC.call(this.endPoint, "SetShippingAddress", [addressId], success, err);
};
ServiceClient.prototype.setBilling = function (billing, success, err) {
GoTSRPC.call(this.endPoint, "SetBilling", [billing], success, err);
};
ServiceClient.prototype.setShipping = function (shipping, success, err) {
GoTSRPC.call(this.endPoint, "SetShipping", [shipping], success, err);
};
ServiceClient.prototype.setPayment = function (payment, success, err) {
GoTSRPC.call(this.endPoint, "SetPayment", [payment], success, err);
};
ServiceClient.prototype.setPage = function (page, success, err) {
GoTSRPC.call(this.endPoint, "SetPage", [page], success, err);
};
ServiceClient.prototype.getOrderSummary = function (success, err) {
GoTSRPC.call(this.endPoint, "GetOrderSummary", [], success, err);
};
ServiceClient.defaultInst = new ServiceClient;
return ServiceClient;
}());
Order.ServiceClient = ServiceClient;
})(Order = Services.Order || (Services.Order = {}));
})(Services = MZG.Services || (MZG.Services = {}));
})(MZG || (MZG = {}));
// ----------------- MZG.Services --------------------
var MZG;
(function (MZG) {
var Services;
(function (Services) {
var Profile;
(function (Profile) {
var ServiceClient = (function () {
function ServiceClient(endPoint) {
if (endPoint === void 0) { endPoint = "/service"; }
this.endPoint = endPoint;
}
ServiceClient.prototype.validateLogin = function (email, success, err) {
GoTSRPC.call(this.endPoint, "ValidateLogin", [email], success, err);
};
ServiceClient.prototype.newCustomer = function (email, success, err) {
GoTSRPC.call(this.endPoint, "NewCustomer", [email], success, err);
};
ServiceClient.prototype.newGuestCustomer = function (email, success, err) {
GoTSRPC.call(this.endPoint, "NewGuestCustomer", [email], success, err);
};
ServiceClient.prototype.addShippingAddress = function (address, success, err) {
GoTSRPC.call(this.endPoint, "AddShippingAddress", [address], success, err);
};
ServiceClient.prototype.addBillingAddress = function (address, success, err) {
GoTSRPC.call(this.endPoint, "AddBillingAddress", [address], success, err);
};
ServiceClient.prototype.setProfileData = function (profileData, success, err) {
GoTSRPC.call(this.endPoint, "SetProfileData", [profileData], success, err);
};
ServiceClient.defaultInst = new ServiceClient;
return ServiceClient;
}());
Profile.ServiceClient = ServiceClient;
})(Profile = Services.Profile || (Services.Profile = {}));
})(Services = MZG.Services || (MZG.Services = {}));
})(MZG || (MZG = {}));

143
test.ts
View File

@ -1,143 +0,0 @@
module GoTSRPC {
export function call(endPoint:string, method:string, args:any[], success:any, err:any) {
var request = new XMLHttpRequest();
request.withCredentials = true;
request.open('POST', endPoint + "/" + encodeURIComponent(method), true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.send(JSON.stringify(args));
request.onload = function() {
if (request.status == 200) {
try {
var data = JSON.parse(request.responseText);
success.apply(null, data);
} catch(e) {
err(request);
}
} else {
err(request);
}
};
request.onerror = function() {
err(request);
};
}
}
module MZG.Services.Order {
export class ServiceClient {
static defaultInst = new ServiceClient;
constructor(public endPoint:string = "/service") { }
validateOrder(success:(ret:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "ValidateOrder", [], success, err);
}
confirmOrder(success:(ret:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "ConfirmOrder", [], success, err);
}
flushPaymentInfo(success:(ret:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "FlushPaymentInfo", [], success, err);
}
setPositionSize(oldItemID:string, newItemID:string, success:(order:MZG.Services.Order.Order, err:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "SetPositionSize", [oldItemID, newItemID], success, err);
}
setPositionCount(itemID:string, count:number, success:(order:MZG.Services.Order.Order, err:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "SetPositionCount", [itemID, count], success, err);
}
getOrder(success:(order:MZG.Services.Order.Order, err:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "GetOrder", [], success, err);
}
setBillingAddress(addressId:string, success:(ret:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "SetBillingAddress", [addressId], success, err);
}
setShippingAddress(addressId:string, success:(ret:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "SetShippingAddress", [addressId], success, err);
}
setBilling(billing:MZG.Services.Order.Billing, success:(ret:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "SetBilling", [billing], success, err);
}
setShipping(shipping:MZG.Services.Order.Shipping, success:(ret:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "SetShipping", [shipping], success, err);
}
setPayment(payment:MZG.Services.Order.Payment, success:(ret:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "SetPayment", [payment], success, err);
}
setPage(page:string, success:(ret:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "SetPage", [page], success, err);
}
getOrderSummary(success:(summary:MZG.Services.Order.OrderSummary, err:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "GetOrderSummary", [], success, err);
}
}
}
// ----------------- MZG.Services.Order --------------------
OrderSummary &{ [ // git.bestbytes.net/Project-Globus-Services/services/order.OrderSummary export interface OrderSummary { numberOfItems:number; subTotal:string; promotionAmount:string; hasPromotions:boolean; vat:string; total:string; totalRappen:string; shippingCosts:string; hasShippingCosts:boolean; amountUntilFreeShipping:string; }] 1}
// ----------------- MZG.Services.Order --------------------
OrderPosition &{ [ // git.bestbytes.net/Project-Globus-Services/services/order.OrderPosition export interface OrderPosition { id:string; name:string; brand:string; imageURL:string; size:string; style:string; quantity:number; pricePerUnit:any; price:any; availability:any; sizes:any[]; }] 1}
// ----------------- MZG.Services.Order --------------------
AddressFormValue &{ [ // git.bestbytes.net/Project-Globus-Services/services/order.AddressFormValue export interface AddressFormValue { salutation:string; firstName:string; title:string; lastName:string; company:string; street:string; streetNumber:string; zip:string; city:string; }] 1}
// ----------------- MZG.Services.Order --------------------
Billing &{ [ // git.bestbytes.net/Project-Globus-Services/services/order.Billing export interface Billing { newAddress?:MZG.Services.Order.AddressFormValue; tacAgree:boolean; email:string; phone:string; birthday:string; }] 1}
// ----------------- MZG.Services.Order --------------------
PaymentInfo &{ [ // git.bestbytes.net/Project-Globus-Services/services/order.PaymentInfo export interface PaymentInfo { method:string; status:string; feedback:string; complete:boolean; amount:string; }] 1}
// ----------------- MZG.Services.Order --------------------
Session &{ [ // git.bestbytes.net/Project-Globus-Services/services/order.Session export interface Session { billing?:MZG.Services.Order.Billing; shipping?:MZG.Services.Order.Shipping; payment?:MZG.Services.Order.Payment; page:string; }] 1}
// ----------------- MZG.Services.Order --------------------
Order &{ [ // git.bestbytes.net/Project-Globus-Services/services/order.Order export interface Order { id:string; positions:MZG.Services.Order.OrderPosition[]; summary?:MZG.Services.Order.OrderSummary; paymentInfo:MZG.Services.Order.PaymentInfo[]; session?:MZG.Services.Order.Session; }] 1}
// ----------------- MZG.Services.Order --------------------
Shipping &{ [ // git.bestbytes.net/Project-Globus-Services/services/order.Shipping export interface Shipping { useBilling:boolean; newAddress?:MZG.Services.Order.AddressFormValue; }] 1}
// ----------------- MZG.Services.Order --------------------
Payment &{ [ // git.bestbytes.net/Project-Globus-Services/services/order.Payment export interface Payment { paymentType:string; coupons:string[]; }] 1}
// ----------------- MZG.Services --------------------
ServiceError &{ [ // git.bestbytes.net/Project-Globus-Services/services.ServiceError export interface ServiceError { error:string; }] 1}
module GoTSRPC {
export function call(endPoint:string, method:string, args:any[], success:any, err:any) {
var request = new XMLHttpRequest();
request.withCredentials = true;
request.open('POST', endPoint + "/" + encodeURIComponent(method), true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.send(JSON.stringify(args));
request.onload = function() {
if (request.status == 200) {
try {
var data = JSON.parse(request.responseText);
success.apply(null, data);
} catch(e) {
err(request);
}
} else {
err(request);
}
};
request.onerror = function() {
err(request);
};
}
}
module MZG.Services.Profile {
export class ServiceClient {
static defaultInst = new ServiceClient;
constructor(public endPoint:string = "/service") { }
validateLogin(email:string, success:(valid:boolean) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "ValidateLogin", [email], success, err);
}
newCustomer(email:string, success:(ret:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "NewCustomer", [email], success, err);
}
newGuestCustomer(email:string, success:(ret:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "NewGuestCustomer", [email], success, err);
}
addShippingAddress(address:MZG.Services.Profile.AddressFormValue, success:(ret:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "AddShippingAddress", [address], success, err);
}
addBillingAddress(address:MZG.Services.Profile.AddressFormValue, success:(ret:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "AddBillingAddress", [address], success, err);
}
setProfileData(profileData:MZG.Services.Profile.ProfileData, success:(ret:MZG.Services.ServiceError) => void, err:(request:XMLHttpRequest) => void) {
GoTSRPC.call(this.endPoint, "SetProfileData", [profileData], success, err);
}
}
}
// ----------------- MZG.Services --------------------
ServiceError &{ [ // git.bestbytes.net/Project-Globus-Services/services.ServiceError export interface ServiceError { error:string; }] 1}
// ----------------- MZG.Services.Profile --------------------
AddressFormValue &{ [ // git.bestbytes.net/Project-Globus-Services/services/profile.AddressFormValue export interface AddressFormValue { salutation:string; firstName:string; title:string; lastName:string; company:string; street:string; streetNumber:string; zip:string; city:string; }] 1}
// ----------------- MZG.Services.Profile --------------------
ProfileData &{ [ // git.bestbytes.net/Project-Globus-Services/services/profile.ProfileData export interface ProfileData { tacAgree:boolean; PhoneMobile:string; Birthday:string; }] 1}

View File

@ -99,22 +99,22 @@ func renderStruct(str *Struct, mappings config.TypeScriptMappings, scalarTypes m
return nil return nil
} }
func renderService(skipGoTSRPC bool, moduleKind config.ModuleKind, service *Service, endpoint string, mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, ts *code) error { func renderService(skipGoTSRPC bool, moduleKind config.ModuleKind, service *Service, mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, ts *code) error {
clientName := service.Name + "Client" clientName := service.Name + "Client"
ts.l("export class " + clientName + " {").ind(1) ts.l("export class " + clientName + " {").ind(1)
if moduleKind == config.ModuleKindCommonJS { if moduleKind == config.ModuleKindCommonJS {
if skipGoTSRPC { if skipGoTSRPC {
ts.l("constructor(public endPoint:string = \"" + endpoint + "\", public transport:(endPoint:string, method:string, args:any[], success:any, err:any) => void) { }") ts.l("constructor(public endPoint:string = \"" + service.Endpoint + "\", public transport:(endPoint:string, method:string, args:any[], success:any, err:any) => void) { }")
} else { } else {
ts.l("static defaultInst = new " + clientName + ";") ts.l("static defaultInst = new " + clientName + ";")
ts.l("constructor(public endPoint:string = \"" + endpoint + "\", public transport = call) { }") ts.l("constructor(public endPoint:string = \"" + service.Endpoint + "\", public transport = call) { }")
} }
} else { } else {
ts.l("static defaultInst = new " + clientName + ";") ts.l("static defaultInst = new " + clientName + ";")
ts.l("constructor(public endPoint:string = \"" + endpoint + "\", public transport = GoTSRPC.call) { }") ts.l("constructor(public endPoint:string = \"" + service.Endpoint + "\", public transport = GoTSRPC.call) { }")
} }
for _, method := range service.Methods { for _, method := range service.Methods {
@ -285,7 +285,7 @@ func ucFirst(str string) string {
return constPrefix return constPrefix
} }
func RenderTypeScriptServices(moduleKind config.ModuleKind, services map[string]*Service, mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, target *config.Target) (typeScript string, err error) { func RenderTypeScriptServices(moduleKind config.ModuleKind, services ServiceList, mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, target *config.Target) (typeScript string, err error) {
ts := newCode(" ") ts := newCode(" ")
if !SkipGoTSRPC { if !SkipGoTSRPC {
@ -327,13 +327,13 @@ func RenderTypeScriptServices(moduleKind config.ModuleKind, services map[string]
ts.ind(1) ts.ind(1)
} }
for endPoint, service := range services { for _, service := range services {
// Check if we should render this service as ts rcp // Check if we should render this service as ts rcp
// Note: remove once there's a separate gorcp generator // Note: remove once there's a separate gorcp generator
if !target.IsTSRPC(service.Name) { if !target.IsTSRPC(service.Name) {
continue continue
} }
err = renderService(SkipGoTSRPC, moduleKind, service, endPoint, mappings, scalarTypes, ts) err = renderService(SkipGoTSRPC, moduleKind, service, mappings, scalarTypes, ts)
if err != nil { if err != nil {
return return
} }