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.
- package/lib/api.js +4 -2
- package/lib/apphosting/backend.js +12 -23
- package/lib/apphosting/config.js +9 -20
- package/lib/apphosting/githubConnections.js +52 -80
- package/lib/apphosting/repo.js +22 -36
- package/lib/apphosting/secrets/dialogs.js +2 -3
- package/lib/apphosting/utils.js +1 -3
- package/lib/auth.js +1 -4
- package/lib/bin/cli.js +131 -0
- package/lib/bin/firebase.js +7 -123
- package/lib/bin/mcp.js +38 -0
- package/lib/commands/apphosting-backends-delete.js +5 -5
- package/lib/commands/apphosting-secrets-set.js +2 -6
- package/lib/commands/apps-create.js +2 -3
- package/lib/commands/apps-sdkconfig.js +2 -7
- package/lib/commands/database-import.js +4 -6
- package/lib/commands/database-remove.js +4 -6
- package/lib/commands/database-set.js +6 -6
- package/lib/commands/database-update.js +5 -5
- package/lib/commands/dataconnect-sql-shell.js +4 -6
- package/lib/commands/ext-dev-deprecate.js +1 -0
- package/lib/commands/ext-dev-init.js +3 -12
- package/lib/commands/ext-dev-register.js +2 -4
- package/lib/commands/ext-dev-undeprecate.js +1 -2
- package/lib/commands/ext-dev-usage.js +1 -3
- package/lib/commands/ext-export.js +1 -2
- package/lib/commands/ext-install.js +1 -0
- package/lib/commands/ext-sdk-install.js +1 -0
- package/lib/commands/ext-update.js +1 -0
- package/lib/commands/firestore-backups-delete.js +1 -2
- package/lib/commands/firestore-backups-schedules-delete.js +1 -2
- package/lib/commands/firestore-databases-delete.js +1 -5
- package/lib/commands/firestore-delete.js +6 -6
- package/lib/commands/functions-artifacts-setpolicy.js +12 -2
- package/lib/commands/functions-config-export.js +5 -9
- package/lib/commands/functions-delete.js +5 -5
- package/lib/commands/functions-deletegcfartifacts.js +4 -4
- package/lib/commands/functions-secrets-destroy.js +8 -10
- package/lib/commands/functions-secrets-prune.js +12 -13
- package/lib/commands/functions-secrets-set.js +11 -15
- package/lib/commands/hosting-channel-create.js +1 -2
- package/lib/commands/hosting-channel-delete.js +4 -4
- package/lib/commands/hosting-channel-open.js +2 -3
- package/lib/commands/hosting-disable.js +5 -5
- package/lib/commands/hosting-sites-delete.js +4 -4
- package/lib/commands/index.js +3 -0
- package/lib/commands/init.js +41 -58
- package/lib/commands/login.js +1 -5
- package/lib/commands/logout.js +2 -3
- package/lib/commands/mcp.js +11 -0
- package/lib/commands/open.js +1 -2
- package/lib/commands/projects-create.js +1 -2
- package/lib/commands/remoteconfig-rollback.js +5 -5
- package/lib/commands/use.js +110 -110
- package/lib/config.js +1 -2
- package/lib/dataconnect/build.js +2 -4
- package/lib/dataconnect/client.js +20 -1
- package/lib/dataconnect/schemaMigration.js +1 -6
- package/lib/deploy/functions/params.js +10 -17
- package/lib/deploy/functions/prompts.js +6 -28
- package/lib/emulator/commandUtils.js +12 -19
- package/lib/emulator/controller.js +1 -2
- package/lib/emulator/downloadableEmulators.js +12 -12
- package/lib/emulator/env.js +19 -20
- package/lib/emulator/functionsEmulator.js +0 -1
- package/lib/emulator/hub.js +2 -1
- package/lib/emulator/initEmulators.js +9 -20
- package/lib/emulator/ui.js +0 -2
- package/lib/experiments.js +5 -0
- package/lib/extensions/askUserForEventsConfig.js +6 -15
- package/lib/extensions/askUserForParam.js +23 -52
- package/lib/extensions/checkProjectBilling.js +3 -9
- package/lib/extensions/diagnose.js +3 -6
- package/lib/extensions/extensionsHelper.js +17 -27
- package/lib/extensions/manifest.js +1 -2
- package/lib/extensions/tos.js +10 -2
- package/lib/extensions/utils.js +1 -10
- package/lib/frameworks/index.js +5 -3
- package/lib/frameworks/next/index.js +7 -4
- package/lib/frameworks/vite/index.js +1 -2
- package/lib/functions/secrets.js +14 -15
- package/lib/gcp/auth.js +84 -1
- package/lib/gcp/firestore.js +12 -1
- package/lib/gif/fdcExperience.js +45 -0
- package/lib/hosting/api.js +4 -0
- package/lib/hosting/interactive.js +2 -3
- package/lib/init/features/account.js +2 -4
- package/lib/init/features/database.js +11 -20
- package/lib/init/features/dataconnect/index.js +7 -14
- package/lib/init/features/dataconnect/sdk.js +14 -19
- package/lib/init/features/emulators.js +19 -41
- package/lib/init/features/firestore/index.js +2 -6
- package/lib/init/features/firestore/indexes.js +17 -31
- package/lib/init/features/firestore/rules.js +17 -31
- package/lib/init/features/functions/index.js +9 -16
- package/lib/init/features/functions/javascript.js +16 -30
- package/lib/init/features/functions/npm-dependencies.js +4 -8
- package/lib/init/features/functions/python.js +1 -3
- package/lib/init/features/functions/typescript.js +24 -43
- package/lib/init/features/genkit/index.js +23 -38
- package/lib/init/features/hosting/github.js +20 -51
- package/lib/init/features/hosting/index.js +36 -57
- package/lib/init/features/project.js +6 -16
- package/lib/init/features/remoteconfig.js +2 -8
- package/lib/init/features/storage.js +1 -3
- package/lib/logger.js +11 -2
- package/lib/management/apps.js +19 -44
- package/lib/management/projects.js +17 -28
- package/lib/mcp/errors.js +15 -0
- package/lib/mcp/index.js +120 -0
- package/lib/mcp/tool.js +11 -0
- package/lib/mcp/tools/auth/disable_auth_user.js +30 -0
- package/lib/mcp/tools/auth/get_auth_user.js +29 -0
- package/lib/mcp/tools/auth/index.js +13 -0
- package/lib/mcp/tools/auth/set_auth_claims.js +34 -0
- package/lib/mcp/tools/auth/set_sms_region_policy.js +36 -0
- package/lib/mcp/tools/core/consult_firebase_assistant.js +27 -0
- package/lib/mcp/tools/core/get_firebase_directory.js +20 -0
- package/lib/mcp/tools/core/index.js +11 -0
- package/lib/mcp/tools/core/set_firebase_directory.js +33 -0
- package/lib/mcp/tools/dataconnect/converter.js +33 -0
- package/lib/mcp/tools/dataconnect/generate_dataconnect_operation.js +33 -0
- package/lib/mcp/tools/dataconnect/generate_dataconnect_schema.js +25 -0
- package/lib/mcp/tools/dataconnect/get_dataconnect_connector.js +31 -0
- package/lib/mcp/tools/dataconnect/get_dataconnect_schema.js +31 -0
- package/lib/mcp/tools/dataconnect/index.js +15 -0
- package/lib/mcp/tools/dataconnect/list_dataconnect_services.js +23 -0
- package/lib/mcp/tools/firestore/converter.js +57 -0
- package/lib/mcp/tools/firestore/get_firestore_documents.js +48 -0
- package/lib/mcp/tools/firestore/get_firestore_rules.js +26 -0
- package/lib/mcp/tools/firestore/index.js +11 -0
- package/lib/mcp/tools/firestore/list_firestore_collections.js +30 -0
- package/lib/mcp/tools/index.js +15 -0
- package/lib/mcp/tools/project/get_project.js +22 -0
- package/lib/mcp/tools/project/get_sdk_config.js +38 -0
- package/lib/mcp/tools/project/index.js +7 -0
- package/lib/mcp/tools/project/list_apps.js +29 -0
- package/lib/mcp/tools/storage/get_storage_rules.js +26 -0
- package/lib/mcp/tools/storage/index.js +5 -0
- package/lib/mcp/types.js +4 -0
- package/lib/mcp/util.js +52 -0
- package/lib/prompt.js +78 -65
- package/lib/requireTosAcceptance.js +4 -0
- package/lib/rulesDeploy.js +10 -15
- package/lib/track.js +1 -34
- package/lib/utils.js +27 -5
- package/package.json +6 -4
- package/templates/init/dataconnect/connector.yaml +3 -0
package/lib/mcp/util.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.commandExistsSync = exports.mcpError = exports.toContent = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const js_yaml_1 = require("js-yaml");
|
|
6
|
+
const os_1 = require("os");
|
|
7
|
+
function toContent(data, options) {
|
|
8
|
+
if (typeof data === "string")
|
|
9
|
+
return { content: [{ type: "text", text: data }] };
|
|
10
|
+
let text = "";
|
|
11
|
+
const format = (options === null || options === void 0 ? void 0 : options.format) || "yaml";
|
|
12
|
+
switch (format) {
|
|
13
|
+
case "json":
|
|
14
|
+
text = JSON.stringify(data);
|
|
15
|
+
break;
|
|
16
|
+
case "yaml":
|
|
17
|
+
text = (0, js_yaml_1.dump)(data);
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
content: [{ type: "text", text }],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
exports.toContent = toContent;
|
|
25
|
+
function mcpError(message, code) {
|
|
26
|
+
let errorMessage = "unknown error";
|
|
27
|
+
if (message instanceof Error) {
|
|
28
|
+
errorMessage = message.message;
|
|
29
|
+
}
|
|
30
|
+
if (typeof message === "string") {
|
|
31
|
+
errorMessage = message;
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
isError: true,
|
|
35
|
+
content: [{ type: "text", text: `Error: ${code ? `${code}: ` : ""}${errorMessage}` }],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
exports.mcpError = mcpError;
|
|
39
|
+
function commandExistsSync(command) {
|
|
40
|
+
try {
|
|
41
|
+
const isWindows = (0, os_1.platform)() === "win32";
|
|
42
|
+
const commandToCheck = isWindows
|
|
43
|
+
? `where "${command}" > nul 2> nul`
|
|
44
|
+
: `which "${command}" > /dev/null 2> /dev/null`;
|
|
45
|
+
(0, child_process_1.execSync)(commandToCheck);
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.commandExistsSync = commandExistsSync;
|
package/lib/prompt.js
CHANGED
|
@@ -1,80 +1,93 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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 (
|
|
18
|
-
|
|
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
|
-
|
|
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.
|
|
37
|
-
async function
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
23
|
+
const { shouldReturn, value } = guard(opts);
|
|
24
|
+
if (shouldReturn) {
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
52
27
|
}
|
|
28
|
+
return inquirer.input(opts);
|
|
53
29
|
}
|
|
54
|
-
exports.
|
|
55
|
-
async function
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
72
|
-
|
|
39
|
+
const { shouldReturn, value } = guard(opts);
|
|
40
|
+
if (shouldReturn) {
|
|
41
|
+
return value;
|
|
73
42
|
}
|
|
74
|
-
|
|
75
|
-
|
|
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
|
|
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.
|
|
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;
|
package/lib/rulesDeploy.js
CHANGED
|
@@ -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 =
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
3
|
+
"version": "14.3.0",
|
|
4
4
|
"description": "Command-Line Interface for Firebase",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -63,6 +63,8 @@
|
|
|
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",
|
|
67
|
+
"@modelcontextprotocol/sdk": "^1.10.2",
|
|
66
68
|
"abort-controller": "^3.0.0",
|
|
67
69
|
"ajv": "^8.17.1",
|
|
68
70
|
"ajv-formats": "3.0.1",
|
|
@@ -90,8 +92,6 @@
|
|
|
90
92
|
"gaxios": "^6.7.0",
|
|
91
93
|
"glob": "^10.4.1",
|
|
92
94
|
"google-auth-library": "^9.11.0",
|
|
93
|
-
"inquirer": "^8.2.6",
|
|
94
|
-
"inquirer-autocomplete-prompt": "^2.0.1",
|
|
95
95
|
"js-yaml": "^3.14.1",
|
|
96
96
|
"jsonwebtoken": "^9.0.0",
|
|
97
97
|
"leven": "^3.1.0",
|
|
@@ -127,7 +127,9 @@
|
|
|
127
127
|
"winston": "^3.0.0",
|
|
128
128
|
"winston-transport": "^4.4.0",
|
|
129
129
|
"ws": "^7.5.10",
|
|
130
|
-
"yaml": "^2.4.1"
|
|
130
|
+
"yaml": "^2.4.1",
|
|
131
|
+
"zod": "^3.24.3",
|
|
132
|
+
"zod-to-json-schema": "^3.24.5"
|
|
131
133
|
},
|
|
132
134
|
"overrides": {
|
|
133
135
|
"@angular-devkit/core": {
|
|
@@ -12,3 +12,6 @@ connectorId: __connectorId__
|
|
|
12
12
|
# kotlinSdk:
|
|
13
13
|
# outputDir: <Path where you want the generated SDK to be written to, relative to this file>
|
|
14
14
|
# package: connectors.default
|
|
15
|
+
# dartSdk:
|
|
16
|
+
# outputDir: <Path where you want the generated SDK to be written to, relative to this file>
|
|
17
|
+
# package: default_connector
|