fix(bun-transpiler): Apply headers when using serveStatic; Improvement: Make options optional; (#349)
* ✅ Add failing serveStatic test (headers not applied) * 🐛 Fix: Apply headers when using serveStatic * 🚸 Make options optional * 🔖 Add changeset * ✏️ Fix naming in comment * 🚸 Export defaultOptions * 🏷️ Improve Typing of defaultOptionspull/350/head
parent
935560f677
commit
b6e59dd19c
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@hono/bun-transpiler': minor
|
||||
---
|
||||
|
||||
Fix: Apply headers when using serveStatic middleware; Improvement: Make options optional;
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@hono/bun-transpiler': minor
|
||||
---
|
||||
|
||||
Export defaultOptions
|
|
@ -1,4 +1,5 @@
|
|||
import { Hono } from 'hono'
|
||||
import { serveStatic } from 'hono/bun'
|
||||
import { bunTranspiler } from '.'
|
||||
|
||||
const HOST = 'http://localhost'
|
||||
|
@ -20,6 +21,9 @@ describe('Bun Transpiler middleware', () => {
|
|||
app.get('/script.tsx', (c) => c.text(TSX))
|
||||
app.get('/bad.ts', (c) => c.text(BAD))
|
||||
|
||||
// serve middleware script to test compliance with serveStatic
|
||||
app.get('/index.ts', serveStatic({ root: './src' }))
|
||||
|
||||
it('Should ignore non typescript content paths', async () => {
|
||||
const res = await app.request(`${HOST}/script.js`)
|
||||
expect(res).not.toBeNull()
|
||||
|
@ -50,4 +54,11 @@ describe('Bun Transpiler middleware', () => {
|
|||
expect(await res.text()).toBe('Parse error')
|
||||
expect(res.headers.get('content-type')).toBe('text/plain')
|
||||
})
|
||||
|
||||
it('Should apply headers when serveStatic is used', async () => {
|
||||
const res = await app.request(`${HOST}/index.ts`)
|
||||
expect(res).not.toBeNull()
|
||||
expect(res.status).toBe(200)
|
||||
expect(res.headers.get('content-type')).toBe('application/javascript')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -2,36 +2,38 @@ import Bun from 'bun'
|
|||
import { createMiddleware } from 'hono/factory'
|
||||
|
||||
type BunTranspilerOptions = {
|
||||
extensions: string[]
|
||||
headers: HeadersInit
|
||||
transpilerOptions: Bun.TranspilerOptions
|
||||
extensions?: string[]
|
||||
headers?: Record<string, string | string[]>
|
||||
transpilerOptions?: Bun.TranspilerOptions
|
||||
}
|
||||
|
||||
export const bunTranspiler = (
|
||||
options: BunTranspilerOptions = {
|
||||
extensions: ['.ts', '.tsx'],
|
||||
headers: { 'content-type': 'application/javascript' },
|
||||
transpilerOptions: {
|
||||
minifyWhitespace: true,
|
||||
target: 'browser',
|
||||
},
|
||||
}
|
||||
) => {
|
||||
export const defaultOptions: Required<BunTranspilerOptions> = {
|
||||
extensions: ['.ts', '.tsx'],
|
||||
headers: { 'content-type': 'application/javascript' },
|
||||
transpilerOptions: {
|
||||
minifyWhitespace: true,
|
||||
target: 'browser',
|
||||
},
|
||||
}
|
||||
|
||||
export const bunTranspiler = (options?: BunTranspilerOptions) => {
|
||||
return createMiddleware(async (c, next) => {
|
||||
await next()
|
||||
const url = new URL(c.req.url)
|
||||
const { extensions, headers, transpilerOptions } = options
|
||||
const extensions = options?.extensions ?? defaultOptions.extensions
|
||||
const headers = options?.headers ?? defaultOptions.headers
|
||||
|
||||
if (extensions.every((ext) => !url.pathname.endsWith(ext))) return
|
||||
if (extensions?.every((ext) => !url.pathname.endsWith(ext))) return
|
||||
|
||||
try {
|
||||
const loader = url.pathname.split('.').pop() as Bun.TranspilerOptions['loader']
|
||||
const transpilerOptions = options?.transpilerOptions ?? defaultOptions.transpilerOptions
|
||||
const transpiler = new Bun.Transpiler({
|
||||
loader,
|
||||
...transpilerOptions,
|
||||
})
|
||||
const transpiledCode = await transpiler.transformSync(await c.res.text())
|
||||
c.res = c.newResponse(transpiledCode, { headers })
|
||||
c.res = c.newResponse(transpiledCode, 200, headers)
|
||||
} catch (error) {
|
||||
console.warn(`Error transpiling ${url.pathname}: ${error}`)
|
||||
const errorHeaders = {
|
||||
|
@ -39,15 +41,9 @@ export const bunTranspiler = (
|
|||
'content-type': 'text/plain',
|
||||
}
|
||||
if (error instanceof Error) {
|
||||
c.res = c.newResponse(error.message, {
|
||||
status: 500,
|
||||
headers: errorHeaders,
|
||||
})
|
||||
c.res = c.newResponse(error.message, 500, errorHeaders)
|
||||
} else {
|
||||
c.res = c.newResponse('Malformed Input', {
|
||||
status: 500,
|
||||
headers: errorHeaders,
|
||||
})
|
||||
c.res = c.newResponse('Malformed Input', 500, errorHeaders)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue