Skip to content

Commit 44759f7

Browse files
authored
Reference doc generator for devsite (#4517)
* copy api documenter fork * make build work * remove unused files * merge with the latest documenter * replace jest with mocha * remove unused command * remove comments * populate title for devsite * smaller font for parameters and examples blocks * move some methods back to the class * update npm script * remove api extractor things for storage-types * remove suffixes to functions, methods, etc * render remark section directly after summary * update heading anchor * clean up * add command for generating ref docs for devsite * remove empty console log * update deps
1 parent 13686cb commit 44759f7

38 files changed

+5433
-500
lines changed

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@
5353
"api-report": "lerna run --scope @firebase/*-exp --scope @firebase/firestore --scope @firebase/storage --scope @firebase/storage-types --scope @firebase/database api-report",
5454
"docgen:exp": "ts-node-script scripts/exp/docgen.ts",
5555
"postinstall": "yarn --cwd repo-scripts/changelog-generator build",
56-
"sa": "ts-node-script repo-scripts/size-analysis/cli.ts"
56+
"sa": "ts-node-script repo-scripts/size-analysis/cli.ts",
57+
"api-documenter-devsite": "ts-node-script repo-scripts/api-documenter/src/start.ts"
5758
},
5859
"repository": {
5960
"type": "git",
@@ -89,8 +90,8 @@
8990
"@typescript-eslint/eslint-plugin": "4.11.1",
9091
"@typescript-eslint/eslint-plugin-tslint": "4.11.1",
9192
"@typescript-eslint/parser": "4.11.1",
92-
"api-documenter-me": "0.1.0",
93-
"api-extractor-me": "0.1.1",
93+
"api-documenter-me": "0.1.1",
94+
"api-extractor-me": "0.1.2",
9495
"babel-loader": "8.2.2",
9596
"chai": "4.2.0",
9697
"chai-as-promised": "7.1.1",

repo-scripts/api-documenter/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# @firebase/api-documenter
2+
3+
It is a fork of [API Documenter](https://github.com/microsoft/rushstack/tree/master/apps/api-documenter)
4+
It reads the *.api.json data files produced by [API Extractor](https://api-extractor.com/),
5+
and then generates files in [Markdown](https://en.wikipedia.org/wiki/Markdown) format suitable for displaying in Firebase Devsite.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
const gulp = require('gulp');
19+
20+
gulp.task('copy-resources', function () {
21+
return gulp.src('./src/schemas/*').pipe(gulp.dest('./dist/schemas'));
22+
});
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "@firebase/api-documenter",
3+
"version": "0.1.0",
4+
"private": true,
5+
"description": "Read JSON files from api-extractor, generate documentation pages",
6+
"repository": {
7+
"directory": "repo-scripts/documenter",
8+
"type": "git",
9+
"url": "https://github.com/firebase/firebase-js-sdk.git"
10+
},
11+
"license": "Apache-2.0",
12+
"scripts": {
13+
"build": "tsc && gulp copy-resources",
14+
"test": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha src/**/*.test.ts --config ../../config/mocharc.node.js"
15+
},
16+
"bin": {
17+
"api-documenter": "./bin/api-documenter"
18+
},
19+
"main": "lib/index.js",
20+
"typings": "dist/rollup.d.ts",
21+
"dependencies": {
22+
"@microsoft/api-extractor-model": "7.12.2",
23+
"@microsoft/tsdoc": "0.12.24",
24+
"@rushstack/node-core-library": "3.36.0",
25+
"@rushstack/ts-command-line": "4.7.8",
26+
"colors": "~1.2.1",
27+
"resolve": "~1.17.0"
28+
},
29+
"devDependencies": {
30+
"@types/resolve": "1.17.1",
31+
"mocha-chai-jest-snapshot": "1.1.1"
32+
}
33+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
19+
// See LICENSE in the project root for license information.
20+
21+
import { CommandLineParser } from '@rushstack/ts-command-line';
22+
import { MarkdownAction } from './MarkdownAction';
23+
24+
export class ApiDocumenterCommandLine extends CommandLineParser {
25+
public constructor() {
26+
super({
27+
toolFilename: 'api-documenter',
28+
toolDescription:
29+
'Reads *.api.json files produced by api-extractor, ' +
30+
' and generates API documentation in various output formats.'
31+
});
32+
this._populateActions();
33+
}
34+
35+
protected onDefineParameters(): void {
36+
// override
37+
// No parameters
38+
}
39+
40+
private _populateActions(): void {
41+
this.addAction(new MarkdownAction(this));
42+
}
43+
}
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
19+
// See LICENSE in the project root for license information.
20+
21+
import * as path from 'path';
22+
import * as tsdoc from '@microsoft/tsdoc';
23+
import colors from 'colors';
24+
25+
import {
26+
CommandLineAction,
27+
CommandLineStringParameter
28+
} from '@rushstack/ts-command-line';
29+
import { FileSystem } from '@rushstack/node-core-library';
30+
import {
31+
ApiModel,
32+
ApiItem,
33+
ApiItemContainerMixin,
34+
ApiDocumentedItem,
35+
IResolveDeclarationReferenceResult
36+
} from '@microsoft/api-extractor-model';
37+
38+
export interface IBuildApiModelResult {
39+
apiModel: ApiModel;
40+
inputFolder: string;
41+
outputFolder: string;
42+
}
43+
44+
export abstract class BaseAction extends CommandLineAction {
45+
private _inputFolderParameter!: CommandLineStringParameter;
46+
private _outputFolderParameter!: CommandLineStringParameter;
47+
48+
protected onDefineParameters(): void {
49+
// override
50+
this._inputFolderParameter = this.defineStringParameter({
51+
parameterLongName: '--input-folder',
52+
parameterShortName: '-i',
53+
argumentName: 'FOLDER1',
54+
description:
55+
`Specifies the input folder containing the *.api.json files to be processed.` +
56+
` If omitted, the default is "./input"`
57+
});
58+
59+
this._outputFolderParameter = this.defineStringParameter({
60+
parameterLongName: '--output-folder',
61+
parameterShortName: '-o',
62+
argumentName: 'FOLDER2',
63+
description:
64+
`Specifies the output folder where the documentation will be written.` +
65+
` ANY EXISTING CONTENTS WILL BE DELETED!` +
66+
` If omitted, the default is "./${this.actionName}"`
67+
});
68+
}
69+
70+
protected buildApiModel(): IBuildApiModelResult {
71+
const apiModel: ApiModel = new ApiModel();
72+
73+
const inputFolder: string = this._inputFolderParameter.value || './input';
74+
if (!FileSystem.exists(inputFolder)) {
75+
throw new Error('The input folder does not exist: ' + inputFolder);
76+
}
77+
78+
const outputFolder: string =
79+
this._outputFolderParameter.value || `./${this.actionName}`;
80+
FileSystem.ensureFolder(outputFolder);
81+
82+
for (const filename of FileSystem.readFolder(inputFolder)) {
83+
if (filename.match(/\.api\.json$/i)) {
84+
console.log(`Reading ${filename}`);
85+
const filenamePath: string = path.join(inputFolder, filename);
86+
apiModel.loadPackage(filenamePath);
87+
}
88+
}
89+
90+
this._applyInheritDoc(apiModel, apiModel);
91+
92+
return { apiModel, inputFolder, outputFolder };
93+
}
94+
95+
// TODO: This is a temporary workaround. The long term plan is for API Extractor's DocCommentEnhancer
96+
// to apply all @inheritDoc tags before the .api.json file is written.
97+
// See DocCommentEnhancer._applyInheritDoc() for more info.
98+
private _applyInheritDoc(apiItem: ApiItem, apiModel: ApiModel): void {
99+
if (apiItem instanceof ApiDocumentedItem) {
100+
if (apiItem.tsdocComment) {
101+
const inheritDocTag: tsdoc.DocInheritDocTag | undefined =
102+
apiItem.tsdocComment.inheritDocTag;
103+
104+
if (inheritDocTag && inheritDocTag.declarationReference) {
105+
// Attempt to resolve the declaration reference
106+
const result: IResolveDeclarationReferenceResult = apiModel.resolveDeclarationReference(
107+
inheritDocTag.declarationReference,
108+
apiItem
109+
);
110+
111+
if (result.errorMessage) {
112+
console.log(
113+
colors.yellow(
114+
`Warning: Unresolved @inheritDoc tag for ${apiItem.displayName}: ` +
115+
result.errorMessage
116+
)
117+
);
118+
} else {
119+
if (
120+
result.resolvedApiItem instanceof ApiDocumentedItem &&
121+
result.resolvedApiItem.tsdocComment &&
122+
result.resolvedApiItem !== apiItem
123+
) {
124+
this._copyInheritedDocs(
125+
apiItem.tsdocComment,
126+
result.resolvedApiItem.tsdocComment
127+
);
128+
}
129+
}
130+
}
131+
}
132+
}
133+
134+
// Recurse members
135+
if (ApiItemContainerMixin.isBaseClassOf(apiItem)) {
136+
for (const member of apiItem.members) {
137+
this._applyInheritDoc(member, apiModel);
138+
}
139+
}
140+
}
141+
142+
/**
143+
* Copy the content from `sourceDocComment` to `targetDocComment`.
144+
* This code is borrowed from DocCommentEnhancer as a temporary workaround.
145+
*/
146+
private _copyInheritedDocs(
147+
targetDocComment: tsdoc.DocComment,
148+
sourceDocComment: tsdoc.DocComment
149+
): void {
150+
targetDocComment.summarySection = sourceDocComment.summarySection;
151+
targetDocComment.remarksBlock = sourceDocComment.remarksBlock;
152+
153+
targetDocComment.params.clear();
154+
for (const param of sourceDocComment.params) {
155+
targetDocComment.params.add(param);
156+
}
157+
for (const typeParam of sourceDocComment.typeParams) {
158+
targetDocComment.typeParams.add(typeParam);
159+
}
160+
targetDocComment.returnsBlock = sourceDocComment.returnsBlock;
161+
162+
targetDocComment.inheritDocTag = undefined;
163+
}
164+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
19+
// See LICENSE in the project root for license information.
20+
21+
import { ApiDocumenterCommandLine } from './ApiDocumenterCommandLine';
22+
import { BaseAction } from './BaseAction';
23+
import { MarkdownDocumenter } from '../documenters/MarkdownDocumenter';
24+
25+
export class MarkdownAction extends BaseAction {
26+
public constructor(parser: ApiDocumenterCommandLine) {
27+
super({
28+
actionName: 'markdown',
29+
summary: 'Generate documentation as Markdown files (*.md)',
30+
documentation:
31+
'Generates API documentation as a collection of files in' +
32+
' Markdown format, suitable for example for publishing on a GitHub site.'
33+
});
34+
}
35+
36+
protected async onExecute(): Promise<void> {
37+
// override
38+
const { apiModel, outputFolder } = this.buildApiModel();
39+
40+
const markdownDocumenter: MarkdownDocumenter = new MarkdownDocumenter({
41+
apiModel,
42+
documenterConfig: undefined,
43+
outputFolder
44+
});
45+
markdownDocumenter.generateFiles();
46+
}
47+
}

0 commit comments

Comments
 (0)