nrdocs 0.2.2 → 0.2.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/dist/bin.mjs +173 -130
- package/package.json +1 -1
package/dist/bin.mjs
CHANGED
|
@@ -268,57 +268,24 @@ var require_punycode = __commonJS({
|
|
|
268
268
|
}
|
|
269
269
|
});
|
|
270
270
|
|
|
271
|
-
//
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
]);
|
|
287
|
-
var REJECTED_EXTENSIONS = /* @__PURE__ */ new Set([".js", ".mjs", ".cjs"]);
|
|
288
|
-
|
|
289
|
-
// ../shared/dist/naming.js
|
|
290
|
-
var INSTANCE_NAME_REGEX = /^[a-z0-9]([a-z0-9-]{0,18}[a-z0-9])?$/;
|
|
291
|
-
var MAX_INSTANCE_LENGTH = 20;
|
|
292
|
-
function validateInstanceName(name) {
|
|
293
|
-
if (!name) {
|
|
294
|
-
return { valid: false, error: "Instance name cannot be empty" };
|
|
295
|
-
}
|
|
296
|
-
if (name.length > MAX_INSTANCE_LENGTH) {
|
|
297
|
-
return { valid: false, error: `Instance name must be ${MAX_INSTANCE_LENGTH} characters or fewer` };
|
|
298
|
-
}
|
|
299
|
-
if (!INSTANCE_NAME_REGEX.test(name)) {
|
|
300
|
-
return {
|
|
301
|
-
valid: false,
|
|
302
|
-
error: "Instance name must be lowercase alphanumeric with hyphens, cannot start or end with a hyphen"
|
|
303
|
-
};
|
|
271
|
+
// src/version.ts
|
|
272
|
+
import { readFileSync } from "node:fs";
|
|
273
|
+
import * as path from "node:path";
|
|
274
|
+
import { fileURLToPath } from "node:url";
|
|
275
|
+
var cached;
|
|
276
|
+
function getCliVersion() {
|
|
277
|
+
if (cached) return cached;
|
|
278
|
+
try {
|
|
279
|
+
const pkgPath = path.join(path.dirname(fileURLToPath(import.meta.url)), "..", "package.json");
|
|
280
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
281
|
+
if (typeof pkg.version === "string" && pkg.version.length > 0) {
|
|
282
|
+
cached = pkg.version;
|
|
283
|
+
return cached;
|
|
284
|
+
}
|
|
285
|
+
} catch {
|
|
304
286
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
function getWorkerName(instance) {
|
|
308
|
-
return `nrdocs-${instance}`;
|
|
309
|
-
}
|
|
310
|
-
function getD1Name(instance) {
|
|
311
|
-
return `nrdocs-${instance}-db`;
|
|
312
|
-
}
|
|
313
|
-
function getR2BucketName(instance) {
|
|
314
|
-
return `nrdocs-${instance}-artifacts`;
|
|
315
|
-
}
|
|
316
|
-
function getResourceNames(instance) {
|
|
317
|
-
return {
|
|
318
|
-
worker: getWorkerName(instance),
|
|
319
|
-
d1: getD1Name(instance),
|
|
320
|
-
r2: getR2BucketName(instance)
|
|
321
|
-
};
|
|
287
|
+
cached = "0.0.0";
|
|
288
|
+
return cached;
|
|
322
289
|
}
|
|
323
290
|
|
|
324
291
|
// src/commands/auth/login.ts
|
|
@@ -326,17 +293,17 @@ import * as readline from "node:readline";
|
|
|
326
293
|
|
|
327
294
|
// src/config/paths.ts
|
|
328
295
|
import * as os from "node:os";
|
|
329
|
-
import * as
|
|
296
|
+
import * as path2 from "node:path";
|
|
330
297
|
var APP_NAME = "nrdocs";
|
|
331
298
|
var CONFIG_FILE = "config.json";
|
|
332
299
|
function getConfigDir(overrideDir) {
|
|
333
300
|
if (overrideDir) return overrideDir;
|
|
334
301
|
const xdg = process.env["XDG_CONFIG_HOME"];
|
|
335
|
-
const base = xdg ||
|
|
336
|
-
return
|
|
302
|
+
const base = xdg || path2.join(os.homedir(), ".config");
|
|
303
|
+
return path2.join(base, APP_NAME);
|
|
337
304
|
}
|
|
338
305
|
function getConfigPath(overrideDir) {
|
|
339
|
-
return
|
|
306
|
+
return path2.join(getConfigDir(overrideDir), CONFIG_FILE);
|
|
340
307
|
}
|
|
341
308
|
|
|
342
309
|
// src/config/schema.ts
|
|
@@ -366,7 +333,7 @@ function validateConfig(data) {
|
|
|
366
333
|
|
|
367
334
|
// src/config/store.ts
|
|
368
335
|
import * as fs from "node:fs";
|
|
369
|
-
import * as
|
|
336
|
+
import * as path3 from "node:path";
|
|
370
337
|
var DIR_MODE = 448;
|
|
371
338
|
var FILE_MODE = 384;
|
|
372
339
|
function ensureConfigDir(configDir) {
|
|
@@ -403,7 +370,7 @@ function loadConfig(overrideDir) {
|
|
|
403
370
|
}
|
|
404
371
|
function saveConfig(config2, overrideDir) {
|
|
405
372
|
const configDir = getConfigDir(overrideDir);
|
|
406
|
-
const configPath =
|
|
373
|
+
const configPath = path3.join(configDir, "config.json");
|
|
407
374
|
ensureConfigDir(configDir);
|
|
408
375
|
const json = JSON.stringify(config2, null, 2) + "\n";
|
|
409
376
|
fs.writeFileSync(configPath, json, { mode: FILE_MODE });
|
|
@@ -600,38 +567,53 @@ function authLogout(opts = {}) {
|
|
|
600
567
|
|
|
601
568
|
// src/commands/init.ts
|
|
602
569
|
import * as fs4 from "node:fs";
|
|
603
|
-
import * as
|
|
570
|
+
import * as path6 from "node:path";
|
|
604
571
|
import * as readline2 from "node:readline";
|
|
605
572
|
|
|
606
573
|
// src/config/docs-config.ts
|
|
607
574
|
import * as fs3 from "node:fs";
|
|
608
|
-
import * as
|
|
575
|
+
import * as path5 from "node:path";
|
|
609
576
|
import YAML from "yaml";
|
|
610
577
|
|
|
611
578
|
// src/renderer/navigation.ts
|
|
612
579
|
import * as fs2 from "node:fs";
|
|
613
|
-
import * as
|
|
580
|
+
import * as path4 from "node:path";
|
|
614
581
|
function extractTitle(markdownContent, filePath) {
|
|
615
582
|
const match2 = markdownContent.match(/^#\s+(.+)$/m);
|
|
616
583
|
if (match2) {
|
|
617
584
|
return match2[1].trim();
|
|
618
585
|
}
|
|
619
|
-
const basename3 =
|
|
586
|
+
const basename3 = path4.basename(filePath, ".md");
|
|
620
587
|
if (basename3 === "index") {
|
|
621
588
|
return "Home";
|
|
622
589
|
}
|
|
623
590
|
return basename3.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
624
591
|
}
|
|
592
|
+
function isSkippablePlaceholderIndex(contentDir, relativePath) {
|
|
593
|
+
const normalized = relativePath.replace(/\\/g, "/");
|
|
594
|
+
if (path4.dirname(normalized) !== ".") return false;
|
|
595
|
+
const full = path4.join(contentDir, normalized);
|
|
596
|
+
let text2;
|
|
597
|
+
try {
|
|
598
|
+
text2 = fs2.readFileSync(full, "utf-8").trim();
|
|
599
|
+
} catch {
|
|
600
|
+
return false;
|
|
601
|
+
}
|
|
602
|
+
if (text2.length === 0) return true;
|
|
603
|
+
if (text2.includes("Welcome to your documentation site powered by nrdocs")) return true;
|
|
604
|
+
if (text2.includes("Edit this file to add your documentation content")) return true;
|
|
605
|
+
return false;
|
|
606
|
+
}
|
|
625
607
|
function findMarkdownFiles(dir, relativeTo) {
|
|
626
608
|
const results = [];
|
|
627
609
|
if (!fs2.existsSync(dir)) return results;
|
|
628
610
|
const entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
629
611
|
for (const entry of entries) {
|
|
630
|
-
const fullPath =
|
|
612
|
+
const fullPath = path4.join(dir, entry.name);
|
|
631
613
|
if (entry.isDirectory()) {
|
|
632
614
|
results.push(...findMarkdownFiles(fullPath, relativeTo));
|
|
633
615
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
634
|
-
results.push(
|
|
616
|
+
results.push(path4.relative(relativeTo, fullPath).replace(/\\/g, "/"));
|
|
635
617
|
}
|
|
636
618
|
}
|
|
637
619
|
return results;
|
|
@@ -654,7 +636,7 @@ function mdPathToHref(filePath) {
|
|
|
654
636
|
return `${withoutExt}/`;
|
|
655
637
|
}
|
|
656
638
|
function navEntryFromFile(contentDir, file) {
|
|
657
|
-
const fullPath =
|
|
639
|
+
const fullPath = path4.join(contentDir, file);
|
|
658
640
|
const content = fs2.readFileSync(fullPath, "utf-8");
|
|
659
641
|
return {
|
|
660
642
|
title: extractTitle(content, file),
|
|
@@ -670,7 +652,7 @@ function groupNavEntriesByFolders(files, contentDir, indexPath = "index.md") {
|
|
|
670
652
|
const rootLinks = [];
|
|
671
653
|
const byFolder = /* @__PURE__ */ new Map();
|
|
672
654
|
for (const file of sorted) {
|
|
673
|
-
const dir =
|
|
655
|
+
const dir = path4.dirname(file).replace(/\\/g, "/");
|
|
674
656
|
if (dir === ".") {
|
|
675
657
|
rootLinks.push(navEntryFromFile(contentDir, file));
|
|
676
658
|
continue;
|
|
@@ -694,7 +676,9 @@ function groupNavEntriesByFolders(files, contentDir, indexPath = "index.md") {
|
|
|
694
676
|
}
|
|
695
677
|
function discoverNavEntries(contentDir, options) {
|
|
696
678
|
const indexPath = (options?.indexPath ?? "index.md").replace(/\\/g, "/");
|
|
697
|
-
const files = findMarkdownFiles(contentDir, contentDir)
|
|
679
|
+
const files = findMarkdownFiles(contentDir, contentDir).filter(
|
|
680
|
+
(f) => !isSkippablePlaceholderIndex(contentDir, f)
|
|
681
|
+
);
|
|
698
682
|
return groupNavEntriesByFolders(files, contentDir, indexPath);
|
|
699
683
|
}
|
|
700
684
|
function navConfigToNavItems(entries, contentDir) {
|
|
@@ -719,7 +703,7 @@ function navConfigToNavItems(entries, contentDir) {
|
|
|
719
703
|
throw new Error("Nav has no pages (entries need path or nested children with paths)");
|
|
720
704
|
}
|
|
721
705
|
for (const item of items) {
|
|
722
|
-
const full =
|
|
706
|
+
const full = path4.join(contentDir, item.path);
|
|
723
707
|
if (!fs2.existsSync(full)) {
|
|
724
708
|
throw new Error(`Nav path not found: ${item.path}`);
|
|
725
709
|
}
|
|
@@ -764,7 +748,7 @@ function flattenNavPaths(entries) {
|
|
|
764
748
|
|
|
765
749
|
// src/config/docs-config.ts
|
|
766
750
|
function loadDocsConfig(docsDir) {
|
|
767
|
-
const configPath =
|
|
751
|
+
const configPath = path5.resolve(docsDir, "nrdocs.yml");
|
|
768
752
|
if (!fs3.existsSync(configPath)) {
|
|
769
753
|
throw new Error(`Config file not found: ${configPath}`);
|
|
770
754
|
}
|
|
@@ -774,7 +758,7 @@ function loadDocsConfig(docsDir) {
|
|
|
774
758
|
throw new Error(`Invalid config: ${configPath}`);
|
|
775
759
|
}
|
|
776
760
|
const sourceDir = config2.content?.source_dir ?? ".";
|
|
777
|
-
const contentDir =
|
|
761
|
+
const contentDir = path5.resolve(docsDir, sourceDir);
|
|
778
762
|
return { config: config2, configPath, contentDir };
|
|
779
763
|
}
|
|
780
764
|
function hasExplicitNav(config2) {
|
|
@@ -830,7 +814,7 @@ function validateNavPaths(entries, contentDir) {
|
|
|
830
814
|
errors.push(`Duplicate nav path: ${p}`);
|
|
831
815
|
}
|
|
832
816
|
seen.add(p);
|
|
833
|
-
const full =
|
|
817
|
+
const full = path5.join(contentDir, p);
|
|
834
818
|
if (!fs3.existsSync(full)) {
|
|
835
819
|
errors.push(`Nav path not found: ${p}`);
|
|
836
820
|
}
|
|
@@ -1011,11 +995,11 @@ async function handleInit(args2) {
|
|
|
1011
995
|
process.exit(2);
|
|
1012
996
|
}
|
|
1013
997
|
const docsDir = opts.docsDir || "docs";
|
|
1014
|
-
const docsPath =
|
|
1015
|
-
const configFile =
|
|
998
|
+
const docsPath = path6.resolve(docsDir);
|
|
999
|
+
const configFile = path6.join(docsPath, "nrdocs.yml");
|
|
1016
1000
|
const existing = readExistingConfig(configFile);
|
|
1017
1001
|
const configExists = fs4.existsSync(configFile);
|
|
1018
|
-
const dirName =
|
|
1002
|
+
const dirName = path6.basename(process.cwd());
|
|
1019
1003
|
let title = opts.title || existing.title;
|
|
1020
1004
|
if (!title) {
|
|
1021
1005
|
title = await prompt2("Site title", `${dirName} Docs`);
|
|
@@ -1048,8 +1032,8 @@ async function handleInit(args2) {
|
|
|
1048
1032
|
process.exit(2);
|
|
1049
1033
|
}
|
|
1050
1034
|
apiUrl = normalizeUrl(apiUrl);
|
|
1051
|
-
const workflowDir =
|
|
1052
|
-
const workflowFile =
|
|
1035
|
+
const workflowDir = path6.resolve(".github", "workflows");
|
|
1036
|
+
const workflowFile = path6.join(workflowDir, "nrdocs.yml");
|
|
1053
1037
|
if (!opts.force && fs4.existsSync(workflowFile)) {
|
|
1054
1038
|
console.error("Error: Workflow already exists:");
|
|
1055
1039
|
console.error(` ${workflowFile}`);
|
|
@@ -1071,12 +1055,12 @@ async function handleInit(args2) {
|
|
|
1071
1055
|
console.log("");
|
|
1072
1056
|
console.log("Created/updated:");
|
|
1073
1057
|
if (createdConfig) {
|
|
1074
|
-
console.log(` ${
|
|
1058
|
+
console.log(` ${path6.relative(process.cwd(), configFile)}`);
|
|
1075
1059
|
}
|
|
1076
|
-
console.log(` ${
|
|
1060
|
+
console.log(` ${path6.relative(process.cwd(), workflowFile)}`);
|
|
1077
1061
|
if (!createdConfig) {
|
|
1078
1062
|
console.log("");
|
|
1079
|
-
console.log(`Using existing: ${
|
|
1063
|
+
console.log(`Using existing: ${path6.relative(process.cwd(), configFile)}`);
|
|
1080
1064
|
}
|
|
1081
1065
|
if (navPageCount > 0) {
|
|
1082
1066
|
console.log(` content.nav: ${navPageCount} page(s) from markdown under ${docsDir}/`);
|
|
@@ -1086,7 +1070,7 @@ async function handleInit(args2) {
|
|
|
1086
1070
|
if (navPageCount === 0) {
|
|
1087
1071
|
console.log(` 1. Add markdown files under ${docsDir}/, then run: nrdocs nav generate`);
|
|
1088
1072
|
} else {
|
|
1089
|
-
console.log(` 1. Edit content.nav in ${
|
|
1073
|
+
console.log(` 1. Edit content.nav in ${path6.relative(process.cwd(), configFile)} to reorder pages`);
|
|
1090
1074
|
}
|
|
1091
1075
|
console.log(" 2. Commit and push to trigger the workflow");
|
|
1092
1076
|
console.log(" 3. Ask your operator to approve the repo");
|
|
@@ -1097,7 +1081,7 @@ import * as fs8 from "node:fs";
|
|
|
1097
1081
|
|
|
1098
1082
|
// src/renderer/index.ts
|
|
1099
1083
|
import * as fs7 from "node:fs";
|
|
1100
|
-
import * as
|
|
1084
|
+
import * as path9 from "node:path";
|
|
1101
1085
|
|
|
1102
1086
|
// ../../node_modules/.pnpm/markdown-it@14.1.1/node_modules/markdown-it/lib/common/utils.mjs
|
|
1103
1087
|
var utils_exports = {};
|
|
@@ -6588,9 +6572,63 @@ function escapeHtml2(str) {
|
|
|
6588
6572
|
|
|
6589
6573
|
// src/renderer/assets.ts
|
|
6590
6574
|
import * as fs5 from "node:fs";
|
|
6591
|
-
import * as
|
|
6575
|
+
import * as path7 from "node:path";
|
|
6576
|
+
|
|
6577
|
+
// ../shared/dist/constants.js
|
|
6578
|
+
var ALLOWED_ASSET_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
6579
|
+
".html",
|
|
6580
|
+
".css",
|
|
6581
|
+
".json",
|
|
6582
|
+
".svg",
|
|
6583
|
+
".png",
|
|
6584
|
+
".jpg",
|
|
6585
|
+
".jpeg",
|
|
6586
|
+
".gif",
|
|
6587
|
+
".webp",
|
|
6588
|
+
".ico",
|
|
6589
|
+
".txt",
|
|
6590
|
+
".pdf"
|
|
6591
|
+
]);
|
|
6592
|
+
var REJECTED_EXTENSIONS = /* @__PURE__ */ new Set([".js", ".mjs", ".cjs"]);
|
|
6593
|
+
|
|
6594
|
+
// ../shared/dist/naming.js
|
|
6595
|
+
var INSTANCE_NAME_REGEX = /^[a-z0-9]([a-z0-9-]{0,18}[a-z0-9])?$/;
|
|
6596
|
+
var MAX_INSTANCE_LENGTH = 20;
|
|
6597
|
+
function validateInstanceName(name) {
|
|
6598
|
+
if (!name) {
|
|
6599
|
+
return { valid: false, error: "Instance name cannot be empty" };
|
|
6600
|
+
}
|
|
6601
|
+
if (name.length > MAX_INSTANCE_LENGTH) {
|
|
6602
|
+
return { valid: false, error: `Instance name must be ${MAX_INSTANCE_LENGTH} characters or fewer` };
|
|
6603
|
+
}
|
|
6604
|
+
if (!INSTANCE_NAME_REGEX.test(name)) {
|
|
6605
|
+
return {
|
|
6606
|
+
valid: false,
|
|
6607
|
+
error: "Instance name must be lowercase alphanumeric with hyphens, cannot start or end with a hyphen"
|
|
6608
|
+
};
|
|
6609
|
+
}
|
|
6610
|
+
return { valid: true };
|
|
6611
|
+
}
|
|
6612
|
+
function getWorkerName(instance) {
|
|
6613
|
+
return `nrdocs-${instance}`;
|
|
6614
|
+
}
|
|
6615
|
+
function getD1Name(instance) {
|
|
6616
|
+
return `nrdocs-${instance}-db`;
|
|
6617
|
+
}
|
|
6618
|
+
function getR2BucketName(instance) {
|
|
6619
|
+
return `nrdocs-${instance}-artifacts`;
|
|
6620
|
+
}
|
|
6621
|
+
function getResourceNames(instance) {
|
|
6622
|
+
return {
|
|
6623
|
+
worker: getWorkerName(instance),
|
|
6624
|
+
d1: getD1Name(instance),
|
|
6625
|
+
r2: getR2BucketName(instance)
|
|
6626
|
+
};
|
|
6627
|
+
}
|
|
6628
|
+
|
|
6629
|
+
// src/renderer/assets.ts
|
|
6592
6630
|
function collectAssets(docsDir) {
|
|
6593
|
-
const resolvedDocsDir =
|
|
6631
|
+
const resolvedDocsDir = path7.resolve(docsDir);
|
|
6594
6632
|
const files = [];
|
|
6595
6633
|
collectFromDir(resolvedDocsDir, resolvedDocsDir, files);
|
|
6596
6634
|
return files;
|
|
@@ -6603,8 +6641,8 @@ function collectFromDir(dir, rootDir, results) {
|
|
|
6603
6641
|
return;
|
|
6604
6642
|
}
|
|
6605
6643
|
for (const entry of entries) {
|
|
6606
|
-
const fullPath =
|
|
6607
|
-
const resolved =
|
|
6644
|
+
const fullPath = path7.join(dir, entry.name);
|
|
6645
|
+
const resolved = path7.resolve(fullPath);
|
|
6608
6646
|
if (!resolved.startsWith(rootDir)) {
|
|
6609
6647
|
continue;
|
|
6610
6648
|
}
|
|
@@ -6612,11 +6650,11 @@ function collectFromDir(dir, rootDir, results) {
|
|
|
6612
6650
|
if (entry.name.startsWith(".")) continue;
|
|
6613
6651
|
collectFromDir(fullPath, rootDir, results);
|
|
6614
6652
|
} else if (entry.isFile()) {
|
|
6615
|
-
const ext =
|
|
6653
|
+
const ext = path7.extname(entry.name).toLowerCase();
|
|
6616
6654
|
if (ext === ".md") continue;
|
|
6617
6655
|
if (REJECTED_EXTENSIONS.has(ext)) continue;
|
|
6618
6656
|
if (!ALLOWED_ASSET_EXTENSIONS.has(ext)) continue;
|
|
6619
|
-
const relativePath =
|
|
6657
|
+
const relativePath = path7.relative(rootDir, fullPath);
|
|
6620
6658
|
if (relativePath.includes("..")) continue;
|
|
6621
6659
|
results.push({
|
|
6622
6660
|
path: relativePath.replace(/\\/g, "/"),
|
|
@@ -6628,15 +6666,15 @@ function collectFromDir(dir, rootDir, results) {
|
|
|
6628
6666
|
|
|
6629
6667
|
// src/renderer/mermaid-runtime.ts
|
|
6630
6668
|
import * as fs6 from "node:fs";
|
|
6631
|
-
import * as
|
|
6632
|
-
import { fileURLToPath } from "node:url";
|
|
6633
|
-
var __dirname =
|
|
6669
|
+
import * as path8 from "node:path";
|
|
6670
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
6671
|
+
var __dirname = path8.dirname(fileURLToPath2(import.meta.url));
|
|
6634
6672
|
var MERMAID_RUNTIME_REL = "runtime/mermaid.min.js";
|
|
6635
6673
|
var MERMAID_ARTIFACT_PATH = "_nrdocs/mermaid.min.js";
|
|
6636
6674
|
function mermaidRuntimeCandidates() {
|
|
6637
6675
|
return [
|
|
6638
|
-
|
|
6639
|
-
|
|
6676
|
+
path8.join(__dirname, MERMAID_RUNTIME_REL),
|
|
6677
|
+
path8.join(__dirname, "../../dist/runtime/mermaid.min.js")
|
|
6640
6678
|
];
|
|
6641
6679
|
}
|
|
6642
6680
|
function loadMermaidRuntime() {
|
|
@@ -6671,18 +6709,18 @@ function resolveNav(resolvedDocsDir, nav, indexPath) {
|
|
|
6671
6709
|
}
|
|
6672
6710
|
async function renderSite(options) {
|
|
6673
6711
|
const { docsDir, siteTitle, baseUrl, owner, repo, nav, indexPath = "index.md" } = options;
|
|
6674
|
-
const resolvedDocsDir =
|
|
6712
|
+
const resolvedDocsDir = path9.resolve(docsDir);
|
|
6675
6713
|
const { items: navItems, sidebarConfig } = resolveNav(resolvedDocsDir, nav, indexPath);
|
|
6676
6714
|
const siteBase = `/${owner}/${repo}/`;
|
|
6677
6715
|
const renderedFiles = [];
|
|
6678
6716
|
let siteHasMermaid = false;
|
|
6679
6717
|
for (const navItem of navItems) {
|
|
6680
|
-
const filePath =
|
|
6718
|
+
const filePath = path9.join(resolvedDocsDir, navItem.path);
|
|
6681
6719
|
const markdownContent = fs7.readFileSync(filePath, "utf-8");
|
|
6682
6720
|
const pageHasMermaid = contentHasMermaid(markdownContent);
|
|
6683
6721
|
if (pageHasMermaid) siteHasMermaid = true;
|
|
6684
6722
|
let html = renderMarkdown(markdownContent);
|
|
6685
|
-
const fileDir =
|
|
6723
|
+
const fileDir = path9.dirname(navItem.path);
|
|
6686
6724
|
const baseLinkPath = fileDir === "." ? "" : fileDir;
|
|
6687
6725
|
html = rewriteLinks(html, baseLinkPath, owner, repo);
|
|
6688
6726
|
const pageTitle = extractTitle(markdownContent, navItem.path);
|
|
@@ -6806,8 +6844,8 @@ function normalizeApiBaseUrl(url) {
|
|
|
6806
6844
|
}
|
|
6807
6845
|
function buildApiUrl(baseUrl, apiPath) {
|
|
6808
6846
|
const { url } = normalizeApiBaseUrl(baseUrl);
|
|
6809
|
-
const
|
|
6810
|
-
return `${url}${
|
|
6847
|
+
const path13 = apiPath.startsWith("/") ? apiPath : `/${apiPath}`;
|
|
6848
|
+
return `${url}${path13}`;
|
|
6811
6849
|
}
|
|
6812
6850
|
function extractFetchError(err) {
|
|
6813
6851
|
if (!(err instanceof Error)) {
|
|
@@ -6950,12 +6988,12 @@ async function probeApiStatus(baseUrl, timeoutMs = 15e3) {
|
|
|
6950
6988
|
};
|
|
6951
6989
|
}
|
|
6952
6990
|
const json = await res.json();
|
|
6953
|
-
const
|
|
6991
|
+
const version2 = json.data?.version;
|
|
6954
6992
|
return {
|
|
6955
6993
|
ok: true,
|
|
6956
6994
|
status: res.status,
|
|
6957
|
-
message:
|
|
6958
|
-
version
|
|
6995
|
+
message: version2 ? `OK (nrdocs ${version2})` : "OK",
|
|
6996
|
+
version: version2
|
|
6959
6997
|
};
|
|
6960
6998
|
} catch (e) {
|
|
6961
6999
|
clearTimeout(timer);
|
|
@@ -7055,8 +7093,8 @@ var ApiClient = class {
|
|
|
7055
7093
|
}
|
|
7056
7094
|
};
|
|
7057
7095
|
}
|
|
7058
|
-
async request(method,
|
|
7059
|
-
const url = buildApiUrl(this.baseUrl,
|
|
7096
|
+
async request(method, path13, body, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
7097
|
+
const url = buildApiUrl(this.baseUrl, path13);
|
|
7060
7098
|
const controller = new AbortController();
|
|
7061
7099
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
7062
7100
|
const init = {
|
|
@@ -7125,8 +7163,8 @@ var ApiClient = class {
|
|
|
7125
7163
|
});
|
|
7126
7164
|
}
|
|
7127
7165
|
async setSelfPasswordAllow(owner, repo, allow) {
|
|
7128
|
-
const
|
|
7129
|
-
return this.request("POST",
|
|
7166
|
+
const path13 = allow ? `/api/repos/${owner}/${repo}/allow-self-password` : `/api/repos/${owner}/${repo}/disallow-self-password`;
|
|
7167
|
+
return this.request("POST", path13);
|
|
7130
7168
|
}
|
|
7131
7169
|
async listRules() {
|
|
7132
7170
|
return this.request("GET", "/api/auto-approval-rules");
|
|
@@ -7396,7 +7434,7 @@ async function handlePublish(args2) {
|
|
|
7396
7434
|
|
|
7397
7435
|
// src/commands/doctor.ts
|
|
7398
7436
|
import * as fs9 from "node:fs";
|
|
7399
|
-
import * as
|
|
7437
|
+
import * as path10 from "node:path";
|
|
7400
7438
|
function parseDoctorArgs(args2) {
|
|
7401
7439
|
const opts = {};
|
|
7402
7440
|
for (const arg of args2) {
|
|
@@ -7410,7 +7448,7 @@ function countMarkdownFiles(docsDir) {
|
|
|
7410
7448
|
let count = 0;
|
|
7411
7449
|
const walk = (dir) => {
|
|
7412
7450
|
for (const entry of fs9.readdirSync(dir, { withFileTypes: true })) {
|
|
7413
|
-
const full =
|
|
7451
|
+
const full = path10.join(dir, entry.name);
|
|
7414
7452
|
if (entry.isDirectory()) walk(full);
|
|
7415
7453
|
else if (entry.name.endsWith(".md")) count++;
|
|
7416
7454
|
}
|
|
@@ -7422,14 +7460,14 @@ async function handleDoctor(args2) {
|
|
|
7422
7460
|
const opts = parseDoctorArgs(args2);
|
|
7423
7461
|
const inCI = opts.ci || process.env["GITHUB_ACTIONS"] === "true";
|
|
7424
7462
|
const checks = [];
|
|
7425
|
-
const isGitRepo = fs9.existsSync(
|
|
7463
|
+
const isGitRepo = fs9.existsSync(path10.resolve(".git"));
|
|
7426
7464
|
checks.push({
|
|
7427
7465
|
section: "Repo setup",
|
|
7428
7466
|
name: "Git repository",
|
|
7429
7467
|
status: isGitRepo ? "ok" : "fail",
|
|
7430
7468
|
message: isGitRepo ? "Found .git directory" : "Not a git repository"
|
|
7431
7469
|
});
|
|
7432
|
-
const configPath =
|
|
7470
|
+
const configPath = path10.resolve("docs", "nrdocs.yml");
|
|
7433
7471
|
const hasConfig = fs9.existsSync(configPath);
|
|
7434
7472
|
checks.push({
|
|
7435
7473
|
section: "Repo setup",
|
|
@@ -7437,7 +7475,7 @@ async function handleDoctor(args2) {
|
|
|
7437
7475
|
status: hasConfig ? "ok" : "fail",
|
|
7438
7476
|
message: hasConfig ? "Found docs/nrdocs.yml" : "Missing docs/nrdocs.yml \u2014 run: nrdocs init"
|
|
7439
7477
|
});
|
|
7440
|
-
const docsDir =
|
|
7478
|
+
const docsDir = path10.resolve("docs");
|
|
7441
7479
|
const mdCount = countMarkdownFiles(docsDir);
|
|
7442
7480
|
checks.push({
|
|
7443
7481
|
section: "Repo setup",
|
|
@@ -7445,7 +7483,7 @@ async function handleDoctor(args2) {
|
|
|
7445
7483
|
status: mdCount > 0 ? "ok" : "warn",
|
|
7446
7484
|
message: mdCount > 0 ? `${mdCount} markdown file(s) in docs/` : "No .md files in docs/ \u2014 publish will produce an empty site"
|
|
7447
7485
|
});
|
|
7448
|
-
const workflowPath =
|
|
7486
|
+
const workflowPath = path10.resolve(".github", "workflows", "nrdocs.yml");
|
|
7449
7487
|
const hasWorkflow = fs9.existsSync(workflowPath);
|
|
7450
7488
|
checks.push({
|
|
7451
7489
|
section: "Repo setup",
|
|
@@ -7626,7 +7664,7 @@ async function handleDoctor(args2) {
|
|
|
7626
7664
|
|
|
7627
7665
|
// src/commands/nav.ts
|
|
7628
7666
|
import * as fs10 from "node:fs";
|
|
7629
|
-
import * as
|
|
7667
|
+
import * as path11 from "node:path";
|
|
7630
7668
|
function parseNavGenerateArgs(args2) {
|
|
7631
7669
|
const opts = {};
|
|
7632
7670
|
for (let i = 0; i < args2.length; i++) {
|
|
@@ -7645,8 +7683,8 @@ function parseNavGenerateArgs(args2) {
|
|
|
7645
7683
|
}
|
|
7646
7684
|
async function handleNavGenerate(args2) {
|
|
7647
7685
|
const opts = parseNavGenerateArgs(args2);
|
|
7648
|
-
const docsDir =
|
|
7649
|
-
const configPath =
|
|
7686
|
+
const docsDir = path11.resolve(opts.docsDir ?? "docs");
|
|
7687
|
+
const configPath = path11.join(docsDir, "nrdocs.yml");
|
|
7650
7688
|
if (!fs10.existsSync(configPath)) {
|
|
7651
7689
|
console.error(`Error: Config file not found: ${configPath}`);
|
|
7652
7690
|
console.error("Run: nrdocs init");
|
|
@@ -7670,8 +7708,9 @@ async function handleNavGenerate(args2) {
|
|
|
7670
7708
|
console.error(`Error: No markdown files found in ${loaded.contentDir}`);
|
|
7671
7709
|
process.exit(10);
|
|
7672
7710
|
}
|
|
7711
|
+
const pageCount = flattenNavPaths(entries).length;
|
|
7673
7712
|
if (opts.json) {
|
|
7674
|
-
console.log(JSON.stringify({ nav: entries,
|
|
7713
|
+
console.log(JSON.stringify({ nav: entries, pages: pageCount }, null, 2));
|
|
7675
7714
|
if (opts.dryRun) return;
|
|
7676
7715
|
} else if (opts.dryRun) {
|
|
7677
7716
|
console.log("# Dry run \u2014 content.nav that would be written:\n");
|
|
@@ -7680,8 +7719,11 @@ async function handleNavGenerate(args2) {
|
|
|
7680
7719
|
}
|
|
7681
7720
|
generateNavInConfig(docsDir, { generatedBy: "nrdocs nav generate", indexPath });
|
|
7682
7721
|
if (!opts.json) {
|
|
7683
|
-
console.log(
|
|
7684
|
-
|
|
7722
|
+
console.log(
|
|
7723
|
+
`Updated content.nav (${pageCount} page(s)) in ${path11.relative(process.cwd(), configPath)}`
|
|
7724
|
+
);
|
|
7725
|
+
console.log("Only nrdocs.yml was changed \u2014 no markdown files are created or modified.");
|
|
7726
|
+
console.log("Edit content.nav to reorder, then publish via GitHub Actions.");
|
|
7685
7727
|
}
|
|
7686
7728
|
}
|
|
7687
7729
|
|
|
@@ -7689,7 +7731,7 @@ async function handleNavGenerate(args2) {
|
|
|
7689
7731
|
import * as readline3 from "node:readline";
|
|
7690
7732
|
import * as crypto from "node:crypto";
|
|
7691
7733
|
import * as fs11 from "node:fs";
|
|
7692
|
-
import * as
|
|
7734
|
+
import * as path12 from "node:path";
|
|
7693
7735
|
import { execSync } from "node:child_process";
|
|
7694
7736
|
function parseDeployArgs(args2) {
|
|
7695
7737
|
const opts = {};
|
|
@@ -7759,35 +7801,35 @@ function normalizeUrl2(url) {
|
|
|
7759
7801
|
function packagedWorkerDir() {
|
|
7760
7802
|
const cliEntry = process.argv[1];
|
|
7761
7803
|
if (!cliEntry) return null;
|
|
7762
|
-
const distDir =
|
|
7763
|
-
const dir =
|
|
7764
|
-
if (fs11.existsSync(
|
|
7804
|
+
const distDir = path12.dirname(path12.resolve(cliEntry));
|
|
7805
|
+
const dir = path12.join(distDir, "deploy-worker");
|
|
7806
|
+
if (fs11.existsSync(path12.join(dir, "index.js"))) return dir;
|
|
7765
7807
|
return null;
|
|
7766
7808
|
}
|
|
7767
7809
|
function findWorkerDir() {
|
|
7768
7810
|
const packaged = packagedWorkerDir();
|
|
7769
7811
|
if (packaged) return packaged;
|
|
7770
7812
|
const monorepoCandidates = [
|
|
7771
|
-
|
|
7772
|
-
|
|
7813
|
+
path12.resolve("packages/worker"),
|
|
7814
|
+
path12.resolve("../worker")
|
|
7773
7815
|
];
|
|
7774
7816
|
if (process.argv[1]) {
|
|
7775
|
-
const cliDir =
|
|
7776
|
-
monorepoCandidates.push(
|
|
7777
|
-
monorepoCandidates.push(
|
|
7817
|
+
const cliDir = path12.dirname(path12.resolve(process.argv[1]));
|
|
7818
|
+
monorepoCandidates.push(path12.resolve(cliDir, "../../../worker"));
|
|
7819
|
+
monorepoCandidates.push(path12.resolve(cliDir, "../../../../packages/worker"));
|
|
7778
7820
|
}
|
|
7779
7821
|
for (const candidate of monorepoCandidates) {
|
|
7780
|
-
if (fs11.existsSync(
|
|
7822
|
+
if (fs11.existsSync(path12.join(candidate, "src", "index.ts"))) {
|
|
7781
7823
|
return candidate;
|
|
7782
7824
|
}
|
|
7783
7825
|
}
|
|
7784
7826
|
return null;
|
|
7785
7827
|
}
|
|
7786
7828
|
function isDocsContentRepo(cwd) {
|
|
7787
|
-
return fs11.existsSync(
|
|
7829
|
+
return fs11.existsSync(path12.join(cwd, "docs", "nrdocs.yml")) && !fs11.existsSync(path12.join(cwd, "packages", "worker", "src", "index.ts"));
|
|
7788
7830
|
}
|
|
7789
7831
|
function workerUsesBundledEntry(workerDir) {
|
|
7790
|
-
return fs11.existsSync(
|
|
7832
|
+
return fs11.existsSync(path12.join(workerDir, "index.js"));
|
|
7791
7833
|
}
|
|
7792
7834
|
async function handleDeploy(args2) {
|
|
7793
7835
|
const opts = parseDeployArgs(args2);
|
|
@@ -7941,11 +7983,11 @@ bucket_name = "${names.r2}"
|
|
|
7941
7983
|
[vars]
|
|
7942
7984
|
BASE_URL = "${baseUrl}"
|
|
7943
7985
|
`;
|
|
7944
|
-
const wranglerPath =
|
|
7986
|
+
const wranglerPath = path12.join(workerDir, "wrangler.toml");
|
|
7945
7987
|
fs11.writeFileSync(wranglerPath, wranglerToml);
|
|
7946
7988
|
console.log("\u2705 wrangler.toml generated");
|
|
7947
7989
|
console.log("Applying D1 migrations...");
|
|
7948
|
-
const migrationsDir =
|
|
7990
|
+
const migrationsDir = path12.join(workerDir, "migrations");
|
|
7949
7991
|
if (fs11.existsSync(migrationsDir)) {
|
|
7950
7992
|
const migResult = runSilent(`npx wrangler d1 migrations apply ${names.d1} --remote --config "${wranglerPath}"`);
|
|
7951
7993
|
if (migResult.ok) {
|
|
@@ -8914,12 +8956,13 @@ function parseAuthLogoutFlags(args2) {
|
|
|
8914
8956
|
|
|
8915
8957
|
// src/bin.ts
|
|
8916
8958
|
var args = process.argv.slice(2);
|
|
8959
|
+
var version = getCliVersion();
|
|
8917
8960
|
if (args.includes("--version") || args.includes("-v")) {
|
|
8918
|
-
console.log(`nrdocs ${
|
|
8961
|
+
console.log(`nrdocs ${version}`);
|
|
8919
8962
|
process.exit(0);
|
|
8920
8963
|
}
|
|
8921
8964
|
if (args.includes("--help") || args.includes("-h") || args.length === 0) {
|
|
8922
|
-
console.log(`nrdocs ${
|
|
8965
|
+
console.log(`nrdocs ${version}
|
|
8923
8966
|
|
|
8924
8967
|
Usage:
|
|
8925
8968
|
nrdocs <command> [options]
|