h3 1.7.0 → 1.7.1

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
@@ -68,7 +68,7 @@ listen(toNodeListener(app));
68
68
 
69
69
  ## Router
70
70
 
71
- The `app` instance created by `h3` uses a middleware stack (see [how it works](#how-it-works)) with the ability to match route prefix and apply matched middleware.
71
+ The `app` instance created by `h3` uses a middleware stack (see [how it works](./src/app.ts)) with the ability to match route prefix and apply matched middleware.
72
72
 
73
73
  To opt-in using a more advanced and convenient routing system, we can create a router instance and register it to app instance.
74
74
 
@@ -98,36 +98,60 @@ Routes are internally stored in a [Radix Tree](https://en.wikipedia.org/wiki/Rad
98
98
 
99
99
  ```js
100
100
  // Handle can directly return object or Promise<object> for JSON response
101
- app.use('/api', eventHandler((event) => ({ url: event.node.req.url })))
101
+ app.use(
102
+ "/api",
103
+ eventHandler((event) => ({ url: event.node.req.url }))
104
+ );
102
105
 
103
106
  // We can have better matching other than quick prefix match
104
- app.use('/odd', eventHandler(() => 'Is odd!'), { match: url => url.substr(1) % 2 })
107
+ app.use(
108
+ "/odd",
109
+ eventHandler(() => "Is odd!"),
110
+ { match: (url) => url.substr(1) % 2 }
111
+ );
105
112
 
106
113
  // Handle can directly return string for HTML response
107
- app.use(eventHandler(() => '<h1>Hello world!</h1>'))
114
+ app.use(eventHandler(() => "<h1>Hello world!</h1>"));
108
115
 
109
116
  // We can chain calls to .use()
110
- app.use('/1', eventHandler(() => '<h1>Hello world!</h1>'))
111
- .use('/2', eventHandler(() => '<h1>Goodbye!</h1>'))
117
+ app
118
+ .use(
119
+ "/1",
120
+ eventHandler(() => "<h1>Hello world!</h1>")
121
+ )
122
+ .use(
123
+ "/2",
124
+ eventHandler(() => "<h1>Goodbye!</h1>")
125
+ );
112
126
 
113
127
  // We can proxy requests and rewrite cookie's domain and path
114
- app.use('/api', eventHandler((event) => proxyRequest(event, 'https://example.com', {
115
- // f.e. keep one domain unchanged, rewrite one domain and remove other domains
116
- cookieDomainRewrite: {
117
- "example.com": "example.com",
118
- "example.com": "somecompany.co.uk",
119
- "*": "",
120
- },
121
- cookiePathRewrite: {
122
- "/": "/api"
123
- },
124
- })))
128
+ app.use(
129
+ "/api",
130
+ eventHandler((event) =>
131
+ proxyRequest(event, "https://example.com", {
132
+ // f.e. keep one domain unchanged, rewrite one domain and remove other domains
133
+ cookieDomainRewrite: {
134
+ "example.com": "example.com",
135
+ "example.com": "somecompany.co.uk",
136
+ "*": "",
137
+ },
138
+ cookiePathRewrite: {
139
+ "/": "/api",
140
+ },
141
+ })
142
+ )
143
+ );
125
144
 
126
145
  // Legacy middleware with 3rd argument are automatically promisified
127
- app.use(fromNodeMiddleware((req, res, next) => { req.setHeader('x-foo', 'bar'); next() }))
146
+ app.use(
147
+ fromNodeMiddleware((req, res, next) => {
148
+ req.setHeader("x-foo", "bar");
149
+ next();
150
+ })
151
+ );
128
152
 
129
153
  // Lazy loaded routes using { lazy: true }
130
- app.use('/big', () => import('./big-handler'), { lazy: true })
154
+ app.use("/big", () => import("./big-handler"), { lazy: true });
131
155
  ```
132
156
 
133
157
  ## Utilities
package/dist/index.cjs CHANGED
@@ -108,7 +108,6 @@ class H3Error extends Error {
108
108
  this.statusCode = 500;
109
109
  this.fatal = false;
110
110
  this.unhandled = false;
111
- this.statusMessage = void 0;
112
111
  }
113
112
  toJSON() {
114
113
  const obj = {
@@ -133,8 +132,8 @@ function createError(input) {
133
132
  return input;
134
133
  }
135
134
  const err = new H3Error(
136
- input.message ?? input.statusMessage,
137
- // @ts-ignore
135
+ input.message ?? input.statusMessage ?? "",
136
+ // @ts-ignore https://v8.dev/features/error-cause
138
137
  input.cause ? { cause: input.cause } : void 0
139
138
  );
140
139
  if ("stack" in input) {
@@ -169,7 +168,7 @@ function createError(input) {
169
168
  const sanitizedMessage = sanitizeStatusMessage(err.statusMessage);
170
169
  if (sanitizedMessage !== originalMessage) {
171
170
  console.warn(
172
- "[h3] Please prefer using `message` for longer error messages instead of `statusMessage`. In the future `statusMessage` will be sanitized by default."
171
+ "[h3] Please prefer using `message` for longer error messages instead of `statusMessage`. In the future, `statusMessage` will be sanitized by default."
173
172
  );
174
173
  }
175
174
  }
package/dist/index.d.ts CHANGED
@@ -170,44 +170,50 @@ declare function createAppEventHandler(stack: Stack, options: AppOptions): Event
170
170
  * H3 Runtime Error
171
171
  * @class
172
172
  * @extends Error
173
- * @property {Number} statusCode An Integer indicating the HTTP response status code.
174
- * @property {String} statusMessage A String representing the HTTP status message
175
- * @property {String} fatal Indicates if the error is a fatal error.
176
- * @property {String} unhandled Indicates if the error was unhandled and auto captured.
177
- * @property {Any} data An extra data that will includes in the response.<br>
178
- * This can be used to pass additional information about the error.
179
- * @property {Boolean} internal Setting this property to <code>true</code> will mark error as an internal error
173
+ * @property {number} statusCode - An integer indicating the HTTP response status code.
174
+ * @property {string} statusMessage - A string representing the HTTP status message.
175
+ * @property {boolean} fatal - Indicates if the error is a fatal error.
176
+ * @property {boolean} unhandled - Indicates if the error was unhandled and auto captured.
177
+ * @property {any} data - An extra data that will be included in the response.
178
+ * This can be used to pass additional information about the error.
179
+ * @property {boolean} internal - Setting this property to `true` will mark the error as an internal error.
180
180
  */
181
181
  declare class H3Error extends Error {
182
182
  static __h3_error__: boolean;
183
- toJSON(): Pick<H3Error, "data" | "statusCode" | "statusMessage" | "message">;
184
183
  statusCode: number;
185
184
  fatal: boolean;
186
185
  unhandled: boolean;
187
186
  statusMessage?: string;
188
187
  data?: any;
188
+ toJSON(): Pick<H3Error, "data" | "statusCode" | "statusMessage" | "message">;
189
189
  }
190
190
  /**
191
- * Creates new `Error` that can be used to handle both internal and runtime errors.
191
+ * Creates a new `Error` that can be used to handle both internal and runtime errors.
192
192
  *
193
- * @param input {Partial<H3Error>}
194
- * @return {H3Error} An instance of the H3Error
193
+ * @param input {string | (Partial<H3Error> & { status?: number; statusText?: string })} - The error message or an object containing error properties.
194
+ * @return {H3Error} - An instance of H3Error.
195
195
  */
196
196
  declare function createError(input: string | (Partial<H3Error> & {
197
197
  status?: number;
198
198
  statusText?: string;
199
199
  })): H3Error;
200
200
  /**
201
- * Receive an error and return the corresponding response.<br>
202
- * H3 internally uses this function to handle unhandled errors.<br>
203
- * Note that calling this function will close the connection and no other data will be sent to client afterwards.
201
+ * Receives an error and returns the corresponding response.
202
+ * H3 internally uses this function to handle unhandled errors.
203
+ * Note that calling this function will close the connection and no other data will be sent to the client afterwards.
204
204
  *
205
- @param event {H3Event} H3 event or req passed by h3 handler
206
- * @param error {H3Error|Error} Raised error
207
- * @param debug {Boolean} Whether application is in debug mode.<br>
208
- * In the debug mode the stack trace of errors will be return in response.
205
+ * @param event {H3Event} - H3 event or req passed by h3 handler.
206
+ * @param error {Error | H3Error} - The raised error.
207
+ * @param debug {boolean} - Whether the application is in debug mode.
208
+ * In the debug mode, the stack trace of errors will be returned in the response.
209
209
  */
210
210
  declare function sendError(event: H3Event, error: Error | H3Error, debug?: boolean): void;
211
+ /**
212
+ * Checks if the given input is an instance of H3Error.
213
+ *
214
+ * @param input {*} - The input to check.
215
+ * @return {boolean} - Returns true if the input is an instance of H3Error, false otherwise.
216
+ */
211
217
  declare function isError(input: any): input is H3Error;
212
218
 
213
219
  declare function useBase(base: string, handler: EventHandler): EventHandler;
@@ -322,11 +328,11 @@ interface ProxyOptions {
322
328
  declare function proxyRequest(event: H3Event, target: string, opts?: ProxyOptions): Promise<any>;
323
329
  declare function sendProxy(event: H3Event, target: string, opts?: ProxyOptions): Promise<any>;
324
330
  declare function getProxyRequestHeaders(event: H3Event): any;
325
- declare function fetchWithEvent(event: H3Event, req: RequestInfo | URL, init?: RequestInit & {
331
+ declare function fetchWithEvent<T = unknown, _R = any, F extends (req: RequestInfo | URL, opts?: any) => any = typeof fetch>(event: H3Event, req: RequestInfo | URL, init?: RequestInit & {
326
332
  context?: H3EventContext;
327
333
  }, options?: {
328
- fetch: typeof fetch;
329
- }): Promise<Response>;
334
+ fetch: F;
335
+ }): unknown extends T ? ReturnType<F> : T;
330
336
 
331
337
  declare function getQuery(event: H3Event): ufo.QueryObject;
332
338
  declare function getRouterParams(event: H3Event): NonNullable<H3Event["context"]["params"]>;
package/dist/index.mjs CHANGED
@@ -101,7 +101,6 @@ class H3Error extends Error {
101
101
  this.statusCode = 500;
102
102
  this.fatal = false;
103
103
  this.unhandled = false;
104
- this.statusMessage = void 0;
105
104
  }
106
105
  toJSON() {
107
106
  const obj = {
@@ -126,8 +125,8 @@ function createError(input) {
126
125
  return input;
127
126
  }
128
127
  const err = new H3Error(
129
- input.message ?? input.statusMessage,
130
- // @ts-ignore
128
+ input.message ?? input.statusMessage ?? "",
129
+ // @ts-ignore https://v8.dev/features/error-cause
131
130
  input.cause ? { cause: input.cause } : void 0
132
131
  );
133
132
  if ("stack" in input) {
@@ -162,7 +161,7 @@ function createError(input) {
162
161
  const sanitizedMessage = sanitizeStatusMessage(err.statusMessage);
163
162
  if (sanitizedMessage !== originalMessage) {
164
163
  console.warn(
165
- "[h3] Please prefer using `message` for longer error messages instead of `statusMessage`. In the future `statusMessage` will be sanitized by default."
164
+ "[h3] Please prefer using `message` for longer error messages instead of `statusMessage`. In the future, `statusMessage` will be sanitized by default."
166
165
  );
167
166
  }
168
167
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "h3",
3
- "version": "1.7.0",
3
+ "version": "1.7.1",
4
4
  "description": "Tiny JavaScript Server",
5
5
  "repository": "unjs/h3",
6
6
  "license": "MIT",
@@ -19,16 +19,6 @@
19
19
  "files": [
20
20
  "dist"
21
21
  ],
22
- "scripts": {
23
- "build": "unbuild",
24
- "dev": "vitest",
25
- "lint": "eslint --cache --ext .ts,.js,.mjs,.cjs . && prettier -c src test playground",
26
- "lint:fix": "eslint --cache --ext .ts,.js,.mjs,.cjs . --fix && prettier -c src test playground -w",
27
- "play": "jiti ./playground/index.ts",
28
- "profile": "0x -o -D .profile -P 'autocannon -c 100 -p 10 -d 40 http://localhost:$PORT' ./playground/server.cjs",
29
- "release": "pnpm test && pnpm build && changelogen --release && pnpm publish && git push --follow-tags",
30
- "test": "pnpm lint && vitest run --coverage"
31
- },
32
22
  "dependencies": {
33
23
  "cookie-es": "^1.0.0",
34
24
  "defu": "^6.1.2",
@@ -60,5 +50,15 @@
60
50
  "unbuild": "^1.2.1",
61
51
  "vitest": "^0.32.2"
62
52
  },
63
- "packageManager": "pnpm@8.6.3"
53
+ "packageManager": "pnpm@8.6.3",
54
+ "scripts": {
55
+ "build": "unbuild",
56
+ "dev": "vitest",
57
+ "lint": "eslint --cache --ext .ts,.js,.mjs,.cjs . && prettier -c src test playground",
58
+ "lint:fix": "eslint --cache --ext .ts,.js,.mjs,.cjs . --fix && prettier -c src test playground -w",
59
+ "play": "jiti ./playground/index.ts",
60
+ "profile": "0x -o -D .profile -P 'autocannon -c 100 -p 10 -d 40 http://localhost:$PORT' ./playground/server.cjs",
61
+ "release": "pnpm test && pnpm build && changelogen --release && pnpm publish && git push --follow-tags",
62
+ "test": "pnpm lint && vitest run --coverage"
63
+ }
64
64
  }