rspress-plugin-api-extractor 0.1.2 → 0.2.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/README.md +2 -2
- package/api-extracted-package.js +426 -0
- package/build-program.js +120 -0
- package/build-stages.js +664 -0
- package/category-resolver.js +50 -0
- package/code-post-processor.js +38 -0
- package/config-helpers.js +106 -0
- package/config-utils.js +258 -0
- package/content-hash.js +79 -0
- package/errors.js +29 -0
- package/formatter.js +69 -0
- package/hide-cut-transformer.js +96 -0
- package/index.d.ts +901 -831
- package/index.js +4 -6128
- package/layers/ConfigServiceLive.js +377 -0
- package/layers/ObservabilityLive.js +136 -0
- package/layers/PathDerivationServiceLive.js +16 -0
- package/layers/SnapshotServiceLive.js +94 -0
- package/layers/TypeRegistryServiceLive.js +46 -0
- package/llms-processing.js +270 -0
- package/llms-program.js +262 -0
- package/loader.js +186 -0
- package/markdown/cross-linker.js +156 -0
- package/markdown/helpers.js +364 -0
- package/markdown/index.js +11 -0
- package/markdown/page-generators/class-page.js +357 -0
- package/markdown/page-generators/enum-page.js +152 -0
- package/markdown/page-generators/function-page.js +127 -0
- package/markdown/page-generators/index-pages.js +27 -0
- package/markdown/page-generators/interface-page.js +307 -0
- package/markdown/page-generators/namespace-page.js +280 -0
- package/markdown/page-generators/type-alias-page.js +110 -0
- package/markdown/page-generators/variable-page.js +110 -0
- package/markdown/shiki-utils.js +48 -0
- package/migrations/001_create_snapshots.js +25 -0
- package/model-loader.js +95 -0
- package/multi-entry-resolver.js +70 -0
- package/og-resolver.js +271 -0
- package/package.json +63 -73
- package/path-derivation.js +48 -0
- package/plugin.js +218 -0
- package/prettier-formatter.js +73 -0
- package/public/tsconfig/rspress.json +44 -0
- package/remark-api-codeblocks.js +130 -0
- package/remark-with-api.js +172 -0
- package/route-collisions.js +52 -0
- package/runtime/components/ApiExample/index.js +29 -25
- package/runtime/components/ApiLlmsPackageActions/index.js +252 -323
- package/runtime/components/ApiLlmsViewOptions/index.js +269 -340
- package/runtime/components/ApiMember/index.js +49 -47
- package/runtime/components/ApiSignature/index.js +32 -28
- package/runtime/components/EnumMembersTable/{index_module.css → index.css} +18 -19
- package/runtime/components/EnumMembersTable/index.js +36 -67
- package/runtime/components/EnumMembersTable/index.module.js +9 -6
- package/runtime/components/ExampleBlock/{index_module.css → index.css} +2 -3
- package/runtime/components/ExampleBlock/index.js +23 -28
- package/runtime/components/ExampleBlock/index.module.js +8 -5
- package/runtime/components/MarkdownContent/index.js +26 -18
- package/runtime/components/MarkdownText/index.js +28 -22
- package/runtime/components/MemberSignature/{index_module.css → index.css} +5 -6
- package/runtime/components/MemberSignature/index.js +46 -46
- package/runtime/components/MemberSignature/index.module.js +9 -6
- package/runtime/components/ParametersTable/{index_module.css → index.css} +19 -20
- package/runtime/components/ParametersTable/index.js +36 -67
- package/runtime/components/ParametersTable/index.module.js +9 -6
- package/runtime/components/SignatureBlock/{index_module.css → index.css} +5 -6
- package/runtime/components/SignatureBlock/index.js +30 -29
- package/runtime/components/SignatureBlock/index.module.js +9 -6
- package/runtime/components/SignatureCode/{index_module.css → index.css} +9 -10
- package/runtime/components/SignatureCode/index.js +40 -32
- package/runtime/components/SignatureCode/index.module.js +9 -6
- package/runtime/components/SignatureToolbar/{index_module.css → index.css} +18 -20
- package/runtime/components/SignatureToolbar/index.js +48 -51
- package/runtime/components/SignatureToolbar/index.module.js +13 -10
- package/runtime/components/buttons/ButtonGroup.js +13 -6
- package/runtime/components/buttons/CopyCodeButton.js +40 -38
- package/runtime/components/buttons/WrapSignatureButton.js +20 -16
- package/runtime/components/buttons/{index_module.css → index.css} +5 -6
- package/runtime/components/buttons/index.module.js +8 -5
- package/runtime/components/icons/CheckIcon/index.js +20 -17
- package/runtime/components/icons/CopyIcon/index.js +20 -17
- package/runtime/components/icons/UnwrapIcon/index.js +22 -18
- package/runtime/components/icons/WrapIcon/index.js +20 -17
- package/runtime/components/shared/_twoslash.css +3 -10
- package/runtime/components/shared/variables.css +0 -3
- package/runtime/hooks/useWrapToggle.js +32 -9
- package/runtime/index.d.ts +513 -173
- package/runtime/index.js +11 -9
- package/runtime/utils/decode-hast.js +31 -16
- package/runtime/utils/hast-renderer.js +21 -7
- package/schemas/config.js +199 -0
- package/schemas/index.js +5 -0
- package/schemas/opengraph.js +26 -0
- package/schemas/performance.js +19 -0
- package/serve.js +133 -0
- package/services/ConfigService.js +7 -0
- package/services/PathDerivationService.js +7 -0
- package/services/SnapshotService.js +7 -0
- package/services/TypeRegistryService.js +7 -0
- package/shiki-transformer.js +758 -0
- package/tsconfig-parser.js +127 -0
- package/tsdoc-metadata.json +11 -11
- package/twoslash-patterns.js +87 -0
- package/twoslash-transformer.js +316 -0
- package/type-reference-extractor.js +201 -0
- package/typescript-config.js +168 -0
- package/vfs-registry.js +121 -0
- package/0~llms-program.js +0 -344
- package/runtime/components/ApiLlmsPackageActions/index.module.js +0 -2
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { MarkdownCrossLinker, markdownCrossLinker } from "./cross-linker.js";
|
|
2
|
+
import { ClassPageGenerator } from "./page-generators/class-page.js";
|
|
3
|
+
import { EnumPageGenerator } from "./page-generators/enum-page.js";
|
|
4
|
+
import { FunctionPageGenerator } from "./page-generators/function-page.js";
|
|
5
|
+
import { MainIndexPageGenerator } from "./page-generators/index-pages.js";
|
|
6
|
+
import { InterfacePageGenerator } from "./page-generators/interface-page.js";
|
|
7
|
+
import { NamespacePageGenerator } from "./page-generators/namespace-page.js";
|
|
8
|
+
import { TypeAliasPageGenerator } from "./page-generators/type-alias-page.js";
|
|
9
|
+
import { VariablePageGenerator } from "./page-generators/variable-page.js";
|
|
10
|
+
|
|
11
|
+
export { };
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { ApiParser } from "../../loader.js";
|
|
2
|
+
import { TypeReferenceExtractor } from "../../type-reference-extractor.js";
|
|
3
|
+
import { escapeMdxGenerics, formatExampleCode, generateAvailableFrom, generateFrontmatter, prepareExampleCode, prependHiddenImports, sanitizeId, stripTwoslashDirectives } from "../helpers.js";
|
|
4
|
+
import { markdownCrossLinker } from "../cross-linker.js";
|
|
5
|
+
import { TypeSignatureFormatter } from "../../formatter.js";
|
|
6
|
+
|
|
7
|
+
//#region src/markdown/page-generators/class-page.ts
|
|
8
|
+
/**
|
|
9
|
+
* Generates MDX documentation pages for TypeScript/JavaScript classes.
|
|
10
|
+
*
|
|
11
|
+
* This class transforms API Extractor class models into rich MDX documentation pages
|
|
12
|
+
* with syntax-highlighted signatures, cross-linked type references, and interactive
|
|
13
|
+
* features like copy-to-clipboard and line wrapping.
|
|
14
|
+
*
|
|
15
|
+
* **Page Structure:**
|
|
16
|
+
* 1. Frontmatter with title, description, and Open Graph metadata
|
|
17
|
+
* 2. Component imports (SourceCode, ParametersTable, ApiSignature, etc.)
|
|
18
|
+
* 3. Page title (H1) and summary
|
|
19
|
+
* 4. Optional deprecation warning and release tag badge
|
|
20
|
+
* 5. Source code link toolbar
|
|
21
|
+
* 6. Full class signature block showing all members
|
|
22
|
+
* 7. Member sections: Constructors, Static Properties, Static Methods, Properties, Getters/Setters, Methods
|
|
23
|
+
* 8. Examples section with Twoslash-enabled code blocks
|
|
24
|
+
* 9. See Also references
|
|
25
|
+
*
|
|
26
|
+
* **Member Rendering:**
|
|
27
|
+
* Each member is rendered with:
|
|
28
|
+
* - An `ApiMember` component showing the signature in class context
|
|
29
|
+
* - Optional `ParametersTable` for methods with parameters
|
|
30
|
+
* - Return type documentation
|
|
31
|
+
* - Cross-linked type references
|
|
32
|
+
*
|
|
33
|
+
* **Relationships:**
|
|
34
|
+
* - Created and invoked by {@link ApiExtractorPlugin} during page generation
|
|
35
|
+
* - Uses {@link TypeSignatureFormatter} for formatting type signatures
|
|
36
|
+
* - Uses {@link ApiParser} for extracting documentation from API models
|
|
37
|
+
* - Uses {@link MarkdownCrossLinker} for adding type reference links
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const generator = new ClassPageGenerator();
|
|
42
|
+
* const { routePath, content } = await generator.generate(
|
|
43
|
+
* apiClass,
|
|
44
|
+
* "/api/my-package",
|
|
45
|
+
* "my-package",
|
|
46
|
+
* "Class",
|
|
47
|
+
* "My Package",
|
|
48
|
+
* sourceConfig,
|
|
49
|
+
* true, // suppressExampleErrors
|
|
50
|
+
* undefined, // llmsPlugin
|
|
51
|
+
* "claude-binary-plugin", // apiScope
|
|
52
|
+
* );
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @see {@link InterfacePageGenerator} for interface documentation
|
|
56
|
+
* @see {@link FunctionPageGenerator} for function documentation
|
|
57
|
+
*/
|
|
58
|
+
var ClassPageGenerator = class {
|
|
59
|
+
typeFormatter = new TypeSignatureFormatter();
|
|
60
|
+
/**
|
|
61
|
+
* Generate a markdown page for a class
|
|
62
|
+
*
|
|
63
|
+
* @param apiScope - API scope identifier for VFS lookup
|
|
64
|
+
*/
|
|
65
|
+
async generate(apiClass, baseRoute, packageName, singularName, apiScope, apiName, sourceConfig, suppressExampleErrors, llmsPlugin, availableFrom) {
|
|
66
|
+
const shouldSuppressErrors = suppressExampleErrors ?? true;
|
|
67
|
+
const name = apiClass.displayName;
|
|
68
|
+
const summary = ApiParser.getSummary(apiClass) || "No description available.";
|
|
69
|
+
const releaseTag = ApiParser.getReleaseTag(apiClass);
|
|
70
|
+
let content = generateFrontmatter(name, summary, singularName, apiName);
|
|
71
|
+
content += `import { SourceCode } from "@rspress/core/theme";\n`;
|
|
72
|
+
content += `import { ParametersTable } from "rspress-plugin-api-extractor/runtime";\n`;
|
|
73
|
+
content += `import { ApiSignature, ApiMember, ApiExample } from "rspress-plugin-api-extractor/runtime";\n\n`;
|
|
74
|
+
content += `# ${name}\n\n`;
|
|
75
|
+
const deprecation = ApiParser.getDeprecation(apiClass);
|
|
76
|
+
if (deprecation) {
|
|
77
|
+
const message = escapeMdxGenerics(markdownCrossLinker.addCrossLinks(deprecation.message));
|
|
78
|
+
content += `> ⚠️ **Deprecated:** ${message}\n\n`;
|
|
79
|
+
}
|
|
80
|
+
if (releaseTag !== "Public") content += `\`${releaseTag}\`\n\n`;
|
|
81
|
+
content += `${summary}\n\n`;
|
|
82
|
+
content += generateAvailableFrom(packageName, availableFrom);
|
|
83
|
+
const sourceLink = ApiParser.getSourceLink(apiClass, sourceConfig);
|
|
84
|
+
if (sourceLink) {
|
|
85
|
+
content += `<div className="api-docs-toolbar">\n`;
|
|
86
|
+
content += ` <div className="api-docs-toolbar-left">\n`;
|
|
87
|
+
content += ` <SourceCode href="${sourceLink}" />\n`;
|
|
88
|
+
content += ` </div>\n`;
|
|
89
|
+
if (llmsPlugin?.enabled) {
|
|
90
|
+
content += ` <div className="api-docs-toolbar-right">\n`;
|
|
91
|
+
content += ` </div>\n`;
|
|
92
|
+
}
|
|
93
|
+
content += `</div>\n\n`;
|
|
94
|
+
}
|
|
95
|
+
const skeleton = this.generateClassSkeletonWithTwoslash(apiClass, packageName);
|
|
96
|
+
const displayCode = stripTwoslashDirectives(skeleton);
|
|
97
|
+
content += `<ApiSignature code={${JSON.stringify(displayCode)}} source={${JSON.stringify(skeleton)}} apiScope={${JSON.stringify(apiScope)}} />\n\n`;
|
|
98
|
+
const constructors = apiClass.members.filter((m) => m.kind === "Constructor");
|
|
99
|
+
if (constructors.length > 0) {
|
|
100
|
+
content += `## Constructors\n\n`;
|
|
101
|
+
for (const ctor of constructors) {
|
|
102
|
+
const ctorSummary = ApiParser.getSummary(ctor);
|
|
103
|
+
const ctorId = sanitizeId("constructor");
|
|
104
|
+
const ctorItem = ctor;
|
|
105
|
+
const params = ApiParser.getParams(ctor);
|
|
106
|
+
const hasParameters = params.length > 0;
|
|
107
|
+
if (ctorItem.excerpt?.text) {
|
|
108
|
+
const memberSignature = this.typeFormatter.format(ctorItem.excerpt).trim();
|
|
109
|
+
const skeletonWithContext = this.generateClassMemberWithContext(apiClass, ctor, packageName);
|
|
110
|
+
const summaryMd = ctorSummary ? escapeMdxGenerics(markdownCrossLinker.addCrossLinks(ctorSummary)) : void 0;
|
|
111
|
+
content += `<ApiMember code={${JSON.stringify(memberSignature)}} source={${JSON.stringify(skeletonWithContext)}} apiScope={${JSON.stringify(apiScope)}} memberName="constructor"${summaryMd ? ` summary={${JSON.stringify(summaryMd)}}` : ""} id={${JSON.stringify(ctorId)}} hasParameters={${hasParameters}} />\n\n`;
|
|
112
|
+
}
|
|
113
|
+
if (hasParameters) content += `<ParametersTable parameters={${JSON.stringify(params.map((p) => ({
|
|
114
|
+
name: p.name,
|
|
115
|
+
type: p.type,
|
|
116
|
+
description: markdownCrossLinker.addCrossLinks(p.description)
|
|
117
|
+
})))}} />\n\n`;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const properties = apiClass.members.filter((m) => m.kind === "Property" || m.kind === "PropertySignature");
|
|
121
|
+
const methods = apiClass.members.filter((m) => m.kind === "Method" || m.kind === "MethodSignature");
|
|
122
|
+
const grouped = methods.length > 0 ? this.groupClassMembers(methods) : {
|
|
123
|
+
staticMethods: [],
|
|
124
|
+
instanceMethods: [],
|
|
125
|
+
getters: []
|
|
126
|
+
};
|
|
127
|
+
const staticProperties = properties.filter((m) => {
|
|
128
|
+
return m.isStatic === true;
|
|
129
|
+
});
|
|
130
|
+
const instanceProperties = properties.filter((m) => {
|
|
131
|
+
const isStatic = m.isStatic === true;
|
|
132
|
+
const isGetter = m.displayName.startsWith("get ") || m.displayName.startsWith("set ");
|
|
133
|
+
return !isStatic && !isGetter;
|
|
134
|
+
});
|
|
135
|
+
const prefixMap = this.detectMemberConflicts(staticProperties, grouped.staticMethods, instanceProperties, grouped.instanceMethods, grouped.getters);
|
|
136
|
+
const renderProperties = async (title, propList) => {
|
|
137
|
+
if (propList.length === 0) return;
|
|
138
|
+
content += `## ${title}\n\n`;
|
|
139
|
+
for (const prop of propList) {
|
|
140
|
+
const propSummary = ApiParser.getSummary(prop);
|
|
141
|
+
const baseName = sanitizeId(prop.displayName);
|
|
142
|
+
const prefix = prefixMap.get(baseName) || "";
|
|
143
|
+
const propId = sanitizeId(prop.displayName, prefix);
|
|
144
|
+
const propItem = prop;
|
|
145
|
+
if (propItem.excerpt?.text) {
|
|
146
|
+
const memberSignature = this.typeFormatter.format(propItem.excerpt).trim();
|
|
147
|
+
const skeletonWithContext = this.generateClassMemberWithContext(apiClass, prop, packageName);
|
|
148
|
+
const summaryMd = propSummary ? escapeMdxGenerics(markdownCrossLinker.addCrossLinks(propSummary)) : void 0;
|
|
149
|
+
content += `<ApiMember code={${JSON.stringify(memberSignature)}} source={${JSON.stringify(skeletonWithContext)}} apiScope={${JSON.stringify(apiScope)}} memberName={${JSON.stringify(prop.displayName)}}${summaryMd ? ` summary={${JSON.stringify(summaryMd)}}` : ""} id={${JSON.stringify(propId)}} />\n\n`;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
const renderMethods = async (title, methodList) => {
|
|
154
|
+
if (methodList.length === 0) return;
|
|
155
|
+
content += `## ${title}\n\n`;
|
|
156
|
+
for (const method of methodList) {
|
|
157
|
+
const methodSummary = ApiParser.getSummary(method);
|
|
158
|
+
const baseName = sanitizeId(method.displayName);
|
|
159
|
+
const prefix = prefixMap.get(baseName) || "";
|
|
160
|
+
const methodId = sanitizeId(method.displayName, prefix);
|
|
161
|
+
const methodItem = method;
|
|
162
|
+
const params = ApiParser.getParams(method);
|
|
163
|
+
const hasParameters = params.length > 0;
|
|
164
|
+
if (methodItem.excerpt?.text) {
|
|
165
|
+
const memberSignature = this.typeFormatter.format(methodItem.excerpt).trim();
|
|
166
|
+
const skeletonWithContext = this.generateClassMemberWithContext(apiClass, method, packageName);
|
|
167
|
+
const summaryMd = methodSummary ? escapeMdxGenerics(markdownCrossLinker.addCrossLinks(methodSummary)) : void 0;
|
|
168
|
+
content += `<ApiMember code={${JSON.stringify(memberSignature)}} source={${JSON.stringify(skeletonWithContext)}} apiScope={${JSON.stringify(apiScope)}} memberName={${JSON.stringify(method.displayName)}}${summaryMd ? ` summary={${JSON.stringify(summaryMd)}}` : ""} id={${JSON.stringify(methodId)}} hasParameters={${hasParameters}} />\n\n`;
|
|
169
|
+
}
|
|
170
|
+
if (hasParameters) content += `<ParametersTable parameters={${JSON.stringify(params.map((p) => ({
|
|
171
|
+
name: p.name,
|
|
172
|
+
type: p.type,
|
|
173
|
+
description: markdownCrossLinker.addCrossLinks(p.description)
|
|
174
|
+
})))}} />\n\n`;
|
|
175
|
+
const returns = ApiParser.getReturns(method);
|
|
176
|
+
if (returns) {
|
|
177
|
+
const description = escapeMdxGenerics(markdownCrossLinker.addCrossLinks(returns.description));
|
|
178
|
+
content += `**Returns:** ${description}\n\n`;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
await renderProperties("Static Properties", staticProperties);
|
|
183
|
+
await renderMethods("Static Methods", grouped.staticMethods);
|
|
184
|
+
await renderProperties("Properties", instanceProperties);
|
|
185
|
+
await renderMethods("Getters & Setters", grouped.getters);
|
|
186
|
+
await renderMethods("Methods", grouped.instanceMethods);
|
|
187
|
+
const examples = ApiParser.getExamples(apiClass);
|
|
188
|
+
if (examples.length > 0) {
|
|
189
|
+
content += `## Examples\n\n`;
|
|
190
|
+
for (const example of examples) {
|
|
191
|
+
const prepared = prepareExampleCode(example, name, packageName, shouldSuppressErrors);
|
|
192
|
+
const formattedCode = await formatExampleCode(prepared.code, prepared.language, {
|
|
193
|
+
api: packageName,
|
|
194
|
+
blockType: "example"
|
|
195
|
+
});
|
|
196
|
+
if (prepared.isTypeScript) {
|
|
197
|
+
const displayCode = stripTwoslashDirectives(formattedCode);
|
|
198
|
+
content += `<ApiExample code={${JSON.stringify(displayCode)}} source={${JSON.stringify(formattedCode)}} apiScope={${JSON.stringify(apiScope)}} />\n\n`;
|
|
199
|
+
} else content += `\`\`\`${prepared.language}\n${formattedCode}\n\`\`\`\n\n`;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const seeReferences = ApiParser.getSeeReferences(apiClass);
|
|
203
|
+
if (seeReferences.length > 0) {
|
|
204
|
+
content += `## See Also\n\n`;
|
|
205
|
+
for (const reference of seeReferences) {
|
|
206
|
+
const refText = escapeMdxGenerics(markdownCrossLinker.addCrossLinks(reference.text));
|
|
207
|
+
content += `- ${refText}\n`;
|
|
208
|
+
}
|
|
209
|
+
content += `\n`;
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
routePath: `${baseRoute}/class/${name.toLowerCase()}`,
|
|
213
|
+
content
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Group class members by their type (static, instance, getters/setters)
|
|
218
|
+
*/
|
|
219
|
+
groupClassMembers(members) {
|
|
220
|
+
const staticMethods = [];
|
|
221
|
+
const instanceMethods = [];
|
|
222
|
+
const getters = [];
|
|
223
|
+
for (const member of members) {
|
|
224
|
+
const isGetter = member.kind === "Method" && (member.displayName.startsWith("get ") || member.displayName.startsWith("set "));
|
|
225
|
+
const isStatic = member.isStatic === true;
|
|
226
|
+
if (isGetter) getters.push(member);
|
|
227
|
+
else if (isStatic) staticMethods.push(member);
|
|
228
|
+
else instanceMethods.push(member);
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
staticMethods,
|
|
232
|
+
instanceMethods,
|
|
233
|
+
getters
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Detect naming conflicts between class members and return prefixes to apply.
|
|
238
|
+
* Returns a Map of sanitized name to prefix (empty string if no conflict).
|
|
239
|
+
*/
|
|
240
|
+
detectMemberConflicts(staticProps, staticMethods, instanceProps, instanceMethods, getters) {
|
|
241
|
+
const prefixMap = /* @__PURE__ */ new Map();
|
|
242
|
+
const staticPropNames = new Set(staticProps.map((p) => sanitizeId(p.displayName)));
|
|
243
|
+
const staticMethodNames = new Set(staticMethods.map((m) => sanitizeId(m.displayName)));
|
|
244
|
+
const instancePropNames = new Set(instanceProps.map((p) => sanitizeId(p.displayName)));
|
|
245
|
+
const instanceMethodNames = new Set(instanceMethods.map((m) => sanitizeId(m.displayName)));
|
|
246
|
+
const getterNames = new Set(getters.map((g) => sanitizeId(g.displayName)));
|
|
247
|
+
for (const name of staticPropNames) if (staticMethodNames.has(name) || instancePropNames.has(name) || instanceMethodNames.has(name) || getterNames.has(name)) prefixMap.set(name, "static-property");
|
|
248
|
+
for (const name of staticMethodNames) if (instanceMethodNames.has(name) || instancePropNames.has(name) || getterNames.has(name)) prefixMap.set(name, "static");
|
|
249
|
+
else if (staticPropNames.has(name)) prefixMap.set(name, "");
|
|
250
|
+
for (const name of instancePropNames) if (instanceMethodNames.has(name) || getterNames.has(name)) prefixMap.set(name, "property");
|
|
251
|
+
else if (staticMethodNames.has(name)) prefixMap.set(name, "");
|
|
252
|
+
for (const name of instanceMethodNames) if (!prefixMap.has(name)) prefixMap.set(name, "");
|
|
253
|
+
for (const name of getterNames) if (!prefixMap.has(name)) prefixMap.set(name, "");
|
|
254
|
+
return prefixMap;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Generate a class member signature with full class context
|
|
258
|
+
* Includes hidden imports with cut directive for external type resolution
|
|
259
|
+
* Uses the simplified approach: 3 lines (class opening, member, closing)
|
|
260
|
+
*/
|
|
261
|
+
generateClassMemberWithContext(apiClass, targetMember, packageName) {
|
|
262
|
+
const className = apiClass.displayName;
|
|
263
|
+
const inheritance = ApiParser.getInheritance(apiClass);
|
|
264
|
+
let declaration = `class ${className}`;
|
|
265
|
+
if (inheritance.extends && inheritance.extends.length > 0) declaration += ` extends ${inheritance.extends.join(", ")}`;
|
|
266
|
+
if (inheritance.implements && inheritance.implements.length > 0) declaration += ` implements ${inheritance.implements.join(", ")}`;
|
|
267
|
+
declaration += " {";
|
|
268
|
+
const memberItem = targetMember;
|
|
269
|
+
const memberSignature = memberItem.excerpt?.text ? this.typeFormatter.format(memberItem.excerpt).trim() : "";
|
|
270
|
+
const skeleton = `${declaration}\n${memberSignature}\n}`;
|
|
271
|
+
const apiPackage = apiClass.getAssociatedPackage?.();
|
|
272
|
+
if (apiPackage) return prependHiddenImports(skeleton, new TypeReferenceExtractor(apiPackage, packageName).extractImportsForApiItem(targetMember));
|
|
273
|
+
return skeleton;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Generate a class skeleton for signature blocks
|
|
277
|
+
* Includes hidden imports with cut directive for external type resolution
|
|
278
|
+
*/
|
|
279
|
+
generateClassSkeletonWithTwoslash(apiClass, packageName) {
|
|
280
|
+
const skeleton = this.generateClassSkeleton(apiClass);
|
|
281
|
+
const apiPackage = apiClass.getAssociatedPackage?.();
|
|
282
|
+
if (apiPackage) return prependHiddenImports(skeleton, new TypeReferenceExtractor(apiPackage, packageName).extractImportsForApiItem(apiClass));
|
|
283
|
+
return skeleton;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Generate a complete class skeleton showing all members
|
|
287
|
+
*/
|
|
288
|
+
generateClassSkeleton(apiClass) {
|
|
289
|
+
const lines = [];
|
|
290
|
+
const className = apiClass.displayName;
|
|
291
|
+
const inheritance = ApiParser.getInheritance(apiClass);
|
|
292
|
+
let declaration = `class ${className}`;
|
|
293
|
+
if (inheritance.extends && inheritance.extends.length > 0) declaration += ` extends ${inheritance.extends.join(", ")}`;
|
|
294
|
+
if (inheritance.implements && inheritance.implements.length > 0) declaration += ` implements ${inheritance.implements.join(", ")}`;
|
|
295
|
+
declaration += " {";
|
|
296
|
+
lines.push(declaration);
|
|
297
|
+
const constructors = apiClass.members.filter((m) => m.kind === "Constructor");
|
|
298
|
+
if (constructors.length > 0) for (const ctor of constructors) {
|
|
299
|
+
const ctorItem = ctor;
|
|
300
|
+
if (ctorItem.excerpt?.text) {
|
|
301
|
+
const signature = this.typeFormatter.format(ctorItem.excerpt).trim();
|
|
302
|
+
lines.push(` ${signature}`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
const methods = apiClass.members.filter((m) => m.kind === "Method" || m.kind === "MethodSignature");
|
|
306
|
+
const grouped = this.groupClassMembers(methods);
|
|
307
|
+
const properties = apiClass.members.filter((m) => m.kind === "Property" || m.kind === "PropertySignature");
|
|
308
|
+
const staticProperties = properties.filter((m) => {
|
|
309
|
+
return m.isStatic === true;
|
|
310
|
+
});
|
|
311
|
+
if (staticProperties.length > 0) for (const prop of staticProperties) {
|
|
312
|
+
const propItem = prop;
|
|
313
|
+
if (propItem.excerpt?.text) {
|
|
314
|
+
const signature = this.typeFormatter.format(propItem.excerpt).trim();
|
|
315
|
+
lines.push(` ${signature}`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (grouped.staticMethods.length > 0) for (const method of grouped.staticMethods) {
|
|
319
|
+
const methodItem = method;
|
|
320
|
+
if (methodItem.excerpt?.text) {
|
|
321
|
+
const signature = this.typeFormatter.format(methodItem.excerpt).trim();
|
|
322
|
+
lines.push(` ${signature}`);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
const instanceProperties = properties.filter((m) => {
|
|
326
|
+
const isStatic = m.isStatic === true;
|
|
327
|
+
const isGetter = m.displayName.startsWith("get ") || m.displayName.startsWith("set ");
|
|
328
|
+
return !isStatic && !isGetter;
|
|
329
|
+
});
|
|
330
|
+
if (instanceProperties.length > 0) for (const prop of instanceProperties) {
|
|
331
|
+
const propItem = prop;
|
|
332
|
+
if (propItem.excerpt?.text) {
|
|
333
|
+
const signature = this.typeFormatter.format(propItem.excerpt).trim();
|
|
334
|
+
lines.push(` ${signature}`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (grouped.getters.length > 0) for (const method of grouped.getters) {
|
|
338
|
+
const methodItem = method;
|
|
339
|
+
if (methodItem.excerpt?.text) {
|
|
340
|
+
const signature = this.typeFormatter.format(methodItem.excerpt).trim();
|
|
341
|
+
lines.push(` ${signature}`);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
if (grouped.instanceMethods.length > 0) for (const method of grouped.instanceMethods) {
|
|
345
|
+
const methodItem = method;
|
|
346
|
+
if (methodItem.excerpt?.text) {
|
|
347
|
+
const signature = this.typeFormatter.format(methodItem.excerpt).trim();
|
|
348
|
+
lines.push(` ${signature}`);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
lines.push("}");
|
|
352
|
+
return lines.join("\n");
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
//#endregion
|
|
357
|
+
export { ClassPageGenerator };
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { ApiParser } from "../../loader.js";
|
|
2
|
+
import { escapeMdxGenerics, formatExampleCode, generateAvailableFrom, generateFrontmatter, prepareExampleCode, stripTwoslashDirectives } from "../helpers.js";
|
|
3
|
+
import { markdownCrossLinker } from "../cross-linker.js";
|
|
4
|
+
|
|
5
|
+
//#region src/markdown/page-generators/enum-page.ts
|
|
6
|
+
/**
|
|
7
|
+
* Generates MDX documentation pages for TypeScript enums.
|
|
8
|
+
*
|
|
9
|
+
* This class transforms API Extractor enum models into rich MDX documentation
|
|
10
|
+
* pages with syntax-highlighted signatures, member tables, and cross-linked
|
|
11
|
+
* type references.
|
|
12
|
+
*
|
|
13
|
+
* **Page Structure:**
|
|
14
|
+
* 1. Frontmatter with title, description, and Open Graph metadata
|
|
15
|
+
* 2. Component imports
|
|
16
|
+
* 3. Page title (H1) and summary
|
|
17
|
+
* 4. Optional deprecation warning and release tag badge
|
|
18
|
+
* 5. Source code link toolbar
|
|
19
|
+
* 6. Enum signature block
|
|
20
|
+
* 7. Members table (Name, Value, Description)
|
|
21
|
+
* 8. Examples section with Twoslash-enabled code blocks
|
|
22
|
+
* 9. See Also references
|
|
23
|
+
*
|
|
24
|
+
* **Relationships:**
|
|
25
|
+
* - Created and invoked by {@link ApiExtractorPlugin} during page generation
|
|
26
|
+
* - Uses {@link TypeSignatureFormatter} for formatting type signatures
|
|
27
|
+
* - Uses {@link ApiParser} for extracting documentation from API models
|
|
28
|
+
* - Uses {@link MarkdownCrossLinker} for adding type reference links
|
|
29
|
+
*
|
|
30
|
+
* @see {@link TypeAliasPageGenerator} for type alias documentation
|
|
31
|
+
* @see {@link VariablePageGenerator} for variable/constant documentation
|
|
32
|
+
*/
|
|
33
|
+
var EnumPageGenerator = class {
|
|
34
|
+
/**
|
|
35
|
+
* Generate a markdown page for an enum
|
|
36
|
+
*
|
|
37
|
+
* @param apiScope - API scope identifier for VFS lookup
|
|
38
|
+
*/
|
|
39
|
+
async generate(apiEnum, baseRoute, packageName, singularName, apiScope, apiName, sourceConfig, suppressExampleErrors, llmsPlugin, availableFrom) {
|
|
40
|
+
const shouldSuppressErrors = suppressExampleErrors ?? true;
|
|
41
|
+
const name = apiEnum.displayName;
|
|
42
|
+
const summary = ApiParser.getSummary(apiEnum) || "No description available.";
|
|
43
|
+
const releaseTag = ApiParser.getReleaseTag(apiEnum);
|
|
44
|
+
let content = generateFrontmatter(name, summary, singularName, apiName);
|
|
45
|
+
content += `import { SourceCode } from "@rspress/core/theme";\n`;
|
|
46
|
+
content += `import { EnumMembersTable } from "rspress-plugin-api-extractor/runtime";\n`;
|
|
47
|
+
content += `import { ApiSignature, ApiExample } from "rspress-plugin-api-extractor/runtime";\n\n`;
|
|
48
|
+
content += `# ${name}\n\n`;
|
|
49
|
+
const deprecation = ApiParser.getDeprecation(apiEnum);
|
|
50
|
+
if (deprecation) {
|
|
51
|
+
const message = escapeMdxGenerics(markdownCrossLinker.addCrossLinks(deprecation.message));
|
|
52
|
+
content += `> ⚠️ **Deprecated:** ${message}\n\n`;
|
|
53
|
+
}
|
|
54
|
+
if (releaseTag !== "Public") content += `\`${releaseTag}\`\n\n`;
|
|
55
|
+
content += `${summary}\n\n`;
|
|
56
|
+
content += generateAvailableFrom(packageName, availableFrom);
|
|
57
|
+
const sourceLink = ApiParser.getSourceLink(apiEnum, sourceConfig);
|
|
58
|
+
if (sourceLink) {
|
|
59
|
+
content += `<div className="api-docs-toolbar">\n`;
|
|
60
|
+
content += ` <div className="api-docs-toolbar-left">\n`;
|
|
61
|
+
content += ` <SourceCode href="${sourceLink}" />\n`;
|
|
62
|
+
content += ` </div>\n`;
|
|
63
|
+
if (llmsPlugin?.enabled) {
|
|
64
|
+
content += ` <div className="api-docs-toolbar-right">\n`;
|
|
65
|
+
content += ` </div>\n`;
|
|
66
|
+
}
|
|
67
|
+
content += `</div>\n\n`;
|
|
68
|
+
}
|
|
69
|
+
const skeleton = this.generateEnumSkeleton(apiEnum);
|
|
70
|
+
const hasMembers = apiEnum.members.length > 0;
|
|
71
|
+
if (skeleton) {
|
|
72
|
+
const displayCode = stripTwoslashDirectives(skeleton);
|
|
73
|
+
const signatureNewlines = hasMembers ? "\n" : "\n\n";
|
|
74
|
+
content += `<ApiSignature code={${JSON.stringify(displayCode)}} source={${JSON.stringify(skeleton)}} apiScope={${JSON.stringify(apiScope)}} hasMembers={${hasMembers}} />${signatureNewlines}`;
|
|
75
|
+
}
|
|
76
|
+
if (hasMembers) {
|
|
77
|
+
const membersData = apiEnum.members.map((member) => {
|
|
78
|
+
const memberItem = member;
|
|
79
|
+
const memberSummary = ApiParser.getSummary(member) || "";
|
|
80
|
+
let value;
|
|
81
|
+
if (memberItem.excerpt?.text) {
|
|
82
|
+
const excerptText = memberItem.excerpt.text.trim();
|
|
83
|
+
const equalsIndex = excerptText.indexOf("=");
|
|
84
|
+
if (equalsIndex !== -1) value = excerptText.substring(equalsIndex + 1).trim().replace(/,\s*$/, "");
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
name: member.displayName,
|
|
88
|
+
value,
|
|
89
|
+
description: markdownCrossLinker.addCrossLinks(memberSummary)
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
content += `<EnumMembersTable members={${JSON.stringify(membersData)}} />\n\n`;
|
|
93
|
+
}
|
|
94
|
+
const examples = ApiParser.getExamples(apiEnum);
|
|
95
|
+
if (examples.length > 0) {
|
|
96
|
+
content += `## Examples\n\n`;
|
|
97
|
+
for (const example of examples) {
|
|
98
|
+
const prepared = prepareExampleCode(example, name, packageName, shouldSuppressErrors);
|
|
99
|
+
const formattedCode = await formatExampleCode(prepared.code, prepared.language, {
|
|
100
|
+
api: packageName,
|
|
101
|
+
blockType: "example"
|
|
102
|
+
});
|
|
103
|
+
if (prepared.isTypeScript) {
|
|
104
|
+
const displayCode = stripTwoslashDirectives(formattedCode);
|
|
105
|
+
content += `<ApiExample code={${JSON.stringify(displayCode)}} source={${JSON.stringify(formattedCode)}} apiScope={${JSON.stringify(apiScope)}} />\n\n`;
|
|
106
|
+
} else content += `\`\`\`${prepared.language}\n${formattedCode}\n\`\`\`\n\n`;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const seeReferences = ApiParser.getSeeReferences(apiEnum);
|
|
110
|
+
if (seeReferences.length > 0) {
|
|
111
|
+
content += `## See Also\n\n`;
|
|
112
|
+
for (const reference of seeReferences) {
|
|
113
|
+
const refText = escapeMdxGenerics(markdownCrossLinker.addCrossLinks(reference.text));
|
|
114
|
+
content += `- ${refText}\n`;
|
|
115
|
+
}
|
|
116
|
+
content += `\n`;
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
routePath: `${baseRoute}/enum/${name.toLowerCase()}`,
|
|
120
|
+
content
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Generate a complete enum skeleton showing all members
|
|
125
|
+
*/
|
|
126
|
+
generateEnumSkeleton(apiEnum) {
|
|
127
|
+
const lines = [];
|
|
128
|
+
const enumName = apiEnum.displayName;
|
|
129
|
+
lines.push(`enum ${enumName} {`);
|
|
130
|
+
const members = apiEnum.members;
|
|
131
|
+
for (let i = 0; i < members.length; i++) {
|
|
132
|
+
const member = members[i];
|
|
133
|
+
const memberItem = member;
|
|
134
|
+
let memberLine = ` ${member.displayName}`;
|
|
135
|
+
if (memberItem.excerpt?.text) {
|
|
136
|
+
const excerptText = memberItem.excerpt.text.trim();
|
|
137
|
+
const equalsIndex = excerptText.indexOf("=");
|
|
138
|
+
if (equalsIndex !== -1) {
|
|
139
|
+
const value = excerptText.substring(equalsIndex + 1).trim().replace(/,\s*$/, "");
|
|
140
|
+
memberLine += ` = ${value}`;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (i < members.length - 1) memberLine += ",";
|
|
144
|
+
lines.push(memberLine);
|
|
145
|
+
}
|
|
146
|
+
lines.push("}");
|
|
147
|
+
return lines.join("\n");
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
//#endregion
|
|
152
|
+
export { EnumPageGenerator };
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { ApiParser } from "../../loader.js";
|
|
2
|
+
import { TypeReferenceExtractor } from "../../type-reference-extractor.js";
|
|
3
|
+
import { escapeMdxGenerics, formatExampleCode, generateAvailableFrom, generateFrontmatter, prepareExampleCode, prependHiddenImports, stripTwoslashDirectives } from "../helpers.js";
|
|
4
|
+
import { markdownCrossLinker } from "../cross-linker.js";
|
|
5
|
+
import { TypeSignatureFormatter } from "../../formatter.js";
|
|
6
|
+
|
|
7
|
+
//#region src/markdown/page-generators/function-page.ts
|
|
8
|
+
/**
|
|
9
|
+
* Generates MDX documentation pages for TypeScript/JavaScript functions.
|
|
10
|
+
*
|
|
11
|
+
* This class transforms API Extractor function models into rich MDX documentation
|
|
12
|
+
* pages with syntax-highlighted signatures and cross-linked type references.
|
|
13
|
+
*
|
|
14
|
+
* **Page Structure:**
|
|
15
|
+
* 1. Frontmatter with title, description, and Open Graph metadata
|
|
16
|
+
* 2. Component imports
|
|
17
|
+
* 3. Page title (H1) and summary
|
|
18
|
+
* 4. Optional deprecation warning and release tag badge
|
|
19
|
+
* 5. Source code link toolbar
|
|
20
|
+
* 6. Function signature block
|
|
21
|
+
* 7. Parameters documentation
|
|
22
|
+
* 8. Returns documentation
|
|
23
|
+
* 9. Examples section with Twoslash-enabled code blocks
|
|
24
|
+
* 10. See Also references
|
|
25
|
+
*
|
|
26
|
+
* **Relationships:**
|
|
27
|
+
* - Created and invoked by {@link ApiExtractorPlugin} during page generation
|
|
28
|
+
* - Uses {@link TypeSignatureFormatter} for formatting type signatures
|
|
29
|
+
* - Uses {@link ApiParser} for extracting documentation from API models
|
|
30
|
+
* - Uses {@link MarkdownCrossLinker} for adding type reference links
|
|
31
|
+
*
|
|
32
|
+
* @see {@link ClassPageGenerator} for class documentation
|
|
33
|
+
* @see {@link TypeAliasPageGenerator} for type alias documentation
|
|
34
|
+
*/
|
|
35
|
+
var FunctionPageGenerator = class {
|
|
36
|
+
typeFormatter = new TypeSignatureFormatter();
|
|
37
|
+
/**
|
|
38
|
+
* Generate a markdown page for a function
|
|
39
|
+
*
|
|
40
|
+
* @param apiScope - API scope identifier for VFS lookup
|
|
41
|
+
*/
|
|
42
|
+
async generate(apiFunction, baseRoute, packageName, singularName, apiScope, apiName, sourceConfig, suppressExampleErrors, llmsPlugin, availableFrom) {
|
|
43
|
+
const shouldSuppressErrors = suppressExampleErrors ?? true;
|
|
44
|
+
const name = apiFunction.displayName;
|
|
45
|
+
const summary = ApiParser.getSummary(apiFunction) || "No description available.";
|
|
46
|
+
const releaseTag = ApiParser.getReleaseTag(apiFunction);
|
|
47
|
+
let content = generateFrontmatter(name, summary, singularName, apiName);
|
|
48
|
+
content += `import { SourceCode } from "@rspress/core/theme";\n`;
|
|
49
|
+
content += `import { ParametersTable } from "rspress-plugin-api-extractor/runtime";\n`;
|
|
50
|
+
content += `import { ApiSignature, ApiExample } from "rspress-plugin-api-extractor/runtime";\n\n`;
|
|
51
|
+
content += `# ${name}\n\n`;
|
|
52
|
+
const deprecation = ApiParser.getDeprecation(apiFunction);
|
|
53
|
+
if (deprecation) {
|
|
54
|
+
const message = escapeMdxGenerics(markdownCrossLinker.addCrossLinks(deprecation.message));
|
|
55
|
+
content += `> ⚠️ **Deprecated:** ${message}\n\n`;
|
|
56
|
+
}
|
|
57
|
+
if (releaseTag !== "Public") content += `\`${releaseTag}\`\n\n`;
|
|
58
|
+
content += `${summary}\n\n`;
|
|
59
|
+
content += generateAvailableFrom(packageName, availableFrom);
|
|
60
|
+
const sourceLink = ApiParser.getSourceLink(apiFunction, sourceConfig);
|
|
61
|
+
if (sourceLink) {
|
|
62
|
+
content += `<div className="api-docs-toolbar">\n`;
|
|
63
|
+
content += ` <div className="api-docs-toolbar-left">\n`;
|
|
64
|
+
content += ` <SourceCode href="${sourceLink}" />\n`;
|
|
65
|
+
content += ` </div>\n`;
|
|
66
|
+
if (llmsPlugin?.enabled) {
|
|
67
|
+
content += ` <div className="api-docs-toolbar-right">\n`;
|
|
68
|
+
content += ` </div>\n`;
|
|
69
|
+
}
|
|
70
|
+
content += `</div>\n\n`;
|
|
71
|
+
}
|
|
72
|
+
const params = ApiParser.getParams(apiFunction);
|
|
73
|
+
const hasParameters = params.length > 0;
|
|
74
|
+
if (apiFunction.excerpt.text) {
|
|
75
|
+
const signature = this.typeFormatter.format(apiFunction.excerpt).trim();
|
|
76
|
+
let signatureWithImports = signature;
|
|
77
|
+
const apiPackage = apiFunction.getAssociatedPackage?.();
|
|
78
|
+
if (apiPackage) signatureWithImports = prependHiddenImports(signature, new TypeReferenceExtractor(apiPackage, packageName).extractImportsForApiItem(apiFunction));
|
|
79
|
+
const displayCode = stripTwoslashDirectives(signatureWithImports);
|
|
80
|
+
content += `<ApiSignature code={${JSON.stringify(displayCode)}} source={${JSON.stringify(signatureWithImports)}} apiScope={${JSON.stringify(apiScope)}} hasParameters={${hasParameters}} />\n\n`;
|
|
81
|
+
}
|
|
82
|
+
if (hasParameters) {
|
|
83
|
+
const parametersData = params.map((param) => ({
|
|
84
|
+
name: param.name,
|
|
85
|
+
type: param.type,
|
|
86
|
+
description: escapeMdxGenerics(markdownCrossLinker.addCrossLinks(param.description))
|
|
87
|
+
}));
|
|
88
|
+
content += `<ParametersTable parameters={${JSON.stringify(parametersData)}} />\n\n`;
|
|
89
|
+
}
|
|
90
|
+
const returns = ApiParser.getReturns(apiFunction);
|
|
91
|
+
if (returns) {
|
|
92
|
+
const description = escapeMdxGenerics(markdownCrossLinker.addCrossLinks(returns.description));
|
|
93
|
+
content += `## Returns\n\n${description}\n\n`;
|
|
94
|
+
}
|
|
95
|
+
const examples = ApiParser.getExamples(apiFunction);
|
|
96
|
+
if (examples.length > 0) {
|
|
97
|
+
content += `## Examples\n\n`;
|
|
98
|
+
for (const example of examples) {
|
|
99
|
+
const prepared = prepareExampleCode(example, name, packageName, shouldSuppressErrors);
|
|
100
|
+
const formattedCode = await formatExampleCode(prepared.code, prepared.language, {
|
|
101
|
+
api: packageName,
|
|
102
|
+
blockType: "example"
|
|
103
|
+
});
|
|
104
|
+
if (prepared.isTypeScript) {
|
|
105
|
+
const displayCode = stripTwoslashDirectives(formattedCode);
|
|
106
|
+
content += `<ApiExample code={${JSON.stringify(displayCode)}} source={${JSON.stringify(formattedCode)}} apiScope={${JSON.stringify(apiScope)}} />\n\n`;
|
|
107
|
+
} else content += `\`\`\`${prepared.language}\n${formattedCode}\n\`\`\`\n\n`;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const seeReferences = ApiParser.getSeeReferences(apiFunction);
|
|
111
|
+
if (seeReferences.length > 0) {
|
|
112
|
+
content += `## See Also\n\n`;
|
|
113
|
+
for (const reference of seeReferences) {
|
|
114
|
+
const refText = escapeMdxGenerics(markdownCrossLinker.addCrossLinks(reference.text));
|
|
115
|
+
content += `- ${refText}\n`;
|
|
116
|
+
}
|
|
117
|
+
content += `\n`;
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
routePath: `${baseRoute}/function/${name.toLowerCase()}`,
|
|
121
|
+
content
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
//#endregion
|
|
127
|
+
export { FunctionPageGenerator };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { escapeYamlString } from "../helpers.js";
|
|
2
|
+
|
|
3
|
+
//#region src/markdown/page-generators/index-pages.ts
|
|
4
|
+
/**
|
|
5
|
+
* Generator for main API index page with only frontmatter (no content)
|
|
6
|
+
*/
|
|
7
|
+
var MainIndexPageGenerator = class {
|
|
8
|
+
/**
|
|
9
|
+
* Generate the main API index page
|
|
10
|
+
*/
|
|
11
|
+
generate(packageName, baseRoute, _categoryCounts) {
|
|
12
|
+
const content = `---
|
|
13
|
+
title: API Reference
|
|
14
|
+
description: Auto-generated API documentation for ${escapeYamlString(packageName)}
|
|
15
|
+
overview: true
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
`;
|
|
19
|
+
return {
|
|
20
|
+
routePath: `${baseRoute}/index`,
|
|
21
|
+
content
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
export { MainIndexPageGenerator };
|