firebase-tools 13.3.1 → 13.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.
Files changed (46) hide show
  1. package/lib/api.js +2 -1
  2. package/lib/commands/apphosting-backends-create.js +3 -3
  3. package/lib/commands/apphosting-backends-delete.js +3 -39
  4. package/lib/commands/apphosting-backends-get.js +4 -35
  5. package/lib/commands/apphosting-backends-list.js +17 -9
  6. package/lib/commands/apphosting-builds-create.js +4 -4
  7. package/lib/commands/apphosting-builds-get.js +2 -2
  8. package/lib/commands/apphosting-rollouts-create.js +3 -3
  9. package/lib/commands/apphosting-rollouts-list.js +2 -2
  10. package/lib/commands/firestore-backups-delete.js +44 -0
  11. package/lib/commands/firestore-backups-get.js +25 -0
  12. package/lib/commands/firestore-backups-list.js +34 -0
  13. package/lib/commands/firestore-backups-schedules-create.js +67 -0
  14. package/lib/commands/firestore-backups-schedules-delete.js +46 -0
  15. package/lib/commands/firestore-backups-schedules-list.js +28 -0
  16. package/lib/commands/firestore-backups-schedules-update.js +33 -0
  17. package/lib/commands/firestore-databases-create.js +4 -2
  18. package/lib/commands/firestore-databases-delete.js +4 -2
  19. package/lib/commands/firestore-databases-get.js +3 -1
  20. package/lib/commands/firestore-databases-list.js +3 -1
  21. package/lib/commands/firestore-databases-restore.js +42 -0
  22. package/lib/commands/firestore-databases-update.js +4 -2
  23. package/lib/commands/firestore-indexes-list.js +5 -3
  24. package/lib/commands/firestore-locations.js +3 -1
  25. package/lib/commands/index.js +10 -0
  26. package/lib/deploy/extensions/v2FunctionHelper.js +2 -1
  27. package/lib/deploy/functions/ensure.js +2 -2
  28. package/lib/deploy/functions/prepare.js +5 -9
  29. package/lib/ensureApiEnabled.js +8 -6
  30. package/lib/extensions/extensionsHelper.js +2 -2
  31. package/lib/extensions/secretsUtils.js +2 -1
  32. package/lib/firestore/api-sort.js +23 -1
  33. package/lib/firestore/api-types.js +6 -1
  34. package/lib/firestore/api.js +18 -115
  35. package/lib/firestore/backupUtils.js +30 -0
  36. package/lib/firestore/pretty-print.js +184 -0
  37. package/lib/functions/secrets.js +1 -1
  38. package/lib/gcp/apphosting.js +2 -3
  39. package/lib/gcp/auth.js +5 -2
  40. package/lib/gcp/firestore.js +75 -1
  41. package/lib/gcp/storage.js +1 -1
  42. package/lib/init/features/apphosting/index.js +12 -7
  43. package/lib/init/features/database.js +2 -1
  44. package/lib/init/features/extensions/index.js +2 -1
  45. package/lib/init/features/functions/index.js +3 -2
  46. package/package.json +2 -1
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PrettyPrint = void 0;
4
+ const clc = require("colorette");
5
+ const Table = require("cli-table");
6
+ const sort = require("./api-sort");
7
+ const types = require("./api-types");
8
+ const logger_1 = require("../logger");
9
+ const util = require("./util");
10
+ class PrettyPrint {
11
+ prettyPrintIndexes(indexes) {
12
+ if (indexes.length === 0) {
13
+ logger_1.logger.info("None");
14
+ return;
15
+ }
16
+ const sortedIndexes = indexes.sort(sort.compareApiIndex);
17
+ sortedIndexes.forEach((index) => {
18
+ logger_1.logger.info(this.prettyIndexString(index));
19
+ });
20
+ }
21
+ prettyPrintDatabases(databases) {
22
+ if (databases.length === 0) {
23
+ logger_1.logger.info("No databases found.");
24
+ return;
25
+ }
26
+ const sortedDatabases = databases.sort(sort.compareApiDatabase);
27
+ const table = new Table({
28
+ head: ["Database Name"],
29
+ colWidths: [Math.max(...sortedDatabases.map((database) => database.name.length + 5), 20)],
30
+ });
31
+ table.push(...sortedDatabases.map((database) => [this.prettyDatabaseString(database)]));
32
+ logger_1.logger.info(table.toString());
33
+ }
34
+ prettyPrintDatabase(database) {
35
+ const table = new Table({
36
+ head: ["Field", "Value"],
37
+ colWidths: [25, Math.max(50, 5 + database.name.length)],
38
+ });
39
+ table.push(["Name", clc.yellow(database.name)], ["Create Time", clc.yellow(database.createTime)], ["Last Update Time", clc.yellow(database.updateTime)], ["Type", clc.yellow(database.type)], ["Location", clc.yellow(database.locationId)], ["Delete Protection State", clc.yellow(database.deleteProtectionState)], ["Point In Time Recovery", clc.yellow(database.pointInTimeRecoveryEnablement)], ["Earliest Version Time", clc.yellow(database.earliestVersionTime)], ["Version Retention Period", clc.yellow(database.versionRetentionPeriod)]);
40
+ logger_1.logger.info(table.toString());
41
+ }
42
+ prettyPrintBackups(backups) {
43
+ if (backups.length === 0) {
44
+ logger_1.logger.info("No backups found.");
45
+ return;
46
+ }
47
+ const sortedBackups = backups.sort(sort.compareApiBackup);
48
+ const table = new Table({
49
+ head: ["Backup Name", "Database Name", "Snapshot Time", "State"],
50
+ colWidths: [
51
+ Math.max(...sortedBackups.map((backup) => backup.name.length + 5), 20),
52
+ Math.max(...sortedBackups.map((backup) => backup.database.length + 5), 20),
53
+ 30,
54
+ 10,
55
+ ],
56
+ });
57
+ table.push(...sortedBackups.map((backup) => [
58
+ this.prettyBackupString(backup),
59
+ this.prettyDatabaseString(backup.database || ""),
60
+ backup.snapshotTime,
61
+ backup.state,
62
+ ]));
63
+ logger_1.logger.info(table.toString());
64
+ }
65
+ prettyPrintBackupSchedules(backupSchedules, databaseId) {
66
+ if (backupSchedules.length === 0) {
67
+ logger_1.logger.info(`No backup schedules for database ${databaseId} found.`);
68
+ return;
69
+ }
70
+ const sortedBackupSchedules = backupSchedules.sort(sort.compareApiBackupSchedule);
71
+ sortedBackupSchedules.forEach((schedule) => this.prettyPrintBackupSchedule(schedule));
72
+ }
73
+ prettyPrintBackupSchedule(backupSchedule) {
74
+ const table = new Table({
75
+ head: ["Field", "Value"],
76
+ colWidths: [25, Math.max(50, 5 + backupSchedule.name.length)],
77
+ });
78
+ table.push(["Name", clc.yellow(backupSchedule.name)], ["Create Time", clc.yellow(backupSchedule.createTime)], ["Last Update Time", clc.yellow(backupSchedule.updateTime)], ["Retention", clc.yellow(backupSchedule.retention)], ["Recurrence", this.prettyRecurrenceString(backupSchedule)]);
79
+ logger_1.logger.info(table.toString());
80
+ }
81
+ prettyRecurrenceString(backupSchedule) {
82
+ if (backupSchedule.dailyRecurrence) {
83
+ return clc.yellow("DAILY");
84
+ }
85
+ else if (backupSchedule.weeklyRecurrence) {
86
+ return clc.yellow(`WEEKLY (${backupSchedule.weeklyRecurrence.day})`);
87
+ }
88
+ return "";
89
+ }
90
+ prettyPrintBackup(backup) {
91
+ const table = new Table({
92
+ head: ["Field", "Value"],
93
+ colWidths: [25, Math.max(50, 5 + backup.name.length, 5 + backup.database.length)],
94
+ });
95
+ table.push(["Name", clc.yellow(backup.name)], ["Database", clc.yellow(backup.database)], ["Database UID", clc.yellow(backup.databaseUid)], ["State", clc.yellow(backup.state)], ["Snapshot Time", clc.yellow(backup.snapshotTime)], ["Expire Time", clc.yellow(backup.expireTime)], ["Stats", clc.yellow(backup.stats)]);
96
+ logger_1.logger.info(table.toString());
97
+ }
98
+ prettyPrintLocations(locations) {
99
+ if (locations.length === 0) {
100
+ logger_1.logger.info("No Locations Available");
101
+ return;
102
+ }
103
+ const table = new Table({
104
+ head: ["Display Name", "LocationId"],
105
+ colWidths: [20, 30],
106
+ });
107
+ table.push(...locations
108
+ .sort(sort.compareLocation)
109
+ .map((location) => [location.displayName, location.locationId]));
110
+ logger_1.logger.info(table.toString());
111
+ }
112
+ printFieldOverrides(fields) {
113
+ if (fields.length === 0) {
114
+ logger_1.logger.info("None");
115
+ return;
116
+ }
117
+ const sortedFields = fields.sort(sort.compareApiField);
118
+ sortedFields.forEach((field) => {
119
+ logger_1.logger.info(this.prettyFieldString(field));
120
+ });
121
+ }
122
+ prettyIndexString(index, includeState = true) {
123
+ let result = "";
124
+ if (index.state && includeState) {
125
+ const stateMsg = `[${index.state}] `;
126
+ if (index.state === types.State.READY) {
127
+ result += clc.green(stateMsg);
128
+ }
129
+ else if (index.state === types.State.CREATING) {
130
+ result += clc.yellow(stateMsg);
131
+ }
132
+ else {
133
+ result += clc.red(stateMsg);
134
+ }
135
+ }
136
+ const nameInfo = util.parseIndexName(index.name);
137
+ result += clc.cyan(`(${nameInfo.collectionGroupId})`);
138
+ result += " -- ";
139
+ index.fields.forEach((field) => {
140
+ if (field.fieldPath === "__name__") {
141
+ return;
142
+ }
143
+ const orderOrArrayConfig = field.order ? field.order : field.arrayConfig;
144
+ result += `(${field.fieldPath},${orderOrArrayConfig}) `;
145
+ });
146
+ return result;
147
+ }
148
+ prettyBackupString(backup) {
149
+ return clc.yellow(backup.name || "");
150
+ }
151
+ prettyBackupScheduleString(backupSchedule) {
152
+ return clc.yellow(backupSchedule.name || "");
153
+ }
154
+ prettyDatabaseString(database) {
155
+ return clc.yellow(typeof database === "string" ? database : database.name);
156
+ }
157
+ prettyFieldString(field) {
158
+ let result = "";
159
+ const parsedName = util.parseFieldName(field.name);
160
+ result +=
161
+ "[" +
162
+ clc.cyan(parsedName.collectionGroupId) +
163
+ "." +
164
+ clc.yellow(parsedName.fieldPath) +
165
+ "] --";
166
+ const fieldIndexes = field.indexConfig.indexes || [];
167
+ if (fieldIndexes.length > 0) {
168
+ fieldIndexes.forEach((index) => {
169
+ const firstField = index.fields[0];
170
+ const mode = firstField.order || firstField.arrayConfig;
171
+ result += ` (${mode})`;
172
+ });
173
+ }
174
+ else {
175
+ result += " (no indexes)";
176
+ }
177
+ const fieldTtl = field.ttlConfig;
178
+ if (fieldTtl) {
179
+ result += ` TTL(${fieldTtl.state})`;
180
+ }
181
+ return result;
182
+ }
183
+ }
184
+ exports.PrettyPrint = PrettyPrint;
@@ -44,7 +44,7 @@ function toUpperSnakeCase(key) {
44
44
  }
45
45
  function ensureApi(options) {
46
46
  const projectId = (0, projectUtils_1.needProjectId)(options);
47
- return ensureApiEnabled.ensure(projectId, "secretmanager.googleapis.com", "secretmanager", true);
47
+ return ensureApiEnabled.ensure(projectId, api_1.secretManagerOrigin, "secretmanager", true);
48
48
  }
49
49
  exports.ensureApi = ensureApi;
50
50
  async function ensureValidKey(key, options) {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getNextRolloutId = exports.ensureApiEnabled = exports.listLocations = exports.updateTraffic = exports.listRollouts = exports.createRollout = exports.createBuild = exports.listBuilds = exports.getBuild = exports.deleteBackend = exports.listBackends = exports.getBackend = exports.createBackend = exports.client = exports.API_VERSION = exports.API_HOST = void 0;
3
+ exports.getNextRolloutId = exports.ensureApiEnabled = exports.listLocations = exports.updateTraffic = exports.listRollouts = exports.createRollout = exports.createBuild = exports.listBuilds = exports.getBuild = exports.deleteBackend = exports.listBackends = exports.getBackend = exports.createBackend = exports.client = exports.API_VERSION = void 0;
4
4
  const proto = require("../gcp/proto");
5
5
  const apiv2_1 = require("../apiv2");
6
6
  const projectUtils_1 = require("../projectUtils");
@@ -9,7 +9,6 @@ const ensureApiEnabled_1 = require("../ensureApiEnabled");
9
9
  const deploymentTool = require("../deploymentTool");
10
10
  const error_1 = require("../error");
11
11
  const metaprogramming_1 = require("../metaprogramming");
12
- exports.API_HOST = new URL(api_1.apphostingOrigin).host;
13
12
  exports.API_VERSION = "v1alpha";
14
13
  exports.client = new apiv2_1.Client({
15
14
  urlPrefix: api_1.apphostingOrigin,
@@ -126,7 +125,7 @@ async function listLocations(projectId) {
126
125
  exports.listLocations = listLocations;
127
126
  async function ensureApiEnabled(options) {
128
127
  const projectId = (0, projectUtils_1.needProjectId)(options);
129
- return await (0, ensureApiEnabled_1.ensure)(projectId, exports.API_HOST, "app hosting", true);
128
+ return await (0, ensureApiEnabled_1.ensure)(projectId, api_1.apphostingOrigin, "app hosting", true);
130
129
  }
131
130
  exports.ensureApiEnabled = ensureApiEnabled;
132
131
  async function getNextRolloutId(projectId, location, backendId, counter) {
package/lib/gcp/auth.js CHANGED
@@ -5,12 +5,15 @@ const apiv2_1 = require("../apiv2");
5
5
  const api_1 = require("../api");
6
6
  const apiClient = new apiv2_1.Client({ urlPrefix: api_1.identityOrigin, auth: true });
7
7
  async function getAuthDomains(project) {
8
- const res = await apiClient.get(`/admin/v2/projects/${project}/config`);
8
+ const res = await apiClient.get(`/admin/v2/projects/${project}/config`, { headers: { "x-goog-user-project": project } });
9
9
  return res.body.authorizedDomains;
10
10
  }
11
11
  exports.getAuthDomains = getAuthDomains;
12
12
  async function updateAuthDomains(project, authDomains) {
13
- const res = await apiClient.patch(`/admin/v2/projects/${project}/config`, { authorizedDomains: authDomains }, { queryParams: { update_mask: "authorizedDomains" } });
13
+ const res = await apiClient.patch(`/admin/v2/projects/${project}/config`, { authorizedDomains: authDomains }, {
14
+ queryParams: { update_mask: "authorizedDomains" },
15
+ headers: { "x-goog-user-project": project },
16
+ });
14
17
  return res.body.authorizedDomains;
15
18
  }
16
19
  exports.updateAuthDomains = updateAuthDomains;
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.deleteDocuments = exports.deleteDocument = exports.listCollectionIds = exports.getDatabase = void 0;
3
+ exports.getBackupSchedule = exports.listBackupSchedules = exports.getBackup = exports.listBackups = exports.deleteBackupSchedule = exports.deleteBackup = exports.updateBackupSchedule = exports.createBackupSchedule = exports.deleteDocuments = exports.deleteDocument = exports.listCollectionIds = exports.getDatabase = exports.DayOfWeek = void 0;
4
4
  const api_1 = require("../api");
5
5
  const apiv2_1 = require("../apiv2");
6
6
  const logger_1 = require("../logger");
7
+ const proto_1 = require("./proto");
8
+ const error_1 = require("../error");
7
9
  const prodOnlyClient = new apiv2_1.Client({
8
10
  auth: true,
9
11
  apiVersion: "v1",
@@ -14,6 +16,16 @@ const emuOrProdClient = new apiv2_1.Client({
14
16
  apiVersion: "v1",
15
17
  urlPrefix: api_1.firestoreOriginOrEmulator,
16
18
  });
19
+ var DayOfWeek;
20
+ (function (DayOfWeek) {
21
+ DayOfWeek["MONDAY"] = "MONDAY";
22
+ DayOfWeek["TUEDAY"] = "TUESDAY";
23
+ DayOfWeek["WEDNESDAY"] = "WEDNESDAY";
24
+ DayOfWeek["THURSDAY"] = "THURSDAY";
25
+ DayOfWeek["FRIDAY"] = "FRIDAY";
26
+ DayOfWeek["SATURDAY"] = "SATURDAY";
27
+ DayOfWeek["SUNDAY"] = "SUNDAY";
28
+ })(DayOfWeek = exports.DayOfWeek || (exports.DayOfWeek = {}));
17
29
  async function getDatabase(project, database, allowEmulator = false) {
18
30
  const apiClient = allowEmulator ? emuOrProdClient : prodOnlyClient;
19
31
  const url = `projects/${project}/databases/${database}`;
@@ -54,3 +66,65 @@ async function deleteDocuments(project, docs, allowEmulator = false) {
54
66
  return res.body.writeResults.length;
55
67
  }
56
68
  exports.deleteDocuments = deleteDocuments;
69
+ async function createBackupSchedule(project, databaseId, retention, dailyRecurrence, weeklyRecurrence) {
70
+ const url = `projects/${project}/databases/${databaseId}/backupSchedules`;
71
+ const data = {
72
+ retention: (0, proto_1.durationFromSeconds)(retention),
73
+ dailyRecurrence,
74
+ weeklyRecurrence,
75
+ };
76
+ (0, proto_1.assertOneOf)("BackupSchedule", data, "recurrence", "dailyRecurrence", "weeklyRecurrence");
77
+ const res = await prodOnlyClient.post(url, data);
78
+ return res.body;
79
+ }
80
+ exports.createBackupSchedule = createBackupSchedule;
81
+ async function updateBackupSchedule(backupScheduleName, retention) {
82
+ const data = {
83
+ retention: (0, proto_1.durationFromSeconds)(retention),
84
+ };
85
+ const res = await prodOnlyClient.patch(backupScheduleName, data);
86
+ return res.body;
87
+ }
88
+ exports.updateBackupSchedule = updateBackupSchedule;
89
+ async function deleteBackup(backupName) {
90
+ await prodOnlyClient.delete(backupName);
91
+ }
92
+ exports.deleteBackup = deleteBackup;
93
+ async function deleteBackupSchedule(backupScheduleName) {
94
+ await prodOnlyClient.delete(backupScheduleName);
95
+ }
96
+ exports.deleteBackupSchedule = deleteBackupSchedule;
97
+ async function listBackups(project, location) {
98
+ const url = `/projects/${project}/locations/${location}/backups`;
99
+ const res = await prodOnlyClient.get(url);
100
+ return res.body;
101
+ }
102
+ exports.listBackups = listBackups;
103
+ async function getBackup(backupName) {
104
+ const res = await prodOnlyClient.get(backupName);
105
+ const backup = res.body;
106
+ if (!backup) {
107
+ throw new error_1.FirebaseError("Not found");
108
+ }
109
+ return backup;
110
+ }
111
+ exports.getBackup = getBackup;
112
+ async function listBackupSchedules(project, database) {
113
+ const url = `/projects/${project}/databases/${database}/backupSchedules`;
114
+ const res = await prodOnlyClient.get(url);
115
+ const backupSchedules = res.body.backupSchedules;
116
+ if (!backupSchedules) {
117
+ return [];
118
+ }
119
+ return backupSchedules;
120
+ }
121
+ exports.listBackupSchedules = listBackupSchedules;
122
+ async function getBackupSchedule(backupScheduleName) {
123
+ const res = await prodOnlyClient.get(backupScheduleName);
124
+ const backupSchedule = res.body;
125
+ if (!backupSchedule) {
126
+ throw new error_1.FirebaseError("Not found");
127
+ }
128
+ return backupSchedule;
129
+ }
130
+ exports.getBackupSchedule = getBackupSchedule;
@@ -10,7 +10,7 @@ const logger_1 = require("../logger");
10
10
  const ensureApiEnabled_1 = require("../ensureApiEnabled");
11
11
  async function getDefaultBucket(projectId) {
12
12
  var _a;
13
- await (0, ensureApiEnabled_1.ensure)(projectId, "firebasestorage.googleapis.com", "storage", false);
13
+ await (0, ensureApiEnabled_1.ensure)(projectId, api_1.firebaseStorageOrigin, "storage", false);
14
14
  try {
15
15
  const localAPIClient = new apiv2_1.Client({ urlPrefix: api_1.firebaseStorageOrigin, apiVersion: "v1alpha" });
16
16
  const response = await localAPIClient.get(`/projects/${projectId}/defaultBucket`);
@@ -24,10 +24,10 @@ const apphostingPollerOptions = {
24
24
  };
25
25
  async function doSetup(projectId, location, serviceAccount) {
26
26
  await Promise.all([
27
- (0, ensureApiEnabled_1.ensure)(projectId, "cloudbuild.googleapis.com", "apphosting", true),
28
- (0, ensureApiEnabled_1.ensure)(projectId, "secretmanager.googleapis.com", "apphosting", true),
29
- (0, ensureApiEnabled_1.ensure)(projectId, "run.googleapis.com", "apphosting", true),
30
- (0, ensureApiEnabled_1.ensure)(projectId, "artifactregistry.googleapis.com", "apphosting", true),
27
+ (0, ensureApiEnabled_1.ensure)(projectId, api_1.cloudbuildOrigin, "apphosting", true),
28
+ (0, ensureApiEnabled_1.ensure)(projectId, api_1.secretManagerOrigin, "apphosting", true),
29
+ (0, ensureApiEnabled_1.ensure)(projectId, api_1.cloudRunApiOrigin, "apphosting", true),
30
+ (0, ensureApiEnabled_1.ensure)(projectId, api_1.artifactRegistryDomain, "apphosting", true),
31
31
  ]);
32
32
  const allowedLocations = (await apphosting.listLocations(projectId)).map((loc) => loc.locationId);
33
33
  if (location) {
@@ -122,9 +122,14 @@ async function createBackend(projectId, location, backendId, repository, service
122
122
  return await createBackendAndPoll();
123
123
  }
124
124
  catch (err) {
125
- if (err.status === 403 && err.message.includes(defaultServiceAccount)) {
126
- await provisionDefaultComputeServiceAccount(projectId);
127
- return await createBackendAndPoll();
125
+ if (err.status === 403) {
126
+ if (err.message.includes(defaultServiceAccount)) {
127
+ await provisionDefaultComputeServiceAccount(projectId);
128
+ return await createBackendAndPoll();
129
+ }
130
+ else if (serviceAccount && err.message.includes(serviceAccount)) {
131
+ throw new error_1.FirebaseError(`Failed to create backend due to missing delegation permissions for ${serviceAccount}. Make sure you have the iam.serviceAccounts.actAs permission.`, { children: [err] });
132
+ }
128
133
  }
129
134
  throw err;
130
135
  }
@@ -12,6 +12,7 @@ const ensureApiEnabled_1 = require("../../ensureApiEnabled");
12
12
  const getDefaultDatabaseInstance_1 = require("../../getDefaultDatabaseInstance");
13
13
  const error_1 = require("../../error");
14
14
  const apiv2_1 = require("../../apiv2");
15
+ const api_1 = require("../../api");
15
16
  const DEFAULT_RULES = JSON.stringify({ rules: { ".read": "auth != null", ".write": "auth != null" } }, null, 2);
16
17
  async function getDBRules(instanceDetails) {
17
18
  if (!instanceDetails || !instanceDetails.name) {
@@ -70,7 +71,7 @@ async function doSetup(setup, config) {
70
71
  setup.config = setup.config || {};
71
72
  let instanceDetails;
72
73
  if (setup.projectId) {
73
- await (0, ensureApiEnabled_1.ensure)(setup.projectId, "firebasedatabase.googleapis.com", "database", false);
74
+ await (0, ensureApiEnabled_1.ensure)(setup.projectId, api_1.rtdbManagementOrigin, "database", false);
74
75
  logger_1.logger.info();
75
76
  setup.instance =
76
77
  setup.instance || (await (0, getDefaultDatabaseInstance_1.getDefaultDatabaseInstance)({ project: setup.projectId }));
@@ -4,12 +4,13 @@ exports.doSetup = void 0;
4
4
  const requirePermissions_1 = require("../../../requirePermissions");
5
5
  const ensureApiEnabled_1 = require("../../../ensureApiEnabled");
6
6
  const manifest = require("../../../extensions/manifest");
7
+ const api_1 = require("../../../api");
7
8
  async function doSetup(setup, config, options) {
8
9
  var _a, _b;
9
10
  const projectId = (_b = (_a = setup === null || setup === void 0 ? void 0 : setup.rcfile) === null || _a === void 0 ? void 0 : _a.projects) === null || _b === void 0 ? void 0 : _b.default;
10
11
  if (projectId) {
11
12
  await (0, requirePermissions_1.requirePermissions)(Object.assign(Object.assign({}, options), { project: projectId }));
12
- await Promise.all([(0, ensureApiEnabled_1.ensure)(projectId, "firebaseextensions.googleapis.com", "unused", true)]);
13
+ await Promise.all([(0, ensureApiEnabled_1.ensure)(projectId, api_1.extensionsOrigin, "unused", true)]);
13
14
  }
14
15
  return manifest.writeEmptyManifest(config, options);
15
16
  }
@@ -8,6 +8,7 @@ const requirePermissions_1 = require("../../../requirePermissions");
8
8
  const ensureApiEnabled_1 = require("../../../ensureApiEnabled");
9
9
  const projectConfig_1 = require("../../../functions/projectConfig");
10
10
  const error_1 = require("../../../error");
11
+ const api_1 = require("../../../api");
11
12
  const MAX_ATTEMPTS = 5;
12
13
  async function doSetup(setup, config, options) {
13
14
  var _a, _b;
@@ -15,8 +16,8 @@ async function doSetup(setup, config, options) {
15
16
  if (projectId) {
16
17
  await (0, requirePermissions_1.requirePermissions)(Object.assign(Object.assign({}, options), { project: projectId }));
17
18
  await Promise.all([
18
- (0, ensureApiEnabled_1.ensure)(projectId, "cloudfunctions.googleapis.com", "unused", true),
19
- (0, ensureApiEnabled_1.ensure)(projectId, "runtimeconfig.googleapis.com", "unused", true),
19
+ (0, ensureApiEnabled_1.ensure)(projectId, api_1.functionsOrigin, "unused", true),
20
+ (0, ensureApiEnabled_1.ensure)(projectId, api_1.runtimeconfigOrigin, "unused", true),
20
21
  ]);
21
22
  }
22
23
  setup.functions = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-tools",
3
- "version": "13.3.1",
3
+ "version": "13.4.0",
4
4
  "description": "Command-Line Interface for Firebase",
5
5
  "main": "./lib/index.js",
6
6
  "bin": {
@@ -74,6 +74,7 @@
74
74
  "cross-env": "^5.1.3",
75
75
  "cross-spawn": "^7.0.3",
76
76
  "csv-parse": "^5.0.4",
77
+ "deep-equal-in-any-order": "^2.0.6",
77
78
  "exegesis": "^4.1.0",
78
79
  "exegesis-express": "^4.0.0",
79
80
  "express": "^4.16.4",