h3 0.3.1 → 0.3.5
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 +37 -17
- package/dist/index.cjs +42 -10
- package/dist/index.d.ts +44 -9
- package/dist/index.mjs +38 -11
- package/package.json +4 -4
- package/CHANGELOG.md +0 -235
package/README.md
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
[](https://npmjs.com/package/h3)
|
|
2
|
+
[](https://npmjs.com/package/h3)
|
|
3
|
+
[](https://bundlephobia.com/result?p=h3)
|
|
4
|
+
[](https://github.com/unjs/h3/actions)
|
|
5
|
+
[](https://codecov.io/gh/unjs/h3)
|
|
6
|
+
[](https://www.jsdocs.io/package/h3)
|
|
6
7
|
|
|
7
8
|
> H3 is a minimal h(ttp) framework built for high performance and portability
|
|
8
9
|
|
|
9
10
|
<!--  -->
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
## Features
|
|
12
13
|
|
|
13
|
-
✔️
|
|
14
|
+
✔️ **Portable:** Works perfectly in Serverless, Workers, and Node.js
|
|
14
15
|
|
|
15
|
-
✔️
|
|
16
|
+
✔️ **Compatible:** Support connect/express middleware
|
|
16
17
|
|
|
17
|
-
✔️
|
|
18
|
+
✔️ **Minimal:** Small, tree-shakable and zero-dependency
|
|
18
19
|
|
|
19
|
-
✔️
|
|
20
|
+
✔️ **Modern:** Native promise support
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
✔️ **Extendable:** Ships with a set of composable utilities but can be extended
|
|
22
23
|
|
|
23
24
|
## Install
|
|
24
25
|
|
|
@@ -42,7 +43,19 @@ app.use('/', () => 'Hello world!')
|
|
|
42
43
|
createServer(app).listen(process.env.PORT || 3000)
|
|
43
44
|
```
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
<details>
|
|
47
|
+
<summary>Example using <a href="https://github.com/unjs/listhen">listhen</a> for an elegant listener.</summary>
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { createApp } from 'h3'
|
|
51
|
+
import { listen } from 'listhen'
|
|
52
|
+
|
|
53
|
+
const app = createApp()
|
|
54
|
+
app.use('/', () => 'Hello world!')
|
|
55
|
+
|
|
56
|
+
listen(app)
|
|
57
|
+
```
|
|
58
|
+
</details>
|
|
46
59
|
|
|
47
60
|
## Examples
|
|
48
61
|
|
|
@@ -78,26 +91,33 @@ Instead of adding helpers to `req` and `res`, h3 exposes them as composable util
|
|
|
78
91
|
- `useBody(req)`
|
|
79
92
|
- `useCookies(req)`
|
|
80
93
|
- `useCookie(req, name)`
|
|
81
|
-
- `setCookie(
|
|
94
|
+
- `setCookie(res, name, value, opts?)`
|
|
82
95
|
- `useQuery(req)`
|
|
83
96
|
- `send(res, data, type?)`
|
|
84
97
|
- `sendRedirect(res, location, code=302)`
|
|
85
98
|
- `appendHeader(res, name, value)`
|
|
86
99
|
- `createError({ statusCode, statusMessage, data? }`
|
|
87
100
|
- `sendError(res, error, debug?)`
|
|
101
|
+
- `defineHandle(handle)`
|
|
102
|
+
- `defineMiddleware(middlware)`
|
|
103
|
+
- `useMethod(req, default?)`
|
|
104
|
+
- `isMethod(req, expected, allowHead?)`
|
|
105
|
+
- `assertMethod(req, expected, allowHead?)`
|
|
106
|
+
|
|
107
|
+
👉 You can learn more about usage in [JSDocs Documentation](https://www.jsdocs.io/package/h3#package-functions).
|
|
88
108
|
|
|
89
109
|
## How it works?
|
|
90
110
|
|
|
91
|
-
Using `createApp`, it returns a standard `(req, res)` handler function and internally an array called middleware stack. using`use()` method we can
|
|
111
|
+
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.
|
|
92
112
|
|
|
93
113
|
When a request comes, each stack item that matches the route will be called and resolved until [`res.writableEnded`](https://nodejs.org/api/http.html#http_response_writableended) flag is set, which means the response is sent. If `writableEnded` is not set after all middleware, a `404` error will be thrown. And if one of the stack items resolves to a value, it will be serialized and sent as response as a shorthand method to sending responses.
|
|
94
114
|
|
|
95
115
|
For maximum compatibility with connect/express middleware (`req, res, next?` signature), h3 converts classic middleware into a promisified version ready to use with stack runner:
|
|
96
116
|
|
|
97
|
-
- If middleware has 3rd next/callback param, promise will `resolve/reject` when called
|
|
117
|
+
- If middleware has 3rd next/callback param, the promise will `resolve/reject` when called
|
|
98
118
|
- If middleware returns a promise, it will be **chained** to the main promise
|
|
99
|
-
- If calling middleware throws an immediate error, promise will be rejected
|
|
100
|
-
- On `close` and `error` events of res, promise will `resolve/reject` (to ensure if middleware simply calls `res.end`)
|
|
119
|
+
- If calling middleware throws an immediate error, the promise will be rejected
|
|
120
|
+
- On `close` and `error` events of res, the promise will `resolve/reject` (to ensure if middleware simply calls `res.end`)
|
|
101
121
|
|
|
102
122
|
## License
|
|
103
123
|
|
package/dist/index.cjs
CHANGED
|
@@ -83,8 +83,8 @@ function parseURL(input = "", defaultProto) {
|
|
|
83
83
|
return defaultProto ? parseURL(defaultProto + input) : parsePath(input);
|
|
84
84
|
}
|
|
85
85
|
const [protocol = "", auth, hostAndPath] = (input.match(/([^:/]+:)?\/\/([^/@]+@)?(.*)/) || []).splice(1);
|
|
86
|
-
const [host = "", path = ""] = (hostAndPath.match(/([
|
|
87
|
-
const {pathname, search, hash} = parsePath(path);
|
|
86
|
+
const [host = "", path = ""] = (hostAndPath.match(/([^/?]*)(.*)?/) || []).splice(1);
|
|
87
|
+
const { pathname, search, hash } = parsePath(path);
|
|
88
88
|
return {
|
|
89
89
|
protocol,
|
|
90
90
|
auth: auth ? auth.substr(0, auth.length - 1) : "",
|
|
@@ -103,6 +103,8 @@ function parsePath(input = "") {
|
|
|
103
103
|
};
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
const defineHandle = (handler) => handler;
|
|
107
|
+
const defineMiddleware = (middleware) => middleware;
|
|
106
108
|
function promisifyHandle(handle) {
|
|
107
109
|
return function(req, res) {
|
|
108
110
|
return callHandle(handle, req, res);
|
|
@@ -199,6 +201,9 @@ function useRawBody(req, encoding = "utf-8") {
|
|
|
199
201
|
if (req[RawBodySymbol]) {
|
|
200
202
|
return Promise.resolve(encoding ? req[RawBodySymbol].toString(encoding) : req[RawBodySymbol]);
|
|
201
203
|
}
|
|
204
|
+
if (req._body) {
|
|
205
|
+
return Promise.resolve(req._body);
|
|
206
|
+
}
|
|
202
207
|
return new Promise((resolve, reject) => {
|
|
203
208
|
const bodyData = [];
|
|
204
209
|
req.on("error", (err) => {
|
|
@@ -346,11 +351,7 @@ function serialize(name, val, options) {
|
|
|
346
351
|
|
|
347
352
|
if (null != opt.maxAge) {
|
|
348
353
|
var maxAge = opt.maxAge - 0;
|
|
349
|
-
|
|
350
|
-
if (isNaN(maxAge) || !isFinite(maxAge)) {
|
|
351
|
-
throw new TypeError('option maxAge is invalid')
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
+
if (isNaN(maxAge)) throw new Error('maxAge should be a Number');
|
|
354
355
|
str += '; Max-Age=' + Math.floor(maxAge);
|
|
355
356
|
}
|
|
356
357
|
|
|
@@ -475,6 +476,31 @@ function setCookie(res, name, value, serializeOptions) {
|
|
|
475
476
|
function useQuery(req) {
|
|
476
477
|
return getQuery(req.url || "");
|
|
477
478
|
}
|
|
479
|
+
function useMethod(req, defaultMethod = "GET") {
|
|
480
|
+
return (req.method || defaultMethod).toUpperCase();
|
|
481
|
+
}
|
|
482
|
+
function isMethod(req, expected, allowHead) {
|
|
483
|
+
const method = useMethod(req);
|
|
484
|
+
if (allowHead && method === "HEAD") {
|
|
485
|
+
return true;
|
|
486
|
+
}
|
|
487
|
+
if (typeof expected === "string") {
|
|
488
|
+
if (method === expected) {
|
|
489
|
+
return true;
|
|
490
|
+
}
|
|
491
|
+
} else if (expected.includes(method)) {
|
|
492
|
+
return true;
|
|
493
|
+
}
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
function assertMethod(req, expected, allowHead) {
|
|
497
|
+
if (!isMethod(req, expected, allowHead)) {
|
|
498
|
+
throw createError({
|
|
499
|
+
statusCode: 405,
|
|
500
|
+
statusMessage: "HTTP method is not allowed."
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
}
|
|
478
504
|
|
|
479
505
|
class H3Error extends Error {
|
|
480
506
|
constructor() {
|
|
@@ -528,7 +554,7 @@ function sendError(res, error, debug) {
|
|
|
528
554
|
|
|
529
555
|
function createApp(options = {}) {
|
|
530
556
|
const stack = [];
|
|
531
|
-
const _handle = createHandle(stack);
|
|
557
|
+
const _handle = createHandle(stack, options);
|
|
532
558
|
const app = function(req, res) {
|
|
533
559
|
return _handle(req, res).catch((error) => {
|
|
534
560
|
if (options.onError) {
|
|
@@ -556,7 +582,8 @@ function use(app, arg1, arg2, arg3) {
|
|
|
556
582
|
}
|
|
557
583
|
return app;
|
|
558
584
|
}
|
|
559
|
-
function createHandle(stack) {
|
|
585
|
+
function createHandle(stack, options) {
|
|
586
|
+
const spacing = options.debug ? 2 : void 0;
|
|
560
587
|
return async function handle(req, res) {
|
|
561
588
|
req.originalUrl = req.originalUrl || req.url || "/";
|
|
562
589
|
const reqUrl = req.url || "/";
|
|
@@ -585,7 +612,7 @@ function createHandle(stack) {
|
|
|
585
612
|
} else if (val instanceof Error) {
|
|
586
613
|
throw createError(val);
|
|
587
614
|
} else {
|
|
588
|
-
return send(res, JSON.stringify(val, null,
|
|
615
|
+
return send(res, JSON.stringify(val, null, spacing), MIMES.json);
|
|
589
616
|
}
|
|
590
617
|
}
|
|
591
618
|
}
|
|
@@ -608,11 +635,15 @@ function normalizeLayer(layer) {
|
|
|
608
635
|
exports.H3Error = H3Error;
|
|
609
636
|
exports.MIMES = MIMES;
|
|
610
637
|
exports.appendHeader = appendHeader;
|
|
638
|
+
exports.assertMethod = assertMethod;
|
|
611
639
|
exports.callHandle = callHandle;
|
|
612
640
|
exports.createApp = createApp;
|
|
613
641
|
exports.createError = createError;
|
|
614
642
|
exports.createHandle = createHandle;
|
|
615
643
|
exports.defaultContentType = defaultContentType;
|
|
644
|
+
exports.defineHandle = defineHandle;
|
|
645
|
+
exports.defineMiddleware = defineMiddleware;
|
|
646
|
+
exports.isMethod = isMethod;
|
|
616
647
|
exports.lazyHandle = lazyHandle;
|
|
617
648
|
exports.promisifyHandle = promisifyHandle;
|
|
618
649
|
exports.send = send;
|
|
@@ -624,5 +655,6 @@ exports.useBase = useBase;
|
|
|
624
655
|
exports.useBody = useBody;
|
|
625
656
|
exports.useCookie = useCookie;
|
|
626
657
|
exports.useCookies = useCookies;
|
|
658
|
+
exports.useMethod = useMethod;
|
|
627
659
|
exports.useQuery = useQuery;
|
|
628
660
|
exports.useRawBody = useRawBody;
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ declare type Handle<T = any> = (req: IncomingMessage, res: ServerResponse) => T;
|
|
|
7
7
|
declare type PHandle = Handle<Promise<any>>;
|
|
8
8
|
declare type Middleware = (req: IncomingMessage, res: ServerResponse, next: (err?: Error) => any) => any;
|
|
9
9
|
declare type LazyHandle = () => Handle | Promise<Handle>;
|
|
10
|
+
declare const defineHandle: <T>(handler: Handle<T>) => Handle<T>;
|
|
11
|
+
declare const defineMiddleware: (middleware: Middleware) => Middleware;
|
|
10
12
|
declare function promisifyHandle(handle: Handle | Middleware): PHandle;
|
|
11
13
|
declare function callHandle(handle: Middleware, req: IncomingMessage, res: ServerResponse): Promise<unknown>;
|
|
12
14
|
declare function lazyHandle(handle: LazyHandle, promisify?: boolean): PHandle;
|
|
@@ -46,7 +48,7 @@ interface AppOptions {
|
|
|
46
48
|
}
|
|
47
49
|
declare function createApp(options?: AppOptions): App;
|
|
48
50
|
declare function use(app: App, arg1: string | Handle | InputLayer | InputLayer[], arg2?: Handle | Partial<InputLayer> | Handle[] | Middleware | Middleware[], arg3?: Partial<InputLayer>): App;
|
|
49
|
-
declare function createHandle(stack: Stack): PHandle;
|
|
51
|
+
declare function createHandle(stack: Stack, options: AppOptions): PHandle;
|
|
50
52
|
|
|
51
53
|
/**
|
|
52
54
|
* H3 Runtime Error
|
|
@@ -84,20 +86,22 @@ declare function sendError(res: ServerResponse, error: Error | H3Error, debug?:
|
|
|
84
86
|
|
|
85
87
|
/**
|
|
86
88
|
* Reads body of the request and returns encoded raw string (default) or `Buffer` if encoding if falsy.
|
|
87
|
-
* @param req {IncomingMessage} An IncomingMessage object is created by
|
|
88
|
-
* <a href="https://nodejs.org/api/http.html#http_class_http_server">http.Server</a>
|
|
89
|
+
* @param req {IncomingMessage} An IncomingMessage object is created by [http.Server](https://nodejs.org/api/http.html#http_class_http_server)
|
|
89
90
|
* @param encoding {Encoding} encoding="utf-8" - The character encoding to use.
|
|
90
91
|
*
|
|
91
92
|
* @return {String|Buffer} Encoded raw string or raw Buffer of the body
|
|
92
93
|
*/
|
|
93
94
|
declare function useRawBody(req: IncomingMessage, encoding?: Encoding): Encoding extends false ? Buffer : Promise<string>;
|
|
94
95
|
/**
|
|
95
|
-
* Reads request body and try to safely parse using
|
|
96
|
-
* @param req {IncomingMessage} An IncomingMessage object
|
|
97
|
-
* <a href="https://nodejs.org/api/http.html#http_class_http_server">http.Server</a>
|
|
96
|
+
* Reads request body and try to safely parse using [destr](https://github.com/unjs/destr)
|
|
97
|
+
* @param req {IncomingMessage} An IncomingMessage object created by [http.Server](https://nodejs.org/api/http.html#http_class_http_server)
|
|
98
98
|
* @param encoding {Encoding} encoding="utf-8" - The character encoding to use.
|
|
99
99
|
*
|
|
100
|
-
* @return {*} The Object
|
|
100
|
+
* @return {*} The `Object`, `Array`, `String`, `Number`, `Boolean`, or `null` value corresponding to the request JSON body
|
|
101
|
+
*
|
|
102
|
+
* ```ts
|
|
103
|
+
* const body = await useBody(req)
|
|
104
|
+
* ```
|
|
101
105
|
*/
|
|
102
106
|
declare function useBody<T = any>(req: IncomingMessage): Promise<T>;
|
|
103
107
|
|
|
@@ -192,15 +196,46 @@ interface CookieSerializeOptions {
|
|
|
192
196
|
secure?: boolean;
|
|
193
197
|
}
|
|
194
198
|
|
|
199
|
+
/**
|
|
200
|
+
* Parse the request to get HTTP Cookie header string and returning an object of all cookie name-value pairs.
|
|
201
|
+
* @param req {IncomingMessage} An IncomingMessage object created by [http.Server](https://nodejs.org/api/http.html#http_class_http_server)
|
|
202
|
+
* @returns Object of cookie name-value pairs
|
|
203
|
+
* ```ts
|
|
204
|
+
* const cookies = useCookies(req)
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
195
207
|
declare function useCookies(req: IncomingMessage): Record<string, string>;
|
|
208
|
+
/**
|
|
209
|
+
* Get a cookie value by name.
|
|
210
|
+
* @param req {IncomingMessage} An IncomingMessage object created by [http.Server](https://nodejs.org/api/http.html#http_class_http_server)
|
|
211
|
+
* @param name Name of the cookie to get
|
|
212
|
+
* @returns {*} Value of the cookie (String or undefined)
|
|
213
|
+
* ```ts
|
|
214
|
+
* const authorization = useCookie(request, 'Authorization')
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
196
217
|
declare function useCookie(req: IncomingMessage, name: string): string | undefined;
|
|
197
|
-
|
|
218
|
+
/**
|
|
219
|
+
* Set a cookie value by name.
|
|
220
|
+
* @param res {ServerResponse} A ServerResponse object created by [http.Server](https://nodejs.org/api/http.html#http_class_http_server)
|
|
221
|
+
* @param name Name of the cookie to set
|
|
222
|
+
* @param value Value of the cookie to set
|
|
223
|
+
* @param serializeOptions {CookieSerializeOptions} Options for serializing the cookie
|
|
224
|
+
* ```ts
|
|
225
|
+
* setCookie(res, 'Authorization', '1234567')
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
declare function setCookie(res: ServerResponse, name: string, value: string, serializeOptions?: CookieSerializeOptions): void;
|
|
198
229
|
|
|
199
230
|
declare function useQuery(req: IncomingMessage): ufo.QueryObject;
|
|
231
|
+
declare type HTTPMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE';
|
|
232
|
+
declare function useMethod(req: IncomingMessage, defaultMethod?: HTTPMethod): HTTPMethod;
|
|
233
|
+
declare function isMethod(req: IncomingMessage, expected: HTTPMethod | HTTPMethod[], allowHead?: boolean): boolean;
|
|
234
|
+
declare function assertMethod(req: IncomingMessage, expected: HTTPMethod | HTTPMethod[], allowHead?: boolean): void;
|
|
200
235
|
|
|
201
236
|
declare function send(res: ServerResponse, data: any, type?: string): Promise<unknown>;
|
|
202
237
|
declare function defaultContentType(res: ServerResponse, type?: string): void;
|
|
203
238
|
declare function sendRedirect(res: ServerResponse, location: string, code?: number): Promise<unknown>;
|
|
204
239
|
declare function appendHeader(res: ServerResponse, name: string, value: string): void;
|
|
205
240
|
|
|
206
|
-
export { App, AppOptions, AppUse, H3Error, Handle, InputLayer, InputStack, Layer, LazyHandle, MIMES, Matcher, Middleware, PHandle, Stack, appendHeader, callHandle, createApp, createError, createHandle, defaultContentType, lazyHandle, promisifyHandle, send, sendError, sendRedirect, setCookie, use, useBase, useBody, useCookie, useCookies, useQuery, useRawBody };
|
|
241
|
+
export { App, AppOptions, AppUse, H3Error, HTTPMethod, Handle, InputLayer, InputStack, Layer, LazyHandle, MIMES, Matcher, Middleware, PHandle, Stack, appendHeader, assertMethod, callHandle, createApp, createError, createHandle, defaultContentType, defineHandle, defineMiddleware, isMethod, lazyHandle, promisifyHandle, send, sendError, sendRedirect, setCookie, use, useBase, useBody, useCookie, useCookies, useMethod, useQuery, useRawBody };
|
package/dist/index.mjs
CHANGED
|
@@ -79,8 +79,8 @@ function parseURL(input = "", defaultProto) {
|
|
|
79
79
|
return defaultProto ? parseURL(defaultProto + input) : parsePath(input);
|
|
80
80
|
}
|
|
81
81
|
const [protocol = "", auth, hostAndPath] = (input.match(/([^:/]+:)?\/\/([^/@]+@)?(.*)/) || []).splice(1);
|
|
82
|
-
const [host = "", path = ""] = (hostAndPath.match(/([
|
|
83
|
-
const {pathname, search, hash} = parsePath(path);
|
|
82
|
+
const [host = "", path = ""] = (hostAndPath.match(/([^/?]*)(.*)?/) || []).splice(1);
|
|
83
|
+
const { pathname, search, hash } = parsePath(path);
|
|
84
84
|
return {
|
|
85
85
|
protocol,
|
|
86
86
|
auth: auth ? auth.substr(0, auth.length - 1) : "",
|
|
@@ -99,6 +99,8 @@ function parsePath(input = "") {
|
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
const defineHandle = (handler) => handler;
|
|
103
|
+
const defineMiddleware = (middleware) => middleware;
|
|
102
104
|
function promisifyHandle(handle) {
|
|
103
105
|
return function(req, res) {
|
|
104
106
|
return callHandle(handle, req, res);
|
|
@@ -195,6 +197,9 @@ function useRawBody(req, encoding = "utf-8") {
|
|
|
195
197
|
if (req[RawBodySymbol]) {
|
|
196
198
|
return Promise.resolve(encoding ? req[RawBodySymbol].toString(encoding) : req[RawBodySymbol]);
|
|
197
199
|
}
|
|
200
|
+
if (req._body) {
|
|
201
|
+
return Promise.resolve(req._body);
|
|
202
|
+
}
|
|
198
203
|
return new Promise((resolve, reject) => {
|
|
199
204
|
const bodyData = [];
|
|
200
205
|
req.on("error", (err) => {
|
|
@@ -342,11 +347,7 @@ function serialize(name, val, options) {
|
|
|
342
347
|
|
|
343
348
|
if (null != opt.maxAge) {
|
|
344
349
|
var maxAge = opt.maxAge - 0;
|
|
345
|
-
|
|
346
|
-
if (isNaN(maxAge) || !isFinite(maxAge)) {
|
|
347
|
-
throw new TypeError('option maxAge is invalid')
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
+
if (isNaN(maxAge)) throw new Error('maxAge should be a Number');
|
|
350
351
|
str += '; Max-Age=' + Math.floor(maxAge);
|
|
351
352
|
}
|
|
352
353
|
|
|
@@ -471,6 +472,31 @@ function setCookie(res, name, value, serializeOptions) {
|
|
|
471
472
|
function useQuery(req) {
|
|
472
473
|
return getQuery(req.url || "");
|
|
473
474
|
}
|
|
475
|
+
function useMethod(req, defaultMethod = "GET") {
|
|
476
|
+
return (req.method || defaultMethod).toUpperCase();
|
|
477
|
+
}
|
|
478
|
+
function isMethod(req, expected, allowHead) {
|
|
479
|
+
const method = useMethod(req);
|
|
480
|
+
if (allowHead && method === "HEAD") {
|
|
481
|
+
return true;
|
|
482
|
+
}
|
|
483
|
+
if (typeof expected === "string") {
|
|
484
|
+
if (method === expected) {
|
|
485
|
+
return true;
|
|
486
|
+
}
|
|
487
|
+
} else if (expected.includes(method)) {
|
|
488
|
+
return true;
|
|
489
|
+
}
|
|
490
|
+
return false;
|
|
491
|
+
}
|
|
492
|
+
function assertMethod(req, expected, allowHead) {
|
|
493
|
+
if (!isMethod(req, expected, allowHead)) {
|
|
494
|
+
throw createError({
|
|
495
|
+
statusCode: 405,
|
|
496
|
+
statusMessage: "HTTP method is not allowed."
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
}
|
|
474
500
|
|
|
475
501
|
class H3Error extends Error {
|
|
476
502
|
constructor() {
|
|
@@ -524,7 +550,7 @@ function sendError(res, error, debug) {
|
|
|
524
550
|
|
|
525
551
|
function createApp(options = {}) {
|
|
526
552
|
const stack = [];
|
|
527
|
-
const _handle = createHandle(stack);
|
|
553
|
+
const _handle = createHandle(stack, options);
|
|
528
554
|
const app = function(req, res) {
|
|
529
555
|
return _handle(req, res).catch((error) => {
|
|
530
556
|
if (options.onError) {
|
|
@@ -552,7 +578,8 @@ function use(app, arg1, arg2, arg3) {
|
|
|
552
578
|
}
|
|
553
579
|
return app;
|
|
554
580
|
}
|
|
555
|
-
function createHandle(stack) {
|
|
581
|
+
function createHandle(stack, options) {
|
|
582
|
+
const spacing = options.debug ? 2 : void 0;
|
|
556
583
|
return async function handle(req, res) {
|
|
557
584
|
req.originalUrl = req.originalUrl || req.url || "/";
|
|
558
585
|
const reqUrl = req.url || "/";
|
|
@@ -581,7 +608,7 @@ function createHandle(stack) {
|
|
|
581
608
|
} else if (val instanceof Error) {
|
|
582
609
|
throw createError(val);
|
|
583
610
|
} else {
|
|
584
|
-
return send(res, JSON.stringify(val, null,
|
|
611
|
+
return send(res, JSON.stringify(val, null, spacing), MIMES.json);
|
|
585
612
|
}
|
|
586
613
|
}
|
|
587
614
|
}
|
|
@@ -601,4 +628,4 @@ function normalizeLayer(layer) {
|
|
|
601
628
|
};
|
|
602
629
|
}
|
|
603
630
|
|
|
604
|
-
export { H3Error, MIMES, appendHeader, callHandle, createApp, createError, createHandle, defaultContentType, lazyHandle, promisifyHandle, send, sendError, sendRedirect, setCookie, use, useBase, useBody, useCookie, useCookies, useQuery, useRawBody };
|
|
631
|
+
export { H3Error, MIMES, appendHeader, assertMethod, callHandle, createApp, createError, createHandle, defaultContentType, defineHandle, defineMiddleware, isMethod, lazyHandle, promisifyHandle, send, sendError, sendRedirect, setCookie, 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.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "Tiny JavaScript Server",
|
|
5
5
|
"repository": "unjs/h3",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"build": "siroc build",
|
|
22
22
|
"dev": "jiti test/playground",
|
|
23
23
|
"lint": "eslint --ext ts .",
|
|
24
|
-
"release": "yarn test && yarn build && standard-version && npm publish && git push --follow-tags",
|
|
25
24
|
"profile": "0x -o -D .profile -P 'autocannon -c 100 -p 10 -d 40 http://localhost:$PORT' ./hello.js",
|
|
25
|
+
"release": "yarn test && yarn build && standard-version && npm publish && git push --follow-tags",
|
|
26
26
|
"test": "yarn lint && jest"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
"@types/supertest": "latest",
|
|
36
36
|
"autocannon": "latest",
|
|
37
37
|
"connect": "latest",
|
|
38
|
-
"cookie": "latest",
|
|
38
|
+
"cookie-es": "latest",
|
|
39
39
|
"destr": "latest",
|
|
40
40
|
"eslint": "latest",
|
|
41
41
|
"express": "latest",
|
|
42
|
-
"get-port": "
|
|
42
|
+
"get-port": "^5.0.0",
|
|
43
43
|
"jest": "latest",
|
|
44
44
|
"jiti": "latest",
|
|
45
45
|
"listhen": "latest",
|
package/CHANGELOG.md
DELETED
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
|
-
|
|
5
|
-
### [0.3.1](https://github.com/unjs/h3/compare/v0.3.0...v0.3.1) (2021-09-09)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
### Bug Fixes
|
|
9
|
-
|
|
10
|
-
* return 'false' and 'null' values as JSON strings ([#33](https://github.com/unjs/h3/issues/33)) ([5613c54](https://github.com/unjs/h3/commit/5613c54e8a5d6681c29fa172f533381cf11a8fd3))
|
|
11
|
-
|
|
12
|
-
## [0.3.0](https://github.com/unjs/h3/compare/v0.2.12...v0.3.0) (2021-07-27)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
### ⚠ BREAKING CHANGES
|
|
16
|
-
|
|
17
|
-
* `useAsync` is removed. use `use` instead
|
|
18
|
-
|
|
19
|
-
### Features
|
|
20
|
-
|
|
21
|
-
* automatically promisify legacyMiddlware with `use` ([2805d4c](https://github.com/unjs/h3/commit/2805d4cc42d22c22c7798a41514aca5cceeb8e19)), closes [#27](https://github.com/unjs/h3/issues/27)
|
|
22
|
-
* handle returned errors (closes [#28](https://github.com/unjs/h3/issues/28)) ([991fcff](https://github.com/unjs/h3/commit/991fcff606b659035d5a23bd4ae97d3750e730cd))
|
|
23
|
-
|
|
24
|
-
### [0.2.12](https://github.com/unjs/h3/compare/v0.2.11...v0.2.12) (2021-07-02)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
### Features
|
|
28
|
-
|
|
29
|
-
* **pkg:** add exports field ([998d872](https://github.com/unjs/h3/commit/998d8723870650a742bdeefb57c1d9acfc407692))
|
|
30
|
-
|
|
31
|
-
### [0.2.11](https://github.com/unjs/h3/compare/v0.2.10...v0.2.11) (2021-06-23)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
### Bug Fixes
|
|
35
|
-
|
|
36
|
-
* createError fallback to statusMessage ([#25](https://github.com/unjs/h3/issues/25)) ([2f792f5](https://github.com/unjs/h3/commit/2f792f5cf64d87aeb41e387bae6cfad1112b3d05))
|
|
37
|
-
|
|
38
|
-
### [0.2.10](https://github.com/unjs/h3/compare/v0.2.9...v0.2.10) (2021-04-21)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
### Bug Fixes
|
|
42
|
-
|
|
43
|
-
* fallback for setImmediate ([6cf61f6](https://github.com/unjs/h3/commit/6cf61f601d206a9d3cdcf368cb700ebd5c2e22de))
|
|
44
|
-
|
|
45
|
-
### [0.2.9](https://github.com/unjs/h3/compare/v0.2.8...v0.2.9) (2021-04-06)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
### Bug Fixes
|
|
49
|
-
|
|
50
|
-
* resolve handle when send was called ([fb58e5b](https://github.com/unjs/h3/commit/fb58e5b274272ba55df4bb38b874a688b617d541))
|
|
51
|
-
|
|
52
|
-
### [0.2.8](https://github.com/unjs/h3/compare/v0.2.7...v0.2.8) (2021-03-27)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
### Bug Fixes
|
|
56
|
-
|
|
57
|
-
* **app:** custom options passed to useAsync ([3c328a4](https://github.com/unjs/h3/commit/3c328a4dc0dbc215d2da82cd0abc1e8ede006665))
|
|
58
|
-
|
|
59
|
-
### [0.2.7](https://github.com/unjs/h3/compare/v0.2.6...v0.2.7) (2021-03-27)
|
|
60
|
-
|
|
61
|
-
### [0.2.6](https://github.com/unjs/h3/compare/v0.2.5...v0.2.6) (2021-03-27)
|
|
62
|
-
|
|
63
|
-
### [0.2.5](https://github.com/unjs/h3/compare/v0.2.4...v0.2.5) (2021-02-19)
|
|
64
|
-
|
|
65
|
-
### [0.2.4](https://github.com/unjs/h3/compare/v0.2.3...v0.2.4) (2021-01-22)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
### Bug Fixes
|
|
69
|
-
|
|
70
|
-
* always restore req.url for each layer to avoid mutation ([aae5787](https://github.com/unjs/h3/commit/aae57876a1bad3972bec86cee385db308ac69764))
|
|
71
|
-
|
|
72
|
-
### [0.2.3](https://github.com/unjs/h3/compare/v0.2.2...v0.2.3) (2021-01-20)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
### Bug Fixes
|
|
76
|
-
|
|
77
|
-
* improve internal error handling ([b38d450](https://github.com/unjs/h3/commit/b38d450e39101104333f33516d75869cd2427f9d))
|
|
78
|
-
|
|
79
|
-
### [0.2.2](https://github.com/unjs/h3/compare/v0.2.1...v0.2.2) (2021-01-20)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
### Bug Fixes
|
|
83
|
-
|
|
84
|
-
* capture stacktrace from createError ([1441784](https://github.com/unjs/h3/commit/14417846554f81f44ae677bfd609517dcfd3c291))
|
|
85
|
-
* handle thrown errors by each layer ([62fd25a](https://github.com/unjs/h3/commit/62fd25a572de72a1f555b8f43e5e4798c392b74b))
|
|
86
|
-
|
|
87
|
-
### [0.2.1](https://github.com/unjs/h3/compare/v0.2.0...v0.2.1) (2021-01-12)
|
|
88
|
-
|
|
89
|
-
## [0.2.0](https://github.com/unjs/h3/compare/v0.0.15...v0.2.0) (2020-12-15)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
### ⚠ BREAKING CHANGES
|
|
93
|
-
|
|
94
|
-
* rename useBodyJSON to useBody and unexposed cached value
|
|
95
|
-
|
|
96
|
-
### Features
|
|
97
|
-
|
|
98
|
-
* `useCookie`, `useCookies` and `setCookie` utilities ([088f413](https://github.com/unjs/h3/commit/088f413434a619a9888bfd9d1b189e56a7d00124)), closes [#17](https://github.com/unjs/h3/issues/17)
|
|
99
|
-
* appendHeader utility ([84be904](https://github.com/unjs/h3/commit/84be9040e2c52b625a47591e8f5107793da29f72))
|
|
100
|
-
* rename useBodyJSON to useBody and unexposed cached value ([d8d39a0](https://github.com/unjs/h3/commit/d8d39a0eefbc22c8d3af8e7dcee5ee8964da07e3))
|
|
101
|
-
|
|
102
|
-
### [0.0.15](https://github.com/unjs/h3/compare/v0.0.14...v0.0.15) (2020-12-12)
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
### Features
|
|
106
|
-
|
|
107
|
-
* add request and response utils ([#15](https://github.com/unjs/h3/issues/15)) ([648e9b9](https://github.com/unjs/h3/commit/648e9b9ceff3a8658a7e3705164d5139e6f95c99))
|
|
108
|
-
* custom error handler ([ad3515f](https://github.com/unjs/h3/commit/ad3515f0da8bb37d3f82a6527c459aa86a63e338))
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
### Bug Fixes
|
|
112
|
-
|
|
113
|
-
* don't override internal flag ([a5ee318](https://github.com/unjs/h3/commit/a5ee31888101cbe7458d7a63527d0cf07845d2a6))
|
|
114
|
-
* hide 404 error ([38fb027](https://github.com/unjs/h3/commit/38fb027bb5a2d3d369f7d3e333edc1342cf32914))
|
|
115
|
-
* preserve error message in console ([3002b27](https://github.com/unjs/h3/commit/3002b27aace50cf6d39c289b8500bb92a065fe7a))
|
|
116
|
-
|
|
117
|
-
### [0.0.14](https://github.com/unjs/h3/compare/v0.0.13...v0.0.14) (2020-12-05)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
### Bug Fixes
|
|
121
|
-
|
|
122
|
-
* **app:** handle buffer ([09c9c6d](https://github.com/unjs/h3/commit/09c9c6da5bcd00ff49e815cae3c74893d4b4806d))
|
|
123
|
-
* **utils:** avoid setting falsy type ([df5e92b](https://github.com/unjs/h3/commit/df5e92b07ca2c096fb078c0deff50b613245c0db))
|
|
124
|
-
|
|
125
|
-
### [0.0.13](https://github.com/unjs/h3/compare/v0.0.12...v0.0.13) (2020-12-05)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
### Bug Fixes
|
|
129
|
-
|
|
130
|
-
* enable debug by default ([010cdfe](https://github.com/unjs/h3/commit/010cdfe32ce80b2453489f8839c5f3d946d027a1))
|
|
131
|
-
|
|
132
|
-
### [0.0.12](https://github.com/unjs/h3/compare/v0.0.11...v0.0.12) (2020-11-23)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
### Features
|
|
136
|
-
|
|
137
|
-
* allow chaining use statements ([#9](https://github.com/unjs/h3/issues/9)) ([e30ea79](https://github.com/unjs/h3/commit/e30ea7911ed378866f2c61b0ece3f332e113e821)), closes [#5](https://github.com/unjs/h3/issues/5)
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
### Bug Fixes
|
|
141
|
-
|
|
142
|
-
* correctly expose route and middleware types ([#10](https://github.com/unjs/h3/issues/10)) ([bb6cd4c](https://github.com/unjs/h3/commit/bb6cd4c6971fc269d6a313ebc07910898b32f178)), closes [#11](https://github.com/unjs/h3/issues/11) [#11](https://github.com/unjs/h3/issues/11)
|
|
143
|
-
* ensure correct url is used when used as a sub-app ([0e4770a](https://github.com/unjs/h3/commit/0e4770af89757c274b1d3e6d7c54b973a7bf9bef))
|
|
144
|
-
* mark app._handle as private to avoid sub-app detection ([1439f35](https://github.com/unjs/h3/commit/1439f354a7e9238113f6d8bc7687df8a5fe7bd10))
|
|
145
|
-
|
|
146
|
-
### [0.0.11](https://github.com/unjs/h3/compare/v0.0.10...v0.0.11) (2020-11-21)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
### Features
|
|
150
|
-
|
|
151
|
-
* `useAsync` ([236e979](https://github.com/unjs/h3/commit/236e97953ac014dffa8977c4bf8cd6f2fa369eb7))
|
|
152
|
-
* custom matcher and improved docs ([1c4f9d1](https://github.com/unjs/h3/commit/1c4f9d138dde212486d1aa7acb0e2df9a8cb8aca))
|
|
153
|
-
|
|
154
|
-
### [0.0.10](https://github.com/unjs/h3/compare/v0.0.9...v0.0.10) (2020-11-20)
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
### Features
|
|
158
|
-
|
|
159
|
-
* rewrite with much sexier API ([0d3680e](https://github.com/unjs/h3/commit/0d3680eacab44d6a40c10b94cfba2036afc571d9))
|
|
160
|
-
|
|
161
|
-
### [0.0.9](https://github.com/unjs/h3/compare/v0.0.8...v0.0.9) (2020-11-20)
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
### Features
|
|
165
|
-
|
|
166
|
-
* createError ([1a80bd9](https://github.com/unjs/h3/commit/1a80bd9432b0585a474d6888e7035636307eead8))
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
### Bug Fixes
|
|
170
|
-
|
|
171
|
-
* throw 404 only when writableEnded is not set ([1c42a07](https://github.com/unjs/h3/commit/1c42a07e3ecc175c96dff026967298a107314f5e))
|
|
172
|
-
|
|
173
|
-
### [0.0.8](https://github.com/unjs/h3/compare/v0.0.7...v0.0.8) (2020-11-19)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
### Bug Fixes
|
|
177
|
-
|
|
178
|
-
* don't log 404 ([541ede0](https://github.com/unjs/h3/commit/541ede03edc6526b953c8a0bb7f31f0dc5fc21d3))
|
|
179
|
-
|
|
180
|
-
### [0.0.7](https://github.com/unjs/h3/compare/v0.0.6...v0.0.7) (2020-11-19)
|
|
181
|
-
|
|
182
|
-
### [0.0.6](https://github.com/unjs/h3/compare/v0.0.5...v0.0.6) (2020-11-19)
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
### Features
|
|
186
|
-
|
|
187
|
-
* add debug option to app ([b0891cd](https://github.com/unjs/h3/commit/b0891cd13d4a7b8ed0fb981ae878185c6728b618))
|
|
188
|
-
|
|
189
|
-
### [0.0.5](https://github.com/unjs/h3/compare/v0.0.4...v0.0.5) (2020-11-19)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
### Features
|
|
193
|
-
|
|
194
|
-
* expose unsafeHandle ([f1245f1](https://github.com/unjs/h3/commit/f1245f13c1a4ec1f9e1ecb4b0b73c50047ee4d3a))
|
|
195
|
-
|
|
196
|
-
### [0.0.4](https://github.com/unjs/h3/compare/v0.0.3...v0.0.4) (2020-11-19)
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
### Features
|
|
200
|
-
|
|
201
|
-
* rewrite promisify logic ([a40aa81](https://github.com/unjs/h3/commit/a40aa81aa80da3ba418061338bcaa6286357ab67))
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
### Bug Fixes
|
|
205
|
-
|
|
206
|
-
* keep top level trailing slash ([2fb92ef](https://github.com/unjs/h3/commit/2fb92efdf462f3c4098af3cac6594599839f7cde))
|
|
207
|
-
* stop middleware when writableEnded flag is set ([d87d8e5](https://github.com/unjs/h3/commit/d87d8e5f7a426409565d1a008b8231c793ec61ef))
|
|
208
|
-
|
|
209
|
-
### [0.0.3](https://github.com/unjs/h3/compare/v0.0.2...v0.0.3) (2020-11-19)
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
### Features
|
|
213
|
-
|
|
214
|
-
* improve error util ([5504f4e](https://github.com/unjs/h3/commit/5504f4e53dfb19cceb6580b00077f8c80d0b5dc5))
|
|
215
|
-
|
|
216
|
-
### [0.0.2](https://github.com/unjs/h3/compare/v0.0.1...v0.0.2) (2020-11-19)
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
### Bug Fixes
|
|
220
|
-
|
|
221
|
-
* remove dependency on process.env ([eb018f5](https://github.com/unjs/h3/commit/eb018f5e23a5f797a4b5d24fdbfe591994c39aef))
|
|
222
|
-
|
|
223
|
-
### 0.0.1 (2020-11-18)
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
### Features
|
|
227
|
-
|
|
228
|
-
* de-default loazy handles ([0cb8c0c](https://github.com/unjs/h3/commit/0cb8c0c74647278806a53f7920f8678bb47749e5))
|
|
229
|
-
* update docs and caller utility ([0ef0020](https://github.com/unjs/h3/commit/0ef0020da1931b8c08344008253703b91b318559))
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
### Bug Fixes
|
|
233
|
-
|
|
234
|
-
* **app:** handle returning promise ([2169f92](https://github.com/unjs/h3/commit/2169f92142d2e92e143913fff945628f17203779))
|
|
235
|
-
* **writable:** set writableEnded and writableFinished ([7058fdc](https://github.com/unjs/h3/commit/7058fdcf38a31edd1ce2afe4b05eb0b050adea78))
|