@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.
- package/.docu/lib/build.deno.js +2 -2
- package/.docu/lib/{build.impl-CFTUVIX7.js → build.impl-ZLUUXLJ2.js} +2 -2
- package/.docu/lib/build.node.js +2 -2
- package/.docu/lib/{chunk-77NNQDFX.js → chunk-6JMYQIHO.js} +3 -3
- package/.docu/lib/{chunk-KHRQUSNL.js → chunk-NN5T3Z5R.js} +7 -2
- package/.docu/lib/{chunk-TU7G4RJV.js → chunk-QYKLXNNB.js} +1 -1
- package/.docu/lib/{chunk-OREEWUOV.js → chunk-RH3WF75F.js} +6 -4
- package/.docu/lib/{chunk-N25ZVCKO.js → chunk-UNRSSV2E.js} +1 -1
- package/.docu/lib/clean.js +1 -1
- package/.docu/lib/deploy.deno.js +1 -1
- package/.docu/lib/deploy.node.js +1 -1
- package/.docu/lib/preview.deno.js +2 -2
- package/.docu/lib/preview.node.js +2 -2
- package/.docu/lib/server.deno.js +2 -2
- package/.docu/lib/server.node.js +2 -2
- package/.docu/node/build.impl.ts +9 -3
- package/.docu/node/deploy.shared.ts +6 -1
- package/.docu/node/deploy.ts +0 -1
- package/.docu/node/server-routes.ts +4 -2
- package/bin/cli.js +10 -0
- package/package.json +3 -3
- package/template/.env.example +19 -3
package/.docu/lib/build.deno.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runBuildCli
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RH3WF75F.js";
|
|
4
4
|
import "./chunk-WSJC3PRH.js";
|
|
5
5
|
import "./chunk-EOK6KATZ.js";
|
|
6
|
-
import "./chunk-
|
|
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-
|
|
4
|
+
} from "./chunk-RH3WF75F.js";
|
|
5
5
|
import "./chunk-WSJC3PRH.js";
|
|
6
6
|
import "./chunk-EOK6KATZ.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-QYKLXNNB.js";
|
|
8
8
|
import "./chunk-4IQXHHPF.js";
|
|
9
9
|
export {
|
|
10
10
|
runBuild,
|
package/.docu/lib/build.node.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runBuildCli
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RH3WF75F.js";
|
|
4
4
|
import "./chunk-WSJC3PRH.js";
|
|
5
5
|
import "./chunk-EOK6KATZ.js";
|
|
6
|
-
import "./chunk-
|
|
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-
|
|
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,
|
|
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,
|
|
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-
|
|
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
|
`
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
} from "./chunk-EOK6KATZ.js";
|
|
22
22
|
import {
|
|
23
23
|
logger
|
|
24
|
-
} from "./chunk-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
package/.docu/lib/clean.js
CHANGED
package/.docu/lib/deploy.deno.js
CHANGED
package/.docu/lib/deploy.node.js
CHANGED
package/.docu/lib/server.deno.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6JMYQIHO.js";
|
|
4
4
|
import "./chunk-WSJC3PRH.js";
|
|
5
5
|
import "./chunk-EOK6KATZ.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-QYKLXNNB.js";
|
|
7
7
|
import "./chunk-4IQXHHPF.js";
|
|
8
8
|
|
|
9
9
|
// .docu/node/server.deno.ts
|
package/.docu/lib/server.node.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6JMYQIHO.js";
|
|
4
4
|
import "./chunk-WSJC3PRH.js";
|
|
5
5
|
import "./chunk-EOK6KATZ.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-QYKLXNNB.js";
|
|
7
7
|
import "./chunk-4IQXHHPF.js";
|
|
8
8
|
|
|
9
9
|
// .docu/node/server.node.ts
|
package/.docu/node/build.impl.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
`
|
package/.docu/node/deploy.ts
CHANGED
|
@@ -45,7 +45,8 @@ function createHtmlResponse(
|
|
|
45
45
|
themeCss: state.inlineThemeCss,
|
|
46
46
|
depth,
|
|
47
47
|
});
|
|
48
|
-
|
|
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
|
-
|
|
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.
|
|
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/
|
|
61
|
-
"@docubook/
|
|
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"
|
package/template/.env.example
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
|
-
# Server
|
|
1
|
+
# ── Server ──────────────────────────────────────────────
|
|
2
|
+
# Dev/preview server port.
|
|
2
3
|
PORT=3000
|
|
3
4
|
|
|
4
|
-
#
|
|
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
|