tempo.ts 0.7.0 → 0.7.2

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.
@@ -1,3 +1,4 @@
1
+ import { Elysia } from 'elysia'
1
2
  import express from 'express'
2
3
  import { Hono } from 'hono'
3
4
  import type { RpcRequest } from 'ox'
@@ -20,6 +21,210 @@ import { withFeePayer } from '../viem/Transport.js'
20
21
  import * as Handler from './Handler.js'
21
22
  import * as Kv from './Kv.js'
22
23
 
24
+ describe('compose', () => {
25
+ test('default', async () => {
26
+ const handler1 = Handler.from()
27
+ handler1.get('/test', () => new Response('test'))
28
+ const handler2 = Handler.from()
29
+ handler2.get('/test2', () => new Response('test2'))
30
+
31
+ const handler = Handler.compose([handler1, handler2])
32
+ expect(handler).toBeDefined()
33
+
34
+ {
35
+ const response = await handler.fetch(new Request('http://localhost/test'))
36
+ expect(response.status).toBe(200)
37
+ expect(await response.text()).toBe('test')
38
+ }
39
+
40
+ {
41
+ const response = await handler.fetch(
42
+ new Request('http://localhost/test2'),
43
+ )
44
+ expect(response.status).toBe(200)
45
+ expect(await response.text()).toBe('test2')
46
+ }
47
+ })
48
+
49
+ test('behavior: path', async () => {
50
+ const handler1 = Handler.from()
51
+ handler1.get('/test', () => new Response('test'))
52
+ const handler2 = Handler.from()
53
+ handler2.get('/test2', () => new Response('test2'))
54
+
55
+ const handler = Handler.compose([handler1, handler2], {
56
+ path: '/api',
57
+ })
58
+ expect(handler).toBeDefined()
59
+
60
+ {
61
+ const response = await handler.fetch(
62
+ new Request('http://localhost/api/test'),
63
+ )
64
+ expect(response.status).toBe(200)
65
+ expect(await response.text()).toBe('test')
66
+ }
67
+
68
+ {
69
+ const response = await handler.fetch(
70
+ new Request('http://localhost/api/test2'),
71
+ )
72
+ expect(response.status).toBe(200)
73
+ expect(await response.text()).toBe('test2')
74
+ }
75
+ })
76
+
77
+ describe('integration', () => {
78
+ const handler1 = Handler.from()
79
+ handler1.get('/foo', () => new Response('foo'))
80
+ handler1.post('/bar', () => new Response('bar'))
81
+
82
+ const handler2 = Handler.from()
83
+ handler2.get('/baz', () => new Response('baz'))
84
+ handler2.post('/qux', () => new Response('qux'))
85
+
86
+ const handler = Handler.compose([handler1, handler2], {
87
+ path: '/api',
88
+ })
89
+
90
+ test('hono', async () => {
91
+ const app = new Hono()
92
+ app.use((c) => handler.fetch(c.req.raw))
93
+
94
+ {
95
+ const response = await app.request('/api/foo')
96
+ expect(await response.text()).toBe('foo')
97
+ }
98
+
99
+ {
100
+ const response = await app.request('/api/bar', {
101
+ method: 'POST',
102
+ })
103
+ expect(await response.text()).toBe('bar')
104
+ }
105
+
106
+ {
107
+ const response = await app.request('/api/baz', {
108
+ method: 'GET',
109
+ })
110
+ expect(await response.text()).toBe('baz')
111
+ }
112
+
113
+ {
114
+ const response = await app.request('/api/qux', {
115
+ method: 'POST',
116
+ })
117
+ expect(await response.text()).toBe('qux')
118
+ }
119
+ })
120
+
121
+ test('elysia', async () => {
122
+ const app = new Elysia().all('*', ({ request }) => handler.fetch(request))
123
+
124
+ {
125
+ const response = await app.handle(
126
+ new Request('http://localhost/api/foo'),
127
+ )
128
+ expect(await response.text()).toBe('foo')
129
+ }
130
+
131
+ {
132
+ const response = await app.handle(
133
+ new Request('http://localhost/api/bar', {
134
+ method: 'POST',
135
+ }),
136
+ )
137
+ expect(await response.text()).toBe('bar')
138
+ }
139
+
140
+ {
141
+ const response = await app.handle(
142
+ new Request('http://localhost/api/baz', {
143
+ method: 'GET',
144
+ }),
145
+ )
146
+ expect(await response.text()).toBe('baz')
147
+ }
148
+
149
+ {
150
+ const response = await app.handle(
151
+ new Request('http://localhost/api/qux', {
152
+ method: 'POST',
153
+ }),
154
+ )
155
+ expect(await response.text()).toBe('qux')
156
+ }
157
+ })
158
+
159
+ test('node.js', async () => {
160
+ const server = await createServer(handler.listener)
161
+
162
+ {
163
+ const response = await fetch(`${server.url}/api/foo`)
164
+ expect(await response.text()).toBe('foo')
165
+ }
166
+
167
+ {
168
+ const response = await fetch(`${server.url}/api/bar`, {
169
+ method: 'POST',
170
+ })
171
+ expect(await response.text()).toBe('bar')
172
+ }
173
+
174
+ {
175
+ const response = await fetch(`${server.url}/api/baz`, {
176
+ method: 'GET',
177
+ })
178
+ expect(await response.text()).toBe('baz')
179
+ }
180
+
181
+ {
182
+ const response = await fetch(`${server.url}/api/qux`, {
183
+ method: 'POST',
184
+ })
185
+ expect(await response.text()).toBe('qux')
186
+ }
187
+
188
+ await server.closeAsync()
189
+ })
190
+
191
+ test('express', async () => {
192
+ const app = express()
193
+ app.use(handler.listener)
194
+
195
+ const server = await createServer(app)
196
+
197
+ {
198
+ const response = await fetch(`${server.url}/api/foo`)
199
+ expect(await response.text()).toBe('foo')
200
+ }
201
+
202
+ {
203
+ const response = await fetch(`${server.url}/api/bar`, {
204
+ method: 'POST',
205
+ })
206
+ expect(await response.text()).toBe('bar')
207
+ }
208
+
209
+ {
210
+ const response = await fetch(`${server.url}/api/baz`, {
211
+ method: 'GET',
212
+ })
213
+ expect(await response.text()).toBe('baz')
214
+ }
215
+
216
+ {
217
+ const response = await fetch(`${server.url}/api/qux`, {
218
+ method: 'POST',
219
+ })
220
+ expect(await response.text()).toBe('qux')
221
+ }
222
+
223
+ await server.closeAsync()
224
+ })
225
+ })
226
+ })
227
+
23
228
  describe('from', () => {
24
229
  test('default', () => {
25
230
  const handler = Handler.from()
@@ -73,6 +278,24 @@ describe('from', () => {
73
278
  }
74
279
  })
75
280
 
281
+ test('elysia', async () => {
282
+ const app = new Elysia().all('*', ({ request }) => handler.fetch(request))
283
+
284
+ {
285
+ const response = await app.handle(new Request('http://localhost/foo'))
286
+ expect(await response.text()).toBe('foo')
287
+ }
288
+
289
+ {
290
+ const response = await app.handle(
291
+ new Request('http://localhost/bar', {
292
+ method: 'POST',
293
+ }),
294
+ )
295
+ expect(await response.text()).toBe('bar')
296
+ }
297
+ })
298
+
76
299
  test('node.js', async () => {
77
300
  const server = await createServer(handler.listener)
78
301
 
@@ -1,4 +1,8 @@
1
- import { createRouter, type Router } from '@remix-run/fetch-router'
1
+ import {
2
+ createRouter,
3
+ type Router,
4
+ type RouterOptions,
5
+ } from '@remix-run/fetch-router'
2
6
  import { RpcRequest, RpcResponse } from 'ox'
3
7
  import * as Base64 from 'ox/Base64'
4
8
  import * as Hex from 'ox/Hex'
@@ -16,14 +20,44 @@ export type Handler = Router & {
16
20
  listener: (req: any, res: any) => void
17
21
  }
18
22
 
23
+ export function compose(
24
+ handlers: Handler[],
25
+ options: compose.Options = {},
26
+ ): Handler {
27
+ const path = options.path ?? '/'
28
+
29
+ return from({
30
+ async defaultHandler(context) {
31
+ const url = new URL(context.request.url)
32
+ if (!url.pathname.startsWith(path))
33
+ return new Response('Not Found', { status: 404 })
34
+
35
+ url.pathname = url.pathname.replace(path, '')
36
+ for (const handler of handlers) {
37
+ const request = new Request(url, context.request.clone())
38
+ const response = await handler.fetch(request)
39
+ if (response.status !== 404) return response
40
+ }
41
+ return new Response('Not Found', { status: 404 })
42
+ },
43
+ })
44
+ }
45
+
46
+ export declare namespace compose {
47
+ export type Options = {
48
+ /** The path to use for the handler. */
49
+ path?: string | undefined
50
+ }
51
+ }
52
+
19
53
  /**
20
54
  * Instantiates a new request handler.
21
55
  *
22
56
  * @param options - constructor options
23
57
  * @returns Handler instance
24
58
  */
25
- export function from(): Handler {
26
- const router = createRouter()
59
+ export function from(options: from.Options = {}): Handler {
60
+ const router = createRouter(options)
27
61
  return {
28
62
  ...router,
29
63
  listener: RequestListener.fromFetchHandler((request) => {
@@ -32,6 +66,10 @@ export function from(): Handler {
32
66
  }
33
67
  }
34
68
 
69
+ export declare namespace from {
70
+ export type Options = RouterOptions
71
+ }
72
+
35
73
  /**
36
74
  * Defines a Key Manager request handler.
37
75
  *