Skip to content

Reference doc generator for devsite #4517

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 22 commits into from
Mar 10, 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
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@
"api-report": "lerna run --scope @firebase/*-exp --scope @firebase/firestore --scope @firebase/storage --scope @firebase/storage-types --scope @firebase/database api-report",
"docgen:exp": "ts-node-script scripts/exp/docgen.ts",
"postinstall": "yarn --cwd repo-scripts/changelog-generator build",
"sa": "ts-node-script repo-scripts/size-analysis/cli.ts"
"sa": "ts-node-script repo-scripts/size-analysis/cli.ts",
"api-documenter-devsite": "ts-node-script repo-scripts/api-documenter/src/start.ts"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -89,8 +90,8 @@
"@typescript-eslint/eslint-plugin": "4.11.1",
"@typescript-eslint/eslint-plugin-tslint": "4.11.1",
"@typescript-eslint/parser": "4.11.1",
"api-documenter-me": "0.1.0",
"api-extractor-me": "0.1.1",
"api-documenter-me": "0.1.1",
"api-extractor-me": "0.1.2",
"babel-loader": "8.2.2",
"chai": "4.2.0",
"chai-as-promised": "7.1.1",
Expand Down
5 changes: 5 additions & 0 deletions repo-scripts/api-documenter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# @firebase/api-documenter

It is a fork of [API Documenter](https://github.com/microsoft/rushstack/tree/master/apps/api-documenter)
It reads the *.api.json data files produced by [API Extractor](https://api-extractor.com/),
and then generates files in [Markdown](https://en.wikipedia.org/wiki/Markdown) format suitable for displaying in Firebase Devsite.
22 changes: 22 additions & 0 deletions repo-scripts/api-documenter/gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* @license
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

const gulp = require('gulp');

gulp.task('copy-resources', function () {
return gulp.src('./src/schemas/*').pipe(gulp.dest('./dist/schemas'));
});
33 changes: 33 additions & 0 deletions repo-scripts/api-documenter/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"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",
"type": "git",
"url": "https://github.com/firebase/firebase-js-sdk.git"
},
"license": "Apache-2.0",
"scripts": {
"build": "tsc && gulp copy-resources",
"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"
},
"main": "lib/index.js",
"typings": "dist/rollup.d.ts",
"dependencies": {
"@microsoft/api-extractor-model": "7.12.2",
"@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"
},
"devDependencies": {
"@types/resolve": "1.17.1",
"mocha-chai-jest-snapshot": "1.1.1"
}
}
43 changes: 43 additions & 0 deletions repo-scripts/api-documenter/src/cli/ApiDocumenterCommandLine.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* @license
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
Copy link
Member Author

Choose a reason for hiding this comment

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

@samtstern This is a fork of https://github.com/microsoft/rushstack/tree/master/apps/api-documenter
What should we do about the license?

// See LICENSE in the project root for license information.

import { CommandLineParser } from '@rushstack/ts-command-line';
import { MarkdownAction } from './MarkdownAction';

export class ApiDocumenterCommandLine extends CommandLineParser {
public constructor() {
super({
toolFilename: 'api-documenter',
toolDescription:
'Reads *.api.json files produced by api-extractor, ' +
' and generates API documentation in various output formats.'
});
this._populateActions();
}

protected onDefineParameters(): void {
// override
// No parameters
}

private _populateActions(): void {
this.addAction(new MarkdownAction(this));
}
}
164 changes: 164 additions & 0 deletions repo-scripts/api-documenter/src/cli/BaseAction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/**
* @license
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.

import * as path from 'path';
import * as tsdoc from '@microsoft/tsdoc';
import colors from 'colors';

import {
CommandLineAction,
CommandLineStringParameter
} from '@rushstack/ts-command-line';
import { FileSystem } from '@rushstack/node-core-library';
import {
ApiModel,
ApiItem,
ApiItemContainerMixin,
ApiDocumentedItem,
IResolveDeclarationReferenceResult
} from '@microsoft/api-extractor-model';

export interface IBuildApiModelResult {
apiModel: ApiModel;
inputFolder: string;
outputFolder: string;
}

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

protected onDefineParameters(): void {
// override
this._inputFolderParameter = this.defineStringParameter({
parameterLongName: '--input-folder',
parameterShortName: '-i',
argumentName: 'FOLDER1',
description:
`Specifies the input folder containing the *.api.json files to be processed.` +
` If omitted, the default is "./input"`
});

this._outputFolderParameter = this.defineStringParameter({
parameterLongName: '--output-folder',
parameterShortName: '-o',
argumentName: 'FOLDER2',
description:
`Specifies the output folder where the documentation will be written.` +
` ANY EXISTING CONTENTS WILL BE DELETED!` +
` If omitted, the default is "./${this.actionName}"`
});
}

protected buildApiModel(): IBuildApiModelResult {
const apiModel: ApiModel = new ApiModel();

const inputFolder: string = this._inputFolderParameter.value || './input';
if (!FileSystem.exists(inputFolder)) {
throw new Error('The input folder does not exist: ' + inputFolder);
}

const outputFolder: string =
this._outputFolderParameter.value || `./${this.actionName}`;
FileSystem.ensureFolder(outputFolder);

for (const filename of FileSystem.readFolder(inputFolder)) {
if (filename.match(/\.api\.json$/i)) {
console.log(`Reading ${filename}`);
const filenamePath: string = path.join(inputFolder, filename);
apiModel.loadPackage(filenamePath);
}
}

this._applyInheritDoc(apiModel, apiModel);

return { apiModel, inputFolder, outputFolder };
}

// TODO: This is a temporary workaround. The long term plan is for API Extractor's DocCommentEnhancer
// to apply all @inheritDoc tags before the .api.json file is written.
// See DocCommentEnhancer._applyInheritDoc() for more info.
private _applyInheritDoc(apiItem: ApiItem, apiModel: ApiModel): void {
if (apiItem instanceof ApiDocumentedItem) {
if (apiItem.tsdocComment) {
const inheritDocTag: tsdoc.DocInheritDocTag | undefined =
apiItem.tsdocComment.inheritDocTag;

if (inheritDocTag && inheritDocTag.declarationReference) {
// Attempt to resolve the declaration reference
const result: IResolveDeclarationReferenceResult = apiModel.resolveDeclarationReference(
inheritDocTag.declarationReference,
apiItem
);

if (result.errorMessage) {
console.log(
colors.yellow(
`Warning: Unresolved @inheritDoc tag for ${apiItem.displayName}: ` +
result.errorMessage
)
);
} else {
if (
result.resolvedApiItem instanceof ApiDocumentedItem &&
result.resolvedApiItem.tsdocComment &&
result.resolvedApiItem !== apiItem
) {
this._copyInheritedDocs(
apiItem.tsdocComment,
result.resolvedApiItem.tsdocComment
);
}
}
}
}
}

// Recurse members
if (ApiItemContainerMixin.isBaseClassOf(apiItem)) {
for (const member of apiItem.members) {
this._applyInheritDoc(member, apiModel);
}
}
}

/**
* Copy the content from `sourceDocComment` to `targetDocComment`.
* This code is borrowed from DocCommentEnhancer as a temporary workaround.
*/
private _copyInheritedDocs(
targetDocComment: tsdoc.DocComment,
sourceDocComment: tsdoc.DocComment
): void {
targetDocComment.summarySection = sourceDocComment.summarySection;
targetDocComment.remarksBlock = sourceDocComment.remarksBlock;

targetDocComment.params.clear();
for (const param of sourceDocComment.params) {
targetDocComment.params.add(param);
}
for (const typeParam of sourceDocComment.typeParams) {
targetDocComment.typeParams.add(typeParam);
}
targetDocComment.returnsBlock = sourceDocComment.returnsBlock;

targetDocComment.inheritDocTag = undefined;
}
}
47 changes: 47 additions & 0 deletions repo-scripts/api-documenter/src/cli/MarkdownAction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* @license
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.

import { ApiDocumenterCommandLine } from './ApiDocumenterCommandLine';
import { BaseAction } from './BaseAction';
import { MarkdownDocumenter } from '../documenters/MarkdownDocumenter';

export class MarkdownAction extends BaseAction {
public constructor(parser: ApiDocumenterCommandLine) {
super({
actionName: 'markdown',
summary: 'Generate documentation as Markdown files (*.md)',
documentation:
'Generates API documentation as a collection of files in' +
' Markdown format, suitable for example for publishing on a GitHub site.'
});
}

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

const markdownDocumenter: MarkdownDocumenter = new MarkdownDocumenter({
apiModel,
documenterConfig: undefined,
outputFolder
});
markdownDocumenter.generateFiles();
}
}
Loading