firebase-tools 15.4.0 → 15.5.1
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/apiv2.js +14 -3
- package/lib/appdistribution/client.js +2 -1
- package/lib/apphosting/backend.js +1 -1
- package/lib/apptesting/parseTestFiles.js +91 -43
- package/lib/bin/cli.js +2 -2
- package/lib/command.js +3 -0
- package/lib/commands/apptesting.js +75 -0
- package/lib/commands/dataconnect-compile.js +46 -0
- package/lib/commands/firestore-databases-create.js +69 -12
- package/lib/commands/firestore-databases-update.js +6 -14
- package/lib/commands/index.js +2 -0
- package/lib/dataconnect/client.js +2 -1
- package/lib/deploy/functions/prepare.js +1 -0
- package/lib/deploy/functions/validate.js +25 -0
- package/lib/emulator/auth/operations.js +2 -2
- package/lib/emulator/dataconnect/pgliteServer.js +26 -33
- package/lib/emulator/downloadableEmulatorInfo.json +24 -24
- package/lib/ensureApiEnabled.js +2 -2
- package/lib/firestore/api-types.js +26 -11
- package/lib/firestore/api.js +3 -0
- package/lib/gcp/iam.js +2 -2
- package/lib/gcp/rules.js +5 -2
- package/lib/gcp/serviceusage.js +2 -2
- package/lib/init/features/firestore/indexes.js +1 -1
- package/lib/init/features/{storage.js → storage/index.js} +12 -4
- package/lib/init/features/storage/rules.js +20 -0
- package/lib/mcp/tools/core/get_security_rules.js +1 -1
- package/lib/mcp/tools/crashlytics/reports.js +1 -1
- package/lib/mcp/tools/firestore/delete_document.js +1 -1
- package/lib/mcp/tools/firestore/query_collection.js +1 -1
- package/lib/tsconfig.publish.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/templates/init/apptesting/smoke_test.yaml +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.PGliteLoggerPatch = exports.PostgresServer = exports.TRUNCATE_TABLES_SQL = void 0;
|
|
4
4
|
exports.fromNodeSocket = fromNodeSocket;
|
|
5
5
|
const pglite_1 = require("@electric-sql/pglite");
|
|
6
6
|
const { dynamicImport } = require(true && "../../dynamicImport");
|
|
@@ -42,12 +42,12 @@ class PostgresServer {
|
|
|
42
42
|
await db.query("DEALLOCATE ALL");
|
|
43
43
|
}
|
|
44
44
|
const response = await db.execProtocolRaw(data);
|
|
45
|
-
for await (const message of extendedQueryPatch.
|
|
45
|
+
for await (const message of extendedQueryPatch.getMessages(data, response)) {
|
|
46
46
|
yield message;
|
|
47
47
|
}
|
|
48
48
|
},
|
|
49
49
|
});
|
|
50
|
-
const extendedQueryPatch = new
|
|
50
|
+
const extendedQueryPatch = new PGliteLoggerPatch(connection);
|
|
51
51
|
socket.on("end", () => {
|
|
52
52
|
logger_1.logger.debug("Postgres client disconnected");
|
|
53
53
|
});
|
|
@@ -202,42 +202,35 @@ async function fromNodeSocket(socket, options) {
|
|
|
202
202
|
: undefined;
|
|
203
203
|
return new pg_gateway_1.PostgresConnection({ readable: rs, writable: ws }, opts);
|
|
204
204
|
}
|
|
205
|
-
|
|
205
|
+
const CODE_TO_FRONTEND_MESSAGE = {};
|
|
206
|
+
for (const key in pg_gateway_1.FrontendMessageCode) {
|
|
207
|
+
if (Object.prototype.hasOwnProperty.call(pg_gateway_1.FrontendMessageCode, key)) {
|
|
208
|
+
CODE_TO_FRONTEND_MESSAGE[pg_gateway_1.FrontendMessageCode[key]] = key;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const CODE_TO_BACKEND_MESSAGE = {};
|
|
212
|
+
for (const key in pg_gateway_1.BackendMessageCode) {
|
|
213
|
+
if (Object.prototype.hasOwnProperty.call(pg_gateway_1.BackendMessageCode, key)) {
|
|
214
|
+
CODE_TO_BACKEND_MESSAGE[pg_gateway_1.BackendMessageCode[key]] = key;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function codeToFrontendMessageName(code) {
|
|
218
|
+
return CODE_TO_FRONTEND_MESSAGE[code] || `UNKNOWN_FRONTEND_CODE_${code}`;
|
|
219
|
+
}
|
|
220
|
+
function codeTogBackendMessageName(code) {
|
|
221
|
+
return CODE_TO_BACKEND_MESSAGE[code] || `UNKNOWN_BACKEND_CODE_${code}`;
|
|
222
|
+
}
|
|
223
|
+
class PGliteLoggerPatch {
|
|
206
224
|
constructor(connection) {
|
|
207
225
|
this.connection = connection;
|
|
208
|
-
this.isExtendedQuery = false;
|
|
209
|
-
this.eqpErrored = false;
|
|
210
226
|
this.pgliteDebugLog = fs.createWriteStream("pglite-debug.log");
|
|
211
227
|
}
|
|
212
|
-
async *
|
|
213
|
-
|
|
214
|
-
pg_gateway_1.FrontendMessageCode.Parse,
|
|
215
|
-
pg_gateway_1.FrontendMessageCode.Bind,
|
|
216
|
-
pg_gateway_1.FrontendMessageCode.Close,
|
|
217
|
-
];
|
|
218
|
-
const decoded = decoder.write(message);
|
|
219
|
-
this.pgliteDebugLog.write("Front: " + decoded);
|
|
220
|
-
if (pipelineStartMessages.includes(message[0])) {
|
|
221
|
-
this.isExtendedQuery = true;
|
|
222
|
-
}
|
|
223
|
-
if (message[0] === pg_gateway_1.FrontendMessageCode.Sync) {
|
|
224
|
-
this.isExtendedQuery = false;
|
|
225
|
-
this.eqpErrored = false;
|
|
226
|
-
}
|
|
228
|
+
async *getMessages(request, response) {
|
|
229
|
+
this.pgliteDebugLog.write(`\n[-> ${codeToFrontendMessageName(request[0])}] ` + decoder.write(request));
|
|
227
230
|
for await (const bm of (0, pg_gateway_1.getMessages)(response)) {
|
|
228
|
-
|
|
229
|
-
continue;
|
|
230
|
-
}
|
|
231
|
-
if (this.isExtendedQuery && bm[0] === pg_gateway_1.BackendMessageCode.ErrorMessage) {
|
|
232
|
-
this.eqpErrored = true;
|
|
233
|
-
}
|
|
234
|
-
if (this.isExtendedQuery && bm[0] === pg_gateway_1.BackendMessageCode.ReadyForQuery) {
|
|
235
|
-
this.pgliteDebugLog.write("Filtered: " + decoder.write(bm));
|
|
236
|
-
continue;
|
|
237
|
-
}
|
|
238
|
-
this.pgliteDebugLog.write("Sent: " + decoder.write(bm));
|
|
231
|
+
this.pgliteDebugLog.write(`\n[<- ${codeTogBackendMessageName(bm[0])}] ${decoder.write(bm)}`);
|
|
239
232
|
yield bm;
|
|
240
233
|
}
|
|
241
234
|
}
|
|
242
235
|
}
|
|
243
|
-
exports.
|
|
236
|
+
exports.PGliteLoggerPatch = PGliteLoggerPatch;
|
|
@@ -54,36 +54,36 @@
|
|
|
54
54
|
},
|
|
55
55
|
"dataconnect": {
|
|
56
56
|
"darwin": {
|
|
57
|
-
"version": "3.1.
|
|
58
|
-
"expectedSize":
|
|
59
|
-
"expectedChecksum": "
|
|
60
|
-
"expectedChecksumSHA256": "
|
|
61
|
-
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-amd64-v3.1.
|
|
62
|
-
"downloadPathRelativeToCacheDir": "dataconnect-emulator-3.1.
|
|
57
|
+
"version": "3.1.1",
|
|
58
|
+
"expectedSize": 30450528,
|
|
59
|
+
"expectedChecksum": "06e49453e3c9f876d445972a3588965f",
|
|
60
|
+
"expectedChecksumSHA256": "07dbbb5d1356597acc478d3c58dbf48e716b3795f4da0e7e174b0fd472b004d2",
|
|
61
|
+
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-amd64-v3.1.1",
|
|
62
|
+
"downloadPathRelativeToCacheDir": "dataconnect-emulator-3.1.1"
|
|
63
63
|
},
|
|
64
64
|
"darwin_arm64": {
|
|
65
|
-
"version": "3.1.
|
|
66
|
-
"expectedSize":
|
|
67
|
-
"expectedChecksum": "
|
|
68
|
-
"expectedChecksumSHA256": "
|
|
69
|
-
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-arm64-v3.1.
|
|
70
|
-
"downloadPathRelativeToCacheDir": "dataconnect-emulator-3.1.
|
|
65
|
+
"version": "3.1.1",
|
|
66
|
+
"expectedSize": 29916818,
|
|
67
|
+
"expectedChecksum": "477dd3da175dba6d7545ade62a8274f6",
|
|
68
|
+
"expectedChecksumSHA256": "472fe448f25fa8546aa383406db78eaf4eec4d8b700bb325dbc65899aba1bd20",
|
|
69
|
+
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-arm64-v3.1.1",
|
|
70
|
+
"downloadPathRelativeToCacheDir": "dataconnect-emulator-3.1.1"
|
|
71
71
|
},
|
|
72
72
|
"win32": {
|
|
73
|
-
"version": "3.1.
|
|
74
|
-
"expectedSize":
|
|
75
|
-
"expectedChecksum": "
|
|
76
|
-
"expectedChecksumSHA256": "
|
|
77
|
-
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-windows-amd64-v3.1.
|
|
78
|
-
"downloadPathRelativeToCacheDir": "dataconnect-emulator-3.1.
|
|
73
|
+
"version": "3.1.1",
|
|
74
|
+
"expectedSize": 30951424,
|
|
75
|
+
"expectedChecksum": "c51ec99bffd2f37fa2bb793f7cc74ea7",
|
|
76
|
+
"expectedChecksumSHA256": "e03d0dae5f040b03d211d6741540ed11206b03548b230eb8e36338b5b57545ee",
|
|
77
|
+
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-windows-amd64-v3.1.1",
|
|
78
|
+
"downloadPathRelativeToCacheDir": "dataconnect-emulator-3.1.1.exe"
|
|
79
79
|
},
|
|
80
80
|
"linux": {
|
|
81
|
-
"version": "3.1.
|
|
82
|
-
"expectedSize":
|
|
83
|
-
"expectedChecksum": "
|
|
84
|
-
"expectedChecksumSHA256": "
|
|
85
|
-
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-linux-amd64-v3.1.
|
|
86
|
-
"downloadPathRelativeToCacheDir": "dataconnect-emulator-3.1.
|
|
81
|
+
"version": "3.1.1",
|
|
82
|
+
"expectedSize": 30372024,
|
|
83
|
+
"expectedChecksum": "8a3977f07facaacaa9be3f9ec6bd90b7",
|
|
84
|
+
"expectedChecksumSHA256": "5c36d16d4ded51dd887c939a82e8cdc7e84cb40a2c5d00cb02bff90ca65c2472",
|
|
85
|
+
"remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-linux-amd64-v3.1.1",
|
|
86
|
+
"downloadPathRelativeToCacheDir": "dataconnect-emulator-3.1.1"
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
}
|
package/lib/ensureApiEnabled.js
CHANGED
|
@@ -27,7 +27,7 @@ async function check(projectId, apiUri, prefix, silent = false) {
|
|
|
27
27
|
return true;
|
|
28
28
|
}
|
|
29
29
|
const res = await apiClient.get(`/projects/${projectId}/services/${apiName}`, {
|
|
30
|
-
headers: { "x-goog-
|
|
30
|
+
headers: { "x-goog-user-project": `${projectId}` },
|
|
31
31
|
skipLog: { resBody: true },
|
|
32
32
|
});
|
|
33
33
|
const isEnabled = res.body.state === "ENABLED";
|
|
@@ -45,7 +45,7 @@ function isPermissionError(e) {
|
|
|
45
45
|
async function enable(projectId, apiName) {
|
|
46
46
|
try {
|
|
47
47
|
await apiClient.post(`/projects/${projectId}/services/${apiName}:enable`, undefined, {
|
|
48
|
-
headers: { "x-goog-
|
|
48
|
+
headers: { "x-goog-user-project": `${projectId}` },
|
|
49
49
|
skipLog: { resBody: true },
|
|
50
50
|
});
|
|
51
51
|
cacheEnabledAPI(projectId, apiName);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RecurrenceType = exports.DatabaseEdition = exports.
|
|
3
|
+
exports.RecurrenceType = exports.DatabaseEdition = exports.DataAccessMode = exports.RealtimeUpdatesMode = exports.PointInTimeRecoveryEnablement = exports.DatabaseDeleteProtectionState = exports.EnablementOption = exports.DatabaseType = exports.StateTtl = exports.State = exports.ArrayConfig = exports.Order = exports.Density = exports.ApiScope = exports.QueryScope = exports.Mode = void 0;
|
|
4
|
+
exports.validateEnablementOption = validateEnablementOption;
|
|
5
|
+
const error_1 = require("../error");
|
|
4
6
|
var Mode;
|
|
5
7
|
(function (Mode) {
|
|
6
8
|
Mode["ASCENDING"] = "ASCENDING";
|
|
@@ -51,26 +53,32 @@ var DatabaseType;
|
|
|
51
53
|
DatabaseType["DATASTORE_MODE"] = "DATASTORE_MODE";
|
|
52
54
|
DatabaseType["FIRESTORE_NATIVE"] = "FIRESTORE_NATIVE";
|
|
53
55
|
})(DatabaseType || (exports.DatabaseType = DatabaseType = {}));
|
|
54
|
-
var
|
|
55
|
-
(function (
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
})(
|
|
56
|
+
var EnablementOption;
|
|
57
|
+
(function (EnablementOption) {
|
|
58
|
+
EnablementOption["ENABLED"] = "ENABLED";
|
|
59
|
+
EnablementOption["DISABLED"] = "DISABLED";
|
|
60
|
+
})(EnablementOption || (exports.EnablementOption = EnablementOption = {}));
|
|
59
61
|
var DatabaseDeleteProtectionState;
|
|
60
62
|
(function (DatabaseDeleteProtectionState) {
|
|
61
63
|
DatabaseDeleteProtectionState["ENABLED"] = "DELETE_PROTECTION_ENABLED";
|
|
62
64
|
DatabaseDeleteProtectionState["DISABLED"] = "DELETE_PROTECTION_DISABLED";
|
|
63
65
|
})(DatabaseDeleteProtectionState || (exports.DatabaseDeleteProtectionState = DatabaseDeleteProtectionState = {}));
|
|
64
|
-
var PointInTimeRecoveryEnablementOption;
|
|
65
|
-
(function (PointInTimeRecoveryEnablementOption) {
|
|
66
|
-
PointInTimeRecoveryEnablementOption["ENABLED"] = "ENABLED";
|
|
67
|
-
PointInTimeRecoveryEnablementOption["DISABLED"] = "DISABLED";
|
|
68
|
-
})(PointInTimeRecoveryEnablementOption || (exports.PointInTimeRecoveryEnablementOption = PointInTimeRecoveryEnablementOption = {}));
|
|
69
66
|
var PointInTimeRecoveryEnablement;
|
|
70
67
|
(function (PointInTimeRecoveryEnablement) {
|
|
71
68
|
PointInTimeRecoveryEnablement["ENABLED"] = "POINT_IN_TIME_RECOVERY_ENABLED";
|
|
72
69
|
PointInTimeRecoveryEnablement["DISABLED"] = "POINT_IN_TIME_RECOVERY_DISABLED";
|
|
73
70
|
})(PointInTimeRecoveryEnablement || (exports.PointInTimeRecoveryEnablement = PointInTimeRecoveryEnablement = {}));
|
|
71
|
+
var RealtimeUpdatesMode;
|
|
72
|
+
(function (RealtimeUpdatesMode) {
|
|
73
|
+
RealtimeUpdatesMode["ENABLED"] = "REALTIME_UPDATES_MODE_ENABLED";
|
|
74
|
+
RealtimeUpdatesMode["DISABLED"] = "REALTIME_UPDATES_MODE_DISABLED";
|
|
75
|
+
})(RealtimeUpdatesMode || (exports.RealtimeUpdatesMode = RealtimeUpdatesMode = {}));
|
|
76
|
+
var DataAccessMode;
|
|
77
|
+
(function (DataAccessMode) {
|
|
78
|
+
DataAccessMode["UNSPECIFIED"] = "DATA_ACCESS_MODE_UNSPECIFIED";
|
|
79
|
+
DataAccessMode["ENABLED"] = "DATA_ACCESS_MODE_ENABLED";
|
|
80
|
+
DataAccessMode["DISABLED"] = "DATA_ACCESS_MODE_DISABLED";
|
|
81
|
+
})(DataAccessMode || (exports.DataAccessMode = DataAccessMode = {}));
|
|
74
82
|
var DatabaseEdition;
|
|
75
83
|
(function (DatabaseEdition) {
|
|
76
84
|
DatabaseEdition["DATABASE_EDITION_UNSPECIFIED"] = "DATABASE_EDITION_UNSPECIFIED";
|
|
@@ -82,3 +90,10 @@ var RecurrenceType;
|
|
|
82
90
|
RecurrenceType["DAILY"] = "DAILY";
|
|
83
91
|
RecurrenceType["WEEKLY"] = "WEEKLY";
|
|
84
92
|
})(RecurrenceType || (exports.RecurrenceType = RecurrenceType = {}));
|
|
93
|
+
function validateEnablementOption(optionValue, flagName, helpCommandText) {
|
|
94
|
+
if (optionValue &&
|
|
95
|
+
optionValue !== EnablementOption.ENABLED &&
|
|
96
|
+
optionValue !== EnablementOption.DISABLED) {
|
|
97
|
+
throw new error_1.FirebaseError(`Invalid value for flag --${flagName}. ${helpCommandText}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
package/lib/firestore/api.js
CHANGED
|
@@ -536,6 +536,9 @@ class FirestoreApi {
|
|
|
536
536
|
databaseEdition: req.databaseEdition,
|
|
537
537
|
deleteProtectionState: req.deleteProtectionState,
|
|
538
538
|
pointInTimeRecoveryEnablement: req.pointInTimeRecoveryEnablement,
|
|
539
|
+
realtimeUpdatesMode: req.realtimeUpdatesMode,
|
|
540
|
+
firestoreDataAccessMode: req.firestoreDataAccessMode,
|
|
541
|
+
mongodbCompatibleDataAccessMode: req.mongodbCompatibleDataAccessMode,
|
|
539
542
|
cmekConfig: req.cmekConfig,
|
|
540
543
|
};
|
|
541
544
|
const options = { queryParams: { databaseId: req.databaseId } };
|
package/lib/gcp/iam.js
CHANGED
|
@@ -63,7 +63,7 @@ async function testResourceIamPermissions(origin, apiVersion, resourceName, perm
|
|
|
63
63
|
}
|
|
64
64
|
const headers = {};
|
|
65
65
|
if (quotaUser) {
|
|
66
|
-
headers["x-goog-
|
|
66
|
+
headers["x-goog-user-project"] = quotaUser;
|
|
67
67
|
}
|
|
68
68
|
const response = await localClient.post(`/${resourceName}:testIamPermissions`, { permissions }, { headers });
|
|
69
69
|
const allowed = new Set(response.body.permissions || []);
|
|
@@ -78,7 +78,7 @@ async function testResourceIamPermissions(origin, apiVersion, resourceName, perm
|
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
80
|
async function testIamPermissions(projectId, permissions) {
|
|
81
|
-
return testResourceIamPermissions((0, api_1.resourceManagerOrigin)(), "v1", `projects/${projectId}`, permissions,
|
|
81
|
+
return testResourceIamPermissions((0, api_1.resourceManagerOrigin)(), "v1", `projects/${projectId}`, permissions, `${projectId}`);
|
|
82
82
|
}
|
|
83
83
|
function mergeBindings(policy, requiredBindings) {
|
|
84
84
|
let updated = false;
|
package/lib/gcp/rules.js
CHANGED
|
@@ -28,9 +28,12 @@ function _handleErrorResponse(response) {
|
|
|
28
28
|
code: 2,
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
|
-
async function getLatestRulesetName(projectId, service) {
|
|
31
|
+
async function getLatestRulesetName(projectId, service, resourceName) {
|
|
32
32
|
const releases = await listAllReleases(projectId);
|
|
33
|
-
|
|
33
|
+
let prefix = `projects/${projectId}/releases/${service}`;
|
|
34
|
+
if (resourceName) {
|
|
35
|
+
prefix += `/${resourceName}`;
|
|
36
|
+
}
|
|
34
37
|
const release = releases.find((r) => r.name.startsWith(prefix));
|
|
35
38
|
if (!release) {
|
|
36
39
|
return null;
|
package/lib/gcp/serviceusage.js
CHANGED
|
@@ -22,7 +22,7 @@ const serviceUsagePollerOptions = {
|
|
|
22
22
|
async function generateServiceIdentity(projectNumber, service, prefix) {
|
|
23
23
|
utils.logLabeledBullet(prefix, `generating the service identity for ${(0, colorette_1.bold)(service)}...`);
|
|
24
24
|
try {
|
|
25
|
-
const res = await exports.apiClient.post(`projects/${projectNumber}/services/${service}:generateServiceIdentity`, {}, { headers: { "x-goog-
|
|
25
|
+
const res = await exports.apiClient.post(`projects/${projectNumber}/services/${service}:generateServiceIdentity`, {}, { headers: { "x-goog-user-project": `${projectNumber}` } });
|
|
26
26
|
return res.body;
|
|
27
27
|
}
|
|
28
28
|
catch (err) {
|
|
@@ -39,6 +39,6 @@ async function generateServiceIdentityAndPoll(projectNumber, service, prefix) {
|
|
|
39
39
|
await poller.pollOperation({
|
|
40
40
|
...serviceUsagePollerOptions,
|
|
41
41
|
operationResourceName: op.name,
|
|
42
|
-
headers: { "x-goog-
|
|
42
|
+
headers: { "x-goog-user-project": `${projectNumber}` },
|
|
43
43
|
});
|
|
44
44
|
}
|
|
@@ -33,7 +33,7 @@ async function initIndexes(setup, config, info) {
|
|
|
33
33
|
utils.logBullet(`Downloaded the existing Firestore indexes from the Firebase console`);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
info.
|
|
36
|
+
info.writeIndexes = await config.confirmWriteProjectFile(info.indexesFilename, info.indexes);
|
|
37
37
|
}
|
|
38
38
|
async function getIndexesFromConsole(projectId, databaseId) {
|
|
39
39
|
const indexesPromise = indexes.listIndexes(projectId, databaseId);
|
|
@@ -3,10 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.askQuestions = askQuestions;
|
|
4
4
|
exports.actuate = actuate;
|
|
5
5
|
const clc = require("colorette");
|
|
6
|
-
const logger_1 = require("
|
|
7
|
-
const prompt_1 = require("
|
|
8
|
-
const templates_1 = require("
|
|
9
|
-
const error_1 = require("
|
|
6
|
+
const logger_1 = require("../../../logger");
|
|
7
|
+
const prompt_1 = require("../../../prompt");
|
|
8
|
+
const templates_1 = require("../../../templates");
|
|
9
|
+
const error_1 = require("../../../error");
|
|
10
|
+
const rules_1 = require("./rules");
|
|
10
11
|
const RULES_TEMPLATE = (0, templates_1.readTemplateSync)("init/storage/storage.rules");
|
|
11
12
|
const DEFAULT_RULES_FILE = "storage.rules";
|
|
12
13
|
async function askQuestions(setup, config) {
|
|
@@ -20,6 +21,13 @@ async function askQuestions(setup, config) {
|
|
|
20
21
|
rules: RULES_TEMPLATE,
|
|
21
22
|
writeRules: true,
|
|
22
23
|
};
|
|
24
|
+
if (setup.projectId) {
|
|
25
|
+
const downloadedRules = await (0, rules_1.getRulesFromConsole)(setup.projectId);
|
|
26
|
+
if (downloadedRules) {
|
|
27
|
+
info.rules = downloadedRules;
|
|
28
|
+
logger_1.logger.info(`Downloaded the existing Storage Security Rules from the Firebase console`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
23
31
|
info.rulesFilename = await (0, prompt_1.input)({
|
|
24
32
|
message: "What file should be used for Storage Rules?",
|
|
25
33
|
default: DEFAULT_RULES_FILE,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getRulesFromConsole = getRulesFromConsole;
|
|
4
|
+
const gcp = require("../../../gcp");
|
|
5
|
+
const utils = require("../../../utils");
|
|
6
|
+
async function getRulesFromConsole(projectId) {
|
|
7
|
+
const defaultBucket = await gcp.storage.getDefaultBucket(projectId);
|
|
8
|
+
const name = await gcp.rules.getLatestRulesetName(projectId, "firebase.storage", defaultBucket);
|
|
9
|
+
if (!name) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
const rules = await gcp.rules.getRulesetContent(name);
|
|
13
|
+
if (rules.length <= 0) {
|
|
14
|
+
return utils.reject("Ruleset has no files", { exit: 1 });
|
|
15
|
+
}
|
|
16
|
+
if (rules.length > 1) {
|
|
17
|
+
return utils.reject("Ruleset has too many files: " + rules.length, { exit: 1 });
|
|
18
|
+
}
|
|
19
|
+
return rules[0].content;
|
|
20
|
+
}
|
|
@@ -10,7 +10,7 @@ const getDefaultDatabaseInstance_1 = require("../../../getDefaultDatabaseInstanc
|
|
|
10
10
|
exports.get_security_rules = (0, tool_1.tool)("core", {
|
|
11
11
|
name: "get_security_rules",
|
|
12
12
|
description: "Use this to retrieve the security rules for a specified Firebase service. " +
|
|
13
|
-
"If there are multiple instances of that service in the product, the rules for the
|
|
13
|
+
"If there are multiple instances of that service in the product, the rules for the default instance are returned.",
|
|
14
14
|
inputSchema: zod_1.z.object({
|
|
15
15
|
type: zod_1.z.enum(["firestore", "rtdb", "storage"]).describe("The service to get rules for."),
|
|
16
16
|
}),
|
|
@@ -31,7 +31,7 @@ function toText(response, filters) {
|
|
|
31
31
|
}
|
|
32
32
|
exports.get_report = (0, tool_1.tool)("crashlytics", {
|
|
33
33
|
name: "get_report",
|
|
34
|
-
description: `Use this to request numerical reports from Crashlytics. The result aggregates the sum of events and impacted users, grouped by a dimension appropriate for that report. Agents must read the [Firebase Crashlytics Reports Guide](firebase://guides/crashlytics/reports) using the \`firebase_read_resources\` tool before calling to understand
|
|
34
|
+
description: `Use this to request numerical reports from Crashlytics. The result aggregates the sum of events and impacted users, grouped by a dimension appropriate for that report. Agents must read the [Firebase Crashlytics Reports Guide](firebase://guides/crashlytics/reports) using the \`firebase_read_resources\` tool before calling to understand critical prerequisites for requesting reports and how to interpret the results.
|
|
35
35
|
`.trim(),
|
|
36
36
|
inputSchema: reports_1.ReportInputSchema,
|
|
37
37
|
annotations: {
|
|
@@ -9,7 +9,7 @@ const delete_1 = require("../../../firestore/delete");
|
|
|
9
9
|
const types_1 = require("../../../emulator/types");
|
|
10
10
|
exports.delete_document = (0, tool_1.tool)("firestore", {
|
|
11
11
|
name: "delete_document",
|
|
12
|
-
description: "Use this to delete
|
|
12
|
+
description: "Use this to delete Firestore documents from a database in the current project by full document paths. Use this if you know the exact path of a document.",
|
|
13
13
|
inputSchema: zod_1.z.object({
|
|
14
14
|
database: zod_1.z
|
|
15
15
|
.string()
|
|
@@ -9,7 +9,7 @@ const converter_1 = require("./converter");
|
|
|
9
9
|
const types_1 = require("../../../emulator/types");
|
|
10
10
|
exports.query_collection = (0, tool_1.tool)("firestore", {
|
|
11
11
|
name: "query_collection",
|
|
12
|
-
description: "Use this to retrieve one or more Firestore documents from a collection
|
|
12
|
+
description: "Use this to retrieve one or more Firestore documents from a collection in 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.",
|
|
13
13
|
inputSchema: zod_1.z.object({
|
|
14
14
|
database: zod_1.z
|
|
15
15
|
.string()
|