veryfront 0.1.33 → 0.1.35
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/esm/deno.js +1 -1
- package/esm/src/server/handlers/preview/markdown-html-generator.d.ts +2 -2
- package/esm/src/server/handlers/preview/markdown-html-generator.d.ts.map +1 -1
- package/esm/src/server/handlers/preview/markdown-html-generator.js +15 -10
- package/esm/src/server/handlers/preview/markdown-preview.handler.d.ts.map +1 -1
- package/esm/src/server/handlers/preview/markdown-preview.handler.js +2 -1
- package/esm/src/studio/bridge-template.js +1 -1
- package/package.json +1 -1
- package/src/deno.js +1 -1
- package/src/src/server/handlers/preview/markdown-html-generator.ts +16 -13
- package/src/src/server/handlers/preview/markdown-preview.handler.ts +2 -1
- package/src/src/studio/bridge-template.ts +1 -1
package/esm/deno.js
CHANGED
|
@@ -26,8 +26,8 @@ export interface MarkdownHtmlOptions {
|
|
|
26
26
|
filePath: string;
|
|
27
27
|
/** Branch ID for Yjs room GUID computation. */
|
|
28
28
|
branchId?: string | null;
|
|
29
|
-
/**
|
|
30
|
-
|
|
29
|
+
/** API base URL for computing the WebSocket URL (e.g. "https://api.veryfront.com"). */
|
|
30
|
+
apiBaseUrl?: string;
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
33
|
* 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;AAMrD,oDAAoD;AACpD,MAAM,WAAW,mBAAmB;IAClC,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,
|
|
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,MAAM,WAAW,mBAAmB;IAClC,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;AAuED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CA2FzE"}
|
|
@@ -25,7 +25,7 @@ function detectTheme(req, url) {
|
|
|
25
25
|
* Injected when embedded in Studio (`studio_embed=true`) or for standalone
|
|
26
26
|
* markdown/MDX pages so the edit button and editor features are available.
|
|
27
27
|
*/
|
|
28
|
-
function buildStudioScript(
|
|
28
|
+
function buildStudioScript(url, projectId, filePath, branchId, apiBaseUrl) {
|
|
29
29
|
const studioEmbed = url.searchParams.get("studio_embed") === "true";
|
|
30
30
|
const isMarkdown = /\.mdx?$/i.test(filePath);
|
|
31
31
|
if (!studioEmbed && !isMarkdown)
|
|
@@ -36,13 +36,18 @@ function buildStudioScript(req, url, projectId, filePath, branchId, requestHost)
|
|
|
36
36
|
const queryFileId = url.searchParams.get("vf_file_id")?.trim() || "";
|
|
37
37
|
const canonicalProjectId = queryProjectId || projectId;
|
|
38
38
|
const canonicalPageId = queryFileId || filePath;
|
|
39
|
-
// Compute Yjs
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
// Compute Yjs WebSocket URL from the API base URL (Yjs endpoint lives on the API server)
|
|
40
|
+
let wsUrl = "";
|
|
41
|
+
if (apiBaseUrl) {
|
|
42
|
+
try {
|
|
43
|
+
const apiUrl = new URL(apiBaseUrl);
|
|
44
|
+
const wsProtocol = apiUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
45
|
+
wsUrl = `${wsProtocol}//${apiUrl.host}/api/ws/${canonicalProjectId}/yjs`;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Invalid API URL — wsUrl stays empty, bridge won't self-connect
|
|
49
|
+
}
|
|
50
|
+
}
|
|
46
51
|
const yjsGuid = branchId ? `${canonicalProjectId}:${branchId}` : canonicalProjectId;
|
|
47
52
|
return `<script>${generateStudioBridgeScript({
|
|
48
53
|
projectId: canonicalProjectId,
|
|
@@ -60,9 +65,9 @@ function buildStudioScript(req, url, projectId, filePath, branchId, requestHost)
|
|
|
60
65
|
* studio bridge integration.
|
|
61
66
|
*/
|
|
62
67
|
export function generateMarkdownHtml(options) {
|
|
63
|
-
const { rawHtml, title, description, request, url, projectId, filePath, branchId,
|
|
68
|
+
const { rawHtml, title, description, request, url, projectId, filePath, branchId, apiBaseUrl } = options;
|
|
64
69
|
const theme = detectTheme(request, url);
|
|
65
|
-
const studioScript = buildStudioScript(
|
|
70
|
+
const studioScript = buildStudioScript(url, projectId, filePath, branchId, apiBaseUrl);
|
|
66
71
|
const themeAttrs = theme ? ` data-theme="${theme}" style="color-scheme: ${theme};"` : "";
|
|
67
72
|
return `<!DOCTYPE html>
|
|
68
73
|
<html lang="en"${themeAttrs}>
|
|
@@ -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;
|
|
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;CAkF7B"}
|
|
@@ -7,6 +7,7 @@ import { isExtendedFSAdapter } from "../../../platform/adapters/fs/wrapper.js";
|
|
|
7
7
|
import { getEnv } from "../../../platform/compat/process.js";
|
|
8
8
|
import { tryNotFoundFallback } from "../request/ssr/not-found-fallback.js";
|
|
9
9
|
import { generateMarkdownHtml } from "./markdown-html-generator.js";
|
|
10
|
+
import { getEnvironmentConfig } from "../../../config/environment-config.js";
|
|
10
11
|
import { validatePathSync } from "../../../security/index.js";
|
|
11
12
|
const logger = serverLogger.component("markdown-preview-handler");
|
|
12
13
|
// Priority 900: between MEDIUM (600) and LOW/SSR (1000)
|
|
@@ -109,7 +110,7 @@ export class MarkdownPreviewHandler extends BaseHandler {
|
|
|
109
110
|
projectId: ctx.projectSlug || ctx.projectId || "markdown-preview",
|
|
110
111
|
filePath,
|
|
111
112
|
branchId: ctx.parsedDomain?.branch ?? null,
|
|
112
|
-
|
|
113
|
+
apiBaseUrl: getEnvironmentConfig().apiBaseUrl,
|
|
113
114
|
});
|
|
114
115
|
const responseBuilder = this.createResponseBuilder(ctx)
|
|
115
116
|
.withCache("no-cache")
|
package/package.json
CHANGED
package/src/deno.js
CHANGED
|
@@ -31,8 +31,8 @@ export interface MarkdownHtmlOptions {
|
|
|
31
31
|
filePath: string;
|
|
32
32
|
/** Branch ID for Yjs room GUID computation. */
|
|
33
33
|
branchId?: string | null;
|
|
34
|
-
/**
|
|
35
|
-
|
|
34
|
+
/** API base URL for computing the WebSocket URL (e.g. "https://api.veryfront.com"). */
|
|
35
|
+
apiBaseUrl?: string;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|
|
@@ -63,12 +63,11 @@ function detectTheme(req: dntShim.Request, url: URL): "light" | "dark" | null {
|
|
|
63
63
|
* markdown/MDX pages so the edit button and editor features are available.
|
|
64
64
|
*/
|
|
65
65
|
function buildStudioScript(
|
|
66
|
-
req: dntShim.Request,
|
|
67
66
|
url: URL,
|
|
68
67
|
projectId: string,
|
|
69
68
|
filePath: string,
|
|
70
69
|
branchId?: string | null,
|
|
71
|
-
|
|
70
|
+
apiBaseUrl?: string,
|
|
72
71
|
): string {
|
|
73
72
|
const studioEmbed = url.searchParams.get("studio_embed") === "true";
|
|
74
73
|
const isMarkdown = /\.mdx?$/i.test(filePath);
|
|
@@ -81,13 +80,17 @@ function buildStudioScript(
|
|
|
81
80
|
const canonicalProjectId = queryProjectId || projectId;
|
|
82
81
|
const canonicalPageId = queryFileId || filePath;
|
|
83
82
|
|
|
84
|
-
// Compute Yjs
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
83
|
+
// Compute Yjs WebSocket URL from the API base URL (Yjs endpoint lives on the API server)
|
|
84
|
+
let wsUrl = "";
|
|
85
|
+
if (apiBaseUrl) {
|
|
86
|
+
try {
|
|
87
|
+
const apiUrl = new URL(apiBaseUrl);
|
|
88
|
+
const wsProtocol = apiUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
89
|
+
wsUrl = `${wsProtocol}//${apiUrl.host}/api/ws/${canonicalProjectId}/yjs`;
|
|
90
|
+
} catch {
|
|
91
|
+
// Invalid API URL — wsUrl stays empty, bridge won't self-connect
|
|
92
|
+
}
|
|
93
|
+
}
|
|
91
94
|
const yjsGuid = branchId ? `${canonicalProjectId}:${branchId}` : canonicalProjectId;
|
|
92
95
|
|
|
93
96
|
return `<script>${
|
|
@@ -109,11 +112,11 @@ function buildStudioScript(
|
|
|
109
112
|
* studio bridge integration.
|
|
110
113
|
*/
|
|
111
114
|
export function generateMarkdownHtml(options: MarkdownHtmlOptions): string {
|
|
112
|
-
const { rawHtml, title, description, request, url, projectId, filePath, branchId,
|
|
115
|
+
const { rawHtml, title, description, request, url, projectId, filePath, branchId, apiBaseUrl } =
|
|
113
116
|
options;
|
|
114
117
|
|
|
115
118
|
const theme = detectTheme(request, url);
|
|
116
|
-
const studioScript = buildStudioScript(
|
|
119
|
+
const studioScript = buildStudioScript(url, projectId, filePath, branchId, apiBaseUrl);
|
|
117
120
|
const themeAttrs = theme ? ` data-theme="${theme}" style="color-scheme: ${theme};"` : "";
|
|
118
121
|
|
|
119
122
|
return `<!DOCTYPE html>
|
|
@@ -19,6 +19,7 @@ import { isExtendedFSAdapter } from "../../../platform/adapters/fs/wrapper.js";
|
|
|
19
19
|
import { getEnv } from "../../../platform/compat/process.js";
|
|
20
20
|
import { tryNotFoundFallback } from "../request/ssr/not-found-fallback.js";
|
|
21
21
|
import { generateMarkdownHtml } from "./markdown-html-generator.js";
|
|
22
|
+
import { getEnvironmentConfig } from "../../../config/environment-config.js";
|
|
22
23
|
import { validatePathSync } from "../../../security/index.js";
|
|
23
24
|
|
|
24
25
|
const logger = serverLogger.component("markdown-preview-handler");
|
|
@@ -160,7 +161,7 @@ export class MarkdownPreviewHandler extends BaseHandler {
|
|
|
160
161
|
projectId: ctx.projectSlug || ctx.projectId || "markdown-preview",
|
|
161
162
|
filePath,
|
|
162
163
|
branchId: ctx.parsedDomain?.branch ?? null,
|
|
163
|
-
|
|
164
|
+
apiBaseUrl: getEnvironmentConfig().apiBaseUrl,
|
|
164
165
|
});
|
|
165
166
|
|
|
166
167
|
const responseBuilder = this.createResponseBuilder(ctx)
|