hono 1.2.0 → 1.3.0

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 (81) hide show
  1. package/README.md +92 -21
  2. package/dist/compose.test.d.ts +1 -0
  3. package/dist/compose.test.js +511 -0
  4. package/dist/context.d.ts +4 -1
  5. package/dist/context.js +31 -6
  6. package/dist/context.test.d.ts +1 -0
  7. package/dist/context.test.js +127 -0
  8. package/dist/hono.d.ts +21 -29
  9. package/dist/hono.js +27 -65
  10. package/dist/hono.test.d.ts +1 -0
  11. package/dist/hono.test.js +656 -0
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.js +1 -2
  14. package/dist/middleware/basic-auth/index.js +7 -8
  15. package/dist/middleware/basic-auth/index.test.d.ts +1 -0
  16. package/dist/middleware/basic-auth/index.test.js +119 -0
  17. package/dist/middleware/body-parse/index.test.d.ts +1 -0
  18. package/dist/middleware/body-parse/index.test.js +59 -0
  19. package/dist/middleware/cookie/index.d.ts +5 -2
  20. package/dist/middleware/cookie/index.js +9 -4
  21. package/dist/middleware/cookie/index.test.d.ts +1 -0
  22. package/dist/middleware/cookie/index.test.js +78 -0
  23. package/dist/middleware/cors/index.test.d.ts +1 -0
  24. package/dist/middleware/cors/index.test.js +59 -0
  25. package/dist/middleware/etag/index.test.d.ts +1 -0
  26. package/dist/middleware/etag/index.test.js +45 -0
  27. package/dist/middleware/graphql-server/index.js +1 -1
  28. package/dist/middleware/graphql-server/index.test.d.ts +1 -0
  29. package/dist/middleware/graphql-server/index.test.js +480 -0
  30. package/dist/middleware/graphql-server/parse-body.test.d.ts +1 -0
  31. package/dist/middleware/graphql-server/parse-body.test.js +57 -0
  32. package/dist/middleware/jwt/index.test.d.ts +1 -0
  33. package/dist/middleware/jwt/index.test.js +51 -0
  34. package/dist/middleware/logger/index.test.d.ts +1 -0
  35. package/dist/middleware/logger/index.test.js +49 -0
  36. package/dist/middleware/mustache/index.test.d.ts +1 -0
  37. package/dist/middleware/mustache/index.test.js +49 -0
  38. package/dist/middleware/powered-by/index.test.d.ts +1 -0
  39. package/dist/middleware/powered-by/index.test.js +15 -0
  40. package/dist/middleware/pretty-json/index.test.d.ts +1 -0
  41. package/dist/middleware/pretty-json/index.test.js +28 -0
  42. package/dist/middleware/serve-static/index.test.d.ts +1 -0
  43. package/dist/middleware/serve-static/index.test.js +58 -0
  44. package/dist/router/reg-exp-router/index.d.ts +1 -1
  45. package/dist/router/reg-exp-router/index.js +1 -1
  46. package/dist/router/reg-exp-router/router.js +1 -1
  47. package/dist/router/reg-exp-router/router.test.d.ts +1 -0
  48. package/dist/router/reg-exp-router/router.test.js +212 -0
  49. package/dist/router/reg-exp-router/trie.d.ts +3 -3
  50. package/dist/router/reg-exp-router/trie.js +1 -1
  51. package/dist/router/trie-router/index.d.ts +1 -1
  52. package/dist/router/trie-router/index.js +1 -1
  53. package/dist/router/trie-router/node.test.d.ts +1 -0
  54. package/dist/router/trie-router/node.test.js +351 -0
  55. package/dist/router/trie-router/router.d.ts +1 -1
  56. package/dist/router/trie-router/router.js +1 -1
  57. package/dist/router/trie-router/router.test.d.ts +1 -0
  58. package/dist/router/trie-router/router.test.js +98 -0
  59. package/dist/utils/body.test.d.ts +1 -0
  60. package/dist/utils/body.test.js +45 -0
  61. package/dist/utils/buffer.js +1 -1
  62. package/dist/utils/buffer.test.d.ts +1 -0
  63. package/dist/utils/buffer.test.js +36 -0
  64. package/dist/utils/cloudflare.test.d.ts +1 -0
  65. package/dist/utils/cloudflare.test.js +42 -0
  66. package/dist/utils/crypto.test.d.ts +1 -0
  67. package/dist/utils/crypto.test.js +15 -0
  68. package/dist/utils/encode.test.d.ts +1 -0
  69. package/dist/utils/encode.test.js +54 -0
  70. package/dist/utils/http-status.test.d.ts +1 -0
  71. package/dist/utils/http-status.test.js +8 -0
  72. package/dist/utils/jwt/jwt.test.d.ts +1 -0
  73. package/dist/utils/jwt/jwt.test.js +171 -0
  74. package/dist/utils/jwt/types.test.d.ts +1 -0
  75. package/dist/utils/jwt/types.test.js +12 -0
  76. package/dist/utils/mime.test.d.ts +1 -0
  77. package/dist/utils/mime.test.js +13 -0
  78. package/dist/utils/url.js +4 -0
  79. package/dist/utils/url.test.d.ts +1 -0
  80. package/dist/utils/url.test.js +96 -0
  81. package/package.json +3 -4
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const context_1 = require("./context");
4
+ describe('Context', () => {
5
+ const req = new Request('http://localhost/');
6
+ let c;
7
+ beforeEach(() => {
8
+ c = new context_1.Context(req);
9
+ });
10
+ it('c.text()', async () => {
11
+ const res = c.text('text in c', 201, { 'X-Custom': 'Message' });
12
+ expect(res.status).toBe(201);
13
+ expect(res.headers.get('Content-Type')).toBe('text/plain; charset=UTF-8');
14
+ expect(await res.text()).toBe('text in c');
15
+ expect(res.headers.get('X-Custom')).toBe('Message');
16
+ });
17
+ it('c.json()', async () => {
18
+ const res = c.json({ message: 'Hello' }, 201, { 'X-Custom': 'Message' });
19
+ expect(res.status).toBe(201);
20
+ expect(res.headers.get('Content-Type')).toMatch('application/json; charset=UTF-8');
21
+ const text = await res.text();
22
+ expect(text).toBe('{"message":"Hello"}');
23
+ expect(res.headers.get('X-Custom')).toBe('Message');
24
+ });
25
+ it('c.json() with c.pretty(true)', async () => {
26
+ c.pretty(true);
27
+ const res = c.json({ message: 'Hello' });
28
+ const text = await res.text();
29
+ expect(text).toBe(`{
30
+ "message": "Hello"
31
+ }`);
32
+ });
33
+ it('c.json() with c.pretty(true, 4)', async () => {
34
+ c.pretty(true, 4);
35
+ const res = c.json({ message: 'Hello' });
36
+ const text = await res.text();
37
+ expect(text).toBe(`{
38
+ "message": "Hello"
39
+ }`);
40
+ });
41
+ it('c.html()', async () => {
42
+ const res = c.html('<h1>Hello! Hono!</h1>', 201, { 'X-Custom': 'Message' });
43
+ expect(res.status).toBe(201);
44
+ expect(res.headers.get('Content-Type')).toMatch('text/html');
45
+ expect(await res.text()).toBe('<h1>Hello! Hono!</h1>');
46
+ expect(res.headers.get('X-Custom')).toBe('Message');
47
+ });
48
+ it('c.redirect()', async () => {
49
+ let res = c.redirect('/destination');
50
+ expect(res.status).toBe(302);
51
+ expect(res.headers.get('Location')).toMatch(/^https?:\/\/.+\/destination$/);
52
+ res = c.redirect('https://example.com/destination');
53
+ expect(res.status).toBe(302);
54
+ expect(res.headers.get('Location')).toBe('https://example.com/destination');
55
+ });
56
+ it('c.header()', async () => {
57
+ c.header('X-Foo', 'Bar');
58
+ const res = c.body('Hi');
59
+ const foo = res.headers.get('X-Foo');
60
+ expect(foo).toBe('Bar');
61
+ });
62
+ it('c.status() and c.statusText()', async () => {
63
+ c.status(201);
64
+ const res = c.body('Hi');
65
+ expect(res.status).toBe(201);
66
+ expect(res.statusText).toBe('Created');
67
+ });
68
+ it('Complex pattern', async () => {
69
+ c.status(404);
70
+ const res = c.json({ hono: 'great app' });
71
+ expect(res.status).toBe(404);
72
+ expect(res.statusText).toBe('Not Found');
73
+ expect(res.headers.get('Content-Type')).toMatch('application/json; charset=UTF-8');
74
+ const obj = await res.json();
75
+ expect(obj['hono']).toBe('great app');
76
+ });
77
+ it('Has headers, status, and statusText', async () => {
78
+ c.header('X-Custom1', 'Message1');
79
+ c.header('X-Custom2', 'Message2');
80
+ c.status(200);
81
+ const res = c.newResponse('this is body', {
82
+ status: 201,
83
+ headers: {
84
+ 'X-Custom3': 'Message3',
85
+ 'X-Custom2': 'Message2-Override',
86
+ },
87
+ });
88
+ expect(res.headers.get('X-Custom1')).toBe('Message1');
89
+ expect(res.headers.get('X-Custom2')).toBe('Message2-Override');
90
+ expect(res.headers.get('X-Custom3')).toBe('Message3');
91
+ expect(res.status).toBe(201);
92
+ expect(await res.text()).toBe('this is body');
93
+ // res is already set.
94
+ c.res = res;
95
+ c.header('X-Custom4', 'Message4');
96
+ c.status(202);
97
+ expect(c.res.headers.get('X-Custom4')).toBe('Message4');
98
+ expect(c.res.status).toBe(201);
99
+ expect(c.res.statusText).toBe('OK');
100
+ });
101
+ it('Should return 200 response', async () => {
102
+ const res = c.text('Text');
103
+ expect(res.status).toBe(200);
104
+ expect(res.statusText).toBe('OK');
105
+ });
106
+ it('Should be able read env', async () => {
107
+ const req = new Request('http://localhost/');
108
+ const key = 'a-secret-key';
109
+ const ctx = new context_1.Context(req, {
110
+ env: {
111
+ API_KEY: key,
112
+ },
113
+ res: null,
114
+ event: null,
115
+ });
116
+ expect(ctx.env.API_KEY).toBe(key);
117
+ });
118
+ it('set and set', async () => {
119
+ const ctx = new context_1.Context(req);
120
+ expect(ctx.get('k-foo')).toEqual(undefined);
121
+ ctx.set('k-foo', 'v-foo');
122
+ expect(ctx.get('k-foo')).toEqual('v-foo');
123
+ expect(ctx.get('k-bar')).toEqual(undefined);
124
+ ctx.set('k-bar', { k: 'v' });
125
+ expect(ctx.get('k-bar')).toEqual({ k: 'v' });
126
+ });
127
+ });
package/dist/hono.d.ts CHANGED
@@ -2,15 +2,23 @@
2
2
  import { Context } from './context';
3
3
  import type { Env } from './context';
4
4
  import type { Router } from './router';
5
- import { METHOD_NAME_ALL_LOWERCASE } from './router';
6
5
  declare global {
7
- interface Request<ParamKeyType = string> {
8
- param: (key: ParamKeyType) => string;
9
- query: (key: string) => string;
10
- header: (name: string) => string;
6
+ interface Request<ParamKeyType extends string = string> {
7
+ param: {
8
+ (key: ParamKeyType): string;
9
+ (): Record<ParamKeyType, string>;
10
+ };
11
+ query: {
12
+ (key: string): string;
13
+ (): Record<string, string>;
14
+ };
15
+ header: {
16
+ (name: string): string;
17
+ (): Record<string, string>;
18
+ };
11
19
  }
12
20
  }
13
- export declare type Handler<RequestParamKeyType = string, E = Env> = (c: Context<RequestParamKeyType, E>, next?: Next) => Response | Promise<Response> | void | Promise<void>;
21
+ export declare type Handler<RequestParamKeyType extends string = string, E = Env> = (c: Context<RequestParamKeyType, E>, next: Next) => Response | Promise<Response> | void | Promise<void>;
14
22
  export declare type NotFoundHandler<E = Env> = (c: Context<string, E>) => Response;
15
23
  export declare type ErrorHandler<E = Env> = (err: Error, c: Context<string, E>) => Response;
16
24
  export declare type Next = () => Promise<void>;
@@ -23,29 +31,11 @@ interface HandlerInterface<T extends string, E = Env, U = Hono<E, T>> {
23
31
  <Path extends string>(...handlers: Handler<ParamKeys<Path> extends never ? string : ParamKeys<Path>, E>[]): U;
24
32
  (...handlers: Handler<string, E>[]): U;
25
33
  }
26
- declare const methods: readonly ["get", "post", "put", "delete", "head", "options", "patch"];
27
- declare type Methods = typeof methods[number] | typeof METHOD_NAME_ALL_LOWERCASE;
28
- interface Routing<E extends Env> {
34
+ interface Route<E extends Env> {
29
35
  path: string;
30
- method: Methods;
36
+ method: string;
31
37
  handler: Handler<string, E>;
32
38
  }
33
- declare const Route_base: new <E_1 extends Env, T extends string, U>() => {
34
- delete: HandlerInterface<T, E_1, U>;
35
- get: HandlerInterface<T, E_1, U>;
36
- all: HandlerInterface<T, E_1, U>;
37
- post: HandlerInterface<T, E_1, U>;
38
- put: HandlerInterface<T, E_1, U>;
39
- head: HandlerInterface<T, E_1, U>;
40
- options: HandlerInterface<T, E_1, U>;
41
- patch: HandlerInterface<T, E_1, U>;
42
- };
43
- export declare class Route<E = Env, P extends string = ''> extends Route_base<E, P, Route<E, P>> {
44
- #private;
45
- routes: Routing<E>[];
46
- constructor();
47
- private add;
48
- }
49
39
  declare const Hono_base: new <E_1 extends Env, T extends string, U>() => {
50
40
  delete: HandlerInterface<T, E_1, U>;
51
41
  get: HandlerInterface<T, E_1, U>;
@@ -56,17 +46,19 @@ declare const Hono_base: new <E_1 extends Env, T extends string, U>() => {
56
46
  options: HandlerInterface<T, E_1, U>;
57
47
  patch: HandlerInterface<T, E_1, U>;
58
48
  };
59
- export declare class Hono<E = Env, P extends string = ''> extends Hono_base<E, P, Hono<E, P>> {
60
- #private;
49
+ export declare class Hono<E = Env, P extends string = '/'> extends Hono_base<E, P, Hono<E, P>> {
61
50
  readonly routerClass: {
62
51
  new (): Router<any>;
63
52
  };
64
53
  readonly strict: boolean;
54
+ private _router;
55
+ private _tempPath;
65
56
  private path;
57
+ routes: Route<E>[];
66
58
  constructor(init?: Partial<Pick<Hono, 'routerClass' | 'strict'>>);
67
59
  private notFoundHandler;
68
60
  private errorHandler;
69
- route(path: string, route?: Route): Hono<E, P>;
61
+ route(path: string, app?: Hono<any>): Hono<E, P>;
70
62
  use(path: string, ...middleware: Handler<string, E>[]): Hono<E, P>;
71
63
  use(...middleware: Handler<string, E>[]): Hono<E, P>;
72
64
  onError(handler: ErrorHandler<E>): Hono<E, P>;
package/dist/hono.js CHANGED
@@ -1,18 +1,6 @@
1
1
  "use strict";
2
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
- if (kind === "m") throw new TypeError("Private method is not writable");
4
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
- };
8
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
- };
13
- var _Route_path, _Hono_router, _Hono_tempPath;
14
2
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.Hono = exports.Route = void 0;
3
+ exports.Hono = void 0;
16
4
  const compose_1 = require("./compose");
17
5
  const context_1 = require("./context");
18
6
  const router_1 = require("./router");
@@ -24,44 +12,13 @@ function defineDynamicClass() {
24
12
  return class {
25
13
  };
26
14
  }
27
- class Route extends defineDynamicClass() {
28
- constructor() {
29
- super();
30
- this.routes = [];
31
- _Route_path.set(this, '');
32
- const allMethods = [...methods, router_2.METHOD_NAME_ALL_LOWERCASE];
33
- allMethods.map((method) => {
34
- this[method] = (args1, ...args) => {
35
- if (typeof args1 === 'string') {
36
- __classPrivateFieldSet(this, _Route_path, args1, "f");
37
- }
38
- else {
39
- this.add(method, __classPrivateFieldGet(this, _Route_path, "f"), args1);
40
- }
41
- args.map((handler) => {
42
- if (typeof handler !== 'string') {
43
- this.add(method, __classPrivateFieldGet(this, _Route_path, "f"), handler);
44
- }
45
- });
46
- return this;
47
- };
48
- });
49
- }
50
- add(method, path, handler) {
51
- const r = { path: path, method: method, handler: handler };
52
- this.routes.push(r);
53
- return this;
54
- }
55
- }
56
- exports.Route = Route;
57
- _Route_path = new WeakMap();
58
15
  class Hono extends defineDynamicClass() {
59
16
  constructor(init = {}) {
60
17
  super();
61
18
  this.routerClass = trie_router_1.TrieRouter;
62
19
  this.strict = true; // strict routing - default is true
63
- _Hono_router.set(this, void 0);
64
- _Hono_tempPath.set(this, void 0);
20
+ this.path = '/';
21
+ this.routes = [];
65
22
  this.notFoundHandler = (c) => {
66
23
  const message = '404 Not Found';
67
24
  return c.text(message, 404);
@@ -89,19 +46,17 @@ class Hono extends defineDynamicClass() {
89
46
  };
90
47
  });
91
48
  Object.assign(this, init);
92
- __classPrivateFieldSet(this, _Hono_router, new this.routerClass(), "f");
93
- __classPrivateFieldSet(this, _Hono_tempPath, null, "f");
49
+ this._router = new this.routerClass();
50
+ this._tempPath = null;
94
51
  }
95
- route(path, route) {
96
- const newHono = new Hono();
97
- __classPrivateFieldSet(newHono, _Hono_tempPath, path, "f");
98
- __classPrivateFieldSet(newHono, _Hono_router, __classPrivateFieldGet(this, _Hono_router, "f"), "f");
99
- if (route) {
100
- route.routes.map((r) => {
101
- newHono.addRoute(r.method, r.path, r.handler);
52
+ route(path, app) {
53
+ this._tempPath = path;
54
+ if (app) {
55
+ app.routes.map((r) => {
56
+ this.addRoute(r.method, r.path, r.handler);
102
57
  });
103
58
  }
104
- return newHono;
59
+ return this;
105
60
  }
106
61
  use(arg1, ...handlers) {
107
62
  if (typeof arg1 === 'string') {
@@ -125,22 +80,30 @@ class Hono extends defineDynamicClass() {
125
80
  }
126
81
  addRoute(method, path, handler) {
127
82
  method = method.toUpperCase();
128
- if (__classPrivateFieldGet(this, _Hono_tempPath, "f")) {
129
- path = (0, url_1.mergePath)(__classPrivateFieldGet(this, _Hono_tempPath, "f"), path);
83
+ if (this._tempPath) {
84
+ path = (0, url_1.mergePath)(this._tempPath, path);
130
85
  }
131
- __classPrivateFieldGet(this, _Hono_router, "f").add(method, path, handler);
86
+ this._router.add(method, path, handler);
87
+ const r = { path: path, method: method, handler: handler };
88
+ this.routes.push(r);
132
89
  }
133
90
  async matchRoute(method, path) {
134
- return __classPrivateFieldGet(this, _Hono_router, "f").match(method, path);
91
+ return this._router.match(method, path);
135
92
  }
136
93
  async dispatch(request, event, env) {
137
94
  const path = (0, url_1.getPathFromURL)(request.url, { strict: this.strict });
138
95
  const method = request.method;
139
96
  const result = await this.matchRoute(method, path);
140
- request.param = (key) => {
141
- if (result)
142
- return result.params[key];
143
- };
97
+ request.param = ((key) => {
98
+ if (result) {
99
+ if (key) {
100
+ return result.params[key];
101
+ }
102
+ else {
103
+ return result.params;
104
+ }
105
+ }
106
+ });
144
107
  const handlers = result ? result.handlers : [this.notFoundHandler];
145
108
  const c = new context_1.Context(request, { env: env, event: event, res: undefined });
146
109
  c.notFound = () => this.notFoundHandler(c);
@@ -175,4 +138,3 @@ class Hono extends defineDynamicClass() {
175
138
  }
176
139
  }
177
140
  exports.Hono = Hono;
178
- _Hono_router = new WeakMap(), _Hono_tempPath = new WeakMap();
@@ -0,0 +1 @@
1
+ export {};