nrdocs 0.1.6 → 0.1.8
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/dist/bin.mjs +236 -78
- package/dist/runtime/mermaid.min.js +3410 -0
- package/package.json +6 -4
package/dist/bin.mjs
CHANGED
|
@@ -815,11 +815,11 @@ async function handleInit(args2) {
|
|
|
815
815
|
}
|
|
816
816
|
|
|
817
817
|
// src/commands/publish.ts
|
|
818
|
-
import * as
|
|
818
|
+
import * as fs8 from "node:fs";
|
|
819
819
|
|
|
820
820
|
// src/renderer/index.ts
|
|
821
|
-
import * as
|
|
822
|
-
import * as
|
|
821
|
+
import * as fs6 from "node:fs";
|
|
822
|
+
import * as path7 from "node:path";
|
|
823
823
|
|
|
824
824
|
// ../../node_modules/.pnpm/markdown-it@14.1.1/node_modules/markdown-it/lib/common/utils.mjs
|
|
825
825
|
var utils_exports = {};
|
|
@@ -6002,6 +6002,21 @@ var md = new lib_default({
|
|
|
6002
6002
|
typographer: false
|
|
6003
6003
|
// No smart quotes or typographic replacements
|
|
6004
6004
|
});
|
|
6005
|
+
var defaultFence = md.renderer.rules.fence;
|
|
6006
|
+
md.renderer.rules.fence = (tokens, idx, options, env, self) => {
|
|
6007
|
+
const token = tokens[idx];
|
|
6008
|
+
const lang = token.info.trim().split(/\s+/g)[0];
|
|
6009
|
+
if (lang === "mermaid") {
|
|
6010
|
+
const escaped = md.utils.escapeHtml(token.content.trim());
|
|
6011
|
+
return `<pre class="mermaid">${escaped}</pre>
|
|
6012
|
+
`;
|
|
6013
|
+
}
|
|
6014
|
+
return defaultFence(tokens, idx, options, env, self);
|
|
6015
|
+
};
|
|
6016
|
+
var MERMAID_FENCE_RE = /^```mermaid\s*$/m;
|
|
6017
|
+
function contentHasMermaid(content) {
|
|
6018
|
+
return MERMAID_FENCE_RE.test(content);
|
|
6019
|
+
}
|
|
6005
6020
|
function renderMarkdown(content) {
|
|
6006
6021
|
return md.render(content);
|
|
6007
6022
|
}
|
|
@@ -6171,11 +6186,39 @@ function addHeadingIds(html) {
|
|
|
6171
6186
|
});
|
|
6172
6187
|
}
|
|
6173
6188
|
function wrapInTemplate(options) {
|
|
6174
|
-
const {
|
|
6189
|
+
const {
|
|
6190
|
+
title,
|
|
6191
|
+
siteTitle,
|
|
6192
|
+
content,
|
|
6193
|
+
nav,
|
|
6194
|
+
canonicalUrl,
|
|
6195
|
+
baseUrl,
|
|
6196
|
+
includeMermaid = false,
|
|
6197
|
+
mermaidScriptSrc = null
|
|
6198
|
+
} = options;
|
|
6175
6199
|
const pageTitle = title === siteTitle ? siteTitle : `${title} - ${siteTitle}`;
|
|
6176
6200
|
const contentWithIds = addHeadingIds(content);
|
|
6177
6201
|
const toc = extractToc(contentWithIds);
|
|
6178
6202
|
const hasToc = toc.length > 1;
|
|
6203
|
+
const mermaidBlock = includeMermaid && mermaidScriptSrc ? `<script src="${escapeHtml2(mermaidScriptSrc)}" defer></script>
|
|
6204
|
+
<script>
|
|
6205
|
+
(function(){
|
|
6206
|
+
function theme(){var t=document.documentElement.dataset.theme;return t==='dark'||t==='light'?t:(window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light');}
|
|
6207
|
+
function api(){
|
|
6208
|
+
var g=typeof globalThis!=='undefined'?globalThis:(typeof window!=='undefined'?window:null);
|
|
6209
|
+
if(!g||!g.mermaid)return null;
|
|
6210
|
+
var m=g.mermaid;
|
|
6211
|
+
return (m.default&&typeof m.default.initialize==='function')?m.default:m;
|
|
6212
|
+
}
|
|
6213
|
+
function initMermaid(){
|
|
6214
|
+
var m=api();if(!m)return;
|
|
6215
|
+
m.initialize({startOnLoad:true,theme:theme()==='dark'?'dark':'default'});
|
|
6216
|
+
m.run();
|
|
6217
|
+
}
|
|
6218
|
+
document.addEventListener('DOMContentLoaded',initMermaid);
|
|
6219
|
+
document.addEventListener('nrdocs-theme-change',initMermaid);
|
|
6220
|
+
})();
|
|
6221
|
+
</script>` : "";
|
|
6179
6222
|
return `<!DOCTYPE html>
|
|
6180
6223
|
<html lang="en">
|
|
6181
6224
|
<head>
|
|
@@ -6187,48 +6230,97 @@ function wrapInTemplate(options) {
|
|
|
6187
6230
|
<meta name="generator" content="nrdocs">
|
|
6188
6231
|
<title>${escapeHtml2(pageTitle)}</title>
|
|
6189
6232
|
<link rel="canonical" href="${escapeHtml2(canonicalUrl)}">
|
|
6233
|
+
<script>
|
|
6234
|
+
(function(){try{var s=localStorage.getItem('nrdocs-theme');if(s==='light'||s==='dark')document.documentElement.dataset.theme=s;}catch(e){}})();
|
|
6235
|
+
</script>
|
|
6190
6236
|
<style>
|
|
6237
|
+
:root{
|
|
6238
|
+
--text:#1a1a1a;--text-muted:#555;--text-footer:#888;
|
|
6239
|
+
--bg-body:#fff;--bg-sidebar:#fafafa;--bg-hover:#e8e8e8;--bg-active:#e0e7ff;
|
|
6240
|
+
--border:#e0e0e0;--border-light:#e8e8e8;
|
|
6241
|
+
--link:#1d4ed8;--link-active:#1d4ed8;
|
|
6242
|
+
--code-bg:#f3f4f6;--pre-bg:#1e1e1e;--pre-text:#d4d4d4;
|
|
6243
|
+
--th-bg:#f5f5f5;--blockquote:#555;
|
|
6244
|
+
--toc-title:#666;--toc-link:#555;
|
|
6245
|
+
}
|
|
6246
|
+
@media(prefers-color-scheme:dark){
|
|
6247
|
+
html:not([data-theme]){
|
|
6248
|
+
--text:#e5e5e5;--text-muted:#a3a3a3;--text-footer:#737373;
|
|
6249
|
+
--bg-body:#0a0a0a;--bg-sidebar:#111;--bg-hover:#262626;--bg-active:#1e3a5f;
|
|
6250
|
+
--border:#333;--border-light:#262626;
|
|
6251
|
+
--link:#60a5fa;--link-active:#93c5fd;
|
|
6252
|
+
--code-bg:#262626;--pre-bg:#1a1a1a;--pre-text:#d4d4d4;
|
|
6253
|
+
--th-bg:#1a1a1a;--blockquote:#a3a3a3;
|
|
6254
|
+
--toc-title:#a3a3a3;--toc-link:#a3a3a3;
|
|
6255
|
+
}
|
|
6256
|
+
}
|
|
6257
|
+
html[data-theme="dark"]{
|
|
6258
|
+
--text:#e5e5e5;--text-muted:#a3a3a3;--text-footer:#737373;
|
|
6259
|
+
--bg-body:#0a0a0a;--bg-sidebar:#111;--bg-hover:#262626;--bg-active:#1e3a5f;
|
|
6260
|
+
--border:#333;--border-light:#262626;
|
|
6261
|
+
--link:#60a5fa;--link-active:#93c5fd;
|
|
6262
|
+
--code-bg:#262626;--pre-bg:#1a1a1a;--pre-text:#d4d4d4;
|
|
6263
|
+
--th-bg:#1a1a1a;--blockquote:#a3a3a3;
|
|
6264
|
+
--toc-title:#a3a3a3;--toc-link:#a3a3a3;
|
|
6265
|
+
}
|
|
6266
|
+
html[data-theme="light"]{
|
|
6267
|
+
--text:#1a1a1a;--text-muted:#555;--text-footer:#888;
|
|
6268
|
+
--bg-body:#fff;--bg-sidebar:#fafafa;--bg-hover:#e8e8e8;--bg-active:#e0e7ff;
|
|
6269
|
+
--border:#e0e0e0;--border-light:#e8e8e8;
|
|
6270
|
+
--link:#1d4ed8;--link-active:#1d4ed8;
|
|
6271
|
+
--code-bg:#f3f4f6;--pre-bg:#1e1e1e;--pre-text:#d4d4d4;
|
|
6272
|
+
--th-bg:#f5f5f5;--blockquote:#555;
|
|
6273
|
+
--toc-title:#666;--toc-link:#555;
|
|
6274
|
+
}
|
|
6191
6275
|
*{margin:0;padding:0;box-sizing:border-box}
|
|
6192
|
-
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;font-size:1.0625rem;line-height:1.7;color
|
|
6193
|
-
nav.sidebar{width:260px;padding:1.5rem;border-right:1px solid
|
|
6194
|
-
|
|
6276
|
+
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;font-size:1.0625rem;line-height:1.7;color:var(--text);background:var(--bg-body);display:flex;min-height:100vh}
|
|
6277
|
+
nav.sidebar{width:260px;padding:1.5rem;border-right:1px solid var(--border);background:var(--bg-sidebar);overflow-y:auto;flex-shrink:0;position:sticky;top:0;height:100vh}
|
|
6278
|
+
.site-header{display:flex;align-items:center;justify-content:space-between;gap:0.5rem;margin-bottom:1rem}
|
|
6279
|
+
nav.sidebar .site-title{font-weight:700;font-size:1.1rem;color:var(--text);flex:1;min-width:0}
|
|
6280
|
+
#theme-toggle{background:var(--bg-hover);border:1px solid var(--border);border-radius:6px;padding:0.35rem 0.5rem;cursor:pointer;font-size:1rem;line-height:1;color:var(--text);flex-shrink:0}
|
|
6281
|
+
#theme-toggle:hover{background:var(--bg-active)}
|
|
6195
6282
|
nav.sidebar ul{list-style:none}
|
|
6196
6283
|
nav.sidebar li{margin-bottom:0.25rem}
|
|
6197
|
-
nav.sidebar a{color
|
|
6198
|
-
nav.sidebar a:hover{background
|
|
6199
|
-
nav.sidebar a.active{background
|
|
6284
|
+
nav.sidebar a{color:var(--text-muted);text-decoration:none;padding:0.3rem 0.6rem;display:block;border-radius:4px;font-size:0.95rem}
|
|
6285
|
+
nav.sidebar a:hover{background:var(--bg-hover);color:var(--text)}
|
|
6286
|
+
nav.sidebar a.active{background:var(--bg-active);color:var(--link-active);font-weight:500}
|
|
6200
6287
|
.content-wrapper{flex:1;display:flex;min-width:0}
|
|
6201
6288
|
main{flex:1;padding:2.5rem 3rem;max-width:52rem;min-width:0;overflow-wrap:break-word}
|
|
6202
|
-
main h1{font-size:2.2rem;margin-bottom:1.2rem;border-bottom:1px solid
|
|
6203
|
-
main h2{font-size:1.6rem;margin-top:2.5rem;margin-bottom:0.75rem;line-height:1.3}
|
|
6204
|
-
main h3{font-size:1.3rem;margin-top:1.8rem;margin-bottom:0.5rem;line-height:1.4}
|
|
6289
|
+
main h1{font-size:2.2rem;margin-bottom:1.2rem;border-bottom:1px solid var(--border);padding-bottom:0.5rem;line-height:1.3;color:var(--text)}
|
|
6290
|
+
main h2{font-size:1.6rem;margin-top:2.5rem;margin-bottom:0.75rem;line-height:1.3;color:var(--text)}
|
|
6291
|
+
main h3{font-size:1.3rem;margin-top:1.8rem;margin-bottom:0.5rem;line-height:1.4;color:var(--text)}
|
|
6205
6292
|
main p{margin-bottom:1.1rem}
|
|
6206
|
-
main a{color
|
|
6207
|
-
main code{background
|
|
6208
|
-
main pre{background
|
|
6293
|
+
main a{color:var(--link);text-decoration:underline}
|
|
6294
|
+
main code{background:var(--code-bg);padding:0.2rem 0.4rem;border-radius:3px;font-size:0.88em;color:var(--text)}
|
|
6295
|
+
main pre{background:var(--pre-bg);color:var(--pre-text);padding:1.2rem;border-radius:6px;overflow-x:auto;margin-bottom:1.2rem;font-size:0.9rem;line-height:1.5}
|
|
6209
6296
|
main pre code{background:none;padding:0;color:inherit;font-size:inherit}
|
|
6297
|
+
main pre.mermaid{background:transparent;color:var(--text);padding:0;margin:1.5rem 0;overflow-x:auto}
|
|
6210
6298
|
main table{border-collapse:collapse;width:100%;margin-bottom:1.2rem}
|
|
6211
|
-
main th,main td{border:1px solid
|
|
6212
|
-
main th{background
|
|
6299
|
+
main th,main td{border:1px solid var(--border);padding:0.6rem 0.85rem;text-align:left;color:var(--text)}
|
|
6300
|
+
main th{background:var(--th-bg);font-weight:600}
|
|
6213
6301
|
main img{max-width:100%;height:auto;border-radius:4px}
|
|
6214
|
-
main blockquote{border-left:4px solid
|
|
6302
|
+
main blockquote{border-left:4px solid var(--border);padding-left:1rem;margin-bottom:1.1rem;color:var(--blockquote);font-style:italic}
|
|
6215
6303
|
main ul,main ol{margin-bottom:1.1rem;padding-left:1.5rem}
|
|
6216
6304
|
main li{margin-bottom:0.3rem}
|
|
6217
|
-
aside.toc{width:220px;padding:1.5rem 1rem;position:sticky;top:0;height:100vh;overflow-y:auto;flex-shrink:0;border-left:1px solid
|
|
6218
|
-
aside.toc .toc-title{font-size:0.8rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;color
|
|
6305
|
+
aside.toc{width:220px;padding:1.5rem 1rem;position:sticky;top:0;height:100vh;overflow-y:auto;flex-shrink:0;border-left:1px solid var(--border-light);background:var(--bg-body)}
|
|
6306
|
+
aside.toc .toc-title{font-size:0.8rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;color:var(--toc-title);margin-bottom:0.75rem}
|
|
6219
6307
|
aside.toc ul{list-style:none}
|
|
6220
6308
|
aside.toc li{margin-bottom:0.3rem}
|
|
6221
|
-
aside.toc a{color
|
|
6222
|
-
aside.toc a:hover{color
|
|
6309
|
+
aside.toc a{color:var(--toc-link);text-decoration:none;font-size:0.85rem;display:block;padding:0.15rem 0;border-radius:2px}
|
|
6310
|
+
aside.toc a:hover{color:var(--link)}
|
|
6223
6311
|
aside.toc .toc-h3{padding-left:0.75rem}
|
|
6224
|
-
footer{padding:1.5rem
|
|
6312
|
+
footer{padding:1.5rem 0;border-top:1px solid var(--border-light);color:var(--text-footer);font-size:0.8rem;text-align:center;margin-top:2rem}
|
|
6313
|
+
footer a{color:var(--link)}
|
|
6225
6314
|
@media(max-width:1100px){aside.toc{display:none}}
|
|
6226
|
-
@media(max-width:768px){body{flex-direction:column}nav.sidebar{width:100%;border-right:none;border-bottom:1px solid
|
|
6315
|
+
@media(max-width:768px){body{flex-direction:column}nav.sidebar{width:100%;border-right:none;border-bottom:1px solid var(--border);position:static;height:auto}main{padding:1.5rem}}
|
|
6227
6316
|
</style>
|
|
6228
6317
|
</head>
|
|
6229
6318
|
<body>
|
|
6230
6319
|
<nav class="sidebar">
|
|
6320
|
+
<div class="site-header">
|
|
6231
6321
|
<div class="site-title">${escapeHtml2(siteTitle)}</div>
|
|
6322
|
+
<button type="button" id="theme-toggle" aria-label="Toggle color theme" title="Toggle light/dark mode">☽</button>
|
|
6323
|
+
</div>
|
|
6232
6324
|
<ul>
|
|
6233
6325
|
${renderNavItems(nav, baseUrl)}
|
|
6234
6326
|
</ul>
|
|
@@ -6240,6 +6332,32 @@ ${contentWithIds}
|
|
|
6240
6332
|
</main>
|
|
6241
6333
|
${hasToc ? renderToc(toc) : ""}
|
|
6242
6334
|
</div>
|
|
6335
|
+
<script>
|
|
6336
|
+
(function(){
|
|
6337
|
+
var key='nrdocs-theme';
|
|
6338
|
+
var root=document.documentElement;
|
|
6339
|
+
function resolved(){
|
|
6340
|
+
var t=root.dataset.theme;
|
|
6341
|
+
if(t==='dark'||t==='light')return t;
|
|
6342
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light';
|
|
6343
|
+
}
|
|
6344
|
+
function apply(next){
|
|
6345
|
+
root.dataset.theme=next;
|
|
6346
|
+
try{localStorage.setItem(key,next);}catch(e){}
|
|
6347
|
+
document.dispatchEvent(new CustomEvent('nrdocs-theme-change',{detail:{theme:next}}));
|
|
6348
|
+
var btn=document.getElementById('theme-toggle');
|
|
6349
|
+
if(btn)btn.textContent=next==='dark'?'\\u2600':'\\u263E';
|
|
6350
|
+
}
|
|
6351
|
+
var btn=document.getElementById('theme-toggle');
|
|
6352
|
+
if(btn){
|
|
6353
|
+
btn.textContent=resolved()==='dark'?'\\u2600':'\\u263E';
|
|
6354
|
+
btn.addEventListener('click',function(){
|
|
6355
|
+
apply(resolved()==='dark'?'light':'dark');
|
|
6356
|
+
});
|
|
6357
|
+
}
|
|
6358
|
+
})();
|
|
6359
|
+
</script>
|
|
6360
|
+
${mermaidBlock}
|
|
6243
6361
|
</body>
|
|
6244
6362
|
</html>`;
|
|
6245
6363
|
}
|
|
@@ -6306,6 +6424,35 @@ function collectFromDir(dir, rootDir, results) {
|
|
|
6306
6424
|
}
|
|
6307
6425
|
}
|
|
6308
6426
|
|
|
6427
|
+
// src/renderer/mermaid-runtime.ts
|
|
6428
|
+
import * as fs5 from "node:fs";
|
|
6429
|
+
import * as path6 from "node:path";
|
|
6430
|
+
import { fileURLToPath } from "node:url";
|
|
6431
|
+
var __dirname = path6.dirname(fileURLToPath(import.meta.url));
|
|
6432
|
+
var MERMAID_RUNTIME_REL = "runtime/mermaid.min.js";
|
|
6433
|
+
var MERMAID_ARTIFACT_PATH = "_nrdocs/mermaid.min.js";
|
|
6434
|
+
function mermaidRuntimeCandidates() {
|
|
6435
|
+
return [
|
|
6436
|
+
path6.join(__dirname, MERMAID_RUNTIME_REL),
|
|
6437
|
+
path6.join(__dirname, "../../dist/runtime/mermaid.min.js")
|
|
6438
|
+
];
|
|
6439
|
+
}
|
|
6440
|
+
function loadMermaidRuntime() {
|
|
6441
|
+
for (const candidate of mermaidRuntimeCandidates()) {
|
|
6442
|
+
if (fs5.existsSync(candidate)) {
|
|
6443
|
+
return fs5.readFileSync(candidate);
|
|
6444
|
+
}
|
|
6445
|
+
}
|
|
6446
|
+
throw new Error(
|
|
6447
|
+
"Mermaid runtime not found. Run: pnpm --filter nrdocs bundle (or pnpm bundle in packages/cli)"
|
|
6448
|
+
);
|
|
6449
|
+
}
|
|
6450
|
+
function mermaidScriptSrcForOutput(outputPath) {
|
|
6451
|
+
const depth = outputPath.split("/").length - 1;
|
|
6452
|
+
const prefix = depth > 0 ? "../".repeat(depth) : "";
|
|
6453
|
+
return `${prefix}${MERMAID_ARTIFACT_PATH}`;
|
|
6454
|
+
}
|
|
6455
|
+
|
|
6309
6456
|
// src/renderer/index.ts
|
|
6310
6457
|
function resolveNavItems(resolvedDocsDir, nav, indexPath) {
|
|
6311
6458
|
if (nav && nav !== "auto" && Array.isArray(nav)) {
|
|
@@ -6315,15 +6462,18 @@ function resolveNavItems(resolvedDocsDir, nav, indexPath) {
|
|
|
6315
6462
|
}
|
|
6316
6463
|
async function renderSite(options) {
|
|
6317
6464
|
const { docsDir, siteTitle, baseUrl, owner, repo, nav, indexPath = "index.md" } = options;
|
|
6318
|
-
const resolvedDocsDir =
|
|
6465
|
+
const resolvedDocsDir = path7.resolve(docsDir);
|
|
6319
6466
|
const navItems = resolveNavItems(resolvedDocsDir, nav, indexPath);
|
|
6320
6467
|
const siteBase = `/${owner}/${repo}/`;
|
|
6321
6468
|
const renderedFiles = [];
|
|
6469
|
+
let siteHasMermaid = false;
|
|
6322
6470
|
for (const navItem of navItems) {
|
|
6323
|
-
const filePath =
|
|
6324
|
-
const markdownContent =
|
|
6471
|
+
const filePath = path7.join(resolvedDocsDir, navItem.path);
|
|
6472
|
+
const markdownContent = fs6.readFileSync(filePath, "utf-8");
|
|
6473
|
+
const pageHasMermaid = contentHasMermaid(markdownContent);
|
|
6474
|
+
if (pageHasMermaid) siteHasMermaid = true;
|
|
6325
6475
|
let html = renderMarkdown(markdownContent);
|
|
6326
|
-
const fileDir =
|
|
6476
|
+
const fileDir = path7.dirname(navItem.path);
|
|
6327
6477
|
const baseLinkPath = fileDir === "." ? "" : fileDir;
|
|
6328
6478
|
html = rewriteLinks(html, baseLinkPath, owner, repo);
|
|
6329
6479
|
const pageTitle = extractTitle(markdownContent, navItem.path);
|
|
@@ -6332,20 +6482,28 @@ async function renderSite(options) {
|
|
|
6332
6482
|
...item,
|
|
6333
6483
|
active: item.path === navItem.path
|
|
6334
6484
|
}));
|
|
6485
|
+
const outputPath = navItem.href === "" ? "index.html" : navItem.href.replace(/\/$/, "") + "/index.html";
|
|
6335
6486
|
const fullHtml = wrapInTemplate({
|
|
6336
6487
|
title: pageTitle,
|
|
6337
6488
|
siteTitle,
|
|
6338
6489
|
content: html,
|
|
6339
6490
|
nav: navWithActive,
|
|
6340
6491
|
canonicalUrl,
|
|
6341
|
-
baseUrl: siteBase
|
|
6492
|
+
baseUrl: siteBase,
|
|
6493
|
+
includeMermaid: pageHasMermaid,
|
|
6494
|
+
mermaidScriptSrc: pageHasMermaid ? mermaidScriptSrcForOutput(outputPath) : null
|
|
6342
6495
|
});
|
|
6343
|
-
const outputPath = navItem.href === "" ? "index.html" : navItem.href.replace(/\/$/, "") + "/index.html";
|
|
6344
6496
|
renderedFiles.push({
|
|
6345
6497
|
path: outputPath,
|
|
6346
6498
|
content: Buffer.from(fullHtml, "utf-8")
|
|
6347
6499
|
});
|
|
6348
6500
|
}
|
|
6501
|
+
if (siteHasMermaid) {
|
|
6502
|
+
renderedFiles.push({
|
|
6503
|
+
path: MERMAID_ARTIFACT_PATH,
|
|
6504
|
+
content: loadMermaidRuntime()
|
|
6505
|
+
});
|
|
6506
|
+
}
|
|
6349
6507
|
const assets = collectAssets(resolvedDocsDir);
|
|
6350
6508
|
renderedFiles.push(...assets);
|
|
6351
6509
|
const manifest = {
|
|
@@ -6442,8 +6600,8 @@ function normalizeApiBaseUrl(url) {
|
|
|
6442
6600
|
}
|
|
6443
6601
|
function buildApiUrl(baseUrl, apiPath) {
|
|
6444
6602
|
const { url } = normalizeApiBaseUrl(baseUrl);
|
|
6445
|
-
const
|
|
6446
|
-
return `${url}${
|
|
6603
|
+
const path12 = apiPath.startsWith("/") ? apiPath : `/${apiPath}`;
|
|
6604
|
+
return `${url}${path12}`;
|
|
6447
6605
|
}
|
|
6448
6606
|
function extractFetchError(err) {
|
|
6449
6607
|
if (!(err instanceof Error)) {
|
|
@@ -6691,8 +6849,8 @@ var ApiClient = class {
|
|
|
6691
6849
|
}
|
|
6692
6850
|
};
|
|
6693
6851
|
}
|
|
6694
|
-
async request(method,
|
|
6695
|
-
const url = buildApiUrl(this.baseUrl,
|
|
6852
|
+
async request(method, path12, body, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
6853
|
+
const url = buildApiUrl(this.baseUrl, path12);
|
|
6696
6854
|
const controller = new AbortController();
|
|
6697
6855
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
6698
6856
|
const init = {
|
|
@@ -6823,21 +6981,21 @@ var ApiClient = class {
|
|
|
6823
6981
|
};
|
|
6824
6982
|
|
|
6825
6983
|
// src/config/docs-config.ts
|
|
6826
|
-
import * as
|
|
6827
|
-
import * as
|
|
6984
|
+
import * as fs7 from "node:fs";
|
|
6985
|
+
import * as path8 from "node:path";
|
|
6828
6986
|
import YAML from "yaml";
|
|
6829
6987
|
function loadDocsConfig(docsDir) {
|
|
6830
|
-
const configPath =
|
|
6831
|
-
if (!
|
|
6988
|
+
const configPath = path8.resolve(docsDir, "nrdocs.yml");
|
|
6989
|
+
if (!fs7.existsSync(configPath)) {
|
|
6832
6990
|
throw new Error(`Config file not found: ${configPath}`);
|
|
6833
6991
|
}
|
|
6834
|
-
const raw =
|
|
6992
|
+
const raw = fs7.readFileSync(configPath, "utf-8");
|
|
6835
6993
|
const config2 = YAML.parse(raw);
|
|
6836
6994
|
if (!config2 || typeof config2 !== "object") {
|
|
6837
6995
|
throw new Error(`Invalid config: ${configPath}`);
|
|
6838
6996
|
}
|
|
6839
6997
|
const sourceDir = config2.content?.source_dir ?? ".";
|
|
6840
|
-
const contentDir =
|
|
6998
|
+
const contentDir = path8.resolve(docsDir, sourceDir);
|
|
6841
6999
|
return { config: config2, configPath, contentDir };
|
|
6842
7000
|
}
|
|
6843
7001
|
function hasExplicitNav(config2) {
|
|
@@ -6883,8 +7041,8 @@ function validateNavPaths(entries, contentDir) {
|
|
|
6883
7041
|
errors.push(`Duplicate nav path: ${p}`);
|
|
6884
7042
|
}
|
|
6885
7043
|
seen.add(p);
|
|
6886
|
-
const full =
|
|
6887
|
-
if (!
|
|
7044
|
+
const full = path8.join(contentDir, p);
|
|
7045
|
+
if (!fs7.existsSync(full)) {
|
|
6888
7046
|
errors.push(`Nav path not found: ${p}`);
|
|
6889
7047
|
}
|
|
6890
7048
|
if (e.children?.length) walk(e.children);
|
|
@@ -6894,7 +7052,7 @@ function validateNavPaths(entries, contentDir) {
|
|
|
6894
7052
|
return { valid: errors.length === 0, errors };
|
|
6895
7053
|
}
|
|
6896
7054
|
function writeNavToConfig(configPath, navEntries) {
|
|
6897
|
-
let raw =
|
|
7055
|
+
let raw = fs7.readFileSync(configPath, "utf-8");
|
|
6898
7056
|
raw = raw.replace(/^# content\.nav generated by: nrdocs nav generate\n/gm, "");
|
|
6899
7057
|
const config2 = YAML.parse(raw);
|
|
6900
7058
|
if (!config2 || typeof config2 !== "object") {
|
|
@@ -6907,7 +7065,7 @@ function writeNavToConfig(configPath, navEntries) {
|
|
|
6907
7065
|
const doc = new YAML.Document(config2);
|
|
6908
7066
|
const header = "# content.nav generated by: nrdocs nav generate\n";
|
|
6909
7067
|
const body = doc.toString();
|
|
6910
|
-
|
|
7068
|
+
fs7.writeFileSync(configPath, header + body, "utf-8");
|
|
6911
7069
|
}
|
|
6912
7070
|
function formatNavYaml(navEntries) {
|
|
6913
7071
|
const partial = {
|
|
@@ -6932,10 +7090,10 @@ function parsePublishArgs(args2) {
|
|
|
6932
7090
|
return opts;
|
|
6933
7091
|
}
|
|
6934
7092
|
function validateConfig2(configPath) {
|
|
6935
|
-
if (!
|
|
7093
|
+
if (!fs8.existsSync(configPath)) {
|
|
6936
7094
|
return { valid: false, error: `Config file not found: ${configPath}` };
|
|
6937
7095
|
}
|
|
6938
|
-
const content =
|
|
7096
|
+
const content = fs8.readFileSync(configPath, "utf-8");
|
|
6939
7097
|
if (!content.includes("site:")) {
|
|
6940
7098
|
return { valid: false, error: 'Config file missing "site:" section' };
|
|
6941
7099
|
}
|
|
@@ -7115,8 +7273,8 @@ async function handlePublish(args2) {
|
|
|
7115
7273
|
}
|
|
7116
7274
|
|
|
7117
7275
|
// src/commands/doctor.ts
|
|
7118
|
-
import * as
|
|
7119
|
-
import * as
|
|
7276
|
+
import * as fs9 from "node:fs";
|
|
7277
|
+
import * as path9 from "node:path";
|
|
7120
7278
|
function parseDoctorArgs(args2) {
|
|
7121
7279
|
const opts = {};
|
|
7122
7280
|
for (const arg of args2) {
|
|
@@ -7126,11 +7284,11 @@ function parseDoctorArgs(args2) {
|
|
|
7126
7284
|
return opts;
|
|
7127
7285
|
}
|
|
7128
7286
|
function countMarkdownFiles(docsDir) {
|
|
7129
|
-
if (!
|
|
7287
|
+
if (!fs9.existsSync(docsDir)) return 0;
|
|
7130
7288
|
let count = 0;
|
|
7131
7289
|
const walk = (dir) => {
|
|
7132
|
-
for (const entry of
|
|
7133
|
-
const full =
|
|
7290
|
+
for (const entry of fs9.readdirSync(dir, { withFileTypes: true })) {
|
|
7291
|
+
const full = path9.join(dir, entry.name);
|
|
7134
7292
|
if (entry.isDirectory()) walk(full);
|
|
7135
7293
|
else if (entry.name.endsWith(".md")) count++;
|
|
7136
7294
|
}
|
|
@@ -7142,22 +7300,22 @@ async function handleDoctor(args2) {
|
|
|
7142
7300
|
const opts = parseDoctorArgs(args2);
|
|
7143
7301
|
const inCI = opts.ci || process.env["GITHUB_ACTIONS"] === "true";
|
|
7144
7302
|
const checks = [];
|
|
7145
|
-
const isGitRepo =
|
|
7303
|
+
const isGitRepo = fs9.existsSync(path9.resolve(".git"));
|
|
7146
7304
|
checks.push({
|
|
7147
7305
|
section: "Repo setup",
|
|
7148
7306
|
name: "Git repository",
|
|
7149
7307
|
status: isGitRepo ? "ok" : "fail",
|
|
7150
7308
|
message: isGitRepo ? "Found .git directory" : "Not a git repository"
|
|
7151
7309
|
});
|
|
7152
|
-
const configPath =
|
|
7153
|
-
const hasConfig =
|
|
7310
|
+
const configPath = path9.resolve("docs", "nrdocs.yml");
|
|
7311
|
+
const hasConfig = fs9.existsSync(configPath);
|
|
7154
7312
|
checks.push({
|
|
7155
7313
|
section: "Repo setup",
|
|
7156
7314
|
name: "Docs config",
|
|
7157
7315
|
status: hasConfig ? "ok" : "fail",
|
|
7158
7316
|
message: hasConfig ? "Found docs/nrdocs.yml" : "Missing docs/nrdocs.yml \u2014 run: nrdocs init"
|
|
7159
7317
|
});
|
|
7160
|
-
const docsDir =
|
|
7318
|
+
const docsDir = path9.resolve("docs");
|
|
7161
7319
|
const mdCount = countMarkdownFiles(docsDir);
|
|
7162
7320
|
checks.push({
|
|
7163
7321
|
section: "Repo setup",
|
|
@@ -7165,8 +7323,8 @@ async function handleDoctor(args2) {
|
|
|
7165
7323
|
status: mdCount > 0 ? "ok" : "warn",
|
|
7166
7324
|
message: mdCount > 0 ? `${mdCount} markdown file(s) in docs/` : "No .md files in docs/ \u2014 publish will produce an empty site"
|
|
7167
7325
|
});
|
|
7168
|
-
const workflowPath =
|
|
7169
|
-
const hasWorkflow =
|
|
7326
|
+
const workflowPath = path9.resolve(".github", "workflows", "nrdocs.yml");
|
|
7327
|
+
const hasWorkflow = fs9.existsSync(workflowPath);
|
|
7170
7328
|
checks.push({
|
|
7171
7329
|
section: "Repo setup",
|
|
7172
7330
|
name: "GitHub workflow",
|
|
@@ -7176,7 +7334,7 @@ async function handleDoctor(args2) {
|
|
|
7176
7334
|
let configApiUrl;
|
|
7177
7335
|
let workflowApiUrl;
|
|
7178
7336
|
if (hasConfig) {
|
|
7179
|
-
const content =
|
|
7337
|
+
const content = fs9.readFileSync(configPath, "utf-8");
|
|
7180
7338
|
configApiUrl = parseApiUrlFromConfig(content);
|
|
7181
7339
|
checks.push({
|
|
7182
7340
|
section: "Publish URL",
|
|
@@ -7186,7 +7344,7 @@ async function handleDoctor(args2) {
|
|
|
7186
7344
|
});
|
|
7187
7345
|
}
|
|
7188
7346
|
if (hasWorkflow) {
|
|
7189
|
-
const wfContent =
|
|
7347
|
+
const wfContent = fs9.readFileSync(workflowPath, "utf-8");
|
|
7190
7348
|
workflowApiUrl = parseApiUrlFromWorkflow(wfContent);
|
|
7191
7349
|
checks.push({
|
|
7192
7350
|
section: "Publish URL",
|
|
@@ -7345,8 +7503,8 @@ async function handleDoctor(args2) {
|
|
|
7345
7503
|
}
|
|
7346
7504
|
|
|
7347
7505
|
// src/commands/nav.ts
|
|
7348
|
-
import * as
|
|
7349
|
-
import * as
|
|
7506
|
+
import * as fs10 from "node:fs";
|
|
7507
|
+
import * as path10 from "node:path";
|
|
7350
7508
|
function parseNavGenerateArgs(args2) {
|
|
7351
7509
|
const opts = {};
|
|
7352
7510
|
for (let i = 0; i < args2.length; i++) {
|
|
@@ -7365,9 +7523,9 @@ function parseNavGenerateArgs(args2) {
|
|
|
7365
7523
|
}
|
|
7366
7524
|
async function handleNavGenerate(args2) {
|
|
7367
7525
|
const opts = parseNavGenerateArgs(args2);
|
|
7368
|
-
const docsDir =
|
|
7369
|
-
const configPath =
|
|
7370
|
-
if (!
|
|
7526
|
+
const docsDir = path10.resolve(opts.docsDir ?? "docs");
|
|
7527
|
+
const configPath = path10.join(docsDir, "nrdocs.yml");
|
|
7528
|
+
if (!fs10.existsSync(configPath)) {
|
|
7371
7529
|
console.error(`Error: Config file not found: ${configPath}`);
|
|
7372
7530
|
console.error("Run: nrdocs init");
|
|
7373
7531
|
process.exit(10);
|
|
@@ -7400,7 +7558,7 @@ async function handleNavGenerate(args2) {
|
|
|
7400
7558
|
}
|
|
7401
7559
|
writeNavToConfig(loaded.configPath, entries);
|
|
7402
7560
|
if (!opts.json) {
|
|
7403
|
-
console.log(`Generated navigation for ${entries.length} page(s) in ${
|
|
7561
|
+
console.log(`Generated navigation for ${entries.length} page(s) in ${path10.relative(process.cwd(), configPath)}`);
|
|
7404
7562
|
console.log("Edit the file to reorder or rename entries, then run publish.");
|
|
7405
7563
|
}
|
|
7406
7564
|
}
|
|
@@ -7408,8 +7566,8 @@ async function handleNavGenerate(args2) {
|
|
|
7408
7566
|
// src/commands/deploy.ts
|
|
7409
7567
|
import * as readline3 from "node:readline";
|
|
7410
7568
|
import * as crypto from "node:crypto";
|
|
7411
|
-
import * as
|
|
7412
|
-
import * as
|
|
7569
|
+
import * as fs11 from "node:fs";
|
|
7570
|
+
import * as path11 from "node:path";
|
|
7413
7571
|
import { execSync } from "node:child_process";
|
|
7414
7572
|
function parseDeployArgs(args2) {
|
|
7415
7573
|
const opts = {};
|
|
@@ -7478,14 +7636,14 @@ function normalizeUrl2(url) {
|
|
|
7478
7636
|
}
|
|
7479
7637
|
function findWorkerDir() {
|
|
7480
7638
|
const candidates = [
|
|
7481
|
-
|
|
7482
|
-
|
|
7639
|
+
path11.resolve("packages/worker"),
|
|
7640
|
+
path11.resolve("../worker")
|
|
7483
7641
|
];
|
|
7484
|
-
const cliDir = process.argv[1] ?
|
|
7485
|
-
candidates.push(
|
|
7486
|
-
candidates.push(
|
|
7642
|
+
const cliDir = process.argv[1] ? path11.dirname(process.argv[1]) : process.cwd();
|
|
7643
|
+
candidates.push(path11.resolve(cliDir, "../../../worker"));
|
|
7644
|
+
candidates.push(path11.resolve(cliDir, "../../../../packages/worker"));
|
|
7487
7645
|
for (const candidate of candidates) {
|
|
7488
|
-
if (
|
|
7646
|
+
if (fs11.existsSync(path11.join(candidate, "src", "index.ts"))) {
|
|
7489
7647
|
return candidate;
|
|
7490
7648
|
}
|
|
7491
7649
|
}
|
|
@@ -7628,12 +7786,12 @@ bucket_name = "${names.r2}"
|
|
|
7628
7786
|
[vars]
|
|
7629
7787
|
BASE_URL = "${baseUrl}"
|
|
7630
7788
|
`;
|
|
7631
|
-
const wranglerPath =
|
|
7632
|
-
|
|
7789
|
+
const wranglerPath = path11.join(workerDir, "wrangler.toml");
|
|
7790
|
+
fs11.writeFileSync(wranglerPath, wranglerToml);
|
|
7633
7791
|
console.log("\u2705 wrangler.toml generated");
|
|
7634
7792
|
console.log("Applying D1 migrations...");
|
|
7635
|
-
const migrationsDir =
|
|
7636
|
-
if (
|
|
7793
|
+
const migrationsDir = path11.join(workerDir, "migrations");
|
|
7794
|
+
if (fs11.existsSync(migrationsDir)) {
|
|
7637
7795
|
const migResult = runSilent(`npx wrangler d1 migrations apply ${names.d1} --remote --config "${wranglerPath}"`);
|
|
7638
7796
|
if (migResult.ok) {
|
|
7639
7797
|
console.log("\u2705 Migrations applied");
|