firebase-tools 14.3.0 → 14.4.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 +10 -2
- package/lib/apphosting/backend.js +72 -18
- package/lib/apphosting/githubConnections.js +13 -19
- package/lib/apphosting/rollout.js +2 -2
- package/lib/apphosting/secrets/dialogs.js +4 -4
- package/lib/apphosting/secrets/index.js +2 -2
- package/lib/auth.js +22 -2
- package/lib/bin/cli.js +1 -33
- package/lib/bin/mcp.js +12 -2
- package/lib/checkValidTargetFilters.js +1 -0
- package/lib/command.js +3 -2
- package/lib/commands/apphosting-secrets-grantaccess.js +1 -1
- package/lib/commands/deploy.js +1 -0
- package/lib/commands/init.js +1 -1
- package/lib/commands/login-use.js +2 -11
- package/lib/commands/use.js +9 -8
- package/lib/config.js +1 -0
- package/lib/crashlytics/listTopIssues.js +44 -0
- package/lib/dataconnect/cloudAICompanionClient.js +67 -0
- package/lib/dataconnect/dataplaneClient.js +16 -1
- package/lib/dataconnect/types.js +5 -1
- package/lib/deploy/apphosting/args.js +2 -0
- package/lib/deploy/apphosting/deploy.js +74 -0
- package/lib/deploy/apphosting/index.js +9 -0
- package/lib/deploy/apphosting/prepare.js +141 -0
- package/lib/deploy/apphosting/release.js +53 -0
- package/lib/deploy/apphosting/util.js +65 -0
- package/lib/deploy/extensions/v2FunctionHelper.js +2 -1
- package/lib/deploy/functions/checkIam.js +3 -3
- package/lib/deploy/functions/ensure.js +2 -1
- package/lib/deploy/functions/prepare.js +23 -16
- package/lib/deploy/functions/release/fabricator.js +4 -4
- package/lib/deploy/functions/release/index.js +1 -1
- package/lib/deploy/functions/runtimes/python/index.js +3 -0
- package/lib/deploy/functions/runtimes/supported/types.js +17 -11
- package/lib/deploy/index.js +2 -0
- package/lib/emulator/apphosting/index.js +1 -0
- package/lib/emulator/apphosting/serve.js +77 -3
- package/lib/emulator/auth/widget_ui.js +2 -1
- package/lib/emulator/controller.js +18 -4
- package/lib/emulator/dataconnectEmulator.js +9 -2
- package/lib/emulator/downloadableEmulatorInfo.json +60 -0
- package/lib/emulator/downloadableEmulators.js +25 -61
- package/lib/ensureApiEnabled.js +11 -1
- package/lib/experiments.js +1 -1
- package/lib/extensions/manifest.js +2 -2
- package/lib/fsAsync.js +9 -2
- package/lib/gcp/auth.js +32 -2
- package/lib/gcp/cloudbilling.js +12 -1
- package/lib/gcp/cloudfunctions.js +1 -2
- package/lib/gcp/cloudfunctionsv2.js +1 -2
- package/lib/gcp/cloudscheduler.js +2 -2
- package/lib/gcp/computeEngine.js +19 -2
- package/lib/gcp/devConnect.js +6 -1
- package/lib/gcp/firestore.js +24 -1
- package/lib/gcp/iam.js +1 -5
- package/lib/gcp/storage.js +43 -1
- package/lib/index.js +1 -2
- package/lib/init/features/apphosting.js +84 -6
- package/lib/init/features/database.js +64 -45
- package/lib/init/features/dataconnect/index.js +51 -53
- package/lib/init/features/emulators.js +9 -5
- package/lib/init/features/firestore/index.js +54 -23
- package/lib/init/features/firestore/indexes.js +23 -23
- package/lib/init/features/firestore/rules.js +35 -40
- package/lib/init/features/functions/index.js +2 -0
- package/lib/init/features/functions/javascript.js +3 -2
- package/lib/init/features/functions/typescript.js +3 -2
- package/lib/init/features/genkit/index.js +2 -1
- package/lib/init/features/hosting/github.js +3 -2
- package/lib/init/features/index.js +8 -4
- package/lib/init/features/remoteconfig.js +3 -2
- package/lib/init/index.js +76 -24
- package/lib/logger.js +71 -7
- package/lib/management/projects.js +25 -2
- package/lib/mcp/errors.js +1 -1
- package/lib/mcp/index.js +134 -51
- package/lib/mcp/tools/auth/{disable_auth_user.js → disable_user.js} +3 -3
- package/lib/mcp/tools/auth/get_user.js +38 -0
- package/lib/mcp/tools/auth/index.js +8 -6
- package/lib/mcp/tools/auth/list_users.js +47 -0
- package/lib/mcp/tools/auth/set_claims.js +43 -0
- package/lib/mcp/tools/auth/set_sms_region_policy.js +1 -1
- package/lib/mcp/tools/core/{consult_firebase_assistant.js → consult_assistant.js} +4 -4
- package/lib/mcp/tools/core/create_android_sha.js +40 -0
- package/lib/mcp/tools/core/create_app.js +90 -0
- package/lib/mcp/tools/core/create_project.js +68 -0
- package/lib/mcp/tools/core/get_admin_sdk_config.js +26 -0
- package/lib/mcp/tools/core/get_environment.js +51 -0
- package/lib/mcp/tools/{project → core}/get_sdk_config.js +6 -3
- package/lib/mcp/tools/core/index.js +20 -6
- package/lib/mcp/tools/core/init.js +129 -0
- package/lib/mcp/tools/core/update_environment.js +55 -0
- package/lib/mcp/tools/crashlytics/index.js +5 -0
- package/lib/mcp/tools/crashlytics/list_top_issues.js +34 -0
- package/lib/mcp/tools/dataconnect/converter.js +30 -1
- package/lib/mcp/tools/dataconnect/emulator.js +32 -0
- package/lib/mcp/tools/dataconnect/execute_graphql.js +48 -0
- package/lib/mcp/tools/dataconnect/execute_graphql_read.js +48 -0
- package/lib/mcp/tools/dataconnect/execute_mutation.js +62 -0
- package/lib/mcp/tools/dataconnect/execute_query.js +62 -0
- package/lib/mcp/tools/dataconnect/{generate_dataconnect_operation.js → generate_operation.js} +9 -9
- package/lib/mcp/tools/dataconnect/{generate_dataconnect_schema.js → generate_schema.js} +4 -4
- package/lib/mcp/tools/dataconnect/{get_dataconnect_connector.js → get_connector.js} +9 -9
- package/lib/mcp/tools/dataconnect/{get_dataconnect_schema.js → get_schema.js} +10 -10
- package/lib/mcp/tools/dataconnect/index.js +14 -10
- package/lib/mcp/tools/dataconnect/{list_dataconnect_services.js → list_services.js} +5 -5
- package/lib/mcp/tools/firestore/converter.js +47 -1
- package/lib/mcp/tools/firestore/delete_document.js +37 -0
- package/lib/mcp/tools/firestore/{get_firestore_documents.js → get_documents.js} +3 -3
- package/lib/mcp/tools/firestore/index.js +12 -6
- package/lib/mcp/tools/firestore/{list_firestore_collections.js → list_collections.js} +4 -9
- package/lib/mcp/tools/firestore/query_collection.js +116 -0
- package/lib/mcp/tools/index.js +44 -8
- package/lib/mcp/tools/messaging/index.js +5 -0
- package/lib/mcp/tools/messaging/send_message.js +42 -0
- package/lib/mcp/tools/remoteconfig/get_template.js +27 -0
- package/lib/mcp/tools/remoteconfig/index.js +7 -0
- package/lib/mcp/tools/remoteconfig/publish_template.js +34 -0
- package/lib/mcp/tools/remoteconfig/rollback_template.js +29 -0
- package/lib/mcp/tools/rules/get_rules.js +29 -0
- package/lib/mcp/tools/rules/validate_rules.js +98 -0
- package/lib/mcp/tools/storage/get_download_url.js +34 -0
- package/lib/mcp/tools/storage/{get_storage_rules.js → get_rules.js} +6 -6
- package/lib/mcp/tools/storage/index.js +8 -2
- package/lib/mcp/types.js +9 -1
- package/lib/mcp/util.js +29 -2
- package/lib/messaging/interfaces.js +2 -0
- package/lib/messaging/sendMessage.js +48 -0
- package/lib/remoteconfig/publish.js +39 -0
- package/lib/requireAuth.js +2 -2
- package/lib/utils.js +2 -37
- package/package.json +2 -1
- package/schema/firebase-config.json +62 -10
- package/templates/init/functions/javascript/package.lint.json +1 -1
- package/templates/init/functions/javascript/package.nolint.json +1 -1
- package/templates/init/functions/typescript/package.lint.json +1 -1
- package/templates/init/functions/typescript/package.nolint.json +2 -2
- package/lib/mcp/tools/auth/get_auth_user.js +0 -29
- package/lib/mcp/tools/auth/set_auth_claims.js +0 -34
- package/lib/mcp/tools/core/get_firebase_directory.js +0 -20
- package/lib/mcp/tools/core/set_firebase_directory.js +0 -33
- package/lib/mcp/tools/firestore/get_firestore_rules.js +0 -26
- package/lib/mcp/tools/project/index.js +0 -7
- /package/lib/mcp/tools/{project → core}/get_project.js +0 -0
- /package/lib/mcp/tools/{project → core}/list_apps.js +0 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.sourceToText = exports.connectorToText = exports.schemaToText = void 0;
|
|
3
|
+
exports.parseVariables = exports.graphqlResponseToToolResponse = exports.sourceToText = exports.connectorToText = exports.schemaToText = void 0;
|
|
4
4
|
const js_yaml_1 = require("js-yaml");
|
|
5
|
+
const types_1 = require("../../../dataconnect/types");
|
|
6
|
+
const util_1 = require("../../util");
|
|
5
7
|
function schemaToText(s) {
|
|
6
8
|
return ((0, js_yaml_1.dump)({
|
|
7
9
|
name: s.name,
|
|
@@ -31,3 +33,30 @@ function sourceToText(s) {
|
|
|
31
33
|
return output;
|
|
32
34
|
}
|
|
33
35
|
exports.sourceToText = sourceToText;
|
|
36
|
+
function graphqlResponseToToolResponse(g) {
|
|
37
|
+
var _a;
|
|
38
|
+
if ((0, types_1.isGraphQLResponse)(g)) {
|
|
39
|
+
const isError = ((_a = g.errors) === null || _a === void 0 ? void 0 : _a.length) > 0;
|
|
40
|
+
const contentString = `${isError ? "A GraphQL error occurred while executing the operation:" : ""}${JSON.stringify(g, null, 2)}`;
|
|
41
|
+
return {
|
|
42
|
+
isError,
|
|
43
|
+
content: [{ type: "text", text: contentString }],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
return (0, util_1.mcpError)(JSON.stringify(g, null, 2));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.graphqlResponseToToolResponse = graphqlResponseToToolResponse;
|
|
51
|
+
function parseVariables(unparsedVariables) {
|
|
52
|
+
try {
|
|
53
|
+
const variables = JSON.parse(unparsedVariables || "{}");
|
|
54
|
+
if (typeof variables !== "object")
|
|
55
|
+
throw new Error("not an object");
|
|
56
|
+
return variables;
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
throw new Error("Provided variables string `" + unparsedVariables + "` is not valid JSON.");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.parseVariables = parseVariables;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDataConnectEmulatorClient = void 0;
|
|
4
|
+
const types_js_1 = require("../../../emulator/types.js");
|
|
5
|
+
const apiv2_js_1 = require("../../../apiv2.js");
|
|
6
|
+
const dataplaneClient_js_1 = require("../../../dataconnect/dataplaneClient.js");
|
|
7
|
+
function formatEndpoint(emulatorInfo) {
|
|
8
|
+
const host = emulatorInfo.host.includes(":") ? `[${emulatorInfo.host}]` : emulatorInfo.host;
|
|
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);
|
|
25
|
+
const apiClient = new apiv2_js_1.Client({
|
|
26
|
+
urlPrefix: emulatorDetails.url,
|
|
27
|
+
apiVersion: dataplaneClient_js_1.DATACONNECT_API_VERSION,
|
|
28
|
+
auth: false,
|
|
29
|
+
});
|
|
30
|
+
return apiClient;
|
|
31
|
+
}
|
|
32
|
+
exports.getDataConnectEmulatorClient = getDataConnectEmulatorClient;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.execute_graphql = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_js_1 = require("../../tool.js");
|
|
6
|
+
const dataplane = require("../../../dataconnect/dataplaneClient.js");
|
|
7
|
+
const fileUtils_js_1 = require("../../../dataconnect/fileUtils.js");
|
|
8
|
+
const converter_js_1 = require("./converter.js");
|
|
9
|
+
const emulator_js_1 = require("./emulator.js");
|
|
10
|
+
exports.execute_graphql = (0, tool_js_1.tool)({
|
|
11
|
+
name: "execute_graphql",
|
|
12
|
+
description: "Executes an arbitrary GraphQL against a Data Connect service or its emulator.",
|
|
13
|
+
inputSchema: zod_1.z.object({
|
|
14
|
+
query: zod_1.z.string().describe("A GraphQL query or mutation to execute against the service"),
|
|
15
|
+
service_id: zod_1.z
|
|
16
|
+
.string()
|
|
17
|
+
.nullable()
|
|
18
|
+
.describe("The Firebase Data Connect service ID to look for. If there is only one service defined in firebase.json, this can be omitted and that will be used."),
|
|
19
|
+
variables: zod_1.z
|
|
20
|
+
.string()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe("A stringified JSON object containing variables for the operation. MUST be valid JSON."),
|
|
23
|
+
use_emulator: zod_1.z.boolean().default(false).describe("Target the DataConnect emulator if true."),
|
|
24
|
+
}),
|
|
25
|
+
annotations: {
|
|
26
|
+
title: "Execute GraphQL Operation",
|
|
27
|
+
readOnlyHint: false,
|
|
28
|
+
},
|
|
29
|
+
_meta: {
|
|
30
|
+
requiresProject: true,
|
|
31
|
+
requiresAuth: true,
|
|
32
|
+
},
|
|
33
|
+
}, async ({ query, service_id, variables: unparsedVariables, use_emulator }, { projectId, config, host }) => {
|
|
34
|
+
const serviceInfo = await (0, fileUtils_js_1.pickService)(projectId, config, service_id || undefined);
|
|
35
|
+
let apiClient;
|
|
36
|
+
if (use_emulator) {
|
|
37
|
+
apiClient = await (0, emulator_js_1.getDataConnectEmulatorClient)(await host.getEmulatorHubClient());
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
apiClient = dataplane.dataconnectDataplaneClient();
|
|
41
|
+
}
|
|
42
|
+
const response = await dataplane.executeGraphQL(apiClient, serviceInfo.serviceName, {
|
|
43
|
+
name: "",
|
|
44
|
+
query,
|
|
45
|
+
variables: (0, converter_js_1.parseVariables)(unparsedVariables),
|
|
46
|
+
});
|
|
47
|
+
return (0, converter_js_1.graphqlResponseToToolResponse)(response.body);
|
|
48
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.execute_graphql_read = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_js_1 = require("../../tool.js");
|
|
6
|
+
const dataplane = require("../../../dataconnect/dataplaneClient.js");
|
|
7
|
+
const fileUtils_js_1 = require("../../../dataconnect/fileUtils.js");
|
|
8
|
+
const converter_js_1 = require("./converter.js");
|
|
9
|
+
const emulator_js_1 = require("./emulator.js");
|
|
10
|
+
exports.execute_graphql_read = (0, tool_js_1.tool)({
|
|
11
|
+
name: "execute_graphql_read",
|
|
12
|
+
description: "Executes an arbitrary GraphQL query against a Data Connect service or its emulator. Cannot write data.",
|
|
13
|
+
inputSchema: zod_1.z.object({
|
|
14
|
+
query: zod_1.z.string().describe("A GraphQL query to execute against the service"),
|
|
15
|
+
service_id: zod_1.z
|
|
16
|
+
.string()
|
|
17
|
+
.nullable()
|
|
18
|
+
.describe("The Firebase Data Connect service ID to look for. If there is only one service defined in firebase.json, this can be omitted and that will be used."),
|
|
19
|
+
variables: zod_1.z
|
|
20
|
+
.string()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe("A stringified JSON object containing variables for the operation. MUST be valid JSON."),
|
|
23
|
+
use_emulator: zod_1.z.boolean().default(false).describe("Target the DataConnect emulator if true."),
|
|
24
|
+
}),
|
|
25
|
+
annotations: {
|
|
26
|
+
title: "Execute Data Connect GraphQL Query",
|
|
27
|
+
readOnlyHint: true,
|
|
28
|
+
},
|
|
29
|
+
_meta: {
|
|
30
|
+
requiresProject: true,
|
|
31
|
+
requiresAuth: true,
|
|
32
|
+
},
|
|
33
|
+
}, async ({ query, service_id, variables: unparsedVariables, use_emulator }, { projectId, config, host }) => {
|
|
34
|
+
const serviceInfo = await (0, fileUtils_js_1.pickService)(projectId, config, service_id || undefined);
|
|
35
|
+
let apiClient;
|
|
36
|
+
if (use_emulator) {
|
|
37
|
+
apiClient = await (0, emulator_js_1.getDataConnectEmulatorClient)(await host.getEmulatorHubClient());
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
apiClient = dataplane.dataconnectDataplaneClient();
|
|
41
|
+
}
|
|
42
|
+
const response = await dataplane.executeGraphQLRead(apiClient, serviceInfo.serviceName, {
|
|
43
|
+
name: "",
|
|
44
|
+
query,
|
|
45
|
+
variables: (0, converter_js_1.parseVariables)(unparsedVariables),
|
|
46
|
+
});
|
|
47
|
+
return (0, converter_js_1.graphqlResponseToToolResponse)(response.body);
|
|
48
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.execute_mutation = 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 dataplane = require("../../../dataconnect/dataplaneClient.js");
|
|
8
|
+
const fileUtils_js_1 = require("../../../dataconnect/fileUtils.js");
|
|
9
|
+
const converter_js_1 = require("./converter.js");
|
|
10
|
+
const emulator_js_1 = require("./emulator.js");
|
|
11
|
+
exports.execute_mutation = (0, tool_js_1.tool)({
|
|
12
|
+
name: "execute_mutation",
|
|
13
|
+
description: "Executes a deployed Data Connect mutation against a service or its emulator. Can read and write data.",
|
|
14
|
+
inputSchema: zod_1.z.object({
|
|
15
|
+
operationName: zod_1.z.string().describe("The name of the deployed operation you want to execute"),
|
|
16
|
+
service_id: zod_1.z
|
|
17
|
+
.string()
|
|
18
|
+
.nullable()
|
|
19
|
+
.describe("The Firebase Data Connect service ID to look for. If there is only one service defined in firebase.json, this can be omitted and that will be used."),
|
|
20
|
+
connector_id: zod_1.z
|
|
21
|
+
.string()
|
|
22
|
+
.nullable()
|
|
23
|
+
.describe("The Firebase Data Connect connector ID to look for. If there is only one connector defined in dataconnect.yaml, this can be omitted and that will be used."),
|
|
24
|
+
variables: zod_1.z
|
|
25
|
+
.string()
|
|
26
|
+
.optional()
|
|
27
|
+
.describe("A stringified JSON object containing the variables needed to execute the operation. The value MUST be able to be parsed as a JSON object."),
|
|
28
|
+
use_emulator: zod_1.z.boolean().default(false).describe("Target the DataConnect emulator if true."),
|
|
29
|
+
}),
|
|
30
|
+
annotations: {
|
|
31
|
+
title: "Execute Data Connect Connector Mutation",
|
|
32
|
+
readOnlyHint: false,
|
|
33
|
+
},
|
|
34
|
+
_meta: {
|
|
35
|
+
requiresProject: true,
|
|
36
|
+
requiresAuth: true,
|
|
37
|
+
},
|
|
38
|
+
}, async ({ operationName, service_id, connector_id, variables: unparsedVariables, use_emulator }, { projectId, config, host }) => {
|
|
39
|
+
const serviceInfo = await (0, fileUtils_js_1.pickService)(projectId, config, service_id || undefined);
|
|
40
|
+
let apiClient;
|
|
41
|
+
if (!connector_id) {
|
|
42
|
+
if (serviceInfo.connectorInfo.length === 0) {
|
|
43
|
+
return (0, util_js_1.mcpError)(`Service ${serviceInfo.serviceName} has no connectors`, "NO_CONNECTORS_FOUND");
|
|
44
|
+
}
|
|
45
|
+
if (serviceInfo.connectorInfo.length > 1) {
|
|
46
|
+
return (0, util_js_1.mcpError)(`Service ${serviceInfo.serviceName} has more than one connector. Please use the connector_id argument to specify which connector this operation is part of.`, "MULTIPLE_CONNECTORS_FOUND");
|
|
47
|
+
}
|
|
48
|
+
connector_id = serviceInfo.connectorInfo[0].connectorYaml.connectorId;
|
|
49
|
+
}
|
|
50
|
+
const connectorPath = `${serviceInfo.serviceName}/connectors/${connector_id}`;
|
|
51
|
+
if (use_emulator) {
|
|
52
|
+
apiClient = await (0, emulator_js_1.getDataConnectEmulatorClient)(await host.getEmulatorHubClient());
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
apiClient = dataplane.dataconnectDataplaneClient();
|
|
56
|
+
}
|
|
57
|
+
const response = await dataplane.executeGraphQLMutation(apiClient, connectorPath, {
|
|
58
|
+
operationName,
|
|
59
|
+
variables: (0, converter_js_1.parseVariables)(unparsedVariables),
|
|
60
|
+
});
|
|
61
|
+
return (0, converter_js_1.graphqlResponseToToolResponse)(response.body);
|
|
62
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.execute_query = 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 dataplane = require("../../../dataconnect/dataplaneClient.js");
|
|
8
|
+
const fileUtils_js_1 = require("../../../dataconnect/fileUtils.js");
|
|
9
|
+
const converter_js_1 = require("./converter.js");
|
|
10
|
+
const emulator_js_1 = require("./emulator.js");
|
|
11
|
+
exports.execute_query = (0, tool_js_1.tool)({
|
|
12
|
+
name: "execute_query",
|
|
13
|
+
description: "Executes a deployed Data Connect query against a service or its emulator. Cannot write any data.",
|
|
14
|
+
inputSchema: zod_1.z.object({
|
|
15
|
+
operationName: zod_1.z.string().describe("The name of the deployed operation you want to execute"),
|
|
16
|
+
service_id: zod_1.z
|
|
17
|
+
.string()
|
|
18
|
+
.nullable()
|
|
19
|
+
.describe("The Firebase Data Connect service ID to look for. If there is only one service defined in firebase.json, this can be omitted and that will be used."),
|
|
20
|
+
connector_id: zod_1.z
|
|
21
|
+
.string()
|
|
22
|
+
.nullable()
|
|
23
|
+
.describe("The Firebase Data Connect connector ID to look for. If there is only one connector defined in dataconnect.yaml, this can be omitted and that will be used."),
|
|
24
|
+
variables: zod_1.z
|
|
25
|
+
.string()
|
|
26
|
+
.optional()
|
|
27
|
+
.describe("A stringified JSON object containing the variables needed to execute the operation. The value MUST be able to be parsed as a JSON object."),
|
|
28
|
+
use_emulator: zod_1.z.boolean().default(false).describe("Target the DataConnect emulator if true."),
|
|
29
|
+
}),
|
|
30
|
+
annotations: {
|
|
31
|
+
title: "Executes a deployed Data Connect query.",
|
|
32
|
+
readOnlyHint: true,
|
|
33
|
+
},
|
|
34
|
+
_meta: {
|
|
35
|
+
requiresProject: true,
|
|
36
|
+
requiresAuth: true,
|
|
37
|
+
},
|
|
38
|
+
}, async ({ operationName, service_id, connector_id, variables: unparsedVariables, use_emulator }, { projectId, config, host }) => {
|
|
39
|
+
const serviceInfo = await (0, fileUtils_js_1.pickService)(projectId, config, service_id || undefined);
|
|
40
|
+
let apiClient;
|
|
41
|
+
if (!connector_id) {
|
|
42
|
+
if (serviceInfo.connectorInfo.length === 0) {
|
|
43
|
+
return (0, util_js_1.mcpError)(`Service ${serviceInfo.serviceName} has no connectors`, "NO_CONNECTORS_FOUND");
|
|
44
|
+
}
|
|
45
|
+
if (serviceInfo.connectorInfo.length > 1) {
|
|
46
|
+
return (0, util_js_1.mcpError)(`Service ${serviceInfo.serviceName} has more than one connector. Please use the connector_id argument to specify which connector this operation is part of.`, "MULTIPLE_CONNECTORS_FOUND");
|
|
47
|
+
}
|
|
48
|
+
connector_id = serviceInfo.connectorInfo[0].connectorYaml.connectorId;
|
|
49
|
+
}
|
|
50
|
+
const connectorPath = `${serviceInfo.serviceName}/connectors/${connector_id}`;
|
|
51
|
+
if (use_emulator) {
|
|
52
|
+
apiClient = await (0, emulator_js_1.getDataConnectEmulatorClient)(await host.getEmulatorHubClient());
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
apiClient = dataplane.dataconnectDataplaneClient();
|
|
56
|
+
}
|
|
57
|
+
const response = await dataplane.executeGraphQLQuery(apiClient, connectorPath, {
|
|
58
|
+
operationName,
|
|
59
|
+
variables: (0, converter_js_1.parseVariables)(unparsedVariables),
|
|
60
|
+
});
|
|
61
|
+
return (0, converter_js_1.graphqlResponseToToolResponse)(response.body);
|
|
62
|
+
});
|
package/lib/mcp/tools/dataconnect/{generate_dataconnect_operation.js → generate_operation.js}
RENAMED
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.generate_operation = 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 fdcExperience_js_1 = require("../../../gif/fdcExperience.js");
|
|
8
8
|
const fileUtils_js_1 = require("../../../dataconnect/fileUtils.js");
|
|
9
|
-
exports.
|
|
10
|
-
name: "
|
|
9
|
+
exports.generate_operation = (0, tool_js_1.tool)({
|
|
10
|
+
name: "generate_operation",
|
|
11
11
|
description: "Generates a single Firebase Data Connect query or mutation based on the currently deployed schema and the provided prompt.",
|
|
12
12
|
inputSchema: zod_1.z.object({
|
|
13
13
|
prompt: zod_1.z
|
|
14
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
|
|
16
|
-
|
|
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 request"),
|
|
16
|
+
service_id: zod_1.z
|
|
17
17
|
.string()
|
|
18
18
|
.nullish()
|
|
19
|
-
.describe("Optional: Uses the
|
|
19
|
+
.describe("Optional: Uses the service ID from the firebase.json file if nothing provided. The service ID of the deployed Firebase resource."),
|
|
20
20
|
}),
|
|
21
21
|
annotations: {
|
|
22
|
-
title: "Generate
|
|
22
|
+
title: "Generate Data Connect Operation",
|
|
23
23
|
readOnlyHint: true,
|
|
24
24
|
},
|
|
25
25
|
_meta: {
|
|
26
26
|
requiresProject: true,
|
|
27
27
|
requiresAuth: true,
|
|
28
28
|
},
|
|
29
|
-
}, async ({ prompt,
|
|
30
|
-
const serviceInfo = await (0, fileUtils_js_1.pickService)(projectId, config,
|
|
29
|
+
}, async ({ prompt, service_id }, { projectId, config }) => {
|
|
30
|
+
const serviceInfo = await (0, fileUtils_js_1.pickService)(projectId, config, service_id || undefined);
|
|
31
31
|
const schema = await (0, fdcExperience_js_1.generateOperation)(prompt, serviceInfo.serviceName, projectId);
|
|
32
32
|
return (0, util_js_1.toContent)(schema);
|
|
33
33
|
});
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.generate_schema = 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 fdcExperience_js_1 = require("../../../gif/fdcExperience.js");
|
|
8
|
-
exports.
|
|
9
|
-
name: "
|
|
8
|
+
exports.generate_schema = (0, tool_js_1.tool)({
|
|
9
|
+
name: "generate_schema",
|
|
10
10
|
description: "Generates a Firebase Data Connect Schema based on the users description of an app.",
|
|
11
11
|
inputSchema: zod_1.z.object({
|
|
12
12
|
prompt: zod_1.z.string().describe("A description of an app that you are interested in building"),
|
|
13
13
|
}),
|
|
14
14
|
annotations: {
|
|
15
|
-
title: "Generate
|
|
15
|
+
title: "Generate Data Connect Schema",
|
|
16
16
|
readOnlyHint: true,
|
|
17
17
|
},
|
|
18
18
|
_meta: {
|
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.get_connectors = 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
|
-
const client = require("../../../dataconnect/client");
|
|
7
|
+
const client = require("../../../dataconnect/client.js");
|
|
8
8
|
const fileUtils_js_1 = require("../../../dataconnect/fileUtils.js");
|
|
9
9
|
const converter_js_1 = require("./converter.js");
|
|
10
|
-
exports.
|
|
11
|
-
name: "
|
|
10
|
+
exports.get_connectors = (0, tool_js_1.tool)({
|
|
11
|
+
name: "get_connectors",
|
|
12
12
|
description: "Get the Firebase Data Connect Connectors in the project, which includes the pre-defined GraphQL queries accessible to client SDKs.",
|
|
13
13
|
inputSchema: zod_1.z.object({
|
|
14
|
-
|
|
14
|
+
service_id: zod_1.z
|
|
15
15
|
.string()
|
|
16
16
|
.nullable()
|
|
17
|
-
.describe("The Firebase Data Connect service ID to look for.
|
|
17
|
+
.describe("The Firebase Data Connect service ID to look for. If there is only one service defined in firebase.json, this can be omitted and that will be used."),
|
|
18
18
|
}),
|
|
19
19
|
annotations: {
|
|
20
|
-
title: "
|
|
20
|
+
title: "Get Data Connect Connectors",
|
|
21
21
|
readOnlyHint: true,
|
|
22
22
|
},
|
|
23
23
|
_meta: {
|
|
24
24
|
requiresProject: true,
|
|
25
25
|
requiresAuth: true,
|
|
26
26
|
},
|
|
27
|
-
}, async ({
|
|
28
|
-
const serviceInfo = await (0, fileUtils_js_1.pickService)(projectId, config,
|
|
27
|
+
}, async ({ service_id }, { projectId, config }) => {
|
|
28
|
+
const serviceInfo = await (0, fileUtils_js_1.pickService)(projectId, config, service_id || undefined);
|
|
29
29
|
const connectors = await client.listConnectors(serviceInfo.serviceName, ["*"]);
|
|
30
30
|
return (0, util_js_1.toContent)(connectors.map(converter_js_1.connectorToText).join("\n\n"));
|
|
31
31
|
});
|
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.get_schema = 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
|
-
const client = require("../../../dataconnect/client");
|
|
7
|
+
const client = require("../../../dataconnect/client.js");
|
|
8
8
|
const fileUtils_js_1 = require("../../../dataconnect/fileUtils.js");
|
|
9
9
|
const converter_js_1 = require("./converter.js");
|
|
10
|
-
exports.
|
|
11
|
-
name: "
|
|
12
|
-
description: "
|
|
10
|
+
exports.get_schema = (0, tool_js_1.tool)({
|
|
11
|
+
name: "get_schema",
|
|
12
|
+
description: "Retrieve information about the Firebase Data Connect Schema in the project, including Cloud SQL data sources and the GraphQL Schema describing the data model.",
|
|
13
13
|
inputSchema: zod_1.z.object({
|
|
14
|
-
|
|
14
|
+
service_id: zod_1.z
|
|
15
15
|
.string()
|
|
16
16
|
.nullable()
|
|
17
|
-
.describe("The Firebase Data Connect service ID to look for.
|
|
17
|
+
.describe("The Firebase Data Connect service ID to look for. If there is only one service defined in firebase.json, this can be omitted and that will be used."),
|
|
18
18
|
}),
|
|
19
19
|
annotations: {
|
|
20
|
-
title: "
|
|
20
|
+
title: "Get Data Connect Schemas",
|
|
21
21
|
readOnlyHint: true,
|
|
22
22
|
},
|
|
23
23
|
_meta: {
|
|
24
24
|
requiresProject: true,
|
|
25
25
|
requiresAuth: true,
|
|
26
26
|
},
|
|
27
|
-
}, async ({
|
|
28
|
-
const serviceInfo = await (0, fileUtils_js_1.pickService)(projectId, config,
|
|
27
|
+
}, async ({ service_id }, { projectId, config }) => {
|
|
28
|
+
const serviceInfo = await (0, fileUtils_js_1.pickService)(projectId, config, service_id || undefined);
|
|
29
29
|
const schemas = await client.listSchemas(serviceInfo.serviceName, ["*"]);
|
|
30
30
|
return (0, util_js_1.toContent)(schemas === null || schemas === void 0 ? void 0 : schemas.map(converter_js_1.schemaToText).join("\n\n"));
|
|
31
31
|
});
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.dataconnectTools = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
4
|
+
const list_services_js_1 = require("./list_services.js");
|
|
5
|
+
const get_schema_js_1 = require("./get_schema.js");
|
|
6
|
+
const get_connector_js_1 = require("./get_connector.js");
|
|
7
|
+
const execute_graphql_js_1 = require("./execute_graphql.js");
|
|
8
|
+
const execute_graphql_read_js_1 = require("./execute_graphql_read.js");
|
|
9
|
+
const execute_query_js_1 = require("./execute_query.js");
|
|
10
|
+
const execute_mutation_js_1 = require("./execute_mutation.js");
|
|
9
11
|
exports.dataconnectTools = [
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
list_services_js_1.list_services,
|
|
13
|
+
get_schema_js_1.get_schema,
|
|
14
|
+
get_connector_js_1.get_connectors,
|
|
15
|
+
execute_graphql_js_1.execute_graphql,
|
|
16
|
+
execute_graphql_read_js_1.execute_graphql_read,
|
|
17
|
+
execute_mutation_js_1.execute_mutation,
|
|
18
|
+
execute_query_js_1.execute_query,
|
|
15
19
|
];
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.list_services = 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
|
-
const client = require("../../../dataconnect/client");
|
|
8
|
-
exports.
|
|
9
|
-
name: "
|
|
7
|
+
const client = require("../../../dataconnect/client.js");
|
|
8
|
+
exports.list_services = (0, tool_js_1.tool)({
|
|
9
|
+
name: "list_services",
|
|
10
10
|
description: "List the Firebase Data Connect services available in the current project.",
|
|
11
11
|
inputSchema: zod_1.z.object({}),
|
|
12
12
|
annotations: {
|
|
13
|
-
title: "List
|
|
13
|
+
title: "List Data Connect Services",
|
|
14
14
|
readOnlyHint: true,
|
|
15
15
|
},
|
|
16
16
|
_meta: {
|
|
@@ -1,7 +1,53 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.firestoreDocumentToJson = void 0;
|
|
3
|
+
exports.firestoreDocumentToJson = exports.convertInputToValue = void 0;
|
|
4
4
|
const logger_1 = require("../../../logger");
|
|
5
|
+
function convertInputToValue(inputValue) {
|
|
6
|
+
if (inputValue === null) {
|
|
7
|
+
return { nullValue: null };
|
|
8
|
+
}
|
|
9
|
+
else if (typeof inputValue === "boolean") {
|
|
10
|
+
return { booleanValue: inputValue };
|
|
11
|
+
}
|
|
12
|
+
else if (typeof inputValue === "number") {
|
|
13
|
+
if (Number.isInteger(inputValue)) {
|
|
14
|
+
return { integerValue: inputValue.toString() };
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
return { doubleValue: inputValue };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
else if (typeof inputValue === "string") {
|
|
21
|
+
return { stringValue: inputValue };
|
|
22
|
+
}
|
|
23
|
+
else if (Array.isArray(inputValue)) {
|
|
24
|
+
const arrayValue = {
|
|
25
|
+
values: inputValue.map((item) => convertInputToValue(item)),
|
|
26
|
+
};
|
|
27
|
+
return { arrayValue: arrayValue };
|
|
28
|
+
}
|
|
29
|
+
else if (typeof inputValue === "object") {
|
|
30
|
+
if (inputValue.hasOwnProperty("latitude") &&
|
|
31
|
+
typeof inputValue.latitude === "number" &&
|
|
32
|
+
inputValue.hasOwnProperty("longitude") &&
|
|
33
|
+
typeof inputValue.longitude === "number") {
|
|
34
|
+
return { geoPointValue: inputValue };
|
|
35
|
+
}
|
|
36
|
+
const mapValue = {
|
|
37
|
+
fields: {},
|
|
38
|
+
};
|
|
39
|
+
for (const key in inputValue) {
|
|
40
|
+
if (Object.prototype.hasOwnProperty.call(inputValue, key)) {
|
|
41
|
+
if (mapValue.fields) {
|
|
42
|
+
mapValue.fields[key] = convertInputToValue(inputValue[key]);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return { mapValue: mapValue };
|
|
47
|
+
}
|
|
48
|
+
return { nullValue: null };
|
|
49
|
+
}
|
|
50
|
+
exports.convertInputToValue = convertInputToValue;
|
|
5
51
|
function firestoreValueToJson(firestoreValue) {
|
|
6
52
|
var _a, _b;
|
|
7
53
|
if ("nullValue" in firestoreValue)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.delete_document = 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 firestore_js_1 = require("../../../gcp/firestore.js");
|
|
8
|
+
const delete_js_1 = require("../../../firestore/delete.js");
|
|
9
|
+
exports.delete_document = (0, tool_js_1.tool)({
|
|
10
|
+
name: "delete_document",
|
|
11
|
+
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.",
|
|
12
|
+
inputSchema: zod_1.z.object({
|
|
13
|
+
path: zod_1.z
|
|
14
|
+
.string()
|
|
15
|
+
.describe("A document path (e.g. `collectionName/documentId` or `parentCollection/parentDocument/collectionName/documentId`)"),
|
|
16
|
+
}),
|
|
17
|
+
annotations: {
|
|
18
|
+
title: "Delete Firestore document",
|
|
19
|
+
destructiveHint: true,
|
|
20
|
+
},
|
|
21
|
+
_meta: {
|
|
22
|
+
requiresAuth: true,
|
|
23
|
+
requiresProject: true,
|
|
24
|
+
},
|
|
25
|
+
}, async ({ path }, { projectId }) => {
|
|
26
|
+
const { documents, missing } = await (0, firestore_js_1.getDocuments)(projectId, [path]);
|
|
27
|
+
if (missing.length > 0 && documents && documents.length === 0) {
|
|
28
|
+
return (0, util_js_1.mcpError)(`None of the specified documents were found in project '${projectId}'`);
|
|
29
|
+
}
|
|
30
|
+
const firestoreDelete = new delete_js_1.FirestoreDelete(projectId, path, { databaseId: "(default)" });
|
|
31
|
+
await firestoreDelete.execute();
|
|
32
|
+
const { documents: postDeleteDocuments, missing: postDeleteMissing } = await (0, firestore_js_1.getDocuments)(projectId, [path]);
|
|
33
|
+
if (postDeleteMissing.length > 0 && postDeleteDocuments.length === 0) {
|
|
34
|
+
return (0, util_js_1.toContent)(`Successfully removed document located at : ${path}`);
|
|
35
|
+
}
|
|
36
|
+
return (0, util_js_1.mcpError)(`Failed to remove document located at : ${path}`);
|
|
37
|
+
});
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.get_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_documents = (0, tool_js_1.tool)({
|
|
10
|
+
name: "get_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
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.firestoreTools = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
4
|
+
const delete_document_1 = require("./delete_document");
|
|
5
|
+
const get_documents_1 = require("./get_documents");
|
|
6
|
+
const list_collections_1 = require("./list_collections");
|
|
7
|
+
const query_collection_1 = require("./query_collection");
|
|
8
|
+
const validate_rules_1 = require("../rules/validate_rules");
|
|
9
|
+
const get_rules_1 = require("../rules/get_rules");
|
|
7
10
|
exports.firestoreTools = [
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
delete_document_1.delete_document,
|
|
12
|
+
get_documents_1.get_documents,
|
|
13
|
+
list_collections_1.list_collections,
|
|
14
|
+
query_collection_1.query_collection,
|
|
15
|
+
(0, get_rules_1.getRulesTool)("Firestore", "cloud.firestore"),
|
|
16
|
+
(0, validate_rules_1.validateRulesTool)("Firestore"),
|
|
11
17
|
];
|