Skip to content

Commit 14fccaf

Browse files
committed
refactor: use event.path instead of event.node.req.url for internal utils
1 parent d11f817 commit 14fccaf

File tree

7 files changed

+47
-34
lines changed

7 files changed

+47
-34
lines changed

src/app.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,22 +102,29 @@ export function use(
102102
export function createAppEventHandler(stack: Stack, options: AppOptions) {
103103
const spacing = options.debug ? 2 : undefined;
104104
return eventHandler(async (event) => {
105-
(event.node.req as any).originalUrl =
106-
(event.node.req as any).originalUrl || event.node.req.url || "/";
107-
const reqUrl = event.node.req.url || "/";
105+
const _reqPath = event.path;
106+
let _layerPath: string;
108107
for (const layer of stack) {
108+
// 1. Remove prefix from path
109109
if (layer.route.length > 1) {
110-
if (!reqUrl.startsWith(layer.route)) {
110+
if (!_reqPath.startsWith(layer.route)) {
111111
continue;
112112
}
113-
event.node.req.url = reqUrl.slice(layer.route.length) || "/";
113+
_layerPath = _reqPath.slice(layer.route.length) || "/";
114114
} else {
115-
event.node.req.url = reqUrl;
115+
_layerPath = _reqPath;
116116
}
117-
if (layer.match && !layer.match(event.node.req.url as string, event)) {
117+
118+
// 2. Custom matcher
119+
if (layer.match && !layer.match(_layerPath, event)) {
118120
continue;
119121
}
120122

123+
// 3. Update event path with layer path
124+
event._path = _layerPath;
125+
event.node.req.url = _layerPath; // Express compatibility
126+
127+
// 4. Handle request
121128
const val = await layer.handler(event);
122129

123130
// Already handled
@@ -181,9 +188,7 @@ export function createAppEventHandler(stack: Stack, options: AppOptions) {
181188
if (!event.handled) {
182189
throw createError({
183190
statusCode: 404,
184-
statusMessage: `Cannot find any path matching ${
185-
event.node.req.url || "/"
186-
}.`,
191+
statusMessage: `Cannot find any path matching ${event.path || "/"}.`,
187192
});
188193
}
189194
});

src/event/event.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
import type { IncomingHttpHeaders } from "node:http";
22
import type { H3EventContext, HTTPMethod } from "../types";
33
import type { NodeIncomingMessage, NodeServerResponse } from "../node";
4-
import {
5-
MIMES,
6-
sanitizeStatusCode,
7-
sanitizeStatusMessage,
8-
getRequestPath,
9-
} from "../utils";
4+
import { MIMES, sanitizeStatusCode, sanitizeStatusMessage } from "../utils";
105
import { H3Response } from "./response";
116

7+
const DOUBLE_SLASH_RE = /[/\\]{2,}/g; // TODO: Dedup from request.ts
8+
129
export interface NodeEventContext {
1310
req: NodeIncomingMessage;
1411
res: NodeServerResponse;
@@ -24,6 +21,7 @@ export class H3Event implements Pick<FetchEvent, "respondWith"> {
2421
// Request
2522
_method: HTTPMethod | undefined;
2623
_headers: Headers | undefined;
24+
_path: string | undefined;
2725

2826
// Response
2927
_handled = false;
@@ -32,8 +30,19 @@ export class H3Event implements Pick<FetchEvent, "respondWith"> {
3230
this.node = { req, res };
3331
}
3432

33+
get _originalPath() {
34+
return (
35+
(this.node.req as { originalUrl?: string }).originalUrl ||
36+
this.node.req.url ||
37+
"/"
38+
);
39+
}
40+
3541
get path() {
36-
return getRequestPath(this);
42+
if (!this._path) {
43+
this._path = this._originalPath.replace(DOUBLE_SLASH_RE, "/");
44+
}
45+
return this._path;
3746
}
3847

3948
get handled(): boolean {

src/router.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export function createRouter(opts: CreateRouterOptions = {}): Router {
7676
// Main handle
7777
router.handler = eventHandler((event) => {
7878
// Remove query parameters for matching
79-
let path = event.node.req.url || "/";
79+
let path = event.path || "/";
8080
const qIndex = path.indexOf("?");
8181
if (qIndex !== -1) {
8282
path = path.slice(0, Math.max(0, qIndex));
@@ -89,9 +89,7 @@ export function createRouter(opts: CreateRouterOptions = {}): Router {
8989
throw createError({
9090
statusCode: 404,
9191
name: "Not Found",
92-
statusMessage: `Cannot find any route matching ${
93-
event.node.req.url || "/"
94-
}.`,
92+
statusMessage: `Cannot find any route matching ${event.path || "/"}.`,
9593
});
9694
} else {
9795
return; // Let app match other handlers

src/utils/request.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { HTTPMethod, RequestHeaders } from "../types";
44
import type { H3Event } from "../event";
55

66
export function getQuery(event: H3Event) {
7-
return _getQuery(event.node.req.url || "");
7+
return _getQuery(event.path || "");
88
}
99

1010
export function getRouterParams(
@@ -113,11 +113,9 @@ export function getRequestProtocol(
113113
return (event.node.req.connection as any).encrypted ? "https" : "http";
114114
}
115115

116-
const DOUBLE_SLASH_RE = /[/\\]{2,}/g;
117-
116+
/** @deprecated Use `event.path` directly */
118117
export function getRequestPath(event: H3Event): string {
119-
const path = (event.node.req.url || "/").replace(DOUBLE_SLASH_RE, "/");
120-
return path;
118+
return event.path;
121119
}
122120

123121
export function getRequestURL(

src/utils/route.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ export function useBase(base: string, handler: EventHandler): EventHandler {
77
if (!base) {
88
return handler;
99
}
10-
return eventHandler((event) => {
11-
(event.node.req as any).originalUrl =
12-
(event.node.req as any).originalUrl || event.node.req.url || "/";
13-
event.node.req.url = withoutBase(event.node.req.url || "/", base);
14-
return handler(event);
10+
return eventHandler(async (event) => {
11+
const _path = event._path;
12+
event._path = withoutBase(event.path || "/", base);
13+
try {
14+
return await handler(event);
15+
} finally {
16+
event._path = _path;
17+
}
1518
});
1619
}

test/app.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ describe("app", () => {
2727
it("can return JSON directly", async () => {
2828
app.use(
2929
"/api",
30-
eventHandler((event) => ({ url: event.node.req.url }))
30+
eventHandler((event) => ({ url: event.path }))
3131
);
3232
const res = await request.get("/api");
3333

test/utils.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ describe("", () => {
4040
"/",
4141
useBase(
4242
"/api",
43-
eventHandler((event) => Promise.resolve(event.node.req.url || "none"))
43+
eventHandler((event) => Promise.resolve(event.path))
4444
)
4545
);
4646
const result = await request.get("/api/test");
@@ -52,7 +52,7 @@ describe("", () => {
5252
"/",
5353
useBase(
5454
"",
55-
eventHandler((event) => Promise.resolve(event.node.req.url || "none"))
55+
eventHandler((event) => Promise.resolve(event.path))
5656
)
5757
);
5858
const result = await request.get("/api/test");

0 commit comments

Comments
 (0)