-
Notifications
You must be signed in to change notification settings - Fork 9
/
server.go.tmpl
112 lines (83 loc) · 3.67 KB
/
server.go.tmpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
{{define "server"}}
{{- $services := .Services -}}
{{- $typeMap := .TypeMap -}}
{{- if $services}}
//
// Server
//
export class WebRPCError extends Error {
statusCode?: number
constructor(msg: string = "error", statusCode?: number) {
super("webrpc error: " + msg);
Object.setPrototypeOf(this, WebRPCError.prototype);
this.statusCode = statusCode;
}
}
import express from 'express'
{{- range $_, $service := $services }}
export type {{$service.Name}}Service = {
{{range $_, $method := $service.Methods}}
{{$method.Name}}: (args: {{$method.Name}}Args) => {{$method.Name}}Return | Promise<{{$method.Name}}Return>
{{end}}
}
export const create{{$service.Name}}App = (serviceImplementation: {{$service.Name}}Service) => {
const app = express();
app.use(express.json())
app.post('/*', async (req, res) => {
const requestPath = req.baseUrl + req.path
res.header(WebrpcHeader, WebrpcHeaderValue);
if (!req.body) {
res.status(400).send("webrpc error: missing body");
return
}
switch(requestPath) {
{{range $_, $method := $service.Methods}}
case "/rpc/{{$service.Name}}/{{$method.Name}}": {
try {
{{ range $_, $input := $method.Inputs }}
{{- if not $input.Optional}}
if (!("{{ $input.Name }}" in req.body)) {
throw new WebRPCError("Missing Argument `{{ $input.Name }}`")
}
{{end -}}
if ("{{ $input.Name }}" in req.body && !validateType(req.body["{{ $input.Name }}"], "{{template "jsType" dict "Type" $input.Type "TypeMap" $typeMap}}")) {
throw new WebRPCError("Invalid Argument: {{ $input.Name }}")
}
{{end}}
const response = await serviceImplementation["{{$method.Name}}"](req.body);
{{ range $_, $output := $method.Outputs}}
if (!("{{ $output.Name }}" in response)) {
throw new WebRPCError("internal", 500);
}
{{end}}
res.status(200).json(response);
} catch (err) {
if (err instanceof WebRPCError) {
const statusCode = err.statusCode || 400
const message = err.message
res.status(statusCode).json({
msg: message,
status: statusCode,
code: ""
});
return
}
if (err.message) {
res.status(400).send(err.message);
return;
}
res.status(400).end();
}
}
return;
{{end}}
default: {
res.status(404).end()
}
}
});
return app;
};
{{- end}}
{{end -}}
{{end}}