hono 0.0.5 → 0.0.6

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 CHANGED
@@ -24,7 +24,7 @@ app.fire()
24
24
  ```
25
25
  hono x 813,001 ops/sec ±2.96% (75 runs sampled)
26
26
  itty-router x 160,415 ops/sec ±3.31% (85 runs sampled)
27
- sundar x 307,438 ops/sec ±4.77% (73 runs sampled)
27
+ sunder x 307,438 ops/sec ±4.77% (73 runs sampled)
28
28
  Fastest is hono
29
29
  ✨ Done in 37.03s.
30
30
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "Minimal web framework for Cloudflare Workers",
5
5
  "main": "src/hono.js",
6
6
  "scripts": {
@@ -17,4 +17,4 @@
17
17
  "jest": "^27.4.5",
18
18
  "node-fetch": "^2.6.6"
19
19
  }
20
- }
20
+ }
package/src/hono.js CHANGED
@@ -4,6 +4,8 @@ const Node = require('./node')
4
4
  const compose = require('./compose')
5
5
  const defaultFilter = require('./middleware/defaultFilter')
6
6
 
7
+ const METHOD_NAME_OF_ALL = 'ALL'
8
+
7
9
  class Router {
8
10
  constructor() {
9
11
  this.node = new Node()
@@ -25,6 +27,18 @@ const getPathFromURL = (url) => {
25
27
  return match[5]
26
28
  }
27
29
 
30
+ const proxyHandler = {
31
+ get:
32
+ (target, prop) =>
33
+ (...args) => {
34
+ if (target.constructor.prototype.hasOwnProperty(prop)) {
35
+ return target[prop](...args)
36
+ } else {
37
+ return target.addRoute(prop, ...args)
38
+ }
39
+ },
40
+ }
41
+
28
42
  class Hono {
29
43
  constructor() {
30
44
  this.router = new Router()
@@ -32,20 +46,8 @@ class Hono {
32
46
  this.middlewareRouters = []
33
47
  }
34
48
 
35
- get(...args) {
36
- return this.addRoute('GET', ...args)
37
- }
38
- post(...args) {
39
- return this.addRoute('POST', ...args)
40
- }
41
- put(...args) {
42
- return this.addRoute('PUT', ...args)
43
- }
44
- delete(...args) {
45
- return this.addRoute('DELETE', ...args)
46
- }
47
- patch(...args) {
48
- return this.addRoute('PATCH', ...args)
49
+ getRouter() {
50
+ return this.router
49
51
  }
50
52
 
51
53
  addRoute(method, ...args) {
@@ -55,27 +57,22 @@ class Hono {
55
57
  } else {
56
58
  this.router.add(method, ...args)
57
59
  }
58
- return this
59
- }
60
-
61
- getRouter() {
62
- return this.router
60
+ return WrappedApp(this)
63
61
  }
64
62
 
65
63
  route(path) {
66
64
  this.router.tempPath = path
67
- return this
65
+ return WrappedApp(this)
68
66
  }
69
67
 
70
68
  use(path, middleware) {
71
69
  const router = new Router()
72
- router.add('all', path, middleware)
70
+ router.add(METHOD_NAME_OF_ALL, path, middleware)
73
71
  this.middlewareRouters.push(router)
74
72
  }
75
73
 
76
74
  async matchRoute(method, path) {
77
- const res = this.router.match(method, path)
78
- return res
75
+ return this.router.match(method, path)
79
76
  }
80
77
 
81
78
  // XXX
@@ -102,7 +99,7 @@ class Hono {
102
99
  const middleware = [defaultFilter] // add defaultFilter later
103
100
 
104
101
  for (const mr of this.middlewareRouters) {
105
- const mwResult = mr.match('all', path)
102
+ const mwResult = mr.match(METHOD_NAME_OF_ALL, path)
106
103
  if (mwResult) {
107
104
  middleware.push(...mwResult.handler)
108
105
  }
@@ -137,8 +134,8 @@ class Hono {
137
134
  }
138
135
  }
139
136
 
140
- const CreateApp = () => {
141
- return new Hono()
137
+ const WrappedApp = (hono = new Hono()) => {
138
+ return new Proxy(hono, proxyHandler)
142
139
  }
143
140
 
144
- module.exports = CreateApp
141
+ module.exports = WrappedApp
package/src/hono.test.js CHANGED
@@ -62,27 +62,53 @@ describe('params and query', () => {
62
62
  describe('Middleware', () => {
63
63
  const app = Hono()
64
64
 
65
- const logger = (c, next) => {
65
+ const logger = async (c, next) => {
66
66
  console.log(`${c.req.method} : ${c.req.url}`)
67
67
  next()
68
68
  }
69
69
 
70
- const customHeader = (c, next) => {
70
+ const rootHeader = async (c, next) => {
71
71
  next()
72
- c.res.headers.append('x-message', 'custom-header')
72
+ await c.res.headers.append('x-custom', 'root')
73
+ }
74
+
75
+ const customHeader = async (c, next) => {
76
+ next()
77
+ await c.res.headers.append('x-message', 'custom-header')
78
+ }
79
+ const customHeader2 = async (c, next) => {
80
+ next()
81
+ await c.res.headers.append('x-message-2', 'custom-header-2')
73
82
  }
74
83
 
75
84
  app.use('*', logger)
85
+ app.use('*', rootHeader)
76
86
  app.use('/hello', customHeader)
87
+ app.use('/hello/*', customHeader2)
77
88
  app.get('/hello', () => {
78
89
  return new fetch.Response('hello')
79
90
  })
91
+ app.get('/hello/:message', (c) => {
92
+ const message = c.req.params('message')
93
+ return new fetch.Response(`${message}`)
94
+ })
80
95
 
81
96
  it('logging and custom header', async () => {
82
97
  let req = new fetch.Request('https://example.com/hello')
83
98
  let res = await app.dispatch(req)
84
99
  expect(res.status).toBe(200)
85
100
  expect(await res.text()).toBe('hello')
101
+ expect(await res.headers.get('x-custom')).toBe('root')
86
102
  expect(await res.headers.get('x-message')).toBe('custom-header')
103
+ expect(await res.headers.get('x-message-2')).toBe('custom-header-2')
104
+ })
105
+
106
+ it('logging and custom header with named params', async () => {
107
+ let req = new fetch.Request('https://example.com/hello/message')
108
+ let res = await app.dispatch(req)
109
+ expect(res.status).toBe(200)
110
+ expect(await res.text()).toBe('message')
111
+ expect(await res.headers.get('x-custom')).toBe('root')
112
+ expect(await res.headers.get('x-message-2')).toBe('custom-header-2')
87
113
  })
88
114
  })
package/src/node.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  const { splitPath, getPattern } = require('./util')
4
4
 
5
- const METHOD_NAME_OF_ALL = 'all'
5
+ const METHOD_NAME_OF_ALL = 'ALL'
6
6
 
7
7
  const createResult = (handler, params) => {
8
8
  return { handler: handler, params: params }
@@ -18,6 +18,7 @@ function Node(method, handler, children) {
18
18
  if (method && handler) {
19
19
  this.method[method] = handler
20
20
  }
21
+ this.middlewares = []
21
22
  }
22
23
 
23
24
  Node.prototype.insert = function (method, path, handler) {
@@ -50,6 +51,7 @@ Node.prototype.search = function (method, path) {
50
51
  continue
51
52
  }
52
53
 
54
+ let isWildcard = false
53
55
  let isParamMatch = false
54
56
  const keys = Object.keys(curNode.children)
55
57
  for (let j = 0; j < keys.length; j++) {
@@ -57,7 +59,7 @@ Node.prototype.search = function (method, path) {
57
59
  // Wildcard
58
60
  if (key === '*') {
59
61
  curNode = curNode.children['*']
60
- isParamMatch = true
62
+ isWildcard = true
61
63
  break
62
64
  }
63
65
  const pattern = getPattern(key)
@@ -74,6 +76,10 @@ Node.prototype.search = function (method, path) {
74
76
  }
75
77
  }
76
78
 
79
+ if (isWildcard) {
80
+ break
81
+ }
82
+
77
83
  if (isParamMatch === false) {
78
84
  return noRoute()
79
85
  }
package/src/node.test.js CHANGED
@@ -123,7 +123,7 @@ describe('Regexp', () => {
123
123
 
124
124
  describe('All', () => {
125
125
  const node = new Node()
126
- node.insert('all', '/all-methods', 'all methods')
126
+ node.insert('ALL', '/all-methods', 'all methods') // ALL
127
127
  it('/all-methods', () => {
128
128
  res = node.search('get', '/all-methods')
129
129
  expect(res).not.toBeNull()
package/src/util.test.js CHANGED
@@ -1,4 +1,4 @@
1
- const { splitPath, getPattern, getParamName } = require('./util')
1
+ const { splitPath, getPattern } = require('./util')
2
2
 
3
3
  describe('Utility methods', () => {
4
4
  it('splitPath', () => {