@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 +11 -0
- package/index.js +13 -14
- package/lib/layer.js +11 -9
- package/lib/route.js +23 -55
- package/package.json +1 -3
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
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,
|
|
32
|
-
if (
|
|
33
|
-
|
|
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 =
|
|
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 =
|
|
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(
|
|
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 =
|
|
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
|
-
|
|
54
|
-
|
|
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
|
|
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 =
|
|
66
|
+
const methods = [...this.methods]
|
|
72
67
|
|
|
73
68
|
// append automatic head
|
|
74
|
-
if (this.methods.
|
|
75
|
-
methods.push('
|
|
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 =
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
|
|
197
|
-
|
|
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
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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 (
|
|
223
|
-
throw new TypeError('argument handler
|
|
194
|
+
if (callbacks.length === 0) {
|
|
195
|
+
throw new TypeError('argument handler is required')
|
|
224
196
|
}
|
|
225
197
|
|
|
226
|
-
|
|
227
|
-
|
|
198
|
+
this.methods.add(method)
|
|
199
|
+
this.stack.push(...callbacks.map(fn => new Layer('/', {}, fn, method)))
|
|
228
200
|
|
|
229
|
-
this
|
|
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.
|
|
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
|
},
|