@docubook/flame 1.3.2 → 1.3.3
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/.docu/node/server-routes.ts +16 -8
- package/.docu/node/server.ts +20 -2
- package/package.json +3 -3
- package/template/docu.json +1 -1
|
@@ -28,7 +28,8 @@ function createHtmlResponse(
|
|
|
28
28
|
description: string,
|
|
29
29
|
body: string,
|
|
30
30
|
status: number,
|
|
31
|
-
state: ServerState
|
|
31
|
+
state: ServerState,
|
|
32
|
+
depth = 0
|
|
32
33
|
): Response {
|
|
33
34
|
const nonce = generateNonce();
|
|
34
35
|
const favicon = state.docuConfig.meta?.favicon || "/favicon.ico";
|
|
@@ -42,6 +43,7 @@ function createHtmlResponse(
|
|
|
42
43
|
nonce,
|
|
43
44
|
extraScripts: hmrScript(nonce),
|
|
44
45
|
themeCss: state.inlineThemeCss,
|
|
46
|
+
depth,
|
|
45
47
|
});
|
|
46
48
|
return htmlResponse(html, nonce, status, process.env.NODE_ENV !== "production");
|
|
47
49
|
}
|
|
@@ -140,6 +142,9 @@ async function renderDocsServerPage(
|
|
|
140
142
|
|
|
141
143
|
const body = renderToString(page);
|
|
142
144
|
|
|
145
|
+
// Match build.ts depth calculation: slug.split("/").length, fallback to 1 for empty
|
|
146
|
+
const depth = slug.length || 1;
|
|
147
|
+
|
|
143
148
|
if (state.builder) {
|
|
144
149
|
const ctx: PageContext = {
|
|
145
150
|
slug: slug.join("/") || "/",
|
|
@@ -164,12 +169,13 @@ async function renderDocsServerPage(
|
|
|
164
169
|
themeCss: state.inlineThemeCss,
|
|
165
170
|
headExtra,
|
|
166
171
|
bodyExtra,
|
|
172
|
+
depth,
|
|
167
173
|
});
|
|
168
174
|
html = await state.builder.runTransformHtmlChain(html, ctx);
|
|
169
175
|
return htmlResponse(html, nonce, 200, process.env.NODE_ENV !== "production");
|
|
170
176
|
}
|
|
171
177
|
|
|
172
|
-
return createHtmlResponse(title, description, body, 200, state);
|
|
178
|
+
return createHtmlResponse(title, description, body, 200, state, depth);
|
|
173
179
|
}
|
|
174
180
|
|
|
175
181
|
function renderPage(
|
|
@@ -178,7 +184,8 @@ function renderPage(
|
|
|
178
184
|
description: string,
|
|
179
185
|
status: number,
|
|
180
186
|
state: ServerState,
|
|
181
|
-
props: Record<string, unknown> = {}
|
|
187
|
+
props: Record<string, unknown> = {},
|
|
188
|
+
depth = 0
|
|
182
189
|
): Response {
|
|
183
190
|
const page = React.createElement(
|
|
184
191
|
DocsLayout,
|
|
@@ -186,19 +193,20 @@ function renderPage(
|
|
|
186
193
|
React.createElement(Component, props)
|
|
187
194
|
);
|
|
188
195
|
const body = renderToString(page);
|
|
189
|
-
return createHtmlResponse(title, description, body, status, state);
|
|
196
|
+
return createHtmlResponse(title, description, body, status, state, depth);
|
|
190
197
|
}
|
|
191
198
|
|
|
192
199
|
export async function handleDocsIndex(state: ServerState): Promise<Response> {
|
|
193
200
|
const doc = await getDocsForSlug("", state);
|
|
194
|
-
if (!doc) return renderPage(NotFoundPage, "404 - Not Found", "", 404, state);
|
|
201
|
+
if (!doc) return renderPage(NotFoundPage, "404 - Not Found", "", 404, state, {}, 1);
|
|
195
202
|
return renderDocsServerPage(doc, [], "/docs", state);
|
|
196
203
|
}
|
|
197
204
|
|
|
198
205
|
export async function handleDocsRoute(slug: string[], state: ServerState): Promise<Response> {
|
|
199
206
|
const path = slug.join("/");
|
|
200
207
|
const doc = await getDocsForSlug(path, state);
|
|
201
|
-
if (!doc)
|
|
208
|
+
if (!doc)
|
|
209
|
+
return renderPage(NotFoundPage, "404 - Not Found", "", 404, state, {}, slug.length || 1);
|
|
202
210
|
return renderDocsServerPage(doc, slug, `/docs/${path}`, state);
|
|
203
211
|
}
|
|
204
212
|
|
|
@@ -214,8 +222,8 @@ export function handleIndex(state: ServerState): Response {
|
|
|
214
222
|
);
|
|
215
223
|
}
|
|
216
224
|
|
|
217
|
-
export function handleNotFound(state: ServerState): Response {
|
|
218
|
-
return renderPage(NotFoundPage, "404 - Not Found", "", 404, state);
|
|
225
|
+
export function handleNotFound(state: ServerState, depth = 0): Response {
|
|
226
|
+
return renderPage(NotFoundPage, "404 - Not Found", "", 404, state, {}, depth);
|
|
219
227
|
}
|
|
220
228
|
|
|
221
229
|
export function serveStatic(pathname: string): Response | null {
|
package/.docu/node/server.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
serverErrorResponse,
|
|
16
16
|
type ServerState,
|
|
17
17
|
} from "./server-routes";
|
|
18
|
+
import { SECURITY_HEADERS, cspHeader, generateNonce } from "./security";
|
|
18
19
|
|
|
19
20
|
const docuConfig = loadDocuConfig();
|
|
20
21
|
|
|
@@ -107,13 +108,30 @@ const server = Bun.serve({
|
|
|
107
108
|
hostname: server.hostname!,
|
|
108
109
|
});
|
|
109
110
|
if (pluginResponse) {
|
|
111
|
+
// Wrap plugin response with security headers.
|
|
112
|
+
// Plugin's own headers take precedence over defaults.
|
|
113
|
+
const securedHeaders = new Headers(pluginResponse.headers);
|
|
114
|
+
for (const [key, value] of Object.entries(SECURITY_HEADERS)) {
|
|
115
|
+
if (!securedHeaders.has(key)) {
|
|
116
|
+
securedHeaders.set(key, value);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const contentType = securedHeaders.get("Content-Type") || "";
|
|
120
|
+
if (contentType.includes("text/html") && !securedHeaders.has("Content-Security-Policy")) {
|
|
121
|
+
securedHeaders.set("Content-Security-Policy", cspHeader(generateNonce(), true));
|
|
122
|
+
}
|
|
123
|
+
const securedResponse = new Response(pluginResponse.body, {
|
|
124
|
+
status: pluginResponse.status,
|
|
125
|
+
statusText: pluginResponse.statusText,
|
|
126
|
+
headers: securedHeaders,
|
|
127
|
+
});
|
|
110
128
|
logger.request(
|
|
111
129
|
req.method,
|
|
112
130
|
pathname,
|
|
113
|
-
|
|
131
|
+
securedResponse.status,
|
|
114
132
|
Math.round(performance.now() - startTime)
|
|
115
133
|
);
|
|
116
|
-
return
|
|
134
|
+
return securedResponse;
|
|
117
135
|
}
|
|
118
136
|
}
|
|
119
137
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docubook/flame",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"description": "A blazing-fast React + MDX framework powered by Bun, built for modern documentation experiences.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
"unified": "^11.0.0",
|
|
55
55
|
"@docubook/core": "^1.7.2",
|
|
56
56
|
"@docubook/mdx-content": "^3.2.2",
|
|
57
|
-
"@docubook/
|
|
58
|
-
"@docubook/
|
|
57
|
+
"@docubook/themes-colors": "^0.10.2",
|
|
58
|
+
"@docubook/ui-react": "^0.1.4"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@sentry/bun": "^10.0.0"
|