Skip to content
Closed
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
39 changes: 0 additions & 39 deletions src/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, string> | 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,
})
78 changes: 0 additions & 78 deletions test/response.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, unknown> = {}
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!')
Expand Down
Loading