├── .eslintignore ├── .eslintrc.js ├── .github ├── CODEOWNERS ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── ---report-a-bug.md │ └── config.yml ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── docs.yaml │ ├── postmerge.yaml │ └── test.yaml ├── .gitignore ├── .mocharc.yaml ├── .prettierignore ├── .prettierrc.js ├── CHANGELOG.md ├── LICENSE ├── README.md ├── deploy_key.enc ├── docgen ├── api-extractor.base.json ├── api-extractor.v1.json ├── api-extractor.v2.json ├── content-sources │ ├── v1 │ │ └── toc.yaml │ └── v2 │ │ └── toc.yaml ├── theme │ └── helpers │ │ └── cleanBreadcrumb.js └── toc.ts ├── integration_test ├── README.md ├── database.rules.json ├── firebase.json ├── firestore.indexes.json ├── firestore.rules ├── functions │ ├── .npmrc │ ├── src │ │ ├── index.ts │ │ ├── region.ts │ │ ├── testing.ts │ │ ├── v1 │ │ │ ├── auth-tests.ts │ │ │ ├── database-tests.ts │ │ │ ├── firestore-tests.ts │ │ │ ├── https-tests.ts │ │ │ ├── index.ts │ │ │ ├── pubsub-tests.ts │ │ │ ├── remoteConfig-tests.ts │ │ │ ├── storage-tests.ts │ │ │ ├── testLab-tests.ts │ │ │ └── testLab-utils.ts │ │ └── v2 │ │ │ ├── https-tests.ts │ │ │ ├── index.ts │ │ │ └── scheduled-tests.ts │ └── tsconfig.json ├── package.json.template └── run_tests.sh ├── logger ├── compat.js └── index.js ├── mocha └── setup.ts ├── package-lock.json ├── package.json ├── protos ├── README.md ├── compiledFirestore.d.ts ├── compiledFirestore.js └── update.sh ├── scripts ├── bin-test │ ├── extsdks │ │ ├── local │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ └── package.json │ │ └── translate │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ └── package.json │ ├── mocha-setup.ts │ ├── run.sh │ ├── sources │ │ ├── commonjs-grouped │ │ │ ├── g1.js │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── commonjs-main │ │ │ ├── functions.js │ │ │ └── package.json │ │ ├── commonjs-preserve │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── commonjs │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── esm-ext │ │ │ ├── index.mjs │ │ │ └── package.json │ │ ├── esm-main │ │ │ ├── functions.js │ │ │ └── package.json │ │ ├── esm-top-level-await │ │ │ ├── exports.js │ │ │ ├── index.js │ │ │ └── package.json │ │ └── esm │ │ │ ├── index.js │ │ │ └── package.json │ └── test.ts ├── fetch-regions ├── publish-container │ ├── Dockerfile │ └── cloudbuild.yaml ├── publish.sh ├── publish │ ├── cloudbuild.yaml │ ├── deploy_key.enc │ ├── hub.enc │ ├── npmrc.enc │ └── twitter.json.enc └── tweet.js ├── spec ├── common │ ├── change.spec.ts │ ├── config.spec.ts │ ├── encoding.spec.ts │ ├── metaprogramming.ts │ ├── options.ts │ ├── params.spec.ts │ ├── providers │ │ ├── https.spec.ts │ │ ├── identity.spec.ts │ │ └── tasks.spec.ts │ ├── trace.spec.ts │ └── utilities │ │ ├── path-pattern.spec.ts │ │ └── path.spec.ts ├── fixtures.ts ├── fixtures │ ├── credential │ │ ├── jwk.json │ │ ├── key.d.ts │ │ ├── key.json │ │ └── unparsable.key.json │ ├── env │ │ └── env.json │ ├── extsdk │ │ ├── local │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ └── package.json │ │ └── translate │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ └── package.json │ ├── http.ts │ ├── mockrequest.ts │ └── sources │ │ ├── commonjs-grouped │ │ ├── g1.js │ │ ├── index.js │ │ └── package.json │ │ ├── commonjs-main │ │ ├── functions.js │ │ └── package.json │ │ ├── commonjs-parametrized-fields │ │ ├── index.js │ │ └── package.json │ │ ├── commonjs-params │ │ ├── index.js │ │ └── package.json │ │ └── commonjs │ │ ├── index.js │ │ └── package.json ├── helper.ts ├── logger.spec.ts ├── params │ └── params.spec.ts ├── runtime │ ├── loader.spec.ts │ └── manifest.spec.ts ├── tslint.json ├── v1 │ ├── cloud-functions.spec.ts │ ├── config.spec.ts │ ├── function-builder.spec.ts │ ├── providers │ │ ├── analytics.spec.input.ts │ │ ├── analytics.spec.ts │ │ ├── auth.spec.ts │ │ ├── database.spec.ts │ │ ├── firestore.spec.ts │ │ ├── fixtures.ts │ │ ├── https.spec.ts │ │ ├── pubsub.spec.ts │ │ ├── remoteConfig.spec.ts │ │ ├── storage.spec.ts │ │ ├── tasks.spec.ts │ │ └── testLab.spec.ts │ └── utils.spec.ts └── v2 │ ├── params.spec.ts │ └── providers │ ├── alerts │ ├── alerts.spec.ts │ ├── appDistribution.spec.ts │ ├── billing.spec.ts │ ├── crashlytics.spec.ts │ └── performance.spec.ts │ ├── database.spec.ts │ ├── eventarc.spec.ts │ ├── firestore.spec.ts │ ├── fixtures.ts │ ├── https.spec.ts │ ├── identity.spec.ts │ ├── pubsub.spec.ts │ ├── remoteConfig.spec.ts │ ├── scheduler.spec.ts │ ├── storage.spec.ts │ ├── tasks.spec.ts │ └── testLab.spec.ts ├── src ├── bin │ └── firebase-functions.ts ├── common │ ├── app.ts │ ├── change.ts │ ├── config.ts │ ├── debug.ts │ ├── encoding.ts │ ├── onInit.ts │ ├── options.ts │ ├── params.ts │ ├── providers │ │ ├── database.ts │ │ ├── firestore.ts │ │ ├── https.ts │ │ ├── identity.ts │ │ └── tasks.ts │ ├── timezone.ts │ ├── trace.ts │ └── utilities │ │ ├── assertions.ts │ │ ├── encoder.ts │ │ ├── path-pattern.ts │ │ ├── path.ts │ │ └── utils.ts ├── function-configuration.ts ├── logger │ ├── common.ts │ ├── compat.ts │ └── index.ts ├── params │ ├── index.ts │ └── types.ts ├── runtime │ ├── loader.ts │ └── manifest.ts ├── types │ └── global.d.ts ├── v1 │ ├── cloud-functions.ts │ ├── config.ts │ ├── function-builder.ts │ ├── function-configuration.ts │ ├── index.ts │ └── providers │ │ ├── analytics.ts │ │ ├── auth.ts │ │ ├── database.ts │ │ ├── firestore.ts │ │ ├── https.ts │ │ ├── pubsub.ts │ │ ├── remoteConfig.ts │ │ ├── storage.ts │ │ ├── tasks.ts │ │ └── testLab.ts └── v2 │ ├── core.ts │ ├── index.ts │ ├── options.ts │ ├── providers │ ├── alerts │ │ ├── alerts.ts │ │ ├── appDistribution.ts │ │ ├── billing.ts │ │ ├── crashlytics.ts │ │ ├── index.ts │ │ └── performance.ts │ ├── database.ts │ ├── eventarc.ts │ ├── firestore.ts │ ├── https.ts │ ├── identity.ts │ ├── pubsub.ts │ ├── remoteConfig.ts │ ├── scheduler.ts │ ├── storage.ts │ ├── tasks.ts │ └── testLab.ts │ └── trace.ts ├── tsconfig.json ├── tsconfig.release.json ├── tslint.json ├── v1 ├── analytics.js ├── auth.js ├── database.js ├── firestore.js ├── index.js ├── pubsub.js ├── remoteConfig.js ├── storage.js ├── tasks.js └── testLab.js └── v2 ├── alerts ├── appDistribution.js ├── billing.js ├── crashlytics.js ├── index.js └── performance.js ├── core.js ├── database.js ├── eventarc.js ├── firestore.js ├── https.js ├── identity.js ├── index.js ├── options.js ├── params.js ├── pubsub.js ├── remoteConfig.js ├── scheduler.js ├── storage.js ├── tasks.js └── testLab.js /.eslintignore: -------------------------------------------------------------------------------- 1 | lib 2 | dev 3 | node_modules 4 | /coverage/ 5 | /docgen/ 6 | /v1/ 7 | /v2/ 8 | /logger/ 9 | /dist/ 10 | /spec/fixtures 11 | /scripts/**/*.js 12 | /protos/ 13 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | es6: true, 4 | node: true, 5 | }, 6 | extends: [ 7 | "eslint:recommended", 8 | "plugin:@typescript-eslint/recommended", 9 | "plugin:@typescript-eslint/recommended-requiring-type-checking", 10 | "plugin:jsdoc/recommended", 11 | "google", 12 | "prettier", 13 | ], 14 | rules: { 15 | "jsdoc/newline-after-description": "off", 16 | "jsdoc/require-jsdoc": ["warn", { publicOnly: true }], 17 | "no-restricted-globals": ["error", "name", "length"], 18 | "prefer-arrow-callback": "error", 19 | "prettier/prettier": "error", 20 | "require-atomic-updates": "off", // This rule is so noisy and isn't useful: https://github.com/eslint/eslint/issues/11899 21 | "require-jsdoc": "off", // This rule is deprecated and superseded by jsdoc/require-jsdoc. 22 | "valid-jsdoc": "off", // This is deprecated but included in recommended configs. 23 | 24 | "no-prototype-builtins": "warn", 25 | "no-useless-escape": "warn", 26 | "prefer-promise-reject-errors": "warn", 27 | }, 28 | overrides: [ 29 | { 30 | files: ["*.ts"], 31 | rules: { 32 | "jsdoc/require-param-type": "off", 33 | "jsdoc/require-returns-type": "off", 34 | 35 | // Google style guide allows us to omit trivial parameters and returns 36 | "jsdoc/require-param": "off", 37 | "jsdoc/require-returns": "off", 38 | 39 | "@typescript-eslint/no-invalid-this": "error", 40 | "@typescript-eslint/no-unused-vars": "error", // Unused vars should not exist. 41 | "@typescript-eslint/no-misused-promises": "warn", // rule does not work with async handlers for express. 42 | "no-invalid-this": "off", // Turned off in favor of @typescript-eslint/no-invalid-this. 43 | "no-unused-vars": "off", // Off in favor of @typescript-eslint/no-unused-vars. 44 | eqeqeq: ["error", "always", { null: "ignore" }], 45 | camelcase: ["error", { properties: "never" }], // snake_case allowed in properties iif to satisfy an external contract / style 46 | 47 | // Ideally, all these warning should be error - let's fix them in the future. 48 | "@typescript-eslint/no-unsafe-argument": "warn", 49 | "@typescript-eslint/no-unsafe-assignment": "warn", 50 | "@typescript-eslint/no-unsafe-call": "warn", 51 | "@typescript-eslint/no-unsafe-member-access": "warn", 52 | "@typescript-eslint/no-unsafe-return": "warn", 53 | "@typescript-eslint/restrict-template-expressions": "warn", 54 | }, 55 | }, 56 | { 57 | files: ["*.spec.*"], 58 | env: { 59 | mocha: true, 60 | }, 61 | rules: {}, 62 | }, 63 | ], 64 | globals: {}, 65 | parserOptions: { 66 | project: "tsconfig.json", 67 | }, 68 | plugins: ["prettier", "@typescript-eslint", "jsdoc"], 69 | parser: "@typescript-eslint/parser", 70 | }; 71 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution, 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult [GitHub Help] for more 22 | information on using pull requests. 23 | 24 | [github help]: https://help.github.com/articles/about-pull-requests/ 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/---report-a-bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "⚠️ Report a Bug" 3 | 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. 4 | title: "" 5 | labels: "" 6 | assignees: "" 7 | --- 8 | 9 | 13 | 14 | ### Related issues 15 | 16 | 17 | 18 | ### [REQUIRED] Version info 19 | 20 | 22 | 23 | **node:** 24 | 25 | 26 | 27 | **firebase-functions:** 28 | 29 | **firebase-tools:** 30 | 31 | 32 | 33 | **firebase-admin:** 34 | 35 | ### [REQUIRED] Test case 36 | 37 | 38 | 39 | ### [REQUIRED] Steps to reproduce 40 | 41 | 42 | 43 | ### [REQUIRED] Expected behavior 44 | 45 | 46 | 47 | ### [REQUIRED] Actual behavior 48 | 49 | 51 | 52 | ### Were you able to successfully deploy your functions? 53 | 54 | 55 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: 💻 Bug in the Firebase CLI 4 | url: https://github.com/firebase/firebase-tools/issues/new/choose 5 | about: Have you found a bug in the Firebase CLI? 6 | - name: 🔥 Firebase Support 7 | url: https://firebase.google.com/support/ 8 | about: If you have an issue with your functions in production, please contact support. 9 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 22 | 23 | ### Description 24 | 25 | 27 | 28 | ### Code sample 29 | 30 | 31 | -------------------------------------------------------------------------------- /.github/workflows/docs.yaml: -------------------------------------------------------------------------------- 1 | name: Docgen 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | docs: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: actions/setup-node@v4 14 | with: 15 | node-version: "20" 16 | - name: Cache npm 17 | uses: actions/cache@v4 18 | with: 19 | path: ~/.npm 20 | key: ${{ runner.os }}-docgen-${{ hashFiles('**/package-lock.json') }} 21 | - name: Install dependencies 22 | run: npm ci 23 | - name: Generate Reference Docs 24 | run: | 25 | npm run docgen:v1 26 | npm run docgen:v2 27 | - uses: actions/upload-artifact@v4 28 | name: Upload Docs Preview 29 | with: 30 | name: reference-docs 31 | path: | 32 | ./docgen/v1/markdown/ 33 | ./docgen/v2/markdown/ 34 | -------------------------------------------------------------------------------- /.github/workflows/postmerge.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | name: Post-merge tests 15 | 16 | on: 17 | workflow_dispatch: 18 | 19 | concurrency: 20 | group: postmerge-${{ github.ref }} 21 | cancel-in-progress: true 22 | 23 | env: 24 | CI: true 25 | 26 | jobs: 27 | postmerge: 28 | runs-on: ubuntu-latest 29 | steps: 30 | - uses: actions/checkout@v3 31 | - uses: actions/setup-node@v3 32 | with: 33 | node-version: 18 34 | 35 | - uses: google-github-actions/auth@v0 36 | with: 37 | credentials_json: "${{ secrets.CF3_INTEGRATION_TEST_GOOGLE_CREDENTIALS }}" 38 | create_credentials_file: true 39 | 40 | - name: "Set up Cloud SDK" 41 | uses: google-github-actions/setup-gcloud@v0 42 | 43 | - name: "Setup Firebase CLI" 44 | run: npm i -g firebase-tools 45 | 46 | - name: "Run integration test" 47 | run: npm run test:postmerge 48 | 49 | - name: Print debug logs 50 | if: failure() 51 | run: find . -type f -name "*debug.log" | xargs cat 52 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: CI Tests 2 | 3 | on: 4 | - pull_request 5 | - push 6 | 7 | env: 8 | CI: true 9 | 10 | jobs: 11 | lint: 12 | runs-on: ubuntu-latest 13 | if: github.event_name == 'pull_request' 14 | strategy: 15 | matrix: 16 | node-version: 17 | - 18.x 18 | steps: 19 | - uses: actions/checkout@v3 20 | with: 21 | fetch-depth: 0 22 | - uses: actions/setup-node@v3 23 | with: 24 | node-version: ${{ matrix.node-version }} 25 | cache: npm 26 | - run: npm ci 27 | - run: npm run lint 28 | unit: 29 | runs-on: ubuntu-latest 30 | strategy: 31 | matrix: 32 | node-version: 33 | - 18.x 34 | - 20.x 35 | - 22.x 36 | steps: 37 | - uses: actions/checkout@v1 38 | - uses: actions/setup-node@v1 39 | with: 40 | node-version: ${{ matrix.node-version }} 41 | - name: Cache npm 42 | uses: actions/cache@v4 43 | with: 44 | path: ~/.npm 45 | key: ${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }} 46 | - run: npm ci 47 | - run: npm run test 48 | integration: 49 | needs: "unit" 50 | runs-on: ubuntu-latest 51 | strategy: 52 | matrix: 53 | node-version: 54 | - 18.x 55 | - 20.x 56 | - 22.x 57 | steps: 58 | - uses: actions/checkout@v1 59 | - uses: actions/setup-node@v1 60 | with: 61 | node-version: ${{ matrix.node-version }} 62 | - name: Cache npm 63 | uses: actions/cache@v4 64 | with: 65 | path: ~/.npm 66 | key: ${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }} 67 | - run: npm ci 68 | - run: npm run test:bin 69 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .npm 3 | .tmp 4 | .vscode/ 5 | coverage 6 | dist/ 7 | docgen/html 8 | docgen/*/temp 9 | docgen/*/markdown 10 | docgen/*/*.json 11 | docgen/*/*.md 12 | firebase-functions-*.tgz 13 | integration_test/.firebaserc 14 | integration_test/*.log 15 | integration_test/functions/firebase-functions.tgz 16 | integration_test/functions/package.json 17 | lib 18 | node_modules 19 | npm-debug.log 20 | typings 21 | yarn.lock 22 | .DS_Store 23 | -------------------------------------------------------------------------------- /.mocharc.yaml: -------------------------------------------------------------------------------- 1 | exit: true 2 | extension: 3 | - ts 4 | package: ./package.json 5 | reporter: spec 6 | require: 7 | - "ts-node/register" 8 | - "source-map-support/register" 9 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /lib/**/* 3 | /CONTRIBUTING.md 4 | /docgen -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 100, 3 | }; -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | - Add @deprecated annotation to callable functions's auth policy (#1675) 2 | - Allows CORS to be a parameter. (#1688) 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Firebase 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Firebase SDK for Cloud Functions 2 | 3 | The `firebase-functions` package provides an SDK for defining Cloud Functions for Firebase. 4 | 5 | Cloud Functions is a hosted, private, and scalable Node.js environment where you can run JavaScript code. The Firebase SDK for Cloud Functions integrates the Firebase platform by letting you write code that responds to events and invokes functionality exposed by other Firebase features. 6 | 7 | ## Learn more 8 | 9 | Learn more about the Firebase SDK for Cloud Functions in the [Firebase documentation](https://firebase.google.com/docs/functions/) or [check out our samples](https://github.com/firebase/functions-samples). 10 | 11 | Here are some resources to get help: 12 | 13 | - Start with the quickstart: https://firebase.google.com/docs/functions/write-firebase-functions 14 | - Go through the guide: https://firebase.google.com/docs/functions/ 15 | - Read the full API reference: https://firebase.google.com/docs/reference/functions/ 16 | - Browse some examples: https://github.com/firebase/functions-samples 17 | 18 | If the official documentation doesn't help, try asking through our official support channels: https://firebase.google.com/support/ 19 | 20 | _Please avoid double posting across multiple channels!_ 21 | 22 | ## Usage 23 | 24 | ```js 25 | // functions/index.js 26 | const { onValueCreated } = require("firebase-functions/database"); 27 | const logger = require("firebase-functions/logger"); 28 | const notifyUsers = require("./notify-users"); 29 | 30 | exports.newPost = onValueCreated({ ref: "/posts/{postId}" }, (event) => { 31 | logger.info("Received new post with ID:", event.params.postId); 32 | return notifyUsers(event.data.val()); 33 | }); 34 | ``` 35 | 36 | ## Contributing 37 | 38 | To contribute a change, [check out the contributing guide](.github/CONTRIBUTING.md). 39 | 40 | ## License 41 | 42 | © Google, 2017. Licensed under [The MIT License](LICENSE). 43 | -------------------------------------------------------------------------------- /deploy_key.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebase/firebase-functions/849f01cd00e24ac1bf61fd634f0927aa70535892/deploy_key.enc -------------------------------------------------------------------------------- /docgen/api-extractor.v1.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", 3 | "extends": "./api-extractor.base.json", 4 | "mainEntryPointFilePath": "/lib/v1/index.d.ts", 5 | "docModel": { 6 | "enabled": true, 7 | "apiJsonFilePath": "/docgen/v1/firebase-functions.api.json" 8 | }, 9 | "apiReport": { 10 | "enabled": true, 11 | "reportTempFolder": "/docgen/v1/temp", 12 | "reportFolder": "/docgen/v1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docgen/api-extractor.v2.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", 3 | "extends": "./api-extractor.base.json", 4 | "mainEntryPointFilePath": "/lib/v2/index.d.ts", 5 | "docModel": { 6 | "enabled": true, 7 | "apiJsonFilePath": "/docgen/v2/firebase-functions.api.json" 8 | }, 9 | "apiReport": { 10 | "enabled": true, 11 | "reportTempFolder": "/docgen/v2/temp", 12 | "reportFolder": "/docgen/v2" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docgen/content-sources/v2/toc.yaml: -------------------------------------------------------------------------------- 1 | toc: 2 | - title: 'functions' 3 | path: /docs/functions/alpha/index.html 4 | - title: 'functions.core' 5 | path: /docs/functions/alpha/v2_core.html 6 | section: 7 | - title: 'Functions v2' 8 | path: /docs/functions/alpha/v2.html 9 | - title: 'functions.CloudEvent' 10 | path: /docs/functions/alpha/v2_core.CloudEvent.html 11 | - title: 'functions.CloudFunction' 12 | path: /docs/functions/alpha/v2_core.CloudFunction.html 13 | - title: 'functions.https' 14 | path: /docs/functions/alpha/v2_providers_https.html 15 | section: 16 | - title: 'functions.https.CallableFunction' 17 | path: /docs/functions/alpha/v2_providers_https.CallableFunction.html 18 | - title: 'functions.https.CallableRequest' 19 | path: /docs/functions/alpha/v2_providers_https.CallableRequest.html 20 | - title: 'functions.https.error' 21 | path: /docs/functions/alpha/v2_providers_https.HttpsError.html 22 | - title: 'functions.https.options' 23 | path: /docs/functions/alpha/v2_providers_https.HttpsOptions.html 24 | - title: 'functions.logger' 25 | path: /docs/functions/alpha/logger.html 26 | section: 27 | - title: 'LogEntry' 28 | path: /docs/functions/alpha/logger.LogEntry.html 29 | - title: 'functions.options' 30 | path: /docs/functions/alpha/v2_options.html 31 | section: 32 | - title: 'functions.options.GlobalOptions' 33 | path: /docs/functions/alpha/v2_options.GlobalOptions.html 34 | - title: 'functions.options.EventHandlerOptions' 35 | path: /docs/functions/alpha/v2_options.EventHandlerOptions.html 36 | - title: 'functions.pubsub' 37 | path: /docs/functions/alpha/v2_providers_pubsub.html 38 | section: 39 | - title: 'Message' 40 | path: /docs/functions/alpha/v2_providers_pubsub.Message.html 41 | - title: 'MessagePublishedData' 42 | path: /docs/functions/alpha/v2_providers_pubsub.MessagePublishedData.html 43 | - title: 'PubSubOptions' 44 | path: /docs/functions/alpha/v2_providers_pubsub.PubSubOptions.html 45 | -------------------------------------------------------------------------------- /docgen/theme/helpers/cleanBreadcrumb.js: -------------------------------------------------------------------------------- 1 | exports.cleanBreadcrumb = function (value) { 2 | const parts = value.replace(/"/g, '').split('/'); 3 | return parts[parts.length - 1]; 4 | }; 5 | -------------------------------------------------------------------------------- /integration_test/README.md: -------------------------------------------------------------------------------- 1 | ## How to Use 2 | 3 | **_ATTENTION_**: Running this test will wipe the contents of the Firebase project(s) you run it against. Make sure you use disposable Firebase project(s)! 4 | 5 | Run the integration test as follows: 6 | 7 | ```bash 8 | ./run_tests.sh [] 9 | ``` 10 | 11 | Test runs cycles of testing, once for Node.js 14 and another for Node.js 16. 12 | 13 | Test uses locally installed firebase to invoke commands for deploying function. The test also requires that you have 14 | gcloud CLI installed and authenticated (`gcloud auth login`). 15 | 16 | Integration test is triggered by invoking HTTP function integrationTest which in turns invokes each function trigger 17 | by issuing actions necessary to trigger it (e.g. write to storage bucket). 18 | 19 | ### Debugging 20 | 21 | The status and result of each test is stored in RTDB of the project used for testing. You can also inspect Cloud Logging 22 | for more clues. 23 | -------------------------------------------------------------------------------- /integration_test/database.rules.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "dbTests": { 4 | "$testId": { 5 | "adminOnly": { 6 | ".validate": false 7 | } 8 | } 9 | }, 10 | ".read": "auth != null", 11 | ".write": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /integration_test/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "database": { 3 | "rules": "database.rules.json" 4 | }, 5 | "firestore": { 6 | "rules": "firestore.rules", 7 | "indexes": "firestore.indexes.json" 8 | }, 9 | "functions": { 10 | "source": "functions", 11 | "codebase": "integration-tests", 12 | "predeploy": ["npm --prefix \"$RESOURCE_DIR\" run build"] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /integration_test/firestore.indexes.json: -------------------------------------------------------------------------------- 1 | { 2 | "indexes": [] 3 | } 4 | -------------------------------------------------------------------------------- /integration_test/firestore.rules: -------------------------------------------------------------------------------- 1 | rules_version = "2"; 2 | 3 | service cloud.firestore { 4 | match /databases/{database}/documents { 5 | match /{document=**} { 6 | allow read, write: if request.auth != null; 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /integration_test/functions/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /integration_test/functions/src/region.ts: -------------------------------------------------------------------------------- 1 | // TODO: Add back support for selecting region for integration test once params is ready. 2 | export const REGION = "us-central1"; 3 | -------------------------------------------------------------------------------- /integration_test/functions/src/v1/auth-tests.ts: -------------------------------------------------------------------------------- 1 | import * as admin from "firebase-admin"; 2 | import * as functions from "firebase-functions"; 3 | import { REGION } from "../region"; 4 | import { expectEq, TestSuite } from "../testing"; 5 | import UserMetadata = admin.auth.UserRecord; 6 | 7 | export const createUserTests: any = functions 8 | .region(REGION) 9 | .auth.user() 10 | .onCreate((u, c) => { 11 | const testId: string = u.displayName; 12 | functions.logger.info(`testId is ${testId}`); 13 | 14 | return new TestSuite("auth user onCreate") 15 | .it("should have a project as resource", (user, context) => 16 | expectEq(context.resource.name, `projects/${process.env.GCLOUD_PROJECT}`) 17 | ) 18 | 19 | .it("should not have a path", (user, context) => expectEq((context as any).path, undefined)) 20 | 21 | .it("should have the correct eventType", (user, context) => 22 | expectEq(context.eventType, "google.firebase.auth.user.create") 23 | ) 24 | 25 | .it("should have an eventId", (user, context) => context.eventId) 26 | 27 | .it("should have a timestamp", (user, context) => context.timestamp) 28 | 29 | .it("should not have auth", (user, context) => expectEq((context as any).auth, undefined)) 30 | 31 | .it("should not have action", (user, context) => expectEq((context as any).action, undefined)) 32 | 33 | .it("should have properly defined meta", (user) => user.metadata) 34 | 35 | .run(testId, u, c); 36 | }); 37 | 38 | export const deleteUserTests: any = functions 39 | .region(REGION) 40 | .auth.user() 41 | .onDelete((u, c) => { 42 | const testId: string = u.displayName; 43 | functions.logger.info(`testId is ${testId}`); 44 | 45 | return new TestSuite("auth user onDelete") 46 | .it("should have a project as resource", (user, context) => 47 | expectEq(context.resource.name, `projects/${process.env.GCLOUD_PROJECT}`) 48 | ) 49 | 50 | .it("should not have a path", (user, context) => expectEq((context as any).path, undefined)) 51 | 52 | .it("should have the correct eventType", (user, context) => 53 | expectEq(context.eventType, "google.firebase.auth.user.delete") 54 | ) 55 | 56 | .it("should have an eventId", (user, context) => context.eventId) 57 | 58 | .it("should have a timestamp", (user, context) => context.timestamp) 59 | 60 | .it("should not have auth", (user, context) => expectEq((context as any).auth, undefined)) 61 | 62 | .it("should not have action", (user, context) => expectEq((context as any).action, undefined)) 63 | 64 | .run(testId, u, c); 65 | }); 66 | -------------------------------------------------------------------------------- /integration_test/functions/src/v1/database-tests.ts: -------------------------------------------------------------------------------- 1 | import * as admin from "firebase-admin"; 2 | import * as functions from "firebase-functions"; 3 | import { REGION } from "../region"; 4 | import { expectEq, expectMatches, TestSuite } from "../testing"; 5 | import DataSnapshot = admin.database.DataSnapshot; 6 | 7 | const testIdFieldName = "testId"; 8 | 9 | export const databaseTests: any = functions 10 | .region(REGION) 11 | .database.ref("dbTests/{testId}/start") 12 | .onWrite((ch, ctx) => { 13 | if (ch.after.val() === null) { 14 | functions.logger.info( 15 | `Event for ${ctx.params[testIdFieldName]} is null; presuming data cleanup, so skipping.` 16 | ); 17 | return; 18 | } 19 | 20 | return new TestSuite>("database ref onWrite") 21 | 22 | .it("should not have event.app", (change, context) => !(context as any).app) 23 | 24 | .it("should give refs access to admin data", (change) => 25 | change.after.ref.parent 26 | .child("adminOnly") 27 | .update({ allowed: 1 }) 28 | .then(() => true) 29 | ) 30 | 31 | .it("should have a correct ref url", (change) => { 32 | const url = change.after.ref.toString(); 33 | return Promise.resolve() 34 | .then(() => { 35 | return expectMatches( 36 | url, 37 | new RegExp( 38 | `^https://${process.env.GCLOUD_PROJECT}(-default-rtdb)*.firebaseio.com/dbTests` 39 | ) 40 | ); 41 | }) 42 | .then(() => { 43 | return expectMatches(url, /\/start$/); 44 | }); 45 | }) 46 | 47 | .it("should have refs resources", (change, context) => 48 | expectMatches( 49 | context.resource.name, 50 | new RegExp( 51 | `^projects/_/instances/${process.env.GCLOUD_PROJECT}(-default-rtdb)*/refs/dbTests/${context.params.testId}/start$` 52 | ) 53 | ) 54 | ) 55 | 56 | .it("should not include path", (change, context) => 57 | expectEq((context as any).path, undefined) 58 | ) 59 | 60 | .it("should have the right eventType", (change, context) => 61 | expectEq(context.eventType, "google.firebase.database.ref.write") 62 | ) 63 | 64 | .it("should have eventId", (change, context) => context.eventId) 65 | 66 | .it("should have timestamp", (change, context) => context.timestamp) 67 | 68 | .it("should not have action", (change, context) => 69 | expectEq((context as any).action, undefined) 70 | ) 71 | 72 | .it("should have admin authType", (change, context) => expectEq(context.authType, "ADMIN")) 73 | 74 | .run(ctx.params[testIdFieldName], ch, ctx); 75 | }); 76 | -------------------------------------------------------------------------------- /integration_test/functions/src/v1/firestore-tests.ts: -------------------------------------------------------------------------------- 1 | import * as admin from "firebase-admin"; 2 | import * as functions from "firebase-functions"; 3 | import { REGION } from "../region"; 4 | import { expectDeepEq, expectEq, TestSuite } from "../testing"; 5 | import DocumentSnapshot = admin.firestore.DocumentSnapshot; 6 | 7 | const testIdFieldName = "documentId"; 8 | 9 | export const firestoreTests: any = functions 10 | .runWith({ 11 | timeoutSeconds: 540, 12 | }) 13 | .region(REGION) 14 | .firestore.document("tests/{documentId}") 15 | .onCreate((s, c) => { 16 | return new TestSuite("firestore document onWrite") 17 | 18 | .it("should not have event.app", (snap, context) => !(context as any).app) 19 | 20 | .it("should give refs write access", (snap) => 21 | snap.ref.set({ allowed: 1 }, { merge: true }).then(() => true) 22 | ) 23 | 24 | .it("should have well-formatted resource", (snap, context) => 25 | expectEq( 26 | context.resource.name, 27 | `projects/${process.env.GCLOUD_PROJECT}/databases/(default)/documents/tests/${context.params.documentId}` 28 | ) 29 | ) 30 | 31 | .it("should have the right eventType", (snap, context) => 32 | expectEq(context.eventType, "google.firestore.document.create") 33 | ) 34 | 35 | .it("should have eventId", (snap, context) => context.eventId) 36 | 37 | .it("should have timestamp", (snap, context) => context.timestamp) 38 | 39 | .it("should have the correct data", (snap, context) => 40 | expectDeepEq(snap.data(), { test: context.params.documentId }) 41 | ) 42 | 43 | .run(c.params[testIdFieldName], s, c); 44 | }); 45 | -------------------------------------------------------------------------------- /integration_test/functions/src/v1/https-tests.ts: -------------------------------------------------------------------------------- 1 | import * as functions from "firebase-functions"; 2 | import { REGION } from "../region"; 3 | import { expectEq, TestSuite } from "../testing"; 4 | 5 | export const callableTests: any = functions 6 | .runWith({ invoker: "private" }) 7 | .region(REGION) 8 | .https.onCall((d) => { 9 | return new TestSuite("https onCall") 10 | .it("should have the correct data", (data: any) => expectEq(data?.foo, "bar")) 11 | .run(d.testId, d); 12 | }); 13 | -------------------------------------------------------------------------------- /integration_test/functions/src/v1/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./pubsub-tests"; 2 | export * from "./database-tests"; 3 | export * from "./auth-tests"; 4 | export * from "./firestore-tests"; 5 | // Temporarily disable http test - will not work unless running on projects w/ permission to create public functions. 6 | // export * from "./https-tests"; 7 | export * from "./remoteConfig-tests"; 8 | export * from "./storage-tests"; 9 | export * from "./testLab-tests"; 10 | -------------------------------------------------------------------------------- /integration_test/functions/src/v1/pubsub-tests.ts: -------------------------------------------------------------------------------- 1 | import * as admin from "firebase-admin"; 2 | import * as functions from "firebase-functions"; 3 | import { REGION } from "../region"; 4 | import { evaluate, expectEq, success, TestSuite } from "../testing"; 5 | import PubsubMessage = functions.pubsub.Message; 6 | 7 | // TODO(inlined) use multiple queues to run inline. 8 | // Expected message data: {"hello": "world"} 9 | export const pubsubTests: any = functions 10 | .region(REGION) 11 | .pubsub.topic("pubsubTests") 12 | .onPublish((m, c) => { 13 | let testId: string; 14 | try { 15 | testId = m.json.testId; 16 | } catch (e) { 17 | /* Ignored. Covered in another test case that `event.data.json` works. */ 18 | } 19 | 20 | return new TestSuite("pubsub onPublish") 21 | .it("should have a topic as resource", (message, context) => 22 | expectEq(context.resource.name, `projects/${process.env.GCLOUD_PROJECT}/topics/pubsubTests`) 23 | ) 24 | 25 | .it("should not have a path", (message, context) => 26 | expectEq((context as any).path, undefined) 27 | ) 28 | 29 | .it("should have the correct eventType", (message, context) => 30 | expectEq(context.eventType, "google.pubsub.topic.publish") 31 | ) 32 | 33 | .it("should have an eventId", (message, context) => context.eventId) 34 | 35 | .it("should have a timestamp", (message, context) => context.timestamp) 36 | 37 | .it("should not have auth", (message, context) => expectEq((context as any).auth, undefined)) 38 | 39 | .it("should not have action", (message, context) => 40 | expectEq((context as any).action, undefined) 41 | ) 42 | 43 | .it("should have pubsub data", (message) => { 44 | const decoded = new Buffer(message.data, "base64").toString(); 45 | const parsed = JSON.parse(decoded); 46 | return evaluate(parsed.hasOwnProperty("testId"), `Raw data was + ${message.data}`); 47 | }) 48 | 49 | .it("should decode JSON payloads with the json helper", (message) => 50 | evaluate(message.json.hasOwnProperty("testId"), message.json) 51 | ) 52 | 53 | .run(testId, m, c); 54 | }); 55 | 56 | export const schedule: any = functions 57 | .region(REGION) 58 | .pubsub.schedule("every 10 hours") // This is a dummy schedule, since we need to put a valid one in. 59 | // For the test, the job is triggered by the jobs:run api 60 | .onRun(async () => { 61 | const db = admin.database(); 62 | const snap = await db.ref("testRuns").orderByChild("timestamp").limitToLast(1).once("value"); 63 | const testId = Object.keys(snap.val())[0]; 64 | return new TestSuite("pubsub scheduleOnRun") 65 | .it("should trigger when the scheduler fires", () => success()) 66 | .run(testId, null); 67 | }); 68 | -------------------------------------------------------------------------------- /integration_test/functions/src/v1/remoteConfig-tests.ts: -------------------------------------------------------------------------------- 1 | import * as functions from "firebase-functions"; 2 | import { REGION } from "../region"; 3 | import { expectEq, TestSuite } from "../testing"; 4 | import TemplateVersion = functions.remoteConfig.TemplateVersion; 5 | 6 | export const remoteConfigTests: any = functions.region(REGION).remoteConfig.onUpdate((v, c) => { 7 | return new TestSuite("remoteConfig onUpdate") 8 | .it("should have a project as resource", (version, context) => 9 | expectEq(context.resource.name, `projects/${process.env.GCLOUD_PROJECT}`) 10 | ) 11 | 12 | .it("should have the correct eventType", (version, context) => 13 | expectEq(context.eventType, "google.firebase.remoteconfig.update") 14 | ) 15 | 16 | .it("should have an eventId", (version, context) => context.eventId) 17 | 18 | .it("should have a timestamp", (version, context) => context.timestamp) 19 | 20 | .it("should not have auth", (version, context) => expectEq((context as any).auth, undefined)) 21 | 22 | .run(v.description, v, c); 23 | }); 24 | -------------------------------------------------------------------------------- /integration_test/functions/src/v1/storage-tests.ts: -------------------------------------------------------------------------------- 1 | import * as functions from "firebase-functions"; 2 | import { REGION } from "../region"; 3 | import { expectEq, TestSuite } from "../testing"; 4 | import ObjectMetadata = functions.storage.ObjectMetadata; 5 | 6 | export const storageTests: any = functions 7 | .runWith({ 8 | timeoutSeconds: 540, 9 | }) 10 | .region(REGION) 11 | .storage.bucket() 12 | .object() 13 | .onFinalize((s, c) => { 14 | const testId = s.name.split(".")[0]; 15 | return new TestSuite("storage object finalize") 16 | 17 | .it("should not have event.app", (data, context) => !(context as any).app) 18 | 19 | .it("should have the right eventType", (snap, context) => 20 | expectEq(context.eventType, "google.storage.object.finalize") 21 | ) 22 | 23 | .it("should have eventId", (snap, context) => context.eventId) 24 | 25 | .it("should have timestamp", (snap, context) => context.timestamp) 26 | 27 | .run(testId, s, c); 28 | }); 29 | -------------------------------------------------------------------------------- /integration_test/functions/src/v1/testLab-tests.ts: -------------------------------------------------------------------------------- 1 | import * as functions from "firebase-functions"; 2 | import { REGION } from "../region"; 3 | import { expectEq, TestSuite } from "../testing"; 4 | import TestMatrix = functions.testLab.TestMatrix; 5 | 6 | export const testLabTests: any = functions 7 | .runWith({ 8 | timeoutSeconds: 540, 9 | }) 10 | .region(REGION) 11 | .testLab.testMatrix() 12 | .onComplete((matrix, context) => { 13 | return new TestSuite("test matrix complete") 14 | .it("should have eventId", (snap, context) => context.eventId) 15 | 16 | .it("should have right eventType", (_, context) => 17 | expectEq(context.eventType, "google.testing.testMatrix.complete") 18 | ) 19 | 20 | .it("should be in state 'INVALID'", (matrix) => expectEq(matrix.state, "INVALID")) 21 | 22 | .run(matrix?.clientInfo?.details?.testId, matrix, context); 23 | }); 24 | -------------------------------------------------------------------------------- /integration_test/functions/src/v1/testLab-utils.ts: -------------------------------------------------------------------------------- 1 | import * as admin from "firebase-admin"; 2 | import fetch from "node-fetch"; 3 | 4 | interface AndroidDevice { 5 | androidModelId: string; 6 | androidVersionId: string; 7 | locale: string; 8 | orientation: string; 9 | } 10 | 11 | const TESTING_API_SERVICE_NAME = "testing.googleapis.com"; 12 | 13 | /** 14 | * Creates a new TestMatrix in Test Lab which is expected to be rejected as 15 | * invalid. 16 | * 17 | * @param projectId Project for which the test run will be created 18 | * @param testId Test id which will be encoded in client info details 19 | * @param accessToken accessToken to attach to requested for authentication 20 | */ 21 | export async function startTestRun(projectId: string, testId: string, accessToken: string) { 22 | const device = await fetchDefaultDevice(accessToken); 23 | return await createTestMatrix(accessToken, projectId, testId, device); 24 | } 25 | 26 | async function fetchDefaultDevice(accessToken: string): Promise { 27 | const resp = await fetch( 28 | `https://${TESTING_API_SERVICE_NAME}/v1/testEnvironmentCatalog/ANDROID`, 29 | { 30 | headers: { 31 | Authorization: "Bearer " + accessToken, 32 | "Content-Type": "application/json", 33 | }, 34 | } 35 | ); 36 | if (!resp.ok) { 37 | throw new Error(resp.statusText); 38 | } 39 | const data = await resp.json(); 40 | const models = data?.androidDeviceCatalog?.models || []; 41 | const defaultModels = models.filter( 42 | (m) => 43 | m.tags !== undefined && 44 | m.tags.indexOf("default") > -1 && 45 | m.supportedVersionIds !== undefined && 46 | m.supportedVersionIds.length > 0 47 | ); 48 | 49 | if (defaultModels.length === 0) { 50 | throw new Error("No default device found"); 51 | } 52 | 53 | const model = defaultModels[0]; 54 | const versions = model.supportedVersionIds; 55 | 56 | return { 57 | androidModelId: model.id, 58 | androidVersionId: versions[versions.length - 1], 59 | locale: "en", 60 | orientation: "portrait", 61 | } as AndroidDevice; 62 | } 63 | 64 | async function createTestMatrix( 65 | accessToken: string, 66 | projectId: string, 67 | testId: string, 68 | device: AndroidDevice 69 | ): Promise { 70 | const body = { 71 | projectId, 72 | testSpecification: { 73 | androidRoboTest: { 74 | appApk: { 75 | gcsPath: "gs://path/to/non-existing-app.apk", 76 | }, 77 | }, 78 | }, 79 | environmentMatrix: { 80 | androidDeviceList: { 81 | androidDevices: [device], 82 | }, 83 | }, 84 | resultStorage: { 85 | googleCloudStorage: { 86 | gcsPath: "gs://" + admin.storage().bucket().name, 87 | }, 88 | }, 89 | clientInfo: { 90 | name: "CloudFunctionsSDKIntegrationTest", 91 | clientInfoDetails: { 92 | key: "testId", 93 | value: testId, 94 | }, 95 | }, 96 | }; 97 | const resp = await fetch( 98 | `https://${TESTING_API_SERVICE_NAME}/v1/projects/${projectId}/testMatrices`, 99 | { 100 | method: "POST", 101 | headers: { 102 | Authorization: "Bearer " + accessToken, 103 | "Content-Type": "application/json", 104 | }, 105 | body: JSON.stringify(body), 106 | } 107 | ); 108 | if (!resp.ok) { 109 | throw new Error(resp.statusText); 110 | } 111 | return; 112 | } 113 | -------------------------------------------------------------------------------- /integration_test/functions/src/v2/https-tests.ts: -------------------------------------------------------------------------------- 1 | import { onCall } from "firebase-functions/v2/https"; 2 | import { expectEq, TestSuite } from "../testing"; 3 | 4 | export const callabletests = onCall({ invoker: "private" }, (req) => { 5 | return new TestSuite("v2 https onCall") 6 | .it("should have the correct data", (data: any) => expectEq(data?.foo, "bar")) 7 | .run(req.data.testId, req.data); 8 | }); 9 | -------------------------------------------------------------------------------- /integration_test/functions/src/v2/index.ts: -------------------------------------------------------------------------------- 1 | import { setGlobalOptions } from "firebase-functions/v2"; 2 | import { REGION } from "../region"; 3 | setGlobalOptions({ region: REGION }); 4 | 5 | // TODO: Temporarily disable - doesn't work unless running on projects w/ permission to create public functions. 6 | // export * from './https-tests'; 7 | export * from "./scheduled-tests"; 8 | -------------------------------------------------------------------------------- /integration_test/functions/src/v2/scheduled-tests.ts: -------------------------------------------------------------------------------- 1 | import * as admin from "firebase-admin"; 2 | import { onSchedule } from "firebase-functions/v2/scheduler"; 3 | import { REGION } from "../region"; 4 | import { success, TestSuite } from "../testing"; 5 | 6 | export const schedule: any = onSchedule( 7 | { 8 | schedule: "every 10 hours", 9 | region: REGION, 10 | }, 11 | async () => { 12 | const db = admin.database(); 13 | const snap = await db.ref("testRuns").orderByChild("timestamp").limitToLast(1).once("value"); 14 | const testId = Object.keys(snap.val())[0]; 15 | return new TestSuite("scheduler scheduleOnRun") 16 | .it("should trigger when the scheduler fires", () => success()) 17 | .run(testId, null); 18 | } 19 | ); 20 | -------------------------------------------------------------------------------- /integration_test/functions/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["es6", "dom"], 4 | "module": "commonjs", 5 | "target": "es2020", 6 | "noImplicitAny": false, 7 | "outDir": "lib", 8 | "declaration": true, 9 | "typeRoots": ["node_modules/@types"] 10 | }, 11 | "files": ["src/index.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /integration_test/package.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions", 3 | "description": "Integration test for the Firebase SDK for Google Cloud Functions", 4 | "scripts": { 5 | "build": "./node_modules/.bin/tsc" 6 | }, 7 | "dependencies": { 8 | "@google-cloud/pubsub": "^2.10.0", 9 | "firebase-admin": "__FIREBASE_ADMIN__", 10 | "firebase-functions": "__SDK_TARBALL__", 11 | "node-fetch": "^2.6.7" 12 | }, 13 | "main": "lib/index.js", 14 | "devDependencies": { 15 | "@types/node-fetch": "^2.6.1", 16 | "typescript": "^4.3.5" 17 | }, 18 | "engines": { 19 | "node": "__NODE_VERSION__" 20 | }, 21 | "private": true 22 | } 23 | -------------------------------------------------------------------------------- /integration_test/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Exit immediately if a command exits with a non-zero status. 4 | set -e 5 | 6 | PROJECT_ID="${GCLOUD_PROJECT}" 7 | TIMESTAMP=$(date +%s) 8 | 9 | if [[ "${PROJECT_ID}" == "" ]]; then 10 | echo "process.env.GCLOUD_PROJECT cannot be empty" 11 | exit 1 12 | fi 13 | 14 | # Directory where this script lives. 15 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 16 | 17 | function announce { 18 | echo -e "\n\n##### $1" 19 | } 20 | 21 | function build_sdk { 22 | announce "Building SDK..." 23 | cd "${DIR}/.." 24 | rm -f firebase-functions-*.tgz 25 | npm run build:pack 26 | mv firebase-functions-*.tgz "integration_test/functions/firebase-functions-${TIMESTAMP}.tgz" 27 | } 28 | 29 | # Creates a Package.json from package.json.template 30 | # @param timestmap of the current SDK build 31 | # @param Node version to test under 32 | function create_package_json { 33 | cd "${DIR}" 34 | cp package.json.template functions/package.json 35 | # we have to do the -e flag here so that it work both on linux and mac os, but that creates an extra 36 | # backup file called package.json-e that we should clean up afterwards. 37 | sed -i -e "s/__SDK_TARBALL__/firebase-functions-$1.tgz/g" functions/package.json 38 | sed -i -e "s/__NODE_VERSION__/$2/g" functions/package.json 39 | sed -i -e "s/__FIREBASE_ADMIN__/$3/g" functions/package.json 40 | rm -f functions/package.json-e 41 | } 42 | 43 | function install_deps { 44 | announce "Installing dependencies..." 45 | cd "${DIR}/functions" 46 | rm -rf node_modules/firebase-functions 47 | npm install 48 | } 49 | 50 | function delete_all_functions { 51 | announce "Deleting all functions in project..." 52 | cd "${DIR}" 53 | # Try to delete, if there are errors it is because the project is already empty, 54 | # in that case do nothing. 55 | firebase functions:delete integrationTests v1 v2 --force --project=$PROJECT_ID || : & 56 | wait 57 | announce "Project emptied." 58 | } 59 | 60 | function deploy { 61 | # Deploy functions, and security rules for database and Firestore. If the deploy fails, retry twice 62 | for i in 1 2; do firebase deploy --project="${PROJECT_ID}" --only functions,database,firestore && break; done 63 | } 64 | 65 | function run_tests { 66 | announce "Running integration tests..." 67 | 68 | # Construct the URL for the test function. This may change in the future, 69 | # causing this script to start failing, but currently we don't have a very 70 | # reliable way of determining the URL dynamically. 71 | TEST_DOMAIN="cloudfunctions.net" 72 | if [[ "${FIREBASE_FUNCTIONS_TEST_REGION}" == "" ]]; then 73 | FIREBASE_FUNCTIONS_TEST_REGION="us-central1" 74 | fi 75 | TEST_URL="https://${FIREBASE_FUNCTIONS_TEST_REGION}-${PROJECT_ID}.${TEST_DOMAIN}/integrationTests" 76 | echo "${TEST_URL}" 77 | 78 | curl --fail -H "Authorization: Bearer $(gcloud auth print-identity-token)" "${TEST_URL}" 79 | } 80 | 81 | function cleanup { 82 | announce "Performing cleanup..." 83 | delete_all_functions 84 | rm "${DIR}/functions/firebase-functions-${TIMESTAMP}.tgz" 85 | rm "${DIR}/functions/package.json" 86 | rm -f "${DIR}/functions/firebase-debug.log" 87 | rm -rf "${DIR}/functions/lib" 88 | rm -rf "${DIR}/functions/node_modules" 89 | } 90 | 91 | # Setup 92 | build_sdk 93 | delete_all_functions 94 | 95 | for version in 14 16; do 96 | create_package_json $TIMESTAMP $version "^10.0.0" 97 | install_deps 98 | announce "Re-deploying the same functions to Node $version runtime ..." 99 | deploy 100 | run_tests 101 | done 102 | 103 | # Cleanup 104 | cleanup 105 | announce "All tests pass!" 106 | -------------------------------------------------------------------------------- /logger/compat.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /logger/index.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /mocha/setup.ts: -------------------------------------------------------------------------------- 1 | import * as chai from "chai"; 2 | import * as chaiAsPromised from "chai-as-promised"; 3 | import * as nock from "nock"; 4 | 5 | chai.use(chaiAsPromised); 6 | 7 | nock.disableNetConnect(); 8 | -------------------------------------------------------------------------------- /protos/README.md: -------------------------------------------------------------------------------- 1 | # Generate compiled ProtoBuf 2 | 3 | Running the script will generate statically-compiled protobufs for decoding `application/protobuf` events. Generate them by running: 4 | 5 | ``` 6 | ./update.sh 7 | ``` 8 | 9 | In order to build, the following repos are cloned 10 | 11 | - https://github.com/googleapis/google-cloudevents 12 | - https://github.com/googleapis/googleapis 13 | - https://github.com/google/protobuf 14 | 15 | The script relies on the [protobufjs-cli](https://github.com/protobufjs/protobuf.js/tree/master/cli#pbts-for-typescript) package to create the compiled js/ts files. 16 | -------------------------------------------------------------------------------- /protos/update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The MIT License (MIT) 4 | # 5 | # Copyright (c) 2023 Firebase 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | # vars 26 | PROTOS_DIR="$(pwd)" 27 | WORK_DIR=`mktemp -d` 28 | 29 | # deletes the temp directory on exit 30 | function cleanup { 31 | rm -rf "$WORK_DIR" 32 | echo "Deleted temp working directory $WORK_DIR" 33 | rm -rf "${PROTOS_DIR}/data.proto" "${PROTOS_DIR}/any.proto" "${PROTOS_DIR}/google" 34 | echo "Deleted copied protos" 35 | } 36 | 37 | # register the cleanup function to be called on the EXIT signal 38 | trap cleanup EXIT 39 | 40 | # Capture location of pbjs / pbts before we pushd. 41 | PBJS="$(npm bin)/pbjs" 42 | PBTS="$(npm bin)/pbts" 43 | 44 | # enter working directory 45 | pushd "$WORK_DIR" 46 | 47 | git clone --depth 1 https://github.com/googleapis/google-cloudevents.git 48 | git clone --depth 1 https://github.com/googleapis/googleapis.git 49 | git clone --depth 1 https://github.com/google/protobuf.git 50 | 51 | # make dirs 52 | mkdir -p "${PROTOS_DIR}/google/type" 53 | 54 | # copy protos 55 | cp google-cloudevents/proto/google/events/cloud/firestore/v1/data.proto \ 56 | "${PROTOS_DIR}/" 57 | 58 | cp protobuf/src/google/protobuf/any.proto \ 59 | "${PROTOS_DIR}/" 60 | 61 | cp protobuf/src/google/protobuf/struct.proto \ 62 | "${PROTOS_DIR}/google/" 63 | 64 | cp protobuf/src/google/protobuf/timestamp.proto \ 65 | "${PROTOS_DIR}/google/" 66 | 67 | cp googleapis/google/type/latlng.proto \ 68 | "${PROTOS_DIR}/google/type/" 69 | 70 | popd 71 | 72 | "${PBJS}" -t static-module -w commonjs -o compiledFirestore.js \ 73 | data.proto any.proto 74 | 75 | "${PBTS}" -o compiledFirestore.d.ts compiledFirestore.js 76 | -------------------------------------------------------------------------------- /scripts/bin-test/extsdks/local/index.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * TaskQueue/LifecycleEvent/RuntimeStatus Tester SDK for backfill@0.0.2 3 | * 4 | * When filing bugs or feature requests please specify: 5 | * "Extensions SDK v1.0.0 for Local extension. 6 | * https://github.com/firebase/firebase-tools/issues/new/choose 7 | * 8 | * GENERATED FILE. DO NOT EDIT. 9 | */ 10 | export type DoBackfillParam = "True" | "False"; 11 | export type LocationParam = 12 | | "us-central1" 13 | | "us-east1" 14 | | "us-east4" 15 | | "europe-west1" 16 | | "europe-west2" 17 | | "europe-west3" 18 | | "asia-east2" 19 | | "asia-northeast1"; 20 | /** 21 | * Parameters for backfill@0.0.2 extension 22 | */ 23 | export interface BackfillParams { 24 | /** 25 | * Do a backfill 26 | */ 27 | DO_BACKFILL: DoBackfillParam; 28 | /** 29 | * Cloud Functions location 30 | */ 31 | LOCATION: LocationParam; 32 | } 33 | export declare function backfill(instanceId: string, params: BackfillParams): Backfill; 34 | /** 35 | * TaskQueue/LifecycleEvent/RuntimeStatus Tester 36 | * A tester for the TaskQueue/LCE/RuntimeStatus project 37 | */ 38 | export declare class Backfill { 39 | private instanceId; 40 | private params; 41 | readonly FIREBASE_EXTENSION_LOCAL_PATH = 42 | "./functions/generated/extensions/local/backfill/0.0.2/src"; 43 | constructor(instanceId: string, params: BackfillParams); 44 | getInstanceId(): string; 45 | getParams(): BackfillParams; 46 | } 47 | -------------------------------------------------------------------------------- /scripts/bin-test/extsdks/local/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * TaskQueue/LifecycleEvent/RuntimeStatus Tester SDK for extensions-try-backfill3@0.0.2 4 | * 5 | * When filing bugs or feature requests please specify: 6 | * "Extensions SDK v1.0.0 for Local extension. 7 | * https://github.com/firebase/firebase-tools/issues/new/choose 8 | * 9 | * GENERATED FILE. DO NOT EDIT. 10 | */ 11 | Object.defineProperty(exports, "__esModule", { value: true }); 12 | exports.backfill = exports.backfill = void 0; 13 | function backfill(instanceId, params) { 14 | return new Backfill(instanceId, params); 15 | } 16 | exports.backfill = backfill; 17 | /** 18 | * TaskQueue/LifecycleEvent/RuntimeStatus Tester 19 | * A tester for the TaskQueue/LCE/RuntimeStatus project 20 | */ 21 | class Backfill { 22 | constructor(instanceId, params) { 23 | this.instanceId = instanceId; 24 | this.params = params; 25 | this.FIREBASE_EXTENSION_LOCAL_PATH = "./functions/generated/extensions/local/backfill/0.0.2/src"; 26 | } 27 | getInstanceId() { return this.instanceId; } 28 | getParams() { return this.params; } 29 | } 30 | exports.Backfill = Backfill; 31 | -------------------------------------------------------------------------------- /scripts/bin-test/extsdks/local/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@firebase-extensions/local-backfill-sdk", 3 | "main": "./index.js" 4 | } -------------------------------------------------------------------------------- /scripts/bin-test/extsdks/translate/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@firebase-extensions/firebase-firestore-translate-text-sdk", 3 | "main": "./index.js" 4 | } -------------------------------------------------------------------------------- /scripts/bin-test/mocha-setup.ts: -------------------------------------------------------------------------------- 1 | import * as chai from "chai"; 2 | import * as chaiAsPromised from "chai-as-promised"; 3 | 4 | chai.use(chaiAsPromised); 5 | -------------------------------------------------------------------------------- /scripts/bin-test/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex # Immediately exit on failure 3 | 4 | # Link the Functions SDK for the testing environment. 5 | npm run build 6 | npm link 7 | 8 | # Link the extensions SDKs for the testing environment. 9 | (cd scripts/bin-test/extsdks/local && npm link) 10 | (cd scripts/bin-test/extsdks/translate && npm link) 11 | (cd scripts/bin-test/extsdks/translate && npm link firebase-functions) 12 | 13 | # Link SDKs to all test sources. 14 | for f in scripts/bin-test/sources/*; do 15 | if [ -d "$f" ]; then 16 | (cd "$f" && npm link firebase-functions) 17 | (cd "$f" && npm link @firebase-extensions/firebase-firestore-translate-text-sdk) 18 | (cd "$f" && npm link @firebase-extensions/local-backfill-sdk) 19 | fi 20 | done 21 | 22 | # Make sure firebase-functions binary is executable 23 | chmod +x ./lib/bin/firebase-functions.js 24 | 25 | mocha \ 26 | --file ./scripts/bin-test/mocha-setup.ts \ 27 | ./scripts/bin-test/test.ts 28 | -------------------------------------------------------------------------------- /scripts/bin-test/sources/commonjs-grouped/g1.js: -------------------------------------------------------------------------------- 1 | const functions = require("firebase-functions/v1"); 2 | 3 | exports.groupedhttp = functions.https.onRequest((req, resp) => { 4 | resp.status(200).send("PASS"); 5 | }); 6 | 7 | exports.groupedcallable = functions.https.onCall(() => { 8 | return "PASS"; 9 | }); 10 | -------------------------------------------------------------------------------- /scripts/bin-test/sources/commonjs-grouped/index.js: -------------------------------------------------------------------------------- 1 | const functions = require("firebase-functions/v1"); 2 | const functionsv2 = require("firebase-functions/v2"); 3 | const firestoreTranslateText = require("@firebase-extensions/firebase-firestore-translate-text-sdk").firestoreTranslateText; 4 | const backfill = require("@firebase-extensions/local-backfill-sdk").backfill; 5 | 6 | 7 | exports.v1http = functions.https.onRequest((req, resp) => { 8 | resp.status(200).send("PASS"); 9 | }); 10 | 11 | exports.v1callable = functions.https.onCall(() => { 12 | return "PASS"; 13 | }); 14 | 15 | exports.v2http = functionsv2.https.onRequest((req, resp) => { 16 | resp.status(200).send("PASS"); 17 | }); 18 | 19 | exports.v2callable = functionsv2.https.onCall(() => { 20 | return "PASS"; 21 | }); 22 | 23 | // A Firebase extension by ref 24 | const extRef1 = firestoreTranslateText("extRef1", { 25 | "COLLECTION_PATH": "collection1", 26 | "INPUT_FIELD_NAME": "input1", 27 | "LANGUAGES": "de,es", 28 | "OUTPUT_FIELD_NAME": "translated", 29 | "_EVENT_ARC_REGION": "us-central1", 30 | "_FUNCTION_LOCATION": "us-central1", 31 | }); 32 | exports.extRef1 = extRef1; 33 | 34 | // A Firebase function defined by extension event 35 | const ttOnStart = extRef1.onStart((event) => { 36 | console.log("onStart got event: " + JSON.stringify(event, null, 2)); 37 | }); 38 | exports.ttOnStart = ttOnStart; 39 | 40 | // A Firebase extension by localPath 41 | exports.extLocal2 = backfill("extLocal2", { 42 | DO_BACKFILL: "False", 43 | LOCATION: "us-central1", 44 | }); 45 | 46 | exports.g1 = require("./g1"); 47 | -------------------------------------------------------------------------------- /scripts/bin-test/sources/commonjs-grouped/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "commonjs-grouped" 3 | } 4 | -------------------------------------------------------------------------------- /scripts/bin-test/sources/commonjs-main/functions.js: -------------------------------------------------------------------------------- 1 | const functions = require("firebase-functions/v1"); 2 | const functionsv2 = require("firebase-functions/v2"); 3 | const firestoreTranslateText = require("@firebase-extensions/firebase-firestore-translate-text-sdk").firestoreTranslateText; 4 | const backfill = require("@firebase-extensions/local-backfill-sdk").backfill; 5 | 6 | exports.v1http = functions.https.onRequest((req, resp) => { 7 | resp.status(200).send("PASS"); 8 | }); 9 | 10 | exports.v1callable = functions.https.onCall(() => { 11 | return "PASS"; 12 | }); 13 | 14 | exports.v2http = functionsv2.https.onRequest((req, resp) => { 15 | resp.status(200).send("PASS"); 16 | }); 17 | 18 | exports.v2callable = functionsv2.https.onCall(() => { 19 | return "PASS"; 20 | }); 21 | 22 | // A Firebase extension by ref 23 | const extRef1 = firestoreTranslateText("extRef1", { 24 | "COLLECTION_PATH": "collection1", 25 | "INPUT_FIELD_NAME": "input1", 26 | "LANGUAGES": "de,es", 27 | "OUTPUT_FIELD_NAME": "translated", 28 | "_EVENT_ARC_REGION": "us-central1", 29 | "_FUNCTION_LOCATION": "us-central1", 30 | }); 31 | exports.extRef1 = extRef1; 32 | 33 | // A Firebase function defined by extension event 34 | const ttOnStart = extRef1.onStart((event) => { 35 | console.log("onStart got event: " + JSON.stringify(event, null, 2)); 36 | }); 37 | exports.ttOnStart = ttOnStart; 38 | 39 | // A Firebase extension by localPath 40 | exports.extLocal2 = backfill("extLocal2", { 41 | DO_BACKFILL: "False", 42 | LOCATION: "us-central1", 43 | }); 44 | -------------------------------------------------------------------------------- /scripts/bin-test/sources/commonjs-main/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "commonjs-main", 3 | "main": "functions.js" 4 | } 5 | -------------------------------------------------------------------------------- /scripts/bin-test/sources/commonjs-preserve/index.js: -------------------------------------------------------------------------------- 1 | const functions = require("firebase-functions/v1"); 2 | const functionsv2 = require("firebase-functions/v2"); 3 | const firestoreTranslateText = require("@firebase-extensions/firebase-firestore-translate-text-sdk").firestoreTranslateText; 4 | const backfill = require("@firebase-extensions/local-backfill-sdk").backfill; 5 | 6 | exports.v1http = functions.https.onRequest((req, resp) => { 7 | resp.status(200).send("PASS"); 8 | }); 9 | 10 | exports.v1httpPreserve = functions 11 | .runWith({ preserveExternalChanges: true }) 12 | .https.onRequest((req, resp) => { 13 | resp.status(200).send("PASS"); 14 | }); 15 | 16 | functionsv2.setGlobalOptions({ preserveExternalChanges: true }); 17 | 18 | exports.v2http = functionsv2.https.onRequest((req, resp) => { 19 | resp.status(200).send("PASS"); 20 | }); 21 | 22 | // A Firebase extension by ref 23 | const extRef1 = firestoreTranslateText("extRef1", { 24 | "COLLECTION_PATH": "collection1", 25 | "INPUT_FIELD_NAME": "input1", 26 | "LANGUAGES": "de,es", 27 | "OUTPUT_FIELD_NAME": "translated", 28 | "_EVENT_ARC_REGION": "us-central1", 29 | "_FUNCTION_LOCATION": "us-central1", 30 | }); 31 | exports.extRef1 = extRef1; 32 | 33 | // A Firebase function defined by extension event 34 | const ttOnStart = extRef1.onStart((event) => { 35 | console.log("onStart got event: " + JSON.stringify(event, null, 2)); 36 | }); 37 | exports.ttOnStart = ttOnStart; 38 | 39 | // A Firebase extension by localPath 40 | exports.extLocal2 = backfill("extLocal2", { 41 | DO_BACKFILL: "False", 42 | LOCATION: "us-central1", 43 | }); -------------------------------------------------------------------------------- /scripts/bin-test/sources/commonjs-preserve/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "commonjs-preserve" 3 | } 4 | -------------------------------------------------------------------------------- /scripts/bin-test/sources/commonjs/index.js: -------------------------------------------------------------------------------- 1 | const functions = require("firebase-functions/v1"); 2 | const functionsv2 = require("firebase-functions/v2"); 3 | const firestoreTranslateText = require("@firebase-extensions/firebase-firestore-translate-text-sdk").firestoreTranslateText; 4 | const backfill = require("@firebase-extensions/local-backfill-sdk").backfill; 5 | 6 | exports.v1http = functions.https.onRequest((req, resp) => { 7 | resp.status(200).send("PASS"); 8 | }); 9 | 10 | exports.v1callable = functions.https.onCall(() => { 11 | return "PASS"; 12 | }); 13 | 14 | exports.v2http = functionsv2.https.onRequest((req, resp) => { 15 | resp.status(200).send("PASS"); 16 | }); 17 | 18 | exports.v2callable = functionsv2.https.onCall(() => { 19 | return "PASS"; 20 | }); 21 | 22 | // A Firebase extension by ref 23 | const extRef1 = firestoreTranslateText("extRef1", { 24 | "COLLECTION_PATH": "collection1", 25 | "INPUT_FIELD_NAME": "input1", 26 | "LANGUAGES": "de,es", 27 | "OUTPUT_FIELD_NAME": "translated", 28 | "_EVENT_ARC_REGION": "us-central1", 29 | "_FUNCTION_LOCATION": "us-central1", 30 | }); 31 | exports.extRef1 = extRef1; 32 | 33 | // A Firebase function defined by extension event 34 | const ttOnStart = extRef1.onStart((event) => { 35 | console.log("onStart got event: " + JSON.stringify(event, null, 2)); 36 | }); 37 | exports.ttOnStart = ttOnStart; 38 | 39 | // A Firebase extension by localPath 40 | exports.extLocal2 = backfill("extLocal2", { 41 | DO_BACKFILL: "False", 42 | LOCATION: "us-central1", 43 | }); 44 | -------------------------------------------------------------------------------- /scripts/bin-test/sources/commonjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "commonjs" 3 | } 4 | -------------------------------------------------------------------------------- /scripts/bin-test/sources/esm-ext/index.mjs: -------------------------------------------------------------------------------- 1 | import * as functions from "firebase-functions/v1"; 2 | import * as functionsv2 from "firebase-functions/v2"; 3 | import { firestoreTranslateText } from "@firebase-extensions/firebase-firestore-translate-text-sdk"; 4 | import { backfill } from "@firebase-extensions/local-backfill-sdk"; 5 | 6 | export const v1http = functions.https.onRequest((req, resp) => { 7 | resp.status(200).send("PASS"); 8 | }); 9 | 10 | export const v1callable = functions.https.onCall(() => { 11 | return "PASS"; 12 | }); 13 | 14 | export const v2http = functionsv2.https.onRequest((req, resp) => { 15 | resp.status(200).send("PASS"); 16 | }); 17 | 18 | export const v2callable = functionsv2.https.onCall(() => { 19 | return "PASS"; 20 | }); 21 | 22 | // A Firebase extension by ref 23 | export const extRef1 = firestoreTranslateText("extRef1", { 24 | "COLLECTION_PATH": "collection1", 25 | "INPUT_FIELD_NAME": "input1", 26 | "LANGUAGES": "de,es", 27 | "OUTPUT_FIELD_NAME": "translated", 28 | "_EVENT_ARC_REGION": "us-central1", 29 | "_FUNCTION_LOCATION": "us-central1", 30 | }); 31 | 32 | // A Firebase function defined by extension event 33 | export const ttOnStart = extRef1.onStart((event) => { 34 | console.log("onStart got event: " + JSON.stringify(event, null, 2)); 35 | }); 36 | 37 | // A Firebase extension by localPath 38 | export const extLocal2 = backfill("extLocal2", { 39 | DO_BACKFILL: "False", 40 | LOCATION: "us-central1", 41 | }); -------------------------------------------------------------------------------- /scripts/bin-test/sources/esm-ext/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esm-ext", 3 | "main": "index.mjs" 4 | } 5 | -------------------------------------------------------------------------------- /scripts/bin-test/sources/esm-main/functions.js: -------------------------------------------------------------------------------- 1 | import * as functions from "firebase-functions/v1"; 2 | import * as functionsv2 from "firebase-functions/v2"; 3 | import { firestoreTranslateText } from "@firebase-extensions/firebase-firestore-translate-text-sdk"; 4 | import { backfill } from "@firebase-extensions/local-backfill-sdk"; 5 | 6 | export const v1http = functions.https.onRequest((req, resp) => { 7 | resp.status(200).send("PASS"); 8 | }); 9 | 10 | export const v1callable = functions.https.onCall(() => { 11 | return "PASS"; 12 | }); 13 | 14 | export const v2http = functionsv2.https.onRequest((req, resp) => { 15 | resp.status(200).send("PASS"); 16 | }); 17 | 18 | export const v2callable = functionsv2.https.onCall(() => { 19 | return "PASS"; 20 | }); 21 | 22 | // A Firebase extension by ref 23 | export const extRef1 = firestoreTranslateText("extRef1", { 24 | "COLLECTION_PATH": "collection1", 25 | "INPUT_FIELD_NAME": "input1", 26 | "LANGUAGES": "de,es", 27 | "OUTPUT_FIELD_NAME": "translated", 28 | "_EVENT_ARC_REGION": "us-central1", 29 | "_FUNCTION_LOCATION": "us-central1", 30 | }); 31 | 32 | // A Firebase function defined by extension event 33 | export const ttOnStart = extRef1.onStart((event) => { 34 | console.log("onStart got event: " + JSON.stringify(event, null, 2)); 35 | }); 36 | 37 | // A Firebase extension by localPath 38 | export const extLocal2 = backfill("extLocal2", { 39 | DO_BACKFILL: "False", 40 | LOCATION: "us-central1", 41 | }); -------------------------------------------------------------------------------- /scripts/bin-test/sources/esm-main/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esm-main", 3 | "main": "functions.js", 4 | "type": "module" 5 | } 6 | -------------------------------------------------------------------------------- /scripts/bin-test/sources/esm-top-level-await/exports.js: -------------------------------------------------------------------------------- 1 | export const fn = () => { 2 | return null; 3 | } -------------------------------------------------------------------------------- /scripts/bin-test/sources/esm-top-level-await/index.js: -------------------------------------------------------------------------------- 1 | import * as functionsv2 from "firebase-functions/v2"; 2 | 3 | const { fn } = await import('./exports.js'); 4 | 5 | export const v2http = functionsv2.https.onRequest((req, resp) => { 6 | fn() 7 | resp.status(200).send("PASS"); 8 | }); 9 | -------------------------------------------------------------------------------- /scripts/bin-test/sources/esm-top-level-await/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esm", 3 | "type": "module" 4 | } 5 | -------------------------------------------------------------------------------- /scripts/bin-test/sources/esm/index.js: -------------------------------------------------------------------------------- 1 | import * as functions from "firebase-functions/v1"; 2 | import * as functionsv2 from "firebase-functions/v2"; 3 | import { firestoreTranslateText } from "@firebase-extensions/firebase-firestore-translate-text-sdk"; 4 | import { backfill } from "@firebase-extensions/local-backfill-sdk"; 5 | 6 | export const v1http = functions.https.onRequest((req, resp) => { 7 | resp.status(200).send("PASS"); 8 | }); 9 | 10 | export const v1callable = functions.https.onCall(() => { 11 | return "PASS"; 12 | }); 13 | 14 | export const v2http = functionsv2.https.onRequest((req, resp) => { 15 | resp.status(200).send("PASS"); 16 | }); 17 | 18 | export const v2callable = functionsv2.https.onCall(() => { 19 | return "PASS"; 20 | }); 21 | 22 | // A Firebase extension by ref 23 | export const extRef1 = firestoreTranslateText("extRef1", { 24 | "COLLECTION_PATH": "collection1", 25 | "INPUT_FIELD_NAME": "input1", 26 | "LANGUAGES": "de,es", 27 | "OUTPUT_FIELD_NAME": "translated", 28 | "_EVENT_ARC_REGION": "us-central1", 29 | "_FUNCTION_LOCATION": "us-central1", 30 | }); 31 | 32 | // A Firebase function defined by extension event 33 | export const ttOnStart = extRef1.onStart((event) => { 34 | console.log("onStart got event: " + JSON.stringify(event, null, 2)); 35 | }); 36 | 37 | // A Firebase extension by localPath 38 | export const extLocal2 = backfill("extLocal2", { 39 | DO_BACKFILL: "False", 40 | LOCATION: "us-central1", 41 | }); -------------------------------------------------------------------------------- /scripts/bin-test/sources/esm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esm", 3 | "type": "module" 4 | } 5 | -------------------------------------------------------------------------------- /scripts/fetch-regions: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z $1 ]; then 4 | echo "Must provide a project id as first argument." && exit 1 5 | fi; 6 | 7 | gcloud functions regions list --project $1 --format=json | jq 'map(.locationId)' -------------------------------------------------------------------------------- /scripts/publish-container/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:20 2 | 3 | # Install dependencies 4 | RUN apt-get update && \ 5 | apt-get install -y curl git jq 6 | 7 | # Install npm at latest. 8 | RUN npm install --global npm@latest 9 | 10 | # Install hub 11 | RUN curl -fsSL --output hub.tgz https://github.com/github/hub/releases/download/v2.13.0/hub-linux-amd64-2.13.0.tgz 12 | RUN tar --strip-components=2 -C /usr/bin -xf hub.tgz hub-linux-amd64-2.13.0/bin/hub 13 | -------------------------------------------------------------------------------- /scripts/publish-container/cloudbuild.yaml: -------------------------------------------------------------------------------- 1 | steps: 2 | - name: "gcr.io/cloud-builders/docker" 3 | args: ["build", "-t", "gcr.io/$PROJECT_ID/package-builder", "."] 4 | images: ["gcr.io/$PROJECT_ID/package-builder"] 5 | -------------------------------------------------------------------------------- /scripts/publish/cloudbuild.yaml: -------------------------------------------------------------------------------- 1 | steps: 2 | # Decrypt the SSH key. 3 | - name: "gcr.io/cloud-builders/gcloud" 4 | args: 5 | [ 6 | "kms", 7 | "decrypt", 8 | "--ciphertext-file=deploy_key.enc", 9 | "--plaintext-file=/root/.ssh/id_rsa", 10 | "--location=global", 11 | "--keyring=${_KEY_RING}", 12 | "--key=${_KEY_NAME}", 13 | ] 14 | 15 | # Decrypt the Twitter credentials. 16 | - name: "gcr.io/cloud-builders/gcloud" 17 | args: 18 | [ 19 | "kms", 20 | "decrypt", 21 | "--ciphertext-file=twitter.json.enc", 22 | "--plaintext-file=twitter.json", 23 | "--location=global", 24 | "--keyring=${_KEY_RING}", 25 | "--key=${_KEY_NAME}", 26 | ] 27 | 28 | # Decrypt the npm credentials. 29 | - name: "gcr.io/cloud-builders/gcloud" 30 | args: 31 | [ 32 | "kms", 33 | "decrypt", 34 | "--ciphertext-file=npmrc.enc", 35 | "--plaintext-file=npmrc", 36 | "--location=global", 37 | "--keyring=${_KEY_RING}", 38 | "--key=${_KEY_NAME}", 39 | ] 40 | 41 | # Decrypt the hub (GitHub) credentials. 42 | - name: "gcr.io/cloud-builders/gcloud" 43 | args: 44 | [ 45 | "kms", 46 | "decrypt", 47 | "--ciphertext-file=hub.enc", 48 | "--plaintext-file=hub", 49 | "--location=global", 50 | "--keyring=${_KEY_RING}", 51 | "--key=${_KEY_NAME}", 52 | ] 53 | 54 | # Set up git with key and domain. 55 | - name: "gcr.io/cloud-builders/git" 56 | entrypoint: "bash" 57 | args: 58 | - "-c" 59 | - | 60 | chmod 600 /root/.ssh/id_rsa 61 | cat </root/.ssh/config 62 | Hostname github.com 63 | IdentityFile /root/.ssh/id_rsa 64 | EOF 65 | ssh-keyscan github.com >> /root/.ssh/known_hosts 66 | 67 | # Clone the repository. 68 | - name: "gcr.io/cloud-builders/git" 69 | args: ["clone", "git@github.com:${_REPOSITORY_ORG}/${_REPOSITORY_NAME}"] 70 | 71 | # Set up the Git configuration. 72 | - name: "gcr.io/cloud-builders/git" 73 | dir: "${_REPOSITORY_NAME}" 74 | args: ["config", "--global", "user.email", "firebase-oss-bot@google.com"] 75 | - name: "gcr.io/cloud-builders/git" 76 | dir: "${_REPOSITORY_NAME}" 77 | args: ["config", "--global", "user.name", "Google Open Source Bot"] 78 | 79 | # Set up the Twitter credentials. 80 | - name: "gcr.io/$PROJECT_ID/package-builder" 81 | entrypoint: "cp" 82 | args: ["-v", "twitter.json", "${_REPOSITORY_NAME}/scripts/twitter.json"] 83 | 84 | # Set up the npm credentials. 85 | - name: "gcr.io/$PROJECT_ID/package-builder" 86 | entrypoint: "bash" 87 | args: ["-c", "cp -v npmrc ~/.npmrc"] 88 | 89 | # Set up the hub credentials for package-builder. 90 | - name: "gcr.io/$PROJECT_ID/package-builder" 91 | entrypoint: "bash" 92 | args: ["-c", "mkdir -vp ~/.config && cp -v hub ~/.config/hub"] 93 | 94 | # Publish the package. 95 | - name: "gcr.io/$PROJECT_ID/package-builder" 96 | dir: "${_REPOSITORY_NAME}" 97 | args: ["bash", "./scripts/publish.sh", "${_VERSION}"] 98 | env: 99 | - "REPOSITORY_ORG=${_REPOSITORY_ORG}" 100 | - "REPOSITORY_NAME=${_REPOSITORY_NAME}" 101 | - "DRY_RUN=${_DRY_RUN}" 102 | - "PRE_RELEASE=${_PRE_RELEASE}" 103 | 104 | options: 105 | volumes: 106 | - name: "ssh" 107 | path: /root/.ssh 108 | 109 | substitutions: 110 | _VERSION: "" 111 | _PRE_RELEASE: "" 112 | _DRY_RUN: "" 113 | _KEY_RING: "npm-publish-keyring" 114 | _KEY_NAME: "publish" 115 | _REPOSITORY_ORG: "firebase" 116 | _REPOSITORY_NAME: "firebase-functions" 117 | -------------------------------------------------------------------------------- /scripts/publish/deploy_key.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebase/firebase-functions/849f01cd00e24ac1bf61fd634f0927aa70535892/scripts/publish/deploy_key.enc -------------------------------------------------------------------------------- /scripts/publish/hub.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebase/firebase-functions/849f01cd00e24ac1bf61fd634f0927aa70535892/scripts/publish/hub.enc -------------------------------------------------------------------------------- /scripts/publish/npmrc.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebase/firebase-functions/849f01cd00e24ac1bf61fd634f0927aa70535892/scripts/publish/npmrc.enc -------------------------------------------------------------------------------- /scripts/publish/twitter.json.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebase/firebase-functions/849f01cd00e24ac1bf61fd634f0927aa70535892/scripts/publish/twitter.json.enc -------------------------------------------------------------------------------- /scripts/tweet.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const fs = require("fs"); 4 | const Twitter = require("twitter"); 5 | 6 | function printUsage() { 7 | console.error( 8 | ` 9 | Usage: tweet.js 10 | 11 | Credentials must be stored in "twitter.json" in this directory. 12 | 13 | Arguments: 14 | - version: Version of module that was released. e.g. "1.2.3" 15 | ` 16 | ); 17 | process.exit(1); 18 | } 19 | 20 | function getUrl(version) { 21 | return `https://github.com/firebase/firebase-functions/releases/tag/v${version}`; 22 | } 23 | 24 | if (process.argv.length !== 3) { 25 | console.error("Missing arguments."); 26 | printUsage(); 27 | } 28 | 29 | const version = process.argv.pop(); 30 | if (!version.match(/^\d+\.\d+\.\d+$/)) { 31 | console.error(`Version "${version}" not a version number.`); 32 | printUsage(); 33 | } 34 | 35 | if (!fs.existsSync(`${__dirname}/twitter.json`)) { 36 | console.error("Missing credentials."); 37 | printUsage(); 38 | } 39 | const creds = require("./twitter.json"); 40 | 41 | const client = new Twitter(creds); 42 | 43 | client.post( 44 | "statuses/update", 45 | { status: `v${version} of @Firebase SDK for Cloud Functions is available. Release notes: ${getUrl(version)}` }, 46 | (err) => { 47 | if (err) { 48 | console.error(err); 49 | process.exit(1); 50 | } 51 | } 52 | ); 53 | -------------------------------------------------------------------------------- /spec/common/config.spec.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2017 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import { expect } from "chai"; 24 | import * as fs from "fs"; 25 | import * as process from "process"; 26 | import Sinon = require("sinon"); 27 | 28 | import { firebaseConfig, resetCache } from "../../src/common/config"; 29 | 30 | describe("firebaseConfig()", () => { 31 | let readFileSync: Sinon.SinonStub; 32 | let cwdStub: Sinon.SinonStub; 33 | 34 | before(() => { 35 | readFileSync = Sinon.stub(fs, "readFileSync"); 36 | readFileSync.throws("Unexpected call"); 37 | cwdStub = Sinon.stub(process, "cwd"); 38 | cwdStub.returns("/srv"); 39 | }); 40 | 41 | after(() => { 42 | Sinon.verifyAndRestore(); 43 | }); 44 | 45 | afterEach(() => { 46 | resetCache(); 47 | 48 | delete process.env.FIREBASE_CONFIG; 49 | delete process.env.K_CONFIGURATION; 50 | }); 51 | 52 | it("loads Firebase configs from FIREBASE_CONFIG env variable", () => { 53 | process.env.FIREBASE_CONFIG = JSON.stringify({ 54 | databaseURL: "foo@firebaseio.com", 55 | }); 56 | expect(firebaseConfig()).to.have.property("databaseURL", "foo@firebaseio.com"); 57 | }); 58 | 59 | it("loads Firebase configs from FIREBASE_CONFIG env variable pointing to a file", () => { 60 | const oldEnv = process.env; 61 | (process as any).env = { 62 | ...oldEnv, 63 | FIREBASE_CONFIG: ".firebaseconfig.json", 64 | }; 65 | try { 66 | readFileSync.returns(Buffer.from('{"databaseURL": "foo@firebaseio.com"}')); 67 | expect(firebaseConfig()).to.have.property("databaseURL", "foo@firebaseio.com"); 68 | } finally { 69 | (process as any).env = oldEnv; 70 | } 71 | }); 72 | }); 73 | -------------------------------------------------------------------------------- /spec/common/encoding.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | import { convertInvoker } from "../../src/common/encoding"; 3 | 4 | describe("convertInvoker", () => { 5 | it("should raise an error on empty array", () => { 6 | expect(() => convertInvoker([])).to.throw; 7 | }); 8 | 9 | it("should raise an error on empty string", () => { 10 | expect(() => convertInvoker("")).to.throw; 11 | }); 12 | 13 | it("should raise an error on empty string with service accounts", () => { 14 | expect(() => convertInvoker(["service-account@", ""])).to.throw; 15 | }); 16 | 17 | it("should raise an error on mixing public and service accounts", () => { 18 | expect(() => convertInvoker(["public", "service-account@"])).to.throw; 19 | }); 20 | 21 | it("should raise an error on mixing private and service accounts", () => { 22 | expect(() => convertInvoker(["private", "service-account@"])).to.throw; 23 | }); 24 | 25 | it("should return the correct public invoker", () => { 26 | const invoker = convertInvoker("public"); 27 | 28 | expect(invoker).to.deep.equal(["public"]); 29 | }); 30 | 31 | it("should return the correct private invoker", () => { 32 | const invoker = convertInvoker("private"); 33 | 34 | expect(invoker).to.deep.equal(["private"]); 35 | }); 36 | 37 | it("should return the correct scalar invoker", () => { 38 | const invoker = convertInvoker("service-account@"); 39 | 40 | expect(invoker).to.deep.equal(["service-account@"]); 41 | }); 42 | 43 | it("should return the correct array invoker", () => { 44 | const invoker = convertInvoker(["service-account1@", "service-account2@"]); 45 | 46 | expect(invoker).to.deep.equal(["service-account1@", "service-account2@"]); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /spec/common/metaprogramming.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // This method will fail to compile if value is not of the explicit parameter type. 23 | /* eslint-disable @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-function */ 24 | export function expectType(value: Type) {} 25 | export function expectNever() {} 26 | -------------------------------------------------------------------------------- /spec/common/options.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ignoreUnusedWarning OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | import { ResettableKeys, ResetValue } from "../../src/common/options"; 23 | import { expectNever, expectType } from "./metaprogramming"; 24 | 25 | describe("ResettableKeys", () => { 26 | it("should pick out keys with a type that includes ResetValue", () => { 27 | type A = { a: number; b: ResetValue; c: number | boolean | ResetValue }; 28 | expectType>("b"); 29 | expectType>("c"); 30 | }); 31 | 32 | it("should return an empty type if no keys are resettable", () => { 33 | type A = { a: number }; 34 | expectNever>(); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /spec/common/trace.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | import { extractTraceContext } from "../../src/common/trace"; 3 | 4 | describe("getTraceContext", () => { 5 | it("reutrns undefined given object without trace properties", () => { 6 | expect(extractTraceContext({ foo: "bar" })).to.be.undefined; 7 | }); 8 | 9 | describe("traceparent", () => { 10 | it("extracts trace context with sampling on", () => { 11 | expect( 12 | extractTraceContext({ 13 | traceparent: "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01", 14 | }) 15 | ).to.deep.equal({ 16 | version: "00", 17 | traceId: "0af7651916cd43dd8448eb211c80319c", 18 | parentId: "b7ad6b7169203331", 19 | sample: true, 20 | }); 21 | }); 22 | 23 | it("extracts trace context with sampling off", () => { 24 | expect( 25 | extractTraceContext({ 26 | traceparent: "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-00", 27 | }) 28 | ).to.deep.equal({ 29 | version: "00", 30 | traceId: "0af7651916cd43dd8448eb211c80319c", 31 | parentId: "b7ad6b7169203331", 32 | sample: false, 33 | }); 34 | }); 35 | 36 | it("returns undefined given invalid trace id", () => { 37 | expect(extractTraceContext({ traceparent: "00-0af7651916cd43dd8448eb211c80319c-ABCDEFG-00" })) 38 | .to.be.undefined; 39 | }); 40 | }); 41 | 42 | describe("X-Cloud-Trace-Context", () => { 43 | it("extracts trace context with sampling on", () => { 44 | expect( 45 | extractTraceContext({ 46 | ["X-Cloud-Trace-Context"]: "105445aa7843bc8bf206b12000100000/2450465917091935019;o=1", 47 | }) 48 | ).to.deep.equal({ 49 | version: "00", 50 | traceId: "105445aa7843bc8bf206b12000100000", 51 | parentId: "2201cdc4ba777400", 52 | sample: true, 53 | }); 54 | }); 55 | 56 | it("extracts trace context with sampling on indicated w/ o=3", () => { 57 | expect( 58 | extractTraceContext({ 59 | ["X-Cloud-Trace-Context"]: "105445aa7843bc8bf206b12000100000/2450465917091935019;o=3", 60 | }) 61 | ).to.deep.equal({ 62 | version: "00", 63 | traceId: "105445aa7843bc8bf206b12000100000", 64 | parentId: "2201cdc4ba777400", 65 | sample: true, 66 | }); 67 | }); 68 | 69 | it("extracts trace context with sampling off", () => { 70 | expect( 71 | extractTraceContext({ 72 | ["X-Cloud-Trace-Context"]: "105445aa7843bc8bf206b12000100000/2450465917091935019;o=0", 73 | }) 74 | ).to.deep.equal({ 75 | version: "00", 76 | traceId: "105445aa7843bc8bf206b12000100000", 77 | parentId: "2201cdc4ba777400", 78 | sample: false, 79 | }); 80 | }); 81 | 82 | it("extracts trace context with no sampling info", () => { 83 | expect( 84 | extractTraceContext({ 85 | ["X-Cloud-Trace-Context"]: "105445aa7843bc8bf206b12000100000/2450465917091935019", 86 | }) 87 | ).to.deep.equal({ 88 | version: "00", 89 | traceId: "105445aa7843bc8bf206b12000100000", 90 | parentId: "2201cdc4ba777400", 91 | sample: false, 92 | }); 93 | }); 94 | 95 | it("returns undefined given invalid parentId", () => { 96 | expect( 97 | extractTraceContext({ 98 | ["X-Cloud-Trace-Context"]: "105445aa7843bc8bf206b12000100000/abcedf;o=0", 99 | }) 100 | ).to.be.undefined; 101 | }); 102 | }); 103 | }); 104 | -------------------------------------------------------------------------------- /spec/common/utilities/path.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | import { normalizePath, pathParts } from "../../../src/common/utilities/path"; 3 | 4 | describe("utilities", () => { 5 | describe("path", () => { 6 | describe("#normalizePath", () => { 7 | it("should strip leading and trailing slash", () => { 8 | expect(normalizePath("/my/path/is/{rad}/")).to.eq("my/path/is/{rad}"); 9 | }); 10 | }); 11 | 12 | describe("#pathParts", () => { 13 | it("should turn a path into an array of strings", () => { 14 | expect(pathParts("/foo/bar/baz")).to.deep.equal(["foo", "bar", "baz"]); 15 | }); 16 | 17 | it("should turn a root path, empty string, or null path into an empty array", () => { 18 | expect(pathParts("")).to.deep.equal([]); 19 | expect(pathParts(null)).to.deep.equal([]); 20 | expect(pathParts("/")).to.deep.equal([]); 21 | }); 22 | }); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /spec/fixtures.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | import { ManifestEndpoint } from "../src/runtime/manifest"; 23 | import { RESET_VALUE } from "../src/common/options"; 24 | 25 | export const MINIMAL_V2_ENDPOINT: ManifestEndpoint = { 26 | availableMemoryMb: RESET_VALUE, 27 | concurrency: RESET_VALUE, 28 | ingressSettings: RESET_VALUE, 29 | maxInstances: RESET_VALUE, 30 | minInstances: RESET_VALUE, 31 | serviceAccountEmail: RESET_VALUE, 32 | timeoutSeconds: RESET_VALUE, 33 | vpc: RESET_VALUE, 34 | }; 35 | 36 | export const MINIMAL_V1_ENDPOINT: ManifestEndpoint = { 37 | availableMemoryMb: RESET_VALUE, 38 | ingressSettings: RESET_VALUE, 39 | maxInstances: RESET_VALUE, 40 | minInstances: RESET_VALUE, 41 | serviceAccountEmail: RESET_VALUE, 42 | timeoutSeconds: RESET_VALUE, 43 | vpc: RESET_VALUE, 44 | }; 45 | 46 | export const FULL_ENDPOINT: ManifestEndpoint = { 47 | region: ["us-west1"], 48 | availableMemoryMb: 512, 49 | timeoutSeconds: 60, 50 | minInstances: 1, 51 | maxInstances: 3, 52 | concurrency: 20, 53 | vpc: { 54 | connector: "aConnector", 55 | egressSettings: "ALL_TRAFFIC", 56 | }, 57 | serviceAccountEmail: "root@", 58 | ingressSettings: "ALLOW_ALL", 59 | cpu: "gcf_gen1", 60 | labels: { 61 | hello: "world", 62 | }, 63 | secretEnvironmentVariables: [{ key: "MY_SECRET" }], 64 | }; 65 | -------------------------------------------------------------------------------- /spec/fixtures/credential/jwk.json: -------------------------------------------------------------------------------- 1 | { 2 | "p": "9cTVRzGXbDfhIMQW9gXtWveDW0u_Hvwnbjx7TRPgSfawZ0MjgKfSbnyHTDXiqM1ifcN_Nk58KJ-PG9eZ7V7_mfTUnPv2puDaecn-kgHobnTJMoBR9hpzyyMpyNJuMvX4kqE7Qh8iFMBK_-p8ICiW15gK5WykswIKfIOkUZc52XM", 3 | "kty": "RSA", 4 | "q": "pYdUNL244sCoc4XrONKlu787AiHrjFFLHdTjoFLbvxSpszXM8iSjoiFAM_MCF-uWks2iBVDw9wlG4MB7MfNf_fD0i1wqyknSOtfMxknU7D4eU_Sp6tI99Jl8f_GAzODK__k_0MpqqXgZmJbUvYuIXMiha-5lddz8ENa4pYpbr7M", 5 | "d": "MpkXqjmjvzwfmlq3o0uZAXjeeAnBlYQSNaSllBWKepgPjg4FxFIt_BlXex1NeP0npNy_oCgaM_x7NiALaaPhwPK52lhYThc-xomCic1KDkyPecODTPXi4Iw94Q_gp442SYMWz2ZktS-2DgXc3599fGHkY80u0rHNSO8ptdk8SUDUIZ82ZQ3pBhClF_uY3c1jZLuqVgCwKksInZmNPnv3ge088wmQC26t0Ph5u1HU6lISgaqZ8ol23iNWJPf4UEi8Twy1a73nphQS-y1yK9UC3c5Knk-WI2TMmjlxqC02ZjKqnRDxElTj9kpodasPRHRV_KJI8rTaStgxd7peMFODzQ", 6 | "e": "AQAB", 7 | "use": "sig", 8 | "kid": "a12KBE", 9 | "qi": "aJCrZVWeOjxYmMBTTI7aJhxcvvfS3I5Q7wwN4Oyb1rJZ4fgGYjDohlzeZz_3fNantPAgcDbzJfa3XS327sHJGaAVqvDugZUgyHeLZGzXGs-_mlL72wzcfvTa1C9_lIndLNZJle5_mg3xJAqRKV0s7kymSdYt0wL5fDaqo5SDNqQ", 10 | "dp": "haBk2hWzoApt5HPZjCDC4g_rosr3enBdPAm0fL8O1whC95JAjmYw-xPIOH6f42nwYDLYSv23chr3I4tBTRe2382HgGdav3dIMqnKOTbCWrQy5LtyVN4jEVLoGCGZ-ylT4t25K4Vj8WZwIN8saAvJoCUx33YHwrCcZQDqadZQhNM", 11 | "alg": "RS256", 12 | "dq": "j6NdeN7hnzMbehPNyGNSmhcZd4JDymGI03w3gpokQi4GDJM1IzKUJE7CTdIkEOnIod97Jy3TzCrqrIGa5f-RXuVG79-s6hkhKxq0gaTz9YT6AFShVjnWtXizRrskz6SJw5JgxCfCYwjq_TR1q313eTxIh0Y6GQsIWPxbApuLcG0", 13 | "n": "nunJGpOcPvVsP3q-NLgf3H6OycPhnXUxywMR2_H_JJP7BUIDSsYcOGBTFe7OphHYfyb1Gs14yAER243swndpNbQkuDJhj9a9kK6dJZmPGmvCySk_E5URj6MimZg1MBbwhsVAbRp2uerESZuoRrfdTdV87E3pGyg6Irl0IXRjy5w9SsFjjIi7E-Qxpf3TcNNjfVRLj9V2bSzmS7hlsPKBhDon0tWecuNKoNNMiGI46mz_MSUa2y1lPV6Cqhf1su_TRd7N7u9eP7xWArr7wqtqHiFTZ3qp1xoA_dr_xv_Ao2kBtohZiAFLV-PQShprSN5fafztRZFkSEF0m2tUkvmoaQ" 14 | } 15 | -------------------------------------------------------------------------------- /spec/fixtures/credential/key.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | declare module '*key.json' { 3 | const type: string; 4 | const user_id: string; 5 | const project_id: string; 6 | const key_id: string; 7 | const private_key: string; 8 | const public_key: string; 9 | const client_email: string; 10 | } 11 | -------------------------------------------------------------------------------- /spec/fixtures/credential/key.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "service_account", 3 | "project_id": "project_id", 4 | "user_id": "SomeUID", 5 | "key_id": "THIS_IS_A_KID", 6 | "private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAwJENcRev+eXZKvhhWLiV3Lz2MvO+naQRHo59g3vaNQnbgyduN/L4krlr\nJ5c6FiikXdtJNb/QrsAHSyJWCu8j3T9CruiwbidGAk2W0RuViTVspjHUTsIHExx9euWM0Uom\nGvYkoqXahdhPL/zViVSJt+Rt8bHLsMvpb8RquTIb9iKY3SMV2tCofNmyCSgVbghq/y7lKORt\nV/IRguWs6R22fbkb0r2MCYoNAbZ9dqnbRIFNZBC7itYtUoTEresRWcyFMh0zfAIJycWOJlVL\nDLqkY2SmIx8u7fuysCg1wcoSZoStuDq02nZEMw1dx8HGzE0hynpHlloRLByuIuOAfMCCYwID\nAQABAoIBADFtihu7TspAO0wSUTpqttzgC/nsIsNn95T2UjVLtyjiDNxPZLUrwq42tdCFur0x\nVW9Z+CK5x6DzXWvltlw8IeKKeF1ZEOBVaFzy+YFXKTz835SROcO1fgdjyrme7lRSShGlmKW/\nGKY+baUNquoDLw5qreXaE0SgMp0jt5ktyYuVxvhLDeV4omw2u6waoGkifsGm8lYivg5l3VR7\nw2IVOvYZTt4BuSYVwOM+qjwaS1vtL7gv0SUjrj85Ja6zERRdFiITDhZw6nsvacr9/+/aut9E\naL/koSSb62g5fntQMEwoT4hRnjPnAedmorM9Rhddh2TB3ZKTBbMN1tUk3fJxOuECgYEA+z6l\neSaAcZ3qvwpntcXSpwwJ0SSmzLTH2RJNf+Ld3eBHiSvLTG53dWB7lJtF4R1KcIwf+KGcOFJv\nsnepzcZBylRvT8RrAAkV0s9OiVm1lXZyaepbLg4GGFJBPi8A6VIAj7zYknToRApdW0s1x/XX\nChewfJDckqsevTMovdbg8YkCgYEAxDYX+3mfvv/opo6HNNY3SfVunM+4vVJL+n8gWZ2w9kz3\nQ9Ub9YbRmI7iQaiVkO5xNuoG1n9bM+3Mnm84aQ1YeNT01YqeyQsipP5Wi+um0PzYTaBw9RO+\n8Gh6992OwlJiRtFk5WjalNWOxY4MU0ImnJwIfKQlUODvLmcixm68NYsCgYEAuAqI3jkk55Vd\nKvotREsX5wP7gPePM+7NYiZ1HNQL4Ab1f/bTojZdTV8Sx6YCR0fUiqMqnE+OBvfkGGBtw22S\nLesx6sWf99Ov58+x4Q0U5dpxL0Lb7d2Z+2Dtp+Z4jXFjNeeI4ae/qG/LOR/b0pE0J5F415ap\n7Mpq5v89vepUtrkCgYAjMXytu4v+q1Ikhc4UmRPDrUUQ1WVSd+9u19yKlnFGTFnRjej86hiw\nH3jPxBhHra0a53EgiilmsBGSnWpl1WH4EmJz5vBCKUAmjgQiBrueIqv9iHiaTNdjsanUyaWw\njyxXfXl2eI80QPXh02+8g1H/pzESgjK7Rg1AqnkfVH9nrwKBgQDJVxKBPTw9pigYMVt9iHrR\niCl9zQVjRMbWiPOc0J56+/5FZYm/AOGl9rfhQ9vGxXZYZiOP5FsNkwt05Y1UoAAH4B4VQwbL\nqod71qOcI0ywgZiIR87CYw40gzRfjWnN+YEEW1qfyoNLilEwJB8iB/T+ZePHGmJ4MmQ/cTn9\nxpdLXA==\n-----END RSA PRIVATE KEY-----\n", 7 | "public_key": "-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAwJENcRev+eXZKvhhWLiV3Lz2MvO+naQRHo59g3vaNQnbgyduN/L4krlrJ5c6\nFiikXdtJNb/QrsAHSyJWCu8j3T9CruiwbidGAk2W0RuViTVspjHUTsIHExx9euWM0UomGvYk\noqXahdhPL/zViVSJt+Rt8bHLsMvpb8RquTIb9iKY3SMV2tCofNmyCSgVbghq/y7lKORtV/IR\nguWs6R22fbkb0r2MCYoNAbZ9dqnbRIFNZBC7itYtUoTEresRWcyFMh0zfAIJycWOJlVLDLqk\nY2SmIx8u7fuysCg1wcoSZoStuDq02nZEMw1dx8HGzE0hynpHlloRLByuIuOAfMCCYwIDAQAB\n-----END RSA PUBLIC KEY-----\n", 8 | "client_email": "foo@project_id.iam.gserviceaccount.com" 9 | } 10 | -------------------------------------------------------------------------------- /spec/fixtures/credential/unparsable.key.json: -------------------------------------------------------------------------------- 1 | { 2 | foo: bar 3 | } 4 | -------------------------------------------------------------------------------- /spec/fixtures/env/env.json: -------------------------------------------------------------------------------- 1 | { 2 | "firebase": { 3 | "database": { 4 | "url": "https://example.firebaseio.com", 5 | "secret": "123SECRET" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /spec/fixtures/extsdk/local/index.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * TaskQueue/LifecycleEvent/RuntimeStatus Tester SDK for backfill@0.0.2 3 | * 4 | * When filing bugs or feature requests please specify: 5 | * "Extensions SDK v1.0.0 for Local extension. 6 | * https://github.com/firebase/firebase-tools/issues/new/choose 7 | * 8 | * GENERATED FILE. DO NOT EDIT. 9 | */ 10 | export type DoBackfillParam = "True" | "False"; 11 | export type LocationParam = "us-central1" | "us-east1" | "us-east4" | "europe-west1" | "europe-west2" | "europe-west3" | "asia-east2" | "asia-northeast1"; 12 | /** 13 | * Parameters for backfill@0.0.2 extension 14 | */ 15 | export interface BackfillParams { 16 | /** 17 | * Do a backfill 18 | */ 19 | DO_BACKFILL: DoBackfillParam; 20 | /** 21 | * Cloud Functions location 22 | */ 23 | LOCATION: LocationParam; 24 | } 25 | export declare function backfill(instanceId: string, params: BackfillParams): Backfill; 26 | /** 27 | * TaskQueue/LifecycleEvent/RuntimeStatus Tester 28 | * A tester for the TaskQueue/LCE/RuntimeStatus project 29 | */ 30 | export declare class Backfill { 31 | private instanceId; 32 | private params; 33 | readonly FIREBASE_EXTENSION_LOCAL_PATH = "./functions/generated/extensions/local/backfill/0.0.2/src"; 34 | constructor(instanceId: string, params: BackfillParams); 35 | getInstanceId(): string; 36 | getParams(): BackfillParams; 37 | } -------------------------------------------------------------------------------- /spec/fixtures/extsdk/local/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * TaskQueue/LifecycleEvent/RuntimeStatus Tester SDK for extensions-try-backfill3@0.0.2 4 | * 5 | * When filing bugs or feature requests please specify: 6 | * "Extensions SDK v1.0.0 for Local extension. 7 | * https://github.com/firebase/firebase-tools/issues/new/choose 8 | * 9 | * GENERATED FILE. DO NOT EDIT. 10 | */ 11 | Object.defineProperty(exports, "__esModule", { value: true }); 12 | exports.backfill = exports.backfill = void 0; 13 | function backfill(instanceId, params) { 14 | return new Backfill(instanceId, params); 15 | } 16 | exports.backfill = backfill; 17 | /** 18 | * TaskQueue/LifecycleEvent/RuntimeStatus Tester 19 | * A tester for the TaskQueue/LCE/RuntimeStatus project 20 | */ 21 | class Backfill { 22 | constructor(instanceId, params) { 23 | this.instanceId = instanceId; 24 | this.params = params; 25 | this.FIREBASE_EXTENSION_LOCAL_PATH = "./functions/generated/extensions/local/backfill/0.0.2/src"; 26 | } 27 | getInstanceId() { return this.instanceId; } 28 | getParams() { return this.params; } 29 | } 30 | exports.Backfill = Backfill; 31 | -------------------------------------------------------------------------------- /spec/fixtures/extsdk/local/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@firebase-extensions/local-backfill-sdk", 3 | "main": "./index.js" 4 | } -------------------------------------------------------------------------------- /spec/fixtures/extsdk/translate/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@firebase-extensions/firebase-firestore-translate-text-sdk", 3 | "main": "./index.js" 4 | } -------------------------------------------------------------------------------- /spec/fixtures/sources/commonjs-grouped/g1.js: -------------------------------------------------------------------------------- 1 | const functions = require("../../../../src/v1"); 2 | 3 | exports.groupedhttp = functions.https.onRequest((req, resp) => { 4 | resp.status(200).send("PASS"); 5 | }); 6 | 7 | exports.groupedcallable = functions.https.onCall(() => { 8 | return "PASS"; 9 | }); 10 | -------------------------------------------------------------------------------- /spec/fixtures/sources/commonjs-grouped/index.js: -------------------------------------------------------------------------------- 1 | const functions = require("../../../../src/v1"); 2 | const functionsv2 = require("../../../../src/v2"); 3 | const firestoreTranslateText = require("../../extsdk/translate").firestoreTranslateText; 4 | const backfill = require("../../extsdk/local").backfill; 5 | 6 | 7 | exports.v1http = functions.https.onRequest((req, resp) => { 8 | resp.status(200).send("PASS"); 9 | }); 10 | 11 | exports.v1callable = functions.https.onCall(() => { 12 | return "PASS"; 13 | }); 14 | 15 | exports.v2http = functionsv2.https.onRequest((req, resp) => { 16 | resp.status(200).send("PASS"); 17 | }); 18 | 19 | exports.v2callable = functionsv2.https.onCall(() => { 20 | return "PASS"; 21 | }); 22 | 23 | // A Firebase extension by ref 24 | const extRef1 = firestoreTranslateText("extRef1", { 25 | "COLLECTION_PATH": "collection1", 26 | "INPUT_FIELD_NAME": "input1", 27 | "LANGUAGES": "de,es", 28 | "OUTPUT_FIELD_NAME": "translated", 29 | "_EVENT_ARC_REGION": "us-central1", 30 | "_FUNCTION_LOCATION": "us-central1", 31 | }); 32 | exports.extRef1 = extRef1; 33 | 34 | // A Firebase function defined by extension event 35 | const ttOnStart = extRef1.onStart((event) => { 36 | console.log("onStart got event: " + JSON.stringify(event, null, 2)); 37 | }); 38 | exports.ttOnStart = ttOnStart; 39 | 40 | // A Firebase extension by localPath 41 | exports.extLocal2 = backfill("extLocal2", { 42 | DO_BACKFILL: "False", 43 | LOCATION: "us-central1", 44 | }); 45 | 46 | exports.g1 = require("./g1"); 47 | -------------------------------------------------------------------------------- /spec/fixtures/sources/commonjs-grouped/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "commonjs-grouped" 3 | } 4 | -------------------------------------------------------------------------------- /spec/fixtures/sources/commonjs-main/functions.js: -------------------------------------------------------------------------------- 1 | const functions = require("../../../../src/v1"); 2 | const functionsv2 = require("../../../../src/v2"); 3 | const firestoreTranslateText = require("../../extsdk/translate").firestoreTranslateText; 4 | const backfill = require("../../extsdk/local").backfill; 5 | 6 | exports.v1http = functions.https.onRequest((req, resp) => { 7 | resp.status(200).send("PASS"); 8 | }); 9 | 10 | exports.v1callable = functions.https.onCall(() => { 11 | return "PASS"; 12 | }); 13 | 14 | exports.v2http = functionsv2.https.onRequest((req, resp) => { 15 | resp.status(200).send("PASS"); 16 | }); 17 | 18 | exports.v2callable = functionsv2.https.onCall(() => { 19 | return "PASS"; 20 | }); 21 | 22 | // A Firebase extension by ref 23 | const extRef1 = firestoreTranslateText("extRef1", { 24 | "COLLECTION_PATH": "collection1", 25 | "INPUT_FIELD_NAME": "input1", 26 | "LANGUAGES": "de,es", 27 | "OUTPUT_FIELD_NAME": "translated", 28 | "_EVENT_ARC_REGION": "us-central1", 29 | "_FUNCTION_LOCATION": "us-central1", 30 | }); 31 | exports.extRef1 = extRef1; 32 | 33 | // A Firebase function defined by extension event 34 | const ttOnStart = extRef1.onStart((event) => { 35 | console.log("onStart got event: " + JSON.stringify(event, null, 2)); 36 | }); 37 | exports.ttOnStart = ttOnStart; 38 | 39 | // A Firebase extension by localPath 40 | exports.extLocal2 = backfill("extLocal2", { 41 | DO_BACKFILL: "False", 42 | LOCATION: "us-central1", 43 | }); -------------------------------------------------------------------------------- /spec/fixtures/sources/commonjs-main/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "commonjs-main", 3 | "main": "functions.js" 4 | } 5 | -------------------------------------------------------------------------------- /spec/fixtures/sources/commonjs-parametrized-fields/index.js: -------------------------------------------------------------------------------- 1 | const functions = require("../../../../src/v1/index"); 2 | const functionsv2 = require("../../../../src/v2/index"); 3 | const params = require("../../../../src/params"); 4 | params.clearParams(); 5 | 6 | const stringParam = params.defineString("STRING_PARAM"); 7 | const intParam = params.defineInt("INT_PARAM"); 8 | const boolParam = params.defineBoolean("BOOLEAN_PARAM"); 9 | 10 | exports.v1http = functions.runWith({ 11 | minInstances: intParam, 12 | maxInstances: intParam, 13 | memory: intParam, 14 | timeoutSeconds: intParam, 15 | serviceAccount: stringParam, 16 | omit: boolParam 17 | }).https.onRequest((req, resp) => { 18 | resp.status(200).send("Hello world!"); 19 | }); 20 | 21 | exports.v2http = functionsv2.https.onRequest({ 22 | minInstances: intParam, 23 | maxInstances: intParam, 24 | memory: intParam, 25 | timeoutSeconds: intParam, 26 | serviceAccount: stringParam, 27 | omit: boolParam 28 | }, (req, resp) => { 29 | resp.status(200).send("Hello world!"); 30 | }); 31 | -------------------------------------------------------------------------------- /spec/fixtures/sources/commonjs-parametrized-fields/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "commonjs-parametrized-fields" 3 | } 4 | -------------------------------------------------------------------------------- /spec/fixtures/sources/commonjs-params/index.js: -------------------------------------------------------------------------------- 1 | const functions = require("../../../../src/v1/index"); 2 | const functionsv2 = require("../../../../src/v2/index"); 3 | const firestoreTranslateText = require("../../extsdk/translate").firestoreTranslateText; 4 | const backfill = require("../../extsdk/local").backfill; 5 | const params = require("../../../../src/params"); 6 | 7 | params.defineString("BORING"); 8 | const foo = params.defineString("FOO", { input: { text: { validationRegex: "w+" } } }); 9 | const bar = params.defineString("BAR", { default: foo, label: "asdf" }); 10 | params.defineString("BAZ", { input: { select: { options: [{ value: "a" }, { value: "b" }] } } }); 11 | 12 | params.defineInt("AN_INT", { default: bar.equals("qux").thenElse(0, 1) }); 13 | params.defineInt("ANOTHER_INT", { 14 | input: { 15 | select: { 16 | options: [ 17 | { label: "a", value: -2 }, 18 | { label: "b", value: 2 }, 19 | ], 20 | }, 21 | }, 22 | }); 23 | 24 | params.defineList("LIST_PARAM", {input: { multiSelect: { options: [{ value: "c" }, { value: "d" }, { value: "e" }]}}}) 25 | 26 | params.defineSecret("SUPER_SECRET_FLAG"); 27 | 28 | // N.B: invocation of the precanned internal params should not affect the manifest 29 | 30 | exports.v1http = functions.https.onRequest((req, resp) => { 31 | resp.status(200).send(params.projectID); 32 | }); 33 | 34 | exports.v1callable = functions.https.onCall(() => { 35 | return params.databaseURL; 36 | }); 37 | 38 | exports.v2http = functionsv2.https.onRequest((req, resp) => { 39 | resp.status(200).send(params.gcloudProject); 40 | }); 41 | 42 | exports.v2callable = functionsv2.https.onCall(() => { 43 | return params.databaseURL; 44 | }); 45 | 46 | // A Firebase extension by ref 47 | const extRef1 = firestoreTranslateText("extRef1", { 48 | "COLLECTION_PATH": "collection1", 49 | "INPUT_FIELD_NAME": "input1", 50 | "LANGUAGES": "de,es", 51 | "OUTPUT_FIELD_NAME": "translated", 52 | "_EVENT_ARC_REGION": "us-central1", 53 | "_FUNCTION_LOCATION": "us-central1", 54 | }); 55 | exports.extRef1 = extRef1; 56 | 57 | // A Firebase function defined by extension event 58 | const ttOnStart = extRef1.onStart((event) => { 59 | console.log("onStart got event: " + JSON.stringify(event, null, 2)); 60 | }); 61 | exports.ttOnStart = ttOnStart; 62 | 63 | // A Firebase extension by localPath 64 | exports.extLocal2 = backfill("extLocal2", { 65 | DO_BACKFILL: "False", 66 | LOCATION: "us-central1", 67 | }); 68 | -------------------------------------------------------------------------------- /spec/fixtures/sources/commonjs-params/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "commonjs-params" 3 | } 4 | -------------------------------------------------------------------------------- /spec/fixtures/sources/commonjs/index.js: -------------------------------------------------------------------------------- 1 | const functions = require("../../../../src/v1"); 2 | const functionsv2 = require("../../../../src/v2"); 3 | const firestoreTranslateText = require("../../extsdk/translate").firestoreTranslateText; 4 | const backfill = require("../../extsdk/local").backfill; 5 | 6 | exports.v1http = functions.https.onRequest((req, resp) => { 7 | resp.status(200).send("PASS"); 8 | }); 9 | 10 | exports.v1callable = functions.https.onCall(() => { 11 | return "PASS"; 12 | }); 13 | 14 | exports.v2http = functionsv2.https.onRequest((req, resp) => { 15 | resp.status(200).send("PASS"); 16 | }); 17 | 18 | exports.v2callable = functionsv2.https.onCall(() => { 19 | return "PASS"; 20 | }); 21 | 22 | // A Firebase extension by ref 23 | const extRef1 = firestoreTranslateText("extRef1", { 24 | "COLLECTION_PATH": "collection1", 25 | "INPUT_FIELD_NAME": "input1", 26 | "LANGUAGES": "de,es", 27 | "OUTPUT_FIELD_NAME": "translated", 28 | "_EVENT_ARC_REGION": "us-central1", 29 | "_FUNCTION_LOCATION": "us-central1", 30 | }); 31 | exports.extRef1 = extRef1; 32 | 33 | // A Firebase function defined by extension event 34 | const ttOnStart = extRef1.onStart((event) => { 35 | console.log("onStart got event: " + JSON.stringify(event, null, 2)); 36 | }); 37 | exports.ttOnStart = ttOnStart; 38 | 39 | // A Firebase extension by localPath 40 | exports.extLocal2 = backfill("extLocal2", { 41 | DO_BACKFILL: "False", 42 | LOCATION: "us-central1", 43 | }); -------------------------------------------------------------------------------- /spec/fixtures/sources/commonjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "commonjs" 3 | } 4 | -------------------------------------------------------------------------------- /spec/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended", 3 | "rules": { 4 | "quotemark": [true, "single", "avoid-escape"], 5 | "interface-name": [false], 6 | "variable-name": [true, "check-format", "allow-leading-underscore"], 7 | "object-literal-sort-keys": false, 8 | "whitespace": [true], 9 | "member-access": [false], 10 | "no-string-literal": false, 11 | "no-console": [false], 12 | "no-namespace": [false] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /spec/v1/config.spec.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2017 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import { expect } from "chai"; 24 | import * as fs from "fs"; 25 | import * as process from "process"; 26 | import Sinon = require("sinon"); 27 | 28 | import { config, resetCache } from "../../src/v1/config"; 29 | 30 | describe("config()", () => { 31 | let readFileSync: Sinon.SinonStub; 32 | let cwdStub: Sinon.SinonStub; 33 | 34 | before(() => { 35 | readFileSync = Sinon.stub(fs, "readFileSync"); 36 | readFileSync.throws("Unexpected call"); 37 | cwdStub = Sinon.stub(process, "cwd"); 38 | cwdStub.returns("/srv"); 39 | }); 40 | 41 | after(() => { 42 | Sinon.verifyAndRestore(); 43 | }); 44 | 45 | afterEach(() => { 46 | resetCache(); 47 | delete process.env.FIREBASE_CONFIG; 48 | delete process.env.CLOUD_RUNTIME_CONFIG; 49 | delete process.env.K_CONFIGURATION; 50 | }); 51 | 52 | it("will never load in GCFv2", () => { 53 | const json = JSON.stringify({ 54 | foo: "bar", 55 | firebase: {}, 56 | }); 57 | readFileSync.withArgs("/srv/.runtimeconfig.json").returns(Buffer.from(json)); 58 | 59 | process.env.K_CONFIGURATION = "my-service"; 60 | expect(config).to.throw(Error, /transition to using environment variables/); 61 | }); 62 | 63 | it("loads config values from .runtimeconfig.json", () => { 64 | const json = JSON.stringify({ 65 | foo: "bar", 66 | firebase: {}, 67 | }); 68 | readFileSync.withArgs("/srv/.runtimeconfig.json").returns(Buffer.from(json)); 69 | const loaded = config(); 70 | expect(loaded).to.not.have.property("firebase"); 71 | expect(loaded).to.have.property("foo", "bar"); 72 | }); 73 | }); 74 | -------------------------------------------------------------------------------- /spec/v1/providers/fixtures.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | import { ManifestEndpoint } from "../../../src/runtime/manifest"; 23 | import * as functions from "../../../src/v1"; 24 | import * as options from "../../../src/v2/options"; 25 | 26 | export const MINIMIAL_TASK_QUEUE_TRIGGER: ManifestEndpoint["taskQueueTrigger"] = { 27 | rateLimits: { 28 | maxConcurrentDispatches: functions.RESET_VALUE, 29 | maxDispatchesPerSecond: functions.RESET_VALUE, 30 | }, 31 | retryConfig: { 32 | maxAttempts: functions.RESET_VALUE, 33 | maxBackoffSeconds: functions.RESET_VALUE, 34 | maxDoublings: functions.RESET_VALUE, 35 | maxRetrySeconds: functions.RESET_VALUE, 36 | minBackoffSeconds: functions.RESET_VALUE, 37 | }, 38 | }; 39 | 40 | export const MINIMAL_SCHEDULE_TRIGGER: ManifestEndpoint["scheduleTrigger"] = { 41 | schedule: "", 42 | timeZone: options.RESET_VALUE, 43 | retryConfig: { 44 | retryCount: options.RESET_VALUE, 45 | maxRetryDuration: options.RESET_VALUE, 46 | maxBackoffDuration: options.RESET_VALUE, 47 | minBackoffDuration: options.RESET_VALUE, 48 | maxDoublings: options.RESET_VALUE, 49 | }, 50 | }; 51 | -------------------------------------------------------------------------------- /spec/v1/utils.spec.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2017 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import { expect } from "chai"; 24 | import { applyChange } from "../../src/common/utilities/utils"; 25 | 26 | describe("utils", () => { 27 | describe(".applyChange(from: any, to: any): any", () => { 28 | it("should return the to value for non-object values of from and to", () => { 29 | expect(applyChange({ a: "b" }, null)).to.eq(null); 30 | expect(applyChange(null, { a: "b" })).to.deep.equal({ a: "b" }); 31 | expect(applyChange(23, null)).to.be.null; 32 | }); 33 | 34 | it("should return the merged value of two objects", () => { 35 | const from = { a: { b: "foo", c: 23, d: 444 }, d: { e: 42 } }; 36 | const to: any = { a: { b: "bar", c: null }, d: null, e: { f: "g" } }; 37 | const result = { a: { b: "bar", d: 444 }, e: { f: "g" } }; 38 | expect(applyChange(from, to)).to.deep.equal(result); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /spec/v2/params.spec.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebase/firebase-functions/849f01cd00e24ac1bf61fd634f0927aa70535892/spec/v2/params.spec.ts -------------------------------------------------------------------------------- /spec/v2/providers/fixtures.ts: -------------------------------------------------------------------------------- 1 | import { ManifestEndpoint } from "../../../src/runtime/manifest"; 2 | import { TriggerAnnotation } from "../../../src/v2/core"; 3 | import * as options from "../../../src/v2/options"; 4 | 5 | export { MINIMAL_V1_ENDPOINT, MINIMAL_V2_ENDPOINT } from "../../fixtures"; 6 | 7 | export const FULL_OPTIONS: options.GlobalOptions = { 8 | region: "us-west1", 9 | memory: "512MiB", 10 | timeoutSeconds: 60, 11 | minInstances: 1, 12 | maxInstances: 3, 13 | concurrency: 20, 14 | vpcConnector: "aConnector", 15 | vpcConnectorEgressSettings: "ALL_TRAFFIC", 16 | serviceAccount: "root@", 17 | ingressSettings: "ALLOW_ALL", 18 | cpu: "gcf_gen1", 19 | labels: { 20 | hello: "world", 21 | }, 22 | secrets: ["MY_SECRET"], 23 | }; 24 | 25 | export const FULL_TRIGGER: TriggerAnnotation = { 26 | platform: "gcfv2", 27 | regions: ["us-west1"], 28 | availableMemoryMb: 512, 29 | timeout: "60s", 30 | minInstances: 1, 31 | maxInstances: 3, 32 | concurrency: 20, 33 | vpcConnector: "aConnector", 34 | vpcConnectorEgressSettings: "ALL_TRAFFIC", 35 | serviceAccountEmail: "root@aProject.iam.gserviceaccount.com", 36 | ingressSettings: "ALLOW_ALL", 37 | labels: { 38 | hello: "world", 39 | }, 40 | secrets: ["MY_SECRET"], 41 | }; 42 | 43 | export const FULL_ENDPOINT: ManifestEndpoint = { 44 | platform: "gcfv2", 45 | region: ["us-west1"], 46 | availableMemoryMb: 512, 47 | timeoutSeconds: 60, 48 | minInstances: 1, 49 | maxInstances: 3, 50 | concurrency: 20, 51 | vpc: { 52 | connector: "aConnector", 53 | egressSettings: "ALL_TRAFFIC", 54 | }, 55 | serviceAccountEmail: "root@", 56 | ingressSettings: "ALLOW_ALL", 57 | cpu: "gcf_gen1", 58 | labels: { 59 | hello: "world", 60 | }, 61 | secretEnvironmentVariables: [{ key: "MY_SECRET" }], 62 | }; 63 | -------------------------------------------------------------------------------- /spec/v2/providers/remoteConfig.spec.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import { expect } from "chai"; 24 | import * as remoteConfig from "../../../src/v2/providers/remoteConfig"; 25 | import * as options from "../../../src/v2/options"; 26 | import { MINIMAL_V2_ENDPOINT } from "../../fixtures"; 27 | import { CloudEvent, onInit } from "../../../src/v2/core"; 28 | 29 | describe("onConfigUpdated", () => { 30 | afterEach(() => { 31 | options.setGlobalOptions({}); 32 | }); 33 | 34 | it("should create a function with a handler", async () => { 35 | const fn = remoteConfig.onConfigUpdated(() => 2); 36 | 37 | expect(fn.__endpoint).to.deep.eq({ 38 | ...MINIMAL_V2_ENDPOINT, 39 | platform: "gcfv2", 40 | labels: {}, 41 | eventTrigger: { 42 | eventType: remoteConfig.eventType, 43 | eventFilters: {}, 44 | retry: false, 45 | }, 46 | }); 47 | await expect(fn(1 as any)).to.eventually.eq(2); 48 | }); 49 | 50 | it("should create a function with opts and a handler", async () => { 51 | options.setGlobalOptions({ 52 | memory: "512MiB", 53 | region: "us-west1", 54 | }); 55 | 56 | const fn = remoteConfig.onConfigUpdated( 57 | { 58 | region: "us-central1", 59 | retry: true, 60 | }, 61 | () => 2 62 | ); 63 | 64 | expect(fn.__endpoint).to.deep.eq({ 65 | ...MINIMAL_V2_ENDPOINT, 66 | platform: "gcfv2", 67 | availableMemoryMb: 512, 68 | region: ["us-central1"], 69 | labels: {}, 70 | eventTrigger: { 71 | eventType: remoteConfig.eventType, 72 | eventFilters: {}, 73 | retry: true, 74 | }, 75 | }); 76 | await expect(fn(1 as any)).to.eventually.eq(2); 77 | }); 78 | 79 | it("calls init function", async () => { 80 | const event: CloudEvent = { 81 | specversion: "1.0", 82 | id: "id", 83 | source: "source", 84 | type: "type", 85 | time: "now", 86 | data: "data", 87 | }; 88 | 89 | let hello; 90 | onInit(() => (hello = "world")); 91 | expect(hello).to.be.undefined; 92 | await remoteConfig.onConfigUpdated(() => null)(event); 93 | expect(hello).to.equal("world"); 94 | }); 95 | }); 96 | -------------------------------------------------------------------------------- /spec/v2/providers/testLab.spec.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import { expect } from "chai"; 24 | import * as testLab from "../../../src/v2/providers/testLab"; 25 | import * as options from "../../../src/v2/options"; 26 | import { MINIMAL_V2_ENDPOINT } from "../../fixtures"; 27 | import { CloudEvent, onInit } from "../../../src/v2/core"; 28 | 29 | describe("onTestMatrixCompleted", () => { 30 | afterEach(() => { 31 | options.setGlobalOptions({}); 32 | }); 33 | 34 | it("should create a function with a handler", () => { 35 | const fn = testLab.onTestMatrixCompleted(() => 2); 36 | 37 | expect(fn.__endpoint).to.deep.eq({ 38 | ...MINIMAL_V2_ENDPOINT, 39 | platform: "gcfv2", 40 | labels: {}, 41 | eventTrigger: { 42 | eventType: testLab.eventType, 43 | eventFilters: {}, 44 | retry: false, 45 | }, 46 | }); 47 | expect(fn.run(1 as any)).to.eq(2); 48 | }); 49 | 50 | it("should create a function with opts and a handler", () => { 51 | options.setGlobalOptions({ 52 | memory: "512MiB", 53 | region: "us-west1", 54 | }); 55 | 56 | const fn = testLab.onTestMatrixCompleted( 57 | { 58 | region: "us-central1", 59 | retry: true, 60 | }, 61 | () => 2 62 | ); 63 | 64 | expect(fn.__endpoint).to.deep.eq({ 65 | ...MINIMAL_V2_ENDPOINT, 66 | platform: "gcfv2", 67 | availableMemoryMb: 512, 68 | region: ["us-central1"], 69 | labels: {}, 70 | eventTrigger: { 71 | eventType: testLab.eventType, 72 | eventFilters: {}, 73 | retry: true, 74 | }, 75 | }); 76 | expect(fn.run(1 as any)).to.eq(2); 77 | }); 78 | 79 | it("calls init function", async () => { 80 | const event: CloudEvent = { 81 | specversion: "1.0", 82 | id: "id", 83 | source: "source", 84 | type: "type", 85 | time: "now", 86 | data: "data", 87 | }; 88 | 89 | let hello; 90 | onInit(() => (hello = "world")); 91 | expect(hello).to.be.undefined; 92 | await testLab.onTestMatrixCompleted(() => null)(event); 93 | expect(hello).to.equal("world"); 94 | }); 95 | }); 96 | -------------------------------------------------------------------------------- /src/bin/firebase-functions.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // The MIT License (MIT) 4 | // 5 | // Copyright (c) 2022 Firebase 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in all 15 | // copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | // SOFTWARE. 24 | 25 | import * as http from "http"; 26 | import * as express from "express"; 27 | import { loadStack } from "../runtime/loader"; 28 | import { stackToWire } from "../runtime/manifest"; 29 | 30 | function printUsageAndExit() { 31 | console.error( 32 | ` 33 | Usage: firebase-functions [functionsDir] 34 | 35 | Arguments: 36 | - functionsDir: Directory containing source code for Firebase Functions. 37 | ` 38 | ); 39 | process.exit(1); 40 | } 41 | 42 | let functionsDir = "."; 43 | 44 | const args = process.argv.slice(2); 45 | if (args.length > 1) { 46 | if (args[0] === "-h" || args[0] === "--help") { 47 | printUsageAndExit(); 48 | } 49 | functionsDir = args[0]; 50 | } 51 | 52 | let server: http.Server = undefined; 53 | const app = express(); 54 | 55 | function handleQuitquitquit(req: express.Request, res: express.Response) { 56 | res.send("ok"); 57 | server.close(); 58 | } 59 | 60 | app.get("/__/quitquitquit", handleQuitquitquit); 61 | app.post("/__/quitquitquit", handleQuitquitquit); 62 | 63 | if (process.env.FUNCTIONS_CONTROL_API === "true") { 64 | app.get("/__/functions.yaml", async (req, res) => { 65 | try { 66 | const stack = await loadStack(functionsDir); 67 | res.setHeader("content-type", "text/yaml"); 68 | res.send(JSON.stringify(stackToWire(stack))); 69 | } catch (e) { 70 | console.error(e); 71 | res.status(400).send(`Failed to generate manifest from function source: ${e}`); 72 | } 73 | }); 74 | } 75 | 76 | let port = 8080; 77 | if (process.env.PORT) { 78 | port = Number.parseInt(process.env.PORT); 79 | } 80 | 81 | console.log("Serving at port", port); 82 | server = app.listen(port); 83 | -------------------------------------------------------------------------------- /src/common/app.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2017 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import { 24 | App, 25 | applicationDefault, 26 | deleteApp, 27 | getApp as getAppNamed, 28 | initializeApp, 29 | } from "firebase-admin/app"; 30 | import { firebaseConfig } from "./config"; 31 | 32 | const APP_NAME = "__FIREBASE_FUNCTIONS_SDK__"; 33 | 34 | let cache: App; 35 | export function getApp(): App { 36 | if (typeof cache === "undefined") { 37 | try { 38 | cache = getAppNamed(/* default */); 39 | } catch { 40 | // Default app does not exist. Initialize app. 41 | cache = initializeApp( 42 | { 43 | ...firebaseConfig(), 44 | credential: applicationDefault(), 45 | }, 46 | APP_NAME 47 | ); 48 | } 49 | } 50 | return cache; 51 | } 52 | 53 | /** 54 | * This function allows the Firebase Emulator Suite to override the FirebaseApp instance 55 | * used by the Firebase Functions SDK. Developers should never call this function for 56 | * other purposes. 57 | * N.B. For clarity for use in testing this name has no mention of emulation, but 58 | * it must be exported from index as app.setEmulatedAdminApp or we break the emulator. 59 | * We can remove this export when: 60 | * A) We complete the new emulator and no longer depend on monkeypatching 61 | * B) We tweak the CLI to look for different APIs to monkeypatch depending on versions. 62 | * @alpha 63 | */ 64 | export function setApp(app?: App) { 65 | if (cache?.name === APP_NAME) { 66 | void deleteApp(cache); 67 | } 68 | cache = app; 69 | } 70 | -------------------------------------------------------------------------------- /src/common/change.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | /** 24 | * `ChangeJson` is the JSON format used to construct a `Change` object. 25 | */ 26 | export interface ChangeJson { 27 | /** 28 | * Key-value pairs representing state of data after the change. 29 | */ 30 | after?: any; 31 | /** 32 | * Key-value pairs representing state of data before the change. If 33 | * `fieldMask` is set, then only fields that changed are present in `before`. 34 | */ 35 | before?: any; 36 | /** 37 | * Comma-separated string that represents names of fields that changed. 38 | */ 39 | fieldMask?: string; 40 | } 41 | 42 | /** @internal */ 43 | export function applyFieldMask(sparseBefore: any, after: any, fieldMask: string) { 44 | const before = { ...after }; 45 | const masks = fieldMask.split(","); 46 | 47 | for (const mask of masks) { 48 | const parts = mask.split("."); 49 | const head = parts[0]; 50 | const tail = parts.slice(1).join("."); 51 | if (parts.length > 1) { 52 | before[head] = applyFieldMask(sparseBefore?.[head], after[head], tail); 53 | continue; 54 | } 55 | const val = sparseBefore?.[head]; 56 | if (typeof val === "undefined") { 57 | delete before[mask]; 58 | } else { 59 | before[mask] = val; 60 | } 61 | } 62 | 63 | return before; 64 | } 65 | 66 | /** 67 | * The Cloud Functions interface for events that change state, such as 68 | * Realtime Database or Cloud Firestore `onWrite` and `onUpdate` events. 69 | * 70 | * For more information about the format used to construct `Change` objects, see 71 | * {@link ChangeJson} below. 72 | * 73 | */ 74 | export class Change { 75 | /** 76 | * Factory method for creating a `Change` from a `before` object and an `after` 77 | * object. 78 | */ 79 | static fromObjects(before: T, after: T) { 80 | return new Change(before, after); 81 | } 82 | 83 | /** 84 | * Factory method for creating a `Change` from JSON and an optional customizer 85 | * function to be applied to both the `before` and the `after` fields. 86 | */ 87 | static fromJSON(json: ChangeJson, customizer: (x: any) => T = (x) => x as T): Change { 88 | let before = { ...json.before }; 89 | if (json.fieldMask) { 90 | before = applyFieldMask(before, json.after, json.fieldMask); 91 | } 92 | 93 | return Change.fromObjects(customizer(before || {}), customizer(json.after || {})); 94 | } 95 | constructor(public before: T, public after: T) {} 96 | } 97 | -------------------------------------------------------------------------------- /src/common/config.ts: -------------------------------------------------------------------------------- 1 | import { AppOptions } from "firebase-admin/app"; 2 | import { readFileSync } from "fs"; 3 | import * as path from "path"; 4 | 5 | import * as logger from "../logger"; 6 | 7 | let cache: AppOptions | null = null; 8 | 9 | /** 10 | * @internal 11 | * @alpha 12 | */ 13 | export function resetCache(newCache: AppOptions = null) { 14 | cache = newCache; 15 | } 16 | 17 | /** 18 | * Get the fields you need to initialize a Firebase app 19 | * @alpha 20 | */ 21 | export function firebaseConfig(): AppOptions | null { 22 | if (cache) { 23 | return cache; 24 | } 25 | 26 | let env = process.env.FIREBASE_CONFIG; 27 | if (env) { 28 | // Firebase Tools will always use a JSON blob in prod, but docs 29 | // explicitly state that the user can set the env to a file: 30 | // https://firebase.google.com/docs/admin/setup#initialize-without-parameters 31 | if (!env.startsWith("{")) { 32 | env = readFileSync(path.join(process.env.PWD, env)).toString("utf8"); 33 | } 34 | 35 | cache = JSON.parse(env); 36 | return cache; 37 | } 38 | 39 | if (process.env.GCLOUD_PROJECT) { 40 | logger.warn( 41 | "Warning, estimating Firebase Config based on GCLOUD_PROJECT. Initializing firebase-admin may fail" 42 | ); 43 | cache = { 44 | databaseURL: 45 | process.env.DATABASE_URL || `https://${process.env.GCLOUD_PROJECT}.firebaseio.com`, 46 | storageBucket: process.env.STORAGE_BUCKET_URL || `${process.env.GCLOUD_PROJECT}.appspot.com`, 47 | projectId: process.env.GCLOUD_PROJECT, 48 | }; 49 | return cache; 50 | } else { 51 | logger.warn( 52 | "Warning, FIREBASE_CONFIG and GCLOUD_PROJECT environment variables are missing. Initializing firebase-admin will fail" 53 | ); 54 | } 55 | 56 | return null; 57 | } 58 | -------------------------------------------------------------------------------- /src/common/debug.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // Do NOT turn on a debug feature in production. 24 | const debugMode = process.env.FIREBASE_DEBUG_MODE === "true"; 25 | 26 | interface DebugFeatures { 27 | skipTokenVerification?: boolean; 28 | enableCors?: boolean; 29 | } 30 | 31 | function loadDebugFeatures(): DebugFeatures { 32 | if (!debugMode) { 33 | return {}; 34 | } 35 | try { 36 | const obj = JSON.parse(process.env.FIREBASE_DEBUG_FEATURES); 37 | if (typeof obj !== "object") { 38 | return {}; 39 | } 40 | return obj as DebugFeatures; 41 | } catch (e) { 42 | return {}; 43 | } 44 | } 45 | 46 | /* @internal */ 47 | export function debugFeatureValue(feat: keyof DebugFeatures): unknown { 48 | if (!debugMode) { 49 | return; 50 | } 51 | return loadDebugFeatures()[feat]; 52 | } 53 | 54 | /* @internal */ 55 | export function isDebugFeatureEnabled(feat: keyof DebugFeatures): boolean { 56 | return debugMode && !!debugFeatureValue(feat); 57 | } 58 | -------------------------------------------------------------------------------- /src/common/onInit.ts: -------------------------------------------------------------------------------- 1 | import * as logger from "../logger"; 2 | 3 | let initCallback: (() => unknown) | null = null; 4 | let didInit = false; 5 | 6 | /** 7 | * Registers a callback that should be run when in a production environment 8 | * before executing any functions code. 9 | * Calling this function more than once leads to undefined behavior. 10 | * @param callback initialization callback to be run before any function executes. 11 | */ 12 | export function onInit(callback: () => unknown) { 13 | if (initCallback) { 14 | logger.warn( 15 | "Setting onInit callback more than once. Only the most recent callback will be called" 16 | ); 17 | } 18 | initCallback = callback; 19 | didInit = false; 20 | } 21 | 22 | type Resolved = T extends Promise ? V : T; 23 | 24 | /** @internal */ 25 | export function withInit unknown>(func: T) { 26 | return async (...args: Parameters): Promise>> => { 27 | if (!didInit) { 28 | if (initCallback) { 29 | await initCallback(); 30 | } 31 | didInit = true; 32 | } 33 | 34 | // Note: This cast is actually inaccurate because it may be a promise, but 35 | // it doesn't actually matter because the async function will promisify 36 | // non-promises and forward promises. 37 | return func(...args) as Resolved>; 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /src/common/options.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | /** 23 | * Special configuration type to reset configuration to platform default. 24 | * 25 | * @alpha 26 | */ 27 | export class ResetValue { 28 | toJSON(): null { 29 | return null; 30 | } 31 | // eslint-disable-next-line @typescript-eslint/no-empty-function 32 | private constructor() {} 33 | public static getInstance() { 34 | return new ResetValue(); 35 | } 36 | } 37 | 38 | /** 39 | * Special configuration value to reset configuration to platform default. 40 | */ 41 | export const RESET_VALUE = ResetValue.getInstance(); 42 | 43 | /** 44 | * @internal 45 | */ 46 | export type ResettableKeys = Required<{ 47 | [K in keyof T as [ResetValue] extends [T[K]] ? K : never]: null; 48 | }>; 49 | -------------------------------------------------------------------------------- /src/common/trace.ts: -------------------------------------------------------------------------------- 1 | import { AsyncLocalStorage } from "async_hooks"; 2 | 3 | /* @internal */ 4 | export const traceContext = new AsyncLocalStorage(); 5 | 6 | export interface TraceContext { 7 | version: string; 8 | traceId: string; 9 | parentId: string; 10 | sample: boolean; 11 | } 12 | 13 | /** 14 | * A regex to match the Cloud Trace header. 15 | * - ([A-Fa-f0-9]{32}): The trace id, a 32 character hex value. (e.g. 4bf92f3577b34da6a3ce929d0e0e4736) 16 | * - ([0-9]+): The parent span id, a 64 bit integer. (e.g. 00f067aa0ba902b7) 17 | * - (?:;o=([0-3])): The trace mask, 1-3 denote it should be traced. 18 | */ 19 | const CLOUD_TRACE_REGEX = new RegExp( 20 | "^(?[A-Fa-f0-9]{32})/" + "(?[0-9]+)" + "(?:;o=(?[0-3]))?$" 21 | ); 22 | const CLOUD_TRACE_HEADER = "X-Cloud-Trace-Context"; 23 | 24 | function matchCloudTraceHeader(carrier: unknown): TraceContext | undefined { 25 | let header: unknown = carrier?.[CLOUD_TRACE_HEADER]; 26 | if (!header) { 27 | // try lowercase header 28 | header = carrier?.[CLOUD_TRACE_HEADER.toLowerCase()]; 29 | } 30 | if (header && typeof header === "string") { 31 | const matches = CLOUD_TRACE_REGEX.exec(header); 32 | if (matches && matches.groups) { 33 | const { traceId, parentIdInt, traceMask } = matches.groups; 34 | // Convert parentId from unsigned int to hex 35 | const parentId = parseInt(parentIdInt); 36 | if (isNaN(parentId)) { 37 | // Ignore traces with invalid parentIds 38 | return; 39 | } 40 | const sample = !!traceMask && traceMask !== "0"; 41 | return { traceId, parentId: parentId.toString(16), sample, version: "00" }; 42 | } 43 | } 44 | } 45 | 46 | /** 47 | * A regex to match the traceparent header. 48 | * - ^([a-f0-9]{2}): The specification version (e.g. 00) 49 | * - ([a-f0-9]{32}): The trace id, a 16-byte array. (e.g. 4bf92f3577b34da6a3ce929d0e0e4736) 50 | * - ([a-f0-9]{16}): The parent span id, an 8-byte array. (e.g. 00f067aa0ba902b7) 51 | * - ([a-f0-9]{2}: The sampled flag. (e.g. 00) 52 | */ 53 | const TRACEPARENT_REGEX = new RegExp( 54 | "^(?[a-f0-9]{2})-" + 55 | "(?[a-f0-9]{32})-" + 56 | "(?[a-f0-9]{16})-" + 57 | "(?[a-f0-9]{2})$" 58 | ); 59 | const TRACEPARENT_HEADER = "traceparent"; 60 | 61 | function matchTraceparentHeader(carrier: unknown): TraceContext | undefined { 62 | const header: unknown = carrier?.[TRACEPARENT_HEADER]; 63 | if (header && typeof header === "string") { 64 | const matches = TRACEPARENT_REGEX.exec(header); 65 | if (matches && matches.groups) { 66 | const { version, traceId, parentId, flag } = matches.groups; 67 | const sample = flag === "01"; 68 | return { traceId, parentId, sample, version }; 69 | } 70 | } 71 | } 72 | 73 | /** 74 | * Extracts trace context from given carrier object, if any. 75 | * 76 | * Supports Cloud Trace and traceparent format. 77 | * 78 | * @param carrier 79 | */ 80 | export function extractTraceContext(carrier: unknown): TraceContext | undefined { 81 | return matchCloudTraceHeader(carrier) || matchTraceparentHeader(carrier); 82 | } 83 | -------------------------------------------------------------------------------- /src/common/utilities/assertions.ts: -------------------------------------------------------------------------------- 1 | /** @hidden 2 | * @file Provides common assertion helpers which can be used to improve 3 | * strictness of both type checking and runtime. 4 | */ 5 | 6 | /** 7 | * Checks that the given value is of type `never` — the type that’s left after 8 | * all other cases have been removed. 9 | * 10 | * @param x A value of type `never`. 11 | */ 12 | export function assertNever(x: never): never { 13 | throw new Error(`Unhandled discriminated union member: ${JSON.stringify(x)}.`); 14 | } 15 | -------------------------------------------------------------------------------- /src/common/utilities/encoder.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2017 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | export function dateToTimestampProto(timeString?: string) { 24 | if (typeof timeString === "undefined") { 25 | return; 26 | } 27 | const date = new Date(timeString); 28 | const seconds = Math.floor(date.getTime() / 1000); 29 | let nanos = 0; 30 | if (timeString.length > 20) { 31 | const nanoString = timeString.substring(20, timeString.length - 1); 32 | const trailingZeroes = 9 - nanoString.length; 33 | nanos = parseInt(nanoString, 10) * Math.pow(10, trailingZeroes); 34 | } 35 | return { seconds, nanos }; 36 | } 37 | -------------------------------------------------------------------------------- /src/common/utilities/path.ts: -------------------------------------------------------------------------------- 1 | /** @hidden 2 | * Removes leading and trailing slashes from a path. 3 | * 4 | * @param path A path to normalize, in POSIX format. 5 | */ 6 | export function normalizePath(path: string): string { 7 | if (!path) { 8 | return ""; 9 | } 10 | return path.replace(/^\//, "").replace(/\/$/, ""); 11 | } 12 | 13 | /** 14 | * Normalizes a given path and splits it into an array of segments. 15 | * 16 | * @param path A path to split, in POSIX format. 17 | */ 18 | export function pathParts(path: string): string[] { 19 | if (!path || path === "" || path === "/") { 20 | return []; 21 | } 22 | return normalizePath(path).split("/"); 23 | } 24 | 25 | /** 26 | * Normalizes given paths and joins these together using a POSIX separator. 27 | * 28 | * @param base A first path segment, in POSIX format. 29 | * @param child A second path segment, in POSIX format. 30 | */ 31 | export function joinPath(base: string, child: string) { 32 | return pathParts(base).concat(pathParts(child)).join("/"); 33 | } 34 | -------------------------------------------------------------------------------- /src/common/utilities/utils.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2017 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | function isObject(obj: any): boolean { 24 | return typeof obj === "object" && !!obj; 25 | } 26 | 27 | /** @hidden */ 28 | export function applyChange(src: any, dest: any) { 29 | // if not mergeable, don't merge 30 | if (!isObject(dest) || !isObject(src)) { 31 | return dest; 32 | } 33 | 34 | return merge(src, dest); 35 | } 36 | 37 | function merge(src: Record, dest: Record): Record { 38 | const res: Record = {}; 39 | const keys = new Set([...Object.keys(src), ...Object.keys(dest)]); 40 | 41 | for (const key of keys.values()) { 42 | if (key in dest) { 43 | if (dest[key] === null) { 44 | continue; 45 | } 46 | res[key] = applyChange(src[key], dest[key]); 47 | } else if (src[key] !== null) { 48 | res[key] = src[key]; 49 | } 50 | } 51 | return res; 52 | } 53 | -------------------------------------------------------------------------------- /src/function-configuration.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebase/firebase-functions/849f01cd00e24ac1bf61fd634f0927aa70535892/src/function-configuration.ts -------------------------------------------------------------------------------- /src/logger/common.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2017 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // Map LogSeverity types to their equivalent `console.*` method. 24 | /** @hidden */ 25 | export const CONSOLE_SEVERITY: { 26 | [severity: string]: "debug" | "info" | "warn" | "error"; 27 | } = { 28 | DEBUG: "debug", 29 | INFO: "info", 30 | NOTICE: "info", 31 | WARNING: "warn", 32 | ERROR: "error", 33 | CRITICAL: "error", 34 | ALERT: "error", 35 | EMERGENCY: "error", 36 | }; 37 | 38 | // safely preserve unpatched console.* methods in case of compat require 39 | /** @hidden */ 40 | export const UNPATCHED_CONSOLE = { 41 | debug: console.debug, 42 | info: console.info, 43 | log: console.log, 44 | warn: console.warn, 45 | error: console.error, 46 | }; 47 | -------------------------------------------------------------------------------- /src/logger/compat.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2017 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import { format } from "util"; 24 | import { CONSOLE_SEVERITY, UNPATCHED_CONSOLE } from "./common"; 25 | 26 | /** @hidden */ 27 | function patchedConsole(severity: string): (data: any, ...args: any[]) => void { 28 | return function (data: any, ...args: any[]): void { 29 | let message = format(data, ...args); 30 | if (severity === "ERROR") { 31 | message = new Error(message).stack || message; 32 | } 33 | 34 | UNPATCHED_CONSOLE[CONSOLE_SEVERITY[severity]](JSON.stringify({ severity, message })); 35 | }; 36 | } 37 | 38 | // IMPORTANT -- "../logger" must be imported before monkeypatching! 39 | console.debug = patchedConsole("DEBUG"); 40 | console.info = patchedConsole("INFO"); 41 | console.log = patchedConsole("INFO"); 42 | console.warn = patchedConsole("WARNING"); 43 | console.error = patchedConsole("ERROR"); 44 | -------------------------------------------------------------------------------- /src/types/global.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | export {}; 3 | 4 | declare global { 5 | interface AbortSignal {} 6 | interface AbortController {} 7 | } 8 | -------------------------------------------------------------------------------- /src/v1/config.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2017 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import * as fs from "fs"; 24 | import * as path from "path"; 25 | 26 | export { firebaseConfig } from "../common/config"; 27 | 28 | /** @internal */ 29 | export let singleton: Record; 30 | 31 | /** @internal */ 32 | export function resetCache(): void { 33 | singleton = undefined; 34 | } 35 | 36 | /** 37 | * Store and retrieve project configuration data such as third-party API 38 | * keys or other settings. You can set configuration values using the 39 | * Firebase CLI as described in 40 | * https://firebase.google.com/docs/functions/config-env. 41 | * 42 | * @deprecated Using functions.config() is discouraged. See https://firebase.google.com/docs/functions/config-env. 43 | */ 44 | export function config(): Record { 45 | // K_CONFIGURATION is only set in GCFv2 46 | if (process.env.K_CONFIGURATION) { 47 | throw new Error( 48 | "functions.config() is no longer available in Cloud Functions for " + 49 | "Firebase v2. Please see the latest documentation for information " + 50 | "on how to transition to using environment variables" 51 | ); 52 | } 53 | if (typeof singleton === "undefined") { 54 | init(); 55 | } 56 | return singleton; 57 | } 58 | 59 | function init() { 60 | try { 61 | const parsed = JSON.parse(process.env.CLOUD_RUNTIME_CONFIG); 62 | delete parsed.firebase; 63 | singleton = parsed; 64 | return; 65 | } catch (e) { 66 | // Do nothing 67 | } 68 | 69 | try { 70 | const configPath = 71 | process.env.CLOUD_RUNTIME_CONFIG || path.join(process.cwd(), ".runtimeconfig.json"); 72 | const contents = fs.readFileSync(configPath); 73 | const parsed = JSON.parse(contents.toString("utf8")); 74 | delete parsed.firebase; 75 | singleton = parsed; 76 | return; 77 | } catch (e) { 78 | // Do nothing 79 | } 80 | 81 | singleton = {}; 82 | } 83 | -------------------------------------------------------------------------------- /src/v1/index.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2017 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // Providers: 24 | import * as logger from "../logger"; 25 | import * as analytics from "./providers/analytics"; 26 | import * as auth from "./providers/auth"; 27 | import * as database from "./providers/database"; 28 | import * as firestore from "./providers/firestore"; 29 | import * as https from "./providers/https"; 30 | import * as pubsub from "./providers/pubsub"; 31 | import * as remoteConfig from "./providers/remoteConfig"; 32 | import * as storage from "./providers/storage"; 33 | import * as tasks from "./providers/tasks"; 34 | import * as testLab from "./providers/testLab"; 35 | 36 | import { setApp as setEmulatedAdminApp } from "../common/app"; 37 | 38 | export { 39 | analytics, 40 | auth, 41 | database, 42 | firestore, 43 | https, 44 | pubsub, 45 | remoteConfig, 46 | storage, 47 | tasks, 48 | testLab, 49 | logger, 50 | }; 51 | 52 | export const app = { setEmulatedAdminApp }; 53 | 54 | // Exported root types: 55 | export * from "./cloud-functions"; 56 | export * from "./config"; 57 | export * from "./function-builder"; 58 | export * from "./function-configuration"; 59 | // NOTE: Equivalent to `export * as params from "../params"` but api-extractor doesn't support that syntax. 60 | import * as params from "../params"; 61 | export { params }; 62 | 63 | export { onInit } from "../common/onInit"; 64 | -------------------------------------------------------------------------------- /src/v2/index.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | /** 24 | * The 2nd gen API for Cloud Functions for Firebase. 25 | * This SDK supports deep imports. For example, the namespace 26 | * `pubsub` is available at `firebase-functions/v2` or is directly importable 27 | * from `firebase-functions/v2/pubsub`. 28 | * @packageDocumentation 29 | */ 30 | 31 | import * as logger from "../logger"; 32 | import * as alerts from "./providers/alerts"; 33 | import * as database from "./providers/database"; 34 | import * as eventarc from "./providers/eventarc"; 35 | import * as https from "./providers/https"; 36 | import * as identity from "./providers/identity"; 37 | import * as pubsub from "./providers/pubsub"; 38 | import * as scheduler from "./providers/scheduler"; 39 | import * as storage from "./providers/storage"; 40 | import * as tasks from "./providers/tasks"; 41 | import * as remoteConfig from "./providers/remoteConfig"; 42 | import * as testLab from "./providers/testLab"; 43 | import * as firestore from "./providers/firestore"; 44 | 45 | export { 46 | alerts, 47 | database, 48 | storage, 49 | https, 50 | identity, 51 | pubsub, 52 | logger, 53 | tasks, 54 | eventarc, 55 | scheduler, 56 | remoteConfig, 57 | testLab, 58 | firestore, 59 | }; 60 | 61 | export { 62 | setGlobalOptions, 63 | GlobalOptions, 64 | SupportedRegion, 65 | MemoryOption, 66 | VpcEgressSetting, 67 | IngressSetting, 68 | EventHandlerOptions, 69 | } from "./options"; 70 | 71 | export { CloudFunction, CloudEvent, ParamsOf, onInit } from "./core"; 72 | export { Change } from "../common/change"; 73 | // NOTE: Equivalent to `export * as params from "../params"` but api-extractor doesn't support that syntax. 74 | import * as params from "../params"; 75 | export { params }; 76 | 77 | // NOTE: Required to support the Functions Emulator which monkey patches `functions.config()` 78 | // TODO(danielylee): Remove in next major release. 79 | export { config } from "../v1/config"; 80 | 81 | // Required for v1 Emulator support. 82 | import { setApp as setEmulatedAdminApp } from "../common/app"; 83 | export const app = { setEmulatedAdminApp }; 84 | -------------------------------------------------------------------------------- /src/v2/providers/alerts/index.ts: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | /** 24 | * Cloud functions to handle events from Firebase Alerts. 25 | * Subpackages give stronger typing to specific services which 26 | * notify users via Firebase Alerts. 27 | * @packageDocumentation 28 | */ 29 | 30 | import * as appDistribution from "./appDistribution"; 31 | import * as billing from "./billing"; 32 | import * as crashlytics from "./crashlytics"; 33 | import * as performance from "./performance"; 34 | 35 | export { appDistribution, billing, crashlytics, performance }; 36 | export * from "./alerts"; 37 | -------------------------------------------------------------------------------- /src/v2/trace.ts: -------------------------------------------------------------------------------- 1 | import * as express from "express"; 2 | 3 | import { TraceContext, extractTraceContext, traceContext } from "../common/trace"; 4 | import { CloudEvent } from "./core"; 5 | 6 | type HttpsFunction = (req: express.Request, res: express.Response) => void | Promise; 7 | type CloudEventFunction = (raw: CloudEvent) => any | Promise; 8 | 9 | /** 10 | * Wraps v2 handler with trace context. 11 | * @param handler 12 | * 13 | * @internal 14 | */ 15 | export function wrapTraceContext(handler: HttpsFunction): HttpsFunction; 16 | export function wrapTraceContext(handler: CloudEventFunction): CloudEventFunction; 17 | export function wrapTraceContext( 18 | handler: HttpsFunction | CloudEventFunction 19 | ): HttpsFunction | CloudEventFunction { 20 | return (...args) => { 21 | let traceParent: TraceContext | undefined; 22 | if (args.length === 1) { 23 | traceParent = extractTraceContext(args[0]); 24 | } else { 25 | traceParent = extractTraceContext(args[0].headers); 26 | } 27 | if (!traceParent) { 28 | // eslint-disable-next-line prefer-spread 29 | return handler.apply(null, args); 30 | } 31 | return traceContext.run(traceParent, handler, ...args); 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "resolveJsonModule": true, 4 | "sourceMap": true 5 | }, 6 | "extends": "./tsconfig.release.json", 7 | "include": [ 8 | "**/*.ts", 9 | ".eslintrc.js", 10 | "integration_test/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tsconfig.release.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "lib": ["es2019"], 5 | "module": "commonjs", 6 | "noImplicitAny": false, 7 | "noUnusedLocals": true, 8 | "outDir": "lib", 9 | "stripInternal": true, 10 | "target": "es2019", 11 | "typeRoots": ["./node_modules/@types"] 12 | }, 13 | "files": [ 14 | "./src/types/global.d.ts", 15 | "./src/v1/index.ts", 16 | "./src/logger/index.ts", 17 | "./src/logger/compat.ts", 18 | "./src/v2/index.ts", 19 | "./src/bin/firebase-functions.ts" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "warning", 3 | "extends": [ 4 | "tslint:recommended", 5 | "tslint-no-unused-expression-chai", 6 | "tslint-config-prettier" 7 | ], 8 | "rules": { 9 | "interface-name": false, 10 | "member-access": false, 11 | "no-namespace": false, 12 | "no-console": false, 13 | "object-literal-key-quotes": [true, "as-needed"], 14 | "object-literal-sort-keys": false, 15 | "quotemark": [true, "single", "avoid-escape"], 16 | "trailing-comma": [true, { "functions": "never" }], 17 | "variable-name": [true, "check-format", "allow-leading-underscore"], 18 | "whitespace": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /v1/analytics.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v1/auth.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v1/database.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v1/firestore.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v1/index.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v1/pubsub.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v1/remoteConfig.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v1/storage.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v1/tasks.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v1/testLab.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/alerts/appDistribution.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/alerts/billing.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/alerts/crashlytics.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/alerts/index.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/alerts/performance.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/core.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/database.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 -------------------------------------------------------------------------------- /v2/eventarc.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/firestore.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2023 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/https.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/identity.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | -------------------------------------------------------------------------------- /v2/index.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/options.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/params.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/pubsub.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/remoteConfig.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/scheduler.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/storage.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2021 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/tasks.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | -------------------------------------------------------------------------------- /v2/testLab.js: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2022 Firebase 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // This file is not part of the firebase-functions SDK. It is used to silence the 24 | // imports eslint plugin until it can understand import paths defined by node 25 | // package exports. 26 | // For more information, see github.com/import-js/eslint-plugin-import/issues/1810 27 | --------------------------------------------------------------------------------