From f623fa1910fd5cbe9726412a81fccf57944743b3 Mon Sep 17 00:00:00 2001 From: Taku Amano Date: Tue, 14 Apr 2026 07:51:12 +0900 Subject: [PATCH] feat: Remove Response.json() and Response.redirect() overrides --- src/response.ts | 39 ---------------------- test/response.test.ts | 78 ------------------------------------------- 2 files changed, 117 deletions(-) diff --git a/src/response.ts b/src/response.ts index 3431ffe..48212ad 100644 --- a/src/response.ts +++ b/src/response.ts @@ -112,42 +112,3 @@ Object.defineProperty(Response.prototype, Symbol.for('nodejs.util.inspect.custom Object.setPrototypeOf(Response, GlobalResponse) Object.setPrototypeOf(Response.prototype, GlobalResponse.prototype) - -// Override Response.json() to return a LightweightResponse so the listener -// fast-path (cacheKey check) is hit instead of falling through to ReadableStream reading. -Object.defineProperty(Response, 'redirect', { - value: function redirect(url: string | URL, status = 302): Response { - if (![301, 302, 303, 307, 308].includes(status)) { - throw new RangeError('Invalid status code') - } - return new Response(null, { - status, - headers: { location: typeof url === 'string' ? url : url.href }, - }) - }, - writable: true, - configurable: true, -}) - -Object.defineProperty(Response, 'json', { - value: function json(data?: unknown, init?: ResponseInit): Response { - const body = JSON.stringify(data) - const initHeaders = init?.headers - let headers: Record | Headers - if (initHeaders) { - headers = new Headers(initHeaders) - if (!(headers as Headers).has('content-type')) { - ;(headers as Headers).set('content-type', 'application/json') - } - } else { - headers = { 'content-type': 'application/json' } - } - return new Response(body, { - status: init?.status ?? 200, - statusText: init?.statusText, - headers, - }) - }, - writable: true, - configurable: true, -}) diff --git a/test/response.test.ts b/test/response.test.ts index a8d62f7..6d1554c 100644 --- a/test/response.test.ts +++ b/test/response.test.ts @@ -100,84 +100,6 @@ describe('Response', () => { expect(await childResponse.text()).toEqual('HONO') }) - describe('Response.json', () => { - it('should return 200 with application/json content-type by default', () => { - const res = Response.json({ hello: 'world' }) - expect(res.status).toBe(200) - expect(res.headers.get('content-type')).toBe('application/json') - }) - - it('should serialize data correctly', async () => { - const data = { hello: 'world', num: 42, arr: [1, 2, 3] } - const res = Response.json(data) - expect(await res.json()).toEqual(data) - }) - - it('should use custom status from init', () => { - const res = Response.json({ error: 'not found' }, { status: 404 }) - expect(res.status).toBe(404) - }) - - it('should preserve statusText from init', () => { - const res = Response.json({ error: 'not found' }, { status: 404, statusText: 'Not Found' }) - expect(res.statusText).toBe('Not Found') - }) - - it('should preserve custom content-type from init headers', () => { - const res = Response.json( - { data: 'test' }, - { headers: { 'content-type': 'application/vnd.api+json' } } - ) - expect(res.headers.get('content-type')).toBe('application/vnd.api+json') - }) - - it('should set application/json when init headers do not include content-type', () => { - const res = Response.json({ data: 'test' }, { headers: { 'x-custom': 'value' } }) - expect(res.headers.get('content-type')).toBe('application/json') - expect(res.headers.get('x-custom')).toBe('value') - }) - - it('should return a LightweightResponse with cacheKey set for the fast path', () => { - const res = Response.json({ ok: true }) - expect(res).toBeInstanceOf(LightweightResponse) - expect(cacheKey in res).toBe(true) - }) - - it('should throw for non-serializable data', () => { - const circ: Record = {} - circ.self = circ - expect(() => Response.json(circ)).toThrow(TypeError) - }) - }) - - describe('Response.redirect', () => { - it('should return a 302 redirect by default', () => { - const res = Response.redirect('https://example.com') - expect(res.status).toBe(302) - expect(res.headers.get('location')).toBe('https://example.com') - }) - - it('should use a custom redirect status', () => { - const res = Response.redirect('https://example.com/new', 301) - expect(res.status).toBe(301) - }) - - it('should accept a URL object', () => { - const res = Response.redirect(new URL('https://example.com/path')) - expect(res.headers.get('location')).toBe('https://example.com/path') - }) - - it('should throw for invalid status codes', () => { - expect(() => Response.redirect('https://example.com', 200)).toThrow(RangeError) - }) - - it('should return a LightweightResponse with cacheKey set for the fast path', () => { - const res = Response.redirect('https://example.com') - expect(res).toBeInstanceOf(LightweightResponse) - expect(cacheKey in res).toBe(true) - }) - }) - describe('Fallback to GlobalResponse object', () => { it('Should return value from internal cache', () => { const res = new Response('Hello! Node!')