@vyckr/tachyon 0.3.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +3 -17
- package/README.md +87 -57
- package/bun.lock +127 -0
- package/components/counter.html +13 -0
- package/deno.lock +19 -0
- package/go.mod +3 -0
- package/lib/gson-2.3.jar +0 -0
- package/main.js +0 -0
- package/package.json +19 -20
- package/routes/DELETE +18 -0
- package/routes/GET +17 -0
- package/routes/HTML +28 -0
- package/routes/POST +32 -0
- package/routes/SOCKET +26 -0
- package/routes/api/:version/DELETE +10 -0
- package/routes/api/:version/GET +29 -0
- package/routes/api/:version/PATCH +24 -0
- package/routes/api/GET +29 -0
- package/routes/api/POST +16 -0
- package/routes/api/PUT +21 -0
- package/src/client/404.html +7 -0
- package/src/client/dev.html +14 -0
- package/src/client/dist.ts +20 -0
- package/src/client/hmr.js +12 -0
- package/src/client/prod.html +13 -0
- package/src/client/render.js +278 -0
- package/src/client/routes.json +1 -0
- package/src/client/yon.ts +341 -0
- package/src/router.ts +185 -0
- package/src/serve.ts +144 -0
- package/src/server/logger.ts +31 -0
- package/src/server/tach.ts +234 -0
- package/tests/index.test.ts +110 -0
- package/tests/stream.ts +24 -0
- package/tests/worker.ts +7 -0
- package/tsconfig.json +1 -1
- package/Dockerfile +0 -47
- package/bun.lockb +0 -0
- package/routes/byos/[primary]/doc/index.ts +0 -28
- package/routes/byos/[primary]/docs/index.ts +0 -28
- package/routes/byos/[primary]/join/[secondary]/docs/index.ts +0 -10
- package/routes/byos/[primary]/schema/index.ts +0 -17
- package/routes/byos/[primary]/stream/doc/index.ts +0 -28
- package/routes/byos/[primary]/stream/docs/index.ts +0 -28
- package/routes/proxy.ts +0 -8
- package/routes/utils/validation.ts +0 -36
- package/src/Tach.ts +0 -543
- package/src/Yon.ts +0 -25
- package/src/runtime.ts +0 -822
- package/types/index.d.ts +0 -13
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { Subprocess, ServerWebSocket, BunFile, BunRequest, Server } from "bun";
|
|
2
|
+
import Router, { _ctx } from "../router.js";
|
|
3
|
+
import { rm } from "fs/promises";
|
|
4
|
+
|
|
5
|
+
export default class Tach {
|
|
6
|
+
|
|
7
|
+
static webSockets = new Map<ServerWebSocket<any>, Subprocess<"pipe", "inherit", "pipe">>()
|
|
8
|
+
|
|
9
|
+
static headers = {
|
|
10
|
+
"Access-Control-Allow-Headers": process.env.ALLOW_HEADERS || "",
|
|
11
|
+
"Access-Control-Allow-Origin": process.env.ALLLOW_ORGINS || "",
|
|
12
|
+
"Access-Control-Allow-Credential": process.env.ALLOW_CREDENTIALS || "false",
|
|
13
|
+
"Access-Control-Expose-Headers": process.env.ALLOW_EXPOSE_HEADERS || "",
|
|
14
|
+
"Access-Control-Max-Age": process.env.ALLOW_MAX_AGE || "",
|
|
15
|
+
"Access-Control-Allow-Methods": process.env.ALLOW_METHODS || ""
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static parseRequest(request: Request) {
|
|
19
|
+
|
|
20
|
+
const req: Record<string, any> = {}
|
|
21
|
+
|
|
22
|
+
req.headers = Object.fromEntries(request.headers)
|
|
23
|
+
req.cache = request.cache
|
|
24
|
+
req.credentials = request.credentials
|
|
25
|
+
req.destination = request.destination
|
|
26
|
+
req.integrity = request.integrity
|
|
27
|
+
req.keepalive = request.keepalive
|
|
28
|
+
req.method = request.method
|
|
29
|
+
req.mode = request.mode
|
|
30
|
+
req.redirect = request.redirect
|
|
31
|
+
req.referrer = request.referrer
|
|
32
|
+
req.referrerPolicy = request.referrerPolicy
|
|
33
|
+
req.url = request.url
|
|
34
|
+
|
|
35
|
+
return req
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private static getParams(request: BunRequest, route: string) {
|
|
39
|
+
|
|
40
|
+
const url = new URL(request.url)
|
|
41
|
+
|
|
42
|
+
const params = url.pathname.slice(route.length).split('/')
|
|
43
|
+
|
|
44
|
+
return { params: Tach.parseParams(params) }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private static parseParams(input: string[]) {
|
|
48
|
+
|
|
49
|
+
const params: (string | boolean | number | null | undefined)[] = []
|
|
50
|
+
|
|
51
|
+
for(const param of input) {
|
|
52
|
+
|
|
53
|
+
const num = Number(param)
|
|
54
|
+
|
|
55
|
+
if(!Number.isNaN(num)) params.push(num)
|
|
56
|
+
|
|
57
|
+
else if(param === 'true') params.push(true)
|
|
58
|
+
|
|
59
|
+
else if(param === 'false') params.push(false)
|
|
60
|
+
|
|
61
|
+
else if(param === 'null') params.push(null)
|
|
62
|
+
|
|
63
|
+
else if(param === 'undefined') params.push(undefined)
|
|
64
|
+
|
|
65
|
+
else params.push(param)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return params
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private static parseKVParams(input: URLSearchParams | FormData) {
|
|
72
|
+
|
|
73
|
+
const params: Record<string, any> = {}
|
|
74
|
+
|
|
75
|
+
for(const [key, val] of input) {
|
|
76
|
+
|
|
77
|
+
if(typeof val === "string") {
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
|
|
81
|
+
params[key] = JSON.parse(val)
|
|
82
|
+
|
|
83
|
+
} catch {
|
|
84
|
+
|
|
85
|
+
const num = Number(val)
|
|
86
|
+
|
|
87
|
+
if(!Number.isNaN(num)) params[key] = num
|
|
88
|
+
|
|
89
|
+
else if(val === 'true') params[key] = true
|
|
90
|
+
|
|
91
|
+
else if(val === 'false') params[key] = false
|
|
92
|
+
|
|
93
|
+
else if(typeof val === "string" && val.includes(',')) params[key] = Tach.parseParams(val.split(','))
|
|
94
|
+
|
|
95
|
+
else if(val === 'null') params[key] = null
|
|
96
|
+
|
|
97
|
+
if(params[key] === undefined) params[key] = val
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
} else params[key] = val
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return params
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
static processRequest(request: BunRequest, route: string, ctx: _ctx) {
|
|
107
|
+
|
|
108
|
+
const { params } = Tach.getParams(request, route)
|
|
109
|
+
|
|
110
|
+
ctx.slugs = request.params
|
|
111
|
+
|
|
112
|
+
const searchParams = new URL(request.url).searchParams
|
|
113
|
+
|
|
114
|
+
let queryParams: Record<string, any> | undefined;
|
|
115
|
+
|
|
116
|
+
if(searchParams.size > 0) queryParams = Tach.parseKVParams(searchParams)
|
|
117
|
+
|
|
118
|
+
ctx.params = params
|
|
119
|
+
ctx.query = queryParams
|
|
120
|
+
|
|
121
|
+
return { ctx }
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private static async processResponse(cmd: string[], input: _ctx) {
|
|
125
|
+
|
|
126
|
+
const proc = Bun.spawn({
|
|
127
|
+
cmd,
|
|
128
|
+
stdout: 'inherit',
|
|
129
|
+
stderr: "pipe",
|
|
130
|
+
stdin: "pipe"
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
proc.stdin.write(JSON.stringify(input))
|
|
134
|
+
proc.stdin.end()
|
|
135
|
+
|
|
136
|
+
let exitCode = await proc.exited
|
|
137
|
+
|
|
138
|
+
if(exitCode !== 0 && proc.stderr.length > 0) {
|
|
139
|
+
exitCode = exitCode < 0 || (exitCode > 0 && exitCode < 100) || exitCode > 599 ? 500 : exitCode
|
|
140
|
+
return { status: exitCode, body: proc.stderr.toString() }
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
exitCode = exitCode === 0 ? 200 : exitCode
|
|
144
|
+
|
|
145
|
+
return { status: exitCode, body: Bun.file(`/tmp/${proc.pid}`) }
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
private static async serveRequest(handler: string, ctx: _ctx) {
|
|
149
|
+
|
|
150
|
+
const res = await Tach.processResponse([handler], ctx) as { status: number, body?: BunFile }
|
|
151
|
+
|
|
152
|
+
const size = res.body ? res.body.size : 0
|
|
153
|
+
|
|
154
|
+
const response = new Response(res.body, { status: res.status, headers: Tach.headers })
|
|
155
|
+
|
|
156
|
+
return { response, size }
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
static createServerRoutes() {
|
|
160
|
+
|
|
161
|
+
for(const [route, methods] of Router.allRoutes) {
|
|
162
|
+
|
|
163
|
+
const serverRoute = async (request?: BunRequest, server?: Server) => {
|
|
164
|
+
|
|
165
|
+
const start = Date.now()
|
|
166
|
+
|
|
167
|
+
let res: Response
|
|
168
|
+
let bodySize: number
|
|
169
|
+
const path = new URL(request!.url).pathname
|
|
170
|
+
const body = `/tmp/${Bun.randomUUIDv7()}`
|
|
171
|
+
|
|
172
|
+
try {
|
|
173
|
+
|
|
174
|
+
const accept = request!.headers.get('accept') || ''
|
|
175
|
+
|
|
176
|
+
if(accept.includes('text/html')) {
|
|
177
|
+
return new Response(await Bun.file(`${import.meta.dir}/../client/dev.html`).text(), { status: 200, headers: { 'Content-Type': 'text/html' } })
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
request!.blob().then(async blob => {
|
|
181
|
+
if(blob.size > 0) await Bun.write(body, blob)
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
const { handler, ctx } = Router.processRequest(request!, route, {
|
|
185
|
+
request: Router.parseRequest(request!),
|
|
186
|
+
ipAddress: server?.requestIP(request!) ? server.requestIP(request!)!.address : '0.0.0.0',
|
|
187
|
+
body
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
const { response, size } = await Tach.serveRequest(handler, ctx!)
|
|
191
|
+
|
|
192
|
+
res = response
|
|
193
|
+
bodySize = size
|
|
194
|
+
|
|
195
|
+
} catch(err) {
|
|
196
|
+
|
|
197
|
+
const error = err as Error
|
|
198
|
+
|
|
199
|
+
bodySize = error.message.length
|
|
200
|
+
|
|
201
|
+
res = Response.json({ error: error.message }, { status: error.cause as number, headers: Tach.headers })
|
|
202
|
+
|
|
203
|
+
} finally {
|
|
204
|
+
|
|
205
|
+
Bun.file(body).exists().then(async exists => {
|
|
206
|
+
if(exists) await rm(body, { recursive: true })
|
|
207
|
+
})
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const status = res.status
|
|
211
|
+
const method = request!.method
|
|
212
|
+
const duration = Date.now() - start
|
|
213
|
+
|
|
214
|
+
console.info(`${path} - ${method} - ${status} - ${duration}ms - ${bodySize} byte(s)`)
|
|
215
|
+
|
|
216
|
+
return res
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
for(const method of methods) {
|
|
220
|
+
|
|
221
|
+
if(method !== 'HTML' && method !== 'SOCKET') {
|
|
222
|
+
|
|
223
|
+
if(!Router.reqRoutes[route]) {
|
|
224
|
+
Router.reqRoutes[route] = {}
|
|
225
|
+
Router.reqRoutes[`${route}/*`] = {}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
Router.reqRoutes[route][method] = serverRoute
|
|
229
|
+
Router.reqRoutes[`${route}/*`][method] = serverRoute
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { test, beforeAll, expect, describe } from 'bun:test'
|
|
2
|
+
|
|
3
|
+
beforeAll(async () => {
|
|
4
|
+
new Worker('./tests/worker.ts').postMessage(`./src/serve.ts`)
|
|
5
|
+
await Bun.sleep(1000)
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
describe('/', () => {
|
|
9
|
+
|
|
10
|
+
test('GET', async () => {
|
|
11
|
+
|
|
12
|
+
const res = await fetch('http://localhost:8080')
|
|
13
|
+
|
|
14
|
+
console.log(await res.json())
|
|
15
|
+
|
|
16
|
+
expect(res.status).toEqual(200)
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
test('POST', async () => {
|
|
20
|
+
|
|
21
|
+
const res = await fetch('http://localhost:8080', {
|
|
22
|
+
method: 'POST'
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
console.log(await res.json())
|
|
26
|
+
|
|
27
|
+
expect(res.status).toEqual(200)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
test('DELETE', async () => {
|
|
31
|
+
|
|
32
|
+
const res = await fetch('http://localhost:8080', {
|
|
33
|
+
method: 'DELETE'
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
console.log(await res.json())
|
|
37
|
+
|
|
38
|
+
expect(res.status).toEqual(200)
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
describe('/api', () => {
|
|
44
|
+
|
|
45
|
+
test('GET', async () => {
|
|
46
|
+
|
|
47
|
+
const res = await fetch('http://localhost:8080/api')
|
|
48
|
+
|
|
49
|
+
console.log(await res.json())
|
|
50
|
+
|
|
51
|
+
expect(res.status).toEqual(200)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test('POST', async () => {
|
|
55
|
+
|
|
56
|
+
const res = await fetch('http://localhost:8080/api', {
|
|
57
|
+
method: 'POST'
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
console.log(await res.json())
|
|
61
|
+
|
|
62
|
+
expect(res.status).toEqual(200)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test('PUT', async () => {
|
|
66
|
+
|
|
67
|
+
const res = await fetch('http://localhost:8080/api', {
|
|
68
|
+
method: 'PUT'
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
console.log(await res.json())
|
|
72
|
+
|
|
73
|
+
expect(res.status).toEqual(200)
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
describe('/api/v2', () => {
|
|
79
|
+
|
|
80
|
+
test('GET', async () => {
|
|
81
|
+
|
|
82
|
+
const res = await fetch('http://localhost:8080/api/v2')
|
|
83
|
+
|
|
84
|
+
console.log(await res.json())
|
|
85
|
+
|
|
86
|
+
expect(res.status).toEqual(200)
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
test('DELETE', async () => {
|
|
90
|
+
|
|
91
|
+
const res = await fetch('http://localhost:8080/api/v2', {
|
|
92
|
+
method: 'DELETE'
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
console.log(await res.json())
|
|
96
|
+
|
|
97
|
+
expect(res.status).toEqual(200)
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
test('PATCH', async () => {
|
|
101
|
+
|
|
102
|
+
const res = await fetch('http://localhost:8080/api/v2/users', {
|
|
103
|
+
method: 'PATCH'
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
console.log(await res.json())
|
|
107
|
+
|
|
108
|
+
expect(res.status).toEqual(200)
|
|
109
|
+
})
|
|
110
|
+
})
|
package/tests/stream.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
new Worker('./tests/worker.ts').postMessage(`./src/serve.ts`)
|
|
2
|
+
|
|
3
|
+
await Bun.sleep(1000)
|
|
4
|
+
|
|
5
|
+
const res = await fetch(`http://localhost:8080/`, {
|
|
6
|
+
headers: {
|
|
7
|
+
'Accept': 'text/html'
|
|
8
|
+
}
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
for await (const chunk of res.body!) {
|
|
12
|
+
|
|
13
|
+
console.log(new TextDecoder().decode(chunk))
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// const ws = new WebSocket(`ws://localhost:8080`)
|
|
17
|
+
|
|
18
|
+
// ws.onopen = (ev) => {
|
|
19
|
+
// ws.send("Ping")
|
|
20
|
+
// }
|
|
21
|
+
|
|
22
|
+
// ws.onmessage = (ev) => {
|
|
23
|
+
// console.log(JSON.parse(ev.data))
|
|
24
|
+
// }
|
package/tests/worker.ts
ADDED
package/tsconfig.json
CHANGED
package/Dockerfile
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
FROM oven/bun:latest AS build
|
|
2
|
-
|
|
3
|
-
RUN apt-get update && apt-get install -y unzip git
|
|
4
|
-
|
|
5
|
-
WORKDIR /app
|
|
6
|
-
|
|
7
|
-
RUN git clone https://github.com/oven-sh/bun.git
|
|
8
|
-
|
|
9
|
-
WORKDIR /app/bun/packages/bun-lambda
|
|
10
|
-
|
|
11
|
-
RUN bun install
|
|
12
|
-
|
|
13
|
-
RUN bun run build-layer
|
|
14
|
-
|
|
15
|
-
RUN unzip bun-lambda-layer.zip -d /tmp
|
|
16
|
-
|
|
17
|
-
WORKDIR /tmp
|
|
18
|
-
|
|
19
|
-
COPY package.json .
|
|
20
|
-
|
|
21
|
-
RUN bun install
|
|
22
|
-
|
|
23
|
-
FROM public.ecr.aws/lambda/provided:al2
|
|
24
|
-
|
|
25
|
-
COPY --from=build /tmp/node_modules ${LAMBDA_TASK_ROOT}/node_modules
|
|
26
|
-
|
|
27
|
-
COPY --from=build /tmp/package.json ${LAMBDA_TASK_ROOT}/package.json
|
|
28
|
-
|
|
29
|
-
COPY --from=build /tmp/bootstrap ${LAMBDA_RUNTIME_DIR}
|
|
30
|
-
|
|
31
|
-
COPY --from=build /tmp/bun /opt
|
|
32
|
-
|
|
33
|
-
COPY ./src/Tach.ts ${LAMBDA_TASK_ROOT}
|
|
34
|
-
|
|
35
|
-
COPY ./tsconfig.json ${LAMBDA_TASK_ROOT}
|
|
36
|
-
|
|
37
|
-
COPY ./src/runtime.ts /opt
|
|
38
|
-
|
|
39
|
-
RUN chmod 777 /opt/bun
|
|
40
|
-
|
|
41
|
-
RUN chmod 777 /opt/runtime.ts
|
|
42
|
-
|
|
43
|
-
RUN chmod 777 ${LAMBDA_TASK_ROOT}/Tach.ts
|
|
44
|
-
|
|
45
|
-
RUN chmod 777 ${LAMBDA_RUNTIME_DIR}/bootstrap
|
|
46
|
-
|
|
47
|
-
CMD ["Tach.fetch"]
|
package/bun.lockb
DELETED
|
Binary file
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { VALIDATE } from "../../../utils/validation.js";
|
|
2
|
-
|
|
3
|
-
export default class Doc {
|
|
4
|
-
|
|
5
|
-
@VALIDATE([{ type: "object" }])
|
|
6
|
-
static async GET({ request }: _HTTPContext) {
|
|
7
|
-
|
|
8
|
-
console.log(request.url)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
@VALIDATE([{ type: "object" }, { type: "object" }])
|
|
12
|
-
static async POST({ request }: _HTTPContext) {
|
|
13
|
-
|
|
14
|
-
console.log(request.url)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
@VALIDATE([{ type: "object" }, { type: "object" }])
|
|
18
|
-
static async PATCH({ request }: _HTTPContext) {
|
|
19
|
-
|
|
20
|
-
console.log(request.url)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
@VALIDATE([{ type: "string" }, { type: "object" }])
|
|
24
|
-
static async DELETE({ request }: _HTTPContext) {
|
|
25
|
-
|
|
26
|
-
console.log(request.url)
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { VALIDATE } from "../../../utils/validation.js";
|
|
2
|
-
|
|
3
|
-
export default class Docs {
|
|
4
|
-
|
|
5
|
-
@VALIDATE([{ type: "object" }])
|
|
6
|
-
static async GET({ request }: _HTTPContext) {
|
|
7
|
-
|
|
8
|
-
console.log(request.url)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
@VALIDATE([{ type: "object" }])
|
|
12
|
-
static async POST({ request }: _HTTPContext) {
|
|
13
|
-
|
|
14
|
-
console.log(request.url)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
@VALIDATE([{ type: "object" }])
|
|
18
|
-
static async PATCH({ request }: _HTTPContext) {
|
|
19
|
-
|
|
20
|
-
console.log(request.url)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
@VALIDATE([{ type: "object" }])
|
|
24
|
-
static async DELETE({ request }: _HTTPContext) {
|
|
25
|
-
|
|
26
|
-
console.log(request.url)
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export default class Schema {
|
|
2
|
-
|
|
3
|
-
static async POST({ request }: _HTTPContext) {
|
|
4
|
-
|
|
5
|
-
console.log(request.url)
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
static async PATCH({ request }: _HTTPContext) {
|
|
9
|
-
|
|
10
|
-
console.log(request.url)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
static DELETE({ request }: _HTTPContext) {
|
|
14
|
-
|
|
15
|
-
console.log(request.url)
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { VALIDATE } from "../../../../utils/validation.js";
|
|
2
|
-
|
|
3
|
-
export default class {
|
|
4
|
-
|
|
5
|
-
@VALIDATE([{ type: "object" }])
|
|
6
|
-
static GET({ request }: _HTTPContext) {
|
|
7
|
-
|
|
8
|
-
return {
|
|
9
|
-
|
|
10
|
-
async *[Symbol.asyncIterator]() {
|
|
11
|
-
|
|
12
|
-
yield request.url
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
@VALIDATE([{ type: "object" }])
|
|
18
|
-
static DELETE({ request }: _HTTPContext) {
|
|
19
|
-
|
|
20
|
-
return {
|
|
21
|
-
|
|
22
|
-
async *[Symbol.asyncIterator]() {
|
|
23
|
-
|
|
24
|
-
yield request.url
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { VALIDATE } from "../../../../utils/validation.js";
|
|
2
|
-
|
|
3
|
-
export default class {
|
|
4
|
-
|
|
5
|
-
@VALIDATE([{ type: "object" }])
|
|
6
|
-
static GET({ request }: _HTTPContext) {
|
|
7
|
-
|
|
8
|
-
return {
|
|
9
|
-
|
|
10
|
-
async *[Symbol.asyncIterator]() {
|
|
11
|
-
|
|
12
|
-
yield request.url
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
@VALIDATE([{ type: "object", default: {} }, { type: "object" }])
|
|
18
|
-
static DELETE({ request }: _HTTPContext) {
|
|
19
|
-
|
|
20
|
-
return {
|
|
21
|
-
|
|
22
|
-
async *[Symbol.asyncIterator]() {
|
|
23
|
-
|
|
24
|
-
yield request.url
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
package/routes/proxy.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
export const VALIDATE = (input: any[]) => (cls: Object, funcName: string, propDesc: PropertyDescriptor) => {
|
|
2
|
-
|
|
3
|
-
const originalFunc: Function = propDesc.value
|
|
4
|
-
|
|
5
|
-
propDesc.value = async function(...args: any[]) {
|
|
6
|
-
|
|
7
|
-
const params = [...input]
|
|
8
|
-
|
|
9
|
-
if(params.length !== args.length) {
|
|
10
|
-
|
|
11
|
-
do {
|
|
12
|
-
|
|
13
|
-
const idx = params.findLastIndex(x => x.default !== undefined)
|
|
14
|
-
|
|
15
|
-
if(idx === -1) break
|
|
16
|
-
|
|
17
|
-
const [ param ] = params.splice(idx, 1)
|
|
18
|
-
|
|
19
|
-
args.unshift(param.default)
|
|
20
|
-
|
|
21
|
-
} while(true)
|
|
22
|
-
|
|
23
|
-
if(input.length !== args.length) throw new Error(`Invalid number of arguments for ${funcName}`)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
for(let i = 0; i < input.length; i++) {
|
|
27
|
-
|
|
28
|
-
if(typeof args[i] !== input[i].type) {
|
|
29
|
-
|
|
30
|
-
throw new Error(`Invalid argument type for ${funcName}`)
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return originalFunc.apply(this, args)
|
|
35
|
-
}
|
|
36
|
-
}
|