firebase-tools 14.12.0 → 14.13.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/README.md +1 -1
- package/lib/commands/dataconnect-services-list.js +5 -5
- package/lib/commands/dataconnect-sql-grant.js +5 -0
- package/lib/commands/dataconnect-sql-setup.js +1 -3
- package/lib/commands/firestore-databases-create.js +11 -0
- package/lib/crashlytics/buildToolsJarHelper.js +1 -2
- package/lib/crashlytics/getIssueDetails.js +41 -0
- package/lib/crashlytics/getSampleCrash.js +48 -0
- package/lib/dataconnect/client.js +23 -15
- package/lib/dataconnect/ensureApis.js +5 -9
- package/lib/dataconnect/fileUtils.js +5 -6
- package/lib/dataconnect/freeTrial.js +16 -39
- package/lib/dataconnect/provisionCloudSql.js +67 -70
- package/lib/dataconnect/schemaMigration.js +75 -47
- package/lib/deploy/dataconnect/deploy.js +9 -11
- package/lib/deploy/dataconnect/prepare.js +9 -12
- package/lib/deploy/dataconnect/release.js +13 -7
- package/lib/deploy/firestore/deploy.js +10 -0
- package/lib/deploy/functions/backend.js +8 -2
- package/lib/deploy/functions/build.js +23 -1
- package/lib/deploy/functions/ensure.js +1 -1
- package/lib/deploy/functions/functionsDeployHelper.js +8 -1
- package/lib/deploy/functions/prepare.js +6 -4
- package/lib/deploy/functions/prepareFunctionsUpload.js +3 -1
- package/lib/deploy/functions/pricing.js +12 -5
- package/lib/deploy/functions/release/fabricator.js +25 -3
- package/lib/emulator/controller.js +2 -1
- package/lib/emulator/downloadableEmulatorInfo.json +18 -18
- package/lib/emulator/functionsEmulator.js +9 -1
- package/lib/experiments.js +4 -0
- package/lib/extensions/extensionsHelper.js +4 -15
- package/lib/extensions/utils.js +1 -12
- package/lib/firestore/api-sort.js +96 -3
- package/lib/firestore/api-types.js +14 -1
- package/lib/firestore/api.js +85 -4
- package/lib/firestore/pretty-print.js +7 -0
- package/lib/firestore/validator.js +1 -1
- package/lib/functional.js +7 -1
- package/lib/functions/deprecationWarnings.js +4 -4
- package/lib/functions/projectConfig.js +25 -2
- package/lib/functions/secrets.js +3 -0
- package/lib/gcp/cloudfunctionsv2.js +3 -31
- package/lib/gcp/cloudscheduler.js +1 -1
- package/lib/gcp/cloudsql/cloudsqladmin.js +2 -14
- package/lib/gcp/cloudsql/connect.js +2 -2
- package/lib/gcp/cloudsql/permissionsSetup.js +13 -15
- package/lib/gcp/k8s.js +32 -0
- package/lib/gcp/runv2.js +178 -0
- package/lib/gemini/fdcExperience.js +5 -3
- package/lib/init/features/dataconnect/index.js +266 -162
- package/lib/init/features/dataconnect/sdk.js +32 -17
- package/lib/init/features/project.js +4 -0
- package/lib/management/studio.js +1 -1
- package/lib/mcp/index.js +75 -2
- package/lib/mcp/prompt.js +10 -0
- package/lib/mcp/prompts/core/deploy.js +58 -0
- package/lib/mcp/prompts/core/index.js +5 -0
- package/lib/mcp/prompts/index.js +45 -0
- package/lib/mcp/tools/core/get_sdk_config.js +10 -0
- package/lib/mcp/tools/core/init.js +7 -6
- package/lib/mcp/tools/crashlytics/get_issue_details.js +33 -0
- package/lib/mcp/tools/crashlytics/get_sample_crash.js +43 -0
- package/lib/mcp/tools/crashlytics/index.js +7 -1
- package/lib/mcp/tools/crashlytics/list_top_issues.js +2 -1
- package/lib/mcp/tools/database/get_data.js +49 -0
- package/lib/mcp/tools/database/get_rules.js +39 -0
- package/lib/mcp/tools/database/index.js +8 -0
- package/lib/mcp/tools/database/set_data.js +57 -0
- package/lib/mcp/tools/database/set_rules.js +41 -0
- package/lib/mcp/tools/database/validate_rules.js +41 -0
- package/lib/mcp/tools/index.js +4 -1
- package/lib/mcp/tools/rules/get_rules.js +1 -1
- package/lib/mcp/types.js +2 -0
- package/lib/mcp/util.js +2 -0
- package/lib/rtdb.js +10 -6
- package/lib/utils.js +24 -1
- package/package.json +1 -1
- package/schema/firebase-config.json +6 -0
- package/templates/init/firestore/firestore.indexes.json +26 -1
- package/lib/extensions/resolveSource.js +0 -24
package/lib/mcp/tools/index.js
CHANGED
|
@@ -10,8 +10,9 @@ const index_6 = require("./messaging/index");
|
|
|
10
10
|
const index_7 = require("./remoteconfig/index");
|
|
11
11
|
const index_8 = require("./crashlytics/index");
|
|
12
12
|
const index_9 = require("./apphosting/index");
|
|
13
|
+
const index_10 = require("./database/index");
|
|
13
14
|
function availableTools(activeFeatures) {
|
|
14
|
-
const toolDefs =
|
|
15
|
+
const toolDefs = [];
|
|
15
16
|
if (!(activeFeatures === null || activeFeatures === void 0 ? void 0 : activeFeatures.length)) {
|
|
16
17
|
activeFeatures = Object.keys(tools);
|
|
17
18
|
}
|
|
@@ -22,6 +23,7 @@ function availableTools(activeFeatures) {
|
|
|
22
23
|
}
|
|
23
24
|
exports.availableTools = availableTools;
|
|
24
25
|
const tools = {
|
|
26
|
+
core: addFeaturePrefix("firebase", index_4.coreTools),
|
|
25
27
|
firestore: addFeaturePrefix("firestore", index_3.firestoreTools),
|
|
26
28
|
auth: addFeaturePrefix("auth", index_1.authTools),
|
|
27
29
|
dataconnect: addFeaturePrefix("dataconnect", index_2.dataconnectTools),
|
|
@@ -30,6 +32,7 @@ const tools = {
|
|
|
30
32
|
remoteconfig: addFeaturePrefix("remoteconfig", index_7.remoteConfigTools),
|
|
31
33
|
crashlytics: addFeaturePrefix("crashlytics", index_8.crashlyticsTools),
|
|
32
34
|
apphosting: addFeaturePrefix("apphosting", index_9.appHostingTools),
|
|
35
|
+
database: addFeaturePrefix("database", index_10.realtimeDatabaseTools),
|
|
33
36
|
};
|
|
34
37
|
function addFeaturePrefix(feature, tools) {
|
|
35
38
|
return tools.map((tool) => (Object.assign(Object.assign({}, tool), { mcp: Object.assign(Object.assign({}, tool.mcp), { name: `${feature}_${tool.mcp.name}`, _meta: Object.assign(Object.assign({}, tool.mcp._meta), { feature }) }) })));
|
|
@@ -21,7 +21,7 @@ function getRulesTool(productName, releaseName) {
|
|
|
21
21
|
}, async (_, { projectId }) => {
|
|
22
22
|
const rulesetName = await (0, rules_1.getLatestRulesetName)(projectId, releaseName);
|
|
23
23
|
if (!rulesetName)
|
|
24
|
-
return (0, util_1.mcpError)(`No active
|
|
24
|
+
return (0, util_1.mcpError)(`No active ${productName} rules were found in project '${projectId}'`);
|
|
25
25
|
const rules = await (0, rules_1.getRulesetContent)(rulesetName);
|
|
26
26
|
return (0, util_1.toContent)(rules[0].content);
|
|
27
27
|
});
|
package/lib/mcp/types.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SERVER_FEATURES = void 0;
|
|
4
4
|
exports.SERVER_FEATURES = [
|
|
5
|
+
"core",
|
|
5
6
|
"firestore",
|
|
6
7
|
"storage",
|
|
7
8
|
"dataconnect",
|
|
@@ -10,4 +11,5 @@ exports.SERVER_FEATURES = [
|
|
|
10
11
|
"remoteconfig",
|
|
11
12
|
"crashlytics",
|
|
12
13
|
"apphosting",
|
|
14
|
+
"database",
|
|
13
15
|
];
|
package/lib/mcp/util.js
CHANGED
|
@@ -56,6 +56,7 @@ function commandExistsSync(command) {
|
|
|
56
56
|
}
|
|
57
57
|
exports.commandExistsSync = commandExistsSync;
|
|
58
58
|
const SERVER_FEATURE_APIS = {
|
|
59
|
+
core: "",
|
|
59
60
|
firestore: (0, api_1.firestoreOrigin)(),
|
|
60
61
|
storage: (0, api_1.storageOrigin)(),
|
|
61
62
|
dataconnect: (0, api_1.dataconnectOrigin)(),
|
|
@@ -64,6 +65,7 @@ const SERVER_FEATURE_APIS = {
|
|
|
64
65
|
remoteconfig: (0, api_1.remoteConfigApiOrigin)(),
|
|
65
66
|
crashlytics: (0, api_1.crashlyticsApiOrigin)(),
|
|
66
67
|
apphosting: (0, api_1.apphostingOrigin)(),
|
|
68
|
+
database: (0, api_1.realtimeOrigin)(),
|
|
67
69
|
};
|
|
68
70
|
async function checkFeatureActive(feature, projectId, options) {
|
|
69
71
|
var _a;
|
package/lib/rtdb.js
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.updateRules = void 0;
|
|
3
|
+
exports.updateRulesWithClient = exports.updateRules = void 0;
|
|
4
4
|
const apiv2_1 = require("./apiv2");
|
|
5
5
|
const database_1 = require("./management/database");
|
|
6
6
|
const error_1 = require("./error");
|
|
7
7
|
const api_1 = require("./database/api");
|
|
8
8
|
const utils = require("./utils");
|
|
9
9
|
async function updateRules(projectId, instance, src, options = {}) {
|
|
10
|
-
const queryParams = {};
|
|
11
|
-
if (options.dryRun) {
|
|
12
|
-
queryParams.dryRun = "true";
|
|
13
|
-
}
|
|
14
10
|
const downstreamOptions = { instance: instance, project: projectId };
|
|
15
11
|
await (0, database_1.populateInstanceDetails)(downstreamOptions);
|
|
16
12
|
if (!downstreamOptions.instanceDetails) {
|
|
@@ -18,6 +14,14 @@ async function updateRules(projectId, instance, src, options = {}) {
|
|
|
18
14
|
}
|
|
19
15
|
const origin = utils.getDatabaseUrl((0, api_1.realtimeOriginOrCustomUrl)(downstreamOptions.instanceDetails.databaseUrl), instance, "");
|
|
20
16
|
const client = new apiv2_1.Client({ urlPrefix: origin });
|
|
17
|
+
return updateRulesWithClient(client, src, options);
|
|
18
|
+
}
|
|
19
|
+
exports.updateRules = updateRules;
|
|
20
|
+
async function updateRulesWithClient(client, src, options = {}) {
|
|
21
|
+
const queryParams = {};
|
|
22
|
+
if (options.dryRun) {
|
|
23
|
+
queryParams.dryRun = "true";
|
|
24
|
+
}
|
|
21
25
|
const response = await client.request({
|
|
22
26
|
method: "PUT",
|
|
23
27
|
path: ".settings/rules.json",
|
|
@@ -32,4 +36,4 @@ async function updateRules(projectId, instance, src, options = {}) {
|
|
|
32
36
|
throw new error_1.FirebaseError("Unexpected error while deploying database rules.", { exit: 2 });
|
|
33
37
|
}
|
|
34
38
|
}
|
|
35
|
-
exports.
|
|
39
|
+
exports.updateRulesWithClient = updateRulesWithClient;
|
package/lib/utils.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.openInBrowserPopup = exports.openInBrowser = exports.connectableHostname = exports.randomInt = exports.debounce = exports.last = exports.cloneDeep = exports.groupBy = exports.assertIsStringOrUndefined = exports.assertIsNumber = exports.assertIsString = exports.thirtyDaysFromNow = exports.isRunningInWSL = exports.isCloudEnvironment = exports.datetimeString = exports.createDestroyer = exports.sleep = exports.promiseWithSpinner = exports.tryParse = exports.promiseProps = exports.withTimeout = exports.promiseWhile = exports.promiseAllSettled = exports.getFunctionsEventProvider = exports.endpoint = exports.makeActiveProject = exports.streamToString = exports.stringToStream = exports.explainStdin = exports.allSettled = exports.reject = exports.logLabeledError = exports.logLabeledWarning = exports.logWarningToStderr = exports.logWarning = exports.logLabeledBullet = exports.logBullet = exports.logLabeledSuccess = exports.logSuccess = exports.addSubdomain = exports.addDatabaseNamespace = exports.getDatabaseViewDataUrl = exports.getDatabaseUrl = exports.envOverride = exports.setVSCodeEnvVars = exports.getInheritedOption = exports.consoleUrl = exports.vscodeEnvVars = exports.envOverrides = exports.IS_WINDOWS = void 0;
|
|
4
|
-
exports.deepEqual = exports.promptForDirectory = exports.updateOrCreateGitignore = exports.readSecretValue = exports.generateId = exports.wrappedSafeLoad = exports.readFileFromDirectory = exports.getHostnameFromUrl = void 0;
|
|
4
|
+
exports.deepEqual = exports.promptForDirectory = exports.updateOrCreateGitignore = exports.readSecretValue = exports.generatePassword = exports.generateId = exports.wrappedSafeLoad = exports.readFileFromDirectory = exports.getHostnameFromUrl = void 0;
|
|
5
5
|
const fs = require("fs-extra");
|
|
6
6
|
const tty = require("tty");
|
|
7
7
|
const path = require("node:path");
|
|
8
8
|
const yaml = require("yaml");
|
|
9
|
+
const crypto = require("node:crypto");
|
|
9
10
|
const _ = require("lodash");
|
|
10
11
|
const url = require("url");
|
|
11
12
|
const http = require("http");
|
|
@@ -546,6 +547,28 @@ function generateId(n = 6) {
|
|
|
546
547
|
return id;
|
|
547
548
|
}
|
|
548
549
|
exports.generateId = generateId;
|
|
550
|
+
function generatePassword(n = 20) {
|
|
551
|
+
const lower = "abcdefghijklmnopqrstuvwxyz";
|
|
552
|
+
const upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
553
|
+
const numbers = "0123456789";
|
|
554
|
+
const special = "!@#$%^&*()_+~`|}{[]:;?><,./-=";
|
|
555
|
+
const all = lower + upper + numbers + special;
|
|
556
|
+
let pw = "";
|
|
557
|
+
pw += lower[crypto.randomInt(lower.length)];
|
|
558
|
+
pw += upper[crypto.randomInt(upper.length)];
|
|
559
|
+
pw += numbers[crypto.randomInt(numbers.length)];
|
|
560
|
+
pw += special[crypto.randomInt(special.length)];
|
|
561
|
+
for (let i = 4; i < n; i++) {
|
|
562
|
+
pw += all[crypto.randomInt(all.length)];
|
|
563
|
+
}
|
|
564
|
+
const pwArray = pw.split("");
|
|
565
|
+
for (let i = pwArray.length - 1; i > 0; i--) {
|
|
566
|
+
const j = crypto.randomInt(i);
|
|
567
|
+
[pwArray[i], pwArray[j]] = [pwArray[j], pwArray[i]];
|
|
568
|
+
}
|
|
569
|
+
return pwArray.join("");
|
|
570
|
+
}
|
|
571
|
+
exports.generatePassword = generatePassword;
|
|
549
572
|
function readSecretValue(prompt, dataFile) {
|
|
550
573
|
if ((!dataFile || dataFile === "-") && tty.isatty(0)) {
|
|
551
574
|
return (0, prompt_1.password)({ message: prompt });
|
package/package.json
CHANGED
|
@@ -88,6 +88,9 @@
|
|
|
88
88
|
"database": {
|
|
89
89
|
"type": "string"
|
|
90
90
|
},
|
|
91
|
+
"edition": {
|
|
92
|
+
"type": "string"
|
|
93
|
+
},
|
|
91
94
|
"indexes": {
|
|
92
95
|
"type": "string"
|
|
93
96
|
},
|
|
@@ -276,6 +279,9 @@
|
|
|
276
279
|
}
|
|
277
280
|
]
|
|
278
281
|
},
|
|
282
|
+
"prefix": {
|
|
283
|
+
"type": "string"
|
|
284
|
+
},
|
|
279
285
|
"runtime": {
|
|
280
286
|
"enum": [
|
|
281
287
|
"nodejs18",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
// Example:
|
|
2
|
+
// Example (Standard Edition):
|
|
3
3
|
//
|
|
4
4
|
// "indexes": [
|
|
5
5
|
// {
|
|
@@ -21,6 +21,31 @@
|
|
|
21
21
|
// },
|
|
22
22
|
// ]
|
|
23
23
|
// ]
|
|
24
|
+
//
|
|
25
|
+
// Example (Enterprise Edition):
|
|
26
|
+
//
|
|
27
|
+
// "indexes": [
|
|
28
|
+
// {
|
|
29
|
+
// "collectionGroup": "reviews",
|
|
30
|
+
// "queryScope": "COLLECTION_GROUP",
|
|
31
|
+
// "apiScope": "MONGODB_COMPATIBLE_API",
|
|
32
|
+
// "density": "DENSE",
|
|
33
|
+
// "multikey": false,
|
|
34
|
+
// "fields": [
|
|
35
|
+
// { "fieldPath": "baz", "mode": "ASCENDING" }
|
|
36
|
+
// ]
|
|
37
|
+
// },
|
|
38
|
+
// {
|
|
39
|
+
// "collectionGroup": "items",
|
|
40
|
+
// "queryScope": "COLLECTION_GROUP",
|
|
41
|
+
// "apiScope": "MONGODB_COMPATIBLE_API",
|
|
42
|
+
// "density": "SPARSE_ANY",
|
|
43
|
+
// "multikey": true,
|
|
44
|
+
// "fields": [
|
|
45
|
+
// { "fieldPath": "baz", "mode": "ASCENDING" }
|
|
46
|
+
// ]
|
|
47
|
+
// },
|
|
48
|
+
// ]
|
|
24
49
|
"indexes": [],
|
|
25
50
|
"fieldOverrides": []
|
|
26
51
|
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getExtensionRegistry = void 0;
|
|
4
|
-
const apiv2_1 = require("../apiv2");
|
|
5
|
-
const api_1 = require("../api");
|
|
6
|
-
const EXTENSIONS_REGISTRY_ENDPOINT = "/extensions.json";
|
|
7
|
-
async function getExtensionRegistry(onlyFeatured = false) {
|
|
8
|
-
var _a;
|
|
9
|
-
const client = new apiv2_1.Client({ urlPrefix: (0, api_1.firebaseExtensionsRegistryOrigin)() });
|
|
10
|
-
const res = await client.get(EXTENSIONS_REGISTRY_ENDPOINT);
|
|
11
|
-
const extensions = res.body.mods || {};
|
|
12
|
-
if (onlyFeatured) {
|
|
13
|
-
const featuredList = new Set(((_a = res.body.featured) === null || _a === void 0 ? void 0 : _a.discover) || []);
|
|
14
|
-
const filteredExtensions = {};
|
|
15
|
-
for (const [name, extension] of Object.entries(extensions)) {
|
|
16
|
-
if (featuredList.has(name)) {
|
|
17
|
-
filteredExtensions[name] = extension;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return filteredExtensions;
|
|
21
|
-
}
|
|
22
|
-
return extensions;
|
|
23
|
-
}
|
|
24
|
-
exports.getExtensionRegistry = getExtensionRegistry;
|