@nuxt/nitro-server 4.3.1 → 4.4.2

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.
@@ -10,7 +10,7 @@ interface Renderer {
10
10
  renderScripts: () => string;
11
11
  }>;
12
12
  }
13
- export declare const getSSRRenderer: unknown;
13
+ export declare const getSSRRenderer: () => Promise<Renderer>;
14
14
  export declare function getRenderer(ssrContext: NuxtSSRContext): Promise<Renderer>;
15
- export declare const getSSRStyles: unknown;
15
+ export declare const getSSRStyles: () => Promise<Record<string, () => Promise<string[]>>>;
16
16
  export {};
@@ -4,10 +4,10 @@ import { stringify, uneval } from "devalue";
4
4
  // @ts-expect-error virtual file
5
5
  import { appId, multiApp } from "#internal/nuxt.config.mjs";
6
6
  // @ts-expect-error virtual file
7
- import { NUXT_JSON_PAYLOADS, NUXT_NO_SSR, NUXT_PAYLOAD_EXTRACTION, NUXT_RUNTIME_PAYLOAD_EXTRACTION } from "#internal/nuxt/nitro-config.mjs";
7
+ import { NUXT_JSON_PAYLOADS, NUXT_NO_SSR } from "#internal/nuxt/nitro-config.mjs";
8
8
  export function renderPayloadResponse(ssrContext) {
9
9
  return {
10
- body: NUXT_JSON_PAYLOADS ? stringify(splitPayload(ssrContext).payload, ssrContext["~payloadReducers"]) : `export default ${devalue(splitPayload(ssrContext).payload)}`,
10
+ body: NUXT_JSON_PAYLOADS ? encodeForwardSlashes(stringify(splitPayload(ssrContext).payload, ssrContext["~payloadReducers"])) : `export default ${devalue(splitPayload(ssrContext).payload)}`,
11
11
  statusCode: getResponseStatus(ssrContext.event),
12
12
  statusMessage: getResponseStatusText(ssrContext.event),
13
13
  headers: {
@@ -17,7 +17,7 @@ export function renderPayloadResponse(ssrContext) {
17
17
  };
18
18
  }
19
19
  export function renderPayloadJsonScript(opts) {
20
- const contents = opts.data ? stringify(opts.data, opts.ssrContext["~payloadReducers"]) : "";
20
+ const contents = opts.data ? encodeForwardSlashes(stringify(opts.data, opts.ssrContext["~payloadReducers"])) : "";
21
21
  const payload = {
22
22
  "type": "application/json",
23
23
  "innerHTML": contents,
@@ -33,13 +33,29 @@ 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
+ */
41
+ function encodeForwardSlashes(str) {
42
+ return str.replaceAll("/", "\\u002F");
43
+ }
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
+ */
48
+ function escapeJsString(str) {
49
+ return str.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"").replaceAll("\n", "\\n").replaceAll("\r", "\\r").replaceAll("/", "\\u002F").replaceAll("<", "\\u003C");
50
+ }
36
51
  export function renderPayloadScript(opts) {
37
52
  opts.data.config = opts.ssrContext.config;
38
- const _PAYLOAD_EXTRACTION = !opts.ssrContext.noSSR && (import.meta.prerender && NUXT_PAYLOAD_EXTRACTION || NUXT_RUNTIME_PAYLOAD_EXTRACTION && (opts.routeOptions.isr || opts.routeOptions.cache));
39
53
  const nuxtData = devalue(opts.data);
40
- if (_PAYLOAD_EXTRACTION) {
41
- const singleAppPayload = `import p from "${opts.src}";window.__NUXT__={...p,...(${nuxtData})}`;
42
- const multiAppPayload = `import p from "${opts.src}";window.__NUXT__=window.__NUXT__||{};window.__NUXT__[${JSON.stringify(appId)}]={...p,...(${nuxtData})}`;
54
+ if (opts.src) {
55
+ // Escape the URL to prevent XSS when interpolated into a JS string literal
56
+ const escapedSrc = escapeJsString(opts.src);
57
+ const singleAppPayload = `import p from "${escapedSrc}";window.__NUXT__={...p,...(${nuxtData})}`;
58
+ const multiAppPayload = `import p from "${escapedSrc}";window.__NUXT__=window.__NUXT__||{};window.__NUXT__[${JSON.stringify(appId)}]={...p,...(${nuxtData})}`;
43
59
  return [{
44
60
  type: "module",
45
61
  innerHTML: multiApp ? multiAppPayload : singleAppPayload
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt/nitro-server",
3
- "version": "4.3.1",
3
+ "version": "4.4.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/nuxt/nuxt.git",
@@ -11,49 +11,71 @@
11
11
  "license": "MIT",
12
12
  "type": "module",
13
13
  "types": "./dist/index.d.mts",
14
+ "typesVersions": {
15
+ "*": {
16
+ "h3": [
17
+ "./dist/runtime/h3-compat.d.mts"
18
+ ]
19
+ }
20
+ },
14
21
  "exports": {
15
- ".": "./dist/index.mjs"
22
+ ".": "./dist/index.mjs",
23
+ "./h3": "./dist/runtime/h3-compat.mjs"
16
24
  },
17
25
  "files": [
18
26
  "dist"
19
27
  ],
20
28
  "dependencies": {
29
+ "@babel/plugin-syntax-typescript": "^7.28.6",
21
30
  "@nuxt/devalue": "^2.0.2",
22
- "@unhead/vue": "^2.1.3",
23
- "@vue/shared": "^3.5.27",
31
+ "@unhead/vue": "^2.1.12",
32
+ "@vue/shared": "^3.5.30",
24
33
  "consola": "^3.4.2",
25
34
  "defu": "^6.1.4",
26
35
  "destr": "^2.0.5",
27
- "devalue": "^5.6.2",
36
+ "devalue": "^5.6.3",
28
37
  "errx": "^0.1.0",
29
38
  "escape-string-regexp": "^5.0.0",
30
39
  "exsolve": "^1.0.8",
31
- "h3": "^1.15.5",
32
- "impound": "^1.0.0",
40
+ "h3": "^1.15.6",
41
+ "impound": "^1.1.5",
33
42
  "klona": "^2.0.6",
34
43
  "mocked-exports": "^0.1.1",
35
44
  "nitropack": "^2.13.1",
45
+ "nypm": "^0.6.5",
36
46
  "ohash": "^2.0.11",
37
47
  "pathe": "^2.0.3",
38
48
  "pkg-types": "^2.3.0",
39
- "rou3": "^0.7.12",
40
- "std-env": "^3.10.0",
49
+ "rou3": "^0.8.1",
50
+ "std-env": "^4.0.0",
41
51
  "ufo": "^1.6.3",
42
52
  "unctx": "^2.5.0",
43
53
  "unstorage": "^1.17.4",
44
- "vue": "^3.5.27",
54
+ "vue": "^3.5.30",
45
55
  "vue-bundle-renderer": "^2.2.0",
46
56
  "vue-devtools-stub": "^0.1.0",
47
- "@nuxt/kit": "4.3.1"
57
+ "@nuxt/kit": "4.4.2"
48
58
  },
49
59
  "peerDependencies": {
50
- "nuxt": "^4.3.1"
60
+ "@babel/plugin-proposal-decorators": "^7.25.0",
61
+ "@rollup/plugin-babel": "^6.0.0 || ^7.0.0",
62
+ "nuxt": "^4.4.2"
63
+ },
64
+ "peerDependenciesMeta": {
65
+ "@babel/plugin-proposal-decorators": {
66
+ "optional": true
67
+ },
68
+ "@rollup/plugin-babel": {
69
+ "optional": true
70
+ }
51
71
  },
52
72
  "devDependencies": {
53
- "obuild": "0.4.27",
73
+ "@babel/plugin-proposal-decorators": "7.29.0",
74
+ "@rollup/plugin-babel": "7.0.0",
75
+ "obuild": "0.4.32",
54
76
  "vitest": "4.0.18",
55
- "@nuxt/schema": "4.3.1",
56
- "nuxt": "4.3.1"
77
+ "nuxt": "4.4.2",
78
+ "@nuxt/schema": "4.4.2"
57
79
  },
58
80
  "engines": {
59
81
  "node": "^20.19.0 || >=22.12.0"