Repository: honojs/node-server (ts)

Issue:
serveStatic need optional parameter that allows to edit the route to file path
Currently, `serveStatic` does this:
```js

$ node src/index.js
Static file: ./.reejs/__reejs/deps/render/index.js is not found
Static file: ./.reejs/__reejs/.reejs/deps/render/index.js is not found
Static file: ./.reejs/__reejs/deps/react/index.js is not found
Static file: ./.reejs/__reejs/cache/cache.json is not found
^C
______________________________________________________________________

$ cat src/index.js
import { serve } from '@hono/node-server';
import { Hono } from 'hono';
import {serveStatic} from '@hono/node-server/serve-static;
const app = new Hono();
app.get('/', (c) => c.text('Hello Hono!'));                           
app.use('/__reejs/**', serveStatic({root: './.reejs/'}));

serve(app)
```

My files are saved inside `.reejs` folder, and not inside `.reejs/__reejs` folder.

Suggested fix: add a new parameter called `rewritePath`
```js
app.use(
  '/__reejs/*',
  serveStatic({ root: './.reejs/', rewritePath: (path: string) => path.replace(/^\/__reejs/, '') })
)
```

Pull request description:
feat(serve-static): add `rewriteRequestPath` option
This PR enables rewriting a request path for Serve Static middleware.

If you want to serve files in `./.foojs` with the request path `/__foo/*`, you can write:

```ts
 app.use(
  '/__foo/*',
  serveStatic({
    root: './.foojs/',
    rewriteRequestPath: (path: string) => path.replace(/^\/__foo/, ''),
  })
)
```

Fix #29 

Patch:
diff --git a/README.md b/README.md
index 1e1eec0..a28fc8e 100644
--- a/README.md
+++ b/README.md
@@ -77,7 +77,7 @@ app.get('/', (c) => c.json({ 'Hono meets': 'Node.js' }))
 serve(app)
 ```
 
-### Serve Static Middleware
+## Serve Static Middleware
 
 Use Serve Static Middleware that has been created for Node.js.
 
@@ -89,7 +89,23 @@ import { serveStatic } from '@hono/node-server/serve-static'
 app.use('/static/*', serveStatic({ root: './' }))
 ```
 
-Note that `root` must be *relative* to the current working directory - absolute paths are not supported.
+Note that `root` must be _relative_ to the current working directory - absolute paths are not supported.
+
+### Options
+
+#### `rewriteRequestPath`
+
+If you want to serve files in `./.foojs` with the request path `/__foo/*`, you can write like the following.
+
+```ts
+app.use(
+  '/__foo/*',
+  serveStatic({
+    root: './.foojs/',
+    rewriteRequestPath: (path: string) => path.replace(/^\/__foo/, ''),
+  })
+)
+```
 
 ## Related projects
 
diff --git a/src/serve-static.ts b/src/serve-static.ts
index 59ed433..c9a3592 100644
--- a/src/serve-static.ts
+++ b/src/serve-static.ts
@@ -11,6 +11,7 @@ export type ServeStaticOptions = {
   root?: string
   path?: string
   index?: string // default is 'index.html'
+  rewriteRequestPath?: (path: string) => string
 }
 
 export const serveStatic = (options: ServeStaticOptions = { root: '' }) => {
@@ -21,8 +22,9 @@ export const serveStatic = (options: ServeStaticOptions = { root: '' }) => {
     }
     const url = new URL(c.req.url)
 
+    const filename = options.path ?? url.pathname
     let path = getFilePath({
-      filename: options.path ?? url.pathname,
+      filename: options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename,
       root: options.root,
       defaultDocument: options.index ?? 'index.html',
     })


Test patch:
diff --git a/test/assets/.static/plain.txt b/test/assets/.static/plain.txt
new file mode 100644
index 0000000..fd3af60
--- /dev/null
+++ b/test/assets/.static/plain.txt
@@ -0,0 +1,1 @@
+This is plain.txt
\ No newline at end of file
diff --git a/test/serve-static.test.ts b/test/serve-static.test.ts
index 0011d85..5df2bda 100644
--- a/test/serve-static.test.ts
+++ b/test/serve-static.test.ts
@@ -8,6 +8,13 @@ describe('Serve Static Middleware', () => {
 
   app.use('/static/*', serveStatic({ root: './test/assets' }))
   app.use('/favicon.ico', serveStatic({ path: './test/assets/favicon.ico' }))
+  app.use(
+    '/dot-static/*',
+    serveStatic({
+      root: './test/assets',
+      rewriteRequestPath: (path) => path.replace(/^\/dot-static/, '/.static'),
+    })
+  )
 
   const server = createAdaptorServer(app)
 
@@ -55,4 +62,16 @@ describe('Serve Static Middleware', () => {
     expect(res.headers['content-type']).toBe('text/plain;charset=UTF-8')
     expect(res.text).toBe('404 Not Found')
   })
+
+  it('Should return 200 with rewriteRequestPath', async () => {
+    const res = await request(server).get('/dot-static/plain.txt')
+    expect(res.status).toBe(200)
+    expect(res.headers['content-type']).toBe('text/plain; charset=utf-8')
+    expect(res.text).toBe('This is plain.txt')
+  })
+
+  it('Should return 404 with rewriteRequestPath', async () => {
+    const res = await request(server).get('/dot-static/does-no-exists.txt')
+    expect(res.status).toBe(404)
+  })
 })