veryfront
Advanced tools
+1
-1
| export default { | ||
| "name": "veryfront", | ||
| "version": "0.1.54", | ||
| "version": "0.1.55", | ||
| "license": "Apache-2.0", | ||
@@ -5,0 +5,0 @@ "nodeModulesDir": "auto", |
@@ -27,6 +27,2 @@ /** | ||
| filePath: string; | ||
| /** Branch ID for Yjs room GUID computation. */ | ||
| branchId?: string | null; | ||
| /** API base URL for computing the WebSocket URL (e.g. "https://api.veryfront.com"). */ | ||
| apiBaseUrl?: string; | ||
| } | ||
@@ -33,0 +29,0 @@ /** |
@@ -1,1 +0,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;IACjB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,uFAAuF;IACvF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA0ED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CA2FzE"} | ||
| {"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"} |
@@ -24,12 +24,10 @@ import { escapeHtml } from "../../../utils/html-escape.js"; | ||
| * Generate the studio bridge `<script>` tag. | ||
| * Injected when embedded in Studio (`studio_embed=true`) or for standalone | ||
| * markdown/MDX pages so the edit button and editor features are available. | ||
| * Injected only when embedded in Studio (`studio_embed=true`). | ||
| */ | ||
| function buildStudioScript(url, projectId, filePath, branchId, apiBaseUrl) { | ||
| function buildStudioScript(url, projectId, filePath) { | ||
| const studioEmbed = url.searchParams.get("studio_embed") === "true"; | ||
| const isMarkdown = /\.mdx?$/i.test(filePath); | ||
| if (!studioEmbed && !isMarkdown) | ||
| if (!studioEmbed) | ||
| return ""; | ||
| const rawQueryProjectId = url.searchParams.get("vf_project_id")?.trim() || ""; | ||
| // Validate query param to prevent path traversal in WebSocket URL | ||
| // Validate query param before using it in bridge config. | ||
| const queryProjectId = /^[a-zA-Z0-9_-]+$/.test(rawQueryProjectId) ? rawQueryProjectId : ""; | ||
@@ -39,15 +37,2 @@ const queryFileId = url.searchParams.get("vf_file_id")?.trim() || ""; | ||
| const canonicalPageId = queryFileId || filePath; | ||
| // Compute Yjs WebSocket URL from the API base URL (Yjs endpoint lives on the API server) | ||
| let wsUrl = ""; | ||
| if (apiBaseUrl) { | ||
| try { | ||
| const apiUrl = new URL(apiBaseUrl); | ||
| const wsProtocol = apiUrl.protocol === "https:" ? "wss:" : "ws:"; | ||
| wsUrl = `${wsProtocol}//${apiUrl.host}/ws/${canonicalProjectId}/yjs`; | ||
| } | ||
| catch (_) { | ||
| /* expected: invalid API URL — wsUrl stays empty, bridge won't self-connect */ | ||
| } | ||
| } | ||
| const yjsGuid = branchId ? `${canonicalProjectId}:${branchId}` : canonicalProjectId; | ||
| const bridgeConfig = { | ||
@@ -58,6 +43,2 @@ projectId: canonicalProjectId, | ||
| }; | ||
| if (wsUrl) | ||
| bridgeConfig.wsUrl = wsUrl; | ||
| if (yjsGuid) | ||
| bridgeConfig.yjsGuid = yjsGuid; | ||
| // Escape </script> sequences to prevent XSS breakout from inline JSON | ||
@@ -76,5 +57,5 @@ const safeJson = JSON.stringify(bridgeConfig).replace(/</g, "\\u003c"); | ||
| export function generateMarkdownHtml(options) { | ||
| const { rawHtml, title, description, request, url, projectId, filePath, branchId, apiBaseUrl } = options; | ||
| const { rawHtml, title, description, request, url, projectId, filePath } = options; | ||
| const theme = detectTheme(request, url); | ||
| const studioScript = buildStudioScript(url, projectId, filePath, branchId, apiBaseUrl); | ||
| const studioScript = buildStudioScript(url, projectId, filePath); | ||
| const themeAttrs = theme ? ` data-theme="${theme}" style="color-scheme: ${theme};"` : ""; | ||
@@ -81,0 +62,0 @@ return `<!DOCTYPE html> |
@@ -1,1 +0,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;AAiBnG,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;YAiEjE,cAAc;CAmF7B"} | ||
| {"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;YAiEjE,cAAc;CAiF7B"} |
@@ -10,3 +10,2 @@ import { BaseHandler } from "../response/base.js"; | ||
| import { generateMarkdownHtml } from "./markdown-html-generator.js"; | ||
| import { getEnvironmentConfig } from "../../../config/environment-config.js"; | ||
| import { validatePathSync } from "../../../security/index.js"; | ||
@@ -114,4 +113,2 @@ const logger = serverLogger.component("markdown-preview-handler"); | ||
| filePath, | ||
| branchId: ctx.parsedDomain?.branch ?? null, | ||
| apiBaseUrl: getEnvironmentConfig().publicApiBaseUrl, | ||
| }); | ||
@@ -118,0 +115,0 @@ const responseBuilder = this.createResponseBuilder(ctx) |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"bridge-bundle.generated.d.ts","sourceRoot":"","sources":["../../../../src/src/studio/bridge/bridge-bundle.generated.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,oBAAoB,EAAE,MAAy8qK,CAAC"} | ||
| {"version":3,"file":"bridge-bundle.generated.d.ts","sourceRoot":"","sources":["../../../../src/src/studio/bridge/bridge-bundle.generated.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,oBAAoB,EAAE,MAA67nD,CAAC"} |
+1
-1
| { | ||
| "name": "veryfront", | ||
| "version": "0.1.54", | ||
| "version": "0.1.55", | ||
| "description": "The simplest way to build AI-powered apps", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
+1
-1
| export default { | ||
| "name": "veryfront", | ||
| "version": "0.1.54", | ||
| "version": "0.1.55", | ||
| "license": "Apache-2.0", | ||
@@ -5,0 +5,0 @@ "nodeModulesDir": "auto", |
@@ -31,6 +31,2 @@ /** | ||
| filePath: string; | ||
| /** Branch ID for Yjs room GUID computation. */ | ||
| branchId?: string | null; | ||
| /** API base URL for computing the WebSocket URL (e.g. "https://api.veryfront.com"). */ | ||
| apiBaseUrl?: string; | ||
| } | ||
@@ -62,4 +58,3 @@ | ||
| * Generate the studio bridge `<script>` tag. | ||
| * Injected when embedded in Studio (`studio_embed=true`) or for standalone | ||
| * markdown/MDX pages so the edit button and editor features are available. | ||
| * Injected only when embedded in Studio (`studio_embed=true`). | ||
| */ | ||
@@ -70,11 +65,8 @@ function buildStudioScript( | ||
| filePath: string, | ||
| branchId?: string | null, | ||
| apiBaseUrl?: string, | ||
| ): string { | ||
| const studioEmbed = url.searchParams.get("studio_embed") === "true"; | ||
| const isMarkdown = /\.mdx?$/i.test(filePath); | ||
| if (!studioEmbed && !isMarkdown) return ""; | ||
| if (!studioEmbed) return ""; | ||
| const rawQueryProjectId = url.searchParams.get("vf_project_id")?.trim() || ""; | ||
| // Validate query param to prevent path traversal in WebSocket URL | ||
| // Validate query param before using it in bridge config. | ||
| const queryProjectId = /^[a-zA-Z0-9_-]+$/.test(rawQueryProjectId) ? rawQueryProjectId : ""; | ||
@@ -85,15 +77,2 @@ const queryFileId = url.searchParams.get("vf_file_id")?.trim() || ""; | ||
| // Compute Yjs WebSocket URL from the API base URL (Yjs endpoint lives on the API server) | ||
| let wsUrl = ""; | ||
| if (apiBaseUrl) { | ||
| try { | ||
| const apiUrl = new URL(apiBaseUrl); | ||
| const wsProtocol = apiUrl.protocol === "https:" ? "wss:" : "ws:"; | ||
| wsUrl = `${wsProtocol}//${apiUrl.host}/ws/${canonicalProjectId}/yjs`; | ||
| } catch (_) { | ||
| /* expected: invalid API URL — wsUrl stays empty, bridge won't self-connect */ | ||
| } | ||
| } | ||
| const yjsGuid = branchId ? `${canonicalProjectId}:${branchId}` : canonicalProjectId; | ||
| const bridgeConfig: Record<string, unknown> = { | ||
@@ -104,4 +83,2 @@ projectId: canonicalProjectId, | ||
| }; | ||
| if (wsUrl) bridgeConfig.wsUrl = wsUrl; | ||
| if (yjsGuid) bridgeConfig.yjsGuid = yjsGuid; | ||
@@ -122,7 +99,6 @@ // Escape </script> sequences to prevent XSS breakout from inline JSON | ||
| export function generateMarkdownHtml(options: MarkdownHtmlOptions): string { | ||
| const { rawHtml, title, description, request, url, projectId, filePath, branchId, apiBaseUrl } = | ||
| options; | ||
| const { rawHtml, title, description, request, url, projectId, filePath } = options; | ||
| const theme = detectTheme(request, url); | ||
| const studioScript = buildStudioScript(url, projectId, filePath, branchId, apiBaseUrl); | ||
| const studioScript = buildStudioScript(url, projectId, filePath); | ||
| const themeAttrs = theme ? ` data-theme="${theme}" style="color-scheme: ${theme};"` : ""; | ||
@@ -129,0 +105,0 @@ |
@@ -22,3 +22,2 @@ /** | ||
| import { generateMarkdownHtml } from "./markdown-html-generator.js"; | ||
| import { getEnvironmentConfig } from "../../../config/environment-config.js"; | ||
| import { validatePathSync } from "../../../security/index.js"; | ||
@@ -165,4 +164,2 @@ | ||
| filePath, | ||
| branchId: ctx.parsedDomain?.branch ?? null, | ||
| apiBaseUrl: getEnvironmentConfig().publicApiBaseUrl, | ||
| }); | ||
@@ -169,0 +166,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 2 instances in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 5 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 2 instances in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 5 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
477
-2.65%16698899
-1.39%348831
-0.23%