hono 4.2.4 → 4.2.6

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.
@@ -16,8 +16,9 @@ var streamToNodeStream = async (reader, writer) => {
16
16
  var streamHandle = (app) => {
17
17
  return awslambda.streamifyResponse(
18
18
  async (event, responseStream, context) => {
19
+ const processor = getProcessor(event);
19
20
  try {
20
- const req = createRequest(event);
21
+ const req = processor.createRequest(event);
21
22
  const requestContext = getRequestContext(event);
22
23
  const res = await app.fetch(req, {
23
24
  event,
@@ -45,81 +46,123 @@ var streamHandle = (app) => {
45
46
  };
46
47
  var handle = (app) => {
47
48
  return async (event, lambdaContext) => {
48
- const req = createRequest(event);
49
+ const processor = getProcessor(event);
50
+ const req = processor.createRequest(event);
49
51
  const requestContext = getRequestContext(event);
50
52
  const res = await app.fetch(req, {
51
53
  event,
52
54
  requestContext,
53
55
  lambdaContext
54
56
  });
55
- return createResult(event, res);
57
+ return processor.createResult(event, res);
56
58
  };
57
59
  };
58
- var createResult = async (event, res) => {
59
- const contentType = res.headers.get("content-type");
60
- let isBase64Encoded = contentType && isContentTypeBinary(contentType) ? true : false;
61
- if (!isBase64Encoded) {
62
- const contentEncoding = res.headers.get("content-encoding");
63
- isBase64Encoded = isContentEncodingBinary(contentEncoding);
60
+ var EventProcessor = class {
61
+ createRequest(event) {
62
+ const queryString = this.getQueryString(event);
63
+ const domainName = event.requestContext && "domainName" in event.requestContext ? event.requestContext.domainName : event.headers?.["host"] ?? event.multiValueHeaders?.["host"]?.[0];
64
+ const path = this.getPath(event);
65
+ const urlPath = `https://${domainName}${path}`;
66
+ const url = queryString ? `${urlPath}?${queryString}` : urlPath;
67
+ const headers = new Headers();
68
+ this.getCookies(event, headers);
69
+ if (event.headers) {
70
+ for (const [k, v] of Object.entries(event.headers)) {
71
+ if (v) {
72
+ headers.set(k, v);
73
+ }
74
+ }
75
+ }
76
+ if (event.multiValueHeaders) {
77
+ for (const [k, values] of Object.entries(event.multiValueHeaders)) {
78
+ if (values) {
79
+ values.forEach((v) => headers.append(k, v));
80
+ }
81
+ }
82
+ }
83
+ const method = this.getMethod(event);
84
+ const requestInit = {
85
+ headers,
86
+ method
87
+ };
88
+ if (event.body) {
89
+ requestInit.body = event.isBase64Encoded ? Buffer.from(event.body, "base64") : event.body;
90
+ }
91
+ return new Request(url, requestInit);
64
92
  }
65
- const body = isBase64Encoded ? encodeBase64(await res.arrayBuffer()) : await res.text();
66
- const result = {
67
- body,
68
- headers: {},
69
- statusCode: res.status,
70
- isBase64Encoded
71
- };
72
- setCookies(event, res, result);
73
- res.headers.forEach((value, key) => {
74
- result.headers[key] = value;
75
- });
76
- return result;
77
- };
78
- var createRequest = (event) => {
79
- const queryString = extractQueryString(event);
80
- const domainName = event.requestContext && "domainName" in event.requestContext ? event.requestContext.domainName : event.headers["host"];
81
- const path = isProxyEventV2(event) ? event.rawPath : event.path;
82
- const urlPath = `https://${domainName}${path}`;
83
- const url = queryString ? `${urlPath}?${queryString}` : urlPath;
84
- const headers = new Headers();
85
- getCookies(event, headers);
86
- for (const [k, v] of Object.entries(event.headers)) {
87
- if (v) {
88
- headers.set(k, v);
93
+ async createResult(event, res) {
94
+ const contentType = res.headers.get("content-type");
95
+ let isBase64Encoded = contentType && isContentTypeBinary(contentType) ? true : false;
96
+ if (!isBase64Encoded) {
97
+ const contentEncoding = res.headers.get("content-encoding");
98
+ isBase64Encoded = isContentEncodingBinary(contentEncoding);
89
99
  }
100
+ const body = isBase64Encoded ? encodeBase64(await res.arrayBuffer()) : await res.text();
101
+ const result = {
102
+ body,
103
+ headers: {},
104
+ statusCode: res.status,
105
+ isBase64Encoded
106
+ };
107
+ this.setCookies(event, res, result);
108
+ res.headers.forEach((value, key) => {
109
+ result.headers[key] = value;
110
+ });
111
+ return result;
90
112
  }
91
- const method = isProxyEventV2(event) ? event.requestContext.http.method : event.httpMethod;
92
- const requestInit = {
93
- headers,
94
- method
113
+ setCookies = (event, res, result) => {
114
+ if (res.headers.has("set-cookie")) {
115
+ const cookies = res.headers.get("set-cookie")?.split(", ");
116
+ if (Array.isArray(cookies)) {
117
+ this.setCookiesToResult(result, cookies);
118
+ res.headers.delete("set-cookie");
119
+ }
120
+ }
95
121
  };
96
- if (event.body) {
97
- requestInit.body = event.isBase64Encoded ? Buffer.from(event.body, "base64") : event.body;
98
- }
99
- return new Request(url, requestInit);
100
122
  };
101
- var extractQueryString = (event) => {
102
- return isProxyEventV2(event) ? event.rawQueryString : Object.entries(event.queryStringParameters || {}).filter(([, value]) => value).map(([key, value]) => `${key}=${value}`).join("&");
103
- };
104
- var getCookies = (event, headers) => {
105
- if (isProxyEventV2(event) && Array.isArray(event.cookies)) {
106
- headers.set("Cookie", event.cookies.join("; "));
123
+ var v2Processor = new class EventV2Processor extends EventProcessor {
124
+ getPath(event) {
125
+ return event.rawPath;
107
126
  }
108
- };
109
- var setCookies = (event, res, result) => {
110
- if (res.headers.has("set-cookie")) {
111
- const cookies = res.headers.get("set-cookie")?.split(", ");
112
- if (Array.isArray(cookies)) {
113
- if (isProxyEventV2(event)) {
114
- result.cookies = cookies;
115
- } else {
116
- result.multiValueHeaders = {
117
- "set-cookie": cookies
118
- };
119
- }
120
- res.headers.delete("set-cookie");
127
+ getMethod(event) {
128
+ return event.requestContext.http.method;
129
+ }
130
+ getQueryString(event) {
131
+ return event.rawQueryString;
132
+ }
133
+ getCookies(event, headers) {
134
+ if (Array.isArray(event.cookies)) {
135
+ headers.set("Cookie", event.cookies.join("; "));
121
136
  }
122
137
  }
138
+ setCookiesToResult(result, cookies) {
139
+ result.cookies = cookies;
140
+ }
141
+ }();
142
+ var v1Processor = new class EventV1Processor extends EventProcessor {
143
+ getPath(event) {
144
+ return event.path;
145
+ }
146
+ getMethod(event) {
147
+ return event.httpMethod;
148
+ }
149
+ getQueryString(event) {
150
+ return Object.entries(event.queryStringParameters || {}).filter(([, value]) => value).map(([key, value]) => `${key}=${value}`).join("&");
151
+ }
152
+ getCookies(event, headers) {
153
+ }
154
+ setCookiesToResult(result, cookies) {
155
+ result.multiValueHeaders = {
156
+ "set-cookie": cookies
157
+ };
158
+ }
159
+ }();
160
+ var getProcessor = (event) => {
161
+ if (isProxyEventV2(event)) {
162
+ return v2Processor;
163
+ } else {
164
+ return v1Processor;
165
+ }
123
166
  };
124
167
  var isProxyEventV2 = (event) => {
125
168
  return Object.prototype.hasOwnProperty.call(event, "rawPath");
@@ -47,8 +47,9 @@ const streamToNodeStream = async (reader, writer) => {
47
47
  const streamHandle = (app) => {
48
48
  return awslambda.streamifyResponse(
49
49
  async (event, responseStream, context) => {
50
+ const processor = getProcessor(event);
50
51
  try {
51
- const req = createRequest(event);
52
+ const req = processor.createRequest(event);
52
53
  const requestContext = getRequestContext(event);
53
54
  const res = await app.fetch(req, {
54
55
  event,
@@ -76,81 +77,123 @@ const streamHandle = (app) => {
76
77
  };
77
78
  const handle = (app) => {
78
79
  return async (event, lambdaContext) => {
79
- const req = createRequest(event);
80
+ const processor = getProcessor(event);
81
+ const req = processor.createRequest(event);
80
82
  const requestContext = getRequestContext(event);
81
83
  const res = await app.fetch(req, {
82
84
  event,
83
85
  requestContext,
84
86
  lambdaContext
85
87
  });
86
- return createResult(event, res);
88
+ return processor.createResult(event, res);
87
89
  };
88
90
  };
89
- const createResult = async (event, res) => {
90
- const contentType = res.headers.get("content-type");
91
- let isBase64Encoded = contentType && isContentTypeBinary(contentType) ? true : false;
92
- if (!isBase64Encoded) {
93
- const contentEncoding = res.headers.get("content-encoding");
94
- isBase64Encoded = isContentEncodingBinary(contentEncoding);
95
- }
96
- const body = isBase64Encoded ? (0, import_encode.encodeBase64)(await res.arrayBuffer()) : await res.text();
97
- const result = {
98
- body,
99
- headers: {},
100
- statusCode: res.status,
101
- isBase64Encoded
102
- };
103
- setCookies(event, res, result);
104
- res.headers.forEach((value, key) => {
105
- result.headers[key] = value;
106
- });
107
- return result;
108
- };
109
- const createRequest = (event) => {
110
- const queryString = extractQueryString(event);
111
- const domainName = event.requestContext && "domainName" in event.requestContext ? event.requestContext.domainName : event.headers["host"];
112
- const path = isProxyEventV2(event) ? event.rawPath : event.path;
113
- const urlPath = `https://${domainName}${path}`;
114
- const url = queryString ? `${urlPath}?${queryString}` : urlPath;
115
- const headers = new Headers();
116
- getCookies(event, headers);
117
- for (const [k, v] of Object.entries(event.headers)) {
118
- if (v) {
119
- headers.set(k, v);
91
+ class EventProcessor {
92
+ createRequest(event) {
93
+ const queryString = this.getQueryString(event);
94
+ const domainName = event.requestContext && "domainName" in event.requestContext ? event.requestContext.domainName : event.headers?.["host"] ?? event.multiValueHeaders?.["host"]?.[0];
95
+ const path = this.getPath(event);
96
+ const urlPath = `https://${domainName}${path}`;
97
+ const url = queryString ? `${urlPath}?${queryString}` : urlPath;
98
+ const headers = new Headers();
99
+ this.getCookies(event, headers);
100
+ if (event.headers) {
101
+ for (const [k, v] of Object.entries(event.headers)) {
102
+ if (v) {
103
+ headers.set(k, v);
104
+ }
105
+ }
106
+ }
107
+ if (event.multiValueHeaders) {
108
+ for (const [k, values] of Object.entries(event.multiValueHeaders)) {
109
+ if (values) {
110
+ values.forEach((v) => headers.append(k, v));
111
+ }
112
+ }
120
113
  }
114
+ const method = this.getMethod(event);
115
+ const requestInit = {
116
+ headers,
117
+ method
118
+ };
119
+ if (event.body) {
120
+ requestInit.body = event.isBase64Encoded ? Buffer.from(event.body, "base64") : event.body;
121
+ }
122
+ return new Request(url, requestInit);
123
+ }
124
+ async createResult(event, res) {
125
+ const contentType = res.headers.get("content-type");
126
+ let isBase64Encoded = contentType && isContentTypeBinary(contentType) ? true : false;
127
+ if (!isBase64Encoded) {
128
+ const contentEncoding = res.headers.get("content-encoding");
129
+ isBase64Encoded = isContentEncodingBinary(contentEncoding);
130
+ }
131
+ const body = isBase64Encoded ? (0, import_encode.encodeBase64)(await res.arrayBuffer()) : await res.text();
132
+ const result = {
133
+ body,
134
+ headers: {},
135
+ statusCode: res.status,
136
+ isBase64Encoded
137
+ };
138
+ this.setCookies(event, res, result);
139
+ res.headers.forEach((value, key) => {
140
+ result.headers[key] = value;
141
+ });
142
+ return result;
121
143
  }
122
- const method = isProxyEventV2(event) ? event.requestContext.http.method : event.httpMethod;
123
- const requestInit = {
124
- headers,
125
- method
144
+ setCookies = (event, res, result) => {
145
+ if (res.headers.has("set-cookie")) {
146
+ const cookies = res.headers.get("set-cookie")?.split(", ");
147
+ if (Array.isArray(cookies)) {
148
+ this.setCookiesToResult(result, cookies);
149
+ res.headers.delete("set-cookie");
150
+ }
151
+ }
126
152
  };
127
- if (event.body) {
128
- requestInit.body = event.isBase64Encoded ? Buffer.from(event.body, "base64") : event.body;
153
+ }
154
+ const v2Processor = new class EventV2Processor extends EventProcessor {
155
+ getPath(event) {
156
+ return event.rawPath;
129
157
  }
130
- return new Request(url, requestInit);
131
- };
132
- const extractQueryString = (event) => {
133
- return isProxyEventV2(event) ? event.rawQueryString : Object.entries(event.queryStringParameters || {}).filter(([, value]) => value).map(([key, value]) => `${key}=${value}`).join("&");
134
- };
135
- const getCookies = (event, headers) => {
136
- if (isProxyEventV2(event) && Array.isArray(event.cookies)) {
137
- headers.set("Cookie", event.cookies.join("; "));
158
+ getMethod(event) {
159
+ return event.requestContext.http.method;
138
160
  }
139
- };
140
- const setCookies = (event, res, result) => {
141
- if (res.headers.has("set-cookie")) {
142
- const cookies = res.headers.get("set-cookie")?.split(", ");
143
- if (Array.isArray(cookies)) {
144
- if (isProxyEventV2(event)) {
145
- result.cookies = cookies;
146
- } else {
147
- result.multiValueHeaders = {
148
- "set-cookie": cookies
149
- };
150
- }
151
- res.headers.delete("set-cookie");
161
+ getQueryString(event) {
162
+ return event.rawQueryString;
163
+ }
164
+ getCookies(event, headers) {
165
+ if (Array.isArray(event.cookies)) {
166
+ headers.set("Cookie", event.cookies.join("; "));
152
167
  }
153
168
  }
169
+ setCookiesToResult(result, cookies) {
170
+ result.cookies = cookies;
171
+ }
172
+ }();
173
+ const v1Processor = new class EventV1Processor extends EventProcessor {
174
+ getPath(event) {
175
+ return event.path;
176
+ }
177
+ getMethod(event) {
178
+ return event.httpMethod;
179
+ }
180
+ getQueryString(event) {
181
+ return Object.entries(event.queryStringParameters || {}).filter(([, value]) => value).map(([key, value]) => `${key}=${value}`).join("&");
182
+ }
183
+ getCookies(event, headers) {
184
+ }
185
+ setCookiesToResult(result, cookies) {
186
+ result.multiValueHeaders = {
187
+ "set-cookie": cookies
188
+ };
189
+ }
190
+ }();
191
+ const getProcessor = (event) => {
192
+ if (isProxyEventV2(event)) {
193
+ return v2Processor;
194
+ } else {
195
+ return v1Processor;
196
+ }
154
197
  };
155
198
  const isProxyEventV2 = (event) => {
156
199
  return Object.prototype.hasOwnProperty.call(event, "rawPath");
@@ -115,8 +115,20 @@ class ClientRequestImpl {
115
115
  });
116
116
  };
117
117
  }
118
- const hc = (baseUrl, options) => createProxy((opts) => {
118
+ const hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
119
119
  const parts = [...opts.path];
120
+ if (parts[parts.length - 1] === "toString") {
121
+ if (parts[parts.length - 2] === "name") {
122
+ return parts[parts.length - 3] || "";
123
+ }
124
+ return proxyCallback.toString();
125
+ }
126
+ if (parts[parts.length - 1] === "valueOf") {
127
+ if (parts[parts.length - 2] === "name") {
128
+ return parts[parts.length - 3] || "";
129
+ }
130
+ return proxyCallback;
131
+ }
120
132
  let method = "";
121
133
  if (/^\$/.test(parts[parts.length - 1])) {
122
134
  const last = parts.pop();
@@ -47,6 +47,9 @@ const replaceUrlProtocol = (urlString, protocol) => {
47
47
  }
48
48
  };
49
49
  const removeIndexString = (urlSting) => {
50
+ if (/^https?:\/\/[^\/]+?\/index$/.test(urlSting)) {
51
+ return urlSting.replace(/\/index$/, "/");
52
+ }
50
53
  return urlSting.replace(/\/index$/, "");
51
54
  };
52
55
  function isObject(item) {
@@ -26,8 +26,8 @@ module.exports = __toCommonJS(utils_exports);
26
26
  var import_router = require("../../router");
27
27
  var import_handler = require("../../utils/handler");
28
28
  const dirname = (path) => {
29
- const splitedPath = path.split(/[\/\\]/);
30
- return splitedPath.slice(0, -1).join("/");
29
+ const splittedPath = path.split(/[\/\\]/);
30
+ return splittedPath.slice(0, -1).join("/");
31
31
  };
32
32
  const normalizePath = (path) => {
33
33
  return path.replace(/(\\)/g, "/").replace(/\/$/g, "");
@@ -53,6 +53,8 @@ const run = async (stream, cb, onError) => {
53
53
  } else {
54
54
  console.error(e);
55
55
  }
56
+ } finally {
57
+ stream.close();
56
58
  }
57
59
  };
58
60
  const streamSSE = (c, cb, onError) => {
@@ -40,7 +40,7 @@ const buildDataStack = [];
40
40
  let nameSpaceContext = void 0;
41
41
  const isNodeString = (node) => Array.isArray(node);
42
42
  const getEventSpec = (key) => {
43
- const match = key.match(/^on([A-Z][a-zA-Z]+?)((?<!Pointer)Capture)?$/);
43
+ const match = key.match(/^on([A-Z][a-zA-Z]+?(?:PointerCapture)?)(Capture)?$/);
44
44
  if (match) {
45
45
  const [, eventName, capture] = match;
46
46
  return [(eventAliasMap[eventName] || eventName).toLowerCase(), !!capture];
@@ -99,8 +99,20 @@ var ClientRequestImpl = class {
99
99
  });
100
100
  };
101
101
  };
102
- var hc = (baseUrl, options) => createProxy((opts) => {
102
+ var hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
103
103
  const parts = [...opts.path];
104
+ if (parts[parts.length - 1] === "toString") {
105
+ if (parts[parts.length - 2] === "name") {
106
+ return parts[parts.length - 3] || "";
107
+ }
108
+ return proxyCallback.toString();
109
+ }
110
+ if (parts[parts.length - 1] === "valueOf") {
111
+ if (parts[parts.length - 2] === "name") {
112
+ return parts[parts.length - 3] || "";
113
+ }
114
+ return proxyCallback;
115
+ }
104
116
  let method = "";
105
117
  if (/^\$/.test(parts[parts.length - 1])) {
106
118
  const last = parts.pop();
@@ -21,6 +21,9 @@ var replaceUrlProtocol = (urlString, protocol) => {
21
21
  }
22
22
  };
23
23
  var removeIndexString = (urlSting) => {
24
+ if (/^https?:\/\/[^\/]+?\/index$/.test(urlSting)) {
25
+ return urlSting.replace(/\/index$/, "/");
26
+ }
24
27
  return urlSting.replace(/\/index$/, "");
25
28
  };
26
29
  function isObject(item) {
@@ -2,8 +2,8 @@
2
2
  import { METHOD_NAME_ALL } from "../../router.js";
3
3
  import { findTargetHandler, isMiddleware } from "../../utils/handler.js";
4
4
  var dirname = (path) => {
5
- const splitedPath = path.split(/[\/\\]/);
6
- return splitedPath.slice(0, -1).join("/");
5
+ const splittedPath = path.split(/[\/\\]/);
6
+ return splittedPath.slice(0, -1).join("/");
7
7
  };
8
8
  var normalizePath = (path) => {
9
9
  return path.replace(/(\\)/g, "/").replace(/\/$/g, "");
@@ -30,6 +30,8 @@ var run = async (stream, cb, onError) => {
30
30
  } else {
31
31
  console.error(e);
32
32
  }
33
+ } finally {
34
+ stream.close();
33
35
  }
34
36
  };
35
37
  var streamSSE = (c, cb, onError) => {
@@ -15,7 +15,7 @@ var buildDataStack = [];
15
15
  var nameSpaceContext = void 0;
16
16
  var isNodeString = (node) => Array.isArray(node);
17
17
  var getEventSpec = (key) => {
18
- const match = key.match(/^on([A-Z][a-zA-Z]+?)((?<!Pointer)Capture)?$/);
18
+ const match = key.match(/^on([A-Z][a-zA-Z]+?(?:PointerCapture)?)(Capture)?$/);
19
19
  if (match) {
20
20
  const [, eventName, capture] = match;
21
21
  return [(eventAliasMap[eventName] || eventName).toLowerCase(), !!capture];
@@ -7,6 +7,7 @@ export interface APIGatewayProxyEventV2 {
7
7
  version: string;
8
8
  routeKey: string;
9
9
  headers: Record<string, string | undefined>;
10
+ multiValueHeaders?: undefined;
10
11
  cookies?: string[];
11
12
  rawPath: string;
12
13
  rawQueryString: string;
@@ -44,7 +45,8 @@ export interface APIGatewayProxyEvent {
44
45
  }
45
46
  export interface ALBProxyEvent {
46
47
  httpMethod: string;
47
- headers: Record<string, string | undefined>;
48
+ headers?: Record<string, string | undefined>;
49
+ multiValueHeaders?: Record<string, string[] | undefined>;
48
50
  path: string;
49
51
  body: string | null;
50
52
  isBase64Encoded: boolean;
@@ -23,15 +23,15 @@ export type ClientRequest<S extends Schema> = {
23
23
  } ? {
24
24
  param: P;
25
25
  } : {} : {}) => URL;
26
- } & {
27
- $ws: S['$get'] extends {
28
- input: {
29
- json: UpgradedWebSocketResponseInputJSONType;
30
- };
31
- } ? S['$get'] extends {
32
- input: infer I;
33
- } ? (args?: Omit<I, 'json'>) => WebSocket : never : never;
34
- };
26
+ } & (S['$get'] extends {
27
+ input: {
28
+ json: UpgradedWebSocketResponseInputJSONType;
29
+ };
30
+ } ? S['$get'] extends {
31
+ input: infer I;
32
+ } ? {
33
+ $ws: (args?: Omit<I, 'json'>) => WebSocket;
34
+ } : {} : {});
35
35
  type BlankRecordToNever<T> = T extends any ? T extends null ? null : keyof T extends never ? never : T : never;
36
36
  export interface ClientResponse<T> {
37
37
  readonly body: ReadableStream | null;
@@ -9,7 +9,7 @@ export interface WSEvents {
9
9
  onClose?: (evt: CloseEvent, ws: WSContext) => void;
10
10
  onError?: (evt: Event, ws: WSContext) => void;
11
11
  }
12
- export type UpgradedWebSocketResponseInputJSONType = '__websocket' | undefined;
12
+ export type UpgradedWebSocketResponseInputJSONType = '__websocket';
13
13
  /**
14
14
  * Upgrade WebSocket Type
15
15
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "4.2.4",
3
+ "version": "4.2.6",
4
4
  "description": "Ultrafast web framework for the Edges",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",