diff --git a/.github/ISSUE_TEMPLATE/---feature-request.md b/.github/ISSUE_TEMPLATE/---feature-request.md deleted file mode 100644 index 93f7d6de1..000000000 --- a/.github/ISSUE_TEMPLATE/---feature-request.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: "\U0001F4A1 Feature Request" -about: - Have a feature you'd like to see in the functions SDK? Request it through our - support channel. -title: '' -labels: '' -assignees: '' ---- - - - -Great, we love hearing how we can improve our products! However, GitHub is not the place to submit them. Please submit your feature requests to: -https://firebase.google.com/support/contact/bugs-features/ diff --git a/.github/ISSUE_TEMPLATE/---report-a-bug.md b/.github/ISSUE_TEMPLATE/---report-a-bug.md index 694c4aedf..3ad82bf60 100644 --- a/.github/ISSUE_TEMPLATE/---report-a-bug.md +++ b/.github/ISSUE_TEMPLATE/---report-a-bug.md @@ -1,6 +1,6 @@ --- name: '⚠️ Report a Bug' -about: Think you found a bug in the SDK? Report it here. +about: Think you found a bug in the firebase-functions SDK? Report it here. Please do not use this form if your function is deployed successfully but not working as you expected. title: '' labels: '' assignees: '' diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..918e205f9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: 💻 Bug in the Firebase CLI + url: https://github.com/firebase/firebase-tools/issues/new/choose + about: Have you found a bug in the Firebase CLI? + - name: 🔥 Firebase Support + url: https://firebase.google.com/support/ + about: If you have an issue with your functions in production, please contact support. diff --git a/.github/workflows/postmerge.yaml b/.github/workflows/postmerge.yaml new file mode 100644 index 000000000..f5105958c --- /dev/null +++ b/.github/workflows/postmerge.yaml @@ -0,0 +1,55 @@ +# Copyright 2022 Google Inc. +# +# 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. +name: Post-merge tests + +on: + workflow_dispatch: + workflow_run: + workflows: ['CI Tests'] + types: [completed] + branches: [master] + +concurrency: + group: postmerge-${{ github.ref }} + cancel-in-progress: true + +env: + CI: true + +jobs: + postmerge: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 16 + + - uses: google-github-actions/auth@v0 + with: + credentials_json: '${{ secrets.CF3_INTEGRATION_TEST_GOOGLE_CREDENTIALS }}' + create_credentials_file: true + + - name: 'Set up Cloud SDK' + uses: google-github-actions/setup-gcloud@v0 + + - name: 'Setup Firebase CLI' + run: npm i -g firebase-tools + + - name: 'Run integration test' + run: npm run test:postmerge + + - name: Print debug logs + if: failure() + run: find . -type f -name "*debug.log" | xargs cat diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 000000000..33242e9b8 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,57 @@ +name: CI Tests + +on: + - pull_request + - push + +env: + CI: true + +jobs: + unit: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: + - 10.x + - 12.x + - 14.x + - 16.x + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + + - name: Cache npm + uses: actions/cache@v1 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }} + + - run: npm ci + - run: npm run lint + - run: npm run format + - run: npm run test + integration: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: + - 12.x + - 14.x + - 16.x + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + + - name: Cache npm + uses: actions/cache@v1 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }} + + - run: npm install + - run: npm run test:bin diff --git a/.gitignore b/.gitignore index ba3cdeec5..017bc9f40 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,12 @@ .tmp .vscode/ coverage +dist/ docgen/html +docgen/*/temp +docgen/*/markdown +docgen/*/*.json +docgen/*/*.md firebase-functions-*.tgz integration_test/.firebaserc integration_test/*.log @@ -14,3 +19,4 @@ node_modules npm-debug.log typings yarn.lock +.DS_Store diff --git a/.mocharc.yaml b/.mocharc.yaml index 932144124..2bb78edfc 100644 --- a/.mocharc.yaml +++ b/.mocharc.yaml @@ -1,10 +1,8 @@ exit: true extension: - ts -file: - - mocha/setup.ts package: ./package.json reporter: spec require: - 'ts-node/register' -spec: spec/**/*.spec.ts + - 'source-map-support/register' diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 43c97e719..000000000 --- a/.npmrc +++ /dev/null @@ -1 +0,0 @@ -package-lock=false diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 18dff4114..000000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -cache: npm -jobs: - include: - - name: lint - script: npm run lint - stage: verify - - name: format - script: npm run format - stage: verify -language: node_js -node_js: - - '8' - - '10' -sudo: false diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..f6a8ba1bc --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,2 @@ +- Fix reference docs for performance monitoring. +- Fix bug where function configuration wil null values couldn't be deployed. (#1246) diff --git a/README.md b/README.md index 59c5c0936..33fbaa746 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ const notifyUsers = require('./notify-users'); exports.newPost = functions.database .ref('/posts/{postId}') .onCreate((snapshot, context) => { - console.log('Received new post with ID:', context.params.postId); + functions.logger.info('Received new post with ID:', context.params.postId); return notifyUsers(snapshot.val()); }); ``` diff --git a/changelog.txt b/changelog.txt deleted file mode 100644 index c3be06fd4..000000000 --- a/changelog.txt +++ /dev/null @@ -1 +0,0 @@ -feature - Add a helper function for the Firebase Emulator suite. \ No newline at end of file diff --git a/deploy_key.enc b/deploy_key.enc new file mode 100644 index 000000000..4451e042b Binary files /dev/null and b/deploy_key.enc differ diff --git a/docgen/api-extractor.base.json b/docgen/api-extractor.base.json new file mode 100644 index 000000000..2938a396f --- /dev/null +++ b/docgen/api-extractor.base.json @@ -0,0 +1,364 @@ +/** + * Config file for API Extractor. For more info, please visit: https://api-extractor.com + */ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + + /** + * Optionally specifies another JSON config file that this file extends from. This provides a way for + * standard settings to be shared across multiple projects. + * + * If the path starts with "./" or "../", the path is resolved relative to the folder of the file that contains + * the "extends" field. Otherwise, the first path segment is interpreted as an NPM package name, and will be + * resolved using NodeJS require(). + * + * SUPPORTED TOKENS: none + * DEFAULT VALUE: "" + */ + // "extends": "./shared/api-extractor-base.json" + // "extends": "my-package/include/api-extractor-base.json" + + /** + * Determines the "" token that can be used with other config file settings. The project folder + * typically contains the tsconfig.json and package.json config files, but the path is user-defined. + * + * The path is resolved relative to the folder of the config file that contains the setting. + * + * The default value for "projectFolder" is the token "", which means the folder is determined by traversing + * parent folders, starting from the folder containing api-extractor.json, and stopping at the first folder + * that contains a tsconfig.json file. If a tsconfig.json file cannot be found in this way, then an error + * will be reported. + * + * SUPPORTED TOKENS: + * DEFAULT VALUE: "" + */ + "projectFolder": "..", + + /** + * (REQUIRED) Specifies the .d.ts file to be used as the starting point for analysis. API Extractor + * analyzes the symbols exported by this module. + * + * The file extension must be ".d.ts" and not ".ts". + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + */ + "mainEntryPointFilePath": "/lib/index.d.ts", + + /** + * A list of NPM package names whose exports should be treated as part of this package. + * + * For example, suppose that Webpack is used to generate a distributed bundle for the project "library1", + * and another NPM package "library2" is embedded in this bundle. Some types from library2 may become part + * of the exported API for library1, but by default API Extractor would generate a .d.ts rollup that explicitly + * imports library2. To avoid this, we can specify: + * + * "bundledPackages": [ "library2" ], + * + * This would direct API Extractor to embed those types directly in the .d.ts rollup, as if they had been + * local files for library1. + */ + "bundledPackages": [], + + /** + * Determines how the TypeScript compiler engine will be invoked by API Extractor. + */ + "compiler": { + /** + * Specifies the path to the tsconfig.json file to be used by API Extractor when analyzing the project. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * Note: This setting will be ignored if "overrideTsconfig" is used. + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/tsconfig.json" + */ + "tsconfigFilePath": "/tsconfig.release.json" + /** + * Provides a compiler configuration that will be used instead of reading the tsconfig.json file from disk. + * The object must conform to the TypeScript tsconfig schema: + * + * http://json.schemastore.org/tsconfig + * + * If omitted, then the tsconfig.json file will be read from the "projectFolder". + * + * DEFAULT VALUE: no overrideTsconfig section + */ + // "overrideTsconfig": { + // . . . + // } + /** + * This option causes the compiler to be invoked with the --skipLibCheck option. This option is not recommended + * and may cause API Extractor to produce incomplete or incorrect declarations, but it may be required when + * dependencies contain declarations that are incompatible with the TypeScript engine that API Extractor uses + * for its analysis. Where possible, the underlying issue should be fixed rather than relying on skipLibCheck. + * + * DEFAULT VALUE: false + */ + // "skipLibCheck": true, + }, + + /** + * Configures how the API report file (*.api.md) will be generated. + */ + "apiReport": { + /** + * (REQUIRED) Whether to generate an API report. + */ + "enabled": true, + + /** + * The filename for the API report files. It will be combined with "reportFolder" or "reportTempFolder" to produce + * a full file path. + * + * The file extension should be ".api.md", and the string should not contain a path separator such as "\" or "/". + * + * SUPPORTED TOKENS: , + * DEFAULT VALUE: ".api.md" + */ + // "reportFileName": ".api.md", + + /** + * Specifies the folder where the API report file is written. The file name portion is determined by + * the "reportFileName" setting. + * + * The API report file is normally tracked by Git. Changes to it can be used to trigger a branch policy, + * e.g. for an API review. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/etc/" + */ + "reportFolder": "/docgen/etc/", + + /** + * Specifies the folder where the temporary report file is written. The file name portion is determined by + * the "reportFileName" setting. + * + * After the temporary file is written to disk, it is compared with the file in the "reportFolder". + * If they are different, a production build will fail. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/temp/" + */ + "reportTempFolder": "/docgen/temp/" + }, + + /** + * Configures how the doc model file (*.api.json) will be generated. + */ + "docModel": { + /** + * (REQUIRED) Whether to generate a doc model file. + */ + "enabled": true, + + /** + * The output path for the doc model file. The file extension should be ".api.json". + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/temp/.api.json" + */ + "apiJsonFilePath": "/docgen/.api.json" + }, + + /** + * Configures how the .d.ts rollup file will be generated. + */ + "dtsRollup": { + /** + * (REQUIRED) Whether to generate the .d.ts rollup file. + */ + "enabled": true + + /** + * Specifies the output path for a .d.ts rollup file to be generated without any trimming. + * This file will include all declarations that are exported by the main entry point. + * + * If the path is an empty string, then this file will not be written. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/dist/.d.ts" + */ + // "untrimmedFilePath": "/dist/.d.ts", + + /** + * Specifies the output path for a .d.ts rollup file to be generated with trimming for a "beta" release. + * This file will include only declarations that are marked as "@public" or "@beta". + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "" + */ + // "betaTrimmedFilePath": "/dist/-beta.d.ts", + + /** + * Specifies the output path for a .d.ts rollup file to be generated with trimming for a "public" release. + * This file will include only declarations that are marked as "@public". + * + * If the path is an empty string, then this file will not be written. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "" + */ + // "publicTrimmedFilePath": "/dist/-public.d.ts", + + /** + * When a declaration is trimmed, by default it will be replaced by a code comment such as + * "Excluded from this release type: exampleMember". Set "omitTrimmingComments" to true to remove the + * declaration completely. + * + * DEFAULT VALUE: false + */ + // "omitTrimmingComments": true + }, + + /** + * Configures how the tsdoc-metadata.json file will be generated. + */ + "tsdocMetadata": { + /** + * Whether to generate the tsdoc-metadata.json file. + * + * DEFAULT VALUE: true + */ + // "enabled": true, + /** + * Specifies where the TSDoc metadata file should be written. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * The default value is "", which causes the path to be automatically inferred from the "tsdocMetadata", + * "typings" or "main" fields of the project's package.json. If none of these fields are set, the lookup + * falls back to "tsdoc-metadata.json" in the package folder. + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "" + */ + // "tsdocMetadataFilePath": "/dist/tsdoc-metadata.json" + }, + + /** + * Specifies what type of newlines API Extractor should use when writing output files. By default, the output files + * will be written with Windows-style newlines. To use POSIX-style newlines, specify "lf" instead. + * To use the OS's default newline kind, specify "os". + * + * DEFAULT VALUE: "crlf" + */ + // "newlineKind": "crlf", + + /** + * Configures how API Extractor reports error and warning messages produced during analysis. + * + * There are three sources of messages: compiler messages, API Extractor messages, and TSDoc messages. + */ + "messages": { + /** + * Configures handling of diagnostic messages reported by the TypeScript compiler engine while analyzing + * the input .d.ts files. + * + * TypeScript message identifiers start with "TS" followed by an integer. For example: "TS2551" + * + * DEFAULT VALUE: A single "default" entry with logLevel=warning. + */ + "compilerMessageReporting": { + /** + * Configures the default routing for messages that don't match an explicit rule in this table. + */ + "default": { + /** + * Specifies whether the message should be written to the the tool's output log. Note that + * the "addToApiReportFile" property may supersede this option. + * + * Possible values: "error", "warning", "none" + * + * Errors cause the build to fail and return a nonzero exit code. Warnings cause a production build fail + * and return a nonzero exit code. For a non-production build (e.g. when "api-extractor run" includes + * the "--local" option), the warning is displayed but the build will not fail. + * + * DEFAULT VALUE: "warning" + */ + "logLevel": "warning" + + /** + * When addToApiReportFile is true: If API Extractor is configured to write an API report file (.api.md), + * then the message will be written inside that file; otherwise, the message is instead logged according to + * the "logLevel" option. + * + * DEFAULT VALUE: false + */ + // "addToApiReportFile": false + } + + // "TS2551": { + // "logLevel": "warning", + // "addToApiReportFile": true + // }, + // + // . . . + }, + + /** + * Configures handling of messages reported by API Extractor during its analysis. + * + * API Extractor message identifiers start with "ae-". For example: "ae-extra-release-tag" + * + * DEFAULT VALUE: See api-extractor-defaults.json for the complete table of extractorMessageReporting mappings + */ + "extractorMessageReporting": { + "default": { + "logLevel": "warning" + // "addToApiReportFile": false + } + + // "ae-extra-release-tag": { + // "logLevel": "warning", + // "addToApiReportFile": true + // }, + // + // . . . + }, + + /** + * Configures handling of messages reported by the TSDoc parser when analyzing code comments. + * + * TSDoc message identifiers start with "tsdoc-". For example: "tsdoc-link-tag-unescaped-text" + * + * DEFAULT VALUE: A single "default" entry with logLevel=warning. + */ + "tsdocMessageReporting": { + "default": { + "logLevel": "warning" + // "addToApiReportFile": false + } + + // "tsdoc-link-tag-unescaped-text": { + // "logLevel": "warning", + // "addToApiReportFile": true + // }, + // + // . . . + } + } +} diff --git a/docgen/api-extractor.v1.json b/docgen/api-extractor.v1.json new file mode 100644 index 000000000..f03058f13 --- /dev/null +++ b/docgen/api-extractor.v1.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + "extends": "./api-extractor.base.json", + "mainEntryPointFilePath": "/lib/index.d.ts", + "docModel": { + "enabled": true, + "apiJsonFilePath": "/docgen/v1/firebase-functions.api.json" + }, + "apiReport": { + "enabled": true, + "reportTempFolder": "/docgen/v1/temp", + "reportFolder": "/docgen/v1" + } +} diff --git a/docgen/api-extractor.v2.json b/docgen/api-extractor.v2.json new file mode 100644 index 000000000..2cf0596b7 --- /dev/null +++ b/docgen/api-extractor.v2.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + "extends": "./api-extractor.base.json", + "mainEntryPointFilePath": "/lib/v2/index.d.ts", + "docModel": { + "enabled": true, + "apiJsonFilePath": "/docgen/v2/firebase-functions.api.json" + }, + "apiReport": { + "enabled": true, + "reportTempFolder": "/docgen/v2/temp", + "reportFolder": "/docgen/v2" + } +} diff --git a/docgen/content-sources/HOME.md b/docgen/content-sources/HOME.md deleted file mode 100644 index c89df0a57..000000000 --- a/docgen/content-sources/HOME.md +++ /dev/null @@ -1,3 +0,0 @@ -# Firebase Functions SDK Reference - -Functions SDK!!! diff --git a/docgen/content-sources/toc.yaml b/docgen/content-sources/toc.yaml deleted file mode 100644 index 9ba761c15..000000000 --- a/docgen/content-sources/toc.yaml +++ /dev/null @@ -1,116 +0,0 @@ -toc: - - title: 'functions' - path: /docs/reference/functions/cloud_functions_.html - section: - - title: 'CloudFunction' - path: /docs/reference/functions/cloud_functions_.html#cloudfunction - - title: 'HttpsFunction' - path: /docs/reference/functions/cloud_functions_.html#httpsfunction - - title: 'EventContext' - path: /docs/reference/functions/cloud_functions_.eventcontext.html - - title: 'FunctionBuilder' - path: /docs/reference/functions/function_builder_.functionbuilder.html - - title: 'Change' - path: /docs/reference/functions/cloud_functions_.change.html - - title: 'ChangeJson' - path: /docs/reference/functions/cloud_functions_.changejson.html - - - title: 'functions.config' - path: /docs/reference/functions/config_.html - section: - - title: 'Config' - path: /docs/reference/functions/config_.config.html - - - title: 'functions.analytics' - path: /docs/reference/functions/providers_analytics_.html - section: - - title: 'AnalyticsEvent' - path: /docs/reference/functions/providers_analytics_.analyticsevent.html - - title: 'AnalyticsEventBuilder' - path: /docs/reference/functions/providers_analytics_.analyticseventbuilder.html - - title: 'AppInfo' - path: /docs/reference/functions/providers_analytics_.appinfo.html - - title: 'DeviceInfo' - path: /docs/reference/functions/providers_analytics_.deviceinfo.html - - title: 'ExportBundleInfo' - path: /docs/reference/functions/providers_analytics_.exportbundleinfo.html - - title: 'GeoInfo' - path: /docs/reference/functions/providers_analytics_.geoinfo.html - - title: 'UserDimensions' - path: /docs/reference/functions/providers_analytics_.userdimensions.html - - title: 'UserPropertyValue' - path: /docs/reference/functions/providers_analytics_.userpropertyvalue.html - - - title: 'functions.auth' - path: /docs/reference/functions/providers_auth_.html - section: - - title: 'UserBuilder' - path: /docs/reference/functions/providers_auth_.userbuilder.html - - title: 'UserInfo' - path: /docs/reference/functions/providers_auth_.html#userinfo - - title: 'UserRecordMetadata' - path: /docs/reference/functions/providers_auth_.userrecordmetadata.html - - title: 'UserRecord' - path: /docs/reference/functions/providers_auth_.html#userrecord - - - title: 'functions.crashlytics' - path: /docs/reference/functions/providers_crashlytics_.html - section: - - title: 'Issue' - path: /docs/reference/functions/providers_crashlytics_.issue.html - - title: 'IssueBuilder' - path: /docs/reference/functions/providers_crashlytics_.issuebuilder.html - - title: 'AppInfo' - path: /docs/reference/functions/providers_crashlytics_.appinfo.html - - title: 'VelocityAlert' - path: /docs/reference/functions/providers_crashlytics_.velocityalert.html - - - title: 'functions.firestore' - path: /docs/reference/functions/providers_firestore_.html - section: - - title: 'DocumentBuilder' - path: /docs/reference/functions/providers_firestore_.documentbuilder.html - - title: 'DocumentSnapshot' - path: /docs/reference/functions/providers_firestore_.html#documentsnapshot - - - title: 'functions.database' - path: /docs/reference/functions/providers_database_.html - section: - - title: 'DataSnapshot' - path: /docs/reference/functions/providers_database_.datasnapshot.html - - title: 'RefBuilder' - path: /docs/reference/functions/providers_database_.refbuilder.html - - title: 'InstanceBuilder' - path: /docs/reference/functions/providers_database_.instancebuilder.html - - - title: 'functions.https' - path: /docs/reference/functions/providers_https_.html - section: - - title: 'HttpsError' - path: /docs/reference/functions/providers_https_.httpserror.html - - - title: 'functions.pubsub' - path: /docs/reference/functions/providers_pubsub_.html - section: - - title: 'Message' - path: /docs/reference/functions/providers_pubsub_.message.html - - title: 'TopicBuilder' - path: /docs/reference/functions/providers_pubsub_.topicbuilder.html - - - title: 'functions.remoteconfig' - path: /docs/reference/functions/providers_remoteconfig_.html - section: - - title: 'RemoteConfigUser' - path: /docs/reference/functions/providers_remoteconfig_.remoteconfiguser.html - - title: 'TemplateVersion' - path: /docs/reference/functions/providers_remoteconfig_.templateversion.html - - - title: 'functions.storage' - path: /docs/reference/functions/providers_storage_.html - section: - - title: 'BucketBuilder' - path: /docs/reference/functions/providers_storage_.bucketbuilder.html - - title: 'ObjectBuilder' - path: /docs/reference/functions/providers_storage_.objectbuilder.html - - title: 'ObjectMetadata' - path: /docs/reference/functions/providers_storage_.objectmetadata.html diff --git a/docgen/content-sources/v1/HOME.md b/docgen/content-sources/v1/HOME.md new file mode 100644 index 000000000..00d2090a0 --- /dev/null +++ b/docgen/content-sources/v1/HOME.md @@ -0,0 +1,8 @@ +# Firebase Functions SDK Reference + +The `firebase-functions` package provides an SDK for defining Cloud Functions for Firebase. + +To get started using Cloud Functions, see +[Get started: write, test, and deploy your first functions](/docs/functions/get-started). + +For source code, see the [Cloud Functions for Firebase GitHub repo](https://github.com/firebase/firebase-functions). diff --git a/docgen/content-sources/v1/toc.yaml b/docgen/content-sources/v1/toc.yaml new file mode 100644 index 000000000..59e380458 --- /dev/null +++ b/docgen/content-sources/v1/toc.yaml @@ -0,0 +1,176 @@ +toc: + - title: 'functions' + path: /docs/reference/functions/cloud_functions.html + section: + - title: 'CloudFunction' + path: /docs/reference/functions/cloud_functions.html#cloudfunction + - title: 'HttpsFunction' + path: /docs/reference/functions/cloud_functions.html#httpsfunction + - title: 'EventContext' + path: /docs/reference/functions/cloud_functions.eventcontext.html + - title: 'FunctionBuilder' + path: /docs/reference/functions/function_builder.functionbuilder.html + - title: 'Change' + path: /docs/reference/functions/cloud_functions.change.html + - title: 'ChangeJson' + path: /docs/reference/functions/cloud_functions.changejson.html + - title: 'BlockingFunction' + path: /docs/reference/functions/cloud_functions.blockingfunction.html + + - title: 'functions.config' + path: /docs/reference/functions/config.html + section: + - title: 'Config' + path: /docs/reference/functions/config.config-1.html + - title: 'config.Config' + path: /docs/reference/functions/config.config-1.config.html + + - title: 'functions.function-configuration' + path: /docs/reference/functions/function_configuration.html + section: + - title: 'config.DeploymentOptions' + path: /docs/reference/functions/function_configuration.deploymentoptions.html + - title: 'config.FailurePolicy' + path: /docs/reference/functions/function_configuration.failurepolicy.html + - title: 'config.RuntimeOptions' + path: /docs/reference/functions/function_configuration.runtimeoptions.html + - title: 'config.Schedule' + path: /docs/reference/functions/function_configuration.schedule.html + - title: 'config.ScheduleRetryConfig' + path: /docs/reference/functions/function_configuration.scheduleretryconfig.html + + - title: 'functions.analytics' + path: /docs/reference/functions/providers_analytics.html + section: + - title: 'AnalyticsEvent' + path: /docs/reference/functions/providers_analytics.analyticsevent.html + - title: 'AnalyticsEventBuilder' + path: /docs/reference/functions/providers_analytics.analyticseventbuilder.html + - title: 'AppInfo' + path: /docs/reference/functions/providers_analytics.appinfo.html + - title: 'DeviceInfo' + path: /docs/reference/functions/providers_analytics.deviceinfo.html + - title: 'ExportBundleInfo' + path: /docs/reference/functions/providers_analytics.exportbundleinfo.html + - title: 'GeoInfo' + path: /docs/reference/functions/providers_analytics.geoinfo.html + - title: 'UserDimensions' + path: /docs/reference/functions/providers_analytics.userdimensions.html + - title: 'UserPropertyValue' + path: /docs/reference/functions/providers_analytics.userpropertyvalue.html + + - title: 'functions.auth' + path: /docs/reference/functions/providers_auth.html + section: + - title: 'UserBuilder' + path: /docs/reference/functions/providers_auth.userbuilder.html + - title: 'UserInfo' + path: /docs/reference/functions/providers_auth.html#userinfo + - title: 'UserRecordMetadata' + path: /docs/reference/functions/providers_auth.userrecordmetadata.html + - title: 'UserRecord' + path: /docs/reference/functions/providers_auth.html#userrecord + + - title: 'functions.firestore' + path: /docs/reference/functions/providers_firestore.html + section: + - title: 'DocumentBuilder' + path: /docs/reference/functions/providers_firestore.documentbuilder.html + - title: 'DocumentSnapshot' + path: /docs/reference/functions/providers_firestore.html#documentsnapshot + + - title: 'functions.database' + path: /docs/reference/functions/providers_database.html + section: + - title: 'DataSnapshot' + path: /docs/reference/functions/providers_database.datasnapshot.html + - title: 'RefBuilder' + path: /docs/reference/functions/providers_database.refbuilder.html + - title: 'InstanceBuilder' + path: /docs/reference/functions/providers_database.instancebuilder.html + + - title: 'functions.https' + path: /docs/reference/functions/providers_https.html + section: + - title: 'HttpsError' + path: /docs/reference/functions/common_providers_https.httpserror.html + - title: 'CallableRequest' + path: /docs/reference/functions/common_providers_https.callablerequest.html + - title: 'CallableContext' + path: /docs/reference/functions/common_providers_https.callablecontext.html + - title: 'AuthData' + path: /docs/reference/functions/common_providers_https.authdata.html + - title: 'AppCheckData' + path: /docs/reference/functions/common_providers_https.appcheckdata.html + + - title: 'functions.logger' + path: /docs/reference/functions/logger.html + section: + - title: 'LogEntry' + path: /docs/reference/functions/logger.logentry.html + + - title: 'functions.pubsub' + path: /docs/reference/functions/providers_pubsub.html + section: + - title: 'Message' + path: /docs/reference/functions/providers_pubsub.message.html + - title: 'TopicBuilder' + path: /docs/reference/functions/providers_pubsub.topicbuilder.html + - title: 'ScheduleBuilder' + path: /docs/reference/functions/providers_pubsub.schedulebuilder.html + + - title: 'functions.remoteconfig' + path: /docs/reference/functions/providers_remoteconfig.html + section: + - title: 'RemoteConfigUser' + path: /docs/reference/functions/providers_remoteconfig.remoteconfiguser.html + - title: 'TemplateVersion' + path: /docs/reference/functions/providers_remoteconfig.templateversion.html + - title: 'UpdateBuilder' + path: /docs/reference/functions/providers_remoteconfig.updatebuilder.html + + - title: 'functions.storage' + path: /docs/reference/functions/providers_storage.html + section: + - title: 'BucketBuilder' + path: /docs/reference/functions/providers_storage.bucketbuilder.html + - title: 'ObjectBuilder' + path: /docs/reference/functions/providers_storage.objectbuilder.html + - title: 'ObjectMetadata' + path: /docs/reference/functions/providers_storage.objectmetadata.html + + - title: 'functions.tasks' + path: /docs/reference/functions/providers_tasks.html + section: + - title: AuthData + path: /docs/reference/functions/common_providers_tasks.authdata.html + - title: RateLimits + path: /docs/reference/functions/common_providers_tasks.ratelimits.html + - title: RetryConfig + path: /docs/reference/functions/common_providers_tasks.retryconfig.html + - title: TaskContext + path: /docs/reference/functions/common_providers_tasks.taskcontext.html + - title: TaskQueueBuilder + path: /docs/reference/functions/providers_tasks.taskqueuebuilder.html + - title: TaskQueueFunction + path: /docs/reference/functions/providers_tasks.taskqueuefunction.html + - title: TaskQueueOptions + path: /docs/reference/functions/providers_tasks.taskqueueoptions.html + + - title: 'functions.testLab' + path: /docs/reference/functions/providers_testlab.html + section: + - title: 'testLab.clientInfo' + path: /docs/reference/functions/providers_testlab.clientinfo.html + - title: 'testLab.resultStorage' + path: /docs/reference/functions/providers_testlab.resultstorage.html + - title: 'testLab.testMatrix' + path: /docs/reference/functions/providers_testlab.testmatrix.html + - title: 'testLab.testMatrixBuilder' + path: /docs/reference/functions/providers_testlab.testmatrixbuilder.html + + - title: 'functions.handler' + path: /docs/reference/functions/handler_builder.html + section: + - title: 'HandlerBuilder' + path: /docs/reference/functions/handler_builder.handlerbuilder.html diff --git a/docgen/content-sources/v2/HOME.md b/docgen/content-sources/v2/HOME.md new file mode 100644 index 000000000..dc6fe541f --- /dev/null +++ b/docgen/content-sources/v2/HOME.md @@ -0,0 +1,8 @@ +# Firebase Functions v2 SDK Reference + +This package provides an SDK for defining Cloud Functions for Firebase v2. + +To get started using Cloud Functions v2, see +the early access guide you were provided when you joined the EAP program. + +**Important:** This API reference is confidential. Do not share or discuss until authorized to do so. diff --git a/docgen/content-sources/v2/toc.yaml b/docgen/content-sources/v2/toc.yaml new file mode 100644 index 000000000..61e330865 --- /dev/null +++ b/docgen/content-sources/v2/toc.yaml @@ -0,0 +1,44 @@ +toc: + - title: 'functions' + path: /docs/functions/alpha/index.html + - title: 'functions.core' + path: /docs/functions/alpha/v2_core.html + section: + - title: 'Functions v2' + path: /docs/functions/alpha/v2.html + - title: 'functions.CloudEvent' + path: /docs/functions/alpha/v2_core.CloudEvent.html + - title: 'functions.CloudFunction' + path: /docs/functions/alpha/v2_core.CloudFunction.html + - title: 'functions.https' + path: /docs/functions/alpha/v2_providers_https.html + section: + - title: 'functions.https.CallableFunction' + path: /docs/functions/alpha/v2_providers_https.CallableFunction.html + - title: 'functions.https.CallableRequest' + path: /docs/functions/alpha/v2_providers_https.CallableRequest.html + - title: 'functions.https.error' + path: /docs/functions/alpha/v2_providers_https.HttpsError.html + - title: 'functions.https.options' + path: /docs/functions/alpha/v2_providers_https.HttpsOptions.html + - title: 'functions.logger' + path: /docs/functions/alpha/logger.html + section: + - title: 'LogEntry' + path: /docs/functions/alpha/logger.LogEntry.html + - title: 'functions.options' + path: /docs/functions/alpha/v2_options.html + section: + - title: 'functions.options.GlobalOptions' + path: /docs/functions/alpha/v2_options.GlobalOptions.html + - title: 'functions.options.EventHandlerOptions' + path: /docs/functions/alpha/v2_options.EventHandlerOptions.html + - title: 'functions.pubsub' + path: /docs/functions/alpha/v2_providers_pubsub.html + section: + - title: 'Message' + path: /docs/functions/alpha/v2_providers_pubsub.Message.html + - title: 'MessagePublishedData' + path: /docs/functions/alpha/v2_providers_pubsub.MessagePublishedData.html + - title: 'PubSubOptions' + path: /docs/functions/alpha/v2_providers_pubsub.PubSubOptions.html diff --git a/docgen/generate-docs.js b/docgen/generate-docs.js index 299250e64..bf07f3881 100644 --- a/docgen/generate-docs.js +++ b/docgen/generate-docs.js @@ -20,24 +20,45 @@ const fs = require('mz/fs'); const path = require('path'); const yargs = require('yargs'); const yaml = require('js-yaml'); -const _ = require('lodash'); const repoPath = path.resolve(`${__dirname}/..`); // Command-line options. -const { source: sourceFile } = yargs - .option('source', { - default: `${repoPath}/src`, +const { api: apiVersion } = yargs + .option('api', { + default: 'v1', describe: 'Typescript source file(s)', - type: 'string' + type: 'string', }) .version(false) .help().argv; +let sourceFile, devsitePath, exclude; +switch (apiVersion) { + case 'v1': + sourceFile = `${repoPath}/src`; + devsitePath = '/docs/reference/functions/'; + exclude = ['"**/v2/**/*.ts"', '"src/index.ts"']; + break; + case 'v2': + sourceFile = `${repoPath}/src/{v2,logger}`; + devsitePath = '/docs/functions/alpha/'; + exclude = []; + break; + default: + throw new Error( + `Unrecognized version ${apiVersion}, must be one of v1 or v2` + ); +} + const docPath = path.resolve(`${__dirname}/html`); -const contentPath = path.resolve(`${__dirname}/content-sources`); +const contentPath = path.resolve(`${__dirname}/content-sources/${apiVersion}`); const tempHomePath = path.resolve(`${contentPath}/HOME_TEMP.md`); -const devsitePath = `/docs/reference/functions/`; + +const { JSDOM } = require('jsdom'); + +const typeMap = require('./type-aliases.json'); +const { existsSync } = require('fs'); /** * Strips path prefix and returns only filename. @@ -56,6 +77,7 @@ function stripPath(path) { function runTypedoc() { const command = `${repoPath}/node_modules/.bin/typedoc ${sourceFile} \ --out ${docPath} \ + ${exclude.map(ex => "--exclude " + ex).join(" ")} \ --readme ${tempHomePath} \ --options ${__dirname}/typedoc.js \ --theme ${__dirname}/theme`; @@ -68,55 +90,82 @@ function runTypedoc() { * Moves files from subdir to root. * @param {string} subdir Subdir to move files out of. */ -function moveFilesToRoot(subdir) { - return exec(`mv ${docPath}/${subdir}/* ${docPath}`) - .then(() => { - exec(`rmdir ${docPath}/${subdir}`); - }) - .catch(e => console.error(e)); +async function moveFilesToRoot(subdir) { + if (existsSync(`${docPath}/${subdir}`)) { + await exec(`mv ${docPath}/${subdir}/* ${docPath}`); + await exec(`rmdir ${docPath}/${subdir}`); + } } /** * Renames files to remove the leading underscores. * We need to do this because devsite hides these files. - * Example: + * Example: * _cloud_functions_.resource.html => cloud_functions_.resource.html */ -function renameFiles() { - return fs.readdir(docPath).then(files => { - console.log(files); - files.forEach(file => { - let newFileName = file; - if (_.startsWith(file, "_") && _.endsWith(file, "html")) { - newFileName = _.trimStart(file, "_"); - fs.rename(`${docPath}/${file}`, `${docPath}/${newFileName}`, (err) => { - if (err) console.log(err) - }); - } - }) - }) +async function renameFiles() { + const files = await fs.readdir(docPath); + const renames = []; + for (const file of files) { + if (file.startsWith('_') && file.endsWith('html')) { + let newFileName = file.substring(1); + renames.push( + fs.rename(`${docPath}/${file}`, `${docPath}/${newFileName}`) + ); + } + } + await Promise.all(renames); } /** * Reformat links to match flat structure. * @param {string} file File to fix links in. */ -function fixLinks(file) { - return fs.readFile(file, 'utf8').then(data => { - const flattenedLinks = data - .replace(/\.\.\//g, '') - .replace(/(modules|interfaces|classes)\//g, '') - .replace(/\"_/g, '"'); - let caseFixedLinks = flattenedLinks; - for (const lower in lowerToUpperLookup) { - const re = new RegExp(lower, 'g'); - caseFixedLinks = caseFixedLinks.replace(re, lowerToUpperLookup[lower]); - } - return fs.writeFile(file, caseFixedLinks); - }); +async function fixLinks(file) { + let data = await fs.readFile(file, 'utf8'); + data = addTypeAliasLinks(data); + const flattenedLinks = data + .replace(/\.\.\//g, '') + .replace(/(modules|interfaces|classes)\//g, '') + .replace(/\"_/g, '"'); + let caseFixedLinks = flattenedLinks; + for (const lower in lowerToUpperLookup) { + const re = new RegExp(lower, 'g'); + caseFixedLinks = caseFixedLinks.replace(re, lowerToUpperLookup[lower]); + } + return fs.writeFile(file, caseFixedLinks); } -let tocText = ''; +/** + * Adds links to external documentation for type aliases that + * reference an external library. + * + * @param data File data to add external library links to. + */ +function addTypeAliasLinks(data) { + const htmlDom = new JSDOM(data); + /** + * Select .tsd-signature-type because all potential external + * links will have this identifier. + */ + const fileTags = htmlDom.window.document.querySelectorAll( + '.tsd-signature-type' + ); + for (const tag of fileTags) { + const mapping = typeMap[tag.textContent]; + if (mapping) { + console.log('Adding link to ' + tag.textContent + ' documentation.'); + + // Add the corresponding document link to this type + const linkChild = htmlDom.window.document.createElement('a'); + linkChild.setAttribute('href', mapping); + linkChild.textContent = tag.textContent; + tag.textContent = null; + tag.appendChild(linkChild); + } + } + return htmlDom.serialize(); +} /** * Generates temporary markdown file that will be sourced by Typedoc to @@ -128,13 +177,13 @@ let tocText = ''; function generateTempHomeMdFile(tocRaw, homeRaw) { const { toc } = yaml.safeLoad(tocRaw); let tocPageLines = [homeRaw, '# API Reference']; - toc.forEach(group => { + for (const group of toc) { tocPageLines.push(`\n## [${group.title}](${stripPath(group.path)})`); const section = group.section || []; - section.forEach(item => { + for (const item of section) { tocPageLines.push(`- [${item.title}](${stripPath(item.path)})`); - }); - }); + } + } return fs.writeFile(tempHomePath, tocPageLines.join('\n')); } @@ -148,37 +197,36 @@ const lowerToUpperLookup = {}; * Checks to see if any files listed in toc.yaml were not generated. * If files exist, fixes filename case to match toc.yaml version. */ -function checkForMissingFilesAndFixFilenameCase() { +async function checkForMissingFilesAndFixFilenameCase(tocText) { // Get filenames from toc.yaml. const filenames = tocText .split('\n') - .filter(line => line.includes('path:')) - .map(line => line.split(devsitePath)[1]); + .filter((line) => line.includes('path:')) + .map((line) => { + parts = line.split('/'); + return parts[parts.length - 1].replace(/#.*$/, ''); + }); // Logs warning to console if a file from TOC is not found. - // console.log(filenames); - const fileCheckPromises = filenames.map(filename => { + const fileCheckPromises = filenames.map(async (filename) => { // Warns if file does not exist, fixes filename case if it does. // Preferred filename for devsite should be capitalized and taken from // toc.yaml. const tocFilePath = `${docPath}/${filename}`; // Generated filename from Typedoc will be lowercase. const generatedFilePath = `${docPath}/${filename.toLowerCase()}`; - return fs.exists(generatedFilePath).then(exists => { - if (exists) { - // Store in a lookup table for link fixing. - lowerToUpperLookup[ - `${filename.toLowerCase()}` - ] = `${filename}`; - return fs.rename(generatedFilePath, tocFilePath); - } else { - console.warn( - `Missing file: ${filename} requested ` + - `in toc.yaml but not found in ${docPath}` - ); - } - }); + if (await fs.exists(generatedFilePath)) { + // Store in a lookup table for link fixing. + lowerToUpperLookup[filename.toLowerCase()] = filename; + return fs.rename(generatedFilePath, tocFilePath); + } else { + console.warn( + `Missing file: ${filename} requested ` + + `in toc.yaml but not found in ${docPath}` + ); + } }); - return Promise.all(fileCheckPromises).then(() => filenames); + await Promise.all(fileCheckPromises); + return filenames; } /** @@ -189,40 +237,30 @@ function checkForMissingFilesAndFixFilenameCase() { * @param {Array} filenamesFromToc Filenames pulled from toc.yaml * @param {boolean} shouldRemove Should just remove the file */ -function checkForUnlistedFiles(filenamesFromToc, shouldRemove) { - return fs.readdir(docPath).then(files => { - const htmlFiles = files - .filter(filename => filename.slice(-4) === 'html'); - const removePromises = []; - htmlFiles.forEach(filename => { - if ( - !filenamesFromToc.includes(filename) && - filename !== 'index' && - filename !== 'globals' - ) { - if (shouldRemove) { - console.log( - `REMOVING ${docPath}/${filename} - not listed in toc.yaml.` - ); - removePromises.push(fs.unlink(`${docPath}/${filename}`)); - } else { - // This is just a warning, it doesn't need to finish before - // the process continues. - console.warn( - `Unlisted file: ${filename} generated ` + - `but not listed in toc.yaml.` - ); - } - } - }); - if (shouldRemove) { - return Promise.all(removePromises).then(() => - htmlFiles.filter(filename => filenamesFromToc.includes(filename)) - ); - } else { - return htmlFiles; - } - }); +async function checkForUnlistedFiles(filenamesFromToc, shouldRemove) { + const files = await fs.readdir(docPath); + const htmlFiles = files.filter((filename) => filename.slice(-4) === 'html'); + const removePromises = []; + const filesToRemove = htmlFiles + .filter((filename) => !filenamesFromToc.includes(filename)) + .filter((filename) => filename !== 'index' && filename != 'globals'); + if (filesToRemove.length && !shouldRemove) { + // This is just a warning, it doesn't need to finish before + // the process continues. + console.warn( + `Unlisted files: ${filesToRemove.join(', ')} generated ` + + `but not listed in toc.yaml.` + ); + return htmlFiles; + } + + await Promise.all( + filesToRemove.map((filename) => { + console.log(`REMOVING ${docPath}/${filename} - not listed in toc.yaml.`); + return fs.unlink(`${docPath}/${filename})`); + }) + ); + return htmlFiles.filter((filename) => filenamesFromToc.includes(filename)); } /** @@ -231,17 +269,16 @@ function checkForUnlistedFiles(filenamesFromToc, shouldRemove) { * * @param {Array} htmlFiles List of html files found in generated dir. */ -function writeGeneratedFileList(htmlFiles) { - const fileList = htmlFiles.map(filename => { +async function writeGeneratedFileList(htmlFiles) { + const fileList = htmlFiles.map((filename) => { return { title: filename, - path: `${devsitePath}${filename}` + path: `${devsitePath}${filename}`, }; }); const generatedTocYAML = yaml.safeDump({ toc: fileList }); - return fs - .writeFile(`${docPath}/_toc_autogenerated.yaml`, generatedTocYAML) - .then(() => htmlFiles); + await fs.writeFile(`${docPath}/_toc_autogenerated.yaml`, generatedTocYAML); + return htmlFiles; } /** @@ -252,10 +289,10 @@ function writeGeneratedFileList(htmlFiles) { */ function fixAllLinks(htmlFiles) { const writePromises = []; - htmlFiles.forEach(file => { + for (const file of htmlFiles) { // Update links in each html file to match flattened file structure. writePromises.push(fixLinks(`${docPath}/${file}`)); - }); + } return Promise.all(writePromises); } @@ -271,69 +308,76 @@ function fixAllLinks(htmlFiles) { * links as needed. * 5) Check for mismatches between TOC list and generated file list. */ -Promise.all([ - fs.readFile(`${contentPath}/toc.yaml`, 'utf8'), - fs.readFile(`${contentPath}/HOME.md`, 'utf8') -]) - // Read TOC and homepage text and assemble a homepage markdown file. - // This file will be sourced by Typedoc to generate index.html. - .then(([tocRaw, homeRaw]) => { - tocText = tocRaw; - return generateTempHomeMdFile(tocRaw, homeRaw); - }) - // Run main Typedoc process (uses index.d.ts and generated temp file above). - .then(runTypedoc) - .then(output => { +(async function () { + try { + const [tocRaw, homeRaw] = await Promise.all([ + fs.readFile(`${contentPath}/toc.yaml`, 'utf8'), + fs.readFile(`${contentPath}/HOME.md`, 'utf8'), + ]); + + // Run main Typedoc process (uses index.d.ts and generated temp file above). + await generateTempHomeMdFile(tocRaw, homeRaw); + const output = await runTypedoc(); + // Typedoc output. console.log(output.stdout); - // Clean up temp home markdown file. (Nothing needs to wait for this.) - fs.unlink(tempHomePath); - // Devsite doesn't like css.map files. - return fs.unlink(`${docPath}/assets/css/main.css.map`); - }) - // Write out TOC file. Do this after Typedoc step to prevent Typedoc - // erroring when it finds an unexpected file in the target dir. - .then(() => fs.writeFile(`${docPath}/_toc.yaml`, tocText)) - // Flatten file structure. These categories don't matter to us and it makes - // it easier to manage the docs directory. - .then(() => { - return Promise.all([ + await Promise.all([ + // Clean up temp home markdown file. (Nothing needs to wait for this.) + fs.unlink(tempHomePath), + + // Devsite doesn't like css.map files. + // NOTE: This doesn't seem to actually get generated anymore, but we'll keep this here just in case. + async () => { + const cssMap = `${docPath}/assets/css/main.css.map`; + if (await fs.exists(cssMap)) { + await fs.unlink(); + } + }, + + // Write out TOC file. Do this after Typedoc step to prevent Typedoc + // erroring when it finds an unexpected file in the target dir. + fs.writeFile(`${docPath}/_toc.yaml`, tocRaw), + ]); + + // Flatten file structure. These categories don't matter to us and it makes + // it easier to manage the docs directory. + await Promise.all([ moveFilesToRoot('classes'), moveFilesToRoot('modules'), moveFilesToRoot('interfaces'), ]); - }) - // Rename files to remove the underscores since devsite hides those. - .then(renameFiles) - // Check for files listed in TOC that are missing and warn if so. - // Not blocking. - .then(checkForMissingFilesAndFixFilenameCase) - // Check for files that exist but aren't listed in the TOC and warn. - // (If API is node, actually remove the file.) - // Removal is blocking, warnings aren't. - .then(filenamesFromToc => - checkForUnlistedFiles(filenamesFromToc, false) - ) - // Write a _toc_autogenerated.yaml to record what files were created. - .then(htmlFiles => writeGeneratedFileList(htmlFiles)) - // Correct the links in all the generated html files now that files have - // all been moved to top level. - // .then(removeUnderscores) - .then(fixAllLinks) - .then(() => { - fs.readFile(`${docPath}/index.html`, 'utf8').then(data => { - // String to include devsite local variables. - const localVariablesIncludeString = `{% include "docs/web/_local_variables.html" %}\n`; - return fs.writeFile( - `${docPath}/index.html`, - localVariablesIncludeString + data - ); - }); - }) - .catch(e => { - if (e.stdout) { - console.error(e.stdout); + // Rename files to remove the underscores since devsite hides those. + await renameFiles(); + + // Check for files listed in TOC that are missing and warn if so. + // Not blocking. + const filenamesFromToc = await checkForMissingFilesAndFixFilenameCase( + tocRaw + ); + + // Check for files that exist but aren't listed in the TOC and warn. + // (If API is node, actually remove the file.) + // Removal is blocking, warnings aren't. + const htmlFiles = await checkForUnlistedFiles(filenamesFromToc, false); + + // Write a _toc_autogenerated.yaml to record what files were created. + const fileList = await writeGeneratedFileList(htmlFiles); + + // Correct the links in all the generated html files now that files have + // all been moved to top level. + await fixAllLinks(fileList); + const data = await fs.readFile(`${docPath}/index.html`, 'utf8'); + // String to include devsite local variables. + const localVariablesIncludeString = `{% include "docs/web/_local_variables.html" %}\n`; + await fs.writeFile( + `${docPath}/index.html`, + localVariablesIncludeString + data + ); + } catch (err) { + if (err.stdout) { + console.error(err.stdout); } else { - console.error(e); + console.error(err); } - }); + } +})(); diff --git a/docgen/theme/helpers/cleanBreadcrumb.js b/docgen/theme/helpers/cleanBreadcrumb.js new file mode 100644 index 000000000..ad52e64a7 --- /dev/null +++ b/docgen/theme/helpers/cleanBreadcrumb.js @@ -0,0 +1,4 @@ +exports.cleanBreadcrumb = function (value) { + const parts = value.replace(/"/g, '').split('/'); + return parts[parts.length - 1]; +}; diff --git a/docgen/theme/layouts/default.hbs b/docgen/theme/layouts/default.hbs index 72111fb4e..17106e8d8 100644 --- a/docgen/theme/layouts/default.hbs +++ b/docgen/theme/layouts/default.hbs @@ -7,6 +7,8 @@ + + {{#ifCond model.name '==' project.name}}{{project.name}}{{else}}{{model.name}} | {{project.name}}{{/ifCond}} diff --git a/docgen/theme/partials/breadcrumb.hbs b/docgen/theme/partials/breadcrumb.hbs index db115163f..6a2147724 100644 --- a/docgen/theme/partials/breadcrumb.hbs +++ b/docgen/theme/partials/breadcrumb.hbs @@ -3,7 +3,7 @@ {{#with parent}}{{> breadcrumb}}{{/with}}