dogsbay 0.2.0-beta.56 → 0.2.0-beta.57
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/commands/migrate-asciidoc.js +10 -1
- package/dist/commands/site-build.js +70 -0
- package/dist/config/load.js +8 -0
- package/package.json +13 -13
|
@@ -367,7 +367,16 @@ function buildDogsbayConfig(opts) {
|
|
|
367
367
|
// them so format-astro skips emitting routes — the .md files
|
|
368
368
|
// stay on disk so includes resolve, but they don't become
|
|
369
369
|
// URLs. See plans/build-at-scale.md.
|
|
370
|
-
` excludeFromRoutes:`, ` - _attributes`, ` - modules`, ` - snippets`, ` - includes
|
|
370
|
+
` excludeFromRoutes:`, ` - _attributes`, ` - modules`, ` - snippets`, ` - includes`,
|
|
371
|
+
// The AsciiBinder topic_map → nav.yml is the authoritative page
|
|
372
|
+
// list. routablesFrom: nav restricts the page set to pages the nav
|
|
373
|
+
// names; everything else (modules, fragments) is pulled into
|
|
374
|
+
// assemblies via `{% include %}` and never emitted standalone — so
|
|
375
|
+
// no fragment leaks into routes / llms.txt / search, and the build
|
|
376
|
+
// skips the ~85% of files that are includes (10.7k → ~1.7k on
|
|
377
|
+
// OpenShift). excludeFromRoutes above stays as the fallback for
|
|
378
|
+
// `routablesFrom: all`. See plans/nav-scoped-processing.md.
|
|
379
|
+
` routablesFrom: nav`);
|
|
371
380
|
// Persist the migration-time --attribute values so subsequent
|
|
372
381
|
// `dogsbay site build` runs resolve {{ var }} / {% if %}
|
|
373
382
|
// without re-passing flags. The build-time preprocessor
|
|
@@ -224,6 +224,23 @@ export async function siteBuild(cwd, options) {
|
|
|
224
224
|
// local preview. Nav entries pointing at filtered pages are pruned
|
|
225
225
|
// recursively so the sidebar doesn't have dead links.
|
|
226
226
|
let { pages, nav, draftCount } = filterDrafts(importResult.pages, importResult.nav, options.includeDrafts === true, config.site.basePath);
|
|
227
|
+
// 7a. routablesFrom: "nav" — restrict the page set to pages the nav
|
|
228
|
+
// lists (the whitelist). Include-only fragments (modules/, _attributes/,
|
|
229
|
+
// etc.) are inlined into their assemblies by the preprocessor, so they
|
|
230
|
+
// never need to be standalone pages; dropping them here keeps them out
|
|
231
|
+
// of autodoc, ref-validation, llms.txt, the sitemap, and emit — no
|
|
232
|
+
// fragment-detection needed. Self-safe: a no-op when the nav is
|
|
233
|
+
// auto-derived (it already covers every page) or routablesFrom is
|
|
234
|
+
// "all". See plans/nav-scoped-processing.md.
|
|
235
|
+
if (config.content.routablesFrom === "nav") {
|
|
236
|
+
const before = pages.length;
|
|
237
|
+
const { kept, dropped } = filterPagesToNav(pages, nav, config.site.basePath);
|
|
238
|
+
if (dropped.length > 0) {
|
|
239
|
+
pages = kept;
|
|
240
|
+
console.log(` routablesFrom: nav — excluded ${dropped.length} non-nav page(s) of ${before}` +
|
|
241
|
+
` (e.g. ${dropped.slice(0, 5).join(", ")})`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
227
244
|
// 7b. onContentImported — let plugins mutate the page set + nav.
|
|
228
245
|
if (resolvedPlugins.some((p) => p.plugin.onContentImported)) {
|
|
229
246
|
const after = await runOnContentImported(resolvedPlugins, baseCtx, pages, nav);
|
|
@@ -677,3 +694,56 @@ function hrefMatchesDroppedSlug(href, droppedSlugs, basePath) {
|
|
|
677
694
|
}
|
|
678
695
|
return droppedSlugs.has(normalized) || droppedSlugs.has(normalized || "index");
|
|
679
696
|
}
|
|
697
|
+
/**
|
|
698
|
+
* Collect the slug of every nav leaf (recursively), normalized the same
|
|
699
|
+
* way `hrefMatchesDroppedSlug` normalizes a single href — strip
|
|
700
|
+
* leading/trailing slashes, strip leading basePath segments; an empty
|
|
701
|
+
* result (the home href `/`) maps to `index`. Used by
|
|
702
|
+
* `content.routablesFrom: "nav"` to restrict the page set to
|
|
703
|
+
* nav-reachable pages.
|
|
704
|
+
*/
|
|
705
|
+
function collectNavSlugs(items, basePath) {
|
|
706
|
+
const out = new Set();
|
|
707
|
+
const bp = normalizeBasePath(basePath);
|
|
708
|
+
const segs = basePathSegments(bp);
|
|
709
|
+
const walk = (nodes) => {
|
|
710
|
+
for (const item of nodes) {
|
|
711
|
+
if (item.href) {
|
|
712
|
+
let normalized = item.href.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
713
|
+
for (const seg of segs) {
|
|
714
|
+
if (normalized === seg) {
|
|
715
|
+
normalized = "";
|
|
716
|
+
break;
|
|
717
|
+
}
|
|
718
|
+
if (normalized.startsWith(`${seg}/`)) {
|
|
719
|
+
normalized = normalized.slice(seg.length + 1);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
out.add(normalized || "index");
|
|
723
|
+
}
|
|
724
|
+
if (item.children && item.children.length > 0)
|
|
725
|
+
walk(item.children);
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
walk(items);
|
|
729
|
+
return out;
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Partition pages by nav membership for `content.routablesFrom: "nav"`.
|
|
733
|
+
* `kept` = pages whose slug is reachable from the nav; `dropped` = the
|
|
734
|
+
* slugs of pages the nav omits (include-only fragments — their content
|
|
735
|
+
* is already inlined into the assemblies that include them). Pure +
|
|
736
|
+
* exported for unit testing.
|
|
737
|
+
*/
|
|
738
|
+
export function filterPagesToNav(pages, nav, basePath) {
|
|
739
|
+
const navSlugs = collectNavSlugs(nav, basePath);
|
|
740
|
+
const kept = [];
|
|
741
|
+
const dropped = [];
|
|
742
|
+
for (const page of pages) {
|
|
743
|
+
if (navSlugs.has(page.slug))
|
|
744
|
+
kept.push(page);
|
|
745
|
+
else
|
|
746
|
+
dropped.push(page.slug);
|
|
747
|
+
}
|
|
748
|
+
return { kept, dropped };
|
|
749
|
+
}
|
package/dist/config/load.js
CHANGED
|
@@ -466,6 +466,13 @@ function validateContent(content, sourcePath) {
|
|
|
466
466
|
}
|
|
467
467
|
excludeFromRoutes = c.excludeFromRoutes;
|
|
468
468
|
}
|
|
469
|
+
let routablesFrom;
|
|
470
|
+
if (c.routablesFrom !== undefined) {
|
|
471
|
+
if (c.routablesFrom !== "all" && c.routablesFrom !== "nav") {
|
|
472
|
+
throw new Error(`content.routablesFrom must be "all" or "nav" in ${sourcePath}`);
|
|
473
|
+
}
|
|
474
|
+
routablesFrom = c.routablesFrom;
|
|
475
|
+
}
|
|
469
476
|
return {
|
|
470
477
|
sources: validatedSources,
|
|
471
478
|
section: c.section,
|
|
@@ -476,6 +483,7 @@ function validateContent(content, sourcePath) {
|
|
|
476
483
|
locales,
|
|
477
484
|
defaultLocale,
|
|
478
485
|
excludeFromRoutes,
|
|
486
|
+
routablesFrom,
|
|
479
487
|
};
|
|
480
488
|
}
|
|
481
489
|
function validateLocales(raw, sourcePath) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dogsbay",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.57",
|
|
4
4
|
"description": "CLI for Dogsbay — scaffold, build, and serve documentation sites with markdown / MkDocs / Obsidian / OpenAPI sources",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -33,18 +33,18 @@
|
|
|
33
33
|
"picocolors": "^1.1.0",
|
|
34
34
|
"prompts": "^2.4.2",
|
|
35
35
|
"yaml": "^2.8.3",
|
|
36
|
-
"@dogsbay/
|
|
37
|
-
"@dogsbay/format-
|
|
38
|
-
"@dogsbay/
|
|
39
|
-
"@dogsbay/format-
|
|
40
|
-
"@dogsbay/format-
|
|
41
|
-
"@dogsbay/format-
|
|
42
|
-
"@dogsbay/format-
|
|
43
|
-
"@dogsbay/format-openapi": "0.2.0-beta.
|
|
44
|
-
"@dogsbay/adoc2md-modular": "0.2.0-beta.
|
|
45
|
-
"@dogsbay/format-asciidoc": "0.2.0-beta.
|
|
46
|
-
"@dogsbay/minja": "0.2.0-beta.
|
|
47
|
-
"@dogsbay/types": "0.2.0-beta.
|
|
36
|
+
"@dogsbay/format-mkdocs": "0.2.0-beta.57",
|
|
37
|
+
"@dogsbay/format-astro": "0.2.0-beta.57",
|
|
38
|
+
"@dogsbay/autodoc-python": "0.2.0-beta.57",
|
|
39
|
+
"@dogsbay/format-obsidian": "0.2.0-beta.57",
|
|
40
|
+
"@dogsbay/format-mdx": "0.2.0-beta.57",
|
|
41
|
+
"@dogsbay/format-starlight": "0.2.0-beta.57",
|
|
42
|
+
"@dogsbay/format-dogsbay-md": "0.2.0-beta.57",
|
|
43
|
+
"@dogsbay/format-openapi": "0.2.0-beta.57",
|
|
44
|
+
"@dogsbay/adoc2md-modular": "0.2.0-beta.57",
|
|
45
|
+
"@dogsbay/format-asciidoc": "0.2.0-beta.57",
|
|
46
|
+
"@dogsbay/minja": "0.2.0-beta.57",
|
|
47
|
+
"@dogsbay/types": "0.2.0-beta.57"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@types/markdown-it": "^14.1.0",
|