veryfront 0.1.129 → 0.1.131

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.
Files changed (112) hide show
  1. package/esm/cli/auth/login.d.ts.map +1 -1
  2. package/esm/cli/auth/login.js +11 -0
  3. package/esm/cli/auth/provider-store.d.ts +20 -0
  4. package/esm/cli/auth/provider-store.d.ts.map +1 -0
  5. package/esm/cli/auth/provider-store.js +62 -0
  6. package/esm/cli/auth/providers/anthropic.d.ts +2 -0
  7. package/esm/cli/auth/providers/anthropic.d.ts.map +1 -0
  8. package/esm/cli/auth/providers/anthropic.js +37 -0
  9. package/esm/cli/auth/providers/openai.d.ts +2 -0
  10. package/esm/cli/auth/providers/openai.d.ts.map +1 -0
  11. package/esm/cli/auth/providers/openai.js +35 -0
  12. package/esm/cli/auth/utils.d.ts +5 -0
  13. package/esm/cli/auth/utils.d.ts.map +1 -1
  14. package/esm/cli/auth/utils.js +9 -0
  15. package/esm/cli/commands/config/command-help.d.ts +3 -0
  16. package/esm/cli/commands/config/command-help.d.ts.map +1 -0
  17. package/esm/cli/commands/config/command-help.js +13 -0
  18. package/esm/cli/commands/config/handler.d.ts +5 -0
  19. package/esm/cli/commands/config/handler.d.ts.map +1 -0
  20. package/esm/cli/commands/config/handler.js +70 -0
  21. package/esm/cli/commands/open/command-help.d.ts +3 -0
  22. package/esm/cli/commands/open/command-help.d.ts.map +1 -0
  23. package/esm/cli/commands/open/command-help.js +17 -0
  24. package/esm/cli/commands/open/command.d.ts +14 -0
  25. package/esm/cli/commands/open/command.d.ts.map +1 -0
  26. package/esm/cli/commands/open/command.js +22 -0
  27. package/esm/cli/commands/open/handler.d.ts +3 -0
  28. package/esm/cli/commands/open/handler.d.ts.map +1 -0
  29. package/esm/cli/commands/open/handler.js +29 -0
  30. package/esm/cli/help/command-definitions.d.ts.map +1 -1
  31. package/esm/cli/help/command-definitions.js +4 -0
  32. package/esm/cli/router.d.ts.map +1 -1
  33. package/esm/cli/router.js +26 -1
  34. package/esm/deno.js +1 -1
  35. package/esm/src/channels/control-plane.js +6 -6
  36. package/esm/src/discovery/handlers/agent-handler.d.ts.map +1 -1
  37. package/esm/src/discovery/handlers/agent-handler.js +10 -1
  38. package/esm/src/platform/compat/framework-source-resolver.d.ts +8 -0
  39. package/esm/src/platform/compat/framework-source-resolver.d.ts.map +1 -1
  40. package/esm/src/platform/compat/framework-source-resolver.js +77 -1
  41. package/esm/src/rendering/rsc/client-boot.ts +18 -1
  42. package/esm/src/server/handlers/preview/markdown-html-generator.d.ts +2 -0
  43. package/esm/src/server/handlers/preview/markdown-html-generator.d.ts.map +1 -1
  44. package/esm/src/server/handlers/preview/markdown-html-generator.js +10 -7
  45. package/esm/src/server/handlers/preview/markdown-preview.handler.d.ts.map +1 -1
  46. package/esm/src/server/handlers/preview/markdown-preview.handler.js +6 -3
  47. package/esm/src/server/handlers/request/api/project-discovery.d.ts.map +1 -1
  48. package/esm/src/server/handlers/request/api/project-discovery.js +16 -5
  49. package/esm/src/server/handlers/request/api/security-headers.d.ts +1 -0
  50. package/esm/src/server/handlers/request/api/security-headers.d.ts.map +1 -1
  51. package/esm/src/server/handlers/request/api/security-headers.js +4 -1
  52. package/esm/src/server/handlers/request/openapi-docs.handler.d.ts.map +1 -1
  53. package/esm/src/server/handlers/request/openapi-docs.handler.js +10 -6
  54. package/esm/src/server/handlers/request/rsc/index.d.ts.map +1 -1
  55. package/esm/src/server/handlers/request/rsc/index.js +5 -2
  56. package/esm/src/server/handlers/request/ssr/ssr-response-builder.d.ts.map +1 -1
  57. package/esm/src/server/handlers/request/ssr/ssr-response-builder.js +12 -2
  58. package/esm/src/server/handlers/response/not-found.d.ts.map +1 -1
  59. package/esm/src/server/handlers/response/not-found.js +14 -15
  60. package/esm/src/server/services/rsc/endpoints/endpoint-router.d.ts +1 -1
  61. package/esm/src/server/services/rsc/endpoints/endpoint-router.d.ts.map +1 -1
  62. package/esm/src/server/services/rsc/endpoints/endpoint-router.js +3 -3
  63. package/esm/src/server/services/rsc/endpoints/rsc-bundles.generated.d.ts.map +1 -1
  64. package/esm/src/server/services/rsc/endpoints/rsc-bundles.generated.js +1 -1
  65. package/esm/src/server/services/rsc/endpoints/types.d.ts +1 -0
  66. package/esm/src/server/services/rsc/endpoints/types.d.ts.map +1 -1
  67. package/esm/src/server/services/rsc/orchestrators/handler.d.ts +1 -1
  68. package/esm/src/server/services/rsc/orchestrators/handler.d.ts.map +1 -1
  69. package/esm/src/server/services/rsc/orchestrators/handler.js +2 -2
  70. package/esm/src/server/services/rsc/orchestrators/page-handler.d.ts +1 -1
  71. package/esm/src/server/services/rsc/orchestrators/page-handler.d.ts.map +1 -1
  72. package/esm/src/server/services/rsc/orchestrators/page-handler.js +7 -5
  73. package/esm/src/transforms/esm/import-parser.d.ts.map +1 -1
  74. package/esm/src/transforms/esm/import-parser.js +6 -0
  75. package/esm/src/transforms/pipeline/stages/ssr-vf-modules/path-resolver.d.ts +1 -1
  76. package/esm/src/transforms/pipeline/stages/ssr-vf-modules/path-resolver.d.ts.map +1 -1
  77. package/esm/src/transforms/pipeline/stages/ssr-vf-modules/path-resolver.js +10 -66
  78. package/esm/src/utils/version-constant.d.ts +1 -1
  79. package/esm/src/utils/version-constant.js +1 -1
  80. package/package.json +1 -1
  81. package/src/cli/auth/login.ts +12 -0
  82. package/src/cli/auth/provider-store.ts +82 -0
  83. package/src/cli/auth/providers/anthropic.ts +46 -0
  84. package/src/cli/auth/providers/openai.ts +45 -0
  85. package/src/cli/auth/utils.ts +10 -0
  86. package/src/cli/commands/config/command-help.ts +15 -0
  87. package/src/cli/commands/config/handler.ts +90 -0
  88. package/src/cli/commands/open/command-help.ts +19 -0
  89. package/src/cli/commands/open/command.ts +28 -0
  90. package/src/cli/commands/open/handler.ts +38 -0
  91. package/src/cli/help/command-definitions.ts +4 -0
  92. package/src/cli/router.ts +28 -1
  93. package/src/deno.js +1 -1
  94. package/src/src/channels/control-plane.ts +6 -6
  95. package/src/src/discovery/handlers/agent-handler.ts +10 -1
  96. package/src/src/platform/compat/framework-source-resolver.ts +101 -1
  97. package/src/src/server/handlers/preview/markdown-html-generator.ts +12 -6
  98. package/src/src/server/handlers/preview/markdown-preview.handler.ts +6 -3
  99. package/src/src/server/handlers/request/api/project-discovery.ts +18 -5
  100. package/src/src/server/handlers/request/api/security-headers.ts +10 -1
  101. package/src/src/server/handlers/request/openapi-docs.handler.ts +10 -6
  102. package/src/src/server/handlers/request/rsc/index.ts +5 -2
  103. package/src/src/server/handlers/request/ssr/ssr-response-builder.ts +16 -2
  104. package/src/src/server/handlers/response/not-found.ts +14 -15
  105. package/src/src/server/services/rsc/endpoints/endpoint-router.ts +3 -3
  106. package/src/src/server/services/rsc/endpoints/rsc-bundles.generated.ts +1 -1
  107. package/src/src/server/services/rsc/endpoints/types.ts +1 -0
  108. package/src/src/server/services/rsc/orchestrators/handler.ts +2 -2
  109. package/src/src/server/services/rsc/orchestrators/page-handler.ts +8 -5
  110. package/src/src/transforms/esm/import-parser.ts +12 -0
  111. package/src/src/transforms/pipeline/stages/ssr-vf-modules/path-resolver.ts +10 -69
  112. package/src/src/utils/version-constant.ts +1 -1
@@ -1,7 +1,8 @@
1
1
  import { join } from "./path/index.js";
2
2
  import { createFileSystem } from "./fs.js";
3
- import { getFrameworkRootFromMeta } from "./vfs-paths.js";
3
+ import { getFrameworkRoot, getFrameworkRootFromMeta } from "./vfs-paths.js";
4
4
  export const FRAMEWORK_ROOT = getFrameworkRootFromMeta(globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).url);
5
+ export const FRAMEWORK_SRC_DIR = join(FRAMEWORK_ROOT, "src");
5
6
  export const FRAMEWORK_EMBEDDED_SRC_DIR = join(FRAMEWORK_ROOT, "dist", "framework-src");
6
7
  export const DEFAULT_FRAMEWORK_SOURCE_EXTENSIONS = [
7
8
  ".tsx.src",
@@ -31,6 +32,40 @@ export function getFrameworkSourceLookupDirs(extraLookupDirs = []) {
31
32
  return true;
32
33
  });
33
34
  }
35
+ export function isFrameworkSourcePath(path) {
36
+ return path.startsWith(`${FRAMEWORK_SRC_DIR}/`) ||
37
+ path.startsWith(`${FRAMEWORK_EMBEDDED_SRC_DIR}/`);
38
+ }
39
+ function expandFrameworkCandidatePaths(candidatePath) {
40
+ const candidates = [candidatePath];
41
+ const candidateRoot = getFrameworkRoot(candidatePath);
42
+ const candidateSrcDir = candidateRoot ? join(candidateRoot, "src") : FRAMEWORK_SRC_DIR;
43
+ const candidateEmbeddedDir = candidateRoot
44
+ ? join(candidateRoot, "dist", "framework-src")
45
+ : FRAMEWORK_EMBEDDED_SRC_DIR;
46
+ if (candidatePath.startsWith(`${candidateSrcDir}/`)) {
47
+ const relativePath = candidatePath.slice(candidateSrcDir.length + 1);
48
+ candidates.push(join(candidateEmbeddedDir, relativePath));
49
+ }
50
+ return [...new Set(candidates)];
51
+ }
52
+ async function findExistingFrameworkCandidate(candidatePath, options = {}) {
53
+ const fs = options.fileSystem ?? createFileSystem();
54
+ const exists = options.exists ?? (async (path) => {
55
+ try {
56
+ const stat = await fs.stat(path);
57
+ return stat.isFile;
58
+ }
59
+ catch {
60
+ return false;
61
+ }
62
+ });
63
+ for (const candidate of expandFrameworkCandidatePaths(candidatePath)) {
64
+ if (await exists(candidate))
65
+ return candidate;
66
+ }
67
+ return null;
68
+ }
34
69
  export async function resolveFrameworkSourcePath(relativePathWithoutExt, options = {}) {
35
70
  const fs = options.fileSystem ?? createFileSystem();
36
71
  const lookupDirs = getFrameworkSourceLookupDirs(options.extraLookupDirs);
@@ -60,3 +95,44 @@ export async function resolveFrameworkSourcePath(relativePathWithoutExt, options
60
95
  }
61
96
  return null;
62
97
  }
98
+ export async function resolveRelativeFrameworkSourceImport(specifier, fromSourcePath, options = {}) {
99
+ const extensions = options.extensions ?? DEFAULT_FRAMEWORK_SOURCE_EXTENSIONS;
100
+ const fromDir = fromSourcePath.substring(0, fromSourcePath.lastIndexOf("/"));
101
+ const parts = fromDir.split("/").filter(Boolean);
102
+ const importParts = specifier.split("/").filter(Boolean);
103
+ for (const part of importParts) {
104
+ if (part === "..") {
105
+ parts.pop();
106
+ }
107
+ else if (part !== ".") {
108
+ parts.push(part);
109
+ }
110
+ }
111
+ const basePath = "/" + parts.join("/");
112
+ if (/\.(tsx?|jsx?|mjs)$/.test(specifier)) {
113
+ const explicitCandidates = [basePath, `${basePath}.src`];
114
+ if (basePath.endsWith(".js") || basePath.endsWith(".mjs")) {
115
+ const stem = basePath.replace(/\.(?:m?js)$/, "");
116
+ for (const ext of [".ts", ".tsx", ".jsx", ".js", ".mjs"]) {
117
+ explicitCandidates.push(`${stem}${ext}.src`, `${stem}${ext}`);
118
+ }
119
+ }
120
+ for (const candidate of explicitCandidates) {
121
+ const resolved = await findExistingFrameworkCandidate(candidate, options);
122
+ if (resolved)
123
+ return resolved;
124
+ }
125
+ return null;
126
+ }
127
+ for (const ext of extensions) {
128
+ const candidate = await findExistingFrameworkCandidate(basePath + ext, options);
129
+ if (candidate)
130
+ return candidate;
131
+ }
132
+ for (const ext of extensions) {
133
+ const candidate = await findExistingFrameworkCandidate(join(basePath, "index" + ext), options);
134
+ if (candidate)
135
+ return candidate;
136
+ }
137
+ return null;
138
+ }
@@ -6,6 +6,7 @@
6
6
  import type { ClientModuleStrategy } from "./client-module-strategy.ts";
7
7
  import {
8
8
  buildClientModuleUrl,
9
+ type ClientRuntimeHydrationData,
9
10
  getHydrationReactImportSpecifiers,
10
11
  readHydrationData,
11
12
  resolveClientModuleStrategy,
@@ -58,6 +59,18 @@ export function selectHydrationRoot<T extends HydrationRootCandidate>(
58
59
  fallback;
59
60
  }
60
61
 
62
+ interface RSCBootDocument {
63
+ getElementById(id: string): Element | null;
64
+ }
65
+
66
+ export function shouldAttemptRSCTransport(
67
+ doc: RSCBootDocument,
68
+ hydrationData: ClientRuntimeHydrationData | null,
69
+ ): boolean {
70
+ if (hydrationData?.pagePath) return false;
71
+ return !!doc.getElementById(RSC_ROOT_ID);
72
+ }
73
+
61
74
  async function tryStream(q: string): Promise<boolean> {
62
75
  try {
63
76
  const res = await fetch(RSC_PATH_PREFIX + "stream" + q);
@@ -151,8 +164,12 @@ export async function boot(): Promise<void> {
151
164
  console.debug?.("[RSC] Found page component in hydration data:", pagePath);
152
165
  if (await hydratePageComponent(pagePath, clientModuleStrategy)) {
153
166
  console.debug?.("[RSC] Client component hydrated successfully");
154
- return;
155
167
  }
168
+ return;
169
+ }
170
+
171
+ if (!shouldAttemptRSCTransport(document, hydrationData)) {
172
+ return;
156
173
  }
157
174
 
158
175
  if (await tryStream(q)) {
@@ -24,6 +24,8 @@ interface MarkdownHtmlOptions {
24
24
  projectId: string;
25
25
  /** File path of the markdown file. */
26
26
  filePath: string;
27
+ /** CSP nonce for inline scripts. */
28
+ nonce?: string;
27
29
  }
28
30
  /**
29
31
  * Generate a complete HTML document for markdown preview rendering.
@@ -1 +1 @@
1
- {"version":3,"file":"markdown-html-generator.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/preview/markdown-html-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AAKrD,oDAAoD;AACpD,UAAU,mBAAmB;IAC3B,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC;IACzB,gDAAgD;IAChD,GAAG,EAAE,GAAG,CAAC;IACT,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAuDD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CA0FzE"}
1
+ {"version":3,"file":"markdown-html-generator.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/preview/markdown-html-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AAMrD,oDAAoD;AACpD,UAAU,mBAAmB;IAC3B,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC;IACzB,gDAAgD;IAChD,GAAG,EAAE,GAAG,CAAC;IACT,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAyDD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CA2FzE"}
@@ -1,4 +1,5 @@
1
1
  import { escapeHtml } from "../../../utils/html-escape.js";
2
+ import { buildNonceAttribute } from "../../../html/html-escape.js";
2
3
  /**
3
4
  * Detect the preferred color theme from request parameters and client hints.
4
5
  *
@@ -23,10 +24,11 @@ function detectTheme(req, url) {
23
24
  * Generate the studio bridge `<script>` tag.
24
25
  * Injected only when embedded in Studio (`studio_embed=true`).
25
26
  */
26
- function buildStudioScript(url, projectId, filePath) {
27
+ function buildStudioScript(url, projectId, filePath, nonce) {
27
28
  const studioEmbed = url.searchParams.get("studio_embed") === "true";
28
29
  if (!studioEmbed)
29
30
  return "";
31
+ const nonceAttr = buildNonceAttribute(nonce);
30
32
  const rawQueryProjectId = url.searchParams.get("vf_project_id")?.trim() || "";
31
33
  // Validate query param before using it in bridge config.
32
34
  const queryProjectId = /^[a-zA-Z0-9_-]+$/.test(rawQueryProjectId) ? rawQueryProjectId : "";
@@ -40,8 +42,8 @@ function buildStudioScript(url, projectId, filePath) {
40
42
  };
41
43
  // Escape </script> sequences to prevent XSS breakout from inline JSON
42
44
  const safeJson = JSON.stringify(bridgeConfig).replace(/</g, "\\u003c");
43
- return `<script>window.__VF_BRIDGE_CONFIG__=${safeJson};</script>
44
- <script type="module" src="/_veryfront/studio-bridge.js"></script>`;
45
+ return `<script${nonceAttr}>window.__VF_BRIDGE_CONFIG__=${safeJson};</script>
46
+ <script type="module" src="/_veryfront/studio-bridge.js"${nonceAttr}></script>`;
45
47
  }
46
48
  /**
47
49
  * Generate a complete HTML document for markdown preview rendering.
@@ -51,10 +53,11 @@ function buildStudioScript(url, projectId, filePath) {
51
53
  * studio bridge integration.
52
54
  */
53
55
  export function generateMarkdownHtml(options) {
54
- const { rawHtml, title, description, request, url, projectId, filePath } = options;
56
+ const { rawHtml, title, description, request, url, projectId, filePath, nonce } = options;
55
57
  const theme = detectTheme(request, url);
56
- const studioScript = buildStudioScript(url, projectId, filePath);
58
+ const studioScript = buildStudioScript(url, projectId, filePath, nonce);
57
59
  const themeAttrs = theme ? ` data-theme="${theme}" style="color-scheme: ${theme};"` : "";
60
+ const nonceAttr = buildNonceAttribute(nonce);
58
61
  return `<!DOCTYPE html>
59
62
  <html lang="en"${themeAttrs}>
60
63
  <head>
@@ -75,7 +78,7 @@ export function generateMarkdownHtml(options) {
75
78
 
76
79
  ${studioScript}
77
80
 
78
- <script type="module">
81
+ <script type="module"${nonceAttr}>
79
82
  import mermaid from 'https://esm.sh/mermaid@11.4.1?pin=v135';
80
83
 
81
84
  function getMermaidTheme() {
@@ -135,7 +138,7 @@ export function generateMarkdownHtml(options) {
135
138
  </script>
136
139
 
137
140
  <!-- Preview HMR -->
138
- <script src="/_veryfront/preview-hmr.js"></script>
141
+ <script src="/_veryfront/preview-hmr.js"${nonceAttr}></script>
139
142
  </body>
140
143
  </html>`;
141
144
  }
@@ -1 +1 @@
1
- {"version":3,"file":"markdown-preview.handler.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/preview/markdown-preview.handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AAgBnG,qBAAa,sBAAuB,SAAQ,WAAW;IACrD,QAAQ,EAAE,eAAe,CAKvB;IAEI,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;YAmEjE,cAAc;CAiF7B"}
1
+ {"version":3,"file":"markdown-preview.handler.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/preview/markdown-preview.handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AAgBnG,qBAAa,sBAAuB,SAAQ,WAAW;IACrD,QAAQ,EAAE,eAAe,CAKvB;IAEI,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;YAmEjE,cAAc;CAoF7B"}
@@ -103,6 +103,7 @@ export class MarkdownPreviewHandler extends BaseHandler {
103
103
  return this.continue();
104
104
  }
105
105
  const bundle = await compileMarkdownRuntime("development", ctx.projectDir, body, frontmatter, filePath, "server");
106
+ const responseBuilder = this.createResponseBuilder(ctx);
106
107
  const html = generateMarkdownHtml({
107
108
  rawHtml: bundle.rawHtml || "",
108
109
  title: frontmatter.title != null ? String(frontmatter.title) : filePath,
@@ -111,15 +112,17 @@ export class MarkdownPreviewHandler extends BaseHandler {
111
112
  url,
112
113
  projectId: ctx.projectSlug || ctx.projectId || "markdown-preview",
113
114
  filePath,
115
+ nonce: responseBuilder.nonce,
114
116
  });
115
- const responseBuilder = this.createResponseBuilder(ctx)
117
+ responseBuilder
116
118
  .withCache("no-cache")
117
- .withContentType("text/html; charset=utf-8", html, HTTP_OK);
119
+ .withSecurity(ctx.securityConfig ?? undefined, req);
120
+ const response = responseBuilder.withContentType("text/html; charset=utf-8", html, HTTP_OK);
118
121
  logger.debug("Serving markdown preview", {
119
122
  filePath,
120
123
  htmlLength: html.length,
121
124
  });
122
- return this.respond(responseBuilder);
125
+ return this.respond(response);
123
126
  }
124
127
  catch (error) {
125
128
  logger.error("Error rendering markdown", {
@@ -1 +1 @@
1
- {"version":3,"file":"project-discovery.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/handlers/request/api/project-discovery.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AA8CrD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAkE/E"}
1
+ {"version":3,"file":"project-discovery.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/handlers/request/api/project-discovery.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AA+DrD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA8D/E"}
@@ -12,6 +12,21 @@ const logger = serverLogger.component("api-wrapper");
12
12
  * allows retry on failure (the key is deleted if discovery rejects).
13
13
  */
14
14
  const discoveredProjects = new Map();
15
+ function buildDiscoveryConfig(ctx) {
16
+ const ai = ctx.config?.ai;
17
+ const skillDiscoveryEnabled = ai?.skills?.discovery?.enabled ?? true;
18
+ return {
19
+ baseDir: ctx.projectDir,
20
+ toolDirs: ai?.tools?.discovery?.paths ?? ["tools"],
21
+ agentDirs: ai?.agents?.discovery?.paths ?? ["agents"],
22
+ skillDirs: skillDiscoveryEnabled ? (ai?.skills?.discovery?.paths ?? ["skills"]) : [],
23
+ resourceDirs: ["resources"],
24
+ promptDirs: ["prompts"],
25
+ workflowDirs: ["workflows"],
26
+ fsAdapter: ctx.adapter.fs,
27
+ verbose: false,
28
+ };
29
+ }
15
30
  /** Build a discovery cache key that incorporates the release/version. */
16
31
  function discoveryKey(ctx) {
17
32
  const cacheContext = tryGetCacheKeyContext();
@@ -59,11 +74,7 @@ export async function ensureProjectDiscovery(ctx) {
59
74
  clearTranspileCache();
60
75
  agentRegistry.clear();
61
76
  toolRegistry.clear();
62
- const result = await discoverAll({
63
- baseDir: ctx.projectDir,
64
- fsAdapter: ctx.adapter.fs,
65
- verbose: false,
66
- });
77
+ const result = await discoverAll(buildDiscoveryConfig(ctx));
67
78
  const logData = {
68
79
  projectSlug: ctx.projectSlug,
69
80
  releaseId: ctx.releaseId,
@@ -3,4 +3,5 @@ import type { HandlerContext } from "../../types.js";
3
3
  export declare function buildCSP(ctx: HandlerContext): string;
4
4
  export declare function getSecurityHeader(headerName: string, defaultValue: string, ctx: HandlerContext): string;
5
5
  export declare function applySecurityHeaders(headers: dntShim.Headers, ctx: HandlerContext, req?: dntShim.Request): void;
6
+ export declare function applySecurityHeadersWithNonce(headers: dntShim.Headers, ctx: HandlerContext, nonce: string, req?: dntShim.Request): void;
6
7
  //# sourceMappingURL=security-headers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"security-headers.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/handlers/request/api/security-headers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,8BAA8B,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAarD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAQpD;AAED,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,cAAc,GAClB,MAAM,CAER;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,OAAO,GAAG,IAAI,CAa/G"}
1
+ {"version":3,"file":"security-headers.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/handlers/request/api/security-headers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,8BAA8B,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAarD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAQpD;AAED,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,cAAc,GAClB,MAAM,CAER;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,OAAO,GAAG,IAAI,CAE/G;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,OAAO,CAAC,OAAO,EACxB,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,MAAM,EACb,GAAG,CAAC,EAAE,OAAO,CAAC,OAAO,GACpB,IAAI,CAaN"}
@@ -10,7 +10,10 @@ export function getSecurityHeader(headerName, defaultValue, ctx) {
10
10
  return coreGetSecurityHeader(headerName, defaultValue, ctx.securityConfig, ctx.adapter);
11
11
  }
12
12
  export function applySecurityHeaders(headers, ctx, req) {
13
- coreApplySecurityHeaders(headers, isDev(ctx), generateNonce(), ctx.cspUserHeader ?? null, ctx.securityConfig, ctx.adapter, ctx.parsedDomain?.allowIframeEmbed ?? false);
13
+ applySecurityHeadersWithNonce(headers, ctx, generateNonce(), req);
14
+ }
15
+ export function applySecurityHeadersWithNonce(headers, ctx, nonce, req) {
16
+ coreApplySecurityHeaders(headers, isDev(ctx), nonce, ctx.cspUserHeader ?? null, ctx.securityConfig, ctx.adapter, ctx.parsedDomain?.allowIframeEmbed ?? false);
14
17
  if (req) {
15
18
  applyCsrfCookie(req, headers, ctx.securityConfig?.csrf);
16
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"openapi-docs.handler.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/request/openapi-docs.handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AAWnG,qBAAa,kBAAmB,SAAQ,WAAW;IACjD,QAAQ,EAAE,eAAe,CAKvB;cAEiB,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO;IAMnF,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAazE,OAAO,CAAC,gBAAgB;CAsCzB"}
1
+ {"version":3,"file":"openapi-docs.handler.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/request/openapi-docs.handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AAWnG,qBAAa,kBAAmB,SAAQ,WAAW;IACjD,QAAQ,EAAE,eAAe,CAKvB;cAEiB,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO;IAMnF,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAezE,OAAO,CAAC,gBAAgB;CAwCzB"}
@@ -1,6 +1,6 @@
1
1
  import { BaseHandler } from "../response/base.js";
2
2
  import { HTTP_OK, PRIORITY_HIGH_DEV } from "../../../utils/constants/index.js";
3
- import { escapeHtml } from "../../../html/html-escape.js";
3
+ import { buildNonceAttribute, escapeHtml } from "../../../html/html-escape.js";
4
4
  /** Default paths */
5
5
  const DEFAULT_DOCS_PATH = "/_docs";
6
6
  const DEFAULT_JSON_PATH = "/_openapi.json";
@@ -21,17 +21,20 @@ export class OpenAPIDocsHandler extends BaseHandler {
21
21
  handle(req, ctx) {
22
22
  if (!this.shouldHandle(req, ctx))
23
23
  return Promise.resolve(this.continue());
24
- const html = this.generateDocsPage(ctx);
25
24
  const isDev = !!ctx.isLocalProject;
26
- const response = this.createResponseBuilder(ctx)
25
+ const builder = this.createResponseBuilder(ctx);
26
+ const html = this.generateDocsPage(ctx, builder.nonce);
27
+ const response = builder
27
28
  .withCache(isDev ? "no-cache" : { maxAge: DOCS_CACHE_MAX_AGE_SECONDS, public: true })
29
+ .withSecurity(ctx.securityConfig ?? undefined, req)
28
30
  .withContentType("text/html; charset=utf-8", html, HTTP_OK);
29
31
  return Promise.resolve(this.respond(response));
30
32
  }
31
- generateDocsPage(ctx) {
33
+ generateDocsPage(ctx, nonce) {
32
34
  const specUrl = ctx.config?.openapi?.paths?.json ?? DEFAULT_JSON_PATH;
33
35
  const title = escapeHtml(ctx.config?.openapi?.title ?? "API Documentation");
34
36
  const description = escapeHtml(ctx.config?.openapi?.description ?? "");
37
+ const nonceAttr = buildNonceAttribute(nonce);
35
38
  const configuration = JSON.stringify({
36
39
  theme: "purple",
37
40
  layout: "modern",
@@ -47,7 +50,7 @@ export class OpenAPIDocsHandler extends BaseHandler {
47
50
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
48
51
  <title>${title}</title>
49
52
  ${description ? `<meta name="description" content="${description}"/>` : ""}
50
- <style>
53
+ <style${nonceAttr}>
51
54
  body {
52
55
  margin: 0;
53
56
  padding: 0;
@@ -59,8 +62,9 @@ export class OpenAPIDocsHandler extends BaseHandler {
59
62
  id="api-reference"
60
63
  data-url="${specUrl}"
61
64
  data-configuration='${configuration}'
65
+ ${nonce ? `nonce="${escapeHtml(nonce)}"` : ""}
62
66
  ></script>
63
- <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
67
+ <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"${nonceAttr}></script>
64
68
  </body>
65
69
  </html>`;
66
70
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/handlers/request/rsc/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,OAAO,MAAM,8BAA8B,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EAEf,aAAa,EACd,MAAM,gBAAgB,CAAC;AAQxB,qBAAa,UAAW,SAAQ,WAAW;IACzC,QAAQ,EAAE,eAAe,CAIvB;IAEF,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CAmD1E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/handlers/request/rsc/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,OAAO,MAAM,8BAA8B,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EAEf,aAAa,EACd,MAAM,gBAAgB,CAAC;AASxB,qBAAa,UAAW,SAAQ,WAAW;IACzC,QAAQ,EAAE,eAAe,CAIvB;IAEF,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CAqD1E"}
@@ -7,10 +7,11 @@ import * as dntShim from "../../../../../_dnt.shims.js";
7
7
  import { BaseHandler } from "../../response/base.js";
8
8
  import { isRSCEnabled } from "../../../../utils/index.js";
9
9
  import { handleRSCEndpoint } from "../../../services/rsc/endpoints/index.js";
10
- import { applySecurityHeaders } from "../api/security-headers.js";
10
+ import { applySecurityHeadersWithNonce } from "../api/security-headers.js";
11
11
  import { applyCORSHeaders } from "../../../../security/index.js";
12
12
  import { HTTP_NOT_FOUND, PRIORITY_MEDIUM } from "../../../../utils/constants/index.js";
13
13
  import { withSpan } from "../../../../observability/tracing/otlp-setup.js";
14
+ import { generateNonce } from "../../../../security/http/response/security-handler.js";
14
15
  export class RSCHandler extends BaseHandler {
15
16
  metadata = {
16
17
  name: "RSCHandler",
@@ -29,6 +30,7 @@ export class RSCHandler extends BaseHandler {
29
30
  if (!isRSCEnabled(ctx.config) && !isHydrationScript && !isDeprecatedEndpoint) {
30
31
  return this.respond(new dntShim.Response("Not Found", { status: HTTP_NOT_FOUND }));
31
32
  }
33
+ const nonce = generateNonce();
32
34
  const res = await handleRSCEndpoint({
33
35
  req,
34
36
  pathname,
@@ -36,6 +38,7 @@ export class RSCHandler extends BaseHandler {
36
38
  projectId: ctx.projectId,
37
39
  adapter: ctx.adapter,
38
40
  config: ctx.config,
41
+ nonce,
39
42
  });
40
43
  if (!res) {
41
44
  return this.continue();
@@ -46,7 +49,7 @@ export class RSCHandler extends BaseHandler {
46
49
  headers,
47
50
  config: ctx.securityConfig?.cors,
48
51
  });
49
- applySecurityHeaders(headers, ctx, req);
52
+ applySecurityHeadersWithNonce(headers, ctx, nonce, req);
50
53
  return this.respond(new dntShim.Response(res.body, {
51
54
  status: res.status,
52
55
  statusText: res.statusText,
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-response-builder.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/handlers/request/ssr/ssr-response-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,OAAO,MAAM,8BAA8B,CAAC;AAGxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAElF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+CAA+C,CAAC;AAErF;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,OAAO,CAAC,OAAO,EACpB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAkD3B"}
1
+ {"version":3,"file":"ssr-response-builder.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/handlers/request/ssr/ssr-response-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,OAAO,MAAM,8BAA8B,CAAC;AAGxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAElF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+CAA+C,CAAC;AAWrF;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,OAAO,CAAC,OAAO,EACpB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAuD3B"}
@@ -10,6 +10,11 @@ import * as dntShim from "../../../../../_dnt.shims.js";
10
10
  import { hasMatchingEtag } from "../../utils/etag.js";
11
11
  import { getContentType } from "../../utils/content-types.js";
12
12
  import { ErrorPages } from "../../../utils/error-html.js";
13
+ import { escapeHtml } from "../../../../html/html-escape.js";
14
+ function addNonceToInlineTags(html, nonce) {
15
+ const escapedNonce = escapeHtml(nonce);
16
+ return html.replace(/<(script|style)\b(?![^>]*\bnonce\s*=)([^>]*)>/giu, `<$1$2 nonce="${escapedNonce}">`);
17
+ }
13
18
  /**
14
19
  * Build an HTTP response from an SSR render result.
15
20
  *
@@ -41,8 +46,13 @@ export async function buildSSRResponse(req, ctx, result, builder) {
41
46
  .notModified(result.etag);
42
47
  }
43
48
  // Buffered response path
44
- const content = result.html || result.stream || ErrorPages.serverError();
45
- const body = isHeadRequest ? null : content;
49
+ const content = typeof result.html === "string"
50
+ ? result.html
51
+ : typeof result.stream === "string"
52
+ ? result.stream
53
+ : ErrorPages.serverError();
54
+ const html = addNonceToInlineTags(content, builder.nonce);
55
+ const body = isHeadRequest ? null : html;
46
56
  let response = builder
47
57
  .withCORS(req, ctx.securityConfig?.cors)
48
58
  .withSecurity(ctx.securityConfig ?? undefined, req)
@@ -1 +1 @@
1
- {"version":3,"file":"not-found.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/response/not-found.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AASnG,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,QAAQ,EAAE,eAAe,CAIvB;IAEF,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAgCzE,OAAO,CAAC,eAAe;CA2GxB"}
1
+ {"version":3,"file":"not-found.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/response/not-found.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AASnG,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,QAAQ,EAAE,eAAe,CAIvB;IAEF,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IA8BzE,OAAO,CAAC,eAAe;CA4GxB"}
@@ -1,7 +1,7 @@
1
1
  import { BaseHandler } from "./base.js";
2
2
  import { ResponseBuilder } from "../../../security/index.js";
3
3
  import { HTTP_INTERNAL_SERVER_ERROR, HTTP_NOT_FOUND, PRIORITY_FALLBACK, } from "../../../utils/constants/index.js";
4
- import { escapeHtml } from "../../../html/html-escape.js";
4
+ import { buildNonceAttribute, escapeHtml } from "../../../html/html-escape.js";
5
5
  export class NotFoundHandler extends BaseHandler {
6
6
  metadata = {
7
7
  name: "NotFoundHandler",
@@ -10,35 +10,34 @@ export class NotFoundHandler extends BaseHandler {
10
10
  };
11
11
  handle(req, ctx) {
12
12
  const pathname = new URL(req.url).pathname;
13
- const securityConfig = ctx.securityConfig;
14
- const corsConfig = ctx.securityConfig?.cors;
15
13
  try {
16
- const html = this.generate404Html(pathname);
17
- const response = ResponseBuilder.html(html, req, {
18
- securityConfig,
19
- corsConfig,
20
- cache: "no-cache",
21
- status: HTTP_NOT_FOUND,
22
- });
14
+ const builder = this.createResponseBuilder(ctx);
15
+ const html = this.generate404Html(pathname, builder.nonce);
16
+ const response = builder
17
+ .withCORS(req, ctx.securityConfig?.cors)
18
+ .withSecurity(ctx.securityConfig ?? undefined, req)
19
+ .withCache("no-cache")
20
+ .html(html, HTTP_NOT_FOUND);
23
21
  return Promise.resolve(this.respond(response));
24
22
  }
25
23
  catch (e) {
26
24
  this.logDebug("404 fallback error", { error: this.getErrorMessage(e) }, ctx);
27
25
  const response = ResponseBuilder.error(HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", req, {
28
- securityConfig,
29
- corsConfig,
26
+ securityConfig: ctx.securityConfig,
27
+ corsConfig: ctx.securityConfig?.cors,
30
28
  });
31
29
  return Promise.resolve(this.respond(response));
32
30
  }
33
31
  }
34
- generate404Html(pathname) {
32
+ generate404Html(pathname, nonce) {
33
+ const nonceAttr = buildNonceAttribute(nonce);
35
34
  return `<!DOCTYPE html>
36
35
  <html lang="en">
37
36
  <head>
38
37
  <meta charset="utf-8"/>
39
38
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
40
39
  <title>404 Not Found</title>
41
- <style>
40
+ <style${nonceAttr}>
42
41
  body {
43
42
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
44
43
  margin: 0;
@@ -132,7 +131,7 @@ export class NotFoundHandler extends BaseHandler {
132
131
  </p>
133
132
  <div class="actions">
134
133
  <a href="/" class="button">Go Home</a>
135
- <a href="javascript:history.back()" class="button secondary">Go Back</a>
134
+ <a href=".." class="button secondary">Go Back</a>
136
135
  </div>
137
136
  </div>
138
137
  </body>
@@ -9,5 +9,5 @@ import type { RSCEndpointParams } from "./types.js";
9
9
  * @param params - RSC endpoint parameters
10
10
  * @returns Response or null if not an RSC endpoint
11
11
  */
12
- export declare function handleRSCEndpoint({ req, pathname, projectDir, projectId, adapter, config }: RSCEndpointParams): Promise<dntShim.Response | null>;
12
+ export declare function handleRSCEndpoint({ req, pathname, projectDir, projectId, adapter, config, nonce }: RSCEndpointParams): Promise<dntShim.Response | null>;
13
13
  //# sourceMappingURL=endpoint-router.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint-router.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/services/rsc/endpoints/endpoint-router.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,OAAO,MAAM,8BAA8B,CAAC;AAexD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAKpD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,iBAAiB,GAC3E,OAAO,CAAC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAyHlC"}
1
+ {"version":3,"file":"endpoint-router.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/services/rsc/endpoints/endpoint-router.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,OAAO,MAAM,8BAA8B,CAAC;AAexD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAKpD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,iBAAiB,GAClF,OAAO,CAAC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAyHlC"}
@@ -19,7 +19,7 @@ const rscLog = serverLogger.component("rsc");
19
19
  * @param params - RSC endpoint parameters
20
20
  * @returns Response or null if not an RSC endpoint
21
21
  */
22
- export async function handleRSCEndpoint({ req, pathname, projectDir, projectId, adapter, config }) {
22
+ export async function handleRSCEndpoint({ req, pathname, projectDir, projectId, adapter, config, nonce }) {
23
23
  if (!pathname.startsWith("/_veryfront/rsc/")) {
24
24
  return null;
25
25
  }
@@ -51,7 +51,7 @@ export async function handleRSCEndpoint({ req, pathname, projectDir, projectId,
51
51
  }
52
52
  if (sub.startsWith("page/")) {
53
53
  metrics.recordRSC("page");
54
- return handler.handlePage(sub.replace("page/", ""), url.searchParams);
54
+ return handler.handlePage(sub.replace("page/", ""), url.searchParams, nonce);
55
55
  }
56
56
  if (sub.startsWith("stream/")) {
57
57
  metrics.recordRSC("stream");
@@ -97,7 +97,7 @@ export async function handleRSCEndpoint({ req, pathname, projectDir, projectId,
97
97
  }
98
98
  if (sub === "page") {
99
99
  metrics.recordRSC("page");
100
- return handler.handlePage("/", url.searchParams);
100
+ return handler.handlePage("/", url.searchParams, nonce);
101
101
  }
102
102
  if (sub === "stream") {
103
103
  metrics.recordRSC("stream");
@@ -1 +1 @@
1
- {"version":3,"file":"rsc-bundles.generated.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/services/rsc/endpoints/rsc-bundles.generated.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,kBAAkB,EAAE,MACkgrB,CAAC;AAEpirB,eAAO,MAAM,iBAAiB,EAAE,MACgpiB,CAAC"}
1
+ {"version":3,"file":"rsc-bundles.generated.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/services/rsc/endpoints/rsc-bundles.generated.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,kBAAkB,EAAE,MACunrB,CAAC;AAEzprB,eAAO,MAAM,iBAAiB,EAAE,MACgpiB,CAAC"}