@nuxt/nitro-server-nightly 4.6.0-29833429.e2a0e5da → 4.6.0-29836601.d5e5f1bd
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/augments.d.mts +37 -4
- package/dist/index.mjs +26 -25
- package/dist/runtime/handlers/error-channel.mjs +17 -0
- package/dist/runtime/handlers/error.mjs +75 -27
- package/dist/runtime/handlers/renderer.mjs +1 -1
- package/dist/runtime/nitro-server/src/h3.mjs +2 -2
- package/dist/runtime/nuxt/src/app/error.mjs +29 -2
- package/dist/runtime/plugins/dev-errors.mjs +62 -0
- package/dist/runtime/plugins/dev-server-logs.mjs +1 -1
- package/dist/runtime/server.mjs +2 -2
- package/dist/runtime/templates/error-500.mjs +1 -1
- package/dist/runtime/utils/cache-driver.mjs +8 -7
- package/dist/runtime/utils/cache.mjs +1 -1
- package/dist/runtime/utils/error-channel.mjs +117 -0
- package/dist/runtime/utils/event.mjs +7 -2
- package/dist/runtime/utils/renderer/options.mjs +3 -0
- package/package.json +10 -8
- package/dist/runtime/utils/dev.mjs +0 -988
package/dist/augments.d.mts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { EventHandler, H3Event } from "h3";
|
|
2
2
|
import { Nitro, NitroConfig, NitroDevEventHandler, NitroEventHandler, NitroOptions, NitroRouteConfig, NitroRouteRules, NitroRuntimeConfig } from "nitropack/types";
|
|
3
|
-
import {
|
|
4
|
-
import { NuxtIslandContext, NuxtIslandResponse, NuxtRenderChunkContext, NuxtRenderCloseContext, NuxtRenderHTMLContext, NuxtRenderRouteContext } from "#app/types";
|
|
3
|
+
import { DevServerLog, NuxtIslandContext, NuxtIslandResponse, NuxtRenderChunkContext, NuxtRenderCloseContext, NuxtRenderHTMLContext, NuxtRenderRouteContext } from "#app/types";
|
|
5
4
|
import { NuxtRequestContext, NuxtRequestContext as NuxtRequestContext$1, RouteRuleConfigExtensions, RuntimeConfig, TracingChannelOptions } from "nuxt/schema";
|
|
6
5
|
//#region src/augments.d.ts
|
|
7
6
|
/** The channels this package's runtime forwards, alongside the Nuxt-owned ones. */
|
|
@@ -17,6 +16,22 @@ interface NitroTracingChannels {
|
|
|
17
16
|
* @experimental Channel names, payload shapes, and option keys may change.
|
|
18
17
|
*/
|
|
19
18
|
export type NuxtTracingChannelOptions = TracingChannelOptions;
|
|
19
|
+
/**
|
|
20
|
+
* Dev-only access to the SSR bundle's transformed modules, registered by the bundler that
|
|
21
|
+
* evaluates them in the Nitro process.
|
|
22
|
+
*
|
|
23
|
+
* @experimental
|
|
24
|
+
*/
|
|
25
|
+
export interface SSRSourceMaps {
|
|
26
|
+
/** Transformed code of an SSR module as it was evaluated. */
|
|
27
|
+
getCode: (file: string) => string | undefined;
|
|
28
|
+
/** Position in generated code a source position was mapped from. */
|
|
29
|
+
getCompiledPosition?: (file: string, line: number, column?: number) => {
|
|
30
|
+
file: string;
|
|
31
|
+
line: number;
|
|
32
|
+
column: number;
|
|
33
|
+
} | undefined;
|
|
34
|
+
}
|
|
20
35
|
declare global {
|
|
21
36
|
interface ImportMeta {
|
|
22
37
|
dev: boolean;
|
|
@@ -50,6 +65,15 @@ declare module "nitropack/types" {
|
|
|
50
65
|
}
|
|
51
66
|
}
|
|
52
67
|
declare module "nitropack" {
|
|
68
|
+
interface NitroApp {
|
|
69
|
+
/**
|
|
70
|
+
* Only set in development, by bundlers that evaluate the SSR bundle within
|
|
71
|
+
* the Nitro process.
|
|
72
|
+
*
|
|
73
|
+
* @experimental
|
|
74
|
+
*/
|
|
75
|
+
ssrSourceMaps?: SSRSourceMaps;
|
|
76
|
+
}
|
|
53
77
|
interface NitroRuntimeConfig extends RuntimeConfig {}
|
|
54
78
|
interface NitroRouteConfig extends RouteRuleConfigExtensions {}
|
|
55
79
|
interface NitroRouteConfig {
|
|
@@ -61,7 +85,7 @@ declare module "nitropack" {
|
|
|
61
85
|
}
|
|
62
86
|
interface NitroRuntimeHooks {
|
|
63
87
|
"dev:ssr-logs": (ctx: {
|
|
64
|
-
logs:
|
|
88
|
+
logs: DevServerLog[];
|
|
65
89
|
path: string;
|
|
66
90
|
}) => void | Promise<void>;
|
|
67
91
|
"render:html": (htmlContext: NuxtRenderHTMLContext, context: {
|
|
@@ -84,6 +108,15 @@ declare module "nitropack" {
|
|
|
84
108
|
}
|
|
85
109
|
}
|
|
86
110
|
declare module "nitropack/types" {
|
|
111
|
+
interface NitroApp {
|
|
112
|
+
/**
|
|
113
|
+
* Only set in development, by bundlers that evaluate the SSR bundle within
|
|
114
|
+
* the Nitro process.
|
|
115
|
+
*
|
|
116
|
+
* @experimental
|
|
117
|
+
*/
|
|
118
|
+
ssrSourceMaps?: SSRSourceMaps;
|
|
119
|
+
}
|
|
87
120
|
interface NitroRuntimeConfig extends RuntimeConfig {}
|
|
88
121
|
interface NitroRouteConfig extends RouteRuleConfigExtensions {}
|
|
89
122
|
interface NitroRouteConfig {
|
|
@@ -95,7 +128,7 @@ declare module "nitropack/types" {
|
|
|
95
128
|
}
|
|
96
129
|
interface NitroRuntimeHooks {
|
|
97
130
|
"dev:ssr-logs": (ctx: {
|
|
98
|
-
logs:
|
|
131
|
+
logs: DevServerLog[];
|
|
99
132
|
path: string;
|
|
100
133
|
}) => void | Promise<void>;
|
|
101
134
|
"render:html": (htmlContext: NuxtRenderHTMLContext, context: {
|
package/dist/index.mjs
CHANGED
|
@@ -21,8 +21,9 @@ import { ImpoundPlugin } from "impound";
|
|
|
21
21
|
import { resolveModulePath } from "exsolve";
|
|
22
22
|
import { runtimeDependencies } from "nitropack/runtime/meta";
|
|
23
23
|
import { matchesGlob } from "node:path";
|
|
24
|
+
import { isLoopbackAddress } from "nuxt/internal/dev/peer";
|
|
24
25
|
//#region package.json
|
|
25
|
-
var version = "4.6.0-
|
|
26
|
+
var version = "4.6.0-29836601.d5e5f1bd";
|
|
26
27
|
//#endregion
|
|
27
28
|
//#region src/utils.ts
|
|
28
29
|
function toArray(value) {
|
|
@@ -105,26 +106,10 @@ const LOOPBACK_HOSTS = /* @__PURE__ */ new Set([
|
|
|
105
106
|
"[::1]",
|
|
106
107
|
"::1"
|
|
107
108
|
]);
|
|
108
|
-
/**
|
|
109
|
-
* Whether the connected peer is a loopback address.
|
|
110
|
-
*
|
|
111
|
-
* This inspects the TCP peer address rather than request metadata, so a
|
|
112
|
-
* non-browser client cannot make itself look local by choosing its `Host`,
|
|
113
|
-
* `Origin`, `Referer` or `Sec-Fetch-*` headers. `x-forwarded-for` is ignored on
|
|
114
|
-
* purpose: only the address of the socket we are actually talking to counts.
|
|
115
|
-
*/
|
|
109
|
+
/** Whether the connected peer is a loopback address. */
|
|
116
110
|
function isLoopbackPeer(event) {
|
|
117
111
|
return isLoopbackAddress(getRequestIP(event));
|
|
118
112
|
}
|
|
119
|
-
function isLoopbackAddress(address) {
|
|
120
|
-
if (!address) return false;
|
|
121
|
-
let normalized = address.trim().toLowerCase().replace(/^\[/, "").replace(/\]$/, "");
|
|
122
|
-
const zoneIndex = normalized.indexOf("%");
|
|
123
|
-
if (zoneIndex !== -1) normalized = normalized.slice(0, zoneIndex);
|
|
124
|
-
if (normalized.startsWith("::ffff:")) normalized = normalized.slice(7);
|
|
125
|
-
if (normalized === "::1") return true;
|
|
126
|
-
return /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(normalized);
|
|
127
|
-
}
|
|
128
113
|
/**
|
|
129
114
|
* Header-based same-origin/allowed-host gate shared by dev-only handlers.
|
|
130
115
|
*
|
|
@@ -421,8 +406,7 @@ ${[...references.map((ref) => renderReference(ref, typesDir)), ...declarations].
|
|
|
421
406
|
|
|
422
407
|
import type { RouteRuleConfigExtensions, RuntimeConfig } from 'nuxt/schema'
|
|
423
408
|
import type { H3Event } from 'h3'
|
|
424
|
-
import type {
|
|
425
|
-
import type { NuxtIslandContext, NuxtIslandResponse, NuxtRenderChunkContext, NuxtRenderCloseContext, NuxtRenderHTMLContext, NuxtRenderRouteContext } from '#app/types'
|
|
409
|
+
import type { DevServerLog, NuxtIslandContext, NuxtIslandResponse, NuxtRenderChunkContext, NuxtRenderCloseContext, NuxtRenderHTMLContext, NuxtRenderRouteContext } from '#app/types'
|
|
426
410
|
|
|
427
411
|
declare module 'nitropack' {
|
|
428
412
|
interface NitroRuntimeConfig extends RuntimeConfig {}
|
|
@@ -444,7 +428,7 @@ declare module 'nitropack' {
|
|
|
444
428
|
appLayout?: string | false
|
|
445
429
|
}
|
|
446
430
|
interface NitroRuntimeHooks {
|
|
447
|
-
'dev:ssr-logs': (ctx: { logs:
|
|
431
|
+
'dev:ssr-logs': (ctx: { logs: DevServerLog[], path: string }) => void | Promise<void>
|
|
448
432
|
'render:html': (htmlContext: NuxtRenderHTMLContext, context: { event: H3Event, streaming?: boolean }) => void | Promise<void>
|
|
449
433
|
'render:html:chunk': (chunkContext: NuxtRenderChunkContext, context: { event: H3Event }) => void | Promise<void>
|
|
450
434
|
'render:html:close': (closeContext: NuxtRenderCloseContext, context: { event: H3Event }) => void | Promise<void>
|
|
@@ -472,7 +456,7 @@ declare module 'nitropack/types' {
|
|
|
472
456
|
appLayout?: string | false
|
|
473
457
|
}
|
|
474
458
|
interface NitroRuntimeHooks {
|
|
475
|
-
'dev:ssr-logs': (ctx: { logs:
|
|
459
|
+
'dev:ssr-logs': (ctx: { logs: DevServerLog[], path: string }) => void | Promise<void>
|
|
476
460
|
'render:html': (htmlContext: NuxtRenderHTMLContext, context: { event: H3Event, streaming?: boolean }) => void | Promise<void>
|
|
477
461
|
'render:html:chunk': (chunkContext: NuxtRenderChunkContext, context: { event: H3Event }) => void | Promise<void>
|
|
478
462
|
'render:html:close': (closeContext: NuxtRenderCloseContext, context: { event: H3Event }) => void | Promise<void>
|
|
@@ -545,11 +529,14 @@ async function bundle(nuxt) {
|
|
|
545
529
|
baseURL: joinURL("/", asset.baseURL || "/", "**"),
|
|
546
530
|
resolvedFrom: "your server directory and then your project root"
|
|
547
531
|
});
|
|
532
|
+
if (nuxt.options.dev) {
|
|
533
|
+
nuxt.options.nitro.virtual = defu(nuxt.options.nitro.virtual, { "#internal/dev-server-logs-options": () => [`export const rootDir = ${JSON.stringify(nuxt.options.rootDir)};`, `export const srcDir = ${JSON.stringify(nuxt.options.srcDir)};`].join("\n") });
|
|
534
|
+
nuxt.options.nitro.externals = defu(nuxt.options.nitro.externals, { inline: [/#internal\/dev-server-logs-options/] });
|
|
535
|
+
addPlugin(resolve(nuxt.options.appDir, "plugins/dev-error-overlay.client"));
|
|
536
|
+
}
|
|
548
537
|
if (nuxt.options.dev && nuxt.options.features.devLogs) {
|
|
549
538
|
addPlugin(resolve(nuxt.options.appDir, "plugins/dev-server-logs"));
|
|
550
539
|
nuxt.options.nitro.plugins.push(resolve(distDir, "runtime/plugins/dev-server-logs"));
|
|
551
|
-
nuxt.options.nitro.externals = defu(nuxt.options.nitro.externals, { inline: [/#internal\/dev-server-logs-options/] });
|
|
552
|
-
nuxt.options.nitro.virtual = defu(nuxt.options.nitro.virtual, { "#internal/dev-server-logs-options": () => `export const rootDir = ${JSON.stringify(nuxt.options.rootDir)};` });
|
|
553
540
|
}
|
|
554
541
|
const clientOnlyApp = !nuxt.options.ssr;
|
|
555
542
|
if (nuxt.options.experimental.componentIslands) {
|
|
@@ -598,6 +585,7 @@ async function bundle(nuxt) {
|
|
|
598
585
|
NUXT_PRERENDER_ERROR_PAGES: JSON.stringify(errorPages),
|
|
599
586
|
NUXT_PRERENDER_NO_SSR_ROUTES: JSON.stringify(noSSRRoutes),
|
|
600
587
|
NUXT_NO_SCRIPTS_PATTERNS: JSON.stringify(noScriptsPatterns),
|
|
588
|
+
NUXT_HAS_NO_SCRIPTS_ROUTES: String(noScriptsPatterns.length > 0),
|
|
601
589
|
NUXT_PAGE_PATTERNS: JSON.stringify(pagePatterns),
|
|
602
590
|
NUXT_EARLY_404: String(early404Patterns.length > 0),
|
|
603
591
|
NUXT_PAGE_MATCHER: compilePageMatcher(early404Patterns),
|
|
@@ -673,7 +661,12 @@ async function bundle(nuxt) {
|
|
|
673
661
|
virtual: {
|
|
674
662
|
"#internal/nuxt.config.mjs": () => nuxt.vfs["#build/nuxt.config.mjs"] || "",
|
|
675
663
|
"#internal/nuxt/app-config": () => nuxt.vfs["#build/app.config.mjs"]?.replace(/\/\*\* client \*\*\/[\s\S]*\/\*\* client-end \*\*\//, "") || "",
|
|
676
|
-
"#internal/nuxt/nitro-config.mjs": () => [
|
|
664
|
+
"#internal/nuxt/nitro-config.mjs": () => [
|
|
665
|
+
`export const NUXT_ERROR_CHANNEL = ${JSON.stringify(nuxt.options.devServer.errorChannel)}`,
|
|
666
|
+
`export const NUXT_DEV_LOGS = ${!!nuxt.options.features.devLogs}`,
|
|
667
|
+
`export const NUXT_ASYNC_CONTEXT = ${!!nuxt.options.experimental.asyncContext}`,
|
|
668
|
+
`export const NUXT_SHARED_DATA = ${!!nuxt.options.experimental.sharedPrerenderData}`
|
|
669
|
+
].join("\n")
|
|
677
670
|
},
|
|
678
671
|
routeRules: {
|
|
679
672
|
...typeof nuxt.options.experimental.ssrStreaming === "object" && nuxt.options.experimental.ssrStreaming.enabled ? { "/**": { streaming: true } } : {},
|
|
@@ -1135,6 +1128,14 @@ async function bundle(nuxt) {
|
|
|
1135
1128
|
const devMiddlewareHandler = dynamicEventHandler();
|
|
1136
1129
|
nitro.options.devHandlers.unshift({ handler: devMiddlewareHandler });
|
|
1137
1130
|
nitro.options.devHandlers.push(...nuxt.options.devServerHandlers);
|
|
1131
|
+
if (nuxt.options.dev) {
|
|
1132
|
+
nitro.options.plugins.push(resolve(distDir, "runtime/plugins/dev-errors"));
|
|
1133
|
+
nitro.options.handlers.unshift({
|
|
1134
|
+
route: joinURL(nuxt.options.devServer.errorChannel, "**"),
|
|
1135
|
+
lazy: true,
|
|
1136
|
+
handler: resolve(distDir, "runtime/handlers/error-channel")
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1138
1139
|
nitro.options.handlers.unshift({
|
|
1139
1140
|
route: "/__nuxt_error",
|
|
1140
1141
|
lazy: true,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useErrorChannel } from "../utils/error-channel.mjs";
|
|
2
|
+
import { defineEventHandler, getRequestIP, toWebRequest } from "h3";
|
|
3
|
+
import { isLoopbackAddress } from "nuxt/internal/dev/peer";
|
|
4
|
+
//#region src/runtime/handlers/error-channel.ts
|
|
5
|
+
/**
|
|
6
|
+
* Serves the live error channel: the SSE stream, report lookups and "open in editor".
|
|
7
|
+
*
|
|
8
|
+
* Trust follows the socket, since a request's origin headers are forgeable over a direct
|
|
9
|
+
* connection.
|
|
10
|
+
*/
|
|
11
|
+
var error_channel_default = defineEventHandler(async (event) => {
|
|
12
|
+
const channel = await useErrorChannel();
|
|
13
|
+
const trusted = isLoopbackAddress(getRequestIP(event));
|
|
14
|
+
return await channel.fetchHandler(toWebRequest(event), { trusted }) ?? new Response("Not Found", { status: 404 });
|
|
15
|
+
});
|
|
16
|
+
//#endregion
|
|
17
|
+
export { error_channel_default as default };
|
|
@@ -1,17 +1,47 @@
|
|
|
1
1
|
import { getFetchedRequestContext } from "../utils/event.mjs";
|
|
2
2
|
import { isJsonRequest } from "../utils/error.mjs";
|
|
3
3
|
import { applyPrerenderHints } from "../utils/prerender.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import { appendResponseHeader, getResponseHeader, send, setResponseHeader, setResponseHeaders, setResponseStatus } from "h3";
|
|
4
|
+
import { appendResponseHeader, getResponseHeader, isError, send, setResponseHeader, setResponseHeaders, setResponseStatus } from "h3";
|
|
6
5
|
import { useNitroApp, useRuntimeConfig } from "nitropack/runtime";
|
|
7
6
|
import { joinURL, withQuery, withoutBase } from "ufo";
|
|
8
7
|
//#region src/runtime/handlers/error.ts
|
|
9
8
|
var error_default = async function errorhandler(error, event, { defaultHandler }) {
|
|
10
|
-
if (event.handled
|
|
11
|
-
const
|
|
9
|
+
if (event.handled) return;
|
|
10
|
+
const isRenderingError = !!(event.context.nuxt?.["~rendering-error"] || getFetchedRequestContext(event)?.["~rendering-error"]);
|
|
11
|
+
let report;
|
|
12
|
+
let errorCause;
|
|
13
|
+
if (import.meta.dev) {
|
|
14
|
+
const errorChannel = await import("../utils/error-channel.mjs");
|
|
15
|
+
const isHTTPError = isError(error);
|
|
16
|
+
report = !error.unhandled && isHTTPError && (error.statusCode || 500) < 500 && !(THROWN_VALUE in error) ? void 0 : await errorChannel.createErrorReport(error, event).catch(() => void 0);
|
|
17
|
+
errorCause = errorChannel.serializeErrorCause(error.cause);
|
|
18
|
+
if (report && !isRenderingError && !import.meta.test) await errorChannel.publishErrorReport(report, event).catch(() => {});
|
|
19
|
+
if (report && !isRenderingError && !errorChannel.shouldForwardReports() && (error.unhandled ?? !isHTTPError)) {
|
|
20
|
+
const rendered = await errorChannel.renderErrorAnsi(report).catch(() => void 0);
|
|
21
|
+
if (rendered) console.log(`[request error] [${event.method}] ${event.path}\n\n${rendered}`);
|
|
22
|
+
else console.error(`[request error] [${event.method}] ${event.path}\n\n`, error);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const stacks = import.meta.dev ? snapshotStacks(error) : void 0;
|
|
26
|
+
if (isJsonRequest(event)) {
|
|
27
|
+
if (!report) return;
|
|
28
|
+
const { headers, status, statusText, body } = await defaultHandler(error, event, {
|
|
29
|
+
json: true,
|
|
30
|
+
silent: true
|
|
31
|
+
});
|
|
32
|
+
stacks?.restore();
|
|
33
|
+
setResponseHeaders(event, headers);
|
|
34
|
+
appendVary(event, "accept, sec-fetch-mode");
|
|
35
|
+
setResponseStatus(event, status, statusText);
|
|
36
|
+
return send(event, typeof body === "string" ? body : JSON.stringify(body, null, 2));
|
|
37
|
+
}
|
|
38
|
+
const defaultRes = await defaultHandler(error, event, {
|
|
39
|
+
json: true,
|
|
40
|
+
silent: import.meta.dev && !!report
|
|
41
|
+
});
|
|
42
|
+
stacks?.restore();
|
|
12
43
|
if (import.meta.prerender) applyPrerenderHints(event);
|
|
13
|
-
|
|
14
|
-
if (status === 404 && defaultRes.status === 302) {
|
|
44
|
+
if ((error.status || error.statusCode || 500) === 404 && defaultRes.status === 302) {
|
|
15
45
|
setResponseHeaders(event, defaultRes.headers);
|
|
16
46
|
appendVary(event, "accept, sec-fetch-mode");
|
|
17
47
|
setResponseStatus(event, defaultRes.status, defaultRes.statusText);
|
|
@@ -24,12 +54,10 @@ var error_default = async function errorhandler(error, event, { defaultHandler }
|
|
|
24
54
|
errorObject.message = error.unhandled ? errorObject.message || "Server Error" : error.message || errorObject.message || "Server Error";
|
|
25
55
|
if (!error.unhandled) errorObject.data ||= error.data;
|
|
26
56
|
errorObject.statusText ||= error.statusText || error.statusMessage;
|
|
27
|
-
const errorCause = import.meta.dev ? serializeErrorCause(error.cause) : void 0;
|
|
28
57
|
delete defaultRes.headers["content-type"];
|
|
29
58
|
delete defaultRes.headers["content-security-policy"];
|
|
30
59
|
setResponseHeaders(event, defaultRes.headers);
|
|
31
60
|
appendVary(event, "accept, sec-fetch-mode");
|
|
32
|
-
const isRenderingError = !!(event.context.nuxt?.["~rendering-error"] || getFetchedRequestContext(event)?.["~rendering-error"]);
|
|
33
61
|
if (!isRenderingError) event.context.nuxt = {
|
|
34
62
|
...event.context.nuxt,
|
|
35
63
|
"~rendering-error": true
|
|
@@ -44,13 +72,20 @@ var error_default = async function errorhandler(error, event, { defaultHandler }
|
|
|
44
72
|
}).catch(() => null);
|
|
45
73
|
if (event.handled) return;
|
|
46
74
|
if (!res) {
|
|
75
|
+
setResponseHeader(event, "Content-Type", "text/html;charset=UTF-8");
|
|
76
|
+
if (import.meta.dev && isRenderingError) setResponseHeader(event, ERROR_PAGE_HEADER, "1");
|
|
77
|
+
else if (import.meta.dev && report) {
|
|
78
|
+
const { renderErrorPage } = await import("../utils/error-channel.mjs");
|
|
79
|
+
const body = await renderErrorPage(report, event).catch(() => void 0);
|
|
80
|
+
if (body) return send(event, body);
|
|
81
|
+
}
|
|
47
82
|
const { template } = await import("../templates/error-500.mjs");
|
|
48
83
|
if (import.meta.dev) errorObject.description = errorObject.message;
|
|
49
|
-
setResponseHeader(event, "Content-Type", "text/html;charset=UTF-8");
|
|
50
84
|
return send(event, template(errorObject));
|
|
51
85
|
}
|
|
52
|
-
|
|
86
|
+
let html = await res.text();
|
|
53
87
|
for (const [header, value] of res.headers.entries()) {
|
|
88
|
+
if (header === ERROR_PAGE_HEADER) continue;
|
|
54
89
|
if (header === "set-cookie" || header === "x-nitro-prerender") {
|
|
55
90
|
appendResponseHeader(event, header, value);
|
|
56
91
|
continue;
|
|
@@ -58,12 +93,39 @@ var error_default = async function errorhandler(error, event, { defaultHandler }
|
|
|
58
93
|
setResponseHeader(event, header, value);
|
|
59
94
|
}
|
|
60
95
|
setResponseStatus(event, res.status && res.status !== 200 ? res.status : defaultRes.status, res.statusText || defaultRes.statusText);
|
|
61
|
-
if (import.meta.dev && !import.meta.test && typeof html === "string") {
|
|
62
|
-
const
|
|
63
|
-
|
|
96
|
+
if (import.meta.dev && !import.meta.test && report && typeof html === "string") {
|
|
97
|
+
const { renderErrorPage, withErrorOverlay } = await import("../utils/error-channel.mjs");
|
|
98
|
+
try {
|
|
99
|
+
html = res.headers.has(ERROR_PAGE_HEADER) ? await renderErrorPage(report, event) : await withErrorOverlay(html, report, {
|
|
100
|
+
startMinimized: true,
|
|
101
|
+
event
|
|
102
|
+
});
|
|
103
|
+
} catch {}
|
|
64
104
|
}
|
|
65
105
|
return send(event, html);
|
|
66
106
|
};
|
|
107
|
+
/** The stacks of an error and its causes as raised, before Nitro rewrites them. */
|
|
108
|
+
function snapshotStacks(error) {
|
|
109
|
+
const stacks = [];
|
|
110
|
+
const seen = /* @__PURE__ */ new Set();
|
|
111
|
+
for (let current = error; current instanceof Error && !seen.has(current); current = current.cause) {
|
|
112
|
+
seen.add(current);
|
|
113
|
+
stacks.push([current, current.stack]);
|
|
114
|
+
}
|
|
115
|
+
return { restore() {
|
|
116
|
+
for (const [target, stack] of stacks) if (target.stack !== stack) try {
|
|
117
|
+
Object.defineProperty(target, "stack", {
|
|
118
|
+
value: stack,
|
|
119
|
+
writable: true,
|
|
120
|
+
configurable: true
|
|
121
|
+
});
|
|
122
|
+
} catch {}
|
|
123
|
+
} };
|
|
124
|
+
}
|
|
125
|
+
/** Set on an error created from a thrown value that was not an `Error`. */
|
|
126
|
+
const THROWN_VALUE = Symbol.for("nuxt:dev:thrown");
|
|
127
|
+
/** Set when the app's own error page could not render. */
|
|
128
|
+
const ERROR_PAGE_HEADER = "x-nuxt-error-page";
|
|
67
129
|
/**
|
|
68
130
|
* Add `value`'s tokens to the response `vary` header, keeping any already
|
|
69
131
|
* present. `*` absorbs everything else, since it means the response varies on
|
|
@@ -85,19 +147,5 @@ function appendVary(event, value) {
|
|
|
85
147
|
function parseVary(value) {
|
|
86
148
|
return (Array.isArray(value) ? value : typeof value === "string" ? value.split(",") : []).map((token) => token.trim().toLowerCase()).filter(Boolean);
|
|
87
149
|
}
|
|
88
|
-
function serializeErrorCause(cause, depth = 0, seen = /* @__PURE__ */ new WeakSet()) {
|
|
89
|
-
if (depth >= 10 || cause instanceof Error && seen.has(cause)) return;
|
|
90
|
-
if (cause instanceof Error) {
|
|
91
|
-
seen.add(cause);
|
|
92
|
-
const nestedCause = serializeErrorCause(cause.cause, depth + 1, seen);
|
|
93
|
-
return {
|
|
94
|
-
name: cause.name,
|
|
95
|
-
message: cause.message,
|
|
96
|
-
...cause.stack && { stack: cause.stack },
|
|
97
|
-
...nestedCause !== void 0 && { cause: nestedCause }
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
if (cause === null || typeof cause === "string" || typeof cause === "number" || typeof cause === "boolean") return cause;
|
|
101
|
-
}
|
|
102
150
|
//#endregion
|
|
103
151
|
export { error_default as default };
|
|
@@ -3,8 +3,8 @@ import { applyPrerenderHints } from "../utils/prerender.mjs";
|
|
|
3
3
|
import { rendererInstance } from "../utils/renderer/options.mjs";
|
|
4
4
|
import { setResponseHeader } from "h3";
|
|
5
5
|
import { defineRenderHandler } from "nitropack/runtime";
|
|
6
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
7
6
|
import { NUXT_ASYNC_CONTEXT } from "#internal/nuxt/nitro-config.mjs";
|
|
7
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8
8
|
import { createNuxtRenderer } from "nuxt/internal/renderer";
|
|
9
9
|
//#region src/runtime/handlers/renderer.ts
|
|
10
10
|
if (NUXT_ASYNC_CONTEXT && !("AsyncLocalStorage" in globalThis)) globalThis.AsyncLocalStorage = AsyncLocalStorage;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import "h3";
|
|
1
|
+
import { createError as createError$1 } from "h3";
|
|
2
2
|
export * from "h3";
|
|
3
|
-
export {};
|
|
3
|
+
export { createError$1 as createError };
|
|
@@ -1,5 +1,32 @@
|
|
|
1
|
-
import "../../../nitro-server/src/h3.mjs";
|
|
1
|
+
import { createError as createError$1 } from "../../../nitro-server/src/h3.mjs";
|
|
2
2
|
//#region ../nuxt/src/app/error.ts
|
|
3
3
|
const NUXT_ERROR_SIGNATURE = "__nuxt_error";
|
|
4
|
+
/** @since 3.0.0 */
|
|
5
|
+
const isNuxtError = (error) => !!error && typeof error === "object" && "__nuxt_error" in error;
|
|
6
|
+
/** @since 3.0.0 */
|
|
7
|
+
const createError = (error) => {
|
|
8
|
+
if (isNuxtError(error)) return error;
|
|
9
|
+
if (typeof error !== "string" && error?.statusText) error.message ??= error.statusText;
|
|
10
|
+
const nuxtError = createError$1(error ?? {});
|
|
11
|
+
Object.defineProperty(nuxtError, NUXT_ERROR_SIGNATURE, {
|
|
12
|
+
value: true,
|
|
13
|
+
configurable: false,
|
|
14
|
+
writable: false
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperty(nuxtError, "status", {
|
|
17
|
+
get: () => nuxtError.statusCode,
|
|
18
|
+
configurable: true
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(nuxtError, "statusText", {
|
|
21
|
+
get: () => nuxtError.statusMessage,
|
|
22
|
+
configurable: true
|
|
23
|
+
});
|
|
24
|
+
return nuxtError;
|
|
25
|
+
};
|
|
26
|
+
/** Set in development on an error created from a thrown value that was not an `Error`. */
|
|
27
|
+
const THROWN_VALUE = Symbol.for("nuxt:dev:thrown");
|
|
28
|
+
/** Set in development to where the app was when it threw. */
|
|
29
|
+
const THROWN_CONTEXT = Symbol.for("nuxt:dev:context");
|
|
30
|
+
import.meta.dev;
|
|
4
31
|
//#endregion
|
|
5
|
-
export { NUXT_ERROR_SIGNATURE };
|
|
32
|
+
export { NUXT_ERROR_SIGNATURE, THROWN_CONTEXT, THROWN_VALUE, createError, isNuxtError };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { publishDevLog, useErrorChannel } from "../utils/error-channel.mjs";
|
|
2
|
+
import { NUXT_DEV_LOGS } from "#internal/nuxt/nitro-config.mjs";
|
|
3
|
+
import { formatWithOptions } from "node:util";
|
|
4
|
+
import { consola } from "consola";
|
|
5
|
+
//#region src/runtime/plugins/dev-errors.ts
|
|
6
|
+
/** Opens the error channel before anything requests a page. */
|
|
7
|
+
var dev_errors_default = (_nitroApp) => {
|
|
8
|
+
useErrorChannel().catch(() => {});
|
|
9
|
+
if (NUXT_DEV_LOGS) streamLogsToChannel();
|
|
10
|
+
};
|
|
11
|
+
/** Mirror what the server logs onto the error channel. */
|
|
12
|
+
function streamLogsToChannel() {
|
|
13
|
+
let publishing = false;
|
|
14
|
+
consola.addReporter({ log(logObject) {
|
|
15
|
+
if (publishing) return;
|
|
16
|
+
publishing = true;
|
|
17
|
+
try {
|
|
18
|
+
publishDevLog(toLogEntry(logObject)).catch(() => {});
|
|
19
|
+
} finally {
|
|
20
|
+
publishing = false;
|
|
21
|
+
}
|
|
22
|
+
} });
|
|
23
|
+
}
|
|
24
|
+
function toLogEntry(logObject) {
|
|
25
|
+
const args = logObject.args ?? [];
|
|
26
|
+
const message = formatWithOptions({
|
|
27
|
+
colors: false,
|
|
28
|
+
depth: 2
|
|
29
|
+
}, ...args);
|
|
30
|
+
return {
|
|
31
|
+
level: toLogLevel(logObject),
|
|
32
|
+
text: logObject.tag ? `[${logObject.tag}] ${message}` : message,
|
|
33
|
+
timestamp: logObject.date ? new Date(logObject.date).getTime() : void 0
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const LOG_LEVELS = {
|
|
37
|
+
trace: "trace",
|
|
38
|
+
debug: "debug",
|
|
39
|
+
verbose: "debug",
|
|
40
|
+
info: "info",
|
|
41
|
+
log: "log",
|
|
42
|
+
warn: "warn",
|
|
43
|
+
error: "error",
|
|
44
|
+
fail: "error",
|
|
45
|
+
fatal: "fatal"
|
|
46
|
+
};
|
|
47
|
+
/** Fallback for consola types whose names say nothing about severity. */
|
|
48
|
+
const LOG_LEVELS_BY_SEVERITY = [
|
|
49
|
+
"error",
|
|
50
|
+
"warn",
|
|
51
|
+
"log",
|
|
52
|
+
"info",
|
|
53
|
+
"debug",
|
|
54
|
+
"trace"
|
|
55
|
+
];
|
|
56
|
+
function toLogLevel(logObject) {
|
|
57
|
+
if (LOG_LEVELS[logObject.type]) return LOG_LEVELS[logObject.type];
|
|
58
|
+
const severity = Math.round(logObject.level);
|
|
59
|
+
return LOG_LEVELS_BY_SEVERITY[Math.max(0, Math.min(severity, LOG_LEVELS_BY_SEVERITY.length - 1))] ?? "log";
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
export { dev_errors_default as default };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { serverDiagnostics } from "../diagnostics.mjs";
|
|
2
2
|
import { withTrailingSlash } from "ufo";
|
|
3
|
+
import { rootDir } from "#internal/dev-server-logs-options";
|
|
3
4
|
import { appId } from "#internal/nuxt.config.mjs";
|
|
4
5
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
6
|
import { consola } from "consola";
|
|
@@ -7,7 +8,6 @@ import { stringify } from "devalue";
|
|
|
7
8
|
import { getContext } from "unctx";
|
|
8
9
|
import { captureRawStackTrace, parseRawStackTrace } from "errx";
|
|
9
10
|
import { isVNode } from "vue";
|
|
10
|
-
import { rootDir } from "#internal/dev-server-logs-options";
|
|
11
11
|
//#region src/runtime/plugins/dev-server-logs.ts
|
|
12
12
|
const devReducers = {
|
|
13
13
|
VNode: (data) => isVNode(data) ? {
|
package/dist/runtime/server.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { NUXT_ERROR_SIGNATURE } from "./nuxt/src/app/error.mjs";
|
|
|
2
2
|
import { toPortableEvent } from "./utils/event.mjs";
|
|
3
3
|
import { createError as createError$1, deleteCookie, getCookie, getQuery as getQuery$1, getRequestHeader as getRequestHeader$1, getRequestHeaders as getRequestHeaders$1, getRequestURL, readBody, setCookie, setResponseHeader, setResponseHeaders, setResponseStatus } from "h3";
|
|
4
4
|
import { getRouteRules as getRouteRules$1, useRuntimeConfig as useRuntimeConfig$1 } from "nitropack/runtime";
|
|
5
|
-
import { toNuxtRequestEvent } from "nuxt/internal/server-default";
|
|
5
|
+
import { clearSession, deriveSecret, getSession, toNuxtRequestEvent, updateSession, useSession } from "nuxt/internal/server-default";
|
|
6
6
|
//#region src/runtime/server.ts
|
|
7
7
|
/**
|
|
8
8
|
* The `nuxt/server` implementations for a nitropack v2 build, registered as
|
|
@@ -130,4 +130,4 @@ function useRuntimeConfig(event) {
|
|
|
130
130
|
return useRuntimeConfig$1(event);
|
|
131
131
|
}
|
|
132
132
|
//#endregion
|
|
133
|
-
export { createError, defineEventHandler, deleteCookie, getCookie, getQuery, getRequestHeader, getRequestHeaders, getRequestURL, getRouteRules, isNuxtError, readBody, sendRedirect, setCookie, setResponseHeader, setResponseHeaders, setResponseStatus, toNuxtRequestEvent, useRuntimeConfig };
|
|
133
|
+
export { clearSession, createError, defineEventHandler, deleteCookie, deriveSecret, getCookie, getQuery, getRequestHeader, getRequestHeaders, getRequestURL, getRouteRules, getSession, isNuxtError, readBody, sendRedirect, setCookie, setResponseHeader, setResponseHeaders, setResponseStatus, toNuxtRequestEvent, updateSession, useRuntimeConfig, useSession };
|
|
@@ -12,7 +12,7 @@ const template = (messages) => {
|
|
|
12
12
|
..._messages,
|
|
13
13
|
...messages
|
|
14
14
|
};
|
|
15
|
-
return "<!DOCTYPE html><html lang=\"en\"><head><title>" + escapeHtml(messages.status) + " - " + escapeHtml(messages.statusText) + " | " + escapeHtml(messages.appName) + "</title><meta charset=\"utf-8\"><meta content=\"width=device-width,initial-scale=1,minimum-scale=1\" name=\"viewport\"><style>*,:after,:before{box-sizing:border-box;border-style:solid;border-width:0;border-color:var(--un-default-border-color,#e5e7eb)}:after,:before{--un-content:\"\"}html{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}h1,h2{font-size:inherit;font-weight:inherit}h1,h2,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x:;--un-pan-y:;--un-pinch-zoom:;--un-scroll-snap-strictness:proximity;--un-ordinal:;--un-slashed-zero:;--un-numeric-figure:;--un-numeric-spacing:;--un-numeric-fraction:;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 #0000;--un-ring-shadow:0 0 #0000;--un-shadow-inset:;--un-shadow:0 0 #0000;--un-ring-inset:;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:#93c5fd80;--un-blur:;--un-brightness:;--un-contrast:;--un-drop-shadow:;--un-grayscale:;--un-hue-rotate:;--un-invert:;--un-saturate:;--un-sepia:;--un-backdrop-blur:;--un-backdrop-brightness:;--un-backdrop-contrast:;--un-backdrop-grayscale:;--un-backdrop-hue-rotate:;--un-backdrop-invert:;--un-backdrop-opacity:;--un-backdrop-saturate:;--un-backdrop-sepia:}.grid{display:grid}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.max-w-520px{max-width:520px}.min-h-screen{min-height:100vh}.place-content-center{place-content:center}.overflow-hidden{overflow:hidden}.bg-white{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-2{padding-left:.5rem;padding-right:.5rem}.text-center{text-align:center}.text-\\[
|
|
15
|
+
return "<!DOCTYPE html><html lang=\"en\"><head><title>" + escapeHtml(messages.status) + " - " + escapeHtml(messages.statusText) + " | " + escapeHtml(messages.appName) + "</title><meta charset=\"utf-8\"><meta content=\"width=device-width,initial-scale=1,minimum-scale=1\" name=\"viewport\"><style>*,:after,:before{box-sizing:border-box;border-style:solid;border-width:0;border-color:var(--un-default-border-color,#e5e7eb)}:after,:before{--un-content:\"\"}html{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}h1,h2{font-size:inherit;font-weight:inherit}h1,h2,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x:;--un-pan-y:;--un-pinch-zoom:;--un-scroll-snap-strictness:proximity;--un-ordinal:;--un-slashed-zero:;--un-numeric-figure:;--un-numeric-spacing:;--un-numeric-fraction:;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 #0000;--un-ring-shadow:0 0 #0000;--un-shadow-inset:;--un-shadow:0 0 #0000;--un-ring-inset:;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:#93c5fd80;--un-blur:;--un-brightness:;--un-contrast:;--un-drop-shadow:;--un-grayscale:;--un-hue-rotate:;--un-invert:;--un-saturate:;--un-sepia:;--un-backdrop-blur:;--un-backdrop-brightness:;--un-backdrop-contrast:;--un-backdrop-grayscale:;--un-backdrop-hue-rotate:;--un-backdrop-invert:;--un-backdrop-opacity:;--un-backdrop-saturate:;--un-backdrop-sepia:}.grid{display:grid}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.max-w-520px{max-width:520px}.min-h-screen{min-height:100vh}.place-content-center{place-content:center}.overflow-hidden{overflow:hidden}.bg-white{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-2{padding-left:.5rem;padding-right:.5rem}.text-center{text-align:center}.text-\\[56px\\]{font-size:56px}.text-2xl{font-size:1.5rem;line-height:2rem}.text-neutral-500{--un-text-opacity:1;color:rgb(115 115 115/var(--un-text-opacity))}.text-neutral-950{--un-text-opacity:1;color:rgb(10 10 10/var(--un-text-opacity))}.font-medium{font-weight:500}.font-semibold{font-weight:600}.leading-none{line-height:1}.tracking-wide{letter-spacing:.025em}.font-sans{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.tabular-nums{--un-numeric-spacing:tabular-nums;font-variant-numeric:var(--un-ordinal) var(--un-slashed-zero) var(--un-numeric-figure) var(--un-numeric-spacing) var(--un-numeric-fraction)}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (prefers-color-scheme:dark){.dark\\:bg-neutral-950{--un-bg-opacity:1;background-color:rgb(10 10 10/var(--un-bg-opacity))}.dark\\:text-white{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media (width>=640px){.sm\\:text-\\[72px\\]{font-size:72px}.sm\\:text-3xl{font-size:1.875rem;line-height:2.25rem}}</style></head><body class=\"antialiased bg-white dark:bg-neutral-950 dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-neutral-950 tracking-wide\"><div class=\"max-w-520px text-center\"><h1 class=\"font-medium leading-none mb-4 sm:text-[72px] tabular-nums text-[56px]\">" + escapeHtml(messages.status) + "</h1><h2 class=\"font-semibold mb-2 sm:text-3xl text-2xl\">" + escapeHtml(messages.statusText) + "</h2><p class=\"mb-4 px-2 text-md text-neutral-500\">" + escapeHtml(messages.description) + "</p></div></body></html>";
|
|
16
16
|
};
|
|
17
17
|
//#endregion
|
|
18
18
|
export { template };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { dirname, join, resolve } from "node:path";
|
|
1
2
|
import crypto from "node:crypto";
|
|
2
3
|
import { mkdir, rename, unlink, writeFile } from "node:fs/promises";
|
|
3
|
-
import
|
|
4
|
+
import flru from "flru";
|
|
4
5
|
import { defineDriver } from "unstorage";
|
|
5
6
|
import fsDriver from "unstorage/drivers/fs-lite";
|
|
6
|
-
import lruCache from "unstorage/drivers/lru-cache";
|
|
7
7
|
//#region src/runtime/utils/cache-driver.mjs
|
|
8
8
|
/**
|
|
9
9
|
* @param {string} item
|
|
@@ -35,19 +35,20 @@ var cache_driver_default = defineDriver(
|
|
|
35
35
|
*/
|
|
36
36
|
(opts) => {
|
|
37
37
|
const fs = fsDriver({ base: opts.base });
|
|
38
|
-
|
|
38
|
+
/** flru keeps an active and a stale half, so up to 2x `max` entries are retained. */
|
|
39
|
+
const lru = flru(500);
|
|
39
40
|
const base = resolve(opts.base || ".");
|
|
40
41
|
return {
|
|
41
42
|
...fs,
|
|
42
|
-
async setItem(key, value
|
|
43
|
+
async setItem(key, value) {
|
|
43
44
|
await atomicWrite(join(base, normalizeFsKey(key)), value);
|
|
44
|
-
|
|
45
|
+
lru.set(key, value);
|
|
45
46
|
},
|
|
46
47
|
async hasItem(key, opts) {
|
|
47
|
-
return
|
|
48
|
+
return lru.has(key) || await fs.hasItem(normalizeFsKey(key), opts);
|
|
48
49
|
},
|
|
49
50
|
async getItem(key, opts) {
|
|
50
|
-
return
|
|
51
|
+
return lru.get(key) || await fs.getItem(normalizeFsKey(key), opts);
|
|
51
52
|
}
|
|
52
53
|
};
|
|
53
54
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useStorage } from "nitropack/runtime";
|
|
2
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
2
|
import { NUXT_SHARED_DATA } from "#internal/nuxt/nitro-config.mjs";
|
|
3
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
4
4
|
//#region src/runtime/utils/cache.ts
|
|
5
5
|
/**
|
|
6
6
|
* Stack of URLs currently rendering in the active async context (oldest first).
|