@ditojs/router 1.25.0 → 1.25.1

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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/src/Node.js +20 -21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ditojs/router",
3
- "version": "1.25.0",
3
+ "version": "1.25.1",
4
4
  "type": "module",
5
5
  "description": "Dito.js Router – Dito.js is a declarative and modern web framework, based on Objection.js, Koa.js and Vue.js",
6
6
  "repository": "https://github.com/ditojs/dito/tree/master/packages/router",
@@ -30,6 +30,6 @@
30
30
  "koa",
31
31
  "dito"
32
32
  ],
33
- "gitHead": "29e7f8d8c613c48a856d90d1ee876e85c8d84c08",
33
+ "gitHead": "bebbf44ddf15a565e50ed8b2cbe0bf8a463c276d",
34
34
  "readme": "# Dito.js Router\n\nDito.js is a declarative and modern web framework with a focus on API driven\ndevelopment, based on Koa.js, Objection.js and Vue.js\n\nReleased in 2018 under the MIT license, with support by https://lineto.com/\n\nDito.js Router is a high performance, tree-based, framework agnostic HTTP\nrouter, based on [trek-router](https://github.com/trekjs/router), which in turn\nis inspired by [Echo](https://github.com/labstack/echo)'s Router.\n\n## How does it work?\n\nThe router relies on a tree structure which makes heavy use of common\nprefixes, essentially a [prefix tree](https://en.wikipedia.org/wiki/Trie).\n\n## Usage\n\n```js\nimport Koa from 'koa'\nimport compose from 'koa-compose'\nimport Router from '@ditojs/router'\n\nconst app = new Koa()\nconst router = new Router()\n\n// static route\nrouter.get('/folders/files/bolt.gif', ctx => {\n ctx.body = `this ain't no GIF!`\n})\n\n// param route\nrouter.get('/users/:id', ctx => {\n ctx.body = `requesting user ${ctx.params.id}`\n})\n\n// match-any route\nrouter.get('/books/*', ctx => {\n ctx.body = `sub-route: ${ctx.params['*']}`\n})\n\n// Handler found\nlet { handler, params } = router.find('get', '/users/233')\nconsole.log(handler) // ctx => { ... }\n\n// Entry not Found\nlet { handler, params } = router.find('get', '/photos/233')\nconsole.log(handler) // null\n\n// Install router middleware\napp.use(async (ctx, next) => {\n const { method, path } = ctx\n const result = router.find(method, path)\n const { handler, params } = result\n if (handler) {\n ctx.params = params || {}\n return handler(ctx, next)\n } else {\n try {\n await next()\n } finally {\n if (ctx.body === undefined && ctx.status === 404) {\n ctx.status = result.status || 404\n if (ctx.status !== 404 && result.allowed) {\n ctx.set('Allow', result.allowed.join(', '))\n }\n }\n }\n }\n})\n\napp.listen(4040, () => console.log('Koa app listening on 4040'))\n```\n"
35
35
  }
package/src/Node.js CHANGED
@@ -133,13 +133,13 @@ export default class Node {
133
133
  }
134
134
  }
135
135
 
136
- find(path, paramValues = []) {
136
+ find(path, parameterValues = []) {
137
137
  const { prefix } = this
138
138
  if (!path || path === prefix) {
139
139
  // It's a match!
140
140
  const { handler } = this
141
141
  if (handler) {
142
- const params = this.parameters.getObject(paramValues)
142
+ const params = this.parameters.getObject(parameterValues)
143
143
  // Support HTTP status on found entries.
144
144
  return { handler, params, status: 200 }
145
145
  }
@@ -165,7 +165,7 @@ export default class Node {
165
165
  child => child.type === TYPE_STATIC && child.label === label
166
166
  )
167
167
  if (staticChild) {
168
- const result = staticChild.find(path, paramValues)
168
+ const result = staticChild.find(path, parameterValues)
169
169
  if (result) {
170
170
  return result
171
171
  }
@@ -185,21 +185,21 @@ export default class Node {
185
185
  while (pos < max && path[pos] !== CHAR_SLASH) {
186
186
  pos++
187
187
  }
188
- paramValues.push(path.slice(0, pos))
189
- const result = paramChild.find(path.slice(pos), paramValues)
188
+ parameterValues.push(path.slice(0, pos))
189
+ const result = paramChild.find(path.slice(pos), parameterValues)
190
190
  if (result) {
191
191
  return result
192
192
  }
193
- paramValues.pop()
193
+ parameterValues.pop()
194
194
  }
195
195
 
196
196
  // Match-any nodes
197
197
  if (this.hasMatchAny) {
198
198
  for (const child of this.children) {
199
- const match = child.parameters?.matchPathPattern(path)
200
- if (match) {
201
- paramValues.push(...Object.values(match.groups))
202
- return child.find('', paramValues) // '' == End
199
+ const values = child.parameters?.matchPathPattern(path)
200
+ if (values) {
201
+ parameterValues.push(...values)
202
+ return child.find('', parameterValues) // '' == End
203
203
  }
204
204
  }
205
205
  }
@@ -240,8 +240,8 @@ class Parameters {
240
240
  this.placeholderIndex = 0
241
241
  }
242
242
 
243
- add(...keys) {
244
- this.keys.push(...keys)
243
+ add(key) {
244
+ this.keys.push(key)
245
245
  }
246
246
 
247
247
  getMatchAnyKey() {
@@ -257,39 +257,38 @@ class Parameters {
257
257
  }
258
258
 
259
259
  matchPathPattern(path) {
260
- return this.pathPattern?.exec(path)
260
+ const match = this.pathPattern?.exec(path)
261
+ return match ? Object.values(match.groups) : null
261
262
  }
262
263
 
263
264
  setupPathPattern(path) {
264
265
  // Replace all '**' with '.+?' and all '*' with '[^/]+'.
265
266
  // Use named groups to merge multiple ** or * into one.
266
267
  const pattern = []
267
- const keys = []
268
268
  for (const token of path.split('/')) {
269
269
  if (token === '**') {
270
270
  const key = this.getMatchAnyKey()
271
271
  pattern.push(`(?<${key}>.+?)`)
272
- keys.push(key)
272
+ this.add(key)
273
273
  } else if (token === '*') {
274
274
  const key = this.getPlaceholderKey()
275
275
  pattern.push(`(?<${key}>[^/]+)`)
276
- keys.push(key)
276
+ this.add(key)
277
277
  } else if (token.startsWith(':')) {
278
278
  const key = token.slice(1)
279
279
  pattern.push(`(?<${key}>[^/]+)`)
280
- keys.push(key)
280
+ this.add(key)
281
281
  } else {
282
282
  pattern.push(token)
283
283
  }
284
284
  }
285
285
  this.pathPattern = new RegExp(`^${pattern.join('/')}$`)
286
- this.add(...keys)
287
286
  }
288
287
 
289
288
  getObject(values) {
290
289
  // Convert parameters and values to a params object, but rename path pattern
291
290
  // groups back to param names
292
- const params = {}
291
+ const object = {}
293
292
  let i = 0
294
293
  for (const key of this.keys) {
295
294
  const name = key.startsWith('$$')
@@ -301,8 +300,8 @@ class Parameters {
301
300
  ? '$'
302
301
  : key
303
302
  : key
304
- params[name] = values[i++]
303
+ object[name] = values[i++]
305
304
  }
306
- return params
305
+ return object
307
306
  }
308
307
  }