@forge-ts/gen 0.7.2 → 0.8.0
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/index.d.ts +264 -1
- package/dist/index.js +912 -542
- package/dist/index.js.map +1 -1
- package/package.json +10 -2
package/dist/index.js
CHANGED
|
@@ -16,33 +16,185 @@ function getAvailableTargets() {
|
|
|
16
16
|
}
|
|
17
17
|
var DEFAULT_TARGET = "mintlify";
|
|
18
18
|
|
|
19
|
-
// src/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
19
|
+
// src/markdown-utils.ts
|
|
20
|
+
import matter from "gray-matter";
|
|
21
|
+
import remarkFrontmatter from "remark-frontmatter";
|
|
22
|
+
import remarkGfm from "remark-gfm";
|
|
23
|
+
import remarkMdx from "remark-mdx";
|
|
24
|
+
import remarkParse from "remark-parse";
|
|
25
|
+
import { unified } from "unified";
|
|
26
|
+
import { SKIP, visit } from "unist-util-visit";
|
|
27
|
+
function createParser() {
|
|
28
|
+
return unified().use(remarkParse).use(remarkGfm).use(remarkFrontmatter, ["yaml"]);
|
|
29
|
+
}
|
|
30
|
+
function createMdxParser() {
|
|
31
|
+
return unified().use(remarkParse).use(remarkMdx).use(remarkGfm).use(remarkFrontmatter, ["yaml"]);
|
|
32
|
+
}
|
|
33
|
+
function getProtectedRangesSafe(content) {
|
|
34
|
+
try {
|
|
35
|
+
return getProtectedRangesFromTree(createMdxParser().parse(content));
|
|
36
|
+
} catch {
|
|
37
|
+
return getProtectedRangesFromTree(createParser().parse(content));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function parseFrontmatter(content) {
|
|
41
|
+
const result = matter(content);
|
|
42
|
+
return { body: result.content, data: result.data };
|
|
43
|
+
}
|
|
44
|
+
function stringifyWithFrontmatter(body, data) {
|
|
45
|
+
if (Object.keys(data).length === 0) return body;
|
|
46
|
+
const normalizedBody = body.startsWith("\n") ? body : `
|
|
47
|
+
${body}`;
|
|
48
|
+
return matter.stringify(normalizedBody, data);
|
|
49
|
+
}
|
|
50
|
+
function stripFrontmatter(content) {
|
|
51
|
+
return matter(content).content;
|
|
52
|
+
}
|
|
53
|
+
var inlineParser = unified().use(remarkParse).use(remarkGfm);
|
|
54
|
+
function parseInline(markdown) {
|
|
55
|
+
if (!markdown) return [];
|
|
56
|
+
const tree = inlineParser.parse(markdown);
|
|
57
|
+
const first = tree.children[0];
|
|
58
|
+
if (first?.type === "paragraph") {
|
|
59
|
+
return first.children;
|
|
60
|
+
}
|
|
61
|
+
return [{ type: "text", value: markdown }];
|
|
62
|
+
}
|
|
63
|
+
function parseBlocks(markdown) {
|
|
64
|
+
if (!markdown) return [];
|
|
65
|
+
const tree = inlineParser.parse(markdown);
|
|
66
|
+
return tree.children;
|
|
67
|
+
}
|
|
68
|
+
function getProtectedRangesFromTree(tree) {
|
|
69
|
+
const ranges = [];
|
|
70
|
+
visit(tree, (node) => {
|
|
71
|
+
const pos = node.position;
|
|
72
|
+
if (!pos?.start.offset || !pos?.end.offset) return;
|
|
73
|
+
if (node.type === "code" || node.type === "inlineCode" || node.type === "yaml") {
|
|
74
|
+
ranges.push({
|
|
75
|
+
start: pos.start.offset,
|
|
76
|
+
end: pos.end.offset
|
|
77
|
+
});
|
|
78
|
+
return SKIP;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
return ranges.sort((a, b) => a.start - b.start);
|
|
82
|
+
}
|
|
83
|
+
function isProtected(offset, ranges) {
|
|
84
|
+
let lo = 0;
|
|
85
|
+
let hi = ranges.length - 1;
|
|
86
|
+
while (lo <= hi) {
|
|
87
|
+
const mid = lo + hi >>> 1;
|
|
88
|
+
const r = ranges[mid];
|
|
89
|
+
if (offset < r.start) {
|
|
90
|
+
hi = mid - 1;
|
|
91
|
+
} else if (offset >= r.end) {
|
|
92
|
+
lo = mid + 1;
|
|
93
|
+
} else {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
function sanitizeForMdx(content) {
|
|
100
|
+
const tree = createParser().parse(content);
|
|
101
|
+
const transforms = [];
|
|
102
|
+
visit(tree, (node) => {
|
|
103
|
+
const pos = node.position;
|
|
104
|
+
if (!pos?.start.offset || !pos?.end.offset) return;
|
|
105
|
+
const start = pos.start.offset;
|
|
106
|
+
const end = pos.end.offset;
|
|
107
|
+
if (node.type === "html") {
|
|
108
|
+
const original = content.slice(start, end);
|
|
109
|
+
const commentMatch = /^<!--([\s\S]*?)-->$/.exec(original);
|
|
110
|
+
if (commentMatch) {
|
|
111
|
+
transforms.push({
|
|
112
|
+
start,
|
|
113
|
+
end,
|
|
114
|
+
replacement: `{/*${commentMatch[1]}*/}`
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
return SKIP;
|
|
118
|
+
}
|
|
119
|
+
if (node.type === "text") {
|
|
120
|
+
const original = content.slice(start, end);
|
|
121
|
+
const escaped = original.replace(/\{(?!\/\*)/g, "\\{").replace(/(?<!\*\/)\}/g, "\\}").replace(/<(\w)/g, "<$1").replace(/(\w)>/g, "$1>");
|
|
122
|
+
if (escaped !== original) {
|
|
123
|
+
transforms.push({ start, end, replacement: escaped });
|
|
124
|
+
}
|
|
125
|
+
return SKIP;
|
|
126
|
+
}
|
|
127
|
+
if (node.type === "code" || node.type === "inlineCode" || node.type === "yaml") {
|
|
128
|
+
return SKIP;
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
let result = content;
|
|
132
|
+
for (const t of transforms.sort((a, b) => b.start - a.start)) {
|
|
133
|
+
result = result.slice(0, t.start) + t.replacement + result.slice(t.end);
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
function findAutoSections(content) {
|
|
138
|
+
const protectedRanges = getProtectedRangesSafe(content);
|
|
139
|
+
const markers = [];
|
|
140
|
+
const patterns = [
|
|
141
|
+
{ regex: /<!--\s*FORGE:AUTO-START\s+(\S+)\s*-->/g, type: "start" },
|
|
142
|
+
{ regex: /<!--\s*FORGE:AUTO-END\s+(\S+)\s*-->/g, type: "end" },
|
|
143
|
+
{ regex: /\{\/\*\s*FORGE:AUTO-START\s+(\S+)\s*\*\/\}/g, type: "start" },
|
|
144
|
+
{ regex: /\{\/\*\s*FORGE:AUTO-END\s+(\S+)\s*\*\/\}/g, type: "end" }
|
|
145
|
+
];
|
|
146
|
+
for (const { regex, type } of patterns) {
|
|
147
|
+
let match;
|
|
148
|
+
while ((match = regex.exec(content)) !== null) {
|
|
149
|
+
if (!isProtected(match.index, protectedRanges)) {
|
|
150
|
+
markers.push({
|
|
151
|
+
type,
|
|
152
|
+
id: match[1],
|
|
153
|
+
offset: match.index,
|
|
154
|
+
length: match[0].length
|
|
155
|
+
});
|
|
29
156
|
}
|
|
30
|
-
continue;
|
|
31
157
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
158
|
+
}
|
|
159
|
+
markers.sort((a, b) => a.offset - b.offset);
|
|
160
|
+
const sections = /* @__PURE__ */ new Map();
|
|
161
|
+
for (let i = 0; i < markers.length; i++) {
|
|
162
|
+
const m = markers[i];
|
|
163
|
+
if (m.type !== "start") continue;
|
|
164
|
+
for (let j = i + 1; j < markers.length; j++) {
|
|
165
|
+
if (markers[j].type === "end" && markers[j].id === m.id) {
|
|
166
|
+
const sectionEnd = markers[j].offset + markers[j].length;
|
|
167
|
+
sections.set(m.id, {
|
|
168
|
+
id: m.id,
|
|
169
|
+
fullText: content.slice(m.offset, sectionEnd),
|
|
170
|
+
start: m.offset,
|
|
171
|
+
end: sectionEnd
|
|
172
|
+
});
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return sections;
|
|
178
|
+
}
|
|
179
|
+
function updateAutoSections(existing, generated) {
|
|
180
|
+
const newSections = findAutoSections(generated);
|
|
181
|
+
if (newSections.size === 0) return null;
|
|
182
|
+
const existingSections = findAutoSections(existing);
|
|
183
|
+
if (existingSections.size === 0) return null;
|
|
184
|
+
const sortedExisting = [...existingSections.entries()].sort(([, a], [, b]) => b.start - a.start);
|
|
185
|
+
let result = existing;
|
|
186
|
+
let changed = false;
|
|
187
|
+
for (const [id, existingSection] of sortedExisting) {
|
|
188
|
+
const newSection = newSections.get(id);
|
|
189
|
+
if (newSection) {
|
|
190
|
+
result = result.slice(0, existingSection.start) + newSection.fullText + result.slice(existingSection.end);
|
|
191
|
+
changed = true;
|
|
36
192
|
}
|
|
37
|
-
let safe = line;
|
|
38
|
-
safe = safe.replace(/<!--([\s\S]*?)-->/g, "{/* $1 */}");
|
|
39
|
-
safe = safe.replace(/\{(?!\/\*)/g, "\\{").replace(/(?<!\*\/)\}/g, "\\}");
|
|
40
|
-
safe = safe.replace(/<(\w)/g, "<$1");
|
|
41
|
-
safe = safe.replace(/(\w)>/g, "$1>");
|
|
42
|
-
result.push(safe);
|
|
43
193
|
}
|
|
44
|
-
return result
|
|
194
|
+
return changed ? result : null;
|
|
45
195
|
}
|
|
196
|
+
|
|
197
|
+
// src/adapters/mintlify.ts
|
|
46
198
|
var styleGuide = {
|
|
47
199
|
pageExtension: "mdx",
|
|
48
200
|
supportsMdx: true,
|
|
@@ -120,13 +272,12 @@ function buildDocsJson(context) {
|
|
|
120
272
|
function addMintlifyFrontmatter(page) {
|
|
121
273
|
const title = String(page.frontmatter.title ?? "");
|
|
122
274
|
const description = page.frontmatter.description ? String(page.frontmatter.description) : void 0;
|
|
123
|
-
const
|
|
275
|
+
const fields = { title };
|
|
124
276
|
if (description) {
|
|
125
|
-
|
|
277
|
+
fields.description = description;
|
|
126
278
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return lines.join("\n") + body;
|
|
279
|
+
const body = stripFrontmatter(page.content);
|
|
280
|
+
return stringifyWithFrontmatter(body, fields);
|
|
130
281
|
}
|
|
131
282
|
var mintlifyAdapter = {
|
|
132
283
|
target: "mintlify",
|
|
@@ -168,7 +319,7 @@ var mintlifyAdapter = {
|
|
|
168
319
|
}
|
|
169
320
|
return line;
|
|
170
321
|
}).join("\n");
|
|
171
|
-
content =
|
|
322
|
+
content = sanitizeForMdx(content);
|
|
172
323
|
return {
|
|
173
324
|
path: page.path.replace(/\.md$/, ".mdx"),
|
|
174
325
|
content,
|
|
@@ -319,16 +470,18 @@ function addDocusaurusFrontmatter(page) {
|
|
|
319
470
|
const description = page.frontmatter.description ? String(page.frontmatter.description) : void 0;
|
|
320
471
|
const sidebarLabel = page.frontmatter.sidebar_label ? String(page.frontmatter.sidebar_label) : title;
|
|
321
472
|
const sidebarPosition = page.frontmatter.sidebar_position;
|
|
322
|
-
const
|
|
473
|
+
const fields = {
|
|
474
|
+
title,
|
|
475
|
+
sidebar_label: sidebarLabel
|
|
476
|
+
};
|
|
323
477
|
if (sidebarPosition !== void 0) {
|
|
324
|
-
|
|
478
|
+
fields.sidebar_position = sidebarPosition;
|
|
325
479
|
}
|
|
326
480
|
if (description) {
|
|
327
|
-
|
|
481
|
+
fields.description = description;
|
|
328
482
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
return lines.join("\n") + body;
|
|
483
|
+
const body = stripFrontmatter(page.content);
|
|
484
|
+
return stringifyWithFrontmatter(body, fields);
|
|
332
485
|
}
|
|
333
486
|
var docusaurusAdapter = {
|
|
334
487
|
target: "docusaurus",
|
|
@@ -565,9 +718,8 @@ function addNextraFrontmatter(page) {
|
|
|
565
718
|
if (!title) {
|
|
566
719
|
return page.content;
|
|
567
720
|
}
|
|
568
|
-
const
|
|
569
|
-
|
|
570
|
-
return lines.join("\n") + body;
|
|
721
|
+
const body = stripFrontmatter(page.content);
|
|
722
|
+
return stringifyWithFrontmatter(body, { title });
|
|
571
723
|
}
|
|
572
724
|
var nextraAdapter = {
|
|
573
725
|
target: "nextra",
|
|
@@ -720,13 +872,12 @@ function buildPackageJson3(context) {
|
|
|
720
872
|
function addVitepressFrontmatter(page) {
|
|
721
873
|
const title = String(page.frontmatter.title ?? "");
|
|
722
874
|
const description = page.frontmatter.description ? String(page.frontmatter.description) : void 0;
|
|
723
|
-
const
|
|
875
|
+
const fields = { title, outline: "deep" };
|
|
724
876
|
if (description) {
|
|
725
|
-
|
|
877
|
+
fields.description = description;
|
|
726
878
|
}
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
return lines.join("\n") + body;
|
|
879
|
+
const body = stripFrontmatter(page.content);
|
|
880
|
+
return stringifyWithFrontmatter(body, fields);
|
|
730
881
|
}
|
|
731
882
|
var vitepressAdapter = {
|
|
732
883
|
target: "vitepress",
|
|
@@ -932,6 +1083,96 @@ function generateLlmsFullTxt(symbols, config) {
|
|
|
932
1083
|
|
|
933
1084
|
// src/markdown.ts
|
|
934
1085
|
import { relative } from "path";
|
|
1086
|
+
|
|
1087
|
+
// src/mdast-builders.ts
|
|
1088
|
+
import remarkFrontmatter2 from "remark-frontmatter";
|
|
1089
|
+
import remarkGfm2 from "remark-gfm";
|
|
1090
|
+
import remarkStringify from "remark-stringify";
|
|
1091
|
+
import { unified as unified2 } from "unified";
|
|
1092
|
+
var md = {
|
|
1093
|
+
// Inline (phrasing) nodes
|
|
1094
|
+
text: (value) => ({ type: "text", value }),
|
|
1095
|
+
inlineCode: (value) => ({ type: "inlineCode", value }),
|
|
1096
|
+
strong: (...children) => ({ type: "strong", children }),
|
|
1097
|
+
emphasis: (...children) => ({ type: "emphasis", children }),
|
|
1098
|
+
link: (url, ...children) => ({ type: "link", url, children }),
|
|
1099
|
+
// Block nodes
|
|
1100
|
+
heading: (depth, ...children) => ({
|
|
1101
|
+
type: "heading",
|
|
1102
|
+
depth,
|
|
1103
|
+
children
|
|
1104
|
+
}),
|
|
1105
|
+
paragraph: (...children) => ({ type: "paragraph", children }),
|
|
1106
|
+
code: (lang, value) => ({ type: "code", lang, value }),
|
|
1107
|
+
blockquote: (...children) => ({ type: "blockquote", children }),
|
|
1108
|
+
html: (value) => ({ type: "html", value }),
|
|
1109
|
+
thematicBreak: () => ({ type: "thematicBreak" }),
|
|
1110
|
+
// List nodes
|
|
1111
|
+
listItem: (...children) => ({
|
|
1112
|
+
type: "listItem",
|
|
1113
|
+
spread: false,
|
|
1114
|
+
children
|
|
1115
|
+
}),
|
|
1116
|
+
list: (items, ordered = false) => ({
|
|
1117
|
+
type: "list",
|
|
1118
|
+
ordered,
|
|
1119
|
+
spread: false,
|
|
1120
|
+
children: items
|
|
1121
|
+
}),
|
|
1122
|
+
// GFM table nodes
|
|
1123
|
+
tableCell: (...children) => ({ type: "tableCell", children }),
|
|
1124
|
+
tableRow: (...cells) => ({ type: "tableRow", children: cells }),
|
|
1125
|
+
table: (align, ...rows) => ({
|
|
1126
|
+
type: "table",
|
|
1127
|
+
align: align ?? void 0,
|
|
1128
|
+
children: rows
|
|
1129
|
+
}),
|
|
1130
|
+
// Root
|
|
1131
|
+
root: (...children) => ({ type: "root", children })
|
|
1132
|
+
};
|
|
1133
|
+
var serializer = unified2().use(remarkGfm2).use(remarkFrontmatter2).use(remarkStringify, {
|
|
1134
|
+
bullet: "-",
|
|
1135
|
+
emphasis: "*",
|
|
1136
|
+
strong: "*",
|
|
1137
|
+
fences: true,
|
|
1138
|
+
listItemIndent: "one",
|
|
1139
|
+
rule: "-"
|
|
1140
|
+
});
|
|
1141
|
+
function serializeMarkdown(tree) {
|
|
1142
|
+
return String(serializer.stringify(tree));
|
|
1143
|
+
}
|
|
1144
|
+
function textP(value) {
|
|
1145
|
+
return md.paragraph(md.text(value));
|
|
1146
|
+
}
|
|
1147
|
+
function textListItem(value) {
|
|
1148
|
+
return md.listItem(md.paragraph(md.text(value)));
|
|
1149
|
+
}
|
|
1150
|
+
function rawBlock(markdown) {
|
|
1151
|
+
return md.html(markdown);
|
|
1152
|
+
}
|
|
1153
|
+
function truncate(text, maxLen = 80) {
|
|
1154
|
+
if (text.length <= maxLen) return text;
|
|
1155
|
+
let cutPoint = maxLen - 3;
|
|
1156
|
+
const prefix = text.slice(0, cutPoint);
|
|
1157
|
+
const backtickCount = (prefix.match(/`/g) || []).length;
|
|
1158
|
+
if (backtickCount % 2 !== 0) {
|
|
1159
|
+
const lastBacktick = prefix.lastIndexOf("`");
|
|
1160
|
+
if (lastBacktick > 0) {
|
|
1161
|
+
cutPoint = lastBacktick;
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
return `${text.slice(0, cutPoint).trimEnd()}...`;
|
|
1165
|
+
}
|
|
1166
|
+
function toAnchor(text) {
|
|
1167
|
+
return text.toLowerCase().replace(/[^a-z0-9\s-]/g, "").trim().replace(/\s+/g, "-");
|
|
1168
|
+
}
|
|
1169
|
+
function slugLink(path) {
|
|
1170
|
+
let slug = path.startsWith("./") ? path.slice(2) : path;
|
|
1171
|
+
slug = slug.replace(/\.(mdx?)$/, "");
|
|
1172
|
+
return `/${slug}`;
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
// src/markdown.ts
|
|
935
1176
|
var KIND_LABELS = {
|
|
936
1177
|
function: "Functions",
|
|
937
1178
|
class: "Classes",
|
|
@@ -950,133 +1191,131 @@ var KIND_ORDER = [
|
|
|
950
1191
|
"enum",
|
|
951
1192
|
"variable"
|
|
952
1193
|
];
|
|
953
|
-
function
|
|
954
|
-
return text.toLowerCase().replace(/[^a-z0-9\s-]/g, "").trim().replace(/\s+/g, "-");
|
|
955
|
-
}
|
|
956
|
-
function buildFrontmatter(config, mdx) {
|
|
1194
|
+
function buildFrontmatter(config, _mdx) {
|
|
957
1195
|
const target = config.gen.ssgTarget;
|
|
958
1196
|
if (!target) return "";
|
|
959
|
-
const
|
|
1197
|
+
const fields = {};
|
|
960
1198
|
switch (target) {
|
|
961
1199
|
case "docusaurus":
|
|
962
|
-
|
|
963
|
-
|
|
1200
|
+
fields.sidebar_position = 1;
|
|
1201
|
+
fields.title = "API Reference";
|
|
964
1202
|
break;
|
|
965
1203
|
case "mintlify":
|
|
966
|
-
|
|
1204
|
+
fields.title = "API Reference";
|
|
967
1205
|
break;
|
|
968
1206
|
case "nextra":
|
|
969
|
-
|
|
970
|
-
|
|
1207
|
+
fields.title = "API Reference";
|
|
1208
|
+
fields.description = "Auto-generated API reference";
|
|
971
1209
|
break;
|
|
972
1210
|
case "vitepress":
|
|
973
|
-
|
|
974
|
-
|
|
1211
|
+
fields.title = "API Reference";
|
|
1212
|
+
fields.outline = "deep";
|
|
975
1213
|
break;
|
|
976
1214
|
}
|
|
977
|
-
|
|
978
|
-
if (mdx) {
|
|
979
|
-
lines.push("");
|
|
980
|
-
}
|
|
981
|
-
return `${lines.join("\n")}
|
|
982
|
-
`;
|
|
1215
|
+
return stringifyWithFrontmatter("", fields);
|
|
983
1216
|
}
|
|
984
1217
|
function buildMdxImports() {
|
|
985
1218
|
return 'import { Callout } from "@components/Callout";\n\n';
|
|
986
1219
|
}
|
|
987
|
-
function
|
|
988
|
-
|
|
989
|
-
`;
|
|
990
|
-
}
|
|
991
|
-
function renderSourceLink(symbol, rootDir) {
|
|
992
|
-
const rel = relative(rootDir, symbol.filePath);
|
|
993
|
-
return `_Defined in \`${rel}:${symbol.line}\`_
|
|
994
|
-
`;
|
|
995
|
-
}
|
|
996
|
-
function renderSymbolSection(symbol, rootDir, mdx, depth) {
|
|
997
|
-
const lines = [];
|
|
998
|
-
const hashes = "#".repeat(depth);
|
|
1220
|
+
function renderSymbolBlocks(symbol, rootDir, depth) {
|
|
1221
|
+
const nodes = [];
|
|
999
1222
|
const ext = symbol.kind === "function" || symbol.kind === "method" ? "()" : "";
|
|
1000
|
-
|
|
1001
|
-
|
|
1223
|
+
const headingDepth = Math.min(depth, 6);
|
|
1224
|
+
nodes.push(md.heading(headingDepth, md.inlineCode(`${symbol.name}${ext}`)));
|
|
1002
1225
|
if (symbol.documentation?.deprecated) {
|
|
1003
|
-
|
|
1226
|
+
nodes.push(
|
|
1227
|
+
md.blockquote(
|
|
1228
|
+
md.paragraph(
|
|
1229
|
+
md.strong(md.text("Deprecated")),
|
|
1230
|
+
md.text(": "),
|
|
1231
|
+
...parseInline(symbol.documentation.deprecated)
|
|
1232
|
+
)
|
|
1233
|
+
)
|
|
1234
|
+
);
|
|
1004
1235
|
}
|
|
1005
|
-
|
|
1236
|
+
const rel = relative(rootDir, symbol.filePath);
|
|
1237
|
+
nodes.push(
|
|
1238
|
+
md.paragraph(md.emphasis(md.text("Defined in "), md.inlineCode(`${rel}:${symbol.line}`)))
|
|
1239
|
+
);
|
|
1006
1240
|
if (symbol.signature) {
|
|
1007
|
-
|
|
1008
|
-
lines.push(symbol.signature);
|
|
1009
|
-
lines.push("```");
|
|
1010
|
-
lines.push("");
|
|
1241
|
+
nodes.push(md.code("typescript", symbol.signature));
|
|
1011
1242
|
}
|
|
1012
1243
|
if (symbol.documentation?.summary) {
|
|
1013
|
-
|
|
1014
|
-
lines.push("");
|
|
1244
|
+
nodes.push(md.paragraph(...parseInline(symbol.documentation.summary)));
|
|
1015
1245
|
}
|
|
1016
1246
|
const params = symbol.documentation?.params ?? [];
|
|
1017
1247
|
if (params.length > 0) {
|
|
1018
|
-
|
|
1019
|
-
|
|
1248
|
+
nodes.push(md.paragraph(md.strong(md.text("Parameters"))));
|
|
1249
|
+
const paramItems = [];
|
|
1020
1250
|
for (const p of params) {
|
|
1021
|
-
const
|
|
1022
|
-
|
|
1251
|
+
const parts = [md.inlineCode(p.name)];
|
|
1252
|
+
if (p.type) {
|
|
1253
|
+
parts.push(md.text(" ("), md.inlineCode(p.type), md.text(")"));
|
|
1254
|
+
}
|
|
1255
|
+
parts.push(md.text(" \u2014 "), ...parseInline(p.description));
|
|
1256
|
+
paramItems.push(md.listItem(md.paragraph(...parts)));
|
|
1023
1257
|
}
|
|
1024
|
-
|
|
1258
|
+
nodes.push(md.list(paramItems));
|
|
1025
1259
|
}
|
|
1026
1260
|
if (symbol.documentation?.returns) {
|
|
1027
|
-
const
|
|
1028
|
-
|
|
1029
|
-
|
|
1261
|
+
const retParts = [md.strong(md.text("Returns"))];
|
|
1262
|
+
if (symbol.documentation.returns.type) {
|
|
1263
|
+
retParts.push(md.text(" ("), md.inlineCode(symbol.documentation.returns.type), md.text(")"));
|
|
1264
|
+
}
|
|
1265
|
+
retParts.push(md.text(": "), ...parseInline(symbol.documentation.returns.description));
|
|
1266
|
+
nodes.push(md.paragraph(...retParts));
|
|
1030
1267
|
}
|
|
1031
1268
|
const throws = symbol.documentation?.throws ?? [];
|
|
1032
1269
|
if (throws.length > 0) {
|
|
1033
|
-
|
|
1034
|
-
|
|
1270
|
+
nodes.push(md.paragraph(md.strong(md.text("Throws"))));
|
|
1271
|
+
const throwItems = [];
|
|
1035
1272
|
for (const t of throws) {
|
|
1036
|
-
const
|
|
1037
|
-
|
|
1273
|
+
const parts = [];
|
|
1274
|
+
if (t.type) {
|
|
1275
|
+
parts.push(md.inlineCode(t.type), md.text(" \u2014 "), ...parseInline(t.description));
|
|
1276
|
+
} else {
|
|
1277
|
+
parts.push(...parseInline(t.description));
|
|
1278
|
+
}
|
|
1279
|
+
throwItems.push(md.listItem(md.paragraph(...parts)));
|
|
1038
1280
|
}
|
|
1039
|
-
|
|
1281
|
+
nodes.push(md.list(throwItems));
|
|
1040
1282
|
}
|
|
1041
1283
|
const examples = symbol.documentation?.examples ?? [];
|
|
1042
1284
|
if (examples.length > 0) {
|
|
1043
|
-
|
|
1044
|
-
lines.push("");
|
|
1285
|
+
nodes.push(md.paragraph(md.strong(md.text("Examples"))));
|
|
1045
1286
|
for (const ex of examples) {
|
|
1046
|
-
|
|
1047
|
-
lines.push(ex.code.trim());
|
|
1048
|
-
lines.push("```");
|
|
1049
|
-
lines.push("");
|
|
1287
|
+
nodes.push(md.code(ex.language, ex.code.trim()));
|
|
1050
1288
|
}
|
|
1051
1289
|
}
|
|
1052
1290
|
const children = symbol.children ?? [];
|
|
1053
1291
|
if (children.length > 0 && depth < 5) {
|
|
1054
|
-
const childDepth = depth + 1;
|
|
1055
1292
|
for (const child of children) {
|
|
1056
|
-
|
|
1293
|
+
nodes.push(...renderSymbolBlocks(child, rootDir, depth + 1));
|
|
1057
1294
|
}
|
|
1058
1295
|
}
|
|
1059
|
-
return
|
|
1296
|
+
return nodes;
|
|
1060
1297
|
}
|
|
1061
|
-
function
|
|
1062
|
-
const
|
|
1063
|
-
lines.push("## Table of Contents");
|
|
1064
|
-
lines.push("");
|
|
1298
|
+
function buildTocBlocks(groups) {
|
|
1299
|
+
const tocItems = [];
|
|
1065
1300
|
for (const kind of KIND_ORDER) {
|
|
1066
1301
|
const group = groups.get(kind);
|
|
1067
1302
|
if (!group || group.length === 0) continue;
|
|
1068
1303
|
const label = KIND_LABELS[kind];
|
|
1069
1304
|
const anchor = toAnchor(label);
|
|
1070
|
-
|
|
1305
|
+
const subItems = [];
|
|
1071
1306
|
for (const symbol of group) {
|
|
1072
1307
|
const ext = kind === "function" ? "()" : "";
|
|
1073
1308
|
const displayName = `${symbol.name}${ext}`;
|
|
1074
1309
|
const symAnchor = toAnchor(displayName);
|
|
1075
|
-
|
|
1310
|
+
subItems.push(
|
|
1311
|
+
md.listItem(md.paragraph(md.link(`#${symAnchor}`, md.inlineCode(displayName))))
|
|
1312
|
+
);
|
|
1076
1313
|
}
|
|
1314
|
+
tocItems.push(
|
|
1315
|
+
md.listItem(md.paragraph(md.link(`#${anchor}`, md.text(label))), md.list(subItems))
|
|
1316
|
+
);
|
|
1077
1317
|
}
|
|
1078
|
-
|
|
1079
|
-
return lines.join("\n");
|
|
1318
|
+
return [md.heading(2, md.text("Table of Contents")), md.list(tocItems)];
|
|
1080
1319
|
}
|
|
1081
1320
|
function generateMarkdown(symbols, config, options = {}) {
|
|
1082
1321
|
const mdx = options.mdx ?? false;
|
|
@@ -1088,34 +1327,40 @@ function generateMarkdown(symbols, config, options = {}) {
|
|
|
1088
1327
|
list.push(symbol);
|
|
1089
1328
|
groups.set(symbol.kind, list);
|
|
1090
1329
|
}
|
|
1091
|
-
const
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
`Generated by [forge-ts](https://github.com/kryptobaseddev/forge-ts) from \`${config.rootDir}\`.
|
|
1102
|
-
`
|
|
1330
|
+
const nodes = [];
|
|
1331
|
+
nodes.push(md.heading(1, md.text("API Reference")));
|
|
1332
|
+
nodes.push(
|
|
1333
|
+
md.paragraph(
|
|
1334
|
+
md.text("Generated by "),
|
|
1335
|
+
md.link("https://github.com/kryptobaseddev/forge-ts", md.text("forge-ts")),
|
|
1336
|
+
md.text(" from "),
|
|
1337
|
+
md.inlineCode(config.rootDir),
|
|
1338
|
+
md.text(".")
|
|
1339
|
+
)
|
|
1103
1340
|
);
|
|
1104
1341
|
if (topLevel.length > 0) {
|
|
1105
|
-
|
|
1342
|
+
nodes.push(...buildTocBlocks(groups));
|
|
1106
1343
|
}
|
|
1107
1344
|
for (const kind of KIND_ORDER) {
|
|
1108
1345
|
const group = groups.get(kind);
|
|
1109
1346
|
if (!group || group.length === 0) continue;
|
|
1110
1347
|
const label = KIND_LABELS[kind];
|
|
1111
|
-
|
|
1112
|
-
`);
|
|
1348
|
+
nodes.push(md.heading(2, md.text(label)));
|
|
1113
1349
|
for (const symbol of group) {
|
|
1114
|
-
|
|
1115
|
-
parts.push("");
|
|
1350
|
+
nodes.push(...renderSymbolBlocks(symbol, config.rootDir, 3));
|
|
1116
1351
|
}
|
|
1117
1352
|
}
|
|
1118
|
-
|
|
1353
|
+
const body = serializeMarkdown(md.root(...nodes));
|
|
1354
|
+
const parts = [];
|
|
1355
|
+
const frontmatter = buildFrontmatter(config, mdx);
|
|
1356
|
+
if (frontmatter) {
|
|
1357
|
+
parts.push(frontmatter);
|
|
1358
|
+
}
|
|
1359
|
+
if (mdx) {
|
|
1360
|
+
parts.push(buildMdxImports());
|
|
1361
|
+
}
|
|
1362
|
+
parts.push(body);
|
|
1363
|
+
return `${parts.join("").trimEnd()}
|
|
1119
1364
|
`;
|
|
1120
1365
|
}
|
|
1121
1366
|
|
|
@@ -1124,59 +1369,67 @@ import { existsSync } from "fs";
|
|
|
1124
1369
|
import { readFile, writeFile } from "fs/promises";
|
|
1125
1370
|
var SECTION_START = "<!-- forge-ts:start -->";
|
|
1126
1371
|
var SECTION_END = "<!-- forge-ts:end -->";
|
|
1127
|
-
function
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
function renderFirstExample(symbol) {
|
|
1136
|
-
const examples = symbol.documentation?.examples ?? [];
|
|
1137
|
-
if (examples.length === 0) return "";
|
|
1138
|
-
const ex = examples[0];
|
|
1139
|
-
return ["", `\`\`\`${ex.language}`, ex.code.trim(), "```"].join("\n");
|
|
1140
|
-
}
|
|
1141
|
-
function buildApiTable(symbols, includeExamples) {
|
|
1142
|
-
const lines = ["| Symbol | Kind | Description |", "|--------|------|-------------|"];
|
|
1372
|
+
function buildApiBlocks(symbols, includeExamples) {
|
|
1373
|
+
const nodes = [];
|
|
1374
|
+
const headerRow = md.tableRow(
|
|
1375
|
+
md.tableCell(md.text("Symbol")),
|
|
1376
|
+
md.tableCell(md.text("Kind")),
|
|
1377
|
+
md.tableCell(md.text("Description"))
|
|
1378
|
+
);
|
|
1379
|
+
const dataRows = [];
|
|
1143
1380
|
for (const s of symbols) {
|
|
1144
|
-
|
|
1381
|
+
let sigText;
|
|
1382
|
+
if (!s.signature) {
|
|
1383
|
+
const ext = s.kind === "function" ? "()" : "";
|
|
1384
|
+
sigText = `${s.name}${ext}`;
|
|
1385
|
+
} else {
|
|
1386
|
+
sigText = s.signature.length > 60 ? `${s.signature.slice(0, 57)}...` : s.signature;
|
|
1387
|
+
}
|
|
1145
1388
|
const summary = s.documentation?.summary ?? "";
|
|
1146
|
-
|
|
1389
|
+
dataRows.push(
|
|
1390
|
+
md.tableRow(
|
|
1391
|
+
md.tableCell(md.inlineCode(sigText)),
|
|
1392
|
+
md.tableCell(md.text(s.kind)),
|
|
1393
|
+
md.tableCell(...summary ? parseInline(summary) : [md.text("")])
|
|
1394
|
+
)
|
|
1395
|
+
);
|
|
1147
1396
|
}
|
|
1397
|
+
nodes.push(md.table(null, headerRow, ...dataRows));
|
|
1148
1398
|
if (includeExamples) {
|
|
1149
1399
|
const withExamples = symbols.filter((s) => (s.documentation?.examples ?? []).length > 0);
|
|
1150
1400
|
if (withExamples.length > 0) {
|
|
1151
|
-
|
|
1152
|
-
lines.push("### Examples");
|
|
1401
|
+
nodes.push(md.heading(3, md.text("Examples")));
|
|
1153
1402
|
for (const s of withExamples) {
|
|
1154
|
-
lines.push("");
|
|
1155
1403
|
const ext = s.kind === "function" ? "()" : "";
|
|
1156
|
-
|
|
1157
|
-
|
|
1404
|
+
nodes.push(md.heading(4, md.inlineCode(`${s.name}${ext}`)));
|
|
1405
|
+
const examples = s.documentation?.examples ?? [];
|
|
1406
|
+
const ex = examples[0];
|
|
1407
|
+
nodes.push(md.code(ex.language, ex.code.trim()));
|
|
1158
1408
|
}
|
|
1159
1409
|
}
|
|
1160
1410
|
}
|
|
1161
|
-
return
|
|
1411
|
+
return nodes;
|
|
1162
1412
|
}
|
|
1163
1413
|
async function syncReadme(readmePath, symbols, options = {}) {
|
|
1164
1414
|
const exported = symbols.filter((s) => s.exported);
|
|
1165
1415
|
if (exported.length === 0) return false;
|
|
1166
1416
|
const badge = options.badge ?? false;
|
|
1167
1417
|
const includeExamples = options.includeExamples ?? false;
|
|
1168
|
-
const
|
|
1169
|
-
|
|
1170
|
-
innerLines.push("");
|
|
1418
|
+
const innerNodes = [];
|
|
1419
|
+
innerNodes.push(md.heading(2, md.text("API Overview")));
|
|
1171
1420
|
if (badge) {
|
|
1172
|
-
|
|
1173
|
-
|
|
1421
|
+
innerNodes.push(
|
|
1422
|
+
rawBlock(
|
|
1423
|
+
"[](https://github.com/forge-ts/forge-ts)"
|
|
1424
|
+
)
|
|
1174
1425
|
);
|
|
1175
|
-
innerLines.push("");
|
|
1176
1426
|
}
|
|
1177
|
-
|
|
1178
|
-
const
|
|
1179
|
-
const injection =
|
|
1427
|
+
innerNodes.push(...buildApiBlocks(exported, includeExamples));
|
|
1428
|
+
const innerMd = serializeMarkdown(md.root(...innerNodes));
|
|
1429
|
+
const injection = `${SECTION_START}
|
|
1430
|
+
|
|
1431
|
+
${innerMd}
|
|
1432
|
+
${SECTION_END}`;
|
|
1180
1433
|
let existing = existsSync(readmePath) ? await readFile(readmePath, "utf8") : "";
|
|
1181
1434
|
const startIdx = existing.indexOf(SECTION_START);
|
|
1182
1435
|
const endIdx = existing.indexOf(SECTION_END);
|
|
@@ -1194,25 +1447,12 @@ ${injection}
|
|
|
1194
1447
|
|
|
1195
1448
|
// src/site-generator.ts
|
|
1196
1449
|
import { basename, relative as relative2 } from "path";
|
|
1197
|
-
function toAnchor2(text) {
|
|
1198
|
-
return text.toLowerCase().replace(/[^a-z0-9\s-]/g, "").trim().replace(/\s+/g, "-");
|
|
1199
|
-
}
|
|
1200
|
-
function escapePipe(text) {
|
|
1201
|
-
return text.replace(/\|/g, "\\|");
|
|
1202
|
-
}
|
|
1203
1450
|
function escapeMdx(text) {
|
|
1204
1451
|
return text.replace(/\{/g, "\\{").replace(/\}/g, "\\}").replace(/<(\w)/g, "<$1").replace(/(\w)>/g, "$1>");
|
|
1205
1452
|
}
|
|
1206
1453
|
function serializeFrontmatter(fields) {
|
|
1207
1454
|
if (Object.keys(fields).length === 0) return "";
|
|
1208
|
-
|
|
1209
|
-
for (const [key, value] of Object.entries(fields)) {
|
|
1210
|
-
lines.push(`${key}: ${value}`);
|
|
1211
|
-
}
|
|
1212
|
-
lines.push("---");
|
|
1213
|
-
return `${lines.join("\n")}
|
|
1214
|
-
|
|
1215
|
-
`;
|
|
1455
|
+
return stringifyWithFrontmatter("", fields);
|
|
1216
1456
|
}
|
|
1217
1457
|
function buildFrontmatterFields(title, description, ssgTarget, sidebarPosition) {
|
|
1218
1458
|
if (!ssgTarget) return {};
|
|
@@ -1250,15 +1490,6 @@ function buildFrontmatterFields(title, description, ssgTarget, sidebarPosition)
|
|
|
1250
1490
|
return {};
|
|
1251
1491
|
}
|
|
1252
1492
|
}
|
|
1253
|
-
function slugLink(path) {
|
|
1254
|
-
let slug = path.startsWith("./") ? path.slice(2) : path;
|
|
1255
|
-
slug = slug.replace(/\.(mdx?)$/, "");
|
|
1256
|
-
return `/${slug}`;
|
|
1257
|
-
}
|
|
1258
|
-
function truncate(text, maxLen = 80) {
|
|
1259
|
-
if (text.length <= maxLen) return text;
|
|
1260
|
-
return `${text.slice(0, maxLen - 3)}...`;
|
|
1261
|
-
}
|
|
1262
1493
|
function groupSymbolsByPackage(symbols, rootDir) {
|
|
1263
1494
|
const result = /* @__PURE__ */ new Map();
|
|
1264
1495
|
for (const symbol of symbols) {
|
|
@@ -1274,33 +1505,46 @@ function groupSymbolsByPackage(symbols, rootDir) {
|
|
|
1274
1505
|
var TYPE_KINDS = /* @__PURE__ */ new Set(["interface", "type", "enum"]);
|
|
1275
1506
|
var FUNCTION_KINDS = /* @__PURE__ */ new Set(["function", "class"]);
|
|
1276
1507
|
function renderProjectIndexPage(symbolsByPackage, options) {
|
|
1277
|
-
const
|
|
1508
|
+
const nodes = [];
|
|
1278
1509
|
if (options.projectDescription) {
|
|
1279
|
-
|
|
1510
|
+
nodes.push(
|
|
1511
|
+
md.paragraph(
|
|
1512
|
+
md.strong(md.text(options.projectName)),
|
|
1513
|
+
md.text(` \u2014 ${options.projectDescription}`)
|
|
1514
|
+
)
|
|
1515
|
+
);
|
|
1280
1516
|
} else {
|
|
1281
|
-
|
|
1282
|
-
|
|
1517
|
+
nodes.push(
|
|
1518
|
+
md.paragraph(
|
|
1519
|
+
md.strong(md.text(options.projectName)),
|
|
1520
|
+
md.text(
|
|
1521
|
+
" is a TypeScript documentation toolkit that performs a single AST traversal of your project and produces API docs, OpenAPI specs, executable doctests, and AI context files in one pass."
|
|
1522
|
+
)
|
|
1523
|
+
)
|
|
1283
1524
|
);
|
|
1284
1525
|
}
|
|
1285
|
-
|
|
1286
|
-
lines.push("## Features");
|
|
1287
|
-
lines.push("");
|
|
1526
|
+
nodes.push(md.heading(2, md.text("Features")));
|
|
1288
1527
|
const pkgCount = symbolsByPackage.size;
|
|
1528
|
+
const featureItems = [];
|
|
1289
1529
|
if (pkgCount > 1) {
|
|
1290
|
-
|
|
1530
|
+
featureItems.push(textListItem(`${pkgCount} packages with full TypeScript support`));
|
|
1291
1531
|
} else {
|
|
1292
|
-
|
|
1293
|
-
}
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1532
|
+
featureItems.push(textListItem("Full TypeScript support with TSDoc extraction"));
|
|
1533
|
+
}
|
|
1534
|
+
featureItems.push(textListItem("Auto-generated API reference from source code"));
|
|
1535
|
+
featureItems.push(
|
|
1536
|
+
md.listItem(
|
|
1537
|
+
md.paragraph(
|
|
1538
|
+
md.text("Executable "),
|
|
1539
|
+
md.inlineCode("@example"),
|
|
1540
|
+
md.text(" blocks as doctests")
|
|
1541
|
+
)
|
|
1542
|
+
)
|
|
1543
|
+
);
|
|
1544
|
+
featureItems.push(textListItem("AI-ready context files from a single build pass"));
|
|
1545
|
+
nodes.push(md.list(featureItems));
|
|
1546
|
+
nodes.push(md.heading(2, md.text("Installation")));
|
|
1547
|
+
nodes.push(md.code("bash", `npm install -D ${options.packageName ?? "@forge-ts/cli"}`));
|
|
1304
1548
|
let firstExample;
|
|
1305
1549
|
outer: for (const [, symbols] of symbolsByPackage) {
|
|
1306
1550
|
for (const s of symbols) {
|
|
@@ -1313,36 +1557,53 @@ function renderProjectIndexPage(symbolsByPackage, options) {
|
|
|
1313
1557
|
}
|
|
1314
1558
|
}
|
|
1315
1559
|
if (firstExample) {
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
lines.push(`\`\`\`${firstExample.language || "typescript"}`);
|
|
1319
|
-
lines.push(firstExample.code.trim());
|
|
1320
|
-
lines.push("```");
|
|
1321
|
-
lines.push("");
|
|
1560
|
+
nodes.push(md.heading(2, md.text("Quick Example")));
|
|
1561
|
+
nodes.push(md.code(firstExample.language || "typescript", firstExample.code.trim()));
|
|
1322
1562
|
}
|
|
1323
1563
|
if (symbolsByPackage.size > 0) {
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1564
|
+
nodes.push(md.heading(2, md.text("Packages")));
|
|
1565
|
+
const headerRow = md.tableRow(
|
|
1566
|
+
md.tableCell(md.text("Package")),
|
|
1567
|
+
md.tableCell(md.text("Description"))
|
|
1568
|
+
);
|
|
1569
|
+
const dataRows = [];
|
|
1328
1570
|
for (const [pkgName, symbols] of symbolsByPackage) {
|
|
1329
1571
|
const pkgDoc = symbols.map((s) => s.documentation?.tags?.packageDocumentation?.[0]).find(Boolean);
|
|
1330
1572
|
const exported = symbols.filter(
|
|
1331
1573
|
(s) => s.exported && s.kind !== "method" && s.kind !== "property"
|
|
1332
1574
|
);
|
|
1333
1575
|
const rawDesc = pkgDoc ?? `${exported.length} exported symbol(s).`;
|
|
1334
|
-
const desc =
|
|
1335
|
-
|
|
1336
|
-
|
|
1576
|
+
const desc = truncate(rawDesc);
|
|
1577
|
+
dataRows.push(
|
|
1578
|
+
md.tableRow(
|
|
1579
|
+
md.tableCell(md.link(slugLink(`packages/${pkgName}/index`), md.inlineCode(pkgName))),
|
|
1580
|
+
md.tableCell(md.text(desc))
|
|
1581
|
+
)
|
|
1582
|
+
);
|
|
1337
1583
|
}
|
|
1338
|
-
|
|
1339
|
-
}
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1584
|
+
nodes.push(md.table(null, headerRow, ...dataRows));
|
|
1585
|
+
}
|
|
1586
|
+
nodes.push(md.heading(2, md.text("Next Steps")));
|
|
1587
|
+
nodes.push(
|
|
1588
|
+
md.list([
|
|
1589
|
+
md.listItem(
|
|
1590
|
+
md.paragraph(
|
|
1591
|
+
md.link("/getting-started", md.text("Getting Started")),
|
|
1592
|
+
md.text(" \u2014 Step-by-step guide")
|
|
1593
|
+
)
|
|
1594
|
+
),
|
|
1595
|
+
md.listItem(
|
|
1596
|
+
md.paragraph(
|
|
1597
|
+
md.link("/packages", md.text("API Reference")),
|
|
1598
|
+
md.text(" \u2014 Full API documentation")
|
|
1599
|
+
)
|
|
1600
|
+
),
|
|
1601
|
+
md.listItem(
|
|
1602
|
+
md.paragraph(md.link("/concepts", md.text("Concepts")), md.text(" \u2014 How it works"))
|
|
1603
|
+
)
|
|
1604
|
+
])
|
|
1605
|
+
);
|
|
1606
|
+
return serializeMarkdown(md.root(...nodes));
|
|
1346
1607
|
}
|
|
1347
1608
|
function renderGettingStartedPage(symbolsByPackage, options) {
|
|
1348
1609
|
let firstExample;
|
|
@@ -1356,126 +1617,143 @@ function renderGettingStartedPage(symbolsByPackage, options) {
|
|
|
1356
1617
|
}
|
|
1357
1618
|
}
|
|
1358
1619
|
}
|
|
1359
|
-
const
|
|
1360
|
-
|
|
1620
|
+
const nodes = [];
|
|
1621
|
+
nodes.push(
|
|
1622
|
+
md.paragraph(
|
|
1623
|
+
md.text("Get up and running with "),
|
|
1624
|
+
md.strong(md.text(options.projectName)),
|
|
1625
|
+
md.text(" in minutes.")
|
|
1626
|
+
)
|
|
1627
|
+
);
|
|
1361
1628
|
if (options.projectDescription) {
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
lines.push("");
|
|
1402
|
-
lines.push("```");
|
|
1403
|
-
lines.push("forge-ts: checking TSDoc coverage...");
|
|
1404
|
-
lines.push(" \u2713 All public symbols documented");
|
|
1405
|
-
lines.push("```");
|
|
1406
|
-
lines.push("");
|
|
1407
|
-
lines.push("## Step 4: Generate docs");
|
|
1408
|
-
lines.push("");
|
|
1409
|
-
lines.push("Build your documentation site:");
|
|
1410
|
-
lines.push("");
|
|
1411
|
-
lines.push("```bash");
|
|
1412
|
-
lines.push("npx forge-ts build");
|
|
1413
|
-
lines.push("```");
|
|
1414
|
-
lines.push("");
|
|
1629
|
+
nodes.push(md.paragraph(...parseInline(options.projectDescription)));
|
|
1630
|
+
}
|
|
1631
|
+
nodes.push(md.heading(2, md.text("Step 1: Install")));
|
|
1632
|
+
nodes.push(md.code("bash", `npm install -D ${options.packageName ?? "@forge-ts/cli"}`));
|
|
1633
|
+
nodes.push(md.heading(2, md.text("Step 2: Add TSDoc to your code")));
|
|
1634
|
+
nodes.push(textP("Add TSDoc comments to your exported functions and types:"));
|
|
1635
|
+
nodes.push(
|
|
1636
|
+
md.code(
|
|
1637
|
+
"typescript",
|
|
1638
|
+
[
|
|
1639
|
+
"/**",
|
|
1640
|
+
" * Adds two numbers together.",
|
|
1641
|
+
" * @param a - First number",
|
|
1642
|
+
" * @param b - Second number",
|
|
1643
|
+
" * @returns The sum of a and b",
|
|
1644
|
+
" * @example",
|
|
1645
|
+
" * ```typescript",
|
|
1646
|
+
" * const result = add(1, 2); // => 3",
|
|
1647
|
+
" * ```",
|
|
1648
|
+
" */",
|
|
1649
|
+
"export function add(a: number, b: number): number {",
|
|
1650
|
+
" return a + b;",
|
|
1651
|
+
"}"
|
|
1652
|
+
].join("\n")
|
|
1653
|
+
)
|
|
1654
|
+
);
|
|
1655
|
+
nodes.push(md.heading(2, md.text("Step 3: Run forge-ts check")));
|
|
1656
|
+
nodes.push(textP("Lint your TSDoc coverage before generating docs:"));
|
|
1657
|
+
nodes.push(md.code("bash", "npx forge-ts check"));
|
|
1658
|
+
nodes.push(textP("Expected output:"));
|
|
1659
|
+
nodes.push(
|
|
1660
|
+
md.code(
|
|
1661
|
+
"",
|
|
1662
|
+
["forge-ts: checking TSDoc coverage...", " \u2713 All public symbols documented"].join("\n")
|
|
1663
|
+
)
|
|
1664
|
+
);
|
|
1665
|
+
nodes.push(md.heading(2, md.text("Step 4: Generate docs")));
|
|
1666
|
+
nodes.push(textP("Build your documentation site:"));
|
|
1667
|
+
nodes.push(md.code("bash", "npx forge-ts build"));
|
|
1415
1668
|
if (firstExample) {
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1669
|
+
nodes.push(textP("Your code examples become live documentation:"));
|
|
1670
|
+
nodes.push(md.code(firstExample.language || "typescript", firstExample.code.trim()));
|
|
1671
|
+
}
|
|
1672
|
+
nodes.push(md.heading(2, md.text("What's Next?")));
|
|
1673
|
+
nodes.push(
|
|
1674
|
+
md.list([
|
|
1675
|
+
md.listItem(
|
|
1676
|
+
md.paragraph(
|
|
1677
|
+
md.link("/concepts", md.text("Concepts")),
|
|
1678
|
+
md.text(" \u2014 Understand how forge-ts works")
|
|
1679
|
+
)
|
|
1680
|
+
),
|
|
1681
|
+
md.listItem(
|
|
1682
|
+
md.paragraph(
|
|
1683
|
+
md.link("/packages", md.text("API Reference")),
|
|
1684
|
+
md.text(" \u2014 Full API documentation")
|
|
1685
|
+
)
|
|
1686
|
+
),
|
|
1687
|
+
md.listItem(
|
|
1688
|
+
md.paragraph(md.link("/guides", md.text("Guides")), md.text(" \u2014 Practical how-to guides"))
|
|
1689
|
+
)
|
|
1690
|
+
])
|
|
1691
|
+
);
|
|
1692
|
+
return serializeMarkdown(md.root(...nodes));
|
|
1429
1693
|
}
|
|
1430
1694
|
function renderConceptsPage(symbolsByPackage, options) {
|
|
1431
|
-
const
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1695
|
+
const nodes = [];
|
|
1696
|
+
nodes.push(
|
|
1697
|
+
md.paragraph(
|
|
1698
|
+
md.text("This page explains the core concepts behind "),
|
|
1699
|
+
md.strong(md.text(options.projectName)),
|
|
1700
|
+
md.text(".")
|
|
1701
|
+
)
|
|
1702
|
+
);
|
|
1703
|
+
nodes.push(
|
|
1704
|
+
md.blockquote(
|
|
1705
|
+
textP("This is a stub page. Edit this file to add your project's conceptual documentation."),
|
|
1706
|
+
textP("Auto-generated sections below (inside FORGE:AUTO markers) update on every build.")
|
|
1707
|
+
)
|
|
1436
1708
|
);
|
|
1437
|
-
lines.push("> Auto-generated sections below (inside FORGE:AUTO markers) update on every build.");
|
|
1438
|
-
lines.push("");
|
|
1439
1709
|
const pkgDoc = [...symbolsByPackage.values()].flatMap((syms) => syms.map((s) => s.documentation?.tags?.packageDocumentation?.[0])).find(Boolean);
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
lines.push("");
|
|
1710
|
+
nodes.push(md.html("<!-- FORGE:AUTO-START how-it-works -->"));
|
|
1711
|
+
nodes.push(md.heading(2, md.text("How It Works")));
|
|
1443
1712
|
if (pkgDoc) {
|
|
1444
|
-
|
|
1713
|
+
nodes.push(md.paragraph(...parseInline(pkgDoc)));
|
|
1445
1714
|
} else {
|
|
1446
|
-
|
|
1447
|
-
|
|
1715
|
+
nodes.push(
|
|
1716
|
+
textP(
|
|
1717
|
+
`${options.projectName} processes your TypeScript source with a single AST traversal, extracting TSDoc comments and type information to generate documentation.`
|
|
1718
|
+
)
|
|
1448
1719
|
);
|
|
1449
1720
|
}
|
|
1450
|
-
|
|
1451
|
-
lines.push("<!-- FORGE:AUTO-END how-it-works -->");
|
|
1452
|
-
lines.push("");
|
|
1721
|
+
nodes.push(md.html("<!-- FORGE:AUTO-END how-it-works -->"));
|
|
1453
1722
|
const allTypeSymbols = [...symbolsByPackage.values()].flat().filter((s) => s.exported && TYPE_KINDS.has(s.kind));
|
|
1454
1723
|
if (allTypeSymbols.length > 0) {
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1724
|
+
nodes.push(md.html("<!-- FORGE:AUTO-START key-abstractions -->"));
|
|
1725
|
+
nodes.push(md.heading(2, md.text("Key Abstractions")));
|
|
1726
|
+
const items = [];
|
|
1458
1727
|
for (const s of allTypeSymbols) {
|
|
1459
1728
|
const desc = s.documentation?.summary ?? `The \`${s.name}\` ${s.kind}.`;
|
|
1460
|
-
|
|
1729
|
+
items.push(
|
|
1730
|
+
md.listItem(
|
|
1731
|
+
md.paragraph(md.strong(md.inlineCode(s.name)), md.text(" \u2014 "), ...parseInline(desc))
|
|
1732
|
+
)
|
|
1733
|
+
);
|
|
1461
1734
|
}
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
lines.push("");
|
|
1735
|
+
nodes.push(md.list(items));
|
|
1736
|
+
nodes.push(md.html("<!-- FORGE:AUTO-END key-abstractions -->"));
|
|
1465
1737
|
}
|
|
1466
|
-
return
|
|
1738
|
+
return serializeMarkdown(md.root(...nodes));
|
|
1467
1739
|
}
|
|
1468
1740
|
function renderGuidesIndexPage() {
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1741
|
+
const nodes = [];
|
|
1742
|
+
nodes.push(textP("Practical how-to guides for common tasks."));
|
|
1743
|
+
nodes.push(
|
|
1744
|
+
md.blockquote(
|
|
1745
|
+
textP(
|
|
1746
|
+
"Add your guides to the `guides/` directory. Each `.md` or `.mdx` file will appear here automatically."
|
|
1747
|
+
)
|
|
1748
|
+
)
|
|
1749
|
+
);
|
|
1750
|
+
nodes.push(md.heading(2, md.text("Getting Things Done")));
|
|
1751
|
+
nodes.push(
|
|
1752
|
+
textP(
|
|
1753
|
+
"Guides will appear here as you add them. Start by creating a file like `guides/my-guide.md`."
|
|
1754
|
+
)
|
|
1755
|
+
);
|
|
1756
|
+
return serializeMarkdown(md.root(...nodes));
|
|
1479
1757
|
}
|
|
1480
1758
|
function renderApiIndexPage(pkgName, symbols) {
|
|
1481
1759
|
const exported = symbols.filter(
|
|
@@ -1484,45 +1762,57 @@ function renderApiIndexPage(pkgName, symbols) {
|
|
|
1484
1762
|
const functions = exported.filter((s) => FUNCTION_KINDS.has(s.kind));
|
|
1485
1763
|
const types = exported.filter((s) => TYPE_KINDS.has(s.kind));
|
|
1486
1764
|
const others = exported.filter((s) => !FUNCTION_KINDS.has(s.kind) && !TYPE_KINDS.has(s.kind));
|
|
1487
|
-
const
|
|
1765
|
+
const nodes = [];
|
|
1488
1766
|
const pkgDoc = symbols.map((s) => s.documentation?.tags?.packageDocumentation?.[0]).find(Boolean);
|
|
1489
1767
|
if (pkgDoc) {
|
|
1490
|
-
|
|
1491
|
-
lines.push("");
|
|
1768
|
+
nodes.push(md.paragraph(...parseInline(pkgDoc)));
|
|
1492
1769
|
} else {
|
|
1493
|
-
|
|
1494
|
-
|
|
1770
|
+
nodes.push(
|
|
1771
|
+
md.paragraph(md.text("API reference for the "), md.inlineCode(pkgName), md.text(" package."))
|
|
1772
|
+
);
|
|
1495
1773
|
}
|
|
1496
1774
|
const renderGroup = (group, heading, pathSuffix) => {
|
|
1497
1775
|
if (group.length === 0) return;
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1776
|
+
nodes.push(md.heading(2, md.text(heading)));
|
|
1777
|
+
const headerRow = md.tableRow(
|
|
1778
|
+
md.tableCell(md.text("Symbol")),
|
|
1779
|
+
md.tableCell(md.text("Kind")),
|
|
1780
|
+
md.tableCell(md.text("Description"))
|
|
1781
|
+
);
|
|
1782
|
+
const dataRows = [];
|
|
1502
1783
|
for (const s of group) {
|
|
1503
1784
|
const ext = s.kind === "function" ? "()" : "";
|
|
1504
|
-
const anchor =
|
|
1505
|
-
const link = `[\`${s.name}${ext}\`](${slugLink(`packages/${pkgName}/${pathSuffix}`)}#${anchor})`;
|
|
1785
|
+
const anchor = toAnchor(`${s.name}${ext}`);
|
|
1506
1786
|
const rawSummary = s.documentation?.summary ?? "";
|
|
1507
|
-
const summary =
|
|
1508
|
-
|
|
1787
|
+
const summary = truncate(rawSummary);
|
|
1788
|
+
dataRows.push(
|
|
1789
|
+
md.tableRow(
|
|
1790
|
+
md.tableCell(
|
|
1791
|
+
md.link(
|
|
1792
|
+
`${slugLink(`packages/${pkgName}/${pathSuffix}`)}#${anchor}`,
|
|
1793
|
+
md.inlineCode(`${s.name}${ext}`)
|
|
1794
|
+
)
|
|
1795
|
+
),
|
|
1796
|
+
md.tableCell(md.text(s.kind)),
|
|
1797
|
+
md.tableCell(...parseInline(summary))
|
|
1798
|
+
)
|
|
1799
|
+
);
|
|
1509
1800
|
}
|
|
1510
|
-
|
|
1801
|
+
nodes.push(md.table(null, headerRow, ...dataRows));
|
|
1511
1802
|
};
|
|
1512
1803
|
renderGroup(functions, "Functions & Classes", "api/functions");
|
|
1513
1804
|
renderGroup(types, "Types & Interfaces", "api/types");
|
|
1514
1805
|
renderGroup(others, "Other Exports", "api/functions");
|
|
1515
|
-
return
|
|
1806
|
+
return serializeMarkdown(md.root(...nodes));
|
|
1516
1807
|
}
|
|
1517
1808
|
function renderPackageOverviewPage(packageName, symbols, _options) {
|
|
1518
1809
|
const exported = symbols.filter(
|
|
1519
1810
|
(s) => s.exported && s.kind !== "method" && s.kind !== "property"
|
|
1520
1811
|
);
|
|
1521
1812
|
const pkgDoc = symbols.map((s) => s.documentation?.tags?.packageDocumentation?.[0]).find(Boolean);
|
|
1522
|
-
const
|
|
1813
|
+
const nodes = [];
|
|
1523
1814
|
if (pkgDoc) {
|
|
1524
|
-
|
|
1525
|
-
lines.push("");
|
|
1815
|
+
nodes.push(md.paragraph(...parseInline(pkgDoc)));
|
|
1526
1816
|
}
|
|
1527
1817
|
if (exported.length > 0) {
|
|
1528
1818
|
const functions = exported.filter((s) => FUNCTION_KINDS.has(s.kind));
|
|
@@ -1530,96 +1820,127 @@ function renderPackageOverviewPage(packageName, symbols, _options) {
|
|
|
1530
1820
|
const others = exported.filter((s) => !FUNCTION_KINDS.has(s.kind) && !TYPE_KINDS.has(s.kind));
|
|
1531
1821
|
const renderGroup = (group, heading) => {
|
|
1532
1822
|
if (group.length === 0) return;
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1823
|
+
nodes.push(md.heading(2, md.text(heading)));
|
|
1824
|
+
const headerRow = md.tableRow(
|
|
1825
|
+
md.tableCell(md.text("Symbol")),
|
|
1826
|
+
md.tableCell(md.text("Kind")),
|
|
1827
|
+
md.tableCell(md.text("Description"))
|
|
1828
|
+
);
|
|
1829
|
+
const dataRows = [];
|
|
1537
1830
|
for (const s of group) {
|
|
1538
1831
|
const ext = s.kind === "function" ? "()" : "";
|
|
1539
|
-
const
|
|
1832
|
+
const anchor = toAnchor(`${s.name}${ext}`);
|
|
1540
1833
|
const rawSummary = s.documentation?.summary ?? "";
|
|
1541
|
-
const summary =
|
|
1542
|
-
|
|
1834
|
+
const summary = truncate(rawSummary);
|
|
1835
|
+
dataRows.push(
|
|
1836
|
+
md.tableRow(
|
|
1837
|
+
md.tableCell(
|
|
1838
|
+
md.link(
|
|
1839
|
+
`${slugLink(`packages/${packageName}/api/index`)}#${anchor}`,
|
|
1840
|
+
md.inlineCode(`${s.name}${ext}`)
|
|
1841
|
+
)
|
|
1842
|
+
),
|
|
1843
|
+
md.tableCell(md.text(s.kind)),
|
|
1844
|
+
md.tableCell(...parseInline(summary))
|
|
1845
|
+
)
|
|
1846
|
+
);
|
|
1543
1847
|
}
|
|
1544
|
-
|
|
1848
|
+
nodes.push(md.table(null, headerRow, ...dataRows));
|
|
1545
1849
|
};
|
|
1546
1850
|
renderGroup(functions, "Functions & Classes");
|
|
1547
1851
|
renderGroup(types, "Types & Interfaces");
|
|
1548
1852
|
renderGroup(others, "Other Exports");
|
|
1549
1853
|
}
|
|
1550
|
-
return
|
|
1854
|
+
return serializeMarkdown(md.root(...nodes));
|
|
1551
1855
|
}
|
|
1552
1856
|
function renderTypesPage(packageName, symbols, _options) {
|
|
1553
1857
|
const typeSymbols = symbols.filter((s) => s.exported && TYPE_KINDS.has(s.kind));
|
|
1554
|
-
const
|
|
1555
|
-
|
|
1556
|
-
|
|
1858
|
+
const nodes = [];
|
|
1859
|
+
nodes.push(
|
|
1860
|
+
textP("Type contracts exported by this package: interfaces, type aliases, and enums.")
|
|
1861
|
+
);
|
|
1557
1862
|
for (const s of typeSymbols) {
|
|
1558
|
-
|
|
1559
|
-
lines.push("");
|
|
1863
|
+
nodes.push(md.heading(2, md.text(s.name)));
|
|
1560
1864
|
if (s.documentation?.deprecated) {
|
|
1561
|
-
|
|
1562
|
-
|
|
1865
|
+
nodes.push(
|
|
1866
|
+
md.blockquote(
|
|
1867
|
+
md.paragraph(
|
|
1868
|
+
md.strong(md.text("Deprecated")),
|
|
1869
|
+
md.text(": "),
|
|
1870
|
+
...parseInline(s.documentation.deprecated)
|
|
1871
|
+
)
|
|
1872
|
+
)
|
|
1873
|
+
);
|
|
1563
1874
|
}
|
|
1564
1875
|
if (s.documentation?.summary) {
|
|
1565
|
-
|
|
1566
|
-
lines.push("");
|
|
1876
|
+
nodes.push(md.paragraph(...parseInline(s.documentation.summary)));
|
|
1567
1877
|
}
|
|
1568
1878
|
if (s.signature && s.kind !== "interface") {
|
|
1569
|
-
|
|
1570
|
-
lines.push(s.signature);
|
|
1571
|
-
lines.push("```");
|
|
1572
|
-
lines.push("");
|
|
1879
|
+
nodes.push(md.code("typescript", s.signature));
|
|
1573
1880
|
}
|
|
1574
1881
|
const children = (s.children ?? []).filter((c) => c.kind === "property" || c.kind === "method");
|
|
1575
1882
|
if (children.length > 0) {
|
|
1576
|
-
|
|
1577
|
-
|
|
1883
|
+
const headerRow = md.tableRow(
|
|
1884
|
+
md.tableCell(md.text("Property")),
|
|
1885
|
+
md.tableCell(md.text("Type")),
|
|
1886
|
+
md.tableCell(md.text("Required")),
|
|
1887
|
+
md.tableCell(md.text("Description"))
|
|
1888
|
+
);
|
|
1889
|
+
const dataRows = [];
|
|
1578
1890
|
for (const child of children) {
|
|
1579
|
-
const
|
|
1580
|
-
const type = child.signature ? `\`${escapePipe(child.signature)}\`` : "\u2014";
|
|
1891
|
+
const typePhrasing = child.signature ? md.inlineCode(child.signature) : md.text("\u2014");
|
|
1581
1892
|
const optional = child.signature?.includes("?") || child.signature?.includes("undefined") ? "No" : "Yes";
|
|
1582
|
-
const description =
|
|
1583
|
-
|
|
1893
|
+
const description = child.documentation?.summary || child.name;
|
|
1894
|
+
dataRows.push(
|
|
1895
|
+
md.tableRow(
|
|
1896
|
+
md.tableCell(md.inlineCode(child.name)),
|
|
1897
|
+
md.tableCell(typePhrasing),
|
|
1898
|
+
md.tableCell(md.text(optional)),
|
|
1899
|
+
md.tableCell(...parseInline(description))
|
|
1900
|
+
)
|
|
1901
|
+
);
|
|
1584
1902
|
}
|
|
1585
|
-
|
|
1903
|
+
nodes.push(md.table(null, headerRow, ...dataRows));
|
|
1586
1904
|
}
|
|
1587
1905
|
}
|
|
1588
1906
|
void packageName;
|
|
1589
|
-
return
|
|
1907
|
+
return serializeMarkdown(md.root(...nodes));
|
|
1590
1908
|
}
|
|
1591
1909
|
function renderFunctionsPage(packageName, symbols, _options) {
|
|
1592
1910
|
const fnSymbols = symbols.filter((s) => s.exported && FUNCTION_KINDS.has(s.kind));
|
|
1593
|
-
const
|
|
1594
|
-
|
|
1595
|
-
lines.push("");
|
|
1911
|
+
const nodes = [];
|
|
1912
|
+
nodes.push(textP("Functions and classes exported by this package."));
|
|
1596
1913
|
for (const s of fnSymbols) {
|
|
1597
1914
|
const paramSig = s.kind === "function" && s.documentation?.params ? s.documentation.params.map((p) => p.name).join(", ") : "";
|
|
1598
1915
|
const heading = s.kind === "function" ? `${s.name}(${paramSig})` : s.name;
|
|
1599
|
-
|
|
1600
|
-
lines.push("");
|
|
1916
|
+
nodes.push(md.heading(2, md.text(heading)));
|
|
1601
1917
|
if (s.documentation?.deprecated) {
|
|
1602
|
-
|
|
1603
|
-
|
|
1918
|
+
nodes.push(
|
|
1919
|
+
md.blockquote(
|
|
1920
|
+
md.paragraph(
|
|
1921
|
+
md.strong(md.text("Deprecated")),
|
|
1922
|
+
md.text(": "),
|
|
1923
|
+
...parseInline(s.documentation.deprecated)
|
|
1924
|
+
)
|
|
1925
|
+
)
|
|
1926
|
+
);
|
|
1604
1927
|
}
|
|
1605
1928
|
if (s.documentation?.summary) {
|
|
1606
|
-
|
|
1607
|
-
lines.push("");
|
|
1929
|
+
nodes.push(md.paragraph(...parseInline(s.documentation.summary)));
|
|
1608
1930
|
}
|
|
1609
1931
|
if (s.signature) {
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
lines.push("```typescript");
|
|
1613
|
-
lines.push(s.signature);
|
|
1614
|
-
lines.push("```");
|
|
1615
|
-
lines.push("");
|
|
1932
|
+
nodes.push(md.paragraph(md.strong(md.text("Signature"))));
|
|
1933
|
+
nodes.push(md.code("typescript", s.signature));
|
|
1616
1934
|
}
|
|
1617
1935
|
const params = s.documentation?.params ?? [];
|
|
1618
1936
|
if (params.length > 0) {
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1937
|
+
nodes.push(md.paragraph(md.strong(md.text("Parameters"))));
|
|
1938
|
+
const headerRow = md.tableRow(
|
|
1939
|
+
md.tableCell(md.text("Name")),
|
|
1940
|
+
md.tableCell(md.text("Type")),
|
|
1941
|
+
md.tableCell(md.text("Description"))
|
|
1942
|
+
);
|
|
1943
|
+
const dataRows = [];
|
|
1623
1944
|
for (const p of params) {
|
|
1624
1945
|
let resolvedType = p.type;
|
|
1625
1946
|
if (!resolvedType && s.signature) {
|
|
@@ -1628,183 +1949,254 @@ function renderFunctionsPage(packageName, symbols, _options) {
|
|
|
1628
1949
|
resolvedType = typeMatch[1].trim();
|
|
1629
1950
|
}
|
|
1630
1951
|
}
|
|
1631
|
-
const
|
|
1632
|
-
|
|
1952
|
+
const typePhrasing = resolvedType ? md.inlineCode(resolvedType) : md.text("\u2014");
|
|
1953
|
+
dataRows.push(
|
|
1954
|
+
md.tableRow(
|
|
1955
|
+
md.tableCell(md.inlineCode(p.name)),
|
|
1956
|
+
md.tableCell(typePhrasing),
|
|
1957
|
+
md.tableCell(...parseInline(p.description))
|
|
1958
|
+
)
|
|
1959
|
+
);
|
|
1633
1960
|
}
|
|
1634
|
-
|
|
1961
|
+
nodes.push(md.table(null, headerRow, ...dataRows));
|
|
1635
1962
|
}
|
|
1636
1963
|
if (s.documentation?.returns) {
|
|
1637
|
-
const
|
|
1638
|
-
|
|
1639
|
-
|
|
1964
|
+
const retParts = [md.strong(md.text("Returns"))];
|
|
1965
|
+
if (s.documentation.returns.type) {
|
|
1966
|
+
retParts.push(md.text(" "));
|
|
1967
|
+
retParts.push(md.inlineCode(s.documentation.returns.type));
|
|
1968
|
+
}
|
|
1969
|
+
retParts.push(md.text(" \u2014 "), ...parseInline(s.documentation.returns.description));
|
|
1970
|
+
nodes.push(md.paragraph(...retParts));
|
|
1640
1971
|
}
|
|
1641
1972
|
const throws = s.documentation?.throws ?? [];
|
|
1642
1973
|
if (throws.length > 0) {
|
|
1643
|
-
|
|
1644
|
-
|
|
1974
|
+
nodes.push(md.paragraph(md.strong(md.text("Throws"))));
|
|
1975
|
+
const throwItems = [];
|
|
1645
1976
|
for (const t of throws) {
|
|
1646
|
-
const
|
|
1647
|
-
|
|
1977
|
+
const throwParts = [];
|
|
1978
|
+
if (t.type) {
|
|
1979
|
+
throwParts.push(md.inlineCode(t.type));
|
|
1980
|
+
throwParts.push(md.text(" \u2014 "), ...parseInline(t.description));
|
|
1981
|
+
} else {
|
|
1982
|
+
throwParts.push(...parseInline(t.description));
|
|
1983
|
+
}
|
|
1984
|
+
throwItems.push(md.listItem(md.paragraph(...throwParts)));
|
|
1648
1985
|
}
|
|
1649
|
-
|
|
1986
|
+
nodes.push(md.list(throwItems));
|
|
1650
1987
|
}
|
|
1651
1988
|
const examples = s.documentation?.examples ?? [];
|
|
1652
1989
|
if (examples.length > 0) {
|
|
1653
1990
|
const ex = examples[0];
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
lines.push(`\`\`\`${ex.language || "typescript"}`);
|
|
1657
|
-
lines.push(ex.code.trim());
|
|
1658
|
-
lines.push("```");
|
|
1659
|
-
lines.push("");
|
|
1991
|
+
nodes.push(md.paragraph(md.strong(md.text("Example"))));
|
|
1992
|
+
nodes.push(md.code(ex.language || "typescript", ex.code.trim()));
|
|
1660
1993
|
}
|
|
1661
1994
|
const methods = (s.children ?? []).filter((c) => c.kind === "method");
|
|
1662
1995
|
if (methods.length > 0) {
|
|
1663
|
-
|
|
1664
|
-
lines.push("");
|
|
1996
|
+
nodes.push(md.paragraph(md.strong(md.text("Methods"))));
|
|
1665
1997
|
for (const method of methods) {
|
|
1666
|
-
|
|
1667
|
-
lines.push("");
|
|
1998
|
+
nodes.push(md.heading(3, md.text(`${method.name}()`)));
|
|
1668
1999
|
if (method.documentation?.summary) {
|
|
1669
|
-
|
|
1670
|
-
lines.push("");
|
|
2000
|
+
nodes.push(md.paragraph(...parseInline(method.documentation.summary)));
|
|
1671
2001
|
}
|
|
1672
2002
|
if (method.signature) {
|
|
1673
|
-
|
|
1674
|
-
lines.push(method.signature);
|
|
1675
|
-
lines.push("```");
|
|
1676
|
-
lines.push("");
|
|
2003
|
+
nodes.push(md.code("typescript", method.signature));
|
|
1677
2004
|
}
|
|
1678
2005
|
}
|
|
1679
2006
|
}
|
|
1680
2007
|
}
|
|
1681
2008
|
void packageName;
|
|
1682
|
-
return
|
|
2009
|
+
return serializeMarkdown(md.root(...nodes));
|
|
1683
2010
|
}
|
|
1684
2011
|
function renderExamplesPage(packageName, symbols, _options) {
|
|
1685
2012
|
const exported = symbols.filter(
|
|
1686
2013
|
(s) => s.exported && s.kind !== "method" && s.kind !== "property"
|
|
1687
2014
|
);
|
|
1688
|
-
const
|
|
1689
|
-
|
|
1690
|
-
lines.push("");
|
|
2015
|
+
const nodes = [];
|
|
2016
|
+
nodes.push(textP("All usage examples from the package, aggregated for quick reference."));
|
|
1691
2017
|
let hasExamples = false;
|
|
1692
2018
|
for (const s of exported) {
|
|
1693
2019
|
const examples = s.documentation?.examples ?? [];
|
|
1694
2020
|
if (examples.length === 0) continue;
|
|
1695
2021
|
hasExamples = true;
|
|
1696
2022
|
const ext = s.kind === "function" ? "()" : "";
|
|
1697
|
-
|
|
1698
|
-
lines.push("");
|
|
2023
|
+
nodes.push(md.heading(2, md.inlineCode(`${s.name}${ext}`)));
|
|
1699
2024
|
if (s.documentation?.summary) {
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
2025
|
+
nodes.push(md.paragraph(md.emphasis(...parseInline(s.documentation.summary))));
|
|
2026
|
+
}
|
|
2027
|
+
nodes.push(
|
|
2028
|
+
md.paragraph(
|
|
2029
|
+
md.link(
|
|
2030
|
+
`${slugLink(`packages/${packageName}/api/functions`)}#${toAnchor(s.name)}`,
|
|
2031
|
+
md.text("View in API reference")
|
|
2032
|
+
)
|
|
2033
|
+
)
|
|
1705
2034
|
);
|
|
1706
|
-
lines.push("");
|
|
1707
2035
|
for (const ex of examples) {
|
|
1708
|
-
|
|
1709
|
-
lines.push(ex.code.trim());
|
|
1710
|
-
lines.push("```");
|
|
1711
|
-
lines.push("");
|
|
2036
|
+
nodes.push(md.code(ex.language || "typescript", ex.code.trim()));
|
|
1712
2037
|
}
|
|
1713
2038
|
}
|
|
1714
2039
|
if (!hasExamples) {
|
|
1715
|
-
|
|
1716
|
-
lines.push("");
|
|
2040
|
+
nodes.push(md.paragraph(md.emphasis(md.text("No examples documented yet."))));
|
|
1717
2041
|
}
|
|
1718
|
-
return
|
|
2042
|
+
return serializeMarkdown(md.root(...nodes));
|
|
1719
2043
|
}
|
|
1720
2044
|
function renderConfigurationPage(symbolsByPackage, options) {
|
|
1721
2045
|
const configSymbol = [...symbolsByPackage.values()].flat().find((s) => s.exported && TYPE_KINDS.has(s.kind) && /config/i.test(s.name));
|
|
1722
|
-
const
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
2046
|
+
const nodes = [];
|
|
2047
|
+
nodes.push(
|
|
2048
|
+
md.paragraph(
|
|
2049
|
+
md.text("Configuration reference for "),
|
|
2050
|
+
md.strong(md.text(options.projectName)),
|
|
2051
|
+
md.text(".")
|
|
2052
|
+
)
|
|
2053
|
+
);
|
|
2054
|
+
nodes.push(md.heading(2, md.text("forge-ts.config.ts")));
|
|
2055
|
+
nodes.push(
|
|
2056
|
+
md.paragraph(
|
|
2057
|
+
md.text("Create a "),
|
|
2058
|
+
md.inlineCode("forge-ts.config.ts"),
|
|
2059
|
+
md.text(" file in your project root:")
|
|
2060
|
+
)
|
|
2061
|
+
);
|
|
2062
|
+
nodes.push(
|
|
2063
|
+
md.code(
|
|
2064
|
+
"typescript",
|
|
2065
|
+
[
|
|
2066
|
+
'import { defineConfig } from "@forge-ts/core";',
|
|
2067
|
+
"",
|
|
2068
|
+
"export default defineConfig({",
|
|
2069
|
+
' rootDir: ".",',
|
|
2070
|
+
' outDir: "docs/generated",',
|
|
2071
|
+
"});"
|
|
2072
|
+
].join("\n")
|
|
2073
|
+
)
|
|
2074
|
+
);
|
|
1738
2075
|
if (configSymbol) {
|
|
1739
|
-
|
|
1740
|
-
lines.push("");
|
|
2076
|
+
nodes.push(md.heading(2, md.inlineCode(configSymbol.name)));
|
|
1741
2077
|
if (configSymbol.documentation?.summary) {
|
|
1742
|
-
|
|
1743
|
-
lines.push("");
|
|
2078
|
+
nodes.push(md.paragraph(...parseInline(configSymbol.documentation.summary)));
|
|
1744
2079
|
}
|
|
1745
2080
|
const children = (configSymbol.children ?? []).filter(
|
|
1746
2081
|
(c) => c.kind === "property" || c.kind === "method"
|
|
1747
2082
|
);
|
|
1748
2083
|
if (children.length > 0) {
|
|
1749
|
-
|
|
1750
|
-
|
|
2084
|
+
const headerRow = md.tableRow(
|
|
2085
|
+
md.tableCell(md.text("Property")),
|
|
2086
|
+
md.tableCell(md.text("Type")),
|
|
2087
|
+
md.tableCell(md.text("Required")),
|
|
2088
|
+
md.tableCell(md.text("Description"))
|
|
2089
|
+
);
|
|
2090
|
+
const dataRows = [];
|
|
1751
2091
|
for (const child of children) {
|
|
1752
|
-
const
|
|
1753
|
-
const type = child.signature ? `\`${escapePipe(child.signature)}\`` : "\u2014";
|
|
2092
|
+
const typePhrasing = child.signature ? md.inlineCode(child.signature) : md.text("\u2014");
|
|
1754
2093
|
const optional = child.signature?.includes("?") || child.signature?.includes("undefined") ? "No" : "Yes";
|
|
1755
|
-
const description =
|
|
1756
|
-
|
|
2094
|
+
const description = child.documentation?.summary || child.name;
|
|
2095
|
+
dataRows.push(
|
|
2096
|
+
md.tableRow(
|
|
2097
|
+
md.tableCell(md.inlineCode(child.name)),
|
|
2098
|
+
md.tableCell(typePhrasing),
|
|
2099
|
+
md.tableCell(md.text(optional)),
|
|
2100
|
+
md.tableCell(...parseInline(description))
|
|
2101
|
+
)
|
|
2102
|
+
);
|
|
1757
2103
|
}
|
|
1758
|
-
|
|
2104
|
+
nodes.push(md.table(null, headerRow, ...dataRows));
|
|
1759
2105
|
}
|
|
1760
2106
|
}
|
|
1761
|
-
return
|
|
2107
|
+
return serializeMarkdown(md.root(...nodes));
|
|
1762
2108
|
}
|
|
1763
2109
|
function renderChangelogPage(options) {
|
|
1764
2110
|
const repoUrl = options.repositoryUrl ?? "";
|
|
1765
|
-
const
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
2111
|
+
const nodes = [];
|
|
2112
|
+
nodes.push(
|
|
2113
|
+
md.paragraph(
|
|
2114
|
+
md.text("Release history for "),
|
|
2115
|
+
md.strong(md.text(options.projectName)),
|
|
2116
|
+
md.text(".")
|
|
2117
|
+
)
|
|
2118
|
+
);
|
|
2119
|
+
nodes.push(
|
|
2120
|
+
md.blockquote(textP("This is a stub page. Link to or embed your `CHANGELOG.md` here."))
|
|
2121
|
+
);
|
|
2122
|
+
if (repoUrl) {
|
|
2123
|
+
nodes.push(
|
|
2124
|
+
md.paragraph(
|
|
2125
|
+
md.text("See "),
|
|
2126
|
+
md.link(`${repoUrl}/blob/main/CHANGELOG.md`, md.text("CHANGELOG.md")),
|
|
2127
|
+
md.text(" for the full release history.")
|
|
2128
|
+
)
|
|
2129
|
+
);
|
|
2130
|
+
} else {
|
|
2131
|
+
nodes.push(
|
|
2132
|
+
md.paragraph(
|
|
2133
|
+
md.text("See your project's "),
|
|
2134
|
+
md.inlineCode("CHANGELOG.md"),
|
|
2135
|
+
md.text(" for the full release history.")
|
|
2136
|
+
)
|
|
2137
|
+
);
|
|
2138
|
+
}
|
|
2139
|
+
return serializeMarkdown(md.root(...nodes));
|
|
1774
2140
|
}
|
|
1775
2141
|
function renderFaqPage(options) {
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
"
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
2142
|
+
const nodes = [];
|
|
2143
|
+
nodes.push(
|
|
2144
|
+
md.paragraph(
|
|
2145
|
+
md.text("Frequently asked questions about "),
|
|
2146
|
+
md.strong(md.text(options.projectName)),
|
|
2147
|
+
md.text(".")
|
|
2148
|
+
)
|
|
2149
|
+
);
|
|
2150
|
+
nodes.push(
|
|
2151
|
+
md.blockquote(textP("This is a stub page. Common questions will be added here as they arise."))
|
|
2152
|
+
);
|
|
2153
|
+
nodes.push(md.heading(2, md.text("How do I configure forge-ts?")));
|
|
2154
|
+
nodes.push(
|
|
2155
|
+
md.paragraph(
|
|
2156
|
+
md.text("Create a "),
|
|
2157
|
+
md.inlineCode("forge-ts.config.ts"),
|
|
2158
|
+
md.text(" file in your project root. See "),
|
|
2159
|
+
md.link("/configuration", md.text("Configuration")),
|
|
2160
|
+
md.text(".")
|
|
2161
|
+
)
|
|
2162
|
+
);
|
|
2163
|
+
nodes.push(md.heading(2, md.text("What TypeScript version is required?")));
|
|
2164
|
+
nodes.push(textP("forge-ts requires TypeScript 5.0 or later."));
|
|
2165
|
+
nodes.push(md.heading(2, md.text("How do I run @example blocks as tests?")));
|
|
2166
|
+
nodes.push(md.code("bash", "npx forge-ts test"));
|
|
2167
|
+
return serializeMarkdown(md.root(...nodes));
|
|
1796
2168
|
}
|
|
1797
2169
|
function renderContributingPage(options) {
|
|
1798
2170
|
const repoUrl = options.repositoryUrl ?? "";
|
|
1799
|
-
const
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
2171
|
+
const nodes = [];
|
|
2172
|
+
nodes.push(
|
|
2173
|
+
md.paragraph(
|
|
2174
|
+
md.text("Contributing to "),
|
|
2175
|
+
md.strong(md.text(options.projectName)),
|
|
2176
|
+
md.text(".")
|
|
2177
|
+
)
|
|
2178
|
+
);
|
|
2179
|
+
nodes.push(
|
|
2180
|
+
md.blockquote(textP("This is a stub page. Link to or embed your `CONTRIBUTING.md` here."))
|
|
2181
|
+
);
|
|
2182
|
+
if (repoUrl) {
|
|
2183
|
+
nodes.push(
|
|
2184
|
+
md.paragraph(
|
|
2185
|
+
md.text("See "),
|
|
2186
|
+
md.link(`${repoUrl}/blob/main/CONTRIBUTING.md`, md.text("CONTRIBUTING.md")),
|
|
2187
|
+
md.text(" for contribution guidelines.")
|
|
2188
|
+
)
|
|
2189
|
+
);
|
|
2190
|
+
} else {
|
|
2191
|
+
nodes.push(
|
|
2192
|
+
md.paragraph(
|
|
2193
|
+
md.text("See your project's "),
|
|
2194
|
+
md.inlineCode("CONTRIBUTING.md"),
|
|
2195
|
+
md.text(" for contribution guidelines.")
|
|
2196
|
+
)
|
|
2197
|
+
);
|
|
2198
|
+
}
|
|
2199
|
+
return serializeMarkdown(md.root(...nodes));
|
|
1808
2200
|
}
|
|
1809
2201
|
function generateDocSite(symbolsByPackage, config, options) {
|
|
1810
2202
|
const ext = options.format === "mdx" ? "mdx" : "md";
|
|
@@ -2679,39 +3071,6 @@ import { existsSync as existsSync2 } from "fs";
|
|
|
2679
3071
|
import { mkdir, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
2680
3072
|
import { dirname, join } from "path";
|
|
2681
3073
|
import { createWalker } from "@forge-ts/core";
|
|
2682
|
-
function updateAutoSections(existing, generated) {
|
|
2683
|
-
const htmlPattern = /<!-- FORGE:AUTO-START (\S+) -->([\s\S]*?)<!-- FORGE:AUTO-END \1 -->/g;
|
|
2684
|
-
const mdxGenPattern = /\{\/\*\s*FORGE:AUTO-START (\S+)\s*\*\/\}([\s\S]*?)\{\/\*\s*FORGE:AUTO-END \1\s*\*\/\}/g;
|
|
2685
|
-
const newSections = /* @__PURE__ */ new Map();
|
|
2686
|
-
let match;
|
|
2687
|
-
while ((match = htmlPattern.exec(generated)) !== null) {
|
|
2688
|
-
newSections.set(match[1], match[0]);
|
|
2689
|
-
}
|
|
2690
|
-
while ((match = mdxGenPattern.exec(generated)) !== null) {
|
|
2691
|
-
if (!newSections.has(match[1])) {
|
|
2692
|
-
newSections.set(match[1], match[0]);
|
|
2693
|
-
}
|
|
2694
|
-
}
|
|
2695
|
-
if (newSections.size === 0) return null;
|
|
2696
|
-
let updated = existing;
|
|
2697
|
-
let changed = false;
|
|
2698
|
-
for (const [id, replacement] of newSections) {
|
|
2699
|
-
const htmlSectionPattern = new RegExp(
|
|
2700
|
-
`<!-- FORGE:AUTO-START ${id} -->[\\s\\S]*?<!-- FORGE:AUTO-END ${id} -->`
|
|
2701
|
-
);
|
|
2702
|
-
const mdxSectionPattern = new RegExp(
|
|
2703
|
-
`\\{/\\*\\s*FORGE:AUTO-START ${id}\\s*\\*/\\}[\\s\\S]*?\\{/\\*\\s*FORGE:AUTO-END ${id}\\s*\\*/\\}`
|
|
2704
|
-
);
|
|
2705
|
-
if (htmlSectionPattern.test(updated)) {
|
|
2706
|
-
updated = updated.replace(htmlSectionPattern, replacement);
|
|
2707
|
-
changed = true;
|
|
2708
|
-
} else if (mdxSectionPattern.test(updated)) {
|
|
2709
|
-
updated = updated.replace(mdxSectionPattern, replacement);
|
|
2710
|
-
changed = true;
|
|
2711
|
-
}
|
|
2712
|
-
}
|
|
2713
|
-
return changed ? updated : null;
|
|
2714
|
-
}
|
|
2715
3074
|
async function generate(config, options) {
|
|
2716
3075
|
const start = Date.now();
|
|
2717
3076
|
const forceStubs = options?.forceStubs ?? false;
|
|
@@ -2824,7 +3183,18 @@ export {
|
|
|
2824
3183
|
getAdapter,
|
|
2825
3184
|
getAvailableTargets,
|
|
2826
3185
|
groupSymbolsByPackage,
|
|
3186
|
+
md,
|
|
3187
|
+
parseBlocks,
|
|
3188
|
+
parseFrontmatter,
|
|
3189
|
+
parseInline,
|
|
2827
3190
|
registerAdapter,
|
|
2828
|
-
|
|
3191
|
+
sanitizeForMdx,
|
|
3192
|
+
serializeMarkdown,
|
|
3193
|
+
slugLink,
|
|
3194
|
+
stringifyWithFrontmatter,
|
|
3195
|
+
stripFrontmatter,
|
|
3196
|
+
syncReadme,
|
|
3197
|
+
toAnchor,
|
|
3198
|
+
truncate
|
|
2829
3199
|
};
|
|
2830
3200
|
//# sourceMappingURL=index.js.map
|