Skip to content

Commit d442eb2

Browse files
authored
generate links for namespaces correctly (#4809)
* generate link for namespaces correctly * add addFileNameSuffix option * add suffix to namespace files * prepare for publishing
1 parent 40888a0 commit d442eb2

File tree

6 files changed

+114
-28
lines changed

6 files changed

+114
-28
lines changed

repo-scripts/api-documenter/package.json

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
{
22
"name": "@firebase/api-documenter",
33
"version": "0.1.0",
4-
"private": true,
54
"description": "Read JSON files from api-extractor, generate documentation pages",
65
"repository": {
76
"directory": "repo-scripts/documenter",
@@ -14,17 +13,21 @@
1413
"test": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha src/**/*.test.ts --config ../../config/mocharc.node.js"
1514
},
1615
"bin": {
17-
"api-documenter": "./bin/api-documenter"
16+
"api-documenter-fire": "./dist/start.js"
1817
},
19-
"main": "lib/index.js",
18+
"files": [
19+
"dist"
20+
],
21+
"main": "dist/index.js",
2022
"typings": "dist/rollup.d.ts",
2123
"dependencies": {
2224
"api-extractor-model-me": "0.1.1",
2325
"@microsoft/tsdoc": "0.12.24",
2426
"@rushstack/node-core-library": "3.36.0",
2527
"@rushstack/ts-command-line": "4.7.8",
2628
"colors": "~1.2.1",
27-
"resolve": "~1.17.0"
29+
"resolve": "~1.17.0",
30+
"tslib": "^2.1.0"
2831
},
2932
"devDependencies": {
3033
"@types/resolve": "1.17.1",

repo-scripts/api-documenter/src/cli/BaseAction.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import colors from 'colors';
2424

2525
import {
2626
CommandLineAction,
27+
CommandLineFlagParameter,
2728
CommandLineStringParameter
2829
} from '@rushstack/ts-command-line';
2930
import { FileSystem } from '@rushstack/node-core-library';
@@ -39,11 +40,13 @@ export interface IBuildApiModelResult {
3940
apiModel: ApiModel;
4041
inputFolder: string;
4142
outputFolder: string;
43+
addFileNameSuffix: boolean;
4244
}
4345

4446
export abstract class BaseAction extends CommandLineAction {
4547
private _inputFolderParameter!: CommandLineStringParameter;
4648
private _outputFolderParameter!: CommandLineStringParameter;
49+
private _fileNameSuffixParameter!: CommandLineFlagParameter;
4750

4851
protected onDefineParameters(): void {
4952
// override
@@ -65,6 +68,17 @@ export abstract class BaseAction extends CommandLineAction {
6568
` ANY EXISTING CONTENTS WILL BE DELETED!` +
6669
` If omitted, the default is "./${this.actionName}"`
6770
});
71+
72+
this._fileNameSuffixParameter = this.defineFlagParameter({
73+
parameterLongName: '--name-suffix',
74+
parameterShortName: '-s',
75+
description:
76+
`Add suffix to interface and class names in the file path.` +
77+
`For example, packageA.myinterface_i.md for MyInterface interface, ` +
78+
`Add packageA.myclass_c.md for MyClass class.` +
79+
`This is to avoid name conflict in case packageA also has, for example, an entry point with the same name in lowercase.` +
80+
`This option is specifically designed for the Admin SDK where such case occurs.`
81+
});
6882
}
6983

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

96+
const addFileNameSuffix: boolean = this._fileNameSuffixParameter.value;
97+
8298
for (const filename of FileSystem.readFolder(inputFolder)) {
8399
if (filename.match(/\.api\.json$/i)) {
84100
console.log(`Reading ${filename}`);
@@ -89,7 +105,7 @@ export abstract class BaseAction extends CommandLineAction {
89105

90106
this._applyInheritDoc(apiModel, apiModel);
91107

92-
return { apiModel, inputFolder, outputFolder };
108+
return { apiModel, inputFolder, outputFolder, addFileNameSuffix };
93109
}
94110

95111
// TODO: This is a temporary workaround. The long term plan is for API Extractor's DocCommentEnhancer

repo-scripts/api-documenter/src/cli/MarkdownAction.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,13 @@ export class MarkdownAction extends BaseAction {
3535

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

4040
const markdownDocumenter: MarkdownDocumenter = new MarkdownDocumenter({
4141
apiModel,
4242
documenterConfig: undefined,
43-
outputFolder
43+
outputFolder,
44+
addFileNameSuffix
4445
});
4546
markdownDocumenter.generateFiles();
4647
}

repo-scripts/api-documenter/src/documenters/MarkdownDocumenter.ts

+52-14
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export interface IMarkdownDocumenterOptions {
9191
apiModel: ApiModel;
9292
documenterConfig: DocumenterConfig | undefined;
9393
outputFolder: string;
94+
addFileNameSuffix: boolean;
9495
}
9596

9697
/**
@@ -104,11 +105,13 @@ export class MarkdownDocumenter {
104105
private readonly _markdownEmitter: CustomMarkdownEmitter;
105106
private readonly _outputFolder: string;
106107
private readonly _pluginLoader: PluginLoader;
108+
private readonly _addFileNameSuffix: boolean;
107109

108110
public constructor(options: IMarkdownDocumenterOptions) {
109111
this._apiModel = options.apiModel;
110112
this._documenterConfig = options.documenterConfig;
111113
this._outputFolder = options.outputFolder;
114+
this._addFileNameSuffix = options.addFileNameSuffix;
112115
this._tsdocConfiguration = CustomDocNodes.configuration;
113116
this._markdownEmitter = new CustomMarkdownEmitter(this._apiModel);
114117

@@ -123,7 +126,7 @@ export class MarkdownDocumenter {
123126
outputFolder: this._outputFolder,
124127
documenter: new MarkdownDocumenterAccessor({
125128
getLinkForApiItem: (apiItem: ApiItem) => {
126-
return getLinkForApiItem(apiItem);
129+
return getLinkForApiItem(apiItem, this._addFileNameSuffix);
127130
}
128131
})
129132
});
@@ -156,7 +159,7 @@ export class MarkdownDocumenter {
156159
// write to file
157160
const filename: string = path.join(
158161
this._outputFolder,
159-
getFilenameForApiItem(apiItem)
162+
getFilenameForApiItem(apiItem, this._addFileNameSuffix)
160163
);
161164
const stringBuilder: StringBuilder = new StringBuilder();
162165

@@ -172,7 +175,7 @@ export class MarkdownDocumenter {
172175
this._markdownEmitter.emit(stringBuilder, output, {
173176
contextApiItem: apiItem,
174177
onGetFilenameForApiItem: (apiItemForFilename: ApiItem) => {
175-
return getLinkForApiItem(apiItemForFilename);
178+
return getLinkForApiItem(apiItemForFilename, this._addFileNameSuffix);
176179
}
177180
});
178181

@@ -393,7 +396,11 @@ export class MarkdownDocumenter {
393396
case ApiItemKind.Constructor: {
394397
constructorsTable.addRow(
395398
new DocTableRow({ configuration }, [
396-
createTitleCell(apiMember, configuration),
399+
createTitleCell(
400+
apiMember,
401+
configuration,
402+
this._addFileNameSuffix
403+
),
397404
createModifiersCell(apiMember, configuration),
398405
createDescriptionCell(apiMember, configuration)
399406
])
@@ -407,7 +414,11 @@ export class MarkdownDocumenter {
407414
case ApiItemKind.Method: {
408415
methodsTable.addRow(
409416
new DocTableRow({ configuration }, [
410-
createTitleCell(apiMember, configuration),
417+
createTitleCell(
418+
apiMember,
419+
configuration,
420+
this._addFileNameSuffix
421+
),
411422
createModifiersCell(apiMember, configuration),
412423
createDescriptionCell(apiMember, configuration)
413424
])
@@ -422,7 +433,11 @@ export class MarkdownDocumenter {
422433
if ((apiMember as ApiPropertyItem).isEventProperty) {
423434
eventsTable.addRow(
424435
new DocTableRow({ configuration }, [
425-
createTitleCell(apiMember, configuration),
436+
createTitleCell(
437+
apiMember,
438+
configuration,
439+
this._addFileNameSuffix
440+
),
426441
createModifiersCell(apiMember, configuration),
427442
this._createPropertyTypeCell(apiMember),
428443
createDescriptionCell(apiMember, configuration)
@@ -435,7 +450,11 @@ export class MarkdownDocumenter {
435450
} else {
436451
propertiesTable.addRow(
437452
new DocTableRow({ configuration }, [
438-
createTitleCell(apiMember, configuration),
453+
createTitleCell(
454+
apiMember,
455+
configuration,
456+
this._addFileNameSuffix
457+
),
439458
createModifiersCell(apiMember, configuration),
440459
this._createPropertyTypeCell(apiMember),
441460
createDescriptionCell(apiMember, configuration)
@@ -509,7 +528,11 @@ export class MarkdownDocumenter {
509528
case ApiItemKind.MethodSignature: {
510529
methodsTable.addRow(
511530
new DocTableRow({ configuration }, [
512-
createTitleCell(apiMember, configuration),
531+
createTitleCell(
532+
apiMember,
533+
configuration,
534+
this._addFileNameSuffix
535+
),
513536
createDescriptionCell(apiMember, configuration)
514537
])
515538
);
@@ -523,7 +546,11 @@ export class MarkdownDocumenter {
523546
if ((apiMember as ApiPropertyItem).isEventProperty) {
524547
eventsTable.addRow(
525548
new DocTableRow({ configuration }, [
526-
createTitleCell(apiMember, configuration),
549+
createTitleCell(
550+
apiMember,
551+
configuration,
552+
this._addFileNameSuffix
553+
),
527554
this._createPropertyTypeCell(apiMember),
528555
createDescriptionCell(apiMember, configuration)
529556
])
@@ -534,7 +561,11 @@ export class MarkdownDocumenter {
534561
} else {
535562
propertiesTable.addRow(
536563
new DocTableRow({ configuration }, [
537-
createTitleCell(apiMember, configuration),
564+
createTitleCell(
565+
apiMember,
566+
configuration,
567+
this._addFileNameSuffix
568+
),
538569
this._createPropertyTypeCell(apiMember),
539570
createDescriptionCell(apiMember, configuration)
540571
])
@@ -686,7 +717,10 @@ export class MarkdownDocumenter {
686717
configuration,
687718
tagName: '@link',
688719
linkText: unwrappedTokenText,
689-
urlDestination: getLinkForApiItem(apiItemResult.resolvedApiItem)
720+
urlDestination: getLinkForApiItem(
721+
apiItemResult.resolvedApiItem,
722+
this._addFileNameSuffix
723+
)
690724
})
691725
);
692726
continue;
@@ -714,7 +748,7 @@ export class MarkdownDocumenter {
714748

715749
for (const apiMember of apiModel.members) {
716750
const row: DocTableRow = new DocTableRow({ configuration }, [
717-
createTitleCell(apiMember, configuration),
751+
createTitleCell(apiMember, configuration, this._addFileNameSuffix),
718752
createDescriptionCell(apiMember, configuration)
719753
]);
720754

@@ -755,7 +789,11 @@ export class MarkdownDocumenter {
755789

756790
for (const entryPoint of apiContainer.entryPoints) {
757791
const row: DocTableRow = new DocTableRow({ configuration }, [
758-
createEntryPointTitleCell(entryPoint, configuration),
792+
createEntryPointTitleCell(
793+
entryPoint,
794+
configuration,
795+
this._addFileNameSuffix
796+
),
759797
createDescriptionCell(entryPoint, configuration)
760798
]);
761799

@@ -828,7 +866,7 @@ export class MarkdownDocumenter {
828866

829867
for (const apiMember of apiMembers) {
830868
const row: DocTableRow = new DocTableRow({ configuration }, [
831-
createTitleCell(apiMember, configuration),
869+
createTitleCell(apiMember, configuration, this._addFileNameSuffix),
832870
createDescriptionCell(apiMember, configuration)
833871
]);
834872

repo-scripts/api-documenter/src/documenters/MarkdownDocumenterHelpers.ts

+33-7
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,19 @@ import { DocNoteBox } from '../nodes/DocNoteBox';
4949
import { DocTableRow } from '../nodes/DocTableRow';
5050
import { DocTableCell } from '../nodes/DocTableCell';
5151

52-
export function getLinkForApiItem(apiItem: ApiItem) {
53-
const fileName = getFilenameForApiItem(apiItem);
52+
export function getLinkForApiItem(
53+
apiItem: ApiItem,
54+
addFileNameSuffix: boolean
55+
) {
56+
const fileName = getFilenameForApiItem(apiItem, addFileNameSuffix);
5457
const headingAnchor = getHeadingAnchorForApiItem(apiItem);
5558
return `./${fileName}#${headingAnchor}`;
5659
}
5760

58-
export function getFilenameForApiItem(apiItem: ApiItem): string {
61+
export function getFilenameForApiItem(
62+
apiItem: ApiItem,
63+
addFileNameSuffix: boolean
64+
): string {
5965
if (apiItem.kind === ApiItemKind.Model) {
6066
return 'index.md';
6167
}
@@ -96,9 +102,27 @@ export function getFilenameForApiItem(apiItem: ApiItem): string {
96102
multipleEntryPoints = true;
97103
}
98104
break;
105+
case ApiItemKind.Namespace:
106+
baseName += '.' + qualifiedName;
107+
if (addFileNameSuffix) {
108+
baseName += '_n';
109+
}
110+
break;
111+
// append the file name with the first letter of the ApiItemKind to avoid name collision.
112+
// Sometimes we could have a class/interface and an entry point that have the same name.
113+
// This happened in the admin SDK where the App interface and the app namespace write to the same file.
99114
case ApiItemKind.Class:
115+
baseName += '.' + qualifiedName;
116+
if (addFileNameSuffix) {
117+
baseName += '_c';
118+
}
119+
break;
100120
case ApiItemKind.Interface:
101121
baseName += '.' + qualifiedName;
122+
if (addFileNameSuffix) {
123+
baseName += '_i';
124+
}
125+
break;
102126
}
103127
}
104128
return baseName + '.md';
@@ -224,15 +248,16 @@ export function createExampleSection(
224248

225249
export function createTitleCell(
226250
apiItem: ApiItem,
227-
configuration: TSDocConfiguration
251+
configuration: TSDocConfiguration,
252+
addFileNameSuffix: boolean
228253
): DocTableCell {
229254
return new DocTableCell({ configuration }, [
230255
new DocParagraph({ configuration }, [
231256
new DocLinkTag({
232257
configuration,
233258
tagName: '@link',
234259
linkText: Utilities.getConciseSignature(apiItem),
235-
urlDestination: getLinkForApiItem(apiItem)
260+
urlDestination: getLinkForApiItem(apiItem, addFileNameSuffix)
236261
})
237262
])
238263
]);
@@ -339,15 +364,16 @@ export function createThrowsSection(
339364

340365
export function createEntryPointTitleCell(
341366
apiItem: ApiEntryPoint,
342-
configuration: TSDocConfiguration
367+
configuration: TSDocConfiguration,
368+
addFileNameSuffix: boolean
343369
): DocTableCell {
344370
return new DocTableCell({ configuration }, [
345371
new DocParagraph({ configuration }, [
346372
new DocLinkTag({
347373
configuration,
348374
tagName: '@link',
349375
linkText: `/${apiItem.displayName}`,
350-
urlDestination: getLinkForApiItem(apiItem)
376+
urlDestination: getLinkForApiItem(apiItem, addFileNameSuffix)
351377
})
352378
])
353379
]);

repo-scripts/api-documenter/src/start.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#!/usr/bin/env node
2+
13
/**
24
* @license
35
* Copyright 2020 Google LLC

0 commit comments

Comments
 (0)