h3 0.7.11 → 0.7.14

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 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
- - `appendHeader(res, name, value)`
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 useQuery(event) {
14
+ function getQuery(event) {
15
15
  return ufo.getQuery(event.req.url || "");
16
16
  }
17
- function useMethod(event, defaultMethod = "GET") {
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 = useMethod(event);
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 useRawBody(event, encoding = "utf-8") {
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
- async function useBody(event) {
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 useRawBody(event);
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
- return send(event, "Redirecting to " + location, MIMES.html);
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);
178
+ }
179
+ const setHeader = setResponseHeader;
180
+ function appendResponseHeaders(event, headers) {
181
+ Object.entries(headers).forEach(([name, value]) => appendResponseHeader(event, name, value));
139
182
  }
140
- function appendHeader(event, name, value) {
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 useCookies(event) {
207
+ function parseCookies(event) {
163
208
  return cookieEs.parse(event.req.headers.cookie || "");
164
209
  }
165
- function useCookie(event, name) {
166
- return useCookies(event)[name];
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: "/",
@@ -188,11 +235,12 @@ class H3Error extends Error {
188
235
  this.statusMessage = "Internal Server Error";
189
236
  }
190
237
  }
238
+ H3Error.__h3_error__ = true;
191
239
  function createError(input) {
192
240
  if (typeof input === "string") {
193
241
  return new H3Error(input);
194
242
  }
195
- if (input instanceof H3Error) {
243
+ if (isError(input)) {
196
244
  return input;
197
245
  }
198
246
  const err = new H3Error(input.message ?? input.statusMessage, input.cause ? { cause: input.cause } : void 0);
@@ -236,7 +284,7 @@ function sendError(event, error, debug) {
236
284
  event.res.end(JSON.stringify(responseBody, null, 2));
237
285
  }
238
286
  function isError(input) {
239
- return input instanceof H3Error;
287
+ return input?.constructor?.__h3_error__ === true;
240
288
  }
241
289
 
242
290
  const defineHandler = (handler) => handler;
@@ -446,8 +494,11 @@ function createAppEventHandler(stack, options) {
446
494
  return send(event, val, MIMES.html);
447
495
  } else if (isStream(val)) {
448
496
  return sendStream(event, val);
497
+ } else if (val === null) {
498
+ event.res.statusCode = 204;
499
+ return send(event);
449
500
  } else if (type === "object" || type === "boolean" || type === "number") {
450
- if (val && val.buffer) {
501
+ if (val.buffer) {
451
502
  return send(event, val);
452
503
  } else if (val instanceof Error) {
453
504
  throw createError(val);
@@ -534,6 +585,9 @@ function createRouter() {
534
585
  exports.H3Error = H3Error;
535
586
  exports.MIMES = MIMES;
536
587
  exports.appendHeader = appendHeader;
588
+ exports.appendHeaders = appendHeaders;
589
+ exports.appendResponseHeader = appendResponseHeader;
590
+ exports.appendResponseHeaders = appendResponseHeaders;
537
591
  exports.assertMethod = assertMethod;
538
592
  exports.callHandler = callHandler;
539
593
  exports.createApp = createApp;
@@ -551,6 +605,17 @@ exports.defineMiddleware = defineMiddleware;
551
605
  exports.deleteCookie = deleteCookie;
552
606
  exports.dynamicEventHandler = dynamicEventHandler;
553
607
  exports.eventHandler = eventHandler;
608
+ exports.getCookie = getCookie;
609
+ exports.getHeader = getHeader;
610
+ exports.getHeaders = getHeaders;
611
+ exports.getMethod = getMethod;
612
+ exports.getQuery = getQuery;
613
+ exports.getRequestHeader = getRequestHeader;
614
+ exports.getRequestHeaders = getRequestHeaders;
615
+ exports.getResponseHeader = getResponseHeader;
616
+ exports.getResponseHeaders = getResponseHeaders;
617
+ exports.getRouterParam = getRouterParam;
618
+ exports.getRouterParams = getRouterParams;
554
619
  exports.handleCacheHeaders = handleCacheHeaders;
555
620
  exports.isError = isError;
556
621
  exports.isEvent = isEvent;
@@ -559,13 +624,20 @@ exports.isMethod = isMethod;
559
624
  exports.isStream = isStream;
560
625
  exports.lazyEventHandler = lazyEventHandler;
561
626
  exports.lazyHandle = lazyHandle;
627
+ exports.parseCookies = parseCookies;
562
628
  exports.promisifyHandle = promisifyHandle;
563
629
  exports.promisifyHandler = promisifyHandler;
630
+ exports.readBody = readBody;
631
+ exports.readRawBody = readRawBody;
564
632
  exports.send = send;
565
633
  exports.sendError = sendError;
566
634
  exports.sendRedirect = sendRedirect;
567
635
  exports.sendStream = sendStream;
568
636
  exports.setCookie = setCookie;
637
+ exports.setHeader = setHeader;
638
+ exports.setHeaders = setHeaders;
639
+ exports.setResponseHeader = setResponseHeader;
640
+ exports.setResponseHeaders = setResponseHeaders;
569
641
  exports.toEventHandler = toEventHandler;
570
642
  exports.use = use;
571
643
  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
 
@@ -105,6 +105,7 @@ declare function createAppEventHandler(stack: Stack, options: AppOptions): Event
105
105
  * @property {Boolean} internal Setting this property to <code>true</code> will mark error as an internal error
106
106
  */
107
107
  declare class H3Error extends Error {
108
+ static __h3_error__: boolean;
108
109
  statusCode: number;
109
110
  fatal: boolean;
110
111
  unhandled: boolean;
@@ -151,7 +152,9 @@ declare function useBase(base: string, handler: Handler): Handler;
151
152
  *
152
153
  * @return {String|Buffer} Encoded raw string or raw Buffer of the body
153
154
  */
154
- declare function useRawBody(event: CompatibilityEvent, encoding?: Encoding): Encoding extends false ? Buffer : Promise<string | Buffer>;
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;
155
158
  /**
156
159
  * Reads request body and try to safely parse using [destr](https://github.com/unjs/destr)
157
160
  * @param event {CompatibilityEvent} H3 event or req passed by h3 handler
@@ -163,7 +166,9 @@ declare function useRawBody(event: CompatibilityEvent, encoding?: Encoding): Enc
163
166
  * const body = await useBody(req)
164
167
  * ```
165
168
  */
166
- declare function useBody<T = any>(event: CompatibilityEvent): Promise<T>;
169
+ declare function readBody<T = any>(event: CompatibilityEvent): Promise<T>;
170
+ /** @deprecated Use `h3.readBody` */
171
+ declare const useBody: typeof readBody;
167
172
 
168
173
  interface CacheConditions {
169
174
  modifiedTime?: string | Date;
@@ -188,10 +193,12 @@ declare const MIMES: {
188
193
  * @param event {CompatibilityEvent} H3 event or req passed by h3 handler
189
194
  * @returns Object of cookie name-value pairs
190
195
  * ```ts
191
- * const cookies = useCookies(req)
196
+ * const cookies = parseCookies(event)
192
197
  * ```
193
198
  */
194
- declare function useCookies(event: CompatibilityEvent): Record<string, string>;
199
+ declare function parseCookies(event: CompatibilityEvent): Record<string, string>;
200
+ /** @deprecated Use `h3.parseCookies` */
201
+ declare const useCookies: typeof parseCookies;
195
202
  /**
196
203
  * Get a cookie value by name.
197
204
  * @param event {CompatibilityEvent} H3 event or req passed by h3 handler
@@ -201,7 +208,9 @@ declare function useCookies(event: CompatibilityEvent): Record<string, string>;
201
208
  * const authorization = useCookie(request, 'Authorization')
202
209
  * ```
203
210
  */
204
- declare function useCookie(event: CompatibilityEvent, name: string): string | undefined;
211
+ declare function getCookie(event: CompatibilityEvent, name: string): string | undefined;
212
+ /** @deprecated Use `h3.getCookie` */
213
+ declare const useCookie: typeof getCookie;
205
214
  /**
206
215
  * Set a cookie value by name.
207
216
  * @param event {CompatibilityEvent} H3 event or res passed by h3 handler
@@ -224,15 +233,34 @@ declare function setCookie(event: CompatibilityEvent, name: string, value: strin
224
233
  */
225
234
  declare function deleteCookie(event: CompatibilityEvent, name: string, serializeOptions?: CookieSerializeOptions): void;
226
235
 
227
- declare function useQuery(event: CompatibilityEvent): ufo.QueryObject;
228
- declare function useMethod(event: CompatibilityEvent, defaultMethod?: HTTPMethod): HTTPMethod;
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;
229
244
  declare function isMethod(event: CompatibilityEvent, expected: HTTPMethod | HTTPMethod[], allowHead?: boolean): boolean;
230
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;
231
250
 
232
- declare function send(event: CompatibilityEvent, data: any, type?: string): Promise<void>;
251
+ declare function send(event: CompatibilityEvent, data?: any, type?: string): Promise<void>;
233
252
  declare function defaultContentType(event: CompatibilityEvent, type?: string): void;
234
253
  declare function sendRedirect(event: CompatibilityEvent, location: string, code?: number): Promise<void>;
235
- declare function appendHeader(event: CompatibilityEvent, name: string, value: string): void;
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;
236
264
  declare function isStream(data: any): any;
237
265
  declare function sendStream(event: CompatibilityEvent, data: any): Promise<void>;
238
266
 
@@ -246,4 +274,4 @@ interface Router extends AddRouteShortcuts {
246
274
  }
247
275
  declare function createRouter(): Router;
248
276
 
249
- 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 useQuery(event) {
7
- return getQuery(event.req.url || "");
6
+ function getQuery(event) {
7
+ return getQuery$1(event.req.url || "");
8
8
  }
9
- function useMethod(event, defaultMethod = "GET") {
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 = useMethod(event);
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 useRawBody(event, encoding = "utf-8") {
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
- async function useBody(event) {
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 useRawBody(event);
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
- return send(event, "Redirecting to " + location, MIMES.html);
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);
170
+ }
171
+ const setHeader = setResponseHeader;
172
+ function appendResponseHeaders(event, headers) {
173
+ Object.entries(headers).forEach(([name, value]) => appendResponseHeader(event, name, value));
131
174
  }
132
- function appendHeader(event, name, value) {
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 useCookies(event) {
199
+ function parseCookies(event) {
155
200
  return parse(event.req.headers.cookie || "");
156
201
  }
157
- function useCookie(event, name) {
158
- return useCookies(event)[name];
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: "/",
@@ -180,11 +227,12 @@ class H3Error extends Error {
180
227
  this.statusMessage = "Internal Server Error";
181
228
  }
182
229
  }
230
+ H3Error.__h3_error__ = true;
183
231
  function createError(input) {
184
232
  if (typeof input === "string") {
185
233
  return new H3Error(input);
186
234
  }
187
- if (input instanceof H3Error) {
235
+ if (isError(input)) {
188
236
  return input;
189
237
  }
190
238
  const err = new H3Error(input.message ?? input.statusMessage, input.cause ? { cause: input.cause } : void 0);
@@ -228,7 +276,7 @@ function sendError(event, error, debug) {
228
276
  event.res.end(JSON.stringify(responseBody, null, 2));
229
277
  }
230
278
  function isError(input) {
231
- return input instanceof H3Error;
279
+ return input?.constructor?.__h3_error__ === true;
232
280
  }
233
281
 
234
282
  const defineHandler = (handler) => handler;
@@ -438,8 +486,11 @@ function createAppEventHandler(stack, options) {
438
486
  return send(event, val, MIMES.html);
439
487
  } else if (isStream(val)) {
440
488
  return sendStream(event, val);
489
+ } else if (val === null) {
490
+ event.res.statusCode = 204;
491
+ return send(event);
441
492
  } else if (type === "object" || type === "boolean" || type === "number") {
442
- if (val && val.buffer) {
493
+ if (val.buffer) {
443
494
  return send(event, val);
444
495
  } else if (val instanceof Error) {
445
496
  throw createError(val);
@@ -523,4 +574,4 @@ function createRouter() {
523
574
  return router;
524
575
  }
525
576
 
526
- 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 };
577
+ 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.11",
3
+ "version": "0.7.14",
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.5.2",
48
+ "packageManager": "pnpm@7.9.0",
49
49
  "scripts": {
50
50
  "build": "unbuild",
51
51
  "dev": "vitest",