firebase-tools 14.2.2 → 14.3.1

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 (139) 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 +65 -99
  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/commands/apphosting-backends-delete.js +5 -5
  10. package/lib/commands/apphosting-secrets-set.js +2 -6
  11. package/lib/commands/apps-create.js +2 -3
  12. package/lib/commands/apps-sdkconfig.js +2 -7
  13. package/lib/commands/database-import.js +4 -6
  14. package/lib/commands/database-remove.js +4 -6
  15. package/lib/commands/database-set.js +6 -6
  16. package/lib/commands/database-update.js +5 -5
  17. package/lib/commands/dataconnect-sql-shell.js +4 -6
  18. package/lib/commands/ext-dev-deprecate.js +1 -0
  19. package/lib/commands/ext-dev-init.js +3 -12
  20. package/lib/commands/ext-dev-register.js +2 -4
  21. package/lib/commands/ext-dev-undeprecate.js +1 -2
  22. package/lib/commands/ext-dev-usage.js +1 -3
  23. package/lib/commands/ext-export.js +1 -2
  24. package/lib/commands/ext-install.js +1 -0
  25. package/lib/commands/ext-sdk-install.js +1 -0
  26. package/lib/commands/ext-update.js +1 -0
  27. package/lib/commands/firestore-backups-delete.js +1 -2
  28. package/lib/commands/firestore-backups-schedules-delete.js +1 -2
  29. package/lib/commands/firestore-databases-delete.js +1 -5
  30. package/lib/commands/firestore-delete.js +6 -6
  31. package/lib/commands/functions-artifacts-setpolicy.js +12 -2
  32. package/lib/commands/functions-config-export.js +5 -9
  33. package/lib/commands/functions-delete.js +5 -5
  34. package/lib/commands/functions-deletegcfartifacts.js +4 -4
  35. package/lib/commands/functions-secrets-destroy.js +8 -10
  36. package/lib/commands/functions-secrets-prune.js +12 -13
  37. package/lib/commands/functions-secrets-set.js +11 -15
  38. package/lib/commands/hosting-channel-create.js +1 -2
  39. package/lib/commands/hosting-channel-delete.js +4 -4
  40. package/lib/commands/hosting-channel-open.js +2 -3
  41. package/lib/commands/hosting-disable.js +5 -5
  42. package/lib/commands/hosting-sites-delete.js +4 -4
  43. package/lib/commands/init.js +41 -58
  44. package/lib/commands/login.js +1 -5
  45. package/lib/commands/logout.js +2 -3
  46. package/lib/commands/open.js +1 -2
  47. package/lib/commands/projects-create.js +1 -2
  48. package/lib/commands/remoteconfig-rollback.js +5 -5
  49. package/lib/commands/use.js +110 -110
  50. package/lib/config.js +1 -2
  51. package/lib/dataconnect/build.js +2 -4
  52. package/lib/dataconnect/client.js +20 -1
  53. package/lib/dataconnect/dataplaneClient.js +16 -1
  54. package/lib/dataconnect/schemaMigration.js +1 -6
  55. package/lib/dataconnect/types.js +5 -1
  56. package/lib/deploy/functions/params.js +10 -17
  57. package/lib/deploy/functions/prompts.js +6 -28
  58. package/lib/emulator/commandUtils.js +4 -13
  59. package/lib/emulator/controller.js +1 -2
  60. package/lib/emulator/downloadableEmulators.js +12 -12
  61. package/lib/emulator/initEmulators.js +9 -20
  62. package/lib/ensureApiEnabled.js +11 -1
  63. package/lib/extensions/askUserForEventsConfig.js +6 -15
  64. package/lib/extensions/askUserForParam.js +23 -52
  65. package/lib/extensions/checkProjectBilling.js +3 -9
  66. package/lib/extensions/diagnose.js +3 -6
  67. package/lib/extensions/extensionsHelper.js +17 -27
  68. package/lib/extensions/manifest.js +1 -2
  69. package/lib/extensions/tos.js +10 -2
  70. package/lib/extensions/utils.js +1 -10
  71. package/lib/frameworks/index.js +1 -2
  72. package/lib/frameworks/next/index.js +7 -4
  73. package/lib/frameworks/vite/index.js +1 -2
  74. package/lib/functions/secrets.js +14 -15
  75. package/lib/gcp/auth.js +29 -1
  76. package/lib/gcp/storage.js +19 -1
  77. package/lib/gif/fdcExperience.js +45 -0
  78. package/lib/hosting/interactive.js +2 -3
  79. package/lib/init/features/account.js +2 -4
  80. package/lib/init/features/database.js +11 -20
  81. package/lib/init/features/dataconnect/index.js +7 -14
  82. package/lib/init/features/dataconnect/sdk.js +15 -22
  83. package/lib/init/features/emulators.js +19 -41
  84. package/lib/init/features/firestore/index.js +2 -6
  85. package/lib/init/features/firestore/indexes.js +18 -31
  86. package/lib/init/features/firestore/rules.js +18 -31
  87. package/lib/init/features/functions/index.js +9 -16
  88. package/lib/init/features/functions/javascript.js +16 -30
  89. package/lib/init/features/functions/npm-dependencies.js +4 -8
  90. package/lib/init/features/functions/python.js +1 -3
  91. package/lib/init/features/functions/typescript.js +24 -43
  92. package/lib/init/features/genkit/index.js +23 -38
  93. package/lib/init/features/hosting/github.js +20 -51
  94. package/lib/init/features/hosting/index.js +36 -57
  95. package/lib/init/features/project.js +6 -16
  96. package/lib/init/features/remoteconfig.js +2 -8
  97. package/lib/init/features/storage.js +1 -3
  98. package/lib/management/apps.js +19 -44
  99. package/lib/management/projects.js +17 -28
  100. package/lib/mcp/index.js +13 -11
  101. package/lib/mcp/tools/auth/{disable_auth_user.js → disable_user.js} +3 -3
  102. package/lib/mcp/tools/auth/{get_auth_user.js → get_user.js} +4 -4
  103. package/lib/mcp/tools/auth/index.js +5 -4
  104. package/lib/mcp/tools/auth/{set_auth_claims.js → set_claims.js} +3 -3
  105. package/lib/mcp/tools/auth/set_sms_region_policy.js +36 -0
  106. package/lib/mcp/tools/core/consult_assistant.js +27 -0
  107. package/lib/mcp/tools/core/index.js +5 -3
  108. package/lib/mcp/tools/dataconnect/converter.js +50 -0
  109. package/lib/mcp/tools/dataconnect/execute_graphql.js +32 -0
  110. package/lib/mcp/tools/dataconnect/execute_graphql_read.js +32 -0
  111. package/lib/mcp/tools/dataconnect/execute_mutation.js +50 -0
  112. package/lib/mcp/tools/dataconnect/execute_query.js +50 -0
  113. package/lib/mcp/tools/dataconnect/generate_operation.js +33 -0
  114. package/lib/mcp/tools/dataconnect/generate_schema.js +25 -0
  115. package/lib/mcp/tools/dataconnect/get_connector.js +31 -0
  116. package/lib/mcp/tools/dataconnect/get_schema.js +31 -0
  117. package/lib/mcp/tools/dataconnect/index.js +20 -2
  118. package/lib/mcp/tools/dataconnect/{list_dataconnect_services.js → list_services.js} +4 -4
  119. package/lib/mcp/tools/{core/get_firebase_directory.js → directory/get_project_directory.js} +5 -5
  120. package/lib/mcp/tools/directory/index.js +6 -0
  121. package/lib/mcp/tools/{core/set_firebase_directory.js → directory/set_project_directory.js} +3 -3
  122. package/lib/mcp/tools/firestore/get_documents.js +2 -2
  123. package/lib/mcp/tools/firestore/{get_firestore_rules.js → get_rules.js} +6 -6
  124. package/lib/mcp/tools/firestore/index.js +2 -2
  125. package/lib/mcp/tools/index.js +26 -8
  126. package/lib/mcp/tools/storage/get_download_url.js +31 -0
  127. package/lib/mcp/tools/storage/get_rules.js +26 -0
  128. package/lib/mcp/tools/storage/index.js +6 -0
  129. package/lib/mcp/types.js +1 -1
  130. package/lib/prompt.js +78 -65
  131. package/lib/requireTosAcceptance.js +4 -0
  132. package/lib/rulesDeploy.js +10 -15
  133. package/lib/track.js +1 -34
  134. package/lib/utils.js +27 -5
  135. package/package.json +2 -3
  136. package/lib/mcp/tools/project/index.js +0 -7
  137. /package/lib/mcp/tools/{project → core}/get_project.js +0 -0
  138. /package/lib/mcp/tools/{project → core}/get_sdk_config.js +0 -0
  139. /package/lib/mcp/tools/{project → core}/list_apps.js +0 -0
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.storageTools = void 0;
4
+ const get_download_url_1 = require("./get_download_url");
5
+ const get_rules_1 = require("./get_rules");
6
+ exports.storageTools = [get_rules_1.get_rules, get_download_url_1.get_object_download_url];
package/lib/mcp/types.js CHANGED
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SERVER_FEATURES = void 0;
4
- exports.SERVER_FEATURES = ["project", "firestore", "storage", "dataconnect", "auth"];
4
+ exports.SERVER_FEATURES = ["firestore", "storage", "dataconnect", "auth"];
package/lib/prompt.js CHANGED
@@ -1,80 +1,93 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.promptForDirectory = exports.confirm = exports.promptOnce = exports.prompt = void 0;
4
- const inquirer = require("inquirer");
5
- const path = require("path");
6
- const fsutils_1 = require("./fsutils");
3
+ exports.search = exports.password = exports.number = exports.select = exports.checkbox = exports.confirm = exports.input = exports.guard = exports.Separator = void 0;
4
+ const inquirer = require("@inquirer/prompts");
7
5
  const error_1 = require("./error");
8
- const logger_1 = require("./logger");
9
- inquirer.registerPrompt("autocomplete", require("inquirer-autocomplete-prompt"));
10
- async function prompt(options, questions) {
11
- const prompts = [];
12
- for (const question of questions) {
13
- if (question.name && options[question.name] === undefined) {
14
- prompts.push(question);
15
- }
6
+ var prompts_1 = require("@inquirer/prompts");
7
+ Object.defineProperty(exports, "Separator", { enumerable: true, get: function () { return prompts_1.Separator; } });
8
+ function guard(opts) {
9
+ if (!opts.nonInteractive) {
10
+ return { shouldReturn: false, value: undefined };
16
11
  }
17
- if (prompts.length && options.nonInteractive) {
18
- const missingOptions = Array.from(new Set(prompts.map((p) => p.name))).join(", ");
19
- throw new error_1.FirebaseError(`Missing required options (${missingOptions}) while running in non-interactive mode`, {
20
- children: prompts,
21
- });
12
+ if (typeof opts.default !== "undefined") {
13
+ return { shouldReturn: true, value: opts.default };
22
14
  }
23
- const answers = await inquirer.prompt(prompts);
24
- Object.keys(answers).forEach((k) => {
25
- options[k] = answers[k];
26
- });
27
- return answers;
28
- }
29
- exports.prompt = prompt;
30
- async function promptOnce(question, options = {}) {
31
- var _a;
32
- question.name = ((_a = question.name) === null || _a === void 0 ? void 0 : _a.replace(/\./g, "/")) || "question";
33
- await prompt(options, [question]);
34
- return options[question.name];
15
+ throw new error_1.FirebaseError(`Question "${opts.message}" does not have a default and cannot be answered in non-interactive mode`);
35
16
  }
36
- exports.promptOnce = promptOnce;
37
- async function confirm(args) {
38
- var _a;
39
- if (!args.nonInteractive && !args.force) {
40
- const message = (_a = args.message) !== null && _a !== void 0 ? _a : `Do you wish to continue?`;
41
- return await promptOnce({
42
- type: "confirm",
43
- message,
44
- default: args.default,
45
- });
46
- }
47
- else if (args.nonInteractive && !args.force) {
48
- throw new error_1.FirebaseError("Pass the --force flag to use this command in non-interactive mode");
17
+ exports.guard = guard;
18
+ async function input(opts) {
19
+ if (typeof opts === "string") {
20
+ opts = { message: opts };
49
21
  }
50
22
  else {
51
- return true;
23
+ const { shouldReturn, value } = guard(opts);
24
+ if (shouldReturn) {
25
+ return value;
26
+ }
52
27
  }
28
+ return inquirer.input(opts);
53
29
  }
54
- exports.confirm = confirm;
55
- async function promptForDirectory(args) {
56
- let dir = "";
57
- while (!dir) {
58
- const promptPath = await promptOnce({
59
- message: args.message,
60
- });
61
- let target;
62
- if (args.relativeTo) {
63
- target = path.resolve(args.relativeTo, promptPath);
64
- }
65
- else {
66
- target = args.config.path(promptPath);
67
- }
68
- if ((0, fsutils_1.fileExistsSync)(target)) {
69
- logger_1.logger.error(`Expected a directory, but ${target} is a file. Please provide a path to a directory.`);
30
+ exports.input = input;
31
+ async function confirm(opts) {
32
+ if (typeof opts === "string") {
33
+ opts = { message: opts };
34
+ }
35
+ else {
36
+ if (opts.force) {
37
+ return true;
70
38
  }
71
- else if (!(0, fsutils_1.dirExistsSync)(target)) {
72
- logger_1.logger.error(`Directory ${target} not found. Please provide a path to a directory`);
39
+ const { shouldReturn, value } = guard(opts);
40
+ if (shouldReturn) {
41
+ return value;
73
42
  }
74
- else {
75
- dir = target;
43
+ }
44
+ return inquirer.confirm(opts);
45
+ }
46
+ exports.confirm = confirm;
47
+ async function checkbox(opts) {
48
+ const { shouldReturn, value } = guard(opts);
49
+ if (shouldReturn) {
50
+ return value;
51
+ }
52
+ return inquirer.checkbox(Object.assign(Object.assign({}, opts), { loop: true }));
53
+ }
54
+ exports.checkbox = checkbox;
55
+ async function select(opts) {
56
+ const { shouldReturn, value } = guard(opts);
57
+ if (shouldReturn) {
58
+ return value;
59
+ }
60
+ return inquirer.select(Object.assign(Object.assign({}, opts), { loop: false }));
61
+ }
62
+ exports.select = select;
63
+ async function number(opts) {
64
+ if (typeof opts === "string") {
65
+ opts = { message: opts };
66
+ }
67
+ else {
68
+ const { shouldReturn, value } = guard(opts);
69
+ if (shouldReturn) {
70
+ return value;
76
71
  }
77
72
  }
78
- return dir;
73
+ return (await inquirer.number(Object.assign(Object.assign({}, opts), { required: true })));
74
+ }
75
+ exports.number = number;
76
+ async function password(opts) {
77
+ if (typeof opts === "string") {
78
+ opts = { message: opts };
79
+ }
80
+ else {
81
+ guard(opts);
82
+ }
83
+ return inquirer.password(Object.assign(Object.assign({}, opts), { mask: "" }));
84
+ }
85
+ exports.password = password;
86
+ async function search(opts) {
87
+ const { shouldReturn, value } = guard(opts);
88
+ if (shouldReturn) {
89
+ return value;
90
+ }
91
+ return inquirer.search(opts);
79
92
  }
80
- exports.promptForDirectory = promptForDirectory;
93
+ exports.search = search;
@@ -4,6 +4,7 @@ exports.requireTosAcceptance = void 0;
4
4
  const error_1 = require("./error");
5
5
  const firedata_1 = require("./gcp/firedata");
6
6
  const api_1 = require("./api");
7
+ const auth_1 = require("./auth");
7
8
  const consoleLandingPage = new Map([
8
9
  [firedata_1.APPHOSTING_TOS_ID, `${(0, api_1.consoleOrigin)()}/project/_/apphosting`],
9
10
  [firedata_1.DATA_CONNECT_TOS_ID, `${(0, api_1.consoleOrigin)()}/project/_/dataconnect`],
@@ -13,6 +14,9 @@ function requireTosAcceptance(tosId) {
13
14
  }
14
15
  exports.requireTosAcceptance = requireTosAcceptance;
15
16
  async function requireTos(tosId) {
17
+ if (!(0, auth_1.loggedIn)()) {
18
+ return;
19
+ }
16
20
  const res = await (0, firedata_1.getTosStatus)();
17
21
  if ((0, firedata_1.isProductTosAccepted)(res, tosId)) {
18
22
  return;
@@ -71,13 +71,11 @@ class RulesDeploy {
71
71
  if (await (0, resourceManager_1.serviceAccountHasRoles)(projectNumber, saEmail, [CROSS_SERVICE_RULES_ROLE], true)) {
72
72
  return;
73
73
  }
74
- const addRole = this.options.force ||
75
- (await (0, prompt_1.promptOnce)({
76
- type: "confirm",
77
- name: "rulesRole",
78
- message: `Cloud Storage for Firebase needs an IAM Role to use cross-service rules. Grant the new role?`,
79
- default: true,
80
- }, this.options));
74
+ const addRole = await (0, prompt_1.confirm)({
75
+ message: `Cloud Storage for Firebase needs an IAM Role to use cross-service rules. Grant the new role?`,
76
+ default: true,
77
+ force: this.options.force,
78
+ });
81
79
  if (addRole) {
82
80
  await (0, resourceManager_1.addServiceAccountToRoles)(projectNumber, saEmail, [CROSS_SERVICE_RULES_ROLE], true);
83
81
  utils.logLabeledBullet(RulesetType[this.type], "updated service account for cross-service rules...");
@@ -119,14 +117,11 @@ class RulesDeploy {
119
117
  utils.logLabeledBullet(RulesetType[this.type], "quota exceeded error while uploading rules");
120
118
  const history = await gcp.rules.listAllRulesets(this.options.project);
121
119
  if (history.length > RULESET_COUNT_LIMIT) {
122
- const confirm = this.options.force ||
123
- (await (0, prompt_1.promptOnce)({
124
- type: "confirm",
125
- name: "force",
126
- message: `You have ${history.length} rules, do you want to delete the oldest ${RULESETS_TO_GC} to free up space?`,
127
- default: false,
128
- }, this.options));
129
- if (confirm) {
120
+ const confirmed = await (0, prompt_1.confirm)({
121
+ message: `You have ${history.length} rules, do you want to delete the oldest ${RULESETS_TO_GC} to free up space?`,
122
+ force: this.options.force,
123
+ });
124
+ if (confirmed) {
130
125
  const releases = await gcp.rules.listAllReleases(this.options.project);
131
126
  const unreleased = history.filter((ruleset) => {
132
127
  return !releases.find((release) => release.rulesetName === ruleset.name);
package/lib/track.js CHANGED
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.track = exports.cliSession = exports.vscodeSession = exports.emulatorSession = exports.trackVSCode = exports.trackEmulator = exports.trackGA4 = exports.usageEnabled = exports.GA4_PROPERTIES = void 0;
3
+ exports.cliSession = exports.vscodeSession = exports.emulatorSession = exports.trackVSCode = exports.trackEmulator = exports.trackGA4 = exports.usageEnabled = exports.GA4_PROPERTIES = void 0;
4
4
  const node_fetch_1 = require("node-fetch");
5
- const ua = require("universal-analytics");
6
5
  const uuid_1 = require("uuid");
7
6
  const auth_1 = require("./auth");
8
7
  const configstore_1 = require("./configstore");
@@ -189,35 +188,3 @@ function isDebugMode() {
189
188
  }
190
189
  return false;
191
190
  }
192
- const FIREBASE_ANALYTICS_UA = process.env.FIREBASE_ANALYTICS_UA || "UA-29174744-3";
193
- let visitor;
194
- function ensureUAVisitor() {
195
- if (!visitor) {
196
- let anonId = configstore_1.configstore.get("analytics-uuid");
197
- if (!anonId) {
198
- anonId = (0, uuid_1.v4)();
199
- configstore_1.configstore.set("analytics-uuid", anonId);
200
- }
201
- visitor = ua(FIREBASE_ANALYTICS_UA, anonId, {
202
- strictCidFormat: false,
203
- https: true,
204
- });
205
- visitor.set("cd1", process.platform);
206
- visitor.set("cd2", process.version);
207
- visitor.set("cd3", process.env.FIREPIT_VERSION || "none");
208
- }
209
- }
210
- function track(action, label, duration = 0) {
211
- ensureUAVisitor();
212
- return new Promise((resolve) => {
213
- if (usageEnabled() && configstore_1.configstore.get("tokens")) {
214
- visitor.event("Firebase CLI " + pkg.version, action, label, duration).send(() => {
215
- resolve();
216
- });
217
- }
218
- else {
219
- resolve();
220
- }
221
- });
222
- }
223
- exports.track = track;
package/lib/utils.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.openInBrowser = exports.connectableHostname = exports.randomInt = exports.debounce = exports.last = exports.cloneDeep = exports.groupBy = exports.assertIsStringOrUndefined = exports.assertIsNumber = exports.assertIsString = exports.thirtyDaysFromNow = exports.isRunningInWSL = exports.isCloudEnvironment = exports.datetimeString = exports.createDestroyer = exports.sleep = exports.promiseWithSpinner = exports.setupLoggers = exports.tryParse = exports.tryStringify = exports.promiseProps = exports.withTimeout = exports.promiseWhile = exports.promiseAllSettled = exports.getFunctionsEventProvider = exports.endpoint = exports.makeActiveProject = exports.streamToString = exports.stringToStream = exports.explainStdin = exports.allSettled = exports.reject = exports.logLabeledError = exports.logLabeledWarning = exports.logWarning = exports.logLabeledBullet = exports.logBullet = exports.logLabeledSuccess = exports.logSuccess = exports.addSubdomain = exports.addDatabaseNamespace = exports.getDatabaseViewDataUrl = exports.getDatabaseUrl = exports.envOverride = exports.setVSCodeEnvVars = exports.getInheritedOption = exports.consoleUrl = exports.vscodeEnvVars = exports.envOverrides = exports.IS_WINDOWS = void 0;
4
- exports.updateOrCreateGitignore = exports.readSecretValue = exports.generateId = exports.wrappedSafeLoad = exports.readFileFromDirectory = exports.getHostnameFromUrl = exports.openInBrowserPopup = void 0;
4
+ exports.promptForDirectory = exports.updateOrCreateGitignore = exports.readSecretValue = exports.generateId = exports.wrappedSafeLoad = exports.readFileFromDirectory = exports.getHostnameFromUrl = exports.openInBrowserPopup = void 0;
5
5
  const fs = require("fs-extra");
6
6
  const tty = require("tty");
7
7
  const path = require("node:path");
@@ -25,6 +25,7 @@ const logger_1 = require("./logger");
25
25
  const prompt_1 = require("./prompt");
26
26
  const templates_1 = require("./templates");
27
27
  const vsCodeUtils_1 = require("./vsCodeUtils");
28
+ const fsutils_1 = require("./fsutils");
28
29
  exports.IS_WINDOWS = process.platform === "win32";
29
30
  const SUCCESS_CHAR = exports.IS_WINDOWS ? "+" : "✔";
30
31
  const WARNING_CHAR = exports.IS_WINDOWS ? "!" : "⚠";
@@ -577,10 +578,7 @@ function generateId(n = 6) {
577
578
  exports.generateId = generateId;
578
579
  function readSecretValue(prompt, dataFile) {
579
580
  if ((!dataFile || dataFile === "-") && tty.isatty(0)) {
580
- return (0, prompt_1.promptOnce)({
581
- type: "password",
582
- message: prompt,
583
- });
581
+ return (0, prompt_1.password)({ message: prompt });
584
582
  }
585
583
  let input = 0;
586
584
  if (dataFile && dataFile !== "-") {
@@ -612,3 +610,27 @@ function updateOrCreateGitignore(dirPath, entries) {
612
610
  fs.writeFileSync(gitignorePath, content);
613
611
  }
614
612
  exports.updateOrCreateGitignore = updateOrCreateGitignore;
613
+ async function promptForDirectory(args) {
614
+ let dir = "";
615
+ while (!dir) {
616
+ const promptPath = await (0, prompt_1.input)(args.message);
617
+ let target;
618
+ if (args.relativeTo) {
619
+ target = path.resolve(args.relativeTo, promptPath);
620
+ }
621
+ else {
622
+ target = args.config.path(promptPath);
623
+ }
624
+ if ((0, fsutils_1.fileExistsSync)(target)) {
625
+ logger_1.logger.error(`Expected a directory, but ${target} is a file. Please provide a path to a directory.`);
626
+ }
627
+ else if (!(0, fsutils_1.dirExistsSync)(target)) {
628
+ logger_1.logger.error(`Directory ${target} not found. Please provide a path to a directory`);
629
+ }
630
+ else {
631
+ dir = target;
632
+ }
633
+ }
634
+ return dir;
635
+ }
636
+ exports.promptForDirectory = promptForDirectory;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-tools",
3
- "version": "14.2.2",
3
+ "version": "14.3.1",
4
4
  "description": "Command-Line Interface for Firebase",
5
5
  "main": "./lib/index.js",
6
6
  "bin": {
@@ -63,6 +63,7 @@
63
63
  "@electric-sql/pglite": "^0.2.16",
64
64
  "@google-cloud/cloud-sql-connector": "^1.3.3",
65
65
  "@google-cloud/pubsub": "^4.5.0",
66
+ "@inquirer/prompts": "^7.4.0",
66
67
  "@modelcontextprotocol/sdk": "^1.10.2",
67
68
  "abort-controller": "^3.0.0",
68
69
  "ajv": "^8.17.1",
@@ -91,8 +92,6 @@
91
92
  "gaxios": "^6.7.0",
92
93
  "glob": "^10.4.1",
93
94
  "google-auth-library": "^9.11.0",
94
- "inquirer": "^8.2.6",
95
- "inquirer-autocomplete-prompt": "^2.0.1",
96
95
  "js-yaml": "^3.14.1",
97
96
  "jsonwebtoken": "^9.0.0",
98
97
  "leven": "^3.1.0",
@@ -1,7 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.projectTools = void 0;
4
- const get_project_js_1 = require("./get_project.js");
5
- const get_sdk_config_js_1 = require("./get_sdk_config.js");
6
- const list_apps_js_1 = require("./list_apps.js");
7
- exports.projectTools = [get_project_js_1.get_project, list_apps_js_1.list_apps, get_sdk_config_js_1.get_sdk_config];
File without changes
File without changes