firebase-tools 13.25.0 → 13.27.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 (69) hide show
  1. package/lib/appdistribution/client.js +62 -8
  2. package/lib/appdistribution/distribution.js +1 -1
  3. package/lib/apphosting/backend.js +4 -4
  4. package/lib/apphosting/config.js +86 -9
  5. package/lib/apphosting/secrets/index.js +5 -43
  6. package/lib/apphosting/yaml.js +3 -0
  7. package/lib/archiveDirectory.js +1 -1
  8. package/lib/auth.js +1 -1
  9. package/lib/command.js +9 -1
  10. package/lib/commands/appdistribution-distribute.js +4 -4
  11. package/lib/commands/{appdistribution-group-create.js → appdistribution-groups-create.js} +2 -1
  12. package/lib/commands/{appdistribution-group-delete.js → appdistribution-groups-delete.js} +3 -2
  13. package/lib/commands/appdistribution-groups-list.js +56 -0
  14. package/lib/commands/appdistribution-testers-list.js +54 -0
  15. package/lib/commands/appdistribution-testers-remove.js +1 -1
  16. package/lib/commands/apphosting-backends-delete.js +3 -1
  17. package/lib/commands/apphosting-backends-get.js +1 -1
  18. package/lib/commands/apphosting-config-export.js +4 -26
  19. package/lib/commands/database-import.js +4 -2
  20. package/lib/commands/database-push.js +4 -2
  21. package/lib/commands/database-set.js +4 -2
  22. package/lib/commands/database-settings-get.js +1 -1
  23. package/lib/commands/database-settings-set.js +1 -1
  24. package/lib/commands/ext-dev-init.js +2 -2
  25. package/lib/commands/ext-dev-list.js +1 -1
  26. package/lib/commands/ext-dev-register.js +2 -2
  27. package/lib/commands/ext-dev-upload.js +2 -2
  28. package/lib/commands/ext-dev-usage.js +2 -2
  29. package/lib/commands/ext-install.js +2 -2
  30. package/lib/commands/index.js +7 -6
  31. package/lib/commands/use.js +1 -1
  32. package/lib/deploy/extensions/deploy.js +3 -1
  33. package/lib/deploy/extensions/deploymentSummary.js +4 -1
  34. package/lib/deploy/extensions/planner.js +14 -3
  35. package/lib/deploy/extensions/prepare.js +9 -9
  36. package/lib/deploy/functions/ensure.js +1 -1
  37. package/lib/deploy/functions/release/fabricator.js +3 -3
  38. package/lib/deploy/lifecycleHooks.js +2 -1
  39. package/lib/emulator/apphosting/config.js +13 -3
  40. package/lib/emulator/apphosting/developmentServer.js +32 -0
  41. package/lib/emulator/apphosting/index.js +5 -3
  42. package/lib/emulator/apphosting/serve.js +15 -12
  43. package/lib/emulator/commandUtils.js +2 -1
  44. package/lib/emulator/controller.js +27 -18
  45. package/lib/emulator/dataconnect/pgliteServer.js +51 -18
  46. package/lib/emulator/dataconnectEmulator.js +26 -2
  47. package/lib/emulator/downloadableEmulators.js +11 -11
  48. package/lib/emulator/hub.js +26 -7
  49. package/lib/emulator/hubExport.js +23 -0
  50. package/lib/emulator/initEmulators.js +49 -0
  51. package/lib/emulator/types.js +2 -2
  52. package/lib/emulator/ui.js +47 -25
  53. package/lib/error.js +8 -1
  54. package/lib/gcp/cloudfunctionsv2.js +1 -0
  55. package/lib/getProjectNumber.js +1 -1
  56. package/lib/init/features/emulators.js +8 -0
  57. package/lib/init/features/project.js +7 -6
  58. package/lib/logger.js +2 -2
  59. package/lib/management/projects.js +24 -4
  60. package/lib/projectUtils.js +1 -1
  61. package/lib/requireDatabaseInstance.js +1 -1
  62. package/lib/requirePermissions.js +1 -1
  63. package/lib/rulesDeploy.js +1 -1
  64. package/lib/templates.js +2 -2
  65. package/lib/utils.js +20 -8
  66. package/lib/vsCodeUtils.js +8 -0
  67. package/package.json +2 -2
  68. package/schema/firebase-config.json +6 -0
  69. package/lib/emulator/apphosting/utils.js +0 -18
@@ -12,13 +12,13 @@ const OPTION_NO_PROJECT = "Don't set up a default project";
12
12
  const OPTION_USE_PROJECT = "Use an existing project";
13
13
  const OPTION_NEW_PROJECT = "Create a new project";
14
14
  const OPTION_ADD_FIREBASE = "Add Firebase to an existing Google Cloud Platform project";
15
- function toProjectInfo(projectMetaData) {
15
+ function toInitProjectInfo(projectMetaData) {
16
16
  const { projectId, displayName, resources } = projectMetaData;
17
17
  return {
18
18
  id: projectId,
19
19
  label: `${projectId}` + (displayName ? ` (${displayName})` : ""),
20
- instance: _.get(resources, "realtimeDatabaseInstance"),
21
- location: _.get(resources, "locationId"),
20
+ instance: resources === null || resources === void 0 ? void 0 : resources.realtimeDatabaseInstance,
21
+ location: resources === null || resources === void 0 ? void 0 : resources.locationId,
22
22
  };
23
23
  }
24
24
  async function promptAndCreateNewProject() {
@@ -65,18 +65,19 @@ async function projectChoicePrompt(options) {
65
65
  }
66
66
  }
67
67
  async function doSetup(setup, config, options) {
68
+ var _a, _b, _c;
68
69
  setup.project = {};
69
70
  logger_1.logger.info();
70
71
  logger_1.logger.info(`First, let's associate this project directory with a Firebase project.`);
71
72
  logger_1.logger.info(`You can create multiple project aliases by running ${clc.bold("firebase use --add")}, `);
72
73
  logger_1.logger.info(`but for now we'll just set up a default project.`);
73
74
  logger_1.logger.info();
74
- const projectFromRcFile = _.get(setup.rcfile, "projects.default");
75
+ const projectFromRcFile = (_b = (_a = setup.rcfile) === null || _a === void 0 ? void 0 : _a.projects) === null || _b === void 0 ? void 0 : _b.default;
75
76
  if (projectFromRcFile && !options.project) {
76
77
  utils.logBullet(`.firebaserc already has a default project, using ${projectFromRcFile}.`);
77
78
  const rcProject = await (0, projects_1.getFirebaseProject)(projectFromRcFile);
78
79
  setup.projectId = rcProject.projectId;
79
- setup.projectLocation = _.get(rcProject, "resources.locationId");
80
+ setup.projectLocation = (_c = rcProject === null || rcProject === void 0 ? void 0 : rcProject.resources) === null || _c === void 0 ? void 0 : _c.locationId;
80
81
  return;
81
82
  }
82
83
  let projectMetaData;
@@ -90,7 +91,7 @@ async function doSetup(setup, config, options) {
90
91
  return;
91
92
  }
92
93
  }
93
- const projectInfo = toProjectInfo(projectMetaData);
94
+ const projectInfo = toInitProjectInfo(projectMetaData);
94
95
  utils.logBullet(`Using project ${projectInfo.label}`);
95
96
  _.set(setup.rcfile, "projects.default", projectInfo.id);
96
97
  setup.projectId = projectInfo.id;
package/lib/logger.js CHANGED
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.logger = exports.vsceLogEmitter = void 0;
4
4
  const winston = require("winston");
5
- const utils_1 = require("./utils");
5
+ const vsCodeUtils_1 = require("./vsCodeUtils");
6
6
  const events_1 = require("events");
7
7
  exports.vsceLogEmitter = new events_1.EventEmitter();
8
8
  function expandErrors(logger) {
@@ -29,7 +29,7 @@ function annotateDebugLines(logger) {
29
29
  return logger;
30
30
  }
31
31
  function maybeUseVSCodeLogger(logger) {
32
- if (!(0, utils_1.isVSCodeExtension)()) {
32
+ if (!(0, vsCodeUtils_1.isVSCodeExtension)()) {
33
33
  return logger;
34
34
  }
35
35
  const oldLogFunc = logger.log.bind(logger);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getFirebaseProject = exports.listFirebaseProjects = exports.getAvailableCloudProjectPage = exports.getFirebaseProjectPage = exports.addFirebaseToCloudProject = exports.createCloudProject = exports.promptAvailableProjectId = exports.getOrPromptProject = exports.addFirebaseToCloudProjectAndLog = exports.createFirebaseProjectAndLog = exports.PROJECTS_CREATE_QUESTIONS = exports.ProjectParentResourceType = void 0;
3
+ exports.getProject = exports.getFirebaseProject = exports.listFirebaseProjects = exports.getAvailableCloudProjectPage = exports.getFirebaseProjectPage = exports.addFirebaseToCloudProject = exports.createCloudProject = exports.promptAvailableProjectId = exports.getOrPromptProject = exports.addFirebaseToCloudProjectAndLog = exports.createFirebaseProjectAndLog = exports.PROJECTS_CREATE_QUESTIONS = exports.ProjectParentResourceType = void 0;
4
4
  const clc = require("colorette");
5
5
  const ora = require("ora");
6
6
  const apiv2_1 = require("../apiv2");
@@ -39,6 +39,10 @@ const firebaseAPIClient = new apiv2_1.Client({
39
39
  auth: true,
40
40
  apiVersion: "v1beta1",
41
41
  });
42
+ const resourceManagerClient = new apiv2_1.Client({
43
+ urlPrefix: api.resourceManagerOrigin(),
44
+ apiVersion: "v1",
45
+ });
42
46
  async function createFirebaseProjectAndLog(projectId, options) {
43
47
  const spinner = ora("Creating Google Cloud Platform project").start();
44
48
  try {
@@ -78,7 +82,9 @@ function logNewFirebaseProjectInfo(projectInfo) {
78
82
  logger_1.logger.info("");
79
83
  logger_1.logger.info("Project information:");
80
84
  logger_1.logger.info(` - Project ID: ${clc.bold(projectInfo.projectId)}`);
81
- logger_1.logger.info(` - Project Name: ${clc.bold(projectInfo.displayName)}`);
85
+ if (projectInfo.displayName) {
86
+ logger_1.logger.info(` - Project Name: ${clc.bold(projectInfo.displayName)}`);
87
+ }
82
88
  logger_1.logger.info("");
83
89
  logger_1.logger.info("Firebase console is available at");
84
90
  logger_1.logger.info(`https://console.firebase.google.com/project/${clc.bold(projectInfo.projectId)}/overview`);
@@ -171,13 +177,12 @@ async function promptAvailableProjectId() {
171
177
  exports.promptAvailableProjectId = promptAvailableProjectId;
172
178
  async function createCloudProject(projectId, options) {
173
179
  try {
174
- const client = new apiv2_1.Client({ urlPrefix: api.resourceManagerOrigin(), apiVersion: "v1" });
175
180
  const data = {
176
181
  projectId,
177
182
  name: options.displayName || projectId,
178
183
  parent: options.parentResource,
179
184
  };
180
- const response = await client.request({
185
+ const response = await resourceManagerClient.request({
181
186
  method: "POST",
182
187
  path: "/projects",
183
188
  body: data,
@@ -300,6 +305,16 @@ async function getFirebaseProject(projectId) {
300
305
  return res.body;
301
306
  }
302
307
  catch (err) {
308
+ if ((0, error_1.getErrStatus)(err) === 404) {
309
+ try {
310
+ logger_1.logger.debug(`Couldn't get project info from firedata for ${projectId}, trying resource manager. Original error: ${err}`);
311
+ const info = await getProject(projectId);
312
+ return info;
313
+ }
314
+ catch (err) {
315
+ logger_1.logger.debug(`Unable to get project info from resourcemanager for ${projectId}: ${err}`);
316
+ }
317
+ }
303
318
  let message = err.message;
304
319
  if (err.original) {
305
320
  message += ` (original: ${err.original.message})`;
@@ -310,3 +325,8 @@ async function getFirebaseProject(projectId) {
310
325
  }
311
326
  }
312
327
  exports.getFirebaseProject = getFirebaseProject;
328
+ async function getProject(projectId) {
329
+ const response = await resourceManagerClient.get(`/projects/${projectId}`);
330
+ return response.body;
331
+ }
332
+ exports.getProject = getProject;
@@ -43,7 +43,7 @@ async function needProjectNumber(options) {
43
43
  return options.projectNumber;
44
44
  }
45
45
  const projectId = needProjectId(options);
46
- const metadata = await (0, projects_1.getFirebaseProject)(projectId);
46
+ const metadata = await (0, projects_1.getProject)(projectId);
47
47
  options.projectNumber = metadata.projectNumber;
48
48
  return options.projectNumber;
49
49
  }
@@ -15,7 +15,7 @@ async function requireDatabaseInstance(options) {
15
15
  }
16
16
  catch (err) {
17
17
  throw new error_1.FirebaseError(`Failed to get details for project: ${options.project}.`, {
18
- original: err,
18
+ original: (0, error_1.getError)(err),
19
19
  });
20
20
  }
21
21
  if (instance === "") {
@@ -23,7 +23,7 @@ async function requirePermissions(options, permissions = []) {
23
23
  }
24
24
  }
25
25
  catch (err) {
26
- logger_1.logger.debug(`[iam] error while checking permissions, command may fail: ${err}`);
26
+ logger_1.logger.debug(`[iam] error while checking permissions, command may fail: ${(0, error_1.getErrMsg)(err)}`);
27
27
  return;
28
28
  }
29
29
  }
@@ -113,7 +113,7 @@ class RulesDeploy {
113
113
  }
114
114
  }
115
115
  catch (err) {
116
- if (err.status !== QUOTA_EXCEEDED_STATUS_CODE) {
116
+ if ((0, error_1.getErrStatus)(err) !== QUOTA_EXCEEDED_STATUS_CODE) {
117
117
  throw err;
118
118
  }
119
119
  utils.logLabeledBullet(RulesetType[this.type], "quota exceeded error while uploading rules");
package/lib/templates.js CHANGED
@@ -4,10 +4,10 @@ exports.readTemplate = exports.readTemplateSync = exports.absoluteTemplateFilePa
4
4
  const fs_1 = require("fs");
5
5
  const promises_1 = require("fs/promises");
6
6
  const path_1 = require("path");
7
- const utils_1 = require("./utils");
7
+ const vsCodeUtils_1 = require("./vsCodeUtils");
8
8
  const TEMPLATE_ENCODING = "utf8";
9
9
  function absoluteTemplateFilePath(relPath) {
10
- if ((0, utils_1.isVSCodeExtension)()) {
10
+ if ((0, vsCodeUtils_1.isVSCodeExtension)()) {
11
11
  return (0, path_1.resolve)(__dirname, "templates", relPath);
12
12
  }
13
13
  return (0, path_1.resolve)(__dirname, "../templates", relPath);
package/lib/utils.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.connectableHostname = exports.randomInt = exports.debounce = exports.last = exports.cloneDeep = exports.groupBy = exports.assertIsStringOrUndefined = exports.assertIsNumber = exports.assertIsString = exports.thirtyDaysFromNow = exports.isRunningInWSL = exports.isVSCodeExtension = exports.isCloudEnvironment = exports.datetimeString = exports.createDestroyer = exports.sleep = exports.promiseWithSpinner = exports.setupLoggers = exports.tryParse = exports.tryStringify = exports.promiseProps = exports.withTimeout = exports.promiseWhile = exports.promiseAllSettled = exports.getFunctionsEventProvider = exports.endpoint = exports.makeActiveProject = exports.streamToString = exports.stringToStream = exports.explainStdin = exports.allSettled = exports.reject = exports.logLabeledError = exports.logLabeledWarning = exports.logWarning = exports.logLabeledBullet = exports.logBullet = exports.logLabeledSuccess = exports.logSuccess = exports.addSubdomain = exports.addDatabaseNamespace = exports.getDatabaseViewDataUrl = exports.getDatabaseUrl = exports.envOverride = exports.setVSCodeEnvVars = exports.getInheritedOption = exports.consoleUrl = exports.vscodeEnvVars = exports.envOverrides = exports.IS_WINDOWS = void 0;
4
- exports.readSecretValue = exports.generateId = exports.wrappedSafeLoad = exports.readFileFromDirectory = exports.getHostnameFromUrl = exports.openInBrowserPopup = exports.openInBrowser = void 0;
3
+ exports.openInBrowser = exports.connectableHostname = exports.randomInt = exports.debounce = exports.last = exports.cloneDeep = exports.groupBy = exports.assertIsStringOrUndefined = exports.assertIsNumber = exports.assertIsString = exports.thirtyDaysFromNow = exports.isRunningInWSL = exports.isCloudEnvironment = exports.datetimeString = exports.createDestroyer = exports.sleep = exports.promiseWithSpinner = exports.setupLoggers = exports.tryParse = exports.tryStringify = exports.promiseProps = exports.withTimeout = exports.promiseWhile = exports.promiseAllSettled = exports.getFunctionsEventProvider = exports.endpoint = exports.makeActiveProject = exports.streamToString = exports.stringToStream = exports.explainStdin = exports.allSettled = exports.reject = exports.logLabeledError = exports.logLabeledWarning = exports.logWarning = exports.logLabeledBullet = exports.logBullet = exports.logLabeledSuccess = exports.logSuccess = exports.addSubdomain = exports.addDatabaseNamespace = exports.getDatabaseViewDataUrl = exports.getDatabaseUrl = exports.envOverride = exports.setVSCodeEnvVars = exports.getInheritedOption = exports.consoleUrl = exports.vscodeEnvVars = exports.envOverrides = exports.IS_WINDOWS = void 0;
4
+ exports.updateOrCreateGitignore = exports.readSecretValue = exports.generateId = exports.wrappedSafeLoad = exports.readFileFromDirectory = exports.getHostnameFromUrl = exports.openInBrowserPopup = void 0;
5
5
  const fs = require("fs-extra");
6
6
  const tty = require("tty");
7
7
  const path = require("node:path");
@@ -24,6 +24,7 @@ const error_1 = require("./error");
24
24
  const logger_1 = require("./logger");
25
25
  const prompt_1 = require("./prompt");
26
26
  const templates_1 = require("./templates");
27
+ const vsCodeUtils_1 = require("./vsCodeUtils");
27
28
  exports.IS_WINDOWS = process.platform === "win32";
28
29
  const SUCCESS_CHAR = exports.IS_WINDOWS ? "+" : "✔";
29
30
  const WARNING_CHAR = exports.IS_WINDOWS ? "!" : "⚠";
@@ -51,7 +52,7 @@ function setVSCodeEnvVars(envVar, value) {
51
52
  }
52
53
  exports.setVSCodeEnvVars = setVSCodeEnvVars;
53
54
  function envOverride(envname, value, coerce) {
54
- const currentEnvValue = isVSCodeExtension() && exports.vscodeEnvVars[envname] ? exports.vscodeEnvVars[envname] : process.env[envname];
55
+ const currentEnvValue = (0, vsCodeUtils_1.isVSCodeExtension)() && exports.vscodeEnvVars[envname] ? exports.vscodeEnvVars[envname] : process.env[envname];
55
56
  if (currentEnvValue && currentEnvValue.length) {
56
57
  exports.envOverrides.push(envname);
57
58
  if (coerce) {
@@ -385,10 +386,6 @@ function isCloudEnvironment() {
385
386
  return !!process.env.CODESPACES || !!process.env.GOOGLE_CLOUD_WORKSTATIONS;
386
387
  }
387
388
  exports.isCloudEnvironment = isCloudEnvironment;
388
- function isVSCodeExtension() {
389
- return !!process.env.VSCODE_CWD;
390
- }
391
- exports.isVSCodeExtension = isVSCodeExtension;
392
389
  function isRunningInWSL() {
393
390
  return !!process.env.WSL_DISTRO_NAME;
394
391
  }
@@ -563,7 +560,7 @@ function wrappedSafeLoad(source) {
563
560
  return yaml.parse(source);
564
561
  }
565
562
  catch (err) {
566
- throw new error_1.FirebaseError(`YAML Error: ${err.message}`, { original: err });
563
+ throw new error_1.FirebaseError(`YAML Error: ${(0, error_1.getErrMsg)(err)}`, { original: (0, error_1.getError)(err) });
567
564
  }
568
565
  }
569
566
  exports.wrappedSafeLoad = wrappedSafeLoad;
@@ -600,3 +597,18 @@ function readSecretValue(prompt, dataFile) {
600
597
  }
601
598
  }
602
599
  exports.readSecretValue = readSecretValue;
600
+ function updateOrCreateGitignore(dirPath, entries) {
601
+ const gitignorePath = path.join(dirPath, ".gitignore");
602
+ if (!fs.existsSync(gitignorePath)) {
603
+ fs.writeFileSync(gitignorePath, entries.join("\n"));
604
+ return;
605
+ }
606
+ let content = fs.readFileSync(gitignorePath, "utf-8");
607
+ for (const entry of entries) {
608
+ if (!content.includes(entry)) {
609
+ content += `\n${entry}\n`;
610
+ }
611
+ }
612
+ fs.writeFileSync(gitignorePath, content);
613
+ }
614
+ exports.updateOrCreateGitignore = updateOrCreateGitignore;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isVSCodeExtension = void 0;
4
+ const process_1 = require("process");
5
+ function isVSCodeExtension() {
6
+ return !!process_1.env.VSCODE_CWD;
7
+ }
8
+ exports.isVSCodeExtension = isVSCodeExtension;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-tools",
3
- "version": "13.25.0",
3
+ "version": "13.27.0",
4
4
  "description": "Command-Line Interface for Firebase",
5
5
  "main": "./lib/index.js",
6
6
  "bin": {
@@ -72,7 +72,7 @@
72
72
  "cjson": "^0.3.1",
73
73
  "cli-table": "0.3.11",
74
74
  "colorette": "^2.0.19",
75
- "commander": "^4.0.1",
75
+ "commander": "^5.1.0",
76
76
  "configstore": "^5.0.1",
77
77
  "cors": "^2.8.5",
78
78
  "cross-env": "^5.1.3",
@@ -366,6 +366,9 @@
366
366
  "port": {
367
367
  "type": "number"
368
368
  },
369
+ "rootDirectory": {
370
+ "type": "string"
371
+ },
369
372
  "startCommandOverride": {
370
373
  "type": "string"
371
374
  }
@@ -399,6 +402,9 @@
399
402
  "dataconnect": {
400
403
  "additionalProperties": false,
401
404
  "properties": {
405
+ "dataDir": {
406
+ "type": "string"
407
+ },
402
408
  "host": {
403
409
  "type": "string"
404
410
  },
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.discoverPackageManager = exports.logger = void 0;
4
- const fs_extra_1 = require("fs-extra");
5
- const path_1 = require("path");
6
- const emulatorLogger_1 = require("../emulatorLogger");
7
- const types_1 = require("../types");
8
- exports.logger = emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.APPHOSTING);
9
- async function discoverPackageManager(rootdir) {
10
- if (await (0, fs_extra_1.pathExists)((0, path_1.join)(rootdir, "pnpm-lock.yaml"))) {
11
- return "pnpm";
12
- }
13
- if (await (0, fs_extra_1.pathExists)((0, path_1.join)(rootdir, "yarn.lock"))) {
14
- return "yarn";
15
- }
16
- return "npm";
17
- }
18
- exports.discoverPackageManager = discoverPackageManager;