@hono/node-server 1.12.1 → 1.13.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 +29 -0
- package/dist/serve-static.d.mts +5 -3
- package/dist/serve-static.d.ts +5 -3
- package/dist/serve-static.js +27 -1
- package/dist/serve-static.mjs +27 -1
- package/package.json +8 -5
package/README.md
CHANGED
|
@@ -194,6 +194,22 @@ app.use(
|
|
|
194
194
|
)
|
|
195
195
|
```
|
|
196
196
|
|
|
197
|
+
#### `onFound`
|
|
198
|
+
|
|
199
|
+
You can specify handling when the requested file is found with `onFound`.
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
app.use(
|
|
203
|
+
'/static/*',
|
|
204
|
+
serveStatic({
|
|
205
|
+
// ...
|
|
206
|
+
onFound: (_path, c) => {
|
|
207
|
+
c.header('Cache-Control', `public, immutable, max-age=31536000`)
|
|
208
|
+
},
|
|
209
|
+
})
|
|
210
|
+
)
|
|
211
|
+
```
|
|
212
|
+
|
|
197
213
|
#### `onNotFound`
|
|
198
214
|
|
|
199
215
|
The `onNotFound` is useful for debugging. You can write a handle for when a file is not found.
|
|
@@ -210,6 +226,19 @@ app.use(
|
|
|
210
226
|
)
|
|
211
227
|
```
|
|
212
228
|
|
|
229
|
+
#### `precompressed`
|
|
230
|
+
|
|
231
|
+
The `precompressed` option checks if files with extensions like `.br` or `.gz` are available and serves them based on the `Accept-Encoding` header. It prioritizes Brotli, then Zstd, and Gzip. If none are available, it serves the original file.
|
|
232
|
+
|
|
233
|
+
```ts
|
|
234
|
+
app.use(
|
|
235
|
+
'/static/*',
|
|
236
|
+
serveStatic({
|
|
237
|
+
precompressed: true,
|
|
238
|
+
})
|
|
239
|
+
)
|
|
240
|
+
```
|
|
241
|
+
|
|
213
242
|
## ConnInfo Helper
|
|
214
243
|
|
|
215
244
|
You can use the [ConnInfo Helper](https://hono.dev/docs/helpers/conninfo) by importing `getConnInfo` from `@hono/node-server/conninfo`.
|
package/dist/serve-static.d.mts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { Context, MiddlewareHandler } from 'hono';
|
|
1
|
+
import { Env, Context, MiddlewareHandler } from 'hono';
|
|
2
2
|
|
|
3
|
-
type ServeStaticOptions = {
|
|
3
|
+
type ServeStaticOptions<E extends Env = Env> = {
|
|
4
4
|
/**
|
|
5
5
|
* Root path, relative to current working directory from which the app was started. Absolute paths are not supported.
|
|
6
6
|
*/
|
|
7
7
|
root?: string;
|
|
8
8
|
path?: string;
|
|
9
9
|
index?: string;
|
|
10
|
+
precompressed?: boolean;
|
|
10
11
|
rewriteRequestPath?: (path: string) => string;
|
|
11
|
-
|
|
12
|
+
onFound?: (path: string, c: Context<E>) => void | Promise<void>;
|
|
13
|
+
onNotFound?: (path: string, c: Context<E>) => void | Promise<void>;
|
|
12
14
|
};
|
|
13
15
|
declare const serveStatic: (options?: ServeStaticOptions) => MiddlewareHandler;
|
|
14
16
|
|
package/dist/serve-static.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { Context, MiddlewareHandler } from 'hono';
|
|
1
|
+
import { Env, Context, MiddlewareHandler } from 'hono';
|
|
2
2
|
|
|
3
|
-
type ServeStaticOptions = {
|
|
3
|
+
type ServeStaticOptions<E extends Env = Env> = {
|
|
4
4
|
/**
|
|
5
5
|
* Root path, relative to current working directory from which the app was started. Absolute paths are not supported.
|
|
6
6
|
*/
|
|
7
7
|
root?: string;
|
|
8
8
|
path?: string;
|
|
9
9
|
index?: string;
|
|
10
|
+
precompressed?: boolean;
|
|
10
11
|
rewriteRequestPath?: (path: string) => string;
|
|
11
|
-
|
|
12
|
+
onFound?: (path: string, c: Context<E>) => void | Promise<void>;
|
|
13
|
+
onNotFound?: (path: string, c: Context<E>) => void | Promise<void>;
|
|
12
14
|
};
|
|
13
15
|
declare const serveStatic: (options?: ServeStaticOptions) => MiddlewareHandler;
|
|
14
16
|
|
package/dist/serve-static.js
CHANGED
|
@@ -23,9 +23,16 @@ __export(serve_static_exports, {
|
|
|
23
23
|
serveStatic: () => serveStatic
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(serve_static_exports);
|
|
26
|
-
var import_fs = require("fs");
|
|
27
26
|
var import_filepath = require("hono/utils/filepath");
|
|
28
27
|
var import_mime = require("hono/utils/mime");
|
|
28
|
+
var import_fs = require("fs");
|
|
29
|
+
var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
|
|
30
|
+
var ENCODINGS = {
|
|
31
|
+
br: ".br",
|
|
32
|
+
zstd: ".zst",
|
|
33
|
+
gzip: ".gz"
|
|
34
|
+
};
|
|
35
|
+
var ENCODINGS_ORDERED_KEYS = Object.keys(ENCODINGS);
|
|
29
36
|
var createStreamBody = (stream) => {
|
|
30
37
|
const body = new ReadableStream({
|
|
31
38
|
start(controller) {
|
|
@@ -86,10 +93,29 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
86
93
|
await options.onNotFound?.(path, c);
|
|
87
94
|
return next();
|
|
88
95
|
}
|
|
96
|
+
await options.onFound?.(path, c);
|
|
89
97
|
const mimeType = (0, import_mime.getMimeType)(path);
|
|
90
98
|
if (mimeType) {
|
|
91
99
|
c.header("Content-Type", mimeType);
|
|
92
100
|
}
|
|
101
|
+
if (options.precompressed && (!mimeType || COMPRESSIBLE_CONTENT_TYPE_REGEX.test(mimeType))) {
|
|
102
|
+
const acceptEncodingSet = new Set(
|
|
103
|
+
c.req.header("Accept-Encoding")?.split(",").map((encoding) => encoding.trim())
|
|
104
|
+
);
|
|
105
|
+
for (const encoding of ENCODINGS_ORDERED_KEYS) {
|
|
106
|
+
if (!acceptEncodingSet.has(encoding)) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const precompressedStats = getStats(path + ENCODINGS[encoding]);
|
|
110
|
+
if (precompressedStats) {
|
|
111
|
+
c.header("Content-Encoding", encoding);
|
|
112
|
+
c.header("Vary", "Accept-Encoding", { append: true });
|
|
113
|
+
stats = precompressedStats;
|
|
114
|
+
path = path + ENCODINGS[encoding];
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
93
119
|
const size = stats.size;
|
|
94
120
|
if (c.req.method == "HEAD" || c.req.method == "OPTIONS") {
|
|
95
121
|
c.header("Content-Length", size.toString());
|
package/dist/serve-static.mjs
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
// src/serve-static.ts
|
|
2
|
-
import { createReadStream, lstatSync } from "fs";
|
|
3
2
|
import { getFilePath, getFilePathWithoutDefaultDocument } from "hono/utils/filepath";
|
|
4
3
|
import { getMimeType } from "hono/utils/mime";
|
|
4
|
+
import { createReadStream, lstatSync } from "fs";
|
|
5
|
+
var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
|
|
6
|
+
var ENCODINGS = {
|
|
7
|
+
br: ".br",
|
|
8
|
+
zstd: ".zst",
|
|
9
|
+
gzip: ".gz"
|
|
10
|
+
};
|
|
11
|
+
var ENCODINGS_ORDERED_KEYS = Object.keys(ENCODINGS);
|
|
5
12
|
var createStreamBody = (stream) => {
|
|
6
13
|
const body = new ReadableStream({
|
|
7
14
|
start(controller) {
|
|
@@ -62,10 +69,29 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
62
69
|
await options.onNotFound?.(path, c);
|
|
63
70
|
return next();
|
|
64
71
|
}
|
|
72
|
+
await options.onFound?.(path, c);
|
|
65
73
|
const mimeType = getMimeType(path);
|
|
66
74
|
if (mimeType) {
|
|
67
75
|
c.header("Content-Type", mimeType);
|
|
68
76
|
}
|
|
77
|
+
if (options.precompressed && (!mimeType || COMPRESSIBLE_CONTENT_TYPE_REGEX.test(mimeType))) {
|
|
78
|
+
const acceptEncodingSet = new Set(
|
|
79
|
+
c.req.header("Accept-Encoding")?.split(",").map((encoding) => encoding.trim())
|
|
80
|
+
);
|
|
81
|
+
for (const encoding of ENCODINGS_ORDERED_KEYS) {
|
|
82
|
+
if (!acceptEncodingSet.has(encoding)) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const precompressedStats = getStats(path + ENCODINGS[encoding]);
|
|
86
|
+
if (precompressedStats) {
|
|
87
|
+
c.header("Content-Encoding", encoding);
|
|
88
|
+
c.header("Vary", "Accept-Encoding", { append: true });
|
|
89
|
+
stats = precompressedStats;
|
|
90
|
+
path = path + ENCODINGS[encoding];
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
69
95
|
const size = stats.size;
|
|
70
96
|
if (c.req.method == "HEAD" || c.req.method == "OPTIONS") {
|
|
71
97
|
c.header("Content-Length", size.toString());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hono/node-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"description": "Node.js Adapter for Hono",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -60,8 +60,8 @@
|
|
|
60
60
|
"postbuild": "publint",
|
|
61
61
|
"prerelease": "yarn build && yarn test",
|
|
62
62
|
"release": "np",
|
|
63
|
-
"lint": "eslint
|
|
64
|
-
"lint:fix": "eslint
|
|
63
|
+
"lint": "eslint src test",
|
|
64
|
+
"lint:fix": "eslint src test --fix",
|
|
65
65
|
"format": "prettier --check \"src/**/*.{js,ts}\" \"test/**/*.{js,ts}\"",
|
|
66
66
|
"format:fix": "prettier --write \"src/**/*.{js,ts}\" \"test/**/*.{js,ts}\""
|
|
67
67
|
},
|
|
@@ -80,12 +80,12 @@
|
|
|
80
80
|
"node": ">=18.14.1"
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
|
-
"@hono/eslint-config": "^
|
|
83
|
+
"@hono/eslint-config": "^1.0.1",
|
|
84
84
|
"@types/jest": "^29.5.3",
|
|
85
85
|
"@types/node": "^20.10.0",
|
|
86
86
|
"@types/supertest": "^2.0.12",
|
|
87
87
|
"@whatwg-node/fetch": "^0.9.14",
|
|
88
|
-
"eslint": "^
|
|
88
|
+
"eslint": "^9.10.0",
|
|
89
89
|
"hono": "^4.4.10",
|
|
90
90
|
"jest": "^29.6.1",
|
|
91
91
|
"np": "^7.7.0",
|
|
@@ -95,5 +95,8 @@
|
|
|
95
95
|
"ts-jest": "^29.1.1",
|
|
96
96
|
"tsup": "^7.2.0",
|
|
97
97
|
"typescript": "^5.3.2"
|
|
98
|
+
},
|
|
99
|
+
"peerDependencies": {
|
|
100
|
+
"hono": "^4"
|
|
98
101
|
}
|
|
99
102
|
}
|