🔧 fix: conditional set headers of String and Object when no set.headers is set

This commit is contained in:
saltyaom
2026-03-03 05:30:57 +07:00
parent 1ecae0a596
commit 169e54a348
6 changed files with 88 additions and 32 deletions
+4
View File
@@ -1,3 +1,7 @@
# 1.4.28 - 3 Mar 2026
Bug fix:
- conditional set headers of String and Object when no set.headers is set
# 1.4.27 - 1 Mar 2026
Bug fix:
- getSchemaValidator: handle TypeBox as sub type
+20 -1
View File
@@ -1,3 +1,22 @@
import { Elysia } from '../src'
import { mapEarlyResponse } from '../src/adapter/web-standard/handler'
new Elysia().get('/', 'Hi').listen(3000)
const body = {
name: 'Shiroko'
}
const context = {
headers: {
'x-powered-by': 'Elysia',
'coffee-scheme': 'Coffee'
},
status: 418,
cookie: {}
}
const response = await mapEarlyResponse(
new Promise((resolve) => resolve(body)),
context
)
console.log(response?.headers)
+18 -6
View File
@@ -58,12 +58,16 @@ export const mapResponse = (
switch (response?.constructor?.name) {
case 'String':
set.headers['content-type'] = 'text/plain'
if (!set.headers['content-type'])
set.headers['content-type'] = 'text/plain'
return new Response(response as string, set as any)
case 'Array':
case 'Object':
set.headers['content-type'] = 'application/json'
if (!set.headers['content-type'])
set.headers['content-type'] = 'application/json'
return new Response(JSON.stringify(response), set as any)
case 'ElysiaFile':
@@ -208,12 +212,16 @@ export const mapEarlyResponse = (
switch (response?.constructor?.name) {
case 'String':
set.headers['content-type'] = 'text/plain'
if (!set.headers['content-type'])
set.headers['content-type'] = 'text/plain'
return new Response(response as string, set as any)
case 'Array':
case 'Object':
set.headers['content-type'] = 'application/json'
if (!set.headers['content-type'])
set.headers['content-type'] = 'application/json'
return new Response(JSON.stringify(response), set as any)
case 'ElysiaFile':
@@ -335,12 +343,16 @@ export const mapEarlyResponse = (
} else
switch (response?.constructor?.name) {
case 'String':
set.headers['content-type'] = 'text/plain'
if (!set.headers['content-type'])
set.headers['content-type'] = 'text/plain'
return new Response(response as string)
case 'Array':
case 'Object':
set.headers['content-type'] = 'application/json'
if (!set.headers['content-type'])
set.headers['content-type'] = 'application/json'
return new Response(JSON.stringify(response), set as any)
case 'ElysiaFile':
@@ -10,14 +10,14 @@ const defaultContext = {
cookie: {}
}
const context = {
const createContext = () => ({
headers: {
'x-powered-by': 'Elysia',
'coffee-scheme': 'Coffee'
},
status: 418,
cookie: {}
}
})
class Student {
constructor(public name: string) {}
@@ -160,6 +160,7 @@ describe('Web Standard - Map Early Response', () => {
})
it('map primitive with custom context', async () => {
const context = createContext()
const response = mapEarlyResponse('Shiroko', context)
expect(response).toBeInstanceOf(Response)
@@ -169,6 +170,7 @@ describe('Web Standard - Map Early Response', () => {
})
it('map Function with custom context', async () => {
const context = createContext()
const response = await mapEarlyResponse(() => 1, context)
expect(response).toBeInstanceOf(Response)
@@ -180,6 +182,8 @@ describe('Web Standard - Map Early Response', () => {
})
it('map Promise with custom context', async () => {
const context = createContext()
const body = {
name: 'Shiroko'
}
@@ -199,6 +203,7 @@ describe('Web Standard - Map Early Response', () => {
})
it('map Error with custom context', async () => {
const context = createContext()
const response = mapEarlyResponse(new Error('Hello'), context)
expect(response).toBeInstanceOf(Response)
@@ -211,6 +216,7 @@ describe('Web Standard - Map Early Response', () => {
})
it('map Response with custom context', async () => {
const context = createContext()
const response = await mapEarlyResponse(
new Response('Shiroko'),
context
@@ -223,6 +229,8 @@ describe('Web Standard - Map Early Response', () => {
})
it('map Response and merge Headers', async () => {
const context = createContext()
const response = await mapEarlyResponse(
new Response('Shiroko', {
headers: {
+34 -15
View File
@@ -12,15 +12,6 @@ const createContext = () => ({
status: 200
})
const context = {
cookie: {},
headers: {
'x-powered-by': 'Elysia',
'coffee-scheme': 'Coffee'
},
status: 418
}
class Student {
constructor(public name: string) {}
@@ -186,33 +177,37 @@ describe('Web Standard - Map Response', () => {
})
it('map primitive with custom context', async () => {
const context = createContext()
const response = mapResponse('Shiroko', context)
expect(response).toBeInstanceOf(Response)
expect(await response.text()).toBe('Shiroko')
expect(response.headers.toJSON()).toEqual(context.headers)
expect(response.status).toBe(418)
expect(response.status).toBe(200)
})
it('map undefined with context', async () => {
const context = createContext()
const response = mapResponse(undefined, context)
expect(response).toBeInstanceOf(Response)
expect(await response.text()).toEqual('')
expect(response.headers.toJSON()).toEqual(context.headers)
expect(response.status).toBe(418)
expect(response.status).toBe(200)
})
it('map null with custom context', async () => {
const context = createContext()
const response = mapResponse(null, context)
expect(response).toBeInstanceOf(Response)
expect(await response.text()).toEqual('')
expect(response.headers.toJSON()).toEqual(context.headers)
expect(response.status).toBe(418)
expect(response.status).toBe(200)
})
it('map Function with custom context', async () => {
const context = createContext()
const response = await mapResponse(() => 1, context)
expect(response).toBeInstanceOf(Response)
@@ -220,10 +215,12 @@ describe('Web Standard - Map Response', () => {
expect(response.headers.toJSON()).toEqual({
...context.headers
})
expect(response.status).toBe(418)
expect(response.status).toBe(200)
})
it('map Promise with custom context', async () => {
const context = createContext()
const body = {
name: 'Shiroko'
}
@@ -239,10 +236,12 @@ describe('Web Standard - Map Response', () => {
...context.headers,
'content-type': 'application/json'
})
expect(response.status).toBe(418)
expect(response.status).toBe(200)
})
it('map Error with custom context', async () => {
const context = createContext()
const response = mapResponse(new Error('Hello'), context)
expect(response).toBeInstanceOf(Response)
@@ -251,10 +250,12 @@ describe('Web Standard - Map Response', () => {
message: 'Hello'
})
expect(response.headers.toJSON()).toEqual(context.headers)
expect(response.status).toBe(418)
expect(response.status).toBe(500)
})
it('map Response with custom context', async () => {
const context = createContext()
const response = await mapResponse(new Response('Shiroko'), context)
const headers = response.headers.toJSON()
@@ -264,6 +265,8 @@ describe('Web Standard - Map Response', () => {
})
it('map Response and merge Headers', async () => {
const context = createContext()
const response = await mapResponse(
new Response('Shiroko', {
headers: {
@@ -438,4 +441,20 @@ describe('Web Standard - Map Response', () => {
expect(response).toBe('b')
})
it('respect set.headers on string response', async () => {
const app = new Elysia()
.onAfterHandle(({ set }) => {
set.headers['content-type'] = 'text/html; charset=utf8'
return '<h1>Hina</h1>'
})
.get('/', () => 'a')
const response = await app.handle(req('/'))
expect(response.headers.get('content-type')).toBe(
'text/html; charset=utf8'
)
})
})
+2 -8
View File
@@ -31,17 +31,11 @@ describe('Native Static Response', () => {
.get('/', 'Static Content')
expect(app.router.response['/'].GET).toBeInstanceOf(Response)
expect(app.router.response['/'].GET.headers.toJSON()).toEqual({
'content-type': 'text/plain',
server: 'Elysia'
})
expect(app.router.response['/'].GET.headers.get('server')).toBe('Elysia')
expect(await app.router.response['/'].GET.text()).toEqual('Static Content')
expect(app.router.response['/plugin'].GET).toBeInstanceOf(Response)
expect(app.router.response['/plugin'].GET.headers.toJSON()).toEqual({
'content-type': 'text/plain',
server: 'Elysia'
})
expect(app.router.response['/plugin'].GET.headers.get('server')).toBe('Elysia')
expect(await app.router.response['/plugin'].GET.text()).toEqual('Plugin')
})