docgen: restructure docs into index + type docs

This commit is contained in:
Patrik Oldsberg
2020-07-16 11:43:06 +02:00
parent 2ec31c5264
commit f668388c9e
2 changed files with 107 additions and 16 deletions
+20 -7
View File
@@ -68,7 +68,6 @@ async function main() {
);
const apiDocGenerator = ApiDocGenerator.fromProgram(program, rootDir, srcDir);
const apiDocs = apis
.map(api => {
try {
@@ -79,7 +78,13 @@ async function main() {
);
}
})
.sort(sortSelector(x => x.id));
.sort(sortSelector(x => x.name));
const apiTypes = Object.values(
Object.fromEntries(
apiDocs.flatMap(d => d.interfaceInfos).map(i => [i.name, i]),
),
).sort(sortSelector(i => i.name));
const apiDocPrinter = new ApiDocPrinter(
() => new MarkdownPrinter(new TypescriptHighlighter()),
@@ -87,11 +92,16 @@ async function main() {
fs.ensureDirSync(resolve(apiRefsDir, 'docs'));
await Promise.all(
apiDocs.map(apiDoc => {
const data = apiDocPrinter.print(apiDoc);
await writeFile(
join(apiRefsDir, 'docs', 'README.md'),
apiDocPrinter.printApiIndex(apiDocs),
);
return writeFile(join(apiRefsDir, 'docs', `${apiDoc.name}.md`), data);
await Promise.all(
Object.values(apiTypes).map(apiType => {
const data = apiDocPrinter.printInterface(apiType, apiDocs);
return writeFile(join(apiRefsDir, 'docs', `${apiType.name}.md`), data);
}),
);
@@ -100,7 +110,10 @@ async function main() {
[
'site_name: api-references',
'nav:',
...apiDocs.map(({ id, name }) => ` - ${id}: '${name}.md'`),
` - Utility API Index: 'README.md'`,
...apiTypes.map(({ name }) => ` - ${name}: '${name}.md'`),
'plugins:',
' - techdocs-core',
].join('\n'),
'utf8',
);
+87 -9
View File
@@ -17,7 +17,7 @@
import { execSync } from 'child_process';
import MarkdownPrinter from './MarkdownPrinter';
import sortSelector from './sortSelector';
import { ApiDoc } from './types';
import { ApiDoc, InterfaceInfo } from './types';
const GH_BASE_URL = 'https://github.com/spotify/backstage';
@@ -67,7 +67,88 @@ export default class ApiDocPrinter {
);
printer.paragraph('All members of the interface are listed below.');
for (const member of ifInfo.members) {
this.addInterfaceMembers(printer, ifInfo);
if (ifInfo.dependentTypes.length) {
printer.header(2, 'Types');
this.addInterfaceTypes(printer, ifInfo);
}
return printer.toBuffer();
}
printApiIndex(apiDocs: ApiDoc[]): Buffer {
const printer = this.printerFactory();
printer.header(1, 'Backstage Utility APIs');
for (const api of apiDocs) {
printer.header(3, `${api.name.replace(/ApiRef$/, '')}`, api.id);
printer.paragraph(api.description);
const typeLinks = api.interfaceInfos.map(i => `[${i.name}](${i.name})`);
printer.paragraph(
`Implemented type${typeLinks.length > 1 ? 's' : ''}: ${typeLinks.join(
', ',
)}`,
);
printer.paragraph(`ApiRef: ${api.name}`);
}
return printer.toBuffer();
}
printInterface(apiType: InterfaceInfo, apiDocs: ApiDoc[]): Buffer {
const printer = this.printerFactory();
// Remove line numbers from codeblocks
printer.style('.linenodiv{ display: none }');
printer.header(1, apiType.name);
printer.paragraph(
`The ${apiType.name} type is defined at ${this.mkTypeLink(apiType)}.`,
);
const apiLinks = apiDocs
.filter(ad => ad.interfaceInfos.some(i => i.name === apiType.name))
.map(ad => `[${ad.name}](../#${ad.id})`);
if (apiLinks.length === 1) {
printer.paragraph(
`The following Utility API implements this type: ${apiLinks}`,
);
} else {
printer.paragraph(`The following Utility APIs implement this type:`);
for (const link of apiLinks) {
printer.text(` - ${link}`);
}
}
printer.header(2, 'Members');
this.addInterfaceMembers(printer, apiType);
if (apiType.dependentTypes.length) {
printer.header(2, 'Supporting types');
printer.paragraph(
'These types are part of the API declaration, but may not be unique to this API.',
);
this.addInterfaceTypes(printer, apiType);
}
return printer.toBuffer();
}
private addInterfaceMembers(
printer: MarkdownPrinter,
apiType: InterfaceInfo,
) {
for (const member of apiType.members) {
printer.header(
3,
`${member.name}${member.type === 'method' ? '()' : ''}`,
@@ -80,11 +161,10 @@ export default class ApiDocPrinter {
printer.codeWithLinks(member);
}
}
if (ifInfo.dependentTypes.length) {
printer.header(2, 'Types');
}
for (const type of ifInfo.dependentTypes
private addInterfaceTypes(printer: MarkdownPrinter, apiType: InterfaceInfo) {
for (const type of apiType.dependentTypes
.slice()
.sort(sortSelector(x => x.name))) {
printer.header(3, `${type.name}`, type.path);
@@ -96,7 +176,7 @@ export default class ApiDocPrinter {
printer.paragraph(`Defined at ${this.mkTypeLink(type)}.`);
const usageLinks = [...ifInfo.members, ...ifInfo.dependentTypes]
const usageLinks = [...apiType.members, ...apiType.dependentTypes]
.filter(member => {
return member.links.some(link => link.id === type.id);
})
@@ -106,7 +186,5 @@ export default class ApiDocPrinter {
printer.paragraph(`Referenced by: ${usageLinks.join(', ')}.`);
}
}
return printer.toBuffer();
}
}