firebase-tools 12.7.0 → 12.8.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.
@@ -18,30 +18,37 @@ exports.command = new command_1.Command("firestore:databases:update <database>")
18
18
  .before(commandUtils_1.warnEmulatorNotSupported, types_1.Emulators.FIRESTORE)
19
19
  .action(async (database, options) => {
20
20
  const api = new fsi.FirestoreApi();
21
- if (!options.type && !options.deleteProtection && !options.pointInTimeRecovery) {
21
+ if (!options.deleteProtection && !options.pointInTimeRecovery) {
22
22
  logger_1.logger.error("Missing properties to update. See firebase firestore:databases:update --help for more info.");
23
23
  return;
24
24
  }
25
- const type = types.DatabaseType.FIRESTORE_NATIVE;
26
25
  if (options.deleteProtection &&
27
26
  options.deleteProtection !== types.DatabaseDeleteProtectionStateOption.ENABLED &&
28
27
  options.deleteProtection !== types.DatabaseDeleteProtectionStateOption.DISABLED) {
29
28
  logger_1.logger.error("Invalid value for flag --delete-protection. See firebase firestore:databases:update --help for more info.");
30
29
  return;
31
30
  }
32
- const deleteProtectionState = options.deleteProtection === types.DatabaseDeleteProtectionStateOption.ENABLED
33
- ? types.DatabaseDeleteProtectionState.ENABLED
34
- : types.DatabaseDeleteProtectionState.DISABLED;
31
+ let deleteProtectionState;
32
+ if (options.deleteProtection === types.DatabaseDeleteProtectionStateOption.ENABLED) {
33
+ deleteProtectionState = types.DatabaseDeleteProtectionState.ENABLED;
34
+ }
35
+ else if (options.deleteProtection === types.DatabaseDeleteProtectionStateOption.DISABLED) {
36
+ deleteProtectionState = types.DatabaseDeleteProtectionState.DISABLED;
37
+ }
35
38
  if (options.pointInTimeRecovery &&
36
39
  options.pointInTimeRecovery !== types.PointInTimeRecoveryEnablementOption.ENABLED &&
37
40
  options.pointInTimeRecovery !== types.PointInTimeRecoveryEnablementOption.DISABLED) {
38
41
  logger_1.logger.error("Invalid value for flag --point-in-time-recovery. See firebase firestore:databases:update --help for more info.");
39
42
  return;
40
43
  }
41
- const pointInTimeRecoveryEnablement = options.pointInTimeRecovery === types.PointInTimeRecoveryEnablementOption.ENABLED
42
- ? types.PointInTimeRecoveryEnablement.ENABLED
43
- : types.PointInTimeRecoveryEnablement.DISABLED;
44
- const databaseResp = await api.updateDatabase(options.project, database, type, deleteProtectionState, pointInTimeRecoveryEnablement);
44
+ let pointInTimeRecoveryEnablement;
45
+ if (options.pointInTimeRecovery === types.PointInTimeRecoveryEnablementOption.ENABLED) {
46
+ pointInTimeRecoveryEnablement = types.PointInTimeRecoveryEnablement.ENABLED;
47
+ }
48
+ else if (options.pointInTimeRecovery === types.PointInTimeRecoveryEnablementOption.DISABLED) {
49
+ pointInTimeRecoveryEnablement = types.PointInTimeRecoveryEnablement.DISABLED;
50
+ }
51
+ const databaseResp = await api.updateDatabase(options.project, database, deleteProtectionState, pointInTimeRecoveryEnablement);
45
52
  if (options.json) {
46
53
  logger_1.logger.info(JSON.stringify(databaseResp, undefined, 2));
47
54
  }
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.command = void 0;
4
+ const command_1 = require("../command");
5
+ const projectUtils_1 = require("../projectUtils");
6
+ const requireInteractive_1 = require("../requireInteractive");
7
+ const frameworks_1 = require("../init/features/frameworks");
8
+ exports.command = new command_1.Command("backends:create")
9
+ .description("Create a backend in a Firebase project")
10
+ .before(requireInteractive_1.default)
11
+ .action(async (options) => {
12
+ const projectId = (0, projectUtils_1.needProjectId)(options);
13
+ await (0, frameworks_1.doSetup)(options, projectId);
14
+ });
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.command = void 0;
4
+ const command_1 = require("../command");
5
+ const projectUtils_1 = require("../projectUtils");
6
+ const error_1 = require("../error");
7
+ const gcp = require("../gcp/frameworks");
8
+ const prompt_1 = require("../prompt");
9
+ const utils = require("../utils");
10
+ exports.command = new command_1.Command("backends:delete")
11
+ .description("Delete a backend from a Firebase project")
12
+ .option("-l, --location <location>", "App Backend location", "us-central1")
13
+ .option("-s, --backendId <backendId>", "Backend Id", "")
14
+ .withForce()
15
+ .action(async (options) => {
16
+ const projectId = (0, projectUtils_1.needProjectId)(options);
17
+ const location = options.location;
18
+ const backendId = options.backendId;
19
+ if (!backendId) {
20
+ throw new error_1.FirebaseError("Backend id can't be empty.");
21
+ }
22
+ const confirmDeletion = await (0, prompt_1.promptOnce)({
23
+ type: "confirm",
24
+ name: "force",
25
+ default: false,
26
+ message: "You are about to delete the backend with id: " + backendId + "\n Are you sure?",
27
+ }, options);
28
+ if (!confirmDeletion) {
29
+ throw new error_1.FirebaseError("Deletion aborted.");
30
+ }
31
+ try {
32
+ await gcp.deleteBackend(projectId, location, backendId);
33
+ utils.logSuccess(`Successfully deleted the backend: ${backendId}`);
34
+ }
35
+ catch (err) {
36
+ throw new error_1.FirebaseError(`Failed to delete backend: ${backendId}. Please check the parameters you have provided.`, { original: err });
37
+ }
38
+ });
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.command = void 0;
4
+ const command_1 = require("../command");
5
+ const projectUtils_1 = require("../projectUtils");
6
+ const gcp = require("../gcp/frameworks");
7
+ const error_1 = require("../error");
8
+ const logger_1 = require("../logger");
9
+ const Table = require("cli-table");
10
+ exports.command = new command_1.Command("backends:get")
11
+ .description("Get backend details of a Firebase project")
12
+ .option("-l, --location <location>", "App Backend location", "us-central1")
13
+ .option("--s, --backendId <backendId>", "Backend Id", "")
14
+ .action(async (options) => {
15
+ const projectId = (0, projectUtils_1.needProjectId)(options);
16
+ const location = options.location;
17
+ const backendId = options.backendId;
18
+ if (!backendId) {
19
+ throw new error_1.FirebaseError("Backend id can't be empty.");
20
+ }
21
+ let backend;
22
+ try {
23
+ backend = await gcp.getBackend(projectId, location, backendId);
24
+ const table = new Table({
25
+ head: ["Backend Id", "Repository Name", "URL", "Location", "Created Date", "Updated Date"],
26
+ style: { head: ["green"] },
27
+ });
28
+ table.push([
29
+ backend.name,
30
+ backend.codebase.repository,
31
+ backend.uri,
32
+ backend.createTime,
33
+ backend.updateTime,
34
+ ]);
35
+ logger_1.logger.info(table.toString());
36
+ }
37
+ catch (err) {
38
+ throw new error_1.FirebaseError(`Failed to get backend: ${backendId}. Please check the parameters you have provided.`, { original: err });
39
+ }
40
+ return backend;
41
+ });
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.command = void 0;
4
+ const command_1 = require("../command");
5
+ const projectUtils_1 = require("../projectUtils");
6
+ const gcp = require("../gcp/frameworks");
7
+ const error_1 = require("../error");
8
+ const logger_1 = require("../logger");
9
+ const colorette_1 = require("colorette");
10
+ const Table = require("cli-table");
11
+ exports.command = new command_1.Command("backends:list")
12
+ .description("List backends of a Firebase project.")
13
+ .option("-l, --location <location>", "App Backend location", "us-central1")
14
+ .action(async (options) => {
15
+ const projectId = (0, projectUtils_1.needProjectId)(options);
16
+ const location = options.location;
17
+ const table = new Table({
18
+ head: ["Backend Id", "Repository Name", "URL", "Location", "Created Date", "Updated Date"],
19
+ style: { head: ["green"] },
20
+ });
21
+ let backendsList;
22
+ try {
23
+ backendsList = await gcp.listBackends(projectId, location);
24
+ for (const backend of backendsList.backends) {
25
+ const entry = [
26
+ backend.name,
27
+ backend.codebase.repository,
28
+ backend.uri,
29
+ backend.createTime,
30
+ backend.updateTime,
31
+ ];
32
+ table.push(entry);
33
+ }
34
+ logger_1.logger.info(`Backends for project ${(0, colorette_1.bold)(projectId)}`);
35
+ logger_1.logger.info(table.toString());
36
+ }
37
+ catch (err) {
38
+ throw new error_1.FirebaseError(`Unable to list backends present in project: ${projectId}. Please check the parameters you have provided.`, { original: err });
39
+ }
40
+ return backendsList;
41
+ });
@@ -145,6 +145,14 @@ function load(client) {
145
145
  client.internaltesting.functions = {};
146
146
  client.internaltesting.functions.discover = loadCommand("internaltesting-functions-discover");
147
147
  }
148
+ if (experiments.isEnabled("internalframeworks")) {
149
+ client.frameworks = {};
150
+ client.frameworks.backends = {};
151
+ client.frameworks.backends.list = loadCommand("frameworks-backends-list");
152
+ client.frameworks.backends.create = loadCommand("frameworks-backends-create");
153
+ client.frameworks.backends.get = loadCommand("frameworks-backends-get");
154
+ client.frameworks.backends.delete = loadCommand("frameworks-backends-delete");
155
+ }
148
156
  client.login = loadCommand("login");
149
157
  client.login.add = loadCommand("login-add");
150
158
  client.login.ci = loadCommand("login-ci");
@@ -485,10 +485,9 @@ class FirestoreApi {
485
485
  }
486
486
  return database;
487
487
  }
488
- async updateDatabase(project, databaseId, type, deleteProtectionState, pointInTimeRecoveryEnablement) {
488
+ async updateDatabase(project, databaseId, deleteProtectionState, pointInTimeRecoveryEnablement) {
489
489
  const url = `/projects/${project}/databases/${databaseId}`;
490
490
  const payload = {
491
- type,
492
491
  deleteProtectionState,
493
492
  pointInTimeRecoveryEnablement,
494
493
  };
@@ -241,6 +241,7 @@ function loadFirebaseEnvs(firebaseConfig, projectId) {
241
241
  return {
242
242
  FIREBASE_CONFIG: JSON.stringify(firebaseConfig),
243
243
  GCLOUD_PROJECT: projectId,
244
+ FIRESTORE_PREFER_REST: "true",
244
245
  };
245
246
  }
246
247
  exports.loadFirebaseEnvs = loadFirebaseEnvs;
@@ -304,7 +304,8 @@ function endpointFromFunction(gcfFunction) {
304
304
  else if (gcfFunction.eventTrigger) {
305
305
  const eventFilters = {};
306
306
  const eventFilterPathPatterns = {};
307
- if (gcfFunction.eventTrigger.pubsubTopic) {
307
+ if (gcfFunction.eventTrigger.pubsubTopic &&
308
+ gcfFunction.eventTrigger.eventType === v2_1.PUBSUB_PUBLISH_EVENT) {
308
309
  eventFilters.topic = gcfFunction.eventTrigger.pubsubTopic;
309
310
  }
310
311
  else {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createBuild = exports.getStack = exports.createStack = exports.API_VERSION = void 0;
3
+ exports.createBuild = exports.deleteBackend = exports.listBackends = exports.getBackend = exports.createStack = exports.API_VERSION = void 0;
4
4
  const apiv2_1 = require("../apiv2");
5
5
  const api_1 = require("../api");
6
6
  exports.API_VERSION = "v1alpha";
@@ -9,21 +9,32 @@ const client = new apiv2_1.Client({
9
9
  auth: true,
10
10
  apiVersion: exports.API_VERSION,
11
11
  });
12
- async function createStack(projectId, location, stackInput) {
13
- const stackId = stackInput.name;
14
- const res = await client.post(`projects/${projectId}/locations/${location}/stacks`, stackInput, { queryParams: { stackId } });
12
+ async function createStack(projectId, location, stackReqBoby, backendId) {
13
+ const res = await client.post(`projects/${projectId}/locations/${location}/backends`, stackReqBoby, { queryParams: { backendId } });
15
14
  return res.body;
16
15
  }
17
16
  exports.createStack = createStack;
18
- async function getStack(projectId, location, stackId) {
19
- const name = `projects/${projectId}/locations/${location}/stacks/${stackId}`;
17
+ async function getBackend(projectId, location, backendId) {
18
+ const name = `projects/${projectId}/locations/${location}/backends/${backendId}`;
20
19
  const res = await client.get(name);
21
20
  return res.body;
22
21
  }
23
- exports.getStack = getStack;
22
+ exports.getBackend = getBackend;
23
+ async function listBackends(projectId, location) {
24
+ const name = `projects/${projectId}/locations/${location}/backends`;
25
+ const res = await client.get(name);
26
+ return res.body;
27
+ }
28
+ exports.listBackends = listBackends;
29
+ async function deleteBackend(projectId, location, backendId) {
30
+ const name = `projects/${projectId}/locations/${location}/backends/${backendId}`;
31
+ const res = await client.delete(name);
32
+ return res.body;
33
+ }
34
+ exports.deleteBackend = deleteBackend;
24
35
  async function createBuild(projectId, location, stackId, buildInput) {
25
36
  const buildId = buildInput.name;
26
- const res = await client.post(`projects/${projectId}/locations/${location}/stacks/${stackId}/builds`, buildInput, { queryParams: { buildId } });
37
+ const res = await client.post(`projects/${projectId}/locations/${location}/backends/${stackId}/builds`, buildInput, { queryParams: { buildId } });
27
38
  return res.body;
28
39
  }
29
40
  exports.createBuild = createBuild;
@@ -217,7 +217,7 @@ async function getCleanDomains(project, site) {
217
217
  acc[current] = true;
218
218
  return acc;
219
219
  }, {});
220
- const siteMatch = new RegExp(`${site}--`, "i");
220
+ const siteMatch = new RegExp(`^${site}--`, "i");
221
221
  const firebaseAppMatch = new RegExp(/firebaseapp.com$/);
222
222
  const domains = await (0, auth_1.getAuthDomains)(project);
223
223
  const authDomains = [];
@@ -18,9 +18,7 @@ const frameworksPollerOptions = {
18
18
  masterTimeout: 25 * 60 * 1000,
19
19
  maxBackoff: 10000,
20
20
  };
21
- async function doSetup(setup) {
22
- var _a, _b;
23
- 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;
21
+ async function doSetup(setup, projectId) {
24
22
  setup.frameworks = {};
25
23
  utils.logBullet("First we need a few details to create your service.");
26
24
  await (0, prompt_1.promptOnce)({
@@ -46,12 +44,18 @@ async function doSetup(setup) {
46
44
  message: "How do you want to deploy",
47
45
  choices: constants_1.ALLOWED_DEPLOY_METHODS,
48
46
  }, setup.frameworks);
49
- await getOrCreateStack(projectId, setup);
47
+ const stack = await getOrCreateStack(projectId, setup);
48
+ if (stack) {
49
+ utils.logSuccess(`Successfully created a stack: ${stack.name}`);
50
+ }
50
51
  }
51
52
  exports.doSetup = doSetup;
52
- function toStack(cloudBuildConnRepo, stackId) {
53
+ function toStack(cloudBuildConnRepo) {
53
54
  return {
54
- name: stackId,
55
+ codebase: {
56
+ repository: `${cloudBuildConnRepo.name}`,
57
+ rootDirectory: "/",
58
+ },
55
59
  labels: {},
56
60
  };
57
61
  }
@@ -65,9 +69,9 @@ async function getOrCreateStack(projectId, setup) {
65
69
  if (err.status === 404) {
66
70
  logger_1.logger.info("Creating new stack.");
67
71
  if (deployMethod === "github") {
68
- const cloudBuildConnRepo = await repo.linkGitHubRepository(projectId, location, setup.frameworks.serviceName);
69
- const stackDetails = toStack(cloudBuildConnRepo, setup.frameworks.serviceName);
70
- return await createStack(projectId, location, stackDetails);
72
+ const cloudBuildConnRepo = await repo.linkGitHubRepository(projectId, location);
73
+ const stackDetails = toStack(cloudBuildConnRepo);
74
+ return await createStack(projectId, location, stackDetails, setup.frameworks.serviceName);
71
75
  }
72
76
  }
73
77
  else {
@@ -78,7 +82,7 @@ async function getOrCreateStack(projectId, setup) {
78
82
  }
79
83
  exports.getOrCreateStack = getOrCreateStack;
80
84
  async function getExistingStack(projectId, setup, location) {
81
- let stack = await gcp.getStack(projectId, location, setup.frameworks.serviceName);
85
+ let stack = await gcp.getBackend(projectId, location, setup.frameworks.serviceName);
82
86
  while (stack) {
83
87
  setup.frameworks.serviceName = undefined;
84
88
  await (0, prompt_1.promptOnce)({
@@ -97,14 +101,14 @@ async function getExistingStack(projectId, setup, location) {
97
101
  default: "acme-inc-web",
98
102
  message: "Please enter a new service name [1-30 characters]",
99
103
  }, setup.frameworks);
100
- stack = await gcp.getStack(projectId, location, setup.frameworks.serviceName);
104
+ stack = await gcp.getBackend(projectId, location, setup.frameworks.serviceName);
101
105
  setup.frameworks.existingStack = undefined;
102
106
  }
103
107
  return stack;
104
108
  }
105
- async function createStack(projectId, location, stackInput) {
106
- const op = await gcp.createStack(projectId, location, stackInput);
107
- const stack = await poller.pollOperation(Object.assign(Object.assign({}, frameworksPollerOptions), { pollerName: `create-${projectId}-${location}-${stackInput.name}`, operationResourceName: op.name }));
109
+ async function createStack(projectId, location, stackReqBoby, stackId) {
110
+ const op = await gcp.createStack(projectId, location, stackReqBoby, stackId);
111
+ const stack = await poller.pollOperation(Object.assign(Object.assign({}, frameworksPollerOptions), { pollerName: `create-${projectId}-${location}-${stackId}`, operationResourceName: op.name }));
108
112
  return stack;
109
113
  }
110
114
  exports.createStack = createStack;
@@ -21,11 +21,15 @@ function extractRepoSlugFromURI(remoteUri) {
21
21
  }
22
22
  return match[1];
23
23
  }
24
- function generateRepositoryId() {
25
- return `composer-repo`;
24
+ function generateRepositoryId(remoteUri) {
25
+ var _a;
26
+ return (_a = extractRepoSlugFromURI(remoteUri)) === null || _a === void 0 ? void 0 : _a.replaceAll("/", "-");
26
27
  }
27
- async function linkGitHubRepository(projectId, location, stackId) {
28
- const connectionId = stackId;
28
+ function generateConnectionId(location) {
29
+ return `frameworks-${location}`;
30
+ }
31
+ async function linkGitHubRepository(projectId, location) {
32
+ const connectionId = generateConnectionId(location);
29
33
  await getOrCreateConnection(projectId, location, connectionId);
30
34
  let remoteUri = await promptRepositoryURI(projectId, location, connectionId);
31
35
  while (remoteUri === "") {
@@ -92,7 +96,7 @@ async function getOrCreateConnection(projectId, location, connectionId) {
92
96
  }
93
97
  exports.getOrCreateConnection = getOrCreateConnection;
94
98
  async function getOrCreateRepository(projectId, location, connectionId, remoteUri) {
95
- const repositoryId = generateRepositoryId();
99
+ const repositoryId = generateRepositoryId(remoteUri);
96
100
  if (!repositoryId) {
97
101
  throw new error_1.FirebaseError(`Failed to generate repositoryId for URI "${remoteUri}".`);
98
102
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-tools",
3
- "version": "12.7.0",
3
+ "version": "12.8.1",
4
4
  "description": "Command-Line Interface for Firebase",
5
5
  "main": "./lib/index.js",
6
6
  "bin": {