From 21dce4c9b84c3151490a9c8c4ef851f1dc676a3f Mon Sep 17 00:00:00 2001 From: saltyaom Date: Sun, 1 Mar 2026 20:24:41 +0700 Subject: [PATCH] :tada: feat: use Response.json on Bun --- CHANGELOG.md | 1 + example/a.ts | 35 ++---------- src/adapter/bun/handler.ts | 106 +++++++++---------------------------- 3 files changed, 29 insertions(+), 113 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32766f39..01bb15cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Bug fix: Improvement: - conditional async on getSchemaValidator when schema is Standard Schema +- use Response.json on Bun # 1.4.26 - 25 Feb 2025 Bug fix: diff --git a/example/a.ts b/example/a.ts index bc7bdd38..017ac063 100644 --- a/example/a.ts +++ b/example/a.ts @@ -2,35 +2,6 @@ import { Elysia, t, getSchemaValidator, fileType } from '../src' import { z } from 'zod' import { post } from '../test/utils' -const bunFilePath6 = `test/images/aris-yuzu.jpg` -const bunFile = Bun.file(bunFilePath6) as File - -const app = new Elysia().post('/upload', ({ body }) => body, { - body: z.object({ - name: z.string(), - file: z.file().refine((file) => fileType(file, 'image/jpeg')), - metadata: z.object({ - age: z.coerce.number() - }) - }) -}) - -const formData = new FormData() -formData.append('name', 'John') -formData.append('file', bunFile) -formData.append('metadata', JSON.stringify({ age: '25' })) - -const response = await app.handle( - new Request('http://localhost/upload', { - method: 'POST', - body: formData - }) -) - -const result = await response.json() -console.log(result) -// expect(response.status).toBe(200) -// expect(result).toMatchObject({ -// name: 'John', -// metadata: { age: 25 } -// }) +console.log(Response.json({ + a: 'a' +})) diff --git a/src/adapter/bun/handler.ts b/src/adapter/bun/handler.ts index b7c1a7e4..a61ec695 100644 --- a/src/adapter/bun/handler.ts +++ b/src/adapter/bun/handler.ts @@ -19,6 +19,8 @@ import { ElysiaCustomStatusResponse } from '../../error' import type { Context } from '../../context' import type { AnyLocalHook } from '../../types' +// Response.json is faster than new Response(JSON.stringify()) in Bun +// https://x.com/jarredsumner/status/2023328556210921948 export const mapResponse = ( response: unknown, set: Context['set'], @@ -33,8 +35,7 @@ export const mapResponse = ( case 'Array': case 'Object': - set.headers['content-type'] = 'application/json' - return new Response(JSON.stringify(response), set as any) + return Response.json(response, set as any) case 'ElysiaFile': return handleFile((response as ElysiaFile).value as File, set) @@ -57,7 +58,7 @@ export const mapResponse = ( case undefined: if (!response) return new Response('', set as any) - return new Response(JSON.stringify(response), set as any) + return Response.json(response, set as any) case 'Response': return handleResponse(response as Response, set, request) @@ -127,11 +128,7 @@ export const mapResponse = ( // custom class with an array-like value // eg. Bun.sql`` result if (Array.isArray(response)) - return new Response(JSON.stringify(response), { - headers: { - 'Content-Type': 'application/json' - } - }) as any + return Response.json(response) as any // @ts-expect-error if (typeof response?.toResponse === 'function') @@ -140,15 +137,8 @@ export const mapResponse = ( if ('charCodeAt' in (response as any)) { const code = (response as any).charCodeAt(0) - if (code === 123 || code === 91) { - if (!set.headers['Content-Type']) - set.headers['Content-Type'] = 'application/json' - - return new Response( - JSON.stringify(response), - set as any - ) as any - } + if (code === 123 || code === 91) + return Response.json(response, set as any) as any } return new Response(response as any, set as any) @@ -182,8 +172,7 @@ export const mapEarlyResponse = ( case 'Array': case 'Object': - set.headers['content-type'] = 'application/json' - return new Response(JSON.stringify(response), set as any) + return Response.json(response, set as any) case 'ElysiaFile': return handleFile((response as ElysiaFile).value as File, set) @@ -206,7 +195,7 @@ export const mapEarlyResponse = ( case undefined: if (!response) return - return new Response(JSON.stringify(response), set as any) + return Response.json(response, set as any) case 'Response': return handleResponse(response as Response, set, request) @@ -279,24 +268,13 @@ export const mapEarlyResponse = ( // custom class with an array-like value // eg. Bun.sql`` result if (Array.isArray(response)) - return new Response(JSON.stringify(response), { - headers: { - 'Content-Type': 'application/json' - } - }) as any + return Response.json(response) as any if ('charCodeAt' in (response as any)) { const code = (response as any).charCodeAt(0) - if (code === 123 || code === 91) { - if (!set.headers['Content-Type']) - set.headers['Content-Type'] = 'application/json' - - return new Response( - JSON.stringify(response), - set as any - ) as any - } + if (code === 123 || code === 91) + return Response.json(response, set as any) as any } return new Response(response as any, set as any) @@ -308,8 +286,7 @@ export const mapEarlyResponse = ( case 'Array': case 'Object': - set.headers['content-type'] = 'application/json' - return new Response(JSON.stringify(response), set as any) + return Response.json(response, set as any) case 'ElysiaFile': return handleFile((response as ElysiaFile).value as File, set) @@ -332,11 +309,7 @@ export const mapEarlyResponse = ( case undefined: if (!response) return new Response('') - return new Response(JSON.stringify(response), { - headers: { - 'content-type': 'application/json' - } - }) + return Response.json(response) case 'Response': return response as Response @@ -406,24 +379,13 @@ export const mapEarlyResponse = ( // custom class with an array-like value // eg. Bun.sql`` result if (Array.isArray(response)) - return new Response(JSON.stringify(response), { - headers: { - 'Content-Type': 'application/json' - } - }) as any + return Response.json(response) as any if ('charCodeAt' in (response as any)) { const code = (response as any).charCodeAt(0) - if (code === 123 || code === 91) { - if (!set.headers['Content-Type']) - set.headers['Content-Type'] = 'application/json' - - return new Response( - JSON.stringify(response), - set as any - ) as any - } + if (code === 123 || code === 91) + return Response.json(response, set as any) as any } return new Response(response as any) @@ -440,11 +402,7 @@ export const mapCompactResponse = ( case 'Object': case 'Array': - return new Response(JSON.stringify(response), { - headers: { - 'Content-Type': 'application/json' - } - }) + return Response.json(response) case 'ElysiaFile': return handleFile((response as ElysiaFile).value as File) @@ -467,11 +425,7 @@ export const mapCompactResponse = ( case undefined: if (!response) return new Response('') - return new Response(JSON.stringify(response), { - headers: { - 'content-type': 'application/json' - } - }) + return Response.json(response) case 'Response': return response as Response @@ -534,23 +488,13 @@ export const mapCompactResponse = ( // custom class with an array-like value // eg. Bun.sql`` result - if (Array.isArray(response)) - return new Response(JSON.stringify(response), { - headers: { - 'Content-Type': 'application/json' - } - }) as any + if (Array.isArray(response)) return Response.json(response) as any if ('charCodeAt' in (response as any)) { const code = (response as any).charCodeAt(0) - if (code === 123 || code === 91) { - return new Response(JSON.stringify(response), { - headers: { - 'Content-Type': 'application/json' - } - }) as any - } + if (code === 123 || code === 91) + return Response.json(response) as any } return new Response(response as any) @@ -573,12 +517,12 @@ export const errorToResponse = (error: Error, set?: Context['set']) => { return typeof raw?.then === 'function' ? raw.then(apply) : apply(raw) } - return new Response( - JSON.stringify({ + return Response.json( + { name: error?.name, message: error?.message, cause: error?.cause - }), + }, { status: set?.status !== 200 ? ((set?.status as number) ?? 500) : 500,