firebase-tools 14.19.1 → 14.20.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.
Files changed (48) hide show
  1. package/lib/appUtils.js +4 -4
  2. package/lib/command.js +1 -0
  3. package/lib/commands/apps-init.js +7 -7
  4. package/lib/commands/dataconnect-execute.js +229 -0
  5. package/lib/commands/firestore-backups-delete.js +1 -6
  6. package/lib/commands/firestore-backups-get.js +2 -8
  7. package/lib/commands/firestore-backups-list.js +4 -10
  8. package/lib/commands/firestore-backups-schedules-create.js +1 -6
  9. package/lib/commands/firestore-backups-schedules-delete.js +1 -6
  10. package/lib/commands/firestore-backups-schedules-list.js +1 -7
  11. package/lib/commands/firestore-backups-schedules-update.js +1 -6
  12. package/lib/commands/firestore-bulkdelete.js +7 -13
  13. package/lib/commands/firestore-databases-create.js +5 -10
  14. package/lib/commands/firestore-databases-delete.js +1 -6
  15. package/lib/commands/firestore-databases-get.js +1 -7
  16. package/lib/commands/firestore-databases-list.js +1 -7
  17. package/lib/commands/firestore-databases-restore.js +5 -10
  18. package/lib/commands/firestore-databases-update.js +1 -6
  19. package/lib/commands/firestore-locations.js +1 -7
  20. package/lib/commands/firestore-operations-cancel.js +3 -9
  21. package/lib/commands/firestore-operations-describe.js +2 -8
  22. package/lib/commands/firestore-operations-list.js +2 -8
  23. package/lib/commands/index.js +1 -0
  24. package/lib/dataconnect/build.js +16 -2
  25. package/lib/dataconnect/load.js +21 -1
  26. package/lib/dataconnect/names.js +6 -1
  27. package/lib/dataconnect/provisionCloudSql.js +38 -11
  28. package/lib/dataconnect/schemaMigration.js +16 -3
  29. package/lib/dataconnect/types.js +1 -10
  30. package/lib/deploy/dataconnect/context.js +26 -0
  31. package/lib/deploy/dataconnect/deploy.js +13 -4
  32. package/lib/deploy/dataconnect/prepare.js +11 -8
  33. package/lib/deploy/dataconnect/release.js +10 -2
  34. package/lib/deploy/index.js +39 -20
  35. package/lib/emulator/downloadableEmulatorInfo.json +18 -18
  36. package/lib/gcp/cloudsql/cloudsqladmin.js +4 -3
  37. package/lib/init/features/dataconnect/index.js +22 -6
  38. package/lib/init/features/dataconnect/sdk.js +40 -22
  39. package/lib/management/apps.js +24 -24
  40. package/lib/mcp/prompts/core/consult.js +2 -3
  41. package/lib/mcp/prompts/core/init.js +3 -4
  42. package/lib/mcp/resources/index.js +0 -4
  43. package/lib/mcp/tools/dataconnect/execute.js +0 -1
  44. package/lib/mcp/util/dataconnect/converter.js +5 -4
  45. package/lib/mcp/util/dataconnect/emulator.js +0 -1
  46. package/lib/responseToError.js +7 -6
  47. package/package.json +1 -1
  48. package/lib/dataconnect/appFinder.js +0 -103
package/lib/appUtils.js CHANGED
@@ -13,8 +13,8 @@ var Platform;
13
13
  })(Platform = exports.Platform || (exports.Platform = {}));
14
14
  var Framework;
15
15
  (function (Framework) {
16
- Framework["REACT"] = "REACT";
17
- Framework["ANGULAR"] = "ANGULAR";
16
+ Framework["REACT"] = "react";
17
+ Framework["ANGULAR"] = "angular";
18
18
  })(Framework = exports.Framework || (exports.Framework = {}));
19
19
  function appDescription(a) {
20
20
  return `${a.directory} (${a.platform.toLowerCase()})`;
@@ -119,8 +119,8 @@ async function packageJsonToWebApp(dirPath, packageJsonFile) {
119
119
  }
120
120
  const WEB_FRAMEWORKS = Object.values(Framework);
121
121
  const WEB_FRAMEWORKS_SIGNALS = {
122
- REACT: ["react", "next"],
123
- ANGULAR: ["@angular/core"],
122
+ react: ["react", "next"],
123
+ angular: ["@angular/core"],
124
124
  };
125
125
  async function detectAppIdsForPlatform(dirPath, platform) {
126
126
  let appIdFiles;
package/lib/command.js CHANGED
@@ -165,6 +165,7 @@ class Command {
165
165
  options.debug = true;
166
166
  }
167
167
  if ((0, utils_1.getInheritedOption)(options, "json")) {
168
+ options.interactive = false;
168
169
  options.nonInteractive = true;
169
170
  }
170
171
  else if (!options.isMCP) {
@@ -8,7 +8,7 @@ const apps_1 = require("../management/apps");
8
8
  const requireAuth_1 = require("../requireAuth");
9
9
  const logger_1 = require("../logger");
10
10
  const projectUtils_1 = require("../projectUtils");
11
- const types_1 = require("../dataconnect/types");
11
+ const appUtils_1 = require("../appUtils");
12
12
  const experiments_1 = require("../experiments");
13
13
  function logUse(platform, filePath) {
14
14
  switch (platform) {
@@ -42,12 +42,12 @@ for information about adding your config file to your project.`);
42
42
  }
43
43
  function toAppPlatform(str) {
44
44
  switch (str.toUpperCase()) {
45
- case types_1.Platform.ANDROID:
46
- return types_1.Platform.ANDROID;
47
- case types_1.Platform.IOS:
48
- return types_1.Platform.IOS;
49
- case types_1.Platform.WEB:
50
- return types_1.Platform.WEB;
45
+ case appUtils_1.Platform.ANDROID:
46
+ return appUtils_1.Platform.ANDROID;
47
+ case appUtils_1.Platform.IOS:
48
+ return appUtils_1.Platform.IOS;
49
+ case appUtils_1.Platform.WEB:
50
+ return appUtils_1.Platform.WEB;
51
51
  }
52
52
  throw new Error(`Platform ${str} is not compatible with apps:configure`);
53
53
  }
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.command = void 0;
4
+ const clc = require("colorette");
5
+ const command_1 = require("../command");
6
+ const projectUtils_1 = require("../projectUtils");
7
+ const load_1 = require("../dataconnect/load");
8
+ const requireAuth_1 = require("../requireAuth");
9
+ const constants_1 = require("../emulator/constants");
10
+ const apiv2_1 = require("../apiv2");
11
+ const dataplaneClient_1 = require("../dataconnect/dataplaneClient");
12
+ const dataplaneClient_2 = require("../dataconnect/dataplaneClient");
13
+ const names_1 = require("../dataconnect/names");
14
+ const error_1 = require("../error");
15
+ const node_fs_1 = require("node:fs");
16
+ const types_1 = require("../dataconnect/types");
17
+ const hub_1 = require("../emulator/hub");
18
+ const promises_1 = require("node:fs/promises");
19
+ const node_os_1 = require("node:os");
20
+ const node_path_1 = require("node:path");
21
+ const consumers_1 = require("node:stream/consumers");
22
+ const logger_1 = require("../logger");
23
+ const responseToError_1 = require("../responseToError");
24
+ let stdinUsedFor = undefined;
25
+ exports.command = new command_1.Command("dataconnect:execute [file] [operationName]")
26
+ .description("execute a Data Connect query or mutation. If FIREBASE_DATACONNECT_EMULATOR_HOST is set (such as during 'firebase emulator:exec', executes against the emulator instead.")
27
+ .option("--service <serviceId>", "The service ID to execute against (optional if there's only one service)")
28
+ .option("--location <locationId>", "The location ID to execute against (optional if there's only one service). Ignored by the emulator.")
29
+ .option("--vars, --variables <vars>", "Supply variables to the operation execution, which must be a JSON object whose keys are variable names. If vars begin with the character @, the rest is interpreted as a file name to read from, or - to read from stdin.")
30
+ .option("--no-debug-details", "Disables debug information in the response. Executions returns helpful errors or GQL extensions by default, which may expose too much for unprivilleged user or programs. If that's the case, this flag turns those output off.")
31
+ .action(async (file = "", operationName, options) => {
32
+ const emulatorHost = process.env[constants_1.Constants.FIREBASE_DATACONNECT_EMULATOR_HOST];
33
+ let projectId;
34
+ if (emulatorHost) {
35
+ projectId = (0, projectUtils_1.getProjectId)(options) || hub_1.EmulatorHub.MISSING_PROJECT_PLACEHOLDER;
36
+ }
37
+ else {
38
+ projectId = (0, projectUtils_1.needProjectId)(options);
39
+ }
40
+ let serviceName = undefined;
41
+ const serviceId = options.service;
42
+ const locationId = options.location;
43
+ if (!file && !operationName) {
44
+ if (process.stdin.isTTY) {
45
+ throw new error_1.FirebaseError("At least one of the [file] [operationName] arguments is required.");
46
+ }
47
+ file = "-";
48
+ }
49
+ let query;
50
+ if (file === "-") {
51
+ stdinUsedFor = "operation source code";
52
+ if (process.stdin.isTTY) {
53
+ process.stderr.write(`${clc.cyan("Reading GraphQL operation from stdin. EOF (CTRL+D) to finish and execute.")}${node_os_1.EOL}`);
54
+ }
55
+ query = await (0, consumers_1.text)(process.stdin);
56
+ }
57
+ else {
58
+ const stat = (0, node_fs_1.statSync)(file, { throwIfNoEntry: false });
59
+ if (stat === null || stat === void 0 ? void 0 : stat.isFile()) {
60
+ const opDisplay = operationName ? clc.bold(operationName) : "operation";
61
+ process.stderr.write(`${clc.cyan(`Executing ${opDisplay} in ${clc.bold(file)}`)}${node_os_1.EOL}`);
62
+ query = await (0, promises_1.readFile)(file, "utf-8");
63
+ }
64
+ else if (stat === null || stat === void 0 ? void 0 : stat.isDirectory()) {
65
+ query = await readQueryFromDir(file);
66
+ }
67
+ else {
68
+ if (operationName === undefined && (0, names_1.isGraphqlName)(file)) {
69
+ operationName = file;
70
+ file = "";
71
+ }
72
+ if (file) {
73
+ throw new error_1.FirebaseError(`${file}: no such file or directory`);
74
+ }
75
+ file = await pickConnectorDir();
76
+ query = await readQueryFromDir(file);
77
+ }
78
+ }
79
+ let apiClient;
80
+ if (emulatorHost) {
81
+ const url = new URL("http://placeholder");
82
+ url.host = emulatorHost;
83
+ apiClient = new apiv2_1.Client({
84
+ urlPrefix: url.toString(),
85
+ apiVersion: dataplaneClient_1.DATACONNECT_API_VERSION,
86
+ });
87
+ }
88
+ else {
89
+ await (0, requireAuth_1.requireAuth)(options);
90
+ apiClient = (0, dataplaneClient_2.dataconnectDataplaneClient)();
91
+ }
92
+ if (!serviceName) {
93
+ if (serviceId && (locationId || emulatorHost)) {
94
+ serviceName = `projects/${projectId}/locations/${locationId || "unused"}/services/${serviceId}`;
95
+ }
96
+ else {
97
+ serviceName = (await getServiceInfo()).serviceName;
98
+ }
99
+ }
100
+ if (!options.variables && !process.stdin.isTTY && !stdinUsedFor) {
101
+ options.variables = "@-";
102
+ }
103
+ const unparsedVars = await literalOrFile(options.variables, "--variables");
104
+ const response = await (0, dataplaneClient_1.executeGraphQL)(apiClient, serviceName, {
105
+ query,
106
+ operationName,
107
+ variables: parseJsonObject(unparsedVars, "--variables"),
108
+ });
109
+ let err = (0, responseToError_1.responseToError)(response, response.body);
110
+ if ((0, types_1.isGraphQLResponseError)(response.body)) {
111
+ const { status, message } = response.body.error;
112
+ if (!err) {
113
+ err = new error_1.FirebaseError(message, {
114
+ context: {
115
+ body: response.body,
116
+ response: response,
117
+ },
118
+ status: response.status,
119
+ });
120
+ }
121
+ if (status === "INVALID_ARGUMENT" && message.includes("operationName is required")) {
122
+ throw new error_1.FirebaseError(err.message + `\nHint: Append <operationName> as an argument to disambiguate.`, Object.assign(Object.assign({}, err), { original: err }));
123
+ }
124
+ }
125
+ if (err) {
126
+ throw err;
127
+ }
128
+ if (!(0, types_1.isGraphQLResponse)(response.body)) {
129
+ throw new error_1.FirebaseError("Got invalid response body with neither .data or .errors", {
130
+ context: {
131
+ body: response.body,
132
+ response: response,
133
+ },
134
+ status: response.status,
135
+ });
136
+ }
137
+ logger_1.logger.info(JSON.stringify(response.body, null, 2));
138
+ if (!response.body.data) {
139
+ throw new error_1.FirebaseError("GraphQL request error(s). See response body (above) for details.", {
140
+ context: {
141
+ body: response.body,
142
+ response: response,
143
+ },
144
+ status: response.status,
145
+ });
146
+ }
147
+ if (response.body.errors && response.body.errors.length > 0) {
148
+ throw new error_1.FirebaseError("Execution completed with error(s). See response body (above) for details.", {
149
+ context: {
150
+ body: response.body,
151
+ response: response,
152
+ },
153
+ status: response.status,
154
+ });
155
+ }
156
+ return response.body;
157
+ async function readQueryFromDir(dir) {
158
+ const opDisplay = operationName ? clc.bold(operationName) : "operation";
159
+ process.stderr.write(`${clc.cyan(`Executing ${opDisplay} in ${clc.bold(dir)}`)}${node_os_1.EOL}`);
160
+ const files = await (0, load_1.readGQLFiles)(dir);
161
+ const query = (0, load_1.squashGraphQL)({ files });
162
+ if (!query) {
163
+ throw new error_1.FirebaseError(`${dir} contains no GQL files or only empty ones`);
164
+ }
165
+ return query;
166
+ }
167
+ async function getServiceInfo() {
168
+ return (0, load_1.pickService)(projectId, options.config, serviceId || undefined).catch((e) => {
169
+ if (!(e instanceof error_1.FirebaseError)) {
170
+ return Promise.reject(e);
171
+ }
172
+ if (!serviceId) {
173
+ e = new error_1.FirebaseError(e.message +
174
+ `\nHint: Try specifying the ${clc.yellow("--service <serviceId>")} option.`, Object.assign(Object.assign({}, e), { original: e }));
175
+ }
176
+ return Promise.reject(e);
177
+ });
178
+ }
179
+ async function pickConnectorDir() {
180
+ const serviceInfo = await getServiceInfo();
181
+ serviceName = serviceInfo.serviceName;
182
+ switch (serviceInfo.connectorInfo.length) {
183
+ case 1: {
184
+ const connector = serviceInfo.connectorInfo[0];
185
+ return (0, node_path_1.relative)(process.cwd(), connector.directory);
186
+ }
187
+ case 0:
188
+ throw new error_1.FirebaseError(`No connector found.\n` +
189
+ "Hint: To execute an operation in a GraphQL file, run:\n" +
190
+ ` firebase dataconnect:execute ${clc.yellow("./path/to/file.gql OPERATION_NAME")}`);
191
+ default: {
192
+ const example = (0, node_path_1.relative)(process.cwd(), serviceInfo.connectorInfo[0].directory);
193
+ throw new error_1.FirebaseError(`A file or directory must be explicitly specified when there are multiple connectors.\n` +
194
+ "Hint: To execute an operation within a connector, try e.g.:\n" +
195
+ ` firebase dataconnect:execute ${clc.yellow(`${example} OPERATION_NAME`)}`);
196
+ }
197
+ }
198
+ }
199
+ });
200
+ function parseJsonObject(json, subject) {
201
+ let obj;
202
+ try {
203
+ obj = JSON.parse(json || "{}");
204
+ }
205
+ catch (e) {
206
+ throw new error_1.FirebaseError(`expected ${subject} to be valid JSON string, got: ${json}`);
207
+ }
208
+ if (typeof obj !== "object" || obj == null)
209
+ throw new error_1.FirebaseError(`Provided ${subject} is not an object`);
210
+ return obj;
211
+ }
212
+ async function literalOrFile(arg, subject) {
213
+ let str = arg;
214
+ if (!str) {
215
+ return "";
216
+ }
217
+ if (str.startsWith("@")) {
218
+ if (str === "@-") {
219
+ if (stdinUsedFor) {
220
+ throw new error_1.FirebaseError(`standard input can only be used for one of ${stdinUsedFor} and ${subject}.`);
221
+ }
222
+ str = await (0, consumers_1.text)(process.stdin);
223
+ }
224
+ else {
225
+ str = await (0, promises_1.readFile)(str.substring(1), "utf-8");
226
+ }
227
+ }
228
+ return str;
229
+ }
@@ -33,11 +33,6 @@ exports.command = new command_1.Command("firestore:backups:delete <backup>")
33
33
  catch (err) {
34
34
  throw new error_1.FirebaseError(`Failed to delete the backup ${backupName}`, { original: err });
35
35
  }
36
- if (options.json) {
37
- logger_1.logger.info(JSON.stringify(backup, undefined, 2));
38
- }
39
- else {
40
- logger_1.logger.info(clc.bold(`Successfully deleted ${clc.yellow(backupName)}`));
41
- }
36
+ logger_1.logger.info(clc.bold(`Successfully deleted ${clc.yellow(backupName)}`));
42
37
  return backup;
43
38
  });
@@ -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 logger_1 = require("../logger");
6
5
  const requirePermissions_1 = require("../requirePermissions");
7
6
  const types_1 = require("../emulator/types");
8
7
  const commandUtils_1 = require("../emulator/commandUtils");
@@ -12,14 +11,9 @@ exports.command = new command_1.Command("firestore:backups:get <backup>")
12
11
  .description("get a Cloud Firestore database backup")
13
12
  .before(requirePermissions_1.requirePermissions, ["datastore.backups.get"])
14
13
  .before(commandUtils_1.warnEmulatorNotSupported, types_1.Emulators.FIRESTORE)
15
- .action(async (backupName, options) => {
14
+ .action(async (backupName) => {
16
15
  const backup = await (0, firestore_1.getBackup)(backupName);
17
16
  const printer = new pretty_print_1.PrettyPrint();
18
- if (options.json) {
19
- logger_1.logger.info(JSON.stringify(backup, undefined, 2));
20
- }
21
- else {
22
- printer.prettyPrintBackup(backup);
23
- }
17
+ printer.prettyPrintBackup(backup);
24
18
  return backup;
25
19
  });
@@ -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 logger_1 = require("../logger");
6
5
  const requirePermissions_1 = require("../requirePermissions");
7
6
  const types_1 = require("../emulator/types");
8
7
  const commandUtils_1 = require("../emulator/commandUtils");
@@ -20,15 +19,10 @@ exports.command = new command_1.Command("firestore:backups:list")
20
19
  const location = (_a = options.location) !== null && _a !== void 0 ? _a : "-";
21
20
  const listBackupsResponse = await (0, firestore_1.listBackups)(options.project, location);
22
21
  const backups = listBackupsResponse.backups || [];
23
- if (options.json) {
24
- logger_1.logger.info(JSON.stringify(listBackupsResponse, undefined, 2));
25
- }
26
- else {
27
- printer.prettyPrintBackups(backups);
28
- if (listBackupsResponse.unreachable && listBackupsResponse.unreachable.length > 0) {
29
- (0, utils_1.logWarning)("We were not able to reach the following locations: " +
30
- listBackupsResponse.unreachable.join(", "));
31
- }
22
+ printer.prettyPrintBackups(backups);
23
+ if (listBackupsResponse.unreachable && listBackupsResponse.unreachable.length > 0) {
24
+ (0, utils_1.logWarning)("We were not able to reach the following locations: " +
25
+ listBackupsResponse.unreachable.join(", "));
32
26
  }
33
27
  return backups;
34
28
  });
@@ -54,11 +54,6 @@ exports.command = new command_1.Command("firestore:backups:schedules:create")
54
54
  };
55
55
  }
56
56
  const backupSchedule = await (0, firestore_1.createBackupSchedule)(options.project, databaseId, retention, dailyRecurrence, weeklyRecurrence);
57
- if (options.json) {
58
- logger_1.logger.info(JSON.stringify(backupSchedule, undefined, 2));
59
- }
60
- else {
61
- logger_1.logger.info(clc.bold(`Successfully created ${printer.prettyBackupScheduleString(backupSchedule)}`));
62
- }
57
+ logger_1.logger.info(clc.bold(`Successfully created ${printer.prettyBackupScheduleString(backupSchedule)}`));
63
58
  return backupSchedule;
64
59
  });
@@ -35,11 +35,6 @@ exports.command = new command_1.Command("firestore:backups:schedules:delete <bac
35
35
  original: err,
36
36
  });
37
37
  }
38
- if (options.json) {
39
- logger_1.logger.info(JSON.stringify(backupSchedule, undefined, 2));
40
- }
41
- else {
42
- logger_1.logger.info(clc.bold(`Successfully deleted ${clc.yellow(backupScheduleName)}`));
43
- }
38
+ logger_1.logger.info(clc.bold(`Successfully deleted ${clc.yellow(backupScheduleName)}`));
44
39
  return backupSchedule;
45
40
  });
@@ -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 logger_1 = require("../logger");
6
5
  const requirePermissions_1 = require("../requirePermissions");
7
6
  const types_1 = require("../emulator/types");
8
7
  const commandUtils_1 = require("../emulator/commandUtils");
@@ -18,11 +17,6 @@ exports.command = new command_1.Command("firestore:backups:schedules:list")
18
17
  const printer = new pretty_print_1.PrettyPrint();
19
18
  const databaseId = (_a = options.database) !== null && _a !== void 0 ? _a : "(default)";
20
19
  const backupSchedules = await (0, firestore_1.listBackupSchedules)(options.project, databaseId);
21
- if (options.json) {
22
- logger_1.logger.info(JSON.stringify(backupSchedules, undefined, 2));
23
- }
24
- else {
25
- printer.prettyPrintBackupSchedules(backupSchedules, databaseId);
26
- }
20
+ printer.prettyPrintBackupSchedules(backupSchedules, databaseId);
27
21
  return backupSchedules;
28
22
  });
@@ -24,11 +24,6 @@ exports.command = new command_1.Command("firestore:backups:schedules:update <bac
24
24
  }
25
25
  const retention = (0, backupUtils_1.calculateRetention)(options.retention);
26
26
  const backupSchedule = await (0, firestore_1.updateBackupSchedule)(backupScheduleName, retention);
27
- if (options.json) {
28
- logger_1.logger.info(JSON.stringify(backupSchedule, undefined, 2));
29
- }
30
- else {
31
- logger_1.logger.info(clc.bold(`Successfully updated ${printer.prettyBackupScheduleString(backupSchedule)}`));
32
- }
27
+ logger_1.logger.info(clc.bold(`Successfully updated ${printer.prettyBackupScheduleString(backupSchedule)}`));
33
28
  return backupSchedule;
34
29
  });
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
4
  const command_1 = require("../command");
5
5
  const fsi = require("../firestore/api");
6
- const logger_1 = require("../logger");
7
6
  const requirePermissions_1 = require("../requirePermissions");
8
7
  const types_1 = require("../emulator/types");
9
8
  const commandUtils_1 = require("../emulator/commandUtils");
@@ -54,20 +53,15 @@ exports.command = new command_1.Command("firestore:bulkdelete")
54
53
  return utils.reject("Command aborted.", { exit: 1 });
55
54
  }
56
55
  const op = await api.bulkDeleteDocuments(options.project, databaseId, collectionIds);
57
- if (options.json) {
58
- logger_1.logger.info(JSON.stringify(op, undefined, 2));
56
+ if (op.name) {
57
+ (0, utils_1.logSuccess)(`Successfully started bulk delete operation.`);
58
+ (0, utils_1.logBullet)(`Operation name: ` + clc.cyan(op.name));
59
+ (0, utils_1.logBullet)("You can monitor the operation's progress using the " +
60
+ clc.cyan(`gcloud firestore operations describe`) +
61
+ ` command.`);
59
62
  }
60
63
  else {
61
- if (op.name) {
62
- (0, utils_1.logSuccess)(`Successfully started bulk delete operation.`);
63
- (0, utils_1.logBullet)(`Operation name: ` + clc.cyan(op.name));
64
- (0, utils_1.logBullet)("You can monitor the operation's progress using the " +
65
- clc.cyan(`gcloud firestore operations describe`) +
66
- ` command.`);
67
- }
68
- else {
69
- (0, utils_1.logLabeledError)(`Bulk Delete:`, `Failed to start a bulk delete operation.`);
70
- }
64
+ (0, utils_1.logLabeledError)(`Bulk Delete:`, `Failed to start a bulk delete operation.`);
71
65
  }
72
66
  return op;
73
67
  });
@@ -72,15 +72,10 @@ exports.command = new command_1.Command("firestore:databases:create <database>")
72
72
  cmekConfig,
73
73
  };
74
74
  const databaseResp = await api.createDatabase(createDatabaseReq);
75
- if (options.json) {
76
- logger_1.logger.info(JSON.stringify(databaseResp, undefined, 2));
77
- }
78
- else {
79
- logger_1.logger.info(clc.bold(`Successfully created ${printer.prettyDatabaseString(databaseResp)}`));
80
- logger_1.logger.info("Please be sure to configure Firebase rules in your Firebase config file for\n" +
81
- "the new database. By default, created databases will have closed rules that\n" +
82
- "block any incoming third-party traffic.");
83
- logger_1.logger.info(`Your database may be viewed at ${printer.firebaseConsoleDatabaseUrl(options.project, database)}`);
84
- }
75
+ logger_1.logger.info(clc.bold(`Successfully created ${printer.prettyDatabaseString(databaseResp)}`));
76
+ logger_1.logger.info("Please be sure to configure Firebase rules in your Firebase config file for\n" +
77
+ "the new database. By default, created databases will have closed rules that\n" +
78
+ "block any incoming third-party traffic.");
79
+ logger_1.logger.info(`Your database may be viewed at ${printer.firebaseConsoleDatabaseUrl(options.project, database)}`);
85
80
  return databaseResp;
86
81
  });
@@ -27,11 +27,6 @@ exports.command = new command_1.Command("firestore:databases:delete <database>")
27
27
  }
28
28
  }
29
29
  const databaseResp = await api.deleteDatabase(options.project, database);
30
- if (options.json) {
31
- logger_1.logger.info(JSON.stringify(databaseResp, undefined, 2));
32
- }
33
- else {
34
- logger_1.logger.info(clc.bold(`Successfully deleted ${printer.prettyDatabaseString(databaseResp)}`));
35
- }
30
+ logger_1.logger.info(clc.bold(`Successfully deleted ${printer.prettyDatabaseString(databaseResp)}`));
36
31
  return databaseResp;
37
32
  });
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
4
  const command_1 = require("../command");
5
5
  const fsi = require("../firestore/api");
6
- const logger_1 = require("../logger");
7
6
  const requirePermissions_1 = require("../requirePermissions");
8
7
  const types_1 = require("../emulator/types");
9
8
  const commandUtils_1 = require("../emulator/commandUtils");
@@ -17,11 +16,6 @@ exports.command = new command_1.Command("firestore:databases:get [database]")
17
16
  const printer = new pretty_print_1.PrettyPrint();
18
17
  const databaseId = database || "(default)";
19
18
  const databaseResp = await api.getDatabase(options.project, databaseId);
20
- if (options.json) {
21
- logger_1.logger.info(JSON.stringify(databaseResp, undefined, 2));
22
- }
23
- else {
24
- printer.prettyPrintDatabase(databaseResp);
25
- }
19
+ printer.prettyPrintDatabase(databaseResp);
26
20
  return databaseResp;
27
21
  });
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
4
  const command_1 = require("../command");
5
5
  const fsi = require("../firestore/api");
6
- const logger_1 = require("../logger");
7
6
  const requirePermissions_1 = require("../requirePermissions");
8
7
  const types_1 = require("../emulator/types");
9
8
  const commandUtils_1 = require("../emulator/commandUtils");
@@ -16,11 +15,6 @@ exports.command = new command_1.Command("firestore:databases:list")
16
15
  const api = new fsi.FirestoreApi();
17
16
  const printer = new pretty_print_1.PrettyPrint();
18
17
  const databases = await api.listDatabases(options.project);
19
- if (options.json) {
20
- logger_1.logger.info(JSON.stringify(databases, undefined, 2));
21
- }
22
- else {
23
- printer.prettyPrintDatabases(databases);
24
- }
18
+ printer.prettyPrintDatabases(databases);
25
19
  return databases;
26
20
  });
@@ -55,16 +55,11 @@ exports.command = new command_1.Command("firestore:databases:restore")
55
55
  throw new error_1.FirebaseError(`Invalid value for flag --encryption-type. ${helpCommandText}`);
56
56
  }
57
57
  const databaseResp = await api.restoreDatabase(options.project, databaseId, backupName, encryptionConfig);
58
- if (options.json) {
59
- logger_1.logger.info(JSON.stringify(databaseResp, undefined, 2));
60
- }
61
- else {
62
- logger_1.logger.info(clc.bold(`Successfully initiated restore of ${printer.prettyDatabaseString(databaseResp)}`));
63
- logger_1.logger.info("Please be sure to configure Firebase rules in your Firebase config file for\n" +
64
- "the new database. By default, created databases will have closed rules that\n" +
65
- "block any incoming third-party traffic.");
66
- logger_1.logger.info(`Once the restore is complete, your database may be viewed at ${printer.firebaseConsoleDatabaseUrl(options.project, databaseId)}`);
67
- }
58
+ logger_1.logger.info(clc.bold(`Successfully initiated restore of ${printer.prettyDatabaseString(databaseResp)}`));
59
+ logger_1.logger.info("Please be sure to configure Firebase rules in your Firebase config file for\n" +
60
+ "the new database. By default, created databases will have closed rules that\n" +
61
+ "block any incoming third-party traffic.");
62
+ logger_1.logger.info(`Once the restore is complete, your database may be viewed at ${printer.firebaseConsoleDatabaseUrl(options.project, databaseId)}`);
68
63
  return databaseResp;
69
64
  function throwIfKmsKeyNameIsSet(kmsKeyName) {
70
65
  if (kmsKeyName) {
@@ -50,11 +50,6 @@ exports.command = new command_1.Command("firestore:databases:update <database>")
50
50
  pointInTimeRecoveryEnablement = types.PointInTimeRecoveryEnablement.DISABLED;
51
51
  }
52
52
  const databaseResp = await api.updateDatabase(options.project, database, deleteProtectionState, pointInTimeRecoveryEnablement);
53
- if (options.json) {
54
- logger_1.logger.info(JSON.stringify(databaseResp, undefined, 2));
55
- }
56
- else {
57
- logger_1.logger.info(clc.bold(`Successfully updated ${printer.prettyDatabaseString(databaseResp)}`));
58
- }
53
+ logger_1.logger.info(clc.bold(`Successfully updated ${printer.prettyDatabaseString(databaseResp)}`));
59
54
  return databaseResp;
60
55
  });
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
4
  const command_1 = require("../command");
5
5
  const fsi = require("../firestore/api");
6
- const logger_1 = require("../logger");
7
6
  const requirePermissions_1 = require("../requirePermissions");
8
7
  const types_1 = require("../emulator/types");
9
8
  const commandUtils_1 = require("../emulator/commandUtils");
@@ -16,11 +15,6 @@ exports.command = new command_1.Command("firestore:locations")
16
15
  const api = new fsi.FirestoreApi();
17
16
  const printer = new pretty_print_1.PrettyPrint();
18
17
  const locations = await api.locations(options.project);
19
- if (options.json) {
20
- logger_1.logger.info(JSON.stringify(locations, undefined, 2));
21
- }
22
- else {
23
- printer.prettyPrintLocations(locations);
24
- }
18
+ printer.prettyPrintLocations(locations);
25
19
  return locations;
26
20
  });
@@ -9,7 +9,6 @@ const firestore_utils_1 = require("./firestore-utils");
9
9
  const prompt_1 = require("../prompt");
10
10
  const clc = require("colorette");
11
11
  const utils = require("../utils");
12
- const logger_1 = require("../logger");
13
12
  exports.command = new command_1.Command("firestore:operations:cancel <operationName>")
14
13
  .description("cancels a long-running Cloud Firestore admin operation")
15
14
  .option("--database <databaseName>", 'Database ID for which the operation is running. "(default)" if none is provided.')
@@ -29,16 +28,11 @@ exports.command = new command_1.Command("firestore:operations:cancel <operationN
29
28
  }
30
29
  const api = new fsi.FirestoreApi();
31
30
  const status = await api.cancelOperation(options.project, databaseId, operationName);
32
- if (options.json) {
33
- logger_1.logger.info(JSON.stringify(status, undefined, 2));
31
+ if (status.success) {
32
+ utils.logSuccess("Operation cancelled successfully.");
34
33
  }
35
34
  else {
36
- if (status.success) {
37
- utils.logSuccess("Operation cancelled successfully.");
38
- }
39
- else {
40
- utils.logWarning("Canceling the operation failed.");
41
- }
35
+ utils.logWarning("Canceling the operation failed.");
42
36
  }
43
37
  return status;
44
38
  });
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
4
  const command_1 = require("../command");
5
5
  const fsi = require("../firestore/api");
6
- const logger_1 = require("../logger");
7
6
  const types_1 = require("../emulator/types");
8
7
  const commandUtils_1 = require("../emulator/commandUtils");
9
8
  const pretty_print_1 = require("../firestore/pretty-print");
@@ -18,12 +17,7 @@ exports.command = new command_1.Command("firestore:operations:describe <operatio
18
17
  operationName = (0, firestore_utils_1.getShortOperationName)(operationName);
19
18
  const api = new fsi.FirestoreApi();
20
19
  const operation = await api.describeOperation(options.project, databaseId, operationName);
21
- if (options.json) {
22
- logger_1.logger.info(JSON.stringify(operation, undefined, 2));
23
- }
24
- else {
25
- const printer = new pretty_print_1.PrettyPrint();
26
- printer.prettyPrintOperation(operation);
27
- }
20
+ const printer = new pretty_print_1.PrettyPrint();
21
+ printer.prettyPrintOperation(operation);
28
22
  return operation;
29
23
  });