firebase-tools 14.11.0 → 14.11.2
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/apptesting/ensureProjectConfigured.js +56 -0
- package/lib/commands/ext-export.js +1 -1
- package/lib/commands/functions-config-clone.js +2 -0
- package/lib/commands/functions-config-get.js +2 -0
- package/lib/commands/functions-config-set.js +2 -0
- package/lib/commands/functions-config-unset.js +2 -0
- package/lib/commands/init.js +1 -1
- package/lib/commands/login.js +2 -2
- package/lib/deploy/functions/params.js +4 -0
- package/lib/deploy/functions/prepare.js +3 -1
- package/lib/deploy/functions/prepareFunctionsUpload.js +2 -0
- package/lib/deploy/functions/release/reporter.js +1 -0
- package/lib/emulator/downloadableEmulatorInfo.json +18 -18
- package/lib/env.js +18 -0
- package/lib/experiments.js +7 -0
- package/lib/firestore/api.js +15 -1
- package/lib/functions/deprecationWarnings.js +21 -0
- package/lib/init/features/aitools/promptUpdater.js +4 -1
- package/lib/init/features/apptesting/index.js +4 -0
- package/lib/mcp/errors.js +7 -1
- package/lib/mcp/index.js +78 -60
- package/lib/mcp/logging-transport.js +23 -0
- package/lib/mcp/tools/apphosting/fetch_logs.js +22 -22
- package/lib/mcp/tools/apphosting/list_backends.js +10 -10
- package/lib/mcp/tools/auth/disable_user.js +7 -7
- package/lib/mcp/tools/auth/get_user.js +6 -6
- package/lib/mcp/tools/auth/index.js +10 -10
- package/lib/mcp/tools/auth/list_users.js +6 -6
- package/lib/mcp/tools/auth/set_claims.js +7 -7
- package/lib/mcp/tools/auth/set_sms_region_policy.js +6 -6
- package/lib/mcp/tools/core/consult_assistant.js +6 -6
- package/lib/mcp/tools/core/create_android_sha.js +9 -9
- package/lib/mcp/tools/core/create_app.js +7 -7
- package/lib/mcp/tools/core/create_project.js +13 -13
- package/lib/mcp/tools/core/get_admin_sdk_config.js +7 -7
- package/lib/mcp/tools/core/get_environment.js +8 -8
- package/lib/mcp/tools/core/get_project.js +5 -5
- package/lib/mcp/tools/core/get_sdk_config.js +9 -9
- package/lib/mcp/tools/core/index.js +24 -24
- package/lib/mcp/tools/core/init.js +8 -8
- package/lib/mcp/tools/core/list_apps.js +6 -6
- package/lib/mcp/tools/core/list_projects.js +6 -6
- package/lib/mcp/tools/core/update_environment.js +10 -10
- package/lib/mcp/tools/crashlytics/index.js +2 -2
- package/lib/mcp/tools/crashlytics/list_top_issues.js +6 -6
- package/lib/mcp/tools/dataconnect/emulator.js +6 -6
- package/lib/mcp/tools/dataconnect/execute_graphql.js +10 -10
- package/lib/mcp/tools/dataconnect/execute_graphql_read.js +10 -10
- package/lib/mcp/tools/dataconnect/execute_mutation.js +13 -13
- package/lib/mcp/tools/dataconnect/execute_query.js +13 -13
- package/lib/mcp/tools/dataconnect/generate_operation.js +8 -8
- package/lib/mcp/tools/dataconnect/generate_schema.js +6 -6
- package/lib/mcp/tools/dataconnect/get_connector.js +8 -8
- package/lib/mcp/tools/dataconnect/get_schema.js +8 -8
- package/lib/mcp/tools/dataconnect/index.js +18 -18
- package/lib/mcp/tools/dataconnect/list_services.js +5 -5
- package/lib/mcp/tools/firestore/delete_document.js +13 -13
- package/lib/mcp/tools/firestore/get_documents.js +13 -13
- package/lib/mcp/tools/firestore/list_collections.js +9 -9
- package/lib/mcp/tools/firestore/query_collection.js +13 -13
- package/lib/mcp/tools/index.js +18 -18
- package/lib/mcp/tools/messaging/index.js +2 -2
- package/lib/mcp/tools/messaging/send_message.js +7 -7
- package/lib/mcp/tools/remoteconfig/get_template.js +5 -5
- package/lib/mcp/tools/remoteconfig/index.js +4 -4
- package/lib/mcp/tools/remoteconfig/publish_template.js +7 -7
- package/lib/mcp/tools/remoteconfig/rollback_template.js +6 -6
- package/lib/mcp/tools/rules/get_rules.js +8 -8
- package/lib/mcp/tools/rules/validate_rules.js +10 -10
- package/lib/mcp/tools/storage/get_download_url.js +8 -8
- package/lib/mcp/tools/storage/get_rules.js +8 -8
- package/lib/mcp/util.js +2 -1
- package/lib/requireAuth.js +9 -3
- package/lib/timeout.js +21 -0
- package/lib/track.js +2 -2
- package/lib/utils.js +7 -2
- package/package.json +1 -1
- package/templates/init/dataconnect/mutations.gql +1 -1
- package/templates/init/dataconnect/queries.gql +3 -3
- package/lib/emulator/adminSdkConfig.test.js +0 -16
- package/lib/firestore/api-sort.test.js +0 -74
- package/lib/firestore/backupUtils.test.js +0 -18
- package/lib/firestore/pretty-print.test.js +0 -61
- package/lib/firestore/util.test.js +0 -42
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ensureProjectConfigured = void 0;
|
|
4
|
+
const resourceManager_1 = require("../gcp/resourceManager");
|
|
5
|
+
const ensureApiEnabled_1 = require("../ensureApiEnabled");
|
|
6
|
+
const api_1 = require("../api");
|
|
7
|
+
const utils_1 = require("../utils");
|
|
8
|
+
const error_1 = require("../error");
|
|
9
|
+
const iam = require("../gcp/iam");
|
|
10
|
+
const prompt_1 = require("../prompt");
|
|
11
|
+
const TEST_RUNNER_ROLE = "roles/firebaseapptesting.testRunner";
|
|
12
|
+
const TEST_RUNNER_SERVICE_ACCOUNT_NAME = "firebaseapptesting-test-runner";
|
|
13
|
+
async function ensureProjectConfigured(projectId) {
|
|
14
|
+
await (0, ensureApiEnabled_1.ensure)(projectId, (0, api_1.appTestingOrigin)(), "Firebase App Testing", false);
|
|
15
|
+
await (0, ensureApiEnabled_1.ensure)(projectId, (0, api_1.cloudRunApiOrigin)(), "Cloud Run", false);
|
|
16
|
+
await (0, ensureApiEnabled_1.ensure)(projectId, (0, api_1.storageOrigin)(), "Cloud Storage", false);
|
|
17
|
+
await (0, ensureApiEnabled_1.ensure)(projectId, (0, api_1.artifactRegistryDomain)(), "Artifact Registry", false);
|
|
18
|
+
const serviceAccount = runnerServiceAccount(projectId);
|
|
19
|
+
const serviceAccountExistsAndIsRunner = await (0, resourceManager_1.serviceAccountHasRoles)(projectId, serviceAccount, [TEST_RUNNER_ROLE], true);
|
|
20
|
+
if (!serviceAccountExistsAndIsRunner) {
|
|
21
|
+
const grant = await (0, prompt_1.confirm)(`Firebase App Testing runs tests in Cloud Run using a service account, provision an account, "${serviceAccount}", with the role "${TEST_RUNNER_ROLE}"?`);
|
|
22
|
+
if (!grant) {
|
|
23
|
+
(0, utils_1.logBullet)("You, or your project administrator, should run the following command to grant the required role:\n\n" +
|
|
24
|
+
`\tgcloud projects add-iam-policy-binding ${projectId} \\\n` +
|
|
25
|
+
`\t --member="serviceAccount:${serviceAccount}" \\\n` +
|
|
26
|
+
`\t --role="${TEST_RUNNER_ROLE}"\n`);
|
|
27
|
+
throw new error_1.FirebaseError(`Firebase App Testing requires a service account named "${serviceAccount}" with the "${TEST_RUNNER_ROLE}" role to execute tests using Cloud Run`);
|
|
28
|
+
}
|
|
29
|
+
await provisionServiceAccount(projectId, serviceAccount);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.ensureProjectConfigured = ensureProjectConfigured;
|
|
33
|
+
async function provisionServiceAccount(projectId, serviceAccount) {
|
|
34
|
+
try {
|
|
35
|
+
await iam.createServiceAccount(projectId, TEST_RUNNER_SERVICE_ACCOUNT_NAME, "Service Account used in Cloud Run, responsible for running tests", "Firebase App Testing Test Runner");
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
if ((0, error_1.getErrStatus)(err) !== 409) {
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
await (0, resourceManager_1.addServiceAccountToRoles)(projectId, serviceAccount, [TEST_RUNNER_ROLE], true);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
if ((0, error_1.getErrStatus)(err) === 400) {
|
|
47
|
+
(0, utils_1.logWarning)(`Your App Testing runner service account, "${serviceAccount}", is still being provisioned in the background. If you encounter an error, please try again after a few moments.`);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
throw err;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function runnerServiceAccount(projectId) {
|
|
55
|
+
return `${TEST_RUNNER_SERVICE_ACCOUNT_NAME}@${projectId}.iam.gserviceaccount.com`;
|
|
56
|
+
}
|
|
@@ -45,7 +45,7 @@ exports.command = new command_1.Command("ext:export")
|
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
47
|
const manifestSpecs = withRefSubbed.map((spec) => {
|
|
48
|
-
const paramCopy = Object.assign({}, spec.params);
|
|
48
|
+
const paramCopy = Object.assign(Object.assign({}, spec.params), spec.systemParams);
|
|
49
49
|
if (spec.eventarcChannel) {
|
|
50
50
|
paramCopy.EVENTARC_CHANNEL = spec.eventarcChannel;
|
|
51
51
|
}
|
|
@@ -10,6 +10,7 @@ const requirePermissions_1 = require("../requirePermissions");
|
|
|
10
10
|
const functionsConfig = require("../functionsConfig");
|
|
11
11
|
const functionsConfigClone_1 = require("../functionsConfigClone");
|
|
12
12
|
const utils = require("../utils");
|
|
13
|
+
const deprecationWarnings_1 = require("../functions/deprecationWarnings");
|
|
13
14
|
exports.command = new command_1.Command("functions:config:clone")
|
|
14
15
|
.description("clone environment config from another project")
|
|
15
16
|
.option("--from <projectId>", "the project from which to clone configuration")
|
|
@@ -50,4 +51,5 @@ exports.command = new command_1.Command("functions:config:clone")
|
|
|
50
51
|
await (0, functionsConfigClone_1.functionsConfigClone)(options.from, projectId, only, except);
|
|
51
52
|
utils.logSuccess(`Cloned functions config from ${clc.bold(options.from)} into ${clc.bold(projectId)}`);
|
|
52
53
|
logger_1.logger.info(`\nPlease deploy your functions for the change to take effect by running ${clc.bold("firebase deploy --only functions")}\n`);
|
|
54
|
+
(0, deprecationWarnings_1.logFunctionsConfigDeprecationWarning)();
|
|
53
55
|
});
|
|
@@ -8,6 +8,7 @@ const logger_1 = require("../logger");
|
|
|
8
8
|
const projectUtils_1 = require("../projectUtils");
|
|
9
9
|
const requirePermissions_1 = require("../requirePermissions");
|
|
10
10
|
const functionsConfig = require("../functionsConfig");
|
|
11
|
+
const deprecationWarnings_1 = require("../functions/deprecationWarnings");
|
|
11
12
|
async function materialize(projectId, path) {
|
|
12
13
|
if (path === undefined) {
|
|
13
14
|
return functionsConfig.materializeAll(projectId);
|
|
@@ -31,5 +32,6 @@ exports.command = new command_1.Command("functions:config:get [path]")
|
|
|
31
32
|
.action(async (path, options) => {
|
|
32
33
|
const result = await materialize((0, projectUtils_1.needProjectId)(options), path);
|
|
33
34
|
logger_1.logger.info(JSON.stringify(result, null, 2));
|
|
35
|
+
(0, deprecationWarnings_1.logFunctionsConfigDeprecationWarning)();
|
|
34
36
|
return result;
|
|
35
37
|
});
|
|
@@ -9,6 +9,7 @@ const projectUtils_1 = require("../projectUtils");
|
|
|
9
9
|
const requirePermissions_1 = require("../requirePermissions");
|
|
10
10
|
const functionsConfig = require("../functionsConfig");
|
|
11
11
|
const utils = require("../utils");
|
|
12
|
+
const deprecationWarnings_1 = require("../functions/deprecationWarnings");
|
|
12
13
|
exports.command = new command_1.Command("functions:config:set [values...]")
|
|
13
14
|
.description("set environment config with key=value syntax")
|
|
14
15
|
.before(requirePermissions_1.requirePermissions, [
|
|
@@ -40,4 +41,5 @@ exports.command = new command_1.Command("functions:config:set [values...]")
|
|
|
40
41
|
await Promise.all(promises);
|
|
41
42
|
utils.logSuccess("Functions config updated.");
|
|
42
43
|
logger_1.logger.info(`\nPlease deploy your functions for the change to take effect by running ${clc.bold("firebase deploy --only functions")}\n`);
|
|
44
|
+
(0, deprecationWarnings_1.logFunctionsConfigDeprecationWarning)();
|
|
43
45
|
});
|
|
@@ -10,6 +10,7 @@ const functionsConfig = require("../functionsConfig");
|
|
|
10
10
|
const runtimeconfig = require("../gcp/runtimeconfig");
|
|
11
11
|
const utils = require("../utils");
|
|
12
12
|
const error_1 = require("../error");
|
|
13
|
+
const deprecationWarnings_1 = require("../functions/deprecationWarnings");
|
|
13
14
|
exports.command = new command_1.Command("functions:config:unset [keys...]")
|
|
14
15
|
.description("unset environment config at the specified path(s)")
|
|
15
16
|
.before(requirePermissions_1.requirePermissions, [
|
|
@@ -39,4 +40,5 @@ exports.command = new command_1.Command("functions:config:unset [keys...]")
|
|
|
39
40
|
}));
|
|
40
41
|
utils.logSuccess("Environment updated.");
|
|
41
42
|
logger_1.logger.info(`\nPlease deploy your functions for the change to take effect by running ${clc.bold("firebase deploy --only functions")}\n`);
|
|
43
|
+
(0, deprecationWarnings_1.logFunctionsConfigDeprecationWarning)();
|
|
42
44
|
});
|
package/lib/commands/init.js
CHANGED
|
@@ -102,7 +102,7 @@ if ((0, experiments_1.isEnabled)("genkit")) {
|
|
|
102
102
|
if ((0, experiments_1.isEnabled)("apptesting")) {
|
|
103
103
|
choices.push({
|
|
104
104
|
value: "apptesting",
|
|
105
|
-
name: "App Testing: create a smoke test",
|
|
105
|
+
name: "App Testing: create a smoke test, enable Cloud APIs (storage, run, & artifactregistry), and add a service account.",
|
|
106
106
|
checked: false,
|
|
107
107
|
});
|
|
108
108
|
}
|
package/lib/commands/login.js
CHANGED
|
@@ -22,7 +22,7 @@ exports.command = new command_1.Command("login")
|
|
|
22
22
|
}
|
|
23
23
|
const user = options.user;
|
|
24
24
|
const tokens = options.tokens;
|
|
25
|
-
if (user && tokens && !options.reauth) {
|
|
25
|
+
if (user && (tokens === null || tokens === void 0 ? void 0 : tokens.refresh_token) && !options.reauth) {
|
|
26
26
|
logger_1.logger.info("Already logged in as", clc.bold(user.email));
|
|
27
27
|
return user;
|
|
28
28
|
}
|
|
@@ -37,7 +37,7 @@ exports.command = new command_1.Command("login")
|
|
|
37
37
|
configstore_1.configstore.set("usage", collectUsage);
|
|
38
38
|
if (geminiUsage || collectUsage) {
|
|
39
39
|
logger_1.logger.info();
|
|
40
|
-
utils.logBullet("To change your
|
|
40
|
+
utils.logBullet("To change your preferences at any time, run `firebase logout` and `firebase login` again.");
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
const useLocalhost = (0, utils_1.isCloudEnvironment)() ? false : options.localhost;
|
|
@@ -108,6 +108,10 @@ class ParamValue {
|
|
|
108
108
|
return ["true", "y", "yes", "1"].includes(this.rawValue);
|
|
109
109
|
}
|
|
110
110
|
asList() {
|
|
111
|
+
if (this.rawValue.includes("[")) {
|
|
112
|
+
const unquoted = this.rawValue.replace(/'/g, '"');
|
|
113
|
+
return JSON.parse(unquoted);
|
|
114
|
+
}
|
|
111
115
|
return this.rawValue.split(this.delimiter);
|
|
112
116
|
}
|
|
113
117
|
asNumber() {
|
|
@@ -53,7 +53,9 @@ async function prepare(context, options, payload) {
|
|
|
53
53
|
context.firebaseConfig = firebaseConfig;
|
|
54
54
|
let runtimeConfig = { firebase: firebaseConfig };
|
|
55
55
|
if (checkAPIsEnabled[1]) {
|
|
56
|
-
|
|
56
|
+
const config = await (0, prepareFunctionsUpload_1.getFunctionsConfig)(projectId);
|
|
57
|
+
runtimeConfig = Object.assign(Object.assign({}, runtimeConfig), config);
|
|
58
|
+
context.hasRuntimeConfig = Object.keys(config).length > 0;
|
|
57
59
|
}
|
|
58
60
|
context.codebaseDeployEvents = {};
|
|
59
61
|
const wantBuilds = await loadCodebases(context.config, options, firebaseConfig, runtimeConfig, context.filters);
|
|
@@ -13,6 +13,7 @@ const hash_1 = require("./cache/hash");
|
|
|
13
13
|
const functionsConfig = require("../../functionsConfig");
|
|
14
14
|
const utils = require("../../utils");
|
|
15
15
|
const fsAsync = require("../../fsAsync");
|
|
16
|
+
const deprecationWarnings_1 = require("../../functions/deprecationWarnings");
|
|
16
17
|
const CONFIG_DEST_FILE = ".runtimeconfig.json";
|
|
17
18
|
async function getFunctionsConfig(projectId) {
|
|
18
19
|
var _a, _b;
|
|
@@ -73,6 +74,7 @@ async function packageSource(sourceDir, config, runtimeConfig) {
|
|
|
73
74
|
name: CONFIG_DEST_FILE,
|
|
74
75
|
mode: 420,
|
|
75
76
|
});
|
|
77
|
+
(0, deprecationWarnings_1.logFunctionsConfigDeprecationWarning)();
|
|
76
78
|
}
|
|
77
79
|
await pipeAsync(archive, fileStream);
|
|
78
80
|
}
|
|
@@ -81,6 +81,7 @@ async function logAndTrackDeployStats(summary, context) {
|
|
|
81
81
|
fn_deploy_num_successes: totalSuccesses,
|
|
82
82
|
fn_deploy_num_canceled: totalAborts,
|
|
83
83
|
fn_deploy_num_failures: totalErrors,
|
|
84
|
+
has_runtime_config: String(!!(context === null || context === void 0 ? void 0 : context.hasRuntimeConfig)),
|
|
84
85
|
};
|
|
85
86
|
reports.push((0, track_1.trackGA4)("function_deploy_group", fnDeployGroupEvent));
|
|
86
87
|
const avgTime = totalTime / (totalSuccesses + totalErrors);
|
|
@@ -54,28 +54,28 @@
|
|
|
54
54
|
},
|
|
55
55
|
"dataconnect": {
|
|
56
56
|
"darwin": {
|
|
57
|
-
"version": "2.10.
|
|
58
|
-
"expectedSize":
|
|
59
|
-
"expectedChecksum": "
|
|
60
|
-
"expectedChecksumSHA256": "
|
|
61
|
-
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-v2.10.
|
|
62
|
-
"downloadPathRelativeToCacheDir": "dataconnect-emulator-2.10.
|
|
57
|
+
"version": "2.10.1",
|
|
58
|
+
"expectedSize": 29336416,
|
|
59
|
+
"expectedChecksum": "328ae0a354505430f1c162edf37da776",
|
|
60
|
+
"expectedChecksumSHA256": "ede5dc299045151f228b2adc346f47ad5d3ee10c3c9d7528df5fc0f0c6d70808",
|
|
61
|
+
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-v2.10.1",
|
|
62
|
+
"downloadPathRelativeToCacheDir": "dataconnect-emulator-2.10.1"
|
|
63
63
|
},
|
|
64
64
|
"win32": {
|
|
65
|
-
"version": "2.10.
|
|
66
|
-
"expectedSize":
|
|
67
|
-
"expectedChecksum": "
|
|
68
|
-
"expectedChecksumSHA256": "
|
|
69
|
-
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-windows-v2.10.
|
|
70
|
-
"downloadPathRelativeToCacheDir": "dataconnect-emulator-2.10.
|
|
65
|
+
"version": "2.10.1",
|
|
66
|
+
"expectedSize": 29829632,
|
|
67
|
+
"expectedChecksum": "82e82e35c1728a214db37967dba751e7",
|
|
68
|
+
"expectedChecksumSHA256": "ba509e921c692ac60c1138b5b9c83a23b4e11feb339f08df5f1cfced44cffc91",
|
|
69
|
+
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-windows-v2.10.1",
|
|
70
|
+
"downloadPathRelativeToCacheDir": "dataconnect-emulator-2.10.1.exe"
|
|
71
71
|
},
|
|
72
72
|
"linux": {
|
|
73
|
-
"version": "2.10.
|
|
74
|
-
"expectedSize":
|
|
75
|
-
"expectedChecksum": "
|
|
76
|
-
"expectedChecksumSHA256": "
|
|
77
|
-
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-linux-v2.10.
|
|
78
|
-
"downloadPathRelativeToCacheDir": "dataconnect-emulator-2.10.
|
|
73
|
+
"version": "2.10.1",
|
|
74
|
+
"expectedSize": 29266104,
|
|
75
|
+
"expectedChecksum": "d183c2335e16f8c568bdc9e782dcd240",
|
|
76
|
+
"expectedChecksumSHA256": "338e0cce561d29993737b91abfe7fc12c7d82d014ef114348ccdafeb3b7be3ae",
|
|
77
|
+
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-linux-v2.10.1",
|
|
78
|
+
"downloadPathRelativeToCacheDir": "dataconnect-emulator-2.10.1"
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
}
|
package/lib/env.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isFirebaseMcp = exports.isFirebaseStudio = void 0;
|
|
4
|
+
const fsutils_1 = require("./fsutils");
|
|
5
|
+
let googleIdxFolderExists;
|
|
6
|
+
function isFirebaseStudio() {
|
|
7
|
+
if (googleIdxFolderExists === true || process.env.MONOSPACE_ENV)
|
|
8
|
+
return true;
|
|
9
|
+
if (googleIdxFolderExists === false)
|
|
10
|
+
return false;
|
|
11
|
+
googleIdxFolderExists = (0, fsutils_1.dirExistsSync)("/google/idx");
|
|
12
|
+
return googleIdxFolderExists;
|
|
13
|
+
}
|
|
14
|
+
exports.isFirebaseStudio = isFirebaseStudio;
|
|
15
|
+
function isFirebaseMcp() {
|
|
16
|
+
return !!process.env.IS_FIREBASE_MCP;
|
|
17
|
+
}
|
|
18
|
+
exports.isFirebaseMcp = isFirebaseMcp;
|
package/lib/experiments.js
CHANGED
|
@@ -41,6 +41,13 @@ exports.ALL_EXPERIMENTS = experiments({
|
|
|
41
41
|
"of how that image was created.",
|
|
42
42
|
public: true,
|
|
43
43
|
},
|
|
44
|
+
dangerouslyAllowFunctionsConfig: {
|
|
45
|
+
shortDescription: "Allows the use of deprecated functions.config() API",
|
|
46
|
+
fullDescription: "The functions.config() API is deprecated and will be removed on December 31, 2025. " +
|
|
47
|
+
"This experiment allows continued use of the API during the migration period.",
|
|
48
|
+
default: true,
|
|
49
|
+
public: true,
|
|
50
|
+
},
|
|
44
51
|
emulatoruisnapshot: {
|
|
45
52
|
shortDescription: "Load pre-release versions of the emulator UI",
|
|
46
53
|
},
|
package/lib/firestore/api.js
CHANGED
|
@@ -18,6 +18,20 @@ class FirestoreApi {
|
|
|
18
18
|
this.apiClient = new apiv2_1.Client({ urlPrefix: (0, api_1.firestoreOrigin)(), apiVersion: "v1" });
|
|
19
19
|
this.printer = new pretty_print_1.PrettyPrint();
|
|
20
20
|
}
|
|
21
|
+
static processIndexes(indexes) {
|
|
22
|
+
return indexes.map((index) => {
|
|
23
|
+
var _a, _b, _c;
|
|
24
|
+
let fields = index.fields;
|
|
25
|
+
const lastField = (_a = index.fields) === null || _a === void 0 ? void 0 : _a[index.fields.length - 1];
|
|
26
|
+
if ((lastField === null || lastField === void 0 ? void 0 : lastField.fieldPath) === "__name__") {
|
|
27
|
+
const defaultDirection = (_c = (_b = index.fields) === null || _b === void 0 ? void 0 : _b[index.fields.length - 2]) === null || _c === void 0 ? void 0 : _c.order;
|
|
28
|
+
if ((lastField === null || lastField === void 0 ? void 0 : lastField.order) === defaultDirection) {
|
|
29
|
+
fields = fields.slice(0, -1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return Object.assign(Object.assign({}, index), { fields });
|
|
33
|
+
});
|
|
34
|
+
}
|
|
21
35
|
async deploy(options, indexes, fieldOverrides, databaseId = "(default)") {
|
|
22
36
|
const spec = this.upgradeOldSpec({
|
|
23
37
|
indexes,
|
|
@@ -126,7 +140,7 @@ class FirestoreApi {
|
|
|
126
140
|
if (!indexes) {
|
|
127
141
|
return [];
|
|
128
142
|
}
|
|
129
|
-
return indexes;
|
|
143
|
+
return FirestoreApi.processIndexes(indexes);
|
|
130
144
|
}
|
|
131
145
|
async listFieldOverrides(project, databaseId = "(default)") {
|
|
132
146
|
const parent = `projects/${project}/databases/${databaseId}/collectionGroups/-`;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.logFunctionsConfigDeprecationWarning = void 0;
|
|
4
|
+
const utils_1 = require("../utils");
|
|
5
|
+
const FUNCTIONS_CONFIG_DEPRECATION_MESSAGE = `DEPRECATION NOTICE: Action required to deploy after Dec 31, 2025
|
|
6
|
+
|
|
7
|
+
functions.config() API is deprecated.
|
|
8
|
+
Cloud Runtime Configuration API, the Google Cloud service used to store function configuration data, will be shut down on December 31, 2025. As a result, you must migrate away from using functions.config() to continue deploying your functions after December 31, 2025.
|
|
9
|
+
|
|
10
|
+
What this means for you:
|
|
11
|
+
|
|
12
|
+
- The Firebase CLI commands for managing this configuration (functions:config:set, get, unset, clone, and export) are deprecated. These commands no longer work after December 31, 2025.
|
|
13
|
+
- firebase deploy command will fail for functions that use the legacy functions.config() API after December 31, 2025.
|
|
14
|
+
|
|
15
|
+
Existing deployments will continue to work with their current configuration.
|
|
16
|
+
|
|
17
|
+
See your migration options at: https://firebase.google.com/docs/functions/config-env#migrate-to-dotenv`;
|
|
18
|
+
function logFunctionsConfigDeprecationWarning() {
|
|
19
|
+
(0, utils_1.logWarningToStderr)(FUNCTIONS_CONFIG_DEPRECATION_MESSAGE);
|
|
20
|
+
}
|
|
21
|
+
exports.logFunctionsConfigDeprecationWarning = logFunctionsConfigDeprecationWarning;
|
|
@@ -7,7 +7,9 @@ const path = require("path");
|
|
|
7
7
|
const prompt_1 = require("../../../prompt");
|
|
8
8
|
const utils = require("../../../utils");
|
|
9
9
|
const logger_1 = require("../../../logger");
|
|
10
|
-
const
|
|
10
|
+
const vsCodeUtils_1 = require("../../../vsCodeUtils");
|
|
11
|
+
const CLI_PROMPTS_DIR = path.join(__dirname, "../../../../prompts");
|
|
12
|
+
const VSCODE_PROMPTS_DIR = path.join(__dirname, "./prompts");
|
|
11
13
|
const FIREBASE_TAG_REGEX = /<firebase_prompts(?:\s+hash="([^"]+)")?>([\s\S]*?)<\/firebase_prompts>/;
|
|
12
14
|
const PROMPT_FILES = {
|
|
13
15
|
base: "FIREBASE.md",
|
|
@@ -92,6 +94,7 @@ function getFeatureContent(feature) {
|
|
|
92
94
|
const filename = PROMPT_FILES[feature];
|
|
93
95
|
if (!filename)
|
|
94
96
|
return "";
|
|
97
|
+
const PROMPTS_DIR = (0, vsCodeUtils_1.isVSCodeExtension)() ? VSCODE_PROMPTS_DIR : CLI_PROMPTS_DIR;
|
|
95
98
|
const content = fs.readFileSync(path.join(PROMPTS_DIR, filename), "utf8");
|
|
96
99
|
return content;
|
|
97
100
|
}
|
|
@@ -4,6 +4,7 @@ exports.actuate = exports.askQuestions = void 0;
|
|
|
4
4
|
const path_1 = require("path");
|
|
5
5
|
const prompt_1 = require("../../../prompt");
|
|
6
6
|
const templates_1 = require("../../../templates");
|
|
7
|
+
const ensureProjectConfigured_1 = require("../../../apptesting/ensureProjectConfigured");
|
|
7
8
|
const SMOKE_TEST_YAML_TEMPLATE = (0, templates_1.readTemplateSync)("init/apptesting/smoke_test.yaml");
|
|
8
9
|
async function askQuestions(setup) {
|
|
9
10
|
var _a, _b;
|
|
@@ -14,6 +15,9 @@ async function askQuestions(setup) {
|
|
|
14
15
|
default: "tests",
|
|
15
16
|
})),
|
|
16
17
|
} });
|
|
18
|
+
if (setup.projectId) {
|
|
19
|
+
await (0, ensureProjectConfigured_1.ensureProjectConfigured)(setup.projectId);
|
|
20
|
+
}
|
|
17
21
|
}
|
|
18
22
|
exports.askQuestions = askQuestions;
|
|
19
23
|
async function actuate(setup, config) {
|
package/lib/mcp/errors.js
CHANGED
|
@@ -3,8 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.mcpGeminiError = exports.mcpAuthError = exports.NO_PROJECT_ERROR = void 0;
|
|
4
4
|
const util_1 = require("./util");
|
|
5
5
|
exports.NO_PROJECT_ERROR = (0, util_1.mcpError)('No active project was found. Use the `firebase_update_environment` tool to set the project directory to an absolute folder location containing a firebase.json config file. Alternatively, change the MCP server config to add [...,"--dir","/absolute/path/to/project/directory"] in its command-line arguments.', "PRECONDITION_FAILED");
|
|
6
|
-
function mcpAuthError() {
|
|
6
|
+
function mcpAuthError(skipADC) {
|
|
7
7
|
const cmd = (0, util_1.commandExistsSync)("firebase") ? "firebase" : "npx -y firebase-tools";
|
|
8
|
+
if (skipADC) {
|
|
9
|
+
return (0, util_1.mcpError)(`The user is not currently logged into the Firebase CLI, which is required to use this tool. Please instruct the user to execute this shell command to sign in.
|
|
10
|
+
\`\`\`sh
|
|
11
|
+
${cmd} login
|
|
12
|
+
\`\`\``);
|
|
13
|
+
}
|
|
8
14
|
return (0, util_1.mcpError)(`The user is not currently logged into the Firebase CLI, which is required to use this tool. Please instruct the user to execute this shell command to sign in or to configure [Application Default Credentials][ADC] on their machine.
|
|
9
15
|
\`\`\`sh
|
|
10
16
|
${cmd} login
|