Skip to content

Commit b9976a4

Browse files
committed
feat(node): support Response static methods
1 parent 9f4fec9 commit b9976a4

File tree

4 files changed

+35
-5
lines changed

4 files changed

+35
-5
lines changed

src/_node-compat/response.ts

+28
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export type NodeResponse = InstanceType<typeof NodeResponse>;
1010
* It is faster because in most cases it doesn't create a full Response instance.
1111
*/
1212
export const NodeResponse = /* @__PURE__ */ (() => {
13+
const CONTENT_TYPE = "content-type";
14+
const JSON_TYPE = "application/json";
15+
const JSON_HEADER = [[CONTENT_TYPE, JSON_TYPE]] as HeadersInit;
16+
1317
const _Response = class Response implements globalThis.Response {
1418
#body?: BodyInit | null;
1519
#init?: ResponseInit;
@@ -19,6 +23,30 @@ export const NodeResponse = /* @__PURE__ */ (() => {
1923
this.#init = init;
2024
}
2125

26+
static json(data: any, init?: ResponseInit): globalThis.Response {
27+
if (init?.headers) {
28+
if (!(init.headers as Record<string, string>)[CONTENT_TYPE]) {
29+
const initHeaders = new Headers(init.headers);
30+
if (!initHeaders.has(CONTENT_TYPE)) {
31+
initHeaders.set(CONTENT_TYPE, JSON_TYPE);
32+
}
33+
init = { ...init, headers: initHeaders };
34+
}
35+
} else {
36+
init = init ? { ...init } : {};
37+
init.headers = JSON_HEADER;
38+
}
39+
return new _Response(JSON.stringify(data), init);
40+
}
41+
42+
static error(): globalThis.Response {
43+
return globalThis.Response.error();
44+
}
45+
46+
static redirect(url: string | URL, status?: number): globalThis.Response {
47+
return globalThis.Response.redirect(url, status);
48+
}
49+
2250
/**
2351
* Prepare Node.js response object
2452
*/

src/adapters/node.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ import { fmtURL, resolvePort, resolveTLSOptions } from "../_utils.ts";
1313
import { wrapFetch } from "../_plugin.ts";
1414

1515
export {
16-
NodeRequest,
1716
NodeRequest as Request,
17+
NodeResponse as Response,
18+
NodeRequest,
19+
NodeResponse,
1820
NodeRequestHeaders,
1921
NodeResponseHeaders,
20-
NodeResponse,
2122
} from "../_node-compat/index.ts";
2223

2324
export function serve(options: ServerOptions): Server {

test/_fixture.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ export const server = serve({
4545
for (const [key, value] of req.headers) {
4646
resHeaders.append(`x-req-${key}`, value);
4747
}
48-
return new Response(
49-
JSON.stringify({
48+
return Response.json(
49+
{
5050
...Object.fromEntries(req.headers.entries()),
5151
unsetHeader: req.headers.get("" + Math.random()), // #44
52-
}),
52+
},
5353
{
5454
headers: resHeaders,
5555
},

test/_tests.ts

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export function addTests(
3232
bar: "baz",
3333
unsetHeader: null,
3434
});
35+
expect(response.headers.get("content-type")).toMatch(/^application\/json/);
3536
expect(response.headers.get("x-req-foo")).toBe("bar");
3637
expect(response.headers.get("x-req-bar")).toBe("baz");
3738
});

0 commit comments

Comments
 (0)