itty-router
Advanced tools
Comparing version 0.3.0 to 0.4.0
{ | ||
"name": "itty-router", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"description": "", | ||
@@ -23,6 +23,3 @@ "main": "src/Router.js", | ||
"yarn-release": "^1.10.2" | ||
}, | ||
"dependencies": { | ||
"path-to-regexp": "^6.1.0" | ||
} | ||
} |
@@ -5,3 +5,3 @@ # itty-router | ||
It's an itty bitty router. That means small. It's tiny. For reals. | ||
It's an itty bitty router. Like... super tiny, with zero dependencies. For reals. | ||
@@ -20,11 +20,11 @@ ## Installation | ||
## Our Goals | ||
- [ ] have a simple express-like (or better) interface | ||
- [x] have a simple express-like (or better) interface | ||
- [x] have a chainable interface! | ||
- [x] be tiny | ||
- [x] be easy to use/implement | ||
- [ ] have as few dependencies as possible (or none) | ||
- [x] have as few dependencies as possible (ZERO) | ||
- [x] have test coverage | ||
- [x] have a README | ||
- [x] have a way to release | ||
- [ ] have pretty code | ||
- [ ] have pretty code (right...) | ||
- [ ] handle all the basics of routing within a serverless function | ||
@@ -80,4 +80,2 @@ - [ ] be platform agnostic (or handle the responses of the major platforms) | ||
```js | ||
const { match } = require('path-to-regexp') | ||
const Router = () => new Proxy({}, { | ||
@@ -88,6 +86,6 @@ get: (obj, prop) => prop === 'handle' | ||
for (let [route, handler] of obj[req.method.toLowerCase()] || []) { | ||
if (hit = match(route, { decode: decodeURIComponent })(path)) { | ||
return handler({ | ||
if (hit = path.match(route)) { | ||
return handler({ | ||
...req, | ||
...hit, | ||
params: hit.groups, | ||
path, | ||
@@ -99,9 +97,12 @@ query: Object.fromEntries(searchParams.entries()) | ||
} | ||
: (path, handler) => { | ||
obj[prop] | ||
? obj[prop].push([path, handler]) | ||
: obj[prop] = [[path, handler]] | ||
return obj | ||
} | ||
: (path, handler) => | ||
(obj[prop] = obj[prop] || []).push([path.replace(/(\/:([^\/\?]+)(\?)?)/gi, '/$3(?<$2>[^\/]+)$3'), handler]) && obj | ||
}) | ||
``` | ||
``` | ||
## Special Thanks | ||
This repo goes out to my past and present colleagues at Arundo - who have brought me such inspiration, fun, | ||
and drive over the last couple years. In particular, the absurd brevity of this code is thanks to a | ||
clever [abuse] of `Proxy`, courtesy of the brilliant [@mvasigh](https://github.com/mvasigh). | ||
This trick allows methods (e.g. "get", "post") to by defined dynamically by the router as they are requested, | ||
**drastically** reducing boilerplate. |
@@ -1,3 +0,1 @@ | ||
const { match } = require('path-to-regexp') | ||
const Router = () => new Proxy({}, { | ||
@@ -8,6 +6,6 @@ get: (obj, prop) => prop === 'handle' | ||
for (let [route, handler] of obj[req.method.toLowerCase()] || []) { | ||
if (hit = match(route, { decode: decodeURIComponent })(path)) { | ||
return handler({ | ||
if (hit = path.match(route)) { | ||
return handler({ | ||
...req, | ||
...hit, | ||
params: hit.groups, | ||
path, | ||
@@ -19,8 +17,4 @@ query: Object.fromEntries(searchParams.entries()) | ||
} | ||
: (path, handler) => { | ||
obj[prop] | ||
? obj[prop].push([path, handler]) | ||
: obj[prop] = [[path, handler]] | ||
return obj | ||
} | ||
: (path, handler) => | ||
(obj[prop] = obj[prop] || []).push([path.replace(/(\/:([^\/\?]+)(\?)?)/gi, '/$3(?<$2>[^\/]+)$3'), handler]) && obj | ||
}) | ||
@@ -27,0 +21,0 @@ |
@@ -5,3 +5,3 @@ const { Router } = require('./Router') | ||
const router = Router() | ||
const buildRequest = ({ method = 'GET', path, url = 'https://example.com' + path }) => ({ method, path, url }) | ||
const buildRequest = ({ method = 'GET', path, url = 'https://example.com' + path, ...other }) => ({ method, path, url, ...other }) | ||
const extract = ({ params, query }) => ({ params, query }) | ||
@@ -13,2 +13,4 @@ | ||
{ path: '/foo', callback: jest.fn(extract), method: 'post' }, | ||
{ path: '/optional/:id?', callback: jest.fn(extract), method: 'get' }, | ||
{ path: '/passthrough', callback: jest.fn(({ path, name }) => ({ path, name })), method: 'get' }, | ||
] | ||
@@ -20,3 +22,3 @@ | ||
it('is exported via { Router } from Router.js', () => { | ||
it(`is exported as { Router } from module`, () => { | ||
expect(typeof Router).toBe('function') | ||
@@ -26,9 +28,2 @@ }) | ||
describe('.handle({ method, url })', () => { | ||
it('earlier routes that match intercept later routes', () => { | ||
const route = routes.find(r => r.path === '/foo/first') | ||
router.handle(buildRequest({ path: '/foo/first' })) | ||
expect(route.callback).toHaveBeenCalled() | ||
}) | ||
it('returns { path, query } from match', () => { | ||
@@ -44,3 +39,10 @@ const route = routes.find(r => r.path === '/foo/:id') | ||
it('honors correct method', () => { | ||
it('match earliest routes that match', () => { | ||
const route = routes.find(r => r.path === '/foo/first') | ||
router.handle(buildRequest({ path: '/foo/first' })) | ||
expect(route.callback).toHaveBeenCalled() | ||
}) | ||
it('honors correct method (e.g. GET, POST, etc)', () => { | ||
const route = routes.find(r => r.path === '/foo' && r.method === 'post') | ||
@@ -51,3 +53,23 @@ router.handle(buildRequest({ method: 'POST', path: '/foo' })) | ||
}) | ||
it('handles optional params (e.g. /foo/:id?)', () => { | ||
const route = routes.find(r => r.path === '/optional/:id?') | ||
router.handle(buildRequest({ path: '/optional' })) | ||
expect(route.callback).toHaveBeenCalled() | ||
router.handle(buildRequest({ path: '/optional/13' })) | ||
expect(route.callback).toHaveBeenCalledTimes(2) | ||
}) | ||
it('passes the entire original request through to the handler', () => { | ||
const route = routes.find(r => r.path === '/passthrough') | ||
router.handle(buildRequest({ path: '/passthrough', name: 'miffles' })) | ||
expect(route.callback).toHaveReturnedWith({ | ||
path: '/passthrough', | ||
name: 'miffles', | ||
}) | ||
}) | ||
}) | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
8041
0
74
103
46
- Removedpath-to-regexp@^6.1.0
- Removedpath-to-regexp@6.3.0(transitive)