@docubook/flame 1.4.4 → 1.5.1

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 (53) hide show
  1. package/.docu/lib/build.deno.js +11 -0
  2. package/.docu/lib/build.impl-7KJ4ZTAJ.js +12 -0
  3. package/.docu/lib/build.node.js +10 -0
  4. package/.docu/lib/chunk-7ZEUL6PR.js +383 -0
  5. package/.docu/lib/chunk-AI7QAMMZ.js +2410 -0
  6. package/.docu/lib/chunk-E4OIJWCU.js +368 -0
  7. package/.docu/lib/chunk-IR5TVJOV.js +79 -0
  8. package/.docu/lib/chunk-J5NMYSBJ.js +59 -0
  9. package/.docu/lib/chunk-PTRZ2S2C.js +298 -0
  10. package/.docu/lib/chunk-RE4NGTMT.js +185 -0
  11. package/.docu/lib/chunk-TE52TIEW.js +92 -0
  12. package/.docu/lib/clean.js +32 -0
  13. package/.docu/lib/deploy.deno.js +13 -0
  14. package/.docu/lib/deploy.node.js +10 -0
  15. package/.docu/lib/preview.deno.js +10 -0
  16. package/.docu/lib/preview.node.js +10 -0
  17. package/.docu/lib/server.deno.js +11 -0
  18. package/.docu/lib/server.node.js +11 -0
  19. package/.docu/node/build.deno.ts +7 -0
  20. package/.docu/node/build.impl.ts +416 -0
  21. package/.docu/node/build.node.ts +3 -0
  22. package/.docu/node/deploy.deno.ts +11 -0
  23. package/.docu/node/deploy.node.ts +6 -0
  24. package/.docu/node/deploy.shared.ts +85 -0
  25. package/.docu/node/deploy.ts +11 -0
  26. package/.docu/node/escapeHtml.ts +18 -0
  27. package/.docu/node/git.ts +79 -0
  28. package/.docu/node/html.shared.ts +110 -0
  29. package/.docu/node/hydrate.node.ts +276 -0
  30. package/.docu/node/hydrate.ts +17 -31
  31. package/.docu/node/mdx.ts +1 -1
  32. package/.docu/node/paths.ts +24 -0
  33. package/.docu/node/plugin-builder.ts +6 -2
  34. package/.docu/node/plugin.ts +11 -2
  35. package/.docu/node/preview.deno.ts +4 -0
  36. package/.docu/node/preview.impl.ts +96 -0
  37. package/.docu/node/preview.node.ts +4 -0
  38. package/.docu/node/security.ts +5 -0
  39. package/.docu/node/server-routes.ts +4 -4
  40. package/.docu/node/server.deno.ts +4 -0
  41. package/.docu/node/server.impl.ts +184 -0
  42. package/.docu/node/server.node.ts +4 -0
  43. package/.docu/styles/globals.css +20 -5
  44. package/README.md +57 -506
  45. package/bin/cli.js +99 -14
  46. package/bin/compile-lib.mjs +67 -0
  47. package/package.json +9 -7
  48. package/template/docs/getting-started/configuration.mdx +18 -0
  49. package/template/docs/getting-started/overview.mdx +50 -0
  50. package/template/docs/guide/deployment.mdx +27 -0
  51. package/template/docs/guide/routing.mdx +25 -0
  52. package/template/docs/index.mdx +8 -205
  53. package/template/docu.json +32 -1
@@ -0,0 +1,11 @@
1
+ import {
2
+ runBuildCli
3
+ } from "./chunk-E4OIJWCU.js";
4
+ import "./chunk-AI7QAMMZ.js";
5
+ import "./chunk-RE4NGTMT.js";
6
+ import "./chunk-PTRZ2S2C.js";
7
+ import "./chunk-J5NMYSBJ.js";
8
+
9
+ // .docu/node/build.deno.ts
10
+ await runBuildCli();
11
+ process.exit(0);
@@ -0,0 +1,12 @@
1
+ import {
2
+ runBuild,
3
+ runBuildCli
4
+ } from "./chunk-E4OIJWCU.js";
5
+ import "./chunk-AI7QAMMZ.js";
6
+ import "./chunk-RE4NGTMT.js";
7
+ import "./chunk-PTRZ2S2C.js";
8
+ import "./chunk-J5NMYSBJ.js";
9
+ export {
10
+ runBuild,
11
+ runBuildCli
12
+ };
@@ -0,0 +1,10 @@
1
+ import {
2
+ runBuildCli
3
+ } from "./chunk-E4OIJWCU.js";
4
+ import "./chunk-AI7QAMMZ.js";
5
+ import "./chunk-RE4NGTMT.js";
6
+ import "./chunk-PTRZ2S2C.js";
7
+ import "./chunk-J5NMYSBJ.js";
8
+
9
+ // .docu/node/build.node.ts
10
+ await runBuildCli();
@@ -0,0 +1,383 @@
1
+ import {
2
+ BuildPluginBuilder,
3
+ DocsLayout,
4
+ DocsPage,
5
+ IndexPage,
6
+ NotFoundPage,
7
+ buildClientBundle,
8
+ captureException,
9
+ compileMdx,
10
+ computeInlineThemeCss,
11
+ errorHtml,
12
+ generateSearchIndex,
13
+ hmrScript,
14
+ htmlShell,
15
+ initSentry,
16
+ loadPlugins
17
+ } from "./chunk-AI7QAMMZ.js";
18
+ import {
19
+ SECURITY_HEADERS,
20
+ generateNonce,
21
+ getContentType,
22
+ htmlResponse,
23
+ isPathSafe,
24
+ isSlugSafe,
25
+ stripDocsHtmlSuffix,
26
+ wrapPluginResponse
27
+ } from "./chunk-RE4NGTMT.js";
28
+ import {
29
+ logger
30
+ } from "./chunk-PTRZ2S2C.js";
31
+ import {
32
+ DIST_DIR,
33
+ DOCS_DIR,
34
+ PROJECT_ROOT,
35
+ loadDocuConfig
36
+ } from "./chunk-J5NMYSBJ.js";
37
+
38
+ // .docu/node/server.impl.ts
39
+ import { watch } from "node:fs";
40
+
41
+ // .docu/node/server-routes.ts
42
+ import { readFile } from "node:fs/promises";
43
+ import { resolve } from "node:path";
44
+ import { readFileSync, statSync } from "node:fs";
45
+ import React from "react";
46
+ import { renderToString } from "react-dom/server";
47
+ function createHtmlResponse(title, description, body, status, state, depth = 0) {
48
+ const nonce = generateNonce();
49
+ const favicon = state.docuConfig.meta?.favicon || "/favicon.ico";
50
+ const html = htmlShell({
51
+ title,
52
+ description,
53
+ body,
54
+ favicon,
55
+ css: state.assetManifest.css,
56
+ js: state.assetManifest.js,
57
+ nonce,
58
+ extraScripts: hmrScript(nonce),
59
+ themeCss: state.inlineThemeCss,
60
+ depth
61
+ });
62
+ return htmlResponse(html, nonce, status, process.env.NODE_ENV !== "production");
63
+ }
64
+ async function getDocsForSlug(slug, state) {
65
+ if (!isSlugSafe(slug, DOCS_DIR)) return null;
66
+ const paths = [
67
+ resolve(DOCS_DIR, slug, "index.mdx"),
68
+ resolve(DOCS_DIR, `${slug}.mdx`),
69
+ resolve(DOCS_DIR, slug, "index.md"),
70
+ resolve(DOCS_DIR, `${slug}.md`)
71
+ ];
72
+ const resolvedDocsDir = resolve(DOCS_DIR);
73
+ let filePath = null;
74
+ let raw = null;
75
+ for (const p of paths) {
76
+ const resolvedCandidate = resolve(p);
77
+ if (resolvedCandidate !== resolvedDocsDir && !resolvedCandidate.startsWith(resolvedDocsDir + "/")) {
78
+ continue;
79
+ }
80
+ try {
81
+ raw = await readFile(resolvedCandidate, "utf-8");
82
+ filePath = resolvedCandidate;
83
+ break;
84
+ } catch (err) {
85
+ if (err.code !== "ENOENT") throw err;
86
+ }
87
+ }
88
+ if (!filePath || !raw) return null;
89
+ const relPath = filePath.replace(PROJECT_ROOT + "/", "");
90
+ let content = raw;
91
+ if (state.builder) {
92
+ const transformed = await state.builder.runOnLoad(relPath, content);
93
+ if (transformed?.contents) {
94
+ content = transformed.contents;
95
+ }
96
+ }
97
+ const remarkPlugins = state.builder?.collectRemarkPlugins();
98
+ const rehypePlugins = state.builder?.collectRehypePlugins();
99
+ const result = await compileMdx(content, relPath, void 0, remarkPlugins, rehypePlugins);
100
+ let frontmatter = result.frontmatter;
101
+ if (state.builder) {
102
+ frontmatter = await state.builder.runTransformFrontmatterChain(frontmatter, {
103
+ slug: slug || "/",
104
+ filePath: relPath,
105
+ content
106
+ });
107
+ }
108
+ return {
109
+ content: result.content,
110
+ compiledSource: result.compiledSource,
111
+ frontmatter,
112
+ tocs: result.tocs,
113
+ filePath: relPath,
114
+ resolvedContent: content
115
+ };
116
+ }
117
+ async function renderDocsServerPage(doc, slug, pathname, state) {
118
+ const title = (typeof doc.frontmatter.title === "string" ? doc.frontmatter.title : "") || slug.join("/") || "Docs";
119
+ const description = typeof doc.frontmatter.description === "string" ? doc.frontmatter.description : "";
120
+ const page = React.createElement(
121
+ DocsLayout,
122
+ { repoUrl: state.docuConfig.repo?.url, pathname },
123
+ React.createElement(DocsPage, {
124
+ slug,
125
+ title,
126
+ description,
127
+ date: doc.frontmatter.date,
128
+ content: doc.content,
129
+ tocs: doc.tocs,
130
+ filePath: doc.filePath,
131
+ repoUrl: state.docuConfig.repo?.url,
132
+ compiledSource: doc.compiledSource
133
+ })
134
+ );
135
+ const body = renderToString(page);
136
+ const depth = slug.length || 1;
137
+ if (state.builder) {
138
+ const ctx = {
139
+ slug: slug.join("/") || "/",
140
+ filePath: doc.filePath,
141
+ frontmatter: doc.frontmatter,
142
+ content: doc.resolvedContent,
143
+ config: state.docuConfig
144
+ };
145
+ const headExtra = state.builder.collectHead(ctx);
146
+ const bodyExtra = state.builder.collectBody(ctx);
147
+ const nonce = generateNonce();
148
+ const favicon = state.docuConfig.meta?.favicon || "/favicon.ico";
149
+ let html = htmlShell({
150
+ title,
151
+ description,
152
+ body,
153
+ favicon,
154
+ css: state.assetManifest.css,
155
+ js: state.assetManifest.js,
156
+ nonce,
157
+ extraScripts: hmrScript(nonce),
158
+ themeCss: state.inlineThemeCss,
159
+ headExtra,
160
+ bodyExtra,
161
+ depth
162
+ });
163
+ html = await state.builder.runTransformHtmlChain(html, ctx);
164
+ return htmlResponse(html, nonce, 200, process.env.NODE_ENV !== "production");
165
+ }
166
+ return createHtmlResponse(title, description, body, 200, state, depth);
167
+ }
168
+ function renderPage(Component, title, description, status, state, props = {}, depth = 0) {
169
+ const page = React.createElement(
170
+ DocsLayout,
171
+ { repoUrl: state.docuConfig.repo?.url, pathname: "/docs" },
172
+ React.createElement(Component, props)
173
+ );
174
+ const body = renderToString(page);
175
+ return createHtmlResponse(title, description, body, status, state, depth);
176
+ }
177
+ async function handleDocsIndex(state) {
178
+ const doc = await getDocsForSlug("", state);
179
+ if (!doc) return renderPage(NotFoundPage, "404 - Not Found", "", 404, state, {}, 1);
180
+ return renderDocsServerPage(doc, [], "/docs", state);
181
+ }
182
+ async function handleDocsRoute(slug, state) {
183
+ const path = slug.join("/");
184
+ const doc = await getDocsForSlug(path, state);
185
+ if (!doc)
186
+ return renderPage(NotFoundPage, "404 - Not Found", "", 404, state, {}, slug.length || 1);
187
+ return renderDocsServerPage(doc, slug, `/docs/${path}`, state);
188
+ }
189
+ function handleIndex(state) {
190
+ const page = React.createElement(IndexPage);
191
+ const body = renderToString(page);
192
+ return createHtmlResponse(
193
+ state.docuConfig.meta?.title || "DocuBook",
194
+ state.docuConfig.meta?.description || "",
195
+ body,
196
+ 200,
197
+ state
198
+ );
199
+ }
200
+ function handleNotFound(state, depth = 0) {
201
+ return renderPage(NotFoundPage, "404 - Not Found", "", 404, state, {}, depth);
202
+ }
203
+ function serveStatic(pathname) {
204
+ let decoded;
205
+ try {
206
+ decoded = decodeURIComponent(pathname);
207
+ } catch {
208
+ return null;
209
+ }
210
+ if (!isPathSafe(pathname, DIST_DIR)) return null;
211
+ const assetPath = resolve(DIST_DIR, decoded.slice(1));
212
+ try {
213
+ const s = statSync(assetPath);
214
+ if (s.isFile()) {
215
+ return new Response(readFileSync(assetPath), {
216
+ headers: { "Content-Type": getContentType(pathname) }
217
+ });
218
+ }
219
+ } catch (err) {
220
+ if (err.code !== "ENOENT") throw err;
221
+ }
222
+ if (decoded.startsWith("/docs/assets/")) {
223
+ const docsAssetsDir = resolve(DOCS_DIR, "assets");
224
+ const requestedRelative = decoded.slice("/docs/assets/".length);
225
+ const docsAsset = resolve(docsAssetsDir, requestedRelative);
226
+ const docsAssetsDirWithSep = docsAssetsDir.endsWith("/") ? docsAssetsDir : docsAssetsDir + "/";
227
+ if (docsAsset !== docsAssetsDir && !docsAsset.startsWith(docsAssetsDirWithSep)) return null;
228
+ try {
229
+ const s = statSync(docsAsset);
230
+ if (s.isFile()) {
231
+ return new Response(readFileSync(docsAsset), {
232
+ headers: { "Content-Type": getContentType(pathname) }
233
+ });
234
+ }
235
+ } catch (err) {
236
+ if (err.code !== "ENOENT") throw err;
237
+ }
238
+ }
239
+ return null;
240
+ }
241
+ function serverErrorResponse(error) {
242
+ const msg = error instanceof Error ? error.message : "Unknown error";
243
+ const st = error instanceof Error ? error.stack : void 0;
244
+ return new Response(errorHtml(msg, st), {
245
+ status: 500,
246
+ headers: {
247
+ "Content-Type": "text/html",
248
+ ...SECURITY_HEADERS,
249
+ "Content-Security-Policy": "default-src 'none'; style-src 'unsafe-inline'"
250
+ }
251
+ });
252
+ }
253
+
254
+ // .docu/node/server.impl.ts
255
+ async function runServer(adapter) {
256
+ const docuConfig = loadDocuConfig();
257
+ const parsedPort = parseInt(process.env.PORT ?? "3000", 10);
258
+ const PORT = Number.isInteger(parsedPort) && parsedPort > 0 && parsedPort <= 65535 ? parsedPort : 3e3;
259
+ logger.buildStart();
260
+ await initSentry();
261
+ logger.bundleStart();
262
+ let t = performance.now();
263
+ const assetManifest = await buildClientBundle();
264
+ logger.bundleDone(Math.round(performance.now() - t));
265
+ const inlineThemeCss = computeInlineThemeCss();
266
+ logger.indexStart();
267
+ t = performance.now();
268
+ const records = await generateSearchIndex();
269
+ logger.indexDone(records, Math.round(performance.now() - t));
270
+ logger.routes();
271
+ const pluginsConfig = docuConfig.plugins ?? [];
272
+ const builder = pluginsConfig.length > 0 ? new BuildPluginBuilder(docuConfig) : null;
273
+ if (builder) {
274
+ const plugins = await loadPlugins(pluginsConfig);
275
+ for (const plugin of plugins) {
276
+ await plugin.setup(builder);
277
+ }
278
+ }
279
+ const state = {
280
+ docuConfig,
281
+ assetManifest,
282
+ inlineThemeCss,
283
+ builder
284
+ };
285
+ const hmrClients = /* @__PURE__ */ new Set();
286
+ let hmrTimeout = null;
287
+ const watcher = watch(DOCS_DIR, { recursive: true }, (_event, filename) => {
288
+ if (!filename || !filename.endsWith(".mdx") && !filename.endsWith(".md")) return;
289
+ if (hmrTimeout) clearTimeout(hmrTimeout);
290
+ hmrTimeout = setTimeout(() => {
291
+ for (const client of [...hmrClients]) {
292
+ try {
293
+ client.enqueue(new TextEncoder().encode("data: reload\n\n"));
294
+ } catch {
295
+ hmrClients.delete(client);
296
+ }
297
+ }
298
+ }, 300);
299
+ });
300
+ process.on("SIGINT", () => {
301
+ watcher.close();
302
+ process.exit(0);
303
+ });
304
+ process.on("SIGTERM", () => {
305
+ watcher.close();
306
+ process.exit(0);
307
+ });
308
+ let handle = null;
309
+ const fetchHandler = async (req) => {
310
+ const url = new URL(req.url);
311
+ const pathname = stripDocsHtmlSuffix(url.pathname);
312
+ const startTime = performance.now();
313
+ if (builder) {
314
+ const pluginResponse = await builder.runHandleRequest(req, {
315
+ port: handle?.port ?? PORT,
316
+ hostname: handle?.hostname ?? "localhost"
317
+ });
318
+ if (pluginResponse) {
319
+ const securedResponse = wrapPluginResponse(pluginResponse, true);
320
+ logger.request(
321
+ req.method,
322
+ pathname,
323
+ securedResponse.status,
324
+ Math.round(performance.now() - startTime)
325
+ );
326
+ return securedResponse;
327
+ }
328
+ }
329
+ try {
330
+ if (pathname === "/__hmr") {
331
+ const stream = new ReadableStream({
332
+ start(controller) {
333
+ hmrClients.add(controller);
334
+ controller.enqueue(new TextEncoder().encode("data: connected\n\n"));
335
+ },
336
+ cancel(controller) {
337
+ hmrClients.delete(controller);
338
+ }
339
+ });
340
+ return new Response(stream, {
341
+ headers: {
342
+ "Content-Type": "text/event-stream",
343
+ "Cache-Control": "no-cache",
344
+ Connection: "keep-alive"
345
+ }
346
+ });
347
+ }
348
+ if (pathname.startsWith("/assets/") || /\.\w+$/.test(pathname)) {
349
+ const staticRes = serveStatic(pathname);
350
+ if (staticRes) return staticRes;
351
+ }
352
+ let response;
353
+ if (pathname === "/") {
354
+ response = handleIndex(state);
355
+ } else if (pathname === "/docs" || pathname === "/docs/") {
356
+ response = await handleDocsIndex(state);
357
+ } else if (pathname.startsWith("/docs/")) {
358
+ const slug = pathname.slice("/docs/".length).split("/").filter(Boolean);
359
+ response = slug.length === 0 ? await handleDocsIndex(state) : await handleDocsRoute(slug, state);
360
+ } else {
361
+ response = handleNotFound(state);
362
+ }
363
+ logger.request(
364
+ req.method,
365
+ pathname,
366
+ response.status,
367
+ Math.round(performance.now() - startTime)
368
+ );
369
+ return response;
370
+ } catch (err) {
371
+ captureException(err, { method: req.method, pathname });
372
+ logger.request(req.method, pathname, 500, Math.round(performance.now() - startTime));
373
+ return serverErrorResponse(err);
374
+ }
375
+ };
376
+ handle = await adapter.serve(fetchHandler, { port: PORT, idleTimeout: 255 });
377
+ logger.ready(handle.port, true);
378
+ return handle;
379
+ }
380
+
381
+ export {
382
+ runServer
383
+ };