itty-router
Advanced tools
Comparing version 1.3.0 to 1.4.0
## Changelog | ||
Until this library makes it to a production release of v1.x, **minor versions may contain breaking changes to the API**. After v1.x, semantic versioning will be honored, and breaking changes will only occur under the umbrella of a major version bump. | ||
- **v1.4.0** - adds support for optional format params (e.g. "/:id.:format?" --> { params: { id: '13', format: 'jpg' }}) | ||
- **v1.3.0** - adds support for multiple args to handle(request, ...args) method (@hunterloftis) | ||
@@ -5,0 +6,0 @@ - **v1.2.2** - fix: require verify/build pass before publishing and fixed README badges (should point to v1.x branch) |
@@ -20,3 +20,3 @@ const Router = (o = {}) => | ||
.replace(/(\/?)\*/g, '($1.*)?') | ||
.replace(/:([^\/\?]+)(\?)?/g, '$2(?<$1>[^/]+)$2') | ||
.replace(/:([^\/\?\.]+)(\?)?/g, '$2(?<$1>[^/\.]+)$2') | ||
}\/?$`, | ||
@@ -23,0 +23,0 @@ hs |
@@ -1,1 +0,1 @@ | ||
const e=(e={})=>new Proxy(e,{get:(r,a,o)=>"handle"===a?async(e,...a)=>{for([p,hs]of r[(e.method||"GET").toLowerCase()]||[])if(m=(u=new URL(e.url)).pathname.match(p))for(h of(e.params=m.groups,e.query=Object.fromEntries(u.searchParams.entries()),hs))if(void 0!==(s=await h(e,...a)))return s}:(s,...t)=>(r[a]=r[a]||[]).push([`^${(e.base||"")+s.replace(/(\/?)\*/g,"($1.*)?").replace(/:([^\/\?]+)(\?)?/g,"$2(?<$1>[^/]+)$2")}/?$`,t])&&o});module.exports={Router:e}; | ||
const e=(e={})=>new Proxy(e,{get:(r,a,o)=>"handle"===a?async(e,...a)=>{for([p,hs]of r[(e.method||"GET").toLowerCase()]||[])if(m=(u=new URL(e.url)).pathname.match(p))for(h of(e.params=m.groups,e.query=Object.fromEntries(u.searchParams.entries()),hs))if(void 0!==(s=await h(e,...a)))return s}:(s,...t)=>(r[a]=r[a]||[]).push([`^${(e.base||"")+s.replace(/(\/?)\*/g,"($1.*)?").replace(/:([^\/\?\.]+)(\?)?/g,"$2(?<$1>[^/.]+)$2")}/?$`,t])&&o});module.exports={Router:e}; |
{ | ||
"name": "itty-router", | ||
"version": "1.3.0", | ||
"version": "1.4.0", | ||
"description": "Tiny, zero-dependency router with route param and query parsing.", | ||
@@ -5,0 +5,0 @@ "main": "./dist/itty-router.min.js", |
@@ -9,6 +9,4 @@ ![Logo][logo-image] | ||
It's an itty bitty router. Like... super tiny, with zero dependencies. For reals. | ||
It's an itty bitty router, designed for Express.js-like routing within [Cloudflare Workers](https://developers.cloudflare.com/workers/) (or any ServiceWorker). Like... it's super tiny, with zero dependencies. For reals. | ||
Did we mention it supports route/query params like in Express.js and was built specifically for use in Workers (e.g. [Cloudflare Workers](https://developers.cloudflare.com/workers/))? | ||
## Installation | ||
@@ -20,16 +18,36 @@ | ||
or if you've been transported back to 2017... | ||
# Example | ||
```js | ||
import { Router } from 'itty-router' | ||
// create a router | ||
const router = Router() // this is a Proxy, not a class | ||
// GET index | ||
router.get('/foo', () => new Response('Foo Index!')) | ||
// GET item | ||
router.get('/foo/:id.:format?', request => { | ||
const { id, format = 'csv' } = request.params | ||
return new Response(`Getting item ${id} in ${format} format.`) | ||
} | ||
// 404/Missing as final catch-all route | ||
router.get('*', () => new Response('Not Found.', { status: 404 })) | ||
// attach the router handle to the event handler | ||
addEventListener('fetch', event => | ||
event.respondWith(router.handle(event.request)) | ||
) | ||
``` | ||
npm install itty-router | ||
``` | ||
## Features | ||
- [x] tiny (~430 bytes) | ||
- [x] zero dependencies! | ||
- [x] dead-simple usage | ||
- [x] route params, with optionals (e.g. `/api/:foo/:id?`) | ||
- [x] bonus query parsing (e.g. `?page=3`) | ||
- [x] tiny (~430 bytes) with zero dependencies | ||
- [x] route params, with optionals (e.g. `/api/:foo/:id?.:format?`) | ||
- [x] bonus query parsing (e.g. `?page=3&foo-bar`) | ||
- [x] adds params & query to request: `{ params: { foo: 'bar' }, query: { page: '3' }}` | ||
- [x] multiple (sync or async) [middleware handlers](#multiple-route-handlers-as-middleware) per route for passthrough logic, auth, errors, etc | ||
- [x] handler functions "stop" at the first handler to return anything at all | ||
- [x] extendable via Proxies | ||
- [x] handler functions "stop" at the first handler to return | ||
- [x] supports [nested routers](#nested-routers) | ||
@@ -40,38 +58,2 @@ - [x] supports [base path](#base-path) option to prefix all routes | ||
# Examples | ||
### Kitchen Sink | ||
```js | ||
import { Router } from 'itty-router' | ||
// create a Router | ||
const router = Router() | ||
// basic GET route (with optional ? flag)... delivers route params and query params as objects to handler | ||
router.get('/todos/:id?', ({ params, query }) => | ||
console.log('matches /todos or /todos/13', `id=${params.id}`, `limit=${query.limit}`) | ||
) | ||
// first match always wins, so be careful with order of registering routes | ||
router | ||
.get('/todos/oops', () => console.log('you will never see this, thanks to upstream /todos/:id?')) | ||
.get('/features/chainable-route-declaration', () => console.log('yep!')) | ||
.get('/features/:optionals?', () => console.log('check!')) // will match /features and /features/14 both | ||
// works with POST, DELETE, PATCH, etc | ||
router.post('/todos', () => console.log('posted a todo')) | ||
// ...or any other method we haven't yet thought of (thanks to @mvasigh implementation of Proxy <3) | ||
router.future('/todos', () => console.log(`this caught using the FUTURE method!`)) | ||
// then handle a request! | ||
router.handle({ method: 'GET', url: 'https://foo.com/todos/13?foo=bar' }) | ||
// ...and viola! the following payload/context is passed to the matching route handler: | ||
// { | ||
// params: { id: '13' }, | ||
// query: { foo: 'bar' }, | ||
// ...whatever else was in the original request object/class (e.g. method, url, etc) | ||
// } | ||
``` | ||
# Usage | ||
@@ -112,19 +94,3 @@ ### 1. Create a Router | ||
# Examples | ||
### Within a Cloudflare Function | ||
```js | ||
import { Router } from 'itty-router' | ||
// create a router | ||
const router = Router() // note the intentional lack of "new" | ||
// register some routes | ||
router | ||
.get('/foo', () => new Response('Foo Index!')) | ||
.get('/foo/:id', ({ params }) => new Response(`Details for item ${params.id}.`)) | ||
.get('*', () => new Response('Not Found.', { status: 404 })) | ||
// attach the router handle to the event handler | ||
addEventListener('fetch', event => event.respondWith(router.handle(event.request))) | ||
``` | ||
### Multiple Route Handlers as Middleware | ||
@@ -131,0 +97,0 @@ ###### Note: Any of these handlers may be awaitable async functions! |
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
15047
217