@docubook/flame 2.0.0-beta.1 → 2.0.0-beta.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.
Files changed (60) hide show
  1. package/.docu/lib/build.deno.js +6 -9
  2. package/.docu/lib/build.deno.js.map +1 -0
  3. package/.docu/lib/build.impl-Bz_p421t.js +424 -0
  4. package/.docu/lib/build.impl-Bz_p421t.js.map +1 -0
  5. package/.docu/lib/build.impl-CtPrlYAE.js +2 -0
  6. package/.docu/lib/build.node.js +6 -9
  7. package/.docu/lib/build.node.js.map +1 -0
  8. package/.docu/lib/clean.js +25 -25
  9. package/.docu/lib/clean.js.map +1 -0
  10. package/.docu/lib/deno-DmEaKggj.js +20 -0
  11. package/.docu/lib/deno-DmEaKggj.js.map +1 -0
  12. package/.docu/lib/deploy.deno.js +9 -9
  13. package/.docu/lib/deploy.deno.js.map +1 -0
  14. package/.docu/lib/deploy.node.js +8 -8
  15. package/.docu/lib/deploy.node.js.map +1 -0
  16. package/.docu/lib/deploy.shared-fk8eM-r4.js +295 -0
  17. package/.docu/lib/deploy.shared-fk8eM-r4.js.map +1 -0
  18. package/.docu/lib/html.shared-FwgbE1WG.js +2696 -0
  19. package/.docu/lib/html.shared-FwgbE1WG.js.map +1 -0
  20. package/.docu/lib/logger-CQyNTE6L.js +306 -0
  21. package/.docu/lib/logger-CQyNTE6L.js.map +1 -0
  22. package/.docu/lib/node-DPTySdwG.js +80 -0
  23. package/.docu/lib/node-DPTySdwG.js.map +1 -0
  24. package/.docu/lib/paths-Bl2cdp9E.js +76 -0
  25. package/.docu/lib/paths-Bl2cdp9E.js.map +1 -0
  26. package/.docu/lib/preview.deno.js +7 -11
  27. package/.docu/lib/preview.deno.js.map +1 -0
  28. package/.docu/lib/preview.impl-CnsbLmDA.js +77 -0
  29. package/.docu/lib/preview.impl-CnsbLmDA.js.map +1 -0
  30. package/.docu/lib/preview.node.js +7 -11
  31. package/.docu/lib/preview.node.js.map +1 -0
  32. package/.docu/lib/server.deno.js +7 -12
  33. package/.docu/lib/server.deno.js.map +1 -0
  34. package/.docu/lib/server.impl-CXTzYqbF.js +358 -0
  35. package/.docu/lib/server.impl-CXTzYqbF.js.map +1 -0
  36. package/.docu/lib/server.node.js +7 -12
  37. package/.docu/lib/server.node.js.map +1 -0
  38. package/.docu/lib/utils-DA17MyQG.js +167 -0
  39. package/.docu/lib/utils-DA17MyQG.js.map +1 -0
  40. package/.docu/node/build.impl.ts +76 -11
  41. package/.docu/node/build.ts +83 -9
  42. package/.docu/node/cache-key.ts +311 -0
  43. package/.docu/node/hydrate.node.ts +124 -177
  44. package/.docu/node/hydrate.ts +13 -14
  45. package/.docu/node/mdx.ts +14 -2
  46. package/.docu/node/paths.ts +27 -1
  47. package/.docu/node/types.ts +23 -5
  48. package/bin/cli.js +56 -18
  49. package/bin/compile-lib.mjs +30 -28
  50. package/package.json +10 -16
  51. package/.docu/lib/build.impl-3ZOQORN3.js +0 -12
  52. package/.docu/lib/chunk-4IQXHHPF.js +0 -62
  53. package/.docu/lib/chunk-6EOUQCRM.js +0 -301
  54. package/.docu/lib/chunk-6HFBJUMG.js +0 -434
  55. package/.docu/lib/chunk-EOK6KATZ.js +0 -191
  56. package/.docu/lib/chunk-FERG25YW.js +0 -470
  57. package/.docu/lib/chunk-MQRFIDS4.js +0 -92
  58. package/.docu/lib/chunk-U7M5SK76.js +0 -330
  59. package/.docu/lib/chunk-UISOJ4RW.js +0 -114
  60. package/.docu/lib/chunk-URBATJEC.js +0 -2720
@@ -1,470 +0,0 @@
1
- import {
2
- BuildPluginBuilder,
3
- DocsLayout,
4
- DocsPage,
5
- IndexPage,
6
- NotFoundPage,
7
- buildClientBundle,
8
- captureException,
9
- compileMdx,
10
- compileMdxModule,
11
- computeInlineThemeCss,
12
- frontmatterField,
13
- generateSearchIndex,
14
- getGitLastModifiedBatch,
15
- getPageContent,
16
- getPageFrontmatter,
17
- getPageStripped,
18
- htmlShell,
19
- initSentry,
20
- loadPlugins,
21
- registerPageContent
22
- } from "./chunk-URBATJEC.js";
23
- import {
24
- cspHeader,
25
- generateNonce,
26
- scanMdxFiles
27
- } from "./chunk-EOK6KATZ.js";
28
- import {
29
- logger
30
- } from "./chunk-6EOUQCRM.js";
31
- import {
32
- ASSETS_DIR,
33
- CACHE_FILE,
34
- DIST_DIR,
35
- DOCS_ASSETS_DIR,
36
- DOCS_DIR,
37
- PROJECT_ROOT,
38
- loadDocuConfig
39
- } from "./chunk-4IQXHHPF.js";
40
-
41
- // .docu/node/build.impl.ts
42
- import { readFile, writeFile, mkdir, readdir, copyFile } from "node:fs/promises";
43
- import { existsSync } from "node:fs";
44
- import { createHash } from "node:crypto";
45
- import { join, dirname } from "node:path";
46
- import React from "react";
47
- import { renderToString } from "react-dom/server";
48
-
49
- // .docu/node/seo.ts
50
- function buildSeoMeta(config, frontmatter, slug) {
51
- const baseURL = config.meta?.baseURL?.replace(/\/+$/, "") || "";
52
- const url = slug ? `${baseURL}/docs/${slug}` : `${baseURL}/`;
53
- const result = {
54
- url,
55
- siteName: config.meta?.title || ""
56
- };
57
- const image = frontmatterField(frontmatter, "image") || config.meta?.ogImage;
58
- if (image) {
59
- try {
60
- result.image = new URL(image, image.startsWith("/") ? baseURL : `${baseURL}/docs/`).href;
61
- } catch {
62
- result.image = image;
63
- }
64
- }
65
- return result;
66
- }
67
-
68
- // .docu/node/build.impl.ts
69
- function parseArgs() {
70
- const args = process.argv.slice(2);
71
- return {
72
- force: args.includes("--force") || args.includes("-f"),
73
- clean: args.includes("--clean") || args.includes("-c")
74
- };
75
- }
76
- function hashContent(content) {
77
- return createHash("sha256").update(content).digest("hex").slice(0, 16);
78
- }
79
- async function readCache() {
80
- try {
81
- if (existsSync(CACHE_FILE)) {
82
- const data = await readFile(CACHE_FILE, "utf-8");
83
- return JSON.parse(data);
84
- }
85
- } catch (err) {
86
- console.error("Failed to load build cache:", err.message);
87
- }
88
- return {};
89
- }
90
- async function writeCache(cache) {
91
- await writeFile(CACHE_FILE, JSON.stringify(cache, null, 2));
92
- }
93
- function parseConcurrency() {
94
- return Math.max(1, parseInt(process.env.BUILD_CONCURRENCY || "4", 10) || 4);
95
- }
96
- function shouldRebuild(path, mtime, cache) {
97
- const cached = cache[path];
98
- if (!cached) return "yes";
99
- if (mtime > cached.builtAt) return "hash_check";
100
- return "no";
101
- }
102
- var assetManifest = { js: "client.js", css: "client.css" };
103
- var inlineThemeCss;
104
- async function renderDocsPage(docuConfig, slug, rawMdx, filePath, gitDates, builder, nonce) {
105
- let content = rawMdx;
106
- if (builder) {
107
- const transformed = await builder.runOnLoad(filePath, content);
108
- if (transformed?.contents) {
109
- content = transformed.contents;
110
- }
111
- }
112
- let result;
113
- try {
114
- const remarkPlugins = builder?.collectRemarkPlugins();
115
- const rehypePlugins = builder?.collectRehypePlugins();
116
- const preFm = getPageFrontmatter(`/${slug}`);
117
- const preStripped = getPageStripped(`/${slug}`);
118
- const pre = preFm !== void 0 && preStripped !== void 0 ? { frontmatter: preFm, strippedContent: preStripped } : void 0;
119
- result = await compileMdx(
120
- content,
121
- filePath,
122
- gitDates,
123
- remarkPlugins,
124
- rehypePlugins,
125
- void 0,
126
- pre
127
- );
128
- } catch (err) {
129
- const msg = err instanceof Error ? err.message : "Unknown MDX error";
130
- throw new Error(`MDX Error in: docs/${slug}.mdx
131
- ${msg}`, { cause: err });
132
- }
133
- let frontmatter = result.frontmatter;
134
- if (builder) {
135
- frontmatter = await builder.runTransformFrontmatterChain(frontmatter, {
136
- slug,
137
- filePath,
138
- content
139
- });
140
- }
141
- const title = frontmatterField(frontmatter, "title") || slug || "Docs";
142
- const description = frontmatterField(frontmatter, "description");
143
- const slugParts = slug ? slug.split("/") : [];
144
- const page = React.createElement(
145
- DocsLayout,
146
- { repoUrl: docuConfig.repo?.url },
147
- React.createElement(DocsPage, {
148
- slug: slugParts,
149
- title,
150
- description,
151
- date: frontmatterField(frontmatter, "date") || void 0,
152
- // Render MDX content as its own root: client hydrates the island as a
153
- // separate root, so SSR must be root-relative too or useId-based ids
154
- // (mdx-compiler components) mismatch during hydration.
155
- content: renderToString(result.content),
156
- tocs: result.tocs,
157
- filePath,
158
- repoUrl: docuConfig.repo?.url,
159
- mdxSlug: slug
160
- })
161
- );
162
- const body = renderToString(page);
163
- const ctx = { slug, filePath, frontmatter, content, config: docuConfig };
164
- const headExtra = builder?.collectHead(ctx);
165
- const bodyExtra = builder?.collectBody(ctx);
166
- const depth = slug ? slug.split("/").length : 1;
167
- const favicon = docuConfig.meta?.favicon || "/docs/assets/images/favicon.ico";
168
- const seo = buildSeoMeta(docuConfig, frontmatter, slug || "");
169
- const csp = cspHeader(nonce);
170
- let html = htmlShell({
171
- title,
172
- description,
173
- body,
174
- favicon,
175
- seo,
176
- csp,
177
- css: assetManifest.css,
178
- js: assetManifest.js,
179
- nonce,
180
- themeCss: inlineThemeCss,
181
- depth,
182
- headExtra,
183
- bodyExtra
184
- });
185
- if (builder) {
186
- html = await builder.runTransformHtmlChain(html, ctx);
187
- }
188
- return html;
189
- }
190
- async function copyDirectoryRecursive(src, dest) {
191
- if (!existsSync(src)) return;
192
- await mkdir(dest, { recursive: true });
193
- const entries = await readdir(src, { withFileTypes: true });
194
- for (const entry of entries) {
195
- const srcPath = join(src, entry.name);
196
- const destPath = join(dest, entry.name);
197
- if (entry.isDirectory()) {
198
- await copyDirectoryRecursive(srcPath, destPath);
199
- } else {
200
- await copyFile(srcPath, destPath);
201
- }
202
- }
203
- }
204
- async function runBuild() {
205
- const docuConfig = loadDocuConfig();
206
- const args = parseArgs();
207
- logger.buildStart();
208
- if (args.clean) {
209
- const { rm } = await import("node:fs/promises");
210
- try {
211
- await rm(DIST_DIR, { recursive: true, force: true });
212
- } catch (err) {
213
- console.error("Failed to clean dist directory:", err.message);
214
- }
215
- }
216
- await mkdir(DIST_DIR, { recursive: true });
217
- await mkdir(ASSETS_DIR, { recursive: true });
218
- await copyDirectoryRecursive(DOCS_ASSETS_DIR, join(DIST_DIR, "docs", "assets"));
219
- const mdxFiles = await scanMdxFiles(DOCS_DIR);
220
- const cache = args.force ? {} : await readCache();
221
- let built = 0;
222
- let skipped = 0;
223
- const pluginsConfig = docuConfig.plugins ?? [];
224
- const builder = pluginsConfig.length > 0 ? new BuildPluginBuilder(docuConfig) : null;
225
- if (builder) {
226
- const plugins = await loadPlugins(pluginsConfig);
227
- for (const plugin of plugins) {
228
- await plugin.setup(builder);
229
- }
230
- await builder.runOnStart();
231
- }
232
- const mdxSources = {};
233
- const prePassTasks = mdxFiles.map(async (file) => {
234
- let raw;
235
- try {
236
- raw = await readFile(file.absPath, "utf-8");
237
- } catch {
238
- return;
239
- }
240
- registerPageContent(`/${file.path}`, raw);
241
- let content = raw;
242
- if (builder) {
243
- const relPath = file.absPath.replace(PROJECT_ROOT + "/", "");
244
- const transformed = await builder.runOnLoad(relPath, content);
245
- if (transformed?.contents) content = transformed.contents;
246
- }
247
- const remarkPlugins = builder?.collectRemarkPlugins();
248
- const rehypePlugins = builder?.collectRehypePlugins();
249
- mdxSources[file.path] = await compileMdxModule(
250
- content,
251
- remarkPlugins,
252
- rehypePlugins,
253
- `/${file.path}`
254
- );
255
- });
256
- await Promise.all(prePassTasks);
257
- const indexMdxPath = join(DOCS_DIR, "index.mdx");
258
- if (existsSync(indexMdxPath)) {
259
- try {
260
- const indexRaw = await readFile(indexMdxPath, "utf-8");
261
- let indexContent = indexRaw;
262
- if (builder) {
263
- const relPath = indexMdxPath.replace(PROJECT_ROOT + "/", "");
264
- const transformed = await builder.runOnLoad(relPath, indexContent);
265
- if (transformed?.contents) indexContent = transformed.contents;
266
- }
267
- mdxSources[""] = await compileMdxModule(
268
- indexContent,
269
- builder?.collectRemarkPlugins(),
270
- builder?.collectRehypePlugins()
271
- );
272
- } catch {
273
- }
274
- }
275
- logger.bundleStart();
276
- let t = performance.now();
277
- assetManifest = await buildClientBundle(mdxSources);
278
- logger.bundleDone(Math.round(performance.now() - t));
279
- inlineThemeCss = computeInlineThemeCss();
280
- const lastManifest = cache["__assets__"];
281
- const assetsChanged = !lastManifest || lastManifest.hash !== `${assetManifest.js}:${assetManifest.css}`;
282
- if (assetsChanged) {
283
- cache["__assets__"] = {
284
- hash: `${assetManifest.js}:${assetManifest.css}`,
285
- mtime: 0,
286
- builtAt: Date.now()
287
- };
288
- }
289
- logger.spinner.start("Building pages...");
290
- t = performance.now();
291
- const allRelPaths = mdxFiles.map((f) => f.absPath.replace(PROJECT_ROOT + "/", ""));
292
- const indexMdxFull = join(DOCS_DIR, "index.mdx");
293
- if (existsSync(indexMdxFull)) {
294
- allRelPaths.push(indexMdxFull.replace(PROJECT_ROOT + "/", ""));
295
- }
296
- const gitDates = await getGitLastModifiedBatch(allRelPaths);
297
- const CONCURRENCY = parseConcurrency();
298
- const buildTasks = [];
299
- const errors = [];
300
- for (const file of mdxFiles) {
301
- const rebuildDecision = shouldRebuild(file.path, file.mtime, cache);
302
- if (rebuildDecision === "no") {
303
- const outputPath = join(DIST_DIR, "docs", `${file.path}.html`);
304
- if (existsSync(outputPath) && !assetsChanged) {
305
- skipped++;
306
- continue;
307
- }
308
- }
309
- let rawMdx = getPageContent(`/${file.path}`);
310
- if (rawMdx === void 0) {
311
- try {
312
- rawMdx = await readFile(file.absPath, "utf-8");
313
- } catch (err) {
314
- if (err.code !== "ENOENT") throw err;
315
- continue;
316
- }
317
- }
318
- if (rebuildDecision === "hash_check") {
319
- const contentHash = hashContent(rawMdx);
320
- const cached = cache[file.path];
321
- if (cached && cached.hash === contentHash) {
322
- if (!assetsChanged) {
323
- const outputPath = join(DIST_DIR, "docs", `${file.path}.html`);
324
- if (existsSync(outputPath)) {
325
- cache[file.path] = { ...cached, mtime: file.mtime, builtAt: Date.now() };
326
- skipped++;
327
- continue;
328
- }
329
- }
330
- }
331
- }
332
- const relPath = file.absPath.replace(PROJECT_ROOT + "/", "");
333
- const capturedRawMdx = rawMdx;
334
- const capturedFile = file;
335
- buildTasks.push(async () => {
336
- try {
337
- const pageNonce = generateNonce();
338
- const html = await renderDocsPage(
339
- docuConfig,
340
- capturedFile.path,
341
- capturedRawMdx,
342
- relPath,
343
- gitDates,
344
- builder,
345
- pageNonce
346
- );
347
- const outputPath = join(DIST_DIR, "docs", `${capturedFile.path}.html`);
348
- await mkdir(dirname(outputPath), { recursive: true });
349
- await writeFile(outputPath, html);
350
- cache[capturedFile.path] = {
351
- hash: hashContent(capturedRawMdx),
352
- mtime: capturedFile.mtime,
353
- builtAt: Date.now()
354
- };
355
- built++;
356
- } catch (err) {
357
- const msg = err instanceof Error ? err.message : String(err);
358
- errors.push(msg);
359
- console.error(`
360
- \u274C ${msg}
361
- `);
362
- }
363
- });
364
- }
365
- for (let i = 0; i < buildTasks.length; i += CONCURRENCY) {
366
- await Promise.all(buildTasks.slice(i, i + CONCURRENCY).map((fn) => fn()));
367
- }
368
- try {
369
- const indexMdxPath2 = join(DOCS_DIR, "index.mdx");
370
- const indexRaw = await readFile(indexMdxPath2, "utf-8");
371
- const indexRelPath = indexMdxPath2.replace(PROJECT_ROOT + "/", "");
372
- const indexHtml = await renderDocsPage(
373
- docuConfig,
374
- "",
375
- indexRaw,
376
- indexRelPath,
377
- gitDates,
378
- builder,
379
- generateNonce()
380
- );
381
- await mkdir(join(DIST_DIR, "docs"), { recursive: true });
382
- await writeFile(join(DIST_DIR, "docs", "index.html"), indexHtml);
383
- } catch (err) {
384
- const msg = err instanceof Error ? err.message : String(err);
385
- errors.push(`index.mdx: ${msg}`);
386
- console.error(`
387
- \u274C Failed to build index: ${msg}
388
- `);
389
- }
390
- const landingPage = React.createElement(IndexPage);
391
- const landingFavicon = docuConfig.meta?.favicon || "/docs/assets/images/favicon.ico";
392
- const landingSeo = buildSeoMeta(docuConfig, docuConfig.meta, "");
393
- const landingNonce = generateNonce();
394
- const landingHtml = htmlShell({
395
- title: docuConfig.meta?.title || "DocuBook",
396
- description: docuConfig.meta?.description || "",
397
- body: renderToString(landingPage),
398
- favicon: landingFavicon,
399
- seo: landingSeo,
400
- csp: cspHeader(landingNonce),
401
- css: assetManifest.css,
402
- js: assetManifest.js,
403
- nonce: landingNonce,
404
- themeCss: inlineThemeCss
405
- });
406
- await writeFile(join(DIST_DIR, "index.html"), landingHtml);
407
- const notFoundPage = React.createElement(
408
- DocsLayout,
409
- { repoUrl: docuConfig.repo?.url },
410
- React.createElement(NotFoundPage)
411
- );
412
- const notFoundFavicon = docuConfig.meta?.favicon || "/docs/assets/images/favicon.ico";
413
- const notFoundNonce = generateNonce();
414
- const notFoundHtml = htmlShell({
415
- title: "404 - Not Found",
416
- description: "",
417
- body: renderToString(notFoundPage),
418
- favicon: notFoundFavicon,
419
- headExtra: ['<meta name="robots" content="noindex,follow">'],
420
- csp: cspHeader(notFoundNonce),
421
- css: assetManifest.css,
422
- js: assetManifest.js,
423
- nonce: notFoundNonce,
424
- themeCss: inlineThemeCss,
425
- // Served as the static-host fallback at ANY requested path — relative
426
- // depth can never be right there, so use root-absolute asset URLs.
427
- absoluteAssets: true
428
- });
429
- await writeFile(join(DIST_DIR, "404.html"), notFoundHtml);
430
- logger.spinner.stop(
431
- `Built ${built} pages (${skipped} cached) \x1B[90m(${Math.round(performance.now() - t)}ms)\x1B[0m`
432
- );
433
- if (builder) {
434
- const pages = mdxFiles.map((f) => ({
435
- slug: f.path,
436
- title: f.path.split("/").pop() || f.path,
437
- filePath: join(DOCS_DIR, f.path),
438
- outputPath: join(DIST_DIR, "docs", `${f.path}.html`)
439
- }));
440
- await builder.runOnEnd(pages);
441
- }
442
- logger.indexStart();
443
- t = performance.now();
444
- const indexSkipped = built === 0 && existsSync(join(ASSETS_DIR, "search-index.json"));
445
- const indexCount = indexSkipped ? 0 : await generateSearchIndex();
446
- logger.indexDone(indexCount, Math.round(performance.now() - t), indexSkipped);
447
- logger.routes();
448
- await writeCache(cache);
449
- if (errors.length > 0) {
450
- console.error(`
451
- \u274C Build completed with ${errors.length} error(s)
452
- `);
453
- process.exit(1);
454
- }
455
- }
456
- async function runBuildCli() {
457
- try {
458
- await initSentry();
459
- await runBuild();
460
- } catch (err) {
461
- captureException(err);
462
- console.error("Build failed:", err);
463
- process.exit(1);
464
- }
465
- }
466
-
467
- export {
468
- runBuild,
469
- runBuildCli
470
- };
@@ -1,92 +0,0 @@
1
- import {
2
- SECURITY_HEADERS,
3
- cspHeader,
4
- generateNonce,
5
- getContentType,
6
- injectNonce
7
- } from "./chunk-EOK6KATZ.js";
8
- import {
9
- logger
10
- } from "./chunk-6EOUQCRM.js";
11
- import {
12
- DIST_DIR
13
- } from "./chunk-4IQXHHPF.js";
14
-
15
- // .docu/node/preview.impl.ts
16
- import { existsSync, statSync, readFileSync } from "node:fs";
17
- import { readFile } from "node:fs/promises";
18
- import { resolve } from "node:path";
19
- function resolveFile(pathname) {
20
- const path = pathname.slice(1);
21
- const isWithinDist = (p) => p === DIST_DIR || p.startsWith(DIST_DIR + "/");
22
- if (!path.includes(".")) {
23
- const withIndex = resolve(DIST_DIR, path, "index.html");
24
- if (isWithinDist(withIndex) && existsSync(withIndex)) return withIndex;
25
- const withHtml = resolve(DIST_DIR, path + ".html");
26
- if (isWithinDist(withHtml) && existsSync(withHtml)) return withHtml;
27
- }
28
- const exact = resolve(DIST_DIR, path);
29
- if (!isWithinDist(exact)) return null;
30
- try {
31
- if (statSync(exact).isFile()) return exact;
32
- } catch (err) {
33
- if (err.code !== "ENOENT") throw err;
34
- }
35
- return null;
36
- }
37
- async function runPreview(adapter) {
38
- const PORT = parseInt(process.env.PORT || "4173", 10);
39
- logger.buildStart();
40
- if (!existsSync(DIST_DIR)) {
41
- logger.spinner.start("Checking build output...");
42
- logger.spinner.info("dist not found. Run \x1B[1mflame build\x1B[0m first.");
43
- process.exit(0);
44
- }
45
- const notFoundPath = resolve(DIST_DIR, "404.html");
46
- const handle = await adapter.serve(
47
- async (req) => {
48
- const url = new URL(req.url);
49
- const pathname = decodeURIComponent(url.pathname);
50
- const filePath = resolveFile(pathname);
51
- if (filePath) {
52
- const contentType = getContentType(filePath);
53
- if (contentType === "text/html") {
54
- const nonce = generateNonce();
55
- const html = await readFile(filePath, "utf-8");
56
- const modified = injectNonce(html, nonce);
57
- return new Response(modified, {
58
- headers: {
59
- "Content-Type": "text/html",
60
- ...SECURITY_HEADERS,
61
- "Content-Security-Policy": cspHeader(nonce)
62
- }
63
- });
64
- }
65
- return new Response(readFileSync(filePath), {
66
- headers: { "Content-Type": contentType }
67
- });
68
- }
69
- if (existsSync(notFoundPath)) {
70
- const nonce = generateNonce();
71
- const html = await readFile(notFoundPath, "utf-8");
72
- const modified = injectNonce(html, nonce);
73
- return new Response(modified, {
74
- status: 404,
75
- headers: {
76
- "Content-Type": "text/html",
77
- ...SECURITY_HEADERS,
78
- "Content-Security-Policy": cspHeader(nonce)
79
- }
80
- });
81
- }
82
- return new Response("404 - Not Found", { status: 404 });
83
- },
84
- { port: PORT }
85
- );
86
- logger.ready(handle.port);
87
- return handle;
88
- }
89
-
90
- export {
91
- runPreview
92
- };