hono 2.7.2 → 2.7.4

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.
@@ -28,6 +28,75 @@ class Context {
28
28
  this._status = 200;
29
29
  this._pretty = false;
30
30
  this._prettySpace = 2;
31
+ this.header = (name, value, options) => {
32
+ this._headers || (this._headers = {});
33
+ const key = name.toLowerCase();
34
+ let shouldAppend = false;
35
+ if (options && options.append) {
36
+ const vAlreadySet = this._headers[key];
37
+ if (vAlreadySet && vAlreadySet.length) {
38
+ shouldAppend = true;
39
+ }
40
+ }
41
+ if (shouldAppend) {
42
+ this._headers[key].push(value);
43
+ } else {
44
+ this._headers[key] = [value];
45
+ }
46
+ if (this.finalized) {
47
+ if (shouldAppend) {
48
+ this.res.headers.append(name, value);
49
+ } else {
50
+ this.res.headers.set(name, value);
51
+ }
52
+ }
53
+ };
54
+ this.status = (status) => {
55
+ this._status = status;
56
+ };
57
+ this.pretty = (prettyJSON, space = 2) => {
58
+ this._pretty = prettyJSON;
59
+ this._prettySpace = space;
60
+ };
61
+ this.newResponse = (data, status, headers = {}) => {
62
+ return new Response(data, {
63
+ status,
64
+ headers: this._finalizeHeaders(headers)
65
+ });
66
+ };
67
+ this.body = (data, status = this._status, headers = {}) => {
68
+ return this.newResponse(data, status, headers);
69
+ };
70
+ this.text = (text, status, headers) => {
71
+ if (!headers && !status && !this._res && !this._headers) {
72
+ return new Response(text);
73
+ }
74
+ status || (status = this._status);
75
+ headers || (headers = {});
76
+ headers["content-type"] = "text/plain; charset=UTF-8";
77
+ return this.newResponse(text, status, headers);
78
+ };
79
+ this.json = (object, status = this._status, headers = {}) => {
80
+ const body = this._pretty ? JSON.stringify(object, null, this._prettySpace) : JSON.stringify(object);
81
+ headers["content-type"] = "application/json; charset=UTF-8";
82
+ return this.newResponse(body, status, headers);
83
+ };
84
+ this.html = (html, status = this._status, headers = {}) => {
85
+ headers["content-type"] = "text/html; charset=UTF-8";
86
+ return this.newResponse(html, status, headers);
87
+ };
88
+ this.redirect = (location, status = 302) => {
89
+ return this.newResponse(null, status, {
90
+ Location: location
91
+ });
92
+ };
93
+ this.cookie = (name, value, opt) => {
94
+ const cookie = (0, import_cookie.serialize)(name, value, opt);
95
+ this.header("set-cookie", cookie, { append: true });
96
+ };
97
+ this.notFound = () => {
98
+ return this.notFoundHandler(this);
99
+ };
31
100
  this._executionCtx = executionCtx;
32
101
  this.req = req;
33
102
  this.env = env;
@@ -52,35 +121,14 @@ class Context {
52
121
  return this._res || (this._res = new Response("404 Not Found", { status: 404 }));
53
122
  }
54
123
  set res(_res) {
124
+ if (this._res) {
125
+ this._res.headers.forEach((v, k) => {
126
+ _res.headers.set(k, v);
127
+ });
128
+ }
55
129
  this._res = _res;
56
130
  this.finalized = true;
57
131
  }
58
- header(name, value, options) {
59
- this._headers || (this._headers = {});
60
- const key = name.toLowerCase();
61
- let shouldAppend = false;
62
- if (options && options.append) {
63
- const vAlreadySet = this._headers[key];
64
- if (vAlreadySet && vAlreadySet.length) {
65
- shouldAppend = true;
66
- }
67
- }
68
- if (shouldAppend) {
69
- this._headers[key].push(value);
70
- } else {
71
- this._headers[key] = [value];
72
- }
73
- if (this.finalized) {
74
- if (shouldAppend) {
75
- this.res.headers.append(name, value);
76
- } else {
77
- this.res.headers.set(name, value);
78
- }
79
- }
80
- }
81
- status(status) {
82
- this._status = status;
83
- }
84
132
  set(key, value) {
85
133
  this._map || (this._map = {});
86
134
  this._map[key] = value;
@@ -91,16 +139,6 @@ class Context {
91
139
  }
92
140
  return this._map[key];
93
141
  }
94
- pretty(prettyJSON, space = 2) {
95
- this._pretty = prettyJSON;
96
- this._prettySpace = space;
97
- }
98
- newResponse(data, status, headers = {}) {
99
- return new Response(data, {
100
- status,
101
- headers: this._finalizeHeaders(headers)
102
- });
103
- }
104
142
  _finalizeHeaders(incomingHeaders) {
105
143
  const finalizedHeaders = [];
106
144
  const headersKv = this._headers || {};
@@ -128,39 +166,6 @@ class Context {
128
166
  }
129
167
  return finalizedHeaders;
130
168
  }
131
- body(data, status = this._status, headers = {}) {
132
- return this.newResponse(data, status, headers);
133
- }
134
- text(text, status, headers) {
135
- if (!headers && !status && !this._res && !this._headers) {
136
- return new Response(text);
137
- }
138
- status || (status = this._status);
139
- headers || (headers = {});
140
- headers["content-type"] = "text/plain; charset=UTF-8";
141
- return this.newResponse(text, status, headers);
142
- }
143
- json(object, status = this._status, headers = {}) {
144
- const body = this._pretty ? JSON.stringify(object, null, this._prettySpace) : JSON.stringify(object);
145
- headers["content-type"] = "application/json; charset=UTF-8";
146
- return this.newResponse(body, status, headers);
147
- }
148
- html(html, status = this._status, headers = {}) {
149
- headers["content-type"] = "text/html; charset=UTF-8";
150
- return this.newResponse(html, status, headers);
151
- }
152
- redirect(location, status = 302) {
153
- return this.newResponse(null, status, {
154
- Location: location
155
- });
156
- }
157
- cookie(name, value, opt) {
158
- const cookie = (0, import_cookie.serialize)(name, value, opt);
159
- this.header("set-cookie", cookie, { append: true });
160
- }
161
- notFound() {
162
- return this.notFoundHandler(this);
163
- }
164
169
  get runtime() {
165
170
  const global = globalThis;
166
171
  if (global?.Deno !== void 0) {
package/dist/context.js CHANGED
@@ -6,6 +6,75 @@ var Context = class {
6
6
  this._status = 200;
7
7
  this._pretty = false;
8
8
  this._prettySpace = 2;
9
+ this.header = (name, value, options) => {
10
+ this._headers || (this._headers = {});
11
+ const key = name.toLowerCase();
12
+ let shouldAppend = false;
13
+ if (options && options.append) {
14
+ const vAlreadySet = this._headers[key];
15
+ if (vAlreadySet && vAlreadySet.length) {
16
+ shouldAppend = true;
17
+ }
18
+ }
19
+ if (shouldAppend) {
20
+ this._headers[key].push(value);
21
+ } else {
22
+ this._headers[key] = [value];
23
+ }
24
+ if (this.finalized) {
25
+ if (shouldAppend) {
26
+ this.res.headers.append(name, value);
27
+ } else {
28
+ this.res.headers.set(name, value);
29
+ }
30
+ }
31
+ };
32
+ this.status = (status) => {
33
+ this._status = status;
34
+ };
35
+ this.pretty = (prettyJSON, space = 2) => {
36
+ this._pretty = prettyJSON;
37
+ this._prettySpace = space;
38
+ };
39
+ this.newResponse = (data, status, headers = {}) => {
40
+ return new Response(data, {
41
+ status,
42
+ headers: this._finalizeHeaders(headers)
43
+ });
44
+ };
45
+ this.body = (data, status = this._status, headers = {}) => {
46
+ return this.newResponse(data, status, headers);
47
+ };
48
+ this.text = (text, status, headers) => {
49
+ if (!headers && !status && !this._res && !this._headers) {
50
+ return new Response(text);
51
+ }
52
+ status || (status = this._status);
53
+ headers || (headers = {});
54
+ headers["content-type"] = "text/plain; charset=UTF-8";
55
+ return this.newResponse(text, status, headers);
56
+ };
57
+ this.json = (object, status = this._status, headers = {}) => {
58
+ const body = this._pretty ? JSON.stringify(object, null, this._prettySpace) : JSON.stringify(object);
59
+ headers["content-type"] = "application/json; charset=UTF-8";
60
+ return this.newResponse(body, status, headers);
61
+ };
62
+ this.html = (html, status = this._status, headers = {}) => {
63
+ headers["content-type"] = "text/html; charset=UTF-8";
64
+ return this.newResponse(html, status, headers);
65
+ };
66
+ this.redirect = (location, status = 302) => {
67
+ return this.newResponse(null, status, {
68
+ Location: location
69
+ });
70
+ };
71
+ this.cookie = (name, value, opt) => {
72
+ const cookie = serialize(name, value, opt);
73
+ this.header("set-cookie", cookie, { append: true });
74
+ };
75
+ this.notFound = () => {
76
+ return this.notFoundHandler(this);
77
+ };
9
78
  this._executionCtx = executionCtx;
10
79
  this.req = req;
11
80
  this.env = env;
@@ -30,35 +99,14 @@ var Context = class {
30
99
  return this._res || (this._res = new Response("404 Not Found", { status: 404 }));
31
100
  }
32
101
  set res(_res) {
102
+ if (this._res) {
103
+ this._res.headers.forEach((v, k) => {
104
+ _res.headers.set(k, v);
105
+ });
106
+ }
33
107
  this._res = _res;
34
108
  this.finalized = true;
35
109
  }
36
- header(name, value, options) {
37
- this._headers || (this._headers = {});
38
- const key = name.toLowerCase();
39
- let shouldAppend = false;
40
- if (options && options.append) {
41
- const vAlreadySet = this._headers[key];
42
- if (vAlreadySet && vAlreadySet.length) {
43
- shouldAppend = true;
44
- }
45
- }
46
- if (shouldAppend) {
47
- this._headers[key].push(value);
48
- } else {
49
- this._headers[key] = [value];
50
- }
51
- if (this.finalized) {
52
- if (shouldAppend) {
53
- this.res.headers.append(name, value);
54
- } else {
55
- this.res.headers.set(name, value);
56
- }
57
- }
58
- }
59
- status(status) {
60
- this._status = status;
61
- }
62
110
  set(key, value) {
63
111
  this._map || (this._map = {});
64
112
  this._map[key] = value;
@@ -69,16 +117,6 @@ var Context = class {
69
117
  }
70
118
  return this._map[key];
71
119
  }
72
- pretty(prettyJSON, space = 2) {
73
- this._pretty = prettyJSON;
74
- this._prettySpace = space;
75
- }
76
- newResponse(data, status, headers = {}) {
77
- return new Response(data, {
78
- status,
79
- headers: this._finalizeHeaders(headers)
80
- });
81
- }
82
120
  _finalizeHeaders(incomingHeaders) {
83
121
  const finalizedHeaders = [];
84
122
  const headersKv = this._headers || {};
@@ -106,39 +144,6 @@ var Context = class {
106
144
  }
107
145
  return finalizedHeaders;
108
146
  }
109
- body(data, status = this._status, headers = {}) {
110
- return this.newResponse(data, status, headers);
111
- }
112
- text(text, status, headers) {
113
- if (!headers && !status && !this._res && !this._headers) {
114
- return new Response(text);
115
- }
116
- status || (status = this._status);
117
- headers || (headers = {});
118
- headers["content-type"] = "text/plain; charset=UTF-8";
119
- return this.newResponse(text, status, headers);
120
- }
121
- json(object, status = this._status, headers = {}) {
122
- const body = this._pretty ? JSON.stringify(object, null, this._prettySpace) : JSON.stringify(object);
123
- headers["content-type"] = "application/json; charset=UTF-8";
124
- return this.newResponse(body, status, headers);
125
- }
126
- html(html, status = this._status, headers = {}) {
127
- headers["content-type"] = "text/html; charset=UTF-8";
128
- return this.newResponse(html, status, headers);
129
- }
130
- redirect(location, status = 302) {
131
- return this.newResponse(null, status, {
132
- Location: location
133
- });
134
- }
135
- cookie(name, value, opt) {
136
- const cookie = serialize(name, value, opt);
137
- this.header("set-cookie", cookie, { append: true });
138
- }
139
- notFound() {
140
- return this.notFoundHandler(this);
141
- }
142
147
  get runtime() {
143
148
  const global = globalThis;
144
149
  if (global?.Deno !== void 0) {
@@ -24,26 +24,26 @@ export declare class Context<P extends string = string, E extends Partial<Enviro
24
24
  get executionCtx(): ExecutionContext;
25
25
  get res(): Response;
26
26
  set res(_res: Response);
27
- header(name: string, value: string, options?: {
27
+ header: (name: string, value: string, options?: {
28
28
  append?: boolean;
29
- }): void;
30
- status(status: StatusCode): void;
29
+ }) => void;
30
+ status: (status: StatusCode) => void;
31
31
  set<Key extends keyof ContextVariableMap>(key: Key, value: ContextVariableMap[Key]): void;
32
32
  set<Key extends keyof E['Variables']>(key: Key, value: E['Variables'][Key]): void;
33
33
  set(key: string, value: unknown): void;
34
34
  get<Key extends keyof ContextVariableMap>(key: Key): ContextVariableMap[Key];
35
35
  get<Key extends keyof E['Variables']>(key: Key): E['Variables'][Key];
36
36
  get<T>(key: string): T;
37
- pretty(prettyJSON: boolean, space?: number): void;
38
- newResponse(data: Data | null, status: StatusCode, headers?: Headers): Response;
37
+ pretty: (prettyJSON: boolean, space?: number) => void;
38
+ newResponse: (data: Data | null, status: StatusCode, headers?: Headers) => Response;
39
39
  private _finalizeHeaders;
40
- body(data: Data | null, status?: StatusCode, headers?: Headers): Response;
41
- text(text: string, status?: StatusCode, headers?: Headers): Response;
42
- json<T>(object: T, status?: StatusCode, headers?: Headers): Response;
43
- html(html: string, status?: StatusCode, headers?: Headers): Response;
44
- redirect(location: string, status?: StatusCode): Response;
45
- cookie(name: string, value: string, opt?: CookieOptions): void;
46
- notFound(): Response | Promise<Response>;
40
+ body: (data: Data | null, status?: StatusCode, headers?: Headers) => Response;
41
+ text: (text: string, status?: StatusCode, headers?: Headers) => Response;
42
+ json: <T>(object: T, status?: StatusCode, headers?: Headers) => Response;
43
+ html: (html: string, status?: StatusCode, headers?: Headers) => Response;
44
+ redirect: (location: string, status?: StatusCode) => Response;
45
+ cookie: (name: string, value: string, opt?: CookieOptions) => void;
46
+ notFound: () => Response | Promise<Response>;
47
47
  get runtime(): Runtime;
48
48
  }
49
49
  export {};
@@ -1,11 +1,15 @@
1
1
  import type { BodyData } from './utils/body';
2
2
  import type { Cookie } from './utils/cookie';
3
+ import type { UnionToIntersection } from './utils/types';
4
+ declare type RemoveQuestion<T> = T extends `${infer R}?` ? R : T;
5
+ declare type UndefinedIfHavingQuestion<T> = T extends `${infer _}?` ? string | undefined : string;
6
+ declare type ParamKeyToRecord<T extends string> = T extends `${infer R}?` ? Record<R, string | undefined> : Record<T, string>;
3
7
  declare global {
4
- interface Request<CfHostMetadata = unknown, ParamKeyType extends string = string, Data = any> {
5
- paramData?: Record<ParamKeyType, string>;
8
+ interface Request<CfHostMetadata = unknown, ParamKey extends string = string, Data = any> {
9
+ paramData?: Record<ParamKey, string>;
6
10
  param: {
7
- (key: ParamKeyType): string;
8
- (): Record<ParamKeyType, string>;
11
+ (key: RemoveQuestion<ParamKey>): UndefinedIfHavingQuestion<ParamKey>;
12
+ (): UnionToIntersection<ParamKeyToRecord<ParamKey>>;
9
13
  };
10
14
  queryData?: Record<string, string>;
11
15
  query: {
@@ -37,3 +41,4 @@ declare global {
37
41
  }
38
42
  }
39
43
  export declare function extendRequestPrototype(): void;
44
+ export {};
@@ -1,3 +1,4 @@
1
1
  export declare type Expect<T extends true> = T;
2
2
  export declare type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
3
3
  export declare type NotEqual<X, Y> = true extends Equal<X, Y> ? false : true;
4
+ export declare type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "2.7.2",
3
+ "version": "2.7.4",
4
4
  "description": "Ultrafast web framework for Cloudflare Workers, Deno, and Bun.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",
@@ -20,6 +20,7 @@
20
20
  "denoify": "rimraf deno_dist && denoify && rimraf 'deno_dist/**/*.test.ts'",
21
21
  "copy:package.cjs.json": "cp ./package.cjs.json ./dist/cjs/package.json && cp ./package.cjs.json ./dist/types/package.json ",
22
22
  "build": "rimraf dist && tsx ./build.ts && yarn copy:package.cjs.json",
23
+ "postbuild": "publint",
23
24
  "watch": "rimraf dist && tsx ./build.ts --watch && yarn copy:package.cjs.json",
24
25
  "prerelease": "yarn denoify && yarn test:deno && yarn build",
25
26
  "release": "np"
@@ -276,6 +277,7 @@
276
277
  "jest-environment-miniflare": "2.7.1",
277
278
  "np": "^7.6.2",
278
279
  "prettier": "^2.6.2",
280
+ "publint": "^0.1.8",
279
281
  "rimraf": "^3.0.2",
280
282
  "ts-jest": "^29.0.1",
281
283
  "tsx": "^3.11.0",