firebase-tools 14.6.0 → 14.7.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/commands/functions-list.js +23 -32
- package/lib/commands/init.js +14 -1
- package/lib/crashlytics/listTopIssues.js +2 -1
- package/lib/emulator/commandUtils.js +2 -1
- package/lib/emulator/controller.js +1 -1
- package/lib/emulator/downloadableEmulatorInfo.json +18 -18
- package/lib/gcp/storage.js +8 -4
- package/lib/mcp/index.js +15 -1
- package/lib/mcp/tools/crashlytics/list_top_issues.js +7 -2
- package/lib/mcp/tools/dataconnect/emulator.js +3 -19
- package/lib/mcp/tools/dataconnect/execute_graphql.js +1 -1
- package/lib/mcp/tools/dataconnect/execute_graphql_read.js +1 -1
- package/lib/mcp/tools/dataconnect/execute_mutation.js +1 -1
- package/lib/mcp/tools/dataconnect/execute_query.js +1 -1
- package/lib/mcp/tools/firestore/delete_document.js +2 -2
- package/lib/mcp/tools/firestore/get_documents.js +2 -2
- package/lib/mcp/tools/firestore/list_collections.js +2 -2
- package/lib/mcp/tools/firestore/query_collection.js +2 -2
- package/lib/mcp/tools/storage/get_download_url.js +8 -2
- package/lib/track.js +4 -0
- package/package.json +1 -1
- package/lib/mcp/tools/firestore/emulator.js +0 -16
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.command = void 0;
|
|
4
4
|
const command_1 = require("../command");
|
|
5
|
-
const error_1 = require("../error");
|
|
6
5
|
const projectUtils_1 = require("../projectUtils");
|
|
7
6
|
const requirePermissions_1 = require("../requirePermissions");
|
|
8
7
|
const backend = require("../deploy/functions/backend");
|
|
@@ -12,36 +11,28 @@ exports.command = new command_1.Command("functions:list")
|
|
|
12
11
|
.description("list all deployed functions in your Firebase project")
|
|
13
12
|
.before(requirePermissions_1.requirePermissions, ["cloudfunctions.functions.list"])
|
|
14
13
|
.action(async (options) => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
table.push(entry);
|
|
37
|
-
}
|
|
38
|
-
logger_1.logger.info(table.toString());
|
|
39
|
-
return endpointsList;
|
|
40
|
-
}
|
|
41
|
-
catch (err) {
|
|
42
|
-
throw new error_1.FirebaseError("Failed to list functions", {
|
|
43
|
-
exit: 1,
|
|
44
|
-
original: err,
|
|
45
|
-
});
|
|
14
|
+
const context = {
|
|
15
|
+
projectId: (0, projectUtils_1.needProjectId)(options),
|
|
16
|
+
};
|
|
17
|
+
const existing = await backend.existingBackend(context);
|
|
18
|
+
const endpointsList = backend.allEndpoints(existing).sort(backend.compareFunctions);
|
|
19
|
+
const table = new Table({
|
|
20
|
+
head: ["Function", "Version", "Trigger", "Location", "Memory", "Runtime"],
|
|
21
|
+
style: { head: ["yellow"] },
|
|
22
|
+
});
|
|
23
|
+
for (const endpoint of endpointsList) {
|
|
24
|
+
const trigger = backend.endpointTriggerType(endpoint);
|
|
25
|
+
const availableMemoryMb = endpoint.availableMemoryMb || "---";
|
|
26
|
+
const entry = [
|
|
27
|
+
endpoint.id,
|
|
28
|
+
endpoint.platform === "gcfv2" ? "v2" : "v1",
|
|
29
|
+
trigger,
|
|
30
|
+
endpoint.region,
|
|
31
|
+
availableMemoryMb,
|
|
32
|
+
endpoint.runtime,
|
|
33
|
+
];
|
|
34
|
+
table.push(entry);
|
|
46
35
|
}
|
|
36
|
+
logger_1.logger.info(table.toString());
|
|
37
|
+
return endpointsList;
|
|
47
38
|
});
|
package/lib/commands/init.js
CHANGED
|
@@ -16,6 +16,7 @@ const utils = require("../utils");
|
|
|
16
16
|
const experiments_1 = require("../experiments");
|
|
17
17
|
const templates_1 = require("../templates");
|
|
18
18
|
const error_1 = require("../error");
|
|
19
|
+
const track_1 = require("../track");
|
|
19
20
|
const homeDir = os.homedir();
|
|
20
21
|
const BANNER_TEXT = (0, templates_1.readTemplateSync)("banner.txt");
|
|
21
22
|
const GITIGNORE_TEMPLATE = (0, templates_1.readTemplateSync)("_gitignore");
|
|
@@ -114,13 +115,14 @@ exports.command = new command_1.Command("init [feature]")
|
|
|
114
115
|
.before(requireAuth_1.requireAuth)
|
|
115
116
|
.action(initAction);
|
|
116
117
|
async function initAction(feature, options) {
|
|
117
|
-
var _a;
|
|
118
|
+
var _a, _b;
|
|
118
119
|
if (feature && !featureNames.includes(feature)) {
|
|
119
120
|
return utils.reject(clc.bold(feature) +
|
|
120
121
|
" is not a supported feature; must be one of " +
|
|
121
122
|
featureNames.join(", ") +
|
|
122
123
|
".");
|
|
123
124
|
}
|
|
125
|
+
const start = process.uptime();
|
|
124
126
|
const cwd = options.cwd || process.cwd();
|
|
125
127
|
const warnings = [];
|
|
126
128
|
let warningText = "";
|
|
@@ -168,6 +170,15 @@ async function initAction(feature, options) {
|
|
|
168
170
|
message: "Which Firebase features do you want to set up for this directory? " +
|
|
169
171
|
"Press Space to select features, then Enter to confirm your choices.",
|
|
170
172
|
choices: choices.filter((c) => !c.hidden),
|
|
173
|
+
validate: (choices) => {
|
|
174
|
+
if (choices.length === 0) {
|
|
175
|
+
return ("Must select at least one feature. Use " +
|
|
176
|
+
clc.bold(clc.underline("SPACEBAR")) +
|
|
177
|
+
" to select features, or specify a feature by running " +
|
|
178
|
+
clc.bold("firebase init [feature_name]"));
|
|
179
|
+
}
|
|
180
|
+
return true;
|
|
181
|
+
},
|
|
171
182
|
});
|
|
172
183
|
}
|
|
173
184
|
if (!setup.features || ((_a = setup.features) === null || _a === void 0 ? void 0 : _a.length) === 0) {
|
|
@@ -191,6 +202,8 @@ async function initAction(feature, options) {
|
|
|
191
202
|
if (!fsutils.fileExistsSync(config.path(".gitignore"))) {
|
|
192
203
|
config.writeProjectFile(".gitignore", GITIGNORE_TEMPLATE);
|
|
193
204
|
}
|
|
205
|
+
const duration = Math.floor((process.uptime() - start) * 1000);
|
|
206
|
+
await (0, track_1.trackGA4)("product_init", { products_initialized: (_b = setup.features) === null || _b === void 0 ? void 0 : _b.join(",") }, duration);
|
|
194
207
|
logger_1.logger.info();
|
|
195
208
|
utils.logSuccess("Firebase initialization complete!");
|
|
196
209
|
}
|
|
@@ -10,10 +10,11 @@ const apiClient = new apiv2_1.Client({
|
|
|
10
10
|
urlPrefix: (0, api_1.crashlyticsApiOrigin)(),
|
|
11
11
|
apiVersion: "v1alpha",
|
|
12
12
|
});
|
|
13
|
-
async function listTopIssues(projectId, appId, issueCount) {
|
|
13
|
+
async function listTopIssues(projectId, appId, issueType, issueCount) {
|
|
14
14
|
try {
|
|
15
15
|
const queryParams = new URLSearchParams();
|
|
16
16
|
queryParams.set("page_size", `${issueCount}`);
|
|
17
|
+
queryParams.set("filter.issue.error_types", `${issueType}`);
|
|
17
18
|
const requestProjectId = parseProjectId(appId);
|
|
18
19
|
if (requestProjectId === undefined) {
|
|
19
20
|
throw new error_1.FirebaseError("Unable to get the projectId from the AppId.");
|
|
@@ -92,7 +92,8 @@ async function beforeEmulatorCommand(options) {
|
|
|
92
92
|
const canStartWithoutConfig = options.only &&
|
|
93
93
|
!controller.shouldStart(optionsWithConfig, types_1.Emulators.FUNCTIONS) &&
|
|
94
94
|
!controller.shouldStart(optionsWithConfig, types_1.Emulators.HOSTING);
|
|
95
|
-
if (!constants_1.Constants.isDemoProject(options.project)
|
|
95
|
+
if (!constants_1.Constants.isDemoProject(options.project) ||
|
|
96
|
+
controller.shouldStart(optionsWithConfig, types_1.Emulators.EXTENSIONS)) {
|
|
96
97
|
try {
|
|
97
98
|
await (0, requireAuth_1.requireAuth)(options);
|
|
98
99
|
}
|
|
@@ -740,7 +740,7 @@ async function exportEmulatorData(exportPath, options, initiatedBy) {
|
|
|
740
740
|
const exportAbsPath = path.resolve(exportPath);
|
|
741
741
|
if (!fs.existsSync(exportAbsPath)) {
|
|
742
742
|
utils.logBullet(`Creating export directory ${exportAbsPath}`);
|
|
743
|
-
fs.mkdirSync(exportAbsPath);
|
|
743
|
+
fs.mkdirSync(exportAbsPath, { recursive: true });
|
|
744
744
|
}
|
|
745
745
|
const existingMetadata = hubExport_1.HubExport.readMetadata(exportAbsPath);
|
|
746
746
|
const isExportDirEmpty = fs.readdirSync(exportAbsPath).length === 0;
|
|
@@ -54,28 +54,28 @@
|
|
|
54
54
|
},
|
|
55
55
|
"dataconnect": {
|
|
56
56
|
"darwin": {
|
|
57
|
-
"version": "2.
|
|
58
|
-
"expectedSize":
|
|
59
|
-
"expectedChecksum": "
|
|
60
|
-
"expectedChecksumSHA256": "
|
|
61
|
-
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-v2.
|
|
62
|
-
"downloadPathRelativeToCacheDir": "dataconnect-emulator-2.
|
|
57
|
+
"version": "2.7.0",
|
|
58
|
+
"expectedSize": 27542272,
|
|
59
|
+
"expectedChecksum": "8b68e45ccae2d2cf35bea368e7ce379c",
|
|
60
|
+
"expectedChecksumSHA256": "6dce6ea23c39e4e44dbaa6db7181c9d7761dd1098589a627fa5aa0fb4a07ccd7",
|
|
61
|
+
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-v2.7.0",
|
|
62
|
+
"downloadPathRelativeToCacheDir": "dataconnect-emulator-2.7.0"
|
|
63
63
|
},
|
|
64
64
|
"win32": {
|
|
65
|
-
"version": "2.
|
|
66
|
-
"expectedSize":
|
|
67
|
-
"expectedChecksum": "
|
|
68
|
-
"expectedChecksumSHA256": "
|
|
69
|
-
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-windows-v2.
|
|
70
|
-
"downloadPathRelativeToCacheDir": "dataconnect-emulator-2.
|
|
65
|
+
"version": "2.7.0",
|
|
66
|
+
"expectedSize": 28001280,
|
|
67
|
+
"expectedChecksum": "03ef2fd3ed2f7263539f1a9d7b748ee6",
|
|
68
|
+
"expectedChecksumSHA256": "3462f15ddc5d11371774de8f19b54468eb75eefac5f3a5623334f42154f06bc8",
|
|
69
|
+
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-windows-v2.7.0",
|
|
70
|
+
"downloadPathRelativeToCacheDir": "dataconnect-emulator-2.7.0.exe"
|
|
71
71
|
},
|
|
72
72
|
"linux": {
|
|
73
|
-
"version": "2.
|
|
74
|
-
"expectedSize":
|
|
75
|
-
"expectedChecksum": "
|
|
76
|
-
"expectedChecksumSHA256": "
|
|
77
|
-
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-linux-v2.
|
|
78
|
-
"downloadPathRelativeToCacheDir": "dataconnect-emulator-2.
|
|
73
|
+
"version": "2.7.0",
|
|
74
|
+
"expectedSize": 27451544,
|
|
75
|
+
"expectedChecksum": "8b73f21f1bdf168a5f2c3137c30abc7b",
|
|
76
|
+
"expectedChecksumSHA256": "e2d03d1d0524f8053b34376c8ad6ea1fdfb8bc48568e80a35c2e3e510754c121",
|
|
77
|
+
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-linux-v2.7.0",
|
|
78
|
+
"downloadPathRelativeToCacheDir": "dataconnect-emulator-2.7.0"
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
}
|
package/lib/gcp/storage.js
CHANGED
|
@@ -143,15 +143,19 @@ async function getServiceAccount(projectId) {
|
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
exports.getServiceAccount = getServiceAccount;
|
|
146
|
-
async function getDownloadUrl(bucketName, objectPath) {
|
|
146
|
+
async function getDownloadUrl(bucketName, objectPath, emulatorUrl) {
|
|
147
147
|
try {
|
|
148
|
-
const
|
|
148
|
+
const origin = emulatorUrl || (0, api_1.firebaseStorageOrigin)();
|
|
149
|
+
const localAPIClient = new apiv2_1.Client({ urlPrefix: origin });
|
|
149
150
|
const response = await localAPIClient.get(`/v0/b/${bucketName}/o/${encodeURIComponent(objectPath)}`);
|
|
151
|
+
if (emulatorUrl) {
|
|
152
|
+
return `${origin}/v0/b/${bucketName}/o/${encodeURIComponent(objectPath)}?alt=media`;
|
|
153
|
+
}
|
|
150
154
|
if (!response.body.downloadTokens) {
|
|
151
|
-
throw new Error(
|
|
155
|
+
throw new Error(`no download tokens exist for ${objectPath}, please visit the Firebase console to make one`);
|
|
152
156
|
}
|
|
153
157
|
const [token] = response.body.downloadTokens.split(",");
|
|
154
|
-
return `${
|
|
158
|
+
return `${origin}/v0/b/${bucketName}/o/${encodeURIComponent(objectPath)}?alt=media&token=${token}`;
|
|
155
159
|
}
|
|
156
160
|
catch (err) {
|
|
157
161
|
logger_1.logger.error(err);
|
package/lib/mcp/index.js
CHANGED
|
@@ -102,6 +102,19 @@ class FirebaseMcpServer {
|
|
|
102
102
|
this.emulatorHubClient = new hubClient_js_1.EmulatorHubClient(projectId);
|
|
103
103
|
return this.emulatorHubClient;
|
|
104
104
|
}
|
|
105
|
+
async getEmulatorUrl(emulatorType) {
|
|
106
|
+
const hubClient = await this.getEmulatorHubClient();
|
|
107
|
+
if (!hubClient) {
|
|
108
|
+
throw Error("Emulator Hub not found or is not running. You can start the emulator by running `firebase emulators:start` in your firebase project directory.");
|
|
109
|
+
}
|
|
110
|
+
const emulators = await hubClient.getEmulators();
|
|
111
|
+
const emulatorInfo = emulators[emulatorType];
|
|
112
|
+
if (!emulatorInfo) {
|
|
113
|
+
throw Error("No Firestore Emulator found running. Make sure your project firebase.json file includes firestore and then rerun emulator using `firebase emulators:start` from your project directory.");
|
|
114
|
+
}
|
|
115
|
+
const host = emulatorInfo.host.includes(":") ? `[${emulatorInfo.host}]` : emulatorInfo.host;
|
|
116
|
+
return `http://${host}:${emulatorInfo.port}`;
|
|
117
|
+
}
|
|
105
118
|
get availableTools() {
|
|
106
119
|
var _a;
|
|
107
120
|
return (0, index_js_2.availableTools)(((_a = this.activeFeatures) === null || _a === void 0 ? void 0 : _a.length) ? this.activeFeatures : this.detectedFeatures);
|
|
@@ -125,7 +138,8 @@ class FirebaseMcpServer {
|
|
|
125
138
|
}
|
|
126
139
|
async getAuthenticatedUser() {
|
|
127
140
|
try {
|
|
128
|
-
|
|
141
|
+
const email = await (0, requireAuth_js_1.requireAuth)(await this.resolveOptions());
|
|
142
|
+
return email !== null && email !== void 0 ? email : "Application Default Credentials";
|
|
129
143
|
}
|
|
130
144
|
catch (e) {
|
|
131
145
|
return null;
|
|
@@ -17,6 +17,10 @@ exports.list_top_issues = (0, tool_js_1.tool)({
|
|
|
17
17
|
.number()
|
|
18
18
|
.optional()
|
|
19
19
|
.describe("Number of issues that needs to be fetched. Defaults to 10 if unspecified."),
|
|
20
|
+
issue_type: zod_1.z
|
|
21
|
+
.enum(["FATAL", "NON-FATAL", "ANR"])
|
|
22
|
+
.optional()
|
|
23
|
+
.describe("Types of issues that can be fetched comma-separated. Defaults to `FATAL` (Crashes). Other values include NON-FATAL (Non-fatal issues), ANR (Application not responding)."),
|
|
20
24
|
}),
|
|
21
25
|
annotations: {
|
|
22
26
|
title: "List Top Crashlytics Issues.",
|
|
@@ -26,9 +30,10 @@ exports.list_top_issues = (0, tool_js_1.tool)({
|
|
|
26
30
|
requiresAuth: true,
|
|
27
31
|
requiresProject: true,
|
|
28
32
|
},
|
|
29
|
-
}, async ({ app_id, issue_count }, { projectId }) => {
|
|
33
|
+
}, async ({ app_id, issue_type, issue_count }, { projectId }) => {
|
|
30
34
|
if (!app_id)
|
|
31
35
|
return (0, util_js_1.mcpError)(`Must specify 'app_id' parameter.`);
|
|
36
|
+
issue_type !== null && issue_type !== void 0 ? issue_type : (issue_type = "FATAL");
|
|
32
37
|
issue_count !== null && issue_count !== void 0 ? issue_count : (issue_count = 10);
|
|
33
|
-
return (0, util_js_1.toContent)(await (0, listTopIssues_js_1.listTopIssues)(projectId, app_id, issue_count));
|
|
38
|
+
return (0, util_js_1.toContent)(await (0, listTopIssues_js_1.listTopIssues)(projectId, app_id, issue_type, issue_count));
|
|
34
39
|
});
|
|
@@ -4,26 +4,10 @@ exports.getDataConnectEmulatorClient = void 0;
|
|
|
4
4
|
const types_js_1 = require("../../../emulator/types.js");
|
|
5
5
|
const apiv2_js_1 = require("../../../apiv2.js");
|
|
6
6
|
const dataplaneClient_js_1 = require("../../../dataconnect/dataplaneClient.js");
|
|
7
|
-
function
|
|
8
|
-
const
|
|
9
|
-
return {
|
|
10
|
-
host: emulatorInfo.host,
|
|
11
|
-
port: emulatorInfo.port,
|
|
12
|
-
url: `http://${host}:${emulatorInfo.port}`,
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
async function getDataConnectEmulatorClient(hubClient) {
|
|
16
|
-
if (!hubClient) {
|
|
17
|
-
throw Error("Emulator Hub not found or is not running. Please ensure the emulator is started, you can start the Data Connect emualtor by running `firebase emulators:start --only dataconnect`.");
|
|
18
|
-
}
|
|
19
|
-
const emulators = await hubClient.getEmulators();
|
|
20
|
-
const dcEmulatorInfo = emulators[types_js_1.Emulators.DATACONNECT];
|
|
21
|
-
if (!dcEmulatorInfo) {
|
|
22
|
-
throw Error("No Data Connect Emulator found running, you can start the emualtor by running `firebase emulators:start --only dataconnect`.");
|
|
23
|
-
}
|
|
24
|
-
const emulatorDetails = formatEndpoint(dcEmulatorInfo);
|
|
7
|
+
async function getDataConnectEmulatorClient(host) {
|
|
8
|
+
const emulatorUrl = await host.getEmulatorUrl(types_js_1.Emulators.DATACONNECT);
|
|
25
9
|
const apiClient = new apiv2_js_1.Client({
|
|
26
|
-
urlPrefix:
|
|
10
|
+
urlPrefix: emulatorUrl,
|
|
27
11
|
apiVersion: dataplaneClient_js_1.DATACONNECT_API_VERSION,
|
|
28
12
|
auth: false,
|
|
29
13
|
});
|
|
@@ -34,7 +34,7 @@ exports.execute_graphql = (0, tool_js_1.tool)({
|
|
|
34
34
|
const serviceInfo = await (0, fileUtils_js_1.pickService)(projectId, config, service_id || undefined);
|
|
35
35
|
let apiClient;
|
|
36
36
|
if (use_emulator) {
|
|
37
|
-
apiClient = await (0, emulator_js_1.getDataConnectEmulatorClient)(
|
|
37
|
+
apiClient = await (0, emulator_js_1.getDataConnectEmulatorClient)(host);
|
|
38
38
|
}
|
|
39
39
|
else {
|
|
40
40
|
apiClient = dataplane.dataconnectDataplaneClient();
|
|
@@ -34,7 +34,7 @@ exports.execute_graphql_read = (0, tool_js_1.tool)({
|
|
|
34
34
|
const serviceInfo = await (0, fileUtils_js_1.pickService)(projectId, config, service_id || undefined);
|
|
35
35
|
let apiClient;
|
|
36
36
|
if (use_emulator) {
|
|
37
|
-
apiClient = await (0, emulator_js_1.getDataConnectEmulatorClient)(
|
|
37
|
+
apiClient = await (0, emulator_js_1.getDataConnectEmulatorClient)(host);
|
|
38
38
|
}
|
|
39
39
|
else {
|
|
40
40
|
apiClient = dataplane.dataconnectDataplaneClient();
|
|
@@ -49,7 +49,7 @@ exports.execute_mutation = (0, tool_js_1.tool)({
|
|
|
49
49
|
}
|
|
50
50
|
const connectorPath = `${serviceInfo.serviceName}/connectors/${connector_id}`;
|
|
51
51
|
if (use_emulator) {
|
|
52
|
-
apiClient = await (0, emulator_js_1.getDataConnectEmulatorClient)(
|
|
52
|
+
apiClient = await (0, emulator_js_1.getDataConnectEmulatorClient)(host);
|
|
53
53
|
}
|
|
54
54
|
else {
|
|
55
55
|
apiClient = dataplane.dataconnectDataplaneClient();
|
|
@@ -49,7 +49,7 @@ exports.execute_query = (0, tool_js_1.tool)({
|
|
|
49
49
|
}
|
|
50
50
|
const connectorPath = `${serviceInfo.serviceName}/connectors/${connector_id}`;
|
|
51
51
|
if (use_emulator) {
|
|
52
|
-
apiClient = await (0, emulator_js_1.getDataConnectEmulatorClient)(
|
|
52
|
+
apiClient = await (0, emulator_js_1.getDataConnectEmulatorClient)(host);
|
|
53
53
|
}
|
|
54
54
|
else {
|
|
55
55
|
apiClient = dataplane.dataconnectDataplaneClient();
|
|
@@ -6,7 +6,7 @@ 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 delete_js_1 = require("../../../firestore/delete.js");
|
|
9
|
-
const
|
|
9
|
+
const types_js_1 = require("../../../emulator/types.js");
|
|
10
10
|
exports.delete_document = (0, tool_js_1.tool)({
|
|
11
11
|
name: "delete_document",
|
|
12
12
|
description: "Deletes a Firestore documents from a database in the current project by full document paths. Use this if you know the exact path of a document.",
|
|
@@ -31,7 +31,7 @@ exports.delete_document = (0, tool_js_1.tool)({
|
|
|
31
31
|
}, async ({ path, database, use_emulator }, { projectId, host }) => {
|
|
32
32
|
let emulatorUrl;
|
|
33
33
|
if (use_emulator) {
|
|
34
|
-
emulatorUrl = await
|
|
34
|
+
emulatorUrl = await host.getEmulatorUrl(types_js_1.Emulators.FIRESTORE);
|
|
35
35
|
}
|
|
36
36
|
const { documents, missing } = await (0, firestore_js_1.getDocuments)(projectId, [path], database, emulatorUrl);
|
|
37
37
|
if (missing.length > 0 && documents && documents.length === 0) {
|
|
@@ -6,7 +6,7 @@ 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
|
-
const
|
|
9
|
+
const types_js_1 = require("../../../emulator/types.js");
|
|
10
10
|
exports.get_documents = (0, tool_js_1.tool)({
|
|
11
11
|
name: "get_documents",
|
|
12
12
|
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.",
|
|
@@ -33,7 +33,7 @@ exports.get_documents = (0, tool_js_1.tool)({
|
|
|
33
33
|
return (0, util_js_1.mcpError)("Must supply at least one document path.");
|
|
34
34
|
let emulatorUrl;
|
|
35
35
|
if (use_emulator) {
|
|
36
|
-
emulatorUrl = await
|
|
36
|
+
emulatorUrl = await host.getEmulatorUrl(types_js_1.Emulators.FIRESTORE);
|
|
37
37
|
}
|
|
38
38
|
const { documents, missing } = await (0, firestore_js_1.getDocuments)(projectId, paths, database, emulatorUrl);
|
|
39
39
|
if (missing.length > 0 && documents && documents.length === 0) {
|
|
@@ -6,7 +6,7 @@ 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
|
-
const
|
|
9
|
+
const types_js_1 = require("../../../emulator/types.js");
|
|
10
10
|
exports.list_collections = (0, tool_js_1.tool)({
|
|
11
11
|
name: "list_collections",
|
|
12
12
|
description: "Retrieves a list of collections from a Firestore database in the current project.",
|
|
@@ -28,7 +28,7 @@ exports.list_collections = (0, tool_js_1.tool)({
|
|
|
28
28
|
}, async ({ database, use_emulator }, { projectId, host }) => {
|
|
29
29
|
let emulatorUrl;
|
|
30
30
|
if (use_emulator) {
|
|
31
|
-
emulatorUrl = await
|
|
31
|
+
emulatorUrl = await host.getEmulatorUrl(types_js_1.Emulators.FIRESTORE);
|
|
32
32
|
}
|
|
33
33
|
if (!projectId)
|
|
34
34
|
return errors_js_1.NO_PROJECT_ERROR;
|
|
@@ -6,7 +6,7 @@ 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
|
-
const
|
|
9
|
+
const types_js_1 = require("../../../emulator/types.js");
|
|
10
10
|
exports.query_collection = (0, tool_js_1.tool)({
|
|
11
11
|
name: "query_collection",
|
|
12
12
|
description: "Retrieves one or more Firestore documents from a collection is a database in the current project by a collection with a full document path. Use this if you know the exact path of a collection and the filtering clause you would like for the document.",
|
|
@@ -123,7 +123,7 @@ exports.query_collection = (0, tool_js_1.tool)({
|
|
|
123
123
|
structuredQuery.limit = limit ? limit : 10;
|
|
124
124
|
let emulatorUrl;
|
|
125
125
|
if (use_emulator) {
|
|
126
|
-
emulatorUrl = await
|
|
126
|
+
emulatorUrl = await host.getEmulatorUrl(types_js_1.Emulators.FIRESTORE);
|
|
127
127
|
}
|
|
128
128
|
const { documents } = await (0, firestore_js_1.queryCollection)(projectId, structuredQuery, database, emulatorUrl);
|
|
129
129
|
const docs = documents.map(converter_js_1.firestoreDocumentToJson);
|
|
@@ -5,6 +5,7 @@ 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 storage_js_1 = require("../../../gcp/storage.js");
|
|
8
|
+
const types_js_1 = require("../../../emulator/types.js");
|
|
8
9
|
exports.get_object_download_url = (0, tool_js_1.tool)({
|
|
9
10
|
name: "get_object_download_url",
|
|
10
11
|
description: "Retrieves the download URL for an object in Firebase Storage.",
|
|
@@ -16,6 +17,7 @@ exports.get_object_download_url = (0, tool_js_1.tool)({
|
|
|
16
17
|
object_path: zod_1.z
|
|
17
18
|
.string()
|
|
18
19
|
.describe("The path to the object in Firebase storage without the bucket name attached"),
|
|
20
|
+
use_emulator: zod_1.z.boolean().default(false).describe("Target the Storage emulator if true."),
|
|
19
21
|
}),
|
|
20
22
|
annotations: {
|
|
21
23
|
title: "Get Storage Object Download URL",
|
|
@@ -25,10 +27,14 @@ exports.get_object_download_url = (0, tool_js_1.tool)({
|
|
|
25
27
|
requiresProject: true,
|
|
26
28
|
requiresAuth: true,
|
|
27
29
|
},
|
|
28
|
-
}, async ({ bucket, object_path }, { projectId }) => {
|
|
30
|
+
}, async ({ bucket, object_path, use_emulator }, { projectId, host }) => {
|
|
29
31
|
if (!bucket) {
|
|
30
32
|
bucket = `${projectId}.firebasestorage.app`;
|
|
31
33
|
}
|
|
32
|
-
|
|
34
|
+
let emulatorUrl;
|
|
35
|
+
if (use_emulator) {
|
|
36
|
+
emulatorUrl = await host.getEmulatorUrl(types_js_1.Emulators.STORAGE);
|
|
37
|
+
}
|
|
38
|
+
const downloadUrl = await (0, storage_js_1.getDownloadUrl)(bucket, object_path, emulatorUrl);
|
|
33
39
|
return (0, util_js_1.toContent)(downloadUrl);
|
|
34
40
|
});
|
package/lib/track.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var _a;
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
exports.cliSession = exports.vscodeSession = exports.emulatorSession = exports.trackVSCode = exports.trackEmulator = exports.trackGA4 = exports.usageEnabled = exports.GA4_PROPERTIES = void 0;
|
|
4
5
|
const node_fetch_1 = require("node-fetch");
|
|
@@ -41,6 +42,9 @@ const GA4_USER_PROPS = {
|
|
|
41
42
|
firepit_version: {
|
|
42
43
|
value: process.env.FIREPIT_VERSION || "none",
|
|
43
44
|
},
|
|
45
|
+
is_firebase_studio: {
|
|
46
|
+
value: (_a = process.env.MONOSPACE_ENV) !== null && _a !== void 0 ? _a : "false",
|
|
47
|
+
},
|
|
44
48
|
};
|
|
45
49
|
async function trackGA4(eventName, params, duration = 1) {
|
|
46
50
|
const session = cliSession();
|
package/package.json
CHANGED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getFirestoreEmulatorUrl = void 0;
|
|
4
|
-
const types_js_1 = require("../../../emulator/types.js");
|
|
5
|
-
async function getFirestoreEmulatorUrl(hubClient) {
|
|
6
|
-
if (!hubClient) {
|
|
7
|
-
throw Error("Emulator Hub not found or is not running. You can start the emulator by running `firebase emulators:start` in your firebase project directory.");
|
|
8
|
-
}
|
|
9
|
-
const emulators = await hubClient.getEmulators();
|
|
10
|
-
const firestoreEmulatorInfo = emulators[types_js_1.Emulators.FIRESTORE];
|
|
11
|
-
if (!firestoreEmulatorInfo) {
|
|
12
|
-
throw Error("No Firestore Emulator found running. Make sure your project firebase.json file includes firestore and then rerun emulator using `firebase emulators:start` from your project directory.");
|
|
13
|
-
}
|
|
14
|
-
return `http://${firestoreEmulatorInfo.host}:${firestoreEmulatorInfo.port}`;
|
|
15
|
-
}
|
|
16
|
-
exports.getFirestoreEmulatorUrl = getFirestoreEmulatorUrl;
|