@docubook/flame 1.6.2 → 1.6.4

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.
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  runBuildCli
3
- } from "./chunk-OREEWUOV.js";
3
+ } from "./chunk-RH3WF75F.js";
4
4
  import "./chunk-WSJC3PRH.js";
5
5
  import "./chunk-EOK6KATZ.js";
6
- import "./chunk-TU7G4RJV.js";
6
+ import "./chunk-QYKLXNNB.js";
7
7
  import "./chunk-4IQXHHPF.js";
8
8
 
9
9
  // .docu/node/build.deno.ts
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  runBuild,
3
3
  runBuildCli
4
- } from "./chunk-OREEWUOV.js";
4
+ } from "./chunk-RH3WF75F.js";
5
5
  import "./chunk-WSJC3PRH.js";
6
6
  import "./chunk-EOK6KATZ.js";
7
- import "./chunk-TU7G4RJV.js";
7
+ import "./chunk-QYKLXNNB.js";
8
8
  import "./chunk-4IQXHHPF.js";
9
9
  export {
10
10
  runBuild,
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  runBuildCli
3
- } from "./chunk-OREEWUOV.js";
3
+ } from "./chunk-RH3WF75F.js";
4
4
  import "./chunk-WSJC3PRH.js";
5
5
  import "./chunk-EOK6KATZ.js";
6
- import "./chunk-TU7G4RJV.js";
6
+ import "./chunk-QYKLXNNB.js";
7
7
  import "./chunk-4IQXHHPF.js";
8
8
 
9
9
  // .docu/node/build.node.ts
@@ -27,7 +27,7 @@ import {
27
27
  } from "./chunk-EOK6KATZ.js";
28
28
  import {
29
29
  logger
30
- } from "./chunk-TU7G4RJV.js";
30
+ } from "./chunk-QYKLXNNB.js";
31
31
  import {
32
32
  DIST_DIR,
33
33
  DOCS_DIR,
@@ -59,7 +59,7 @@ function createHtmlResponse(title, description, body, status, state, depth = 0)
59
59
  themeCss: state.inlineThemeCss,
60
60
  depth
61
61
  });
62
- return htmlResponse(html, nonce, status, process.env.NODE_ENV !== "production");
62
+ return htmlResponse(html, nonce, status, true);
63
63
  }
64
64
  async function getDocsForSlug(slug, state) {
65
65
  if (!isSlugSafe(slug, DOCS_DIR)) return null;
@@ -161,7 +161,7 @@ async function renderDocsServerPage(doc, slug, pathname, state) {
161
161
  depth
162
162
  });
163
163
  html = await state.builder.runTransformHtmlChain(html, ctx);
164
- return htmlResponse(html, nonce, 200, process.env.NODE_ENV !== "production");
164
+ return htmlResponse(html, nonce, 200, true);
165
165
  }
166
166
  return createHtmlResponse(title, description, body, 200, state, depth);
167
167
  }
@@ -24,6 +24,7 @@ var NGINX_CONF = `server {
24
24
  add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
25
25
  add_header Referrer-Policy "strict-origin-when-cross-origin" always;
26
26
  add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
27
+ add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self' data:; connect-src 'self' https:; frame-src https://www.youtube-nocookie.com; frame-ancestors 'none'" always;
27
28
 
28
29
  location /assets/ {
29
30
  expires 1y;
@@ -33,6 +34,7 @@ var NGINX_CONF = `server {
33
34
  add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
34
35
  add_header Referrer-Policy "strict-origin-when-cross-origin" always;
35
36
  add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
37
+ add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self' data:; connect-src 'self' https:; frame-src https://www.youtube-nocookie.com; frame-ancestors 'none'" always;
36
38
  }
37
39
 
38
40
  location /docs/assets/ {
@@ -43,6 +45,7 @@ var NGINX_CONF = `server {
43
45
  add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
44
46
  add_header Referrer-Policy "strict-origin-when-cross-origin" always;
45
47
  add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
48
+ add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self' data:; connect-src 'self' https:; frame-src https://www.youtube-nocookie.com; frame-ancestors 'none'" always;
46
49
  }
47
50
 
48
51
  location / {
@@ -104,7 +107,10 @@ function detectPkgManager(dir) {
104
107
  var HEADERS_FILE = `/*
105
108
  X-Frame-Options: DENY
106
109
  X-Content-Type-Options: nosniff
110
+ Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
107
111
  Referrer-Policy: strict-origin-when-cross-origin
112
+ Permissions-Policy: camera=(), microphone=(), geolocation=()
113
+ Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self' data:; connect-src 'self' https:; frame-src https://www.youtube-nocookie.com; frame-ancestors 'none'
108
114
 
109
115
  /assets/*
110
116
  Cache-Control: public, max-age=31536000, immutable
@@ -127,7 +133,7 @@ async function runBuild() {
127
133
  process.env.FLAME_BUILD_SILENT = "1";
128
134
  process.env.LOG_LEVEL = "error";
129
135
  }
130
- const { runBuildCli } = await import("./build.impl-CFTUVIX7.js");
136
+ const { runBuildCli } = await import("./build.impl-ZLUUXLJ2.js");
131
137
  await runBuildCli();
132
138
  }
133
139
  async function writeDockerFiles() {
@@ -146,7 +152,6 @@ RUN ${pm.runCmd} run build
146
152
  FROM nginx:alpine
147
153
  COPY --from=builder /app/.docu/dist /usr/share/nginx/html
148
154
  COPY nginx.conf /etc/nginx/conf.d/default.conf
149
- USER nginx
150
155
  EXPOSE 80
151
156
  CMD ["nginx", "-g", "daemon off;"]
152
157
  `
@@ -5,7 +5,7 @@ import {
5
5
  // package.json
6
6
  var package_default = {
7
7
  name: "@docubook/flame",
8
- version: "1.6.2",
8
+ version: "1.6.4",
9
9
  description: "A blazing-fast React + MDX framework powered by Bun, built for modern documentation experiences.",
10
10
  type: "module",
11
11
  bin: {
@@ -21,7 +21,7 @@ import {
21
21
  } from "./chunk-EOK6KATZ.js";
22
22
  import {
23
23
  logger
24
- } from "./chunk-TU7G4RJV.js";
24
+ } from "./chunk-QYKLXNNB.js";
25
25
  import {
26
26
  ASSETS_DIR,
27
27
  CACHE_FILE,
@@ -146,7 +146,7 @@ ${msg}`, { cause: err });
146
146
  const depth = slug ? slug.split("/").length : 1;
147
147
  const favicon = docuConfig.meta?.favicon || "/docs/assets/images/favicon.ico";
148
148
  const seo = buildSeoMeta(docuConfig, frontmatter, slug || "");
149
- const csp = cspHeader(nonce, process.env.NODE_ENV !== "production");
149
+ const csp = cspHeader(nonce, true);
150
150
  let html = htmlShell({
151
151
  title,
152
152
  description,
@@ -332,7 +332,8 @@ async function runBuild() {
332
332
  body: renderToString(landingPage),
333
333
  favicon: landingFavicon,
334
334
  seo: landingSeo,
335
- csp: cspHeader(landingNonce, process.env.NODE_ENV !== "production"),
335
+ /** unsafe-eval required by mdx-remote hydration — see above. */
336
+ csp: cspHeader(landingNonce, true),
336
337
  css: assetManifest.css,
337
338
  js: assetManifest.js,
338
339
  nonce: landingNonce,
@@ -352,7 +353,8 @@ async function runBuild() {
352
353
  body: renderToString(notFoundPage),
353
354
  favicon: notFoundFavicon,
354
355
  headExtra: ['<meta name="robots" content="noindex,follow">'],
355
- csp: cspHeader(notFoundNonce, process.env.NODE_ENV !== "production"),
356
+ /** unsafe-eval required by mdx-remote hydration — see above. */
357
+ csp: cspHeader(notFoundNonce, true),
356
358
  css: assetManifest.css,
357
359
  js: assetManifest.js,
358
360
  nonce: notFoundNonce,
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-EOK6KATZ.js";
8
8
  import {
9
9
  logger
10
- } from "./chunk-TU7G4RJV.js";
10
+ } from "./chunk-QYKLXNNB.js";
11
11
  import {
12
12
  DIST_DIR
13
13
  } from "./chunk-4IQXHHPF.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  logger
3
- } from "./chunk-TU7G4RJV.js";
3
+ } from "./chunk-QYKLXNNB.js";
4
4
  import "./chunk-4IQXHHPF.js";
5
5
 
6
6
  // .docu/node/clean.ts
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runDeploy
3
- } from "./chunk-KHRQUSNL.js";
3
+ } from "./chunk-NN5T3Z5R.js";
4
4
  import "./chunk-4IQXHHPF.js";
5
5
 
6
6
  // .docu/node/deploy.deno.ts
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runDeploy
3
- } from "./chunk-KHRQUSNL.js";
3
+ } from "./chunk-NN5T3Z5R.js";
4
4
  import "./chunk-4IQXHHPF.js";
5
5
 
6
6
  // .docu/node/deploy.node.ts
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  runPreview
3
- } from "./chunk-N25ZVCKO.js";
3
+ } from "./chunk-UNRSSV2E.js";
4
4
  import "./chunk-EOK6KATZ.js";
5
- import "./chunk-TU7G4RJV.js";
5
+ import "./chunk-QYKLXNNB.js";
6
6
  import "./chunk-4IQXHHPF.js";
7
7
 
8
8
  // .docu/node/preview.deno.ts
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  runPreview
3
- } from "./chunk-N25ZVCKO.js";
3
+ } from "./chunk-UNRSSV2E.js";
4
4
  import "./chunk-EOK6KATZ.js";
5
- import "./chunk-TU7G4RJV.js";
5
+ import "./chunk-QYKLXNNB.js";
6
6
  import "./chunk-4IQXHHPF.js";
7
7
 
8
8
  // .docu/node/preview.node.ts
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  runServer
3
- } from "./chunk-77NNQDFX.js";
3
+ } from "./chunk-6JMYQIHO.js";
4
4
  import "./chunk-WSJC3PRH.js";
5
5
  import "./chunk-EOK6KATZ.js";
6
- import "./chunk-TU7G4RJV.js";
6
+ import "./chunk-QYKLXNNB.js";
7
7
  import "./chunk-4IQXHHPF.js";
8
8
 
9
9
  // .docu/node/server.deno.ts
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  runServer
3
- } from "./chunk-77NNQDFX.js";
3
+ } from "./chunk-6JMYQIHO.js";
4
4
  import "./chunk-WSJC3PRH.js";
5
5
  import "./chunk-EOK6KATZ.js";
6
- import "./chunk-TU7G4RJV.js";
6
+ import "./chunk-QYKLXNNB.js";
7
7
  import "./chunk-4IQXHHPF.js";
8
8
 
9
9
  // .docu/node/server.node.ts
@@ -149,7 +149,11 @@ async function renderDocsPage(
149
149
  const depth = slug ? slug.split("/").length : 1;
150
150
  const favicon = docuConfig.meta?.favicon || "/docs/assets/images/favicon.ico";
151
151
  const seo = buildSeoMeta(docuConfig, frontmatter, slug || "");
152
- const csp = cspHeader(nonce, process.env.NODE_ENV !== "production");
152
+ /**
153
+ * @docubook/mdx-remote uses new Function(compiledSource) for
154
+ * client-side MDX hydration. Keep allowEval=true until mdx-remote drops new Function.
155
+ */
156
+ const csp = cspHeader(nonce, true);
153
157
  let html = htmlShell({
154
158
  title,
155
159
  description,
@@ -358,7 +362,8 @@ export async function runBuild(): Promise<void> {
358
362
  body: renderToString(landingPage),
359
363
  favicon: landingFavicon,
360
364
  seo: landingSeo,
361
- csp: cspHeader(landingNonce, process.env.NODE_ENV !== "production"),
365
+ /** unsafe-eval required by mdx-remote hydration — see above. */
366
+ csp: cspHeader(landingNonce, true),
362
367
  css: assetManifest.css,
363
368
  js: assetManifest.js,
364
369
  nonce: landingNonce,
@@ -379,7 +384,8 @@ export async function runBuild(): Promise<void> {
379
384
  body: renderToString(notFoundPage),
380
385
  favicon: notFoundFavicon,
381
386
  headExtra: ['<meta name="robots" content="noindex,follow">'],
382
- csp: cspHeader(notFoundNonce, process.env.NODE_ENV !== "production"),
387
+ /** unsafe-eval required by mdx-remote hydration — see above. */
388
+ csp: cspHeader(notFoundNonce, true),
383
389
  css: assetManifest.css,
384
390
  js: assetManifest.js,
385
391
  nonce: notFoundNonce,
@@ -31,6 +31,7 @@ export const NGINX_CONF = `server {
31
31
  add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
32
32
  add_header Referrer-Policy "strict-origin-when-cross-origin" always;
33
33
  add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
34
+ add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self' data:; connect-src 'self' https:; frame-src https://www.youtube-nocookie.com; frame-ancestors 'none'" always;
34
35
 
35
36
  location /assets/ {
36
37
  expires 1y;
@@ -40,6 +41,7 @@ export const NGINX_CONF = `server {
40
41
  add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
41
42
  add_header Referrer-Policy "strict-origin-when-cross-origin" always;
42
43
  add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
44
+ add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self' data:; connect-src 'self' https:; frame-src https://www.youtube-nocookie.com; frame-ancestors 'none'" always;
43
45
  }
44
46
 
45
47
  location /docs/assets/ {
@@ -50,6 +52,7 @@ export const NGINX_CONF = `server {
50
52
  add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
51
53
  add_header Referrer-Policy "strict-origin-when-cross-origin" always;
52
54
  add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
55
+ add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self' data:; connect-src 'self' https:; frame-src https://www.youtube-nocookie.com; frame-ancestors 'none'" always;
53
56
  }
54
57
 
55
58
  location / {
@@ -126,7 +129,10 @@ export function detectPkgManager(dir: string): {
126
129
  export const HEADERS_FILE = `/*
127
130
  X-Frame-Options: DENY
128
131
  X-Content-Type-Options: nosniff
132
+ Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
129
133
  Referrer-Policy: strict-origin-when-cross-origin
134
+ Permissions-Policy: camera=(), microphone=(), geolocation=()
135
+ Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self' data:; connect-src 'self' https:; frame-src https://www.youtube-nocookie.com; frame-ancestors 'none'
130
136
 
131
137
  /assets/*
132
138
  Cache-Control: public, max-age=31536000, immutable
@@ -172,7 +178,6 @@ RUN ${pm.runCmd} run build
172
178
  FROM nginx:alpine
173
179
  COPY --from=builder /app/.docu/dist /usr/share/nginx/html
174
180
  COPY nginx.conf /etc/nginx/conf.d/default.conf
175
- USER nginx
176
181
  EXPOSE 80
177
182
  CMD ["nginx", "-g", "daemon off;"]
178
183
  `
@@ -53,7 +53,6 @@ RUN bun run build
53
53
  FROM nginx:alpine
54
54
  COPY --from=builder /app/.docu/dist /usr/share/nginx/html
55
55
  COPY nginx.conf /etc/nginx/conf.d/default.conf
56
- USER nginx
57
56
  EXPOSE 80
58
57
  CMD ["nginx", "-g", "daemon off;"]
59
58
  `;
@@ -45,7 +45,8 @@ function createHtmlResponse(
45
45
  themeCss: state.inlineThemeCss,
46
46
  depth,
47
47
  });
48
- return htmlResponse(html, nonce, status, process.env.NODE_ENV !== "production");
48
+ /** unsafe-eval required by mdx-remote hydration — see build.impl.ts */
49
+ return htmlResponse(html, nonce, status, true);
49
50
  }
50
51
 
51
52
  async function getDocsForSlug(
@@ -183,7 +184,8 @@ async function renderDocsServerPage(
183
184
  depth,
184
185
  });
185
186
  html = await state.builder.runTransformHtmlChain(html, ctx);
186
- return htmlResponse(html, nonce, 200, process.env.NODE_ENV !== "production");
187
+ /** unsafe-eval required by mdx-remote hydration — see build.impl.ts */
188
+ return htmlResponse(html, nonce, 200, true);
187
189
  }
188
190
 
189
191
  return createHtmlResponse(title, description, body, 200, state, depth);
package/bin/cli.js CHANGED
@@ -61,6 +61,16 @@ const hasSilent = process.argv.includes("--silent");
61
61
  if (hasDocker) process.env.FLAME_DEPLOY_DOCKER = "1";
62
62
  if (hasSilent) process.env.FLAME_DEPLOY_SILENT = "1";
63
63
 
64
+ // Production mode for build/preview/deploy — ensures minified client bundle
65
+ // on all platforms (Coolify, Vercel, etc.) without requiring the user to
66
+ // set NODE_ENV manually.
67
+ if (
68
+ (command === "build" || command === "preview" || command === "deploy") &&
69
+ !process.env.NODE_ENV
70
+ ) {
71
+ process.env.NODE_ENV = "production";
72
+ }
73
+
64
74
  if (!command || command === "--help" || command === "-h") {
65
75
  console.log(`
66
76
  @docubook/flame — A blazing-fast React + MDX framework for modern documentation experiences. Runs on Bun, Node.js, and Deno.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docubook/flame",
3
- "version": "1.6.2",
3
+ "version": "1.6.4",
4
4
  "description": "A blazing-fast React + MDX framework powered by Bun, built for modern documentation experiences.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -57,8 +57,8 @@
57
57
  "@docubook/core": "^1.8.2",
58
58
  "@docubook/mdx-content": "^3.4.5",
59
59
  "@docubook/runt": "^1.0.0",
60
- "@docubook/ui-react": "^1.0.0",
61
- "@docubook/themes-colors": "^1.0.2"
60
+ "@docubook/themes-colors": "^1.0.2",
61
+ "@docubook/ui-react": "^1.0.0"
62
62
  },
63
63
  "peerDependencies": {
64
64
  "@sentry/bun": "^10.0.0"
@@ -1,10 +1,26 @@
1
- # Server
1
+ # ── Server ──────────────────────────────────────────────
2
+ # Dev/preview server port.
2
3
  PORT=3000
3
4
 
4
- # Theme (optional — overrides docu.json themes.colors)
5
+ # ── Build ────────────────────────────────────────────────
6
+ # Max concurrent MDX pages to build (default: 4).
7
+ # Increase for faster builds on high-core machines.
8
+ # BUILD_CONCURRENCY=8
9
+
10
+ # ── Logging ──────────────────────────────────────────────
11
+ # Log level: debug | info | warn | error (default: info)
12
+ LOG_LEVEL=info
13
+ # Log format: pretty | json (default: pretty)
14
+ LOG_FORMAT=pretty
15
+
16
+ # ── Theme ────────────────────────────────────────────────
17
+ # Override docu.json themes.colors at runtime.
18
+ # Available presets: default, freshlime, coffee
5
19
  # FLAME_THEME=default
6
20
  # FLAME_THEME=freshlime
7
21
  # FLAME_THEME=coffee
8
22
 
9
- # Error Monitoring (optional)
23
+ # ── Error Monitoring (optional) ─────────────────────────
24
+ # Requires @sentry/bun installed (Bun) or @sentry/node (Node/Deno).
10
25
  # SENTRY_DSN=https://your-dsn@sentry.io/project-id
26
+ # SENTRY_RELEASE=1.0.0