firebase-tools 11.14.1 → 11.14.3-canary.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 (66) hide show
  1. package/lib/bin/firebase.js +3 -3
  2. package/lib/commands/deploy.js +3 -3
  3. package/lib/commands/emulators-start.js +20 -16
  4. package/lib/deploy/functions/params.js +9 -1
  5. package/lib/deploy/functions/release/fabricator.js +1 -0
  6. package/lib/deploy/hosting/convertConfig.js +5 -4
  7. package/lib/deploy/hosting/release.js +6 -2
  8. package/lib/deploy/index.js +10 -0
  9. package/lib/emulator/ExpressBasedEmulator.js +92 -0
  10. package/lib/emulator/auth/cloudFunctions.js +3 -12
  11. package/lib/emulator/auth/index.js +2 -2
  12. package/lib/emulator/auth/utils.js +1 -1
  13. package/lib/emulator/commandUtils.js +21 -44
  14. package/lib/emulator/constants.js +3 -10
  15. package/lib/emulator/controller.js +129 -130
  16. package/lib/emulator/databaseEmulator.js +3 -8
  17. package/lib/emulator/dns.js +49 -0
  18. package/lib/emulator/downloadableEmulators.js +19 -13
  19. package/lib/emulator/emulatorLogger.js +14 -7
  20. package/lib/emulator/env.js +35 -0
  21. package/lib/emulator/eventarcEmulator.js +2 -8
  22. package/lib/emulator/extensions/postinstall.js +8 -8
  23. package/lib/emulator/extensionsEmulator.js +7 -7
  24. package/lib/emulator/firestoreEmulator.js +3 -11
  25. package/lib/emulator/functionsEmulator.js +24 -60
  26. package/lib/emulator/functionsEmulatorShared.js +5 -3
  27. package/lib/emulator/functionsEmulatorShell.js +1 -1
  28. package/lib/emulator/hostingEmulator.js +7 -2
  29. package/lib/emulator/hub.js +50 -58
  30. package/lib/emulator/hubClient.js +24 -10
  31. package/lib/emulator/hubExport.js +3 -11
  32. package/lib/emulator/portUtils.js +228 -29
  33. package/lib/emulator/pubsubEmulator.js +11 -12
  34. package/lib/emulator/registry.js +11 -20
  35. package/lib/emulator/storage/apis/gcloud.js +3 -6
  36. package/lib/emulator/storage/cloudFunctions.js +2 -7
  37. package/lib/emulator/storage/metadata.js +11 -5
  38. package/lib/emulator/storage/rules/runtime.js +1 -6
  39. package/lib/emulator/ui.js +6 -7
  40. package/lib/experiments.js +10 -1
  41. package/lib/extensions/displayExtensionInfo.js +43 -6
  42. package/lib/extensions/secretsUtils.js +2 -1
  43. package/lib/frameworks/angular/index.js +1 -1
  44. package/lib/frameworks/express/index.js +1 -1
  45. package/lib/frameworks/index.js +33 -17
  46. package/lib/frameworks/next/index.js +2 -2
  47. package/lib/frameworks/nuxt/index.js +1 -1
  48. package/lib/frameworks/vite/index.js +1 -1
  49. package/lib/functions/ensureTargeted.js +21 -0
  50. package/lib/functions/env.js +33 -19
  51. package/lib/functionsShellCommandAction.js +12 -5
  52. package/lib/gcp/cloudfunctions.js +1 -0
  53. package/lib/gcp/run.js +0 -1
  54. package/lib/handlePreviewToggles.js +2 -2
  55. package/lib/hosting/api.js +2 -6
  56. package/lib/hosting/functionsProxy.js +2 -3
  57. package/lib/hosting/implicitInit.js +2 -11
  58. package/lib/hosting/runTags.js +3 -4
  59. package/lib/serve/functions.js +8 -10
  60. package/lib/serve/hosting.js +35 -37
  61. package/lib/serve/index.js +2 -2
  62. package/lib/utils.js +14 -1
  63. package/npm-shrinkwrap.json +2 -2
  64. package/package.json +1 -1
  65. package/templates/hosting/init.js +3 -2
  66. package/lib/emulator/emulatorServer.js +0 -29
@@ -74,7 +74,9 @@ if (utils.envOverrides.length) {
74
74
  }
75
75
  logger_1.logger.debug("-".repeat(70));
76
76
  logger_1.logger.debug();
77
+ const experiments_1 = require("../experiments");
77
78
  const fetchMOTD_1 = require("../fetchMOTD");
79
+ (0, experiments_1.enableExperimentsFromCliEnvVariable)();
78
80
  (0, fetchMOTD_1.fetchMOTD)();
79
81
  process.on("exit", (code) => {
80
82
  code = process.exitCode || code;
@@ -123,9 +125,7 @@ process.on("uncaughtException", (err) => {
123
125
  });
124
126
  if (!(0, handlePreviewToggles_1.handlePreviewToggles)(args)) {
125
127
  cmd = client.cli.parse(process.argv);
126
- args = args.filter((arg) => {
127
- return arg.indexOf("-") < 0;
128
- });
128
+ args = args.filter((arg) => !arg.includes("-"));
129
129
  if (!args.length) {
130
130
  client.cli.help();
131
131
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.command = exports.VALID_DEPLOY_TARGETS = void 0;
3
+ exports.command = exports.TARGET_PERMISSIONS = exports.VALID_DEPLOY_TARGETS = void 0;
4
4
  const requireDatabaseInstance_1 = require("../requireDatabaseInstance");
5
5
  const requirePermissions_1 = require("../requirePermissions");
6
6
  const checkIam_1 = require("../deploy/functions/checkIam");
@@ -19,7 +19,7 @@ exports.VALID_DEPLOY_TARGETS = [
19
19
  "remoteconfig",
20
20
  "extensions",
21
21
  ];
22
- const TARGET_PERMISSIONS = {
22
+ exports.TARGET_PERMISSIONS = {
23
23
  database: ["firebasedatabase.instances.update"],
24
24
  hosting: ["firebasehosting.sites.update"],
25
25
  functions: [
@@ -57,7 +57,7 @@ exports.command = new command_1.Command("deploy")
57
57
  .before((options) => {
58
58
  options.filteredTargets = (0, filterTargets_1.filterTargets)(options, exports.VALID_DEPLOY_TARGETS);
59
59
  const permissions = options.filteredTargets.reduce((perms, target) => {
60
- return perms.concat(TARGET_PERMISSIONS[target]);
60
+ return perms.concat(exports.TARGET_PERMISSIONS[target]);
61
61
  }, []);
62
62
  return (0, requirePermissions_1.requirePermissions)(options, permissions);
63
63
  })
@@ -56,17 +56,15 @@ function printEmulatorOverview(options) {
56
56
  });
57
57
  }
58
58
  const reservedPortsString = reservedPorts.length > 0 ? reservedPorts.join(", ") : "None";
59
- const uiInfo = registry_1.EmulatorRegistry.getInfo(types_1.Emulators.UI);
60
- const hubInfo = registry_1.EmulatorRegistry.getInfo(types_1.Emulators.HUB);
61
- const uiUrl = uiInfo ? `http://${registry_1.EmulatorRegistry.getInfoHostString(uiInfo)}` : "unknown";
59
+ const uiRunning = registry_1.EmulatorRegistry.isRunning(types_1.Emulators.UI);
62
60
  const head = ["Emulator", "Host:Port"];
63
- if (uiInfo) {
61
+ if (uiRunning) {
64
62
  head.push(`View in ${constants_1.Constants.description(types_1.Emulators.UI)}`);
65
63
  }
66
64
  const successMessageTable = new Table();
67
65
  let successMsg = `${clc.green("✔")} ${clc.bold("All emulators ready! It is now safe to connect your app.")}`;
68
- if (uiInfo) {
69
- successMsg += `\n${clc.cyan("i")} View Emulator UI at ${stylizeLink(uiUrl)}`;
66
+ if (uiRunning) {
67
+ successMsg += `\n${clc.cyan("i")} View Emulator UI at ${stylizeLink(registry_1.EmulatorRegistry.url(types_1.Emulators.UI).toString())}`;
70
68
  }
71
69
  successMessageTable.push([successMsg]);
72
70
  const emulatorsTable = new Table({
@@ -80,15 +78,21 @@ function printEmulatorOverview(options) {
80
78
  .map((emulator) => {
81
79
  const emulatorName = constants_1.Constants.description(emulator).replace(/ emulator/i, "");
82
80
  const isSupportedByUi = types_1.EMULATORS_SUPPORTED_BY_UI.includes(emulator);
83
- const info = registry_1.EmulatorRegistry.getInfo(emulator);
84
- if (!info) {
85
- return [emulatorName, "Failed to initialize (see above)", "", ""];
81
+ const listen = commandUtils.getListenOverview(emulator);
82
+ if (!listen) {
83
+ const row = [emulatorName, "Failed to initialize (see above)"];
84
+ if (uiRunning) {
85
+ row.push("");
86
+ }
87
+ return row;
88
+ }
89
+ let uiLink = "n/a";
90
+ if (isSupportedByUi && uiRunning) {
91
+ const url = registry_1.EmulatorRegistry.url(types_1.Emulators.UI);
92
+ url.pathname = `/${emulator}`;
93
+ uiLink = stylizeLink(url.toString());
86
94
  }
87
- return [
88
- emulatorName,
89
- registry_1.EmulatorRegistry.getInfoHostString(info),
90
- isSupportedByUi && uiInfo ? stylizeLink(`${uiUrl}/${emulator}`) : clc.blackBright("n/a"),
91
- ];
95
+ return [emulatorName, listen, uiLink];
92
96
  })
93
97
  .map((col) => col.slice(0, head.length))
94
98
  .filter((v) => v));
@@ -100,8 +104,8 @@ function printEmulatorOverview(options) {
100
104
  logger_1.logger.info(`\n${successMessageTable}
101
105
 
102
106
  ${emulatorsTable}
103
- ${hubInfo
104
- ? clc.blackBright(" Emulator Hub running at ") + registry_1.EmulatorRegistry.getInfoHostString(hubInfo)
107
+ ${registry_1.EmulatorRegistry.isRunning(types_1.Emulators.HUB)
108
+ ? clc.blackBright(" Emulator Hub running at ") + registry_1.EmulatorRegistry.url(types_1.Emulators.HUB).host
105
109
  : clc.blackBright(" Emulator Hub not running.")}
106
110
  ${clc.blackBright(" Other reserved ports:")} ${reservedPortsString}
107
111
  ${extensionsTable}
@@ -176,7 +176,15 @@ function populateDefaultParams(config) {
176
176
  async function handleSecret(secretParam, projectId) {
177
177
  const metadata = await secretManager.getSecretMetadata(projectId, secretParam.name, "latest");
178
178
  if (!metadata.secret) {
179
- throw new error_1.FirebaseError(`Your project currently doesn't have any secret named ${secretParam.name}. Create one by running firebase functions:secrets:set ${secretParam.name} command and try the deploy again.`);
179
+ const secretValue = await (0, prompt_1.promptOnce)({
180
+ name: secretParam.name,
181
+ type: "password",
182
+ message: `This secret will be stored in Cloud Secret Manager (https://cloud.google.com/secret-manager/pricing) as ${secretParam.name}. Enter a value for ${secretParam.label || secretParam.name}:`,
183
+ });
184
+ const secretLabel = { "firebase-hosting-managed": "yes" };
185
+ await secretManager.createSecret(projectId, secretParam.name, secretLabel);
186
+ await secretManager.addVersion(projectId, secretParam.name, secretValue);
187
+ return secretValue;
180
188
  }
181
189
  else if (!metadata.secretVersion) {
182
190
  throw new error_1.FirebaseError(`Cloud Secret Manager has no latest version of the secret defined by param ${secretParam.label || secretParam.name}`);
@@ -414,6 +414,7 @@ class Fabricator {
414
414
  logger_1.logger.debug("Skipping setRunTraits on", serviceName, " because it already matches");
415
415
  return;
416
416
  }
417
+ delete service.spec.template.metadata.name;
417
418
  await run.updateService(serviceName, service);
418
419
  })
419
420
  .catch(rethrowAs(endpoint, "set concurrency"));
@@ -70,9 +70,9 @@ async function convertConfig(context, deploy) {
70
70
  if (err.status === 403) {
71
71
  logger_1.logger.debug(`Deploying hosting site ${deploy.config.site}, did not have permissions to check for backends: `, err);
72
72
  }
73
- else {
74
- throw err;
75
- }
73
+ }
74
+ else {
75
+ throw err;
76
76
  }
77
77
  }
78
78
  }
@@ -131,7 +131,8 @@ async function convertConfig(context, deploy) {
131
131
  (0, functional_1.assertExhaustive)(rewrite);
132
132
  });
133
133
  if (config.rewrites) {
134
- await runTags.setRewriteTags(config.rewrites, context.projectId, deploy.version);
134
+ const versionId = (0, utils_1.last)(deploy.version.split("/"));
135
+ await runTags.setRewriteTags(config.rewrites, context.projectId, versionId);
135
136
  }
136
137
  config.redirects = (_c = deploy.config.redirects) === null || _c === void 0 ? void 0 : _c.map((redirect) => {
137
138
  const apiRedirect = Object.assign(Object.assign({}, extractPattern("redirect", redirect)), { location: redirect.destination });
@@ -6,7 +6,7 @@ const logger_1 = require("../../logger");
6
6
  const utils = require("../../utils");
7
7
  const convertConfig_1 = require("./convertConfig");
8
8
  const error_1 = require("../../error");
9
- async function release(context) {
9
+ async function release(context, options) {
10
10
  if (!context.hosting || !context.hosting.deploys) {
11
11
  return;
12
12
  }
@@ -28,7 +28,11 @@ async function release(context) {
28
28
  if (context.hostingChannel) {
29
29
  logger_1.logger.debug("[hosting] releasing to channel:", context.hostingChannel);
30
30
  }
31
- const release = await api.createRelease(deploy.config.site, context.hostingChannel || "live", deploy.version);
31
+ const otherReleaseOpts = {};
32
+ if (options.message) {
33
+ otherReleaseOpts.message = options.message;
34
+ }
35
+ const release = await api.createRelease(deploy.config.site, context.hostingChannel || "live", deploy.version, otherReleaseOpts);
32
36
  logger_1.logger.debug("[hosting] release:", release);
33
37
  utils.logLabeledSuccess(`hosting[${deploy.config.site}]`, "release complete");
34
38
  }));
@@ -19,6 +19,8 @@ const StorageTarget = require("./storage");
19
19
  const RemoteConfigTarget = require("./remoteconfig");
20
20
  const ExtensionsTarget = require("./extensions");
21
21
  const frameworks_1 = require("../frameworks");
22
+ const requirePermissions_1 = require("../requirePermissions");
23
+ const deploy_1 = require("../commands/deploy");
22
24
  const TARGETS = {
23
25
  hosting: HostingTarget,
24
26
  database: DatabaseTarget,
@@ -47,7 +49,15 @@ const deploy = async function (targetNames, options, customContext = {}) {
47
49
  const config = options.config.get("hosting");
48
50
  if (Array.isArray(config) ? config.some((it) => it.source) : config.source) {
49
51
  experiments.assertEnabled("webframeworks", "deploy a web framework to hosting");
52
+ const usedToTargetFunctions = targetNames.includes("functions");
50
53
  await (0, frameworks_1.prepareFrameworks)(targetNames, context, options);
54
+ const nowTargetsFunctions = targetNames.includes("functions");
55
+ if (nowTargetsFunctions && !usedToTargetFunctions) {
56
+ if (context.hostingChannel && !experiments.isEnabled("pintags")) {
57
+ throw new error_1.FirebaseError("Web frameworks with dynamic content do not yet support deploying to preview channels");
58
+ }
59
+ await (0, requirePermissions_1.requirePermissions)(deploy_1.TARGET_PERMISSIONS["functions"]);
60
+ }
51
61
  }
52
62
  }
53
63
  for (const targetName of targetNames) {
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExpressBasedEmulator = void 0;
4
+ const cors = require("cors");
5
+ const express = require("express");
6
+ const bodyParser = require("body-parser");
7
+ const utils = require("../utils");
8
+ const node_http_1 = require("node:http");
9
+ const dns_1 = require("./dns");
10
+ class ExpressBasedEmulator {
11
+ constructor(options) {
12
+ this.options = options;
13
+ this.destroyers = new Set();
14
+ }
15
+ createExpressApp() {
16
+ const app = express();
17
+ if (!this.options.noCors) {
18
+ app.use(cors({ origin: true }));
19
+ app.use((req, res, next) => {
20
+ if (req.headers["access-control-request-private-network"]) {
21
+ res.setHeader("access-control-allow-private-network", "true");
22
+ }
23
+ next();
24
+ });
25
+ }
26
+ if (!this.options.noBodyParser) {
27
+ app.use(bodyParser.json());
28
+ }
29
+ app.set("json spaces", 2);
30
+ return Promise.resolve(app);
31
+ }
32
+ async start() {
33
+ const app = await this.createExpressApp();
34
+ const promises = [];
35
+ const specs = this.options.listen;
36
+ for (const opt of ExpressBasedEmulator.listenOptionsFromSpecs(specs)) {
37
+ promises.push(new Promise((resolve, reject) => {
38
+ const server = (0, node_http_1.createServer)(app).listen(opt);
39
+ server.once("listening", resolve);
40
+ server.once("error", reject);
41
+ this.destroyers.add(utils.createDestroyer(server));
42
+ }));
43
+ }
44
+ }
45
+ static listenOptionsFromSpecs(specs) {
46
+ const listenOptions = [];
47
+ const dualStackPorts = new Set();
48
+ for (const spec of specs) {
49
+ if (spec.address === dns_1.IPV6_UNSPECIFIED.address) {
50
+ if (specs.some((s) => s.port === spec.port && s.address === dns_1.IPV4_UNSPECIFIED.address)) {
51
+ listenOptions.push({
52
+ port: spec.port,
53
+ ipv6Only: false,
54
+ });
55
+ dualStackPorts.add(spec.port);
56
+ }
57
+ }
58
+ }
59
+ for (const spec of specs) {
60
+ if (!dualStackPorts.has(spec.port)) {
61
+ listenOptions.push({
62
+ host: spec.address,
63
+ port: spec.port,
64
+ ipv6Only: spec.family === "IPv6",
65
+ });
66
+ }
67
+ }
68
+ return listenOptions;
69
+ }
70
+ async connect() {
71
+ }
72
+ async stop() {
73
+ const promises = [];
74
+ for (const destroyer of this.destroyers) {
75
+ promises.push(destroyer().then(() => this.destroyers.delete(destroyer)));
76
+ }
77
+ await Promise.all(promises);
78
+ }
79
+ getInfo() {
80
+ return {
81
+ name: this.getName(),
82
+ listen: this.options.listen,
83
+ host: this.options.listen[0].address,
84
+ port: this.options.listen[0].port,
85
+ };
86
+ }
87
+ }
88
+ exports.ExpressBasedEmulator = ExpressBasedEmulator;
89
+ ExpressBasedEmulator.PATH_EXPORT = "/_admin/export";
90
+ ExpressBasedEmulator.PATH_DISABLE_FUNCTIONS = "/functions/disableBackgroundTriggers";
91
+ ExpressBasedEmulator.PATH_ENABLE_FUNCTIONS = "/functions/enableBackgroundTriggers";
92
+ ExpressBasedEmulator.PATH_EMULATORS = "/emulators";
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AuthCloudFunction = void 0;
4
4
  const uuid = require("uuid");
5
- const apiv2_1 = require("../../apiv2");
6
5
  const types_1 = require("../types");
7
6
  const emulatorLogger_1 = require("../emulatorLogger");
8
7
  const registry_1 = require("../registry");
@@ -10,27 +9,19 @@ class AuthCloudFunction {
10
9
  constructor(projectId) {
11
10
  this.projectId = projectId;
12
11
  this.logger = emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.AUTH);
13
- this.multicastOrigin = "";
14
- this.multicastPath = "";
15
12
  this.enabled = false;
16
- const functionsEmulator = registry_1.EmulatorRegistry.get(types_1.Emulators.FUNCTIONS);
17
- if (functionsEmulator) {
18
- this.enabled = true;
19
- this.functionsEmulatorInfo = functionsEmulator.getInfo();
20
- this.multicastOrigin = `http://${registry_1.EmulatorRegistry.getInfoHostString(this.functionsEmulatorInfo)}`;
21
- this.multicastPath = `/functions/projects/${projectId}/trigger_multicast`;
22
- }
13
+ this.enabled = registry_1.EmulatorRegistry.isRunning(types_1.Emulators.FUNCTIONS);
23
14
  }
24
15
  async dispatch(action, user) {
25
16
  if (!this.enabled)
26
17
  return;
27
18
  const userInfoPayload = this.createUserInfoPayload(user);
28
19
  const multicastEventBody = this.createEventRequestBody(action, userInfoPayload);
29
- const c = new apiv2_1.Client({ urlPrefix: this.multicastOrigin, auth: false });
20
+ const c = registry_1.EmulatorRegistry.client(types_1.Emulators.FUNCTIONS);
30
21
  let res;
31
22
  let err;
32
23
  try {
33
- res = await c.post(this.multicastPath, multicastEventBody);
24
+ res = await c.post(`/functions/projects/${this.projectId}/trigger_multicast`, multicastEventBody);
34
25
  }
35
26
  catch (e) {
36
27
  err = e;
@@ -57,7 +57,7 @@ class AuthEmulator {
57
57
  logger.logLabeled("BULLET", "auth", `Importing config from ${configPath}`);
58
58
  await importFromFile({
59
59
  method: "PATCH",
60
- host,
60
+ host: utils.connectableHostname(host),
61
61
  port,
62
62
  path: `/emulator/v1/projects/${projectId}/config`,
63
63
  headers: {
@@ -75,7 +75,7 @@ class AuthEmulator {
75
75
  logger.logLabeled("BULLET", "auth", `Importing accounts from ${accountsPath}`);
76
76
  await importFromFile({
77
77
  method: "POST",
78
- host,
78
+ host: utils.connectableHostname(host),
79
79
  port,
80
80
  path: `/identitytoolkit.googleapis.com/v1/projects/${projectId}/accounts:batchCreate`,
81
81
  headers: {
@@ -64,7 +64,7 @@ function logError(err) {
64
64
  }
65
65
  exports.logError = logError;
66
66
  function authEmulatorUrl(req) {
67
- if (registry_1.EmulatorRegistry.getInfo(types_1.Emulators.AUTH)) {
67
+ if (registry_1.EmulatorRegistry.isRunning(types_1.Emulators.AUTH)) {
68
68
  return registry_1.EmulatorRegistry.url(types_1.Emulators.AUTH);
69
69
  }
70
70
  else {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.JAVA_DEPRECATION_WARNING = exports.MIN_SUPPORTED_JAVA_MAJOR_VERSION = exports.checkJavaMajorVersion = exports.emulatorExec = exports.shutdownWhenKilled = exports.setExportOnExitOptions = exports.parseInspectionPort = exports.beforeEmulatorCommand = exports.warnEmulatorNotSupported = exports.printNoticeIfEmulated = exports.DESC_TEST_PARAMS = exports.FLAG_TEST_PARAMS = exports.DESC_TEST_CONFIG = exports.FLAG_TEST_CONFIG = exports.DESC_UI = exports.FLAG_UI = exports.EXPORT_ON_EXIT_CWD_DANGER = exports.EXPORT_ON_EXIT_USAGE_ERROR = exports.DESC_EXPORT_ON_EXIT = exports.FLAG_EXPORT_ON_EXIT = exports.FLAG_EXPORT_ON_EXIT_NAME = exports.DESC_IMPORT = exports.FLAG_IMPORT = exports.DESC_INSPECT_FUNCTIONS = exports.FLAG_INSPECT_FUNCTIONS = exports.DESC_ONLY = exports.FLAG_ONLY = void 0;
3
+ exports.JAVA_DEPRECATION_WARNING = exports.MIN_SUPPORTED_JAVA_MAJOR_VERSION = exports.checkJavaMajorVersion = exports.emulatorExec = exports.getListenOverview = exports.shutdownWhenKilled = exports.setExportOnExitOptions = exports.parseInspectionPort = exports.beforeEmulatorCommand = exports.warnEmulatorNotSupported = exports.printNoticeIfEmulated = exports.DESC_TEST_PARAMS = exports.FLAG_TEST_PARAMS = exports.DESC_TEST_CONFIG = exports.FLAG_TEST_CONFIG = exports.DESC_UI = exports.FLAG_UI = exports.EXPORT_ON_EXIT_CWD_DANGER = exports.EXPORT_ON_EXIT_USAGE_ERROR = exports.DESC_EXPORT_ON_EXIT = exports.FLAG_EXPORT_ON_EXIT = exports.FLAG_EXPORT_ON_EXIT_NAME = exports.DESC_IMPORT = exports.FLAG_IMPORT = exports.DESC_INSPECT_FUNCTIONS = exports.FLAG_INSPECT_FUNCTIONS = exports.DESC_ONLY = exports.FLAG_ONLY = void 0;
4
4
  const clc = require("colorette");
5
5
  const childProcess = require("child_process");
6
6
  const controller = require("../emulator/controller");
@@ -14,13 +14,12 @@ const requireConfig_1 = require("../requireConfig");
14
14
  const types_1 = require("./types");
15
15
  const error_1 = require("../error");
16
16
  const registry_1 = require("./registry");
17
- const firestoreEmulator_1 = require("./firestoreEmulator");
18
17
  const projectUtils_1 = require("../projectUtils");
19
18
  const prompt_1 = require("../prompt");
20
- const controller_1 = require("./controller");
21
19
  const fsutils = require("../fsutils");
22
20
  const Table = require("cli-table");
23
21
  const track_1 = require("../track");
22
+ const env_1 = require("./env");
24
23
  exports.FLAG_ONLY = "--only <emulators>";
25
24
  exports.DESC_ONLY = "only specific emulators. " +
26
25
  "This is a comma separated list of emulator names. " +
@@ -151,6 +150,7 @@ function processKillSignal(signal, res, rej, options) {
151
150
  let lastSignal = new Date().getTime();
152
151
  let signalCount = 0;
153
152
  return async () => {
153
+ var _a;
154
154
  try {
155
155
  const now = new Date().getTime();
156
156
  const diff = now - lastSignal;
@@ -166,7 +166,7 @@ function processKillSignal(signal, res, rej, options) {
166
166
  if (signalCount === 1) {
167
167
  utils.logLabeledBullet("emulators", `Received ${signalDisplay} for the first time. Starting a clean shutdown.`);
168
168
  utils.logLabeledBullet("emulators", `Please wait for a clean shutdown or send the ${signalDisplay} signal again to stop right now.`);
169
- await (0, controller_1.onExit)(options);
169
+ await controller.onExit(options);
170
170
  await controller.cleanShutdown();
171
171
  }
172
172
  else {
@@ -184,7 +184,7 @@ function processKillSignal(signal, res, rej, options) {
184
184
  pids.push(emulatorInfo.pid);
185
185
  emulatorsTable.push([
186
186
  constants_1.Constants.description(emulatorInfo.name),
187
- registry_1.EmulatorRegistry.getInfoHostString(emulatorInfo),
187
+ (_a = getListenOverview(emulatorInfo.name)) !== null && _a !== void 0 ? _a : "unknown",
188
188
  emulatorInfo.pid,
189
189
  ]);
190
190
  }
@@ -219,44 +219,7 @@ exports.shutdownWhenKilled = shutdownWhenKilled;
219
219
  async function runScript(script, extraEnv) {
220
220
  utils.logBullet(`Running script: ${clc.bold(script)}`);
221
221
  const env = Object.assign(Object.assign({}, process.env), extraEnv);
222
- const databaseInstance = registry_1.EmulatorRegistry.get(types_1.Emulators.DATABASE);
223
- if (databaseInstance) {
224
- const info = databaseInstance.getInfo();
225
- const address = registry_1.EmulatorRegistry.getInfoHostString(info);
226
- env[constants_1.Constants.FIREBASE_DATABASE_EMULATOR_HOST] = address;
227
- }
228
- const firestoreInstance = registry_1.EmulatorRegistry.get(types_1.Emulators.FIRESTORE);
229
- if (firestoreInstance) {
230
- const info = firestoreInstance.getInfo();
231
- const address = registry_1.EmulatorRegistry.getInfoHostString(info);
232
- env[constants_1.Constants.FIRESTORE_EMULATOR_HOST] = address;
233
- env[firestoreEmulator_1.FirestoreEmulator.FIRESTORE_EMULATOR_ENV_ALT] = address;
234
- }
235
- const storageInstance = registry_1.EmulatorRegistry.get(types_1.Emulators.STORAGE);
236
- if (storageInstance) {
237
- const info = storageInstance.getInfo();
238
- const address = registry_1.EmulatorRegistry.getInfoHostString(info);
239
- env[constants_1.Constants.FIREBASE_STORAGE_EMULATOR_HOST] = address;
240
- env[constants_1.Constants.CLOUD_STORAGE_EMULATOR_HOST] = `http://${address}`;
241
- }
242
- const authInstance = registry_1.EmulatorRegistry.get(types_1.Emulators.AUTH);
243
- if (authInstance) {
244
- const info = authInstance.getInfo();
245
- const address = registry_1.EmulatorRegistry.getInfoHostString(info);
246
- env[constants_1.Constants.FIREBASE_AUTH_EMULATOR_HOST] = address;
247
- }
248
- const hubInstance = registry_1.EmulatorRegistry.get(types_1.Emulators.HUB);
249
- if (hubInstance) {
250
- const info = hubInstance.getInfo();
251
- const address = registry_1.EmulatorRegistry.getInfoHostString(info);
252
- env[constants_1.Constants.FIREBASE_EMULATOR_HUB] = address;
253
- }
254
- const eventarcInstance = registry_1.EmulatorRegistry.get(types_1.Emulators.EVENTARC);
255
- if (eventarcInstance) {
256
- const info = eventarcInstance.getInfo();
257
- const address = registry_1.EmulatorRegistry.getInfoHostString(info);
258
- env[constants_1.Constants.CLOUD_EVENTARC_EMULATOR_HOST] = address;
259
- }
222
+ (0, env_1.setEnvVarsForEmulators)(env);
260
223
  const proc = childProcess.spawn(script, {
261
224
  stdio: ["inherit", "inherit", "inherit"],
262
225
  shell: true,
@@ -289,6 +252,20 @@ async function runScript(script, extraEnv) {
289
252
  });
290
253
  });
291
254
  }
255
+ function getListenOverview(emulator) {
256
+ var _a;
257
+ const info = (_a = registry_1.EmulatorRegistry.get(emulator)) === null || _a === void 0 ? void 0 : _a.getInfo();
258
+ if (!info) {
259
+ return undefined;
260
+ }
261
+ if (info.host.includes(":")) {
262
+ return `[${info.host}]:${info.port}`;
263
+ }
264
+ else {
265
+ return `${info.host}:${info.port}`;
266
+ }
267
+ }
268
+ exports.getListenOverview = getListenOverview;
292
269
  async function emulatorExec(script, options) {
293
270
  const projectId = (0, projectUtils_1.getProjectId)(options);
294
271
  const extraEnv = {};
@@ -305,7 +282,7 @@ async function emulatorExec(script, options) {
305
282
  const showUI = !!options.ui;
306
283
  ({ deprecationNotices } = await controller.startAll(options, showUI));
307
284
  exitCode = await runScript(script, extraEnv);
308
- await (0, controller_1.onExit)(options);
285
+ await controller.onExit(options);
309
286
  }
310
287
  finally {
311
288
  await controller.cleanShutdown();
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Constants = exports.DEFAULT_HOST = exports.EMULATOR_DESCRIPTION = exports.FIND_AVAILBLE_PORT_BY_DEFAULT = exports.DEFAULT_PORTS = void 0;
4
- const url = require("url");
5
4
  exports.DEFAULT_PORTS = {
6
5
  ui: 4000,
7
6
  hub: 4400,
@@ -20,7 +19,7 @@ exports.FIND_AVAILBLE_PORT_BY_DEFAULT = {
20
19
  ui: true,
21
20
  hub: true,
22
21
  logging: true,
23
- hosting: false,
22
+ hosting: true,
24
23
  functions: false,
25
24
  firestore: false,
26
25
  database: false,
@@ -81,14 +80,6 @@ class Constants {
81
80
  static description(name) {
82
81
  return exports.EMULATOR_DESCRIPTION[name];
83
82
  }
84
- static normalizeHost(host) {
85
- let normalized = host;
86
- if (!normalized.startsWith("http")) {
87
- normalized = `http://${normalized}`;
88
- }
89
- const u = url.parse(normalized);
90
- return u.hostname || exports.DEFAULT_HOST;
91
- }
92
83
  static isDemoProject(projectId) {
93
84
  return !!projectId && projectId.startsWith(this.FAKE_PROJECT_ID_PREFIX);
94
85
  }
@@ -98,10 +89,12 @@ Constants.FAKE_PROJECT_ID_PREFIX = "demo-";
98
89
  Constants.FAKE_PROJECT_NUMBER = "0";
99
90
  Constants.DEFAULT_DATABASE_EMULATOR_NAMESPACE = "fake-server";
100
91
  Constants.FIRESTORE_EMULATOR_HOST = "FIRESTORE_EMULATOR_HOST";
92
+ Constants.FIRESTORE_EMULATOR_ENV_ALT = "FIREBASE_FIRESTORE_EMULATOR_ADDRESS";
101
93
  Constants.FIREBASE_DATABASE_EMULATOR_HOST = "FIREBASE_DATABASE_EMULATOR_HOST";
102
94
  Constants.FIREBASE_AUTH_EMULATOR_HOST = "FIREBASE_AUTH_EMULATOR_HOST";
103
95
  Constants.FIREBASE_STORAGE_EMULATOR_HOST = "FIREBASE_STORAGE_EMULATOR_HOST";
104
96
  Constants.CLOUD_STORAGE_EMULATOR_HOST = "STORAGE_EMULATOR_HOST";
97
+ Constants.PUBSUB_EMULATOR_HOST = "PUBSUB_EMULATOR_HOST";
105
98
  Constants.CLOUD_EVENTARC_EMULATOR_HOST = "CLOUD_EVENTARC_EMULATOR_HOST";
106
99
  Constants.FIREBASE_EMULATOR_HUB = "FIREBASE_EMULATOR_HUB";
107
100
  Constants.FIREBASE_GA_SESSION = "FIREBASE_GA_SESSION";