Skip to content

Commit d0bbc92

Browse files
authored
feat(serve-static): add onFound option (#198)
1 parent d560932 commit d0bbc92

File tree

3 files changed

+31
-4
lines changed

3 files changed

+31
-4
lines changed

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,22 @@ app.use(
194194
)
195195
```
196196

197+
#### `onFound`
198+
199+
You can specify handling when the requested file is found with `onFound`.
200+
201+
```ts
202+
app.get(
203+
'/static/*',
204+
serveStatic({
205+
// ...
206+
onFound: (_path, c) => {
207+
c.header('Cache-Control', `public, immutable, max-age=31536000`)
208+
},
209+
})
210+
)
211+
```
212+
197213
#### `onNotFound`
198214

199215
The `onNotFound` is useful for debugging. You can write a handle for when a file is not found.

src/serve-static.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1-
import type { Context, MiddlewareHandler } from 'hono'
1+
import type { Context, Env, MiddlewareHandler } from 'hono'
22
import { getFilePath, getFilePathWithoutDefaultDocument } from 'hono/utils/filepath'
33
import { getMimeType } from 'hono/utils/mime'
44
import { createReadStream, lstatSync } from 'fs'
55
import type { ReadStream, Stats } from 'fs'
66

7-
export type ServeStaticOptions = {
7+
export type ServeStaticOptions<E extends Env = Env> = {
88
/**
99
* Root path, relative to current working directory from which the app was started. Absolute paths are not supported.
1010
*/
1111
root?: string
1212
path?: string
1313
index?: string // default is 'index.html'
1414
rewriteRequestPath?: (path: string) => string
15-
onNotFound?: (path: string, c: Context) => void | Promise<void>
15+
onFound?: (path: string, c: Context<E>) => void | Promise<void>
16+
onNotFound?: (path: string, c: Context<E>) => void | Promise<void>
1617
}
1718

1819
const createStreamBody = (stream: ReadStream) => {
@@ -87,6 +88,7 @@ export const serveStatic = (options: ServeStaticOptions = { root: '' }): Middlew
8788
await options.onNotFound?.(path, c)
8889
return next()
8990
}
91+
await options.onFound?.(path, c)
9092

9193
const mimeType = getMimeType(path)
9294
if (mimeType) {

test/serve-static.test.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,15 @@ import { createAdaptorServer } from './../src/server'
66
describe('Serve Static Middleware', () => {
77
const app = new Hono()
88

9-
app.use('/static/*', serveStatic({ root: './test/assets' }))
9+
app.use(
10+
'/static/*',
11+
serveStatic({
12+
root: './test/assets',
13+
onFound: (path, c) => {
14+
c.header('X-Custom', `Found the file at ${path}`)
15+
},
16+
})
17+
)
1018
app.use('/favicon.ico', serveStatic({ path: './test/assets/favicon.ico' }))
1119
app.use(
1220
'/dot-static/*',
@@ -34,6 +42,7 @@ describe('Serve Static Middleware', () => {
3442
expect(res.status).toBe(200)
3543
expect(res.text).toBe('<h1>Hello Hono</h1>')
3644
expect(res.headers['content-type']).toBe('text/html; charset=utf-8')
45+
expect(res.headers['x-custom']).toBe('Found the file at ./test/assets/static/index.html')
3746
})
3847

3948
it('Should return hono.html', async () => {

0 commit comments

Comments
 (0)