Skip to content

generate links for namespaces correctly #4809

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions repo-scripts/api-documenter/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"name": "@firebase/api-documenter",
"version": "0.1.0",
"private": true,
"description": "Read JSON files from api-extractor, generate documentation pages",
"repository": {
"directory": "repo-scripts/documenter",
Expand All @@ -14,17 +13,21 @@
"test": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha src/**/*.test.ts --config ../../config/mocharc.node.js"
},
"bin": {
"api-documenter": "./bin/api-documenter"
"api-documenter-fire": "./dist/start.js"
},
"main": "lib/index.js",
"files": [
"dist"
],
"main": "dist/index.js",
"typings": "dist/rollup.d.ts",
"dependencies": {
"api-extractor-model-me": "0.1.1",
"@microsoft/tsdoc": "0.12.24",
"@rushstack/node-core-library": "3.36.0",
"@rushstack/ts-command-line": "4.7.8",
"colors": "~1.2.1",
"resolve": "~1.17.0"
"resolve": "~1.17.0",
"tslib": "^2.1.0"
},
"devDependencies": {
"@types/resolve": "1.17.1",
Expand Down
18 changes: 17 additions & 1 deletion repo-scripts/api-documenter/src/cli/BaseAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import colors from 'colors';

import {
CommandLineAction,
CommandLineFlagParameter,
CommandLineStringParameter
} from '@rushstack/ts-command-line';
import { FileSystem } from '@rushstack/node-core-library';
Expand All @@ -39,11 +40,13 @@ export interface IBuildApiModelResult {
apiModel: ApiModel;
inputFolder: string;
outputFolder: string;
addFileNameSuffix: boolean;
}

export abstract class BaseAction extends CommandLineAction {
private _inputFolderParameter!: CommandLineStringParameter;
private _outputFolderParameter!: CommandLineStringParameter;
private _fileNameSuffixParameter!: CommandLineFlagParameter;

protected onDefineParameters(): void {
// override
Expand All @@ -65,6 +68,17 @@ export abstract class BaseAction extends CommandLineAction {
` ANY EXISTING CONTENTS WILL BE DELETED!` +
` If omitted, the default is "./${this.actionName}"`
});

this._fileNameSuffixParameter = this.defineFlagParameter({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this defaults to false?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct.

parameterLongName: '--name-suffix',
parameterShortName: '-s',
description:
`Add suffix to interface and class names in the file path.` +
`For example, packageA.myinterface_i.md for MyInterface interface, ` +
`Add packageA.myclass_c.md for MyClass class.` +
`This is to avoid name conflict in case packageA also has, for example, an entry point with the same name in lowercase.` +
`This option is specifically designed for the Admin SDK where such case occurs.`
});
}

protected buildApiModel(): IBuildApiModelResult {
Expand All @@ -79,6 +93,8 @@ export abstract class BaseAction extends CommandLineAction {
this._outputFolderParameter.value || `./${this.actionName}`;
FileSystem.ensureFolder(outputFolder);

const addFileNameSuffix: boolean = this._fileNameSuffixParameter.value;

for (const filename of FileSystem.readFolder(inputFolder)) {
if (filename.match(/\.api\.json$/i)) {
console.log(`Reading ${filename}`);
Expand All @@ -89,7 +105,7 @@ export abstract class BaseAction extends CommandLineAction {

this._applyInheritDoc(apiModel, apiModel);

return { apiModel, inputFolder, outputFolder };
return { apiModel, inputFolder, outputFolder, addFileNameSuffix };
}

// TODO: This is a temporary workaround. The long term plan is for API Extractor's DocCommentEnhancer
Expand Down
5 changes: 3 additions & 2 deletions repo-scripts/api-documenter/src/cli/MarkdownAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@ export class MarkdownAction extends BaseAction {

protected async onExecute(): Promise<void> {
// override
const { apiModel, outputFolder } = this.buildApiModel();
const { apiModel, outputFolder, addFileNameSuffix } = this.buildApiModel();

const markdownDocumenter: MarkdownDocumenter = new MarkdownDocumenter({
apiModel,
documenterConfig: undefined,
outputFolder
outputFolder,
addFileNameSuffix
});
markdownDocumenter.generateFiles();
}
Expand Down
66 changes: 52 additions & 14 deletions repo-scripts/api-documenter/src/documenters/MarkdownDocumenter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export interface IMarkdownDocumenterOptions {
apiModel: ApiModel;
documenterConfig: DocumenterConfig | undefined;
outputFolder: string;
addFileNameSuffix: boolean;
}

/**
Expand All @@ -104,11 +105,13 @@ export class MarkdownDocumenter {
private readonly _markdownEmitter: CustomMarkdownEmitter;
private readonly _outputFolder: string;
private readonly _pluginLoader: PluginLoader;
private readonly _addFileNameSuffix: boolean;

public constructor(options: IMarkdownDocumenterOptions) {
this._apiModel = options.apiModel;
this._documenterConfig = options.documenterConfig;
this._outputFolder = options.outputFolder;
this._addFileNameSuffix = options.addFileNameSuffix;
this._tsdocConfiguration = CustomDocNodes.configuration;
this._markdownEmitter = new CustomMarkdownEmitter(this._apiModel);

Expand All @@ -123,7 +126,7 @@ export class MarkdownDocumenter {
outputFolder: this._outputFolder,
documenter: new MarkdownDocumenterAccessor({
getLinkForApiItem: (apiItem: ApiItem) => {
return getLinkForApiItem(apiItem);
return getLinkForApiItem(apiItem, this._addFileNameSuffix);
}
})
});
Expand Down Expand Up @@ -156,7 +159,7 @@ export class MarkdownDocumenter {
// write to file
const filename: string = path.join(
this._outputFolder,
getFilenameForApiItem(apiItem)
getFilenameForApiItem(apiItem, this._addFileNameSuffix)
);
const stringBuilder: StringBuilder = new StringBuilder();

Expand All @@ -172,7 +175,7 @@ export class MarkdownDocumenter {
this._markdownEmitter.emit(stringBuilder, output, {
contextApiItem: apiItem,
onGetFilenameForApiItem: (apiItemForFilename: ApiItem) => {
return getLinkForApiItem(apiItemForFilename);
return getLinkForApiItem(apiItemForFilename, this._addFileNameSuffix);
}
});

Expand Down Expand Up @@ -393,7 +396,11 @@ export class MarkdownDocumenter {
case ApiItemKind.Constructor: {
constructorsTable.addRow(
new DocTableRow({ configuration }, [
createTitleCell(apiMember, configuration),
createTitleCell(
apiMember,
configuration,
this._addFileNameSuffix
),
createModifiersCell(apiMember, configuration),
createDescriptionCell(apiMember, configuration)
])
Expand All @@ -407,7 +414,11 @@ export class MarkdownDocumenter {
case ApiItemKind.Method: {
methodsTable.addRow(
new DocTableRow({ configuration }, [
createTitleCell(apiMember, configuration),
createTitleCell(
apiMember,
configuration,
this._addFileNameSuffix
),
createModifiersCell(apiMember, configuration),
createDescriptionCell(apiMember, configuration)
])
Expand All @@ -422,7 +433,11 @@ export class MarkdownDocumenter {
if ((apiMember as ApiPropertyItem).isEventProperty) {
eventsTable.addRow(
new DocTableRow({ configuration }, [
createTitleCell(apiMember, configuration),
createTitleCell(
apiMember,
configuration,
this._addFileNameSuffix
),
createModifiersCell(apiMember, configuration),
this._createPropertyTypeCell(apiMember),
createDescriptionCell(apiMember, configuration)
Expand All @@ -435,7 +450,11 @@ export class MarkdownDocumenter {
} else {
propertiesTable.addRow(
new DocTableRow({ configuration }, [
createTitleCell(apiMember, configuration),
createTitleCell(
apiMember,
configuration,
this._addFileNameSuffix
),
createModifiersCell(apiMember, configuration),
this._createPropertyTypeCell(apiMember),
createDescriptionCell(apiMember, configuration)
Expand Down Expand Up @@ -509,7 +528,11 @@ export class MarkdownDocumenter {
case ApiItemKind.MethodSignature: {
methodsTable.addRow(
new DocTableRow({ configuration }, [
createTitleCell(apiMember, configuration),
createTitleCell(
apiMember,
configuration,
this._addFileNameSuffix
),
createDescriptionCell(apiMember, configuration)
])
);
Expand All @@ -523,7 +546,11 @@ export class MarkdownDocumenter {
if ((apiMember as ApiPropertyItem).isEventProperty) {
eventsTable.addRow(
new DocTableRow({ configuration }, [
createTitleCell(apiMember, configuration),
createTitleCell(
apiMember,
configuration,
this._addFileNameSuffix
),
this._createPropertyTypeCell(apiMember),
createDescriptionCell(apiMember, configuration)
])
Expand All @@ -534,7 +561,11 @@ export class MarkdownDocumenter {
} else {
propertiesTable.addRow(
new DocTableRow({ configuration }, [
createTitleCell(apiMember, configuration),
createTitleCell(
apiMember,
configuration,
this._addFileNameSuffix
),
this._createPropertyTypeCell(apiMember),
createDescriptionCell(apiMember, configuration)
])
Expand Down Expand Up @@ -686,7 +717,10 @@ export class MarkdownDocumenter {
configuration,
tagName: '@link',
linkText: unwrappedTokenText,
urlDestination: getLinkForApiItem(apiItemResult.resolvedApiItem)
urlDestination: getLinkForApiItem(
apiItemResult.resolvedApiItem,
this._addFileNameSuffix
)
})
);
continue;
Expand Down Expand Up @@ -714,7 +748,7 @@ export class MarkdownDocumenter {

for (const apiMember of apiModel.members) {
const row: DocTableRow = new DocTableRow({ configuration }, [
createTitleCell(apiMember, configuration),
createTitleCell(apiMember, configuration, this._addFileNameSuffix),
createDescriptionCell(apiMember, configuration)
]);

Expand Down Expand Up @@ -755,7 +789,11 @@ export class MarkdownDocumenter {

for (const entryPoint of apiContainer.entryPoints) {
const row: DocTableRow = new DocTableRow({ configuration }, [
createEntryPointTitleCell(entryPoint, configuration),
createEntryPointTitleCell(
entryPoint,
configuration,
this._addFileNameSuffix
),
createDescriptionCell(entryPoint, configuration)
]);

Expand Down Expand Up @@ -828,7 +866,7 @@ export class MarkdownDocumenter {

for (const apiMember of apiMembers) {
const row: DocTableRow = new DocTableRow({ configuration }, [
createTitleCell(apiMember, configuration),
createTitleCell(apiMember, configuration, this._addFileNameSuffix),
createDescriptionCell(apiMember, configuration)
]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,19 @@ import { DocNoteBox } from '../nodes/DocNoteBox';
import { DocTableRow } from '../nodes/DocTableRow';
import { DocTableCell } from '../nodes/DocTableCell';

export function getLinkForApiItem(apiItem: ApiItem) {
const fileName = getFilenameForApiItem(apiItem);
export function getLinkForApiItem(
apiItem: ApiItem,
addFileNameSuffix: boolean
) {
const fileName = getFilenameForApiItem(apiItem, addFileNameSuffix);
const headingAnchor = getHeadingAnchorForApiItem(apiItem);
return `./${fileName}#${headingAnchor}`;
}

export function getFilenameForApiItem(apiItem: ApiItem): string {
export function getFilenameForApiItem(
apiItem: ApiItem,
addFileNameSuffix: boolean
): string {
if (apiItem.kind === ApiItemKind.Model) {
return 'index.md';
}
Expand Down Expand Up @@ -96,9 +102,27 @@ export function getFilenameForApiItem(apiItem: ApiItem): string {
multipleEntryPoints = true;
}
break;
case ApiItemKind.Namespace:
baseName += '.' + qualifiedName;
if (addFileNameSuffix) {
baseName += '_n';
}
break;
// append the file name with the first letter of the ApiItemKind to avoid name collision.
// Sometimes we could have a class/interface and an entry point that have the same name.
// This happened in the admin SDK where the App interface and the app namespace write to the same file.
case ApiItemKind.Class:
baseName += '.' + qualifiedName;
if (addFileNameSuffix) {
baseName += '_c';
}
break;
case ApiItemKind.Interface:
baseName += '.' + qualifiedName;
if (addFileNameSuffix) {
baseName += '_i';
}
break;
}
}
return baseName + '.md';
Expand Down Expand Up @@ -224,15 +248,16 @@ export function createExampleSection(

export function createTitleCell(
apiItem: ApiItem,
configuration: TSDocConfiguration
configuration: TSDocConfiguration,
addFileNameSuffix: boolean
): DocTableCell {
return new DocTableCell({ configuration }, [
new DocParagraph({ configuration }, [
new DocLinkTag({
configuration,
tagName: '@link',
linkText: Utilities.getConciseSignature(apiItem),
urlDestination: getLinkForApiItem(apiItem)
urlDestination: getLinkForApiItem(apiItem, addFileNameSuffix)
})
])
]);
Expand Down Expand Up @@ -339,15 +364,16 @@ export function createThrowsSection(

export function createEntryPointTitleCell(
apiItem: ApiEntryPoint,
configuration: TSDocConfiguration
configuration: TSDocConfiguration,
addFileNameSuffix: boolean
): DocTableCell {
return new DocTableCell({ configuration }, [
new DocParagraph({ configuration }, [
new DocLinkTag({
configuration,
tagName: '@link',
linkText: `/${apiItem.displayName}`,
urlDestination: getLinkForApiItem(apiItem)
urlDestination: getLinkForApiItem(apiItem, addFileNameSuffix)
})
])
]);
Expand Down
2 changes: 2 additions & 0 deletions repo-scripts/api-documenter/src/start.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/usr/bin/env node

/**
* @license
* Copyright 2020 Google LLC
Expand Down