h3 0.7.12 → 0.7.15
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/README.md +16 -1
- package/dist/index.cjs +98 -15
- package/dist/index.d.ts +38 -11
- package/dist/index.mjs +80 -18
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -112,6 +112,8 @@ app.use((req, res, next) => { req.setHeader('X-Foo', 'bar'); next() })
|
|
|
112
112
|
|
|
113
113
|
## Utilities
|
|
114
114
|
|
|
115
|
+
### Built-in
|
|
116
|
+
|
|
115
117
|
Instead of adding helpers to `req` and `res`, h3 exposes them as composable utilities.
|
|
116
118
|
|
|
117
119
|
- `useRawBody(req, encoding?)`
|
|
@@ -121,9 +123,15 @@ Instead of adding helpers to `req` and `res`, h3 exposes them as composable util
|
|
|
121
123
|
- `setCookie(res, name, value, opts?)`
|
|
122
124
|
- `deleteCookie(res, name, opts?)`
|
|
123
125
|
- `useQuery(req)`
|
|
126
|
+
- `getRouterParams(event)`
|
|
124
127
|
- `send(res, data, type?)`
|
|
125
128
|
- `sendRedirect(res, location, code=302)`
|
|
126
|
-
- `
|
|
129
|
+
- `getRequestHeaders(event, headers)` (alias: `getHeaders`)
|
|
130
|
+
- `getRequestHeader(event, name)` (alias: `getHeader`)
|
|
131
|
+
- `setResponseHeaders(event, headers)` (alias: `setHeaders`)
|
|
132
|
+
- `setResponseHeader(event, name, value)` (alias: `setHeader`)
|
|
133
|
+
- `appendResponseHeaders(event, headers)` (alias: `appendHeaders`)
|
|
134
|
+
- `appendResponseHeader(event, name, value)` (alias: `appendHeader`)
|
|
127
135
|
- `createError({ statusCode, statusMessage, data? })`
|
|
128
136
|
- `sendError(res, error, debug?)`
|
|
129
137
|
- `defineHandle(handle)`
|
|
@@ -134,6 +142,13 @@ Instead of adding helpers to `req` and `res`, h3 exposes them as composable util
|
|
|
134
142
|
|
|
135
143
|
👉 You can learn more about usage in [JSDocs Documentation](https://www.jsdocs.io/package/h3#package-functions).
|
|
136
144
|
|
|
145
|
+
### Add-ons
|
|
146
|
+
|
|
147
|
+
More composable utilities can be found in community packages.
|
|
148
|
+
|
|
149
|
+
- `validateBody(event, schema)` from [h3-typebox](https://github.com/kevinmarrec/h3-typebox)
|
|
150
|
+
- `validateQuery(event, schema)` from [h3-typebox](https://github.com/kevinmarrec/h3-typebox)
|
|
151
|
+
|
|
137
152
|
## How it works?
|
|
138
153
|
|
|
139
154
|
Using `createApp`, it returns a standard `(req, res)` handler function and internally an array called middleware stack. using`use()` method we can add an item to this internal stack.
|
package/dist/index.cjs
CHANGED
|
@@ -11,14 +11,23 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
|
|
|
11
11
|
|
|
12
12
|
const destr__default = /*#__PURE__*/_interopDefaultLegacy(destr);
|
|
13
13
|
|
|
14
|
-
function
|
|
14
|
+
function getQuery(event) {
|
|
15
15
|
return ufo.getQuery(event.req.url || "");
|
|
16
16
|
}
|
|
17
|
-
|
|
17
|
+
const useQuery = getQuery;
|
|
18
|
+
function getRouterParams(event) {
|
|
19
|
+
return event.context.params || {};
|
|
20
|
+
}
|
|
21
|
+
function getRouterParam(event, name) {
|
|
22
|
+
const params = getRouterParams(event);
|
|
23
|
+
return params[name];
|
|
24
|
+
}
|
|
25
|
+
function getMethod(event, defaultMethod = "GET") {
|
|
18
26
|
return (event.req.method || defaultMethod).toUpperCase();
|
|
19
27
|
}
|
|
28
|
+
const useMethod = getMethod;
|
|
20
29
|
function isMethod(event, expected, allowHead) {
|
|
21
|
-
const method =
|
|
30
|
+
const method = getMethod(event);
|
|
22
31
|
if (allowHead && method === "HEAD") {
|
|
23
32
|
return true;
|
|
24
33
|
}
|
|
@@ -39,11 +48,21 @@ function assertMethod(event, expected, allowHead) {
|
|
|
39
48
|
});
|
|
40
49
|
}
|
|
41
50
|
}
|
|
51
|
+
function getRequestHeaders(event) {
|
|
52
|
+
return event.req.headers;
|
|
53
|
+
}
|
|
54
|
+
const getHeaders = getRequestHeaders;
|
|
55
|
+
function getRequestHeader(event, name) {
|
|
56
|
+
const headers = getRequestHeaders(event);
|
|
57
|
+
const value = headers[name.toLowerCase()];
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
const getHeader = getRequestHeader;
|
|
42
61
|
|
|
43
62
|
const RawBodySymbol = Symbol("h3RawBody");
|
|
44
63
|
const ParsedBodySymbol = Symbol("h3RawBody");
|
|
45
64
|
const PayloadMethods = ["PATCH", "POST", "PUT", "DELETE"];
|
|
46
|
-
function
|
|
65
|
+
function readRawBody(event, encoding = "utf-8") {
|
|
47
66
|
assertMethod(event, PayloadMethods);
|
|
48
67
|
if (RawBodySymbol in event.req) {
|
|
49
68
|
const promise2 = Promise.resolve(event.req[RawBodySymbol]);
|
|
@@ -64,11 +83,12 @@ function useRawBody(event, encoding = "utf-8") {
|
|
|
64
83
|
});
|
|
65
84
|
return encoding ? promise.then((buff) => buff.toString(encoding)) : promise;
|
|
66
85
|
}
|
|
67
|
-
|
|
86
|
+
const useRawBody = readRawBody;
|
|
87
|
+
async function readBody(event) {
|
|
68
88
|
if (ParsedBodySymbol in event.req) {
|
|
69
89
|
return event.req[ParsedBodySymbol];
|
|
70
90
|
}
|
|
71
|
-
const body = await
|
|
91
|
+
const body = await readRawBody(event);
|
|
72
92
|
if (event.req.headers["content-type"] === "application/x-www-form-urlencoded") {
|
|
73
93
|
const parsedForm = Object.fromEntries(new URLSearchParams(body));
|
|
74
94
|
return parsedForm;
|
|
@@ -77,6 +97,7 @@ async function useBody(event) {
|
|
|
77
97
|
event.req[ParsedBodySymbol] = json;
|
|
78
98
|
return json;
|
|
79
99
|
}
|
|
100
|
+
const useBody = readBody;
|
|
80
101
|
|
|
81
102
|
function handleCacheHeaders(event, opts) {
|
|
82
103
|
const cacheControls = ["public"].concat(opts.cacheControls || []);
|
|
@@ -135,9 +156,32 @@ function defaultContentType(event, type) {
|
|
|
135
156
|
function sendRedirect(event, location, code = 302) {
|
|
136
157
|
event.res.statusCode = code;
|
|
137
158
|
event.res.setHeader("Location", location);
|
|
138
|
-
|
|
159
|
+
const html = `<!DOCTYPE html>
|
|
160
|
+
<html>
|
|
161
|
+
<head><meta http-equiv="refresh" content="0; url=${encodeURI(location)}"></head>
|
|
162
|
+
<body>Redirecting to <a href=${JSON.stringify(location)}>${encodeURI(location)}</a></body>
|
|
163
|
+
</html>`;
|
|
164
|
+
return send(event, html, MIMES.html);
|
|
165
|
+
}
|
|
166
|
+
function getResponseHeaders(event) {
|
|
167
|
+
return event.res.getHeaders();
|
|
168
|
+
}
|
|
169
|
+
function getResponseHeader(event, name) {
|
|
170
|
+
return event.res.getHeader(name);
|
|
171
|
+
}
|
|
172
|
+
function setResponseHeaders(event, headers) {
|
|
173
|
+
Object.entries(headers).forEach(([name, value]) => event.res.setHeader(name, value));
|
|
174
|
+
}
|
|
175
|
+
const setHeaders = setResponseHeaders;
|
|
176
|
+
function setResponseHeader(event, name, value) {
|
|
177
|
+
event.res.setHeader(name, value);
|
|
139
178
|
}
|
|
140
|
-
|
|
179
|
+
const setHeader = setResponseHeader;
|
|
180
|
+
function appendResponseHeaders(event, headers) {
|
|
181
|
+
Object.entries(headers).forEach(([name, value]) => appendResponseHeader(event, name, value));
|
|
182
|
+
}
|
|
183
|
+
const appendHeaders = appendResponseHeaders;
|
|
184
|
+
function appendResponseHeader(event, name, value) {
|
|
141
185
|
let current = event.res.getHeader(name);
|
|
142
186
|
if (!current) {
|
|
143
187
|
event.res.setHeader(name, value);
|
|
@@ -148,6 +192,7 @@ function appendHeader(event, name, value) {
|
|
|
148
192
|
}
|
|
149
193
|
event.res.setHeader(name, current.concat(value));
|
|
150
194
|
}
|
|
195
|
+
const appendHeader = appendResponseHeader;
|
|
151
196
|
function isStream(data) {
|
|
152
197
|
return data && typeof data === "object" && typeof data.pipe === "function" && typeof data.on === "function";
|
|
153
198
|
}
|
|
@@ -159,12 +204,14 @@ function sendStream(event, data) {
|
|
|
159
204
|
});
|
|
160
205
|
}
|
|
161
206
|
|
|
162
|
-
function
|
|
207
|
+
function parseCookies(event) {
|
|
163
208
|
return cookieEs.parse(event.req.headers.cookie || "");
|
|
164
209
|
}
|
|
165
|
-
|
|
166
|
-
|
|
210
|
+
const useCookies = parseCookies;
|
|
211
|
+
function getCookie(event, name) {
|
|
212
|
+
return parseCookies(event)[name];
|
|
167
213
|
}
|
|
214
|
+
const useCookie = getCookie;
|
|
168
215
|
function setCookie(event, name, value, serializeOptions) {
|
|
169
216
|
const cookieStr = cookieEs.serialize(name, value, {
|
|
170
217
|
path: "/",
|
|
@@ -197,6 +244,18 @@ function createError(input) {
|
|
|
197
244
|
return input;
|
|
198
245
|
}
|
|
199
246
|
const err = new H3Error(input.message ?? input.statusMessage, input.cause ? { cause: input.cause } : void 0);
|
|
247
|
+
if ("stack" in input) {
|
|
248
|
+
try {
|
|
249
|
+
Object.defineProperty(err, "stack", { get() {
|
|
250
|
+
return input.stack;
|
|
251
|
+
} });
|
|
252
|
+
} catch {
|
|
253
|
+
try {
|
|
254
|
+
err.stack = input.stack;
|
|
255
|
+
} catch {
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
200
259
|
if (input.statusCode) {
|
|
201
260
|
err.statusCode = input.statusCode;
|
|
202
261
|
}
|
|
@@ -390,12 +449,12 @@ function createApp(options = {}) {
|
|
|
390
449
|
if (!isError(_error)) {
|
|
391
450
|
error.unhandled = true;
|
|
392
451
|
}
|
|
393
|
-
if (error.unhandled || error.fatal) {
|
|
394
|
-
console.error("[h3]", error.fatal ? "[fatal]" : "[unhandled]", error);
|
|
395
|
-
}
|
|
396
452
|
if (options.onError) {
|
|
397
453
|
await options.onError(error, event);
|
|
398
454
|
} else {
|
|
455
|
+
if (error.unhandled || error.fatal) {
|
|
456
|
+
console.error("[h3]", error.fatal ? "[fatal]" : "[unhandled]", error);
|
|
457
|
+
}
|
|
399
458
|
await sendError(event, error, !!options.debug);
|
|
400
459
|
}
|
|
401
460
|
}
|
|
@@ -447,8 +506,11 @@ function createAppEventHandler(stack, options) {
|
|
|
447
506
|
return send(event, val, MIMES.html);
|
|
448
507
|
} else if (isStream(val)) {
|
|
449
508
|
return sendStream(event, val);
|
|
509
|
+
} else if (val === null) {
|
|
510
|
+
event.res.statusCode = 204;
|
|
511
|
+
return send(event);
|
|
450
512
|
} else if (type === "object" || type === "boolean" || type === "number") {
|
|
451
|
-
if (val
|
|
513
|
+
if (val.buffer) {
|
|
452
514
|
return send(event, val);
|
|
453
515
|
} else if (val instanceof Error) {
|
|
454
516
|
throw createError(val);
|
|
@@ -535,6 +597,9 @@ function createRouter() {
|
|
|
535
597
|
exports.H3Error = H3Error;
|
|
536
598
|
exports.MIMES = MIMES;
|
|
537
599
|
exports.appendHeader = appendHeader;
|
|
600
|
+
exports.appendHeaders = appendHeaders;
|
|
601
|
+
exports.appendResponseHeader = appendResponseHeader;
|
|
602
|
+
exports.appendResponseHeaders = appendResponseHeaders;
|
|
538
603
|
exports.assertMethod = assertMethod;
|
|
539
604
|
exports.callHandler = callHandler;
|
|
540
605
|
exports.createApp = createApp;
|
|
@@ -552,6 +617,17 @@ exports.defineMiddleware = defineMiddleware;
|
|
|
552
617
|
exports.deleteCookie = deleteCookie;
|
|
553
618
|
exports.dynamicEventHandler = dynamicEventHandler;
|
|
554
619
|
exports.eventHandler = eventHandler;
|
|
620
|
+
exports.getCookie = getCookie;
|
|
621
|
+
exports.getHeader = getHeader;
|
|
622
|
+
exports.getHeaders = getHeaders;
|
|
623
|
+
exports.getMethod = getMethod;
|
|
624
|
+
exports.getQuery = getQuery;
|
|
625
|
+
exports.getRequestHeader = getRequestHeader;
|
|
626
|
+
exports.getRequestHeaders = getRequestHeaders;
|
|
627
|
+
exports.getResponseHeader = getResponseHeader;
|
|
628
|
+
exports.getResponseHeaders = getResponseHeaders;
|
|
629
|
+
exports.getRouterParam = getRouterParam;
|
|
630
|
+
exports.getRouterParams = getRouterParams;
|
|
555
631
|
exports.handleCacheHeaders = handleCacheHeaders;
|
|
556
632
|
exports.isError = isError;
|
|
557
633
|
exports.isEvent = isEvent;
|
|
@@ -560,13 +636,20 @@ exports.isMethod = isMethod;
|
|
|
560
636
|
exports.isStream = isStream;
|
|
561
637
|
exports.lazyEventHandler = lazyEventHandler;
|
|
562
638
|
exports.lazyHandle = lazyHandle;
|
|
639
|
+
exports.parseCookies = parseCookies;
|
|
563
640
|
exports.promisifyHandle = promisifyHandle;
|
|
564
641
|
exports.promisifyHandler = promisifyHandler;
|
|
642
|
+
exports.readBody = readBody;
|
|
643
|
+
exports.readRawBody = readRawBody;
|
|
565
644
|
exports.send = send;
|
|
566
645
|
exports.sendError = sendError;
|
|
567
646
|
exports.sendRedirect = sendRedirect;
|
|
568
647
|
exports.sendStream = sendStream;
|
|
569
648
|
exports.setCookie = setCookie;
|
|
649
|
+
exports.setHeader = setHeader;
|
|
650
|
+
exports.setHeaders = setHeaders;
|
|
651
|
+
exports.setResponseHeader = setResponseHeader;
|
|
652
|
+
exports.setResponseHeaders = setResponseHeaders;
|
|
570
653
|
exports.toEventHandler = toEventHandler;
|
|
571
654
|
exports.use = use;
|
|
572
655
|
exports.useBase = useBase;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import http from 'http';
|
|
1
|
+
import http, { OutgoingMessage } from 'http';
|
|
2
2
|
import { CookieSerializeOptions } from 'cookie-es';
|
|
3
3
|
import * as ufo from 'ufo';
|
|
4
4
|
|
|
@@ -152,7 +152,9 @@ declare function useBase(base: string, handler: Handler): Handler;
|
|
|
152
152
|
*
|
|
153
153
|
* @return {String|Buffer} Encoded raw string or raw Buffer of the body
|
|
154
154
|
*/
|
|
155
|
-
declare function
|
|
155
|
+
declare function readRawBody(event: CompatibilityEvent, encoding?: Encoding): Encoding extends false ? Buffer : Promise<string | Buffer>;
|
|
156
|
+
/** @deprecated Use `h3.readRawBody` */
|
|
157
|
+
declare const useRawBody: typeof readRawBody;
|
|
156
158
|
/**
|
|
157
159
|
* Reads request body and try to safely parse using [destr](https://github.com/unjs/destr)
|
|
158
160
|
* @param event {CompatibilityEvent} H3 event or req passed by h3 handler
|
|
@@ -164,7 +166,9 @@ declare function useRawBody(event: CompatibilityEvent, encoding?: Encoding): Enc
|
|
|
164
166
|
* const body = await useBody(req)
|
|
165
167
|
* ```
|
|
166
168
|
*/
|
|
167
|
-
declare function
|
|
169
|
+
declare function readBody<T = any>(event: CompatibilityEvent): Promise<T>;
|
|
170
|
+
/** @deprecated Use `h3.readBody` */
|
|
171
|
+
declare const useBody: typeof readBody;
|
|
168
172
|
|
|
169
173
|
interface CacheConditions {
|
|
170
174
|
modifiedTime?: string | Date;
|
|
@@ -189,10 +193,12 @@ declare const MIMES: {
|
|
|
189
193
|
* @param event {CompatibilityEvent} H3 event or req passed by h3 handler
|
|
190
194
|
* @returns Object of cookie name-value pairs
|
|
191
195
|
* ```ts
|
|
192
|
-
* const cookies =
|
|
196
|
+
* const cookies = parseCookies(event)
|
|
193
197
|
* ```
|
|
194
198
|
*/
|
|
195
|
-
declare function
|
|
199
|
+
declare function parseCookies(event: CompatibilityEvent): Record<string, string>;
|
|
200
|
+
/** @deprecated Use `h3.parseCookies` */
|
|
201
|
+
declare const useCookies: typeof parseCookies;
|
|
196
202
|
/**
|
|
197
203
|
* Get a cookie value by name.
|
|
198
204
|
* @param event {CompatibilityEvent} H3 event or req passed by h3 handler
|
|
@@ -202,7 +208,9 @@ declare function useCookies(event: CompatibilityEvent): Record<string, string>;
|
|
|
202
208
|
* const authorization = useCookie(request, 'Authorization')
|
|
203
209
|
* ```
|
|
204
210
|
*/
|
|
205
|
-
declare function
|
|
211
|
+
declare function getCookie(event: CompatibilityEvent, name: string): string | undefined;
|
|
212
|
+
/** @deprecated Use `h3.getCookie` */
|
|
213
|
+
declare const useCookie: typeof getCookie;
|
|
206
214
|
/**
|
|
207
215
|
* Set a cookie value by name.
|
|
208
216
|
* @param event {CompatibilityEvent} H3 event or res passed by h3 handler
|
|
@@ -225,15 +233,34 @@ declare function setCookie(event: CompatibilityEvent, name: string, value: strin
|
|
|
225
233
|
*/
|
|
226
234
|
declare function deleteCookie(event: CompatibilityEvent, name: string, serializeOptions?: CookieSerializeOptions): void;
|
|
227
235
|
|
|
228
|
-
declare function
|
|
229
|
-
|
|
236
|
+
declare function getQuery(event: CompatibilityEvent): ufo.QueryObject;
|
|
237
|
+
/** @deprecated Use `h3.getQuery` */
|
|
238
|
+
declare const useQuery: typeof getQuery;
|
|
239
|
+
declare function getRouterParams(event: CompatibilityEvent): CompatibilityEvent['context'];
|
|
240
|
+
declare function getRouterParam(event: CompatibilityEvent, name: string): CompatibilityEvent['context'][string];
|
|
241
|
+
declare function getMethod(event: CompatibilityEvent, defaultMethod?: HTTPMethod): HTTPMethod;
|
|
242
|
+
/** @deprecated Use `h3.getMethod` */
|
|
243
|
+
declare const useMethod: typeof getMethod;
|
|
230
244
|
declare function isMethod(event: CompatibilityEvent, expected: HTTPMethod | HTTPMethod[], allowHead?: boolean): boolean;
|
|
231
245
|
declare function assertMethod(event: CompatibilityEvent, expected: HTTPMethod | HTTPMethod[], allowHead?: boolean): void;
|
|
246
|
+
declare function getRequestHeaders(event: CompatibilityEvent): CompatibilityEvent['req']['headers'];
|
|
247
|
+
declare const getHeaders: typeof getRequestHeaders;
|
|
248
|
+
declare function getRequestHeader(event: CompatibilityEvent, name: string): CompatibilityEvent['req']['headers'][string];
|
|
249
|
+
declare const getHeader: typeof getRequestHeader;
|
|
232
250
|
|
|
233
|
-
declare function send(event: CompatibilityEvent, data
|
|
251
|
+
declare function send(event: CompatibilityEvent, data?: any, type?: string): Promise<void>;
|
|
234
252
|
declare function defaultContentType(event: CompatibilityEvent, type?: string): void;
|
|
235
253
|
declare function sendRedirect(event: CompatibilityEvent, location: string, code?: number): Promise<void>;
|
|
236
|
-
declare function
|
|
254
|
+
declare function getResponseHeaders(event: CompatibilityEvent): ReturnType<CompatibilityEvent['res']['getHeaders']>;
|
|
255
|
+
declare function getResponseHeader(event: CompatibilityEvent, name: string): ReturnType<CompatibilityEvent['res']['getHeader']>;
|
|
256
|
+
declare function setResponseHeaders(event: CompatibilityEvent, headers: Record<string, Parameters<OutgoingMessage['setHeader']>[1]>): void;
|
|
257
|
+
declare const setHeaders: typeof setResponseHeaders;
|
|
258
|
+
declare function setResponseHeader(event: CompatibilityEvent, name: string, value: Parameters<OutgoingMessage['setHeader']>[1]): void;
|
|
259
|
+
declare const setHeader: typeof setResponseHeader;
|
|
260
|
+
declare function appendResponseHeaders(event: CompatibilityEvent, headers: Record<string, string>): void;
|
|
261
|
+
declare const appendHeaders: typeof appendResponseHeaders;
|
|
262
|
+
declare function appendResponseHeader(event: CompatibilityEvent, name: string, value: string): void;
|
|
263
|
+
declare const appendHeader: typeof appendResponseHeader;
|
|
237
264
|
declare function isStream(data: any): any;
|
|
238
265
|
declare function sendStream(event: CompatibilityEvent, data: any): Promise<void>;
|
|
239
266
|
|
|
@@ -247,4 +274,4 @@ interface Router extends AddRouteShortcuts {
|
|
|
247
274
|
}
|
|
248
275
|
declare function createRouter(): Router;
|
|
249
276
|
|
|
250
|
-
export { AddRouteShortcuts, App, AppOptions, AppUse, CacheConditions, CompatibilityEvent, CompatibilityEventHandler, DynamicEventHandler, Encoding, EventHandler, H3Error, H3Event, H3EventContext, H3Response, HTTPMethod, Handler, IncomingMessage, InputLayer, InputStack, Layer, LazyEventHandler, LazyHandler, MIMES, Matcher, Middleware, NodeHandler, PromisifiedHandler, Router, RouterMethod, RouterUse, ServerResponse, Stack, appendHeader, assertMethod, callHandler, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineHandle, defineHandler, defineLazyEventHandler, defineLazyHandler, defineMiddleware, deleteCookie, dynamicEventHandler, eventHandler, handleCacheHeaders, isError, isEvent, isEventHandler, isMethod, isStream, lazyEventHandler, lazyHandle, promisifyHandle, promisifyHandler, send, sendError, sendRedirect, sendStream, setCookie, toEventHandler, use, useBase, useBody, useCookie, useCookies, useMethod, useQuery, useRawBody };
|
|
277
|
+
export { AddRouteShortcuts, App, AppOptions, AppUse, CacheConditions, CompatibilityEvent, CompatibilityEventHandler, DynamicEventHandler, Encoding, EventHandler, H3Error, H3Event, H3EventContext, H3Response, HTTPMethod, Handler, IncomingMessage, InputLayer, InputStack, Layer, LazyEventHandler, LazyHandler, MIMES, Matcher, Middleware, NodeHandler, PromisifiedHandler, Router, RouterMethod, RouterUse, ServerResponse, Stack, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callHandler, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineHandle, defineHandler, defineLazyEventHandler, defineLazyHandler, defineMiddleware, deleteCookie, dynamicEventHandler, eventHandler, getCookie, getHeader, getHeaders, getMethod, getQuery, getRequestHeader, getRequestHeaders, getResponseHeader, getResponseHeaders, getRouterParam, getRouterParams, handleCacheHeaders, isError, isEvent, isEventHandler, isMethod, isStream, lazyEventHandler, lazyHandle, parseCookies, promisifyHandle, promisifyHandler, readBody, readRawBody, send, sendError, sendRedirect, sendStream, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, toEventHandler, use, useBase, useBody, useCookie, useCookies, useMethod, useQuery, useRawBody };
|
package/dist/index.mjs
CHANGED
|
@@ -1,16 +1,25 @@
|
|
|
1
|
-
import { getQuery, withoutTrailingSlash, withoutBase } from 'ufo';
|
|
1
|
+
import { getQuery as getQuery$1, withoutTrailingSlash, withoutBase } from 'ufo';
|
|
2
2
|
import { createRouter as createRouter$1 } from 'radix3';
|
|
3
3
|
import destr from 'destr';
|
|
4
4
|
import { parse, serialize } from 'cookie-es';
|
|
5
5
|
|
|
6
|
-
function
|
|
7
|
-
return getQuery(event.req.url || "");
|
|
6
|
+
function getQuery(event) {
|
|
7
|
+
return getQuery$1(event.req.url || "");
|
|
8
8
|
}
|
|
9
|
-
|
|
9
|
+
const useQuery = getQuery;
|
|
10
|
+
function getRouterParams(event) {
|
|
11
|
+
return event.context.params || {};
|
|
12
|
+
}
|
|
13
|
+
function getRouterParam(event, name) {
|
|
14
|
+
const params = getRouterParams(event);
|
|
15
|
+
return params[name];
|
|
16
|
+
}
|
|
17
|
+
function getMethod(event, defaultMethod = "GET") {
|
|
10
18
|
return (event.req.method || defaultMethod).toUpperCase();
|
|
11
19
|
}
|
|
20
|
+
const useMethod = getMethod;
|
|
12
21
|
function isMethod(event, expected, allowHead) {
|
|
13
|
-
const method =
|
|
22
|
+
const method = getMethod(event);
|
|
14
23
|
if (allowHead && method === "HEAD") {
|
|
15
24
|
return true;
|
|
16
25
|
}
|
|
@@ -31,11 +40,21 @@ function assertMethod(event, expected, allowHead) {
|
|
|
31
40
|
});
|
|
32
41
|
}
|
|
33
42
|
}
|
|
43
|
+
function getRequestHeaders(event) {
|
|
44
|
+
return event.req.headers;
|
|
45
|
+
}
|
|
46
|
+
const getHeaders = getRequestHeaders;
|
|
47
|
+
function getRequestHeader(event, name) {
|
|
48
|
+
const headers = getRequestHeaders(event);
|
|
49
|
+
const value = headers[name.toLowerCase()];
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
const getHeader = getRequestHeader;
|
|
34
53
|
|
|
35
54
|
const RawBodySymbol = Symbol("h3RawBody");
|
|
36
55
|
const ParsedBodySymbol = Symbol("h3RawBody");
|
|
37
56
|
const PayloadMethods = ["PATCH", "POST", "PUT", "DELETE"];
|
|
38
|
-
function
|
|
57
|
+
function readRawBody(event, encoding = "utf-8") {
|
|
39
58
|
assertMethod(event, PayloadMethods);
|
|
40
59
|
if (RawBodySymbol in event.req) {
|
|
41
60
|
const promise2 = Promise.resolve(event.req[RawBodySymbol]);
|
|
@@ -56,11 +75,12 @@ function useRawBody(event, encoding = "utf-8") {
|
|
|
56
75
|
});
|
|
57
76
|
return encoding ? promise.then((buff) => buff.toString(encoding)) : promise;
|
|
58
77
|
}
|
|
59
|
-
|
|
78
|
+
const useRawBody = readRawBody;
|
|
79
|
+
async function readBody(event) {
|
|
60
80
|
if (ParsedBodySymbol in event.req) {
|
|
61
81
|
return event.req[ParsedBodySymbol];
|
|
62
82
|
}
|
|
63
|
-
const body = await
|
|
83
|
+
const body = await readRawBody(event);
|
|
64
84
|
if (event.req.headers["content-type"] === "application/x-www-form-urlencoded") {
|
|
65
85
|
const parsedForm = Object.fromEntries(new URLSearchParams(body));
|
|
66
86
|
return parsedForm;
|
|
@@ -69,6 +89,7 @@ async function useBody(event) {
|
|
|
69
89
|
event.req[ParsedBodySymbol] = json;
|
|
70
90
|
return json;
|
|
71
91
|
}
|
|
92
|
+
const useBody = readBody;
|
|
72
93
|
|
|
73
94
|
function handleCacheHeaders(event, opts) {
|
|
74
95
|
const cacheControls = ["public"].concat(opts.cacheControls || []);
|
|
@@ -127,9 +148,32 @@ function defaultContentType(event, type) {
|
|
|
127
148
|
function sendRedirect(event, location, code = 302) {
|
|
128
149
|
event.res.statusCode = code;
|
|
129
150
|
event.res.setHeader("Location", location);
|
|
130
|
-
|
|
151
|
+
const html = `<!DOCTYPE html>
|
|
152
|
+
<html>
|
|
153
|
+
<head><meta http-equiv="refresh" content="0; url=${encodeURI(location)}"></head>
|
|
154
|
+
<body>Redirecting to <a href=${JSON.stringify(location)}>${encodeURI(location)}</a></body>
|
|
155
|
+
</html>`;
|
|
156
|
+
return send(event, html, MIMES.html);
|
|
157
|
+
}
|
|
158
|
+
function getResponseHeaders(event) {
|
|
159
|
+
return event.res.getHeaders();
|
|
160
|
+
}
|
|
161
|
+
function getResponseHeader(event, name) {
|
|
162
|
+
return event.res.getHeader(name);
|
|
163
|
+
}
|
|
164
|
+
function setResponseHeaders(event, headers) {
|
|
165
|
+
Object.entries(headers).forEach(([name, value]) => event.res.setHeader(name, value));
|
|
166
|
+
}
|
|
167
|
+
const setHeaders = setResponseHeaders;
|
|
168
|
+
function setResponseHeader(event, name, value) {
|
|
169
|
+
event.res.setHeader(name, value);
|
|
131
170
|
}
|
|
132
|
-
|
|
171
|
+
const setHeader = setResponseHeader;
|
|
172
|
+
function appendResponseHeaders(event, headers) {
|
|
173
|
+
Object.entries(headers).forEach(([name, value]) => appendResponseHeader(event, name, value));
|
|
174
|
+
}
|
|
175
|
+
const appendHeaders = appendResponseHeaders;
|
|
176
|
+
function appendResponseHeader(event, name, value) {
|
|
133
177
|
let current = event.res.getHeader(name);
|
|
134
178
|
if (!current) {
|
|
135
179
|
event.res.setHeader(name, value);
|
|
@@ -140,6 +184,7 @@ function appendHeader(event, name, value) {
|
|
|
140
184
|
}
|
|
141
185
|
event.res.setHeader(name, current.concat(value));
|
|
142
186
|
}
|
|
187
|
+
const appendHeader = appendResponseHeader;
|
|
143
188
|
function isStream(data) {
|
|
144
189
|
return data && typeof data === "object" && typeof data.pipe === "function" && typeof data.on === "function";
|
|
145
190
|
}
|
|
@@ -151,12 +196,14 @@ function sendStream(event, data) {
|
|
|
151
196
|
});
|
|
152
197
|
}
|
|
153
198
|
|
|
154
|
-
function
|
|
199
|
+
function parseCookies(event) {
|
|
155
200
|
return parse(event.req.headers.cookie || "");
|
|
156
201
|
}
|
|
157
|
-
|
|
158
|
-
|
|
202
|
+
const useCookies = parseCookies;
|
|
203
|
+
function getCookie(event, name) {
|
|
204
|
+
return parseCookies(event)[name];
|
|
159
205
|
}
|
|
206
|
+
const useCookie = getCookie;
|
|
160
207
|
function setCookie(event, name, value, serializeOptions) {
|
|
161
208
|
const cookieStr = serialize(name, value, {
|
|
162
209
|
path: "/",
|
|
@@ -189,6 +236,18 @@ function createError(input) {
|
|
|
189
236
|
return input;
|
|
190
237
|
}
|
|
191
238
|
const err = new H3Error(input.message ?? input.statusMessage, input.cause ? { cause: input.cause } : void 0);
|
|
239
|
+
if ("stack" in input) {
|
|
240
|
+
try {
|
|
241
|
+
Object.defineProperty(err, "stack", { get() {
|
|
242
|
+
return input.stack;
|
|
243
|
+
} });
|
|
244
|
+
} catch {
|
|
245
|
+
try {
|
|
246
|
+
err.stack = input.stack;
|
|
247
|
+
} catch {
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
192
251
|
if (input.statusCode) {
|
|
193
252
|
err.statusCode = input.statusCode;
|
|
194
253
|
}
|
|
@@ -382,12 +441,12 @@ function createApp(options = {}) {
|
|
|
382
441
|
if (!isError(_error)) {
|
|
383
442
|
error.unhandled = true;
|
|
384
443
|
}
|
|
385
|
-
if (error.unhandled || error.fatal) {
|
|
386
|
-
console.error("[h3]", error.fatal ? "[fatal]" : "[unhandled]", error);
|
|
387
|
-
}
|
|
388
444
|
if (options.onError) {
|
|
389
445
|
await options.onError(error, event);
|
|
390
446
|
} else {
|
|
447
|
+
if (error.unhandled || error.fatal) {
|
|
448
|
+
console.error("[h3]", error.fatal ? "[fatal]" : "[unhandled]", error);
|
|
449
|
+
}
|
|
391
450
|
await sendError(event, error, !!options.debug);
|
|
392
451
|
}
|
|
393
452
|
}
|
|
@@ -439,8 +498,11 @@ function createAppEventHandler(stack, options) {
|
|
|
439
498
|
return send(event, val, MIMES.html);
|
|
440
499
|
} else if (isStream(val)) {
|
|
441
500
|
return sendStream(event, val);
|
|
501
|
+
} else if (val === null) {
|
|
502
|
+
event.res.statusCode = 204;
|
|
503
|
+
return send(event);
|
|
442
504
|
} else if (type === "object" || type === "boolean" || type === "number") {
|
|
443
|
-
if (val
|
|
505
|
+
if (val.buffer) {
|
|
444
506
|
return send(event, val);
|
|
445
507
|
} else if (val instanceof Error) {
|
|
446
508
|
throw createError(val);
|
|
@@ -524,4 +586,4 @@ function createRouter() {
|
|
|
524
586
|
return router;
|
|
525
587
|
}
|
|
526
588
|
|
|
527
|
-
export { H3Error, MIMES, appendHeader, assertMethod, callHandler, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineHandle, defineHandler, defineLazyEventHandler, defineLazyHandler, defineMiddleware, deleteCookie, dynamicEventHandler, eventHandler, handleCacheHeaders, isError, isEvent, isEventHandler, isMethod, isStream, lazyEventHandler, lazyHandle, promisifyHandle, promisifyHandler, send, sendError, sendRedirect, sendStream, setCookie, toEventHandler, use, useBase, useBody, useCookie, useCookies, useMethod, useQuery, useRawBody };
|
|
589
|
+
export { H3Error, MIMES, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callHandler, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineHandle, defineHandler, defineLazyEventHandler, defineLazyHandler, defineMiddleware, deleteCookie, dynamicEventHandler, eventHandler, getCookie, getHeader, getHeaders, getMethod, getQuery, getRequestHeader, getRequestHeaders, getResponseHeader, getResponseHeaders, getRouterParam, getRouterParams, handleCacheHeaders, isError, isEvent, isEventHandler, isMethod, isStream, lazyEventHandler, lazyHandle, parseCookies, promisifyHandle, promisifyHandler, readBody, readRawBody, send, sendError, sendRedirect, sendStream, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, toEventHandler, use, useBase, useBody, useCookie, useCookies, useMethod, useQuery, useRawBody };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "h3",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.15",
|
|
4
4
|
"description": "Tiny JavaScript Server",
|
|
5
5
|
"repository": "unjs/h3",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"unbuild": "latest",
|
|
46
46
|
"vitest": "latest"
|
|
47
47
|
},
|
|
48
|
-
"packageManager": "pnpm@7.
|
|
48
|
+
"packageManager": "pnpm@7.9.0",
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "unbuild",
|
|
51
51
|
"dev": "vitest",
|