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.
Files changed (37) hide show
  1. package/BuildEnv.js +0 -1
  2. package/build-program.js +4 -4
  3. package/build-stages.js +98 -281
  4. package/config-helpers.js +1 -1
  5. package/emit/mdx.js +311 -0
  6. package/emit/meta.js +62 -0
  7. package/index.d.ts +1 -42
  8. package/layers/build-metrics.js +1 -2
  9. package/layers/config-resolution.js +3 -5
  10. package/layers/type-environment.js +1 -2
  11. package/llms-program.js +3 -3
  12. package/markdown/helpers.js +10 -176
  13. package/observability/sinks/console-sink.js +0 -1
  14. package/observability/sinks/metrics-sink.js +0 -2
  15. package/package.json +6 -5
  16. package/path-derivation.js +1 -29
  17. package/plugin.js +2 -1
  18. package/prettier-formatter.js +27 -59
  19. package/remark-with-api.js +3 -2
  20. package/schemas/config.js +1 -18
  21. package/schemas/observability.js +0 -2
  22. package/schemas/performance.js +0 -1
  23. package/services/TwoslashCacheService.js +1 -1
  24. package/twoslash-transformer.js +14 -2
  25. package/code-post-processor.js +0 -38
  26. package/llms-processing.js +0 -270
  27. package/markdown/page-generators/class-page.js +0 -363
  28. package/markdown/page-generators/enum-page.js +0 -152
  29. package/markdown/page-generators/function-page.js +0 -127
  30. package/markdown/page-generators/index-pages.js +0 -25
  31. package/markdown/page-generators/interface-page.js +0 -310
  32. package/markdown/page-generators/namespace-page.js +0 -277
  33. package/markdown/page-generators/type-alias-page.js +0 -110
  34. package/markdown/page-generators/variable-page.js +0 -110
  35. package/markdown/prose-linker.js +0 -22
  36. package/twoslash-cache.js +0 -174
  37. package/twoslash-patterns.js +0 -87
@@ -1,277 +0,0 @@
1
- import { escapeMdxGenerics, formatExampleCode, generateAvailableFrom, generateFrontmatter, prepareExampleCode, prependHiddenImports, stripTwoslashDirectives } from "../helpers.js";
2
- import { linkProse } from "../prose-linker.js";
3
- import { ApiItemKind } from "@microsoft/api-extractor-model";
4
- import { ApiItems, Signature, Tsdoc, TypeReferenceExtractor } from "@tsdoctor/model";
5
-
6
- //#region src/markdown/page-generators/namespace-page.ts
7
- /**
8
- * Generates MDX documentation pages for TypeScript namespaces.
9
- *
10
- * This class transforms API Extractor namespace models into rich MDX documentation pages
11
- * with syntax-highlighted signatures, cross-linked type references, and member listings.
12
- *
13
- * **Page Structure:**
14
- * 1. Frontmatter with title, description, and Open Graph metadata
15
- * 2. Component imports (SourceCode, ApiSignature, etc.)
16
- * 3. Page title (H1) and summary
17
- * 4. Optional deprecation warning and release tag badge
18
- * 5. Source code link toolbar
19
- * 6. Full namespace signature block showing all members
20
- * 7. Member sections: Classes, Interfaces, Functions, Variables, Types, Enums, Namespaces
21
- * 8. Examples section with Twoslash-enabled code blocks
22
- * 9. See Also references
23
- *
24
- * **Member Rendering:**
25
- * Each member section lists members with links to their individual documentation pages.
26
- *
27
- * **Relationships:**
28
- * - Created and invoked by {@link ApiExtractorPlugin} during page generation
29
- * - Uses `Signature.format` from `@tsdoctor/model` for formatting type signatures
30
- * - Uses the `Tsdoc` / `ApiItems` modules from `@tsdoctor/model` for extracting documentation
31
- * - Uses the per-build prose linker (`linkProse`) for adding type reference links
32
- *
33
- * @example
34
- * ```ts
35
- * const generator = new NamespacePageGenerator();
36
- * const { routePath, content } = await generator.generate(
37
- * apiNamespace,
38
- * "/api/my-package",
39
- * "my-package",
40
- * "Namespace",
41
- * "My Package",
42
- * sourceConfig,
43
- * true, // suppressExampleErrors
44
- * undefined, // llmsPlugin
45
- * "my-scope"
46
- * );
47
- * ```
48
- *
49
- * @see {@link ClassPageGenerator} for class documentation
50
- * @see {@link InterfacePageGenerator} for interface documentation
51
- */
52
- var NamespacePageGenerator = class {
53
- /**
54
- * Generate a markdown page for a namespace
55
- *
56
- * @param apiScope - API scope identifier for VFS lookup
57
- */
58
- async generate(apiNamespace, baseRoute, packageName, singularName, apiScope, apiName, sourceConfig, suppressExampleErrors, llmsPlugin, availableFrom) {
59
- const shouldSuppressErrors = suppressExampleErrors ?? true;
60
- const name = apiNamespace.displayName;
61
- const summary = Tsdoc.summary(apiNamespace) || "No description available.";
62
- const releaseTag = Tsdoc.releaseTag(apiNamespace);
63
- let content = generateFrontmatter(name, summary, singularName, apiName);
64
- content += `import { SourceCode } from "@rspress/core/theme";\n`;
65
- content += `import { ApiSignature, ApiExample } from "rspress-plugin-api-extractor/runtime";\n\n`;
66
- content += `# ${name}\n\n`;
67
- const deprecation = Tsdoc.deprecation(apiNamespace);
68
- if (deprecation) {
69
- const message = escapeMdxGenerics(linkProse(deprecation.message));
70
- content += `> **Deprecated:** ${message}\n\n`;
71
- }
72
- if (releaseTag !== "Public") content += `\`${releaseTag}\`\n\n`;
73
- content += `${summary}\n\n`;
74
- content += generateAvailableFrom(packageName, availableFrom);
75
- const sourceLink = ApiItems.sourceLink(apiNamespace, sourceConfig);
76
- if (sourceLink) {
77
- content += `<div className="api-docs-toolbar">\n`;
78
- content += ` <div className="api-docs-toolbar-left">\n`;
79
- content += ` <SourceCode href="${sourceLink}" />\n`;
80
- content += ` </div>\n`;
81
- if (llmsPlugin?.enabled) {
82
- content += ` <div className="api-docs-toolbar-right">\n`;
83
- content += ` </div>\n`;
84
- }
85
- content += `</div>\n\n`;
86
- }
87
- const skeleton = this.generateNamespaceSkeletonWithTwoslash(apiNamespace, packageName);
88
- const displayCode = stripTwoslashDirectives(skeleton);
89
- content += `<ApiSignature code={${JSON.stringify(displayCode)}} source={${JSON.stringify(skeleton)}} apiScope={${JSON.stringify(apiScope)}} />\n\n`;
90
- const grouped = this.groupNamespaceMembers(apiNamespace.members);
91
- content += this.renderMemberSection("Classes", grouped.classes, baseRoute, "class", name);
92
- content += this.renderMemberSection("Interfaces", grouped.interfaces, baseRoute, "interface", name);
93
- content += this.renderMemberSection("Functions", grouped.functions, baseRoute, "function", name);
94
- content += this.renderMemberSection("Variables", grouped.variables, baseRoute, "variable", name);
95
- content += this.renderMemberSection("Types", grouped.typeAliases, baseRoute, "type", name);
96
- content += this.renderMemberSection("Enums", grouped.enums, baseRoute, "enum", name);
97
- content += this.renderMemberSection("Namespaces", grouped.namespaces, baseRoute, "namespace", name);
98
- const examples = Tsdoc.examples(apiNamespace);
99
- if (examples.length > 0) {
100
- content += `## Examples\n\n`;
101
- for (const example of examples) {
102
- const prepared = prepareExampleCode(example, name, packageName, shouldSuppressErrors);
103
- const formattedCode = await formatExampleCode(prepared.code, prepared.language, {
104
- api: packageName,
105
- blockType: "example"
106
- });
107
- if (prepared.isTypeScript) {
108
- const displayCode = stripTwoslashDirectives(formattedCode);
109
- content += `<ApiExample code={${JSON.stringify(displayCode)}} source={${JSON.stringify(formattedCode)}} apiScope={${JSON.stringify(apiScope)}} />\n\n`;
110
- } else content += `\`\`\`${prepared.language}\n${formattedCode}\n\`\`\`\n\n`;
111
- }
112
- }
113
- const seeReferences = Tsdoc.seeReferences(apiNamespace);
114
- if (seeReferences.length > 0) {
115
- content += `## See Also\n\n`;
116
- for (const reference of seeReferences) {
117
- const refText = escapeMdxGenerics(linkProse(reference.text));
118
- content += `- ${refText}\n`;
119
- }
120
- content += `\n`;
121
- }
122
- return {
123
- routePath: `${baseRoute}/namespace/${name.toLowerCase()}`,
124
- content
125
- };
126
- }
127
- /**
128
- * Group namespace members by their type
129
- */
130
- groupNamespaceMembers(members) {
131
- const classes = [];
132
- const interfaces = [];
133
- const functions = [];
134
- const variables = [];
135
- const typeAliases = [];
136
- const enums = [];
137
- const namespaces = [];
138
- for (const member of members) switch (member.kind) {
139
- case ApiItemKind.Class:
140
- classes.push(member);
141
- break;
142
- case ApiItemKind.Interface:
143
- interfaces.push(member);
144
- break;
145
- case ApiItemKind.Function:
146
- functions.push(member);
147
- break;
148
- case ApiItemKind.Variable:
149
- variables.push(member);
150
- break;
151
- case ApiItemKind.TypeAlias:
152
- typeAliases.push(member);
153
- break;
154
- case ApiItemKind.Enum:
155
- enums.push(member);
156
- break;
157
- case ApiItemKind.Namespace: namespaces.push(member);
158
- }
159
- return {
160
- classes,
161
- interfaces,
162
- functions,
163
- variables,
164
- typeAliases,
165
- enums,
166
- namespaces
167
- };
168
- }
169
- /**
170
- * Render a section of members with links to their pages
171
- * @param title - Section heading
172
- * @param members - Array of API items to list
173
- * @param baseRoute - Base API route (e.g., /api/package)
174
- * @param categoryFolder - Category folder name (e.g., "class", "function")
175
- * @param namespaceName - Parent namespace name for qualified routes
176
- */
177
- renderMemberSection(title, members, baseRoute, categoryFolder, namespaceName) {
178
- if (members.length === 0) return "";
179
- let section = `## ${title}\n\n`;
180
- for (const member of members) {
181
- const memberName = member.displayName;
182
- const memberSummary = Tsdoc.summary(member);
183
- const memberRoute = `${baseRoute}/${categoryFolder}/${`${namespaceName}.${memberName}`.toLowerCase()}`;
184
- if (memberSummary) {
185
- const escapedSummary = escapeMdxGenerics(linkProse(memberSummary));
186
- section += `- [${memberName}](${memberRoute}) - ${escapedSummary}\n`;
187
- } else section += `- [${memberName}](${memberRoute})\n`;
188
- }
189
- section += `\n`;
190
- return section;
191
- }
192
- /**
193
- * Generate a namespace skeleton for signature blocks
194
- * Includes hidden imports with cut directive for external type resolution
195
- */
196
- generateNamespaceSkeletonWithTwoslash(apiNamespace, packageName) {
197
- const skeleton = this.generateNamespaceSkeleton(apiNamespace);
198
- const apiPackage = apiNamespace.getAssociatedPackage?.();
199
- if (apiPackage) {
200
- const imports = new TypeReferenceExtractor(apiPackage, packageName).extractImportsForApiItem(apiNamespace);
201
- return prependHiddenImports(skeleton, imports);
202
- }
203
- return skeleton;
204
- }
205
- /**
206
- * Generate a complete namespace skeleton showing all members
207
- */
208
- generateNamespaceSkeleton(apiNamespace) {
209
- const lines = [];
210
- const namespaceName = apiNamespace.displayName;
211
- lines.push(`namespace ${namespaceName} {`);
212
- const grouped = this.groupNamespaceMembers(apiNamespace.members);
213
- for (const cls of grouped.classes) {
214
- const clsItem = cls;
215
- if (clsItem.excerpt?.text) {
216
- const signature = Signature.format(clsItem.excerpt).trim();
217
- lines.push(` ${this.abbreviateDeclaration(signature, "class")} { }`);
218
- }
219
- }
220
- for (const iface of grouped.interfaces) {
221
- const ifaceItem = iface;
222
- if (ifaceItem.excerpt?.text) {
223
- const signature = Signature.format(ifaceItem.excerpt).trim();
224
- lines.push(` ${this.abbreviateDeclaration(signature, "interface")} { }`);
225
- }
226
- }
227
- for (const func of grouped.functions) {
228
- const funcItem = func;
229
- if (funcItem.excerpt?.text) {
230
- const signature = Signature.format(funcItem.excerpt).trim();
231
- lines.push(` ${signature}`);
232
- }
233
- }
234
- for (const variable of grouped.variables) {
235
- const varItem = variable;
236
- if (varItem.excerpt?.text) {
237
- const signature = Signature.format(varItem.excerpt).trim();
238
- lines.push(` ${signature}`);
239
- }
240
- }
241
- for (const typeAlias of grouped.typeAliases) {
242
- const typeItem = typeAlias;
243
- if (typeItem.excerpt?.text) {
244
- const signature = Signature.format(typeItem.excerpt).trim();
245
- lines.push(` ${signature}`);
246
- }
247
- }
248
- for (const enumItem of grouped.enums) {
249
- const enumDeclItem = enumItem;
250
- if (enumDeclItem.excerpt?.text) {
251
- const signature = Signature.format(enumDeclItem.excerpt).trim();
252
- lines.push(` ${this.abbreviateDeclaration(signature, "enum")} { }`);
253
- }
254
- }
255
- for (const ns of grouped.namespaces) {
256
- const nsItem = ns;
257
- if (nsItem.excerpt?.text) {
258
- const signature = Signature.format(nsItem.excerpt).trim();
259
- lines.push(` ${this.abbreviateDeclaration(signature, "namespace")} { }`);
260
- }
261
- }
262
- lines.push("}");
263
- return lines.join("\n");
264
- }
265
- /**
266
- * Abbreviate a full declaration to just its header
267
- * For example, `class Foo extends Bar implements Baz \{ ... \}` becomes `class Foo extends Bar implements Baz`
268
- */
269
- abbreviateDeclaration(signature, _keyword) {
270
- const braceIndex = signature.indexOf("{");
271
- if (braceIndex === -1) return signature;
272
- return signature.substring(0, braceIndex).trim();
273
- }
274
- };
275
-
276
- //#endregion
277
- export { NamespacePageGenerator };
@@ -1,110 +0,0 @@
1
- import { escapeMdxGenerics, formatExampleCode, generateAvailableFrom, generateFrontmatter, prepareExampleCode, prependHiddenImports, stripTwoslashDirectives } from "../helpers.js";
2
- import { linkProse } from "../prose-linker.js";
3
- import { ApiItems, Signature, Tsdoc, TypeReferenceExtractor } from "@tsdoctor/model";
4
-
5
- //#region src/markdown/page-generators/type-alias-page.ts
6
- /**
7
- * Generates MDX documentation pages for TypeScript type aliases.
8
- *
9
- * This class transforms API Extractor type alias models into rich MDX documentation
10
- * pages with syntax-highlighted signatures and cross-linked type references.
11
- *
12
- * **Page Structure:**
13
- * 1. Frontmatter with title, description, and Open Graph metadata
14
- * 2. Component imports
15
- * 3. Page title (H1) and summary
16
- * 4. Optional deprecation warning and release tag badge
17
- * 5. Source code link toolbar
18
- * 6. Type alias signature block (full type definition)
19
- * 7. Examples section with Twoslash-enabled code blocks
20
- * 8. See Also references
21
- *
22
- * **Relationships:**
23
- * - Created and invoked by {@link ApiExtractorPlugin} during page generation
24
- * - Uses `Signature.format` from `@tsdoctor/model` for formatting type signatures
25
- * - Uses the `Tsdoc` / `ApiItems` modules from `@tsdoctor/model` for extracting documentation
26
- * - Uses the per-build prose linker (`linkProse`) for adding type reference links
27
- *
28
- * @see {@link InterfacePageGenerator} for interface documentation
29
- * @see {@link EnumPageGenerator} for enum documentation
30
- */
31
- var TypeAliasPageGenerator = class {
32
- /**
33
- * Generate a markdown page for a type alias
34
- *
35
- * @param apiScope - API scope identifier for VFS lookup
36
- */
37
- async generate(apiTypeAlias, baseRoute, packageName, singularName, apiScope, apiName, sourceConfig, suppressExampleErrors, llmsPlugin, availableFrom) {
38
- const shouldSuppressErrors = suppressExampleErrors ?? true;
39
- const name = apiTypeAlias.displayName;
40
- const summary = Tsdoc.summary(apiTypeAlias) || "No description available.";
41
- const releaseTag = Tsdoc.releaseTag(apiTypeAlias);
42
- let content = generateFrontmatter(name, summary, singularName, apiName);
43
- content += `import { SourceCode } from "@rspress/core/theme";\n`;
44
- content += `import { ParametersTable } from "rspress-plugin-api-extractor/runtime";\n`;
45
- content += `import { ApiSignature, ApiExample } from "rspress-plugin-api-extractor/runtime";\n\n`;
46
- content += `# ${name}\n\n`;
47
- const deprecation = Tsdoc.deprecation(apiTypeAlias);
48
- if (deprecation) {
49
- const message = escapeMdxGenerics(linkProse(deprecation.message));
50
- content += `> ⚠️ **Deprecated:** ${message}\n\n`;
51
- }
52
- if (releaseTag !== "Public") content += `\`${releaseTag}\`\n\n`;
53
- content += `${summary}\n\n`;
54
- content += generateAvailableFrom(packageName, availableFrom);
55
- const sourceLink = ApiItems.sourceLink(apiTypeAlias, sourceConfig);
56
- if (sourceLink) {
57
- content += `<div className="api-docs-toolbar">\n`;
58
- content += ` <div className="api-docs-toolbar-left">\n`;
59
- content += ` <SourceCode href="${sourceLink}" />\n`;
60
- content += ` </div>\n`;
61
- if (llmsPlugin?.enabled) {
62
- content += ` <div className="api-docs-toolbar-right">\n`;
63
- content += ` </div>\n`;
64
- }
65
- content += `</div>\n\n`;
66
- }
67
- if (apiTypeAlias.excerpt.text) {
68
- const signature = Signature.format(apiTypeAlias.excerpt).trim();
69
- let signatureWithImports = signature;
70
- const apiPackage = apiTypeAlias.getAssociatedPackage?.();
71
- if (apiPackage) {
72
- const imports = new TypeReferenceExtractor(apiPackage, packageName).extractImportsForApiItem(apiTypeAlias);
73
- signatureWithImports = prependHiddenImports(signature, imports);
74
- }
75
- const displayCode = stripTwoslashDirectives(signatureWithImports);
76
- content += `<ApiSignature code={${JSON.stringify(displayCode)}} source={${JSON.stringify(signatureWithImports)}} apiScope={${JSON.stringify(apiScope)}} />\n\n`;
77
- }
78
- const examples = Tsdoc.examples(apiTypeAlias);
79
- if (examples.length > 0) {
80
- content += `## Examples\n\n`;
81
- for (const example of examples) {
82
- const prepared = prepareExampleCode(example, name, packageName, shouldSuppressErrors);
83
- const formattedCode = await formatExampleCode(prepared.code, prepared.language, {
84
- api: packageName,
85
- blockType: "example"
86
- });
87
- if (prepared.isTypeScript) {
88
- const displayCode = stripTwoslashDirectives(formattedCode);
89
- content += `<ApiExample code={${JSON.stringify(displayCode)}} source={${JSON.stringify(formattedCode)}} apiScope={${JSON.stringify(apiScope)}} />\n\n`;
90
- } else content += `\`\`\`${prepared.language}\n${formattedCode}\n\`\`\`\n\n`;
91
- }
92
- }
93
- const seeReferences = Tsdoc.seeReferences(apiTypeAlias);
94
- if (seeReferences.length > 0) {
95
- content += `## See Also\n\n`;
96
- for (const reference of seeReferences) {
97
- const refText = escapeMdxGenerics(linkProse(reference.text));
98
- content += `- ${refText}\n`;
99
- }
100
- content += `\n`;
101
- }
102
- return {
103
- routePath: `${baseRoute}/type/${name.toLowerCase()}`,
104
- content
105
- };
106
- }
107
- };
108
-
109
- //#endregion
110
- export { TypeAliasPageGenerator };
@@ -1,110 +0,0 @@
1
- import { escapeMdxGenerics, formatExampleCode, generateAvailableFrom, generateFrontmatter, prepareExampleCode, prependHiddenImports, stripTwoslashDirectives } from "../helpers.js";
2
- import { linkProse } from "../prose-linker.js";
3
- import { ApiItems, Signature, Tsdoc, TypeReferenceExtractor } from "@tsdoctor/model";
4
-
5
- //#region src/markdown/page-generators/variable-page.ts
6
- /**
7
- * Generates MDX documentation pages for exported variables and constants.
8
- *
9
- * This class transforms API Extractor variable models into rich MDX documentation
10
- * pages with syntax-highlighted signatures and cross-linked type references.
11
- *
12
- * **Page Structure:**
13
- * 1. Frontmatter with title, description, and Open Graph metadata
14
- * 2. Component imports
15
- * 3. Page title (H1) and summary
16
- * 4. Optional deprecation warning and release tag badge
17
- * 5. Source code link toolbar
18
- * 6. Variable signature block (const/let declaration with type)
19
- * 7. Examples section with Twoslash-enabled code blocks
20
- * 8. See Also references
21
- *
22
- * **Relationships:**
23
- * - Created and invoked by {@link ApiExtractorPlugin} during page generation
24
- * - Uses `Signature.format` from `@tsdoctor/model` for formatting type signatures
25
- * - Uses the `Tsdoc` / `ApiItems` modules from `@tsdoctor/model` for extracting documentation
26
- * - Uses the per-build prose linker (`linkProse`) for adding type reference links
27
- *
28
- * @see {@link FunctionPageGenerator} for function documentation
29
- * @see {@link EnumPageGenerator} for enum documentation
30
- */
31
- var VariablePageGenerator = class {
32
- /**
33
- * Generate a markdown page for a variable
34
- *
35
- * @param apiScope - API scope identifier for VFS lookup
36
- */
37
- async generate(apiVariable, baseRoute, packageName, singularName, apiScope, apiName, sourceConfig, suppressExampleErrors, llmsPlugin, availableFrom) {
38
- const shouldSuppressErrors = suppressExampleErrors ?? true;
39
- const name = apiVariable.displayName;
40
- const summary = Tsdoc.summary(apiVariable) || "No description available.";
41
- const releaseTag = Tsdoc.releaseTag(apiVariable);
42
- let content = generateFrontmatter(name, summary, singularName, apiName);
43
- content += `import { SourceCode } from "@rspress/core/theme";\n`;
44
- content += `import { ParametersTable } from "rspress-plugin-api-extractor/runtime";\n`;
45
- content += `import { ApiSignature, ApiExample } from "rspress-plugin-api-extractor/runtime";\n\n`;
46
- content += `# ${name}\n\n`;
47
- const deprecation = Tsdoc.deprecation(apiVariable);
48
- if (deprecation) {
49
- const message = escapeMdxGenerics(linkProse(deprecation.message));
50
- content += `> ⚠️ **Deprecated:** ${message}\n\n`;
51
- }
52
- if (releaseTag !== "Public") content += `\`${releaseTag}\`\n\n`;
53
- content += `${summary}\n\n`;
54
- content += generateAvailableFrom(packageName, availableFrom);
55
- const sourceLink = ApiItems.sourceLink(apiVariable, sourceConfig);
56
- if (sourceLink) {
57
- content += `<div className="api-docs-toolbar">\n`;
58
- content += ` <div className="api-docs-toolbar-left">\n`;
59
- content += ` <SourceCode href="${sourceLink}" />\n`;
60
- content += ` </div>\n`;
61
- if (llmsPlugin?.enabled) {
62
- content += ` <div className="api-docs-toolbar-right">\n`;
63
- content += ` </div>\n`;
64
- }
65
- content += `</div>\n\n`;
66
- }
67
- if (apiVariable.excerpt.text) {
68
- const signature = Signature.format(apiVariable.excerpt).trim();
69
- let signatureWithImports = signature;
70
- const apiPackage = apiVariable.getAssociatedPackage?.();
71
- if (apiPackage) {
72
- const imports = new TypeReferenceExtractor(apiPackage, packageName).extractImportsForApiItem(apiVariable);
73
- signatureWithImports = prependHiddenImports(signature, imports);
74
- }
75
- const displayCode = stripTwoslashDirectives(signatureWithImports);
76
- content += `<ApiSignature code={${JSON.stringify(displayCode)}} source={${JSON.stringify(signatureWithImports)}} apiScope={${JSON.stringify(apiScope)}} />\n\n`;
77
- }
78
- const examples = Tsdoc.examples(apiVariable);
79
- if (examples.length > 0) {
80
- content += `## Examples\n\n`;
81
- for (const example of examples) {
82
- const prepared = prepareExampleCode(example, name, packageName, shouldSuppressErrors);
83
- const formattedCode = await formatExampleCode(prepared.code, prepared.language, {
84
- api: packageName,
85
- blockType: "example"
86
- });
87
- if (prepared.isTypeScript) {
88
- const displayCode = stripTwoslashDirectives(formattedCode);
89
- content += `<ApiExample code={${JSON.stringify(displayCode)}} source={${JSON.stringify(formattedCode)}} apiScope={${JSON.stringify(apiScope)}} />\n\n`;
90
- } else content += `\`\`\`${prepared.language}\n${formattedCode}\n\`\`\`\n\n`;
91
- }
92
- }
93
- const seeReferences = Tsdoc.seeReferences(apiVariable);
94
- if (seeReferences.length > 0) {
95
- content += `## See Also\n\n`;
96
- for (const reference of seeReferences) {
97
- const refText = escapeMdxGenerics(linkProse(reference.text));
98
- content += `- ${refText}\n`;
99
- }
100
- content += `\n`;
101
- }
102
- return {
103
- routePath: `${baseRoute}/variable/${name.toLowerCase()}`,
104
- content
105
- };
106
- }
107
- };
108
-
109
- //#endregion
110
- export { VariablePageGenerator };
@@ -1,22 +0,0 @@
1
- import { CrossLinker } from "@tsdoctor/model";
2
-
3
- //#region src/markdown/prose-linker.ts
4
- /**
5
- * Per-build prose cross-linker holder. Adapter wiring, not logic: the build
6
- * program installs the immutable `@tsdoctor/model` CrossLinker built from the
7
- * routes `prepareWorkItems` computed, and page generators link prose through
8
- * it. Page generators run synchronously outside any service context, hence
9
- * the module-level holder (the same shape as the sync-island event emitters).
10
- */
11
- let current = CrossLinker.empty;
12
- /** Install the cross-linker for the current API build from its route map. */
13
- function setProseLinker(routes) {
14
- current = CrossLinker.fromRoutes(routes);
15
- }
16
- /** Cross-link prose text with the currently installed linker. */
17
- function linkProse(text) {
18
- return current.link(text);
19
- }
20
-
21
- //#endregion
22
- export { linkProse, setProseLinker };