itty-router 2.5.0 → 2.5.3
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/CHANGELOG.md +4 -1
- package/README.md +58 -35
- package/dist/itty-router.d.ts +1 -1
- package/dist/itty-router.min.js +1 -1
- package/package.json +10 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
## Changelog
|
|
2
2
|
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.
|
|
3
3
|
|
|
4
|
-
[@SupremeTechnopriest)(https://github.com/SupremeTechnopriest) - improved TypeScript support and documentation! :D
|
|
4
|
+
[@SupremeTechnopriest)(https://github.com/SupremeTechnopriest) - improved TypeScript support and documentation! :D\
|
|
5
|
+
|
|
6
|
+
- **v2.5.2** - fixes issue with arrow functions in CommonJS named exports (rare issue)
|
|
7
|
+
- **v2.5.1** - added context to Cloudflare ES module syntax example (credit [@jcapogna](https://github.com/jcapogna))
|
|
5
8
|
- **v2.5.0** - improved TypeScript docs/types (thanks [@SupremeTechnopriest](https://github.com/SupremeTechnopriest)!)
|
|
6
9
|
- **v2.4.9** - fixed the cursed "optional" file format capturing bug - RIP all the bytes lost
|
|
7
10
|
- **v2.4.6** - fixed README issues
|
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
<img alt="Join the discussion on Github" src="https://img.shields.io/badge/Github%20Discussions%20%26%20Support-Chat%20now!-blue" />
|
|
20
20
|
</a>-->
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Tiny, zero-dependency router with route param and query parsing - built for [Cloudflare Workers](https://developers.cloudflare.com/workers/), but works everywhere!
|
|
23
23
|
|
|
24
24
|
### Addons & Related Libraries
|
|
25
25
|
1. [itty-router-extras](https://www.npmjs.com/package/itty-router-extras) - adds quality-of-life improvements and utility functions for simplifying request/response code (e.g. middleware, cookies, body parsing, json handling, errors, and an itty version with automatic exception handling)!
|
|
@@ -27,9 +27,9 @@ It's an itty bitty router, designed for express-like routing within [Cloudflare
|
|
|
27
27
|
|
|
28
28
|
## Features
|
|
29
29
|
- [x] Tiny ([~500 bytes](https://bundlephobia.com/package/itty-router) compressed), with zero dependencies.
|
|
30
|
-
- [x] [TypeScript support](#typescript)
|
|
31
|
-
- [x]
|
|
32
|
-
- [x]
|
|
30
|
+
- [x] [Fully typed/TypeScript support](#typescript)
|
|
31
|
+
- [x] Supports sync/async handlers/middleware.
|
|
32
|
+
- [x] Parses route params, with wildcards and optionals (e.g. `/api/:collection/:id?`)
|
|
33
33
|
- [x] Query parsing (e.g. `?page=3&foo=bar`)
|
|
34
34
|
- [x] [Middleware support](#middleware). Any number of sync/async handlers may be passed to a route.
|
|
35
35
|
- [x] [Nestable](#nested-routers-with-404-handling). Supports nesting routers for API branching.
|
|
@@ -105,9 +105,9 @@ router.get('/todos/:user/:item?', (req) => {
|
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
### 3. Handle Incoming Request(s)
|
|
108
|
-
##### `async router.handle(request.proxy: Proxy || request: Request, ...anything else)
|
|
108
|
+
##### `async router.handle(request.proxy: Proxy || request: Request, ...anything else) => Promise<any>`
|
|
109
109
|
Requests (doesn't have to be a real Request class) should have both a **method** and full **url**.
|
|
110
|
-
The `handle` method will then return the first matching route handler that returns something (or nothing at all if no match).
|
|
110
|
+
The `handle` method will then return a Promise, resolving with the first matching route handler that returns something (or nothing at all if no match).
|
|
111
111
|
|
|
112
112
|
```js
|
|
113
113
|
router.handle({
|
|
@@ -283,16 +283,33 @@ router.get('/todos/:id.:format?', request => {
|
|
|
283
283
|
```
|
|
284
284
|
|
|
285
285
|
### Cloudflare ES6 Module Syntax (required for Durable Objects) <a id="cf-es6-module-syntax"></a>
|
|
286
|
+
See https://developers.cloudflare.com/workers/runtime-apis/fetch-event#syntax-module-worker
|
|
286
287
|
```js
|
|
288
|
+
import { Router } from 'itty-router'
|
|
289
|
+
|
|
287
290
|
const router = Router()
|
|
288
291
|
|
|
289
|
-
router.get('/', (request, env) => {
|
|
292
|
+
router.get('/', (request, env, context) => {
|
|
290
293
|
// now have access to the env (where CF bindings like durables, KV, etc now are)
|
|
291
294
|
})
|
|
292
295
|
|
|
293
296
|
export default {
|
|
294
297
|
fetch: router.handle // yep, it's this easy.
|
|
295
298
|
}
|
|
299
|
+
|
|
300
|
+
// alternative advanced/manual approach for downstream control
|
|
301
|
+
export default {
|
|
302
|
+
fetch: (...args) => router
|
|
303
|
+
.handle(...args)
|
|
304
|
+
.then(response => {
|
|
305
|
+
// can modify response here before final return, e.g. CORS headers
|
|
306
|
+
|
|
307
|
+
return response
|
|
308
|
+
})
|
|
309
|
+
.catch(err => {
|
|
310
|
+
// and do something with the errors here, like logging, error status, etc
|
|
311
|
+
})
|
|
312
|
+
}
|
|
296
313
|
```
|
|
297
314
|
|
|
298
315
|
### Extending itty router
|
|
@@ -435,7 +452,7 @@ const router = Router<Request, IMethods>() // Valid
|
|
|
435
452
|
const router = Router<void, IMethods>() // Valid
|
|
436
453
|
```
|
|
437
454
|
|
|
438
|
-
The router will also accept any string as a method, not just those provided on the `TMethods` type.
|
|
455
|
+
The router will also accept any string as a method, not just those provided on the `TMethods` type.
|
|
439
456
|
|
|
440
457
|
```ts
|
|
441
458
|
import { Router, Route } from 'itty-router'
|
|
@@ -490,36 +507,38 @@ router.puppy('/', request => {}) // Strongly typed
|
|
|
490
507
|
|
|
491
508
|
### The Entire Code (for more legibility, [see src on GitHub](https://github.com/kwhitley/itty-router/blob/v2.x/src/itty-router.js))
|
|
492
509
|
```js
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
q.
|
|
516
|
-
|
|
517
|
-
|
|
510
|
+
function Router({ base = '', routes = [] } = {}) {
|
|
511
|
+
return {
|
|
512
|
+
__proto__: new Proxy({}, {
|
|
513
|
+
get: (t, k, c) => (p, ...H) =>
|
|
514
|
+
routes.push([
|
|
515
|
+
k.toUpperCase(),
|
|
516
|
+
RegExp(`^${(base + p)
|
|
517
|
+
.replace(/(\/?)\*/g, '($1.*)?')
|
|
518
|
+
.replace(/\/$/, '')
|
|
519
|
+
.replace(/:(\w+)(\?)?(\.)?/g, '$2(?<$1>[^/]+)$2$3')
|
|
520
|
+
.replace(/\.(?=[\w(])/, '\\.')
|
|
521
|
+
.replace(/\)\.\?\(([^\[]+)\[\^/g, '?)\\.?($1(?<=\\.)[^\\.') // RIP all the bytes lost :'(
|
|
522
|
+
}/*$`),
|
|
523
|
+
H,
|
|
524
|
+
]) && c
|
|
525
|
+
}),
|
|
526
|
+
routes,
|
|
527
|
+
async handle (q, ...a) {
|
|
528
|
+
let s, m,
|
|
529
|
+
u = new URL(q.url)
|
|
530
|
+
q.query = Object.fromEntries(u.searchParams)
|
|
531
|
+
for (let [M, p, H] of routes) {
|
|
532
|
+
if ((M === q.method || M === 'ALL') && (m = u.pathname.match(p))) {
|
|
533
|
+
q.params = m.groups
|
|
534
|
+
for (let h of H) {
|
|
535
|
+
if ((s = await h(q.proxy || q, ...a)) !== undefined) return s
|
|
536
|
+
}
|
|
518
537
|
}
|
|
519
538
|
}
|
|
520
539
|
}
|
|
521
540
|
}
|
|
522
|
-
}
|
|
541
|
+
}
|
|
523
542
|
```
|
|
524
543
|
|
|
525
544
|
## Special Thanks
|
|
@@ -558,4 +577,8 @@ These folks are the real heroes, making open source the powerhouse that it is!
|
|
|
558
577
|
- [@technoyes](https://github.com/technoyes) - three kind-of-a-big-deal errors fixed. Imagine the look on my face... thanks man!! :)
|
|
559
578
|
- [@roojay520](https://github.com/roojay520) - TS interface fixes
|
|
560
579
|
#### Documentation
|
|
561
|
-
- [@arunsathiya](https://github.com/arunsathiya),
|
|
580
|
+
- [@arunsathiya](https://github.com/arunsathiya),
|
|
581
|
+
[@poacher2k](https://github.com/poacher2k),
|
|
582
|
+
[@ddarkr](https://github.com/ddarkr),
|
|
583
|
+
[@kclauson](https://github.com/kclauson),
|
|
584
|
+
[@jcapogna](https://github.com/jcapogna)
|
package/dist/itty-router.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ export interface IHTTPMethods {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
export type Router<TRequest = Request, TMethods = {}> = {
|
|
45
|
-
handle: (request: TRequest, ...extra: any) => any
|
|
45
|
+
handle: (request: TRequest, ...extra: any) => Promise<any>
|
|
46
46
|
routes: RouteEntry<TRequest>[]
|
|
47
47
|
all: Route
|
|
48
48
|
} & TMethods & {
|
package/dist/itty-router.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports={Router:({base:
|
|
1
|
+
module.exports={Router:function({base:t="",routes:n=[]}={}){return{__proto__:new Proxy({},{get:(e,a,o)=>(e,...r)=>n.push([a.toUpperCase(),RegExp(`^${(t+e).replace(/(\/?)\*/g,"($1.*)?").replace(/\/$/,"").replace(/:(\w+)(\?)?(\.)?/g,"$2(?<$1>[^/]+)$2$3").replace(/\.(?=[\w(])/,"\\.").replace(/\)\.\?\(([^\[]+)\[\^/g,"?)\\.?($1(?<=\\.)[^\\.")}/*$`),r])&&o}),routes:n,async handle(e,...r){let a,o,t=new URL(e.url);e.query=Object.fromEntries(t.searchParams);for(var[p,s,u]of n)if((p===e.method||"ALL"===p)&&(o=t.pathname.match(s))){e.params=o.groups;for(var c of u)if(void 0!==(a=await c(e.proxy||e,...r)))return a}}}}};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "itty-router",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.3",
|
|
4
4
|
"description": "Tiny, zero-dependency router with route param and query parsing - built for Cloudflare Workers, but works everywhere!",
|
|
5
5
|
"main": "./dist/itty-router.min.js",
|
|
6
6
|
"types": "./dist/itty-router.d.ts",
|
|
@@ -62,20 +62,19 @@
|
|
|
62
62
|
},
|
|
63
63
|
"homepage": "https://itty-router.dev",
|
|
64
64
|
"devDependencies": {
|
|
65
|
-
"@vitejs/plugin-vue": "^
|
|
66
|
-
"@vue/compiler-sfc": "^3.2.
|
|
67
|
-
"chalk": "^4.1.2",
|
|
65
|
+
"@vitejs/plugin-vue": "^2.2.4",
|
|
66
|
+
"@vue/compiler-sfc": "^3.2.31",
|
|
68
67
|
"coveralls": "^3.1.1",
|
|
69
|
-
"eslint": "^
|
|
70
|
-
"eslint-plugin-jest": "^
|
|
71
|
-
"fs-extra": "^10.0.
|
|
68
|
+
"eslint": "^8.11.0",
|
|
69
|
+
"eslint-plugin-jest": "^26.1.2",
|
|
70
|
+
"fs-extra": "^10.0.1",
|
|
72
71
|
"gzip-size": "^6.0.0",
|
|
73
72
|
"isomorphic-fetch": "^3.0.0",
|
|
74
|
-
"jest": "^27.
|
|
73
|
+
"jest": "^27.5.1",
|
|
75
74
|
"rimraf": "^3.0.2",
|
|
76
|
-
"uglify-js": "^3.
|
|
77
|
-
"vite": "^2.
|
|
78
|
-
"yarn": "^1.22.
|
|
75
|
+
"uglify-js": "^3.15.3",
|
|
76
|
+
"vite": "^2.8.6",
|
|
77
|
+
"yarn": "^1.22.18",
|
|
79
78
|
"yarn-release": "^1.10.3"
|
|
80
79
|
}
|
|
81
80
|
}
|