firebase-tools 11.14.1 → 11.14.2

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 (62) 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 +2 -1
  7. package/lib/deploy/index.js +10 -0
  8. package/lib/emulator/ExpressBasedEmulator.js +92 -0
  9. package/lib/emulator/auth/cloudFunctions.js +3 -12
  10. package/lib/emulator/auth/index.js +2 -2
  11. package/lib/emulator/auth/utils.js +1 -1
  12. package/lib/emulator/commandUtils.js +21 -44
  13. package/lib/emulator/constants.js +2 -9
  14. package/lib/emulator/controller.js +129 -130
  15. package/lib/emulator/databaseEmulator.js +3 -8
  16. package/lib/emulator/dns.js +49 -0
  17. package/lib/emulator/downloadableEmulators.js +19 -13
  18. package/lib/emulator/emulatorLogger.js +14 -7
  19. package/lib/emulator/env.js +35 -0
  20. package/lib/emulator/eventarcEmulator.js +2 -8
  21. package/lib/emulator/extensions/postinstall.js +8 -8
  22. package/lib/emulator/extensionsEmulator.js +7 -7
  23. package/lib/emulator/firestoreEmulator.js +3 -11
  24. package/lib/emulator/functionsEmulator.js +24 -60
  25. package/lib/emulator/functionsEmulatorShared.js +5 -3
  26. package/lib/emulator/functionsEmulatorShell.js +1 -1
  27. package/lib/emulator/hub.js +50 -58
  28. package/lib/emulator/hubClient.js +24 -10
  29. package/lib/emulator/hubExport.js +3 -11
  30. package/lib/emulator/portUtils.js +208 -29
  31. package/lib/emulator/pubsubEmulator.js +11 -12
  32. package/lib/emulator/registry.js +11 -20
  33. package/lib/emulator/storage/apis/gcloud.js +3 -6
  34. package/lib/emulator/storage/cloudFunctions.js +2 -7
  35. package/lib/emulator/storage/metadata.js +11 -5
  36. package/lib/emulator/storage/rules/runtime.js +1 -6
  37. package/lib/emulator/ui.js +6 -7
  38. package/lib/experiments.js +10 -1
  39. package/lib/extensions/displayExtensionInfo.js +43 -6
  40. package/lib/extensions/secretsUtils.js +2 -1
  41. package/lib/frameworks/angular/index.js +1 -1
  42. package/lib/frameworks/express/index.js +1 -1
  43. package/lib/frameworks/index.js +33 -17
  44. package/lib/frameworks/next/index.js +1 -1
  45. package/lib/frameworks/nuxt/index.js +1 -1
  46. package/lib/frameworks/vite/index.js +1 -1
  47. package/lib/functions/ensureTargeted.js +21 -0
  48. package/lib/functions/env.js +33 -19
  49. package/lib/functionsShellCommandAction.js +12 -5
  50. package/lib/gcp/run.js +0 -1
  51. package/lib/handlePreviewToggles.js +2 -2
  52. package/lib/hosting/functionsProxy.js +2 -3
  53. package/lib/hosting/implicitInit.js +2 -11
  54. package/lib/hosting/runTags.js +3 -4
  55. package/lib/serve/functions.js +8 -10
  56. package/lib/serve/hosting.js +10 -4
  57. package/lib/serve/index.js +2 -2
  58. package/lib/utils.js +14 -1
  59. package/npm-shrinkwrap.json +2 -2
  60. package/package.json +1 -1
  61. package/templates/hosting/init.js +3 -2
  62. package/lib/emulator/emulatorServer.js +0 -29
@@ -27,7 +27,6 @@ const ui_1 = require("./ui");
27
27
  const loggingEmulator_1 = require("./loggingEmulator");
28
28
  const dbRulesConfig = require("../database/rulesConfig");
29
29
  const emulatorLogger_1 = require("./emulatorLogger");
30
- const portUtils = require("./portUtils");
31
30
  const hubClient_1 = require("./hubClient");
32
31
  const prompt_1 = require("../prompt");
33
32
  const commandUtils_1 = require("./commandUtils");
@@ -41,87 +40,8 @@ const projectConfig_1 = require("../functions/projectConfig");
41
40
  const downloadableEmulators_1 = require("./downloadableEmulators");
42
41
  const frameworks_1 = require("../frameworks");
43
42
  const experiments = require("../experiments");
43
+ const portUtils_1 = require("./portUtils");
44
44
  const START_LOGGING_EMULATOR = utils.envOverride("START_LOGGING_EMULATOR", "false", (val) => val === "true");
45
- async function getAndCheckAddress(emulator, options) {
46
- var _a, _b, _c, _d;
47
- if (emulator === types_1.Emulators.EXTENSIONS) {
48
- emulator = types_1.Emulators.FUNCTIONS;
49
- }
50
- let host = ((_b = (_a = options.config.src.emulators) === null || _a === void 0 ? void 0 : _a[emulator]) === null || _b === void 0 ? void 0 : _b.host) || constants_1.Constants.getDefaultHost();
51
- if (host === "localhost" && utils.isRunningInWSL()) {
52
- host = "127.0.0.1";
53
- }
54
- const portVal = (_d = (_c = options.config.src.emulators) === null || _c === void 0 ? void 0 : _c[emulator]) === null || _d === void 0 ? void 0 : _d.port;
55
- let port;
56
- let findAvailablePort = false;
57
- if (portVal) {
58
- port = parseInt(`${portVal}`, 10);
59
- }
60
- else {
61
- port = constants_1.Constants.getDefaultPort(emulator);
62
- findAvailablePort = constants_1.FIND_AVAILBLE_PORT_BY_DEFAULT[emulator];
63
- }
64
- const loggerForEmulator = emulatorLogger_1.EmulatorLogger.forEmulator(emulator);
65
- const portOpen = await portUtils.checkPortOpen(port, host);
66
- if (!portOpen) {
67
- if (findAvailablePort) {
68
- const newPort = await portUtils.findAvailablePort(host, port);
69
- if (newPort !== port) {
70
- loggerForEmulator.logLabeled("WARN", emulator, `${constants_1.Constants.description(emulator)} unable to start on port ${port}, starting on ${newPort} instead.`);
71
- port = newPort;
72
- }
73
- }
74
- else {
75
- await cleanShutdown();
76
- const description = constants_1.Constants.description(emulator);
77
- loggerForEmulator.logLabeled("WARN", emulator, `Port ${port} is not open on ${host}, could not start ${description}.`);
78
- loggerForEmulator.logLabeled("WARN", emulator, `To select a different host/port, specify that host/port in a firebase.json config file:
79
- {
80
- // ...
81
- "emulators": {
82
- "${emulator}": {
83
- "host": "${clc.yellow("HOST")}",
84
- "port": "${clc.yellow("PORT")}"
85
- }
86
- }
87
- }`);
88
- return utils.reject(`Could not start ${description}, port taken.`, {});
89
- }
90
- }
91
- if (portUtils.isRestricted(port)) {
92
- const suggested = portUtils.suggestUnrestricted(port);
93
- loggerForEmulator.logLabeled("WARN", emulator, `Port ${port} is restricted by some web browsers, including Chrome. You may want to choose a different port such as ${suggested}.`);
94
- }
95
- return { host, port };
96
- }
97
- async function getFirestoreWebSocketPort(host, port, emulator) {
98
- let websocketPort;
99
- if (port) {
100
- const portOpen = await portUtils.checkPortOpen(port, host);
101
- if (!portOpen) {
102
- await cleanShutdown();
103
- const logger = emulatorLogger_1.EmulatorLogger.forEmulator(emulator);
104
- logger.logLabeled("WARN", emulator, `Port ${port} is not open on ${host}, could not start websocket server for Firestore emulator.`);
105
- logger.logLabeled("WARN", emulator, `To select a different port, specify that port in a firebase.json config file:
106
- {
107
- // ...
108
- "emulators": {
109
- "${emulator}": {
110
- "host": "${clc.yellow("HOST")}",
111
- ...
112
- "websocketPort": "${clc.yellow("WEBSOCKET_PORT")}"
113
- }
114
- }
115
- }`);
116
- return utils.reject(`Could not start websocket, port taken.`, {});
117
- }
118
- websocketPort = port;
119
- }
120
- else {
121
- websocketPort = await portUtils.findAvailablePort(host, 9150);
122
- }
123
- return websocketPort;
124
- }
125
45
  async function exportOnExit(options) {
126
46
  const exportOnExitDir = options.exportOnExit;
127
47
  if (exportOnExitDir) {
@@ -232,7 +152,7 @@ function findExportMetadata(importPath) {
232
152
  }
233
153
  }
234
154
  async function startAll(options, showUI = true) {
235
- var _a, _b, _c, _d, _e;
155
+ var _a, _b, _c, _d, _e, _f, _g;
236
156
  const targets = filterEmulatorTargets(options);
237
157
  options.targets = targets;
238
158
  const singleProjectModeEnabled = ((_a = options.config.src.emulators) === null || _a === void 0 ? void 0 : _a.singleProjectMode) === undefined ||
@@ -268,6 +188,60 @@ async function startAll(options, showUI = true) {
268
188
  }
269
189
  }
270
190
  }
191
+ const emulatableBackends = [];
192
+ let extensionEmulator = undefined;
193
+ if (shouldStart(options, types_1.Emulators.EXTENSIONS)) {
194
+ const projectNumber = isDemoProject
195
+ ? constants_1.Constants.FAKE_PROJECT_NUMBER
196
+ : await (0, projectUtils_1.needProjectNumber)(options);
197
+ const aliases = (0, projectUtils_1.getAliases)(options, projectId);
198
+ extensionEmulator = new extensionsEmulator_1.ExtensionsEmulator({
199
+ projectId,
200
+ projectDir: options.config.projectDir,
201
+ projectNumber,
202
+ aliases,
203
+ extensions: options.config.get("extensions"),
204
+ });
205
+ const extensionsBackends = await extensionEmulator.getExtensionBackends();
206
+ const filteredExtensionsBackends = extensionEmulator.filterUnemulatedTriggers(options, extensionsBackends);
207
+ emulatableBackends.push(...filteredExtensionsBackends);
208
+ }
209
+ const listenConfig = {};
210
+ if (emulatableBackends.length) {
211
+ listenConfig[types_1.Emulators.FUNCTIONS] = getListenConfig(options, types_1.Emulators.FUNCTIONS);
212
+ listenConfig[types_1.Emulators.EVENTARC] = getListenConfig(options, types_1.Emulators.EVENTARC);
213
+ }
214
+ for (const emulator of types_1.ALL_EMULATORS) {
215
+ if (emulator === types_1.Emulators.FUNCTIONS ||
216
+ emulator === types_1.Emulators.EVENTARC ||
217
+ emulator === types_1.Emulators.EXTENSIONS ||
218
+ (emulator === types_1.Emulators.UI && !showUI)) {
219
+ continue;
220
+ }
221
+ if (shouldStart(options, emulator) ||
222
+ (emulator === types_1.Emulators.LOGGING &&
223
+ ((showUI && shouldStart(options, types_1.Emulators.UI)) || START_LOGGING_EMULATOR))) {
224
+ const config = getListenConfig(options, emulator);
225
+ listenConfig[emulator] = config;
226
+ if (emulator === types_1.Emulators.FIRESTORE) {
227
+ const wsPortConfig = (_d = (_c = options.config.src.emulators) === null || _c === void 0 ? void 0 : _c.firestore) === null || _d === void 0 ? void 0 : _d.websocketPort;
228
+ listenConfig["firestore.websocket"] = {
229
+ host: config.host,
230
+ port: wsPortConfig || 9150,
231
+ portFixed: !!wsPortConfig,
232
+ };
233
+ }
234
+ }
235
+ }
236
+ let listenForEmulator = await (0, portUtils_1.resolveHostAndAssignPorts)(listenConfig);
237
+ hubLogger.log("DEBUG", "assigned listening specs for emulators", { user: listenForEmulator });
238
+ function legacyGetFirstAddr(name) {
239
+ const firstSpec = listenForEmulator[name][0];
240
+ return {
241
+ host: firstSpec.address,
242
+ port: firstSpec.port,
243
+ };
244
+ }
271
245
  function startEmulator(instance) {
272
246
  const name = instance.getName();
273
247
  void (0, track_1.track)("Emulator Run", name);
@@ -277,9 +251,12 @@ async function startAll(options, showUI = true) {
277
251
  });
278
252
  return registry_1.EmulatorRegistry.start(instance);
279
253
  }
280
- if (shouldStart(options, types_1.Emulators.HUB)) {
281
- const hubAddr = await getAndCheckAddress(types_1.Emulators.HUB, options);
282
- const hub = new hub_1.EmulatorHub(Object.assign({ projectId }, hubAddr));
254
+ if (listenForEmulator.hub) {
255
+ const hub = new hub_1.EmulatorHub({
256
+ projectId,
257
+ listen: listenForEmulator[types_1.Emulators.HUB],
258
+ listenForEmulator,
259
+ });
283
260
  void (0, track_1.track)("emulators:start", "hub");
284
261
  await startEmulator(hub);
285
262
  }
@@ -306,15 +283,18 @@ async function startAll(options, showUI = true) {
306
283
  experiments.assertEnabled("webframeworks", "emulate a web framework");
307
284
  const emulators = [];
308
285
  if (experiments.isEnabled("webframeworks")) {
309
- for (const e of types_1.EMULATORS_SUPPORTED_BY_UI) {
310
- const info = registry_1.EmulatorRegistry.getInfo(e);
311
- if (info)
312
- emulators.push(info);
286
+ for (const e of types_1.ALL_SERVICE_EMULATORS) {
287
+ if (listenForEmulator[e]) {
288
+ emulators.push({
289
+ name: e,
290
+ host: utils.connectableHostname(listenForEmulator[e][0].address),
291
+ port: listenForEmulator[e][0].port,
292
+ });
293
+ }
313
294
  }
314
295
  }
315
296
  await (0, frameworks_1.prepareFrameworks)(targets, options, options, emulators);
316
297
  }
317
- const emulatableBackends = [];
318
298
  const projectDir = (options.extDevDir || options.config.projectDir);
319
299
  if (shouldStart(options, types_1.Emulators.FUNCTIONS)) {
320
300
  const functionsCfg = (0, projectConfig_1.normalizeAndValidate)(options.config.src.functions);
@@ -331,26 +311,18 @@ async function startAll(options, showUI = true) {
331
311
  });
332
312
  }
333
313
  }
334
- if (shouldStart(options, types_1.Emulators.EXTENSIONS)) {
335
- const projectNumber = isDemoProject
336
- ? constants_1.Constants.FAKE_PROJECT_NUMBER
337
- : await (0, projectUtils_1.needProjectNumber)(options);
338
- const aliases = (0, projectUtils_1.getAliases)(options, projectId);
339
- const extensionEmulator = new extensionsEmulator_1.ExtensionsEmulator({
340
- projectId,
341
- projectDir: options.config.projectDir,
342
- projectNumber,
343
- aliases,
344
- extensions: options.config.get("extensions"),
345
- });
346
- const extensionsBackends = await extensionEmulator.getExtensionBackends();
347
- const filteredExtensionsBackends = extensionEmulator.filterUnemulatedTriggers(options, extensionsBackends);
348
- emulatableBackends.push(...filteredExtensionsBackends);
314
+ if (extensionEmulator) {
349
315
  await startEmulator(extensionEmulator);
350
316
  }
351
317
  if (emulatableBackends.length) {
318
+ if (!listenForEmulator.functions || !listenForEmulator.eventarc) {
319
+ listenForEmulator = await (0, portUtils_1.resolveHostAndAssignPorts)(Object.assign(Object.assign({}, listenForEmulator), { functions: (_e = listenForEmulator.functions) !== null && _e !== void 0 ? _e : getListenConfig(options, types_1.Emulators.FUNCTIONS), eventarc: (_f = listenForEmulator.eventarc) !== null && _f !== void 0 ? _f : getListenConfig(options, types_1.Emulators.EVENTARC) }));
320
+ hubLogger.log("DEBUG", "late-assigned ports for functions and eventarc emulators", {
321
+ user: listenForEmulator,
322
+ });
323
+ }
352
324
  const functionsLogger = emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.FUNCTIONS);
353
- const functionsAddr = await getAndCheckAddress(types_1.Emulators.FUNCTIONS, options);
325
+ const functionsAddr = legacyGetFirstAddr(types_1.Emulators.FUNCTIONS);
354
326
  const projectId = (0, projectUtils_1.needProjectId)(options);
355
327
  let inspectFunctions;
356
328
  if (options.inspectFunctions) {
@@ -358,7 +330,7 @@ async function startAll(options, showUI = true) {
358
330
  functionsLogger.logLabeled("WARN", "functions", `You are running the Functions emulator in debug mode (port=${inspectFunctions}). This means that functions will execute in sequence rather than in parallel.`);
359
331
  }
360
332
  const emulatorsNotRunning = types_1.ALL_SERVICE_EMULATORS.filter((e) => {
361
- return e !== types_1.Emulators.FUNCTIONS && !shouldStart(options, e);
333
+ return e !== types_1.Emulators.FUNCTIONS && !listenForEmulator[e];
362
334
  });
363
335
  if (emulatorsNotRunning.length > 0 && !constants_1.Constants.isDemoProject(projectId)) {
364
336
  functionsLogger.logLabeled("WARN", "functions", `The following emulators are not running, calls to these services from the Functions emulator will affect production: ${clc.bold(emulatorsNotRunning.join(", "))}`);
@@ -375,18 +347,17 @@ async function startAll(options, showUI = true) {
375
347
  projectAlias: options.projectAlias,
376
348
  });
377
349
  await startEmulator(functionsEmulator);
378
- const eventarcAddr = await getAndCheckAddress(types_1.Emulators.EVENTARC, options);
350
+ const eventarcAddr = legacyGetFirstAddr(types_1.Emulators.EVENTARC);
379
351
  const eventarcEmulator = new eventarcEmulator_1.EventarcEmulator({
380
352
  host: eventarcAddr.host,
381
353
  port: eventarcAddr.port,
382
354
  });
383
355
  await startEmulator(eventarcEmulator);
384
356
  }
385
- if (shouldStart(options, types_1.Emulators.FIRESTORE)) {
357
+ if (listenForEmulator.firestore) {
386
358
  const firestoreLogger = emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.FIRESTORE);
387
- const firestoreAddr = await getAndCheckAddress(types_1.Emulators.FIRESTORE, options);
388
- const portVal = (_d = (_c = options.config.src.emulators) === null || _c === void 0 ? void 0 : _c.firestore) === null || _d === void 0 ? void 0 : _d.websocketPort;
389
- const websocketPort = await getFirestoreWebSocketPort(firestoreAddr.host, portVal, types_1.Emulators.FIRESTORE);
359
+ const firestoreAddr = legacyGetFirstAddr(types_1.Emulators.FIRESTORE);
360
+ const websocketPort = legacyGetFirstAddr("firestore.websocket").port;
390
361
  const args = {
391
362
  host: firestoreAddr.host,
392
363
  port: firestoreAddr.port,
@@ -406,7 +377,7 @@ async function startAll(options, showUI = true) {
406
377
  });
407
378
  }
408
379
  const config = options.config;
409
- const rulesLocalPath = (_e = config.src.firestore) === null || _e === void 0 ? void 0 : _e.rules;
380
+ const rulesLocalPath = (_g = config.src.firestore) === null || _g === void 0 ? void 0 : _g.rules;
410
381
  let rulesFileFound = false;
411
382
  if (rulesLocalPath) {
412
383
  const rules = config.path(rulesLocalPath);
@@ -437,14 +408,15 @@ async function startAll(options, showUI = true) {
437
408
  await startEmulator(firestoreEmulator);
438
409
  firestoreLogger.logLabeled("SUCCESS", types_1.Emulators.FIRESTORE, `Firestore Emulator UI websocket is running on ${websocketPort}.`);
439
410
  }
440
- if (shouldStart(options, types_1.Emulators.DATABASE)) {
411
+ if (listenForEmulator.database) {
441
412
  const databaseLogger = emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.DATABASE);
442
- const databaseAddr = await getAndCheckAddress(types_1.Emulators.DATABASE, options);
413
+ const databaseAddr = legacyGetFirstAddr(types_1.Emulators.DATABASE);
443
414
  const args = {
444
415
  host: databaseAddr.host,
445
416
  port: databaseAddr.port,
446
417
  projectId,
447
418
  auto_download: true,
419
+ single_project_mode: singleProjectModeEnabled ? "Warning" : undefined,
448
420
  };
449
421
  try {
450
422
  if (!options.instance) {
@@ -487,11 +459,11 @@ async function startAll(options, showUI = true) {
487
459
  }
488
460
  }
489
461
  }
490
- if (shouldStart(options, types_1.Emulators.AUTH)) {
462
+ if (listenForEmulator.auth) {
491
463
  if (!projectId) {
492
464
  throw new error_1.FirebaseError(`Cannot start the ${constants_1.Constants.description(types_1.Emulators.AUTH)} without a project: run 'firebase init' or provide the --project flag`);
493
465
  }
494
- const authAddr = await getAndCheckAddress(types_1.Emulators.AUTH, options);
466
+ const authAddr = legacyGetFirstAddr(types_1.Emulators.AUTH);
495
467
  const authEmulator = new auth_1.AuthEmulator({
496
468
  host: authAddr.host,
497
469
  port: authAddr.port,
@@ -508,11 +480,11 @@ async function startAll(options, showUI = true) {
508
480
  await authEmulator.importData(authExportDir, projectId, { initiatedBy: "start" });
509
481
  }
510
482
  }
511
- if (shouldStart(options, types_1.Emulators.PUBSUB)) {
483
+ if (listenForEmulator.pubsub) {
512
484
  if (!projectId) {
513
485
  throw new error_1.FirebaseError("Cannot start the Pub/Sub emulator without a project: run 'firebase init' or provide the --project flag");
514
486
  }
515
- const pubsubAddr = await getAndCheckAddress(types_1.Emulators.PUBSUB, options);
487
+ const pubsubAddr = legacyGetFirstAddr(types_1.Emulators.PUBSUB);
516
488
  const pubsubEmulator = new pubsubEmulator_1.PubsubEmulator({
517
489
  host: pubsubAddr.host,
518
490
  port: pubsubAddr.port,
@@ -521,8 +493,8 @@ async function startAll(options, showUI = true) {
521
493
  });
522
494
  await startEmulator(pubsubEmulator);
523
495
  }
524
- if (shouldStart(options, types_1.Emulators.STORAGE)) {
525
- const storageAddr = await getAndCheckAddress(types_1.Emulators.STORAGE, options);
496
+ if (listenForEmulator.storage) {
497
+ const storageAddr = legacyGetFirstAddr(types_1.Emulators.STORAGE);
526
498
  const storageEmulator = new storage_1.StorageEmulator({
527
499
  host: storageAddr.host,
528
500
  port: storageAddr.port,
@@ -537,8 +509,8 @@ async function startAll(options, showUI = true) {
537
509
  storageEmulator.storageLayer.import(storageExportDir, { initiatedBy: "start" });
538
510
  }
539
511
  }
540
- if (shouldStart(options, types_1.Emulators.HOSTING)) {
541
- const hostingAddr = await getAndCheckAddress(types_1.Emulators.HOSTING, options);
512
+ if (listenForEmulator.hosting) {
513
+ const hostingAddr = legacyGetFirstAddr(types_1.Emulators.HOSTING);
542
514
  const hostingEmulator = new hostingEmulator_1.HostingEmulator({
543
515
  host: hostingAddr.host,
544
516
  port: hostingAddr.port,
@@ -551,17 +523,20 @@ async function startAll(options, showUI = true) {
551
523
  "products have an interaction layer in Emulator UI or it cannot " +
552
524
  "determine the Project ID. Pass the --project flag to specify a project.");
553
525
  }
554
- if (showUI && (shouldStart(options, types_1.Emulators.UI) || START_LOGGING_EMULATOR)) {
555
- const loggingAddr = await getAndCheckAddress(types_1.Emulators.LOGGING, options);
526
+ if (listenForEmulator.logging) {
527
+ const loggingAddr = legacyGetFirstAddr(types_1.Emulators.LOGGING);
556
528
  const loggingEmulator = new loggingEmulator_1.LoggingEmulator({
557
529
  host: loggingAddr.host,
558
530
  port: loggingAddr.port,
559
531
  });
560
532
  await startEmulator(loggingEmulator);
561
533
  }
562
- if (showUI && shouldStart(options, types_1.Emulators.UI)) {
563
- const uiAddr = await getAndCheckAddress(types_1.Emulators.UI, options);
564
- const ui = new ui_1.EmulatorUI(Object.assign({ projectId: projectId, auto_download: true }, uiAddr));
534
+ if (listenForEmulator.ui) {
535
+ const ui = new ui_1.EmulatorUI({
536
+ projectId: projectId,
537
+ auto_download: true,
538
+ listen: listenForEmulator[types_1.Emulators.UI],
539
+ });
565
540
  await startEmulator(ui);
566
541
  }
567
542
  let serviceEmulatorCount = 0;
@@ -583,6 +558,29 @@ async function startAll(options, showUI = true) {
583
558
  return { deprecationNotices: [] };
584
559
  }
585
560
  exports.startAll = startAll;
561
+ function getListenConfig(options, emulator) {
562
+ var _a, _b, _c, _d;
563
+ let host = ((_b = (_a = options.config.src.emulators) === null || _a === void 0 ? void 0 : _a[emulator]) === null || _b === void 0 ? void 0 : _b.host) || constants_1.Constants.getDefaultHost();
564
+ if (host === "localhost" && utils.isRunningInWSL()) {
565
+ host = "127.0.0.1";
566
+ }
567
+ const portVal = (_d = (_c = options.config.src.emulators) === null || _c === void 0 ? void 0 : _c[emulator]) === null || _d === void 0 ? void 0 : _d.port;
568
+ let port;
569
+ let portFixed;
570
+ if (portVal) {
571
+ port = parseInt(`${portVal}`, 10);
572
+ portFixed = true;
573
+ }
574
+ else {
575
+ port = constants_1.Constants.getDefaultPort(emulator);
576
+ portFixed = !constants_1.FIND_AVAILBLE_PORT_BY_DEFAULT[emulator];
577
+ }
578
+ return {
579
+ host,
580
+ port,
581
+ portFixed,
582
+ };
583
+ }
586
584
  async function exportEmulatorData(exportPath, options, initiatedBy) {
587
585
  const projectId = options.project;
588
586
  if (!projectId) {
@@ -592,14 +590,15 @@ async function exportEmulatorData(exportPath, options, initiatedBy) {
592
590
  if (!hubClient.foundHub()) {
593
591
  throw new error_1.FirebaseError(`Did not find any running emulators for project ${clc.bold(projectId)}.`, { exit: 1 });
594
592
  }
593
+ let origin;
595
594
  try {
596
- await hubClient.getStatus();
595
+ origin = await hubClient.getStatus();
597
596
  }
598
597
  catch (e) {
599
598
  const filePath = hub_1.EmulatorHub.getLocatorFilePath(projectId);
600
599
  throw new error_1.FirebaseError(`The emulator hub for ${projectId} did not respond to a status check. If this error continues try shutting down all running emulators and deleting the file ${filePath}`, { exit: 1 });
601
600
  }
602
- utils.logBullet(`Found running emulator hub for project ${clc.bold(projectId)} at ${hubClient.origin}`);
601
+ utils.logBullet(`Found running emulator hub for project ${clc.bold(projectId)} at ${origin}`);
603
602
  const exportAbsPath = path.resolve(exportPath);
604
603
  if (!fs.existsSync(exportAbsPath)) {
605
604
  utils.logBullet(`Creating export directory ${exportAbsPath}`);
@@ -13,7 +13,7 @@ const registry_1 = require("./registry");
13
13
  const emulatorLogger_1 = require("./emulatorLogger");
14
14
  const error_1 = require("../error");
15
15
  const parseBoltRules_1 = require("../parseBoltRules");
16
- const apiv2_1 = require("../apiv2");
16
+ const utils_1 = require("../utils");
17
17
  class DatabaseEmulator {
18
18
  constructor(args) {
19
19
  this.args = args;
@@ -94,7 +94,7 @@ class DatabaseEmulator {
94
94
  await new Promise((resolve, reject) => {
95
95
  const req = http.request({
96
96
  method: "PUT",
97
- host,
97
+ host: (0, utils_1.connectableHostname)(host),
98
98
  port,
99
99
  path: `/.json?ns=${ns}&disableTriggers=true&writeSizeLimit=unlimited`,
100
100
  headers: {
@@ -127,13 +127,8 @@ class DatabaseEmulator {
127
127
  const content = rulesExt === ".bolt"
128
128
  ? (0, parseBoltRules_1.parseBoltRules)(rulesPath).toString()
129
129
  : fs.readFileSync(rulesPath, "utf8");
130
- const info = this.getInfo();
131
130
  try {
132
- const client = new apiv2_1.Client({
133
- urlPrefix: `http://${registry_1.EmulatorRegistry.getInfoHostString(info)}`,
134
- auth: false,
135
- });
136
- await client.put(`/.settings/rules.json`, content, {
131
+ await registry_1.EmulatorRegistry.client(types_1.Emulators.DATABASE).put(`/.settings/rules.json`, content, {
137
132
  headers: { Authorization: "Bearer owner" },
138
133
  queryParams: { ns: instance },
139
134
  });
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Resolver = exports.IPV6_UNSPECIFIED = exports.IPV4_UNSPECIFIED = exports.IPV6_LOOPBACK = exports.IPV4_LOOPBACK = void 0;
4
+ const node_dns_1 = require("node:dns");
5
+ const node_net_1 = require("node:net");
6
+ const logger_1 = require("../logger");
7
+ exports.IPV4_LOOPBACK = { address: "127.0.0.1", family: 4 };
8
+ exports.IPV6_LOOPBACK = { address: "::1", family: 6 };
9
+ exports.IPV4_UNSPECIFIED = { address: "0.0.0.0", family: 4 };
10
+ exports.IPV6_UNSPECIFIED = { address: "::", family: 6 };
11
+ class Resolver {
12
+ constructor(lookup = node_dns_1.promises.lookup) {
13
+ this.lookup = lookup;
14
+ this.cache = new Map([
15
+ ["localhost", [exports.IPV4_LOOPBACK, exports.IPV6_LOOPBACK]],
16
+ ]);
17
+ }
18
+ async lookupFirst(hostname) {
19
+ const addresses = await this.lookupAll(hostname);
20
+ if (addresses.length === 1) {
21
+ return addresses[0];
22
+ }
23
+ const result = addresses[0];
24
+ const discarded = [];
25
+ for (let i = 1; i < addresses.length; i++) {
26
+ discarded.push(result.address);
27
+ }
28
+ logger_1.logger.debug(`Resolved hostname "${hostname}" to the first result "${result.address}" (ignoring candidates: ${discarded.join(",")}).`);
29
+ return result;
30
+ }
31
+ async lookupAll(hostname) {
32
+ const family = (0, node_net_1.isIP)(hostname);
33
+ if (family > 0) {
34
+ return [{ family, address: hostname }];
35
+ }
36
+ const cached = this.cache.get(hostname);
37
+ if (cached) {
38
+ return cached;
39
+ }
40
+ const addresses = await this.lookup(hostname, {
41
+ verbatim: false,
42
+ all: true,
43
+ });
44
+ this.cache.set(hostname, addresses);
45
+ return addresses;
46
+ }
47
+ }
48
+ exports.Resolver = Resolver;
49
+ Resolver.DEFAULT = new Resolver();
@@ -18,13 +18,13 @@ const EMULATOR_INSTANCE_KILL_TIMEOUT = 4000;
18
18
  const CACHE_DIR = process.env.FIREBASE_EMULATORS_PATH || path.join(os.homedir(), ".cache", "firebase", "emulators");
19
19
  exports.DownloadDetails = {
20
20
  database: {
21
- downloadPath: path.join(CACHE_DIR, "firebase-database-emulator-v4.9.0.jar"),
22
- version: "4.9.0",
21
+ downloadPath: path.join(CACHE_DIR, "firebase-database-emulator-v4.10.0.jar"),
22
+ version: "4.10.0",
23
23
  opts: {
24
24
  cacheDir: CACHE_DIR,
25
- remoteUrl: "https://storage.googleapis.com/firebase-preview-drop/emulator/firebase-database-emulator-v4.9.0.jar",
26
- expectedSize: 34204485,
27
- expectedChecksum: "1c3f5974f0ee5559ebf27b56f2e62108",
25
+ remoteUrl: "https://storage.googleapis.com/firebase-preview-drop/emulator/firebase-database-emulator-v4.10.0.jar",
26
+ expectedSize: 34230230,
27
+ expectedChecksum: "e99b23f0e723813de4f4ea0e879b46b0",
28
28
  namePrefix: "firebase-database-emulator",
29
29
  },
30
30
  },
@@ -67,15 +67,15 @@ exports.DownloadDetails = {
67
67
  },
68
68
  }
69
69
  : {
70
- version: "1.10.0",
71
- downloadPath: path.join(CACHE_DIR, "ui-v1.10.0.zip"),
72
- unzipDir: path.join(CACHE_DIR, "ui-v1.10.0"),
73
- binaryPath: path.join(CACHE_DIR, "ui-v1.10.0", "server", "server.js"),
70
+ version: "1.11.1",
71
+ downloadPath: path.join(CACHE_DIR, "ui-v1.11.1.zip"),
72
+ unzipDir: path.join(CACHE_DIR, "ui-v1.11.1"),
73
+ binaryPath: path.join(CACHE_DIR, "ui-v1.11.1", "server", "server.js"),
74
74
  opts: {
75
75
  cacheDir: CACHE_DIR,
76
- remoteUrl: "https://storage.googleapis.com/firebase-preview-drop/emulator/ui-v1.10.0.zip",
77
- expectedSize: 3062540,
78
- expectedChecksum: "7dec1e82acccc196efc4d364e2664288",
76
+ remoteUrl: "https://storage.googleapis.com/firebase-preview-drop/emulator/ui-v1.11.1.zip",
77
+ expectedSize: 3061713,
78
+ expectedChecksum: "a4944414518be206280b495f526f18bf",
79
79
  namePrefix: "ui",
80
80
  },
81
81
  },
@@ -124,7 +124,13 @@ const Commands = {
124
124
  database: {
125
125
  binary: "java",
126
126
  args: ["-Duser.language=en", "-jar", getExecPath(types_1.Emulators.DATABASE)],
127
- optionalArgs: ["port", "host", "functions_emulator_port", "functions_emulator_host"],
127
+ optionalArgs: [
128
+ "port",
129
+ "host",
130
+ "functions_emulator_port",
131
+ "functions_emulator_host",
132
+ "single_project_mode",
133
+ ],
128
134
  joinArgs: false,
129
135
  },
130
136
  firestore: {
@@ -4,6 +4,7 @@ exports.EmulatorLogger = exports.Verbosity = void 0;
4
4
  const clc = require("colorette");
5
5
  const utils = require("../utils");
6
6
  const logger_1 = require("../logger");
7
+ const types_1 = require("./types");
7
8
  const utils_1 = require("../utils");
8
9
  const TYPE_VERBOSITY = {
9
10
  DEBUG: 0,
@@ -22,11 +23,12 @@ var Verbosity;
22
23
  Verbosity[Verbosity["QUIET"] = 2] = "QUIET";
23
24
  })(Verbosity = exports.Verbosity || (exports.Verbosity = {}));
24
25
  class EmulatorLogger {
25
- constructor(data = {}) {
26
+ constructor(name, data = {}) {
27
+ this.name = name;
26
28
  this.data = data;
27
29
  }
28
30
  static forEmulator(emulator) {
29
- return new EmulatorLogger({
31
+ return new EmulatorLogger(emulator, {
30
32
  metadata: {
31
33
  emulator: {
32
34
  name: emulator,
@@ -35,10 +37,10 @@ class EmulatorLogger {
35
37
  });
36
38
  }
37
39
  static forFunction(functionName, extensionLogInfo) {
38
- return new EmulatorLogger({
40
+ return new EmulatorLogger(types_1.Emulators.FUNCTIONS, {
39
41
  metadata: {
40
42
  emulator: {
41
- name: "functions",
43
+ name: types_1.Emulators.FUNCTIONS,
42
44
  },
43
45
  function: {
44
46
  name: functionName,
@@ -48,10 +50,10 @@ class EmulatorLogger {
48
50
  });
49
51
  }
50
52
  static forExtension(extensionLogInfo) {
51
- return new EmulatorLogger({
53
+ return new EmulatorLogger(types_1.Emulators.EXTENSIONS, {
52
54
  metadata: {
53
55
  emulator: {
54
- name: "extensions",
56
+ name: types_1.Emulators.EXTENSIONS,
55
57
  },
56
58
  extension: extensionLogInfo,
57
59
  },
@@ -186,7 +188,12 @@ You can probably fix this by running "npm install ${systemLog.data.name}@latest"
186
188
  default:
187
189
  }
188
190
  }
189
- logLabeled(type, label, text) {
191
+ logLabeled(type, labelOrText, text) {
192
+ let label = labelOrText;
193
+ if (text === undefined) {
194
+ text = label;
195
+ label = this.name;
196
+ }
190
197
  if (EmulatorLogger.shouldSupress(type)) {
191
198
  logger_1.logger.debug(`[${label}] ${text}`);
192
199
  return;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setEnvVarsForEmulators = void 0;
4
+ const constants_1 = require("./constants");
5
+ const types_1 = require("./types");
6
+ const registry_1 = require("./registry");
7
+ function setEnvVarsForEmulators(env) {
8
+ if (registry_1.EmulatorRegistry.isRunning(types_1.Emulators.DATABASE)) {
9
+ env[constants_1.Constants.FIREBASE_DATABASE_EMULATOR_HOST] = registry_1.EmulatorRegistry.url(types_1.Emulators.DATABASE).host;
10
+ }
11
+ if (registry_1.EmulatorRegistry.isRunning(types_1.Emulators.FIRESTORE)) {
12
+ const { host } = registry_1.EmulatorRegistry.url(types_1.Emulators.FIRESTORE);
13
+ env[constants_1.Constants.FIRESTORE_EMULATOR_HOST] = host;
14
+ env[constants_1.Constants.FIRESTORE_EMULATOR_ENV_ALT] = host;
15
+ }
16
+ if (registry_1.EmulatorRegistry.isRunning(types_1.Emulators.STORAGE)) {
17
+ const { host } = registry_1.EmulatorRegistry.url(types_1.Emulators.STORAGE);
18
+ env[constants_1.Constants.FIREBASE_STORAGE_EMULATOR_HOST] = host;
19
+ env[constants_1.Constants.CLOUD_STORAGE_EMULATOR_HOST] = `http://${host}`;
20
+ }
21
+ if (registry_1.EmulatorRegistry.isRunning(types_1.Emulators.AUTH)) {
22
+ env[constants_1.Constants.FIREBASE_AUTH_EMULATOR_HOST] = registry_1.EmulatorRegistry.url(types_1.Emulators.AUTH).host;
23
+ }
24
+ if (registry_1.EmulatorRegistry.isRunning(types_1.Emulators.HUB)) {
25
+ env[constants_1.Constants.FIREBASE_EMULATOR_HUB] = registry_1.EmulatorRegistry.url(types_1.Emulators.HUB).host;
26
+ }
27
+ const pubsubEmulator = registry_1.EmulatorRegistry.isRunning(types_1.Emulators.PUBSUB);
28
+ if (pubsubEmulator) {
29
+ env[constants_1.Constants.PUBSUB_EMULATOR_HOST] = registry_1.EmulatorRegistry.url(types_1.Emulators.PUBSUB).host;
30
+ }
31
+ if (registry_1.EmulatorRegistry.isRunning(types_1.Emulators.EVENTARC)) {
32
+ env[constants_1.Constants.CLOUD_EVENTARC_EMULATOR_HOST] = `http://${registry_1.EmulatorRegistry.url(types_1.Emulators.EVENTARC).host}`;
33
+ }
34
+ }
35
+ exports.setEnvVarsForEmulators = setEnvVarsForEmulators;