From fd9d014fe44bb23fd04ace8cf2bdf9722e5ebc04 Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Thu, 20 May 2021 23:01:19 -0700 Subject: [PATCH 1/6] make toc generation part of the api-documenter --- package.json | 3 +- repo-scripts/api-documenter/package.json | 4 +- .../src/cli/ApiDocumenterCommandLine.ts | 2 + .../api-documenter/src/cli/TocAction.ts | 65 +++++++++ repo-scripts/api-documenter/src/toc.ts | 97 +++++++++++++ scripts/exp/generate-devsite-toc.ts | 134 ------------------ 6 files changed, 168 insertions(+), 137 deletions(-) create mode 100644 repo-scripts/api-documenter/src/cli/TocAction.ts create mode 100644 repo-scripts/api-documenter/src/toc.ts delete mode 100644 scripts/exp/generate-devsite-toc.ts diff --git a/package.json b/package.json index 441cc90b05d..5cb6ad70e2a 100644 --- a/package.json +++ b/package.json @@ -54,8 +54,7 @@ "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", - "api-documenter-devsite": "ts-node-script repo-scripts/api-documenter/src/start.ts", - "toc-devsite": "ts-node-script scripts/exp/generate-devsite-toc.ts -i temp" + "api-documenter-devsite": "ts-node-script repo-scripts/api-documenter/src/start.ts" }, "repository": { "type": "git", diff --git a/repo-scripts/api-documenter/package.json b/repo-scripts/api-documenter/package.json index deba19c0281..60a6b0dbb18 100644 --- a/repo-scripts/api-documenter/package.json +++ b/repo-scripts/api-documenter/package.json @@ -27,9 +27,11 @@ "@rushstack/ts-command-line": "4.7.8", "colors": "~1.2.1", "resolve": "~1.17.0", - "tslib": "^2.1.0" + "tslib": "^2.1.0", + "js-yaml": "4.0.0" }, "devDependencies": { + "@types/js-yaml": "4.0.0", "@types/resolve": "1.17.1", "mocha-chai-jest-snapshot": "1.1.1" } diff --git a/repo-scripts/api-documenter/src/cli/ApiDocumenterCommandLine.ts b/repo-scripts/api-documenter/src/cli/ApiDocumenterCommandLine.ts index ac10e970edd..4e98f53df13 100644 --- a/repo-scripts/api-documenter/src/cli/ApiDocumenterCommandLine.ts +++ b/repo-scripts/api-documenter/src/cli/ApiDocumenterCommandLine.ts @@ -20,6 +20,7 @@ import { CommandLineParser } from '@rushstack/ts-command-line'; import { MarkdownAction } from './MarkdownAction'; +import { TocAction } from './TocAction'; export class ApiDocumenterCommandLine extends CommandLineParser { public constructor() { @@ -39,5 +40,6 @@ export class ApiDocumenterCommandLine extends CommandLineParser { private _populateActions(): void { this.addAction(new MarkdownAction(this)); + this.addAction(new TocAction(this)); } } diff --git a/repo-scripts/api-documenter/src/cli/TocAction.ts b/repo-scripts/api-documenter/src/cli/TocAction.ts new file mode 100644 index 00000000000..bd1e02d9104 --- /dev/null +++ b/repo-scripts/api-documenter/src/cli/TocAction.ts @@ -0,0 +1,65 @@ +/** + * @license + * Copyright 2021 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. + */ + +import { CommandLineStringParameter } from '@rushstack/ts-command-line'; +import { ApiDocumenterCommandLine } from './ApiDocumenterCommandLine'; +import { BaseAction } from './BaseAction'; +import { generateToc } from '../toc'; + +export class TocAction extends BaseAction { + private _g3PathParameter!: CommandLineStringParameter; + public constructor(parser: ApiDocumenterCommandLine) { + super({ + actionName: 'toc', + 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 onDefineParameters(): void { + super.onDefineParameters(); + + this._g3PathParameter = this.defineStringParameter({ + parameterLongName: '--g3-path', + parameterShortName: '-p', + argumentName: 'G3PREFIX', + description: `Specifies the path where the reference docs will be written to in g3. + Used to generate paths in the toc` + }); + } + + protected async onExecute(): Promise { + // override + const { apiModel, outputFolder, addFileNameSuffix } = this.buildApiModel(); + const g3Path: string | undefined = this._g3PathParameter.value; + + if (!g3Path) { + throw new Error( + '--g3-path is a required to generate toc, but it is not provided' + ); + } + + generateToc({ + apiModel, + outputFolder, + addFileNameSuffix, + g3Path + }); + } +} diff --git a/repo-scripts/api-documenter/src/toc.ts b/repo-scripts/api-documenter/src/toc.ts new file mode 100644 index 00000000000..b50dcc12074 --- /dev/null +++ b/repo-scripts/api-documenter/src/toc.ts @@ -0,0 +1,97 @@ +/** + * @license + * Copyright 2021 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. + */ + +import yaml from 'js-yaml'; +import { ApiItem, ApiItemKind, ApiModel } from 'api-extractor-model-me'; +import { getFilenameForApiItem } from './documenters/MarkdownDocumenterHelpers'; +import { ModuleSource } from '@microsoft/tsdoc/lib-commonjs/beta/DeclarationReference'; +import { writeFileSync } from 'fs'; +import { resolve } from 'path'; + +export interface ITocGenerationOptions { + apiModel: ApiModel; + g3Path: string; + outputFolder: string; + addFileNameSuffix: boolean; +} + +interface ITocItem { + title: string; + path: string; + section?: ITocItem[]; +} + +export function generateToc({ + apiModel, + g3Path, + outputFolder, + addFileNameSuffix +}: ITocGenerationOptions) { + const js: ITocItem = { + title: 'firebase', + path: `${g3Path}/index`, + section: [] + }; + const toc = [js]; + + generateTocRecursively(apiModel, g3Path, addFileNameSuffix, toc); + + writeFileSync( + resolve(outputFolder, 'toc.yaml'), + yaml.dump( + { toc }, + { + quotingType: '"' + } + ) + ); +} + +function generateTocRecursively( + apiItem: ApiItem, + g3Path: string, + addFileNameSuffix: boolean, + toc: ITocItem[] +) { + if (apiItem.kind === ApiItemKind.EntryPoint) { + // Entry point + const entryPointName = (apiItem.canonicalReference + .source! as ModuleSource).escapedPath.replace('@firebase/', ''); + const entryPointToc: ITocItem = { + title: entryPointName, + path: `${g3Path}/${getFilenameForApiItem(apiItem, addFileNameSuffix)}`, + section: [] + }; + + for (const member of apiItem.members) { + const fileName = getFilenameForApiItem(member, addFileNameSuffix); + + if (fileName) { + entryPointToc.section!.push({ + title: member.displayName, + path: `${g3Path}/${fileName}` + }); + } + } + toc.push(entryPointToc); + } else { + // travel the api tree to find the next entry point + for (const member of apiItem.members) { + generateTocRecursively(member, g3Path, addFileNameSuffix, toc); + } + } +} diff --git a/scripts/exp/generate-devsite-toc.ts b/scripts/exp/generate-devsite-toc.ts deleted file mode 100644 index 93ab5352dc0..00000000000 --- a/scripts/exp/generate-devsite-toc.ts +++ /dev/null @@ -1,134 +0,0 @@ -/** - * @license - * Copyright 2021 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. - */ - -import * as yargs from 'yargs'; -import * as fs from 'fs'; -import * as path from 'path'; -import * as yaml from 'js-yaml'; - -interface TocItem { - title: string; - path: string; - section?: TocItem[]; -} - -const argv = yargs - .options({ - input: { - alias: 'i', - type: 'string', - default: 'temp' - } - }) - .help().argv; - -const REF_DOC_DIR = '/docs/reference/js'; -const REPORT_DIR = path.resolve(process.cwd(), argv.input); - -const js: TocItem = { - title: 'firebase', - path: `${REF_DOC_DIR}/index` -}; -const toc = [js]; - -for (const fileName of fs.readdirSync(REPORT_DIR)) { - const report = require(`${REPORT_DIR}/${fileName}`); - - /** - * Entry point - */ - for (const entryPoint of report.members) { - const entryPointName = entryPoint.canonicalReference - .replace('!', '') - .replace('@firebase/', ''); - const entryPointToc: Required = { - title: entryPointName, - path: `${REF_DOC_DIR}/${getFileName( - entryPoint, - entryPoint, - report.members.length > 1 - )}`, - section: [] - }; - - for (const member of entryPoint.members) { - const fileName = getFileName( - member, - entryPoint, - report.members.length > 1 - ); - - if (fileName) { - entryPointToc.section.push({ - title: member.name, - path: `${REF_DOC_DIR}/${fileName}` - }); - } - } - toc.push(entryPointToc); - } -} - -console.log( - yaml.dump( - { toc }, - { - quotingType: '"' - } - ) -); - -function getFileName( - apiMember: any, - entryPoint: any, - multipleEntryPoints = false -) { - const entryPointName = entryPoint.canonicalReference.replace('!', ''); - const unscopedName = getUnscopedName(entryPointName); - let entryPointPrefix = unscopedName; - - if (multipleEntryPoints) { - const nameParts = unscopedName.split('/'); - if (nameParts.length === 1) { - entryPointPrefix = `${unscopedName}_`; - } else { - // > 1 - entryPointPrefix = nameParts.join('_'); - } - } - - switch (apiMember.kind) { - case 'EntryPoint': - return entryPointPrefix; - case 'Class': - case 'Interface': - return `${entryPointPrefix}.${apiMember.name.toLowerCase()}`; - default: - // other kinds don't have their own files - return null; - } -} - -function getUnscopedName(packageName: string) { - const parts = packageName.split('/'); - if (parts.length === 1) { - return packageName; - } - - parts.shift(); - return parts.join('/'); -} From bda6d05106b6de93c13756cc513a3d648c926a97 Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Thu, 20 May 2021 23:15:27 -0700 Subject: [PATCH 2/6] add instruction for generating toc --- repo-scripts/api-documenter/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/repo-scripts/api-documenter/README.md b/repo-scripts/api-documenter/README.md index 8c57fc065e8..594bb87109b 100644 --- a/repo-scripts/api-documenter/README.md +++ b/repo-scripts/api-documenter/README.md @@ -3,3 +3,12 @@ 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. + +## Generate toc for Firebase devsite +`api-documenter-fire toc -i temp -p "/docs/reference/js/v9"` + +`-i` and `-p` are required parameters. +Use `-i` to specify the folder that contains api.json files. +Use `-p` to specify the g3 path that contains the reference docs. + +By default, the command will create `toc.yaml` in folder `/toc`. To change the output folder, use the flag `-o`. \ No newline at end of file From c60057653696f2c34b24d6f02a3548a3988b6871 Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Fri, 21 May 2021 15:50:46 -0700 Subject: [PATCH 3/6] generate toc only for classes and interfaces --- repo-scripts/api-documenter/src/toc.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/repo-scripts/api-documenter/src/toc.ts b/repo-scripts/api-documenter/src/toc.ts index b50dcc12074..056e15f755f 100644 --- a/repo-scripts/api-documenter/src/toc.ts +++ b/repo-scripts/api-documenter/src/toc.ts @@ -78,15 +78,19 @@ function generateTocRecursively( }; for (const member of apiItem.members) { - const fileName = getFilenameForApiItem(member, addFileNameSuffix); - - if (fileName) { + // only classes and interfaces have dedicated pages + if ( + member.kind === ApiItemKind.Class || + member.kind === ApiItemKind.Interface + ) { + const fileName = getFilenameForApiItem(member, addFileNameSuffix); entryPointToc.section!.push({ title: member.displayName, path: `${g3Path}/${fileName}` }); } } + toc.push(entryPointToc); } else { // travel the api tree to find the next entry point From 43f8605bfa1c2a26d56cdf395b9bf574ed9a92ab Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Fri, 21 May 2021 16:14:18 -0700 Subject: [PATCH 4/6] add jssdk flag --- repo-scripts/api-documenter/README.md | 4 +++- .../api-documenter/src/cli/TocAction.ts | 18 +++++++++++++++-- repo-scripts/api-documenter/src/toc.ts | 20 ++++++++++++------- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/repo-scripts/api-documenter/README.md b/repo-scripts/api-documenter/README.md index 594bb87109b..ec5c3e772ba 100644 --- a/repo-scripts/api-documenter/README.md +++ b/repo-scripts/api-documenter/README.md @@ -11,4 +11,6 @@ and then generates files in [Markdown](https://en.wikipedia.org/wiki/Markdown) f Use `-i` to specify the folder that contains api.json files. Use `-p` to specify the g3 path that contains the reference docs. -By default, the command will create `toc.yaml` in folder `/toc`. To change the output folder, use the flag `-o`. \ No newline at end of file +By default, the command will create `toc.yaml` in folder `/toc`. To change the output folder, use the flag `-o`. + +To generate toc for the Firebase JS SDK, also set the flag `-j` to create the top level `firebase` toc item. \ No newline at end of file diff --git a/repo-scripts/api-documenter/src/cli/TocAction.ts b/repo-scripts/api-documenter/src/cli/TocAction.ts index bd1e02d9104..ce7c2dbe53f 100644 --- a/repo-scripts/api-documenter/src/cli/TocAction.ts +++ b/repo-scripts/api-documenter/src/cli/TocAction.ts @@ -15,13 +15,17 @@ * limitations under the License. */ -import { CommandLineStringParameter } from '@rushstack/ts-command-line'; +import { + CommandLineFlagParameter, + CommandLineStringParameter +} from '@rushstack/ts-command-line'; import { ApiDocumenterCommandLine } from './ApiDocumenterCommandLine'; import { BaseAction } from './BaseAction'; import { generateToc } from '../toc'; export class TocAction extends BaseAction { private _g3PathParameter!: CommandLineStringParameter; + private _jsSDKParameter!: CommandLineFlagParameter; public constructor(parser: ApiDocumenterCommandLine) { super({ actionName: 'toc', @@ -42,12 +46,21 @@ export class TocAction extends BaseAction { description: `Specifies the path where the reference docs will be written to in g3. Used to generate paths in the toc` }); + + this._jsSDKParameter = this.defineFlagParameter({ + parameterLongName: '--js-sdk', + parameterShortName: '-j', + description: + `Generating toc for the Firebase JS SDK.` + + `It will create an artificial top level toc item "firebase".` + }); } protected async onExecute(): Promise { // override const { apiModel, outputFolder, addFileNameSuffix } = this.buildApiModel(); const g3Path: string | undefined = this._g3PathParameter.value; + const jsSdk: boolean = this._jsSDKParameter.value; if (!g3Path) { throw new Error( @@ -59,7 +72,8 @@ export class TocAction extends BaseAction { apiModel, outputFolder, addFileNameSuffix, - g3Path + g3Path, + jsSdk }); } } diff --git a/repo-scripts/api-documenter/src/toc.ts b/repo-scripts/api-documenter/src/toc.ts index 056e15f755f..2b71f3c8922 100644 --- a/repo-scripts/api-documenter/src/toc.ts +++ b/repo-scripts/api-documenter/src/toc.ts @@ -27,6 +27,7 @@ export interface ITocGenerationOptions { g3Path: string; outputFolder: string; addFileNameSuffix: boolean; + jsSdk: boolean; } interface ITocItem { @@ -39,14 +40,19 @@ export function generateToc({ apiModel, g3Path, outputFolder, - addFileNameSuffix + addFileNameSuffix, + jsSdk }: ITocGenerationOptions) { - const js: ITocItem = { - title: 'firebase', - path: `${g3Path}/index`, - section: [] - }; - const toc = [js]; + const toc = []; + + if (jsSdk) { + const firebaseToc: ITocItem = { + title: 'firebase', + path: `${g3Path}/index`, + section: [] + }; + toc.push(firebaseToc); + } generateTocRecursively(apiModel, g3Path, addFileNameSuffix, toc); From 0a1b29edde7a9e2f44ab255524733c820bf15b08 Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Mon, 24 May 2021 15:26:43 -0700 Subject: [PATCH 5/6] update description of the command --- repo-scripts/api-documenter/src/cli/TocAction.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/repo-scripts/api-documenter/src/cli/TocAction.ts b/repo-scripts/api-documenter/src/cli/TocAction.ts index ce7c2dbe53f..6ddf9dfc410 100644 --- a/repo-scripts/api-documenter/src/cli/TocAction.ts +++ b/repo-scripts/api-documenter/src/cli/TocAction.ts @@ -29,10 +29,8 @@ export class TocAction extends BaseAction { public constructor(parser: ApiDocumenterCommandLine) { super({ actionName: 'toc', - 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.' + summary: 'Generate TOC(table of content) for Firebase devsite.', + documentation: 'Generate TOC(table of content) for Firebase devsite.' }); } From 679fa99a34a9a68f477842d509057720657c0a24 Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Mon, 24 May 2021 15:31:09 -0700 Subject: [PATCH 6/6] change parameter name to --host-path --- repo-scripts/api-documenter/README.md | 2 +- repo-scripts/api-documenter/src/cli/TocAction.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/repo-scripts/api-documenter/README.md b/repo-scripts/api-documenter/README.md index ec5c3e772ba..302cdd25bd8 100644 --- a/repo-scripts/api-documenter/README.md +++ b/repo-scripts/api-documenter/README.md @@ -7,7 +7,7 @@ and then generates files in [Markdown](https://en.wikipedia.org/wiki/Markdown) f ## Generate toc for Firebase devsite `api-documenter-fire toc -i temp -p "/docs/reference/js/v9"` -`-i` and `-p` are required parameters. +`-i` and `-p` (`--host-path`) are required parameters. Use `-i` to specify the folder that contains api.json files. Use `-p` to specify the g3 path that contains the reference docs. diff --git a/repo-scripts/api-documenter/src/cli/TocAction.ts b/repo-scripts/api-documenter/src/cli/TocAction.ts index 6ddf9dfc410..316be83a0d2 100644 --- a/repo-scripts/api-documenter/src/cli/TocAction.ts +++ b/repo-scripts/api-documenter/src/cli/TocAction.ts @@ -38,10 +38,10 @@ export class TocAction extends BaseAction { super.onDefineParameters(); this._g3PathParameter = this.defineStringParameter({ - parameterLongName: '--g3-path', + parameterLongName: '--host-path', parameterShortName: '-p', - argumentName: 'G3PREFIX', - description: `Specifies the path where the reference docs will be written to in g3. + argumentName: 'HOSTPATH', + description: `Specifies the path where the reference docs resides (e.g. g3). Used to generate paths in the toc` });