hono 2.1.4 → 2.2.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 (145) hide show
  1. package/README.md +13 -14
  2. package/dist/cjs/compose.js +48 -0
  3. package/dist/cjs/context.js +147 -0
  4. package/dist/cjs/hono.js +152 -0
  5. package/dist/cjs/index.js +13 -0
  6. package/dist/cjs/middleware/basic-auth/index.js +48 -0
  7. package/dist/cjs/middleware/bearer-auth/index.js +57 -0
  8. package/dist/cjs/middleware/cache/index.js +32 -0
  9. package/dist/cjs/middleware/compress/index.js +19 -0
  10. package/dist/cjs/middleware/cors/index.js +75 -0
  11. package/dist/cjs/middleware/etag/index.js +27 -0
  12. package/dist/cjs/middleware/html/index.js +36 -0
  13. package/dist/cjs/middleware/jsx/index.js +193 -0
  14. package/dist/cjs/middleware/jsx/jsx-dev-runtime.js +10 -0
  15. package/dist/cjs/middleware/jsx/jsx-runtime.js +7 -0
  16. package/dist/cjs/middleware/jwt/index.js +63 -0
  17. package/dist/cjs/middleware/logger/index.js +49 -0
  18. package/dist/cjs/middleware/powered-by/index.js +10 -0
  19. package/dist/cjs/middleware/pretty-json/index.js +11 -0
  20. package/dist/cjs/middleware/serve-static/bun.js +41 -0
  21. package/dist/cjs/middleware/serve-static/index.js +5 -0
  22. package/dist/cjs/middleware/serve-static/serve-static.js +40 -0
  23. package/dist/cjs/middleware/validator/index.js +5 -0
  24. package/dist/cjs/middleware/validator/middleware.js +56 -0
  25. package/dist/cjs/middleware/validator/rule.js +66 -0
  26. package/dist/cjs/middleware/validator/sanitizer.js +6 -0
  27. package/dist/cjs/middleware/validator/validator.js +195 -0
  28. package/dist/cjs/request.js +120 -0
  29. package/dist/cjs/router/reg-exp-router/index.js +5 -0
  30. package/dist/cjs/router/reg-exp-router/node.js +108 -0
  31. package/dist/cjs/router/reg-exp-router/router.js +161 -0
  32. package/dist/cjs/router/reg-exp-router/trie.js +42 -0
  33. package/dist/cjs/router/smart-router/index.js +5 -0
  34. package/dist/cjs/router/smart-router/router.js +57 -0
  35. package/dist/cjs/router/static-router/index.js +5 -0
  36. package/dist/cjs/router/static-router/router.js +72 -0
  37. package/dist/cjs/router/trie-router/index.js +5 -0
  38. package/dist/cjs/router/trie-router/node.js +175 -0
  39. package/dist/cjs/router/trie-router/router.js +24 -0
  40. package/dist/cjs/router.js +9 -0
  41. package/dist/cjs/utils/body.js +18 -0
  42. package/dist/cjs/utils/buffer.js +39 -0
  43. package/dist/cjs/utils/cloudflare.js +39 -0
  44. package/dist/cjs/utils/cookie.js +40 -0
  45. package/dist/cjs/utils/crypto.js +53 -0
  46. package/dist/cjs/utils/encode.js +80 -0
  47. package/dist/cjs/utils/filepath.js +25 -0
  48. package/dist/cjs/utils/html.js +38 -0
  49. package/dist/cjs/utils/http-status.js +50 -0
  50. package/dist/cjs/utils/json.js +22 -0
  51. package/dist/cjs/utils/jwt/index.js +27 -0
  52. package/dist/cjs/utils/jwt/jwt.js +101 -0
  53. package/dist/cjs/utils/jwt/types.js +49 -0
  54. package/dist/cjs/utils/mime.js +92 -0
  55. package/dist/cjs/utils/url.js +94 -0
  56. package/dist/compose.d.ts +2 -2
  57. package/dist/compose.js +3 -7
  58. package/dist/context.d.ts +14 -9
  59. package/dist/context.js +55 -25
  60. package/dist/hono.d.ts +28 -27
  61. package/dist/hono.js +22 -23
  62. package/dist/index.js +3 -6
  63. package/dist/middleware/basic-auth/index.d.ts +2 -3
  64. package/dist/middleware/basic-auth/index.js +7 -11
  65. package/dist/middleware/bearer-auth/index.d.ts +2 -3
  66. package/dist/middleware/bearer-auth/index.js +4 -12
  67. package/dist/middleware/cache/index.d.ts +2 -3
  68. package/dist/middleware/cache/index.js +1 -5
  69. package/dist/middleware/compress/index.d.ts +2 -3
  70. package/dist/middleware/compress/index.js +1 -5
  71. package/dist/middleware/cors/index.d.ts +3 -4
  72. package/dist/middleware/cors/index.js +16 -6
  73. package/dist/middleware/etag/index.d.ts +2 -3
  74. package/dist/middleware/etag/index.js +3 -7
  75. package/dist/middleware/html/index.js +6 -11
  76. package/dist/middleware/jsx/index.js +9 -15
  77. package/dist/middleware/jsx/jsx-dev-runtime.js +3 -7
  78. package/dist/middleware/jsx/jsx-runtime.js +2 -7
  79. package/dist/middleware/jwt/index.d.ts +2 -3
  80. package/dist/middleware/jwt/index.js +3 -7
  81. package/dist/middleware/logger/index.d.ts +2 -3
  82. package/dist/middleware/logger/index.js +3 -7
  83. package/dist/middleware/powered-by/index.d.ts +2 -3
  84. package/dist/middleware/powered-by/index.js +1 -5
  85. package/dist/middleware/pretty-json/index.d.ts +2 -3
  86. package/dist/middleware/pretty-json/index.js +1 -5
  87. package/dist/middleware/serve-static/bun.d.ts +2 -3
  88. package/dist/middleware/serve-static/bun.js +18 -19
  89. package/dist/middleware/serve-static/index.js +1 -5
  90. package/dist/middleware/serve-static/module.d.mts +1 -1
  91. package/dist/middleware/serve-static/serve-static.d.ts +2 -3
  92. package/dist/middleware/serve-static/serve-static.js +7 -11
  93. package/dist/middleware/validator/index.d.ts +2 -0
  94. package/dist/middleware/validator/index.js +2 -0
  95. package/dist/middleware/validator/middleware.d.ts +21 -0
  96. package/dist/middleware/validator/middleware.js +52 -0
  97. package/dist/middleware/validator/rule.d.ts +21 -0
  98. package/dist/middleware/validator/rule.js +63 -0
  99. package/dist/middleware/validator/sanitizer.d.ts +3 -0
  100. package/dist/middleware/validator/sanitizer.js +3 -0
  101. package/dist/middleware/validator/validator.d.ts +75 -0
  102. package/dist/middleware/validator/validator.js +186 -0
  103. package/dist/request.d.ts +15 -5
  104. package/dist/request.js +58 -28
  105. package/dist/router/reg-exp-router/index.js +1 -5
  106. package/dist/router/reg-exp-router/node.d.ts +1 -3
  107. package/dist/router/reg-exp-router/node.js +21 -17
  108. package/dist/router/reg-exp-router/router.d.ts +3 -27
  109. package/dist/router/reg-exp-router/router.js +105 -315
  110. package/dist/router/reg-exp-router/trie.d.ts +0 -4
  111. package/dist/router/reg-exp-router/trie.js +4 -8
  112. package/dist/router/smart-router/index.d.ts +1 -0
  113. package/dist/router/smart-router/index.js +1 -0
  114. package/dist/router/smart-router/router.d.ts +9 -0
  115. package/dist/router/smart-router/router.js +53 -0
  116. package/dist/router/static-router/index.d.ts +1 -0
  117. package/dist/router/static-router/index.js +1 -0
  118. package/dist/router/static-router/router.d.ts +8 -0
  119. package/dist/router/static-router/router.js +68 -0
  120. package/dist/router/trie-router/index.js +1 -5
  121. package/dist/router/trie-router/node.js +7 -11
  122. package/dist/router/trie-router/router.js +11 -7
  123. package/dist/router.d.ts +3 -0
  124. package/dist/router.js +5 -5
  125. package/dist/utils/body.d.ts +2 -1
  126. package/dist/utils/body.js +1 -5
  127. package/dist/utils/buffer.d.ts +1 -1
  128. package/dist/utils/buffer.js +5 -11
  129. package/dist/utils/cloudflare.d.ts +1 -1
  130. package/dist/utils/cloudflare.js +1 -5
  131. package/dist/utils/cookie.js +2 -7
  132. package/dist/utils/crypto.js +8 -15
  133. package/dist/utils/encode.js +10 -20
  134. package/dist/utils/filepath.js +1 -5
  135. package/dist/utils/html.js +1 -5
  136. package/dist/utils/http-status.js +1 -5
  137. package/dist/utils/json.d.ts +1 -0
  138. package/dist/utils/json.js +18 -0
  139. package/dist/utils/jwt/index.js +1 -27
  140. package/dist/utils/jwt/jwt.js +22 -28
  141. package/dist/utils/jwt/types.js +8 -16
  142. package/dist/utils/mime.js +1 -5
  143. package/dist/utils/url.d.ts +1 -1
  144. package/dist/utils/url.js +18 -22
  145. package/package.json +122 -35
package/README.md CHANGED
@@ -21,7 +21,7 @@
21
21
  [![GitHub commit activity](https://img.shields.io/github/commit-activity/m/honojs/hono)](https://github.com/honojs/hono/pulse)
22
22
  [![GitHub last commit](https://img.shields.io/github/last-commit/honojs/hono)](https://github.com/honojs/hono/commits/main)
23
23
  [![Deno badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fdeno-visualizer.danopia.net%2Fshields%2Flatest-version%2Fx%2Fhono%2Fmod.ts)](https://doc.deno.land/https/deno.land/x/hono/mod.ts)
24
- [![Discord badge](https://img.shields.io/discord/1011308539819597844?label=Discord&logo=Discord)](https://discord.gg/KVYKWmfD)
24
+ [![Discord badge](https://img.shields.io/discord/1011308539819597844?label=Discord&logo=Discord)](https://discord.gg/KMh2eNSdxV)
25
25
 
26
26
  Hono - _**[炎] means flame🔥 in Japanese**_ - is a small, simple, and ultrafast web framework for Cloudflare Workers, Deno, Bun, and others.
27
27
 
@@ -36,24 +36,23 @@ export default app
36
36
 
37
37
  ## Features
38
38
 
39
- - **Ultrafast** - the router does not use linear loops.
40
- - **Zero-dependencies** - using only Service Worker and Web Standard API.
41
- - **Middleware** - built-in middleware, custom middleware, and third-party middleware.
42
- - **TypeScript** - first-class TypeScript support.
43
- - **Multi-platform** - works on Cloudflare Workers, Fastly Compute@Edge, Deno, or Bun.
39
+ - **Ultrafast** - The routers are really smart. Not using linear loops. The fastest one will be selected from three routers.
40
+ - **Zero-dependencies** - Using only Web Standard API. Does not depend on other npm or Deno libraries.
41
+ - **Middleware** - Hono has built-in middleware, custom middleware, and third-party middleware. Batteries included.
42
+ - **TypeScript** - First-class TypeScript support. Now, we've got "Types".
43
+ - **Multi-runtime** - Works on Cloudflare Workers, Fastly Compute@Edge, Deno, Bun, or Node.js. The same code runs on all platforms.
44
44
 
45
45
  ## Benchmarks
46
46
 
47
47
  **Hono is fastest**, compared to other routers for Cloudflare Workers.
48
48
 
49
49
  ```plain
50
- hono - trie-router(default) x 482,004 ops/sec ±5.00% (79 runs sampled)
51
- hono - regexp-router x 604,006 ops/sec ±4.80% (81 runs sampled)
52
- itty-router x 203,623 ops/sec ±2.10% (94 runs sampled)
53
- sunder x 306,457 ops/sec ±2.49% (89 runs sampled)
54
- worktop x 189,450 ops/sec ±3.14% (88 runs sampled)
55
- Fastest is hono - regexp-router
56
- ✨ Done in 36.79s.
50
+ Hono x 616,464 ops/sec ±4.76% (83 runs sampled)
51
+ itty-router x 203,074 ops/sec ±3.66% (88 runs sampled)
52
+ sunder x 314,306 ops/sec ±2.28% (87 runs sampled)
53
+ worktop x 194,111 ops/sec ±2.78% (81 runs sampled)
54
+ Fastest is Hono
55
+ ✨ Done in 30.77s.
57
56
  ```
58
57
 
59
58
  ## Documentation
@@ -66,7 +65,7 @@ Migration guide is available on [docs/MIGRATION.md](docs/MIGRATION.md).
66
65
 
67
66
  ## Communication
68
67
 
69
- [Twitter](https://twitter.com/honojs) and [Discord channel](https://discord.gg/KVYKWmfD) are available.
68
+ [Twitter](https://twitter.com/honojs) and [Discord channel](https://discord.gg/KMh2eNSdxV) are available.
70
69
 
71
70
  ## Contributing
72
71
 
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compose = void 0;
4
+ const context_1 = require("./context");
5
+ // Based on the code in the MIT licensed `koa-compose` package.
6
+ const compose = (middleware, onNotFound) => {
7
+ const middlewareLength = middleware.length;
8
+ return (context, next) => {
9
+ let index = -1;
10
+ return dispatch(0);
11
+ function dispatch(i) {
12
+ if (i <= index) {
13
+ throw new Error('next() called multiple times');
14
+ }
15
+ let handler = middleware[i];
16
+ index = i;
17
+ if (i === middlewareLength && next)
18
+ handler = next;
19
+ let res;
20
+ if (!handler) {
21
+ if (context instanceof context_1.HonoContext && context.finalized === false && onNotFound) {
22
+ res = onNotFound(context);
23
+ }
24
+ }
25
+ else {
26
+ res = handler(context, () => {
27
+ const dispatchRes = dispatch(i + 1);
28
+ return dispatchRes instanceof Promise ? dispatchRes : Promise.resolve(dispatchRes);
29
+ });
30
+ }
31
+ if (!(res instanceof Promise)) {
32
+ if (res && context.finalized === false) {
33
+ context.res = res;
34
+ }
35
+ return context;
36
+ }
37
+ else {
38
+ return res.then((res) => {
39
+ if (res && context.finalized === false) {
40
+ context.res = res;
41
+ }
42
+ return context;
43
+ });
44
+ }
45
+ }
46
+ };
47
+ };
48
+ exports.compose = compose;
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HonoContext = void 0;
4
+ const cookie_1 = require("./utils/cookie");
5
+ class HonoContext {
6
+ constructor(req, env = undefined, executionCtx = undefined, notFoundHandler = () => new Response()) {
7
+ this._status = 200;
8
+ this._pretty = false;
9
+ this._prettySpace = 2;
10
+ this._executionCtx = executionCtx;
11
+ this.req = req;
12
+ this.env = env || {};
13
+ this.notFoundHandler = notFoundHandler;
14
+ this.finalized = false;
15
+ }
16
+ get event() {
17
+ if (this._executionCtx instanceof FetchEvent) {
18
+ return this._executionCtx;
19
+ }
20
+ else {
21
+ throw Error('This context has no FetchEvent');
22
+ }
23
+ }
24
+ get executionCtx() {
25
+ if (this._executionCtx) {
26
+ return this._executionCtx;
27
+ }
28
+ else {
29
+ throw Error('This context has no ExecutionContext');
30
+ }
31
+ }
32
+ get res() {
33
+ return (this._res || (this._res = new Response('404 Not Found', { status: 404 })));
34
+ }
35
+ set res(_res) {
36
+ this._res = _res;
37
+ this.finalized = true;
38
+ }
39
+ header(name, value, options) {
40
+ this._headers || (this._headers = {});
41
+ const key = name.toLowerCase();
42
+ let shouldAppend = false;
43
+ if (options && options.append) {
44
+ const vAlreadySet = this._headers[key];
45
+ if (vAlreadySet && vAlreadySet.length) {
46
+ shouldAppend = true;
47
+ }
48
+ }
49
+ if (shouldAppend) {
50
+ this._headers[key].push(value);
51
+ }
52
+ else {
53
+ this._headers[key] = [value];
54
+ }
55
+ if (this.finalized) {
56
+ if (shouldAppend) {
57
+ this.res.headers.append(name, value);
58
+ }
59
+ else {
60
+ this.res.headers.set(name, value);
61
+ }
62
+ }
63
+ }
64
+ status(status) {
65
+ this._status = status;
66
+ }
67
+ set(key, value) {
68
+ this._map || (this._map = {});
69
+ this._map[key] = value;
70
+ }
71
+ get(key) {
72
+ if (!this._map) {
73
+ return undefined;
74
+ }
75
+ return this._map[key];
76
+ }
77
+ pretty(prettyJSON, space = 2) {
78
+ this._pretty = prettyJSON;
79
+ this._prettySpace = space;
80
+ }
81
+ newResponse(data, status, headers = {}) {
82
+ return new Response(data, {
83
+ status: status || this._status || 200,
84
+ headers: this._finalizeHeaders(headers),
85
+ });
86
+ }
87
+ _finalizeHeaders(incomingHeaders) {
88
+ const finalizedHeaders = [];
89
+ const headersKv = this._headers || {};
90
+ // If Response is already set
91
+ if (this._res) {
92
+ this._res.headers.forEach((v, k) => {
93
+ headersKv[k] = [v];
94
+ });
95
+ }
96
+ for (const key of Object.keys(incomingHeaders)) {
97
+ const value = incomingHeaders[key];
98
+ if (typeof value === 'string') {
99
+ finalizedHeaders.push([key, value]);
100
+ }
101
+ else {
102
+ for (const v of value) {
103
+ finalizedHeaders.push([key, v]);
104
+ }
105
+ }
106
+ delete headersKv[key];
107
+ }
108
+ for (const key of Object.keys(headersKv)) {
109
+ for (const value of headersKv[key]) {
110
+ const kv = [key, value];
111
+ finalizedHeaders.push(kv);
112
+ }
113
+ }
114
+ return finalizedHeaders;
115
+ }
116
+ body(data, status = this._status, headers = {}) {
117
+ return this.newResponse(data, status, headers);
118
+ }
119
+ text(text, status = this._status, headers = {}) {
120
+ headers['content-type'] = 'text/plain; charset=UTF-8';
121
+ return this.body(text, status, headers);
122
+ }
123
+ json(object, status = this._status, headers = {}) {
124
+ const body = this._pretty
125
+ ? JSON.stringify(object, null, this._prettySpace)
126
+ : JSON.stringify(object);
127
+ headers['content-type'] = 'application/json; charset=UTF-8';
128
+ return this.body(body, status, headers);
129
+ }
130
+ html(html, status = this._status, headers = {}) {
131
+ headers['content-type'] = 'text/html; charset=UTF-8';
132
+ return this.body(html, status, headers);
133
+ }
134
+ redirect(location, status = 302) {
135
+ return this.newResponse(null, status, {
136
+ Location: location,
137
+ });
138
+ }
139
+ cookie(name, value, opt) {
140
+ const cookie = (0, cookie_1.serialize)(name, value, opt);
141
+ this.header('set-cookie', cookie, { append: true });
142
+ }
143
+ notFound() {
144
+ return this.notFoundHandler(this);
145
+ }
146
+ }
147
+ exports.HonoContext = HonoContext;
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Hono = void 0;
4
+ const compose_1 = require("./compose");
5
+ const context_1 = require("./context");
6
+ const request_1 = require("./request");
7
+ const router_1 = require("./router");
8
+ const router_2 = require("./router");
9
+ const reg_exp_router_1 = require("./router/reg-exp-router");
10
+ const smart_router_1 = require("./router/smart-router");
11
+ const static_router_1 = require("./router/static-router");
12
+ const trie_router_1 = require("./router/trie-router");
13
+ const url_1 = require("./utils/url");
14
+ function defineDynamicClass() {
15
+ return class {
16
+ };
17
+ }
18
+ class Hono extends defineDynamicClass() {
19
+ constructor(init = {}) {
20
+ super();
21
+ this.router = new smart_router_1.SmartRouter({
22
+ routers: [new static_router_1.StaticRouter(), new reg_exp_router_1.RegExpRouter(), new trie_router_1.TrieRouter()],
23
+ });
24
+ this.strict = true; // strict routing - default is true
25
+ this._tempPath = '';
26
+ this.path = '/';
27
+ this.routes = [];
28
+ this.notFoundHandler = (c) => {
29
+ return c.text('404 Not Found', 404);
30
+ };
31
+ this.errorHandler = (err, c) => {
32
+ console.error(`${err.stack || err.message}`);
33
+ const message = 'Internal Server Error';
34
+ return c.text(message, 500);
35
+ };
36
+ this.fetch = (request, Environment, executionCtx) => {
37
+ return this.dispatch(request, executionCtx, Environment);
38
+ };
39
+ (0, request_1.extendRequestPrototype)();
40
+ const allMethods = [...router_1.METHODS, router_2.METHOD_NAME_ALL_LOWERCASE];
41
+ allMethods.map((method) => {
42
+ this[method] = (args1, ...args) => {
43
+ if (typeof args1 === 'string') {
44
+ this.path = args1;
45
+ }
46
+ else {
47
+ this.addRoute(method, this.path, args1);
48
+ }
49
+ args.map((handler) => {
50
+ if (typeof handler !== 'string') {
51
+ this.addRoute(method, this.path, handler);
52
+ }
53
+ });
54
+ return this;
55
+ };
56
+ });
57
+ Object.assign(this, init);
58
+ }
59
+ route(path, app) {
60
+ this._tempPath = path;
61
+ if (app) {
62
+ app.routes.map((r) => {
63
+ this.addRoute(r.method, r.path, r.handler);
64
+ });
65
+ this._tempPath = '';
66
+ }
67
+ return this;
68
+ }
69
+ use(arg1, ...handlers) {
70
+ if (typeof arg1 === 'string') {
71
+ this.path = arg1;
72
+ }
73
+ else {
74
+ handlers.unshift(arg1);
75
+ }
76
+ handlers.map((handler) => {
77
+ this.addRoute(router_2.METHOD_NAME_ALL, this.path, handler);
78
+ });
79
+ return this;
80
+ }
81
+ onError(handler) {
82
+ this.errorHandler = handler;
83
+ return this;
84
+ }
85
+ notFound(handler) {
86
+ this.notFoundHandler = handler;
87
+ return this;
88
+ }
89
+ addRoute(method, path, handler) {
90
+ method = method.toUpperCase();
91
+ if (this._tempPath) {
92
+ path = (0, url_1.mergePath)(this._tempPath, path);
93
+ }
94
+ this.router.add(method, path, handler);
95
+ const r = { path: path, method: method, handler: handler };
96
+ this.routes.push(r);
97
+ }
98
+ matchRoute(method, path) {
99
+ return this.router.match(method, path);
100
+ }
101
+ async dispatch(request, eventOrExecutionCtx, env) {
102
+ const path = (0, url_1.getPathFromURL)(request.url, this.strict);
103
+ const method = request.method;
104
+ const result = this.matchRoute(method, path);
105
+ request.paramData = result?.params;
106
+ const c = new context_1.HonoContext(request, env, eventOrExecutionCtx, this.notFoundHandler);
107
+ // Do not `compose` if it has only one handler
108
+ if (result && result.handlers.length === 1) {
109
+ const handler = result.handlers[0];
110
+ try {
111
+ const res = handler(c, async () => { });
112
+ if (res) {
113
+ const awaited = res instanceof Promise ? await res : res;
114
+ if (awaited)
115
+ return awaited;
116
+ }
117
+ return this.notFoundHandler(c);
118
+ }
119
+ catch (err) {
120
+ if (err instanceof Error) {
121
+ return this.errorHandler(err, c);
122
+ }
123
+ throw err;
124
+ }
125
+ }
126
+ const handlers = result ? result.handlers : [this.notFoundHandler];
127
+ const composed = (0, compose_1.compose)(handlers, this.notFoundHandler);
128
+ let context;
129
+ try {
130
+ const tmp = composed(c);
131
+ context = tmp instanceof Promise ? await tmp : tmp;
132
+ if (!context.finalized) {
133
+ throw new Error('Context is not finalized. You may forget returning Response object or `await next()`');
134
+ }
135
+ }
136
+ catch (err) {
137
+ if (err instanceof Error) {
138
+ return this.errorHandler(err, c);
139
+ }
140
+ throw err;
141
+ }
142
+ return context.res;
143
+ }
144
+ handleEvent(event) {
145
+ return this.dispatch(event.request, event);
146
+ }
147
+ request(input, requestInit) {
148
+ const req = input instanceof Request ? input : new Request(input, requestInit);
149
+ return this.dispatch(req);
150
+ }
151
+ }
152
+ exports.Hono = Hono;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ // @denoify-ignore
3
+ // eslint-disable-next-line @typescript-eslint/triple-slash-reference
4
+ /// <reference path="./request.ts" /> Import "declare global" for the Request interface.
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Hono = void 0;
7
+ const hono_1 = require("./hono");
8
+ Object.defineProperty(exports, "Hono", { enumerable: true, get: function () { return hono_1.Hono; } });
9
+ hono_1.Hono.prototype.fire = function () {
10
+ addEventListener('fetch', (event) => {
11
+ void event.respondWith(this.handleEvent(event));
12
+ });
13
+ };
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.basicAuth = void 0;
4
+ const buffer_1 = require("../../utils/buffer");
5
+ const encode_1 = require("../../utils/encode");
6
+ const CREDENTIALS_REGEXP = /^ *(?:[Bb][Aa][Ss][Ii][Cc]) +([A-Za-z0-9._~+/-]+=*) *$/;
7
+ const USER_PASS_REGEXP = /^([^:]*):(.*)$/;
8
+ const auth = (req) => {
9
+ const match = CREDENTIALS_REGEXP.exec(req.headers.get('Authorization') || '');
10
+ if (!match) {
11
+ return undefined;
12
+ }
13
+ const userPass = USER_PASS_REGEXP.exec((0, encode_1.decodeBase64)(match[1]));
14
+ if (!userPass) {
15
+ return undefined;
16
+ }
17
+ return { username: userPass[1], password: userPass[2] };
18
+ };
19
+ const basicAuth = (options, ...users) => {
20
+ if (!options) {
21
+ throw new Error('basic auth middleware requires options for "username and password"');
22
+ }
23
+ if (!options.realm) {
24
+ options.realm = 'Secure Area';
25
+ }
26
+ users.unshift({ username: options.username, password: options.password });
27
+ return async (ctx, next) => {
28
+ const requestUser = auth(ctx.req);
29
+ if (requestUser) {
30
+ for (const user of users) {
31
+ const usernameEqual = await (0, buffer_1.timingSafeEqual)(user.username, requestUser.username, options.hashFunction);
32
+ const passwordEqual = await (0, buffer_1.timingSafeEqual)(user.password, requestUser.password, options.hashFunction);
33
+ if (usernameEqual && passwordEqual) {
34
+ await next();
35
+ return;
36
+ }
37
+ }
38
+ }
39
+ ctx.res = new Response('Unauthorized', {
40
+ status: 401,
41
+ headers: {
42
+ 'WWW-Authenticate': 'Basic realm="' + options.realm?.replace(/"/g, '\\"') + '"',
43
+ },
44
+ });
45
+ await next();
46
+ };
47
+ };
48
+ exports.basicAuth = basicAuth;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.bearerAuth = void 0;
4
+ const buffer_1 = require("../../utils/buffer");
5
+ const TOKEN_STRINGS = '[A-Za-z0-9._~+/-]+=*';
6
+ const PREFIX = 'Bearer';
7
+ const bearerAuth = (options) => {
8
+ if (!options.token) {
9
+ throw new Error('bearer auth middleware requires options for "token"');
10
+ }
11
+ if (!options.realm) {
12
+ options.realm = '';
13
+ }
14
+ if (!options.prefix) {
15
+ options.prefix = PREFIX;
16
+ }
17
+ const realm = options.realm?.replace(/"/g, '\\"');
18
+ return async (c, next) => {
19
+ const headerToken = c.req.headers.get('Authorization');
20
+ if (!headerToken) {
21
+ // No Authorization header
22
+ c.res = new Response('Unauthorized', {
23
+ status: 401,
24
+ headers: {
25
+ 'WWW-Authenticate': `${options.prefix} realm="` + realm + '"',
26
+ },
27
+ });
28
+ }
29
+ else {
30
+ const regexp = new RegExp('^' + options.prefix + ' +(' + TOKEN_STRINGS + ') *$');
31
+ const match = regexp.exec(headerToken);
32
+ if (!match) {
33
+ // Invalid Request
34
+ c.res = new Response('Bad Request', {
35
+ status: 400,
36
+ headers: {
37
+ 'WWW-Authenticate': `${options.prefix} error="invalid_request"`,
38
+ },
39
+ });
40
+ }
41
+ else {
42
+ const equal = await (0, buffer_1.timingSafeEqual)(options.token, match[1], options.hashFunction);
43
+ if (!equal) {
44
+ // Invalid Token
45
+ c.res = new Response('Unauthorized', {
46
+ status: 401,
47
+ headers: {
48
+ 'WWW-Authenticate': `${options.prefix} error="invalid_token"`,
49
+ },
50
+ });
51
+ }
52
+ }
53
+ }
54
+ await next();
55
+ };
56
+ };
57
+ exports.bearerAuth = bearerAuth;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cache = void 0;
4
+ const cache = (options) => {
5
+ if (options.wait === undefined) {
6
+ options.wait = false;
7
+ }
8
+ const addHeader = (response) => {
9
+ if (options.cacheControl)
10
+ response.headers.append('Cache-Control', options.cacheControl);
11
+ };
12
+ return async (c, next) => {
13
+ const key = c.req;
14
+ const cache = await caches.open(options.cacheName);
15
+ const response = await cache.match(key);
16
+ if (!response) {
17
+ await next();
18
+ addHeader(c.res);
19
+ const response = c.res.clone();
20
+ if (options.wait) {
21
+ await cache.put(key, response);
22
+ }
23
+ else {
24
+ c.executionCtx.waitUntil(cache.put(key, response));
25
+ }
26
+ }
27
+ else {
28
+ return response;
29
+ }
30
+ };
31
+ };
32
+ exports.cache = cache;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compress = void 0;
4
+ const compress = (options) => {
5
+ return async (ctx, next) => {
6
+ await next();
7
+ const accepted = ctx.req.headers.get('Accept-Encoding');
8
+ const pattern = options?.encoding ?? /gzip|deflate/;
9
+ const match = accepted?.match(pattern);
10
+ if (!accepted || !match || !ctx.res.body) {
11
+ return;
12
+ }
13
+ const encoding = match[0];
14
+ const stream = new CompressionStream(encoding);
15
+ ctx.res = new Response(ctx.res.body.pipeThrough(stream), ctx.res.clone());
16
+ ctx.res.headers.set('Content-Encoding', encoding);
17
+ };
18
+ };
19
+ exports.compress = compress;
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cors = void 0;
4
+ const cors = (options) => {
5
+ const defaults = {
6
+ origin: '*',
7
+ allowMethods: ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH'],
8
+ allowHeaders: [],
9
+ exposeHeaders: [],
10
+ };
11
+ const opts = {
12
+ ...defaults,
13
+ ...options,
14
+ };
15
+ const findAllowOrigin = ((optsOrigin) => {
16
+ if (typeof optsOrigin === 'string') {
17
+ return () => optsOrigin;
18
+ }
19
+ else if (typeof optsOrigin === 'function') {
20
+ return optsOrigin;
21
+ }
22
+ else {
23
+ return (origin) => (optsOrigin.includes(origin) ? origin : optsOrigin[0]);
24
+ }
25
+ })(opts.origin);
26
+ return async (c, next) => {
27
+ await next();
28
+ function set(key, value) {
29
+ c.res.headers.append(key, value);
30
+ }
31
+ const allowOrigin = findAllowOrigin(c.req.headers.get('origin') || '');
32
+ if (allowOrigin) {
33
+ set('Access-Control-Allow-Origin', allowOrigin);
34
+ }
35
+ // Suppose the server sends a response with an Access-Control-Allow-Origin value with an explicit origin (rather than the "*" wildcard).
36
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
37
+ if (opts.origin !== '*') {
38
+ set('Vary', 'Origin');
39
+ }
40
+ if (opts.credentials) {
41
+ set('Access-Control-Allow-Credentials', 'true');
42
+ }
43
+ if (opts.exposeHeaders?.length) {
44
+ set('Access-Control-Expose-Headers', opts.exposeHeaders.join(','));
45
+ }
46
+ if (c.req.method === 'OPTIONS') {
47
+ // Preflight
48
+ if (opts.maxAge != null) {
49
+ set('Access-Control-Max-Age', opts.maxAge.toString());
50
+ }
51
+ if (opts.allowMethods?.length) {
52
+ set('Access-Control-Allow-Methods', opts.allowMethods.join(','));
53
+ }
54
+ let headers = opts.allowHeaders;
55
+ if (!headers?.length) {
56
+ const requestHeaders = c.req.headers.get('Access-Control-Request-Headers');
57
+ if (requestHeaders) {
58
+ headers = requestHeaders.split(/\s*,\s*/);
59
+ }
60
+ }
61
+ if (headers?.length) {
62
+ set('Access-Control-Allow-Headers', headers.join(','));
63
+ set('Vary', 'Access-Control-Request-Headers');
64
+ }
65
+ c.res.headers.delete('Content-Length');
66
+ c.res.headers.delete('Content-Type');
67
+ c.res = new Response(null, {
68
+ headers: c.res.headers,
69
+ status: 204,
70
+ statusText: c.res.statusText,
71
+ });
72
+ }
73
+ };
74
+ };
75
+ exports.cors = cors;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.etag = void 0;
4
+ const crypto_1 = require("../../utils/crypto");
5
+ const etag = (options = { weak: false }) => {
6
+ return async (c, next) => {
7
+ const ifNoneMatch = c.req.header('If-None-Match') || c.req.header('if-none-match');
8
+ await next();
9
+ const res = c.res;
10
+ const clone = res.clone();
11
+ const hash = await (0, crypto_1.sha1)(res.body || '');
12
+ const etag = options.weak ? `W/"${hash}"` : `"${hash}"`;
13
+ if (ifNoneMatch && ifNoneMatch === etag) {
14
+ await clone.blob(); // Force using body
15
+ c.res = new Response(null, {
16
+ status: 304,
17
+ statusText: 'Not Modified',
18
+ });
19
+ c.res.headers.delete('Content-Length');
20
+ }
21
+ else {
22
+ c.res = new Response(clone.body, clone);
23
+ c.res.headers.append('ETag', etag);
24
+ }
25
+ };
26
+ };
27
+ exports.etag = etag;