h3 0.8.3 → 0.8.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 +1 -1
- package/dist/index.cjs +16 -15
- package/dist/index.d.ts +6 -3
- package/dist/index.mjs +16 -15
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -101,7 +101,7 @@ app.use('/1', eventHandler(() => '<h1>Hello world!</h1>'))
|
|
|
101
101
|
.use('/2', eventHandler(() => '<h1>Goodbye!</h1>'))
|
|
102
102
|
|
|
103
103
|
// Legacy middleware with 3rd argument are automatically promisified
|
|
104
|
-
app.use(fromNodeMiddleware((req, res, next) => { req.setHeader('
|
|
104
|
+
app.use(fromNodeMiddleware((req, res, next) => { req.setHeader('x-foo', 'bar'); next() }))
|
|
105
105
|
|
|
106
106
|
// Lazy loaded routes using { lazy: true }
|
|
107
107
|
app.use('/big', () => import('./big-handler'), { lazy: true })
|
package/dist/index.cjs
CHANGED
|
@@ -88,7 +88,7 @@ function sendError(event, error, debug) {
|
|
|
88
88
|
if (h3Error.statusMessage) {
|
|
89
89
|
event.res.statusMessage = h3Error.statusMessage;
|
|
90
90
|
}
|
|
91
|
-
event.res.setHeader("
|
|
91
|
+
event.res.setHeader("content-type", MIMES.json);
|
|
92
92
|
event.res.end(JSON.stringify(responseBody, null, 2));
|
|
93
93
|
}
|
|
94
94
|
function isError(input) {
|
|
@@ -133,7 +133,12 @@ function assertMethod(event, expected, allowHead) {
|
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
function getRequestHeaders(event) {
|
|
136
|
-
|
|
136
|
+
const _headers = {};
|
|
137
|
+
for (const key in event.req.headers) {
|
|
138
|
+
const val = event.req.headers[key];
|
|
139
|
+
_headers[key] = Array.isArray(val) ? val.filter(Boolean).join(", ") : val;
|
|
140
|
+
}
|
|
141
|
+
return _headers;
|
|
137
142
|
}
|
|
138
143
|
const getHeaders = getRequestHeaders;
|
|
139
144
|
function getRequestHeader(event, name) {
|
|
@@ -195,7 +200,7 @@ function handleCacheHeaders(event, opts) {
|
|
|
195
200
|
if (opts.modifiedTime) {
|
|
196
201
|
const modifiedTime = new Date(opts.modifiedTime);
|
|
197
202
|
const ifModifiedSince = event.req.headers["if-modified-since"];
|
|
198
|
-
event.res.setHeader("
|
|
203
|
+
event.res.setHeader("last-modified", modifiedTime.toUTCString());
|
|
199
204
|
if (ifModifiedSince) {
|
|
200
205
|
if (new Date(ifModifiedSince) >= opts.modifiedTime) {
|
|
201
206
|
cacheMatched = true;
|
|
@@ -203,16 +208,16 @@ function handleCacheHeaders(event, opts) {
|
|
|
203
208
|
}
|
|
204
209
|
}
|
|
205
210
|
if (opts.etag) {
|
|
206
|
-
event.res.setHeader("
|
|
211
|
+
event.res.setHeader("etag", opts.etag);
|
|
207
212
|
const ifNonMatch = event.req.headers["if-none-match"];
|
|
208
213
|
if (ifNonMatch === opts.etag) {
|
|
209
214
|
cacheMatched = true;
|
|
210
215
|
}
|
|
211
216
|
}
|
|
212
|
-
event.res.setHeader("
|
|
217
|
+
event.res.setHeader("cache-control", cacheControls.join(", "));
|
|
213
218
|
if (cacheMatched) {
|
|
214
219
|
event.res.statusCode = 304;
|
|
215
|
-
event.res.end(
|
|
220
|
+
event.res.end();
|
|
216
221
|
return true;
|
|
217
222
|
}
|
|
218
223
|
return false;
|
|
@@ -236,13 +241,13 @@ function send(event, data, type) {
|
|
|
236
241
|
});
|
|
237
242
|
}
|
|
238
243
|
function defaultContentType(event, type) {
|
|
239
|
-
if (type && !event.res.getHeader("
|
|
240
|
-
event.res.setHeader("
|
|
244
|
+
if (type && !event.res.getHeader("content-type")) {
|
|
245
|
+
event.res.setHeader("content-type", type);
|
|
241
246
|
}
|
|
242
247
|
}
|
|
243
248
|
function sendRedirect(event, location, code = 302) {
|
|
244
249
|
event.res.statusCode = code;
|
|
245
|
-
event.res.setHeader("
|
|
250
|
+
event.res.setHeader("location", location);
|
|
246
251
|
const encodedLoc = location.replace(/"/g, "%22");
|
|
247
252
|
const html = `<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${encodedLoc}"></head></html>`;
|
|
248
253
|
return send(event, html, MIMES.html);
|
|
@@ -290,7 +295,7 @@ function sendStream(event, data) {
|
|
|
290
295
|
const noop = () => {
|
|
291
296
|
};
|
|
292
297
|
function writeEarlyHints(event, hints, cb = noop) {
|
|
293
|
-
if (!event.res.socket
|
|
298
|
+
if (!event.res.socket) {
|
|
294
299
|
cb();
|
|
295
300
|
return;
|
|
296
301
|
}
|
|
@@ -299,10 +304,6 @@ function writeEarlyHints(event, hints, cb = noop) {
|
|
|
299
304
|
}
|
|
300
305
|
if (hints.link) {
|
|
301
306
|
hints.link = Array.isArray(hints.link) ? hints.link : hints.link.split(",");
|
|
302
|
-
hints.link = hints.link.map((l) => l.trim().replace(/; crossorigin/g, ""));
|
|
303
|
-
}
|
|
304
|
-
if ("writeEarlyHints" in event.res) {
|
|
305
|
-
return event.res.writeEarlyHints(hints, cb);
|
|
306
307
|
}
|
|
307
308
|
const headers = Object.entries(hints).map((e) => [e[0].toLowerCase(), e[1]]);
|
|
308
309
|
if (!headers.length) {
|
|
@@ -441,7 +442,7 @@ class H3Event {
|
|
|
441
442
|
this.res.statusMessage = response.statusText;
|
|
442
443
|
}
|
|
443
444
|
if (response.redirected) {
|
|
444
|
-
this.res.setHeader("
|
|
445
|
+
this.res.setHeader("location", response.url);
|
|
445
446
|
}
|
|
446
447
|
if (!response._body) {
|
|
447
448
|
return this.res.end();
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,9 @@ interface EventHandler<T = any> {
|
|
|
13
13
|
(event: H3Event): EventHandlerResponse<T>;
|
|
14
14
|
}
|
|
15
15
|
declare type LazyEventHandler = () => EventHandler | Promise<EventHandler>;
|
|
16
|
+
declare type RequestHeaders = {
|
|
17
|
+
[name: string]: string | undefined;
|
|
18
|
+
};
|
|
16
19
|
|
|
17
20
|
declare type NodeListener = (req: IncomingMessage, res: ServerResponse) => void;
|
|
18
21
|
declare type NodePromisifiedHandler = (req: IncomingMessage, res: ServerResponse) => Promise<any>;
|
|
@@ -250,9 +253,9 @@ declare function getMethod(event: H3Event, defaultMethod?: HTTPMethod): HTTPMeth
|
|
|
250
253
|
declare const useMethod: typeof getMethod;
|
|
251
254
|
declare function isMethod(event: H3Event, expected: HTTPMethod | HTTPMethod[], allowHead?: boolean): boolean;
|
|
252
255
|
declare function assertMethod(event: H3Event, expected: HTTPMethod | HTTPMethod[], allowHead?: boolean): void;
|
|
253
|
-
declare function getRequestHeaders(event: H3Event):
|
|
256
|
+
declare function getRequestHeaders(event: H3Event): RequestHeaders;
|
|
254
257
|
declare const getHeaders: typeof getRequestHeaders;
|
|
255
|
-
declare function getRequestHeader(event: H3Event, name: string):
|
|
258
|
+
declare function getRequestHeader(event: H3Event, name: string): RequestHeaders[string];
|
|
256
259
|
declare const getHeader: typeof getRequestHeader;
|
|
257
260
|
|
|
258
261
|
declare function send(event: H3Event, data?: any, type?: string): Promise<void>;
|
|
@@ -285,4 +288,4 @@ interface CreateRouterOptions {
|
|
|
285
288
|
}
|
|
286
289
|
declare function createRouter(opts?: CreateRouterOptions): Router;
|
|
287
290
|
|
|
288
|
-
export { AddRouteShortcuts, App, AppOptions, AppUse, CacheConditions, CreateRouterOptions, DynamicEventHandler, Encoding, EventHandler, EventHandlerResponse, H3Error, H3Event, H3EventContext, H3Headers, H3Response, HTTPMethod, InputLayer, InputStack, Layer, LazyEventHandler, MIMES, Matcher, NodeListener, NodeMiddleware, NodePromisifiedHandler, Router, RouterMethod, RouterUse, Stack, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, deleteCookie, dynamicEventHandler, eventHandler, fromNodeMiddleware, getCookie, getHeader, getHeaders, getMethod, getQuery, getRequestHeader, getRequestHeaders, getResponseHeader, getResponseHeaders, getRouterParam, getRouterParams, handleCacheHeaders, isError, isEvent, isEventHandler, isMethod, isStream, lazyEventHandler, parseCookies, promisifyNodeListener, readBody, readRawBody, send, sendError, sendRedirect, sendStream, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, toEventHandler, toNodeListener, use, useBase, useBody, useCookie, useCookies, useMethod, useQuery, useRawBody, writeEarlyHints };
|
|
291
|
+
export { AddRouteShortcuts, App, AppOptions, AppUse, CacheConditions, CreateRouterOptions, DynamicEventHandler, Encoding, EventHandler, EventHandlerResponse, H3Error, H3Event, H3EventContext, H3Headers, H3Response, HTTPMethod, InputLayer, InputStack, Layer, LazyEventHandler, MIMES, Matcher, NodeListener, NodeMiddleware, NodePromisifiedHandler, RequestHeaders, Router, RouterMethod, RouterUse, Stack, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, deleteCookie, dynamicEventHandler, eventHandler, fromNodeMiddleware, getCookie, getHeader, getHeaders, getMethod, getQuery, getRequestHeader, getRequestHeaders, getResponseHeader, getResponseHeaders, getRouterParam, getRouterParams, handleCacheHeaders, isError, isEvent, isEventHandler, isMethod, isStream, lazyEventHandler, parseCookies, promisifyNodeListener, readBody, readRawBody, send, sendError, sendRedirect, sendStream, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, toEventHandler, toNodeListener, use, useBase, useBody, useCookie, useCookies, useMethod, useQuery, useRawBody, writeEarlyHints };
|
package/dist/index.mjs
CHANGED
|
@@ -86,7 +86,7 @@ function sendError(event, error, debug) {
|
|
|
86
86
|
if (h3Error.statusMessage) {
|
|
87
87
|
event.res.statusMessage = h3Error.statusMessage;
|
|
88
88
|
}
|
|
89
|
-
event.res.setHeader("
|
|
89
|
+
event.res.setHeader("content-type", MIMES.json);
|
|
90
90
|
event.res.end(JSON.stringify(responseBody, null, 2));
|
|
91
91
|
}
|
|
92
92
|
function isError(input) {
|
|
@@ -131,7 +131,12 @@ function assertMethod(event, expected, allowHead) {
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
function getRequestHeaders(event) {
|
|
134
|
-
|
|
134
|
+
const _headers = {};
|
|
135
|
+
for (const key in event.req.headers) {
|
|
136
|
+
const val = event.req.headers[key];
|
|
137
|
+
_headers[key] = Array.isArray(val) ? val.filter(Boolean).join(", ") : val;
|
|
138
|
+
}
|
|
139
|
+
return _headers;
|
|
135
140
|
}
|
|
136
141
|
const getHeaders = getRequestHeaders;
|
|
137
142
|
function getRequestHeader(event, name) {
|
|
@@ -193,7 +198,7 @@ function handleCacheHeaders(event, opts) {
|
|
|
193
198
|
if (opts.modifiedTime) {
|
|
194
199
|
const modifiedTime = new Date(opts.modifiedTime);
|
|
195
200
|
const ifModifiedSince = event.req.headers["if-modified-since"];
|
|
196
|
-
event.res.setHeader("
|
|
201
|
+
event.res.setHeader("last-modified", modifiedTime.toUTCString());
|
|
197
202
|
if (ifModifiedSince) {
|
|
198
203
|
if (new Date(ifModifiedSince) >= opts.modifiedTime) {
|
|
199
204
|
cacheMatched = true;
|
|
@@ -201,16 +206,16 @@ function handleCacheHeaders(event, opts) {
|
|
|
201
206
|
}
|
|
202
207
|
}
|
|
203
208
|
if (opts.etag) {
|
|
204
|
-
event.res.setHeader("
|
|
209
|
+
event.res.setHeader("etag", opts.etag);
|
|
205
210
|
const ifNonMatch = event.req.headers["if-none-match"];
|
|
206
211
|
if (ifNonMatch === opts.etag) {
|
|
207
212
|
cacheMatched = true;
|
|
208
213
|
}
|
|
209
214
|
}
|
|
210
|
-
event.res.setHeader("
|
|
215
|
+
event.res.setHeader("cache-control", cacheControls.join(", "));
|
|
211
216
|
if (cacheMatched) {
|
|
212
217
|
event.res.statusCode = 304;
|
|
213
|
-
event.res.end(
|
|
218
|
+
event.res.end();
|
|
214
219
|
return true;
|
|
215
220
|
}
|
|
216
221
|
return false;
|
|
@@ -234,13 +239,13 @@ function send(event, data, type) {
|
|
|
234
239
|
});
|
|
235
240
|
}
|
|
236
241
|
function defaultContentType(event, type) {
|
|
237
|
-
if (type && !event.res.getHeader("
|
|
238
|
-
event.res.setHeader("
|
|
242
|
+
if (type && !event.res.getHeader("content-type")) {
|
|
243
|
+
event.res.setHeader("content-type", type);
|
|
239
244
|
}
|
|
240
245
|
}
|
|
241
246
|
function sendRedirect(event, location, code = 302) {
|
|
242
247
|
event.res.statusCode = code;
|
|
243
|
-
event.res.setHeader("
|
|
248
|
+
event.res.setHeader("location", location);
|
|
244
249
|
const encodedLoc = location.replace(/"/g, "%22");
|
|
245
250
|
const html = `<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${encodedLoc}"></head></html>`;
|
|
246
251
|
return send(event, html, MIMES.html);
|
|
@@ -288,7 +293,7 @@ function sendStream(event, data) {
|
|
|
288
293
|
const noop = () => {
|
|
289
294
|
};
|
|
290
295
|
function writeEarlyHints(event, hints, cb = noop) {
|
|
291
|
-
if (!event.res.socket
|
|
296
|
+
if (!event.res.socket) {
|
|
292
297
|
cb();
|
|
293
298
|
return;
|
|
294
299
|
}
|
|
@@ -297,10 +302,6 @@ function writeEarlyHints(event, hints, cb = noop) {
|
|
|
297
302
|
}
|
|
298
303
|
if (hints.link) {
|
|
299
304
|
hints.link = Array.isArray(hints.link) ? hints.link : hints.link.split(",");
|
|
300
|
-
hints.link = hints.link.map((l) => l.trim().replace(/; crossorigin/g, ""));
|
|
301
|
-
}
|
|
302
|
-
if ("writeEarlyHints" in event.res) {
|
|
303
|
-
return event.res.writeEarlyHints(hints, cb);
|
|
304
305
|
}
|
|
305
306
|
const headers = Object.entries(hints).map((e) => [e[0].toLowerCase(), e[1]]);
|
|
306
307
|
if (!headers.length) {
|
|
@@ -439,7 +440,7 @@ class H3Event {
|
|
|
439
440
|
this.res.statusMessage = response.statusText;
|
|
440
441
|
}
|
|
441
442
|
if (response.redirected) {
|
|
442
|
-
this.res.setHeader("
|
|
443
|
+
this.res.setHeader("location", response.url);
|
|
443
444
|
}
|
|
444
445
|
if (!response._body) {
|
|
445
446
|
return this.res.end();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "h3",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.5",
|
|
4
4
|
"description": "Tiny JavaScript Server",
|
|
5
5
|
"repository": "unjs/h3",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"cookie-es": "^0.5.0",
|
|
24
|
-
"destr": "^1.
|
|
24
|
+
"destr": "^1.2.0",
|
|
25
25
|
"radix3": "^0.2.1",
|
|
26
26
|
"ufo": "^0.8.6"
|
|
27
27
|
},
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"lint": "eslint --ext ts,mjs,cjs .",
|
|
53
53
|
"play": "jiti ./playground/index.ts",
|
|
54
54
|
"profile": "0x -o -D .profile -P 'autocannon -c 100 -p 10 -d 40 http://localhost:$PORT' ./playground/server.cjs",
|
|
55
|
-
"release": "pnpm test && pnpm
|
|
55
|
+
"release": "pnpm test && pnpm build && changelogen --release && pnpm publish && git push --follow-tags",
|
|
56
56
|
"test": "pnpm lint && vitest run --coverage"
|
|
57
57
|
}
|
|
58
58
|
}
|