@nuxt/nitro-server-nightly 4.4.3-29621460.375401cc → 4.4.3-29621635.a4e85d14

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/index.d.mts CHANGED
@@ -4,8 +4,6 @@ import { Nitro, NitroConfig, NitroDevEventHandler, NitroEventHandler, NitroOptio
4
4
  import { LogObject } from "consola";
5
5
  import { NuxtIslandContext, NuxtIslandResponse, NuxtRenderHTMLContext } from "nuxt/app";
6
6
  import { HookResult, RuntimeConfig, TSReference } from "nuxt/schema";
7
-
8
- //#region src/augments.d.ts
9
7
  declare module "nitropack" {
10
8
  interface NitroRuntimeConfigApp {
11
9
  buildAssetsDir: string;
@@ -282,10 +280,7 @@ declare module "nuxt/schema" {
282
280
  rules?: NitroRouteConfig;
283
281
  }
284
282
  }
285
- //#endregion
286
- //#region src/index.d.ts
287
283
  declare function bundle(nuxt: Nuxt & {
288
284
  _nitro?: Nitro;
289
285
  }): Promise<void>;
290
- //#endregion
291
286
  export { bundle };
package/dist/index.mjs CHANGED
@@ -21,23 +21,16 @@ import { hasTTY, isCI, isWindows } from "std-env";
21
21
  import { ImpoundPlugin } from "impound";
22
22
  import { resolveModulePath } from "exsolve";
23
23
  import { runtimeDependencies } from "nitropack/runtime/meta";
24
- //#region package.json
25
- var version = "4.4.3-29621460.375401cc";
26
- //#endregion
27
- //#region src/utils.ts
24
+ var version = "4.4.3-29621635.a4e85d14";
28
25
  function toArray(value) {
29
26
  return Array.isArray(value) ? value : [value];
30
27
  }
31
28
  let _distDir = dirname(fileURLToPath(import.meta.url));
32
29
  if (/(?:chunks|shared)$/.test(_distDir)) _distDir = dirname(_distDir);
33
30
  const distDir = _distDir;
34
- //#endregion
35
- //#region ../ui-templates/dist/templates/spa-loading-icon.ts
36
31
  const template = () => {
37
32
  return "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"80\" fill=\"none\" class=\"nuxt-spa-loading\" viewBox=\"0 0 37 25\"><path d=\"M24.236 22.006h10.742L25.563 5.822l-8.979 14.31a4 4 0 0 1-3.388 1.874H2.978l11.631-20 5.897 10.567\"/></svg><style>.nuxt-spa-loading{left:50%;position:fixed;top:50%;transform:translate(-50%,-50%)}.nuxt-spa-loading>path{animation:nuxt-spa-loading-move 3s linear infinite;fill:none;stroke:#00dc82;stroke-dasharray:128;stroke-dashoffset:128;stroke-linecap:round;stroke-linejoin:round;stroke-width:4px}@keyframes nuxt-spa-loading-move{to{stroke-dashoffset:-128}}</style>";
38
33
  };
39
- //#endregion
40
- //#region ../nuxt/src/core/plugins/import-protection.ts
41
34
  function createImportProtectionPatterns(nuxt, options) {
42
35
  const patterns = [];
43
36
  const context = contextFlags[options.context];
@@ -97,8 +90,6 @@ const contextFlags = {
97
90
  "nuxt-app": "the Vue part of your app",
98
91
  "shared": "the #shared directory"
99
92
  };
100
- //#endregion
101
- //#region src/templates.ts
102
93
  const nitroSchemaTemplate = {
103
94
  filename: "types/nitro-nuxt.d.ts",
104
95
  async getContents({ nuxt }) {
@@ -175,8 +166,6 @@ declare module 'nitropack/types' {
175
166
  function renderReference(ref, baseDir) {
176
167
  return `/// <reference ${"path" in ref ? `path="${isAbsolute(ref.path) ? relative(baseDir, ref.path) : ref.path}"` : `types="${ref.types}"`} />`;
177
168
  }
178
- //#endregion
179
- //#region src/index.ts
180
169
  const logLevelMapReverse = {
181
170
  silent: 0,
182
171
  info: 3,
@@ -921,5 +910,4 @@ async function spaLoadingTemplate(nuxt) {
921
910
  if (nuxt.options.spaLoadingTemplate) logger.warn(`Could not load custom \`spaLoadingTemplate\` path as it does not exist: \`${nuxt.options.spaLoadingTemplate}\`.`);
922
911
  return "";
923
912
  }
924
- //#endregion
925
913
  export { bundle };
@@ -1,4 +1,2 @@
1
- /**
2
- * h3 compatibility layer for Nuxt runtime code.
3
- */
1
+
4
2
  export * from "h3";
@@ -5,12 +5,12 @@ import { isJsonRequest } from "../utils/error.mjs";
5
5
  import { generateErrorOverlayHTML } from "../utils/dev.mjs";
6
6
  export default (async function errorhandler(error, event, { defaultHandler }) {
7
7
  if (event.handled || isJsonRequest(event)) {
8
- // let Nitro handle JSON errors
8
+
9
9
  return;
10
10
  }
11
- // invoke default Nitro error handler (which will log appropriately if required)
11
+
12
12
  const defaultRes = await defaultHandler(error, event, { json: true });
13
- // let Nitro handle redirect if appropriate
13
+
14
14
  const status = error.status || error.statusCode || 500;
15
15
  if (status === 404 && defaultRes.status === 302) {
16
16
  setResponseHeaders(event, defaultRes.headers);
@@ -18,26 +18,26 @@ export default (async function errorhandler(error, event, { defaultHandler }) {
18
18
  return send(event, JSON.stringify(defaultRes.body, null, 2));
19
19
  }
20
20
  if (import.meta.dev && typeof defaultRes.body !== "string" && Array.isArray(defaultRes.body.stack)) {
21
- // normalize to string format expected by nuxt `error.vue`
21
+
22
22
  defaultRes.body.stack = defaultRes.body.stack.join("\n");
23
23
  }
24
24
  const errorObject = defaultRes.body;
25
- // remove proto/hostname/port from URL
25
+
26
26
  const url = new URL(errorObject.url);
27
27
  errorObject.url = withoutBase(url.pathname, useRuntimeConfig(event).app.baseURL) + url.search + url.hash;
28
- // add default server message (keep sanitized for unhandled errors)
28
+
29
29
  errorObject.message = error.unhandled ? errorObject.message || "Server Error" : error.message || errorObject.message || "Server Error";
30
- // we will be rendering this error internally so we can pass along the error.data safely
30
+
31
31
  errorObject.data ||= error.data;
32
32
  errorObject.statusText ||= error.statusText || error.statusMessage;
33
33
  delete defaultRes.headers["content-type"];
34
34
  delete defaultRes.headers["content-security-policy"];
35
35
  setResponseHeaders(event, defaultRes.headers);
36
- // Access request headers
36
+
37
37
  const reqHeaders = getRequestHeaders(event);
38
- // Detect to avoid recursion in SSR rendering of errors
38
+
39
39
  const isRenderingError = event.path.startsWith("/__nuxt_error") || !!reqHeaders["x-nuxt-error"];
40
- // HTML response (via SSR)
40
+
41
41
  const res = isRenderingError ? null : await useNitroApp().localFetch(withQuery(joinURL(useRuntimeConfig(event).app.baseURL, "/__nuxt_error"), errorObject), {
42
42
  headers: {
43
43
  ...reqHeaders,
@@ -48,11 +48,11 @@ export default (async function errorhandler(error, event, { defaultHandler }) {
48
48
  if (event.handled) {
49
49
  return;
50
50
  }
51
- // Fallback to static rendered error page
51
+
52
52
  if (!res) {
53
53
  const { template } = await import("../templates/error-500");
54
54
  if (import.meta.dev) {
55
- // TODO: Support `message` in template
55
+
56
56
  errorObject.description = errorObject.message;
57
57
  }
58
58
  setResponseHeader(event, "Content-Type", "text/html;charset=UTF-8");
@@ -26,13 +26,13 @@ const handler = defineEventHandler(async (event) => {
26
26
  noSSR: false,
27
27
  url: islandContext.url
28
28
  };
29
- // Render app
29
+
30
30
  const renderer = await getSSRRenderer();
31
31
  const renderResult = await renderer.renderToString(ssrContext).catch(async (err) => {
32
32
  await ssrContext.nuxt?.hooks.callHook("app:error", err);
33
33
  throw err;
34
34
  });
35
- // Handle errors
35
+
36
36
  if (ssrContext.payload?.error) {
37
37
  throw ssrContext.payload.error;
38
38
  }
@@ -48,12 +48,12 @@ const handler = defineEventHandler(async (event) => {
48
48
  const { styles } = getRequestDependencies(ssrContext, renderer.rendererContext);
49
49
  const link = [];
50
50
  for (const resource of Object.values(styles)) {
51
- // Do not add links to resources that are inlined (vite v5+)
51
+
52
52
  if ("inline" in getURLQuery(resource.file)) {
53
53
  continue;
54
54
  }
55
- // Add CSS links in <head> for CSS files
56
- // - in dev mode when rendering an island and the file has scoped styles and is not a page
55
+
56
+
57
57
  if (resource.file.includes("scoped") && !resource.file.includes("pages/")) {
58
58
  link.push({
59
59
  rel: "stylesheet",
@@ -68,7 +68,7 @@ const handler = defineEventHandler(async (event) => {
68
68
  }
69
69
  const islandHead = {};
70
70
  for (const entry of ssrContext.head.entries.values()) {
71
- // eslint-disable-next-line @typescript-eslint/no-deprecated
71
+
72
72
  for (const [key, value] of Object.entries(resolveUnrefHeadInput(entry.input))) {
73
73
  const currentValue = islandHead[key];
74
74
  if (Array.isArray(currentValue)) {
@@ -101,7 +101,7 @@ const VALID_COMPONENT_NAME_RE = /^[a-z][\w.-]*$/i;
101
101
  async function getIslandContext(event) {
102
102
  let url = event.path || "";
103
103
  if (import.meta.prerender && event.path && await islandPropCache.hasItem(event.path)) {
104
- // rehydrate props from cache so we can rerender island if cache does not have it any more
104
+
105
105
  url = await islandPropCache.getItem(event.path);
106
106
  }
107
107
  if (!url.startsWith(ISLAND_PATH_PREFIX)) {
@@ -120,7 +120,7 @@ async function getIslandContext(event) {
120
120
  });
121
121
  }
122
122
  const context = event.method === "GET" ? getQuery(event) : await readBody(event);
123
- // Only extract known context fields to prevent arbitrary data injection
123
+
124
124
  return {
125
125
  url: typeof context?.url === "string" ? context.url : "/",
126
126
  id: hashId,
@@ -28,7 +28,7 @@ import { relative } from "pathe";
28
28
  globalThis.__buildAssetsURL = buildAssetsURL;
29
29
  // @ts-expect-error private property consumed by vite-generated url helpers
30
30
  globalThis.__publicAssetsURL = publicAssetsURL;
31
- // Polyfill for unctx (https://github.com/unjs/unctx#native-async-context)
31
+
32
32
  if (NUXT_ASYNC_CONTEXT && !("AsyncLocalStorage" in globalThis)) {
33
33
  globalThis.AsyncLocalStorage = AsyncLocalStorage;
34
34
  }
@@ -40,7 +40,7 @@ const PAYLOAD_FILENAME = NUXT_JSON_PAYLOADS ? "_payload.json" : "_payload.js";
40
40
  let entryPath;
41
41
  const handler = defineRenderHandler(async (event) => {
42
42
  const nitroApp = useNitroApp();
43
- // Whether we're rendering an error page
43
+
44
44
  const ssrError = event.path.startsWith("/__nuxt_error") ? getQuery(event) : null;
45
45
  if (ssrError && !("__unenv__" in event.node.req)) {
46
46
  throw createError({
@@ -49,16 +49,16 @@ const handler = defineRenderHandler(async (event) => {
49
49
  message: "Page Not Found: /__nuxt_error"
50
50
  });
51
51
  }
52
- // Initialize ssr context
52
+
53
53
  const ssrContext = createSSRContext(event);
54
- // needed for hash hydration plugin to work
54
+
55
55
  const headEntryOptions = { mode: "server" };
56
56
  ssrContext.head.push(appHead, headEntryOptions);
57
57
  if (ssrError) {
58
- // eslint-disable-next-line @typescript-eslint/no-deprecated
58
+
59
59
  const status = ssrError.status || ssrError.statusCode;
60
60
  if (status) {
61
- // eslint-disable-next-line @typescript-eslint/no-deprecated
61
+
62
62
  ssrError.status = ssrError.statusCode = Number.parseInt(status);
63
63
  }
64
64
  if (PARSE_ERROR_DATA && typeof ssrError.data === "string") {
@@ -68,13 +68,13 @@ const handler = defineRenderHandler(async (event) => {
68
68
  }
69
69
  setSSRError(ssrContext, ssrError);
70
70
  }
71
- // Get route options (for `ssr: false`, `isr`, `cache` and `noScripts`)
71
+
72
72
  const routeOptions = getRouteRules(event);
73
- // Whether we are prerendering route or using ISR/SWR caching
73
+
74
74
  const _PAYLOAD_EXTRACTION = !ssrContext.noSSR && (import.meta.prerender && NUXT_PAYLOAD_EXTRACTION || NUXT_RUNTIME_PAYLOAD_EXTRACTION && (routeOptions.isr || routeOptions.cache));
75
- // When NUXT_PAYLOAD_INLINE is true (payloadExtraction: 'client'), we inline the full payload
76
- // in the HTML to avoid a separate _payload.json fetch on initial load (which would trigger a
77
- // second render or lambda invocation). The _payload.json endpoint still works for client-side nav.
75
+
76
+
77
+
78
78
  const _PAYLOAD_INLINE = !_PAYLOAD_EXTRACTION || NUXT_PAYLOAD_INLINE;
79
79
  const isRenderingPayload = (_PAYLOAD_EXTRACTION || import.meta.dev && routeOptions.prerender) && PAYLOAD_URL_RE.test(ssrContext.url);
80
80
  if (isRenderingPayload) {
@@ -89,9 +89,9 @@ const handler = defineRenderHandler(async (event) => {
89
89
  ssrContext.noSSR = true;
90
90
  }
91
91
  const payloadURL = _PAYLOAD_EXTRACTION ? joinURL(ssrContext.runtimeConfig.app.cdnURL || ssrContext.runtimeConfig.app.baseURL, ssrContext.url.replace(/\?.*$/, ""), PAYLOAD_FILENAME) + "?" + ssrContext.runtimeConfig.app.buildId : undefined;
92
- // Render app
92
+
93
93
  const renderer = await getRenderer(ssrContext);
94
- // Render 103 Early Hints
94
+
95
95
  if (NUXT_EARLY_HINTS && !isRenderingPayload && !import.meta.prerender) {
96
96
  const { link } = renderResourceHeaders({}, renderer.rendererContext);
97
97
  if (link) {
@@ -104,32 +104,32 @@ const handler = defineRenderHandler(async (event) => {
104
104
  }
105
105
  }
106
106
  const _rendered = await renderer.renderToString(ssrContext).catch(async (error) => {
107
- // We use error to bypass full render if we have an early response we can make
108
- // TODO: remove _renderResponse in nuxt v5
107
+
108
+
109
109
  if ((ssrContext["~renderResponse"] || ssrContext._renderResponse) && error.message === "skipping render") {
110
110
  return {};
111
111
  }
112
- // Use explicitly thrown error in preference to subsequent rendering errors
112
+
113
113
  const _err = !ssrError && ssrContext.payload?.error || error;
114
114
  await ssrContext.nuxt?.hooks.callHook("app:error", _err);
115
115
  throw _err;
116
116
  });
117
- // Render inline styles
118
- // TODO: remove _renderResponse in nuxt v5
117
+
118
+
119
119
  const inlinedStyles = NUXT_INLINE_STYLES && !ssrContext["~renderResponse"] && !ssrContext._renderResponse && !isRenderingPayload ? await renderInlineStyles(ssrContext.modules ?? []) : [];
120
120
  await ssrContext.nuxt?.hooks.callHook("app:rendered", {
121
121
  ssrContext,
122
122
  renderResult: _rendered
123
123
  });
124
124
  if (ssrContext["~renderResponse"] || ssrContext._renderResponse) {
125
- // TODO: remove _renderResponse in nuxt v5
125
+
126
126
  return ssrContext["~renderResponse"] || ssrContext._renderResponse;
127
127
  }
128
- // Handle errors
128
+
129
129
  if (ssrContext.payload?.error && !ssrError) {
130
130
  throw ssrContext.payload.error;
131
131
  }
132
- // Directly render payload routes
132
+
133
133
  if (isRenderingPayload) {
134
134
  const response = renderPayloadResponse(ssrContext);
135
135
  if (payloadCache) {
@@ -139,29 +139,29 @@ const handler = defineRenderHandler(async (event) => {
139
139
  }
140
140
  if (_PAYLOAD_EXTRACTION) {
141
141
  if (import.meta.prerender) {
142
- // Hint nitro to prerender payload for this route
142
+
143
143
  appendResponseHeader(event, "x-nitro-prerender", joinURL(ssrContext.url.replace(/\?.*$/, ""), PAYLOAD_FILENAME));
144
144
  }
145
- // Cache payload from the current SSR context so _payload.json requests can be served
146
- // without a full re-render (during prerender via LRU+FS, at runtime via in-memory TTL cache)
145
+
146
+
147
147
  if (payloadCache) {
148
148
  await payloadCache.setItem(ssrContext.url === "/" ? "/" : ssrContext.url.replace(/\/$/, ""), renderPayloadResponse(ssrContext));
149
149
  }
150
150
  }
151
151
  const NO_SCRIPTS = NUXT_NO_SCRIPTS || routeOptions.noScripts;
152
- // Setup head
152
+
153
153
  const { styles, scripts } = getRequestDependencies(ssrContext, renderer.rendererContext);
154
- // 0. Add import map for stable chunk hashes
154
+
155
155
  if (entryFileName && !NO_SCRIPTS) {
156
156
  let path = entryPath;
157
157
  if (!path) {
158
158
  path = buildAssetsURL(entryFileName);
159
159
  if (ssrContext.runtimeConfig.app.cdnURL || /^(?:\/|\.+\/)/.test(path)) {
160
- // cache absolute entry path
160
+
161
161
  entryPath = path;
162
162
  } else {
163
- // TODO: provide support for relative paths in assets as well
164
- // relativise path
163
+
164
+
165
165
  path = relative(event.path.replace(/\/[^/]+$/, "/"), joinURL("/", path));
166
166
  if (!/^(?:\/|\.+\/)/.test(path)) {
167
167
  path = `./${path}`;
@@ -175,8 +175,8 @@ const handler = defineRenderHandler(async (event) => {
175
175
  innerHTML: JSON.stringify({ imports: { "#entry": path } })
176
176
  }] }, headEntryOptions);
177
177
  }
178
- // 1. Preload payloads and app manifest
179
- // Skip preload when inlining full payload in HTML (no separate fetch needed for initial load)
178
+
179
+
180
180
  if (_PAYLOAD_EXTRACTION && !_PAYLOAD_INLINE && !NO_SCRIPTS) {
181
181
  ssrContext.head.push({ link: [NUXT_JSON_PAYLOADS ? {
182
182
  rel: "preload",
@@ -189,19 +189,19 @@ const handler = defineRenderHandler(async (event) => {
189
189
  href: payloadURL
190
190
  }] }, headEntryOptions);
191
191
  }
192
- // 2. Styles
192
+
193
193
  if (inlinedStyles.length) {
194
194
  ssrContext.head.push({ style: inlinedStyles });
195
195
  }
196
196
  const link = [];
197
197
  for (const resource of Object.values(styles)) {
198
- // Do not add links to resources that are inlined (vite v5+)
198
+
199
199
  if (import.meta.dev && "inline" in getURLQuery(resource.file)) {
200
200
  continue;
201
201
  }
202
- // Add CSS links in <head> for CSS files
203
- // - in production
204
- // - in dev mode when not rendering an island
202
+
203
+
204
+
205
205
  link.push({
206
206
  rel: "stylesheet",
207
207
  href: renderer.rendererContext.buildAssetsURL(resource.file),
@@ -212,9 +212,9 @@ const handler = defineRenderHandler(async (event) => {
212
212
  ssrContext.head.push({ link }, headEntryOptions);
213
213
  }
214
214
  if (!NO_SCRIPTS) {
215
- // 4. Resource Hints
216
- // Remove lazy hydrated modules from ssrContext.modules so they don't get preloaded
217
- // (CSS links are already added above, this only affects JS preloads)
215
+
216
+
217
+
218
218
  if (ssrContext["~lazyHydratedModules"]) {
219
219
  for (const id of ssrContext["~lazyHydratedModules"]) {
220
220
  ssrContext.modules?.delete(id);
@@ -222,7 +222,7 @@ const handler = defineRenderHandler(async (event) => {
222
222
  }
223
223
  ssrContext.head.push({ link: getPreloadLinks(ssrContext, renderer.rendererContext) }, headEntryOptions);
224
224
  ssrContext.head.push({ link: getPrefetchLinks(ssrContext, renderer.rendererContext) }, headEntryOptions);
225
- // 5. Payloads
225
+
226
226
  ssrContext.head.push({ script: _PAYLOAD_INLINE ? NUXT_JSON_PAYLOADS ? renderPayloadJsonScript({
227
227
  ssrContext,
228
228
  data: ssrContext.payload
@@ -241,23 +241,26 @@ const handler = defineRenderHandler(async (event) => {
241
241
  src: payloadURL
242
242
  }) }, {
243
243
  ...headEntryOptions,
244
+
244
245
  tagPosition: "bodyClose",
245
246
  tagPriority: "high"
246
247
  });
247
248
  }
248
- // 6. Scripts
249
+
249
250
  if (!routeOptions.noScripts) {
250
251
  const tagPosition = _PAYLOAD_EXTRACTION && !_PAYLOAD_INLINE && !NUXT_JSON_PAYLOADS ? "bodyClose" : "head";
251
252
  ssrContext.head.push({ script: Object.values(scripts).map((resource) => ({
252
253
  type: resource.module ? "module" : null,
253
254
  src: renderer.rendererContext.buildAssetsURL(resource.file),
254
255
  defer: resource.module ? null : true,
256
+
257
+
255
258
  tagPosition,
256
259
  crossorigin: ""
257
260
  })) }, headEntryOptions);
258
261
  }
259
262
  const { headTags, bodyTags, bodyTagsOpen, htmlAttrs, bodyAttrs } = await renderSSRHead(ssrContext.head, renderSSRHeadOptions);
260
- // Create render context
263
+
261
264
  const htmlContext = {
262
265
  htmlAttrs: htmlAttrs ? [htmlAttrs] : [],
263
266
  head: normalizeChunks([headTags]),
@@ -266,9 +269,9 @@ const handler = defineRenderHandler(async (event) => {
266
269
  body: [componentIslands ? replaceIslandTeleports(ssrContext, _rendered.html) : _rendered.html, APP_TELEPORT_OPEN_TAG + (HAS_APP_TELEPORTS ? joinTags([ssrContext.teleports?.[`#${appTeleportAttrs.id}`]]) : "") + APP_TELEPORT_CLOSE_TAG],
267
270
  bodyAppend: [bodyTags]
268
271
  };
269
- // Allow hooking into the rendered result
272
+
270
273
  await nitroApp.hooks.callHook("render:html", htmlContext, { event });
271
- // Construct HTML response
274
+
272
275
  return {
273
276
  body: renderHTMLDocument(htmlContext),
274
277
  statusCode: getResponseStatus(event),
@@ -55,10 +55,12 @@ export default (nitroApp) => {
55
55
  }
56
56
  const log = {
57
57
  ..._log,
58
+
58
59
  filename,
60
+
59
61
  stack: trace
60
62
  };
61
- // retain log to be include in the next render
63
+
62
64
  ctx.logs.push(log);
63
65
  });
64
66
  nitroApp.hooks.hook("afterResponse", () => {
@@ -71,7 +73,7 @@ export default (nitroApp) => {
71
73
  path: ctx.event.path
72
74
  });
73
75
  });
74
- // Pass any logs to the client
76
+
75
77
  nitroApp.hooks.hook("render:html", (htmlContext) => {
76
78
  const ctx = asyncContext.tryUse();
77
79
  if (!ctx) {
@@ -1,24 +1,24 @@
1
1
  import { klona } from "klona";
2
2
  // @ts-expect-error virtual file
3
3
  import _inlineAppConfig from "#internal/nuxt/app-config";
4
- // App config
4
+
5
5
  const _sharedAppConfig = _deepFreeze(klona(_inlineAppConfig));
6
6
  export function useAppConfig(event) {
7
- // Backwards compatibility with ambient context
7
+
8
8
  if (!event) {
9
9
  return _sharedAppConfig;
10
10
  }
11
11
  event.context.nuxt ||= {};
12
- // Reuse cached app config from event context
12
+
13
13
  if (event.context.nuxt.appConfig) {
14
14
  return event.context.nuxt.appConfig;
15
15
  }
16
- // Prepare app config for event context
16
+
17
17
  const appConfig = klona(_inlineAppConfig);
18
18
  event.context.nuxt.appConfig = appConfig;
19
19
  return appConfig;
20
20
  }
21
- // --- Utils ---
21
+
22
22
  function _deepFreeze(object) {
23
23
  const propNames = Object.getOwnPropertyNames(object);
24
24
  for (const name of propNames) {
@@ -1,9 +1,7 @@
1
1
  import { getRequestHeader } from "h3";
2
- /**
3
- * Nitro internal functions extracted from https://github.com/nitrojs/nitro/blob/v2/src/runtime/internal/utils.ts
4
- */
2
+
5
3
  export function isJsonRequest(event) {
6
- // If the client specifically requests HTML, then avoid classifying as JSON.
4
+
7
5
  if (hasReqHeader(event, "accept", "text/html")) {
8
6
  return false;
9
7
  }
@@ -1,18 +1,18 @@
1
1
  import { joinRelativeURL } from "ufo";
2
2
  import { useRuntimeConfig } from "nitropack/runtime";
3
3
  export function baseURL() {
4
- // TODO: support passing event to `useRuntimeConfig`
4
+
5
5
  return useRuntimeConfig().app.baseURL;
6
6
  }
7
7
  export function buildAssetsDir() {
8
- // TODO: support passing event to `useRuntimeConfig`
8
+
9
9
  return useRuntimeConfig().app.buildAssetsDir;
10
10
  }
11
11
  export function buildAssetsURL(...path) {
12
12
  return joinRelativeURL(publicAssetsURL(), buildAssetsDir(), ...path);
13
13
  }
14
14
  export function publicAssetsURL(...path) {
15
- // TODO: support passing event to `useRuntimeConfig`
15
+
16
16
  const app = useRuntimeConfig().app;
17
17
  const publicBase = app.cdnURL || app.baseURL;
18
18
  return path.length ? joinRelativeURL(publicBase, ...path) : publicBase;
@@ -20,16 +20,16 @@ const getServerEntry = () => import("#build/dist/server/server.mjs").then((r) =>
20
20
  const getClientManifest = () => import("#build/dist/server/client.manifest.mjs").then((r) => r.default || r).then((r) => typeof r === "function" ? r() : r);
21
21
  // @ts-expect-error file will be produced after app build
22
22
  const getPrecomputedDependencies = () => import("#build/dist/server/client.precomputed.mjs").then((r) => r.default || r).then((r) => typeof r === "function" ? r() : r);
23
- // -- SSR Renderer --
23
+
24
24
  export const getSSRRenderer = lazyCachedFunction(async () => {
25
- // Load server bundle
25
+
26
26
  const createSSRApp = await getServerEntry();
27
27
  if (!createSSRApp) {
28
28
  throw new Error("Server bundle is not available");
29
29
  }
30
- // Load precomputed dependencies
30
+
31
31
  const precomputed = import.meta.dev ? undefined : await getPrecomputedDependencies();
32
- // Create renderer
32
+
33
33
  const renderer = createRenderer(createSSRApp, {
34
34
  precomputed,
35
35
  manifest: import.meta.dev ? await getClientManifest() : undefined,
@@ -38,8 +38,8 @@ export const getSSRRenderer = lazyCachedFunction(async () => {
38
38
  });
39
39
  async function renderToString(input, context) {
40
40
  const html = await _renderToString(input, context);
41
- // In development with vite-node, the manifest is on-demand and will be available after rendering
42
- // eslint-disable-next-line no-restricted-globals
41
+
42
+
43
43
  if (import.meta.dev && process.env.NUXT_VITE_NODE_OPTIONS) {
44
44
  renderer.rendererContext.updateManifest(await getClientManifest());
45
45
  }
@@ -47,7 +47,7 @@ export const getSSRRenderer = lazyCachedFunction(async () => {
47
47
  }
48
48
  return renderer;
49
49
  });
50
- // -- SPA Renderer --
50
+
51
51
  const getSPARenderer = lazyCachedFunction(async () => {
52
52
  const precomputed = import.meta.dev ? undefined : await getPrecomputedDependencies();
53
53
  // @ts-expect-error virtual file
@@ -62,7 +62,7 @@ const getSPARenderer = lazyCachedFunction(async () => {
62
62
  return APP_ROOT_OPEN_TAG + r + APP_ROOT_CLOSE_TAG;
63
63
  }
64
64
  });
65
- // Create SPA renderer and cache the result for all requests
65
+
66
66
  const renderer = createRenderer(() => () => {}, {
67
67
  precomputed,
68
68
  manifest: import.meta.dev ? await getClientManifest() : undefined,
@@ -1,9 +1,7 @@
1
1
  // @ts-expect-error virtual file
2
2
  import { appRootTag } from "#internal/nuxt.config.mjs";
3
3
  const ROOT_NODE_REGEX = new RegExp(`^<${appRootTag}[^>]*>([\\s\\S]*)<\\/${appRootTag}>$`);
4
- /**
5
- * remove the root node from the html body
6
- */
4
+
7
5
  export function getServerComponentHTML(body) {
8
6
  const match = body.match(ROOT_NODE_REGEX);
9
7
  return match?.[1] || body;
@@ -30,7 +28,7 @@ export function getClientIslandResponse(ssrContext) {
30
28
  }
31
29
  const response = {};
32
30
  for (const [clientUid, component] of Object.entries(ssrContext.islandContext.components)) {
33
- // remove teleport anchor to avoid hydration issues
31
+
34
32
  const html = ssrContext.teleports?.[clientUid]?.replaceAll("<!--teleport start anchor-->", "") || "";
35
33
  response[clientUid] = {
36
34
  ...component,
@@ -33,18 +33,11 @@ export function renderPayloadJsonScript(opts) {
33
33
  const config = uneval(opts.ssrContext.config);
34
34
  return [payload, { innerHTML: multiApp ? `window.__NUXT__=window.__NUXT__||{};window.__NUXT__[${JSON.stringify(appId)}]={config:${config}}` : `window.__NUXT__={};window.__NUXT__.config=${config}` }];
35
35
  }
36
- /**
37
- * Encode forward slashes as unicode escape sequences to prevent
38
- * Google from treating them as internal links and trying to crawl them.
39
- * @see https://github.com/nuxt/nuxt/issues/24175
40
- */
36
+
41
37
  function encodeForwardSlashes(str) {
42
38
  return str.replaceAll("/", "\\u002F");
43
39
  }
44
- /**
45
- * Escape a string for safe interpolation inside a double-quoted JavaScript string literal.
46
- * Prevents XSS when user-controlled URLs are embedded in inline `<script>` tags.
47
- */
40
+
48
41
  function escapeJsString(str) {
49
42
  return str.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"").replaceAll("\n", "\\n").replaceAll("\r", "\\r").replaceAll("/", "\\u002F").replaceAll("<", "\\u003C");
50
43
  }
@@ -52,7 +45,7 @@ export function renderPayloadScript(opts) {
52
45
  opts.data.config = opts.ssrContext.config;
53
46
  const nuxtData = devalue(opts.data);
54
47
  if (opts.src) {
55
- // Escape the URL to prevent XSS when interpolated into a JS string literal
48
+
56
49
  const escapedSrc = escapeJsString(opts.src);
57
50
  const singleAppPayload = `import p from "${escapedSrc}";window.__NUXT__={...p,...(${nuxtData})}`;
58
51
  const multiAppPayload = `import p from "${escapedSrc}";window.__NUXT__=window.__NUXT__||{};window.__NUXT__[${JSON.stringify(appId)}]={...p,...(${nuxtData})}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt/nitro-server-nightly",
3
- "version": "4.4.3-29621460.375401cc",
3
+ "version": "4.4.3-29621635.a4e85d14",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/nuxt/nuxt.git",
@@ -28,13 +28,13 @@
28
28
  "dependencies": {
29
29
  "@babel/plugin-syntax-typescript": "^7.28.6",
30
30
  "@nuxt/devalue": "^2.0.2",
31
- "@nuxt/kit": "npm:@nuxt/kit-nightly@4.4.3-29621460.375401cc",
32
- "@unhead/vue": "^2.1.12",
33
- "@vue/shared": "^3.5.30",
31
+ "@nuxt/kit": "npm:@nuxt/kit-nightly@4.4.3-29621635.a4e85d14",
32
+ "@unhead/vue": "^2.1.13",
33
+ "@vue/shared": "^3.5.33",
34
34
  "consola": "^3.4.2",
35
- "defu": "^6.1.4",
35
+ "defu": "^6.1.7",
36
36
  "destr": "^2.0.5",
37
- "devalue": "^5.6.4",
37
+ "devalue": "^5.7.1",
38
38
  "errx": "^0.1.0",
39
39
  "escape-string-regexp": "^5.0.0",
40
40
  "exsolve": "^1.0.8",
@@ -43,22 +43,22 @@
43
43
  "klona": "^2.0.6",
44
44
  "mocked-exports": "^0.1.1",
45
45
  "nitropack": "^2.13.1",
46
- "nypm": "^0.6.5",
46
+ "nypm": "^0.6.6",
47
47
  "ohash": "^2.0.11",
48
48
  "pathe": "^2.0.3",
49
49
  "rou3": "^0.8.1",
50
- "std-env": "^4.0.0",
50
+ "std-env": "^4.1.0",
51
51
  "ufo": "^1.6.3",
52
52
  "unctx": "^2.5.0",
53
53
  "unstorage": "^1.17.4",
54
- "vue": "^3.5.30",
54
+ "vue": "^3.5.33",
55
55
  "vue-bundle-renderer": "^2.2.0",
56
56
  "vue-devtools-stub": "^0.1.0"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "@babel/plugin-proposal-decorators": "^7.25.0",
60
60
  "@rollup/plugin-babel": "^6.0.0 || ^7.0.0",
61
- "nuxt": "npm:nuxt-nightly@4.4.3-29621460.375401cc"
61
+ "nuxt": "npm:nuxt-nightly@4.4.3-29621635.a4e85d14"
62
62
  },
63
63
  "peerDependenciesMeta": {
64
64
  "@babel/plugin-proposal-decorators": {
@@ -70,11 +70,11 @@
70
70
  },
71
71
  "devDependencies": {
72
72
  "@babel/plugin-proposal-decorators": "7.29.0",
73
- "@nuxt/schema": "npm:@nuxt/schema-nightly@4.4.3-29621460.375401cc",
73
+ "@nuxt/schema": "npm:@nuxt/schema-nightly@4.4.3-29621635.a4e85d14",
74
74
  "@rollup/plugin-babel": "7.0.0",
75
- "nuxt": "npm:nuxt-nightly@4.4.3-29621460.375401cc",
76
- "obuild": "0.4.32",
77
- "vitest": "4.0.18"
75
+ "nuxt": "npm:nuxt-nightly@4.4.3-29621635.a4e85d14",
76
+ "obuild": "0.4.33",
77
+ "vitest": "4.1.5"
78
78
  },
79
79
  "engines": {
80
80
  "node": "^20.19.0 || >=22.12.0"