From 46512414260dd1d374dc2513656ee151bbb93668 Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Thu, 5 May 2022 19:37:10 +0900 Subject: [PATCH 1/9] Add custom script for generating toc for v2 refs. --- docgen/toc.ts | 187 ++++++++++++++++++++++++++ package-lock.json | 289 ++++++++++++----------------------------- package.json | 4 +- src/cloud-functions.ts | 4 +- 4 files changed, 271 insertions(+), 213 deletions(-) create mode 100644 docgen/toc.ts diff --git a/docgen/toc.ts b/docgen/toc.ts new file mode 100644 index 000000000..2893dbeb9 --- /dev/null +++ b/docgen/toc.ts @@ -0,0 +1,187 @@ +/** + * @license + * Copyright 2022 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 { writeFileSync } from 'fs'; +import { join, resolve } from 'path'; + +import yargs from 'yargs'; +import * as yaml from 'js-yaml'; +import { + ApiItem, + ApiItemKind, + ApiModel, + ApiPackage, + ApiParameterListMixin, +} from 'api-extractor-model-me'; +import { FileSystem, PackageName } from '@rushstack/node-core-library'; +import { ModuleSource } from '@microsoft/tsdoc/lib-commonjs/beta/DeclarationReference'; + +const badFilenameCharsRegExp: RegExp = /[^a-z0-9_\-\.]/gi; + +export interface ITocGenerationOptions { + apiModel: ApiModel; + g3Path: string; + outputFolder: string; +} + +interface ITocItem { + title: string; + path: string; + section?: ITocItem[]; +} + +function getSafeFilenameForName(name: string): string { + // We will fix that as part of https://github.com/microsoft/rushstack/issues/1308 + return name.replace(badFilenameCharsRegExp, '_').toLowerCase(); +} + +export function generateToc({ + apiModel, + g3Path, + outputFolder, +}: ITocGenerationOptions) { + const toc = []; + generateTocRecursively(toc, apiModel, g3Path); + + writeFileSync( + resolve(outputFolder, 'toc.yaml'), + yaml.dump( + { toc }, + { + quotingType: '"', + } + ) + ); +} + +export function getFilenameForApiItem( + apiItem: ApiItem, + addFileNameSuffix: boolean +): string { + if (apiItem.kind === ApiItemKind.Model) { + return 'index.md'; + } + + let baseName: string = ''; + let multipleEntryPoints: boolean = false; + for (const hierarchyItem of apiItem.getHierarchy()) { + // For overloaded methods, add a suffix such as "MyClass.myMethod_2". + let qualifiedName: string = getSafeFilenameForName( + hierarchyItem.displayName + ); + if (ApiParameterListMixin.isBaseClassOf(hierarchyItem)) { + if (hierarchyItem.overloadIndex > 1) { + // Subtract one for compatibility with earlier releases of API Documenter. + // (This will get revamped when we fix GitHub issue #1308) + qualifiedName += `_${hierarchyItem.overloadIndex - 1}`; + } + } + + switch (hierarchyItem.kind) { + case ApiItemKind.Model: + break; + case ApiItemKind.EntryPoint: + const packageName: string = hierarchyItem.parent!.displayName; + let entryPointName: string = PackageName.getUnscopedName(packageName); + if (multipleEntryPoints) { + entryPointName = `${PackageName.getUnscopedName(packageName)}/${ + hierarchyItem.displayName + }`; + } + baseName = getSafeFilenameForName(entryPointName); + break; + case ApiItemKind.Package: + baseName = getSafeFilenameForName( + PackageName.getUnscopedName(hierarchyItem.displayName) + ); + if ((hierarchyItem as ApiPackage).entryPoints.length > 1) { + multipleEntryPoints = true; + } + break; + case ApiItemKind.Namespace: + baseName += '.' + qualifiedName; + if (addFileNameSuffix) { + baseName += '_n'; + } + break; + case ApiItemKind.Class: + case ApiItemKind.Interface: + baseName += '.' + qualifiedName; + break; + } + } + return baseName + '.md'; +} + +function generateTocRecursively( + toc: ITocItem[], + apiItem: ApiItem, + g3Path: string +) { + // Each version of the functions SDK should have 1 entry point made up of many namespaces so recursion is unncessary. + // We keep the code nonetheless for the future where we run the api-documenter once to generate both v1 and v2 refs. + if (apiItem.kind === ApiItemKind.EntryPoint) { + const entryPointName = (apiItem.canonicalReference.source! as ModuleSource).escapedPath; + const entryPointToc: ITocItem = { + title: entryPointName, + path: `${g3Path}/${getFilenameForApiItem(apiItem, false)}`, + section: [], + }; + for (const member of apiItem.members) { + if (member.kind == 'Namespace') { + entryPointToc.section.push({ + title: member.displayName, + path: `${g3Path}/${getFilenameForApiItem(apiItem, false)}`, + }); + } + } + toc.push(entryPointToc); + } else { + // travel the api tree to find the next entry point + for (const member of apiItem.members) { + generateTocRecursively(toc, member, g3Path); + } + } +} + +const { input, output, path } = yargs(process.argv.slice(2)) + .option('input', { + alias: 'i', + describe: 'input folder containing the *.api.json files to be processed.', + default: './input', + }) + .option('output', { + alias: 'o', + describe: 'destination for the generated toc content.', + default: './toc', + }) + .option('path', { + alias: 'p', + describe: 'specifies the path where the reference docs resides (e.g. g3)', + default: '/', + }) + .help().argv; + +const apiModel: ApiModel = new ApiModel(); +for (const filename of FileSystem.readFolder(input)) { + if (filename.match(/\.api\.json$/i)) { + console.log(`Reading ${filename}`); + const filenamePath: string = join(input, filename); + apiModel.loadPackage(filenamePath); + } +} +FileSystem.ensureFolder(output); +generateToc({ apiModel, g3Path: path, outputFolder: output }); diff --git a/package-lock.json b/package-lock.json index 2bd402d37..1762037a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -61,122 +61,12 @@ "tslib": "^2.1.0" }, "dependencies": { - "@microsoft/tsdoc": { - "version": "0.12.24", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.12.24.tgz", - "integrity": "sha512-Mfmij13RUTmHEMi9vRUhMXD7rnGR2VvxeNYtaGtaJ4redwwjT4UXYJ+nzmVJF7hhd4pn/Fx5sncDKxMVFJSWPg==", - "dev": true - }, - "@rushstack/node-core-library": { - "version": "3.36.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.36.0.tgz", - "integrity": "sha512-bID2vzXpg8zweXdXgQkKToEdZwVrVCN9vE9viTRk58gqzYaTlz4fMId6V3ZfpXN6H0d319uGi2KDlm+lUEeqCg==", - "dev": true, - "requires": { - "@types/node": "10.17.13", - "colors": "~1.2.1", - "fs-extra": "~7.0.1", - "import-lazy": "~4.0.0", - "jju": "~1.4.0", - "resolve": "~1.17.0", - "semver": "~7.3.0", - "timsort": "~0.3.0", - "z-schema": "~3.18.3" - } - }, - "@rushstack/ts-command-line": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.7.8.tgz", - "integrity": "sha512-8ghIWhkph7NnLCMDJtthpsb7TMOsVGXVDvmxjE/CeklTqjbbUFBjGXizJfpbEkRQTELuZQ2+vGn7sGwIWKN2uA==", - "dev": true, - "requires": { - "@types/argparse": "1.0.38", - "argparse": "~1.0.9", - "colors": "~1.2.1", - "string-argv": "~0.3.1" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - } - } - }, - "@types/argparse": { - "version": "1.0.38", - "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", - "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", - "dev": true - }, - "@types/node": { - "version": "10.17.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz", - "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==", - "dev": true - }, - "api-extractor-model-me": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/api-extractor-model-me/-/api-extractor-model-me-0.1.1.tgz", - "integrity": "sha512-Ez801ZMADfkseOWNRFquvyQYDm3D9McpxfkKMWL6JFCGcpub0miJ+TFNphIR1nSZbrsxz3kIeOovNMY4VlL6Bw==", - "dev": true, - "requires": { - "@microsoft/tsdoc": "0.12.24", - "@rushstack/node-core-library": "3.36.0" - } - }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "colors": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", - "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", - "dev": true - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "optional": true - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "import-lazy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", - "dev": true - }, - "jju": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", - "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=", - "dev": true - }, "js-yaml": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", @@ -186,42 +76,6 @@ "argparse": "^2.0.1" } }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true - }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -230,69 +84,6 @@ "requires": { "path-parse": "^1.0.6" } - }, - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", - "dev": true - }, - "timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", - "dev": true - }, - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "validator": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz", - "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "z-schema": { - "version": "3.18.4", - "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.18.4.tgz", - "integrity": "sha512-DUOKC/IhbkdLKKiV89gw9DUauTV8U/8yJl1sjf6MtDmzevLKOF2duNJ495S3MFVjqZarr+qNGCPbkg4mu4PpLw==", - "dev": true, - "requires": { - "commander": "^2.7.1", - "lodash.get": "^4.0.0", - "lodash.isequal": "^4.0.0", - "validator": "^8.0.0" - } } } }, @@ -761,6 +552,12 @@ } } }, + "@microsoft/tsdoc": { + "version": "0.12.24", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.12.24.tgz", + "integrity": "sha512-Mfmij13RUTmHEMi9vRUhMXD7rnGR2VvxeNYtaGtaJ4redwwjT4UXYJ+nzmVJF7hhd4pn/Fx5sncDKxMVFJSWPg==", + "dev": true + }, "@microsoft/tsdoc-config": { "version": "0.16.1", "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.1.tgz", @@ -871,6 +668,40 @@ "dev": true, "optional": true }, + "@rushstack/node-core-library": { + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.36.0.tgz", + "integrity": "sha512-bID2vzXpg8zweXdXgQkKToEdZwVrVCN9vE9viTRk58gqzYaTlz4fMId6V3ZfpXN6H0d319uGi2KDlm+lUEeqCg==", + "dev": true, + "requires": { + "@types/node": "10.17.13", + "colors": "~1.2.1", + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.17.0", + "semver": "~7.3.0", + "timsort": "~0.3.0", + "z-schema": "~3.18.3" + }, + "dependencies": { + "@types/node": { + "version": "10.17.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz", + "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, "@rushstack/rig-package": { "version": "0.3.11", "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.3.11.tgz", @@ -898,6 +729,18 @@ } } }, + "@rushstack/ts-command-line": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.7.8.tgz", + "integrity": "sha512-8ghIWhkph7NnLCMDJtthpsb7TMOsVGXVDvmxjE/CeklTqjbbUFBjGXizJfpbEkRQTELuZQ2+vGn7sGwIWKN2uA==", + "dev": true, + "requires": { + "@types/argparse": "1.0.38", + "argparse": "~1.0.9", + "colors": "~1.2.1", + "string-argv": "~0.3.1" + } + }, "@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -1286,6 +1129,16 @@ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", "dev": true }, + "api-extractor-model-me": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/api-extractor-model-me/-/api-extractor-model-me-0.1.1.tgz", + "integrity": "sha512-Ez801ZMADfkseOWNRFquvyQYDm3D9McpxfkKMWL6JFCGcpub0miJ+TFNphIR1nSZbrsxz3kIeOovNMY4VlL6Bw==", + "dev": true, + "requires": { + "@microsoft/tsdoc": "0.12.24", + "@rushstack/node-core-library": "3.36.0" + } + }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -4818,6 +4671,12 @@ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, + "validator": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz", + "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==", + "dev": true + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -5296,6 +5155,18 @@ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "optional": true + }, + "z-schema": { + "version": "3.18.4", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.18.4.tgz", + "integrity": "sha512-DUOKC/IhbkdLKKiV89gw9DUauTV8U/8yJl1sjf6MtDmzevLKOF2duNJ495S3MFVjqZarr+qNGCPbkg4mu4PpLw==", + "dev": true, + "requires": { + "commander": "^2.7.1", + "lodash.get": "^4.0.0", + "lodash.isequal": "^4.0.0", + "validator": "^8.0.0" + } } } } diff --git a/package.json b/package.json index 86e128cad..455b5e5f5 100644 --- a/package.json +++ b/package.json @@ -161,7 +161,8 @@ "docgen:v1:gen": "api-documenter-fire markdown -i docgen/v1 -o docgen/v1/markdown && api-documenter-fire toc -i docgen/v1 -o docgen/v1/markdown/toc -p /docs/reference/functions", "docgen:v1": "npm run docgen:v1:extract && npm run docgen:v1:gen", "docgen:v2:extract": "api-extractor run -c docgen/api-extractor.v2.json --local", - "docgen:v2:gen": "api-documenter-fire markdown -i docgen/v2 -o docgen/v2/markdown && api-documenter-fire toc -i docgen/v2 -o docgen/v2/markdown/toc -p /docs/reference/functions/v2", + "docgen:v2:toc": "ts-node docgen/toc.ts --input docgen/v2 --output docgen/v2/markdown/toc --path /docs/reference/functions/v2", + "docgen:v2:gen": "api-documenter-fire markdown -i docgen/v2 -o docgen/v2/markdown && npm run docgen:v2:toc", "docgen:v2": "npm run docgen:v2:extract && npm run docgen:v2:gen", "build:pack": "rm -rf lib && npm install && tsc -p tsconfig.release.json && npm pack", "build:release": "npm ci --production && npm install --no-save typescript firebase-admin && tsc -p tsconfig.release.json", @@ -196,6 +197,7 @@ "@types/node": "^8.10.50", "@types/node-fetch": "^3.0.3", "@types/sinon": "^7.0.13", + "api-extractor-model-me": "^0.1.1", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "child-process-promise": "^2.2.1", diff --git a/src/cloud-functions.ts b/src/cloud-functions.ts index 6018e4caa..7fe855819 100644 --- a/src/cloud-functions.ts +++ b/src/cloud-functions.ts @@ -43,9 +43,7 @@ import { ManifestEndpoint, ManifestRequiredAPI } from './runtime/manifest'; const WILDCARD_REGEX = new RegExp('{[^/{}]*}', 'g'); /** - * Wire format for an event. - * - * @internal + * Wire format for an event destined for a cloud function instance. */ export interface Event { context: { From a26178fe035847851638641f565f25ba7ff25232 Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Thu, 5 May 2022 19:44:53 +0900 Subject: [PATCH 2/9] Fix bug where path for section was wrong. --- docgen/toc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docgen/toc.ts b/docgen/toc.ts index 2893dbeb9..edd5397bc 100644 --- a/docgen/toc.ts +++ b/docgen/toc.ts @@ -144,7 +144,7 @@ function generateTocRecursively( if (member.kind == 'Namespace') { entryPointToc.section.push({ title: member.displayName, - path: `${g3Path}/${getFilenameForApiItem(apiItem, false)}`, + path: `${g3Path}/${getFilenameForApiItem(member, false)}`, }); } } From e144f1f7dee83da6d6585e9ec9733792888235ab Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Thu, 5 May 2022 19:45:11 +0900 Subject: [PATCH 3/9] Update path for v2 beta reference docs. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 455b5e5f5..a0c1bd2fa 100644 --- a/package.json +++ b/package.json @@ -161,7 +161,7 @@ "docgen:v1:gen": "api-documenter-fire markdown -i docgen/v1 -o docgen/v1/markdown && api-documenter-fire toc -i docgen/v1 -o docgen/v1/markdown/toc -p /docs/reference/functions", "docgen:v1": "npm run docgen:v1:extract && npm run docgen:v1:gen", "docgen:v2:extract": "api-extractor run -c docgen/api-extractor.v2.json --local", - "docgen:v2:toc": "ts-node docgen/toc.ts --input docgen/v2 --output docgen/v2/markdown/toc --path /docs/reference/functions/v2", + "docgen:v2:toc": "ts-node docgen/toc.ts --input docgen/v2 --output docgen/v2/markdown/toc --path /docs/functions/beta/reference", "docgen:v2:gen": "api-documenter-fire markdown -i docgen/v2 -o docgen/v2/markdown && npm run docgen:v2:toc", "docgen:v2": "npm run docgen:v2:extract && npm run docgen:v2:gen", "build:pack": "rm -rf lib && npm install && tsc -p tsconfig.release.json && npm pack", From fdeca3fe074156f3c4ca2c4f21438a7f27e5b79a Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Thu, 5 May 2022 19:46:53 +0900 Subject: [PATCH 4/9] Add comment that this script is a fork of @firebase/api-documenter. --- docgen/toc.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docgen/toc.ts b/docgen/toc.ts index edd5397bc..d01e597be 100644 --- a/docgen/toc.ts +++ b/docgen/toc.ts @@ -14,6 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +/** + * Forked of https://github.com/firebase/firebase-js-sdk/blob/5ce06766303b92fea969c58172a7c1ab8695e21e/repo-scripts/api-documenter/src/toc.ts. + */ import { writeFileSync } from 'fs'; import { join, resolve } from 'path'; From 2e121c940fff7742f0272d3aab003fe4e47d2556 Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Thu, 5 May 2022 19:49:06 +0900 Subject: [PATCH 5/9] Format. --- docgen/toc.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docgen/toc.ts b/docgen/toc.ts index d01e597be..1326ddbce 100644 --- a/docgen/toc.ts +++ b/docgen/toc.ts @@ -138,7 +138,8 @@ function generateTocRecursively( // Each version of the functions SDK should have 1 entry point made up of many namespaces so recursion is unncessary. // We keep the code nonetheless for the future where we run the api-documenter once to generate both v1 and v2 refs. if (apiItem.kind === ApiItemKind.EntryPoint) { - const entryPointName = (apiItem.canonicalReference.source! as ModuleSource).escapedPath; + const entryPointName = (apiItem.canonicalReference.source! as ModuleSource) + .escapedPath; const entryPointToc: ITocItem = { title: entryPointName, path: `${g3Path}/${getFilenameForApiItem(apiItem, false)}`, From 37e1a75f735056b40914ee1afddb503f6fcf6df5 Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Fri, 6 May 2022 22:09:10 +0900 Subject: [PATCH 6/9] Revamp toc to include section for all generated docs. --- docgen/toc.ts | 176 +++++++++++++++----------------------------------- package.json | 2 +- 2 files changed, 53 insertions(+), 125 deletions(-) diff --git a/docgen/toc.ts b/docgen/toc.ts index 1326ddbce..d0a6b7298 100644 --- a/docgen/toc.ts +++ b/docgen/toc.ts @@ -19,46 +19,73 @@ * Forked of https://github.com/firebase/firebase-js-sdk/blob/5ce06766303b92fea969c58172a7c1ab8695e21e/repo-scripts/api-documenter/src/toc.ts. */ import { writeFileSync } from 'fs'; -import { join, resolve } from 'path'; +import { resolve } from 'path'; import yargs from 'yargs'; import * as yaml from 'js-yaml'; -import { - ApiItem, - ApiItemKind, - ApiModel, - ApiPackage, - ApiParameterListMixin, -} from 'api-extractor-model-me'; -import { FileSystem, PackageName } from '@rushstack/node-core-library'; -import { ModuleSource } from '@microsoft/tsdoc/lib-commonjs/beta/DeclarationReference'; +import { FileSystem } from '@rushstack/node-core-library'; -const badFilenameCharsRegExp: RegExp = /[^a-z0-9_\-\.]/gi; - -export interface ITocGenerationOptions { - apiModel: ApiModel; - g3Path: string; +export interface TocGenerationOptions { + inputFolder: string; outputFolder: string; + g3Path: string; } -interface ITocItem { +interface TocItem { title: string; path: string; - section?: ITocItem[]; + section?: TocItem[]; } -function getSafeFilenameForName(name: string): string { - // We will fix that as part of https://github.com/microsoft/rushstack/issues/1308 - return name.replace(badFilenameCharsRegExp, '_').toLowerCase(); +function fileExt(f: string) { + const parts = f.split('.'); + if (parts.length < 2) { + return ''; + } + return parts.pop(); } export function generateToc({ - apiModel, + inputFolder, g3Path, outputFolder, -}: ITocGenerationOptions) { - const toc = []; - generateTocRecursively(toc, apiModel, g3Path); +}: TocGenerationOptions) { + const asObj = FileSystem.readFolder(inputFolder) + .filter((f) => fileExt(f) === 'md') + .reduce((acc, f) => { + const parts = f.split('.'); + parts.pop(); // Get rid of file extenion (.md) + + let cursor = acc; + for (const p of parts) { + cursor[p] = cursor[p] || {}; + cursor = cursor[p]; + } + return acc; + }, {} as any); + + function toToc(obj, prefix = ''): TocItem[] { + const toc: TocItem[] = []; + for (const key of Object.keys(obj)) { + const item = prefix?.length ? `${prefix}.${key}` : key; + + toc.push({ + title: item.replace(/\./g, '/'), + path: `${g3Path}/${item}.md`, + section: toToc(obj[key], item), + }); + } + return toc; + } + + const toc: TocItem[] = [ + { + title: 'firebase-functions', + path: `${g3Path}/firebase-functions.md`, + section: [], + }, + ...toToc(asObj['firebase-functions'], 'firebase-functions'), + ]; writeFileSync( resolve(outputFolder, 'toc.yaml'), @@ -71,97 +98,6 @@ export function generateToc({ ); } -export function getFilenameForApiItem( - apiItem: ApiItem, - addFileNameSuffix: boolean -): string { - if (apiItem.kind === ApiItemKind.Model) { - return 'index.md'; - } - - let baseName: string = ''; - let multipleEntryPoints: boolean = false; - for (const hierarchyItem of apiItem.getHierarchy()) { - // For overloaded methods, add a suffix such as "MyClass.myMethod_2". - let qualifiedName: string = getSafeFilenameForName( - hierarchyItem.displayName - ); - if (ApiParameterListMixin.isBaseClassOf(hierarchyItem)) { - if (hierarchyItem.overloadIndex > 1) { - // Subtract one for compatibility with earlier releases of API Documenter. - // (This will get revamped when we fix GitHub issue #1308) - qualifiedName += `_${hierarchyItem.overloadIndex - 1}`; - } - } - - switch (hierarchyItem.kind) { - case ApiItemKind.Model: - break; - case ApiItemKind.EntryPoint: - const packageName: string = hierarchyItem.parent!.displayName; - let entryPointName: string = PackageName.getUnscopedName(packageName); - if (multipleEntryPoints) { - entryPointName = `${PackageName.getUnscopedName(packageName)}/${ - hierarchyItem.displayName - }`; - } - baseName = getSafeFilenameForName(entryPointName); - break; - case ApiItemKind.Package: - baseName = getSafeFilenameForName( - PackageName.getUnscopedName(hierarchyItem.displayName) - ); - if ((hierarchyItem as ApiPackage).entryPoints.length > 1) { - multipleEntryPoints = true; - } - break; - case ApiItemKind.Namespace: - baseName += '.' + qualifiedName; - if (addFileNameSuffix) { - baseName += '_n'; - } - break; - case ApiItemKind.Class: - case ApiItemKind.Interface: - baseName += '.' + qualifiedName; - break; - } - } - return baseName + '.md'; -} - -function generateTocRecursively( - toc: ITocItem[], - apiItem: ApiItem, - g3Path: string -) { - // Each version of the functions SDK should have 1 entry point made up of many namespaces so recursion is unncessary. - // We keep the code nonetheless for the future where we run the api-documenter once to generate both v1 and v2 refs. - if (apiItem.kind === ApiItemKind.EntryPoint) { - const entryPointName = (apiItem.canonicalReference.source! as ModuleSource) - .escapedPath; - const entryPointToc: ITocItem = { - title: entryPointName, - path: `${g3Path}/${getFilenameForApiItem(apiItem, false)}`, - section: [], - }; - for (const member of apiItem.members) { - if (member.kind == 'Namespace') { - entryPointToc.section.push({ - title: member.displayName, - path: `${g3Path}/${getFilenameForApiItem(member, false)}`, - }); - } - } - toc.push(entryPointToc); - } else { - // travel the api tree to find the next entry point - for (const member of apiItem.members) { - generateTocRecursively(toc, member, g3Path); - } - } -} - const { input, output, path } = yargs(process.argv.slice(2)) .option('input', { alias: 'i', @@ -180,13 +116,5 @@ const { input, output, path } = yargs(process.argv.slice(2)) }) .help().argv; -const apiModel: ApiModel = new ApiModel(); -for (const filename of FileSystem.readFolder(input)) { - if (filename.match(/\.api\.json$/i)) { - console.log(`Reading ${filename}`); - const filenamePath: string = join(input, filename); - apiModel.loadPackage(filenamePath); - } -} FileSystem.ensureFolder(output); -generateToc({ apiModel, g3Path: path, outputFolder: output }); +generateToc({ inputFolder: input, g3Path: path, outputFolder: output }); diff --git a/package.json b/package.json index a0c1bd2fa..80a726327 100644 --- a/package.json +++ b/package.json @@ -161,7 +161,7 @@ "docgen:v1:gen": "api-documenter-fire markdown -i docgen/v1 -o docgen/v1/markdown && api-documenter-fire toc -i docgen/v1 -o docgen/v1/markdown/toc -p /docs/reference/functions", "docgen:v1": "npm run docgen:v1:extract && npm run docgen:v1:gen", "docgen:v2:extract": "api-extractor run -c docgen/api-extractor.v2.json --local", - "docgen:v2:toc": "ts-node docgen/toc.ts --input docgen/v2 --output docgen/v2/markdown/toc --path /docs/functions/beta/reference", + "docgen:v2:toc": "ts-node docgen/toc.ts --input docgen/v2/markdown --output docgen/v2/markdown/toc --path /docs/functions/beta/reference", "docgen:v2:gen": "api-documenter-fire markdown -i docgen/v2 -o docgen/v2/markdown && npm run docgen:v2:toc", "docgen:v2": "npm run docgen:v2:extract && npm run docgen:v2:gen", "build:pack": "rm -rf lib && npm install && tsc -p tsconfig.release.json && npm pack", From 023a7e34900bd5b081ab98fe05d17a6066f326b2 Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Sat, 7 May 2022 02:23:51 +0900 Subject: [PATCH 7/9] Don't output empty sections. --- docgen/toc.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docgen/toc.ts b/docgen/toc.ts index d0a6b7298..042fe4160 100644 --- a/docgen/toc.ts +++ b/docgen/toc.ts @@ -68,12 +68,15 @@ export function generateToc({ const toc: TocItem[] = []; for (const key of Object.keys(obj)) { const item = prefix?.length ? `${prefix}.${key}` : key; - - toc.push({ + const section = toToc(obj[key], item); + const tic: TocItem = { title: item.replace(/\./g, '/'), path: `${g3Path}/${item}.md`, - section: toToc(obj[key], item), - }); + }; + if (section.length > 0) { + tic.section = section; + } + toc.push(tic); } return toc; } @@ -82,7 +85,6 @@ export function generateToc({ { title: 'firebase-functions', path: `${g3Path}/firebase-functions.md`, - section: [], }, ...toToc(asObj['firebase-functions'], 'firebase-functions'), ]; From 106698fea60675dce074f84636b1f81c47328201 Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Sat, 7 May 2022 02:48:28 +0900 Subject: [PATCH 8/9] Add experimental status, shorten title. --- docgen/toc.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docgen/toc.ts b/docgen/toc.ts index 042fe4160..c8151df20 100644 --- a/docgen/toc.ts +++ b/docgen/toc.ts @@ -35,6 +35,7 @@ interface TocItem { title: string; path: string; section?: TocItem[]; + status?: "experimental", } function fileExt(f: string) { @@ -67,11 +68,11 @@ export function generateToc({ function toToc(obj, prefix = ''): TocItem[] { const toc: TocItem[] = []; for (const key of Object.keys(obj)) { - const item = prefix?.length ? `${prefix}.${key}` : key; - const section = toToc(obj[key], item); + const path = prefix?.length ? `${prefix}.${key}` : key; + const section = toToc(obj[key], path); const tic: TocItem = { - title: item.replace(/\./g, '/'), - path: `${g3Path}/${item}.md`, + title: key, + path: `${g3Path}/${path}.md`, }; if (section.length > 0) { tic.section = section; @@ -84,6 +85,7 @@ export function generateToc({ const toc: TocItem[] = [ { title: 'firebase-functions', + status: "experimental", path: `${g3Path}/firebase-functions.md`, }, ...toToc(asObj['firebase-functions'], 'firebase-functions'), From bc527fddf4ce42762dc98d217efbbbaa13bf5d34 Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Sat, 7 May 2022 02:58:29 +0900 Subject: [PATCH 9/9] Format. --- docgen/toc.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docgen/toc.ts b/docgen/toc.ts index c8151df20..d552a9cba 100644 --- a/docgen/toc.ts +++ b/docgen/toc.ts @@ -35,7 +35,7 @@ interface TocItem { title: string; path: string; section?: TocItem[]; - status?: "experimental", + status?: 'experimental'; } function fileExt(f: string) { @@ -85,7 +85,7 @@ export function generateToc({ const toc: TocItem[] = [ { title: 'firebase-functions', - status: "experimental", + status: 'experimental', path: `${g3Path}/firebase-functions.md`, }, ...toToc(asObj['firebase-functions'], 'firebase-functions'),