Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions src/adapter/bun/handler.ts
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ export const mapResponse = (
request?: Request
): Response => {
if (isNotEmpty(set.headers) || set.status !== 200 || set.cookie) {
if (
response?.constructor?.name === 'Object' ||
response?.constructor?.name === 'Array'
)
set.headers['content-type'] = 'application/json'
Comment on lines +31 to +32
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new pre-handleSet assignment uses index-based writes (set.headers['content-type'] = ...). set.headers can be a Headers instance in some call paths (for example when handleSet already ran before calling mapResponse, or after recursive mapResponse calls using the same set), in which case this write is ignored and JSON responses won’t get Content-Type. Update to set the header via Headers.set(...) when set.headers instanceof Headers (or use a helper that supports both shapes).

Suggested change
)
set.headers['content-type'] = 'application/json'
) {
if (set.headers instanceof Headers)
set.headers.set('content-type', 'application/json')
else (set.headers as any)['content-type'] = 'application/json'
}

Copilot uses AI. Check for mistakes.

handleSet(set)

switch (response?.constructor?.name) {
Expand All @@ -33,7 +39,6 @@ export const mapResponse = (

case 'Array':
case 'Object':
set.headers['content-type'] = 'application/json'
return new Response(JSON.stringify(response), set as any)

case 'ElysiaFile':
Expand Down Expand Up @@ -141,7 +146,10 @@ export const mapResponse = (
const code = (response as any).charCodeAt(0)

if (code === 123 || code === 91) {
if (!set.headers['Content-Type'])
if (set.headers instanceof Headers) {
if (!set.headers.has('Content-Type'))
set.headers.set('Content-Type', 'application/json')
} else if (!set.headers['Content-Type'])
set.headers['Content-Type'] = 'application/json'

return new Response(
Expand Down Expand Up @@ -174,6 +182,12 @@ export const mapEarlyResponse = (
if (response === undefined || response === null) return

if (isNotEmpty(set.headers) || set.status !== 200 || set.cookie) {
if (
response?.constructor?.name === 'Object' ||
response?.constructor?.name === 'Array'
)
set.headers['content-type'] = 'application/json'
Comment on lines +188 to +189
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as mapResponse: this pre-handleSet set.headers['content-type'] write assumes set.headers is a plain object. If set.headers is already a Headers instance, the assignment won’t apply and JSON responses can miss the Content-Type header. Handle the Headers case explicitly (e.g. set.headers.set('content-type', 'application/json')).

Suggested change
)
set.headers['content-type'] = 'application/json'
) {
if (set.headers instanceof Headers) {
set.headers.set('content-type', 'application/json')
} else {
;(set.headers as any)['content-type'] = 'application/json'
}
}

Copilot uses AI. Check for mistakes.

handleSet(set)

switch (response?.constructor?.name) {
Expand All @@ -182,7 +196,6 @@ export const mapEarlyResponse = (

case 'Array':
case 'Object':
set.headers['content-type'] = 'application/json'
return new Response(JSON.stringify(response), set as any)

case 'ElysiaFile':
Expand Down Expand Up @@ -289,7 +302,10 @@ export const mapEarlyResponse = (
const code = (response as any).charCodeAt(0)

if (code === 123 || code === 91) {
if (!set.headers['Content-Type'])
if (set.headers instanceof Headers) {
if (!set.headers.has('Content-Type'))
set.headers.set('Content-Type', 'application/json')
} else if (!set.headers['Content-Type'])
set.headers['Content-Type'] = 'application/json'

return new Response(
Expand Down
34 changes: 28 additions & 6 deletions src/adapter/web-standard/handler.ts
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,24 @@ export const mapResponse = (
request?: Request
): Response => {
if (isNotEmpty(set.headers) || set.status !== 200 || set.cookie) {
switch (response?.constructor?.name) {
case 'String':
set.headers['content-type'] = 'text/plain'
break
case 'Array':
case 'Object':
set.headers['content-type'] = 'application/json'
break
}
Comment on lines +57 to +65
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting set.headers['content-type'] here assumes set.headers is a plain object. However set.headers can already be a Headers instance in this codepath (e.g. if handleSet was called earlier, or after the ElysiaCustomStatusResponse branch recurses with a set whose headers were converted by handleSet). In that case, index assignment won’t write the header and the Content-Type fix won’t apply (and the post-handleSet assignment was removed). Update this block to support both Headers and plain objects (e.g. use set.headers.set('content-type', ...) when set.headers instanceof Headers).

Copilot uses AI. Check for mistakes.

handleSet(set)

switch (response?.constructor?.name) {
case 'String':
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'
return new Response(JSON.stringify(response), set as any)

case 'ElysiaFile':
Expand Down Expand Up @@ -171,7 +179,10 @@ export const mapResponse = (
const code = (response as any).charCodeAt(0)

if (code === 123 || code === 91) {
if (!set.headers['Content-Type'])
if (set.headers instanceof Headers) {
if (!set.headers.has('Content-Type'))
set.headers.set('Content-Type', 'application/json')
} else if (!set.headers['Content-Type'])
set.headers['Content-Type'] = 'application/json'

return new Response(
Expand Down Expand Up @@ -204,16 +215,24 @@ export const mapEarlyResponse = (
if (response === undefined || response === null) return

if (isNotEmpty(set.headers) || set.status !== 200 || set.cookie) {
switch (response?.constructor?.name) {
case 'String':
set.headers['content-type'] = 'text/plain'
break
case 'Array':
case 'Object':
set.headers['content-type'] = 'application/json'
break
}
Comment on lines +218 to +226
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as mapResponse: this pre-handleSet set.headers['content-type'] write will fail if set.headers is already a Headers instance (possible when mapEarlyResponse is called with a set that has already passed through handleSet elsewhere). Since the post-handleSet content-type assignment was removed, this can leave JSON responses without Content-Type. Handle both Headers and plain header objects when setting this value.

Copilot uses AI. Check for mistakes.

handleSet(set)

switch (response?.constructor?.name) {
case 'String':
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'
return new Response(JSON.stringify(response), set as any)

case 'ElysiaFile':
Expand Down Expand Up @@ -320,7 +339,10 @@ export const mapEarlyResponse = (
const code = (response as any).charCodeAt(0)

if (code === 123 || code === 91) {
if (!set.headers['Content-Type'])
if (set.headers instanceof Headers) {
if (!set.headers.has('Content-Type'))
set.headers.set('Content-Type', 'application/json')
} else if (!set.headers['Content-Type'])
set.headers['Content-Type'] = 'application/json'

return new Response(
Expand Down
Loading