dogsbay 0.2.0-beta.124 → 0.2.0-beta.126

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.
@@ -0,0 +1,8 @@
1
+ import type { Issue, Rule } from "@dogsbay/site-check";
2
+ export declare const markdownSyntax: Rule;
3
+ /** The issues `markdown/syntax` reports on the next audit. */
4
+ export declare function setMarkdownSyntaxIssues(issues: Issue[]): void;
5
+ /** Whether a content source is Dogsbay Markdown: named so, or detected as it. */
6
+ export declare function isDogsbayMdSource(dir: string, from: string | undefined): boolean;
7
+ /** `markdown/syntax` findings for these content folders, paths relative to the site. */
8
+ export declare function markdownSyntaxIssues(dirs: string[], siteRoot: string): Issue[];
@@ -0,0 +1,89 @@
1
+ /**
2
+ * `markdown/syntax` — what the Dogsbay Markdown parser recovers from without a
3
+ * word: an unclosed `:::` block (it takes in the rest of the page), a `:::`
4
+ * that closes nothing, an unknown `:::name` or inline `:name[]`, an attribute
5
+ * block it cannot read. Each reaches the page as literal text or a plain box,
6
+ * and a build passes. The findings are `dogsbayMdToTree`'s diagnostics, with
7
+ * the source file and line.
8
+ *
9
+ * Reads the source files of every content source in Dogsbay Markdown (`from:
10
+ * dogsbay-md`, or detected as it), as written: before the template engine
11
+ * runs, so `{% … %}` lines are protected the way the editor parses them.
12
+ * Other formats are left alone: their files are not Dogsbay Markdown.
13
+ * Warnings, so a site with findings still exits 0 unless `--strict`.
14
+ */
15
+ import { readdirSync, readFileSync, statSync } from "node:fs";
16
+ import { join, relative } from "node:path";
17
+ import { dogsbayMdToTree } from "@dogsbay/format-dogsbay-md";
18
+ import { detectFormat } from "../../formats.js";
19
+ let pending = [];
20
+ export const markdownSyntax = {
21
+ id: "markdown/syntax",
22
+ category: "markdown",
23
+ stage: "source-corpus",
24
+ severity: "warning",
25
+ description: "Dogsbay Markdown the parser recovers from silently: an unclosed or stray `:::`, an unknown `:::name` or `:name[]`, an unreadable `{…}` attribute block.",
26
+ // Filled by `site check` once sources are resolved (I/O happens there, not here)
27
+ run: () => pending,
28
+ };
29
+ /** The issues `markdown/syntax` reports on the next audit. */
30
+ export function setMarkdownSyntaxIssues(issues) {
31
+ pending = issues;
32
+ }
33
+ /** Whether a content source is Dogsbay Markdown: named so, or detected as it. */
34
+ export function isDogsbayMdSource(dir, from) {
35
+ if (from && from !== "auto")
36
+ return from === "dogsbay-md";
37
+ return detectFormat(dir)?.name === "dogsbay-md";
38
+ }
39
+ /**
40
+ * The `.md` pages under a folder, as the dogsbay-md importer walks them
41
+ * (`walkMdFiles`): `_`-prefixed files and folders are include fragments, not
42
+ * pages, and a fragment may open a block its includer closes, so they are not
43
+ * checked on their own. Symlinked files count. Dot folders and node_modules
44
+ * are skipped.
45
+ */
46
+ function markdownFiles(dir) {
47
+ const out = [];
48
+ const walk = (d) => {
49
+ let entries;
50
+ try {
51
+ entries = readdirSync(d, { withFileTypes: true });
52
+ }
53
+ catch {
54
+ return;
55
+ }
56
+ for (const e of entries.sort((a, b) => a.name.localeCompare(b.name))) {
57
+ if (e.name.startsWith(".") || e.name.startsWith("_") || e.name === "node_modules")
58
+ continue;
59
+ const p = join(d, e.name);
60
+ if (e.isDirectory())
61
+ walk(p);
62
+ else if (e.name.endsWith(".md") && (e.isFile() || (e.isSymbolicLink() && isFileTarget(p))))
63
+ out.push(p);
64
+ }
65
+ };
66
+ walk(dir);
67
+ return out;
68
+ }
69
+ const isFileTarget = (path) => {
70
+ try {
71
+ return statSync(path).isFile();
72
+ }
73
+ catch {
74
+ return false;
75
+ }
76
+ };
77
+ /** `markdown/syntax` findings for these content folders, paths relative to the site. */
78
+ export function markdownSyntaxIssues(dirs, siteRoot) {
79
+ const issues = [];
80
+ for (const dir of dirs) {
81
+ for (const file of markdownFiles(dir)) {
82
+ const { diagnostics = [] } = dogsbayMdToTree(readFileSync(file, "utf-8"), { diagnostics: true, directives: "preserve" });
83
+ for (const d of diagnostics) {
84
+ issues.push({ ruleId: markdownSyntax.id, severity: "warning", file: relative(siteRoot, file), line: d.line, message: d.message, context: d.code });
85
+ }
86
+ }
87
+ }
88
+ return issues;
89
+ }
@@ -6,6 +6,7 @@
6
6
  import { registerRule } from "@dogsbay/site-check";
7
7
  import { navTargetExists } from "./nav-target-exists.js";
8
8
  import { topicmapValid } from "./topicmap-valid.js";
9
+ import { markdownSyntax } from "../markdown-syntax.js";
9
10
  let registered = false;
10
11
  /** Idempotent, like the shared register* functions. */
11
12
  export function registerCliStructureRules() {
@@ -14,4 +15,5 @@ export function registerCliStructureRules() {
14
15
  registered = true;
15
16
  registerRule(navTargetExists);
16
17
  registerRule(topicmapValid);
18
+ registerRule(markdownSyntax);
17
19
  }
@@ -33,6 +33,7 @@ import { loadPlugins, collectAuditRules, runOnContentImported, runTransformNav,
33
33
  import { filterRules, formatJson, formatText, registerRule, registerFrontmatterRules, registerSeoRules, registerStructureRules, reportExitCode, runAudit, } from "@dogsbay/site-check";
34
34
  import { collectAssets, crawlDist, distFileReader } from "@dogsbay/site-check/node";
35
35
  import { registerCliStructureRules } from "../audit/rules/structure/index.js";
36
+ import { isDogsbayMdSource, markdownSyntaxIssues, setMarkdownSyntaxIssues } from "../audit/rules/markdown-syntax.js";
36
37
  import { siteReleaseComparisons } from "../release/compare.js";
37
38
  import { frontmatterPolicyFromConfig } from "@dogsbay/types";
38
39
  export async function siteCheck(cwd, options) {
@@ -259,6 +260,10 @@ export async function siteCheck(cwd, options) {
259
260
  siteRoot,
260
261
  })));
261
262
  }
263
+ // `markdown/syntax`: the parser's diagnostics over each Dogsbay Markdown source, as written
264
+ setMarkdownSyntaxIssues(wantSource && rules.some((r) => r.id === "markdown/syntax")
265
+ ? markdownSyntaxIssues(auditSources.map((a) => a.contentDir).filter((dir, i) => isDogsbayMdSource(dir, config.content.sources[i]?.from)), siteRoot)
266
+ : []);
262
267
  // Asset set for `structure/asset-refs` — walks every source's
263
268
  // content tree for files matching `copyAssets`'s extension
264
269
  // list. Keep `collectAssets` in sync with that helper or refs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dogsbay",
3
- "version": "0.2.0-beta.124",
3
+ "version": "0.2.0-beta.126",
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": {
@@ -43,36 +43,36 @@
43
43
  "typescript": "^5.9.3",
44
44
  "valibot": "1.1.0",
45
45
  "yaml": "^2.9.0",
46
- "@dogsbay/adoc2md-modular": "0.2.0-beta.124",
47
- "@dogsbay/commands": "0.2.0-beta.124",
48
- "@dogsbay/autodoc-python": "0.2.0-beta.124",
49
- "@dogsbay/format-asciidoc": "0.2.0-beta.124",
50
- "@dogsbay/format-astro": "0.2.0-beta.124",
51
- "@dogsbay/format-dita": "0.2.0-beta.124",
52
- "@dogsbay/format-docusaurus": "0.2.0-beta.124",
53
- "@dogsbay/format-dogsbay-md": "0.2.0-beta.124",
54
- "@dogsbay/format-fluidtopics-markdown": "0.2.0-beta.124",
55
- "@dogsbay/format-fluidtopics-rest": "0.2.0-beta.124",
56
- "@dogsbay/format-gatsby": "0.2.0-beta.124",
57
- "@dogsbay/format-gitbook": "0.2.0-beta.124",
58
- "@dogsbay/format-hugo": "0.2.0-beta.124",
59
- "@dogsbay/format-mdx": "0.2.0-beta.124",
60
- "@dogsbay/format-mkdocs": "0.2.0-beta.124",
61
- "@dogsbay/format-myst": "0.2.0-beta.124",
62
- "@dogsbay/format-obsidian": "0.2.0-beta.124",
63
- "@dogsbay/format-openapi": "0.2.0-beta.124",
64
- "@dogsbay/format-openknowledge": "0.2.0-beta.124",
65
- "@dogsbay/format-rst": "0.2.0-beta.124",
66
- "@dogsbay/format-starlight": "0.2.0-beta.124",
67
- "@dogsbay/format-topicmap": "0.2.0-beta.124",
68
- "@dogsbay/format-vitepress": "0.2.0-beta.124",
69
- "@dogsbay/minja": "0.2.0-beta.124",
70
- "@dogsbay/render": "0.2.0-beta.124",
71
- "@dogsbay/render-html": "0.2.0-beta.124",
72
- "@dogsbay/serialize-core": "0.2.0-beta.124",
73
- "@dogsbay/site-check": "0.2.0-beta.124",
74
- "@dogsbay/site-files": "0.2.0-beta.124",
75
- "@dogsbay/types": "0.2.0-beta.124"
46
+ "@dogsbay/adoc2md-modular": "0.2.0-beta.126",
47
+ "@dogsbay/autodoc-python": "0.2.0-beta.126",
48
+ "@dogsbay/commands": "0.2.0-beta.126",
49
+ "@dogsbay/format-asciidoc": "0.2.0-beta.126",
50
+ "@dogsbay/format-astro": "0.2.0-beta.126",
51
+ "@dogsbay/format-dita": "0.2.0-beta.126",
52
+ "@dogsbay/format-docusaurus": "0.2.0-beta.126",
53
+ "@dogsbay/format-dogsbay-md": "0.2.0-beta.126",
54
+ "@dogsbay/format-fluidtopics-markdown": "0.2.0-beta.126",
55
+ "@dogsbay/format-fluidtopics-rest": "0.2.0-beta.126",
56
+ "@dogsbay/format-gatsby": "0.2.0-beta.126",
57
+ "@dogsbay/format-gitbook": "0.2.0-beta.126",
58
+ "@dogsbay/format-hugo": "0.2.0-beta.126",
59
+ "@dogsbay/format-mdx": "0.2.0-beta.126",
60
+ "@dogsbay/format-mkdocs": "0.2.0-beta.126",
61
+ "@dogsbay/format-myst": "0.2.0-beta.126",
62
+ "@dogsbay/format-obsidian": "0.2.0-beta.126",
63
+ "@dogsbay/format-openapi": "0.2.0-beta.126",
64
+ "@dogsbay/format-rst": "0.2.0-beta.126",
65
+ "@dogsbay/format-openknowledge": "0.2.0-beta.126",
66
+ "@dogsbay/format-starlight": "0.2.0-beta.126",
67
+ "@dogsbay/format-topicmap": "0.2.0-beta.126",
68
+ "@dogsbay/format-vitepress": "0.2.0-beta.126",
69
+ "@dogsbay/minja": "0.2.0-beta.126",
70
+ "@dogsbay/render": "0.2.0-beta.126",
71
+ "@dogsbay/render-html": "0.2.0-beta.126",
72
+ "@dogsbay/serialize-core": "0.2.0-beta.126",
73
+ "@dogsbay/site-check": "0.2.0-beta.126",
74
+ "@dogsbay/site-files": "0.2.0-beta.126",
75
+ "@dogsbay/types": "0.2.0-beta.126"
76
76
  },
77
77
  "devDependencies": {
78
78
  "@mdx-js/mdx": "^3.1.1",