@pirxpilot/router 1.0.0 → 1.1.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/HISTORY.md CHANGED
@@ -1,4 +1,15 @@
1
1
 
2
+ 1.1.0 / 2025-01-18
3
+ ==================
4
+
5
+ * simplify layer creation
6
+ * remove `methods` dependency
7
+ * replace run-series with await/async
8
+ * allow using rawrequest with promises
9
+ * minor ES6 fixes
10
+ * minor improvement in Router.use
11
+ * use Set to keep track of route methods
12
+
2
13
  1.0.0 / 2024-12-31
3
14
  ==================
4
15
 
package/index.js CHANGED
@@ -12,8 +12,8 @@
12
12
  * @private
13
13
  */
14
14
 
15
+ const { METHODS } = require('node:http')
15
16
  const Layer = require('./lib/layer')
16
- const methods = require('methods')
17
17
  const parseUrl = require('parseurl')
18
18
  const Route = require('./lib/route')
19
19
 
@@ -375,9 +375,7 @@ Router.prototype.use = function use (handler, ...args) {
375
375
  throw new TypeError('argument handler is required')
376
376
  }
377
377
 
378
- for (let i = 0; i < callbacks.length; i++) {
379
- const fn = callbacks[i]
380
-
378
+ this.stack.push(...callbacks.map(fn => {
381
379
  if (typeof fn !== 'function') {
382
380
  throw new TypeError('argument handler must be a function')
383
381
  }
@@ -390,9 +388,8 @@ Router.prototype.use = function use (handler, ...args) {
390
388
  }, fn)
391
389
 
392
390
  layer.route = undefined
393
-
394
- this.stack.push(layer)
395
- }
391
+ return layer
392
+ }))
396
393
 
397
394
  return this
398
395
  }
@@ -430,13 +427,15 @@ Router.prototype.route = function route (path) {
430
427
  }
431
428
 
432
429
  // create Router#VERB functions
433
- methods.concat('all').forEach(function (method) {
434
- Router.prototype[method] = function (path, ...args) {
435
- const route = this.route(path)
436
- route[method].apply(route, args)
437
- return this
438
- }
439
- })
430
+ METHODS.concat('all')
431
+ .map(m => m.toLowerCase())
432
+ .forEach(method => {
433
+ Router.prototype[method] = function (path, ...args) {
434
+ const route = this.route(path)
435
+ route[method].apply(route, args)
436
+ return this
437
+ }
438
+ })
440
439
 
441
440
  /**
442
441
  * Generate a callback that will make an OPTIONS response.
package/lib/layer.js CHANGED
@@ -28,20 +28,22 @@ const MATCHING_GROUP_REGEXP = /\((?:\?<(.*?)>)?(?!\?)/g
28
28
 
29
29
  module.exports = Layer
30
30
 
31
- function Layer (path, options, fn) {
32
- if (!(this instanceof Layer)) {
33
- return new Layer(path, options, fn)
31
+ function Layer (path, opts = {}, fn, method) {
32
+ if (typeof fn !== 'function') {
33
+ throw new TypeError('argument handler must be a function')
34
34
  }
35
-
36
- const opts = options || {}
37
-
38
35
  this.handle = fn
39
36
  this.keys = []
40
37
  this.name = fn.name || '<anonymous>'
41
38
  this.params = undefined
42
39
  this.path = undefined
43
40
  this.slash = path === '/' && opts.end === false
44
- this.matchers = Array.isArray(path) ? path.map(p => matcher(p, opts)) : [matcher(path, opts)]
41
+ this.matchers = this.slash
42
+ ? []
43
+ : Array.isArray(path)
44
+ ? path.map(p => matcher(p, opts))
45
+ : [matcher(path, opts)]
46
+ this.method = method
45
47
  }
46
48
 
47
49
  function matcher (path, { sensitive, end, strict }) {
@@ -203,7 +205,7 @@ function decodeParam (val) {
203
205
  return decodeURIComponent(val)
204
206
  } catch (err) {
205
207
  if (err instanceof URIError) {
206
- err.message = 'Failed to decode param \'' + val + '\''
208
+ err.message = `Failed to decode param '${val}'`
207
209
  err.status = 400
208
210
  }
209
211
 
@@ -220,6 +222,6 @@ function loosen (path) {
220
222
  }
221
223
 
222
224
  return Array.isArray(path)
223
- ? path.map(function (p) { return loosen(p) })
225
+ ? path.map(p => loosen(p))
224
226
  : String(path).replace(TRAILING_SLASH_REGEXP, '')
225
227
  }
package/lib/route.js CHANGED
@@ -12,8 +12,8 @@
12
12
  * @private
13
13
  */
14
14
 
15
+ const { METHODS } = require('node:http')
15
16
  const Layer = require('./layer')
16
- const methods = require('methods')
17
17
 
18
18
  /**
19
19
  * Module variables.
@@ -38,7 +38,7 @@ function Route (path) {
38
38
  this.stack = []
39
39
 
40
40
  // route handlers for various http methods
41
- this.methods = Object.create(null)
41
+ this.methods = new Set()
42
42
  }
43
43
 
44
44
  /**
@@ -50,16 +50,11 @@ Route.prototype._handlesMethod = function _handlesMethod (method) {
50
50
  return true
51
51
  }
52
52
 
53
- // normalize name
54
- let name = typeof method === 'string'
55
- ? method.toLowerCase()
56
- : method
57
-
58
- if (name === 'head' && !this.methods.head) {
59
- name = 'get'
53
+ if (method === 'HEAD' && !this.methods.has('HEAD')) {
54
+ method = 'GET'
60
55
  }
61
56
 
62
- return Boolean(this.methods[name])
57
+ return this.methods.has(method)
63
58
  }
64
59
 
65
60
  /**
@@ -68,16 +63,11 @@ Route.prototype._handlesMethod = function _handlesMethod (method) {
68
63
  */
69
64
 
70
65
  Route.prototype._methods = function _methods () {
71
- const methods = Object.keys(this.methods)
66
+ const methods = [...this.methods]
72
67
 
73
68
  // append automatic head
74
- if (this.methods.get && !this.methods.head) {
75
- methods.push('head')
76
- }
77
-
78
- for (let i = 0; i < methods.length; i++) {
79
- // make upper case
80
- methods[i] = methods[i].toUpperCase()
69
+ if (this.methods.has('GET') && !this.methods.has('HEAD')) {
70
+ methods.push('HEAD')
81
71
  }
82
72
 
83
73
  return methods
@@ -98,12 +88,9 @@ Route.prototype.dispatch = function dispatch (req, res, done) {
98
88
  return done()
99
89
  }
100
90
 
101
- let method = typeof req.method === 'string'
102
- ? req.method.toLowerCase()
103
- : req.method
104
-
105
- if (method === 'head' && !this.methods.head) {
106
- method = 'get'
91
+ let { method } = req
92
+ if (method === 'HEAD' && !this.methods.has('HEAD')) {
93
+ method = 'GET'
107
94
  }
108
95
 
109
96
  req.route = this
@@ -193,43 +180,24 @@ Route.prototype.all = function all (...args) {
193
180
  throw new TypeError('argument handler is required')
194
181
  }
195
182
 
196
- for (const fn of callbacks) {
197
- if (typeof fn !== 'function') {
198
- throw new TypeError('argument handler must be a function')
199
- }
200
-
201
- const layer = Layer('/', {}, fn)
202
- layer.method = undefined
203
-
204
- this.methods._all = true
205
- this.stack.push(layer)
206
- }
183
+ this.methods._all = true
184
+ this.stack.push(...callbacks.map(fn => new Layer('/', {}, fn)))
207
185
 
208
186
  return this
209
187
  }
210
188
 
211
- methods.forEach(function (method) {
212
- Route.prototype[method] = function (...args) {
213
- const callbacks = args.flat(Infinity)
214
-
215
- if (callbacks.length === 0) {
216
- throw new TypeError('argument handler is required')
217
- }
218
-
219
- for (let i = 0; i < callbacks.length; i++) {
220
- const fn = callbacks[i]
189
+ METHODS
190
+ .forEach(method => {
191
+ Route.prototype[method.toLowerCase()] = function (...args) {
192
+ const callbacks = args.flat(Infinity)
221
193
 
222
- if (typeof fn !== 'function') {
223
- throw new TypeError('argument handler must be a function')
194
+ if (callbacks.length === 0) {
195
+ throw new TypeError('argument handler is required')
224
196
  }
225
197
 
226
- const layer = Layer('/', {}, fn)
227
- layer.method = method
198
+ this.methods.add(method)
199
+ this.stack.push(...callbacks.map(fn => new Layer('/', {}, fn, method)))
228
200
 
229
- this.methods[method] = true
230
- this.stack.push(layer)
201
+ return this
231
202
  }
232
-
233
- return this
234
- }
235
- })
203
+ })
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pirxpilot/router",
3
3
  "description": "Simple middleware-style router",
4
- "version": "1.0.0",
4
+ "version": "1.1.0",
5
5
  "author": "Douglas Christopher Wilson <doug@somethingdoug.com>",
6
6
  "contributors": [
7
7
  "Blake Embrey <hello@blakeembrey.com>"
@@ -12,13 +12,11 @@
12
12
  "url": "git+https://github.com/pirxpilot/router.git"
13
13
  },
14
14
  "dependencies": {
15
- "methods": "~1",
16
15
  "parseurl": "~1",
17
16
  "path-to-regexp": "~8"
18
17
  },
19
18
  "devDependencies": {
20
19
  "finalhandler": "~1",
21
- "run-series": "~1",
22
20
  "standard": "~17",
23
21
  "supertest": "~7"
24
22
  },