hono 4.4.2 → 4.4.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.
Files changed (37) hide show
  1. package/README.md +2 -1
  2. package/dist/adapter/cloudflare-workers/index.js +2 -0
  3. package/dist/adapter/cloudflare-workers/websocket.js +1 -0
  4. package/dist/adapter/deno/serve-static.js +2 -3
  5. package/dist/adapter/deno/websocket.js +1 -1
  6. package/dist/cjs/adapter/cloudflare-workers/index.js +3 -0
  7. package/dist/cjs/adapter/cloudflare-workers/websocket.js +1 -0
  8. package/dist/cjs/adapter/deno/serve-static.js +2 -3
  9. package/dist/cjs/adapter/deno/websocket.js +1 -1
  10. package/dist/cjs/context.js +2 -2
  11. package/dist/cjs/{adapter/aws-lambda/custom-context.js → helper/conninfo/types.js} +2 -2
  12. package/dist/cjs/hono-base.js +31 -18
  13. package/dist/cjs/jsx/utils.js +4 -0
  14. package/dist/cjs/middleware/serve-static/index.js +5 -3
  15. package/dist/cjs/utils/filepath.js +1 -1
  16. package/dist/context.js +2 -2
  17. package/dist/hono-base.js +32 -19
  18. package/dist/jsx/utils.js +4 -0
  19. package/dist/middleware/serve-static/index.js +5 -3
  20. package/dist/types/adapter/aws-lambda/handler.d.ts +1 -2
  21. package/dist/types/adapter/aws-lambda/index.d.ts +1 -2
  22. package/dist/types/adapter/aws-lambda/types.d.ts +82 -0
  23. package/dist/types/adapter/cloudflare-workers/index.d.ts +1 -0
  24. package/dist/types/context.d.ts +54 -25
  25. package/dist/types/helper/conninfo/index.d.ts +1 -36
  26. package/dist/types/helper/conninfo/types.d.ts +36 -0
  27. package/dist/types/hono-base.d.ts +86 -15
  28. package/dist/types/http-exception.d.ts +9 -1
  29. package/dist/types/jsx/utils.d.ts +6 -0
  30. package/dist/types/request.d.ts +42 -14
  31. package/dist/types/types.d.ts +11 -8
  32. package/dist/types/utils/http-status.d.ts +10 -5
  33. package/dist/types/utils/types.d.ts +10 -3
  34. package/dist/utils/filepath.js +1 -1
  35. package/package.json +5 -4
  36. package/dist/types/adapter/aws-lambda/custom-context.d.ts +0 -83
  37. /package/dist/{adapter/aws-lambda/custom-context.js → helper/conninfo/types.js} +0 -0
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  <p align="center">
10
10
  <a href="https://hono.dev"><b>Documentation 👉 hono.dev</b></a><br />
11
- <i>v4 has been released!</i> <a href="docs/MIGRATION.md">Migration guide</b>
11
+ <i>Now supports <a href="https://jsr.io/@hono/hono">JSR</a> and <code>deno.land/x</code> is deprecated! See <a href="docs/MIGRATION.md">Migration guide</a>.</i>
12
12
  </p>
13
13
 
14
14
  <hr />
@@ -22,6 +22,7 @@
22
22
  [![Bundle Size](https://img.shields.io/bundlephobia/minzip/hono)](https://bundlephobia.com/result?p=hono)
23
23
  [![GitHub commit activity](https://img.shields.io/github/commit-activity/m/honojs/hono)](https://github.com/honojs/hono/pulse)
24
24
  [![GitHub last commit](https://img.shields.io/github/last-commit/honojs/hono)](https://github.com/honojs/hono/commits/main)
25
+ [![codecov](https://codecov.io/github/honojs/hono/graph/badge.svg)](https://codecov.io/github/honojs/hono)
25
26
  [![Discord badge](https://img.shields.io/discord/1011308539819597844?label=Discord&logo=Discord)](https://discord.gg/KMh2eNSdxV)
26
27
 
27
28
  Hono - _**\[炎\] means flame🔥 in Japanese**_ - is a small, simple, and ultrafast web framework for the Edges.
@@ -1,7 +1,9 @@
1
1
  // src/adapter/cloudflare-workers/index.ts
2
2
  import { serveStatic } from "./serve-static-module.js";
3
3
  import { upgradeWebSocket } from "./websocket.js";
4
+ import { getConnInfo } from "./conninfo.js";
4
5
  export {
6
+ getConnInfo,
5
7
  serveStatic,
6
8
  upgradeWebSocket
7
9
  };
@@ -35,6 +35,7 @@ var upgradeWebSocket = (createEvents) => async (c, next) => {
35
35
  }
36
36
  server.accept?.();
37
37
  return new Response(null, {
38
+ status: 101,
38
39
  webSocket: client
39
40
  });
40
41
  };
@@ -4,13 +4,12 @@ var { open } = Deno;
4
4
  var serveStatic = (options) => {
5
5
  return async function serveStatic2(c, next) {
6
6
  const getContent = async (path) => {
7
- let file;
8
7
  try {
9
- file = await open(path);
8
+ const file = await open(path);
9
+ return file ? file.readable : null;
10
10
  } catch (e) {
11
11
  console.warn(`${e}`);
12
12
  }
13
- return file ? file.readable : null;
14
13
  };
15
14
  const pathResolve = (path) => {
16
15
  return `./${path}`;
@@ -3,8 +3,8 @@ var upgradeWebSocket = (createEvents) => async (c, next) => {
3
3
  if (c.req.header("upgrade") !== "websocket") {
4
4
  return await next();
5
5
  }
6
- const { response, socket } = Deno.upgradeWebSocket(c.req.raw);
7
6
  const events = await createEvents(c);
7
+ const { response, socket } = Deno.upgradeWebSocket(c.req.raw);
8
8
  const wsContext = {
9
9
  binaryType: "arraybuffer",
10
10
  close: (code, reason) => socket.close(code, reason),
@@ -18,14 +18,17 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var cloudflare_workers_exports = {};
20
20
  __export(cloudflare_workers_exports, {
21
+ getConnInfo: () => import_conninfo.getConnInfo,
21
22
  serveStatic: () => import_serve_static_module.serveStatic,
22
23
  upgradeWebSocket: () => import_websocket.upgradeWebSocket
23
24
  });
24
25
  module.exports = __toCommonJS(cloudflare_workers_exports);
25
26
  var import_serve_static_module = require("./serve-static-module");
26
27
  var import_websocket = require("./websocket");
28
+ var import_conninfo = require("./conninfo");
27
29
  // Annotate the CommonJS export names for ESM import in node:
28
30
  0 && (module.exports = {
31
+ getConnInfo,
29
32
  serveStatic,
30
33
  upgradeWebSocket
31
34
  });
@@ -57,6 +57,7 @@ const upgradeWebSocket = (createEvents) => async (c, next) => {
57
57
  }
58
58
  server.accept?.();
59
59
  return new Response(null, {
60
+ status: 101,
60
61
  webSocket: client
61
62
  });
62
63
  };
@@ -26,13 +26,12 @@ const { open } = Deno;
26
26
  const serveStatic = (options) => {
27
27
  return async function serveStatic2(c, next) {
28
28
  const getContent = async (path) => {
29
- let file;
30
29
  try {
31
- file = await open(path);
30
+ const file = await open(path);
31
+ return file ? file.readable : null;
32
32
  } catch (e) {
33
33
  console.warn(`${e}`);
34
34
  }
35
- return file ? file.readable : null;
36
35
  };
37
36
  const pathResolve = (path) => {
38
37
  return `./${path}`;
@@ -25,8 +25,8 @@ const upgradeWebSocket = (createEvents) => async (c, next) => {
25
25
  if (c.req.header("upgrade") !== "websocket") {
26
26
  return await next();
27
27
  }
28
- const { response, socket } = Deno.upgradeWebSocket(c.req.raw);
29
28
  const events = await createEvents(c);
29
+ const { response, socket } = Deno.upgradeWebSocket(c.req.raw);
30
30
  const wsContext = {
31
31
  binaryType: "arraybuffer",
32
32
  close: (code, reason) => socket.close(code, reason),
@@ -232,10 +232,10 @@ class Context {
232
232
  }
233
233
  return typeof arg === "number" ? this.newResponse(html, arg, headers) : this.newResponse(html, arg);
234
234
  };
235
- redirect = (location, status = 302) => {
235
+ redirect = (location, status) => {
236
236
  this.#headers ??= new Headers();
237
237
  this.#headers.set("Location", location);
238
- return this.newResponse(null, status);
238
+ return this.newResponse(null, status ?? 302);
239
239
  };
240
240
  notFound = () => {
241
241
  return this.notFoundHandler(this);
@@ -12,5 +12,5 @@ var __copyProps = (to, from, except, desc) => {
12
12
  return to;
13
13
  };
14
14
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
- var custom_context_exports = {};
16
- module.exports = __toCommonJS(custom_context_exports);
15
+ var types_exports = {};
16
+ module.exports = __toCommonJS(types_exports);
@@ -24,7 +24,6 @@ __export(hono_base_exports, {
24
24
  module.exports = __toCommonJS(hono_base_exports);
25
25
  var import_compose = require("./compose");
26
26
  var import_context = require("./context");
27
- var import_http_exception = require("./http-exception");
28
27
  var import_request = require("./request");
29
28
  var import_router = require("./router");
30
29
  var import_url = require("./utils/url");
@@ -33,7 +32,7 @@ const notFoundHandler = (c) => {
33
32
  return c.text("404 Not Found", 404);
34
33
  };
35
34
  const errorHandler = (err, c) => {
36
- if (err instanceof import_http_exception.HTTPException) {
35
+ if ("getResponse" in err) {
37
36
  return err.getResponse();
38
37
  }
39
38
  console.error(err);
@@ -142,25 +141,39 @@ class Hono {
142
141
  this.notFoundHandler = handler;
143
142
  return this;
144
143
  };
145
- mount(path, applicationHandler, optionHandler) {
146
- const mergedPath = (0, import_url.mergePath)(this._basePath, path);
147
- const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
148
- const handler = async (c, next) => {
144
+ mount(path, applicationHandler, options) {
145
+ let replaceRequest;
146
+ let optionHandler;
147
+ if (options) {
148
+ if (typeof options === "function") {
149
+ optionHandler = options;
150
+ } else {
151
+ optionHandler = options.optionHandler;
152
+ replaceRequest = options.replaceRequest;
153
+ }
154
+ }
155
+ const getOptions = optionHandler ? (c) => {
156
+ const options2 = optionHandler(c);
157
+ return Array.isArray(options2) ? options2 : [options2];
158
+ } : (c) => {
149
159
  let executionContext = void 0;
150
160
  try {
151
161
  executionContext = c.executionCtx;
152
162
  } catch {
153
163
  }
154
- const options = optionHandler ? optionHandler(c) : [c.env, executionContext];
155
- const optionsArray = Array.isArray(options) ? options : [options];
156
- const queryStrings = (0, import_url.getQueryStrings)(c.req.url);
157
- const res = await applicationHandler(
158
- new Request(
159
- new URL((c.req.path.slice(pathPrefixLength) || "/") + queryStrings, c.req.url),
160
- c.req.raw
161
- ),
162
- ...optionsArray
163
- );
164
+ return [c.env, executionContext];
165
+ };
166
+ replaceRequest ||= (() => {
167
+ const mergedPath = (0, import_url.mergePath)(this._basePath, path);
168
+ const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
169
+ return (request) => {
170
+ const url = new URL(request.url);
171
+ url.pathname = url.pathname.slice(pathPrefixLength) || "/";
172
+ return new Request(url, request);
173
+ };
174
+ })();
175
+ const handler = async (c, next) => {
176
+ const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c));
164
177
  if (res) {
165
178
  return res;
166
179
  }
@@ -207,7 +220,7 @@ class Hono {
207
220
  }
208
221
  return res instanceof Promise ? res.then(
209
222
  (resolved) => resolved || (c.finalized ? c.res : this.notFoundHandler(c))
210
- ).catch((err) => this.handleError(err, c)) : res;
223
+ ).catch((err) => this.handleError(err, c)) : res ?? this.notFoundHandler(c);
211
224
  }
212
225
  const composed = (0, import_compose.compose)(matchResult[0], this.errorHandler, this.notFoundHandler);
213
226
  return (async () => {
@@ -215,7 +228,7 @@ class Hono {
215
228
  const context = await composed(c);
216
229
  if (!context.finalized) {
217
230
  throw new Error(
218
- "Context is not finalized. You may forget returning Response object or `await next()`"
231
+ "Context is not finalized. Did you forget to return a Response object or `await next()`?"
219
232
  );
220
233
  }
221
234
  return context.res;
@@ -27,6 +27,10 @@ const normalizeIntrinsicElementProps = (props) => {
27
27
  props["class"] = props["className"];
28
28
  delete props["className"];
29
29
  }
30
+ if (props && "htmlFor" in props) {
31
+ props["for"] = props["htmlFor"];
32
+ delete props["htmlFor"];
33
+ }
30
34
  };
31
35
  const styleObjectForEach = (style, fn) => {
32
36
  for (const [k, v] of Object.entries(style)) {
@@ -55,9 +55,11 @@ const serveStatic = (options) => {
55
55
  return await next();
56
56
  }
57
57
  pathWithOutDefaultDocument = pathResolve(pathWithOutDefaultDocument);
58
- content = await getContent(pathWithOutDefaultDocument, c);
59
- if (content) {
60
- path = pathWithOutDefaultDocument;
58
+ if (pathWithOutDefaultDocument !== path) {
59
+ content = await getContent(pathWithOutDefaultDocument, c);
60
+ if (content) {
61
+ path = pathWithOutDefaultDocument;
62
+ }
61
63
  }
62
64
  }
63
65
  if (content instanceof Response) {
@@ -27,7 +27,7 @@ const getFilePath = (options) => {
27
27
  const defaultDocument = options.defaultDocument || "index.html";
28
28
  if (filename.endsWith("/")) {
29
29
  filename = filename.concat(defaultDocument);
30
- } else if (!filename.match(/\.[a-zA-Z0-9]+$/)) {
30
+ } else if (!filename.match(/\.[a-zA-Z0-9_-]+$/)) {
31
31
  filename = filename.concat("/" + defaultDocument);
32
32
  }
33
33
  const path = getFilePathWithoutDefaultDocument({
package/dist/context.js CHANGED
@@ -209,10 +209,10 @@ var Context = class {
209
209
  }
210
210
  return typeof arg === "number" ? this.newResponse(html, arg, headers) : this.newResponse(html, arg);
211
211
  };
212
- redirect = (location, status = 302) => {
212
+ redirect = (location, status) => {
213
213
  this.#headers ??= new Headers();
214
214
  this.#headers.set("Location", location);
215
- return this.newResponse(null, status);
215
+ return this.newResponse(null, status ?? 302);
216
216
  };
217
217
  notFound = () => {
218
218
  return this.notFoundHandler(this);
package/dist/hono-base.js CHANGED
@@ -1,16 +1,15 @@
1
1
  // src/hono-base.ts
2
2
  import { compose } from "./compose.js";
3
3
  import { Context } from "./context.js";
4
- import { HTTPException } from "./http-exception.js";
5
4
  import { HonoRequest } from "./request.js";
6
5
  import { METHODS, METHOD_NAME_ALL, METHOD_NAME_ALL_LOWERCASE } from "./router.js";
7
- import { getPath, getPathNoStrict, getQueryStrings, mergePath } from "./utils/url.js";
6
+ import { getPath, getPathNoStrict, mergePath } from "./utils/url.js";
8
7
  var COMPOSED_HANDLER = Symbol("composedHandler");
9
8
  var notFoundHandler = (c) => {
10
9
  return c.text("404 Not Found", 404);
11
10
  };
12
11
  var errorHandler = (err, c) => {
13
- if (err instanceof HTTPException) {
12
+ if ("getResponse" in err) {
14
13
  return err.getResponse();
15
14
  }
16
15
  console.error(err);
@@ -119,25 +118,39 @@ var Hono = class {
119
118
  this.notFoundHandler = handler;
120
119
  return this;
121
120
  };
122
- mount(path, applicationHandler, optionHandler) {
123
- const mergedPath = mergePath(this._basePath, path);
124
- const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
125
- const handler = async (c, next) => {
121
+ mount(path, applicationHandler, options) {
122
+ let replaceRequest;
123
+ let optionHandler;
124
+ if (options) {
125
+ if (typeof options === "function") {
126
+ optionHandler = options;
127
+ } else {
128
+ optionHandler = options.optionHandler;
129
+ replaceRequest = options.replaceRequest;
130
+ }
131
+ }
132
+ const getOptions = optionHandler ? (c) => {
133
+ const options2 = optionHandler(c);
134
+ return Array.isArray(options2) ? options2 : [options2];
135
+ } : (c) => {
126
136
  let executionContext = void 0;
127
137
  try {
128
138
  executionContext = c.executionCtx;
129
139
  } catch {
130
140
  }
131
- const options = optionHandler ? optionHandler(c) : [c.env, executionContext];
132
- const optionsArray = Array.isArray(options) ? options : [options];
133
- const queryStrings = getQueryStrings(c.req.url);
134
- const res = await applicationHandler(
135
- new Request(
136
- new URL((c.req.path.slice(pathPrefixLength) || "/") + queryStrings, c.req.url),
137
- c.req.raw
138
- ),
139
- ...optionsArray
140
- );
141
+ return [c.env, executionContext];
142
+ };
143
+ replaceRequest ||= (() => {
144
+ const mergedPath = mergePath(this._basePath, path);
145
+ const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
146
+ return (request) => {
147
+ const url = new URL(request.url);
148
+ url.pathname = url.pathname.slice(pathPrefixLength) || "/";
149
+ return new Request(url, request);
150
+ };
151
+ })();
152
+ const handler = async (c, next) => {
153
+ const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c));
141
154
  if (res) {
142
155
  return res;
143
156
  }
@@ -184,7 +197,7 @@ var Hono = class {
184
197
  }
185
198
  return res instanceof Promise ? res.then(
186
199
  (resolved) => resolved || (c.finalized ? c.res : this.notFoundHandler(c))
187
- ).catch((err) => this.handleError(err, c)) : res;
200
+ ).catch((err) => this.handleError(err, c)) : res ?? this.notFoundHandler(c);
188
201
  }
189
202
  const composed = compose(matchResult[0], this.errorHandler, this.notFoundHandler);
190
203
  return (async () => {
@@ -192,7 +205,7 @@ var Hono = class {
192
205
  const context = await composed(c);
193
206
  if (!context.finalized) {
194
207
  throw new Error(
195
- "Context is not finalized. You may forget returning Response object or `await next()`"
208
+ "Context is not finalized. Did you forget to return a Response object or `await next()`?"
196
209
  );
197
210
  }
198
211
  return context.res;
package/dist/jsx/utils.js CHANGED
@@ -4,6 +4,10 @@ var normalizeIntrinsicElementProps = (props) => {
4
4
  props["class"] = props["className"];
5
5
  delete props["className"];
6
6
  }
7
+ if (props && "htmlFor" in props) {
8
+ props["for"] = props["htmlFor"];
9
+ delete props["htmlFor"];
10
+ }
7
11
  };
8
12
  var styleObjectForEach = (style, fn) => {
9
13
  for (const [k, v] of Object.entries(style)) {
@@ -33,9 +33,11 @@ var serveStatic = (options) => {
33
33
  return await next();
34
34
  }
35
35
  pathWithOutDefaultDocument = pathResolve(pathWithOutDefaultDocument);
36
- content = await getContent(pathWithOutDefaultDocument, c);
37
- if (content) {
38
- path = pathWithOutDefaultDocument;
36
+ if (pathWithOutDefaultDocument !== path) {
37
+ content = await getContent(pathWithOutDefaultDocument, c);
38
+ if (content) {
39
+ path = pathWithOutDefaultDocument;
40
+ }
39
41
  }
40
42
  }
41
43
  if (content instanceof Response) {
@@ -1,7 +1,6 @@
1
1
  import type { Hono } from '../../hono';
2
2
  import type { Env, Schema } from '../../types';
3
- import type { ALBRequestContext, ApiGatewayRequestContext, ApiGatewayRequestContextV2 } from './custom-context';
4
- import type { Handler, LambdaContext } from './types';
3
+ import type { ALBRequestContext, ApiGatewayRequestContext, ApiGatewayRequestContextV2, Handler, LambdaContext } from './types';
5
4
  export type LambdaEvent = APIGatewayProxyEvent | APIGatewayProxyEventV2 | ALBProxyEvent;
6
5
  export interface APIGatewayProxyEventV2 {
7
6
  version: string;
@@ -4,5 +4,4 @@
4
4
  */
5
5
  export { handle, streamHandle } from './handler';
6
6
  export type { APIGatewayProxyResult, LambdaEvent } from './handler';
7
- export type { ApiGatewayRequestContext, ApiGatewayRequestContextV2, ALBRequestContext, } from './custom-context';
8
- export type { LambdaContext } from './types';
7
+ export type { ApiGatewayRequestContext, ApiGatewayRequestContextV2, ALBRequestContext, LambdaContext, } from './types';
@@ -40,4 +40,86 @@ export interface LambdaContext {
40
40
  }
41
41
  type Callback<TResult = any> = (error?: Error | string | null, result?: TResult) => void;
42
42
  export type Handler<TEvent = any, TResult = any> = (event: TEvent, context: LambdaContext, callback: Callback<TResult>) => void | Promise<TResult>;
43
+ interface ClientCert {
44
+ clientCertPem: string;
45
+ subjectDN: string;
46
+ issuerDN: string;
47
+ serialNumber: string;
48
+ validity: {
49
+ notBefore: string;
50
+ notAfter: string;
51
+ };
52
+ }
53
+ interface Identity {
54
+ accessKey?: string;
55
+ accountId?: string;
56
+ caller?: string;
57
+ cognitoAuthenticationProvider?: string;
58
+ cognitoAuthenticationType?: string;
59
+ cognitoIdentityId?: string;
60
+ cognitoIdentityPoolId?: string;
61
+ principalOrgId?: string;
62
+ sourceIp: string;
63
+ user?: string;
64
+ userAgent: string;
65
+ userArn?: string;
66
+ clientCert?: ClientCert;
67
+ }
68
+ export interface ApiGatewayRequestContext {
69
+ accountId: string;
70
+ apiId: string;
71
+ authorizer: {
72
+ claims?: unknown;
73
+ scopes?: unknown;
74
+ };
75
+ domainName: string;
76
+ domainPrefix: string;
77
+ extendedRequestId: string;
78
+ httpMethod: string;
79
+ identity: Identity;
80
+ path: string;
81
+ protocol: string;
82
+ requestId: string;
83
+ requestTime: string;
84
+ requestTimeEpoch: number;
85
+ resourceId?: string;
86
+ resourcePath: string;
87
+ stage: string;
88
+ }
89
+ interface Authorizer {
90
+ iam?: {
91
+ accessKey: string;
92
+ accountId: string;
93
+ callerId: string;
94
+ cognitoIdentity: null;
95
+ principalOrgId: null;
96
+ userArn: string;
97
+ userId: string;
98
+ };
99
+ }
100
+ export interface ApiGatewayRequestContextV2 {
101
+ accountId: string;
102
+ apiId: string;
103
+ authentication: null;
104
+ authorizer: Authorizer;
105
+ domainName: string;
106
+ domainPrefix: string;
107
+ http: {
108
+ method: string;
109
+ path: string;
110
+ protocol: string;
111
+ sourceIp: string;
112
+ userAgent: string;
113
+ };
114
+ requestId: string;
115
+ routeKey: string;
116
+ stage: string;
117
+ time: string;
118
+ timeEpoch: number;
119
+ }
120
+ export interface ALBRequestContext {
121
+ elb: {
122
+ targetGroupArn: string;
123
+ };
124
+ }
43
125
  export {};
@@ -4,3 +4,4 @@
4
4
  */
5
5
  export { serveStatic } from './serve-static-module';
6
6
  export { upgradeWebSocket } from './websocket';
7
+ export { getConnInfo } from './conninfo';