Skip to content

Commit

Permalink
feat(event): event.request getter to access web request (#454)
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 authored Jul 24, 2023
1 parent 3211109 commit 5c4521f
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 2 deletions.
35 changes: 33 additions & 2 deletions src/event/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,16 @@ import {
} from "../utils";
import { H3Response } from "./response";

const DOUBLE_SLASH_RE = /[/\\]{2,}/g; // TODO: Dedup from request.ts
// TODO: Dedup from request.ts
const DOUBLE_SLASH_RE = /[/\\]{2,}/g;

// TODO: Dedup from body.ts
const PayloadMethods: Set<HTTPMethod> = new Set([
"PATCH",
"POST",
"PUT",
"DELETE",
]);

export interface NodeEventContext {
req: NodeIncomingMessage;
Expand All @@ -24,6 +33,7 @@ export class H3Event implements Pick<FetchEvent, "respondWith"> {
context: H3EventContext = {};

// Request
_request: Request | undefined;
_method: HTTPMethod | undefined;
_headers: Headers | undefined;
_path: string | undefined;
Expand All @@ -45,6 +55,10 @@ export class H3Event implements Pick<FetchEvent, "respondWith"> {
);
}

get _hasBody() {
return PayloadMethods.has(this.method!);
}

get path() {
if (!this._path) {
this._path = this._originalPath.replace(DOUBLE_SLASH_RE, "/");
Expand Down Expand Up @@ -87,7 +101,10 @@ export class H3Event implements Pick<FetchEvent, "respondWith"> {
}

get body() {
if (!this._body) {
if (!this._hasBody) {
return undefined;
}
if (this._body === undefined) {
this._body = new ReadableStream({
start: (controller) => {
this.node.req.on("data", (chunk) => {
Expand All @@ -105,6 +122,20 @@ export class H3Event implements Pick<FetchEvent, "respondWith"> {
return this._body;
}

/** @experimental */
get request(): Request {
if (!this._request) {
this._request = new Request(this.url, {
// @ts-ignore Undici option
duplex: "half",
method: this.method,
headers: this.headers,
body: this.body,
});
}
return this._request;
}

// Implementation of FetchEvent
respondWith(r: H3Response | PromiseLike<H3Response>): void {
Promise.resolve(r).then((_response) => {
Expand Down
24 changes: 24 additions & 0 deletions test/event.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,28 @@ describe("Event", () => {

expect(result.body).toMatchObject({ bytes: 3 });
});

it("can convert to a web request", async () => {
app.use(
"/",
eventHandler(async (event) => {
expect(event.request.method).toBe("POST");
expect(event.request.headers.get("x-test")).toBe("123");
// TODO: Find a workaround for Node.js 16
if (!process.versions.node.startsWith("16")) {
expect(await event.request.text()).toMatchObject(
JSON.stringify({ hello: "world" })
);
}
return "200";
})
);
const result = await request
.post("/hello")
.set("x-test", "123")
.set("content-type", "application/json")
.send(JSON.stringify({ hello: "world" }));

expect(result.text).toBe("200");
});
});

0 comments on commit 5c4521f

Please sign in to comment.