firebase-tools 14.2.1 → 14.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/lib/api.js +4 -2
  2. package/lib/apphosting/backend.js +12 -23
  3. package/lib/apphosting/config.js +9 -20
  4. package/lib/apphosting/githubConnections.js +52 -80
  5. package/lib/apphosting/repo.js +22 -36
  6. package/lib/apphosting/secrets/dialogs.js +2 -3
  7. package/lib/apphosting/utils.js +1 -3
  8. package/lib/auth.js +1 -4
  9. package/lib/bin/cli.js +131 -0
  10. package/lib/bin/firebase.js +7 -123
  11. package/lib/bin/mcp.js +38 -0
  12. package/lib/commands/apphosting-backends-delete.js +5 -5
  13. package/lib/commands/apphosting-secrets-set.js +2 -6
  14. package/lib/commands/apps-create.js +2 -3
  15. package/lib/commands/apps-sdkconfig.js +2 -7
  16. package/lib/commands/database-import.js +4 -6
  17. package/lib/commands/database-remove.js +4 -6
  18. package/lib/commands/database-set.js +6 -6
  19. package/lib/commands/database-update.js +5 -5
  20. package/lib/commands/dataconnect-sql-shell.js +4 -6
  21. package/lib/commands/ext-dev-deprecate.js +1 -0
  22. package/lib/commands/ext-dev-init.js +3 -12
  23. package/lib/commands/ext-dev-register.js +2 -4
  24. package/lib/commands/ext-dev-undeprecate.js +1 -2
  25. package/lib/commands/ext-dev-usage.js +1 -3
  26. package/lib/commands/ext-export.js +1 -2
  27. package/lib/commands/ext-install.js +1 -0
  28. package/lib/commands/ext-sdk-install.js +1 -0
  29. package/lib/commands/ext-update.js +1 -0
  30. package/lib/commands/firestore-backups-delete.js +1 -2
  31. package/lib/commands/firestore-backups-schedules-delete.js +1 -2
  32. package/lib/commands/firestore-databases-delete.js +1 -5
  33. package/lib/commands/firestore-delete.js +6 -6
  34. package/lib/commands/functions-artifacts-setpolicy.js +12 -2
  35. package/lib/commands/functions-config-export.js +5 -9
  36. package/lib/commands/functions-delete.js +5 -5
  37. package/lib/commands/functions-deletegcfartifacts.js +4 -4
  38. package/lib/commands/functions-secrets-destroy.js +8 -10
  39. package/lib/commands/functions-secrets-prune.js +12 -13
  40. package/lib/commands/functions-secrets-set.js +11 -15
  41. package/lib/commands/hosting-channel-create.js +1 -2
  42. package/lib/commands/hosting-channel-delete.js +4 -4
  43. package/lib/commands/hosting-channel-open.js +2 -3
  44. package/lib/commands/hosting-disable.js +5 -5
  45. package/lib/commands/hosting-sites-delete.js +4 -4
  46. package/lib/commands/index.js +3 -0
  47. package/lib/commands/init.js +41 -58
  48. package/lib/commands/login.js +1 -5
  49. package/lib/commands/logout.js +2 -3
  50. package/lib/commands/mcp.js +11 -0
  51. package/lib/commands/open.js +1 -2
  52. package/lib/commands/projects-create.js +1 -2
  53. package/lib/commands/remoteconfig-rollback.js +5 -5
  54. package/lib/commands/use.js +110 -110
  55. package/lib/config.js +1 -2
  56. package/lib/dataconnect/build.js +2 -4
  57. package/lib/dataconnect/client.js +20 -1
  58. package/lib/dataconnect/schemaMigration.js +1 -6
  59. package/lib/deploy/functions/params.js +10 -17
  60. package/lib/deploy/functions/prompts.js +6 -28
  61. package/lib/emulator/commandUtils.js +12 -19
  62. package/lib/emulator/controller.js +1 -2
  63. package/lib/emulator/downloadableEmulators.js +12 -12
  64. package/lib/emulator/env.js +19 -20
  65. package/lib/emulator/functionsEmulator.js +0 -1
  66. package/lib/emulator/hub.js +2 -1
  67. package/lib/emulator/initEmulators.js +9 -20
  68. package/lib/emulator/ui.js +0 -2
  69. package/lib/experiments.js +5 -0
  70. package/lib/extensions/askUserForEventsConfig.js +6 -15
  71. package/lib/extensions/askUserForParam.js +23 -52
  72. package/lib/extensions/checkProjectBilling.js +3 -9
  73. package/lib/extensions/diagnose.js +3 -6
  74. package/lib/extensions/extensionsHelper.js +17 -27
  75. package/lib/extensions/manifest.js +1 -2
  76. package/lib/extensions/tos.js +10 -2
  77. package/lib/extensions/utils.js +1 -10
  78. package/lib/frameworks/index.js +5 -3
  79. package/lib/frameworks/next/index.js +7 -4
  80. package/lib/frameworks/vite/index.js +1 -2
  81. package/lib/functions/secrets.js +14 -15
  82. package/lib/gcp/auth.js +84 -1
  83. package/lib/gcp/firestore.js +12 -1
  84. package/lib/gif/fdcExperience.js +45 -0
  85. package/lib/hosting/api.js +4 -0
  86. package/lib/hosting/interactive.js +2 -3
  87. package/lib/init/features/account.js +2 -4
  88. package/lib/init/features/database.js +11 -20
  89. package/lib/init/features/dataconnect/index.js +7 -14
  90. package/lib/init/features/dataconnect/sdk.js +14 -19
  91. package/lib/init/features/emulators.js +19 -41
  92. package/lib/init/features/firestore/index.js +2 -6
  93. package/lib/init/features/firestore/indexes.js +17 -31
  94. package/lib/init/features/firestore/rules.js +17 -31
  95. package/lib/init/features/functions/index.js +9 -16
  96. package/lib/init/features/functions/javascript.js +16 -30
  97. package/lib/init/features/functions/npm-dependencies.js +4 -8
  98. package/lib/init/features/functions/python.js +1 -3
  99. package/lib/init/features/functions/typescript.js +24 -43
  100. package/lib/init/features/genkit/index.js +23 -38
  101. package/lib/init/features/hosting/github.js +20 -51
  102. package/lib/init/features/hosting/index.js +36 -57
  103. package/lib/init/features/project.js +6 -16
  104. package/lib/init/features/remoteconfig.js +2 -8
  105. package/lib/init/features/storage.js +1 -3
  106. package/lib/logger.js +11 -2
  107. package/lib/management/apps.js +19 -44
  108. package/lib/management/projects.js +17 -28
  109. package/lib/mcp/errors.js +15 -0
  110. package/lib/mcp/index.js +120 -0
  111. package/lib/mcp/tool.js +11 -0
  112. package/lib/mcp/tools/auth/disable_auth_user.js +30 -0
  113. package/lib/mcp/tools/auth/get_auth_user.js +29 -0
  114. package/lib/mcp/tools/auth/index.js +13 -0
  115. package/lib/mcp/tools/auth/set_auth_claims.js +34 -0
  116. package/lib/mcp/tools/auth/set_sms_region_policy.js +36 -0
  117. package/lib/mcp/tools/core/consult_firebase_assistant.js +27 -0
  118. package/lib/mcp/tools/core/get_firebase_directory.js +20 -0
  119. package/lib/mcp/tools/core/index.js +11 -0
  120. package/lib/mcp/tools/core/set_firebase_directory.js +33 -0
  121. package/lib/mcp/tools/dataconnect/converter.js +33 -0
  122. package/lib/mcp/tools/dataconnect/generate_dataconnect_operation.js +33 -0
  123. package/lib/mcp/tools/dataconnect/generate_dataconnect_schema.js +25 -0
  124. package/lib/mcp/tools/dataconnect/get_dataconnect_connector.js +31 -0
  125. package/lib/mcp/tools/dataconnect/get_dataconnect_schema.js +31 -0
  126. package/lib/mcp/tools/dataconnect/index.js +15 -0
  127. package/lib/mcp/tools/dataconnect/list_dataconnect_services.js +23 -0
  128. package/lib/mcp/tools/firestore/converter.js +57 -0
  129. package/lib/mcp/tools/firestore/get_firestore_documents.js +48 -0
  130. package/lib/mcp/tools/firestore/get_firestore_rules.js +26 -0
  131. package/lib/mcp/tools/firestore/index.js +11 -0
  132. package/lib/mcp/tools/firestore/list_firestore_collections.js +30 -0
  133. package/lib/mcp/tools/index.js +15 -0
  134. package/lib/mcp/tools/project/get_project.js +22 -0
  135. package/lib/mcp/tools/project/get_sdk_config.js +38 -0
  136. package/lib/mcp/tools/project/index.js +7 -0
  137. package/lib/mcp/tools/project/list_apps.js +29 -0
  138. package/lib/mcp/tools/storage/get_storage_rules.js +26 -0
  139. package/lib/mcp/tools/storage/index.js +5 -0
  140. package/lib/mcp/types.js +4 -0
  141. package/lib/mcp/util.js +52 -0
  142. package/lib/prompt.js +78 -65
  143. package/lib/requireTosAcceptance.js +4 -0
  144. package/lib/rulesDeploy.js +10 -15
  145. package/lib/track.js +1 -34
  146. package/lib/utils.js +27 -5
  147. package/package.json +6 -4
  148. package/templates/init/dataconnect/connector.yaml +3 -0
@@ -27,12 +27,12 @@ exports.command = new command_1.Command("functions:deletegcfartifacts")
27
27
  const dockerHelper = {};
28
28
  try {
29
29
  const gcfPaths = await (0, containerCleaner_1.listGcfPaths)(projectId, regions, dockerHelper);
30
- const confirmDeletion = await (0, prompt_1.promptOnce)({
31
- type: "confirm",
32
- name: "force",
30
+ const confirmDeletion = await (0, prompt_1.confirm)({
33
31
  default: false,
34
32
  message: getConfirmationMessage(gcfPaths),
35
- }, options);
33
+ force: options.force,
34
+ nonInteractive: options.nonInteractive,
35
+ });
36
36
  if (!confirmDeletion) {
37
37
  throw new error_1.FirebaseError("Command aborted.", { exit: 1 });
38
38
  }
@@ -40,16 +40,14 @@ exports.command = new command_1.Command("functions:secrets:destroy <KEY>[@versio
40
40
  return;
41
41
  }
42
42
  }
43
- if (!options.force) {
44
- const confirm = await (0, prompt_1.promptOnce)({
45
- name: "destroy",
46
- type: "confirm",
47
- default: true,
48
- message: `Are you sure you want to destroy ${sv.secret.name}@${sv.versionId}`,
49
- }, options);
50
- if (!confirm) {
51
- return;
52
- }
43
+ const areYouSure = await (0, prompt_1.confirm)({
44
+ message: `Are you sure you want to destroy ${sv.secret.name}@${sv.versionId}`,
45
+ default: true,
46
+ nonInteractive: options.nonInteractive,
47
+ force: options.force,
48
+ });
49
+ if (!areYouSure) {
50
+ return;
53
51
  }
54
52
  await (0, secretManager_1.destroySecretVersion)(projectId, name, version);
55
53
  (0, utils_1.logBullet)(`Destroyed secret version ${name}@${sv.versionId}`);
@@ -38,20 +38,19 @@ exports.command = new command_1.Command("functions:secrets:prune")
38
38
  }
39
39
  (0, utils_1.logBullet)(`Found ${pruned.length} unused active secret versions:\n\t` +
40
40
  pruned.map((sv) => `${sv.secret}@${sv.version}`).join("\n\t"));
41
- if (!options.force) {
42
- const confirm = await (0, prompt_1.promptOnce)({
43
- name: "destroy",
44
- type: "confirm",
45
- default: true,
41
+ const confirmed = options.destroy ||
42
+ (await (0, prompt_1.confirm)({
46
43
  message: `Do you want to destroy unused secret versions?`,
47
- }, options);
48
- if (!confirm) {
49
- (0, utils_1.logBullet)("Run the following commands to destroy each unused secret version:\n\t" +
50
- pruned
51
- .map((sv) => `firebase functions:secrets:destroy ${sv.secret}@${sv.version}`)
52
- .join("\n\t"));
53
- return;
54
- }
44
+ default: true,
45
+ force: options.force,
46
+ nonInteractive: options.nonInteractive,
47
+ }));
48
+ if (!confirmed) {
49
+ (0, utils_1.logBullet)("Run the following commands to destroy each unused secret version:\n\t" +
50
+ pruned
51
+ .map((sv) => `firebase functions:secrets:destroy ${sv.secret}@${sv.version}`)
52
+ .join("\n\t"));
53
+ return;
55
54
  }
56
55
  await Promise.all(pruned.map((sv) => (0, secretManager_1.destroySecretVersion)(projectId, sv.secret, sv.version)));
57
56
  (0, utils_1.logSuccess)("Destroyed all unused secrets!");
@@ -53,21 +53,17 @@ exports.command = new command_1.Command("functions:secrets:set <KEY>")
53
53
  }
54
54
  (0, utils_1.logBullet)(`${endpointsToUpdate.length} functions are using stale version of secret ${secret.name}:\n\t` +
55
55
  endpointsToUpdate.map((e) => `${e.id}(${e.region})`).join("\n\t"));
56
- if (!options.force) {
57
- let confirm = false;
58
- if (!options.nonInteractive) {
59
- confirm = await (0, prompt_1.promptOnce)({
60
- name: "redeploy",
61
- type: "confirm",
62
- default: true,
63
- message: `Do you want to re-deploy the functions and destroy the stale version of secret ${secret.name}?`,
64
- }, options);
65
- }
66
- if (!confirm) {
67
- (0, utils_1.logBullet)("Please deploy your functions for the change to take effect by running:\n\t" +
68
- clc.bold("firebase deploy --only functions"));
69
- return;
70
- }
56
+ const redeploy = options.nonInteractive
57
+ ? false
58
+ : await (0, prompt_1.confirm)({
59
+ message: `Do you want to re-deploy the functions and destroy the stale version of secret ${secret.name}?`,
60
+ default: true,
61
+ force: options.force,
62
+ });
63
+ if (!redeploy) {
64
+ (0, utils_1.logBullet)("Please deploy your functions for the change to take effect by running:\n\t" +
65
+ clc.bold("firebase deploy --only functions"));
66
+ return;
71
67
  }
72
68
  const updateOps = endpointsToUpdate.map(async (e) => {
73
69
  (0, utils_1.logBullet)(`Updating function ${e.id}(${e.region})...`);
@@ -45,8 +45,7 @@ exports.command = new command_1.Command("hosting:channel:create [channelId]")
45
45
  }
46
46
  channelId =
47
47
  channelId ||
48
- (await (0, prompt_1.promptOnce)({
49
- type: "input",
48
+ (await (0, prompt_1.input)({
50
49
  message: "Please provide a URL-friendly name for the channel:",
51
50
  validate: (s) => s.length > 0,
52
51
  }));
@@ -24,12 +24,12 @@ exports.command = new command_1.Command("hosting:channel:delete <channelId>")
24
24
  const siteId = options.site;
25
25
  channelId = (0, api_1.normalizeName)(channelId);
26
26
  const channel = await (0, api_1.getChannel)(projectId, siteId, channelId);
27
- const confirmed = await (0, prompt_1.promptOnce)({
28
- name: "force",
29
- type: "confirm",
27
+ const confirmed = await (0, prompt_1.confirm)({
30
28
  message: `Are you sure you want to delete the Hosting Channel ${(0, colorette_1.underline)(channelId)} for site ${(0, colorette_1.underline)(siteId)}?`,
31
29
  default: false,
32
- }, options);
30
+ force: options.force,
31
+ nonInteractive: options.nonInteractive,
32
+ });
33
33
  if (!confirmed) {
34
34
  return;
35
35
  }
@@ -11,8 +11,8 @@ const requirePermissions_1 = require("../requirePermissions");
11
11
  const projectUtils_1 = require("../projectUtils");
12
12
  const requireConfig_1 = require("../requireConfig");
13
13
  const utils_1 = require("../utils");
14
- const prompt_1 = require("../prompt");
15
14
  const requireHostingSite_1 = require("../requireHostingSite");
15
+ const prompt_1 = require("../prompt");
16
16
  exports.command = new command_1.Command("hosting:channel:open [channelId]")
17
17
  .description("opens the URL for a Firebase Hosting channel")
18
18
  .help("if unable to open the URL in a browser, it will be displayed in the output")
@@ -29,8 +29,7 @@ exports.command = new command_1.Command("hosting:channel:open [channelId]")
29
29
  }
30
30
  const channels = await (0, api_1.listChannels)(projectId, siteId);
31
31
  (0, lodash_1.sortBy)(channels, ["name"]);
32
- channelId = await (0, prompt_1.promptOnce)({
33
- type: "list",
32
+ channelId = await (0, prompt_1.select)({
34
33
  message: "Which channel would you like to open?",
35
34
  choices: channels.map((c) => (0, lodash_1.last)(c.name.split("/")) || c.name),
36
35
  });
@@ -17,12 +17,12 @@ exports.command = new command_1.Command("hosting:disable")
17
17
  .before(requireHostingSite_1.requireHostingSite)
18
18
  .action(async (options) => {
19
19
  const siteToDisable = options.site;
20
- const confirm = await (0, prompt_1.promptOnce)({
21
- type: "confirm",
22
- name: "force",
20
+ const confirmed = await (0, prompt_1.confirm)({
23
21
  message: `Are you sure you want to disable Firebase Hosting for the site ${clc.underline(siteToDisable)}\n${clc.underline("This will immediately make your site inaccessible!")}`,
24
- }, options);
25
- if (!confirm) {
22
+ force: options.force,
23
+ nonInteractive: options.nonInteractive,
24
+ });
25
+ if (!confirmed) {
26
26
  return;
27
27
  }
28
28
  const c = new apiv2_1.Client({ urlPrefix: (0, api_1.hostingApiOrigin)(), apiVersion: "v1beta1", auth: true });
@@ -24,12 +24,12 @@ exports.command = new command_1.Command("hosting:sites:delete <siteId>")
24
24
  }
25
25
  logger_1.logger.info(`Deleting a site is a permanent action. If you delete a site, Firebase doesn't maintain records of deployed files or deployment history, and the site ${(0, colorette_1.underline)(siteId)} cannot be reactivated by you or anyone else.`);
26
26
  logger_1.logger.info();
27
- const confirmed = await (0, prompt_1.promptOnce)({
28
- name: "force",
29
- type: "confirm",
27
+ const confirmed = await (0, prompt_1.confirm)({
30
28
  message: `Are you sure you want to delete the Hosting site ${(0, colorette_1.underline)(siteId)} for project ${(0, colorette_1.underline)(projectId)}? `,
31
29
  default: false,
32
- }, options);
30
+ force: options.force,
31
+ nonInteractive: options.nonInteractive,
32
+ });
33
33
  if (!confirmed) {
34
34
  return;
35
35
  }
@@ -190,6 +190,9 @@ function load(client) {
190
190
  client.login.list = loadCommand("login-list");
191
191
  client.login.use = loadCommand("login-use");
192
192
  client.logout = loadCommand("logout");
193
+ if (experiments.isEnabled("mcp")) {
194
+ client.mcp = loadCommand("mcp");
195
+ }
193
196
  client.open = loadCommand("open");
194
197
  client.projects = {};
195
198
  client.projects.addfirebase = loadCommand("projects-addfirebase");
@@ -15,6 +15,7 @@ const fsutils = require("../fsutils");
15
15
  const utils = require("../utils");
16
16
  const experiments_1 = require("../experiments");
17
17
  const templates_1 = require("../templates");
18
+ const error_1 = require("../error");
18
19
  const homeDir = os.homedir();
19
20
  const BANNER_TEXT = (0, templates_1.readTemplateSync)("banner.txt");
20
21
  const GITIGNORE_TEMPLATE = (0, templates_1.readTemplateSync)("_gitignore");
@@ -112,7 +113,8 @@ exports.command = new command_1.Command("init [feature]")
112
113
  .help(HELP)
113
114
  .before(requireAuth_1.requireAuth)
114
115
  .action(initAction);
115
- function initAction(feature, options) {
116
+ async function initAction(feature, options) {
117
+ var _a;
116
118
  if (feature && !featureNames.includes(feature)) {
117
119
  return utils.reject(clc.bold(feature) +
118
120
  " is not a supported feature; must be one of " +
@@ -152,66 +154,47 @@ function initAction(feature, options) {
152
154
  fallback: {},
153
155
  }),
154
156
  };
155
- let next;
156
157
  if (process.platform === "win32") {
157
- next = (0, prompt_1.promptOnce)({
158
- type: "confirm",
159
- message: "Are you ready to proceed?",
160
- });
158
+ if (!(await (0, prompt_1.confirm)("Are you ready to proceed?"))) {
159
+ throw new error_1.FirebaseError("Aborted by user.", { exit: 1 });
160
+ }
161
+ }
162
+ if (feature) {
163
+ setup.featureArg = true;
164
+ setup.features = [feature];
161
165
  }
162
166
  else {
163
- next = Promise.resolve(true);
167
+ setup.features = await (0, prompt_1.checkbox)({
168
+ message: "Which Firebase features do you want to set up for this directory? " +
169
+ "Press Space to select features, then Enter to confirm your choices.",
170
+ choices: choices.filter((c) => !c.hidden),
171
+ });
164
172
  }
165
- return next
166
- .then((proceed) => {
167
- if (!proceed) {
168
- return utils.reject("Aborted by user.", { exit: 1 });
169
- }
170
- if (feature) {
171
- setup.featureArg = true;
172
- setup.features = [feature];
173
- return undefined;
174
- }
175
- return (0, prompt_1.prompt)(setup, [
176
- {
177
- type: "checkbox",
178
- name: "features",
179
- message: "Which Firebase features do you want to set up for this directory? " +
180
- "Press Space to select features, then Enter to confirm your choices.",
181
- choices: choices.filter((c) => !c.hidden),
182
- },
183
- ]);
184
- })
185
- .then(() => {
186
- var _a;
187
- if (!setup.features || ((_a = setup.features) === null || _a === void 0 ? void 0 : _a.length) === 0) {
188
- return utils.reject("Must select at least one feature. Use " +
189
- clc.bold(clc.underline("SPACEBAR")) +
190
- " to select features, or specify a feature by running " +
191
- clc.bold("firebase init [feature_name]"));
192
- }
193
- setup.features.unshift("project");
194
- const allAccounts = (0, auth_1.getAllAccounts)();
195
- if (allAccounts.length > 1) {
196
- setup.features.unshift("account");
197
- }
198
- if (setup.features.includes("hosting") && setup.features.includes("hosting:github")) {
199
- setup.features = setup.features.filter((f) => f !== "hosting:github");
200
- }
201
- return (0, init_1.init)(setup, config, options);
202
- })
203
- .then(() => {
204
- logger_1.logger.info();
205
- utils.logBullet("Writing configuration info to " + clc.bold("firebase.json") + "...");
206
- config.writeProjectFile("firebase.json", setup.config);
207
- utils.logBullet("Writing project information to " + clc.bold(".firebaserc") + "...");
208
- config.writeProjectFile(".firebaserc", setup.rcfile);
209
- if (!fsutils.fileExistsSync(config.path(".gitignore"))) {
210
- utils.logBullet("Writing gitignore file to " + clc.bold(".gitignore") + "...");
211
- config.writeProjectFile(".gitignore", GITIGNORE_TEMPLATE);
212
- }
213
- logger_1.logger.info();
214
- utils.logSuccess("Firebase initialization complete!");
215
- });
173
+ if (!setup.features || ((_a = setup.features) === null || _a === void 0 ? void 0 : _a.length) === 0) {
174
+ throw new error_1.FirebaseError("Must select at least one feature. Use " +
175
+ clc.bold(clc.underline("SPACEBAR")) +
176
+ " to select features, or specify a feature by running " +
177
+ clc.bold("firebase init [feature_name]"));
178
+ }
179
+ setup.features.unshift("project");
180
+ const allAccounts = (0, auth_1.getAllAccounts)();
181
+ if (allAccounts.length > 1) {
182
+ setup.features.unshift("account");
183
+ }
184
+ if (setup.features.includes("hosting") && setup.features.includes("hosting:github")) {
185
+ setup.features = setup.features.filter((f) => f !== "hosting:github");
186
+ }
187
+ await (0, init_1.init)(setup, config, options);
188
+ logger_1.logger.info();
189
+ utils.logBullet("Writing configuration info to " + clc.bold("firebase.json") + "...");
190
+ config.writeProjectFile("firebase.json", setup.config);
191
+ utils.logBullet("Writing project information to " + clc.bold(".firebaserc") + "...");
192
+ config.writeProjectFile(".firebaserc", setup.rcfile);
193
+ if (!fsutils.fileExistsSync(config.path(".gitignore"))) {
194
+ utils.logBullet("Writing gitignore file to " + clc.bold(".gitignore") + "...");
195
+ config.writeProjectFile(".gitignore", GITIGNORE_TEMPLATE);
196
+ }
197
+ logger_1.logger.info();
198
+ utils.logSuccess("Firebase initialization complete!");
216
199
  }
217
200
  exports.initAction = initAction;
@@ -28,11 +28,7 @@ exports.command = new command_1.Command("login")
28
28
  }
29
29
  if (!options.reauth) {
30
30
  utils.logBullet("Firebase optionally collects CLI and Emulator Suite usage and error reporting information to help improve our products. Data is collected in accordance with Google's privacy policy (https://policies.google.com/privacy) and is not used to identify you.\n");
31
- const collectUsage = await (0, prompt_1.promptOnce)({
32
- type: "confirm",
33
- name: "collectUsage",
34
- message: "Allow Firebase to collect CLI and Emulator Suite usage and error reporting information?",
35
- });
31
+ const collectUsage = await (0, prompt_1.confirm)("Allow Firebase to collect CLI and Emulator Suite usage and error reporting information?");
36
32
  configstore_1.configstore.set("usage", collectUsage);
37
33
  if (collectUsage) {
38
34
  utils.logBullet("To change your data collection preference at any time, run `firebase logout` and log in again.");
@@ -5,8 +5,8 @@ const command_1 = require("../command");
5
5
  const logger_1 = require("../logger");
6
6
  const clc = require("colorette");
7
7
  const utils = require("../utils");
8
- const prompt_1 = require("../prompt");
9
8
  const auth_1 = require("../auth");
9
+ const prompt_1 = require("../prompt");
10
10
  exports.command = new command_1.Command("logout [email]")
11
11
  .description("log the CLI out of Firebase")
12
12
  .action(logoutAction);
@@ -38,8 +38,7 @@ async function logoutAction(email, options) {
38
38
  value: a,
39
39
  };
40
40
  });
41
- newDefaultAccount = await (0, prompt_1.promptOnce)({
42
- type: "list",
41
+ newDefaultAccount = await (0, prompt_1.select)({
43
42
  message: "You are logging out of your default account, which account should become the new default?",
44
43
  choices,
45
44
  });
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.command = void 0;
4
+ const command_1 = require("../command");
5
+ const requireAuth_1 = require("../requireAuth");
6
+ exports.command = new command_1.Command("experimental:mcp")
7
+ .description("Start an MCP server with access to the current working directory's project and resources.")
8
+ .before(requireAuth_1.requireAuth)
9
+ .action(() => {
10
+ throw new Error("MCP logic is implemented elsewhere, this should never be reached.");
11
+ });
@@ -67,8 +67,7 @@ exports.command = new command_1.Command("open [link]")
67
67
  throw new error_1.FirebaseError("Unrecognized link name. Valid links are:\n\n" + LINKS.map((l) => l.arg).join("\n"));
68
68
  }
69
69
  if (!link) {
70
- const name = await (0, prompt_1.promptOnce)({
71
- type: "list",
70
+ const name = await (0, prompt_1.select)({
72
71
  message: "What link would you like to open?",
73
72
  choices: CHOICES,
74
73
  });
@@ -4,7 +4,6 @@ exports.command = void 0;
4
4
  const command_1 = require("../command");
5
5
  const error_1 = require("../error");
6
6
  const projects_1 = require("../management/projects");
7
- const prompt_1 = require("../prompt");
8
7
  const requireAuth_1 = require("../requireAuth");
9
8
  exports.command = new command_1.Command("projects:create [projectId]")
10
9
  .description("creates a new Google Cloud Platform project, then adds Firebase resources to the project")
@@ -18,7 +17,7 @@ exports.command = new command_1.Command("projects:create [projectId]")
18
17
  throw new error_1.FirebaseError("Invalid argument, please provide only one type of project parent (organization or folder)");
19
18
  }
20
19
  if (!options.nonInteractive) {
21
- await (0, prompt_1.prompt)(options, projects_1.PROJECTS_CREATE_QUESTIONS);
20
+ options = Object.assign(Object.assign({}, options), (await (0, projects_1.promptProjectCreation)()));
22
21
  }
23
22
  if (!options.projectId) {
24
23
  throw new error_1.FirebaseError("Project ID cannot be empty");
@@ -35,13 +35,13 @@ exports.command = new command_1.Command("remoteconfig:rollback")
35
35
  `. ` +
36
36
  `Invalid Version Number`);
37
37
  }
38
- const confirm = await (0, prompt_1.promptOnce)({
39
- type: "confirm",
40
- name: "force",
38
+ const proceed = await (0, prompt_1.confirm)({
41
39
  message: "Proceed to rollback template to version " + targetVersion + "?",
42
40
  default: false,
43
- }, options);
44
- if (!confirm) {
41
+ force: options.force,
42
+ nonInteractive: options.nonInteractive,
43
+ });
44
+ if (!proceed) {
45
45
  return;
46
46
  }
47
47
  return (0, rollback_1.rollbackTemplate)((0, projectUtils_1.needProjectId)(options), targetVersion);