hono 0.0.11 → 0.0.15
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/README.md +190 -56
- package/dist/context.d.ts +23 -0
- package/dist/context.js +65 -0
- package/dist/hono.d.ts +13 -16
- package/dist/hono.js +20 -26
- package/dist/index.d.ts +5 -1
- package/dist/index.js +4 -2
- package/dist/middleware/basic-auth/basic-auth.d.ts +6 -0
- package/dist/middleware/basic-auth/basic-auth.js +50 -0
- package/dist/middleware/body-parse/body-parse.d.ts +2 -0
- package/dist/middleware/body-parse/body-parse.js +27 -0
- package/dist/middleware/default.d.ts +2 -0
- package/dist/middleware/default.js +16 -0
- package/dist/middleware/logger/logger.d.ts +2 -1
- package/dist/middleware/logger/logger.js +3 -1
- package/dist/middleware/{poweredBy/poweredBy.d.ts → powered-by/powered-by.d.ts} +1 -1
- package/dist/middleware/{poweredBy/poweredBy.js → powered-by/powered-by.js} +0 -0
- package/dist/middleware.d.ts +10 -3
- package/dist/middleware.js +8 -4
- package/dist/node.js +5 -2
- package/dist/util.d.ts +2 -0
- package/dist/util.js +38 -2
- package/package.json +20 -4
- package/dist/methods.d.ts +0 -1
- package/dist/methods.js +0 -31
- package/dist/middleware/defaultFilter.d.ts +0 -2
- package/dist/middleware/defaultFilter.js +0 -11
package/README.md
CHANGED
|
@@ -1,56 +1,66 @@
|
|
|
1
1
|
# Hono
|
|
2
2
|
|
|
3
|
-
Hono
|
|
3
|
+
Hono[炎] - _**means flame🔥 in Japanese**_ - is small, simple, and ultrafast web flamework for a Service Workers API based serverless such as Cloudflare Workers and Fastly Compute@Edge.
|
|
4
4
|
|
|
5
5
|
```js
|
|
6
|
-
|
|
6
|
+
import { Hono } from 'hono'
|
|
7
7
|
const app = new Hono()
|
|
8
8
|
|
|
9
|
-
app.get('/', () =>
|
|
9
|
+
app.get('/', (c) => c.text('Hono!!'))
|
|
10
10
|
|
|
11
11
|
app.fire()
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
## Features
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
- Flexible - you can make your own middlewares.
|
|
21
|
-
- Easy - simple API, builtin middleware, and TypeScript support.
|
|
22
|
-
- Optimized - for Cloudflare Workers or Fastly Compute@Edge.
|
|
16
|
+
- **Ultra fast** - the router is implemented with Trie-Tree structure.
|
|
17
|
+
- **Zero dependencies** - using only Web standard API.
|
|
18
|
+
- **Middleware** - builtin middleware, and you can make your own middleware.
|
|
19
|
+
- **Optimized** - for Cloudflare Workers.
|
|
23
20
|
|
|
24
21
|
## Benchmark
|
|
25
22
|
|
|
26
|
-
Hono is fastest
|
|
23
|
+
**Hono is fastest** compared to other routers for Cloudflare Workers.
|
|
27
24
|
|
|
28
|
-
```
|
|
29
|
-
hono x
|
|
30
|
-
itty-router x 158,
|
|
31
|
-
sunder x
|
|
25
|
+
```plain
|
|
26
|
+
hono x 748,188 ops/sec ±5.40% (77 runs sampled)
|
|
27
|
+
itty-router x 158,817 ops/sec ±3.62% (87 runs sampled)
|
|
28
|
+
sunder x 332,339 ops/sec ±1.11% (95 runs sampled)
|
|
29
|
+
worktop x 205,906 ops/sec ±4.43% (83 runs sampled)
|
|
32
30
|
Fastest is hono
|
|
33
|
-
✨ Done in
|
|
31
|
+
✨ Done in 52.79s.
|
|
34
32
|
```
|
|
35
33
|
|
|
34
|
+
## Hono in 1 minute
|
|
35
|
+
|
|
36
|
+
Below is a demonstration to create an application of Cloudflare Workers with Hono.
|
|
37
|
+
|
|
38
|
+

|
|
39
|
+
|
|
36
40
|
## Install
|
|
37
41
|
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
You can install from npm registry:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
yarn add hono
|
|
40
46
|
```
|
|
41
47
|
|
|
42
48
|
or
|
|
43
49
|
|
|
44
50
|
```sh
|
|
45
|
-
|
|
51
|
+
npm install hono
|
|
46
52
|
```
|
|
47
53
|
|
|
48
54
|
## Methods
|
|
49
55
|
|
|
56
|
+
Instance of `Hono` has these methods:
|
|
57
|
+
|
|
50
58
|
- app.**HTTP_METHOD**(path, handler)
|
|
51
59
|
- app.**all**(path, handler)
|
|
52
60
|
- app.**route**(path)
|
|
53
61
|
- app.**use**(path, middleware)
|
|
62
|
+
- app.**fire**()
|
|
63
|
+
- app.**fetch**(request, env, event)
|
|
54
64
|
|
|
55
65
|
## Routing
|
|
56
66
|
|
|
@@ -60,12 +70,12 @@ $ npm install hono
|
|
|
60
70
|
|
|
61
71
|
```js
|
|
62
72
|
// HTTP Methods
|
|
63
|
-
app.get('/', () =>
|
|
64
|
-
app.post('/', () =>
|
|
73
|
+
app.get('/', (c) => c.text('GET /'))
|
|
74
|
+
app.post('/', (c) => c.text('POST /'))
|
|
65
75
|
|
|
66
76
|
// Wildcard
|
|
67
|
-
app.get('/wild/*/card', () => {
|
|
68
|
-
return
|
|
77
|
+
app.get('/wild/*/card', (c) => {
|
|
78
|
+
return c.text('GET /wild/*/card')
|
|
69
79
|
})
|
|
70
80
|
```
|
|
71
81
|
|
|
@@ -73,7 +83,7 @@ app.get('/wild/*/card', () => {
|
|
|
73
83
|
|
|
74
84
|
```js
|
|
75
85
|
// Any HTTP methods
|
|
76
|
-
app.all('/hello', () =>
|
|
86
|
+
app.all('/hello', (c) => c.text('Any Method /hello'))
|
|
77
87
|
```
|
|
78
88
|
|
|
79
89
|
### Named Parameter
|
|
@@ -104,12 +114,12 @@ app
|
|
|
104
114
|
.put(() => {...})
|
|
105
115
|
```
|
|
106
116
|
|
|
107
|
-
##
|
|
117
|
+
## async/await
|
|
108
118
|
|
|
109
119
|
```js
|
|
110
|
-
app.get('/fetch-url', async () => {
|
|
120
|
+
app.get('/fetch-url', async (c) => {
|
|
111
121
|
const response = await fetch('https://example.com/')
|
|
112
|
-
return
|
|
122
|
+
return c.text(`Status is ${response.status}`)
|
|
113
123
|
})
|
|
114
124
|
```
|
|
115
125
|
|
|
@@ -118,17 +128,27 @@ app.get('/fetch-url', async () => {
|
|
|
118
128
|
### Builtin Middleware
|
|
119
129
|
|
|
120
130
|
```js
|
|
121
|
-
|
|
131
|
+
import { Hono, Middleware } from 'hono'
|
|
122
132
|
|
|
123
133
|
...
|
|
124
134
|
|
|
125
135
|
app.use('*', Middleware.poweredBy())
|
|
126
136
|
app.use('*', Middleware.logger())
|
|
127
|
-
|
|
137
|
+
app.use(
|
|
138
|
+
'/auth/*',
|
|
139
|
+
Middleware.basicAuth({
|
|
140
|
+
username: 'hono',
|
|
141
|
+
password: 'acoolproject',
|
|
142
|
+
})
|
|
143
|
+
)
|
|
128
144
|
```
|
|
129
145
|
|
|
146
|
+
Available builtin middleware are listed on [src/middleware](https://github.com/yusukebe/hono/tree/master/src/middleware).
|
|
147
|
+
|
|
130
148
|
### Custom Middleware
|
|
131
149
|
|
|
150
|
+
You can write your own middleware:
|
|
151
|
+
|
|
132
152
|
```js
|
|
133
153
|
// Custom logger
|
|
134
154
|
app.use('*', async (c, next) => {
|
|
@@ -136,17 +156,19 @@ app.use('*', async (c, next) => {
|
|
|
136
156
|
await next()
|
|
137
157
|
})
|
|
138
158
|
|
|
139
|
-
// Add custom header
|
|
159
|
+
// Add a custom header
|
|
140
160
|
app.use('/message/*', async (c, next) => {
|
|
141
161
|
await next()
|
|
142
162
|
await c.res.headers.add('x-message', 'This is middleware!')
|
|
143
163
|
})
|
|
144
164
|
|
|
145
|
-
app.get('/message/hello', () => 'Hello Middleware!')
|
|
165
|
+
app.get('/message/hello', (c) => c.text('Hello Middleware!'))
|
|
146
166
|
```
|
|
147
167
|
|
|
148
168
|
### Custom 404 Response
|
|
149
169
|
|
|
170
|
+
You can customize 404 Not Found response:
|
|
171
|
+
|
|
150
172
|
```js
|
|
151
173
|
app.use('*', async (c, next) => {
|
|
152
174
|
await next()
|
|
@@ -156,8 +178,23 @@ app.use('*', async (c, next) => {
|
|
|
156
178
|
})
|
|
157
179
|
```
|
|
158
180
|
|
|
181
|
+
### Handling Error
|
|
182
|
+
|
|
183
|
+
```js
|
|
184
|
+
app.use('*', async (c, next) => {
|
|
185
|
+
try {
|
|
186
|
+
await next()
|
|
187
|
+
} catch (err) {
|
|
188
|
+
console.error(`${err}`)
|
|
189
|
+
c.res = new Response('Custom Error Message', { status: 500 })
|
|
190
|
+
}
|
|
191
|
+
})
|
|
192
|
+
```
|
|
193
|
+
|
|
159
194
|
### Complex Pattern
|
|
160
195
|
|
|
196
|
+
You can also do this:
|
|
197
|
+
|
|
161
198
|
```js
|
|
162
199
|
// Output response time
|
|
163
200
|
app.use('*', async (c, next) => {
|
|
@@ -177,7 +214,9 @@ app.use('*', async (c, next) => {
|
|
|
177
214
|
|
|
178
215
|
## Context
|
|
179
216
|
|
|
180
|
-
|
|
217
|
+
To handle Request and Reponse easily, you can use Context object:
|
|
218
|
+
|
|
219
|
+
### c.req
|
|
181
220
|
|
|
182
221
|
```js
|
|
183
222
|
|
|
@@ -200,7 +239,7 @@ app.get('/entry/:id', (c) => {
|
|
|
200
239
|
})
|
|
201
240
|
```
|
|
202
241
|
|
|
203
|
-
### res
|
|
242
|
+
### c.res
|
|
204
243
|
|
|
205
244
|
```js
|
|
206
245
|
// Response object
|
|
@@ -210,7 +249,31 @@ app.use('/', (c, next) => {
|
|
|
210
249
|
})
|
|
211
250
|
```
|
|
212
251
|
|
|
213
|
-
###
|
|
252
|
+
### c.event
|
|
253
|
+
|
|
254
|
+
```js
|
|
255
|
+
// FetchEvent object
|
|
256
|
+
app.use('*', async (c, next) => {
|
|
257
|
+
c.event.waitUntil(
|
|
258
|
+
...
|
|
259
|
+
)
|
|
260
|
+
await next()
|
|
261
|
+
})
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### c.env
|
|
265
|
+
|
|
266
|
+
```js
|
|
267
|
+
// Environment object for Cloudflare Workers
|
|
268
|
+
app.get('*', async c => {
|
|
269
|
+
const counter = c.env.COUNTER
|
|
270
|
+
...
|
|
271
|
+
})
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### c.text()
|
|
275
|
+
|
|
276
|
+
Render text as `Content-Type:text/plain`:
|
|
214
277
|
|
|
215
278
|
```js
|
|
216
279
|
app.get('/say', (c) => {
|
|
@@ -218,20 +281,69 @@ app.get('/say', (c) => {
|
|
|
218
281
|
})
|
|
219
282
|
```
|
|
220
283
|
|
|
221
|
-
|
|
284
|
+
### c.json()
|
|
222
285
|
|
|
223
|
-
|
|
286
|
+
Render JSON as `Content-Type:application/json`:
|
|
224
287
|
|
|
225
|
-
|
|
288
|
+
```js
|
|
289
|
+
app.get('/api', (c) => {
|
|
290
|
+
return c.json({ message: 'Hello!' })
|
|
291
|
+
})
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### c.html()
|
|
295
|
+
|
|
296
|
+
Render HTML as `Content-Type:text/html`:
|
|
297
|
+
|
|
298
|
+
```js
|
|
299
|
+
app.get('/', (c) => {
|
|
300
|
+
return c.html('<h1>Hello! Hono!</h1>')
|
|
301
|
+
})
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### c.redirect()
|
|
305
|
+
|
|
306
|
+
Redirect, default status code is `302`:
|
|
307
|
+
|
|
308
|
+
```js
|
|
309
|
+
app.get('/redirect', (c) => c.redirect('/'))
|
|
310
|
+
app.get('/redirect-permanently', (c) => c.redirect('/', 301))
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## fire
|
|
314
|
+
|
|
315
|
+
`app.fire()` do:
|
|
316
|
+
|
|
317
|
+
```js
|
|
318
|
+
addEventListener('fetch', (event) => {
|
|
319
|
+
event.respondWith(this.handleEvent(event))
|
|
320
|
+
})
|
|
321
|
+
```
|
|
226
322
|
|
|
227
|
-
|
|
323
|
+
## fetch
|
|
324
|
+
|
|
325
|
+
`app.fetch()` is for Cloudflare Module Worker syntax.
|
|
326
|
+
|
|
327
|
+
```js
|
|
328
|
+
export default {
|
|
329
|
+
fetch(request: Request, env: Env, event: FetchEvent) {
|
|
330
|
+
return app.fetch(request, env, event)
|
|
331
|
+
},
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## Cloudflare Workers with Hono
|
|
336
|
+
|
|
337
|
+
Using `wrangler` or `miniflare`, you can develop the application locally and publish it with few commands.
|
|
338
|
+
|
|
339
|
+
Let's write your first code for Cloudflare Workers with Hono.
|
|
228
340
|
|
|
229
341
|
### 1. Install Wrangler
|
|
230
342
|
|
|
231
343
|
Install Cloudflare Command Line "[Wrangler](https://github.com/cloudflare/wrangler)"
|
|
232
344
|
|
|
233
345
|
```sh
|
|
234
|
-
|
|
346
|
+
npm i @cloudflare/wrangler -g
|
|
235
347
|
```
|
|
236
348
|
|
|
237
349
|
### 2. `npm init`
|
|
@@ -239,9 +351,9 @@ $ npm i @cloudflare/wrangler -g
|
|
|
239
351
|
Make npm skeleton directory.
|
|
240
352
|
|
|
241
353
|
```sh
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
354
|
+
mkdir hono-example
|
|
355
|
+
cd hono-example
|
|
356
|
+
npm init -y
|
|
245
357
|
```
|
|
246
358
|
|
|
247
359
|
### 3. `wrangler init`
|
|
@@ -249,46 +361,68 @@ $ npm init -y
|
|
|
249
361
|
Init as a wrangler project.
|
|
250
362
|
|
|
251
363
|
```sh
|
|
252
|
-
|
|
364
|
+
wrangler init
|
|
253
365
|
```
|
|
254
366
|
|
|
255
367
|
### 4. `npm install hono`
|
|
256
368
|
|
|
257
|
-
Install `hono` from npm
|
|
369
|
+
Install `hono` from npm registry.
|
|
258
370
|
|
|
259
|
-
```
|
|
260
|
-
|
|
371
|
+
```sh
|
|
372
|
+
npm i hono
|
|
261
373
|
```
|
|
262
374
|
|
|
263
375
|
### 5. Write your app
|
|
264
376
|
|
|
265
|
-
Only 4
|
|
377
|
+
Only 4 lines!!
|
|
266
378
|
|
|
267
379
|
```js
|
|
268
|
-
|
|
380
|
+
import { Hono } from 'hono'
|
|
269
381
|
const app = new Hono()
|
|
270
382
|
|
|
271
|
-
app.get('/', () =>
|
|
383
|
+
app.get('/', (c) => c.text('Hello! Hono!'))
|
|
272
384
|
|
|
273
385
|
app.fire()
|
|
274
386
|
```
|
|
275
387
|
|
|
276
|
-
### 6. Run
|
|
388
|
+
### 6. Run
|
|
277
389
|
|
|
278
|
-
Run the development server locally.
|
|
390
|
+
Run the development server locally. Then, access like `http://127.0.0.1:8787/` in your Web browser.
|
|
279
391
|
|
|
280
392
|
```sh
|
|
281
|
-
|
|
393
|
+
wrangler dev
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Publish
|
|
397
|
+
|
|
398
|
+
Deploy to Cloudflare. That's all!
|
|
399
|
+
|
|
400
|
+
```sh
|
|
401
|
+
wrangler publish
|
|
282
402
|
```
|
|
283
403
|
|
|
284
404
|
## Related projects
|
|
285
405
|
|
|
286
|
-
-
|
|
406
|
+
Implementation of the router is inspired by [goblin](https://github.com/bmf-san/goblin). API design is inspired by [express](https://github.com/expressjs/express) and [koa](https://github.com/koajs/koa). [itty-router](https://github.com/kwhitley/itty-router), [Sunder](https://github.com/SunderJS/sunder), and [worktop](https://github.com/lukeed/worktop) are the other routers or frameworks for Cloudflare Workers.
|
|
407
|
+
|
|
287
408
|
- express <https://github.com/expressjs/express>
|
|
288
|
-
-
|
|
409
|
+
- koa <https://github.com/koajs/koa>
|
|
289
410
|
- itty-router <https://github.com/kwhitley/itty-router>
|
|
290
411
|
- Sunder <https://github.com/SunderJS/sunder>
|
|
291
412
|
- goblin <https://github.com/bmf-san/goblin>
|
|
413
|
+
- worktop <https://github.com/lukeed/worktop>
|
|
414
|
+
|
|
415
|
+
## Contributing
|
|
416
|
+
|
|
417
|
+
Contributions Welcome! You can contribute by the following way:
|
|
418
|
+
|
|
419
|
+
- Write or fix documents
|
|
420
|
+
- Write code of middleware
|
|
421
|
+
- Fix bugs
|
|
422
|
+
- Refactor the code
|
|
423
|
+
- etc.
|
|
424
|
+
|
|
425
|
+
If you can, let's make Hono together!
|
|
292
426
|
|
|
293
427
|
## Author
|
|
294
428
|
|
|
@@ -296,4 +430,4 @@ Yusuke Wada <https://github.com/yusukebe>
|
|
|
296
430
|
|
|
297
431
|
## License
|
|
298
432
|
|
|
299
|
-
MIT
|
|
433
|
+
Distributed under the MIT License. See [LICENSE](LICENSE) for more information.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
+
declare type Headers = {
|
|
3
|
+
[key: string]: string;
|
|
4
|
+
};
|
|
5
|
+
export interface Env {
|
|
6
|
+
}
|
|
7
|
+
export declare class Context {
|
|
8
|
+
req: Request;
|
|
9
|
+
res: Response;
|
|
10
|
+
env: Env;
|
|
11
|
+
event: FetchEvent;
|
|
12
|
+
constructor(req: Request, opts?: {
|
|
13
|
+
res: Response;
|
|
14
|
+
env: Env;
|
|
15
|
+
event: FetchEvent;
|
|
16
|
+
});
|
|
17
|
+
newResponse(body?: BodyInit | null | undefined, init?: ResponseInit | undefined): Response;
|
|
18
|
+
text(text: string, status?: number, headers?: Headers): Response;
|
|
19
|
+
json(object: object, status?: number, headers?: Headers): Response;
|
|
20
|
+
html(html: string, status?: number, headers?: Headers): Response;
|
|
21
|
+
redirect(location: string, status?: number): Response;
|
|
22
|
+
}
|
|
23
|
+
export {};
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Context = void 0;
|
|
4
|
+
const util_1 = require("./util");
|
|
5
|
+
class Context {
|
|
6
|
+
constructor(req, opts) {
|
|
7
|
+
this.req = req;
|
|
8
|
+
if (opts) {
|
|
9
|
+
this.res = opts.res;
|
|
10
|
+
this.env = opts.env;
|
|
11
|
+
this.event = opts.event;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
newResponse(body, init) {
|
|
15
|
+
return new Response(body, init);
|
|
16
|
+
}
|
|
17
|
+
text(text, status = 200, headers = {}) {
|
|
18
|
+
if (typeof text !== 'string') {
|
|
19
|
+
throw new TypeError('text method arg must be a string!');
|
|
20
|
+
}
|
|
21
|
+
headers['Content-Type'] = 'text/plain';
|
|
22
|
+
return this.newResponse(text, {
|
|
23
|
+
status: status,
|
|
24
|
+
headers: headers,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
json(object, status = 200, headers = {}) {
|
|
28
|
+
if (typeof object !== 'object') {
|
|
29
|
+
throw new TypeError('json method arg must be a object!');
|
|
30
|
+
}
|
|
31
|
+
const body = JSON.stringify(object);
|
|
32
|
+
headers['Content-Type'] = 'application/json; charset=UTF-8';
|
|
33
|
+
return this.newResponse(body, {
|
|
34
|
+
status: status,
|
|
35
|
+
headers: headers,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
html(html, status = 200, headers = {}) {
|
|
39
|
+
if (typeof html !== 'string') {
|
|
40
|
+
throw new TypeError('html method arg must be a string!');
|
|
41
|
+
}
|
|
42
|
+
headers['Content-Type'] = 'text/html; charset=UTF-8';
|
|
43
|
+
return this.newResponse(html, {
|
|
44
|
+
status: status,
|
|
45
|
+
headers: headers,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
redirect(location, status = 302) {
|
|
49
|
+
if (typeof location !== 'string') {
|
|
50
|
+
throw new TypeError('location must be a string!');
|
|
51
|
+
}
|
|
52
|
+
if (!(0, util_1.isAbsoluteURL)(location)) {
|
|
53
|
+
const url = new URL(this.req.url);
|
|
54
|
+
url.pathname = location;
|
|
55
|
+
location = url.toString();
|
|
56
|
+
}
|
|
57
|
+
return this.newResponse(null, {
|
|
58
|
+
status: status,
|
|
59
|
+
headers: {
|
|
60
|
+
Location: location,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.Context = Context;
|
package/dist/hono.d.ts
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
2
|
+
import type { Result } from './node';
|
|
3
|
+
import { Node } from './node';
|
|
4
|
+
import { Context } from './context';
|
|
5
|
+
import type { Env } from './context';
|
|
5
6
|
declare global {
|
|
6
7
|
interface Request {
|
|
7
|
-
params: (key: string) =>
|
|
8
|
+
params: (key: string) => string;
|
|
8
9
|
query: (key: string) => string | null;
|
|
10
|
+
parsedBody: any;
|
|
9
11
|
}
|
|
10
12
|
}
|
|
11
|
-
export declare
|
|
12
|
-
|
|
13
|
-
res: Response;
|
|
14
|
-
constructor(req: Request, res: Response);
|
|
15
|
-
newResponse(body?: BodyInit | null | undefined, init?: ResponseInit | undefined): Response;
|
|
16
|
-
text(body: string): Response;
|
|
17
|
-
}
|
|
18
|
-
declare type Handler = (c: Context, next?: Function) => Response | Promise<Response>;
|
|
19
|
-
declare type MiddlwareHandler = (c: Context, next: Function) => Promise<void>;
|
|
13
|
+
export declare type Handler = (c: Context, next?: Function) => Response | Promise<Response>;
|
|
14
|
+
export declare type MiddlewareHandler = (c: Context, next: Function) => Promise<void>;
|
|
20
15
|
export declare class Router<T> {
|
|
21
16
|
node: Node<T>;
|
|
22
17
|
constructor();
|
|
@@ -25,7 +20,7 @@ export declare class Router<T> {
|
|
|
25
20
|
}
|
|
26
21
|
export declare class Hono {
|
|
27
22
|
router: Router<Handler[]>;
|
|
28
|
-
middlewareRouters: Router<
|
|
23
|
+
middlewareRouters: Router<MiddlewareHandler>[];
|
|
29
24
|
tempPath: string;
|
|
30
25
|
constructor();
|
|
31
26
|
get(arg: string | Handler, ...args: Handler[]): Hono;
|
|
@@ -37,11 +32,13 @@ export declare class Hono {
|
|
|
37
32
|
patch(arg: string | Handler, ...args: Handler[]): Hono;
|
|
38
33
|
all(arg: string | Handler, ...args: Handler[]): Hono;
|
|
39
34
|
route(path: string): Hono;
|
|
40
|
-
use(path: string, middleware:
|
|
35
|
+
use(path: string, middleware: MiddlewareHandler): void;
|
|
41
36
|
addRoute(method: string, arg: string | Handler, ...args: Handler[]): Hono;
|
|
42
37
|
matchRoute(method: string, path: string): Promise<Result<Handler[]>>;
|
|
43
|
-
dispatch(request: Request,
|
|
38
|
+
dispatch(request: Request, env?: Env, event?: FetchEvent): Promise<Response>;
|
|
44
39
|
handleEvent(event: FetchEvent): Promise<Response>;
|
|
40
|
+
fetch(request: Request, env?: Env, event?: FetchEvent): Promise<Response>;
|
|
45
41
|
fire(): void;
|
|
42
|
+
onError(err: any): Response;
|
|
46
43
|
notFound(): Response;
|
|
47
44
|
}
|
package/dist/hono.js
CHANGED
|
@@ -1,30 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Hono = exports.Router =
|
|
3
|
+
exports.Hono = exports.Router = void 0;
|
|
4
4
|
const node_1 = require("./node");
|
|
5
5
|
const compose_1 = require("./compose");
|
|
6
6
|
const util_1 = require("./util");
|
|
7
7
|
const middleware_1 = require("./middleware");
|
|
8
|
-
|
|
8
|
+
const context_1 = require("./context");
|
|
9
9
|
const METHOD_NAME_OF_ALL = 'ALL';
|
|
10
|
-
class Context {
|
|
11
|
-
constructor(req, res) {
|
|
12
|
-
this.req = req;
|
|
13
|
-
this.res = res;
|
|
14
|
-
}
|
|
15
|
-
newResponse(body, init) {
|
|
16
|
-
return new Response(body, init);
|
|
17
|
-
}
|
|
18
|
-
text(body) {
|
|
19
|
-
return this.newResponse(body, {
|
|
20
|
-
status: 200,
|
|
21
|
-
headers: {
|
|
22
|
-
'Content-Type': 'text/plain',
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
exports.Context = Context;
|
|
28
10
|
class Router {
|
|
29
11
|
constructor() {
|
|
30
12
|
this.node = new node_1.Node();
|
|
@@ -99,6 +81,7 @@ class Hono {
|
|
|
99
81
|
addRoute(method, arg, ...args) {
|
|
100
82
|
method = method.toUpperCase();
|
|
101
83
|
if (typeof arg === 'string') {
|
|
84
|
+
this.tempPath = arg;
|
|
102
85
|
this.router.add(method, arg, args);
|
|
103
86
|
}
|
|
104
87
|
else {
|
|
@@ -110,7 +93,7 @@ class Hono {
|
|
|
110
93
|
async matchRoute(method, path) {
|
|
111
94
|
return this.router.match(method, path);
|
|
112
95
|
}
|
|
113
|
-
async dispatch(request,
|
|
96
|
+
async dispatch(request, env, event) {
|
|
114
97
|
const [method, path] = [request.method, (0, util_1.getPathFromURL)(request.url)];
|
|
115
98
|
const result = await this.matchRoute(method, path);
|
|
116
99
|
request.params = (key) => {
|
|
@@ -119,7 +102,7 @@ class Hono {
|
|
|
119
102
|
}
|
|
120
103
|
return '';
|
|
121
104
|
};
|
|
122
|
-
|
|
105
|
+
const handler = result ? result.handler[0] : this.notFound; // XXX
|
|
123
106
|
const middleware = [];
|
|
124
107
|
for (const mr of this.middlewareRouters) {
|
|
125
108
|
const mwResult = mr.match(METHOD_NAME_OF_ALL, path);
|
|
@@ -127,25 +110,36 @@ class Hono {
|
|
|
127
110
|
middleware.push(mwResult.handler);
|
|
128
111
|
}
|
|
129
112
|
}
|
|
130
|
-
|
|
113
|
+
const wrappedHandler = async (context, next) => {
|
|
131
114
|
context.res = await handler(context);
|
|
132
115
|
await next();
|
|
133
116
|
};
|
|
134
|
-
middleware.push(middleware_1.Middleware.
|
|
117
|
+
middleware.push(middleware_1.Middleware.default);
|
|
135
118
|
middleware.push(wrappedHandler);
|
|
136
119
|
const composed = (0, compose_1.compose)(middleware);
|
|
137
|
-
const c = new Context(request,
|
|
120
|
+
const c = new context_1.Context(request, { env: env, event: event, res: null });
|
|
138
121
|
await composed(c);
|
|
139
122
|
return c.res;
|
|
140
123
|
}
|
|
141
124
|
async handleEvent(event) {
|
|
142
|
-
return this.dispatch(event.request)
|
|
125
|
+
return this.dispatch(event.request, {}, event).catch((err) => {
|
|
126
|
+
return this.onError(err);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
async fetch(request, env, event) {
|
|
130
|
+
return this.dispatch(request, env, event).catch((err) => {
|
|
131
|
+
return this.onError(err);
|
|
132
|
+
});
|
|
143
133
|
}
|
|
144
134
|
fire() {
|
|
145
135
|
addEventListener('fetch', (event) => {
|
|
146
136
|
event.respondWith(this.handleEvent(event));
|
|
147
137
|
});
|
|
148
138
|
}
|
|
139
|
+
onError(err) {
|
|
140
|
+
console.error(err);
|
|
141
|
+
return new Response('Internal Server Error', { status: 500 });
|
|
142
|
+
}
|
|
149
143
|
notFound() {
|
|
150
144
|
return new Response('Not Found', { status: 404 });
|
|
151
145
|
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -3,5 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Context = exports.Middleware = exports.Hono = void 0;
|
|
4
4
|
var hono_1 = require("./hono");
|
|
5
5
|
Object.defineProperty(exports, "Hono", { enumerable: true, get: function () { return hono_1.Hono; } });
|
|
6
|
-
|
|
7
|
-
Object.defineProperty(exports, "
|
|
6
|
+
var middleware_1 = require("./middleware");
|
|
7
|
+
Object.defineProperty(exports, "Middleware", { enumerable: true, get: function () { return middleware_1.Middleware; } });
|
|
8
|
+
var context_1 = require("./context");
|
|
9
|
+
Object.defineProperty(exports, "Context", { enumerable: true, get: function () { return context_1.Context; } });
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.basicAuth = void 0;
|
|
4
|
+
const util_1 = require("../../util");
|
|
5
|
+
const CREDENTIALS_REGEXP = /^ *(?:[Bb][Aa][Ss][Ii][Cc]) +([A-Za-z0-9._~+/-]+=*) *$/;
|
|
6
|
+
const USER_PASS_REGEXP = /^([^:]*):(.*)$/;
|
|
7
|
+
const auth = (req) => {
|
|
8
|
+
if (!req) {
|
|
9
|
+
throw new TypeError('argument req is required');
|
|
10
|
+
}
|
|
11
|
+
if (typeof req !== 'object') {
|
|
12
|
+
throw new TypeError('argument req is required to be an object');
|
|
13
|
+
}
|
|
14
|
+
if (!req.headers || typeof req.headers !== 'object') {
|
|
15
|
+
throw new TypeError('argument req is required to have headers property');
|
|
16
|
+
}
|
|
17
|
+
const match = CREDENTIALS_REGEXP.exec(req.headers.get('Authorization'));
|
|
18
|
+
if (!match) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
const userPass = USER_PASS_REGEXP.exec(decodeBase64(match[1]));
|
|
22
|
+
if (!userPass) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
return { username: userPass[1], password: userPass[2] };
|
|
26
|
+
};
|
|
27
|
+
function decodeBase64(str) {
|
|
28
|
+
return Buffer.from(str, 'base64').toString();
|
|
29
|
+
}
|
|
30
|
+
const basicAuth = (options) => {
|
|
31
|
+
if (!options.realm) {
|
|
32
|
+
options.realm = 'Secure Area';
|
|
33
|
+
}
|
|
34
|
+
return async (ctx, next) => {
|
|
35
|
+
const user = auth(ctx.req);
|
|
36
|
+
const usernameEqual = user && await (0, util_1.timingSafeEqual)(options.username, user.username);
|
|
37
|
+
const passwordEqual = user && await (0, util_1.timingSafeEqual)(options.password, user.password);
|
|
38
|
+
if (!user || !usernameEqual || !passwordEqual) {
|
|
39
|
+
ctx.res = new Response('Unauthorized', {
|
|
40
|
+
status: 401,
|
|
41
|
+
headers: {
|
|
42
|
+
'WWW-Authenticate': 'Basic realm="' + options.realm.replace(/"/g, '\\"') + '"',
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
return next();
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
exports.basicAuth = basicAuth;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bodyParse = void 0;
|
|
4
|
+
const bodyParse = () => {
|
|
5
|
+
return async (ctx, next) => {
|
|
6
|
+
const contentType = ctx.req.headers.get('Content-Type') || '';
|
|
7
|
+
if (contentType.includes('application/json')) {
|
|
8
|
+
ctx.req.parsedBody = await ctx.req.json();
|
|
9
|
+
}
|
|
10
|
+
else if (contentType.includes('application/text')) {
|
|
11
|
+
ctx.req.parsedBody = await ctx.req.text();
|
|
12
|
+
}
|
|
13
|
+
else if (contentType.includes('text/html')) {
|
|
14
|
+
ctx.req.parsedBody = await ctx.req.text();
|
|
15
|
+
}
|
|
16
|
+
else if (contentType.includes('form')) {
|
|
17
|
+
const form = {};
|
|
18
|
+
const data = [...(await ctx.req.formData())].reduce((acc, cur) => {
|
|
19
|
+
acc[cur[0]] = cur[1];
|
|
20
|
+
return acc;
|
|
21
|
+
}, form);
|
|
22
|
+
ctx.req.parsedBody = data;
|
|
23
|
+
}
|
|
24
|
+
await next();
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
exports.bodyParse = bodyParse;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defaultMiddleware = void 0;
|
|
4
|
+
const defaultMiddleware = async (c, next) => {
|
|
5
|
+
c.req.query = (key) => {
|
|
6
|
+
// eslint-disable-next-line
|
|
7
|
+
const url = new URL(c.req.url);
|
|
8
|
+
return url.searchParams.get(key);
|
|
9
|
+
};
|
|
10
|
+
await next();
|
|
11
|
+
if (c.res.body) {
|
|
12
|
+
const buff = await c.res.clone().arrayBuffer();
|
|
13
|
+
c.res.headers.append('Content-Length', buff.byteLength.toString());
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
exports.defaultMiddleware = defaultMiddleware;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { Context } from '../../
|
|
1
|
+
import type { Context } from '../../context';
|
|
2
2
|
export declare const logger: (fn?: {
|
|
3
3
|
(...data: any[]): void;
|
|
4
4
|
(...data: any[]): void;
|
|
5
|
+
(message?: any, ...optionalParams: any[]): void;
|
|
5
6
|
}) => (c: Context, next: Function) => Promise<void>;
|
|
@@ -12,7 +12,9 @@ const humanize = (n, opts) => {
|
|
|
12
12
|
};
|
|
13
13
|
const time = (start) => {
|
|
14
14
|
const delta = Date.now() - start;
|
|
15
|
-
return humanize([
|
|
15
|
+
return humanize([
|
|
16
|
+
delta < 10000 ? delta + 'ms' : Math.round(delta / 1000) + 's',
|
|
17
|
+
]);
|
|
16
18
|
};
|
|
17
19
|
const LogPrefix = {
|
|
18
20
|
Outgoing: '-->',
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Context } from '../../
|
|
1
|
+
import type { Context } from '../../context';
|
|
2
2
|
export declare const poweredBy: () => (c: Context, next: Function) => Promise<void>;
|
|
File without changes
|
package/dist/middleware.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
export declare class Middleware {
|
|
2
|
-
static
|
|
3
|
-
static poweredBy: () => (c: import("./
|
|
2
|
+
static default: (c: import("./context").Context, next: Function) => Promise<void>;
|
|
3
|
+
static poweredBy: () => (c: import("./context").Context, next: Function) => Promise<void>;
|
|
4
4
|
static logger: (fn?: {
|
|
5
5
|
(...data: any[]): void;
|
|
6
6
|
(...data: any[]): void;
|
|
7
|
-
|
|
7
|
+
(message?: any, ...optionalParams: any[]): void;
|
|
8
|
+
}) => (c: import("./context").Context, next: Function) => Promise<void>;
|
|
9
|
+
static basicAuth: (options: {
|
|
10
|
+
username: string;
|
|
11
|
+
password: string;
|
|
12
|
+
realm?: string;
|
|
13
|
+
}) => (ctx: import("./context").Context, next: Function) => Promise<any>;
|
|
14
|
+
static bodyParse: () => (ctx: import("./context").Context, next: Function) => Promise<void>;
|
|
8
15
|
}
|
package/dist/middleware.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Middleware = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const default_1 = require("./middleware/default");
|
|
5
|
+
const powered_by_1 = require("./middleware/powered-by/powered-by");
|
|
6
6
|
const logger_1 = require("./middleware/logger/logger");
|
|
7
|
+
const basic_auth_1 = require("./middleware/basic-auth/basic-auth");
|
|
8
|
+
const body_parse_1 = require("./middleware/body-parse/body-parse");
|
|
7
9
|
class Middleware {
|
|
8
10
|
}
|
|
9
11
|
exports.Middleware = Middleware;
|
|
10
|
-
Middleware.
|
|
11
|
-
Middleware.poweredBy =
|
|
12
|
+
Middleware.default = default_1.defaultMiddleware;
|
|
13
|
+
Middleware.poweredBy = powered_by_1.poweredBy;
|
|
12
14
|
Middleware.logger = logger_1.logger;
|
|
15
|
+
Middleware.basicAuth = basic_auth_1.basicAuth;
|
|
16
|
+
Middleware.bodyParse = body_parse_1.bodyParse;
|
package/dist/node.js
CHANGED
|
@@ -23,6 +23,7 @@ class Node {
|
|
|
23
23
|
this.middlewares = [];
|
|
24
24
|
}
|
|
25
25
|
insert(method, path, handler) {
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
26
27
|
let curNode = this;
|
|
27
28
|
const parts = (0, util_1.splitPath)(path);
|
|
28
29
|
for (let i = 0, len = parts.length; i < len; i++) {
|
|
@@ -38,13 +39,15 @@ class Node {
|
|
|
38
39
|
return curNode;
|
|
39
40
|
}
|
|
40
41
|
search(method, path) {
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
41
43
|
let curNode = this;
|
|
42
44
|
const params = {};
|
|
43
|
-
|
|
45
|
+
const parts = (0, util_1.splitPath)(path);
|
|
44
46
|
for (let i = 0, len = parts.length; i < len; i++) {
|
|
45
47
|
const p = parts[i];
|
|
46
48
|
// '*' => match any path
|
|
47
|
-
|
|
49
|
+
// /api/* => default wildcard match
|
|
50
|
+
if (curNode.children['*'] && !curNode.children[p]) {
|
|
48
51
|
const astNode = curNode.children['*'];
|
|
49
52
|
if (Object.keys(astNode.children).length === 0) {
|
|
50
53
|
curNode = astNode;
|
package/dist/util.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export declare const splitPath: (path: string) => string[];
|
|
2
2
|
export declare const getPattern: (label: string) => string[] | null;
|
|
3
3
|
export declare const getPathFromURL: (url: string) => string;
|
|
4
|
+
export declare const isAbsoluteURL: (url: string) => boolean;
|
|
5
|
+
export declare const timingSafeEqual: (a: any, b: any) => Promise<boolean>;
|
package/dist/util.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getPathFromURL = exports.getPattern = exports.splitPath = void 0;
|
|
3
|
+
exports.timingSafeEqual = exports.isAbsoluteURL = exports.getPathFromURL = exports.getPattern = exports.splitPath = void 0;
|
|
4
|
+
const URL_REGEXP = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
|
|
4
5
|
const splitPath = (path) => {
|
|
5
6
|
const paths = path.split(/\//); // faster than path.split('/')
|
|
6
7
|
if (paths[0] === '') {
|
|
@@ -27,10 +28,45 @@ const getPattern = (label) => {
|
|
|
27
28
|
exports.getPattern = getPattern;
|
|
28
29
|
const getPathFromURL = (url) => {
|
|
29
30
|
// XXX
|
|
30
|
-
const match = url.match(
|
|
31
|
+
const match = url.match(URL_REGEXP);
|
|
31
32
|
if (match) {
|
|
32
33
|
return match[5];
|
|
33
34
|
}
|
|
34
35
|
return '';
|
|
35
36
|
};
|
|
36
37
|
exports.getPathFromURL = getPathFromURL;
|
|
38
|
+
const isAbsoluteURL = (url) => {
|
|
39
|
+
const match = url.match(URL_REGEXP);
|
|
40
|
+
if (match && match[1]) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
};
|
|
45
|
+
exports.isAbsoluteURL = isAbsoluteURL;
|
|
46
|
+
const bufferEqual = (a, b) => {
|
|
47
|
+
if (a === b) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
if (a.byteLength !== b.byteLength) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
const va = new DataView(a);
|
|
54
|
+
const vb = new DataView(b);
|
|
55
|
+
let i = va.byteLength;
|
|
56
|
+
while (i--) {
|
|
57
|
+
if (va.getUint8(i) !== vb.getUint8(i)) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return true;
|
|
62
|
+
};
|
|
63
|
+
const timingSafeEqual = async (a, b) => {
|
|
64
|
+
const sa = await crypto.subtle.digest({
|
|
65
|
+
name: 'SHA-256',
|
|
66
|
+
}, new TextEncoder().encode(String(a)));
|
|
67
|
+
const sb = await crypto.subtle.digest({
|
|
68
|
+
name: 'SHA-256',
|
|
69
|
+
}, new TextEncoder().encode(String(b)));
|
|
70
|
+
return bufferEqual(sa, sb) && a === b;
|
|
71
|
+
};
|
|
72
|
+
exports.timingSafeEqual = timingSafeEqual;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.15",
|
|
4
|
+
"description": "[炎] Ultrafast web framework for Cloudflare Workers.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
],
|
|
10
10
|
"scripts": {
|
|
11
11
|
"test": "jest",
|
|
12
|
+
"lint": "eslint --ext js,ts src .eslintrc.js test",
|
|
12
13
|
"build": "rimraf dist && tsc",
|
|
13
14
|
"watch": "tsc -w",
|
|
14
15
|
"prepublishOnly": "yarn build"
|
|
@@ -35,11 +36,26 @@
|
|
|
35
36
|
"devDependencies": {
|
|
36
37
|
"@cloudflare/workers-types": "^3.3.0",
|
|
37
38
|
"@types/jest": "^27.4.0",
|
|
38
|
-
"@types/
|
|
39
|
+
"@types/node": "^17.0.8",
|
|
40
|
+
"@typescript-eslint/eslint-plugin": "^5.9.0",
|
|
41
|
+
"@typescript-eslint/parser": "^5.9.0",
|
|
42
|
+
"eslint": "^7.26.0",
|
|
43
|
+
"eslint-config-prettier": "^8.1.0",
|
|
44
|
+
"eslint-define-config": "^1.2.1",
|
|
45
|
+
"eslint-import-resolver-typescript": "^2.0.0",
|
|
46
|
+
"eslint-plugin-eslint-comments": "^3.2.0",
|
|
47
|
+
"eslint-plugin-flowtype": "^5.7.2",
|
|
48
|
+
"eslint-plugin-import": "^2.20.2",
|
|
49
|
+
"eslint-plugin-node": "^11.1.0",
|
|
50
|
+
"eslint-plugin-prettier": "^4.0.0",
|
|
51
|
+
"form-data": "^4.0.0",
|
|
39
52
|
"jest": "^27.4.5",
|
|
53
|
+
"jest-environment-miniflare": "^2.0.0",
|
|
40
54
|
"rimraf": "^3.0.2",
|
|
41
|
-
"service-worker-mock": "^2.0.5",
|
|
42
55
|
"ts-jest": "^27.1.2",
|
|
43
56
|
"typescript": "^4.5.4"
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=11.0.0"
|
|
44
60
|
}
|
|
45
61
|
}
|
package/dist/methods.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const methods: string[];
|
package/dist/methods.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.methods = void 0;
|
|
4
|
-
exports.methods = [
|
|
5
|
-
'get',
|
|
6
|
-
'post',
|
|
7
|
-
'put',
|
|
8
|
-
'head',
|
|
9
|
-
'delete',
|
|
10
|
-
'options',
|
|
11
|
-
'trace',
|
|
12
|
-
'copy',
|
|
13
|
-
'lock',
|
|
14
|
-
'mkcol',
|
|
15
|
-
'move',
|
|
16
|
-
'patch',
|
|
17
|
-
'purge',
|
|
18
|
-
'propfind',
|
|
19
|
-
'proppatch',
|
|
20
|
-
'unlock',
|
|
21
|
-
'report',
|
|
22
|
-
'mkactivity',
|
|
23
|
-
'checkout',
|
|
24
|
-
'merge',
|
|
25
|
-
'm-search',
|
|
26
|
-
'notify',
|
|
27
|
-
'subscribe',
|
|
28
|
-
'unsubscribe',
|
|
29
|
-
'search',
|
|
30
|
-
'connect',
|
|
31
|
-
];
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.defaultFilter = void 0;
|
|
4
|
-
const defaultFilter = async (c, next) => {
|
|
5
|
-
c.req.query = (key) => {
|
|
6
|
-
const url = new URL(c.req.url);
|
|
7
|
-
return url.searchParams.get(key);
|
|
8
|
-
};
|
|
9
|
-
await next();
|
|
10
|
-
};
|
|
11
|
-
exports.defaultFilter = defaultFilter;
|