From 753032ad602963bb37378a1aa1f992fd862e6994 Mon Sep 17 00:00:00 2001 From: Julien Ripouteau Date: Sun, 15 Mar 2026 18:26:16 +0100 Subject: [PATCH 1/2] fix: allow dotfiles option --- src/static_middleware.ts | 5 +++- tests/static_middleware.spec.ts | 48 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/static_middleware.ts b/src/static_middleware.ts index efe6f3c..1c8513a 100644 --- a/src/static_middleware.ts +++ b/src/static_middleware.ts @@ -54,8 +54,11 @@ export default class StaticMiddleware { * ``` */ constructor(publicPath: string, config: AssetsConfig) { + const { dotFiles, ...rest } = config + this.#sendFile = staticServer(publicPath, { - ...config, + ...rest, + dotfiles: dotFiles, fallthrough: true, setHeaders: (res, path, stats) => { const headers = res.parent!.getHeaders() diff --git a/tests/static_middleware.spec.ts b/tests/static_middleware.spec.ts index 5b6befe..8eaa79f 100644 --- a/tests/static_middleware.spec.ts +++ b/tests/static_middleware.spec.ts @@ -107,6 +107,54 @@ test.group('Serve Static', (group) => { assert.equal(text, 'Route not found') }) + test('serve files inside dotfile directories when dotFiles is allow', async ({ assert }) => { + await fs.outputFile( + join(BASE_PATH, 'public/.well-known/apple-developer-merchantid-domain-association'), + 'merchant-id-content' + ) + + const server = createServer(async (req, res) => { + const serveStatic = new StaticMiddleware( + join(BASE_PATH, 'public'), + defineConfig({ dotFiles: 'allow' }) + ) + + const request = new RequestFactory().merge({ req, res }).create() + const response = new ResponseFactory().merge({ req, res }).create() + const ctx = new HttpContextFactory().merge({ request, response }).create() + + await serveStatic.handle(ctx, () => { + ctx.response.status(404).send('404') + ctx.response.finish() + }) + }) + + const res = await supertest(server) + .get('/.well-known/apple-developer-merchantid-domain-association') + .expect(200) + + assert.equal(Buffer.from(res.body).toString(), 'merchant-id-content') + }) + + test('ignore dotfiles by default', async ({ assert }) => { + await fs.outputFile(join(BASE_PATH, 'public/.env'), 'SECRET=123') + + const server = createServer(async (req, res) => { + const serveStatic = new StaticMiddleware(join(BASE_PATH, 'public'), defineConfig({})) + + const request = new RequestFactory().merge({ req, res }).create() + const response = new ResponseFactory().merge({ req, res }).create() + const ctx = new HttpContextFactory().merge({ request, response }).create() + + await serveStatic.handle(ctx, () => { + ctx.response.status(404).send('404') + ctx.response.finish() + }) + }) + + await supertest(server).get('/.env').expect(404) + }) + test('set headers defined via config', async ({ assert }) => { await fs.outputFile(join(BASE_PATH, 'public/style.css'), 'body { background: #000 }') From 30d5a411c6890ec6e7387377a326a2cd80741694 Mon Sep 17 00:00:00 2001 From: Julien Ripouteau Date: Sun, 15 Mar 2026 18:28:46 +0100 Subject: [PATCH 2/2] style: remove unused var --- tests/static_middleware.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/static_middleware.spec.ts b/tests/static_middleware.spec.ts index 8eaa79f..4ecea03 100644 --- a/tests/static_middleware.spec.ts +++ b/tests/static_middleware.spec.ts @@ -136,7 +136,7 @@ test.group('Serve Static', (group) => { assert.equal(Buffer.from(res.body).toString(), 'merchant-id-content') }) - test('ignore dotfiles by default', async ({ assert }) => { + test('ignore dotfiles by default', async () => { await fs.outputFile(join(BASE_PATH, 'public/.env'), 'SECRET=123') const server = createServer(async (req, res) => {