firebase-tools 14.2.2 → 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/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/init.js +41 -58
- package/lib/commands/login.js +1 -5
- package/lib/commands/logout.js +2 -3
- 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 +4 -13
- package/lib/emulator/controller.js +1 -2
- package/lib/emulator/downloadableEmulators.js +12 -12
- package/lib/emulator/initEmulators.js +9 -20
- 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 +1 -2
- 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 +29 -1
- package/lib/gif/fdcExperience.js +45 -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 +15 -22
- 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/management/apps.js +19 -44
- package/lib/management/projects.js +17 -28
- package/lib/mcp/index.js +12 -1
- package/lib/mcp/tools/auth/index.js +7 -1
- 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/index.js +6 -1
- 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 +11 -1
- package/lib/mcp/tools/firestore/{get_documents.js → get_firestore_documents.js} +5 -5
- package/lib/mcp/tools/firestore/index.js +7 -3
- package/lib/mcp/tools/firestore/{list_collections.js → list_firestore_collections.js} +3 -3
- package/lib/mcp/tools/index.js +2 -1
- package/lib/mcp/tools/storage/get_storage_rules.js +26 -0
- package/lib/mcp/tools/storage/index.js +5 -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 +2 -3
|
@@ -13,9 +13,7 @@ async function doSetup(setup, config) {
|
|
|
13
13
|
logger_1.logger.info("uploads and downloads. You can keep these rules in your project directory");
|
|
14
14
|
logger_1.logger.info("and publish them with " + clc.bold("firebase deploy") + ".");
|
|
15
15
|
logger_1.logger.info();
|
|
16
|
-
const storageRulesFile = await (0, prompt_1.
|
|
17
|
-
type: "input",
|
|
18
|
-
name: "rules",
|
|
16
|
+
const storageRulesFile = await (0, prompt_1.input)({
|
|
19
17
|
message: "What file should be used for Storage Rules?",
|
|
20
18
|
default: "storage.rules",
|
|
21
19
|
});
|
package/lib/management/apps.js
CHANGED
|
@@ -11,23 +11,20 @@ const logger_1 = require("../logger");
|
|
|
11
11
|
const operation_poller_1 = require("../operation-poller");
|
|
12
12
|
const types_1 = require("../dataconnect/types");
|
|
13
13
|
const projectUtils_1 = require("../projectUtils");
|
|
14
|
-
const
|
|
14
|
+
const prompt = require("../prompt");
|
|
15
15
|
const projects_1 = require("./projects");
|
|
16
16
|
const fileUtils_1 = require("../dataconnect/fileUtils");
|
|
17
17
|
const utils_1 = require("../utils");
|
|
18
18
|
const TIMEOUT_MILLIS = 30000;
|
|
19
19
|
exports.APP_LIST_PAGE_SIZE = 100;
|
|
20
20
|
const CREATE_APP_API_REQUEST_TIMEOUT_MILLIS = 15000;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
default: "",
|
|
25
|
-
message: "What would you like to call your app?",
|
|
26
|
-
};
|
|
21
|
+
async function getDisplayName() {
|
|
22
|
+
return await prompt.input("What would you like to call your app?");
|
|
23
|
+
}
|
|
27
24
|
async function getPlatform(appDir, config) {
|
|
28
25
|
let targetPlatform = await (0, fileUtils_1.getPlatformFromFolder)(appDir);
|
|
29
26
|
if (targetPlatform === types_1.Platform.NONE) {
|
|
30
|
-
appDir = await (0,
|
|
27
|
+
appDir = await (0, utils_1.promptForDirectory)({
|
|
31
28
|
config,
|
|
32
29
|
relativeTo: appDir,
|
|
33
30
|
message: "We couldn't determine what kind of app you're using. Where is your app directory?",
|
|
@@ -46,9 +43,8 @@ async function getPlatform(appDir, config) {
|
|
|
46
43
|
{ name: "Web (JavaScript)", value: types_1.Platform.WEB },
|
|
47
44
|
{ name: "Android (Kotlin)", value: types_1.Platform.ANDROID },
|
|
48
45
|
];
|
|
49
|
-
targetPlatform = await
|
|
46
|
+
targetPlatform = await prompt.select({
|
|
50
47
|
message: "Which platform do you want to set up an SDK for? Note: We currently do not support automatically setting up C++ or Unity projects.",
|
|
51
|
-
type: "list",
|
|
52
48
|
choices: platforms,
|
|
53
49
|
});
|
|
54
50
|
}
|
|
@@ -69,21 +65,11 @@ https://firebase.google.com/docs/flutter/setup
|
|
|
69
65
|
exports.getPlatform = getPlatform;
|
|
70
66
|
async function initiateIosAppCreation(options) {
|
|
71
67
|
if (!options.nonInteractive) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
name: "bundleId",
|
|
78
|
-
message: "Please specify your iOS app bundle ID:",
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
type: "input",
|
|
82
|
-
default: "",
|
|
83
|
-
name: "appStoreId",
|
|
84
|
-
message: "Please specify your iOS app App Store ID:",
|
|
85
|
-
},
|
|
86
|
-
]);
|
|
68
|
+
options.displayName = options.displayName || (await getDisplayName());
|
|
69
|
+
options.bundleId =
|
|
70
|
+
options.bundleId || (await prompt.input("Please specify your iOS app bundle ID:"));
|
|
71
|
+
options.appStoreId =
|
|
72
|
+
options.appStoreId || (await prompt.input("Please specify your iOS app App Store ID:"));
|
|
87
73
|
}
|
|
88
74
|
if (!options.bundleId) {
|
|
89
75
|
throw new error_1.FirebaseError("Bundle ID for iOS app cannot be empty");
|
|
@@ -105,15 +91,9 @@ async function initiateIosAppCreation(options) {
|
|
|
105
91
|
}
|
|
106
92
|
async function initiateAndroidAppCreation(options) {
|
|
107
93
|
if (!options.nonInteractive) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
type: "input",
|
|
112
|
-
default: "",
|
|
113
|
-
name: "packageName",
|
|
114
|
-
message: "Please specify your Android app package name:",
|
|
115
|
-
},
|
|
116
|
-
]);
|
|
94
|
+
options.displayName = options.displayName || (await getDisplayName());
|
|
95
|
+
options.packageName =
|
|
96
|
+
options.packageName || (await prompt.input("Please specify your Android app package name:"));
|
|
117
97
|
}
|
|
118
98
|
if (!options.packageName) {
|
|
119
99
|
throw new error_1.FirebaseError("Package name for Android app cannot be empty");
|
|
@@ -134,7 +114,7 @@ async function initiateAndroidAppCreation(options) {
|
|
|
134
114
|
}
|
|
135
115
|
async function initiateWebAppCreation(options) {
|
|
136
116
|
if (!options.nonInteractive) {
|
|
137
|
-
|
|
117
|
+
options.displayName = options.displayName || (await getDisplayName());
|
|
138
118
|
}
|
|
139
119
|
if (!options.displayName) {
|
|
140
120
|
throw new error_1.FirebaseError("Display name for Web app cannot be empty");
|
|
@@ -198,8 +178,7 @@ async function selectAppInteractively(apps, appPlatform) {
|
|
|
198
178
|
value: app,
|
|
199
179
|
};
|
|
200
180
|
});
|
|
201
|
-
return await
|
|
202
|
-
type: "list",
|
|
181
|
+
return await prompt.select({
|
|
203
182
|
message: `Select the ${appPlatform === AppPlatform.ANY ? "" : appPlatform + " "}` +
|
|
204
183
|
"app to get the configuration data:",
|
|
205
184
|
choices,
|
|
@@ -436,11 +415,7 @@ async function writeConfigToFile(filename, nonInteractive, fileContents) {
|
|
|
436
415
|
if (nonInteractive) {
|
|
437
416
|
throw new error_1.FirebaseError(`${filename} already exists`);
|
|
438
417
|
}
|
|
439
|
-
const overwrite = await (
|
|
440
|
-
type: "confirm",
|
|
441
|
-
default: false,
|
|
442
|
-
message: `${filename} already exists. Do you want to overwrite?`,
|
|
443
|
-
});
|
|
418
|
+
const overwrite = await prompt.confirm(`${filename} already exists. Do you want to overwrite?`);
|
|
444
419
|
if (!overwrite) {
|
|
445
420
|
return false;
|
|
446
421
|
}
|
|
@@ -544,7 +519,7 @@ async function findIntelligentPathForIOS(appDir, options) {
|
|
|
544
519
|
}
|
|
545
520
|
let outputPath = null;
|
|
546
521
|
if (!options.nonInteractive) {
|
|
547
|
-
outputPath = await (0,
|
|
522
|
+
outputPath = await (0, utils_1.promptForDirectory)({
|
|
548
523
|
config: options.config,
|
|
549
524
|
message: `We weren't able to automatically determine the output directory. Where would you like to output your config file?`,
|
|
550
525
|
relativeTo: appDir,
|
|
@@ -579,7 +554,7 @@ async function findIntelligentPathForAndroid(appDir, options) {
|
|
|
579
554
|
return module;
|
|
580
555
|
}
|
|
581
556
|
if (!options.nonInteractive) {
|
|
582
|
-
module = await (0,
|
|
557
|
+
module = await (0, utils_1.promptForDirectory)({
|
|
583
558
|
config: options.config,
|
|
584
559
|
message: `We weren't able to automatically determine the output directory. Where would you like to output your config file?`,
|
|
585
560
|
});
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getProject = exports.getFirebaseProject = exports.listFirebaseProjects = exports.getAvailableCloudProjectPage = exports.getFirebaseProjectPage = exports.addFirebaseToCloudProject = exports.createCloudProject = exports.promptAvailableProjectId = exports.getOrPromptProject = exports.addFirebaseToCloudProjectAndLog = exports.createFirebaseProjectAndLog = exports.
|
|
3
|
+
exports.getProject = exports.getFirebaseProject = exports.listFirebaseProjects = exports.getAvailableCloudProjectPage = exports.getFirebaseProjectPage = exports.addFirebaseToCloudProject = exports.createCloudProject = exports.promptAvailableProjectId = exports.getOrPromptProject = exports.addFirebaseToCloudProjectAndLog = exports.createFirebaseProjectAndLog = exports.promptProjectCreation = exports.ProjectParentResourceType = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
5
|
const ora = require("ora");
|
|
6
6
|
const apiv2_1 = require("../apiv2");
|
|
7
7
|
const error_1 = require("../error");
|
|
8
8
|
const operation_poller_1 = require("../operation-poller");
|
|
9
|
-
const
|
|
9
|
+
const prompt = require("../prompt");
|
|
10
10
|
const api = require("../api");
|
|
11
11
|
const logger_1 = require("../logger");
|
|
12
12
|
const utils = require("../utils");
|
|
13
|
+
const ensureApiEnabled_1 = require("../ensureApiEnabled");
|
|
13
14
|
const TIMEOUT_MILLIS = 30000;
|
|
14
15
|
const MAXIMUM_PROMPT_LIST = 100;
|
|
15
16
|
const PROJECT_LIST_PAGE_SIZE = 1000;
|
|
@@ -19,11 +20,8 @@ var ProjectParentResourceType;
|
|
|
19
20
|
ProjectParentResourceType["ORGANIZATION"] = "organization";
|
|
20
21
|
ProjectParentResourceType["FOLDER"] = "folder";
|
|
21
22
|
})(ProjectParentResourceType = exports.ProjectParentResourceType || (exports.ProjectParentResourceType = {}));
|
|
22
|
-
|
|
23
|
-
{
|
|
24
|
-
type: "input",
|
|
25
|
-
name: "projectId",
|
|
26
|
-
default: "",
|
|
23
|
+
async function promptProjectCreation() {
|
|
24
|
+
const projectId = await prompt.input({
|
|
27
25
|
message: "Please specify a unique project id " +
|
|
28
26
|
`(${clc.yellow("warning")}: cannot be modified afterward) [6-30 characters]:\n`,
|
|
29
27
|
validate: (projectId) => {
|
|
@@ -37,11 +35,9 @@ exports.PROJECTS_CREATE_QUESTIONS = [
|
|
|
37
35
|
return true;
|
|
38
36
|
}
|
|
39
37
|
},
|
|
40
|
-
}
|
|
41
|
-
{
|
|
42
|
-
|
|
43
|
-
name: "displayName",
|
|
44
|
-
default: (answers) => answers.projectId,
|
|
38
|
+
});
|
|
39
|
+
const displayName = await prompt.input({
|
|
40
|
+
default: projectId,
|
|
45
41
|
message: "What would you like to call your project? (defaults to your project ID)",
|
|
46
42
|
validate: (displayName) => {
|
|
47
43
|
if (displayName.length < 4) {
|
|
@@ -54,8 +50,10 @@ exports.PROJECTS_CREATE_QUESTIONS = [
|
|
|
54
50
|
return true;
|
|
55
51
|
}
|
|
56
52
|
},
|
|
57
|
-
}
|
|
58
|
-
|
|
53
|
+
});
|
|
54
|
+
return { projectId, displayName };
|
|
55
|
+
}
|
|
56
|
+
exports.promptProjectCreation = promptProjectCreation;
|
|
59
57
|
const firebaseAPIClient = new apiv2_1.Client({
|
|
60
58
|
urlPrefix: api.firebaseApiOrigin(),
|
|
61
59
|
auth: true,
|
|
@@ -130,10 +128,7 @@ async function selectProjectInteractively(pageSize = MAXIMUM_PROMPT_LIST) {
|
|
|
130
128
|
return selectProjectFromList(projects);
|
|
131
129
|
}
|
|
132
130
|
async function selectProjectByPrompting() {
|
|
133
|
-
const projectId = await (
|
|
134
|
-
type: "input",
|
|
135
|
-
message: "Please input the project ID you would like to use:",
|
|
136
|
-
});
|
|
131
|
+
const projectId = await prompt.input("Please input the project ID you would like to use:");
|
|
137
132
|
return await getFirebaseProject(projectId);
|
|
138
133
|
}
|
|
139
134
|
async function selectProjectFromList(projects = []) {
|
|
@@ -150,9 +145,7 @@ async function selectProjectFromList(projects = []) {
|
|
|
150
145
|
utils.logBullet(`Don't want to scroll through all your projects? If you know your project ID, ` +
|
|
151
146
|
`you can initialize it directly using ${clc.bold("firebase init --project <project_id>")}.\n`);
|
|
152
147
|
}
|
|
153
|
-
const projectId = await
|
|
154
|
-
type: "list",
|
|
155
|
-
name: "id",
|
|
148
|
+
const projectId = await prompt.select({
|
|
156
149
|
message: "Select a default Firebase project for this directory:",
|
|
157
150
|
choices,
|
|
158
151
|
});
|
|
@@ -172,10 +165,7 @@ async function promptAvailableProjectId() {
|
|
|
172
165
|
throw new error_1.FirebaseError("There are no available Google Cloud projects to add Firebase services.");
|
|
173
166
|
}
|
|
174
167
|
if (nextPageToken) {
|
|
175
|
-
return await (
|
|
176
|
-
type: "input",
|
|
177
|
-
message: "Please input the ID of the Google Cloud Project you would like to add Firebase:",
|
|
178
|
-
});
|
|
168
|
+
return await prompt.input("Please input the ID of the Google Cloud Project you would like to add Firebase:");
|
|
179
169
|
}
|
|
180
170
|
else {
|
|
181
171
|
const choices = projects
|
|
@@ -188,9 +178,7 @@ async function promptAvailableProjectId() {
|
|
|
188
178
|
};
|
|
189
179
|
})
|
|
190
180
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
191
|
-
return await
|
|
192
|
-
type: "list",
|
|
193
|
-
name: "id",
|
|
181
|
+
return await prompt.select({
|
|
194
182
|
message: "Select the Google Cloud Platform project you would like to add Firebase:",
|
|
195
183
|
choices,
|
|
196
184
|
});
|
|
@@ -348,6 +336,7 @@ async function getFirebaseProject(projectId) {
|
|
|
348
336
|
}
|
|
349
337
|
exports.getFirebaseProject = getFirebaseProject;
|
|
350
338
|
async function getProject(projectId) {
|
|
339
|
+
await (0, ensureApiEnabled_1.ensure)(projectId, api.resourceManagerOrigin(), "firebase", true);
|
|
351
340
|
const response = await resourceManagerClient.get(`/projects/${projectId}`);
|
|
352
341
|
return response.body;
|
|
353
342
|
}
|
package/lib/mcp/index.js
CHANGED
|
@@ -12,6 +12,8 @@ const command_js_1 = require("../command.js");
|
|
|
12
12
|
const requireAuth_js_1 = require("../requireAuth.js");
|
|
13
13
|
const projectUtils_js_1 = require("../projectUtils.js");
|
|
14
14
|
const errors_js_1 = require("./errors.js");
|
|
15
|
+
const track_js_1 = require("../track.js");
|
|
16
|
+
const config_js_1 = require("../config.js");
|
|
15
17
|
const SERVER_VERSION = "0.0.1";
|
|
16
18
|
const PROJECT_ROOT_KEY = "mcp.projectRoot";
|
|
17
19
|
const cmd = new command_js_1.Command("experimental:mcp").before(requireAuth_js_1.requireAuth);
|
|
@@ -44,6 +46,7 @@ class FirebaseMcpServer {
|
|
|
44
46
|
}
|
|
45
47
|
async mcpListTools() {
|
|
46
48
|
const hasActiveProject = !!(await this.getProjectId());
|
|
49
|
+
await (0, track_js_1.trackGA4)("mcp_list_tools", {});
|
|
47
50
|
return {
|
|
48
51
|
tools: this.availableTools.map((t) => t.mcp),
|
|
49
52
|
_meta: {
|
|
@@ -95,9 +98,17 @@ class FirebaseMcpServer {
|
|
|
95
98
|
if (((_b = tool.mcp._meta) === null || _b === void 0 ? void 0 : _b.requiresProject) && !projectId)
|
|
96
99
|
return errors_js_1.NO_PROJECT_ERROR;
|
|
97
100
|
try {
|
|
98
|
-
|
|
101
|
+
const config = config_js_1.Config.load({ cwd: this.projectRoot });
|
|
102
|
+
const res = await tool.fn(toolArgs, {
|
|
103
|
+
projectId: await this.getProjectId(),
|
|
104
|
+
host: this,
|
|
105
|
+
config,
|
|
106
|
+
});
|
|
107
|
+
await (0, track_js_1.trackGA4)("mcp_tool_call", { tool_name: toolName, error: res.isError ? 1 : 0 });
|
|
108
|
+
return res;
|
|
99
109
|
}
|
|
100
110
|
catch (err) {
|
|
111
|
+
await (0, track_js_1.trackGA4)("mcp_tool_call", { tool_name: toolName, error: 1 });
|
|
101
112
|
return (0, util_js_1.mcpError)(err);
|
|
102
113
|
}
|
|
103
114
|
}
|
|
@@ -4,4 +4,10 @@ exports.authTools = void 0;
|
|
|
4
4
|
const get_auth_user_js_1 = require("./get_auth_user.js");
|
|
5
5
|
const disable_auth_user_js_1 = require("./disable_auth_user.js");
|
|
6
6
|
const set_auth_claims_js_1 = require("./set_auth_claims.js");
|
|
7
|
-
|
|
7
|
+
const set_sms_region_policy_js_1 = require("./set_sms_region_policy.js");
|
|
8
|
+
exports.authTools = [
|
|
9
|
+
get_auth_user_js_1.get_auth_user,
|
|
10
|
+
disable_auth_user_js_1.disable_auth_user,
|
|
11
|
+
set_auth_claims_js_1.set_auth_claim,
|
|
12
|
+
set_sms_region_policy_js_1.set_sms_region_policy,
|
|
13
|
+
];
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.set_sms_region_policy = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_js_1 = require("../../tool.js");
|
|
6
|
+
const util_js_1 = require("../../util.js");
|
|
7
|
+
const auth_js_1 = require("../../../gcp/auth.js");
|
|
8
|
+
exports.set_sms_region_policy = (0, tool_js_1.tool)({
|
|
9
|
+
name: "set_sms_region_policy",
|
|
10
|
+
description: "Sets an SMS Region Policy for Firebase Auth to restrict the regions which can receive text messages based on an ALLOW or DENY list of country codes. This policy will override any existing policies when set.",
|
|
11
|
+
inputSchema: zod_1.z.object({
|
|
12
|
+
policy_type: zod_1.z
|
|
13
|
+
.enum(["ALLOW", "DENY"])
|
|
14
|
+
.describe("with an ALLOW policy, only the specified country codes can use SMS auth. with a DENY policy, all countries can use SMS auth except the ones specified"),
|
|
15
|
+
country_codes: zod_1.z
|
|
16
|
+
.array(zod_1.z.string())
|
|
17
|
+
.describe("the country codes to allow or deny based on ISO 3166"),
|
|
18
|
+
}),
|
|
19
|
+
annotations: {
|
|
20
|
+
title: "Set the SMS Region Policy on your Firebase Project",
|
|
21
|
+
idempotentHint: true,
|
|
22
|
+
destructiveHint: true,
|
|
23
|
+
},
|
|
24
|
+
_meta: {
|
|
25
|
+
requiresProject: true,
|
|
26
|
+
requiresAuth: true,
|
|
27
|
+
},
|
|
28
|
+
}, async ({ policy_type, country_codes }, { projectId }) => {
|
|
29
|
+
country_codes = country_codes.map((code) => {
|
|
30
|
+
return code.toUpperCase();
|
|
31
|
+
});
|
|
32
|
+
if (policy_type === "ALLOW") {
|
|
33
|
+
return (0, util_js_1.toContent)(await (0, auth_js_1.setAllowSmsRegionPolicy)(projectId, country_codes));
|
|
34
|
+
}
|
|
35
|
+
return (0, util_js_1.toContent)(await (0, auth_js_1.setDenySmsRegionPolicy)(projectId, country_codes));
|
|
36
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.consult_firebase_assistant = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_js_1 = require("../../tool.js");
|
|
6
|
+
const util_js_1 = require("../../util.js");
|
|
7
|
+
const fdcExperience_js_1 = require("../../../gif/fdcExperience.js");
|
|
8
|
+
exports.consult_firebase_assistant = (0, tool_js_1.tool)({
|
|
9
|
+
name: "consult_firebase_assistant",
|
|
10
|
+
description: "Send a question to an AI assistant specifically enhanced to answer Firebase questions.",
|
|
11
|
+
inputSchema: zod_1.z.object({
|
|
12
|
+
prompt: zod_1.z
|
|
13
|
+
.string()
|
|
14
|
+
.describe("A description of what the user is trying to do or learn with Firebase."),
|
|
15
|
+
}),
|
|
16
|
+
annotations: {
|
|
17
|
+
title: "Helps answer queries and provide information related to Firebase.",
|
|
18
|
+
readOnlyHint: true,
|
|
19
|
+
},
|
|
20
|
+
_meta: {
|
|
21
|
+
requiresProject: true,
|
|
22
|
+
requiresAuth: true,
|
|
23
|
+
},
|
|
24
|
+
}, async ({ prompt }, { projectId }) => {
|
|
25
|
+
const schema = await (0, fdcExperience_js_1.chatWithFirebase)(prompt, projectId);
|
|
26
|
+
return (0, util_js_1.toContent)(schema);
|
|
27
|
+
});
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.coreTools = void 0;
|
|
4
|
+
const consult_firebase_assistant_1 = require("./consult_firebase_assistant");
|
|
4
5
|
const get_firebase_directory_1 = require("./get_firebase_directory");
|
|
5
6
|
const set_firebase_directory_1 = require("./set_firebase_directory");
|
|
6
|
-
exports.coreTools = [
|
|
7
|
+
exports.coreTools = [
|
|
8
|
+
get_firebase_directory_1.get_firebase_directory,
|
|
9
|
+
set_firebase_directory_1.set_firebase_directory,
|
|
10
|
+
consult_firebase_assistant_1.consult_firebase_assistant,
|
|
11
|
+
];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sourceToText = exports.connectorToText = exports.schemaToText = void 0;
|
|
4
|
+
const js_yaml_1 = require("js-yaml");
|
|
5
|
+
function schemaToText(s) {
|
|
6
|
+
return ((0, js_yaml_1.dump)({
|
|
7
|
+
name: s.name,
|
|
8
|
+
datasources: s.datasources,
|
|
9
|
+
}) +
|
|
10
|
+
"\n\n" +
|
|
11
|
+
sourceToText(s.source));
|
|
12
|
+
}
|
|
13
|
+
exports.schemaToText = schemaToText;
|
|
14
|
+
function connectorToText(s) {
|
|
15
|
+
return ((0, js_yaml_1.dump)({
|
|
16
|
+
name: s.name,
|
|
17
|
+
}) +
|
|
18
|
+
"\n\n" +
|
|
19
|
+
sourceToText(s.source));
|
|
20
|
+
}
|
|
21
|
+
exports.connectorToText = connectorToText;
|
|
22
|
+
function sourceToText(s) {
|
|
23
|
+
var _a;
|
|
24
|
+
let output = "";
|
|
25
|
+
(_a = s.files) === null || _a === void 0 ? void 0 : _a.forEach((f) => {
|
|
26
|
+
output += `\n# ${f.path}`;
|
|
27
|
+
output += "\n```graphql\n";
|
|
28
|
+
output += `${f.content.trim()}\n`;
|
|
29
|
+
output += "```\n";
|
|
30
|
+
});
|
|
31
|
+
return output;
|
|
32
|
+
}
|
|
33
|
+
exports.sourceToText = sourceToText;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generate_dataconnect_operation = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_js_1 = require("../../tool.js");
|
|
6
|
+
const util_js_1 = require("../../util.js");
|
|
7
|
+
const fdcExperience_js_1 = require("../../../gif/fdcExperience.js");
|
|
8
|
+
const fileUtils_js_1 = require("../../../dataconnect/fileUtils.js");
|
|
9
|
+
exports.generate_dataconnect_operation = (0, tool_js_1.tool)({
|
|
10
|
+
name: "generate_dataconnect_operation",
|
|
11
|
+
description: "Generates a single Firebase Data Connect query or mutation based on the currently deployed schema and the provided prompt.",
|
|
12
|
+
inputSchema: zod_1.z.object({
|
|
13
|
+
prompt: zod_1.z
|
|
14
|
+
.string()
|
|
15
|
+
.describe("Write the prompt like you're talking to a person, describe the task you're trying to accomplish and give details that are specific to the users requst"),
|
|
16
|
+
serviceId: zod_1.z
|
|
17
|
+
.string()
|
|
18
|
+
.nullish()
|
|
19
|
+
.describe("Optional: Uses the serviceId from the firebase.json file if nothing provided. The serviceId of the deployed Firebase resource."),
|
|
20
|
+
}),
|
|
21
|
+
annotations: {
|
|
22
|
+
title: "Generate a Firebase Data Connect Operation on a deployed Firebase Data Connect Schema.",
|
|
23
|
+
readOnlyHint: true,
|
|
24
|
+
},
|
|
25
|
+
_meta: {
|
|
26
|
+
requiresProject: true,
|
|
27
|
+
requiresAuth: true,
|
|
28
|
+
},
|
|
29
|
+
}, async ({ prompt, serviceId }, { projectId, config }) => {
|
|
30
|
+
const serviceInfo = await (0, fileUtils_js_1.pickService)(projectId, config, serviceId || undefined);
|
|
31
|
+
const schema = await (0, fdcExperience_js_1.generateOperation)(prompt, serviceInfo.serviceName, projectId);
|
|
32
|
+
return (0, util_js_1.toContent)(schema);
|
|
33
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generate_dataconnect_schema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_js_1 = require("../../tool.js");
|
|
6
|
+
const util_js_1 = require("../../util.js");
|
|
7
|
+
const fdcExperience_js_1 = require("../../../gif/fdcExperience.js");
|
|
8
|
+
exports.generate_dataconnect_schema = (0, tool_js_1.tool)({
|
|
9
|
+
name: "generate_dataconnect_schema",
|
|
10
|
+
description: "Generates a Firebase Data Connect Schema based on the users description of an app.",
|
|
11
|
+
inputSchema: zod_1.z.object({
|
|
12
|
+
prompt: zod_1.z.string().describe("A description of an app that you are interested in building"),
|
|
13
|
+
}),
|
|
14
|
+
annotations: {
|
|
15
|
+
title: "Generate a Firebase Data Connect Schema for a new Firebase project.",
|
|
16
|
+
readOnlyHint: true,
|
|
17
|
+
},
|
|
18
|
+
_meta: {
|
|
19
|
+
requiresProject: true,
|
|
20
|
+
requiresAuth: true,
|
|
21
|
+
},
|
|
22
|
+
}, async ({ prompt }, { projectId }) => {
|
|
23
|
+
const schema = await (0, fdcExperience_js_1.generateSchema)(prompt, projectId);
|
|
24
|
+
return (0, util_js_1.toContent)(schema);
|
|
25
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.get_dataconnect_connector = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_js_1 = require("../../tool.js");
|
|
6
|
+
const util_js_1 = require("../../util.js");
|
|
7
|
+
const client = require("../../../dataconnect/client");
|
|
8
|
+
const fileUtils_js_1 = require("../../../dataconnect/fileUtils.js");
|
|
9
|
+
const converter_js_1 = require("./converter.js");
|
|
10
|
+
exports.get_dataconnect_connector = (0, tool_js_1.tool)({
|
|
11
|
+
name: "get_dataconnect_connector",
|
|
12
|
+
description: "Get the Firebase Data Connect Connectors in the project, which includes the pre-defined GraphQL queries accessible to client SDKs.",
|
|
13
|
+
inputSchema: zod_1.z.object({
|
|
14
|
+
serviceId: zod_1.z
|
|
15
|
+
.string()
|
|
16
|
+
.nullable()
|
|
17
|
+
.describe("The Firebase Data Connect service ID to look for. By default, it would pick the the service ID project directory."),
|
|
18
|
+
}),
|
|
19
|
+
annotations: {
|
|
20
|
+
title: "Obtain the Firebase Data Connect Connectors that's available in the backend",
|
|
21
|
+
readOnlyHint: true,
|
|
22
|
+
},
|
|
23
|
+
_meta: {
|
|
24
|
+
requiresProject: true,
|
|
25
|
+
requiresAuth: true,
|
|
26
|
+
},
|
|
27
|
+
}, async ({ serviceId }, { projectId, config }) => {
|
|
28
|
+
const serviceInfo = await (0, fileUtils_js_1.pickService)(projectId, config, serviceId || undefined);
|
|
29
|
+
const connectors = await client.listConnectors(serviceInfo.serviceName, ["*"]);
|
|
30
|
+
return (0, util_js_1.toContent)(connectors.map(converter_js_1.connectorToText).join("\n\n"));
|
|
31
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.get_dataconnect_schema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_js_1 = require("../../tool.js");
|
|
6
|
+
const util_js_1 = require("../../util.js");
|
|
7
|
+
const client = require("../../../dataconnect/client");
|
|
8
|
+
const fileUtils_js_1 = require("../../../dataconnect/fileUtils.js");
|
|
9
|
+
const converter_js_1 = require("./converter.js");
|
|
10
|
+
exports.get_dataconnect_schema = (0, tool_js_1.tool)({
|
|
11
|
+
name: "get_dataconnect_schema",
|
|
12
|
+
description: "List the Firebase Data Connect Schema in the project, which includes Cloud SQL data sources and the GraphQL Schema describing what tables are available.",
|
|
13
|
+
inputSchema: zod_1.z.object({
|
|
14
|
+
serviceId: zod_1.z
|
|
15
|
+
.string()
|
|
16
|
+
.nullable()
|
|
17
|
+
.describe("The Firebase Data Connect service ID to look for. By default, it would pick the the service ID project directory."),
|
|
18
|
+
}),
|
|
19
|
+
annotations: {
|
|
20
|
+
title: "Obtain the Firebase Data Connect Schemas that's available in the backend",
|
|
21
|
+
readOnlyHint: true,
|
|
22
|
+
},
|
|
23
|
+
_meta: {
|
|
24
|
+
requiresProject: true,
|
|
25
|
+
requiresAuth: true,
|
|
26
|
+
},
|
|
27
|
+
}, async ({ serviceId }, { projectId, config }) => {
|
|
28
|
+
const serviceInfo = await (0, fileUtils_js_1.pickService)(projectId, config, serviceId || undefined);
|
|
29
|
+
const schemas = await client.listSchemas(serviceInfo.serviceName, ["*"]);
|
|
30
|
+
return (0, util_js_1.toContent)(schemas === null || schemas === void 0 ? void 0 : schemas.map(converter_js_1.schemaToText).join("\n\n"));
|
|
31
|
+
});
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.dataconnectTools = void 0;
|
|
4
|
+
const generate_dataconnect_operation_js_1 = require("./generate_dataconnect_operation.js");
|
|
5
|
+
const generate_dataconnect_schema_js_1 = require("./generate_dataconnect_schema.js");
|
|
4
6
|
const list_dataconnect_services_js_1 = require("./list_dataconnect_services.js");
|
|
5
|
-
|
|
7
|
+
const get_dataconnect_schema_js_1 = require("./get_dataconnect_schema.js");
|
|
8
|
+
const get_dataconnect_connector_js_1 = require("./get_dataconnect_connector.js");
|
|
9
|
+
exports.dataconnectTools = [
|
|
10
|
+
list_dataconnect_services_js_1.list_dataconnect_services,
|
|
11
|
+
generate_dataconnect_schema_js_1.generate_dataconnect_schema,
|
|
12
|
+
generate_dataconnect_operation_js_1.generate_dataconnect_operation,
|
|
13
|
+
get_dataconnect_schema_js_1.get_dataconnect_schema,
|
|
14
|
+
get_dataconnect_connector_js_1.get_dataconnect_connector,
|
|
15
|
+
];
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.get_firestore_documents = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const tool_js_1 = require("../../tool.js");
|
|
6
6
|
const util_js_1 = require("../../util.js");
|
|
7
7
|
const firestore_js_1 = require("../../../gcp/firestore.js");
|
|
8
8
|
const converter_js_1 = require("./converter.js");
|
|
9
|
-
exports.
|
|
10
|
-
name: "
|
|
9
|
+
exports.get_firestore_documents = (0, tool_js_1.tool)({
|
|
10
|
+
name: "get_firestore_documents",
|
|
11
11
|
description: "Retrieves one or more Firestore documents from a database in the current project by full document paths. Use this if you know the exact path of a document.",
|
|
12
12
|
inputSchema: zod_1.z.object({
|
|
13
13
|
paths: zod_1.z
|
|
@@ -23,10 +23,10 @@ exports.get_documents = (0, tool_js_1.tool)({
|
|
|
23
23
|
requiresProject: true,
|
|
24
24
|
},
|
|
25
25
|
}, async ({ paths }, { projectId }) => {
|
|
26
|
-
if (!paths.length)
|
|
26
|
+
if (!paths || !paths.length)
|
|
27
27
|
return (0, util_js_1.mcpError)("Must supply at least one document path.");
|
|
28
28
|
const { documents, missing } = await (0, firestore_js_1.getDocuments)(projectId, paths);
|
|
29
|
-
if (missing.length > 0 && documents.length === 0) {
|
|
29
|
+
if (missing.length > 0 && documents && documents.length === 0) {
|
|
30
30
|
return (0, util_js_1.mcpError)(`None of the specified documents were found in project '${projectId}'`);
|
|
31
31
|
}
|
|
32
32
|
const docs = documents.map(converter_js_1.firestoreDocumentToJson);
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.firestoreTools = void 0;
|
|
4
|
-
const
|
|
4
|
+
const get_firestore_documents_1 = require("./get_firestore_documents");
|
|
5
5
|
const get_firestore_rules_1 = require("./get_firestore_rules");
|
|
6
|
-
const
|
|
7
|
-
exports.firestoreTools = [
|
|
6
|
+
const list_firestore_collections_1 = require("./list_firestore_collections");
|
|
7
|
+
exports.firestoreTools = [
|
|
8
|
+
list_firestore_collections_1.list_firestore_collections,
|
|
9
|
+
get_firestore_documents_1.get_firestore_documents,
|
|
10
|
+
get_firestore_rules_1.get_firestore_rules,
|
|
11
|
+
];
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.list_firestore_collections = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const tool_js_1 = require("../../tool.js");
|
|
6
6
|
const util_js_1 = require("../../util.js");
|
|
7
7
|
const firestore_js_1 = require("../../../gcp/firestore.js");
|
|
8
8
|
const errors_js_1 = require("../../errors.js");
|
|
9
|
-
exports.
|
|
10
|
-
name: "
|
|
9
|
+
exports.list_firestore_collections = (0, tool_js_1.tool)({
|
|
10
|
+
name: "list_firestore_collections",
|
|
11
11
|
description: "Retrieves a list of collections from a Firestore database in the current project.",
|
|
12
12
|
inputSchema: zod_1.z.object({
|
|
13
13
|
document_path: zod_1.z
|
package/lib/mcp/tools/index.js
CHANGED
|
@@ -5,10 +5,11 @@ const index_js_1 = require("./auth/index.js");
|
|
|
5
5
|
const index_js_2 = require("./dataconnect/index.js");
|
|
6
6
|
const index_js_3 = require("./firestore/index.js");
|
|
7
7
|
const index_js_4 = require("./project/index.js");
|
|
8
|
+
const index_js_5 = require("./storage/index.js");
|
|
8
9
|
exports.tools = {
|
|
9
10
|
project: index_js_4.projectTools,
|
|
10
11
|
firestore: index_js_3.firestoreTools,
|
|
11
12
|
auth: index_js_1.authTools,
|
|
12
13
|
dataconnect: index_js_2.dataconnectTools,
|
|
13
|
-
storage:
|
|
14
|
+
storage: index_js_5.storageTools,
|
|
14
15
|
};
|