From 9c0ca9718bafa6010432f4c0e1b81717b91c80b9 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 23:19:43 +0000 Subject: [PATCH] feat: Add global dataDir for emulator persistence Implements a global `emulators.dataDir` setting in `firebase.json` to allow users to easily persist and re-load emulator data across sessions. Key changes: - Added `emulators.dataDir` to `firebase.json` schema. - Updated `firebase init emulators` to prompt for `dataDir` configuration. - Added `--ephemeral` flag to `emulators:start` and `emulators:exec` to ignore `dataDir` for a single run. - Emulators now automatically import data from `dataDir` on startup if it exists and contains valid export metadata. - Emulators now automatically export data to `dataDir` on clean shutdown if `dataDir` is configured (and not overridden by `--export-on-exit` flag). - Handled deprecation of `emulators.dataconnect.dataDir`, preferring the global `emulators.dataDir` with warnings. - Added unit tests for the new functionality. --- npm-shrinkwrap.json | 1 + schema/firebase-config.json | 3 + src/command.ts | 15 ++++ src/commands/emulators-exec.ts | 1 + src/commands/emulators-start.ts | 1 + src/config.spec.ts | 48 +++++++++- src/config.ts | 30 +++++++ src/emulator/commandUtils.spec.ts | 48 ++++++++++ src/emulator/commandUtils.ts | 6 ++ src/emulator/controller.spec.ts | 130 +++++++++++++++++++++++++++- src/emulator/controller.ts | 66 ++++++++++++-- src/firebaseConfig.ts | 1 + src/init/features/emulators.spec.ts | 70 +++++++++++++++ src/init/features/emulators.ts | 16 ++++ 14 files changed, 427 insertions(+), 9 deletions(-) create mode 100644 src/init/features/emulators.spec.ts diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 36b7394c2c9..9314ea3bdd0 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -20508,6 +20508,7 @@ "resolved": "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.65.1.tgz", "integrity": "sha512-tuGH7ff2jPaUYi6as3lHyHcKpSmXIqN7/mu50x3HlYn0EHzLpmt3nplZ7EuhUkO0eqDRc9GqWNkfjgBPIS9kxg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@types/json-schema": "^7.0.9", "@types/node": "^18.11.9", diff --git a/schema/firebase-config.json b/schema/firebase-config.json index 546d045af00..2e1bdc141e1 100644 --- a/schema/firebase-config.json +++ b/schema/firebase-config.json @@ -1194,6 +1194,9 @@ }, "type": "object" }, + "dataDir": { + "type": "string" + }, "database": { "additionalProperties": false, "properties": { diff --git a/src/command.ts b/src/command.ts index 325654c7953..221822e261c 100644 --- a/src/command.ts +++ b/src/command.ts @@ -89,6 +89,21 @@ export class Command { return this; } + // TODO: refactor this to be a private method and ensure all commands that need it call it. + // TODO: add a test for this. + /** + * Adds the --ephemeral flag to the command. + * @return The command, for chaining. + */ + withEphemeral(): Command { + this.option( + "--ephemeral", + "ignore emulators.dataDir and start with a clean state", + false, // Default value if the flag is not present + ); + return this; + } + /** * Sets up --force flag for the command. * diff --git a/src/commands/emulators-exec.ts b/src/commands/emulators-exec.ts index dadd455bd3a..e11ca60930f 100644 --- a/src/commands/emulators-exec.ts +++ b/src/commands/emulators-exec.ts @@ -8,6 +8,7 @@ export const command = new Command("emulators:exec