@hono/node-server 1.11.5 → 1.12.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.
package/README.md CHANGED
@@ -169,7 +169,7 @@ my-hono-project/
169
169
  index.html
170
170
  ```
171
171
 
172
- Typically, you would run your app from the project's root directory (`my-hono-project`),
172
+ Typically, you would run your app from the project's root directory (`my-hono-project`),
173
173
  so you would need the following code to serve the `static` folder:
174
174
 
175
175
  ```ts
@@ -210,6 +210,19 @@ app.use(
210
210
  )
211
211
  ```
212
212
 
213
+ ## ConnInfo Helper
214
+
215
+ You can use the [ConnInfo Helper](https://hono.dev/docs/helpers/conninfo) by importing `getConnInfo` from `@hono/node-server/conninfo`.
216
+
217
+ ```ts
218
+ import { getConnInfo } from '@hono/node-server/conninfo'
219
+
220
+ app.get('/', (c) => {
221
+ const info = getConnInfo(c) // info is `ConnInfo`
222
+ return c.text(`Your remote address is ${info.remote.address}`)
223
+ })
224
+ ```
225
+
213
226
  ## Accessing Node.js API
214
227
 
215
228
  You can access the Node.js API from `c.env` in Node.js. For example, if you want to specify a type, you can write the following.
@@ -0,0 +1,10 @@
1
+ import { GetConnInfo } from 'hono/conninfo';
2
+
3
+ /**
4
+ * ConnInfo Helper for Node.js
5
+ * @param c Context
6
+ * @returns ConnInfo
7
+ */
8
+ declare const getConnInfo: GetConnInfo;
9
+
10
+ export { getConnInfo };
@@ -0,0 +1,10 @@
1
+ import { GetConnInfo } from 'hono/conninfo';
2
+
3
+ /**
4
+ * ConnInfo Helper for Node.js
5
+ * @param c Context
6
+ * @returns ConnInfo
7
+ */
8
+ declare const getConnInfo: GetConnInfo;
9
+
10
+ export { getConnInfo };
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/conninfo.ts
21
+ var conninfo_exports = {};
22
+ __export(conninfo_exports, {
23
+ getConnInfo: () => getConnInfo
24
+ });
25
+ module.exports = __toCommonJS(conninfo_exports);
26
+ var getConnInfo = (c) => {
27
+ const bindings = c.env.server ? c.env.server : c.env;
28
+ const address = bindings.incoming.socket.address();
29
+ if (!("address" in address)) {
30
+ return {
31
+ remote: {}
32
+ };
33
+ }
34
+ return {
35
+ remote: {
36
+ address: address.address,
37
+ addressType: address.family === "IPv4" ? "IPv4" : address.family === "IPv6" ? "IPv6" : "unknown",
38
+ port: address.port
39
+ }
40
+ };
41
+ };
42
+ // Annotate the CommonJS export names for ESM import in node:
43
+ 0 && (module.exports = {
44
+ getConnInfo
45
+ });
@@ -0,0 +1,20 @@
1
+ // src/conninfo.ts
2
+ var getConnInfo = (c) => {
3
+ const bindings = c.env.server ? c.env.server : c.env;
4
+ const address = bindings.incoming.socket.address();
5
+ if (!("address" in address)) {
6
+ return {
7
+ remote: {}
8
+ };
9
+ }
10
+ return {
11
+ remote: {
12
+ address: address.address,
13
+ addressType: address.family === "IPv4" ? "IPv4" : address.family === "IPv6" ? "IPv6" : "unknown",
14
+ port: address.port
15
+ }
16
+ };
17
+ };
18
+ export {
19
+ getConnInfo
20
+ };
@@ -42,22 +42,47 @@ var createStreamBody = (stream) => {
42
42
  });
43
43
  return body;
44
44
  };
45
+ var addCurrentDirPrefix = (path) => {
46
+ return `./${path}`;
47
+ };
48
+ var getStats = (path) => {
49
+ let stats;
50
+ try {
51
+ stats = (0, import_fs.lstatSync)(path);
52
+ } catch {
53
+ }
54
+ return stats;
55
+ };
45
56
  var serveStatic = (options = { root: "" }) => {
46
57
  return async (c, next) => {
47
58
  if (c.finalized) {
48
59
  return next();
49
60
  }
50
61
  const filename = options.path ?? decodeURIComponent(c.req.path);
51
- let path = (0, import_filepath.getFilePath)({
62
+ let path = (0, import_filepath.getFilePathWithoutDefaultDocument)({
52
63
  filename: options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename,
53
- root: options.root,
54
- defaultDocument: options.index ?? "index.html"
64
+ root: options.root
55
65
  });
56
- if (!path) {
66
+ if (path) {
67
+ path = addCurrentDirPrefix(path);
68
+ } else {
57
69
  return next();
58
70
  }
59
- path = `./${path}`;
60
- if (!(0, import_fs.existsSync)(path)) {
71
+ let stats = getStats(path);
72
+ if (stats && stats.isDirectory()) {
73
+ path = (0, import_filepath.getFilePath)({
74
+ filename: options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename,
75
+ root: options.root,
76
+ defaultDocument: options.index ?? "index.html"
77
+ });
78
+ if (path) {
79
+ path = addCurrentDirPrefix(path);
80
+ } else {
81
+ return next();
82
+ }
83
+ stats = getStats(path);
84
+ }
85
+ if (!stats) {
61
86
  await options.onNotFound?.(path, c);
62
87
  return next();
63
88
  }
@@ -65,8 +90,7 @@ var serveStatic = (options = { root: "" }) => {
65
90
  if (mimeType) {
66
91
  c.header("Content-Type", mimeType);
67
92
  }
68
- const stat = (0, import_fs.lstatSync)(path);
69
- const size = stat.size;
93
+ const size = stats.size;
70
94
  if (c.req.method == "HEAD" || c.req.method == "OPTIONS") {
71
95
  c.header("Content-Length", size.toString());
72
96
  c.status(200);
@@ -78,17 +102,17 @@ var serveStatic = (options = { root: "" }) => {
78
102
  return c.body(createStreamBody((0, import_fs.createReadStream)(path)), 200);
79
103
  }
80
104
  c.header("Accept-Ranges", "bytes");
81
- c.header("Date", stat.birthtime.toUTCString());
105
+ c.header("Date", stats.birthtime.toUTCString());
82
106
  const parts = range.replace(/bytes=/, "").split("-", 2);
83
107
  const start = parts[0] ? parseInt(parts[0], 10) : 0;
84
- let end = parts[1] ? parseInt(parts[1], 10) : stat.size - 1;
108
+ let end = parts[1] ? parseInt(parts[1], 10) : stats.size - 1;
85
109
  if (size < end - start + 1) {
86
110
  end = size - 1;
87
111
  }
88
112
  const chunksize = end - start + 1;
89
113
  const stream = (0, import_fs.createReadStream)(path, { start, end });
90
114
  c.header("Content-Length", chunksize.toString());
91
- c.header("Content-Range", `bytes ${start}-${end}/${stat.size}`);
115
+ c.header("Content-Range", `bytes ${start}-${end}/${stats.size}`);
92
116
  return c.body(createStreamBody(stream), 206);
93
117
  };
94
118
  };
@@ -1,6 +1,6 @@
1
1
  // src/serve-static.ts
2
- import { createReadStream, existsSync, lstatSync } from "fs";
3
- import { getFilePath } from "hono/utils/filepath";
2
+ import { createReadStream, lstatSync } from "fs";
3
+ import { getFilePath, getFilePathWithoutDefaultDocument } from "hono/utils/filepath";
4
4
  import { getMimeType } from "hono/utils/mime";
5
5
  var createStreamBody = (stream) => {
6
6
  const body = new ReadableStream({
@@ -18,22 +18,47 @@ var createStreamBody = (stream) => {
18
18
  });
19
19
  return body;
20
20
  };
21
+ var addCurrentDirPrefix = (path) => {
22
+ return `./${path}`;
23
+ };
24
+ var getStats = (path) => {
25
+ let stats;
26
+ try {
27
+ stats = lstatSync(path);
28
+ } catch {
29
+ }
30
+ return stats;
31
+ };
21
32
  var serveStatic = (options = { root: "" }) => {
22
33
  return async (c, next) => {
23
34
  if (c.finalized) {
24
35
  return next();
25
36
  }
26
37
  const filename = options.path ?? decodeURIComponent(c.req.path);
27
- let path = getFilePath({
38
+ let path = getFilePathWithoutDefaultDocument({
28
39
  filename: options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename,
29
- root: options.root,
30
- defaultDocument: options.index ?? "index.html"
40
+ root: options.root
31
41
  });
32
- if (!path) {
42
+ if (path) {
43
+ path = addCurrentDirPrefix(path);
44
+ } else {
33
45
  return next();
34
46
  }
35
- path = `./${path}`;
36
- if (!existsSync(path)) {
47
+ let stats = getStats(path);
48
+ if (stats && stats.isDirectory()) {
49
+ path = getFilePath({
50
+ filename: options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename,
51
+ root: options.root,
52
+ defaultDocument: options.index ?? "index.html"
53
+ });
54
+ if (path) {
55
+ path = addCurrentDirPrefix(path);
56
+ } else {
57
+ return next();
58
+ }
59
+ stats = getStats(path);
60
+ }
61
+ if (!stats) {
37
62
  await options.onNotFound?.(path, c);
38
63
  return next();
39
64
  }
@@ -41,8 +66,7 @@ var serveStatic = (options = { root: "" }) => {
41
66
  if (mimeType) {
42
67
  c.header("Content-Type", mimeType);
43
68
  }
44
- const stat = lstatSync(path);
45
- const size = stat.size;
69
+ const size = stats.size;
46
70
  if (c.req.method == "HEAD" || c.req.method == "OPTIONS") {
47
71
  c.header("Content-Length", size.toString());
48
72
  c.status(200);
@@ -54,17 +78,17 @@ var serveStatic = (options = { root: "" }) => {
54
78
  return c.body(createStreamBody(createReadStream(path)), 200);
55
79
  }
56
80
  c.header("Accept-Ranges", "bytes");
57
- c.header("Date", stat.birthtime.toUTCString());
81
+ c.header("Date", stats.birthtime.toUTCString());
58
82
  const parts = range.replace(/bytes=/, "").split("-", 2);
59
83
  const start = parts[0] ? parseInt(parts[0], 10) : 0;
60
- let end = parts[1] ? parseInt(parts[1], 10) : stat.size - 1;
84
+ let end = parts[1] ? parseInt(parts[1], 10) : stats.size - 1;
61
85
  if (size < end - start + 1) {
62
86
  end = size - 1;
63
87
  }
64
88
  const chunksize = end - start + 1;
65
89
  const stream = createReadStream(path, { start, end });
66
90
  c.header("Content-Length", chunksize.toString());
67
- c.header("Content-Range", `bytes ${start}-${end}/${stat.size}`);
91
+ c.header("Content-Range", `bytes ${start}-${end}/${stats.size}`);
68
92
  return c.body(createStreamBody(stream), 206);
69
93
  };
70
94
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hono/node-server",
3
- "version": "1.11.5",
3
+ "version": "1.12.0",
4
4
  "description": "Node.js Adapter for Hono",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -27,6 +27,11 @@
27
27
  "types": "./dist/utils/*.d.ts",
28
28
  "require": "./dist/utils/*.js",
29
29
  "import": "./dist/utils/*.mjs"
30
+ },
31
+ "./conninfo": {
32
+ "types": "./dist/conninfo.d.ts",
33
+ "require": "./dist/conninfo.js",
34
+ "import": "./dist/conninfo.mjs"
30
35
  }
31
36
  },
32
37
  "typesVersions": {
@@ -42,6 +47,9 @@
42
47
  ],
43
48
  "utils/*": [
44
49
  "./dist/utils/*.d.ts"
50
+ ],
51
+ "conninfo": [
52
+ "./dist/conninfo.d.ts"
45
53
  ]
46
54
  }
47
55
  },