rspress-plugin-api-extractor 0.14.0 → 0.15.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/BuildEnv.js +0 -1
- package/build-program.js +4 -4
- package/build-stages.js +98 -281
- package/config-helpers.js +1 -1
- package/emit/mdx.js +311 -0
- package/emit/meta.js +62 -0
- package/index.d.ts +1 -42
- package/layers/build-metrics.js +1 -2
- package/layers/config-resolution.js +3 -5
- package/layers/type-environment.js +1 -2
- package/llms-program.js +3 -3
- package/markdown/helpers.js +10 -176
- package/observability/sinks/console-sink.js +0 -1
- package/observability/sinks/metrics-sink.js +0 -2
- package/package.json +6 -5
- package/path-derivation.js +1 -29
- package/plugin.js +2 -1
- package/prettier-formatter.js +27 -59
- package/remark-with-api.js +3 -2
- package/schemas/config.js +1 -18
- package/schemas/observability.js +0 -2
- package/schemas/performance.js +0 -1
- package/services/TwoslashCacheService.js +1 -1
- package/twoslash-transformer.js +14 -2
- package/code-post-processor.js +0 -38
- package/llms-processing.js +0 -270
- package/markdown/page-generators/class-page.js +0 -363
- package/markdown/page-generators/enum-page.js +0 -152
- package/markdown/page-generators/function-page.js +0 -127
- package/markdown/page-generators/index-pages.js +0 -25
- package/markdown/page-generators/interface-page.js +0 -310
- package/markdown/page-generators/namespace-page.js +0 -277
- package/markdown/page-generators/type-alias-page.js +0 -110
- package/markdown/page-generators/variable-page.js +0 -110
- package/markdown/prose-linker.js +0 -22
- package/twoslash-cache.js +0 -174
- package/twoslash-patterns.js +0 -87
package/emit/mdx.js
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { Result } from "effect";
|
|
2
|
+
import { Blockquote, Code, Heading, InlineCode, Link, List, ListItem, Markdown, MdxJsxAttribute, MdxJsxAttributeValueExpression, MdxJsxFlowElement, MdxjsEsm, Paragraph, Root, Strong, Text } from "@effected/markdown";
|
|
3
|
+
|
|
4
|
+
//#region src/emit/mdx.ts
|
|
5
|
+
/** Serialize one flow node as its own document, without the trailing newline. */
|
|
6
|
+
function serialize(node) {
|
|
7
|
+
return Result.map(Markdown.stringifyResult(Root.make({ children: [node] })), (text) => text.replace(/\n$/, ""));
|
|
8
|
+
}
|
|
9
|
+
/** Serialize phrasing content to the one-line string a JSX prop or a table cell carries. */
|
|
10
|
+
function inlineText(children) {
|
|
11
|
+
if (children.length === 0) return Result.succeed("");
|
|
12
|
+
return serialize(Paragraph.make({ children: [...children] }));
|
|
13
|
+
}
|
|
14
|
+
const GENERICS = /<([A-Z][A-Za-z0-9_]*(?:\s+extends\s+[^,>\s][^,>]*)?(?:,\s*[A-Z][A-Za-z0-9_]*(?:\s+extends\s+[^,>\s][^,>]*)?)*)>/g;
|
|
15
|
+
/**
|
|
16
|
+
* {@link escapeMdxGenerics} as an mdast transform: a generic parameter list
|
|
17
|
+
* in a text run becomes an inline code node, and a raw-HTML node that IS a
|
|
18
|
+
* generic (`<T>` parses as an HTML tag) becomes one too. Code spans are
|
|
19
|
+
* already inline code and are left alone; container nodes are walked.
|
|
20
|
+
*
|
|
21
|
+
* @remarks
|
|
22
|
+
* Done on the tree rather than on the serialized string because the kit
|
|
23
|
+
* escapes a bare `<` in text (`Map\<K, V\>`) as it serializes, and the
|
|
24
|
+
* string-level regex would no longer see the generic. The two spellings are
|
|
25
|
+
* the same MDX; the tree form is what lets the kit own every byte.
|
|
26
|
+
*/
|
|
27
|
+
function escapeGenericsInPhrasing(children) {
|
|
28
|
+
const out = [];
|
|
29
|
+
for (const node of children) if (node.type === "text") {
|
|
30
|
+
let last = 0;
|
|
31
|
+
for (const match of node.value.matchAll(GENERICS)) {
|
|
32
|
+
const index = match.index ?? 0;
|
|
33
|
+
if (index > last) out.push(Text.make({ value: node.value.slice(last, index) }));
|
|
34
|
+
out.push(InlineCode.make({ value: match[0] }));
|
|
35
|
+
last = index + match[0].length;
|
|
36
|
+
}
|
|
37
|
+
if (last === 0) out.push(node);
|
|
38
|
+
else if (last < node.value.length) out.push(Text.make({ value: node.value.slice(last) }));
|
|
39
|
+
} else if (node.type === "html" && new RegExp(`^${GENERICS.source}$`).test(node.value)) out.push(InlineCode.make({ value: node.value }));
|
|
40
|
+
else if (node.type === "link" || node.type === "strong" || node.type === "emphasis" || node.type === "delete") out.push({
|
|
41
|
+
...node,
|
|
42
|
+
children: [...escapeGenericsInPhrasing(node.children)]
|
|
43
|
+
});
|
|
44
|
+
else out.push(node);
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
/** Phrasing content with generics escaped — the tree form of {@link escapeMdxGenerics}. */
|
|
48
|
+
function escapedPhrasing(children) {
|
|
49
|
+
return Result.succeed(escapeGenericsInPhrasing(children));
|
|
50
|
+
}
|
|
51
|
+
const text = (value) => Text.make({ value });
|
|
52
|
+
const paragraph = (children) => Paragraph.make({ children: [...children] });
|
|
53
|
+
const heading = (depth, value) => Heading.make({
|
|
54
|
+
depth,
|
|
55
|
+
children: [text(value)]
|
|
56
|
+
});
|
|
57
|
+
const code = (value) => InlineCode.make({ value });
|
|
58
|
+
const expression = (name, value) => MdxJsxAttribute.make({
|
|
59
|
+
name,
|
|
60
|
+
value: MdxJsxAttributeValueExpression.make({ value: JSON.stringify(value) })
|
|
61
|
+
});
|
|
62
|
+
const literal = (name, value) => MdxJsxAttribute.make({
|
|
63
|
+
name,
|
|
64
|
+
value
|
|
65
|
+
});
|
|
66
|
+
const element = (name, attributes, children = []) => MdxJsxFlowElement.make({
|
|
67
|
+
name,
|
|
68
|
+
attributes: [...attributes],
|
|
69
|
+
children: [...children]
|
|
70
|
+
});
|
|
71
|
+
var Body = class {
|
|
72
|
+
chunks = [];
|
|
73
|
+
failure;
|
|
74
|
+
push(node, trailing = "\n\n") {
|
|
75
|
+
if (this.failure) return;
|
|
76
|
+
const result = serialize(node);
|
|
77
|
+
if (Result.isFailure(result)) {
|
|
78
|
+
this.failure = result.failure;
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
this.chunks.push({
|
|
82
|
+
text: result.success,
|
|
83
|
+
trailing
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/** Push a heading. */
|
|
87
|
+
heading(depth, value) {
|
|
88
|
+
this.push(heading(depth, value));
|
|
89
|
+
}
|
|
90
|
+
pushResult(result, use) {
|
|
91
|
+
if (this.failure) return;
|
|
92
|
+
if (Result.isFailure(result)) {
|
|
93
|
+
this.failure = result.failure;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
use(result.success);
|
|
97
|
+
}
|
|
98
|
+
render() {
|
|
99
|
+
if (this.failure) return Result.fail(this.failure);
|
|
100
|
+
return Result.succeed(this.chunks.map((chunk) => chunk.text + chunk.trailing).join(""));
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
const RUNTIME = "rspress-plugin-api-extractor/runtime";
|
|
104
|
+
/** The component import lines each page kind carried. */
|
|
105
|
+
function importLines(kind) {
|
|
106
|
+
const lines = [`import { SourceCode } from "@rspress/core/theme";`];
|
|
107
|
+
if (kind === "enum") lines.push(`import { EnumMembersTable } from "${RUNTIME}";`);
|
|
108
|
+
else if (kind !== "namespace") lines.push(`import { ParametersTable } from "${RUNTIME}";`);
|
|
109
|
+
const components = kind === "class" || kind === "interface" ? "ApiSignature, ApiMember, ApiExample" : "ApiSignature, ApiExample";
|
|
110
|
+
lines.push(`import { ${components} } from "${RUNTIME}";`);
|
|
111
|
+
return lines.join("\n");
|
|
112
|
+
}
|
|
113
|
+
function parameterRows(rows, escapeGenerics) {
|
|
114
|
+
return Result.all(rows.map((row) => Result.map(inlineText(escapeGenerics ? escapeGenericsInPhrasing(row.description) : row.description), (description) => ({
|
|
115
|
+
name: row.name,
|
|
116
|
+
...row.type !== void 0 ? { type: row.type } : {},
|
|
117
|
+
description
|
|
118
|
+
}))));
|
|
119
|
+
}
|
|
120
|
+
function enumRows(rows) {
|
|
121
|
+
return Result.all(rows.map((row) => Result.map(inlineText(row.description), (description) => ({
|
|
122
|
+
name: row.name,
|
|
123
|
+
...row.value !== void 0 ? { value: row.value } : {},
|
|
124
|
+
description
|
|
125
|
+
}))));
|
|
126
|
+
}
|
|
127
|
+
/** The literal `memberName` a role fixes, or none when the member's own name is spent as an expression. */
|
|
128
|
+
function fixedMemberName(member) {
|
|
129
|
+
switch (member.role) {
|
|
130
|
+
case "constructor": return "constructor";
|
|
131
|
+
case "call-signature": return "Call Signature";
|
|
132
|
+
case "construct-signature": return "Construct Signature";
|
|
133
|
+
case "index-signature": return "Index Signature";
|
|
134
|
+
default: return;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/** Whether the role carried a `hasParameters` prop — constructors and methods, never properties or signatures. */
|
|
138
|
+
function carriesHasParameters(member) {
|
|
139
|
+
return member.role === "constructor" || member.role === "method" || member.role === "getter";
|
|
140
|
+
}
|
|
141
|
+
function emitMember(body, member, apiScope) {
|
|
142
|
+
body.pushResult(member.summary ? escapedPhrasing(member.summary) : Result.succeed(void 0), (summaryNodes) => {
|
|
143
|
+
body.pushResult(summaryNodes ? inlineText(summaryNodes) : Result.succeed(""), (summary) => {
|
|
144
|
+
const fixedName = fixedMemberName(member);
|
|
145
|
+
const attributes = [
|
|
146
|
+
expression("code", member.code.display),
|
|
147
|
+
expression("source", member.code.source),
|
|
148
|
+
expression("apiScope", apiScope),
|
|
149
|
+
fixedName !== void 0 ? literal("memberName", fixedName) : expression("memberName", member.name)
|
|
150
|
+
];
|
|
151
|
+
if (summary) attributes.push(expression("summary", summary));
|
|
152
|
+
attributes.push(expression("id", member.anchor));
|
|
153
|
+
if (carriesHasParameters(member)) attributes.push(expression("hasParameters", member.parameters !== void 0));
|
|
154
|
+
body.push(element("ApiMember", attributes));
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
if (member.parameters !== void 0) body.pushResult(parameterRows(member.parameters, false), (rows) => {
|
|
158
|
+
body.push(element("ParametersTable", [expression("parameters", rows)]));
|
|
159
|
+
});
|
|
160
|
+
if (member.returns !== void 0) body.pushResult(escapedPhrasing(member.returns), (returns) => {
|
|
161
|
+
body.push(paragraph([
|
|
162
|
+
Strong.make({ children: [text("Returns:")] }),
|
|
163
|
+
text(" "),
|
|
164
|
+
...returns
|
|
165
|
+
]));
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
function emitBlock(body, block, page, options) {
|
|
169
|
+
const { apiScope } = options;
|
|
170
|
+
switch (block.kind) {
|
|
171
|
+
case "title":
|
|
172
|
+
body.heading(1, block.name);
|
|
173
|
+
if (block.deprecation !== void 0) body.pushResult(escapedPhrasing(block.deprecation), (message) => {
|
|
174
|
+
body.push(Blockquote.make({ children: [paragraph([
|
|
175
|
+
text("⚠️ "),
|
|
176
|
+
Strong.make({ children: [text("Deprecated:")] }),
|
|
177
|
+
text(" "),
|
|
178
|
+
...message
|
|
179
|
+
])] }));
|
|
180
|
+
});
|
|
181
|
+
if (block.releaseTag !== "Public") body.push(paragraph([code(block.releaseTag)]));
|
|
182
|
+
return;
|
|
183
|
+
case "prose":
|
|
184
|
+
if (block.role === "summary") {
|
|
185
|
+
for (const node of block.content) body.push(node);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
body.heading(2, block.role === "remarks" ? "Remarks" : "Returns");
|
|
189
|
+
for (const node of block.content) if (block.role === "returns" && node.type === "paragraph") body.pushResult(escapedPhrasing(node.children), (children) => body.push(paragraph(children)));
|
|
190
|
+
else body.push(node);
|
|
191
|
+
return;
|
|
192
|
+
case "available-from": {
|
|
193
|
+
const children = [text("Available from: ")];
|
|
194
|
+
block.entryPoints.forEach((entryPoint, index) => {
|
|
195
|
+
if (index > 0) children.push(text(", "));
|
|
196
|
+
children.push(code(entryPoint === "default" ? block.packageName : `${block.packageName}/${entryPoint}`));
|
|
197
|
+
});
|
|
198
|
+
body.push(paragraph(children));
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
case "source-link": {
|
|
202
|
+
const children = [element("div", [literal("className", "api-docs-toolbar-left")], [element("SourceCode", [literal("href", block.href)])])];
|
|
203
|
+
if (options.llmsEnabled) children.push(element("div", [literal("className", "api-docs-toolbar-right")]));
|
|
204
|
+
body.push(element("div", [literal("className", "api-docs-toolbar")], children));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
case "signature": {
|
|
208
|
+
const attributes = [
|
|
209
|
+
expression("code", block.code.display),
|
|
210
|
+
expression("source", block.code.source),
|
|
211
|
+
expression("apiScope", apiScope)
|
|
212
|
+
];
|
|
213
|
+
if (block.hasParameters !== void 0) attributes.push(expression("hasParameters", block.hasParameters));
|
|
214
|
+
if (block.hasMembers !== void 0) attributes.push(expression("hasMembers", block.hasMembers));
|
|
215
|
+
body.push(element("ApiSignature", attributes), block.hasMembers === true ? "\n" : "\n\n");
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
case "base-class":
|
|
219
|
+
body.heading(2, "Base Class");
|
|
220
|
+
body.push(paragraph([
|
|
221
|
+
code(block.className),
|
|
222
|
+
text(" extends "),
|
|
223
|
+
code(block.baseName),
|
|
224
|
+
text(", a compiler-generated declaration that is not exported from "),
|
|
225
|
+
code(block.packageName),
|
|
226
|
+
text(".")
|
|
227
|
+
]));
|
|
228
|
+
body.push(element("ApiSignature", [
|
|
229
|
+
expression("code", block.code.display),
|
|
230
|
+
expression("source", block.code.source),
|
|
231
|
+
expression("apiScope", apiScope)
|
|
232
|
+
]));
|
|
233
|
+
return;
|
|
234
|
+
case "member-group":
|
|
235
|
+
body.heading(2, block.title);
|
|
236
|
+
for (const member of block.members) emitMember(body, member, apiScope);
|
|
237
|
+
return;
|
|
238
|
+
case "parameters":
|
|
239
|
+
body.pushResult(parameterRows(block.rows, true), (rows) => {
|
|
240
|
+
body.push(element("ParametersTable", [expression("parameters", rows)]));
|
|
241
|
+
});
|
|
242
|
+
return;
|
|
243
|
+
case "enum-members":
|
|
244
|
+
body.pushResult(enumRows(block.rows), (rows) => {
|
|
245
|
+
body.push(element("EnumMembersTable", [expression("members", rows)]));
|
|
246
|
+
});
|
|
247
|
+
return;
|
|
248
|
+
case "examples":
|
|
249
|
+
body.heading(2, "Examples");
|
|
250
|
+
for (const example of block.items) if (example.typeChecked) body.push(element("ApiExample", [
|
|
251
|
+
expression("code", example.code.display),
|
|
252
|
+
expression("source", example.code.source),
|
|
253
|
+
expression("apiScope", apiScope)
|
|
254
|
+
]));
|
|
255
|
+
else body.push(Code.make({
|
|
256
|
+
value: example.code.display,
|
|
257
|
+
lang: example.language
|
|
258
|
+
}));
|
|
259
|
+
return;
|
|
260
|
+
case "see-also":
|
|
261
|
+
body.heading(2, "See Also");
|
|
262
|
+
body.pushResult(Result.all(block.references.map(escapedPhrasing)), (references) => {
|
|
263
|
+
body.push(List.make({
|
|
264
|
+
ordered: false,
|
|
265
|
+
spread: false,
|
|
266
|
+
children: references.map((reference) => ListItem.make({
|
|
267
|
+
spread: false,
|
|
268
|
+
children: [paragraph(reference)]
|
|
269
|
+
}))
|
|
270
|
+
}));
|
|
271
|
+
});
|
|
272
|
+
return;
|
|
273
|
+
case "member-index":
|
|
274
|
+
body.heading(2, block.title);
|
|
275
|
+
body.pushResult(Result.all(block.entries.map((entry) => entry.summary ? escapedPhrasing(entry.summary) : Result.succeed(void 0))), (summaries) => {
|
|
276
|
+
const items = block.entries.map((entry, index) => {
|
|
277
|
+
const children = [Link.make({
|
|
278
|
+
url: entry.route,
|
|
279
|
+
children: [text(entry.name)]
|
|
280
|
+
})];
|
|
281
|
+
const summary = summaries[index];
|
|
282
|
+
if (summary !== void 0) children.push(text(" - "), ...summary);
|
|
283
|
+
return ListItem.make({
|
|
284
|
+
spread: false,
|
|
285
|
+
children: [paragraph(children)]
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
body.push(List.make({
|
|
289
|
+
ordered: false,
|
|
290
|
+
spread: false,
|
|
291
|
+
children: items
|
|
292
|
+
}));
|
|
293
|
+
});
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Emit a page's MDX body: the component import lines followed by every
|
|
299
|
+
* block, joined as the generators joined them. No frontmatter — the adapter
|
|
300
|
+
* assembles that from the page facts, in the generate stage the snapshot
|
|
301
|
+
* hash is taken in.
|
|
302
|
+
*/
|
|
303
|
+
function emitMdxBody(page, options) {
|
|
304
|
+
const body = new Body();
|
|
305
|
+
body.push(MdxjsEsm.make({ value: importLines(page.kind) }));
|
|
306
|
+
for (const block of page.blocks) emitBlock(body, block, page, options);
|
|
307
|
+
return body.render();
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
//#endregion
|
|
311
|
+
export { emitMdxBody };
|
package/emit/meta.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { emitFrontmatterBlock } from "@tsdoctor/model";
|
|
2
|
+
|
|
3
|
+
//#region src/emit/meta.ts
|
|
4
|
+
/**
|
|
5
|
+
* The RSPress navigation and landing-page emitters: the root and
|
|
6
|
+
* per-category `_meta.json` files rendered from a `@tsdoctor/pages`
|
|
7
|
+
* {@link NavTree}, and the `index.mdx` frontmatter rendered from an
|
|
8
|
+
* {@link IndexPage}.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* Pure functions of the IR. The renderer defaults (`collapsible` and
|
|
12
|
+
* `collapsed` true, `overviewHeaders` `[2]`) are RSPress sidebar policy the
|
|
13
|
+
* tree leaves to its consumer; the tab-indented JSON is the spelling the
|
|
14
|
+
* snapshot system compares an existing file against.
|
|
15
|
+
*
|
|
16
|
+
* @packageDocumentation
|
|
17
|
+
*/
|
|
18
|
+
/** The root `_meta.json` entries, one per category group that received a page. */
|
|
19
|
+
function rootMetaEntries(tree) {
|
|
20
|
+
return tree.groups.map((group) => ({
|
|
21
|
+
type: "dir",
|
|
22
|
+
name: group.category.folderName,
|
|
23
|
+
label: group.category.displayName,
|
|
24
|
+
collapsible: group.category.collapsible ?? true,
|
|
25
|
+
collapsed: group.category.collapsed ?? true,
|
|
26
|
+
overviewHeaders: group.category.overviewHeaders ?? [2]
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
/** A category folder's `_meta.json` entries, in the tree's (label-sorted) order. */
|
|
30
|
+
function categoryMetaEntries(group) {
|
|
31
|
+
return group.pages.map((page) => ({
|
|
32
|
+
type: "file",
|
|
33
|
+
name: page.name,
|
|
34
|
+
label: page.label
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
/** Serialize `_meta.json` entries the way the plugin always has: tab-indented JSON, no trailing newline. */
|
|
38
|
+
function renderMeta(entries) {
|
|
39
|
+
return JSON.stringify(entries, null, " ");
|
|
40
|
+
}
|
|
41
|
+
/** The root `_meta.json` text for an API. */
|
|
42
|
+
function renderRootMeta(tree) {
|
|
43
|
+
return renderMeta(rootMetaEntries(tree));
|
|
44
|
+
}
|
|
45
|
+
/** A category folder's `_meta.json` text. */
|
|
46
|
+
function renderCategoryMeta(group) {
|
|
47
|
+
return renderMeta(categoryMetaEntries(group));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The `index.mdx` text for an API: frontmatter only, with RSPress's
|
|
51
|
+
* `overview: true` so the page lists its category folders.
|
|
52
|
+
*/
|
|
53
|
+
function emitIndexPage(index) {
|
|
54
|
+
return emitFrontmatterBlock({
|
|
55
|
+
title: index.title,
|
|
56
|
+
description: index.description,
|
|
57
|
+
overview: true
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
//#endregion
|
|
62
|
+
export { categoryMetaEntries, emitIndexPage, renderCategoryMeta, renderMeta, renderRootMeta, rootMetaEntries };
|
package/index.d.ts
CHANGED
|
@@ -12,14 +12,6 @@ import "unified";
|
|
|
12
12
|
import "vfile";
|
|
13
13
|
import "react";
|
|
14
14
|
//#region src/schemas/config.d.ts
|
|
15
|
-
/**
|
|
16
|
-
* Verbosity level for plugin build output.
|
|
17
|
-
*
|
|
18
|
-
* @public
|
|
19
|
-
*/
|
|
20
|
-
declare const LogLevel: Schema.Literals<readonly ["none", "info", "verbose", "debug", "warn", "error"]>;
|
|
21
|
-
/** @public */
|
|
22
|
-
type LogLevel = typeof LogLevel.Type;
|
|
23
15
|
/**
|
|
24
16
|
* Configuration for a single documentation category (e.g. Classes, Functions).
|
|
25
17
|
*
|
|
@@ -34,8 +26,6 @@ declare const CategoryConfig: Schema.Struct<{
|
|
|
34
26
|
readonly folderName: Schema.String;
|
|
35
27
|
/** API item kinds included in this category. */
|
|
36
28
|
readonly itemKinds: Schema.optional<Schema.mutable<Schema.$Array<Schema.declare<ApiItemKind, ApiItemKind>>>>;
|
|
37
|
-
/** TSDoc modifier tag that marks items for this category. */
|
|
38
|
-
readonly tsdocModifier: Schema.optional<Schema.String>;
|
|
39
29
|
/** Whether the sidebar section is collapsible. Defaults to `true`. */
|
|
40
30
|
readonly collapsible: Schema.withDecodingDefault<Schema.Boolean, never>;
|
|
41
31
|
/** Whether the sidebar section starts collapsed. Defaults to `true`. */
|
|
@@ -90,8 +80,6 @@ declare const VersionConfig: Schema.Struct<{
|
|
|
90
80
|
readonly folderName: Schema.String;
|
|
91
81
|
/** API item kinds included in this category. */
|
|
92
82
|
readonly itemKinds: Schema.optional<Schema.mutable<Schema.$Array<Schema.declare<ApiItemKind, ApiItemKind>>>>;
|
|
93
|
-
/** TSDoc modifier tag that marks items for this category. */
|
|
94
|
-
readonly tsdocModifier: Schema.optional<Schema.String>;
|
|
95
83
|
/** Whether the sidebar section is collapsible. Defaults to `true`. */
|
|
96
84
|
readonly collapsible: Schema.withDecodingDefault<Schema.Boolean, never>;
|
|
97
85
|
/** Whether the sidebar section starts collapsed. Defaults to `true`. */
|
|
@@ -110,8 +98,6 @@ declare const VersionConfig: Schema.Struct<{
|
|
|
110
98
|
readonly externalPackages: Schema.optional<Schema.mutable<Schema.$Array<Schema.Struct<{
|
|
111
99
|
readonly name: Schema.String;
|
|
112
100
|
readonly version: Schema.String;
|
|
113
|
-
readonly tsconfig: Schema.optional<Schema.declare<string | URL | ((...args: Array<unknown>) => unknown), string | URL | ((...args: Array<unknown>) => unknown)>>;
|
|
114
|
-
readonly compilerOptions: Schema.optional<Schema.Unknown>;
|
|
115
101
|
}>>>>;
|
|
116
102
|
/** Auto-detect external packages from `package.json` dependency fields. */
|
|
117
103
|
readonly autoDetectDependencies: Schema.optional<Schema.Struct<{
|
|
@@ -176,8 +162,6 @@ declare const SingleApiConfig: Schema.Struct<{
|
|
|
176
162
|
readonly folderName: Schema.String;
|
|
177
163
|
/** API item kinds included in this category. */
|
|
178
164
|
readonly itemKinds: Schema.optional<Schema.mutable<Schema.$Array<Schema.declare<ApiItemKind, ApiItemKind>>>>;
|
|
179
|
-
/** TSDoc modifier tag that marks items for this category. */
|
|
180
|
-
readonly tsdocModifier: Schema.optional<Schema.String>;
|
|
181
165
|
/** Whether the sidebar section is collapsible. Defaults to `true`. */
|
|
182
166
|
readonly collapsible: Schema.withDecodingDefault<Schema.Boolean, never>;
|
|
183
167
|
/** Whether the sidebar section starts collapsed. Defaults to `true`. */
|
|
@@ -196,8 +180,6 @@ declare const SingleApiConfig: Schema.Struct<{
|
|
|
196
180
|
readonly externalPackages: Schema.optional<Schema.mutable<Schema.$Array<Schema.Struct<{
|
|
197
181
|
readonly name: Schema.String;
|
|
198
182
|
readonly version: Schema.String;
|
|
199
|
-
readonly tsconfig: Schema.optional<Schema.declare<string | URL | ((...args: Array<unknown>) => unknown), string | URL | ((...args: Array<unknown>) => unknown)>>;
|
|
200
|
-
readonly compilerOptions: Schema.optional<Schema.Unknown>;
|
|
201
183
|
}>>>>;
|
|
202
184
|
/** Auto-detect external packages from `package.json` dependency fields. */
|
|
203
185
|
readonly autoDetectDependencies: Schema.optional<Schema.Struct<{
|
|
@@ -241,8 +223,6 @@ declare const SingleApiConfig: Schema.Struct<{
|
|
|
241
223
|
readonly folderName: Schema.String;
|
|
242
224
|
/** API item kinds included in this category. */
|
|
243
225
|
readonly itemKinds: Schema.optional<Schema.mutable<Schema.$Array<Schema.declare<ApiItemKind, ApiItemKind>>>>;
|
|
244
|
-
/** TSDoc modifier tag that marks items for this category. */
|
|
245
|
-
readonly tsdocModifier: Schema.optional<Schema.String>;
|
|
246
226
|
/** Whether the sidebar section is collapsible. Defaults to `true`. */
|
|
247
227
|
readonly collapsible: Schema.withDecodingDefault<Schema.Boolean, never>;
|
|
248
228
|
/** Whether the sidebar section starts collapsed. Defaults to `true`. */
|
|
@@ -261,8 +241,6 @@ declare const SingleApiConfig: Schema.Struct<{
|
|
|
261
241
|
readonly externalPackages: Schema.optional<Schema.mutable<Schema.$Array<Schema.Struct<{
|
|
262
242
|
readonly name: Schema.String;
|
|
263
243
|
readonly version: Schema.String;
|
|
264
|
-
readonly tsconfig: Schema.optional<Schema.declare<string | URL | ((...args: Array<unknown>) => unknown), string | URL | ((...args: Array<unknown>) => unknown)>>;
|
|
265
|
-
readonly compilerOptions: Schema.optional<Schema.Unknown>;
|
|
266
244
|
}>>>>;
|
|
267
245
|
/** Auto-detect external packages from `package.json` dependency fields. */
|
|
268
246
|
readonly autoDetectDependencies: Schema.optional<Schema.Struct<{
|
|
@@ -330,8 +308,6 @@ declare const MultiApiConfig: Schema.Struct<{
|
|
|
330
308
|
readonly folderName: Schema.String;
|
|
331
309
|
/** API item kinds included in this category. */
|
|
332
310
|
readonly itemKinds: Schema.optional<Schema.mutable<Schema.$Array<Schema.declare<ApiItemKind, ApiItemKind>>>>;
|
|
333
|
-
/** TSDoc modifier tag that marks items for this category. */
|
|
334
|
-
readonly tsdocModifier: Schema.optional<Schema.String>;
|
|
335
311
|
/** Whether the sidebar section is collapsible. Defaults to `true`. */
|
|
336
312
|
readonly collapsible: Schema.withDecodingDefault<Schema.Boolean, never>;
|
|
337
313
|
/** Whether the sidebar section starts collapsed. Defaults to `true`. */
|
|
@@ -350,8 +326,6 @@ declare const MultiApiConfig: Schema.Struct<{
|
|
|
350
326
|
readonly externalPackages: Schema.optional<Schema.mutable<Schema.$Array<Schema.Struct<{
|
|
351
327
|
readonly name: Schema.String;
|
|
352
328
|
readonly version: Schema.String;
|
|
353
|
-
readonly tsconfig: Schema.optional<Schema.declare<string | URL | ((...args: Array<unknown>) => unknown), string | URL | ((...args: Array<unknown>) => unknown)>>;
|
|
354
|
-
readonly compilerOptions: Schema.optional<Schema.Unknown>;
|
|
355
329
|
}>>>>;
|
|
356
330
|
/** Auto-detect external packages from `package.json` dependency fields. */
|
|
357
331
|
readonly autoDetectDependencies: Schema.optional<Schema.Struct<{
|
|
@@ -442,8 +416,6 @@ declare const PluginOptions: Schema.Struct<{
|
|
|
442
416
|
readonly folderName: Schema.String;
|
|
443
417
|
/** API item kinds included in this category. */
|
|
444
418
|
readonly itemKinds: Schema.optional<Schema.mutable<Schema.$Array<Schema.declare<ApiItemKind, ApiItemKind>>>>;
|
|
445
|
-
/** TSDoc modifier tag that marks items for this category. */
|
|
446
|
-
readonly tsdocModifier: Schema.optional<Schema.String>;
|
|
447
419
|
/** Whether the sidebar section is collapsible. Defaults to `true`. */
|
|
448
420
|
readonly collapsible: Schema.withDecodingDefault<Schema.Boolean, never>;
|
|
449
421
|
/** Whether the sidebar section starts collapsed. Defaults to `true`. */
|
|
@@ -462,8 +434,6 @@ declare const PluginOptions: Schema.Struct<{
|
|
|
462
434
|
readonly externalPackages: Schema.optional<Schema.mutable<Schema.$Array<Schema.Struct<{
|
|
463
435
|
readonly name: Schema.String;
|
|
464
436
|
readonly version: Schema.String;
|
|
465
|
-
readonly tsconfig: Schema.optional<Schema.declare<string | URL | ((...args: Array<unknown>) => unknown), string | URL | ((...args: Array<unknown>) => unknown)>>;
|
|
466
|
-
readonly compilerOptions: Schema.optional<Schema.Unknown>;
|
|
467
437
|
}>>>>;
|
|
468
438
|
/** Auto-detect external packages from `package.json` dependency fields. */
|
|
469
439
|
readonly autoDetectDependencies: Schema.optional<Schema.Struct<{
|
|
@@ -507,8 +477,6 @@ declare const PluginOptions: Schema.Struct<{
|
|
|
507
477
|
readonly folderName: Schema.String;
|
|
508
478
|
/** API item kinds included in this category. */
|
|
509
479
|
readonly itemKinds: Schema.optional<Schema.mutable<Schema.$Array<Schema.declare<ApiItemKind, ApiItemKind>>>>;
|
|
510
|
-
/** TSDoc modifier tag that marks items for this category. */
|
|
511
|
-
readonly tsdocModifier: Schema.optional<Schema.String>;
|
|
512
480
|
/** Whether the sidebar section is collapsible. Defaults to `true`. */
|
|
513
481
|
readonly collapsible: Schema.withDecodingDefault<Schema.Boolean, never>;
|
|
514
482
|
/** Whether the sidebar section starts collapsed. Defaults to `true`. */
|
|
@@ -527,8 +495,6 @@ declare const PluginOptions: Schema.Struct<{
|
|
|
527
495
|
readonly externalPackages: Schema.optional<Schema.mutable<Schema.$Array<Schema.Struct<{
|
|
528
496
|
readonly name: Schema.String;
|
|
529
497
|
readonly version: Schema.String;
|
|
530
|
-
readonly tsconfig: Schema.optional<Schema.declare<string | URL | ((...args: Array<unknown>) => unknown), string | URL | ((...args: Array<unknown>) => unknown)>>;
|
|
531
|
-
readonly compilerOptions: Schema.optional<Schema.Unknown>;
|
|
532
498
|
}>>>>;
|
|
533
499
|
/** Auto-detect external packages from `package.json` dependency fields. */
|
|
534
500
|
readonly autoDetectDependencies: Schema.optional<Schema.Struct<{
|
|
@@ -590,8 +556,6 @@ declare const PluginOptions: Schema.Struct<{
|
|
|
590
556
|
readonly folderName: Schema.String;
|
|
591
557
|
/** API item kinds included in this category. */
|
|
592
558
|
readonly itemKinds: Schema.optional<Schema.mutable<Schema.$Array<Schema.declare<ApiItemKind, ApiItemKind>>>>;
|
|
593
|
-
/** TSDoc modifier tag that marks items for this category. */
|
|
594
|
-
readonly tsdocModifier: Schema.optional<Schema.String>;
|
|
595
559
|
/** Whether the sidebar section is collapsible. Defaults to `true`. */
|
|
596
560
|
readonly collapsible: Schema.withDecodingDefault<Schema.Boolean, never>;
|
|
597
561
|
/** Whether the sidebar section starts collapsed. Defaults to `true`. */
|
|
@@ -610,8 +574,6 @@ declare const PluginOptions: Schema.Struct<{
|
|
|
610
574
|
readonly externalPackages: Schema.optional<Schema.mutable<Schema.$Array<Schema.Struct<{
|
|
611
575
|
readonly name: Schema.String;
|
|
612
576
|
readonly version: Schema.String;
|
|
613
|
-
readonly tsconfig: Schema.optional<Schema.declare<string | URL | ((...args: Array<unknown>) => unknown), string | URL | ((...args: Array<unknown>) => unknown)>>;
|
|
614
|
-
readonly compilerOptions: Schema.optional<Schema.Unknown>;
|
|
615
577
|
}>>>>;
|
|
616
578
|
/** Auto-detect external packages from `package.json` dependency fields. */
|
|
617
579
|
readonly autoDetectDependencies: Schema.optional<Schema.Struct<{
|
|
@@ -677,8 +639,6 @@ declare const PluginOptions: Schema.Struct<{
|
|
|
677
639
|
readonly folderName: Schema.String;
|
|
678
640
|
/** API item kinds included in this category. */
|
|
679
641
|
readonly itemKinds: Schema.optional<Schema.mutable<Schema.$Array<Schema.declare<ApiItemKind, ApiItemKind>>>>;
|
|
680
|
-
/** TSDoc modifier tag that marks items for this category. */
|
|
681
|
-
readonly tsdocModifier: Schema.optional<Schema.String>;
|
|
682
642
|
/** Whether the sidebar section is collapsible. Defaults to `true`. */
|
|
683
643
|
readonly collapsible: Schema.withDecodingDefault<Schema.Boolean, never>;
|
|
684
644
|
/** Whether the sidebar section starts collapsed. Defaults to `true`. */
|
|
@@ -710,7 +670,6 @@ declare const PluginOptions: Schema.Struct<{
|
|
|
710
670
|
readonly slowPageGeneration: Schema.withDecodingDefault<Schema.Number, never>;
|
|
711
671
|
readonly slowApiLoad: Schema.withDecodingDefault<Schema.Number, never>;
|
|
712
672
|
readonly slowFileOperation: Schema.withDecodingDefault<Schema.Number, never>;
|
|
713
|
-
readonly slowHttpRequest: Schema.withDecodingDefault<Schema.Number, never>;
|
|
714
673
|
readonly slowDbOperation: Schema.withDecodingDefault<Schema.Number, never>;
|
|
715
674
|
}>>;
|
|
716
675
|
}>>;
|
|
@@ -936,5 +895,5 @@ declare function resolveServeConfig(options?: ServeOptions): ResolvedServeConfig
|
|
|
936
895
|
*/
|
|
937
896
|
declare function serve(options?: ServeOptions): Promise<void>;
|
|
938
897
|
//#endregion
|
|
939
|
-
export { ApiExtractorPlugin, type PluginOptions as ApiExtractorPluginOptions, type BaseRoute, type CategoryConfig, DEFAULT_CATEGORIES, type DirInfo, type FromDirOptions, type LoadedModel, type
|
|
898
|
+
export { ApiExtractorPlugin, type PluginOptions as ApiExtractorPluginOptions, type BaseRoute, type CategoryConfig, DEFAULT_CATEGORIES, type DirInfo, type FromDirOptions, type LoadedModel, type MultiApiConfig, type OpenGraphImageConfig, type OpenGraphImageMetadata, type OpenGraphMetadata, type ResolvedServeConfig, type ServeMode, type ServeOptions, type SingleApiConfig, type SourceConfig, type VersionConfig, isServerReady, resolveServeConfig, serve };
|
|
940
899
|
//# sourceMappingURL=index.d.ts.map
|
package/layers/build-metrics.js
CHANGED
|
@@ -81,8 +81,7 @@ const BuildMetrics = {
|
|
|
81
81
|
phaseTimeMs: Metric.counter("phase.time.ms"),
|
|
82
82
|
vfsFiles: Metric.counter("vfs.files"),
|
|
83
83
|
importsPrepended: Metric.counter("imports.prepended"),
|
|
84
|
-
twoslashDiagnostics: Metric.counter("twoslash.diagnostics")
|
|
85
|
-
configDefaultsApplied: Metric.counter("config.defaults.applied")
|
|
84
|
+
twoslashDiagnostics: Metric.counter("twoslash.diagnostics")
|
|
86
85
|
};
|
|
87
86
|
|
|
88
87
|
//#endregion
|
|
@@ -4,22 +4,22 @@ import { PluginEvent } from "../observability/events.js";
|
|
|
4
4
|
import { emit, wantsLevel } from "../observability/EventBus.js";
|
|
5
5
|
import { withPhase } from "../observability/spans.js";
|
|
6
6
|
import { normalizeThemeConfig } from "../markdown/shiki-utils.js";
|
|
7
|
-
import { apiScopeOf, deriveOutputPaths, normalizeBaseRoute, unscopedName } from "../path-derivation.js";
|
|
8
7
|
import { classifyApiConfig, extractAutoDetectedPackages, isVersionConfig, mergeLlmsPluginConfig, validateExternalPackages } from "../config-utils.js";
|
|
9
8
|
import { CategoryResolver } from "../category-resolver.js";
|
|
10
9
|
import { ConfigValidationError } from "../errors.js";
|
|
11
10
|
import { loadApiModel, loadPackageJson, loadVersionModel } from "../model-loader.js";
|
|
11
|
+
import { deriveOutputPaths } from "../path-derivation.js";
|
|
12
12
|
import { DEFAULT_CATEGORIES } from "../schemas/config.js";
|
|
13
13
|
import { PluginConfig } from "../services/PluginConfig.js";
|
|
14
14
|
import { TypeRegistryService } from "../services/TypeRegistryService.js";
|
|
15
15
|
import { emitVfsPayloadEvents, mergeApiResult } from "./api-results.js";
|
|
16
16
|
import { mergeExternalTypes } from "./external-types.js";
|
|
17
17
|
import { registerTypeEnvironments, resolveTsConfigTyped } from "./type-environment.js";
|
|
18
|
-
import
|
|
18
|
+
import { apiScopeOf, normalizeBaseRoute, unscopedName } from "@tsdoctor/pages";
|
|
19
19
|
import { Effect, Metric } from "effect";
|
|
20
|
+
import { ApiExtractedPackage, TypeReferenceExtractor } from "@tsdoctor/model";
|
|
20
21
|
import { deriveSiteUrl } from "@tsdoctor/seo";
|
|
21
22
|
import { hashContent } from "@tsdoctor/snapshot";
|
|
22
|
-
import { ApiExtractedPackage, TypeReferenceExtractor } from "@tsdoctor/model";
|
|
23
23
|
import { PackageManifest } from "@effected/package-json";
|
|
24
24
|
|
|
25
25
|
//#region src/layers/config-resolution.ts
|
|
@@ -261,7 +261,6 @@ const makeConfigService = Effect.gen(function* () {
|
|
|
261
261
|
...resolvedLlms != null ? { llmsPlugin: resolvedLlms } : {},
|
|
262
262
|
...siteUrl != null ? { siteUrl } : {},
|
|
263
263
|
...resolvedOgImage != null ? { ogImage: resolvedOgImage } : {},
|
|
264
|
-
docsDir: path.dirname(outputDir),
|
|
265
264
|
...docsRoot != null ? { docsRoot } : {},
|
|
266
265
|
...resolvedTheme != null ? { theme: resolvedTheme } : {}
|
|
267
266
|
}
|
|
@@ -343,7 +342,6 @@ const makeConfigService = Effect.gen(function* () {
|
|
|
343
342
|
...resolvedLlms != null ? { llmsPlugin: resolvedLlms } : {},
|
|
344
343
|
...siteUrl != null ? { siteUrl } : {},
|
|
345
344
|
...resolvedOgImage != null ? { ogImage: resolvedOgImage } : {},
|
|
346
|
-
docsDir: path.dirname(outputDir),
|
|
347
345
|
...docsRoot != null ? { docsRoot } : {},
|
|
348
346
|
...resolvedTheme != null ? { theme: resolvedTheme } : {}
|
|
349
347
|
}
|
|
@@ -2,10 +2,9 @@ import { PluginEvent } from "../observability/events.js";
|
|
|
2
2
|
import { emit } from "../observability/EventBus.js";
|
|
3
3
|
import { TwoslashEnvironments } from "../services/TwoslashEnvironments.js";
|
|
4
4
|
import { ConfigValidationError } from "../errors.js";
|
|
5
|
-
import { twoslashEnvHash } from "../twoslash-cache.js";
|
|
6
5
|
import { TwoslashCacheService } from "../services/TwoslashCacheService.js";
|
|
7
6
|
import { Effect } from "effect";
|
|
8
|
-
import { resolveTypeScriptConfig } from "@tsdoctor/vfs";
|
|
7
|
+
import { resolveTypeScriptConfig, twoslashEnvHash } from "@tsdoctor/vfs";
|
|
9
8
|
import ts from "typescript";
|
|
10
9
|
|
|
11
10
|
//#region src/layers/type-environment.ts
|
package/llms-program.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { PluginEvent } from "./observability/events.js";
|
|
2
2
|
import { emit } from "./observability/EventBus.js";
|
|
3
|
-
import { filterLlmsFullTxt, filterLlmsTxt, generatePackageLlmsFullTxt, generatePackageLlmsTxt, generateStructuredLlmsTxt, parseLlmsTxtLine } from "./llms-processing.js";
|
|
4
3
|
import path from "node:path";
|
|
4
|
+
import { filterLlmsFullTxt, filterLlmsTxt, generatePackageLlmsFullTxt, generatePackageLlmsTxt, generateStructuredLlmsTxt, parseLlmsTxtLine } from "@tsdoctor/pages";
|
|
5
5
|
import { Effect, FileSystem } from "effect";
|
|
6
6
|
|
|
7
7
|
//#region src/llms-program.ts
|
|
8
8
|
/**
|
|
9
9
|
* Effect program for post-processing LLMs text files in afterBuild.
|
|
10
10
|
*
|
|
11
|
-
* Wires the pure processing functions from
|
|
11
|
+
* Wires the pure processing functions from @tsdoctor/pages into the
|
|
12
12
|
* plugin lifecycle, handling file I/O via the core `effect` FileSystem service.
|
|
13
13
|
*
|
|
14
14
|
* Responsibilities:
|
|
@@ -89,7 +89,7 @@ function buildPackagePointers(buildResults, prefix, packageRoutes) {
|
|
|
89
89
|
* Collect API page entries from the global llms.txt for a specific package.
|
|
90
90
|
*
|
|
91
91
|
* Parses the global llms.txt to find entries whose URLs match this package's
|
|
92
|
-
* generated API routes, building the LlmsTxtEntry array for per-package files.
|
|
92
|
+
* generated API routes, building the `LlmsTxtEntry` array for per-package files.
|
|
93
93
|
*/
|
|
94
94
|
function collectApiEntries(globalLlmsTxtContent, result) {
|
|
95
95
|
const base = result.baseRoute.endsWith("/") ? result.baseRoute : `${result.baseRoute}/`;
|