@depup/h3 2.0.1-rc.17-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +25 -0
- package/bin/h3.mjs +35 -0
- package/changes.json +5 -0
- package/dist/THIRD-PARTY-LICENSES.md +70 -0
- package/dist/_entries/bun.d.mts +8 -0
- package/dist/_entries/bun.mjs +11 -0
- package/dist/_entries/cloudflare.d.mts +8 -0
- package/dist/_entries/cloudflare.mjs +11 -0
- package/dist/_entries/deno.d.mts +8 -0
- package/dist/_entries/deno.mjs +11 -0
- package/dist/_entries/generic.d.mts +8 -0
- package/dist/_entries/generic.mjs +11 -0
- package/dist/_entries/node.d.mts +12 -0
- package/dist/_entries/node.mjs +14 -0
- package/dist/_entries/service-worker.d.mts +8 -0
- package/dist/_entries/service-worker.mjs +11 -0
- package/dist/h3-C304D6TZ.d.mts +1275 -0
- package/dist/h3-CGHxXEqb.mjs +2605 -0
- package/dist/h3-DagAgogP.mjs +4 -0
- package/dist/h3-QfzdiyNf.d.mts +836 -0
- package/dist/tracing.d.mts +26 -0
- package/dist/tracing.mjs +76 -0
- package/package.json +128 -0
- package/skills/h3/SKILL.md +10 -0
- package/skills/h3/docs/TOC.md +35 -0
- package/skills/h3/docs/_navigation.json +311 -0
- package/skills/h3/docs/examples/handle-cookie.md +67 -0
- package/skills/h3/docs/examples/handle-session.md +130 -0
- package/skills/h3/docs/examples/index.md +16 -0
- package/skills/h3/docs/examples/serve-static-assets.md +66 -0
- package/skills/h3/docs/examples/stream-response.md +76 -0
- package/skills/h3/docs/examples/validate-data.md +193 -0
- package/skills/h3/docs/guide/advanced/nightly.md +13 -0
- package/skills/h3/docs/guide/advanced/plugins.md +50 -0
- package/skills/h3/docs/guide/advanced/websocket.md +124 -0
- package/skills/h3/docs/guide/api/h3.md +145 -0
- package/skills/h3/docs/guide/api/h3event.md +113 -0
- package/skills/h3/docs/guide/basics/error.md +117 -0
- package/skills/h3/docs/guide/basics/handler.md +165 -0
- package/skills/h3/docs/guide/basics/lifecycle.md +68 -0
- package/skills/h3/docs/guide/basics/middleware.md +97 -0
- package/skills/h3/docs/guide/basics/nested-apps.md +57 -0
- package/skills/h3/docs/guide/basics/response.md +162 -0
- package/skills/h3/docs/guide/basics/routing.md +92 -0
- package/skills/h3/docs/guide/index.md +117 -0
- package/skills/h3/docs/migration/index.md +200 -0
- package/skills/h3/docs/utils/community.md +42 -0
- package/skills/h3/docs/utils/cookie.md +33 -0
- package/skills/h3/docs/utils/index.md +46 -0
- package/skills/h3/docs/utils/mcp.md +71 -0
- package/skills/h3/docs/utils/more.md +78 -0
- package/skills/h3/docs/utils/proxy.md +31 -0
- package/skills/h3/docs/utils/request.md +355 -0
- package/skills/h3/docs/utils/response.md +144 -0
- package/skills/h3/docs/utils/security.md +109 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Cookie
|
|
2
|
+
|
|
3
|
+
> H3 cookie utilities.
|
|
4
|
+
|
|
5
|
+
### `deleteChunkedCookie(event, name, serializeOptions?)`
|
|
6
|
+
|
|
7
|
+
Remove a set of chunked cookies by name.
|
|
8
|
+
|
|
9
|
+
### `deleteCookie(event, name, serializeOptions?)`
|
|
10
|
+
|
|
11
|
+
Remove a cookie by name.
|
|
12
|
+
|
|
13
|
+
### `getChunkedCookie(event, name)`
|
|
14
|
+
|
|
15
|
+
Get a chunked cookie value by name. Will join chunks together.
|
|
16
|
+
|
|
17
|
+
### `getCookie(event, name)`
|
|
18
|
+
|
|
19
|
+
Get a cookie value by name.
|
|
20
|
+
|
|
21
|
+
### `getValidatedCookies(event, validate, options?: { onError?: OnValidateError })`
|
|
22
|
+
|
|
23
|
+
### `parseCookies(event)`
|
|
24
|
+
|
|
25
|
+
Parse the request to get HTTP Cookie header string and returning an object of all cookie name-value pairs.
|
|
26
|
+
|
|
27
|
+
### `setChunkedCookie(event, name, value, options?)`
|
|
28
|
+
|
|
29
|
+
Set a cookie value by name. Chunked cookies will be created as needed.
|
|
30
|
+
|
|
31
|
+
### `setCookie(event, name, value, options?)`
|
|
32
|
+
|
|
33
|
+
Set a cookie value by name.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# H3 Utils
|
|
2
|
+
|
|
3
|
+
H3 is a composable framework. Instead of providing a big core, you start with a lightweight [H3](/guide/api/h3) instance and for every functionality, there is either a built-in utility or you can make yours.
|
|
4
|
+
|
|
5
|
+
<card-group>
|
|
6
|
+
|
|
7
|
+
<card>
|
|
8
|
+
|
|
9
|
+
Utilities for incoming request.
|
|
10
|
+
</card>
|
|
11
|
+
|
|
12
|
+
<card>
|
|
13
|
+
|
|
14
|
+
Utilities for preparing and sending response.
|
|
15
|
+
</card>
|
|
16
|
+
|
|
17
|
+
<card>
|
|
18
|
+
|
|
19
|
+
Cookie utilities.
|
|
20
|
+
</card>
|
|
21
|
+
|
|
22
|
+
<card>
|
|
23
|
+
|
|
24
|
+
Security utilities.
|
|
25
|
+
</card>
|
|
26
|
+
|
|
27
|
+
<card>
|
|
28
|
+
|
|
29
|
+
Proxy utilities.
|
|
30
|
+
</card>
|
|
31
|
+
|
|
32
|
+
<card>
|
|
33
|
+
|
|
34
|
+
MCP related utilities.
|
|
35
|
+
</card>
|
|
36
|
+
|
|
37
|
+
<card>
|
|
38
|
+
|
|
39
|
+
More Utilities.
|
|
40
|
+
</card>
|
|
41
|
+
|
|
42
|
+
<card>
|
|
43
|
+
|
|
44
|
+
Community made utilities.
|
|
45
|
+
</card>
|
|
46
|
+
</card-group>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# MCP
|
|
2
|
+
|
|
3
|
+
> H3 MCP related utils.
|
|
4
|
+
|
|
5
|
+
### `defineJsonRpcHandler()`
|
|
6
|
+
|
|
7
|
+
Creates an H3 event handler that implements the JSON-RPC 2.0 specification.
|
|
8
|
+
|
|
9
|
+
**Example:**
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
app.post(
|
|
13
|
+
"/rpc",
|
|
14
|
+
defineJsonRpcHandler({
|
|
15
|
+
methods: {
|
|
16
|
+
echo: ({ params }, event) => {
|
|
17
|
+
return `Received \`${params}\` on path \`${event.url.pathname}\``;
|
|
18
|
+
},
|
|
19
|
+
sum: ({ params }, event) => {
|
|
20
|
+
return params.a + params.b;
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
}),
|
|
24
|
+
);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### `defineJsonRpcWebSocketHandler()`
|
|
28
|
+
|
|
29
|
+
Creates an H3 event handler that implements JSON-RPC 2.0 over WebSocket.
|
|
30
|
+
|
|
31
|
+
This is an opt-in feature that allows JSON-RPC communication over WebSocket connections for bi-directional messaging. Each incoming WebSocket text message is processed as a JSON-RPC request, and responses are sent back to the peer.
|
|
32
|
+
|
|
33
|
+
**Example:**
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
app.get(
|
|
37
|
+
"/rpc/ws",
|
|
38
|
+
defineJsonRpcWebSocketHandler({
|
|
39
|
+
methods: {
|
|
40
|
+
echo: ({ params }) => {
|
|
41
|
+
return `Received: ${Array.isArray(params) ? params[0] : params?.message}`;
|
|
42
|
+
},
|
|
43
|
+
sum: ({ params }) => {
|
|
44
|
+
return params.a + params.b;
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
}),
|
|
48
|
+
);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Example:**
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
// With additional WebSocket hooks
|
|
55
|
+
app.get(
|
|
56
|
+
"/rpc/ws",
|
|
57
|
+
defineJsonRpcWebSocketHandler({
|
|
58
|
+
methods: {
|
|
59
|
+
greet: ({ params }) => `Hello, ${params.name}!`,
|
|
60
|
+
},
|
|
61
|
+
hooks: {
|
|
62
|
+
open(peer) {
|
|
63
|
+
console.log(`Peer connected: ${peer.id}`);
|
|
64
|
+
},
|
|
65
|
+
close(peer, details) {
|
|
66
|
+
console.log(`Peer disconnected: ${peer.id}`, details);
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
}),
|
|
70
|
+
);
|
|
71
|
+
```
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# More utils
|
|
2
|
+
|
|
3
|
+
> More H3 utilities.
|
|
4
|
+
|
|
5
|
+
## Base
|
|
6
|
+
|
|
7
|
+
### `withBase(base, input)`
|
|
8
|
+
|
|
9
|
+
Returns a new event handler that removes the base url of the event before calling the original handler.
|
|
10
|
+
|
|
11
|
+
**Example:**
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
const api = new H3()
|
|
15
|
+
.get("/", () => "Hello API!");
|
|
16
|
+
const app = new H3();
|
|
17
|
+
.use("/api/**", withBase("/api", api.handler));
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Event
|
|
21
|
+
|
|
22
|
+
### `getEventContext(event)`
|
|
23
|
+
|
|
24
|
+
Gets the context of the event, if it does not exists, initializes a new context on `req.context`.
|
|
25
|
+
|
|
26
|
+
### `isEvent(input)`
|
|
27
|
+
|
|
28
|
+
Checks if the input is an H3Event object.
|
|
29
|
+
|
|
30
|
+
### `isHTTPEvent(input)`
|
|
31
|
+
|
|
32
|
+
Checks if the input is an object with `{ req: Request }` signature.
|
|
33
|
+
|
|
34
|
+
### `mockEvent(_request, options?)`
|
|
35
|
+
|
|
36
|
+
## Middleware
|
|
37
|
+
|
|
38
|
+
### `bodyLimit(limit)`
|
|
39
|
+
|
|
40
|
+
Define a middleware that checks whether request body size is within specified limit.
|
|
41
|
+
|
|
42
|
+
If body size exceeds the limit, throws a `413` Request Entity Too Large response error. If you need custom handling for this case, use `assertBodySize` instead.
|
|
43
|
+
|
|
44
|
+
### `onError(hook)`
|
|
45
|
+
|
|
46
|
+
Define a middleware that runs when an error occurs.
|
|
47
|
+
|
|
48
|
+
You can return a new Response from the handler to gracefully handle the error.
|
|
49
|
+
|
|
50
|
+
### `onRequest(hook)`
|
|
51
|
+
|
|
52
|
+
Define a middleware that runs on each request.
|
|
53
|
+
|
|
54
|
+
### `onResponse(hook)`
|
|
55
|
+
|
|
56
|
+
Define a middleware that runs after Response is generated.
|
|
57
|
+
|
|
58
|
+
You can return a new Response from the handler to replace the original response.
|
|
59
|
+
|
|
60
|
+
## WebSocket
|
|
61
|
+
|
|
62
|
+
### `defineWebSocket(hooks)`
|
|
63
|
+
|
|
64
|
+
Define WebSocket hooks.
|
|
65
|
+
|
|
66
|
+
### `defineWebSocketHandler()`
|
|
67
|
+
|
|
68
|
+
Define WebSocket event handler.
|
|
69
|
+
|
|
70
|
+
## Adapters
|
|
71
|
+
|
|
72
|
+
### `defineNodeHandler(handler)`
|
|
73
|
+
|
|
74
|
+
### `defineNodeMiddleware(handler)`
|
|
75
|
+
|
|
76
|
+
### `fromNodeHandler(handler)`
|
|
77
|
+
|
|
78
|
+
### `fromWebHandler(handler)`
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Proxy
|
|
2
|
+
|
|
3
|
+
> H3 proxy utilities.
|
|
4
|
+
|
|
5
|
+
### `fetchWithEvent(event, url, init?)`
|
|
6
|
+
|
|
7
|
+
Make a fetch request with the event's context and headers.
|
|
8
|
+
|
|
9
|
+
If the `url` starts with `/`, the request is dispatched internally via `event.app.fetch()` (sub-request) and never leaves the process.
|
|
10
|
+
|
|
11
|
+
**Security:** Never pass unsanitized user input as the `url`. Callers are responsible for validating and restricting the URL.
|
|
12
|
+
|
|
13
|
+
### `getProxyRequestHeaders(event)`
|
|
14
|
+
|
|
15
|
+
Get the request headers object without headers known to cause issues when proxying.
|
|
16
|
+
|
|
17
|
+
### `proxy(event, target, opts)`
|
|
18
|
+
|
|
19
|
+
Make a proxy request to a target URL and send the response back to the client.
|
|
20
|
+
|
|
21
|
+
If the `target` starts with `/`, the request is dispatched internally via `event.app.fetch()` (sub-request) and never leaves the process. This bypasses any external security layer (reverse proxy auth, IP allowlisting, mTLS).
|
|
22
|
+
|
|
23
|
+
**Security:** Never pass unsanitized user input as the `target`. Callers are responsible for validating and restricting the target URL (e.g. allowlisting hosts, blocking internal paths, enforcing protocol).
|
|
24
|
+
|
|
25
|
+
### `proxyRequest(event, target, opts)`
|
|
26
|
+
|
|
27
|
+
Proxy the incoming request to a target URL.
|
|
28
|
+
|
|
29
|
+
If the `target` starts with `/`, the request is handled internally by the app router via `event.app.fetch()` instead of making an external HTTP request.
|
|
30
|
+
|
|
31
|
+
**Security:** Never pass unsanitized user input as the `target`. Callers are responsible for validating and restricting the target URL (e.g. allowlisting hosts, blocking internal paths, enforcing protocol). Consider using `bodyLimit()` middleware to prevent large request bodies from consuming excessive resources when proxying untrusted input.
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# Request
|
|
2
|
+
|
|
3
|
+
> H3 request utilities.
|
|
4
|
+
|
|
5
|
+
## Body
|
|
6
|
+
|
|
7
|
+
### `assertBodySize(event, limit)`
|
|
8
|
+
|
|
9
|
+
Asserts that request body size is within the specified limit.
|
|
10
|
+
|
|
11
|
+
If body size exceeds the limit, throws a `413` Request Entity Too Large response error.
|
|
12
|
+
|
|
13
|
+
**Example:**
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
app.get("/", async (event) => {
|
|
17
|
+
await assertBodySize(event, 10 * 1024 * 1024); // 10MB
|
|
18
|
+
const data = await event.req.formData();
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### `readBody(event)`
|
|
23
|
+
|
|
24
|
+
Reads request body and tries to parse using JSON.parse or URLSearchParams.
|
|
25
|
+
|
|
26
|
+
**Example:**
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
app.get("/", async (event) => {
|
|
30
|
+
const body = await readBody(event);
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### `readValidatedBody(event, validate)`
|
|
35
|
+
|
|
36
|
+
Tries to read the request body via `readBody`, then uses the provided validation schema or function and either throws a validation error or returns the result.
|
|
37
|
+
|
|
38
|
+
You can use a simple function to validate the body or use a Standard-Schema compatible library like `zod` to define a schema.
|
|
39
|
+
|
|
40
|
+
**Example:**
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
function validateBody(body: any) {
|
|
44
|
+
return typeof body === "object" && body !== null;
|
|
45
|
+
}
|
|
46
|
+
app.post("/", async (event) => {
|
|
47
|
+
const body = await readValidatedBody(event, validateBody);
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Example:**
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { z } from "zod";
|
|
55
|
+
const objectSchema = z.object({
|
|
56
|
+
name: z.string().min(3).max(20),
|
|
57
|
+
age: z.number({ coerce: true }).positive().int(),
|
|
58
|
+
});
|
|
59
|
+
app.post("/", async (event) => {
|
|
60
|
+
const body = await readValidatedBody(event, objectSchema);
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Example:**
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import * as v from "valibot";
|
|
68
|
+
app.post("/", async (event) => {
|
|
69
|
+
const body = await readValidatedBody(
|
|
70
|
+
event,
|
|
71
|
+
v.object({
|
|
72
|
+
name: v.pipe(v.string(), v.minLength(3), v.maxLength(20)),
|
|
73
|
+
age: v.pipe(v.number(), v.integer(), v.minValue(1)),
|
|
74
|
+
}),
|
|
75
|
+
{
|
|
76
|
+
onError: ({ issues }) => ({
|
|
77
|
+
statusText: "Custom validation error",
|
|
78
|
+
message: v.summarize(issues),
|
|
79
|
+
}),
|
|
80
|
+
},
|
|
81
|
+
);
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Cache
|
|
86
|
+
|
|
87
|
+
### `handleCacheHeaders(event, opts)`
|
|
88
|
+
|
|
89
|
+
Check request caching headers (`If-Modified-Since`) and add caching headers (Last-Modified, Cache-Control) Note: `public` cache control will be added by default
|
|
90
|
+
|
|
91
|
+
## More Request Utils
|
|
92
|
+
|
|
93
|
+
### `assertMethod(event, expected, allowHead?)`
|
|
94
|
+
|
|
95
|
+
Asserts that the incoming request method is of the expected type using `isMethod`.
|
|
96
|
+
|
|
97
|
+
If the method is not allowed, it will throw a 405 error and include an `Allow` response header listing the permitted methods, as required by RFC 9110.
|
|
98
|
+
|
|
99
|
+
If `allowHead` is `true`, it will allow `HEAD` requests to pass if the expected method is `GET`.
|
|
100
|
+
|
|
101
|
+
**Example:**
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
app.get("/", (event) => {
|
|
105
|
+
assertMethod(event, "GET");
|
|
106
|
+
// Handle GET request, otherwise throw 405 error
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### `getQuery(event)`
|
|
111
|
+
|
|
112
|
+
Get parsed query string object from the request URL.
|
|
113
|
+
|
|
114
|
+
**Example:**
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
app.get("/", (event) => {
|
|
118
|
+
const query = getQuery(event); // { key: "value", key2: ["value1", "value2"] }
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### `getRequestHost(event, opts: { xForwardedHost? })`
|
|
123
|
+
|
|
124
|
+
Get the request hostname.
|
|
125
|
+
|
|
126
|
+
If `xForwardedHost` is `true`, it will use the `x-forwarded-host` header if it exists.
|
|
127
|
+
|
|
128
|
+
If no host header is found, it will return an empty string.
|
|
129
|
+
|
|
130
|
+
**Example:**
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
app.get("/", (event) => {
|
|
134
|
+
const host = getRequestHost(event); // "example.com"
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### `getRequestIP(event)`
|
|
139
|
+
|
|
140
|
+
Try to get the client IP address from the incoming request.
|
|
141
|
+
|
|
142
|
+
If `xForwardedFor` is `true`, it will use the `x-forwarded-for` header if it exists.
|
|
143
|
+
|
|
144
|
+
If IP cannot be determined, it will default to `undefined`.
|
|
145
|
+
|
|
146
|
+
**Example:**
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
app.get("/", (event) => {
|
|
150
|
+
const ip = getRequestIP(event); // "192.0.2.0"
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### `getRequestProtocol(event, opts: { xForwardedProto? })`
|
|
155
|
+
|
|
156
|
+
Get the request protocol.
|
|
157
|
+
|
|
158
|
+
If `x-forwarded-proto` header is set to "https", it will return "https". You can disable this behavior by setting `xForwardedProto` to `false`.
|
|
159
|
+
|
|
160
|
+
If protocol cannot be determined, it will default to "http".
|
|
161
|
+
|
|
162
|
+
**Example:**
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
app.get("/", (event) => {
|
|
166
|
+
const protocol = getRequestProtocol(event); // "https"
|
|
167
|
+
});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### `getRequestURL(event, opts: { xForwardedHost?, xForwardedProto? })`
|
|
171
|
+
|
|
172
|
+
Generated the full incoming request URL.
|
|
173
|
+
|
|
174
|
+
If `xForwardedHost` is `true`, it will use the `x-forwarded-host` header if it exists.
|
|
175
|
+
|
|
176
|
+
If `xForwardedProto` is `false`, it will not use the `x-forwarded-proto` header.
|
|
177
|
+
|
|
178
|
+
**Example:**
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
app.get("/", (event) => {
|
|
182
|
+
const url = getRequestURL(event); // "https://example.com/path"
|
|
183
|
+
});
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### `getRouterParam(event, name, opts: { decode? })`
|
|
187
|
+
|
|
188
|
+
Get a matched route param by name.
|
|
189
|
+
|
|
190
|
+
If `decode` option is `true`, it will decode the matched route param using `decodeURI`.
|
|
191
|
+
|
|
192
|
+
**Example:**
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
app.get("/", (event) => {
|
|
196
|
+
const param = getRouterParam(event, "key");
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### `getRouterParams(event, opts: { decode? })`
|
|
201
|
+
|
|
202
|
+
Get matched route params.
|
|
203
|
+
|
|
204
|
+
If `decode` option is `true`, it will decode the matched route params using `decodeURIComponent`.
|
|
205
|
+
|
|
206
|
+
**Example:**
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
app.get("/", (event) => {
|
|
210
|
+
const params = getRouterParams(event); // { key: "value" }
|
|
211
|
+
});
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### `getValidatedQuery(event, validate)`
|
|
215
|
+
|
|
216
|
+
Get the query param from the request URL validated with validate function.
|
|
217
|
+
|
|
218
|
+
You can use a simple function to validate the query object or use a Standard-Schema compatible library like `zod` to define a schema.
|
|
219
|
+
|
|
220
|
+
**Example:**
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
app.get("/", async (event) => {
|
|
224
|
+
const query = await getValidatedQuery(event, (data) => {
|
|
225
|
+
return "key" in data && typeof data.key === "string";
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**Example:**
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
import { z } from "zod";
|
|
234
|
+
app.get("/", async (event) => {
|
|
235
|
+
const query = await getValidatedQuery(
|
|
236
|
+
event,
|
|
237
|
+
z.object({
|
|
238
|
+
key: z.string(),
|
|
239
|
+
}),
|
|
240
|
+
);
|
|
241
|
+
});
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Example:**
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
import * as v from "valibot";
|
|
248
|
+
app.get("/", async (event) => {
|
|
249
|
+
const params = await getValidatedQuery(
|
|
250
|
+
event,
|
|
251
|
+
v.object({
|
|
252
|
+
key: v.string(),
|
|
253
|
+
}),
|
|
254
|
+
{
|
|
255
|
+
onError: ({ issues }) => ({
|
|
256
|
+
statusText: "Custom validation error",
|
|
257
|
+
message: v.summarize(issues),
|
|
258
|
+
}),
|
|
259
|
+
},
|
|
260
|
+
);
|
|
261
|
+
});
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### `getValidatedRouterParams(event, validate)`
|
|
265
|
+
|
|
266
|
+
Get matched route params and validate with validate function.
|
|
267
|
+
|
|
268
|
+
If `decode` option is `true`, it will decode the matched route params using `decodeURI`.
|
|
269
|
+
|
|
270
|
+
You can use a simple function to validate the params object or use a Standard-Schema compatible library like `zod` to define a schema.
|
|
271
|
+
|
|
272
|
+
**Example:**
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
app.get("/:key", async (event) => {
|
|
276
|
+
const params = await getValidatedRouterParams(event, (data) => {
|
|
277
|
+
return "key" in data && typeof data.key === "string";
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**Example:**
|
|
283
|
+
|
|
284
|
+
```ts
|
|
285
|
+
import { z } from "zod";
|
|
286
|
+
app.get("/:key", async (event) => {
|
|
287
|
+
const params = await getValidatedRouterParams(
|
|
288
|
+
event,
|
|
289
|
+
z.object({
|
|
290
|
+
key: z.string(),
|
|
291
|
+
}),
|
|
292
|
+
);
|
|
293
|
+
});
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
**Example:**
|
|
297
|
+
|
|
298
|
+
```ts
|
|
299
|
+
import * as v from "valibot";
|
|
300
|
+
app.get("/:key", async (event) => {
|
|
301
|
+
const params = await getValidatedRouterParams(
|
|
302
|
+
event,
|
|
303
|
+
v.object({
|
|
304
|
+
key: v.pipe(v.string(), v.picklist(["route-1", "route-2", "route-3"])),
|
|
305
|
+
}),
|
|
306
|
+
{
|
|
307
|
+
decode: true,
|
|
308
|
+
onError: ({ issues }) => ({
|
|
309
|
+
statusText: "Custom validation error",
|
|
310
|
+
message: v.summarize(issues),
|
|
311
|
+
}),
|
|
312
|
+
},
|
|
313
|
+
);
|
|
314
|
+
});
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### `isMethod(event, expected, allowHead?)`
|
|
318
|
+
|
|
319
|
+
Checks if the incoming request method is of the expected type.
|
|
320
|
+
|
|
321
|
+
If `allowHead` is `true`, it will allow `HEAD` requests to pass if the expected method is `GET`.
|
|
322
|
+
|
|
323
|
+
**Example:**
|
|
324
|
+
|
|
325
|
+
```ts
|
|
326
|
+
app.get("/", (event) => {
|
|
327
|
+
if (isMethod(event, "GET")) {
|
|
328
|
+
// Handle GET request
|
|
329
|
+
} else if (isMethod(event, ["POST", "PUT"])) {
|
|
330
|
+
// Handle POST or PUT request
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### `requestWithBaseURL(req, base)`
|
|
336
|
+
|
|
337
|
+
Create a lightweight request proxy with the base path stripped from the URL pathname.
|
|
338
|
+
|
|
339
|
+
### `requestWithURL(req, url)`
|
|
340
|
+
|
|
341
|
+
Create a lightweight request proxy that overrides only the URL.
|
|
342
|
+
|
|
343
|
+
Avoids cloning the original request (no `new Request()` allocation).
|
|
344
|
+
|
|
345
|
+
### `toRequest(input, options?)`
|
|
346
|
+
|
|
347
|
+
Convert input into a web [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request).
|
|
348
|
+
|
|
349
|
+
If input is a relative URL, it will be normalized into a full path based on headers.
|
|
350
|
+
|
|
351
|
+
If input is already a Request and no options are provided, it will be returned as-is.
|
|
352
|
+
|
|
353
|
+
### `getRequestFingerprint(event, opts)`
|
|
354
|
+
|
|
355
|
+
Get a unique fingerprint for the incoming request.
|