@dogsbay/commands 0.2.0-beta.101
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/README.md +137 -0
- package/dist/commands/content.d.ts +78 -0
- package/dist/commands/content.d.ts.map +1 -0
- package/dist/commands/content.js +634 -0
- package/dist/commands/content.js.map +1 -0
- package/dist/commands/examples.d.ts +49 -0
- package/dist/commands/examples.d.ts.map +1 -0
- package/dist/commands/examples.js +173 -0
- package/dist/commands/examples.js.map +1 -0
- package/dist/commands/keys.d.ts +14 -0
- package/dist/commands/keys.d.ts.map +1 -0
- package/dist/commands/keys.js +87 -0
- package/dist/commands/keys.js.map +1 -0
- package/dist/commands/link-retarget.d.ts +18 -0
- package/dist/commands/link-retarget.d.ts.map +1 -0
- package/dist/commands/link-retarget.js +104 -0
- package/dist/commands/link-retarget.js.map +1 -0
- package/dist/commands/refactor-files.d.ts +27 -0
- package/dist/commands/refactor-files.d.ts.map +1 -0
- package/dist/commands/refactor-files.js +264 -0
- package/dist/commands/refactor-files.js.map +1 -0
- package/dist/commands/refactor-keys.d.ts +21 -0
- package/dist/commands/refactor-keys.d.ts.map +1 -0
- package/dist/commands/refactor-keys.js +224 -0
- package/dist/commands/refactor-keys.js.map +1 -0
- package/dist/commands/refactor-structure.d.ts +19 -0
- package/dist/commands/refactor-structure.d.ts.map +1 -0
- package/dist/commands/refactor-structure.js +314 -0
- package/dist/commands/refactor-structure.js.map +1 -0
- package/dist/commands/reindex.d.ts +10 -0
- package/dist/commands/reindex.d.ts.map +1 -0
- package/dist/commands/reindex.js +23 -0
- package/dist/commands/reindex.js.map +1 -0
- package/dist/commands/topicmap-edit.d.ts +65 -0
- package/dist/commands/topicmap-edit.d.ts.map +1 -0
- package/dist/commands/topicmap-edit.js +194 -0
- package/dist/commands/topicmap-edit.js.map +1 -0
- package/dist/commands/topicmap.d.ts +13 -0
- package/dist/commands/topicmap.d.ts.map +1 -0
- package/dist/commands/topicmap.js +69 -0
- package/dist/commands/topicmap.js.map +1 -0
- package/dist/commands/validate.d.ts +13 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +753 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/where-used.d.ts +16 -0
- package/dist/commands/where-used.d.ts.map +1 -0
- package/dist/commands/where-used.js +83 -0
- package/dist/commands/where-used.js.map +1 -0
- package/dist/edits.d.ts +54 -0
- package/dist/edits.d.ts.map +1 -0
- package/dist/edits.js +158 -0
- package/dist/edits.js.map +1 -0
- package/dist/engine.d.ts +103 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +115 -0
- package/dist/engine.js.map +1 -0
- package/dist/flags.d.ts +31 -0
- package/dist/flags.d.ts.map +1 -0
- package/dist/flags.js +73 -0
- package/dist/flags.js.map +1 -0
- package/dist/frontmatter-schema.d.ts +97 -0
- package/dist/frontmatter-schema.d.ts.map +1 -0
- package/dist/frontmatter-schema.js +240 -0
- package/dist/frontmatter-schema.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/indexes.d.ts +175 -0
- package/dist/indexes.d.ts.map +1 -0
- package/dist/indexes.js +536 -0
- package/dist/indexes.js.map +1 -0
- package/dist/json-schema.d.ts +10 -0
- package/dist/json-schema.d.ts.map +1 -0
- package/dist/json-schema.js +50 -0
- package/dist/json-schema.js.map +1 -0
- package/dist/storage.d.ts +68 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +193 -0
- package/dist/storage.js.map +1 -0
- package/dist/workspace.d.ts +30 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +63 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +47 -0
package/dist/indexes.js
ADDED
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace indexes — first-class artifacts every command reads.
|
|
3
|
+
*
|
|
4
|
+
* One pass over the workspace builds: a per-document table (frontmatter,
|
|
5
|
+
* headings, anchors, links, includes, key uses), the topic-map table
|
|
6
|
+
* (parsed maps + their entry refs), the key-definition table (from
|
|
7
|
+
* `*.keys.yaml`), and the inverted inbound-reference graph. Refactorings
|
|
8
|
+
* and queries become index lookups; `reindex` rebuilds.
|
|
9
|
+
*
|
|
10
|
+
* Everything here is pure over `Storage` — no node:fs, browser-safe.
|
|
11
|
+
*/
|
|
12
|
+
import { dogsbayMdToTree, extractHeadings, isMinjaProcessedFence, transformCodeRegions } from "@dogsbay/format-dogsbay-md";
|
|
13
|
+
import { includeDirectiveRe } from "@dogsbay/minja";
|
|
14
|
+
import { parseTopicMap, isTopicMapPath, isExternalHref, normalizePath, dirname, joinPath, } from "@dogsbay/format-topicmap";
|
|
15
|
+
import { load as loadYaml } from "js-yaml";
|
|
16
|
+
import { contentHash } from "./commands/content.js";
|
|
17
|
+
const isKeysFilePath = (path) => path.endsWith(".keys.yaml") || path.endsWith(".keys.yml") || /(^|\/)keys\.ya?ml$/.test(path);
|
|
18
|
+
const isDocPath = (path) => path.endsWith(".md");
|
|
19
|
+
/**
|
|
20
|
+
* Blank out code-region CONTENT so the raw-source include scan never
|
|
21
|
+
* counts template EXAMPLES as real includes. The fence/span grammar is
|
|
22
|
+
* @dogsbay/format-dogsbay-md's transformCodeRegions — the same walker
|
|
23
|
+
* the build preprocessor uses, so "what counts as code" cannot drift
|
|
24
|
+
* between validate and the build. (The include grammar itself comes
|
|
25
|
+
* from @dogsbay/minja for the same reason.)
|
|
26
|
+
*
|
|
27
|
+
* A `{minja}`-marked fence is NOT blanked, for the same no-drift reason:
|
|
28
|
+
* the build preprocessor PROCESSES marked fences (its masker skips them),
|
|
29
|
+
* so a directive inside one is real and must be visible to validation.
|
|
30
|
+
*/
|
|
31
|
+
export const blankCodeRegions = (source) => transformCodeRegions(source, (code, ctx) => isMinjaProcessedFence(ctx.fenceInfo) ? code : " ".repeat(code.length));
|
|
32
|
+
const inlineText = (nodes) => {
|
|
33
|
+
if (!nodes)
|
|
34
|
+
return "";
|
|
35
|
+
return nodes
|
|
36
|
+
.map((node) => {
|
|
37
|
+
switch (node.type) {
|
|
38
|
+
case "text":
|
|
39
|
+
case "code":
|
|
40
|
+
return node.text;
|
|
41
|
+
case "link":
|
|
42
|
+
case "highlight":
|
|
43
|
+
return inlineText(node.children);
|
|
44
|
+
default:
|
|
45
|
+
return "";
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
.join("");
|
|
49
|
+
};
|
|
50
|
+
const HTML_ANCHOR_RE = /<a\s[^>]*id\s*=\s*["']([^"']+)["']/gi;
|
|
51
|
+
const recordHref = (state, href, kind) => {
|
|
52
|
+
if (href.startsWith("key:")) {
|
|
53
|
+
const name = href.slice("key:".length).split("#")[0];
|
|
54
|
+
if (name)
|
|
55
|
+
state.entry.keyUses.push(name);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const link = { href, kind };
|
|
59
|
+
const hashIdx = href.indexOf("#");
|
|
60
|
+
let pathPart = hashIdx >= 0 ? href.slice(0, hashIdx) : href;
|
|
61
|
+
const fragment = hashIdx >= 0 ? href.slice(hashIdx + 1) : undefined;
|
|
62
|
+
if (fragment)
|
|
63
|
+
link.fragment = fragment;
|
|
64
|
+
// a query string is not part of the file (`page.md?h=term` — mkdocs search highlight)
|
|
65
|
+
const qIdx = pathPart.indexOf("?");
|
|
66
|
+
if (qIdx >= 0)
|
|
67
|
+
pathPart = pathPart.slice(0, qIdx);
|
|
68
|
+
// percent-encoded paths name the DECODED file (`ASO%20Helm%20Chart.md`)
|
|
69
|
+
if (/%[0-9A-Fa-f]{2}/.test(pathPart)) {
|
|
70
|
+
try {
|
|
71
|
+
pathPart = decodeURIComponent(pathPart);
|
|
72
|
+
}
|
|
73
|
+
catch { /* keep as written */ }
|
|
74
|
+
}
|
|
75
|
+
if (isExternalHref(pathPart)) {
|
|
76
|
+
// External: not ours to check
|
|
77
|
+
}
|
|
78
|
+
else if (pathPart.startsWith("/")) {
|
|
79
|
+
// Site-absolute: validate resolves it against the content roots (several layouts)
|
|
80
|
+
link.siteAbsolute = true;
|
|
81
|
+
link.sitePath = pathPart.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
82
|
+
}
|
|
83
|
+
else if (pathPart === "") {
|
|
84
|
+
// "#fragment" — same-file anchor
|
|
85
|
+
link.target = state.entry.path;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
link.target = joinPath(state.docDir, pathPart);
|
|
89
|
+
// a target that climbs out of the workspace root is a DIFFERENT finding
|
|
90
|
+
// from a missing file ("../../docs-dev/x.md" exists one level up): keep the
|
|
91
|
+
// fact so validate can say so instead of claiming it does not exist
|
|
92
|
+
if (link.target.startsWith("../"))
|
|
93
|
+
link.escapes = true;
|
|
94
|
+
}
|
|
95
|
+
state.entry.links.push(link);
|
|
96
|
+
};
|
|
97
|
+
const scanHtmlAnchors = (state, html) => {
|
|
98
|
+
for (const match of html.matchAll(HTML_ANCHOR_RE)) {
|
|
99
|
+
state.entry.anchors.push(match[1]);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
const scanInline = (state, nodes) => {
|
|
103
|
+
if (!nodes)
|
|
104
|
+
return;
|
|
105
|
+
for (const node of nodes) {
|
|
106
|
+
switch (node.type) {
|
|
107
|
+
case "link":
|
|
108
|
+
recordHref(state, node.href, "link");
|
|
109
|
+
scanInline(state, node.children);
|
|
110
|
+
break;
|
|
111
|
+
case "image":
|
|
112
|
+
recordHref(state, node.src, "image");
|
|
113
|
+
break;
|
|
114
|
+
case "html-inline":
|
|
115
|
+
scanHtmlAnchors(state, node.html);
|
|
116
|
+
break;
|
|
117
|
+
case "highlight":
|
|
118
|
+
scanInline(state, node.children);
|
|
119
|
+
break;
|
|
120
|
+
default:
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
/** Explicit anchor on a node — the parser stores `{#id}` as props.slug on headings, props.id elsewhere. */
|
|
126
|
+
const explicitAnchor = (node) => {
|
|
127
|
+
if (typeof node.props?.id === "string")
|
|
128
|
+
return node.props.id;
|
|
129
|
+
if (typeof node.props?.slug === "string")
|
|
130
|
+
return node.props.slug;
|
|
131
|
+
return undefined;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Walk the tree collecting headings, EXPLICIT anchors, links, and key
|
|
135
|
+
* uses. Auto-generated heading anchors are NOT derived here: they come
|
|
136
|
+
* from format-dogsbay-md's extractHeadings afterwards (the renderer's
|
|
137
|
+
* own assignment — top-level headings only, text-node text, ASCII
|
|
138
|
+
* slugs, -1/-2 dedupe), so validate agrees with what the site emits.
|
|
139
|
+
* Must run BEFORE extractHeadings, which backfills props.slug and would
|
|
140
|
+
* make auto slugs indistinguishable from authored `{#id}` anchors.
|
|
141
|
+
*/
|
|
142
|
+
const scanTree = (state, nodes) => {
|
|
143
|
+
for (const node of nodes) {
|
|
144
|
+
if (node.type === "heading") {
|
|
145
|
+
const text = inlineText(node.inline);
|
|
146
|
+
const id = explicitAnchor(node);
|
|
147
|
+
const level = Number(node.props?.level ?? 0) || 0;
|
|
148
|
+
state.entry.headings.push({ level, text, ...(id ? { id } : {}) });
|
|
149
|
+
}
|
|
150
|
+
if (node.type === "image") {
|
|
151
|
+
const src = node.props?.src;
|
|
152
|
+
if (typeof src === "string" && src.length > 0)
|
|
153
|
+
recordHref(state, src, "image");
|
|
154
|
+
}
|
|
155
|
+
if ((node.type === "html" || node.type === "html-container") && node.html) {
|
|
156
|
+
scanHtmlAnchors(state, node.html);
|
|
157
|
+
}
|
|
158
|
+
const anchor = explicitAnchor(node);
|
|
159
|
+
if (anchor)
|
|
160
|
+
state.entry.anchors.push(anchor);
|
|
161
|
+
scanInline(state, node.inline);
|
|
162
|
+
if (node.children)
|
|
163
|
+
scanTree(state, node.children);
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* Everything `validate` needs to know about the frontmatter BLOCK (as opposed
|
|
168
|
+
* to its parsed value), in one scan: whether it opens, whether it closes,
|
|
169
|
+
* where each top-level key is, and whether it holds anything at all.
|
|
170
|
+
*/
|
|
171
|
+
const scanFrontmatter = (source) => {
|
|
172
|
+
const keyLines = new Map();
|
|
173
|
+
const lines = source.split("\n");
|
|
174
|
+
if (lines[0]?.trim() !== "---")
|
|
175
|
+
return { frontmatterBlock: "none", frontmatterKeyLines: keyLines, frontmatterEmpty: true };
|
|
176
|
+
let closed = false;
|
|
177
|
+
let empty = true;
|
|
178
|
+
for (let i = 1; i < lines.length; i++) {
|
|
179
|
+
const line = lines[i];
|
|
180
|
+
// the closer is at COLUMN 0 (what splitFrontmatter matches): an indented `---` inside a
|
|
181
|
+
// block scalar is content, not the end of the block
|
|
182
|
+
if (/^(---|\.\.\.)[ \t]*\r?$/.test(line)) {
|
|
183
|
+
closed = true;
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
const trimmed = line.trim();
|
|
187
|
+
if (trimmed !== "" && !trimmed.startsWith("#"))
|
|
188
|
+
empty = false;
|
|
189
|
+
const m = /^(?:"([^"]+)"|'([^']+)'|([A-Za-z_][\w.-]*))\s*:/.exec(line); // top level: no leading space
|
|
190
|
+
const key = m?.[1] ?? m?.[2] ?? m?.[3];
|
|
191
|
+
if (key && !keyLines.has(key))
|
|
192
|
+
keyLines.set(key, i + 1);
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
frontmatterBlock: closed ? "block" : "unterminated",
|
|
196
|
+
frontmatterKeyLines: keyLines,
|
|
197
|
+
frontmatterEmpty: closed ? empty : true,
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
const indexDoc = (path, source) => {
|
|
201
|
+
const entry = {
|
|
202
|
+
path,
|
|
203
|
+
frontmatter: {},
|
|
204
|
+
headings: [],
|
|
205
|
+
anchors: [],
|
|
206
|
+
links: [],
|
|
207
|
+
includes: [],
|
|
208
|
+
keyUses: [],
|
|
209
|
+
hash: contentHash(source),
|
|
210
|
+
...scanFrontmatter(source),
|
|
211
|
+
};
|
|
212
|
+
const state = { entry, docDir: dirname(path) };
|
|
213
|
+
// Includes come from the RAW source (code regions masked): the
|
|
214
|
+
// markdown parser's attrs plugin mangles `{% include %}` lines into
|
|
215
|
+
// element attributes, so the tree never sees them. The raw scan is
|
|
216
|
+
// exactly what the build preprocessor will execute anyway.
|
|
217
|
+
const masked = blankCodeRegions(source);
|
|
218
|
+
// line starts once; lineAt is a binary search (O(links × log lines), not O(links × bytes))
|
|
219
|
+
const lineStarts = [0];
|
|
220
|
+
for (let i = 0; i < masked.length; i++)
|
|
221
|
+
if (masked.charCodeAt(i) === 10)
|
|
222
|
+
lineStarts.push(i + 1);
|
|
223
|
+
const lineAt = (offset) => {
|
|
224
|
+
let lo = 0;
|
|
225
|
+
let hi = lineStarts.length - 1;
|
|
226
|
+
while (lo < hi) {
|
|
227
|
+
const mid = (lo + hi + 1) >> 1;
|
|
228
|
+
if (lineStarts[mid] <= offset)
|
|
229
|
+
lo = mid;
|
|
230
|
+
else
|
|
231
|
+
hi = mid - 1;
|
|
232
|
+
}
|
|
233
|
+
return lo + 1;
|
|
234
|
+
};
|
|
235
|
+
/**
|
|
236
|
+
* Link DESTINATIONS in the masked source, in document order, by exact token:
|
|
237
|
+
* `](dest)` / `](<dest>)` inline links and images, `[label]: dest` reference
|
|
238
|
+
* definitions, `href="dest"` / `src="dest"` in raw HTML. A link is matched to
|
|
239
|
+
* the next unconsumed occurrence of its href (or its percent-decoded /
|
|
240
|
+
* encoded twin — markdown-it normalizes `café.md` to `caf%C3%A9.md`), never
|
|
241
|
+
* to a substring of a longer path or a prose mention.
|
|
242
|
+
*/
|
|
243
|
+
const destOffsets = new Map();
|
|
244
|
+
const pushDest = (raw, offset) => {
|
|
245
|
+
const dest = raw.trim();
|
|
246
|
+
if (!dest)
|
|
247
|
+
return;
|
|
248
|
+
const variants = new Set([dest]);
|
|
249
|
+
try {
|
|
250
|
+
variants.add(decodeURIComponent(dest));
|
|
251
|
+
}
|
|
252
|
+
catch { /* not encoded */ }
|
|
253
|
+
try {
|
|
254
|
+
variants.add(encodeURI(dest));
|
|
255
|
+
}
|
|
256
|
+
catch { /* cannot encode */ }
|
|
257
|
+
for (const v of variants) {
|
|
258
|
+
const list = destOffsets.get(v) ?? [];
|
|
259
|
+
list.push(offset);
|
|
260
|
+
destOffsets.set(v, list);
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
for (const m of masked.matchAll(/\]\(\s*(?:<([^>]*)>|([^)\s]+))/g))
|
|
264
|
+
pushDest(m[1] ?? m[2] ?? "", m.index ?? 0);
|
|
265
|
+
for (const m of masked.matchAll(/^[ \t]{0,3}\[[^\]]+\]:[ \t]+(?:<([^>]*)>|(\S+))/gm))
|
|
266
|
+
pushDest(m[1] ?? m[2] ?? "", m.index ?? 0);
|
|
267
|
+
for (const m of masked.matchAll(/\b(?:href|src)\s*=\s*["']([^"']+)["']/g))
|
|
268
|
+
pushDest(m[1] ?? "", m.index ?? 0);
|
|
269
|
+
// per-href lists were filled regex-by-regex (inline, then reference definitions, then HTML):
|
|
270
|
+
// document order across kinds needs a sort, or a `[ref]: x` + `[q](x)` pair swaps lines
|
|
271
|
+
for (const list of destOffsets.values())
|
|
272
|
+
list.sort((a, b) => a - b);
|
|
273
|
+
const used = new Map();
|
|
274
|
+
const findHref = (href) => {
|
|
275
|
+
const list = destOffsets.get(href);
|
|
276
|
+
if (!list)
|
|
277
|
+
return -1;
|
|
278
|
+
const i = used.get(href) ?? 0;
|
|
279
|
+
if (i >= list.length)
|
|
280
|
+
return list[list.length - 1]; // a reference-style link used twice: the definition line
|
|
281
|
+
used.set(href, i + 1);
|
|
282
|
+
return list[i];
|
|
283
|
+
};
|
|
284
|
+
for (const match of masked.matchAll(includeDirectiveRe())) {
|
|
285
|
+
entry.includes.push({ raw: match[1], target: joinPath(state.docDir, match[1]), line: lineAt(match.index ?? 0) });
|
|
286
|
+
}
|
|
287
|
+
try {
|
|
288
|
+
const { tree, frontmatter } = dogsbayMdToTree(source);
|
|
289
|
+
entry.frontmatter = frontmatter;
|
|
290
|
+
if (typeof frontmatter.title === "string")
|
|
291
|
+
entry.title = frontmatter.title;
|
|
292
|
+
scanTree(state, tree);
|
|
293
|
+
// Lines for links: each href's successive occurrences in the code-masked source, in
|
|
294
|
+
// document order (the tree carries no positions) — a repeated href maps to the next
|
|
295
|
+
// occurrence, so two identical links land on their own lines
|
|
296
|
+
for (const link of entry.links) {
|
|
297
|
+
const at = findHref(link.href);
|
|
298
|
+
if (at >= 0)
|
|
299
|
+
link.line = lineAt(at);
|
|
300
|
+
}
|
|
301
|
+
// Renderer-parity auto anchors: exactly the ids the site build
|
|
302
|
+
// assigns (and only those) — scanTree above already captured
|
|
303
|
+
// authored {#id} anchors, including on nested headings
|
|
304
|
+
for (const heading of extractHeadings(tree)) {
|
|
305
|
+
if (heading.slug)
|
|
306
|
+
entry.anchors.push(heading.slug);
|
|
307
|
+
}
|
|
308
|
+
// extractHeadings backfilled props.slug on the heading NODES; read them back in the same tree order
|
|
309
|
+
// scanTree used, so each scanned heading learns the anchor the site renders for it
|
|
310
|
+
const slugs = [];
|
|
311
|
+
const walkSlugs = (nodes) => {
|
|
312
|
+
for (const node of nodes) {
|
|
313
|
+
if (node.type === "heading")
|
|
314
|
+
slugs.push(typeof node.props?.slug === "string" && node.props.slug ? node.props.slug : undefined);
|
|
315
|
+
if (node.children)
|
|
316
|
+
walkSlugs(node.children);
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
walkSlugs(tree);
|
|
320
|
+
entry.headings.forEach((h, i) => { const slug = slugs[i]; if (slug && !h.id)
|
|
321
|
+
h.slug = slug; });
|
|
322
|
+
entry.anchors = [...new Set(entry.anchors)];
|
|
323
|
+
}
|
|
324
|
+
catch (error) {
|
|
325
|
+
entry.parseError = error instanceof Error ? error.message : String(error);
|
|
326
|
+
}
|
|
327
|
+
return entry;
|
|
328
|
+
};
|
|
329
|
+
const collectMapRefs = (entries, mapPath, out) => {
|
|
330
|
+
for (const entry of entries) {
|
|
331
|
+
if (entry.href) {
|
|
332
|
+
const external = isExternalHref(entry.href);
|
|
333
|
+
const rootRelative = !external && entry.href.startsWith("/");
|
|
334
|
+
out.push({
|
|
335
|
+
href: entry.href,
|
|
336
|
+
...(external || rootRelative ? {} : { target: joinPath(dirname(mapPath), entry.href) }),
|
|
337
|
+
...(rootRelative ? { rootRelative: true } : {}),
|
|
338
|
+
isMap: entry.format === "topicmap",
|
|
339
|
+
...(entry.navtitle ? { navtitle: entry.navtitle } : {}),
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
if (entry.topics)
|
|
343
|
+
collectMapRefs(entry.topics, mapPath, out);
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
const indexMap = (path, source) => {
|
|
347
|
+
const { map, errors } = parseTopicMap(source, path);
|
|
348
|
+
const refs = [];
|
|
349
|
+
if (map)
|
|
350
|
+
collectMapRefs(map.topics, path, refs);
|
|
351
|
+
return {
|
|
352
|
+
path,
|
|
353
|
+
...(map?.title ? { title: map.title } : {}),
|
|
354
|
+
refs,
|
|
355
|
+
errors,
|
|
356
|
+
};
|
|
357
|
+
};
|
|
358
|
+
const indexKeysFile = (path, source, keys, errors) => {
|
|
359
|
+
let raw;
|
|
360
|
+
try {
|
|
361
|
+
raw = loadYaml(source);
|
|
362
|
+
}
|
|
363
|
+
catch (error) {
|
|
364
|
+
errors.push({ file: path, message: error instanceof Error ? error.message : String(error) });
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
const table = raw?.keys;
|
|
368
|
+
if (table === undefined || table === null) {
|
|
369
|
+
errors.push({ file: path, message: "missing top-level `keys:` table" });
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
if (typeof table !== "object" || Array.isArray(table)) {
|
|
373
|
+
errors.push({ file: path, message: "`keys:` must be a mapping of key name → definition" });
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
for (const [name, def] of Object.entries(table)) {
|
|
377
|
+
const defs = keys.get(name) ?? [];
|
|
378
|
+
defs.push({
|
|
379
|
+
name,
|
|
380
|
+
file: path,
|
|
381
|
+
def: def !== null && typeof def === "object" && !Array.isArray(def)
|
|
382
|
+
? def
|
|
383
|
+
: { value: def },
|
|
384
|
+
});
|
|
385
|
+
keys.set(name, defs);
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
/**
|
|
389
|
+
* Anchors OTHER renderers would give a heading text — GitHub-slugger
|
|
390
|
+
* (lowercase, punctuation removed except `-`/space, spaces → `-`, no
|
|
391
|
+
* collapse) and Python-Markdown/mkdocs (non-word chars removed, runs of
|
|
392
|
+
* `-`/space → one `-`). Dogsbay's own rule (the site build's) is what
|
|
393
|
+
* `anchors` holds; these let validate tell "the anchor exists under another
|
|
394
|
+
* tool's rule" (a migration-era mismatch) from "no such heading" (a dead
|
|
395
|
+
* link in any tool).
|
|
396
|
+
*/
|
|
397
|
+
/** For each alias (GitHub/mkdocs slug) the DOGSBAY anchor of the same heading — what a mismatched link should be retargeted to. */
|
|
398
|
+
export function anchorAliasTargets(headings, dogsbayAnchors) {
|
|
399
|
+
// each scanned heading carries the slug the site renders for it (`slug`, paired from extractHeadings) or
|
|
400
|
+
// an explicit id; aliases of headings without either are not offered as fixes
|
|
401
|
+
const out = new Map();
|
|
402
|
+
const seenGh = new Map();
|
|
403
|
+
const seenMk = new Map();
|
|
404
|
+
const known = new Set(dogsbayAnchors);
|
|
405
|
+
const dedupe = (seen, base) => { const n = seen.get(base) ?? 0; seen.set(base, n + 1); return n === 0 ? base : `${base}-${n}`; };
|
|
406
|
+
for (const h of headings) {
|
|
407
|
+
const text = h.text.trim();
|
|
408
|
+
const db = h.id ?? h.slug;
|
|
409
|
+
if (!db || !known.has(db))
|
|
410
|
+
continue;
|
|
411
|
+
const gh = text.toLowerCase().replace(/[^\p{L}\p{N}\s-]/gu, "").replace(/\s/g, "-");
|
|
412
|
+
const mk = text.toLowerCase().replace(/[^\w\s-]/g, "").trim().replace(/[-\s]+/g, "-");
|
|
413
|
+
if (gh) {
|
|
414
|
+
const a = dedupe(seenGh, gh);
|
|
415
|
+
if (a !== db && !out.has(a))
|
|
416
|
+
out.set(a, db);
|
|
417
|
+
}
|
|
418
|
+
if (mk) {
|
|
419
|
+
const a = dedupe(seenMk, mk);
|
|
420
|
+
if (a !== db && !out.has(a))
|
|
421
|
+
out.set(a, db);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return out;
|
|
425
|
+
}
|
|
426
|
+
export function anchorAliases(headings) {
|
|
427
|
+
const out = new Set();
|
|
428
|
+
const seenGh = new Map();
|
|
429
|
+
const seenMk = new Map();
|
|
430
|
+
const dedupe = (seen, base) => {
|
|
431
|
+
const n = seen.get(base) ?? 0;
|
|
432
|
+
seen.set(base, n + 1);
|
|
433
|
+
return n === 0 ? base : `${base}-${n}`;
|
|
434
|
+
};
|
|
435
|
+
for (const h of headings) {
|
|
436
|
+
const text = h.text.trim();
|
|
437
|
+
const gh = text.toLowerCase().replace(/[^\p{L}\p{N}\s-]/gu, "").replace(/\s/g, "-");
|
|
438
|
+
const mk = text.toLowerCase().replace(/[^\w\s-]/g, "").trim().replace(/[-\s]+/g, "-");
|
|
439
|
+
if (gh)
|
|
440
|
+
out.add(dedupe(seenGh, gh));
|
|
441
|
+
if (mk)
|
|
442
|
+
out.add(dedupe(seenMk, mk));
|
|
443
|
+
}
|
|
444
|
+
return out;
|
|
445
|
+
}
|
|
446
|
+
/** Build every index in one pass over the workspace (or patch a previous one — see BuildIndexOptions). */
|
|
447
|
+
export async function buildWorkspaceIndex(storage, options = {}) {
|
|
448
|
+
const files = (await storage.list()).map(normalizePath);
|
|
449
|
+
const current = new Set(files);
|
|
450
|
+
const docs = new Map();
|
|
451
|
+
const maps = new Map();
|
|
452
|
+
const keys = new Map();
|
|
453
|
+
const keyFileErrors = [];
|
|
454
|
+
const changed = options.previous && options.changed ? new Set(options.changed.map(normalizePath)) : null;
|
|
455
|
+
if (changed && options.previous) {
|
|
456
|
+
for (const [path, doc] of options.previous.docs)
|
|
457
|
+
if (current.has(path) && !changed.has(path))
|
|
458
|
+
docs.set(path, doc);
|
|
459
|
+
for (const [path, map] of options.previous.maps)
|
|
460
|
+
if (current.has(path) && !changed.has(path))
|
|
461
|
+
maps.set(path, map);
|
|
462
|
+
}
|
|
463
|
+
for (const path of files) {
|
|
464
|
+
const reuse = changed !== null && !changed.has(path);
|
|
465
|
+
if (isTopicMapPath(path)) {
|
|
466
|
+
if (!(reuse && maps.has(path)))
|
|
467
|
+
maps.set(path, indexMap(path, await storage.read(path)));
|
|
468
|
+
}
|
|
469
|
+
else if (isKeysFilePath(path)) {
|
|
470
|
+
indexKeysFile(path, await storage.read(path), keys, keyFileErrors);
|
|
471
|
+
}
|
|
472
|
+
else if (isDocPath(path)) {
|
|
473
|
+
if (!(reuse && docs.has(path)))
|
|
474
|
+
docs.set(path, indexDoc(path, await storage.read(path)));
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
// ---- inverted graphs --------------------------------------------------
|
|
478
|
+
const inbound = new Map();
|
|
479
|
+
const keyUses = new Map();
|
|
480
|
+
const addInbound = (target, ref) => {
|
|
481
|
+
const list = inbound.get(target) ?? [];
|
|
482
|
+
list.push(ref);
|
|
483
|
+
inbound.set(target, list);
|
|
484
|
+
};
|
|
485
|
+
let linkCount = 0;
|
|
486
|
+
let includeCount = 0;
|
|
487
|
+
for (const doc of docs.values()) {
|
|
488
|
+
for (const link of doc.links) {
|
|
489
|
+
linkCount++;
|
|
490
|
+
if (link.target && link.target !== doc.path) {
|
|
491
|
+
addInbound(link.target, {
|
|
492
|
+
from: doc.path,
|
|
493
|
+
kind: link.kind,
|
|
494
|
+
raw: link.href,
|
|
495
|
+
...(link.fragment ? { fragment: link.fragment } : {}),
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
for (const include of doc.includes) {
|
|
500
|
+
includeCount++;
|
|
501
|
+
addInbound(include.target, { from: doc.path, kind: "include", raw: include.raw });
|
|
502
|
+
}
|
|
503
|
+
for (const name of doc.keyUses) {
|
|
504
|
+
const users = keyUses.get(name) ?? [];
|
|
505
|
+
if (!users.includes(doc.path))
|
|
506
|
+
users.push(doc.path);
|
|
507
|
+
keyUses.set(name, users);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
for (const map of maps.values()) {
|
|
511
|
+
for (const ref of map.refs) {
|
|
512
|
+
if (ref.target) {
|
|
513
|
+
addInbound(ref.target, { from: map.path, kind: "topicmap", raw: ref.href });
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
return {
|
|
518
|
+
files: current,
|
|
519
|
+
docs,
|
|
520
|
+
maps,
|
|
521
|
+
keys,
|
|
522
|
+
keyFileErrors,
|
|
523
|
+
inbound,
|
|
524
|
+
keyUses,
|
|
525
|
+
stats: {
|
|
526
|
+
files: files.length,
|
|
527
|
+
docs: docs.size,
|
|
528
|
+
maps: maps.size,
|
|
529
|
+
keyFiles: new Set([...keys.values()].flat().map((d) => d.file)).size,
|
|
530
|
+
keys: keys.size,
|
|
531
|
+
links: linkCount,
|
|
532
|
+
includes: includeCount,
|
|
533
|
+
},
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
//# sourceMappingURL=indexes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexes.js","sourceRoot":"","sources":["../src/indexes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type CommandDef } from "./engine.js";
|
|
2
|
+
export interface CommandJsonSchema {
|
|
3
|
+
type: "object";
|
|
4
|
+
properties: Record<string, unknown>;
|
|
5
|
+
required?: string[];
|
|
6
|
+
additionalProperties: false;
|
|
7
|
+
}
|
|
8
|
+
/** The JSON Schema for a command's input object. */
|
|
9
|
+
export declare const commandInputJsonSchema: (def: CommandDef) => CommandJsonSchema;
|
|
10
|
+
//# sourceMappingURL=json-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema.d.ts","sourceRoot":"","sources":["../src/json-schema.ts"],"names":[],"mappings":"AAQA,OAAO,EAA+B,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAE3E,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,oBAAoB,EAAE,KAAK,CAAC;CAC7B;AA0BD,oDAAoD;AACpD,eAAO,MAAM,sBAAsB,GAAI,KAAK,UAAU,KAAG,iBAaxD,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command schema → JSON Schema derivation, for the machine surfaces:
|
|
3
|
+
* JSON-RPC `commands/list` and MCP tool `inputSchema`. Same constrained
|
|
4
|
+
* type set as the CLI flag generator (flags.ts) — the conformance test
|
|
5
|
+
* runs BOTH over every registered command, so a command that ships is
|
|
6
|
+
* expressible on every surface by construction.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import { shapeOf, unwrap, isRequired } from "./engine.js";
|
|
10
|
+
const fieldJsonSchema = (name, schema) => {
|
|
11
|
+
const base = unwrap(schema);
|
|
12
|
+
const description = schema.description ?? base.description;
|
|
13
|
+
const withDescription = (json) => description ? { ...json, description } : json;
|
|
14
|
+
if (base instanceof z.ZodBoolean)
|
|
15
|
+
return withDescription({ type: "boolean" });
|
|
16
|
+
if (base instanceof z.ZodString)
|
|
17
|
+
return withDescription({ type: "string" });
|
|
18
|
+
if (base instanceof z.ZodNumber)
|
|
19
|
+
return withDescription({ type: "number" });
|
|
20
|
+
if (base instanceof z.ZodEnum) {
|
|
21
|
+
return withDescription({
|
|
22
|
+
type: "string",
|
|
23
|
+
enum: [...base.options],
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (base instanceof z.ZodArray && unwrap(base.element) instanceof z.ZodString) {
|
|
27
|
+
return withDescription({ type: "array", items: { type: "string" } });
|
|
28
|
+
}
|
|
29
|
+
if (base instanceof z.ZodRecord) {
|
|
30
|
+
return withDescription({ type: "object", additionalProperties: { type: "string" } });
|
|
31
|
+
}
|
|
32
|
+
throw new Error(`Command schema field "${name}" has no JSON Schema mapping`);
|
|
33
|
+
};
|
|
34
|
+
/** The JSON Schema for a command's input object. */
|
|
35
|
+
export const commandInputJsonSchema = (def) => {
|
|
36
|
+
const properties = {};
|
|
37
|
+
const required = [];
|
|
38
|
+
for (const [name, field] of Object.entries(shapeOf(def.input))) {
|
|
39
|
+
properties[name] = fieldJsonSchema(name, field);
|
|
40
|
+
if (isRequired(field))
|
|
41
|
+
required.push(name);
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
type: "object",
|
|
45
|
+
properties,
|
|
46
|
+
...(required.length > 0 ? { required } : {}),
|
|
47
|
+
additionalProperties: false,
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=json-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema.js","sourceRoot":"","sources":["../src/json-schema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAmB,MAAM,aAAa,CAAC;AAS3E,MAAM,eAAe,GAAG,CAAC,IAAY,EAAE,MAAoB,EAA2B,EAAE;IACtF,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5B,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC;IAC3D,MAAM,eAAe,GAAG,CAAC,IAA6B,EAA2B,EAAE,CACjF,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAEhD,IAAI,IAAI,YAAY,CAAC,CAAC,UAAU;QAAE,OAAO,eAAe,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IAC9E,IAAI,IAAI,YAAY,CAAC,CAAC,SAAS;QAAE,OAAO,eAAe,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5E,IAAI,IAAI,YAAY,CAAC,CAAC,SAAS;QAAE,OAAO,eAAe,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5E,IAAI,IAAI,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;QAC9B,OAAO,eAAe,CAAC;YACrB,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,GAAI,IAAkB,CAAC,OAAO,CAAa;SACnD,CAAC,CAAC;IACL,CAAC;IACD,IAAI,IAAI,YAAY,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAE,IAAiC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,SAAS,EAAE,CAAC;QAC5G,OAAO,eAAe,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,IAAI,YAAY,CAAC,CAAC,SAAS,EAAE,CAAC;QAChC,OAAO,eAAe,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,8BAA8B,CAAC,CAAC;AAC/E,CAAC,CAAC;AAEF,oDAAoD;AACpD,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAe,EAAqB,EAAE;IAC3E,MAAM,UAAU,GAA4B,EAAE,CAAC;IAC/C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QAC/D,UAAU,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAChD,IAAI,UAAU,CAAC,KAAK,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,UAAU;QACV,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,oBAAoB,EAAE,KAAK;KAC5B,CAAC;AACJ,CAAC,CAAC"}
|