nitropack-nightly 2.11.2-20250305-192721.72225800 → 2.11.3-20250306-104907.06147e7a
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/dist/core/index.mjs +79 -82
- package/dist/kit/index.d.mts +1 -1
- package/dist/kit/index.d.ts +1 -1
- package/dist/meta/index.d.mts +1 -1
- package/dist/meta/index.d.ts +1 -1
- package/dist/meta/index.mjs +1 -1
- package/dist/rollup/index.mjs +7 -1
- package/dist/runtime/internal/error/dev.d.ts +6 -0
- package/dist/runtime/internal/error/dev.mjs +74 -67
- package/dist/runtime/internal/error/prod.d.ts +6 -0
- package/dist/runtime/internal/error/prod.mjs +58 -49
- package/dist/runtime/internal/error/utils.d.ts +6 -2
- package/dist/runtime/internal/error/utils.mjs +0 -17
- package/dist/shared/{nitro.0NUDI83a.d.mts → nitro.JLO839lv.d.mts} +12 -1
- package/dist/shared/{nitro.0NUDI83a.d.ts → nitro.JLO839lv.d.ts} +12 -1
- package/dist/types/index.d.mts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/package.json +4 -4
package/dist/core/index.mjs
CHANGED
|
@@ -40,7 +40,7 @@ import { gzipSize } from 'gzip-size';
|
|
|
40
40
|
import prettyBytes from 'pretty-bytes';
|
|
41
41
|
import zlib from 'node:zlib';
|
|
42
42
|
import { walk, parse } from 'ultrahtml';
|
|
43
|
-
import { createError,
|
|
43
|
+
import { createError, getRequestURL, getRequestHeader, getResponseHeader, getRequestHeaders, setResponseHeaders, setResponseStatus, send, eventHandler, getRequestIP, toNodeListener, createApp, fromNodeMiddleware } from 'h3';
|
|
44
44
|
import { Worker } from 'node:worker_threads';
|
|
45
45
|
import { createProxyServer } from 'httpxy';
|
|
46
46
|
import { resolve as resolve$1, dirname as dirname$1 } from 'node:path';
|
|
@@ -2364,10 +2364,9 @@ class NodeDevWorker {
|
|
|
2364
2364
|
await new Promise((resolve) => {
|
|
2365
2365
|
const gracefulShutdownTimeoutSec = Number.parseInt(process.env.NITRO_SHUTDOWN_TIMEOUT || "", 10) || 5;
|
|
2366
2366
|
const timeout = setTimeout(() => {
|
|
2367
|
-
|
|
2368
|
-
`force closing dev worker
|
|
2369
|
-
|
|
2370
|
-
resolve();
|
|
2367
|
+
if (process.env.DEBUG) {
|
|
2368
|
+
consola.warn(`force closing dev worker...`);
|
|
2369
|
+
}
|
|
2371
2370
|
}, gracefulShutdownTimeoutSec * 1e3);
|
|
2372
2371
|
this.#worker?.on("message", (message) => {
|
|
2373
2372
|
if (message.event === "exit") {
|
|
@@ -2392,88 +2391,84 @@ class NodeDevWorker {
|
|
|
2392
2391
|
function defineNitroErrorHandler(handler) {
|
|
2393
2392
|
return handler;
|
|
2394
2393
|
}
|
|
2395
|
-
function setSecurityHeaders(event, allowjs = false) {
|
|
2396
|
-
setResponseHeaders(event, {
|
|
2397
|
-
// Prevent browser from guessing the MIME types of resources.
|
|
2398
|
-
"X-Content-Type-Options": "nosniff",
|
|
2399
|
-
// Prevent error page from being embedded in an iframe
|
|
2400
|
-
"X-Frame-Options": "DENY",
|
|
2401
|
-
// Prevent browsers from sending the Referer header
|
|
2402
|
-
"Referrer-Policy": "no-referrer",
|
|
2403
|
-
// Disable the execution of any js
|
|
2404
|
-
"Content-Security-Policy": allowjs ? "script-src 'self' 'unsafe-inline'; object-src 'none'; base-uri 'self';" : "script-src 'none'; frame-ancestors 'none';"
|
|
2405
|
-
});
|
|
2406
|
-
}
|
|
2407
2394
|
|
|
2408
|
-
const
|
|
2395
|
+
const devErrorHandler = defineNitroErrorHandler(
|
|
2409
2396
|
async function defaultNitroErrorHandler(error, event) {
|
|
2410
|
-
const
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
if (statusCode === 404) {
|
|
2415
|
-
const baseURL = import.meta.baseURL || "/";
|
|
2416
|
-
if (/^\/[^/]/.test(baseURL) && !url.pathname.startsWith(baseURL)) {
|
|
2417
|
-
return sendRedirect(
|
|
2418
|
-
event,
|
|
2419
|
-
`${baseURL}${url.pathname.slice(1)}${url.search}`
|
|
2420
|
-
);
|
|
2421
|
-
}
|
|
2422
|
-
}
|
|
2423
|
-
await loadStackTrace(error).catch(consola.error);
|
|
2424
|
-
const youch = new Youch();
|
|
2425
|
-
if (isSensitive) {
|
|
2426
|
-
const tags = [error.unhandled && "[unhandled]", error.fatal && "[fatal]"].filter(Boolean).join(" ");
|
|
2427
|
-
const columns = process.stderr.columns;
|
|
2428
|
-
const ansiError = await (await youch.toANSI(error)).replaceAll(process.cwd(), ".");
|
|
2429
|
-
if (!columns) {
|
|
2430
|
-
process.stderr.columns = columns;
|
|
2431
|
-
}
|
|
2432
|
-
consola.error(
|
|
2433
|
-
`[request error] ${tags} [${event.method}] ${url}
|
|
2434
|
-
|
|
2435
|
-
`,
|
|
2436
|
-
ansiError
|
|
2437
|
-
);
|
|
2438
|
-
}
|
|
2439
|
-
setResponseStatus(event, statusCode, statusMessage);
|
|
2440
|
-
setSecurityHeaders(
|
|
2397
|
+
const res = await defaultHandler(error, event);
|
|
2398
|
+
setResponseHeaders(event, res.headers);
|
|
2399
|
+
setResponseStatus(event, res.status, res.statusText);
|
|
2400
|
+
return send(
|
|
2441
2401
|
event,
|
|
2442
|
-
|
|
2443
|
-
/* allow js */
|
|
2402
|
+
typeof res.body === "string" ? res.body : JSON.stringify(res.body, null, 2)
|
|
2444
2403
|
);
|
|
2445
|
-
|
|
2446
|
-
|
|
2404
|
+
}
|
|
2405
|
+
);
|
|
2406
|
+
async function defaultHandler(error, event, opts) {
|
|
2407
|
+
const isSensitive = error.unhandled || error.fatal;
|
|
2408
|
+
const statusCode = error.statusCode || 500;
|
|
2409
|
+
const statusMessage = error.statusMessage || "Server Error";
|
|
2410
|
+
const url = getRequestURL(event, { xForwardedHost: true, xForwardedProto: true });
|
|
2411
|
+
if (statusCode === 404) {
|
|
2412
|
+
const baseURL = import.meta.baseURL || "/";
|
|
2413
|
+
if (/^\/[^/]/.test(baseURL) && !url.pathname.startsWith(baseURL)) {
|
|
2414
|
+
const redirectTo = `${baseURL}${url.pathname.slice(1)}${url.search}`;
|
|
2415
|
+
return {
|
|
2416
|
+
status: 302,
|
|
2417
|
+
statusText: "Found",
|
|
2418
|
+
headers: { location: redirectTo },
|
|
2419
|
+
body: `Redirecting...`
|
|
2420
|
+
};
|
|
2447
2421
|
}
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
event,
|
|
2460
|
-
JSON.stringify(
|
|
2461
|
-
{
|
|
2462
|
-
error: true,
|
|
2463
|
-
url,
|
|
2464
|
-
statusCode,
|
|
2465
|
-
statusMessage,
|
|
2466
|
-
message: error.message,
|
|
2467
|
-
data: error.data,
|
|
2468
|
-
stack: error.stack?.split("\n").map((line) => line.trim())
|
|
2469
|
-
},
|
|
2470
|
-
null,
|
|
2471
|
-
2
|
|
2472
|
-
),
|
|
2473
|
-
"application/json"
|
|
2422
|
+
}
|
|
2423
|
+
await loadStackTrace(error).catch(consola.error);
|
|
2424
|
+
const youch = new Youch();
|
|
2425
|
+
if (isSensitive && !opts?.silent) {
|
|
2426
|
+
const tags = [error.unhandled && "[unhandled]", error.fatal && "[fatal]"].filter(Boolean).join(" ");
|
|
2427
|
+
const ansiError = await (await youch.toANSI(error)).replaceAll(process.cwd(), ".");
|
|
2428
|
+
consola.error(
|
|
2429
|
+
`[request error] ${tags} [${event.method}] ${url}
|
|
2430
|
+
|
|
2431
|
+
`,
|
|
2432
|
+
ansiError
|
|
2474
2433
|
);
|
|
2475
2434
|
}
|
|
2476
|
-
);
|
|
2435
|
+
const useJSON = opts?.json || !getRequestHeader(event, "accept")?.includes("text/html");
|
|
2436
|
+
const headers = {
|
|
2437
|
+
"content-type": useJSON ? "application/json" : "text/html",
|
|
2438
|
+
// Prevent browser from guessing the MIME types of resources.
|
|
2439
|
+
"x-content-type-options": "nosniff",
|
|
2440
|
+
// Prevent error page from being embedded in an iframe
|
|
2441
|
+
"x-frame-options": "DENY",
|
|
2442
|
+
// Prevent browsers from sending the Referer header
|
|
2443
|
+
"referrer-policy": "no-referrer",
|
|
2444
|
+
// Disable the execution of any js
|
|
2445
|
+
"content-security-policy": "script-src 'self' 'unsafe-inline'; object-src 'none'; base-uri 'self';"
|
|
2446
|
+
};
|
|
2447
|
+
if (statusCode === 404 || !getResponseHeader(event, "cache-control")) {
|
|
2448
|
+
headers["Cache-Control"] = "no-cache";
|
|
2449
|
+
}
|
|
2450
|
+
const body = useJSON ? {
|
|
2451
|
+
error: true,
|
|
2452
|
+
url,
|
|
2453
|
+
statusCode,
|
|
2454
|
+
statusMessage,
|
|
2455
|
+
message: error.message,
|
|
2456
|
+
data: error.data,
|
|
2457
|
+
stack: error.stack?.split("\n").map((line) => line.trim())
|
|
2458
|
+
} : await youch.toHTML(error, {
|
|
2459
|
+
request: {
|
|
2460
|
+
url: url.href,
|
|
2461
|
+
method: event.method,
|
|
2462
|
+
headers: getRequestHeaders(event)
|
|
2463
|
+
}
|
|
2464
|
+
});
|
|
2465
|
+
return {
|
|
2466
|
+
status: statusCode,
|
|
2467
|
+
statusText: statusMessage,
|
|
2468
|
+
headers,
|
|
2469
|
+
body
|
|
2470
|
+
};
|
|
2471
|
+
}
|
|
2477
2472
|
async function loadStackTrace(error) {
|
|
2478
2473
|
if (!(error instanceof Error)) {
|
|
2479
2474
|
return;
|
|
@@ -2807,10 +2802,12 @@ class DevServer {
|
|
|
2807
2802
|
createApp() {
|
|
2808
2803
|
const app = createApp({
|
|
2809
2804
|
onError: async (error, event) => {
|
|
2810
|
-
const errorHandler = this.nitro.options.devErrorHandler ||
|
|
2805
|
+
const errorHandler = this.nitro.options.devErrorHandler || devErrorHandler;
|
|
2811
2806
|
await loadStackTrace(error).catch(() => {
|
|
2812
2807
|
});
|
|
2813
|
-
return errorHandler(error, event
|
|
2808
|
+
return errorHandler(error, event, {
|
|
2809
|
+
defaultHandler: defaultHandler
|
|
2810
|
+
});
|
|
2814
2811
|
}
|
|
2815
2812
|
});
|
|
2816
2813
|
for (const handler of this.nitro.options.devHandlers) {
|
package/dist/kit/index.d.mts
CHANGED
package/dist/kit/index.d.ts
CHANGED
package/dist/meta/index.d.mts
CHANGED
package/dist/meta/index.d.ts
CHANGED
package/dist/meta/index.mjs
CHANGED
package/dist/rollup/index.mjs
CHANGED
|
@@ -1646,6 +1646,10 @@ function errorHandler(nitro) {
|
|
|
1646
1646
|
{
|
|
1647
1647
|
"#nitro-internal-virtual/error-handler": () => {
|
|
1648
1648
|
const errorHandlers = Array.isArray(nitro.options.errorHandler) ? nitro.options.errorHandler : [nitro.options.errorHandler];
|
|
1649
|
+
const builtinHandler = join(
|
|
1650
|
+
runtimeDir,
|
|
1651
|
+
`internal/error/${nitro.options.dev ? "dev" : "prod"}`
|
|
1652
|
+
);
|
|
1649
1653
|
return (
|
|
1650
1654
|
/* js */
|
|
1651
1655
|
`
|
|
@@ -1653,10 +1657,12 @@ ${errorHandlers.map((h, i) => `import errorHandler$${i} from "${h}";`).join("\n"
|
|
|
1653
1657
|
|
|
1654
1658
|
const errorHandlers = [${errorHandlers.map((_, i) => `errorHandler$${i}`).join(", ")}];
|
|
1655
1659
|
|
|
1660
|
+
import { defaultHandler } from "${builtinHandler}";
|
|
1661
|
+
|
|
1656
1662
|
export default async function(error, event) {
|
|
1657
1663
|
for (const handler of errorHandlers) {
|
|
1658
1664
|
try {
|
|
1659
|
-
await handler(error, event);
|
|
1665
|
+
await handler(error, event, { defaultHandler });
|
|
1660
1666
|
if (event.handled) {
|
|
1661
1667
|
return; // Response handled
|
|
1662
1668
|
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import { type H3Event, type H3Error } from "h3";
|
|
2
|
+
import { type InternalHandlerResponse } from "./utils";
|
|
1
3
|
declare const _default: NitroErrorHandler;
|
|
2
4
|
export default _default;
|
|
5
|
+
export declare function defaultHandler(error: H3Error, event: H3Event, opts?: {
|
|
6
|
+
silent?: boolean;
|
|
7
|
+
json?: boolean;
|
|
8
|
+
}): Promise<InternalHandlerResponse>;
|
|
3
9
|
export declare function loadStackTrace(error: any): Promise<void>;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
send,
|
|
3
|
-
sendRedirect,
|
|
4
3
|
getRequestHeader,
|
|
5
4
|
getRequestHeaders,
|
|
6
|
-
setResponseHeader,
|
|
7
|
-
setResponseStatus,
|
|
8
5
|
getRequestURL,
|
|
9
|
-
getResponseHeader
|
|
6
|
+
getResponseHeader,
|
|
7
|
+
setResponseHeaders,
|
|
8
|
+
setResponseStatus
|
|
10
9
|
} from "h3";
|
|
11
10
|
import { readFile } from "node:fs/promises";
|
|
12
11
|
import { resolve, dirname } from "node:path";
|
|
@@ -14,76 +13,84 @@ import consola from "consola";
|
|
|
14
13
|
import { ErrorParser } from "youch-core";
|
|
15
14
|
import { Youch } from "youch";
|
|
16
15
|
import { SourceMapConsumer } from "source-map";
|
|
17
|
-
import { defineNitroErrorHandler
|
|
16
|
+
import { defineNitroErrorHandler } from "./utils.mjs";
|
|
18
17
|
export default defineNitroErrorHandler(
|
|
19
18
|
async function defaultNitroErrorHandler(error, event) {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (statusCode === 404) {
|
|
25
|
-
const baseURL = import.meta.baseURL || "/";
|
|
26
|
-
if (/^\/[^/]/.test(baseURL) && !url.pathname.startsWith(baseURL)) {
|
|
27
|
-
return sendRedirect(
|
|
28
|
-
event,
|
|
29
|
-
`${baseURL}${url.pathname.slice(1)}${url.search}`
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
await loadStackTrace(error).catch(consola.error);
|
|
34
|
-
const youch = new Youch();
|
|
35
|
-
if (isSensitive) {
|
|
36
|
-
const tags = [error.unhandled && "[unhandled]", error.fatal && "[fatal]"].filter(Boolean).join(" ");
|
|
37
|
-
const columns = process.stderr.columns;
|
|
38
|
-
const ansiError = await (await youch.toANSI(error)).replaceAll(process.cwd(), ".");
|
|
39
|
-
if (!columns) {
|
|
40
|
-
process.stderr.columns = columns;
|
|
41
|
-
}
|
|
42
|
-
consola.error(
|
|
43
|
-
`[request error] ${tags} [${event.method}] ${url}
|
|
44
|
-
|
|
45
|
-
`,
|
|
46
|
-
ansiError
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
setResponseStatus(event, statusCode, statusMessage);
|
|
50
|
-
setSecurityHeaders(
|
|
19
|
+
const res = await defaultHandler(error, event);
|
|
20
|
+
setResponseHeaders(event, res.headers);
|
|
21
|
+
setResponseStatus(event, res.status, res.statusText);
|
|
22
|
+
return send(
|
|
51
23
|
event,
|
|
52
|
-
|
|
53
|
-
/* allow js */
|
|
24
|
+
typeof res.body === "string" ? res.body : JSON.stringify(res.body, null, 2)
|
|
54
25
|
);
|
|
55
|
-
|
|
56
|
-
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
export async function defaultHandler(error, event, opts) {
|
|
29
|
+
const isSensitive = error.unhandled || error.fatal;
|
|
30
|
+
const statusCode = error.statusCode || 500;
|
|
31
|
+
const statusMessage = error.statusMessage || "Server Error";
|
|
32
|
+
const url = getRequestURL(event, { xForwardedHost: true, xForwardedProto: true });
|
|
33
|
+
if (statusCode === 404) {
|
|
34
|
+
const baseURL = import.meta.baseURL || "/";
|
|
35
|
+
if (/^\/[^/]/.test(baseURL) && !url.pathname.startsWith(baseURL)) {
|
|
36
|
+
const redirectTo = `${baseURL}${url.pathname.slice(1)}${url.search}`;
|
|
37
|
+
return {
|
|
38
|
+
status: 302,
|
|
39
|
+
statusText: "Found",
|
|
40
|
+
headers: { location: redirectTo },
|
|
41
|
+
body: `Redirecting...`
|
|
42
|
+
};
|
|
57
43
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
event,
|
|
70
|
-
JSON.stringify(
|
|
71
|
-
{
|
|
72
|
-
error: true,
|
|
73
|
-
url,
|
|
74
|
-
statusCode,
|
|
75
|
-
statusMessage,
|
|
76
|
-
message: error.message,
|
|
77
|
-
data: error.data,
|
|
78
|
-
stack: error.stack?.split("\n").map((line) => line.trim())
|
|
79
|
-
},
|
|
80
|
-
null,
|
|
81
|
-
2
|
|
82
|
-
),
|
|
83
|
-
"application/json"
|
|
44
|
+
}
|
|
45
|
+
await loadStackTrace(error).catch(consola.error);
|
|
46
|
+
const youch = new Youch();
|
|
47
|
+
if (isSensitive && !opts?.silent) {
|
|
48
|
+
const tags = [error.unhandled && "[unhandled]", error.fatal && "[fatal]"].filter(Boolean).join(" ");
|
|
49
|
+
const ansiError = await (await youch.toANSI(error)).replaceAll(process.cwd(), ".");
|
|
50
|
+
consola.error(
|
|
51
|
+
`[request error] ${tags} [${event.method}] ${url}
|
|
52
|
+
|
|
53
|
+
`,
|
|
54
|
+
ansiError
|
|
84
55
|
);
|
|
85
56
|
}
|
|
86
|
-
);
|
|
57
|
+
const useJSON = opts?.json || !getRequestHeader(event, "accept")?.includes("text/html");
|
|
58
|
+
const headers = {
|
|
59
|
+
"content-type": useJSON ? "application/json" : "text/html",
|
|
60
|
+
// Prevent browser from guessing the MIME types of resources.
|
|
61
|
+
"x-content-type-options": "nosniff",
|
|
62
|
+
// Prevent error page from being embedded in an iframe
|
|
63
|
+
"x-frame-options": "DENY",
|
|
64
|
+
// Prevent browsers from sending the Referer header
|
|
65
|
+
"referrer-policy": "no-referrer",
|
|
66
|
+
// Disable the execution of any js
|
|
67
|
+
"content-security-policy": "script-src 'self' 'unsafe-inline'; object-src 'none'; base-uri 'self';"
|
|
68
|
+
};
|
|
69
|
+
if (statusCode === 404 || !getResponseHeader(event, "cache-control")) {
|
|
70
|
+
headers["Cache-Control"] = "no-cache";
|
|
71
|
+
}
|
|
72
|
+
const body = useJSON ? {
|
|
73
|
+
error: true,
|
|
74
|
+
url,
|
|
75
|
+
statusCode,
|
|
76
|
+
statusMessage,
|
|
77
|
+
message: error.message,
|
|
78
|
+
data: error.data,
|
|
79
|
+
stack: error.stack?.split("\n").map((line) => line.trim())
|
|
80
|
+
} : await youch.toHTML(error, {
|
|
81
|
+
request: {
|
|
82
|
+
url: url.href,
|
|
83
|
+
method: event.method,
|
|
84
|
+
headers: getRequestHeaders(event)
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
return {
|
|
88
|
+
status: statusCode,
|
|
89
|
+
statusText: statusMessage,
|
|
90
|
+
headers,
|
|
91
|
+
body
|
|
92
|
+
};
|
|
93
|
+
}
|
|
87
94
|
export async function loadStackTrace(error) {
|
|
88
95
|
if (!(error instanceof Error)) {
|
|
89
96
|
return;
|
|
@@ -1,2 +1,8 @@
|
|
|
1
|
+
import { type H3Error, type H3Event } from "h3";
|
|
2
|
+
import { type InternalHandlerResponse } from "./utils";
|
|
1
3
|
declare const _default: NitroErrorHandler;
|
|
2
4
|
export default _default;
|
|
5
|
+
export declare function defaultHandler(error: H3Error, event: H3Event, opts?: {
|
|
6
|
+
silent?: boolean;
|
|
7
|
+
json?: boolean;
|
|
8
|
+
}): InternalHandlerResponse;
|
|
@@ -2,58 +2,67 @@ import {
|
|
|
2
2
|
getRequestURL,
|
|
3
3
|
getResponseHeader,
|
|
4
4
|
send,
|
|
5
|
-
|
|
6
|
-
setResponseHeader,
|
|
5
|
+
setResponseHeaders,
|
|
7
6
|
setResponseStatus
|
|
8
7
|
} from "h3";
|
|
9
|
-
import { defineNitroErrorHandler
|
|
8
|
+
import { defineNitroErrorHandler } from "./utils.mjs";
|
|
10
9
|
export default defineNitroErrorHandler(
|
|
11
10
|
function defaultNitroErrorHandler(error, event) {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (statusCode === 404) {
|
|
17
|
-
const baseURL = import.meta.baseURL || "/";
|
|
18
|
-
if (/^\/[^/]/.test(baseURL) && !url.pathname.startsWith(baseURL)) {
|
|
19
|
-
return sendRedirect(
|
|
20
|
-
event,
|
|
21
|
-
`${baseURL}${url.pathname.slice(1)}${url.search}`
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
if (isSensitive) {
|
|
26
|
-
const tags = [error.unhandled && "[unhandled]", error.fatal && "[fatal]"].filter(Boolean).join(" ");
|
|
27
|
-
console.error(
|
|
28
|
-
`[request error] ${tags} [${event.method}] ${url}
|
|
29
|
-
`,
|
|
30
|
-
error
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
setSecurityHeaders(
|
|
34
|
-
event,
|
|
35
|
-
false
|
|
36
|
-
/* no js */
|
|
37
|
-
);
|
|
38
|
-
setResponseStatus(event, statusCode, statusMessage);
|
|
39
|
-
if (statusCode === 404 || !getResponseHeader(event, "cache-control")) {
|
|
40
|
-
setResponseHeader(event, "cache-control", "no-cache");
|
|
41
|
-
}
|
|
42
|
-
return send(
|
|
43
|
-
event,
|
|
44
|
-
JSON.stringify(
|
|
45
|
-
{
|
|
46
|
-
error: true,
|
|
47
|
-
url: url.href,
|
|
48
|
-
statusCode,
|
|
49
|
-
statusMessage,
|
|
50
|
-
message: isSensitive ? "Server Error" : error.message,
|
|
51
|
-
data: isSensitive ? void 0 : error.data
|
|
52
|
-
},
|
|
53
|
-
null,
|
|
54
|
-
2
|
|
55
|
-
),
|
|
56
|
-
"application/json"
|
|
57
|
-
);
|
|
11
|
+
const res = defaultHandler(error, event);
|
|
12
|
+
setResponseHeaders(event, res.headers);
|
|
13
|
+
setResponseStatus(event, res.status, res.statusText);
|
|
14
|
+
return send(event, JSON.stringify(res.body, null, 2));
|
|
58
15
|
}
|
|
59
16
|
);
|
|
17
|
+
export function defaultHandler(error, event, opts) {
|
|
18
|
+
const isSensitive = error.unhandled || error.fatal;
|
|
19
|
+
const statusCode = error.statusCode || 500;
|
|
20
|
+
const statusMessage = error.statusMessage || "Server Error";
|
|
21
|
+
const url = getRequestURL(event, { xForwardedHost: true, xForwardedProto: true });
|
|
22
|
+
if (statusCode === 404) {
|
|
23
|
+
const baseURL = import.meta.baseURL || "/";
|
|
24
|
+
if (/^\/[^/]/.test(baseURL) && !url.pathname.startsWith(baseURL)) {
|
|
25
|
+
const redirectTo = `${baseURL}${url.pathname.slice(1)}${url.search}`;
|
|
26
|
+
return {
|
|
27
|
+
status: 302,
|
|
28
|
+
statusText: "Found",
|
|
29
|
+
headers: { location: redirectTo },
|
|
30
|
+
body: `Redirecting...`
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (isSensitive && !opts?.silent) {
|
|
35
|
+
const tags = [error.unhandled && "[unhandled]", error.fatal && "[fatal]"].filter(Boolean).join(" ");
|
|
36
|
+
console.error(`[request error] ${tags} [${event.method}] ${url}
|
|
37
|
+
`, error);
|
|
38
|
+
}
|
|
39
|
+
const headers = {
|
|
40
|
+
"content-type": "application/json",
|
|
41
|
+
// Prevent browser from guessing the MIME types of resources.
|
|
42
|
+
"x-content-type-options": "nosniff",
|
|
43
|
+
// Prevent error page from being embedded in an iframe
|
|
44
|
+
"x-frame-options": "DENY",
|
|
45
|
+
// Prevent browsers from sending the Referer header
|
|
46
|
+
"referrer-policy": "no-referrer",
|
|
47
|
+
// Disable the execution of any js
|
|
48
|
+
"content-security-policy": "script-src 'none'; frame-ancestors 'none';"
|
|
49
|
+
};
|
|
50
|
+
setResponseStatus(event, statusCode, statusMessage);
|
|
51
|
+
if (statusCode === 404 || !getResponseHeader(event, "cache-control")) {
|
|
52
|
+
headers["cache-control"] = "no-cache";
|
|
53
|
+
}
|
|
54
|
+
const body = {
|
|
55
|
+
error: true,
|
|
56
|
+
url: url.href,
|
|
57
|
+
statusCode,
|
|
58
|
+
statusMessage,
|
|
59
|
+
message: isSensitive ? "Server Error" : error.message,
|
|
60
|
+
data: isSensitive ? void 0 : error.data
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
status: statusCode,
|
|
64
|
+
statusText: statusMessage,
|
|
65
|
+
headers,
|
|
66
|
+
body
|
|
67
|
+
};
|
|
68
|
+
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { NitroErrorHandler } from "nitropack/types";
|
|
2
|
-
import type { H3Event } from "h3";
|
|
3
2
|
export declare function defineNitroErrorHandler(handler: NitroErrorHandler): NitroErrorHandler;
|
|
4
|
-
export
|
|
3
|
+
export type InternalHandlerResponse = {
|
|
4
|
+
status: number;
|
|
5
|
+
statusText: string;
|
|
6
|
+
headers: Record<string, string>;
|
|
7
|
+
body: string | Record<string, any>;
|
|
8
|
+
};
|
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
import { getRequestHeader, setResponseHeaders } from "h3";
|
|
2
1
|
export function defineNitroErrorHandler(handler) {
|
|
3
2
|
return handler;
|
|
4
3
|
}
|
|
5
|
-
export function setSecurityHeaders(event, allowjs = false) {
|
|
6
|
-
setResponseHeaders(event, {
|
|
7
|
-
// Prevent browser from guessing the MIME types of resources.
|
|
8
|
-
"X-Content-Type-Options": "nosniff",
|
|
9
|
-
// Prevent error page from being embedded in an iframe
|
|
10
|
-
"X-Frame-Options": "DENY",
|
|
11
|
-
// Prevent browsers from sending the Referer header
|
|
12
|
-
"Referrer-Policy": "no-referrer",
|
|
13
|
-
// Disable the execution of any js
|
|
14
|
-
"Content-Security-Policy": allowjs ? "script-src 'self' 'unsafe-inline'; object-src 'none'; base-uri 'self';" : "script-src 'none'; frame-ancestors 'none';"
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
function hasReqHeader(event, name, includes) {
|
|
18
|
-
const value = getRequestHeader(event, name);
|
|
19
|
-
return value && typeof value === "string" && value.toLowerCase().includes(includes);
|
|
20
|
-
}
|
|
@@ -106,7 +106,18 @@ interface NitroDevEventHandler {
|
|
|
106
106
|
*/
|
|
107
107
|
handler: EventHandler;
|
|
108
108
|
}
|
|
109
|
-
type
|
|
109
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
110
|
+
type NitroErrorHandler = (error: H3Error, event: H3Event, _: {
|
|
111
|
+
defaultHandler: (error: H3Error, event: H3Event, opts?: {
|
|
112
|
+
silent?: boolean;
|
|
113
|
+
json?: boolean;
|
|
114
|
+
}) => MaybePromise<{
|
|
115
|
+
status: number;
|
|
116
|
+
statusText: string;
|
|
117
|
+
headers: Record<string, string>;
|
|
118
|
+
body: string | Record<string, any>;
|
|
119
|
+
}>;
|
|
120
|
+
}) => void | Promise<void>;
|
|
110
121
|
|
|
111
122
|
interface PrerenderRoute {
|
|
112
123
|
route: string;
|
|
@@ -106,7 +106,18 @@ interface NitroDevEventHandler {
|
|
|
106
106
|
*/
|
|
107
107
|
handler: EventHandler;
|
|
108
108
|
}
|
|
109
|
-
type
|
|
109
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
110
|
+
type NitroErrorHandler = (error: H3Error, event: H3Event, _: {
|
|
111
|
+
defaultHandler: (error: H3Error, event: H3Event, opts?: {
|
|
112
|
+
silent?: boolean;
|
|
113
|
+
json?: boolean;
|
|
114
|
+
}) => MaybePromise<{
|
|
115
|
+
status: number;
|
|
116
|
+
statusText: string;
|
|
117
|
+
headers: Record<string, string>;
|
|
118
|
+
body: string | Record<string, any>;
|
|
119
|
+
}>;
|
|
120
|
+
}) => void | Promise<void>;
|
|
110
121
|
|
|
111
122
|
interface PrerenderRoute {
|
|
112
123
|
route: string;
|
package/dist/types/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { App, Router, H3Event, RouterMethod } from 'h3';
|
|
2
2
|
import { FetchRequest, FetchOptions, FetchResponse } from 'ofetch';
|
|
3
|
-
import { a as NitroOptions, b as NitroConfig, N as NitroModule } from '../shared/nitro.
|
|
4
|
-
export { A as AppConfig, C as CacheEntry, c as CacheOptions, d as CachedEventHandlerOptions, e as CompressOptions, g as DatabaseConnectionConfig, h as DatabaseConnectionConfigs, D as DatabaseConnectionName, l as DevServerOptions, I as EsbuildOptions, O as HTTPStatusCode, L as LoadConfigOptions, u as Nitro, y as NitroBuildInfo, q as NitroDevEventHandler, n as NitroDevServer, v as NitroDynamicConfig, r as NitroErrorHandler, p as NitroEventHandler, x as NitroFrameworkInfo, s as NitroHooks, t as NitroModuleInput, k as NitroOpenAPIConfig, E as NitroPreset, F as NitroPresetMeta, Q as NitroRouteConfig, o as NitroRouteMeta, T as NitroRouteRules, j as NitroRuntimeConfig, i as NitroRuntimeConfigApp, w as NitroTypes, m as NitroWorker, J as NodeExternalsOptions, B as PrerenderGenerateRoute, z as PrerenderRoute, P as PublicAssetDir, M as RawOptions, R as ResponseCacheEntry, G as RollupConfig, H as RollupVirtualOptions, S as ServerAssetDir, K as ServerAssetOptions, f as StorageMounts, V as VirtualModule } from '../shared/nitro.
|
|
3
|
+
import { a as NitroOptions, b as NitroConfig, N as NitroModule } from '../shared/nitro.JLO839lv.mjs';
|
|
4
|
+
export { A as AppConfig, C as CacheEntry, c as CacheOptions, d as CachedEventHandlerOptions, e as CompressOptions, g as DatabaseConnectionConfig, h as DatabaseConnectionConfigs, D as DatabaseConnectionName, l as DevServerOptions, I as EsbuildOptions, O as HTTPStatusCode, L as LoadConfigOptions, u as Nitro, y as NitroBuildInfo, q as NitroDevEventHandler, n as NitroDevServer, v as NitroDynamicConfig, r as NitroErrorHandler, p as NitroEventHandler, x as NitroFrameworkInfo, s as NitroHooks, t as NitroModuleInput, k as NitroOpenAPIConfig, E as NitroPreset, F as NitroPresetMeta, Q as NitroRouteConfig, o as NitroRouteMeta, T as NitroRouteRules, j as NitroRuntimeConfig, i as NitroRuntimeConfigApp, w as NitroTypes, m as NitroWorker, J as NodeExternalsOptions, B as PrerenderGenerateRoute, z as PrerenderRoute, P as PublicAssetDir, M as RawOptions, R as ResponseCacheEntry, G as RollupConfig, H as RollupVirtualOptions, S as ServerAssetDir, K as ServerAssetOptions, f as StorageMounts, V as VirtualModule } from '../shared/nitro.JLO839lv.mjs';
|
|
5
5
|
import { Hookable } from 'hookable';
|
|
6
6
|
import { NitroRuntimeHooks as NitroRuntimeHooks$1 } from 'nitropack';
|
|
7
7
|
import { AbstractRequest, AbstractResponse } from 'node-mock-http';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { App, Router, H3Event, RouterMethod } from 'h3';
|
|
2
2
|
import { FetchRequest, FetchOptions, FetchResponse } from 'ofetch';
|
|
3
|
-
import { a as NitroOptions, b as NitroConfig, N as NitroModule } from '../shared/nitro.
|
|
4
|
-
export { A as AppConfig, C as CacheEntry, c as CacheOptions, d as CachedEventHandlerOptions, e as CompressOptions, g as DatabaseConnectionConfig, h as DatabaseConnectionConfigs, D as DatabaseConnectionName, l as DevServerOptions, I as EsbuildOptions, O as HTTPStatusCode, L as LoadConfigOptions, u as Nitro, y as NitroBuildInfo, q as NitroDevEventHandler, n as NitroDevServer, v as NitroDynamicConfig, r as NitroErrorHandler, p as NitroEventHandler, x as NitroFrameworkInfo, s as NitroHooks, t as NitroModuleInput, k as NitroOpenAPIConfig, E as NitroPreset, F as NitroPresetMeta, Q as NitroRouteConfig, o as NitroRouteMeta, T as NitroRouteRules, j as NitroRuntimeConfig, i as NitroRuntimeConfigApp, w as NitroTypes, m as NitroWorker, J as NodeExternalsOptions, B as PrerenderGenerateRoute, z as PrerenderRoute, P as PublicAssetDir, M as RawOptions, R as ResponseCacheEntry, G as RollupConfig, H as RollupVirtualOptions, S as ServerAssetDir, K as ServerAssetOptions, f as StorageMounts, V as VirtualModule } from '../shared/nitro.
|
|
3
|
+
import { a as NitroOptions, b as NitroConfig, N as NitroModule } from '../shared/nitro.JLO839lv.js';
|
|
4
|
+
export { A as AppConfig, C as CacheEntry, c as CacheOptions, d as CachedEventHandlerOptions, e as CompressOptions, g as DatabaseConnectionConfig, h as DatabaseConnectionConfigs, D as DatabaseConnectionName, l as DevServerOptions, I as EsbuildOptions, O as HTTPStatusCode, L as LoadConfigOptions, u as Nitro, y as NitroBuildInfo, q as NitroDevEventHandler, n as NitroDevServer, v as NitroDynamicConfig, r as NitroErrorHandler, p as NitroEventHandler, x as NitroFrameworkInfo, s as NitroHooks, t as NitroModuleInput, k as NitroOpenAPIConfig, E as NitroPreset, F as NitroPresetMeta, Q as NitroRouteConfig, o as NitroRouteMeta, T as NitroRouteRules, j as NitroRuntimeConfig, i as NitroRuntimeConfigApp, w as NitroTypes, m as NitroWorker, J as NodeExternalsOptions, B as PrerenderGenerateRoute, z as PrerenderRoute, P as PublicAssetDir, M as RawOptions, R as ResponseCacheEntry, G as RollupConfig, H as RollupVirtualOptions, S as ServerAssetDir, K as ServerAssetOptions, f as StorageMounts, V as VirtualModule } from '../shared/nitro.JLO839lv.js';
|
|
5
5
|
import { Hookable } from 'hookable';
|
|
6
6
|
import { NitroRuntimeHooks as NitroRuntimeHooks$1 } from 'nitropack';
|
|
7
7
|
import { AbstractRequest, AbstractResponse } from 'node-mock-http';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nitropack-nightly",
|
|
3
|
-
"version": "2.11.
|
|
3
|
+
"version": "2.11.3-20250306-104907.06147e7a",
|
|
4
4
|
"description": "Build and Deploy Universal JavaScript Servers",
|
|
5
5
|
"repository": "nitrojs/nitro",
|
|
6
6
|
"license": "MIT",
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
"esbuild": "^0.25.0",
|
|
127
127
|
"escape-string-regexp": "^5.0.0",
|
|
128
128
|
"etag": "^1.8.1",
|
|
129
|
-
"exsolve": "^1.0.
|
|
129
|
+
"exsolve": "^1.0.2",
|
|
130
130
|
"fs-extra": "^11.3.0",
|
|
131
131
|
"globby": "^14.1.0",
|
|
132
132
|
"gzip-size": "^7.0.0",
|
|
@@ -176,7 +176,7 @@
|
|
|
176
176
|
"devDependencies": {
|
|
177
177
|
"@azure/functions": "^3.5.1",
|
|
178
178
|
"@azure/static-web-apps-cli": "^2.0.4",
|
|
179
|
-
"@cloudflare/workers-types": "^4.
|
|
179
|
+
"@cloudflare/workers-types": "^4.20250303.0",
|
|
180
180
|
"@deno/types": "^0.0.1",
|
|
181
181
|
"@netlify/edge-functions": "^2.11.1",
|
|
182
182
|
"@scalar/api-reference": "^1.25.125",
|
|
@@ -200,7 +200,7 @@
|
|
|
200
200
|
"firebase-admin": "^12.7.0",
|
|
201
201
|
"firebase-functions": "^4.9.0",
|
|
202
202
|
"get-port-please": "^3.1.2",
|
|
203
|
-
"miniflare": "^3.20250214.
|
|
203
|
+
"miniflare": "^3.20250214.2",
|
|
204
204
|
"ohash-v1": "npm:ohash@^1.1.5",
|
|
205
205
|
"prettier": "^3.5.3",
|
|
206
206
|
"typescript": "^5.8.2",
|