├── mockdata ├── mock.apk ├── function_source_v1.txt └── function_source_v2.txt ├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ └── mcp.md ├── scripts ├── dataconnect-test │ ├── .firebaserc │ ├── templates │ │ ├── connector.yaml │ │ └── dataconnect.yaml │ ├── firebase.json │ └── run.sh ├── publish │ ├── .gitignore │ ├── hub.enc │ ├── npmrc.enc │ ├── deploy_key.enc │ ├── firebase-docker-image │ │ ├── package.json │ │ └── run.sh │ ├── twitter.json.enc │ └── run.sh ├── extensions-deploy-tests │ ├── .firebaserc │ ├── extensions │ │ ├── test-instance2.env │ │ └── test-instance1.env │ ├── firebase.json │ └── run.sh ├── functions-deploy-tests │ ├── .firebaserc │ ├── firebase.json │ ├── functions │ │ └── package.json │ └── run.sh ├── emulator-tests │ ├── .gitignore │ ├── tsconfig.dev.json │ ├── functions │ │ └── package.json │ └── run.sh ├── test-project │ ├── functions │ │ ├── .gitignore │ │ └── package.json │ ├── public │ │ ├── 404.html │ │ └── index.html │ ├── database.rules.json │ └── firebase.json ├── webframeworks-deploy-tests │ ├── angular │ │ ├── src │ │ │ ├── assets │ │ │ │ └── .gitkeep │ │ │ ├── styles.css │ │ │ ├── index.html │ │ │ ├── locale │ │ │ │ ├── messages.es.xlf │ │ │ │ └── messages.fr.xlf │ │ │ ├── main.server.ts │ │ │ ├── app │ │ │ │ ├── app.config.ts │ │ │ │ ├── app-routing.module.ts │ │ │ │ ├── foo │ │ │ │ │ └── foo.component.ts │ │ │ │ ├── home │ │ │ │ │ └── home.component.ts │ │ │ │ ├── app.config.server.ts │ │ │ │ └── app.component.ts │ │ │ └── main.ts │ │ ├── .editorconfig │ │ ├── tsconfig.app.json │ │ ├── tsconfig.server.json │ │ ├── tsconfig.spec.json │ │ └── .gitignore │ ├── functions │ │ ├── .gitignore │ │ ├── index.js │ │ └── package.json │ ├── nextjs │ │ ├── .eslintrc.json │ │ ├── app │ │ │ ├── app │ │ │ │ ├── ssg │ │ │ │ │ └── page.tsx │ │ │ │ ├── isr │ │ │ │ │ └── page.tsx │ │ │ │ ├── ssr │ │ │ │ │ └── page.tsx │ │ │ │ ├── image │ │ │ │ │ └── page.tsx │ │ │ │ └── api │ │ │ │ │ ├── static │ │ │ │ │ └── route.ts │ │ │ │ │ └── dynamic │ │ │ │ │ └── route.ts │ │ │ └── layout.tsx │ │ ├── pages │ │ │ ├── _app.tsx │ │ │ ├── pages │ │ │ │ ├── ssg │ │ │ │ │ └── index.tsx │ │ │ │ ├── ssr │ │ │ │ │ └── index.tsx │ │ │ │ ├── isr │ │ │ │ │ └── index.tsx │ │ │ │ └── fallback │ │ │ │ │ └── [id].tsx │ │ │ └── api │ │ │ │ └── hello.ts │ │ ├── middleware.ts │ │ ├── styles │ │ │ └── globals.css │ │ ├── .gitignore │ │ └── package.json │ ├── .firebaserc │ └── run.sh ├── firepit-builder │ ├── .dockerignore │ ├── cloudbuild.yaml │ └── package.json ├── triggers-end-to-end-tests │ ├── v1 │ │ ├── .gitignore │ │ └── package.json │ ├── v2 │ │ ├── .gitignore │ │ └── package.json │ ├── triggers │ │ ├── .gitignore │ │ └── package.json │ ├── .firebaserc │ └── storage.rules ├── extensions-emulator-tests │ ├── functions │ │ ├── .gitignore │ │ ├── test.png │ │ └── package.json │ ├── .firebaserc │ ├── storage.rules │ ├── run.sh │ ├── extensions │ │ └── resize-images.env │ └── firebase.json ├── clean-shrinkwrap.sh ├── dataconnect-emulator-tests │ ├── fdc-test │ │ ├── schema │ │ │ └── schema.gql │ │ ├── connector │ │ │ ├── connector.yaml │ │ │ └── queries.gql │ │ └── dataconnect.yaml │ ├── firebase.json │ └── run.sh ├── functions-discover-tests │ ├── fixtures │ │ ├── yarn-workspaces │ │ │ ├── packages │ │ │ │ ├── a-test-pkg │ │ │ │ │ ├── index.js │ │ │ │ │ └── package.json │ │ │ │ └── functions │ │ │ │ │ ├── package.json │ │ │ │ │ └── index.js │ │ │ ├── install.sh │ │ │ ├── firebase.json │ │ │ └── package.json │ │ ├── bundled │ │ │ ├── dist │ │ │ │ ├── package.json │ │ │ │ └── index.js │ │ │ ├── install.sh │ │ │ ├── firebase.json │ │ │ └── package.json │ │ ├── esm │ │ │ ├── firebase.json │ │ │ ├── install.sh │ │ │ └── functions │ │ │ │ ├── package.json │ │ │ │ └── index.js │ │ ├── pnpm │ │ │ ├── firebase.json │ │ │ ├── install.sh │ │ │ └── functions │ │ │ │ ├── package.json │ │ │ │ └── index.js │ │ ├── simple │ │ │ ├── firebase.json │ │ │ ├── install.sh │ │ │ └── functions │ │ │ │ ├── package.json │ │ │ │ └── index.js │ │ ├── stress-test │ │ │ ├── firebase.json │ │ │ ├── install.sh │ │ │ └── functions │ │ │ │ ├── package.json │ │ │ │ └── index.js │ │ └── codebases │ │ │ ├── install.sh │ │ │ ├── v1 │ │ │ ├── package.json │ │ │ └── index.js │ │ │ ├── v2 │ │ │ ├── package.json │ │ │ └── index.js │ │ │ └── firebase.json │ └── run.sh ├── storage-emulator-integration │ ├── import │ │ ├── mapped-emulator-data │ │ │ ├── storage_export │ │ │ │ ├── blobs │ │ │ │ │ └── eaa2803e-4374-44bd-98cb-cdd7d31e3347 │ │ │ │ ├── buckets.json │ │ │ │ └── metadata │ │ │ │ │ └── eaa2803e-4374-44bd-98cb-cdd7d31e3347.json │ │ │ └── firebase-export-metadata.json │ │ ├── nested-emulator-data │ │ │ ├── storage_export │ │ │ │ ├── blobs │ │ │ │ │ └── fake-project-id.appspot.com │ │ │ │ │ │ └── test_upload.jpg │ │ │ │ ├── buckets.json │ │ │ │ └── metadata │ │ │ │ │ └── fake-project-id.appspot.com │ │ │ │ │ └── test_upload.jpg.json │ │ │ └── firebase-export-metadata.json │ │ ├── windows-emulator-data │ │ │ ├── storage_export │ │ │ │ ├── blobs │ │ │ │ │ ├── fake-project-id.appspot.com%5Ctest_upload.jpg │ │ │ │ │ └── fake-project-id.appspot.com%5Ctest-directory%5Ctest_nested_upload.jpg │ │ │ │ ├── buckets.json │ │ │ │ └── metadata │ │ │ │ │ └── fake-project-id.appspot.com%5Ctest_upload.jpg.json │ │ │ └── firebase-export-metadata.json │ │ ├── flattened-emulator-data │ │ │ ├── storage_export │ │ │ │ ├── blobs │ │ │ │ │ └── fake-project-id.appspot.com%2Ftest_upload.jpg │ │ │ │ ├── buckets.json │ │ │ │ └── metadata │ │ │ │ │ └── fake-project-id.appspot.com%2Ftest_upload.jpg.json │ │ │ └── firebase-export-metadata.json │ │ └── flattened-emulator-data-missing-blobs-and-metadata │ │ │ ├── storage_export │ │ │ └── buckets.json │ │ │ └── firebase-export-metadata.json │ ├── multiple-targets │ │ ├── allowAll.rules │ │ ├── allowNone.rules │ │ ├── firebase.json │ │ └── .firebaserc │ └── firebase.json ├── creds-private.json.enc ├── creds-public.json.enc ├── emulator-import-export-tests │ ├── .firebaserc │ ├── run.sh │ └── storage.rules ├── clean.ts ├── client-integration-tests │ ├── run.sh │ └── test-project │ │ ├── firebase.json │ │ └── public │ │ ├── 404.html │ │ └── index.html ├── mcp-tests │ ├── tsconfig.json │ └── package.json ├── hosting-tests │ └── rewrites-tests │ │ └── run.sh ├── assets │ └── functions_to_test_minimal.js ├── build │ ├── cloudbuild.yaml │ └── Dockerfile ├── examples │ └── hosting │ │ └── update-single-file │ │ └── tsconfig.json ├── set-default-credentials.sh └── clean-install.sh ├── src ├── frameworks │ ├── docs │ │ ├── index.ts │ │ ├── lit.md │ │ ├── react.md │ │ ├── preact.md │ │ ├── svelte.md │ │ └── _includes │ │ │ ├── _preview-disclaimer.md │ │ │ ├── _before-you-begin.md │ │ │ └── _initialize-firebase.md │ ├── sveltekit │ │ └── interfaces.ts │ ├── next │ │ └── testing │ │ │ └── index.ts │ ├── angular │ │ └── interfaces.ts │ ├── nuxt │ │ ├── interfaces.ts │ │ └── utils.ts │ ├── react │ │ └── index.ts │ ├── lit │ │ └── index.ts │ ├── preact │ │ └── index.ts │ ├── svelte │ │ └── index.ts │ └── compose │ │ └── driver │ │ └── index.ts ├── test │ ├── fixtures │ │ ├── fbrc │ │ │ ├── firebase.json │ │ │ ├── invalid │ │ │ │ ├── firebase.json │ │ │ │ └── .firebaserc │ │ │ ├── .firebaserc │ │ │ ├── conflict │ │ │ │ └── .firebaserc │ │ │ └── index.ts │ │ ├── config-imports │ │ │ ├── unsupported.txt │ │ │ ├── rules.json │ │ │ ├── firebase.json │ │ │ ├── hosting.json │ │ │ └── index.ts │ │ ├── simplehosting │ │ │ ├── public │ │ │ │ └── index.html │ │ │ ├── firebase.json │ │ │ └── index.ts │ │ ├── ignores │ │ │ ├── .hiddenfile │ │ │ ├── ignored.txt │ │ │ ├── index.html │ │ │ ├── ignored │ │ │ │ ├── ignore.txt │ │ │ │ ├── deeper │ │ │ │ │ └── index.txt │ │ │ │ └── index.html │ │ │ ├── present │ │ │ │ └── index.html │ │ │ ├── firebase.json │ │ │ └── index.ts │ │ ├── dup-top-level │ │ │ ├── rules.json │ │ │ ├── firebase.json │ │ │ └── index.ts │ │ ├── extension-yamls │ │ │ ├── invalid │ │ │ │ ├── extension.yaml │ │ │ │ └── index.ts │ │ │ ├── sample-ext-preinstall │ │ │ │ ├── PREINSTALL.md │ │ │ │ ├── index.ts │ │ │ │ └── extension.yaml │ │ │ ├── sample-ext │ │ │ │ ├── index.ts │ │ │ │ └── extension.yaml │ │ │ ├── minimal │ │ │ │ ├── index.ts │ │ │ │ └── extension.yaml │ │ │ ├── valid-yaml-invalid-spec │ │ │ │ ├── extension.yaml │ │ │ │ └── index.ts │ │ │ └── hello-world │ │ │ │ └── index.ts │ │ ├── zip-files │ │ │ ├── node-unzipper-testData │ │ │ │ ├── uncompressed │ │ │ │ │ ├── inflated │ │ │ │ │ │ ├── dir │ │ │ │ │ │ │ └── fileInsideDir.txt │ │ │ │ │ │ └── file.txt │ │ │ │ │ └── archive.zip │ │ │ │ ├── zip-slip │ │ │ │ │ ├── inflated │ │ │ │ │ │ └── good.txt │ │ │ │ │ └── archive.zip │ │ │ │ ├── compressed-standard │ │ │ │ │ ├── inflated │ │ │ │ │ │ └── dir │ │ │ │ │ │ │ └── fileInsideDir.txt │ │ │ │ │ └── archive.zip │ │ │ │ ├── compressed-flags-set │ │ │ │ │ ├── inflated │ │ │ │ │ │ └── dir │ │ │ │ │ │ │ └── fileInsideDir.txt │ │ │ │ │ └── archive.zip │ │ │ │ ├── zip64 │ │ │ │ │ ├── inflated │ │ │ │ │ │ └── README │ │ │ │ │ └── archive.zip │ │ │ │ ├── compressed-directory-entry │ │ │ │ │ ├── inflated │ │ │ │ │ │ ├── mimetype │ │ │ │ │ │ ├── page_styles.css │ │ │ │ │ │ ├── stylesheet.css │ │ │ │ │ │ ├── META-INF │ │ │ │ │ │ │ └── container.xml │ │ │ │ │ │ └── index.html │ │ │ │ │ └── archive.zip │ │ │ │ └── compressed-cp866 │ │ │ │ │ ├── archive.zip │ │ │ │ │ └── inflated │ │ │ │ │ └── Тест.txt │ │ │ └── index.ts │ │ ├── rulesDeployCrossService │ │ │ ├── index.ts │ │ │ ├── firebase.json │ │ │ └── storage.rules │ │ ├── rulesDeploy │ │ │ ├── storage.rules │ │ │ ├── firestore.rules │ │ │ ├── firebase.json │ │ │ └── index.ts │ │ ├── valid-config │ │ │ └── index.ts │ │ └── profiler-data │ │ │ └── index.ts │ ├── emulators │ │ └── extensions │ │ │ └── firebase │ │ │ └── storage-resize-images@0.1.18 │ │ │ └── functions │ │ │ ├── .gitignore │ │ │ └── package.json │ └── helpers │ │ ├── global-mock-auth.ts │ │ ├── mocha-bootstrap.ts │ │ └── index.ts ├── deploy │ ├── functions │ │ ├── ensureCloudBuildEnabled.ts │ │ ├── index.ts │ │ ├── release │ │ │ └── timer.ts │ │ ├── runtimes │ │ │ └── discovery │ │ │ │ └── mockDiscoveryServer.ts │ │ ├── services │ │ │ ├── database.ts │ │ │ ├── testLab.ts │ │ │ ├── remoteConfig.ts │ │ │ └── firebaseAlerts.ts │ │ └── triggerRegionHelper.ts │ ├── remoteconfig │ │ ├── deploy.ts │ │ ├── index.ts │ │ └── release.ts │ ├── hosting │ │ ├── index.ts │ │ ├── args.ts │ │ └── context.ts │ ├── database │ │ ├── deploy.ts │ │ └── index.ts │ ├── extensions │ │ ├── index.ts │ │ ├── args.ts │ │ └── validate.ts │ ├── storage │ │ ├── index.ts │ │ └── deploy.ts │ ├── apphosting │ │ ├── index.ts │ │ └── args.ts │ ├── dataconnect │ │ └── index.ts │ └── firestore │ │ └── index.ts ├── apphosting │ ├── index.ts │ └── constants.ts ├── mcp │ ├── prompts │ │ ├── core │ │ │ └── index.ts │ │ ├── crashlytics │ │ │ └── index.ts │ │ └── dataconnect │ │ │ └── index.ts │ ├── tools │ │ ├── messaging │ │ │ └── index.ts │ │ ├── apphosting │ │ │ └── index.ts │ │ ├── remoteconfig │ │ │ └── index.ts │ │ ├── database │ │ │ └── index.ts │ │ ├── storage │ │ │ └── index.ts │ │ ├── auth │ │ │ └── index.ts │ │ ├── dataconnect │ │ │ └── index.ts │ │ ├── crashlytics │ │ │ └── constants.ts │ │ ├── firestore │ │ │ └── index.ts │ │ └── core │ │ │ └── get_project.ts │ ├── types.ts │ └── util │ │ └── dataconnect │ │ ├── emulator.ts │ │ └── compile.ts ├── types │ ├── update-notifier-cjs.d.ts │ ├── proxy │ │ └── index.d.ts │ ├── extractTriggers.d.ts │ └── project │ │ └── index.d.ts ├── functions │ └── events │ │ ├── index.ts │ │ └── v1.ts ├── configstore.ts ├── extensions │ ├── publishHelpers.ts │ ├── utils.spec.ts │ └── metricsTypeDef.ts ├── emulator │ ├── auth │ │ └── types.ts │ ├── storage │ │ ├── errors.ts │ │ ├── rfc.ts │ │ └── metadata.spec.ts │ ├── shared │ │ └── request.ts │ └── adminSdkConfig.spec.ts ├── throttler │ ├── errors │ │ ├── timeout-error.ts │ │ ├── task-error.ts │ │ └── retries-exhausted-error.ts │ └── queue.ts ├── vsCodeUtils.ts ├── gcp │ └── index.ts ├── listFiles.ts ├── init │ └── features │ │ ├── aitools │ │ └── index.ts │ │ └── functions │ │ └── npm-dependencies.ts ├── commands │ ├── setup-emulators-ui.ts │ ├── setup-emulators-database.ts │ ├── setup-emulators-firestore.ts │ ├── mcp.ts │ ├── setup-emulators-pubsub.ts │ ├── setup-emulators-storage.ts │ ├── functions-secrets-get.ts │ ├── functions-secrets-describe.ts │ ├── functions-shell.ts │ ├── emulators-export.ts │ ├── target-clear.ts │ └── target-remove.ts ├── requireInteractive.ts ├── loadCJSON.ts ├── env.ts ├── requireHostingSite.ts ├── deploymentTool.ts ├── getDefaultDatabaseInstance.ts ├── requireConfig.ts ├── dataconnect │ └── ensureApis.ts ├── getProjectNumber.ts ├── firestore │ └── backupUtils.spec.ts ├── scopes.ts ├── errorOut.ts ├── archiveDirectory.spec.ts └── bin │ └── firebase.ts ├── templates ├── extensions │ ├── javascript │ │ ├── _gitignore │ │ ├── integration-test.js │ │ └── package.nolint.json │ ├── CL-template.md │ ├── integration-test.env │ ├── typescript │ │ ├── tsconfig.dev.json │ │ ├── _gitignore │ │ ├── _mocharc │ │ ├── tsconfig.json │ │ ├── integration-test.ts │ │ └── package.nolint.json │ └── integration-test.json ├── init │ ├── functions │ │ ├── javascript │ │ │ ├── _gitignore │ │ │ ├── _eslintrc │ │ │ ├── package.nolint.json │ │ │ └── package.lint.json │ │ ├── python │ │ │ ├── requirements.txt │ │ │ └── _gitignore │ │ └── typescript │ │ │ ├── tsconfig.dev.json │ │ │ ├── _gitignore │ │ │ ├── tsconfig.json │ │ │ └── package.nolint.json │ ├── dataconnect │ │ ├── connector.yaml │ │ └── dataconnect.yaml │ ├── aitools │ │ ├── cursor-rules-header.txt │ │ └── gemini-extension.json │ ├── apptesting │ │ └── smoke_test.yaml │ ├── storage │ │ └── storage.rules │ └── apphosting │ │ └── apphosting.yaml ├── firebase.json ├── emulators │ └── default_storage.rules └── banner.txt ├── .prettierrc.js ├── firebase-vscode ├── .prettierrc.js ├── src │ ├── test │ │ ├── test_projects │ │ │ ├── empty │ │ │ │ └── README │ │ │ ├── .gitignore │ │ │ └── fishfood │ │ │ │ ├── dataconnect │ │ │ │ ├── connectors │ │ │ │ │ └── a │ │ │ │ │ │ ├── connector.yaml │ │ │ │ │ │ ├── queryWithFragment.gql │ │ │ │ │ │ ├── queries.gql │ │ │ │ │ │ └── mutations.gql │ │ │ │ ├── schema │ │ │ │ │ └── schema.gql │ │ │ │ └── dataconnect.yaml │ │ │ │ ├── .firebaserc │ │ │ │ ├── .graphqlrc │ │ │ │ ├── firebase.json │ │ │ │ └── test-node-app │ │ │ │ └── package.json │ │ ├── suite │ │ │ └── src │ │ │ │ ├── cli.test.ts │ │ │ │ └── core │ │ │ │ └── project.test.ts │ │ ├── utils │ │ │ ├── page_objects │ │ │ │ ├── status_bar.ts │ │ │ │ ├── quick_picks.ts │ │ │ │ └── terminal.ts │ │ │ ├── user.ts │ │ │ └── sidebar.ts │ │ ├── empty_wdio.conf.ts │ │ ├── integration │ │ │ └── queries_with_error.gql │ │ └── fishfood_wdio.conf.ts │ ├── stubs │ │ ├── empty-class.js │ │ ├── empty-function.js │ │ └── marked.js │ ├── utils │ │ ├── env.ts │ │ ├── promise.ts │ │ ├── graphql.ts │ │ └── globals.ts │ ├── metaprogramming.ts │ ├── data-connect │ │ ├── types.ts │ │ └── language-server.ts │ └── auth │ │ └── service.ts ├── resources │ ├── GMPIcons.woff2 │ ├── monicons.woff │ ├── firebase_logo.png │ └── firebase_dataconnect_logo.png ├── .gitignore ├── graphql-language-service-5.4.0.tgz ├── .prettierignore ├── graphql-language-service-server-2.14.8.tgz ├── common │ ├── types.d.ts │ ├── declarations.d.ts │ └── messaging │ │ └── types.d.ts ├── .vscode │ ├── extensions.json │ ├── settings.json │ └── tasks.json ├── webviews │ ├── globals │ │ ├── tokens.scss │ │ ├── index.scss │ │ ├── app.tsx │ │ └── web-logger.ts │ ├── components │ │ ├── ui │ │ │ ├── ExternalLink.scss │ │ │ ├── ButtonGroup.tsx │ │ │ ├── ButtonGroup.scss │ │ │ ├── Spacer.tsx │ │ │ ├── Spacer.scss │ │ │ ├── PanelSection.scss │ │ │ ├── Icon.scss │ │ │ ├── ExternalLink.tsx │ │ │ └── IconButton.tsx │ │ ├── EmulatorPanel.scss │ │ └── AccountSection.scss │ ├── data-connect │ │ └── data-connect-execution-results.entry.tsx │ ├── fdc_sidebar.entry.tsx │ ├── tsconfig.json │ └── fdc_sidebar.entry.scss ├── webpack.dev.js ├── .vscodeignore ├── .eslintrc.json ├── webpack.prod.js └── tsconfig.json ├── .eslintignore ├── tsconfig.publish.json ├── tsconfig.dev.json ├── .mocharc.yml ├── standalone ├── check.js └── config.template.js ├── .prettierignore ├── tsconfig.compile.json └── tsconfig.json /mockdata/mock.apk: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: "0x80" 2 | -------------------------------------------------------------------------------- /scripts/dataconnect-test/.firebaserc: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /scripts/publish/.gitignore: -------------------------------------------------------------------------------- 1 | originals 2 | -------------------------------------------------------------------------------- /src/frameworks/docs/index.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /src/test/fixtures/fbrc/firebase.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /src/deploy/functions/ensureCloudBuildEnabled.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/fixtures/config-imports/unsupported.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /scripts/extensions-deploy-tests/.firebaserc: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /scripts/functions-deploy-tests/.firebaserc: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /scripts/functions-deploy-tests/firebase.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /src/test/fixtures/fbrc/invalid/firebase.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /scripts/emulator-tests/.gitignore: -------------------------------------------------------------------------------- 1 | ./functions/index.js 2 | -------------------------------------------------------------------------------- /scripts/test-project/functions/.gitignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/fixtures/fbrc/invalid/.firebaserc: -------------------------------------------------------------------------------- 1 | {{INVALID JSON}} 2 | -------------------------------------------------------------------------------- /src/test/fixtures/simplehosting/public/index.html: -------------------------------------------------------------------------------- 1 | hello 2 | -------------------------------------------------------------------------------- /templates/extensions/javascript/_gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 100, 3 | }; 4 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/functions/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | -------------------------------------------------------------------------------- /src/test/fixtures/ignores/.hiddenfile: -------------------------------------------------------------------------------- 1 | THIS SHOULD BE IGNORED 2 | -------------------------------------------------------------------------------- /src/test/fixtures/ignores/ignored.txt: -------------------------------------------------------------------------------- 1 | THIS SHOULD BE IGNORED 2 | -------------------------------------------------------------------------------- /src/test/fixtures/ignores/index.html: -------------------------------------------------------------------------------- 1 | THIS SHOULD NOT BE IGNORED 2 | -------------------------------------------------------------------------------- /scripts/firepit-builder/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | -------------------------------------------------------------------------------- /src/test/fixtures/ignores/ignored/ignore.txt: -------------------------------------------------------------------------------- 1 | THIS SHOULD BE IGNORED 2 | -------------------------------------------------------------------------------- /templates/extensions/CL-template.md: -------------------------------------------------------------------------------- 1 | ## Version 0.0.1 2 | - Initial Version -------------------------------------------------------------------------------- /templates/init/functions/javascript/_gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | *.local -------------------------------------------------------------------------------- /templates/init/functions/python/requirements.txt: -------------------------------------------------------------------------------- 1 | firebase_functions~=0.1.0 -------------------------------------------------------------------------------- /src/test/fixtures/ignores/ignored/deeper/index.txt: -------------------------------------------------------------------------------- 1 | THIS SHOULD BE IGNORED 2 | -------------------------------------------------------------------------------- /src/test/fixtures/ignores/ignored/index.html: -------------------------------------------------------------------------------- 1 | THIS SHOULD NOT BE IGNORED 2 | -------------------------------------------------------------------------------- /src/test/fixtures/ignores/present/index.html: -------------------------------------------------------------------------------- 1 | THIS SHOULD NOT BE IGNORED 2 | -------------------------------------------------------------------------------- /templates/init/dataconnect/connector.yaml: -------------------------------------------------------------------------------- 1 | connectorId: __connectorId__ 2 | -------------------------------------------------------------------------------- /firebase-vscode/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 80, 3 | }; 4 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/test_projects/empty/README: -------------------------------------------------------------------------------- 1 | DO NOT DELETE - Used for testing -------------------------------------------------------------------------------- /templates/extensions/integration-test.env: -------------------------------------------------------------------------------- 1 | GREETING=Hello 2 | LOCATION=us-central1 -------------------------------------------------------------------------------- /scripts/test-project/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /firebase-vscode/src/stubs/empty-class.js: -------------------------------------------------------------------------------- 1 | class Noop {} 2 | 3 | module.exports = Noop; 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | coverage 2 | dev 3 | lib 4 | node_modules 5 | standalone 6 | templates 7 | .firebase 8 | -------------------------------------------------------------------------------- /firebase-vscode/src/stubs/empty-function.js: -------------------------------------------------------------------------------- 1 | const noop = () => {}; 2 | 3 | module.exports = noop; 4 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/test_projects/.gitignore: -------------------------------------------------------------------------------- 1 | # Don't commit generated files 2 | **/.dataconnect/ -------------------------------------------------------------------------------- /scripts/dataconnect-test/templates/connector.yaml: -------------------------------------------------------------------------------- 1 | connectorId: "connectorId" 2 | authMode: "PUBLIC" 3 | -------------------------------------------------------------------------------- /scripts/triggers-end-to-end-tests/v1/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .eslintrc 3 | package-lock.json 4 | -------------------------------------------------------------------------------- /scripts/triggers-end-to-end-tests/v2/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .eslintrc 3 | package-lock.json 4 | -------------------------------------------------------------------------------- /src/test/fixtures/config-imports/rules.json: -------------------------------------------------------------------------------- 1 | { 2 | ".read": false, 3 | ".write": false 4 | } 5 | -------------------------------------------------------------------------------- /src/test/fixtures/dup-top-level/rules.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | ".read": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/test/fixtures/extension-yamls/invalid/extension.yaml: -------------------------------------------------------------------------------- 1 | name: foo 2 | unknownkey 3 | other: value 4 | -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/uncompressed/inflated/dir/fileInsideDir.txt: -------------------------------------------------------------------------------- 1 | 42 2 | -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/uncompressed/inflated/file.txt: -------------------------------------------------------------------------------- 1 | node.js rocks 2 | -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/zip-slip/inflated/good.txt: -------------------------------------------------------------------------------- 1 | this is a good one 2 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/test_projects/fishfood/dataconnect/connectors/a/connector.yaml: -------------------------------------------------------------------------------- 1 | connectorId: "a" 2 | -------------------------------------------------------------------------------- /scripts/extensions-emulator-tests/functions/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .eslintrc 3 | package-lock.json 4 | -------------------------------------------------------------------------------- /scripts/triggers-end-to-end-tests/triggers/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .eslintrc 3 | package-lock.json 4 | -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/compressed-standard/inflated/dir/fileInsideDir.txt: -------------------------------------------------------------------------------- 1 | 42 2 | -------------------------------------------------------------------------------- /scripts/clean-shrinkwrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | npx ts-node ./scripts/clean-shrinkwrap.ts "$1" 5 | -------------------------------------------------------------------------------- /scripts/dataconnect-emulator-tests/fdc-test/schema/schema.gql: -------------------------------------------------------------------------------- 1 | type Order @table { 2 | name: String! 3 | } 4 | -------------------------------------------------------------------------------- /scripts/dataconnect-test/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "dataconnect": { 3 | "source": "fdc-test" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/apphosting/index.ts: -------------------------------------------------------------------------------- 1 | import { doSetup } from "./backend"; 2 | 3 | export { doSetup as setupBackend }; 4 | -------------------------------------------------------------------------------- /src/test/fixtures/dup-top-level/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "firebase":"random", 3 | "rules":"rules.json" 4 | } 5 | -------------------------------------------------------------------------------- /src/test/fixtures/simplehosting/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": { 3 | "public": "public" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/compressed-flags-set/inflated/dir/fileInsideDir.txt: -------------------------------------------------------------------------------- 1 | 42 2 | -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/zip64/inflated/README: -------------------------------------------------------------------------------- 1 | This small file is in ZIP64 format. 2 | -------------------------------------------------------------------------------- /templates/extensions/typescript/tsconfig.dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | ".eslintrc.js" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /firebase-vscode/src/utils/env.ts: -------------------------------------------------------------------------------- 1 | // Set by the `package.json` file 2 | export const isTest = !!process.env.TEST; 3 | -------------------------------------------------------------------------------- /scripts/publish/hub.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/scripts/publish/hub.enc -------------------------------------------------------------------------------- /scripts/publish/npmrc.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/scripts/publish/npmrc.enc -------------------------------------------------------------------------------- /scripts/test-project/database.rules.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | ".read": true, 4 | ".write": true 5 | } 6 | } -------------------------------------------------------------------------------- /src/mcp/prompts/core/index.ts: -------------------------------------------------------------------------------- 1 | import { deploy } from "./deploy"; 2 | 3 | export const corePrompts = [deploy]; 4 | -------------------------------------------------------------------------------- /src/test/fixtures/extension-yamls/sample-ext-preinstall/PREINSTALL.md: -------------------------------------------------------------------------------- 1 | This is a PREINSTALL file for testing with. 2 | -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/compressed-directory-entry/inflated/mimetype: -------------------------------------------------------------------------------- 1 | application/epub+zip -------------------------------------------------------------------------------- /templates/init/functions/typescript/tsconfig.dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | ".eslintrc.js" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /scripts/dataconnect-emulator-tests/fdc-test/connector/connector.yaml: -------------------------------------------------------------------------------- 1 | connectorId: "connectorId" 2 | authMode: "PUBLIC" 3 | -------------------------------------------------------------------------------- /scripts/dataconnect-emulator-tests/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "dataconnect": { 3 | "source": "fdc-test" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/yarn-workspaces/packages/a-test-pkg/index.js: -------------------------------------------------------------------------------- 1 | exports.msg = "Hello world!"; 2 | -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/mapped-emulator-data/storage_export/blobs/eaa2803e-4374-44bd-98cb-cdd7d31e3347: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/fixtures/config-imports/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": "hosting.json", 3 | "rules": "rules.json" 4 | } 5 | -------------------------------------------------------------------------------- /firebase-vscode/src/stubs/marked.js: -------------------------------------------------------------------------------- 1 | function marked() {} 2 | 3 | marked.setOptions = () => {}; 4 | 5 | export { marked }; 6 | -------------------------------------------------------------------------------- /scripts/creds-private.json.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/scripts/creds-private.json.enc -------------------------------------------------------------------------------- /scripts/creds-public.json.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/scripts/creds-public.json.enc -------------------------------------------------------------------------------- /scripts/emulator-import-export-tests/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "fir-tools-testing" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /scripts/extensions-emulator-tests/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "fir-tools-testing" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/bundled/dist/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dist", 3 | "version": "0.0.1" 4 | } 5 | -------------------------------------------------------------------------------- /scripts/publish/deploy_key.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/scripts/publish/deploy_key.enc -------------------------------------------------------------------------------- /scripts/triggers-end-to-end-tests/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "fir-tools-testing" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /scripts/publish/firebase-docker-image/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "firebase-tools": "latest" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /scripts/publish/twitter.json.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/scripts/publish/twitter.json.enc -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/nested-emulator-data/storage_export/blobs/fake-project-id.appspot.com/test_upload.jpg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/windows-emulator-data/storage_export/blobs/fake-project-id.appspot.com%5Ctest_upload.jpg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/app/app/ssg/page.tsx: -------------------------------------------------------------------------------- 1 | export default function SSG() { 2 | return <>SSG; 3 | } 4 | -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/flattened-emulator-data/storage_export/blobs/fake-project-id.appspot.com%2Ftest_upload.jpg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /scripts/test-project/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /src/deploy/remoteconfig/deploy.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-empty-function 2 | export default async function () {} 3 | -------------------------------------------------------------------------------- /src/test/fixtures/fbrc/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "top": true, 3 | "projects": { 4 | "default": "top", 5 | "other": "top" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/types/update-notifier-cjs.d.ts: -------------------------------------------------------------------------------- 1 | declare module "update-notifier-cjs" { 2 | import m from "update-notifier"; 3 | export = m; 4 | } 5 | -------------------------------------------------------------------------------- /templates/init/functions/python/_gitignore: -------------------------------------------------------------------------------- 1 | # Python bytecode 2 | __pycache__/ 3 | 4 | # Python virtual environment 5 | venv/ 6 | *.local 7 | -------------------------------------------------------------------------------- /firebase-vscode/resources/GMPIcons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/firebase-vscode/resources/GMPIcons.woff2 -------------------------------------------------------------------------------- /firebase-vscode/resources/monicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/firebase-vscode/resources/monicons.woff -------------------------------------------------------------------------------- /src/deploy/hosting/index.ts: -------------------------------------------------------------------------------- 1 | export { prepare } from "./prepare"; 2 | export { deploy } from "./deploy"; 3 | export { release } from "./release"; 4 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/bundled/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euxo pipefail # bash strict mode 3 | IFS=$'\n\t' 4 | 5 | npm i 6 | -------------------------------------------------------------------------------- /src/deploy/database/deploy.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-empty-function 2 | export async function deploy(): Promise {} 3 | -------------------------------------------------------------------------------- /src/deploy/database/index.ts: -------------------------------------------------------------------------------- 1 | export { prepare } from "./prepare"; 2 | export { deploy } from "./deploy"; 3 | export { release } from "./release"; 4 | -------------------------------------------------------------------------------- /src/deploy/extensions/index.ts: -------------------------------------------------------------------------------- 1 | export { prepare } from "./prepare"; 2 | export { deploy } from "./deploy"; 3 | export { release } from "./release"; 4 | -------------------------------------------------------------------------------- /src/deploy/functions/index.ts: -------------------------------------------------------------------------------- 1 | export { prepare } from "./prepare"; 2 | export { deploy } from "./deploy"; 3 | export { release } from "./release"; 4 | -------------------------------------------------------------------------------- /src/deploy/hosting/args.ts: -------------------------------------------------------------------------------- 1 | import type { Payload as FunctionsPayload } from "../functions/args"; 2 | 3 | export type Payload = FunctionsPayload; 4 | -------------------------------------------------------------------------------- /src/frameworks/docs/lit.md: -------------------------------------------------------------------------------- 1 | # Integrate Lit 2 | 3 | Lit support is built on the Vite framework integration. See [vite.md](./vite.md) for full guidance. -------------------------------------------------------------------------------- /src/test/emulators/extensions/firebase/storage-resize-images@0.1.18/functions/.gitignore: -------------------------------------------------------------------------------- 1 | #include node_modules here for testing. 2 | !/node_modules 3 | -------------------------------------------------------------------------------- /src/test/fixtures/fbrc/conflict/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "conflict", 4 | "unconflicted": "conflict" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /firebase-vscode/resources/firebase_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/firebase-vscode/resources/firebase_logo.png -------------------------------------------------------------------------------- /scripts/clean.ts: -------------------------------------------------------------------------------- 1 | import { removeSync } from "fs-extra"; 2 | import { resolve } from "path"; 3 | 4 | removeSync(`${resolve(__dirname, "..", "lib")}`); 5 | -------------------------------------------------------------------------------- /scripts/client-integration-tests/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source scripts/set-default-credentials.sh 4 | 5 | mocha scripts/client-integration-tests/tests.ts -------------------------------------------------------------------------------- /scripts/dataconnect-emulator-tests/fdc-test/connector/queries.gql: -------------------------------------------------------------------------------- 1 | mutation createOrder($name: String!) { 2 | order_insert(data : {name: $name}) 3 | } 4 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/bundled/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "functions": { 3 | "source": "dist", 4 | "runtime": "nodejs22" 5 | } 6 | } -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/windows-emulator-data/storage_export/blobs/fake-project-id.appspot.com%5Ctest-directory%5Ctest_nested_upload.jpg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/frameworks/docs/react.md: -------------------------------------------------------------------------------- 1 | # Integrate React 2 | 3 | React support is built on the Vite framework integration. See [vite.md](./vite.md) for full guidance. -------------------------------------------------------------------------------- /firebase-vscode/.gitignore: -------------------------------------------------------------------------------- 1 | *.vsix 2 | dist/ 3 | *.scss.d.ts 4 | resources/dist 5 | .vscode-test 6 | .wdio-vscode-service 7 | logs 8 | !*.tgz 9 | prebuilt-extensions -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/esm/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "functions": { 3 | "source": "functions", 4 | "runtime": "nodejs22" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/esm/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euxo pipefail # bash strict mode 3 | IFS=$'\n\t' 4 | 5 | cd functions && npm i 6 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/pnpm/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "functions": { 3 | "source": "functions", 4 | "runtime": "nodejs22" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/yarn-workspaces/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euxo pipefail # bash strict mode 3 | IFS=$'\n\t' 4 | 5 | yarn install -------------------------------------------------------------------------------- /src/frameworks/docs/preact.md: -------------------------------------------------------------------------------- 1 | # Integrate Preact 2 | 3 | Preact support is built on the Vite framework integration. See [vite.md](./vite.md) for full guidance. -------------------------------------------------------------------------------- /src/frameworks/docs/svelte.md: -------------------------------------------------------------------------------- 1 | # Integrate Svelte 2 | 3 | Svelte support is built on the Vite framework integration. See [vite.md](./vite.md) for full guidance. -------------------------------------------------------------------------------- /firebase-vscode/graphql-language-service-5.4.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/firebase-vscode/graphql-language-service-5.4.0.tgz -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/simple/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "functions": { 3 | "source": "functions", 4 | "runtime": "nodejs22" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/simple/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euxo pipefail # bash strict mode 3 | IFS=$'\n\t' 4 | 5 | cd functions && npm i 6 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/stress-test/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "functions": { 3 | "source": "functions", 4 | "runtime": "nodejs22" 5 | } 6 | } -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/stress-test/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euxo pipefail # bash strict mode 3 | IFS=$'\n\t' 4 | 5 | cd functions && npm i -------------------------------------------------------------------------------- /scripts/mcp-tests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2022", 4 | "module": "NodeNext", 5 | "skipLibCheck": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /scripts/test-project/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "database": { 3 | "rules": "database.rules.json" 4 | }, 5 | "hosting": { 6 | "public": "public" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/app/app/isr/page.tsx: -------------------------------------------------------------------------------- 1 | export const revalidate = 60; 2 | 3 | export default function ISR() { 4 | return <>ISR; 5 | } 6 | -------------------------------------------------------------------------------- /src/test/fixtures/ignores/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": { 3 | "public": ".", 4 | "ignore": ["index.ts", "ignored.txt", "ignored/**/*.txt"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /scripts/extensions-emulator-tests/functions/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/scripts/extensions-emulator-tests/functions/test.png -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/pnpm/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euxo pipefail # bash strict mode 3 | IFS=$'\n\t' 4 | 5 | cd functions && pnpm install 6 | -------------------------------------------------------------------------------- /scripts/hosting-tests/rewrites-tests/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source scripts/set-default-credentials.sh 4 | 5 | mocha scripts/hosting-tests/rewrites-tests/tests.ts 6 | -------------------------------------------------------------------------------- /src/functions/events/index.ts: -------------------------------------------------------------------------------- 1 | import * as v1 from "./v1"; 2 | import * as v2 from "./v2"; 3 | 4 | export { v1, v2 }; 5 | 6 | export type Event = v1.Event | v2.Event; 7 | -------------------------------------------------------------------------------- /firebase-vscode/resources/firebase_dataconnect_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/firebase-vscode/resources/firebase_dataconnect_logo.png -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/pnpm/functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pnpm", 3 | "dependencies": { 4 | "firebase-functions": "^6.4.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/simple/functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple", 3 | "dependencies": { 4 | "firebase-functions": "^6.4.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/yarn-workspaces/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "functions": { 3 | "source": "packages/functions", 4 | "runtime": "nodejs22" 5 | } 6 | } -------------------------------------------------------------------------------- /src/test/fixtures/config-imports/hosting.json: -------------------------------------------------------------------------------- 1 | { 2 | // this is a comment, deal with it 3 | "public": ".", 4 | "ignore": ["index.ts", "**/.*"], 5 | "extra": true 6 | } 7 | -------------------------------------------------------------------------------- /src/test/fixtures/extension-yamls/invalid/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * An extension directory containing an invalid extension.yaml. 3 | */ 4 | export const FIXTURE_DIR = __dirname; 5 | -------------------------------------------------------------------------------- /src/test/fixtures/extension-yamls/sample-ext/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A valid extension directory containing an extension.yaml. 3 | */ 4 | export const FIXTURE_DIR = __dirname; 5 | -------------------------------------------------------------------------------- /src/test/fixtures/ignores/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A directory containing a firebase.json that specifies files to be ignored. 3 | */ 4 | export const FIXTURE_DIR = __dirname; 5 | -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/compressed-directory-entry/inflated/page_styles.css: -------------------------------------------------------------------------------- 1 | @page { 2 | margin-bottom: 5pt; 3 | margin-top: 5pt 4 | } 5 | -------------------------------------------------------------------------------- /firebase-vscode/.prettierignore: -------------------------------------------------------------------------------- 1 | ## The default 2 | **/.git 3 | **/.svn 4 | **/.hg 5 | **/node_modules 6 | 7 | ## The good stuff 8 | dist 9 | resources 10 | package-lock.json -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/codebases/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euxo pipefail # bash strict mode 3 | IFS=$'\n\t' 4 | 5 | (cd v1 && npm i) 6 | (cd v2 && npm i) 7 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/codebases/v1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codebase-v1", 3 | "dependencies": { 4 | "firebase-functions": "^6.4.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/stress-test/functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stress-test", 3 | "dependencies": { 4 | "firebase-functions": "^6.4.0" 5 | } 6 | } -------------------------------------------------------------------------------- /src/deploy/storage/index.ts: -------------------------------------------------------------------------------- 1 | import prepare from "./prepare"; 2 | import deploy from "./deploy"; 3 | import release from "./release"; 4 | 5 | export { prepare, deploy, release }; 6 | -------------------------------------------------------------------------------- /src/test/fixtures/extension-yamls/minimal/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A valid extension directory containing a minimal extension.yaml. 3 | */ 4 | export const FIXTURE_DIR = __dirname; 5 | -------------------------------------------------------------------------------- /src/test/fixtures/extension-yamls/valid-yaml-invalid-spec/extension.yaml: -------------------------------------------------------------------------------- 1 | specVersion: v1beta 2 | name: fixture-ext-missing-resources 3 | version: 1.0.0 4 | license: apache-2.0 5 | -------------------------------------------------------------------------------- /templates/extensions/typescript/_gitignore: -------------------------------------------------------------------------------- 1 | ## Compiled JavaScript files 2 | **/*.js 3 | **/*.js.map 4 | 5 | # Typescript v1 declaration files 6 | typings/ 7 | 8 | node_modules/ 9 | -------------------------------------------------------------------------------- /firebase-vscode/graphql-language-service-server-2.14.8.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/firebase-vscode/graphql-language-service-server-2.14.8.tgz -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/bundled/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dist", 3 | "version": "0.0.1", 4 | "dependencies": { 5 | "firebase-functions": "^6.4.0" 6 | } 7 | } -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/yarn-workspaces/packages/a-test-pkg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@firebase/a-test-pkg", 3 | "version": "0.0.1", 4 | "private": true 5 | } 6 | -------------------------------------------------------------------------------- /src/deploy/apphosting/index.ts: -------------------------------------------------------------------------------- 1 | import prepare from "./prepare"; 2 | import deploy from "./deploy"; 3 | import release from "./release"; 4 | 5 | export { prepare, deploy, release }; 6 | -------------------------------------------------------------------------------- /src/deploy/dataconnect/index.ts: -------------------------------------------------------------------------------- 1 | import prepare from "./prepare"; 2 | import deploy from "./deploy"; 3 | import release from "./release"; 4 | 5 | export { prepare, deploy, release }; 6 | -------------------------------------------------------------------------------- /src/deploy/firestore/index.ts: -------------------------------------------------------------------------------- 1 | import prepare from "./prepare"; 2 | import deploy from "./deploy"; 3 | import release from "./release"; 4 | 5 | export { prepare, deploy, release }; 6 | -------------------------------------------------------------------------------- /src/deploy/remoteconfig/index.ts: -------------------------------------------------------------------------------- 1 | import prepare from "./prepare"; 2 | import release from "./release"; 3 | import deploy from "./deploy"; 4 | 5 | export { prepare, release, deploy }; 6 | -------------------------------------------------------------------------------- /src/frameworks/sveltekit/interfaces.ts: -------------------------------------------------------------------------------- 1 | export interface SvelteKitConfig { 2 | kit: { 3 | outDir: string; 4 | adapter?: { 5 | name: string; 6 | }; 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /src/test/fixtures/extension-yamls/hello-world/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A valid extension directory containing a full-blown extension.yaml. 3 | */ 4 | export const FIXTURE_DIR = __dirname; 5 | -------------------------------------------------------------------------------- /src/test/fixtures/extension-yamls/sample-ext-preinstall/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A valid extension directory containing a PREINSTALL.md. 3 | */ 4 | export const FIXTURE_DIR = __dirname; 5 | -------------------------------------------------------------------------------- /src/test/fixtures/rulesDeployCrossService/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A directory containing storage rules that fetches data from Firestore. 3 | */ 4 | export const FIXTURE_DIR = __dirname; 5 | -------------------------------------------------------------------------------- /templates/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "firebase": null, 3 | "public": null, 4 | "ignore": [ 5 | "firebase.json", 6 | "**/.*", 7 | "**/node_modules/**" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/mapped-emulator-data/storage_export/buckets.json: -------------------------------------------------------------------------------- 1 | { 2 | "buckets": [ 3 | { 4 | "id": "fake-project-id.appspot.com" 5 | } 6 | ] 7 | } -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/nested-emulator-data/storage_export/buckets.json: -------------------------------------------------------------------------------- 1 | { 2 | "buckets": [ 3 | { 4 | "id": "fake-project-id.appspot.com" 5 | } 6 | ] 7 | } -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/windows-emulator-data/storage_export/buckets.json: -------------------------------------------------------------------------------- 1 | { 2 | "buckets": [ 3 | { 4 | "id": "fake-project-id.appspot.com" 5 | } 6 | ] 7 | } -------------------------------------------------------------------------------- /src/types/proxy/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module "proxy" { 2 | import { Server } from "http"; 3 | 4 | function SetupFunction(server: Server): Server; 5 | 6 | export = SetupFunction; 7 | } 8 | -------------------------------------------------------------------------------- /scripts/extensions-deploy-tests/extensions/test-instance2.env: -------------------------------------------------------------------------------- 1 | IMG_BUCKET=joehanley-public.appspot.com 2 | IMG_SIZES=100x100 3 | DELETE_ORIGINAL_FILE=false 4 | IMAGE_TYPE=jpeg 5 | LOCATION=us-central1 -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/esm/functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esm", 3 | "type": "module", 4 | "dependencies": { 5 | "firebase-functions": "^6.4.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/yarn-workspaces/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yarn-workspace", 3 | "private": true, 4 | "workspaces": ["packages/functions", "packages/a-test-pkg"] 5 | } -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/flattened-emulator-data/storage_export/buckets.json: -------------------------------------------------------------------------------- 1 | { 2 | "buckets": [ 3 | { 4 | "id": "fake-project-id.appspot.com" 5 | } 6 | ] 7 | } -------------------------------------------------------------------------------- /src/mcp/tools/messaging/index.ts: -------------------------------------------------------------------------------- 1 | import { ServerTool } from "../../tool"; 2 | import { send_message } from "./send_message"; 3 | 4 | export const messagingTools: ServerTool[] = [send_message]; 5 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/codebases/v2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codebase-v2", 3 | "type": "module", 4 | "dependencies": { 5 | "firebase-functions": "^6.4.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/mcp/prompts/crashlytics/index.ts: -------------------------------------------------------------------------------- 1 | import type { ServerPrompt } from "../../prompt"; 2 | import { connect } from "./connect"; 3 | 4 | export const crashlyticsPrompts: ServerPrompt[] = [connect]; 5 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/test_projects/fishfood/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "test-project" 4 | }, 5 | "targets": {}, 6 | "etags": {}, 7 | "dataconnectEmulatorConfig": {} 8 | } -------------------------------------------------------------------------------- /firebase-vscode/src/test/test_projects/fishfood/dataconnect/connectors/a/queryWithFragment.gql: -------------------------------------------------------------------------------- 1 | query fragmentTest @auth(level: PUBLIC) { 2 | comments { 3 | ...CommentContent 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /scripts/assets/functions_to_test_minimal.js: -------------------------------------------------------------------------------- 1 | var functions = require("firebase-functions"); 2 | 3 | exports.httpsAction = functions.https.onRequest(function (req, res) { 4 | res.send(req.body); 5 | }); 6 | -------------------------------------------------------------------------------- /scripts/emulator-import-export-tests/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source scripts/set-default-credentials.sh 4 | ./scripts/clean-install.sh 5 | 6 | npx mocha --exit scripts/emulator-import-export-tests/tests.ts -------------------------------------------------------------------------------- /src/test/fixtures/extension-yamls/valid-yaml-invalid-spec/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A valid yaml file, but not a valid extension spec (missing required fields); 3 | */ 4 | export const FIXTURE_DIR = __dirname; 5 | -------------------------------------------------------------------------------- /src/test/fixtures/rulesDeploy/storage.rules: -------------------------------------------------------------------------------- 1 | service firebase.storage { 2 | match /b/{bucket}/o { 3 | match /{allPaths=**} { 4 | allow read, write: if request.auth != null; 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/zip64/archive.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/src/test/fixtures/zip-files/node-unzipper-testData/zip64/archive.zip -------------------------------------------------------------------------------- /scripts/build/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/extensions-deploy-tests/extensions/test-instance1.env: -------------------------------------------------------------------------------- 1 | TABLE_ID=posts 2 | TABLE_PARTITIONING=NONE 3 | LOCATION=us-east1 4 | DATASET_LOCATION=us 5 | COLLECTION_PATH=posters 6 | DATASET_ID=firestore_export -------------------------------------------------------------------------------- /scripts/publish/firebase-docker-image/run.sh: -------------------------------------------------------------------------------- 1 | ## Script for testing Docker image creation without running a full release. 2 | PROJECT_ID=$1 3 | npm i 4 | gcloud --project $PROJECT_ID \ 5 | builds \ 6 | submit -------------------------------------------------------------------------------- /src/test/fixtures/rulesDeploy/firestore.rules: -------------------------------------------------------------------------------- 1 | service cloud.firestore {{ 2 | match /databases/{database}/documents { 3 | match /{document=**} { 4 | allow read, write: if false; 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/zip-slip/archive.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/src/test/fixtures/zip-files/node-unzipper-testData/zip-slip/archive.zip -------------------------------------------------------------------------------- /templates/emulators/default_storage.rules: -------------------------------------------------------------------------------- 1 | rules_version = '2'; 2 | service firebase.storage { 3 | match /b/{bucket}/o { 4 | match /{allPaths=**} { 5 | allow read, write; 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.publish.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "sourceMap": false 5 | }, 6 | "exclude": ["src/**/*.spec.*", "src/**/testing/**/*", "src/test/**/*"] 7 | } 8 | -------------------------------------------------------------------------------- /firebase-vscode/common/types.d.ts: -------------------------------------------------------------------------------- 1 | export interface ServiceAccount { 2 | user: ServiceAccountUser; 3 | } 4 | 5 | export interface ServiceAccountUser { 6 | email: string; 7 | type: "service_account"; 8 | } 9 | -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/mapped-emulator-data/firebase-export-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "11.3.0", 3 | "storage": { 4 | "version": "11.3.0", 5 | "path": "storage_export" 6 | } 7 | } -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/nested-emulator-data/firebase-export-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "10.4.2", 3 | "storage": { 4 | "version": "10.4.2", 5 | "path": "storage_export" 6 | } 7 | } -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/windows-emulator-data/firebase-export-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "10.4.2", 3 | "storage": { 4 | "version": "10.4.2", 5 | "path": "storage_export" 6 | } 7 | } -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/uncompressed/archive.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/src/test/fixtures/zip-files/node-unzipper-testData/uncompressed/archive.zip -------------------------------------------------------------------------------- /firebase-vscode/common/declarations.d.ts: -------------------------------------------------------------------------------- 1 | // We need to tell TypeScript that when we write "import styles from './styles.scss' we mean to load a module (to look for a './styles.scss.d.ts'). 2 | declare module "*.scss"; 3 | -------------------------------------------------------------------------------- /scripts/firepit-builder/cloudbuild.yaml: -------------------------------------------------------------------------------- 1 | steps: 2 | - name: "gcr.io/cloud-builders/docker" 3 | args: ["build", "-t", "gcr.io/$PROJECT_ID/firepit-builder", "."] 4 | images: ["gcr.io/$PROJECT_ID/firepit-builder"] 5 | -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/flattened-emulator-data-missing-blobs-and-metadata/storage_export/buckets.json: -------------------------------------------------------------------------------- 1 | { 2 | "buckets": [ 3 | { 4 | "id": "fake-project-id.appspot.com" 5 | } 6 | ] 7 | } -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/flattened-emulator-data/firebase-export-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "10.4.2", 3 | "storage": { 4 | "version": "10.4.2", 5 | "path": "storage_export" 6 | } 7 | } -------------------------------------------------------------------------------- /src/apphosting/constants.ts: -------------------------------------------------------------------------------- 1 | export const DEFAULT_LOCATION = "us-central1"; 2 | export const DEFAULT_DEPLOY_METHOD = "github"; 3 | export const ALLOWED_DEPLOY_METHODS = [{ name: "Deploy using github", value: "github" }]; 4 | -------------------------------------------------------------------------------- /src/test/fixtures/rulesDeploy/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "storage": { 3 | "rules": "storage.rules" 4 | }, 5 | "firestore": { 6 | "rules": "firestore.rules", 7 | "indexes": "firestore.indexes.json" 8 | } 9 | } -------------------------------------------------------------------------------- /firebase-vscode/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": ["dbaeumer.vscode-eslint"] 5 | } 6 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/globals/tokens.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | --space-xsmall: 2px; 3 | --space-small: 4px; 4 | --space-medium: 8px; 5 | --space-large: 12px; 6 | --space-xlarge: 16px; 7 | --space-xxlarge: 24px; 8 | } 9 | -------------------------------------------------------------------------------- /scripts/emulator-import-export-tests/storage.rules: -------------------------------------------------------------------------------- 1 | rules_version = '2'; 2 | service firebase.storage { 3 | match /b/{bucket}/o { 4 | match /{allPaths=**} { 5 | allow read, write: if true; 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /scripts/extensions-deploy-tests/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensions": { 3 | "test-instance1": "firebase/firestore-bigquery-export@^0.1.18", 4 | "test-instance2": "firebase/storage-resize-images@^0.1.22" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /scripts/extensions-emulator-tests/storage.rules: -------------------------------------------------------------------------------- 1 | rules_version = '2'; 2 | service firebase.storage { 3 | match /b/{bucket}/o { 4 | match /{allPaths=**} { 5 | allow read, write: if true; 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /scripts/triggers-end-to-end-tests/storage.rules: -------------------------------------------------------------------------------- 1 | rules_version = '2'; 2 | service firebase.storage { 3 | match /b/{bucket}/o { 4 | match /{allPaths=**} { 5 | allow read, write: if true; 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/emulators/extensions/firebase/storage-resize-images@0.1.18/functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "storage-resize-images", 3 | "vresion": "0.1.18", 4 | "description": "Package file for testing only" 5 | } 6 | -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/compressed-cp866/archive.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/src/test/fixtures/zip-files/node-unzipper-testData/compressed-cp866/archive.zip -------------------------------------------------------------------------------- /templates/init/aitools/cursor-rules-header.txt: -------------------------------------------------------------------------------- 1 | --- 2 | description: Firebase project development guidelines 3 | globs: 4 | - "firebase.json" 5 | - "firestore.rules" 6 | - "**/*.rules" 7 | - "functions/**/*" 8 | --- 9 | -------------------------------------------------------------------------------- /src/test/fixtures/rulesDeployCrossService/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "storage": { 3 | "rules": "storage.rules" 4 | }, 5 | "firestore": { 6 | "rules": "firestore.rules", 7 | "indexes": "firestore.indexes.json" 8 | } 9 | } -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/compressed-standard/archive.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/src/test/fixtures/zip-files/node-unzipper-testData/compressed-standard/archive.zip -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/functions/index.js: -------------------------------------------------------------------------------- 1 | import { onRequest } from "firebase-functions/v2/https"; 2 | 3 | export const helloWorld = onRequest((request, response) => { 4 | response.send("Hello from Firebase!"); 5 | }); 6 | -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/compressed-cp866/inflated/Тест.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/src/test/fixtures/zip-files/node-unzipper-testData/compressed-cp866/inflated/Тест.txt -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/compressed-flags-set/archive.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/src/test/fixtures/zip-files/node-unzipper-testData/compressed-flags-set/archive.zip -------------------------------------------------------------------------------- /scripts/extensions-deploy-tests/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e # Immediately exit on failure 3 | 4 | # Globally link the CLI for the testing framework 5 | ./scripts/clean-install.sh 6 | 7 | mocha scripts/extensions-deploy-tests/tests.ts 8 | -------------------------------------------------------------------------------- /templates/extensions/typescript/_mocharc: -------------------------------------------------------------------------------- 1 | { 2 | "require": "ts-node/register", 3 | "extensions": ["ts", "tsx"], 4 | "spec": [ 5 | "integration-tests/**/*.spec.*" 6 | ], 7 | "watch-files": [ 8 | "src" 9 | ] 10 | } -------------------------------------------------------------------------------- /firebase-vscode/src/metaprogramming.ts: -------------------------------------------------------------------------------- 1 | export type DeepReadOnly = T extends Record 2 | ? { readonly [K in keyof T]: DeepReadOnly } 3 | : T extends Array 4 | ? ReadonlyArray> 5 | : T; 6 | -------------------------------------------------------------------------------- /firebase-vscode/webpack.dev.js: -------------------------------------------------------------------------------- 1 | const { merge } = require("webpack-merge"); 2 | const common = require("./webpack.common.js"); 3 | 4 | module.exports = common.map((config) => 5 | merge(config, { 6 | mode: "development", 7 | }) 8 | ); 9 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/codebases/v1/index.js: -------------------------------------------------------------------------------- 1 | const functions = require("firebase-functions"); 2 | 3 | exports.hellov1 = functions.https.onRequest((request, response) => { 4 | response.send("Hello from Firebase!"); 5 | }); 6 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/codebases/v2/index.js: -------------------------------------------------------------------------------- 1 | import { onRequest } from "firebase-functions/v2/https"; 2 | 3 | export const hellov2 = onRequest((request, response) => { 4 | response.send("Hello from Firebase!"); 5 | }); 6 | -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/flattened-emulator-data-missing-blobs-and-metadata/firebase-export-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "10.4.2", 3 | "storage": { 4 | "version": "10.4.2", 5 | "path": "storage_export" 6 | } 7 | } -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/multiple-targets/allowAll.rules: -------------------------------------------------------------------------------- 1 | rules_version = '2'; 2 | service firebase.storage { 3 | match /b/{bucket}/o { 4 | match /{allPaths=**} { 5 | allow read, write: if true; 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/multiple-targets/allowNone.rules: -------------------------------------------------------------------------------- 1 | rules_version = '2'; 2 | service firebase.storage { 3 | match /b/{bucket}/o { 4 | match /{allPaths=**} { 5 | allow read, write: if false; 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/app/app/ssr/page.tsx: -------------------------------------------------------------------------------- 1 | 'use server' 2 | 3 | import { headers } from 'next/headers'; 4 | 5 | export default async function SSR() { 6 | const headersList = headers(); 7 | return <>SSR; 8 | } 9 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/app/layout.tsx: -------------------------------------------------------------------------------- 1 | export default function RootLayout({ children }: any) { 2 | return ( 3 | 4 | 5 | {children} 6 | 7 | ) 8 | } 9 | -------------------------------------------------------------------------------- /src/configstore.ts: -------------------------------------------------------------------------------- 1 | import * as Configstore from "configstore"; 2 | 3 | // eslint-disable-next-line @typescript-eslint/no-var-requires 4 | const pkg = require("../package.json"); 5 | 6 | export const configstore = new Configstore(pkg.name); 7 | -------------------------------------------------------------------------------- /src/extensions/publishHelpers.ts: -------------------------------------------------------------------------------- 1 | import { consoleOrigin } from "../api"; 2 | 3 | export function consoleInstallLink(extVersionRef: string): string { 4 | return `${consoleOrigin()}/project/_/extensions/install?ref=${extVersionRef}`; 5 | } 6 | -------------------------------------------------------------------------------- /src/test/fixtures/dup-top-level/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A directory containing a rules.json that has a top-level `rules: {...}` key 3 | * that is duplicate with the `rules:` key in `firebase.json`. 4 | */ 5 | export const FIXTURE_DIR = __dirname; 6 | -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/compressed-directory-entry/archive.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x80/firebase-tools-with-isolate/HEAD/src/test/fixtures/zip-files/node-unzipper-testData/compressed-directory-entry/archive.zip -------------------------------------------------------------------------------- /templates/init/functions/typescript/_gitignore: -------------------------------------------------------------------------------- 1 | # Compiled JavaScript files 2 | lib/**/*.js 3 | lib/**/*.js.map 4 | 5 | # TypeScript v1 declaration files 6 | typings/ 7 | 8 | # Node.js dependency directory 9 | node_modules/ 10 | *.local -------------------------------------------------------------------------------- /src/test/fixtures/rulesDeployCrossService/storage.rules: -------------------------------------------------------------------------------- 1 | service firebase.storage { 2 | match /b/{bucket}/o { 3 | match /{allPaths=**} { 4 | allow read, write: if firestore.exists(/databases/default/documents/foo/bar); 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /firebase-vscode/src/test/test_projects/fishfood/dataconnect/schema/schema.gql: -------------------------------------------------------------------------------- 1 | type Post @table { 2 | id: String! 3 | content: String! 4 | } 5 | 6 | type Comment @table { 7 | id: String! 8 | content: String! 9 | post: Post! 10 | } 11 | -------------------------------------------------------------------------------- /src/emulator/auth/types.ts: -------------------------------------------------------------------------------- 1 | import * as schema from "./schema"; 2 | export type Schemas = schema.components["schemas"]; 3 | export type MfaEnrollment = Schemas["GoogleCloudIdentitytoolkitV1MfaEnrollment"]; 4 | export type MfaEnrollments = MfaEnrollment[]; 5 | -------------------------------------------------------------------------------- /src/mcp/tools/apphosting/index.ts: -------------------------------------------------------------------------------- 1 | import { ServerTool } from "../../tool"; 2 | import { fetch_logs } from "./fetch_logs"; 3 | import { list_backends } from "./list_backends"; 4 | 5 | export const appHostingTools: ServerTool[] = [fetch_logs, list_backends]; 6 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/components/ui/ExternalLink.scss: -------------------------------------------------------------------------------- 1 | .link-content { 2 | align-items: center; 3 | display: inline-flex; 4 | gap: 4px; 5 | } 6 | 7 | .link:hover .link-text, 8 | .link:focus .link-text { 9 | text-decoration: underline; 10 | } 11 | -------------------------------------------------------------------------------- /src/emulator/storage/errors.ts: -------------------------------------------------------------------------------- 1 | /** Error that signals that a resource could not be found */ 2 | export class NotFoundError extends Error {} 3 | 4 | /** Error that signals that a necessary permission was lacking. */ 5 | export class ForbiddenError extends Error {} 6 | -------------------------------------------------------------------------------- /src/throttler/errors/timeout-error.ts: -------------------------------------------------------------------------------- 1 | import TaskError from "./task-error"; 2 | 3 | export default class TimeoutError extends TaskError { 4 | constructor(taskName: string, timeout: number) { 5 | super(taskName, `timed out after ${timeout}ms.`); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tsconfig.dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "noEmit": true, 5 | "removeComments": false, 6 | }, 7 | "include": [ 8 | "scripts/**/*", 9 | ".eslintrc.js", 10 | ".prettierrc.js", 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/globals/index.scss: -------------------------------------------------------------------------------- 1 | @import "./tokens.scss"; 2 | @import "./vscode.scss"; 3 | 4 | body { 5 | background-color: transparent; 6 | cursor: default; 7 | } 8 | 9 | :global #root { 10 | display: flex; 11 | flex-direction: column; 12 | } 13 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import '../styles/globals.css' 2 | import type { AppProps } from 'next/app' 3 | 4 | function MyApp({ Component, pageProps }: AppProps) { 5 | return 6 | } 7 | 8 | export default MyApp 9 | -------------------------------------------------------------------------------- /src/deploy/apphosting/args.ts: -------------------------------------------------------------------------------- 1 | import { AppHostingSingle } from "../../firebaseConfig"; 2 | 3 | export interface Context { 4 | backendConfigs: Map; 5 | backendLocations: Map; 6 | backendStorageUris: Map; 7 | } 8 | -------------------------------------------------------------------------------- /src/frameworks/next/testing/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./paths"; 2 | export * from "./headers"; 3 | export * from "./redirects"; 4 | export * from "./rewrites"; 5 | export * from "./images"; 6 | export * from "./middleware"; 7 | export * from "./npm"; 8 | export * from "./app"; 9 | -------------------------------------------------------------------------------- /src/test/fixtures/valid-config/index.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from "path"; 2 | 3 | /** 4 | * A directory containing valid full-blown firebase.json. 5 | */ 6 | export const FIXTURE_DIR = __dirname; 7 | 8 | export const FIREBASE_JSON_PATH = resolve(__dirname, "firebase.json"); 9 | -------------------------------------------------------------------------------- /.mocharc.yml: -------------------------------------------------------------------------------- 1 | require: 2 | - ts-node/register 3 | - source-map-support/register 4 | - src/test/helpers/mocha-bootstrap.ts 5 | file: 6 | - src/test/helpers/global-mock-auth.ts 7 | timeout: 1000 8 | recursive: true 9 | node-options: 10 | - no-experimental-strip-types 11 | -------------------------------------------------------------------------------- /templates/init/apptesting/smoke_test.yaml: -------------------------------------------------------------------------------- 1 | tests: 2 | - testName: Smoke test 3 | steps: 4 | - goal: View the provided application 5 | hint: No additional actions should be necessary 6 | successCriteria: The application should load with no obvious errors 7 | -------------------------------------------------------------------------------- /scripts/client-integration-tests/test-project/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": [{ 3 | "target": "client-integration-site", 4 | "public": "public", 5 | "ignore": [ 6 | "firebase.json", 7 | "**/.*", 8 | "**/node_modules/**" 9 | ] 10 | }] 11 | } 12 | -------------------------------------------------------------------------------- /src/test/helpers/global-mock-auth.ts: -------------------------------------------------------------------------------- 1 | import * as sinon from "sinon"; 2 | 3 | import { mockAuth } from "./"; 4 | 5 | const authSandbox = sinon.createSandbox(); 6 | before(() => { 7 | mockAuth(authSandbox); 8 | }); 9 | 10 | after(() => { 11 | authSandbox.restore(); 12 | }); 13 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/components/ui/ButtonGroup.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactNode } from "react"; 2 | import styles from "./ButtonGroup.scss"; 3 | 4 | export function ButtonGroup({ children }: { children: ReactNode }) { 5 | return
{children}
; 6 | } 7 | -------------------------------------------------------------------------------- /scripts/extensions-emulator-tests/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source scripts/set-default-credentials.sh 4 | ./scripts/clean-install.sh 5 | 6 | ( 7 | cd scripts/extensions-emulator-tests/functions 8 | npm install 9 | ) 10 | 11 | mocha scripts/extensions-emulator-tests/tests.ts 12 | -------------------------------------------------------------------------------- /scripts/test-project/functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions", 3 | "description": "Firebase Functions", 4 | "dependencies": { 5 | "firebase-admin": "^12.0.0", 6 | "firebase-functions": "^4.9.0" 7 | }, 8 | "engines": { 9 | "node": "20" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/fixtures/rulesDeploy/index.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from "path"; 2 | 3 | /** 4 | * A directory containing firestore and storage rules to be deployed. 5 | */ 6 | export const FIXTURE_DIR = __dirname; 7 | 8 | export const FIXTURE_FIRESTORE_RULES_PATH = resolve(__dirname, "firestore.rules"); 9 | -------------------------------------------------------------------------------- /src/test/fixtures/simplehosting/index.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from "path"; 2 | 3 | /** 4 | * A directory containing a simple project with Firebase Hosting configured. 5 | */ 6 | export const FIXTURE_DIR = __dirname; 7 | 8 | export const FIREBASE_JSON_PATH = resolve(__dirname, "firebase.json"); 9 | -------------------------------------------------------------------------------- /src/test/fixtures/config-imports/index.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from "path"; 2 | 3 | /** 4 | * A directory containing a simple firebase.json with hosting and rules config. 5 | */ 6 | export const FIXTURE_DIR = __dirname; 7 | 8 | export const FIREBASE_JSON_PATH = resolve(__dirname, "firebase.json"); 9 | -------------------------------------------------------------------------------- /templates/extensions/integration-test.json: -------------------------------------------------------------------------------- 1 | { 2 | "emulators": { 3 | "functions": { 4 | "port": 5001 5 | }, 6 | "ui": { 7 | "enabled": true 8 | }, 9 | "singleProjectMode": true 10 | }, 11 | "extensions": { 12 | "greet-the-world": "../.." 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/frameworks/docs/_includes/_preview-disclaimer.md: -------------------------------------------------------------------------------- 1 | Note: Framework-aware {{hosting}} is an early public preview. This means 2 | that the functionality might change in backward-incompatible ways. A preview 3 | release is not subject to any SLA or deprecation policy and may receive limited 4 | or no support. 5 | -------------------------------------------------------------------------------- /src/throttler/errors/task-error.ts: -------------------------------------------------------------------------------- 1 | import { FirebaseError } from "../../error"; 2 | 3 | export default abstract class TaskError extends FirebaseError { 4 | constructor(taskName: string, message: string, options: object = {}) { 5 | super(`Task ${taskName} failed: ${message}`, options); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/test_projects/fishfood/.graphqlrc: -------------------------------------------------------------------------------- 1 | schema: 2 | - ./dataconnect/schema/**/*.gql 3 | - ./dataconnect/.dataconnect/**/*.gql 4 | documents: 5 | - ./dataconnect/connectors/**/*.gql 6 | extensions: 7 | endpoints: 8 | default: 9 | url: http://127.0.0.1:8080/__/graphql 10 | -------------------------------------------------------------------------------- /standalone/check.js: -------------------------------------------------------------------------------- 1 | /* 2 | This file is used in firepit.js#VerifyNodePath() to test if the binary file is acting as a Node.js 3 | runtime or not. If it is acting as a runtime, then this script will return a checkmark, otherwise 4 | Firepit will respond with a non-checkmark log. 5 | */ 6 | console.log("✓"); 7 | -------------------------------------------------------------------------------- /src/test/helpers/mocha-bootstrap.ts: -------------------------------------------------------------------------------- 1 | import * as chai from "chai"; 2 | import * as chaiAsPromised from "chai-as-promised"; 3 | import * as sinonChai from "sinon-chai"; 4 | 5 | chai.use(chaiAsPromised); 6 | chai.use(sinonChai); 7 | 8 | process.on("unhandledRejection", (error) => { 9 | throw error; 10 | }); 11 | -------------------------------------------------------------------------------- /firebase-vscode/src/data-connect/types.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | 3 | export enum OPERATION_TYPE { 4 | query = "query", 5 | mutation = "mutation", 6 | } 7 | 8 | export interface OperationLocation { 9 | document: string; 10 | documentPath: string; 11 | position: vscode.Position; 12 | } 13 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/src/locale/messages.es.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/src/locale/messages.fr.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/test/fixtures/extension-yamls/sample-ext/extension.yaml: -------------------------------------------------------------------------------- 1 | specVersion: v1beta 2 | name: fixture-ext 3 | version: 1.0.0 4 | license: apache-2.0 5 | resources: 6 | - name: capitalizeMessages 7 | type: firebaseextensions.v1beta.function 8 | params: 9 | - param: DO_BACKFILL 10 | label: Do a backfill 11 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/test_projects/fishfood/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "dataconnect": { 3 | "source": "./dataconnect" 4 | }, 5 | "emulators": { 6 | "dataconnect": { 7 | "port": 9399 8 | }, 9 | "ui": { 10 | "enabled": false 11 | }, 12 | "singleProjectMode": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/compressed-directory-entry/inflated/stylesheet.css: -------------------------------------------------------------------------------- 1 | .calibre { 2 | display: block; 3 | font-size: 1em; 4 | padding-left: 0; 5 | padding-right: 0; 6 | margin: 0 5pt 7 | } 8 | .calibre1 { 9 | display: block; 10 | margin: 1em 0 11 | } 12 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/pages/pages/ssg/index.tsx: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/router"; 2 | 3 | export const getStaticProps = async () => { 4 | return { props: { } }; 5 | } 6 | 7 | export default function SSG() { 8 | const { locale } = useRouter(); 9 | return <>SSG { locale }; 10 | } 11 | -------------------------------------------------------------------------------- /src/vsCodeUtils.ts: -------------------------------------------------------------------------------- 1 | let _IS_WEBPACKED_FOR_VSCE = false; 2 | /** 3 | * Detect if code is running in a VSCode Extension 4 | */ 5 | export function isVSCodeExtension(): boolean { 6 | return _IS_WEBPACKED_FOR_VSCE; 7 | } 8 | 9 | export function setIsVSCodeExtension(v: boolean) { 10 | _IS_WEBPACKED_FOR_VSCE = v; 11 | } 12 | -------------------------------------------------------------------------------- /templates/init/aitools/gemini-extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "firebase", 3 | "version": "0.0.1", 4 | "mcpServers": { 5 | "firebase": { 6 | "command": "npx", 7 | "args": ["-y", "firebase-tools", "experimental:mcp", "--dir", "{{PROJECT_PATH}}"] 8 | } 9 | }, 10 | "contextFileName": "FIREBASE.md" 11 | } -------------------------------------------------------------------------------- /firebase-vscode/webviews/components/ui/ButtonGroup.scss: -------------------------------------------------------------------------------- 1 | .button-group { 2 | vscode-button + vscode-button { 3 | border-top-left-radius: 0; 4 | border-bottom-left-radius: 0; 5 | } 6 | 7 | vscode-button:has(+ vscode-button) { 8 | border-top-right-radius: 0; 9 | border-bottom-right-radius: 0; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/mcp/prompts/dataconnect/index.ts: -------------------------------------------------------------------------------- 1 | import { isEnabled } from "../../../experiments"; 2 | import { schema } from "./schema"; 3 | import type { ServerPrompt } from "../../prompt"; 4 | 5 | export const dataconnectPrompts: ServerPrompt[] = []; 6 | 7 | if (isEnabled("mcpalpha")) { 8 | dataconnectPrompts.push(schema); 9 | } 10 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/suite/src/cli.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from "assert"; 2 | import { firebaseSuite, firebaseTest } from "../../utils/test_hooks"; 3 | 4 | firebaseSuite("empty test", () => { 5 | firebaseTest( 6 | "empty test", 7 | async () => { 8 | assert.deepStrictEqual([], []); 9 | } 10 | ); 11 | }); 12 | -------------------------------------------------------------------------------- /scripts/emulator-tests/tsconfig.dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.dev.json", 3 | "compilerOptions": { 4 | "sourceMap": false, 5 | "outDir": "../../dev", 6 | "noEmit": false, 7 | }, 8 | "include": [ 9 | "../../src/**/*", 10 | "../../src/*", 11 | "./*", 12 | ], 13 | "exclude": [], 14 | } 15 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/pages/pages/ssr/index.tsx: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/router"; 2 | 3 | export const getServerSideProps = async () => { 4 | return { props: { foo: 1 } }; 5 | } 6 | 7 | export default function SSR() { 8 | const { locale } = useRouter(); 9 | return <>SSR {locale}; 10 | } 11 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/src/main.server.ts: -------------------------------------------------------------------------------- 1 | import { bootstrapApplication } from '@angular/platform-browser'; 2 | import { AppComponent } from './app/app.component'; 3 | import { config } from './app/app.config.server'; 4 | 5 | const bootstrap = () => bootstrapApplication(AppComponent, config); 6 | 7 | export default bootstrap; 8 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/pages/pages/isr/index.tsx: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/router"; 2 | 3 | export const getStaticProps = async () => { 4 | return { props: { }, revalidate: 10 }; 5 | } 6 | 7 | export default function ISR() { 8 | const { locale } = useRouter(); 9 | return <>ISR { locale }; 10 | } 11 | -------------------------------------------------------------------------------- /src/test/fixtures/extension-yamls/sample-ext-preinstall/extension.yaml: -------------------------------------------------------------------------------- 1 | specVersion: v1beta 2 | name: fixture-ext-with-preinstall 3 | version: 1.0.0 4 | license: apache-2.0 5 | resources: 6 | - name: capitalizeMessages 7 | type: firebaseextensions.v1beta.function 8 | params: 9 | - param: DO_BACKFILL 10 | label: Do a backfill 11 | -------------------------------------------------------------------------------- /scripts/client-integration-tests/test-project/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |

404

6 |

Page Not Found

7 |

The specified file was not found on this website. Please check the URL for mistakes and try again.

8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /scripts/dataconnect-test/templates/dataconnect.yaml: -------------------------------------------------------------------------------- 1 | specVersion: "v1beta" 2 | serviceId: "__serviceId__" 3 | location: "us-central1" 4 | schema: 5 | source: "./schema" 6 | datasource: 7 | postgresql: 8 | database: "__databaseId__" 9 | cloudSql: 10 | instanceId: "dataconnect-test" 11 | connectorDirs: ["./connector"] 12 | -------------------------------------------------------------------------------- /src/frameworks/angular/interfaces.ts: -------------------------------------------------------------------------------- 1 | interface AngularLocale { 2 | translation?: string; 3 | baseHref?: string; 4 | } 5 | 6 | export interface AngularI18nConfig { 7 | sourceLocale: 8 | | string 9 | | { 10 | code: string; 11 | baseHref?: string; 12 | }; 13 | locales: Record; 14 | } 15 | -------------------------------------------------------------------------------- /scripts/dataconnect-emulator-tests/fdc-test/dataconnect.yaml: -------------------------------------------------------------------------------- 1 | specVersion: "v1beta" 2 | serviceId: "fake-service" 3 | location: "us-central1" 4 | schema: 5 | source: "./schema" 6 | datasource: 7 | postgresql: 8 | database: "postgres" 9 | cloudSql: 10 | instanceId: "dataconnect-test" 11 | connectorDirs: ["./connector"] 12 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/src/app/app.config.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationConfig, NgModule } from '@angular/core'; 2 | import { provideRouter } from '@angular/router'; 3 | import { routes } from './app-routing.module'; 4 | 5 | export const appConfig: ApplicationConfig = { 6 | providers: [ 7 | provideRouter(routes), 8 | ], 9 | } 10 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/app/app/image/page.tsx: -------------------------------------------------------------------------------- 1 | import Image from 'next/image' 2 | 3 | export default function PageWithImage() { 4 | return ; 10 | } -------------------------------------------------------------------------------- /src/mcp/tools/remoteconfig/index.ts: -------------------------------------------------------------------------------- 1 | import { ServerTool } from "../../tool"; 2 | import { get_template } from "./get_template"; 3 | import { rollback_template } from "./rollback_template"; 4 | import { publish_template } from "./publish_template"; 5 | 6 | export const remoteConfigTools: ServerTool[] = [get_template, publish_template, rollback_template]; 7 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/data-connect/data-connect-execution-results.entry.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | import { DataConnectExecutionResultsApp } from "./DataConnectExecutionResultsApp"; 4 | 5 | const root = createRoot(document.getElementById("root")!); 6 | root.render(); 7 | -------------------------------------------------------------------------------- /scripts/examples/hosting/update-single-file/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2020", 4 | "strict": true, 5 | "outDir": "lib", 6 | "removeComments": true, 7 | "moduleResolution": "node", 8 | "allowSyntheticDefaultImports": true, 9 | "target": "es2020" 10 | }, 11 | "include": ["src/**/*"] 12 | } 13 | -------------------------------------------------------------------------------- /scripts/extensions-emulator-tests/extensions/resize-images.env: -------------------------------------------------------------------------------- 1 | IMG_SIZES=200x200 2 | DELETE_ORIGINAL_FILE=false 3 | IMAGE_TYPE=png 4 | LOCATION=us-central1 5 | IMG_BUCKET=${param:PROJECT_ID}.appspot.com 6 | EVENTARC_CHANNEL=projects/${param:PROJECT_ID}/locations/us-west1/channels/firebase 7 | ALLOWED_EVENT_TYPES=firebase.extensions.storage-resize-images.v1.complete 8 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/app/app/api/static/route.ts: -------------------------------------------------------------------------------- 1 | export const dynamic = 'force-static' 2 | 3 | export async function GET() { 4 | return new Response(JSON.stringify([1, 2, 3]), { 5 | status: 200, 6 | headers: { 7 | "content-type": "application/json", 8 | "custom-header": "custom-value", 9 | }, 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/test_projects/fishfood/dataconnect/dataconnect.yaml: -------------------------------------------------------------------------------- 1 | specVersion: "v1alpha" 2 | serviceId: "us-east" 3 | location: "europe-north1" 4 | schema: 5 | source: "./schema" 6 | datasource: 7 | postgresql: 8 | database: "emulator" 9 | cloudSql: 10 | instanceId: "dataconnect-test" 11 | connectorDirs: ["./connectors/a"] 12 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/stress-test/functions/index.js: -------------------------------------------------------------------------------- 1 | const { onRequest } = require("firebase-functions/v2/https"); 2 | 3 | // Generate 20 functions for stress testing 4 | for (let i = 1; i <= 20; i++) { 5 | exports[`stressFunction${i}`] = onRequest((request, response) => { 6 | response.send(`Hello from stress function ${i}!`); 7 | }); 8 | } 9 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | import { FooComponent } from './foo/foo.component'; 3 | import { HomeComponent } from './home/home.component'; 4 | 5 | export const routes: Routes = [ 6 | { path: '', component: HomeComponent }, 7 | { path: 'foo/:id', component: FooComponent } 8 | ]; 9 | -------------------------------------------------------------------------------- /src/mcp/tools/database/index.ts: -------------------------------------------------------------------------------- 1 | import type { ServerTool } from "../../tool"; 2 | import { get_rules } from "./get_rules"; 3 | import { get_data } from "./get_data"; 4 | import { set_data } from "./set_data"; 5 | import { validate_rules } from "./validate_rules"; 6 | 7 | export const realtimeDatabaseTools: ServerTool[] = [get_data, set_data, get_rules, validate_rules]; 8 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/src/main.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { appConfig } from './app/app.config'; 3 | import { bootstrapApplication } from '@angular/platform-browser'; 4 | import { AppComponent } from './app/app.component'; 5 | 6 | 7 | bootstrapApplication(AppComponent, appConfig) 8 | .catch(err => console.error(err)); 9 | -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/compressed-directory-entry/inflated/META-INF/container.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /templates/extensions/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "noImplicitReturns": true, 5 | "noUnusedLocals": true, 6 | "outDir": "lib", 7 | "sourceMap": true, 8 | "strict": true, 9 | "target": "es2017" 10 | }, 11 | "compileOnSave": true, 12 | "include": [ 13 | "src" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/components/EmulatorPanel.scss: -------------------------------------------------------------------------------- 1 | @import "../globals/index.scss"; 2 | 3 | .list { 4 | list-style: none; 5 | } 6 | 7 | .fullWidth { 8 | width: 100%; 9 | } 10 | 11 | .list-item { 12 | align-items: center; 13 | display: flex; 14 | gap: 4px; 15 | } 16 | 17 | .running-indicator { 18 | color: var(--vscode-testing-runAction, green); 19 | } 20 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/yarn-workspaces/packages/functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple", 3 | "version": "0.0.1", 4 | "dependencies": { 5 | "firebase-functions": "^6.4.0", 6 | "firebase-admin": "^11.2.0", 7 | "@firebase/a-test-pkg": "0.0.1" 8 | }, 9 | "engines": { 10 | "node": ">=20" 11 | }, 12 | "private": true 13 | } 14 | -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "functions": {}, 3 | "storage": { 4 | "rules": "storage.rules" 5 | }, 6 | "emulators": { 7 | "hub": { 8 | "port": 4000 9 | }, 10 | "auth": { 11 | "port": 9099 12 | }, 13 | "storage": { 14 | "port": 9199 15 | } 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /src/gcp/index.ts: -------------------------------------------------------------------------------- 1 | export * as cloudbilling from "./cloudbilling"; 2 | export * as cloudfunctions from "./cloudfunctions"; 3 | export * as cloudscheduler from "./cloudscheduler"; 4 | export * as cloudlogging from "./cloudlogging"; 5 | export * as iam from "./iam"; 6 | export * as pubsub from "./pubsub"; 7 | export * as storage from "./storage"; 8 | export * as rules from "./rules"; 9 | -------------------------------------------------------------------------------- /src/listFiles.ts: -------------------------------------------------------------------------------- 1 | import { sync } from "glob"; 2 | 3 | export function listFiles(cwd: string, ignore: string[] = []): string[] { 4 | return sync("**/*", { 5 | cwd, 6 | dot: true, 7 | follow: true, 8 | ignore: ["**/firebase-debug.log", "**/firebase-debug.*.log", ".firebase/*"].concat(ignore), 9 | nodir: true, 10 | posix: true, 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /src/test/fixtures/profiler-data/index.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from "path"; 2 | 3 | /** 4 | * A sample JSON file for profiler input. 5 | */ 6 | export const SAMPLE_INPUT_PATH = resolve(__dirname, "sample.json"); 7 | 8 | /** 9 | * A sample JSON output file generated by the profiler. 10 | */ 11 | export const SAMPLE_OUTPUT_PATH = resolve(__dirname, "sample-output.json"); 12 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | /templates 2 | /node_modules 3 | /lib/**/* 4 | /CONTRIBUTING.md 5 | /scripts/frameworks-tests/vite-project/** 6 | /scripts/webframeworks-deploy-tests/angular/** 7 | /scripts/webframeworks-deploy-tests/nextjs/** 8 | /src/frameworks/docs/** 9 | /prompts 10 | 11 | # Intentionally invalid YAML file: 12 | /src/test/fixtures/extension-yamls/invalid/extension.yaml 13 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "nextjs-demo-73e34" 4 | }, 5 | "targets": { 6 | "demo-123": { 7 | "hosting": { 8 | "angular": [ 9 | "demo-angular" 10 | ], 11 | "nextjs": [ 12 | "demo-nextjs" 13 | ] 14 | } 15 | } 16 | }, 17 | "etags": {} 18 | } 19 | -------------------------------------------------------------------------------- /src/mcp/tools/storage/index.ts: -------------------------------------------------------------------------------- 1 | import { getRulesTool } from "../rules/get_rules"; 2 | import { validateRulesTool } from "../rules/validate_rules"; 3 | import { get_object_download_url } from "./get_download_url"; 4 | 5 | export const storageTools = [ 6 | getRulesTool("Storage", "firebase.storage"), 7 | validateRulesTool("Storage"), 8 | get_object_download_url, 9 | ]; 10 | -------------------------------------------------------------------------------- /scripts/extensions-emulator-tests/functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions", 3 | "description": "Cloud Functions for Firebase", 4 | "scripts": {}, 5 | "engines": { 6 | "node": "20" 7 | }, 8 | "dependencies": { 9 | "firebase-admin": "^12.1.0", 10 | "firebase-functions": "^5.1.0", 11 | "fs-extra": "^5.0.0" 12 | }, 13 | "private": true 14 | } 15 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/src/app/foo/foo.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject } from '@angular/core'; 2 | import { LOCALE_ID } from '@angular/core'; 3 | 4 | @Component({ 5 | selector: 'app-foo', 6 | template: `Foo {{ locale }}`, 7 | styles: [] 8 | }) 9 | export class FooComponent { 10 | constructor(@Inject(LOCALE_ID) protected locale: string) {} 11 | } 12 | -------------------------------------------------------------------------------- /src/extensions/utils.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | import * as utils from "./utils"; 4 | 5 | describe("extensions utils", () => { 6 | describe("formatTimestamp", () => { 7 | it("should format timestamp correctly", () => { 8 | expect(utils.formatTimestamp("2020-05-11T03:45:13.583677Z")).to.equal("2020-05-11 03:45:13"); 9 | }); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /scripts/client-integration-tests/test-project/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |

Welcome

6 |

Firebase Hosting Setup Complete

7 |

You're seeing this because you've successfully setup Firebase Hosting. Now it's time to go build something extraordinary!

8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/src/app/home/home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject } from '@angular/core'; 2 | import { LOCALE_ID } from '@angular/core'; 3 | 4 | @Component({ 5 | selector: 'app-home', 6 | template: `Home {{ locale }}`, 7 | styles: [] 8 | }) 9 | export class HomeComponent { 10 | constructor(@Inject(LOCALE_ID) protected locale: string) {} 11 | } 12 | -------------------------------------------------------------------------------- /src/frameworks/nuxt/interfaces.ts: -------------------------------------------------------------------------------- 1 | // TODO: define more fields as needed 2 | // The NuxtOptions interface is huge and depends on multiple external types 3 | // and packages. For now only the fields that are being used are defined. 4 | export interface NuxtOptions { 5 | ssr: boolean; 6 | app: { 7 | baseURL: string; 8 | }; 9 | dir: { 10 | public: string; 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /src/frameworks/react/index.ts: -------------------------------------------------------------------------------- 1 | import { FrameworkType } from "../interfaces"; 2 | import { initViteTemplate, vitePluginDiscover } from "../vite"; 3 | 4 | export * from "../vite"; 5 | 6 | export const name = "React"; 7 | export const type = FrameworkType.Framework; 8 | 9 | export const init = initViteTemplate("react"); 10 | export const discover = vitePluginDiscover("vite:react-jsx"); 11 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/components/AccountSection.scss: -------------------------------------------------------------------------------- 1 | .account-row { 2 | display: flex; 3 | justify-content: space-between; 4 | position: relative; 5 | 6 | &-label { 7 | display: flex; 8 | align-items: center; 9 | } 10 | 11 | &-icon { 12 | margin-right: 8px; 13 | } 14 | 15 | &-project { 16 | display: flex; 17 | flex-direction: column; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/components/ui/Spacer.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styles from "./Spacer.scss"; 3 | 4 | type SpacerSize = 5 | | "xsmall" 6 | | "small" 7 | | "medium" 8 | | "large" 9 | | "xlarge" 10 | | "xxlarge"; 11 | 12 | export function Spacer({ size = "large" }: { size: SpacerSize }) { 13 | return
; 14 | } 15 | -------------------------------------------------------------------------------- /src/frameworks/lit/index.ts: -------------------------------------------------------------------------------- 1 | import { FrameworkType } from "../interfaces"; 2 | import { initViteTemplate, viteDiscoverWithNpmDependency } from "../vite"; 3 | 4 | export * from "../vite"; 5 | 6 | export const name = "Lit"; 7 | export const type = FrameworkType.Framework; 8 | 9 | export const init = initViteTemplate("lit"); 10 | export const discover = viteDiscoverWithNpmDependency("lit"); 11 | -------------------------------------------------------------------------------- /src/frameworks/preact/index.ts: -------------------------------------------------------------------------------- 1 | import { FrameworkType } from "../interfaces"; 2 | import { initViteTemplate, vitePluginDiscover } from "../vite"; 3 | 4 | export * from "../vite"; 5 | 6 | export const name = "Preact"; 7 | export const type = FrameworkType.Framework; 8 | 9 | export const init = initViteTemplate("preact"); 10 | export const discover = vitePluginDiscover("vite:preact-jsx"); 11 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /src/frameworks/svelte/index.ts: -------------------------------------------------------------------------------- 1 | import { FrameworkType } from "../interfaces"; 2 | import { initViteTemplate, vitePluginDiscover } from "../vite"; 3 | 4 | export * from "../vite"; 5 | 6 | export const name = "Svelte"; 7 | export const type = FrameworkType.Framework; 8 | 9 | export const init = initViteTemplate("svelte"); 10 | export const discover = vitePluginDiscover("vite-plugin-svelte"); 11 | -------------------------------------------------------------------------------- /src/init/features/aitools/index.ts: -------------------------------------------------------------------------------- 1 | import { AIToolModule } from "./types"; 2 | import { cursor } from "./cursor"; 3 | import { gemini } from "./gemini"; 4 | import { studio } from "./studio"; 5 | import { claude } from "./claude"; 6 | 7 | export const AI_TOOLS: Record = { 8 | cursor, 9 | gemini, 10 | studio, 11 | claude, 12 | }; 13 | 14 | export * from "./types"; 15 | -------------------------------------------------------------------------------- /templates/banner.txt: -------------------------------------------------------------------------------- 1 | 2 | ######## #### ######## ######## ######## ### ###### ######## 3 | ## ## ## ## ## ## ## ## ## ## ## 4 | ###### ## ######## ###### ######## ######### ###### ###### 5 | ## ## ## ## ## ## ## ## ## ## ## 6 | ## #### ## ## ######## ######## ## ## ###### ######## 7 | -------------------------------------------------------------------------------- /templates/init/storage/storage.rules: -------------------------------------------------------------------------------- 1 | rules_version = '2'; 2 | 3 | // Craft rules based on data in your Firestore database 4 | // allow write: if firestore.get( 5 | // /databases/(default)/documents/users/$(request.auth.uid)).data.isAdmin; 6 | service firebase.storage { 7 | match /b/{bucket}/o { 8 | match /{allPaths=**} { 9 | allow read, write: if false; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /firebase-vscode/src/utils/promise.ts: -------------------------------------------------------------------------------- 1 | export function cancelableThen( 2 | promise: Promise, 3 | then: (t: T) => void, 4 | ): { cancel: () => void } { 5 | let canceled = false; 6 | function cancel() { 7 | canceled = true; 8 | } 9 | 10 | promise.then((t) => { 11 | if (!canceled) { 12 | then(t); 13 | } 14 | return t; 15 | }); 16 | 17 | return { cancel }; 18 | } 19 | -------------------------------------------------------------------------------- /scripts/emulator-tests/functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-fns", 3 | "version": "0.0.1", 4 | "description": "Test function package for functions emulator integration tests", 5 | "main": "index.js", 6 | "dependencies": { 7 | "express": "^4.18.1", 8 | "firebase-admin": "^11.5.0", 9 | "firebase-functions": "^5.1.0" 10 | }, 11 | "engines": { 12 | "node": "20" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/app/app/api/dynamic/route.ts: -------------------------------------------------------------------------------- 1 | import { headers } from 'next/headers'; 2 | 3 | export async function GET() { 4 | const _ = headers(); 5 | return new Response(JSON.stringify([1, 2, 3]), { 6 | status: 200, 7 | headers: { 8 | "content-type": "application/json", 9 | "custom-header": "custom-value-2", 10 | }, 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/globals/app.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactNode, StrictMode } from "react"; 2 | import styles from "./index.scss"; 3 | 4 | /** Generic wrapper that all webviews should be wrapped with */ 5 | export function App({ children }: { children: ReactNode }): JSX.Element { 6 | return ( 7 | 8 |
{children}
9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/multiple-targets/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "storage": [ 3 | { 4 | "target": "allowNone", 5 | "rules": "allowNone.rules" 6 | }, 7 | { 8 | "target": "allowAll", 9 | "rules": "allowAll.rules" 10 | } 11 | ], 12 | "emulators": { 13 | "storage": { 14 | "port": 9199 15 | } 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/pages/api/hello.ts: -------------------------------------------------------------------------------- 1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction 2 | import type { NextApiRequest, NextApiResponse } from 'next' 3 | 4 | type Data = { 5 | name: string 6 | } 7 | 8 | export default function handler( 9 | req: NextApiRequest, 10 | res: NextApiResponse 11 | ) { 12 | res.status(200).json({ name: 'John Doe' }) 13 | } 14 | -------------------------------------------------------------------------------- /src/commands/setup-emulators-ui.ts: -------------------------------------------------------------------------------- 1 | import { Command } from "../command"; 2 | import { downloadEmulator } from "../emulator/download"; 3 | import { Emulators } from "../emulator/types"; 4 | 5 | const NAME = Emulators.UI; 6 | 7 | export const command = new Command(`setup:emulators:${NAME}`) 8 | .description(`download the ${NAME} emulator`) 9 | .action(() => { 10 | return downloadEmulator(NAME); 11 | }); 12 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/utils/page_objects/status_bar.ts: -------------------------------------------------------------------------------- 1 | import { Workbench } from "wdio-vscode-service"; 2 | 3 | export class StatusBar { 4 | constructor(readonly workbench: Workbench) {} 5 | 6 | get emulatorsStatus() { 7 | return $('[id="firebase.firebase-vscode.emulators"]'); 8 | } 9 | 10 | get currentProjectElement() { 11 | return $('[id="firebase.firebase-vscode.projectPicker"]'); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [ 7 | "@angular/localize" 8 | ] 9 | }, 10 | "files": [ 11 | "src/main.ts" 12 | ], 13 | "include": [ 14 | "src/**/*.d.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/tsconfig.server.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.app.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/server", 6 | "types": [ 7 | "node", 8 | "@angular/localize" 9 | ] 10 | }, 11 | "files": [ 12 | "src/main.server.ts", 13 | "server.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine", 8 | "@angular/localize" 9 | ] 10 | }, 11 | "include": [ 12 | "src/**/*.spec.ts", 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /scripts/firepit-builder/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cloud_build", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "pipeline.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "MIT", 12 | "private": true, 13 | "dependencies": { 14 | "shelljs": "^0.8.5", 15 | "yargs": "^13.3.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/pnpm/functions/index.js: -------------------------------------------------------------------------------- 1 | const functions = require("firebase-functions"); 2 | const { onRequest } = require("firebase-functions/v2/https"); 3 | 4 | exports.hellov1 = functions.https.onRequest((request, response) => { 5 | response.send("Hello from Firebase!"); 6 | }); 7 | 8 | exports.hellov2 = onRequest((request, response) => { 9 | response.send("Hello from Firebase!"); 10 | }); 11 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/simple/functions/index.js: -------------------------------------------------------------------------------- 1 | const functions = require("firebase-functions"); 2 | const { onRequest } = require("firebase-functions/v2/https"); 3 | 4 | exports.hellov1 = functions.https.onRequest((request, response) => { 5 | response.send("Hello from Firebase!"); 6 | }); 7 | 8 | exports.hellov2 = onRequest((request, response) => { 9 | response.send("Hello from Firebase!"); 10 | }); 11 | -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/multiple-targets/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": {}, 3 | "targets": { 4 | "fake-project-id": { 5 | "storage": { 6 | "allowNone": [ 7 | "fake-project-id.appspot.com" 8 | ], 9 | "allowAll": [ 10 | "fake-project-id-2.appspot.com" 11 | ] 12 | } 13 | } 14 | }, 15 | "etags": {}, 16 | "dataconnectEmulatorConfig": {} 17 | } -------------------------------------------------------------------------------- /scripts/triggers-end-to-end-tests/v2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions", 3 | "description": "Cloud Functions for Firebase", 4 | "scripts": {}, 5 | "engines": { 6 | "node": "20" 7 | }, 8 | "dependencies": { 9 | "firebase-admin": "^11.0.0", 10 | "firebase-functions": "^5.1.0" 11 | }, 12 | "devDependencies": { 13 | "firebase-functions-test": "^0.2.0" 14 | }, 15 | "private": true 16 | } 17 | -------------------------------------------------------------------------------- /src/commands/setup-emulators-database.ts: -------------------------------------------------------------------------------- 1 | import { Command } from "../command"; 2 | import { downloadEmulator } from "../emulator/download"; 3 | import { Emulators } from "../emulator/types"; 4 | 5 | const NAME = Emulators.DATABASE; 6 | 7 | export const command = new Command(`setup:emulators:${NAME}`) 8 | .description(`download the ${NAME} emulator`) 9 | .action(() => { 10 | return downloadEmulator(NAME); 11 | }); 12 | -------------------------------------------------------------------------------- /firebase-vscode/.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | src/** 4 | webviews/** 5 | common/** 6 | extension/** 7 | public/** 8 | .gitignore 9 | .yarnrc 10 | vsc-extension-quickstart.md 11 | **/tsconfig.json 12 | **/.eslintrc.json 13 | **/*.map 14 | **/*.ts 15 | *.vsix 16 | webpack.*.js 17 | ../ 18 | *.zip 19 | node_modules/ 20 | dist/test/ 21 | *.tgz 22 | package-lock.json 23 | .wdio-vscode-service/ 24 | prebuilt-extensions/ -------------------------------------------------------------------------------- /src/commands/setup-emulators-firestore.ts: -------------------------------------------------------------------------------- 1 | import { Command } from "../command"; 2 | import { downloadEmulator } from "../emulator/download"; 3 | import { Emulators } from "../emulator/types"; 4 | 5 | const NAME = Emulators.FIRESTORE; 6 | 7 | export const command = new Command(`setup:emulators:${NAME}`) 8 | .description(`download the ${NAME} emulator`) 9 | .action(() => { 10 | return downloadEmulator(NAME); 11 | }); 12 | -------------------------------------------------------------------------------- /src/requireInteractive.ts: -------------------------------------------------------------------------------- 1 | import type { Options } from "./options"; 2 | 3 | import { FirebaseError } from "./error"; 4 | 5 | export default function requireInteractive(options: Options) { 6 | if (options.nonInteractive) { 7 | return Promise.reject( 8 | new FirebaseError("This command cannot run in non-interactive mode", { 9 | exit: 1, 10 | }), 11 | ); 12 | } 13 | return Promise.resolve(); 14 | } 15 | -------------------------------------------------------------------------------- /src/test/helpers/index.ts: -------------------------------------------------------------------------------- 1 | import * as sinon from "sinon"; 2 | import * as auth from "../../auth"; 3 | 4 | /** 5 | * Mocks getAccessToken so that tests don't take forever. 6 | * @param sandbox a sinon sandbox. 7 | */ 8 | export function mockAuth(sandbox: sinon.SinonSandbox): void { 9 | const authMock = sandbox.mock(auth); 10 | authMock.expects("getAccessToken").atLeast(1).resolves({ access_token: "an_access_token" }); 11 | } 12 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/test_projects/fishfood/test-node-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-node-app", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "author": "", 9 | "license": "ISC", 10 | "description": "", 11 | "dependencies": { 12 | "@firebasegen/a-connector": "file:dataconnect-generated/js/a-connector" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /scripts/functions-deploy-tests/functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions", 3 | "description": "Cloud Functions for Firebase", 4 | "type": "module", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | }, 9 | "dependencies": { 10 | "firebase-admin": "^11.0.0", 11 | "firebase-functions": "^4.1.0" 12 | }, 13 | "engines": { 14 | "node": "20" 15 | }, 16 | "private": true 17 | } 18 | -------------------------------------------------------------------------------- /src/deploy/functions/release/timer.ts: -------------------------------------------------------------------------------- 1 | /** Measures the time taken from construction to the call to stop() */ 2 | export class Timer { 3 | private readonly start: bigint; 4 | 5 | constructor() { 6 | this.start = process.hrtime.bigint(); 7 | } 8 | 9 | stop(): number { 10 | const stop = process.hrtime.bigint(); 11 | const elapsedNanos = stop - this.start; 12 | return Number(elapsedNanos / BigInt(1e6)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /templates/init/functions/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "NodeNext", 4 | "esModuleInterop": true, 5 | "moduleResolution": "nodenext", 6 | "noImplicitReturns": true, 7 | "noUnusedLocals": true, 8 | "outDir": "lib", 9 | "sourceMap": true, 10 | "strict": true, 11 | "target": "es2017" 12 | }, 13 | "compileOnSave": true, 14 | "include": [ 15 | "src" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/utils/user.ts: -------------------------------------------------------------------------------- 1 | import { User } from "../../types/auth"; 2 | import * as vscode from "vscode"; 3 | 4 | export async function mockUser(user: User | undefined): Promise { 5 | return browser.executeWorkbench( 6 | async (vs: typeof vscode, user: User) => { 7 | const promise = vs.commands.executeCommand("fdc-graphql.mock.user", user); 8 | return promise; 9 | }, 10 | user, 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/components/ui/Spacer.scss: -------------------------------------------------------------------------------- 1 | .spacerxsmall { 2 | height: var(--space-xsmall); 3 | } 4 | 5 | .spacersmall { 6 | height: var(--space-small); 7 | } 8 | 9 | .spacermedium { 10 | height: var(--space-medium); 11 | } 12 | 13 | .spacerlarge { 14 | height: var(--space-large); 15 | } 16 | 17 | .spacerxlarge { 18 | height: var(--space-xlarge); 19 | } 20 | 21 | .spacerxxlarge { 22 | height: var(--space-xxlarge); 23 | } 24 | -------------------------------------------------------------------------------- /src/frameworks/docs/_includes/_before-you-begin.md: -------------------------------------------------------------------------------- 1 | ## Before you begin 2 | 3 | Before you get started deploying your app to Firebase, 4 | review the following requirements and options: 5 | 6 | - {{firebase_cli}} version 12.1.0 or later. Make sure to 7 | [install the {{cli}}](/docs/cli#install_the_firebase_cli) 8 | using your preferred method. 9 | - Optional: Billing enabled on your Firebase project 10 | (required if you plan to use SSR) 11 | -------------------------------------------------------------------------------- /mockdata/function_source_v1.txt: -------------------------------------------------------------------------------- 1 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras ac lectus dolor. Fusce luctus non leo ac tempor. Donec interdum magna eget erat aliquam rutrum. Fusce ultricies ut velit eu ullamcorper. Nullam mattis risus pretium, euismod sem id, viverra ligula. Nullam volutpat purus a metus bibendum, et ultrices urna accumsan. Nunc accumsan, nisl ut tristique lacinia, quam dolor lobortis dui, dignissim porta enim lectus at erat. 2 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/fdc_sidebar.entry.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | import { SidebarApp } from "./SidebarApp"; 4 | import { App } from "./globals/app"; 5 | import style from "./fdc_sidebar.entry.scss"; 6 | 7 | // Prevent scss tree shaking 8 | style; 9 | 10 | const root = createRoot(document.getElementById("root")!); 11 | root.render( 12 | 13 | 14 | , 15 | ); 16 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/middleware.ts: -------------------------------------------------------------------------------- 1 | // middleware.ts 2 | import { NextRequest, NextResponse } from 'next/server'; 3 | 4 | // This function can be marked `async` if using `await` inside 5 | export function middleware(request: NextRequest) { 6 | return NextResponse.redirect(new URL('/about-2', request.url)); 7 | } 8 | 9 | // See "Matching Paths" below to learn more 10 | export const config = { 11 | matcher: '/about/:path*', 12 | } 13 | -------------------------------------------------------------------------------- /src/commands/mcp.ts: -------------------------------------------------------------------------------- 1 | import { Command } from "../command"; 2 | import { requireAuth } from "../requireAuth"; 3 | 4 | export const command = new Command("experimental:mcp") 5 | .description( 6 | "Start an MCP server with access to the current working directory's project and resources.", 7 | ) 8 | .before(requireAuth) 9 | .action(() => { 10 | throw new Error("MCP logic is implemented elsewhere, this should never be reached."); 11 | }); 12 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/yarn-workspaces/packages/functions/index.js: -------------------------------------------------------------------------------- 1 | const functions = require("firebase-functions"); 2 | const { onRequest } = require("firebase-functions/v2/https"); 3 | const { msg } = require("@firebase/a-test-pkg"); 4 | 5 | exports.hellov1 = functions.https.onRequest((request, response) => { 6 | response.send(msg); 7 | }); 8 | 9 | exports.hellov2 = onRequest((request, response) => { 10 | response.send(msg); 11 | }); 12 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/src/app/app.config.server.ts: -------------------------------------------------------------------------------- 1 | import { mergeApplicationConfig, ApplicationConfig } from '@angular/core'; 2 | import { provideServerRendering } from '@angular/platform-server'; 3 | import { appConfig } from './app.config'; 4 | 5 | const serverConfig: ApplicationConfig = { 6 | providers: [ 7 | provideServerRendering() 8 | ] 9 | }; 10 | 11 | export const config = mergeApplicationConfig(appConfig, serverConfig); 12 | -------------------------------------------------------------------------------- /src/commands/setup-emulators-pubsub.ts: -------------------------------------------------------------------------------- 1 | import { Command } from "../command"; 2 | import { downloadEmulator } from "../emulator/download"; 3 | import { Emulators } from "../emulator/types"; 4 | 5 | const EMULATOR_NAME = Emulators.PUBSUB; 6 | 7 | export const command = new Command(`setup:emulators:${EMULATOR_NAME}`) 8 | .description(`download the ${EMULATOR_NAME} emulator`) 9 | .action(() => { 10 | return downloadEmulator(EMULATOR_NAME); 11 | }); 12 | -------------------------------------------------------------------------------- /src/commands/setup-emulators-storage.ts: -------------------------------------------------------------------------------- 1 | import { Command } from "../command"; 2 | import { downloadEmulator } from "../emulator/download"; 3 | import { Emulators } from "../emulator/types"; 4 | 5 | const EMULATOR_NAME = Emulators.STORAGE; 6 | 7 | export const command = new Command(`setup:emulators:${EMULATOR_NAME}`) 8 | .description(`download the ${EMULATOR_NAME} emulator`) 9 | .action(() => { 10 | return downloadEmulator(EMULATOR_NAME); 11 | }); 12 | -------------------------------------------------------------------------------- /src/deploy/functions/runtimes/discovery/mockDiscoveryServer.ts: -------------------------------------------------------------------------------- 1 | import * as express from "express"; 2 | 3 | const app = express(); 4 | app.get("/backend.yaml", (req, res) => { 5 | res.setHeader("content-type", "text/yaml"); 6 | res.send(process.env.BACKEND); 7 | }); 8 | 9 | let port = 8080; 10 | if (process.env.ADMIN_PORT) { 11 | port = Number.parseInt(process.env.ADMIN_PORT); 12 | } 13 | console.error("Serving at port", port); 14 | app.listen(port); 15 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { Component } from '@angular/core'; 3 | import { RouterOutlet } from '@angular/router'; 4 | 5 | @Component({ 6 | selector: 'app-root', 7 | standalone: true, 8 | imports: [CommonModule, RouterOutlet], 9 | template: ` 10 | 11 | `, 12 | styles: [] 13 | }) 14 | export class AppComponent { 15 | } 16 | -------------------------------------------------------------------------------- /scripts/triggers-end-to-end-tests/v1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions", 3 | "description": "Cloud Functions for Firebase", 4 | "scripts": {}, 5 | "engines": { 6 | "node": "20" 7 | }, 8 | "dependencies": { 9 | "@firebase/database-compat": "0.1.2", 10 | "firebase-admin": "^11.0.0", 11 | "firebase-functions": "^5.1.0" 12 | }, 13 | "devDependencies": { 14 | "firebase-functions-test": "^0.2.0" 15 | }, 16 | "private": true 17 | } 18 | -------------------------------------------------------------------------------- /src/mcp/types.ts: -------------------------------------------------------------------------------- 1 | export const SERVER_FEATURES = [ 2 | "core", 3 | "firestore", 4 | "storage", 5 | "dataconnect", 6 | "auth", 7 | "messaging", 8 | "remoteconfig", 9 | "crashlytics", 10 | "apphosting", 11 | "database", 12 | ] as const; 13 | export type ServerFeature = (typeof SERVER_FEATURES)[number]; 14 | 15 | export interface ClientConfig { 16 | /** The current project root directory for this client. */ 17 | projectRoot?: string | null; 18 | } 19 | -------------------------------------------------------------------------------- /src/throttler/errors/retries-exhausted-error.ts: -------------------------------------------------------------------------------- 1 | import TaskError from "./task-error"; 2 | 3 | export default class RetriesExhaustedError extends TaskError { 4 | constructor(taskName: string, totalRetries: number, lastTrialError: Error) { 5 | super( 6 | taskName, 7 | `retries exhausted after ${totalRetries + 1} attempts, with error: ${lastTrialError.message}`, 8 | { 9 | original: lastTrialError, 10 | }, 11 | ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /firebase-vscode/src/utils/graphql.ts: -------------------------------------------------------------------------------- 1 | import * as graphql from "graphql"; 2 | import * as vscode from "vscode"; 3 | 4 | export function locationToRange(location: graphql.Location): vscode.Range { 5 | // -1 because Range uses 0-based indexing but Location uses 1-based indexing 6 | return new vscode.Range( 7 | location.startToken.line - 1, 8 | location.startToken.column - 1, 9 | location.endToken.line - 1, 10 | location.endToken.column - 1 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2020", 4 | "moduleResolution": "Node", 5 | "target": "ES2020", 6 | "lib": ["ES2020", "DOM"], 7 | "esModuleInterop": true, 8 | "jsx": "react", 9 | "sourceMap": true, 10 | "rootDirs": ["./", "../../src", "../common"], 11 | "strict": true /* enable all strict type-checking options */ 12 | }, 13 | "include": ["../webviews/**/*", "../common/**/*"] 14 | } 15 | -------------------------------------------------------------------------------- /src/loadCJSON.ts: -------------------------------------------------------------------------------- 1 | import { FirebaseError } from "./error"; 2 | import * as cjson from "cjson"; 3 | 4 | /** 5 | * Loads CJSON from given path. 6 | */ 7 | export function loadCJSON(path: string): any { 8 | try { 9 | return cjson.load(path); 10 | } catch (e: any) { 11 | if (e.code === "ENOENT") { 12 | throw new FirebaseError(`File ${path} does not exist`); 13 | } 14 | throw new FirebaseError(`Parse Error in ${path}:\n\n${e.message}`); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /scripts/dataconnect-test/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e # Immediately exit on failure 3 | # Globally link the CLI for the testing framework 4 | ./scripts/clean-install.sh 5 | source scripts/set-default-credentials.sh 6 | 7 | echo "Running in ${CWD}" 8 | echo "Running with node: $(which node)" 9 | echo "Running with npm: $(which npm)" 10 | echo "Running with Application Creds: ${GOOGLE_APPLICATION_CREDENTIALS}" 11 | 12 | mocha scripts/dataconnect-test/tests.ts 13 | rm -rf ../../clean -------------------------------------------------------------------------------- /scripts/mcp-tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mcp-tests", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "type": "module", 6 | "scripts": { 7 | "test": "tsx ./gemini-smoke-test.ts" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "description": "", 13 | "dependencies": { 14 | "@modelcontextprotocol/sdk": "^1.11.5", 15 | "tsx": "^4.19.4" 16 | }, 17 | "devDependencies": { 18 | "typescript": "^5.8.3" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/mcp/tools/auth/index.ts: -------------------------------------------------------------------------------- 1 | import { ServerTool } from "../../tool"; 2 | import { get_user } from "./get_user"; 3 | import { disable_user } from "./disable_user"; 4 | import { set_claim } from "./set_claims"; 5 | import { set_sms_region_policy } from "./set_sms_region_policy"; 6 | import { list_users } from "./list_users"; 7 | 8 | export const authTools: ServerTool[] = [ 9 | get_user, 10 | disable_user, 11 | list_users, 12 | set_claim, 13 | set_sms_region_policy, 14 | ]; 15 | -------------------------------------------------------------------------------- /scripts/set-default-credentials.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | CWD="$(pwd)" 5 | 6 | if [[ -z $CI ]]; then 7 | echo "CI is unset, assuming local testing." 8 | export COMMIT_SHA="localtesting" 9 | export CI_JOB_ID="$(echo $RANDOM)" 10 | else 11 | echo "CI=${CI}, setting GOOGLE_APPLICATION_CREDENTIALS" 12 | export GOOGLE_APPLICATION_CREDENTIALS="${CWD}/scripts/service-account.json" 13 | fi 14 | 15 | echo "Application Default Credentials: ${GOOGLE_APPLICATION_CREDENTIALS}" -------------------------------------------------------------------------------- /src/env.ts: -------------------------------------------------------------------------------- 1 | import { dirExistsSync } from "./fsutils"; 2 | 3 | let googleIdxFolderExists: boolean | undefined; 4 | export function isFirebaseStudio() { 5 | if (googleIdxFolderExists === true || process.env.MONOSPACE_ENV) return true; 6 | if (googleIdxFolderExists === false) return false; 7 | googleIdxFolderExists = dirExistsSync("/google/idx"); 8 | return googleIdxFolderExists; 9 | } 10 | 11 | export function isFirebaseMcp() { 12 | return !!process.env.IS_FIREBASE_MCP; 13 | } 14 | -------------------------------------------------------------------------------- /src/requireHostingSite.ts: -------------------------------------------------------------------------------- 1 | import { getDefaultHostingSite } from "./getDefaultHostingSite"; 2 | 3 | /** 4 | * Ensure that a hosting site is set, fetching it from defaultHostingSite if not already present. 5 | * @param options command line options passed in. 6 | */ 7 | export async function requireHostingSite(options: any) { 8 | if (options.site) { 9 | return Promise.resolve(); 10 | } 11 | 12 | const site = await getDefaultHostingSite(options); 13 | options.site = site; 14 | } 15 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/esm/functions/index.js: -------------------------------------------------------------------------------- 1 | import * as functions from "firebase-functions"; 2 | import { onRequest } from "firebase-functions/v2/https"; 3 | 4 | export const hellov1 = functions.https.onRequest((request, response) => { 5 | functions.logger.info("Hello logs!", { structuredData: true }); 6 | response.send("Hello from Firebase!"); 7 | }); 8 | 9 | export const hellov2 = onRequest((request, response) => { 10 | response.send("Hello from Firebase!"); 11 | }); 12 | -------------------------------------------------------------------------------- /src/deploymentTool.ts: -------------------------------------------------------------------------------- 1 | export const BASE = "cli-firebase"; 2 | 3 | export function value() { 4 | if (!process.env.FIREBASE_DEPLOY_AGENT) { 5 | return BASE; 6 | } 7 | 8 | return [BASE, process.env.FIREBASE_DEPLOY_AGENT].join("--"); 9 | } 10 | 11 | export function labels() { 12 | return { 13 | "deployment-tool": value(), 14 | }; 15 | } 16 | 17 | export function isFirebaseManaged(labels: { [key: string]: any }) { 18 | return labels?.["deployment-tool"]?.startsWith(BASE); 19 | } 20 | -------------------------------------------------------------------------------- /src/mcp/tools/dataconnect/index.ts: -------------------------------------------------------------------------------- 1 | import type { ServerTool } from "../../tool"; 2 | import { generate_operation } from "./generate_operation"; 3 | import { generate_schema } from "./generate_schema"; 4 | import { list_services } from "./list_services"; 5 | import { compile } from "./compile"; 6 | import { execute } from "./execute"; 7 | 8 | export const dataconnectTools: ServerTool[] = [ 9 | compile, 10 | generate_schema, 11 | generate_operation, 12 | list_services, 13 | execute, 14 | ]; 15 | -------------------------------------------------------------------------------- /firebase-vscode/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "dist": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "dist": true // set this to false to include "out" folder in search results 8 | }, 9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 10 | "typescript.tsc.autoDetect": "off" 11 | } 12 | -------------------------------------------------------------------------------- /firebase-vscode/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "plugins": [ 9 | "@typescript-eslint" 10 | // "react" 11 | ], 12 | "rules": { 13 | "@typescript-eslint/semi": "warn", 14 | "curly": "warn", 15 | "eqeqeq": "warn", 16 | "no-throw-literal": "warn", 17 | "semi": "off" 18 | }, 19 | "ignorePatterns": ["out", "dist", "**/*.d.ts"] 20 | } 21 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/fdc_sidebar.entry.scss: -------------------------------------------------------------------------------- 1 | @import "./globals/index.scss"; 2 | 3 | a:not(:hover):not(:focus) { 4 | text-decoration: none; 5 | } 6 | 7 | .fullWidth { 8 | width: 100%; 9 | } 10 | 11 | .integrationStatus { 12 | padding-left: 28px; 13 | position: relative; 14 | 15 | &-label { 16 | line-height: 16px; 17 | } 18 | 19 | &-icon { 20 | position: absolute; 21 | left: 0; 22 | top: 0; 23 | } 24 | 25 | &-loading { 26 | width: 16px; 27 | height: 16px; 28 | } 29 | } -------------------------------------------------------------------------------- /scripts/functions-deploy-tests/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e # Immediately exit on failure 3 | 4 | # Globally link the CLI for the testing framework 5 | ./scripts/clean-install.sh 6 | 7 | # Create a secret for testing if it doesn't exist 8 | firebase functions:secrets:get TOP --project $GCLOUD_PROJECT || (echo secret | firebase functions:secrets:set --data-file=- TOP --project $GCLOUD_PROJECT -f) 9 | 10 | (cd scripts/functions-deploy-tests/functions && npm i) 11 | 12 | mocha scripts/functions-deploy-tests/tests.ts -------------------------------------------------------------------------------- /src/mcp/tools/crashlytics/constants.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const APP_ID_FIELD = z 4 | .string() 5 | .describe( 6 | "AppId for the application. For an Android application, read the " + 7 | "mobilesdk_app_id value specified in the google-services.json file for " + 8 | "the current package name. For an iOS Application, read the GOOGLE_APP_ID " + 9 | "from GoogleService-Info.plist. If neither is available, ask the user to " + 10 | "provide the app id.", 11 | ); 12 | -------------------------------------------------------------------------------- /src/deploy/storage/deploy.ts: -------------------------------------------------------------------------------- 1 | import { get } from "lodash"; 2 | 3 | import { RulesDeploy, RulesetServiceType } from "../../rulesDeploy"; 4 | 5 | /** 6 | * Deploys Firebase Storage rulesets. 7 | * @param context The deploy context. 8 | */ 9 | export default async function (context: any): Promise { 10 | const rulesDeploy: RulesDeploy = get(context, "storage.rulesDeploy"); 11 | if (!rulesDeploy) { 12 | return; 13 | } 14 | await rulesDeploy.createRulesets(RulesetServiceType.FIREBASE_STORAGE); 15 | } 16 | -------------------------------------------------------------------------------- /src/deploy/extensions/args.ts: -------------------------------------------------------------------------------- 1 | import * as planner from "./planner"; 2 | 3 | export interface Payload { 4 | instancesToCreate?: planner.DeploymentInstanceSpec[]; 5 | instancesToConfigure?: planner.DeploymentInstanceSpec[]; 6 | instancesToUpdate?: planner.DeploymentInstanceSpec[]; 7 | instancesToDelete?: planner.DeploymentInstanceSpec[]; 8 | } 9 | 10 | export interface Context { 11 | have?: planner.DeploymentInstanceSpec[]; 12 | want?: planner.DeploymentInstanceSpec[]; 13 | extensionsStartTime?: number; 14 | } 15 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/test_projects/fishfood/dataconnect/connectors/a/queries.gql: -------------------------------------------------------------------------------- 1 | query getPost($id: String!) @auth(level: PUBLIC) { 2 | post(id: $id) { 3 | content 4 | comments: comments_on_post { 5 | id 6 | content 7 | } 8 | } 9 | } 10 | 11 | query listPostsForUser($userId: String!) @auth(level: PUBLIC) { 12 | posts(where: { id: { eq: $userId } }) { 13 | id 14 | content 15 | } 16 | } 17 | 18 | query listPostsOnlyId @auth(level: PUBLIC) { 19 | posts { 20 | id 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/test_projects/fishfood/dataconnect/connectors/a/mutations.gql: -------------------------------------------------------------------------------- 1 | mutation createPost($id: String, $content: String!) @auth(level: PUBLIC) { 2 | post_insert(data: { id: $id, content: $content }) 3 | } 4 | mutation deletePost($id: String!) @auth(level: PUBLIC) { 5 | post_delete(id: $id) 6 | } 7 | 8 | mutation createComment($id: String, $content: String) @auth(level: PUBLIC) { 9 | comment_insert(data: { id: $id, content: $content }) 10 | } 11 | 12 | fragment CommentContent on Comment { 13 | content 14 | } 15 | -------------------------------------------------------------------------------- /src/getDefaultDatabaseInstance.ts: -------------------------------------------------------------------------------- 1 | import { getFirebaseProject } from "./management/projects"; 2 | 3 | /** 4 | * Tries to determine the default database instance for a project. 5 | * @param options The command-line options object 6 | * @return The instance ID, empty if it doesn't exist. 7 | */ 8 | export async function getDefaultDatabaseInstance(options: any): Promise { 9 | const projectDetails = await getFirebaseProject(options.project); 10 | return projectDetails.resources?.realtimeDatabaseInstance || ""; 11 | } 12 | -------------------------------------------------------------------------------- /firebase-vscode/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": ["$tsc-watch", "$ts-webpack-watch"], 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "always" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /scripts/triggers-end-to-end-tests/triggers/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions", 3 | "description": "Cloud Functions for Firebase", 4 | "scripts": {}, 5 | "engines": { 6 | "node": "20" 7 | }, 8 | "dependencies": { 9 | "@firebase/database-compat": "0.1.2", 10 | "@google-cloud/pubsub": "^3.0.1", 11 | "firebase": "^9.9.0", 12 | "firebase-admin": "^11.0.0", 13 | "firebase-functions": "^5.1.0" 14 | }, 15 | "devDependencies": { 16 | "firebase-functions-test": "^0.2.0" 17 | }, 18 | "private": true 19 | } 20 | -------------------------------------------------------------------------------- /templates/extensions/typescript/integration-test.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import { expect } from "chai"; 3 | 4 | describe("greet-the-world", () => { 5 | it("should respond with the configured greeting", async () => { 6 | const expected = "Hello World from greet-the-world"; 7 | 8 | const httpFunctionUri = "http://localhost:5001/demo-test/us-central1/ext-greet-the-world-greetTheWorld/"; 9 | const res = await axios.get(httpFunctionUri); 10 | 11 | return expect(res.data).to.eql(expected); 12 | }).timeout(10000); 13 | }); 14 | -------------------------------------------------------------------------------- /scripts/extensions-emulator-tests/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensions": { 3 | "resize-images": "firebase/storage-resize-images@0.1.28" 4 | }, 5 | "storage": { 6 | "rules": "storage.rules" 7 | }, 8 | "functions": {}, 9 | "emulators": { 10 | "hub": { 11 | "port": 4000 12 | }, 13 | "storage": { 14 | "port": 9199 15 | }, 16 | "functions": { 17 | "port": 9002 18 | }, 19 | "firestore": { 20 | "port": 8080 21 | }, 22 | "eventarc": { 23 | "port": 9299 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/emulator/storage/rfc.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Adapted from: 3 | * - https://datatracker.ietf.org/doc/html/rfc5987 4 | * - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent#examples 5 | * 6 | * @returns RFC5987 encoded string 7 | */ 8 | export function encodeRFC5987(str: string): string { 9 | return encodeURIComponent(str) 10 | .replace(/['()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`) 11 | .replace(/%(7C|60|5E)/g, (str, hex) => String.fromCharCode(parseInt(hex, 16))); 12 | } 13 | -------------------------------------------------------------------------------- /templates/extensions/javascript/integration-test.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const chai = require("chai"); 3 | 4 | describe("greet-the-world", () => { 5 | it("should respond with the configured greeting", async () => { 6 | const expected = "Hello World from greet-the-world"; 7 | 8 | const httpFunctionUri = "http://localhost:5001/demo-test/us-central1/ext-greet-the-world-greetTheWorld/"; 9 | const res = await axios.get(httpFunctionUri); 10 | 11 | return chai.expect(res.data).to.eql(expected); 12 | }).timeout(10000); 13 | }); 14 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/empty_wdio.conf.ts: -------------------------------------------------------------------------------- 1 | import { merge } from "lodash"; 2 | import { config as baseConfig, vscodeConfigs } from "./default_wdio.conf"; 3 | import * as path from "path"; 4 | 5 | const emptyPath = path.resolve(process.cwd(), "src/test/test_projects/empty"); 6 | 7 | export const config: WebdriverIO.Config = { 8 | ...baseConfig, 9 | specs: ["./integration/empty/**/*.ts"], 10 | maxInstances: 1, 11 | capabilities: [ 12 | merge(vscodeConfigs, { 13 | "wdio:vscodeOptions": { workspacePath: emptyPath }, 14 | }), 15 | ], 16 | }; 17 | -------------------------------------------------------------------------------- /scripts/dataconnect-emulator-tests/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex # Immediately exit on failure 3 | # Globally link the CLI for the testing framework 4 | ./scripts/clean-install.sh 5 | source scripts/set-default-credentials.sh 6 | 7 | echo "Running in ${CWD}" 8 | echo "Running with node: $(which node)" 9 | echo "Running with npm: $(which npm)" 10 | echo "Running with Application Creds: ${GOOGLE_APPLICATION_CREDENTIALS}" 11 | 12 | cd scripts/dataconnect-emulator-tests 13 | firebase emulators:exec "cd ." --only dataconnect -P demo-test 14 | # rm -rf ../../clean 15 | -------------------------------------------------------------------------------- /templates/init/dataconnect/dataconnect.yaml: -------------------------------------------------------------------------------- 1 | specVersion: "v1" 2 | serviceId: __serviceId__ 3 | location: __location__ 4 | schema: 5 | source: "./schema" 6 | datasource: 7 | postgresql: 8 | database: __cloudSqlDatabase__ 9 | cloudSql: 10 | instanceId: __cloudSqlInstanceId__ 11 | # schemaValidation: "STRICT" # STRICT mode makes Postgres schema match Data Connect exactly. 12 | # schemaValidation: "COMPATIBLE" # COMPATIBLE mode makes Postgres schema compatible with Data Connect. 13 | connectorDirs: __connectorDirs__ 14 | -------------------------------------------------------------------------------- /src/emulator/shared/request.ts: -------------------------------------------------------------------------------- 1 | import { Request } from "express"; 2 | 3 | /** Returns the body of a {@link Request} as a {@link Buffer}. */ 4 | export async function reqBodyToBuffer(req: Request): Promise { 5 | if (req.body instanceof Buffer) { 6 | return Buffer.from(req.body); 7 | } 8 | const bufs: Buffer[] = []; 9 | req.on("data", (data) => { 10 | bufs.push(data); 11 | }); 12 | await new Promise((resolve) => { 13 | req.on("end", () => { 14 | resolve(); 15 | }); 16 | }); 17 | return Buffer.concat(bufs); 18 | } 19 | -------------------------------------------------------------------------------- /templates/extensions/javascript/package.nolint.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "greet-the-world", 3 | "description": "Greet the world", 4 | "main": "index.js", 5 | "dependencies": { 6 | "firebase-admin": "^12.6.0", 7 | "firebase-functions": "^6.0.1" 8 | }, 9 | "devDependencies": { 10 | "axios": "^1.3.2", 11 | "chai": "^4.3.7", 12 | "mocha": "^10.2.0" 13 | }, 14 | "scripts": { 15 | "mocha": "mocha '**/*.spec.js'", 16 | "test": "(cd integration-tests && firebase emulators:exec 'npm run mocha' -P demo-test)" 17 | }, 18 | "private": true 19 | } -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/styles/globals.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | padding: 0; 4 | margin: 0; 5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 7 | } 8 | 9 | a { 10 | color: inherit; 11 | text-decoration: none; 12 | } 13 | 14 | * { 15 | box-sizing: border-box; 16 | } 17 | 18 | @media (prefers-color-scheme: dark) { 19 | html { 20 | color-scheme: dark; 21 | } 22 | body { 23 | color: white; 24 | background: black; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/requireConfig.ts: -------------------------------------------------------------------------------- 1 | import { FirebaseError } from "./error"; 2 | import { Options } from "./options"; 3 | 4 | /** 5 | * Rejects if there is no config in `options`. 6 | */ 7 | export async function requireConfig(options: Options): Promise { 8 | return new Promise((resolve, reject) => 9 | options.config 10 | ? resolve() 11 | : reject( 12 | options.configError ?? 13 | new FirebaseError( 14 | "Not in a Firebase project directory (could not locate firebase.json)", 15 | ), 16 | ), 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/globals/web-logger.ts: -------------------------------------------------------------------------------- 1 | import { broker } from "./html-broker"; 2 | 3 | type Level = "debug" | "info" | "error"; 4 | const levels: Level[] = ["debug", "info", "error"]; 5 | 6 | type WebLogger = Record void>; 7 | 8 | const tempObject: Partial = {}; 9 | 10 | for (const level of levels) { 11 | tempObject[level] = (...args: string[]) => 12 | broker.send("writeLog", { level, args }); 13 | } 14 | 15 | // Recast it now that it's populated. 16 | const webLogger = tempObject as WebLogger; 17 | 18 | export { webLogger }; 19 | -------------------------------------------------------------------------------- /src/dataconnect/ensureApis.ts: -------------------------------------------------------------------------------- 1 | import * as api from "../api"; 2 | import { ensure } from "../ensureApiEnabled"; 3 | 4 | const prefix = "dataconnect"; 5 | 6 | export async function ensureApis(projectId: string, silent: boolean = false): Promise { 7 | await Promise.all([ 8 | ensure(projectId, api.dataconnectOrigin(), prefix, silent), 9 | ensure(projectId, api.cloudSQLAdminOrigin(), prefix, silent), 10 | ]); 11 | } 12 | 13 | export async function ensureGIFApis(projectId: string): Promise { 14 | await ensure(projectId, api.cloudAiCompanionOrigin(), prefix); 15 | } 16 | -------------------------------------------------------------------------------- /src/frameworks/docs/_includes/_initialize-firebase.md: -------------------------------------------------------------------------------- 1 | ## Initialize Firebase 2 | 3 | To get started, initialize Firebase for your framework project. 4 | Use the {{firebase_cli}} for a new project, or modify `firebase.json` for an 5 | existing project. 6 | 7 | ### Initialize a new project 8 | 9 | 1. In the {{firebase_cli}}, enable the web frameworks preview: 10 |
firebase experiments:enable webframeworks
11 | 1. Run the initialization command from the {{cli}} and then follow the prompts: 12 |
firebase init hosting
13 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/components/ui/PanelSection.scss: -------------------------------------------------------------------------------- 1 | .panel { 2 | display: flex; 3 | flex-direction: column; 4 | } 5 | 6 | .panelExpando { 7 | appearance: none; 8 | background-color: transparent; 9 | display: flex; 10 | align-items: center; 11 | line-height: 16px; 12 | padding: 0; 13 | border: 0; 14 | cursor: pointer; 15 | gap: 4px; 16 | color: var(--vscode-descriptionForeground); 17 | 18 | .panelExpandoIcon { 19 | transition: transform 0.1s ease; 20 | } 21 | 22 | &:not(.isExpanded) .panelExpandoIcon { 23 | transform: rotate(-90deg); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/utils/sidebar.ts: -------------------------------------------------------------------------------- 1 | import { Workbench } from "wdio-vscode-service"; 2 | 3 | export function openFirebaseSidebar() { 4 | return $("a.codicon-mono-firebase").click(); 5 | } 6 | 7 | export async function switchToFirebaseSidebarFrame(workbench: Workbench) { 8 | const sidebarView = await workbench.getWebviewByTitle(""); 9 | await browser.switchToFrame(sidebarView.elem); 10 | 11 | const firebaseView = await $('iframe[title="Firebase"]'); 12 | await firebaseView.waitForDisplayed(); 13 | await browser.switchToFrame(firebaseView); 14 | 15 | return firebaseView; 16 | } 17 | -------------------------------------------------------------------------------- /src/commands/functions-secrets-get.ts: -------------------------------------------------------------------------------- 1 | import { requireAuth } from "../requireAuth"; 2 | import { Command } from "../command"; 3 | import { requirePermissions } from "../requirePermissions"; 4 | import * as secretManager from "../gcp/secretManager"; 5 | import * as secrets from "../functions/secrets"; 6 | 7 | export const command = new Command("functions:secrets:get ") 8 | .description("get metadata for secret and its versions") 9 | .before(requireAuth) 10 | .before(secretManager.ensureApi) 11 | .before(requirePermissions, ["secretmanager.secrets.get"]) 12 | .action(secrets.describeSecret); 13 | -------------------------------------------------------------------------------- /src/mcp/tools/firestore/index.ts: -------------------------------------------------------------------------------- 1 | import { delete_document } from "./delete_document"; 2 | import { get_documents } from "./get_documents"; 3 | import { list_collections } from "./list_collections"; 4 | import { query_collection } from "./query_collection"; 5 | import { validateRulesTool } from "../rules/validate_rules"; 6 | import { getRulesTool } from "../rules/get_rules"; 7 | 8 | export const firestoreTools = [ 9 | delete_document, 10 | get_documents, 11 | list_collections, 12 | query_collection, 13 | getRulesTool("Firestore", "cloud.firestore"), 14 | validateRulesTool("Firestore"), 15 | ]; 16 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/bundled/dist/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Minimal example of a "bundled" function source. 3 | * 4 | * Instead of actually bundling the source code, we manually annotate 5 | * the exported function with the __endpoint property to test the situation 6 | * where the distributed package doesn't include Firebase Functions SDK as a 7 | * dependency. 8 | */ 9 | 10 | const hello = (req, resp) => { 11 | resp.send("hello"); 12 | }; 13 | 14 | hello.__endpoint = { 15 | platform: "gcfv2", 16 | region: "region", 17 | httpsTrigger: {}, 18 | }; 19 | 20 | exports.hello = hello; 21 | -------------------------------------------------------------------------------- /src/emulator/storage/metadata.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | import { toSerializedDate } from "./metadata"; 3 | 4 | describe("toSerializedDate", () => { 5 | it("correctly serializes date", () => { 6 | const testDate = new Date("2022-01-01T00:00:00.000Z"); 7 | 8 | expect(toSerializedDate(testDate)).to.equal("2022-01-01T00:00:00.000Z"); 9 | }); 10 | it("correctly serializes date with different timezone", () => { 11 | const testDate = new Date("2022-01-01T00:00:00.000+07:00"); 12 | 13 | expect(toSerializedDate(testDate)).to.equal("2021-12-31T17:00:00.000Z"); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/components/ui/Icon.scss: -------------------------------------------------------------------------------- 1 | .monicon { 2 | font-family: "Monicons"; 3 | font-weight: normal; 4 | font-style: normal; 5 | font-size: inherit; 6 | display: inline-block; 7 | width: 1em; 8 | height: 1em; 9 | line-height: 1; 10 | text-transform: none; 11 | letter-spacing: normal; 12 | word-wrap: normal; 13 | white-space: nowrap; 14 | direction: ltr; 15 | -webkit-font-smoothing: antialiased; 16 | text-rendering: optimizeLegibility; 17 | -moz-osx-font-smoothing: grayscale; 18 | font-feature-settings: "liga"; 19 | speak: none; 20 | text-decoration: inherit; 21 | } 22 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | 38 | .vscode 39 | -------------------------------------------------------------------------------- /src/getProjectNumber.ts: -------------------------------------------------------------------------------- 1 | import { getProject } from "./management/projects"; 2 | import { needProjectId } from "./projectUtils"; 3 | /** 4 | * Fetches the project number. 5 | * @param options CLI options. 6 | * @return the project number, as a string. 7 | */ 8 | export async function getProjectNumber(options: any): Promise { 9 | if (options.projectNumber) { 10 | return options.projectNumber; 11 | } 12 | const projectId = needProjectId(options); 13 | const metadata = await getProject(projectId); 14 | options.projectNumber = metadata.projectNumber; 15 | return options.projectNumber; 16 | } 17 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/integration/queries_with_error.gql: -------------------------------------------------------------------------------- 1 | # This file is used to test the codelens error through the extension, 2 | # it contains a syntax error in the query. 3 | query getPost(id: String!) @auth(level: PUBLIC) { 4 | post(id: $id) { 5 | content 6 | comments: comments_on_post { 7 | id 8 | content 9 | } 10 | } 11 | } 12 | 13 | query listPostsForUser($userId: String!) @auth(level: PUBLIC) { 14 | posts(where: { id: { eq: $userId } }) { 15 | id 16 | content 17 | } 18 | } 19 | 20 | query listPostsOnlyId @auth(level: PUBLIC) { 21 | posts { 22 | id 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euxo pipefail # bash strict mode 3 | IFS=$'\n\t' 4 | 5 | # Globally link the CLI for the testing framework 6 | ./scripts/clean-install.sh 7 | 8 | # Unlock internal commands for discovering functions in a project. 9 | firebase experiments:enable internaltesting 10 | 11 | # Install yarn 12 | npm i -g yarn 13 | 14 | # Install pnpm 15 | npm install -g pnpm --force # it's okay to reinstall pnpm 16 | 17 | for dir in ./scripts/functions-discover-tests/fixtures/*; do 18 | (cd $dir && ./install.sh) 19 | done 20 | 21 | mocha scripts/functions-discover-tests/tests.ts -------------------------------------------------------------------------------- /src/deploy/hosting/context.ts: -------------------------------------------------------------------------------- 1 | import { HostingResolved } from "../../hosting/config"; 2 | import { Context as FunctionsContext } from "../functions/args"; 3 | 4 | export interface HostingDeploy { 5 | // Note: a HostingMultiple[number] is a stronger guarantee than a HostingSingle 6 | // because at least one of site and target must exist. 7 | config: HostingResolved; 8 | version: string; 9 | } 10 | 11 | export interface Context extends FunctionsContext { 12 | hosting?: { 13 | deploys: HostingDeploy[]; 14 | }; 15 | 16 | // Set as a global in hosting-channel-deploy.ts 17 | hostingChannel?: string; 18 | } 19 | -------------------------------------------------------------------------------- /src/firestore/backupUtils.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | import { calculateRetention } from "./backupUtils"; 4 | 5 | describe("calculateRetention", () => { 6 | it("should accept minutes", () => { 7 | expect(calculateRetention("5m")).to.eq(300); 8 | }); 9 | 10 | it("should accept hours", () => { 11 | expect(calculateRetention("3h")).to.eq(10800); 12 | }); 13 | 14 | it("should accept days", () => { 15 | expect(calculateRetention("2d")).to.eq(172800); 16 | }); 17 | 18 | it("should accept weeks", () => { 19 | expect(calculateRetention("3w")).to.eq(1814400); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /firebase-vscode/common/messaging/types.d.ts: -------------------------------------------------------------------------------- 1 | import { EmulatorInfo } from "../emulator/types"; 2 | 3 | export interface Message { 4 | command: string; 5 | data: M[keyof M]; 6 | } 7 | 8 | export type Listener = (args?: M[keyof M]) => void; 9 | 10 | export interface MessageListeners { 11 | [message: string]: Listener[]; 12 | } 13 | 14 | /** 15 | * Info to display in the UI while the emulators are running 16 | */ 17 | export interface RunningEmulatorInfo { 18 | uiUrl: string; 19 | displayInfo: EmulatorInfo[]; 20 | } 21 | 22 | export type EmulatorsStatus = "running" | "stopped" | "starting" | "stopping"; 23 | -------------------------------------------------------------------------------- /scripts/functions-discover-tests/fixtures/codebases/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "functions": [ 3 | { 4 | "source": "v1", 5 | "codebase": "v1", 6 | "runtime": "nodejs22", 7 | "ignore": [ 8 | "node_modules", 9 | ".git", 10 | "firebase-debug.log", 11 | "firebase-debug.*.log" 12 | ] 13 | }, 14 | { 15 | "source": "v2", 16 | "codebase": "v2", 17 | "runtime": "nodejs22", 18 | "ignore": [ 19 | "node_modules", 20 | ".git", 21 | "firebase-debug.log", 22 | "firebase-debug.*.log" 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /tsconfig.compile.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "noEmit": true, // Don't actually produce any compiled output. 5 | "checkJs": true, // We want to do a pass on JS files. 6 | "resolveJsonModule": true, // Makes require(package.json) acceptable (added). 7 | "strict": false, // Need to relax some strictness to check JS (changed). 8 | "strictBindCallApply": true, // This is part of "strict: true" (added). 9 | "strictFunctionTypes": true, // This is part of "strict: true" (added). 10 | "noImplicitThis": true, // This is part of "strict: true" (added). 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /firebase-vscode/webpack.prod.js: -------------------------------------------------------------------------------- 1 | const { merge } = require("webpack-merge"); 2 | const TerserPlugin = require("terser-webpack-plugin"); 3 | const common = require("./webpack.common.js"); 4 | 5 | module.exports = common.map((config) => 6 | merge(config, { 7 | mode: "production", 8 | optimization: { 9 | minimize: true, 10 | minimizer: [ 11 | new TerserPlugin({ 12 | terserOptions: { 13 | keep_classnames: /AbortSignal/, 14 | keep_fnames: /AbortSignal/, 15 | }, 16 | parallel: 2, 17 | }), 18 | "...", 19 | ], 20 | }, 21 | }), 22 | ); 23 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/components/ui/ExternalLink.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { VSCodeLink } from "@vscode/webview-ui-toolkit/react"; 3 | import styles from "./ExternalLink.scss"; 4 | 5 | export function ExternalLink({ 6 | href, 7 | children, 8 | prefix, 9 | }: { 10 | href: string; 11 | children: string; 12 | prefix?: JSX.Element; 13 | }) { 14 | return ( 15 | 16 | 17 | {prefix} 18 | {children} 19 | 20 | 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "checkJs": false, 5 | "module": "commonjs", 6 | "strict": true, 7 | "outDir": "lib", 8 | "removeComments": true, 9 | "allowSyntheticDefaultImports": true, 10 | "target": "ES2020", 11 | "resolveJsonModule": true, 12 | "sourceMap": true, 13 | "skipLibCheck": true, 14 | "typeRoots": [ 15 | "node_modules/@types", 16 | "src/types" 17 | ] 18 | }, 19 | "lib": [ 20 | "dom", 21 | "dom.iterable", 22 | "ES2020" 23 | ], 24 | "include": ["src/**/*"], 25 | "exclude": ["src/dynamicImport.js"] 26 | } 27 | -------------------------------------------------------------------------------- /src/mcp/util/dataconnect/emulator.ts: -------------------------------------------------------------------------------- 1 | import { Emulators } from "../../../emulator/types"; 2 | import { Client } from "../../../apiv2"; 3 | import { DATACONNECT_API_VERSION } from "../../../dataconnect/dataplaneClient"; 4 | import type { FirebaseMcpServer } from "../../index"; 5 | 6 | export async function getDataConnectEmulatorClient(host: FirebaseMcpServer): Promise { 7 | const emulatorUrl = await host.getEmulatorUrl(Emulators.DATACONNECT); 8 | 9 | const apiClient = new Client({ 10 | urlPrefix: emulatorUrl, 11 | apiVersion: DATACONNECT_API_VERSION, 12 | auth: false, 13 | }); 14 | 15 | return apiClient; 16 | } 17 | -------------------------------------------------------------------------------- /scripts/build/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:20 2 | 3 | # Install dependencies 4 | RUN curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - 5 | RUN echo "deb https://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list 6 | RUN apt-get update && \ 7 | apt-get install -y curl git jq google-cloud-cli 8 | 9 | # Install hub 10 | RUN curl -fsSL --output hub.tgz https://github.com/github/hub/releases/download/v2.14.2/hub-linux-amd64-2.14.2.tgz 11 | RUN tar --strip-components=2 -C /usr/bin -xf hub.tgz hub-linux-amd64-2.14.2/bin/hub 12 | 13 | # Upgrade npm to 9. 14 | RUN npm install --global npm@9.5 15 | -------------------------------------------------------------------------------- /src/scopes.ts: -------------------------------------------------------------------------------- 1 | // default scopes 2 | export const OPENID = "openid"; 3 | export const EMAIL = "email"; 4 | export const USERINFO_EMAIL = "https://www.googleapis.com/auth/userinfo.email"; 5 | export const CLOUD_PROJECTS_READONLY = 6 | "https://www.googleapis.com/auth/cloudplatformprojects.readonly"; 7 | export const FIREBASE_PLATFORM = "https://www.googleapis.com/auth/firebase"; 8 | 9 | // incremental scopes 10 | export const CLOUD_PLATFORM = "https://www.googleapis.com/auth/cloud-platform"; 11 | export const CLOUD_STORAGE = "https://www.googleapis.com/auth/devstorage.read_write"; 12 | export const CLOUD_PUBSUB = "https://www.googleapis.com/auth/pubsub"; 13 | -------------------------------------------------------------------------------- /src/throttler/queue.ts: -------------------------------------------------------------------------------- 1 | import { Throttler, ThrottlerOptions } from "./throttler"; 2 | 3 | export class Queue extends Throttler { 4 | cursor: number = 0; 5 | 6 | constructor(options: ThrottlerOptions) { 7 | super(options); 8 | this.name = this.name || "queue"; 9 | } 10 | 11 | hasWaitingTask(): boolean { 12 | return this.cursor !== this.total; 13 | } 14 | 15 | nextWaitingTaskIndex(): number { 16 | if (this.cursor >= this.total) { 17 | throw new Error("There is no more task in queue"); 18 | } 19 | this.cursor++; 20 | return this.cursor - 1; 21 | } 22 | } 23 | 24 | export default Queue; 25 | -------------------------------------------------------------------------------- /templates/init/functions/javascript/_eslintrc: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | es6: true, 4 | node: true, 5 | }, 6 | parserOptions: { 7 | "ecmaVersion": 2018, 8 | }, 9 | extends: [ 10 | "eslint:recommended", 11 | "google", 12 | ], 13 | rules: { 14 | "no-restricted-globals": ["error", "name", "length"], 15 | "prefer-arrow-callback": "error", 16 | "quotes": ["error", "double", {"allowTemplateLiterals": true}], 17 | }, 18 | overrides: [ 19 | { 20 | files: ["**/*.spec.*"], 21 | env: { 22 | mocha: true, 23 | }, 24 | rules: {}, 25 | }, 26 | ], 27 | globals: {}, 28 | }; 29 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/utils/page_objects/quick_picks.ts: -------------------------------------------------------------------------------- 1 | import { Workbench } from "wdio-vscode-service"; 2 | 3 | /* Workaround to workbench not exposing a way to get an InputBox 4 | * without triggering a command. */ 5 | 6 | export class QuickPick { 7 | constructor(readonly workbench: Workbench) {} 8 | 9 | get okElement() { 10 | return $("a=OK"); 11 | } 12 | 13 | async findQuickPicks() { 14 | // TODO find a way to use InputBox manually that does not trigger a build error 15 | return await $(".quick-input-widget") 16 | .$(".quick-input-list") 17 | .$(".monaco-list-rows") 18 | .$$(".monaco-list-row"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/functions/events/v1.ts: -------------------------------------------------------------------------------- 1 | export const BEFORE_CREATE_EVENT = "providers/cloud.auth/eventTypes/user.beforeCreate"; 2 | 3 | export const BEFORE_SIGN_IN_EVENT = "providers/cloud.auth/eventTypes/user.beforeSignIn"; 4 | 5 | export const BEFORE_SEND_EMAIL_EVENT = "providers/cloud.auth/eventTypes/user.beforeSendEmail"; 6 | 7 | export const BEFORE_SEND_SMS_EVENT = "providers/cloud.auth/eventTypes/user.beforeSendSms"; 8 | 9 | export const AUTH_BLOCKING_EVENTS = [ 10 | BEFORE_CREATE_EVENT, 11 | BEFORE_SIGN_IN_EVENT, 12 | BEFORE_SEND_EMAIL_EVENT, 13 | BEFORE_SEND_SMS_EVENT, 14 | ] as const; 15 | 16 | export type Event = (typeof AUTH_BLOCKING_EVENTS)[number]; 17 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/fishfood_wdio.conf.ts: -------------------------------------------------------------------------------- 1 | import { merge } from "lodash"; 2 | import { config as baseConfig, vscodeConfigs } from "./default_wdio.conf"; 3 | import * as path from "path"; 4 | 5 | const fishfoodPath = path.resolve( 6 | process.cwd(), 7 | "src/test/test_projects/fishfood", 8 | ); 9 | 10 | export const config: WebdriverIO.Config = { 11 | ...baseConfig, 12 | // Disable concurrency as tests may write to the same files. 13 | maxInstances: 1, 14 | specs: ["./integration/fishfood/**/*.ts"], 15 | capabilities: [ 16 | merge(vscodeConfigs, { 17 | "wdio:vscodeOptions": { workspacePath: fishfoodPath }, 18 | }), 19 | ], 20 | }; 21 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e # Immediately exit on failure 3 | 4 | # Globally link the CLI for the testing framework 5 | ./scripts/clean-install.sh 6 | 7 | source scripts/set-default-credentials.sh 8 | 9 | npm ci --prefix scripts/webframeworks-deploy-tests/nextjs 10 | npm ci --prefix scripts/webframeworks-deploy-tests/angular 11 | npm ci --prefix scripts/webframeworks-deploy-tests/functions 12 | 13 | FIREBASE_CLI_EXPERIMENTS=webframeworks,pintags firebase emulators:exec "mocha scripts/webframeworks-deploy-tests/tests.ts --exit --retries 2" --config scripts/webframeworks-deploy-tests/firebase.json --project demo-123 --debug 14 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hosting", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "next": "15.0.0", 13 | "react": "19.0.0-rc-65a56d0e-20241020", 14 | "react-dom": "19.0.0-rc-65a56d0e-20241020" 15 | }, 16 | "devDependencies": { 17 | "@types/node": "^20", 18 | "@types/react": "^18", 19 | "@types/react-dom": "^18", 20 | "eslint": "^9", 21 | "eslint-config-next": "15.0.0", 22 | "typescript": "^5" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/emulator/adminSdkConfig.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | import { getProjectAdminSdkConfigOrCached } from "./adminSdkConfig"; 3 | 4 | describe("adminSdkConfig", () => { 5 | describe("getProjectAdminSdkConfigOrCached", () => { 6 | it("should return a fake config for a demo project id", async () => { 7 | const projectId = "demo-project-1234"; 8 | await expect(getProjectAdminSdkConfigOrCached(projectId)).to.eventually.deep.equal({ 9 | projectId: "demo-project-1234", 10 | databaseURL: "https://demo-project-1234.firebaseio.com", 11 | storageBucket: "demo-project-1234.appspot.com", 12 | }); 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/index.ts: -------------------------------------------------------------------------------- 1 | import { join } from "path"; 2 | 3 | const zipFixturesDir = __dirname; 4 | const testDataDir = join(zipFixturesDir, "node-unzipper-testData"); 5 | 6 | export const ZIP_CASES = [ 7 | { name: "compressed-cp866" }, 8 | { name: "compressed-directory-entry" }, 9 | { name: "compressed-flags-set" }, 10 | { name: "compressed-standard" }, 11 | { name: "uncompressed" }, 12 | { name: "zip-slip", wantErr: "a path outside of" }, 13 | { name: "zip64" }, 14 | ].map(({ name, wantErr }) => ({ 15 | name, 16 | archivePath: join(testDataDir, name, "archive.zip"), 17 | inflatedDir: join(testDataDir, name, "inflated"), 18 | wantErr, 19 | })); 20 | -------------------------------------------------------------------------------- /firebase-vscode/src/data-connect/language-server.ts: -------------------------------------------------------------------------------- 1 | import { startServer } from "graphql-language-service-server"; 2 | // The npm scripts are configured to only build this once before 3 | // watching the extension, so please restart the extension debugger for changes! 4 | 5 | async function start() { 6 | try { 7 | await startServer({ 8 | method: "node", 9 | loadConfigOptions: { rootDir: ".firebase" }, 10 | }); 11 | // eslint-disable-next-line no-console 12 | console.log("Firebase GraphQL Language Server started!"); 13 | } catch (err) { 14 | // eslint-disable-next-line no-console 15 | console.error(err); 16 | } 17 | } 18 | 19 | void start(); 20 | -------------------------------------------------------------------------------- /src/types/extractTriggers.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Extracts trigger definitions from a function file. 3 | * @param {Object} mod module, usually the result of require(functions/index.js) 4 | * @param {ParsedTriggerDefinition[]} triggers array of EmulatedTriggerDefinitions to extend (in-place). 5 | * @param {string=} prefix optional function name prefix, for example when using grouped functions. 6 | */ 7 | import { ParsedTriggerDefinition } from "../emulator/functionsEmulatorShared"; 8 | 9 | export declare function extractTriggers( 10 | mod: Array, // eslint-disable-line @typescript-eslint/ban-types 11 | triggers: ParsedTriggerDefinition[], 12 | prefix?: string, 13 | ): void; 14 | -------------------------------------------------------------------------------- /src/commands/functions-secrets-describe.ts: -------------------------------------------------------------------------------- 1 | import { requireAuth } from "../requireAuth"; 2 | import { Command } from "../command"; 3 | import { requirePermissions } from "../requirePermissions"; 4 | import * as secretManager from "../gcp/secretManager"; 5 | import * as secrets from "../functions/secrets"; 6 | 7 | export const command = new Command("functions:secrets:describe ") 8 | .description( 9 | "get metadata for secret and its versions. Alias for functions:secrets:get to align with gcloud", 10 | ) 11 | .before(requireAuth) 12 | .before(secretManager.ensureApi) 13 | .before(requirePermissions, ["secretmanager.secrets.get"]) 14 | .action(secrets.describeSecret); 15 | -------------------------------------------------------------------------------- /src/errorOut.ts: -------------------------------------------------------------------------------- 1 | import { logError } from "./logError"; 2 | import { FirebaseError } from "./error"; 3 | 4 | /** 5 | * Errors out by calling `process.exit` with an exit code of 2. 6 | * @param error an Error to be logged. 7 | */ 8 | export function errorOut(error: Error): void { 9 | let fbError: FirebaseError; 10 | if (error instanceof FirebaseError) { 11 | fbError = error; 12 | } else { 13 | fbError = new FirebaseError("An unexpected error has occurred.", { 14 | original: error, 15 | exit: 2, 16 | }); 17 | } 18 | 19 | logError(fbError); 20 | process.exitCode = fbError.exit || 2; 21 | setTimeout(() => { 22 | process.exit(); 23 | }, 250); 24 | } 25 | -------------------------------------------------------------------------------- /src/init/features/functions/npm-dependencies.ts: -------------------------------------------------------------------------------- 1 | import { logger } from "../../../logger"; 2 | import { confirm } from "../../../prompt"; 3 | import { wrapSpawn } from "../../spawn"; 4 | 5 | export async function askInstallDependencies(setup: any, config: any): Promise { 6 | setup.npm = await confirm({ 7 | message: "Do you want to install dependencies with npm now?", 8 | default: true, 9 | }); 10 | if (setup.npm) { 11 | try { 12 | await wrapSpawn("npm", ["install"], config.projectDir + `/${setup.source}`); 13 | } catch (e) { 14 | logger.info(); 15 | logger.error("NPM install failed, continuing with Firebase initialization..."); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/deploy/remoteconfig/release.ts: -------------------------------------------------------------------------------- 1 | import { publishTemplate, getEtag } from "./functions"; 2 | import { needProjectNumber } from "../../projectUtils"; 3 | import { RemoteConfigTemplate } from "../../remoteconfig/interfaces"; 4 | 5 | interface ReleaseContext { 6 | remoteconfigTemplate?: RemoteConfigTemplate; 7 | } 8 | 9 | export default async function (context: ReleaseContext, options: any) { 10 | if (!context?.remoteconfigTemplate) { 11 | return; 12 | } 13 | const template = context.remoteconfigTemplate; 14 | const projectNumber = await needProjectNumber(options); 15 | const etag = await getEtag(projectNumber); 16 | return publishTemplate(projectNumber, template, etag, options); 17 | } 18 | -------------------------------------------------------------------------------- /src/deploy/functions/services/database.ts: -------------------------------------------------------------------------------- 1 | import * as backend from "../backend"; 2 | import { FirebaseError } from "../../../error"; 3 | 4 | /** 5 | * Sets a database event trigger's region to the function region. 6 | * @param endpoint the database endpoint 7 | */ 8 | export function ensureDatabaseTriggerRegion( 9 | endpoint: backend.Endpoint & backend.EventTriggered, 10 | ): Promise { 11 | if (!endpoint.eventTrigger.region) { 12 | endpoint.eventTrigger.region = endpoint.region; 13 | } 14 | if (endpoint.eventTrigger.region !== endpoint.region) { 15 | throw new FirebaseError("A database trigger location must match the function region."); 16 | } 17 | return Promise.resolve(); 18 | } 19 | -------------------------------------------------------------------------------- /src/deploy/functions/services/testLab.ts: -------------------------------------------------------------------------------- 1 | import * as backend from "../backend"; 2 | import { FirebaseError } from "../../../error"; 3 | 4 | /** 5 | * Sets a Test Lab event trigger's region to 'global' since the service is global 6 | * @param endpoint the test lab endpoint 7 | */ 8 | export function ensureTestLabTriggerRegion( 9 | endpoint: backend.Endpoint & backend.EventTriggered, 10 | ): Promise { 11 | if (!endpoint.eventTrigger.region) { 12 | endpoint.eventTrigger.region = "global"; 13 | } 14 | if (endpoint.eventTrigger.region !== "global") { 15 | throw new FirebaseError("A Test Lab trigger must specify 'global' trigger location"); 16 | } 17 | return Promise.resolve(); 18 | } 19 | -------------------------------------------------------------------------------- /templates/init/functions/javascript/package.nolint.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions", 3 | "description": "Cloud Functions for Firebase", 4 | "scripts": { 5 | "serve": "firebase emulators:start --only functions", 6 | "shell": "firebase functions:shell", 7 | "start": "npm run shell", 8 | "deploy": "firebase deploy --only functions", 9 | "logs": "firebase functions:log" 10 | }, 11 | "engines": { 12 | "node": "{{RUNTIME}}" 13 | }, 14 | "main": "index.js", 15 | "dependencies": { 16 | "firebase-admin": "^12.6.0", 17 | "firebase-functions": "^6.0.1" 18 | }, 19 | "devDependencies": { 20 | "firebase-functions-test": "^3.1.0" 21 | }, 22 | "private": true 23 | } 24 | -------------------------------------------------------------------------------- /mockdata/function_source_v2.txt: -------------------------------------------------------------------------------- 1 | Nullam nisi leo, aliquam eget scelerisque ac, suscipit et nisi. Donec vestibulum sollicitudin nisi, eleifend elementum massa auctor quis. Proin vulputate nisi molestie suscipit aliquam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Pellentesque mattis metus quis felis consectetur, in venenatis metus consequat. Maecenas a arcu in nulla faucibus tempor. Duis in odio tristique, faucibus eros non, feugiat velit. Maecenas egestas nisl sed diam viverra, vitae mattis ante sagittis. Nunc interdum congue aliquam. Suspendisse vel euismod eros. Fusce et porta augue. Sed at interdum ex, ut dapibus felis. Sed augue nulla, malesuada sed suscipit vel, varius ac diam. 2 | -------------------------------------------------------------------------------- /src/commands/functions-shell.ts: -------------------------------------------------------------------------------- 1 | import { Command } from "../command"; 2 | import { requirePermissions } from "../requirePermissions"; 3 | import { actionFunction } from "../functionsShellCommandAction"; 4 | import { requireConfig } from "../requireConfig"; 5 | import { DESC_INSPECT_FUNCTIONS, FLAG_INSPECT_FUNCTIONS } from "../emulator/commandUtils"; 6 | 7 | export const command = new Command("functions:shell") 8 | .description("launch full Node shell with emulated functions") 9 | .option("-p, --port ", "the port on which to emulate functions") 10 | .option(FLAG_INSPECT_FUNCTIONS, DESC_INSPECT_FUNCTIONS) 11 | .before(requireConfig) 12 | .before(requirePermissions) 13 | .action(actionFunction); 14 | -------------------------------------------------------------------------------- /firebase-vscode/src/auth/service.ts: -------------------------------------------------------------------------------- 1 | import { Disposable } from "vscode"; 2 | import { ExtensionBrokerImpl } from "../extension-broker"; 3 | import { UserMock } from "../../common/messaging/protocol"; 4 | 5 | export class AuthService implements Disposable { 6 | constructor(readonly broker: ExtensionBrokerImpl) { 7 | this.disposable.push({ 8 | dispose: broker.on( 9 | "notifyAuthUserMockChange", 10 | (userMock) => (this.userMock = userMock) 11 | ), 12 | }); 13 | } 14 | 15 | userMock: UserMock | undefined; 16 | disposable: Disposable[] = []; 17 | 18 | dispose() { 19 | for (const disposable of this.disposable) { 20 | disposable.dispose(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/nextjs/pages/pages/fallback/[id].tsx: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/router"; 2 | 3 | export const getStaticPaths = async () => { 4 | return { 5 | paths: [ 6 | { params: { id: '1' }, locale: 'en' }, 7 | { params: { id: '2' }, locale: 'en' }, 8 | { params: { id: '1' }, locale: 'fr' }, 9 | { params: { id: '2' }, locale: 'fr' }, 10 | ], 11 | fallback: true, 12 | }; 13 | } 14 | 15 | export const getStaticProps = async () => { 16 | return { props: { } }; 17 | } 18 | 19 | export default function SSG() { 20 | const { locale, query: { id }} = useRouter(); 21 | return <>SSG {id} {locale}; 22 | } 23 | -------------------------------------------------------------------------------- /src/commands/emulators-export.ts: -------------------------------------------------------------------------------- 1 | import { Command } from "../command"; 2 | import * as controller from "../emulator/controller"; 3 | import * as commandUtils from "../emulator/commandUtils"; 4 | 5 | const COMMAND_NAME = "emulators:export"; 6 | export const command = new Command(`${COMMAND_NAME} `) 7 | .description("export data from running emulators") 8 | .withForce("overwrite any export data in the target directory") 9 | .option(commandUtils.FLAG_ONLY, commandUtils.DESC_ONLY) 10 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 11 | .action((exportPath: string, options: any) => { 12 | return controller.exportEmulatorData(exportPath, options, /* initiatedBy= */ COMMAND_NAME); 13 | }); 14 | -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions", 3 | "description": "Cloud Functions for Firebase", 4 | "type": "module", 5 | "scripts": { 6 | "serve": "firebase emulators:start --only functions", 7 | "shell": "firebase functions:shell", 8 | "start": "npm run shell", 9 | "deploy": "firebase deploy --only functions", 10 | "logs": "firebase functions:log" 11 | }, 12 | "engines": { 13 | "node": "20" 14 | }, 15 | "main": "index.js", 16 | "dependencies": { 17 | "firebase-admin": "^11.11.0", 18 | "firebase-functions": "^4.5.0" 19 | }, 20 | "devDependencies": { 21 | "firebase-functions-test": "^3.1.0" 22 | }, 23 | "private": true 24 | } 25 | -------------------------------------------------------------------------------- /templates/extensions/typescript/package.nolint.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions", 3 | "scripts": { 4 | "build": "tsc", 5 | "build:watch": "tsc --watch", 6 | "mocha": "mocha '**/*.spec.ts'", 7 | "test": "(cd integration-tests && firebase emulators:exec 'npm run mocha' -P demo-test)" 8 | }, 9 | "main": "lib/index.js", 10 | "dependencies": { 11 | "firebase-admin": "^12.6.0", 12 | "firebase-functions": "^6.0.1" 13 | }, 14 | "devDependencies": { 15 | "@types/chai": "^4.3.4", 16 | "@types/mocha": "^10.0.1", 17 | "typescript": "^4.9.0", 18 | "axios": "^1.3.2", 19 | "chai": "^4.3.7", 20 | "mocha": "^10.2.0", 21 | "ts-node": "^10.4.0" 22 | }, 23 | "private": true 24 | } 25 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/suite/src/core/project.test.ts: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import { _promptUserForProject } from "../../../../core/project"; 3 | import { firebaseSuite, firebaseTest } from "../../../utils/test_hooks"; 4 | import * as vscode from "vscode"; 5 | 6 | firebaseSuite("_promptUserForProject", () => { 7 | firebaseTest("supports not selecting a project", async () => { 8 | const tokenSource = new vscode.CancellationTokenSource(); 9 | 10 | const result = _promptUserForProject( 11 | new Promise((resolve) => resolve([])), 12 | tokenSource.token 13 | ); 14 | 15 | // Cancel the prompt 16 | tokenSource.cancel(); 17 | 18 | assert.equal(await result, undefined); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /scripts/emulator-tests/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | # Clean the destination of the upcoming build. 5 | rm -rf dev 6 | # Run a special build for these tests and the source code. 7 | tsc --build scripts/emulator-tests/tsconfig.dev.json 8 | # Setup a cleanup process to run before exit. 9 | function cleanup() { 10 | # Remove the built artifacts. 11 | rm -rf dev 12 | } 13 | trap cleanup EXIT 14 | # Need to copy `package.json` to the directory so it can be referenced in code. 15 | cp package.json dev/package.json 16 | 17 | # Install deps required to run test triggers. 18 | (cd scripts/emulator-tests/functions && npm ci) 19 | 20 | # Run the tests from the built dev directory. 21 | mocha dev/scripts/emulator-tests/*.spec.* 22 | -------------------------------------------------------------------------------- /scripts/publish/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | printusage() { 5 | echo "run.sh " 6 | echo "" 7 | echo "Arguments:" 8 | echo " version: 'patch', 'minor', 'major', or 'artifactsOnly'" 9 | } 10 | 11 | VERSION=$1 12 | if [[ $VERSION == "" ]]; then 13 | printusage 14 | exit 1 15 | elif [[ ! ($VERSION == "patch" || $VERSION == "minor" || $VERSION == "major" || $VERSION == "artifactsOnly") ]]; then 16 | printusage 17 | exit 1 18 | fi 19 | 20 | THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 21 | 22 | cd "$THIS_DIR" 23 | 24 | gcloud --project fir-tools-builds \ 25 | builds \ 26 | submit \ 27 | --machine-type=e2-highcpu-8 \ 28 | --substitutions=_VERSION=$VERSION \ 29 | . -------------------------------------------------------------------------------- /src/deploy/functions/services/remoteConfig.ts: -------------------------------------------------------------------------------- 1 | import * as backend from "../backend"; 2 | import { FirebaseError } from "../../../error"; 3 | 4 | /** 5 | * Sets a Remote Config event trigger's region to 'global' since the service is global 6 | * @param endpoint the remote config endpoint 7 | */ 8 | export function ensureRemoteConfigTriggerRegion( 9 | endpoint: backend.Endpoint & backend.EventTriggered, 10 | ): Promise { 11 | if (!endpoint.eventTrigger.region) { 12 | endpoint.eventTrigger.region = "global"; 13 | } 14 | if (endpoint.eventTrigger.region !== "global") { 15 | throw new FirebaseError("A remote config trigger must specify 'global' trigger location"); 16 | } 17 | return Promise.resolve(); 18 | } 19 | -------------------------------------------------------------------------------- /src/mcp/tools/core/get_project.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { tool } from "../../tool"; 3 | import { getProject } from "../../../management/projects"; 4 | import { toContent } from "../../util"; 5 | 6 | export const get_project = tool( 7 | { 8 | name: "get_project", 9 | description: "Retrieves information about the currently active Firebase project.", 10 | inputSchema: z.object({}), 11 | annotations: { 12 | title: "Get Current Firebase Project", 13 | readOnlyHint: true, 14 | }, 15 | _meta: { 16 | requiresAuth: true, 17 | requiresProject: true, 18 | }, 19 | }, 20 | async (_, { projectId }) => { 21 | return toContent(await getProject(projectId)); 22 | }, 23 | ); 24 | -------------------------------------------------------------------------------- /firebase-vscode/src/test/utils/page_objects/terminal.ts: -------------------------------------------------------------------------------- 1 | import { Workbench } from "wdio-vscode-service"; 2 | 3 | export class TerminalView { 4 | constructor(readonly workbench: Workbench) {} 5 | 6 | private readonly bottomBar = this.workbench.getBottomBar(); 7 | async getTerminalText() { 8 | const tv = await this.bottomBar.openTerminalView(); 9 | /** 10 | * SEE: https://github.com/webdriverio-community/wdio-vscode-service/blob/e4ef4d5a1da194e9a6195fad881733c3aa6720d8/src/pageobjects/workbench/Workbench.ts#L183 11 | * The code recognizes our webview, and chooses to send `F1` as an input instead of as a keystroke. 12 | */ 13 | await browser.keys("F1"); 14 | return await tv.getText(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/commands/target-clear.ts: -------------------------------------------------------------------------------- 1 | import * as clc from "colorette"; 2 | 3 | import { Command } from "../command"; 4 | import { requireConfig } from "../requireConfig"; 5 | import * as utils from "../utils"; 6 | 7 | export const command = new Command("target:clear ") 8 | .description("clear all resources from a named resource target") 9 | .before(requireConfig) 10 | .action((type, name, options) => { 11 | const existed = options.rc.clearTarget(options.project, type, name); 12 | if (existed) { 13 | utils.logSuccess(`Cleared ${type} target ${clc.bold(name)}`); 14 | } else { 15 | utils.logWarning(`No action taken. No ${type} target found named ${clc.bold(name)}`); 16 | } 17 | return existed; 18 | }); 19 | -------------------------------------------------------------------------------- /src/deploy/extensions/validate.ts: -------------------------------------------------------------------------------- 1 | import { checkBillingEnabled } from "../../gcp/cloudbilling"; 2 | import { enableBilling } from "../../extensions/checkProjectBilling"; 3 | import { FirebaseError } from "../../error"; 4 | 5 | export async function checkBilling(projectId: string, nonInteractive: boolean) { 6 | const enabled = await checkBillingEnabled(projectId); 7 | if (!enabled && nonInteractive) { 8 | throw new FirebaseError( 9 | `Extensions require the Blaze plan, but project ${projectId} is not on the Blaze plan. ` + 10 | `Please visit https://console.cloud.google.com/billing/linkedaccount?project=${projectId} to upgrade your project.`, 11 | ); 12 | } else if (!enabled) { 13 | await enableBilling(projectId); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/extensions/metricsTypeDef.ts: -------------------------------------------------------------------------------- 1 | import * as refs from "./refs"; 2 | 3 | /** 4 | * Interface for representing a metric to be rendered by the extension's CLI. 5 | */ 6 | export interface BucketedMetric { 7 | ref: refs.Ref; 8 | valueToday: Bucket | undefined; 9 | value7dAgo: Bucket | undefined; 10 | value28dAgo: Bucket | undefined; 11 | } 12 | 13 | /** 14 | * Bucket is the range that a raw number falls under. 15 | * 16 | * Valid bucket sizes are: 17 | * 0 18 | * 0 - 10 19 | * 10 - 20 20 | * 20 - 30 21 | * ... 22 | * 90 - 100 23 | * 100 - 200 24 | * 200 - 300 25 | * every 100... 26 | * 27 | * Note the buckets overlaps intentionally as a UX-optimization. 28 | */ 29 | export interface Bucket { 30 | low: number; 31 | high: number; 32 | } 33 | -------------------------------------------------------------------------------- /src/test/fixtures/extension-yamls/minimal/extension.yaml: -------------------------------------------------------------------------------- 1 | # Learn detailed information about the fields of an extension.yaml file in the docs: 2 | # https://firebase.google.com/docs/extensions/reference/extension-yaml 3 | 4 | # Identifier for your extension 5 | # TODO: Replace this with an descriptive name for your extension. 6 | name: greet-the-world 7 | version: 0.0.1 # Follow semver versioning 8 | specVersion: v1beta # Version of the Firebase Extensions specification 9 | 10 | # Friendly display name for your extension (~3-5 words) 11 | displayName: Greet the world 12 | 13 | # Brief description of the task your extension performs (~1 sentence) 14 | description: >- 15 | Sends the world a greeting. 16 | 17 | license: Apache-2.0 # https://spdx.org/licenses/ 18 | -------------------------------------------------------------------------------- /src/deploy/functions/triggerRegionHelper.ts: -------------------------------------------------------------------------------- 1 | import * as backend from "./backend"; 2 | import { serviceForEndpoint } from "./services"; 3 | 4 | /** 5 | * Ensures the trigger regions are set and correct 6 | * @param want the list of function specs we want to deploy 7 | * @param have the list of function specs we have deployed 8 | */ 9 | export async function ensureTriggerRegions(want: backend.Backend): Promise { 10 | const regionLookups: Array> = []; 11 | 12 | for (const ep of backend.allEndpoints(want)) { 13 | if (ep.platform === "gcfv1" || !backend.isEventTriggered(ep)) { 14 | continue; 15 | } 16 | regionLookups.push(serviceForEndpoint(ep).ensureTriggerRegion(ep)); 17 | } 18 | await Promise.all(regionLookups); 19 | } 20 | -------------------------------------------------------------------------------- /src/types/project/index.d.ts: -------------------------------------------------------------------------------- 1 | export interface CloudProjectInfo { 2 | project: string /* The resource name of the GCP project: "projects/projectId" */; 3 | displayName?: string; 4 | locationId?: string; 5 | } 6 | 7 | export interface ProjectPage { 8 | projects: T[]; 9 | nextPageToken?: string; 10 | } 11 | 12 | export interface FirebaseProjectMetadata { 13 | name: string /* The fully qualified resource name of the Firebase project */; 14 | projectId: string; 15 | projectNumber: string; 16 | displayName?: string; 17 | resources?: DefaultProjectResources; 18 | } 19 | 20 | export interface DefaultProjectResources { 21 | hostingSite?: string; 22 | realtimeDatabaseInstance?: string; 23 | storageBucket?: string; 24 | locationId?: string; 25 | } 26 | -------------------------------------------------------------------------------- /src/archiveDirectory.spec.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from "path"; 2 | import { expect } from "chai"; 3 | import { FirebaseError } from "./error"; 4 | 5 | import { archiveDirectory } from "./archiveDirectory"; 6 | import { FIXTURE_DIR } from "./test/fixtures/config-imports"; 7 | 8 | describe("archiveDirectory", () => { 9 | it("should archive happy little directories", async () => { 10 | const result = await archiveDirectory(FIXTURE_DIR, {}); 11 | expect(result.source).to.equal(FIXTURE_DIR); 12 | expect(result.size).to.be.greaterThan(0); 13 | }); 14 | 15 | it("should throw a happy little error if the directory doesn't exist", async () => { 16 | await expect(archiveDirectory(resolve(__dirname, "foo"), {})).to.be.rejectedWith(FirebaseError); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/mapped-emulator-data/storage_export/metadata/eaa2803e-4374-44bd-98cb-cdd7d31e3347.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test_upload.jpg", 3 | "bucket": "fake-project-id.appspot.com", 4 | "contentType": "application/octet-stream", 5 | "metageneration": 1, 6 | "generation": 1648084940926, 7 | "storageClass": "STANDARD", 8 | "contentDisposition": "inline", 9 | "cacheControl": "public, max-age=3600", 10 | "contentEncoding": "identity", 11 | "downloadTokens": [ 12 | "c3c71086-95a8-445d-96e7-f625972de4b0" 13 | ], 14 | "etag": "PQJQBXRweACX9yRsBEInQjOJ/0s", 15 | "timeCreated": "2022-03-24T01:22:20.926Z", 16 | "updated": "2022-03-24T01:22:20.926Z", 17 | "size": 0, 18 | "md5Hash": "1B2M2Y8AsgTpgAmY7PhCfg==", 19 | "crc32c": "0" 20 | } -------------------------------------------------------------------------------- /src/mcp/util/dataconnect/compile.ts: -------------------------------------------------------------------------------- 1 | import { prettify } from "../../../dataconnect/graphqlError"; 2 | import { DataConnectEmulator } from "../../../emulator/dataconnectEmulator"; 3 | 4 | export async function compileErrors( 5 | configDir: string, 6 | errorFilter?: "all" | "schema" | "operations", 7 | ) { 8 | const errors = (await DataConnectEmulator.build({ configDir })).errors; 9 | return ( 10 | errors 11 | ?.filter((e) => { 12 | const isOperationError = ["query", "mutation"].includes(e.path?.[0] as string); 13 | if (errorFilter === "operations") return isOperationError; 14 | if (errorFilter === "schema") return !isOperationError; 15 | return true; 16 | }) 17 | .map(prettify) 18 | .join("\n") || "" 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /src/test/fixtures/fbrc/index.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from "path"; 2 | 3 | /** 4 | * A directory containing a valid .firebaserc file along firebase.json. 5 | */ 6 | export const VALID_RC_DIR = __dirname; 7 | 8 | /** 9 | * Path of the firebase.json in the `VALID_RC_DIR` directory. 10 | */ 11 | export const FIREBASE_JSON_PATH = resolve(__dirname, "firebase.json"); 12 | 13 | /** 14 | * A directory containing a .firebaserc file containing invalid JSON. 15 | */ 16 | export const INVALID_RC_DIR = resolve(__dirname, "invalid"); 17 | 18 | /** 19 | * A directory containing a .firebaserc file with project alias conflicts. 20 | * 21 | * While it does not contain a firebase.json, its parent directory does. 22 | */ 23 | export const CONFLICT_RC_DIR = resolve(__dirname, "conflict"); 24 | -------------------------------------------------------------------------------- /firebase-vscode/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true /* enable all strict type-checking options */, 4 | "allowJs": true, 5 | "checkJs": false, 6 | "sourceMap": true, 7 | "resolveJsonModule": true, 8 | "allowSyntheticDefaultImports": true, 9 | "jsx": "react", 10 | "outDir": "dist", 11 | "module": "ES2022", 12 | "target": "ES2017", 13 | "lib": ["ES2020", "DOM"], 14 | "moduleResolution": "node", 15 | "rootDirs": ["src", "../src", "common"], 16 | "types": [ 17 | "node", 18 | "@wdio/mocha-framework", 19 | "@wdio/globals/types", 20 | "@types/mocha" 21 | ] 22 | }, 23 | "ts-node": { 24 | "esm": true 25 | }, 26 | "include": ["src/**/*", "common/**/*", "../src/types/**/*"] 27 | } 28 | -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/nested-emulator-data/storage_export/metadata/fake-project-id.appspot.com/test_upload.jpg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test_upload.jpg", 3 | "bucket": "fake-project-id.appspot.com", 4 | "contentType": "application/octet-stream", 5 | "metageneration": 1, 6 | "generation": 1648084940926, 7 | "storageClass": "STANDARD", 8 | "contentDisposition": "inline", 9 | "cacheControl": "public, max-age=3600", 10 | "contentEncoding": "identity", 11 | "downloadTokens": [ 12 | "c3c71086-95a8-445d-96e7-f625972de4b0" 13 | ], 14 | "etag": "PQJQBXRweACX9yRsBEInQjOJ/0s", 15 | "timeCreated": "2022-03-24T01:22:20.926Z", 16 | "updated": "2022-03-24T01:22:20.926Z", 17 | "size": 0, 18 | "md5Hash": "1B2M2Y8AsgTpgAmY7PhCfg==", 19 | "crc32c": "0" 20 | } -------------------------------------------------------------------------------- /scripts/webframeworks-deploy-tests/angular/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # Compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | /bazel-out 8 | 9 | # Node 10 | /node_modules 11 | npm-debug.log 12 | yarn-error.log 13 | 14 | # IDEs and editors 15 | .idea/ 16 | .project 17 | .classpath 18 | .c9/ 19 | *.launch 20 | .settings/ 21 | *.sublime-workspace 22 | 23 | # Visual Studio Code 24 | .vscode/* 25 | !.vscode/settings.json 26 | !.vscode/tasks.json 27 | !.vscode/launch.json 28 | !.vscode/extensions.json 29 | .history/* 30 | 31 | # Miscellaneous 32 | /.angular/cache 33 | .sass-cache/ 34 | /connect.lock 35 | /coverage 36 | /libpeerconnection.log 37 | testem.log 38 | /typings 39 | 40 | # System files 41 | .DS_Store 42 | Thumbs.db 43 | -------------------------------------------------------------------------------- /src/frameworks/nuxt/utils.ts: -------------------------------------------------------------------------------- 1 | import { pathExists } from "fs-extra"; 2 | import { join } from "path"; 3 | import { findDependency } from "../utils"; 4 | 5 | export function getNuxtVersion(cwd: string): string | undefined { 6 | return findDependency("nuxt", { 7 | cwd, 8 | depth: 0, 9 | omitDev: false, 10 | })?.version; 11 | } 12 | 13 | /** 14 | * 15 | * @param dir current app directory 16 | * @return true or false if Nuxt config file was found in the directory 17 | */ 18 | export async function nuxtConfigFilesExist(dir: string): Promise { 19 | const configFilesExist = await Promise.all([ 20 | pathExists(join(dir, "nuxt.config.js")), 21 | pathExists(join(dir, "nuxt.config.ts")), 22 | ]); 23 | 24 | return configFilesExist.some((it) => it); 25 | } 26 | -------------------------------------------------------------------------------- /templates/init/functions/typescript/package.nolint.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions", 3 | "scripts": { 4 | "build": "tsc", 5 | "build:watch": "tsc --watch", 6 | "serve": "npm run build && firebase emulators:start --only functions", 7 | "shell": "npm run build && firebase functions:shell", 8 | "start": "npm run shell", 9 | "deploy": "firebase deploy --only functions", 10 | "logs": "firebase functions:log" 11 | }, 12 | "engines": { 13 | "node": "{{RUNTIME}}" 14 | }, 15 | "main": "lib/index.js", 16 | "dependencies": { 17 | "firebase-admin": "^12.6.0", 18 | "firebase-functions": "^6.0.1" 19 | }, 20 | "devDependencies": { 21 | "typescript": "^5.7.3", 22 | "firebase-functions-test": "^3.1.0" 23 | }, 24 | "private": true 25 | } 26 | -------------------------------------------------------------------------------- /firebase-vscode/src/utils/globals.ts: -------------------------------------------------------------------------------- 1 | // Various utilities to make globals testable. 2 | // This is a workaround. Ideally, we would not use globals at all. 3 | 4 | import { Signal, signal } from "@preact/signals-react"; 5 | 6 | const globals: Array> = []; 7 | 8 | export function resetGlobals() { 9 | globals.forEach((g) => g.reset()); 10 | } 11 | 12 | export interface GlobalSignal extends Signal { 13 | reset(): void; 14 | } 15 | 16 | export function globalSignal(initialData: T): GlobalSignal { 17 | const s: any = signal(initialData); 18 | 19 | s.reset = () => { 20 | s.value = initialData; 21 | }; 22 | 23 | // TODO: Track globals only in test mode 24 | globals.push(s as GlobalSignal); 25 | 26 | return s as GlobalSignal; 27 | } 28 | -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/flattened-emulator-data/storage_export/metadata/fake-project-id.appspot.com%2Ftest_upload.jpg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test_upload.jpg", 3 | "bucket": "fake-project-id.appspot.com", 4 | "contentType": "application/octet-stream", 5 | "metageneration": 1, 6 | "generation": 1648084940926, 7 | "storageClass": "STANDARD", 8 | "contentDisposition": "inline", 9 | "cacheControl": "public, max-age=3600", 10 | "contentEncoding": "identity", 11 | "downloadTokens": [ 12 | "c3c71086-95a8-445d-96e7-f625972de4b0" 13 | ], 14 | "etag": "PQJQBXRweACX9yRsBEInQjOJ/0s", 15 | "timeCreated": "2022-03-24T01:22:20.926Z", 16 | "updated": "2022-03-24T01:22:20.926Z", 17 | "size": 0, 18 | "md5Hash": "1B2M2Y8AsgTpgAmY7PhCfg==", 19 | "crc32c": "0" 20 | } -------------------------------------------------------------------------------- /scripts/storage-emulator-integration/import/windows-emulator-data/storage_export/metadata/fake-project-id.appspot.com%5Ctest_upload.jpg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test_upload.jpg", 3 | "bucket": "fake-project-id.appspot.com", 4 | "contentType": "application/octet-stream", 5 | "metageneration": 1, 6 | "generation": 1648084940926, 7 | "storageClass": "STANDARD", 8 | "contentDisposition": "inline", 9 | "cacheControl": "public, max-age=3600", 10 | "contentEncoding": "identity", 11 | "downloadTokens": [ 12 | "c3c71086-95a8-445d-96e7-f625972de4b0" 13 | ], 14 | "etag": "PQJQBXRweACX9yRsBEInQjOJ/0s", 15 | "timeCreated": "2022-03-24T01:22:20.926Z", 16 | "updated": "2022-03-24T01:22:20.926Z", 17 | "size": 0, 18 | "md5Hash": "1B2M2Y8AsgTpgAmY7PhCfg==", 19 | "crc32c": "0" 20 | } -------------------------------------------------------------------------------- /src/deploy/functions/services/firebaseAlerts.ts: -------------------------------------------------------------------------------- 1 | import * as backend from "../backend"; 2 | import { FirebaseError } from "../../../error"; 3 | 4 | /** 5 | * Sets a Firebase Alerts event trigger's region to 'global' since the service is global 6 | * @param endpoint the storage endpoint 7 | * @param eventTrigger the endpoints event trigger 8 | */ 9 | export function ensureFirebaseAlertsTriggerRegion( 10 | endpoint: backend.Endpoint & backend.EventTriggered, 11 | ): Promise { 12 | if (!endpoint.eventTrigger.region) { 13 | endpoint.eventTrigger.region = "global"; 14 | } 15 | if (endpoint.eventTrigger.region !== "global") { 16 | throw new FirebaseError("A firebase alerts trigger must specify 'global' trigger location"); 17 | } 18 | return Promise.resolve(); 19 | } 20 | -------------------------------------------------------------------------------- /standalone/config.template.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | /* 3 | Headless mode forces the firepit builds to exactly imitate firebase-tools, 4 | so the resulting binary "firebase" is a drop in replacement for the script 5 | installed via npm. This is the behavior for CI / Cloud Shell / Docker etc. 6 | 7 | When headless mode is disabled, the "double click" experience is enabled 8 | which allows the binary to spawn a terminal on Windows and Mac. The is the 9 | behavior for desktop users. 10 | */ 11 | headless: false, 12 | 13 | /* 14 | This is generally set to "firebase-tools@latest" however a custom value 15 | can be supplied for EAPs which would like to have builds pointed at 16 | specific tgz bundles. 17 | */ 18 | firebase_tools_package: "" 19 | }; 20 | -------------------------------------------------------------------------------- /scripts/clean-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | function cleanup() { 5 | echo "Cleaning up artifacts..." 6 | rm -rf ./clean 7 | echo "Artifacts deleted." 8 | } 9 | 10 | trap cleanup EXIT 11 | 12 | rm -rf ./clean || true 13 | echo "Running clean-publish@5.0.0 --without-publish, as we would before publishing to npm..." 14 | npx --yes clean-publish@5.0.0 --without-publish --before-script ./scripts/clean-shrinkwrap.sh --temp-dir clean 15 | echo "Ran clean-publish@5.0.0 --without-publish." 16 | echo "Packaging cleaned firebase-tools..." 17 | cd ./clean 18 | PACKED=$(npm pack --pack-destination ./ | tail -n 1) 19 | echo "Packaged firebase-tools to $PACKED." 20 | echo "Installing clean-packaged firebase-tools..." 21 | npm install -g $PACKED 22 | echo "Installed clean-packaged firebase-tools." 23 | -------------------------------------------------------------------------------- /src/bin/firebase.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // Check for older versions of Node no longer supported by the CLI. 4 | import * as semver from "semver"; 5 | import { isEnabled } from "../experiments"; 6 | const pkg = require("../../package.json"); 7 | const nodeVersion = process.version; 8 | if (!semver.satisfies(nodeVersion, pkg.engines.node)) { 9 | console.error( 10 | `Firebase CLI v${pkg.version} is incompatible with Node.js ${nodeVersion} Please upgrade Node.js to version ${pkg.engines.node}`, 11 | ); 12 | process.exit(1); 13 | } 14 | 15 | // we short-circuit the normal process for MCP 16 | if (isEnabled("mcp") && process.argv[2] === "experimental:mcp") { 17 | const { mcp } = require("./mcp"); 18 | mcp(); 19 | } else { 20 | const { cli } = require("./cli"); 21 | cli(pkg); 22 | } 23 | -------------------------------------------------------------------------------- /src/test/fixtures/zip-files/node-unzipper-testData/compressed-directory-entry/inflated/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Blank PDF Document 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

14 | 15 | 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/mcp.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "🤖 MCP Server" 3 | about: Report bugs or request features for the Firebase MCP Server. 4 | title: "[MCP]" 5 | labels: "api: mcp" 6 | assignees: "" 7 | --- 8 | 9 | 13 | 14 | ## Summary 15 | 16 | 17 | 18 | ## Bug Info 19 | 20 | - **Affected Tool(s):** 21 | - **MCP Client:** 22 | - **Operating System:** 23 | 24 | ### Steps to Reproduce 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/commands/target-remove.ts: -------------------------------------------------------------------------------- 1 | import * as clc from "colorette"; 2 | 3 | import { Command } from "../command"; 4 | import { requireConfig } from "../requireConfig"; 5 | import * as utils from "../utils"; 6 | 7 | export const command = new Command("target:remove ") 8 | .description("remove a resource target") 9 | .before(requireConfig) 10 | .action((type, resource, options) => { 11 | const name = options.rc.removeTarget(options.project, type, resource); 12 | if (name) { 13 | utils.logSuccess(`Removed ${type} target ${clc.bold(name)} from ${clc.bold(resource)}`); 14 | } else { 15 | utils.logWarning( 16 | `No action taken. No target found for ${type} resource ${clc.bold(resource)}`, 17 | ); 18 | } 19 | return Promise.resolve(name); 20 | }); 21 | -------------------------------------------------------------------------------- /src/frameworks/compose/driver/index.ts: -------------------------------------------------------------------------------- 1 | import { Driver } from "../interfaces"; 2 | import { LocalDriver } from "./local"; 3 | import { DockerDriver } from "./docker"; 4 | import { RuntimeSpec } from "../discover/types"; 5 | 6 | export const SUPPORTED_MODES = ["local", "docker"] as const; 7 | export type Mode = (typeof SUPPORTED_MODES)[number]; 8 | 9 | /** 10 | * Returns the driver that provides the execution context for the composer. 11 | */ 12 | export function getDriver(mode: Mode, app: RuntimeSpec): Driver { 13 | if (mode === "local") { 14 | return new LocalDriver(app); 15 | } else if (mode === "docker") { 16 | return new DockerDriver(app); 17 | } 18 | // eslint-disable-next-line @typescript-eslint/restrict-template-expressions 19 | throw new Error(`Unsupported mode ${mode}`); 20 | } 21 | -------------------------------------------------------------------------------- /templates/init/apphosting/apphosting.yaml: -------------------------------------------------------------------------------- 1 | # Settings for Backend (on Cloud Run). 2 | # See https://firebase.google.com/docs/app-hosting/configure#cloud-run 3 | runConfig: 4 | minInstances: 0 5 | # maxInstances: 100 6 | # concurrency: 80 7 | # cpu: 1 8 | # memoryMiB: 512 9 | 10 | # Environment variables and secrets. 11 | # env: 12 | # Configure environment variables. 13 | # See https://firebase.google.com/docs/app-hosting/configure#user-defined-environment 14 | # - variable: MESSAGE 15 | # value: Hello world! 16 | # availability: 17 | # - BUILD 18 | # - RUNTIME 19 | 20 | # Grant access to secrets in Cloud Secret Manager. 21 | # See https://firebase.google.com/docs/app-hosting/configure#secret-parameters 22 | # - variable: MY_SECRET 23 | # secret: mySecretRef 24 | -------------------------------------------------------------------------------- /templates/init/functions/javascript/package.lint.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions", 3 | "description": "Cloud Functions for Firebase", 4 | "scripts": { 5 | "lint": "eslint .", 6 | "serve": "firebase emulators:start --only functions", 7 | "shell": "firebase functions:shell", 8 | "start": "npm run shell", 9 | "deploy": "firebase deploy --only functions", 10 | "logs": "firebase functions:log" 11 | }, 12 | "engines": { 13 | "node": "{{RUNTIME}}" 14 | }, 15 | "main": "index.js", 16 | "dependencies": { 17 | "firebase-admin": "^12.6.0", 18 | "firebase-functions": "^6.0.1" 19 | }, 20 | "devDependencies": { 21 | "eslint": "^8.15.0", 22 | "eslint-config-google": "^0.14.0", 23 | "firebase-functions-test": "^3.1.0" 24 | }, 25 | "private": true 26 | } 27 | -------------------------------------------------------------------------------- /firebase-vscode/webviews/components/ui/IconButton.tsx: -------------------------------------------------------------------------------- 1 | import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"; 2 | import React, { HTMLAttributes, PropsWithChildren } from "react"; 3 | import { Icon, IconName } from "./Icon"; 4 | 5 | type TextProps = PropsWithChildren< 6 | T & 7 | HTMLAttributes & { 8 | icon: IconName; 9 | tooltip: string; 10 | } 11 | >; 12 | 13 | export const IconButton: React.FC> = ({ 14 | icon, 15 | tooltip, 16 | className, 17 | ...props 18 | }) => { 19 | return ( 20 | 27 | 28 | 29 | ); 30 | }; 31 | --------------------------------------------------------------------------------