firebase-tools 9.17.0 → 9.21.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 (95) hide show
  1. package/CHANGELOG.md +3 -7
  2. package/lib/api.js +1 -0
  3. package/lib/apiv2.js +5 -3
  4. package/lib/appdistribution/client.js +84 -72
  5. package/lib/appdistribution/distribution.js +8 -26
  6. package/lib/appdistribution/options-parser-util.js +51 -0
  7. package/lib/command.js +1 -1
  8. package/lib/commands/appdistribution-distribute.js +74 -91
  9. package/lib/commands/appdistribution-testers-add.js +18 -0
  10. package/lib/commands/appdistribution-testers-remove.js +32 -0
  11. package/lib/commands/crashlytics-symbols-upload.js +146 -0
  12. package/lib/commands/ext-configure.js +9 -1
  13. package/lib/commands/ext-dev-extension-delete.js +2 -1
  14. package/lib/commands/ext-dev-publish.js +11 -4
  15. package/lib/commands/ext-dev-unpublish.js +12 -4
  16. package/lib/commands/ext-install.js +115 -48
  17. package/lib/commands/ext-uninstall.js +6 -0
  18. package/lib/commands/ext-update.js +61 -18
  19. package/lib/commands/functions-config-export.js +115 -0
  20. package/lib/commands/functions-delete.js +45 -25
  21. package/lib/commands/functions-list.js +54 -0
  22. package/lib/commands/functions-log.js +5 -22
  23. package/lib/commands/hosting-channel-deploy.js +6 -4
  24. package/lib/commands/index.js +12 -0
  25. package/lib/deploy/functions/backend.js +118 -121
  26. package/lib/deploy/functions/checkIam.js +8 -8
  27. package/lib/deploy/functions/containerCleaner.js +5 -1
  28. package/lib/deploy/functions/deploy.js +11 -15
  29. package/lib/deploy/functions/functionsDeployHelper.js +3 -68
  30. package/lib/deploy/functions/prepare.js +67 -33
  31. package/lib/deploy/functions/pricing.js +17 -17
  32. package/lib/deploy/functions/prompts.js +24 -41
  33. package/lib/deploy/functions/release/executor.js +39 -0
  34. package/lib/deploy/functions/release/fabricator.js +362 -0
  35. package/lib/deploy/functions/release/index.js +69 -0
  36. package/lib/deploy/functions/release/planner.js +159 -0
  37. package/lib/deploy/functions/release/reporter.js +162 -0
  38. package/lib/deploy/functions/release/sourceTokenScraper.js +28 -0
  39. package/lib/deploy/functions/release/timer.js +14 -0
  40. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +102 -126
  41. package/lib/deploy/functions/runtimes/node/parseTriggers.js +34 -50
  42. package/lib/deploy/functions/triggerRegionHelper.js +40 -0
  43. package/lib/deploy/functions/validate.js +1 -24
  44. package/lib/downloadUtils.js +37 -0
  45. package/lib/emulator/auth/apiSpec.js +1788 -403
  46. package/lib/emulator/auth/handlers.js +6 -5
  47. package/lib/emulator/auth/operations.js +439 -40
  48. package/lib/emulator/auth/server.js +32 -11
  49. package/lib/emulator/auth/state.js +205 -5
  50. package/lib/emulator/auth/widget_ui.js +2 -2
  51. package/lib/emulator/download.js +2 -31
  52. package/lib/emulator/downloadableEmulators.js +7 -7
  53. package/lib/emulator/emulatorLogger.js +0 -3
  54. package/lib/emulator/events/types.js +16 -0
  55. package/lib/emulator/functionsEmulator.js +117 -20
  56. package/lib/emulator/functionsEmulatorRuntime.js +46 -121
  57. package/lib/emulator/functionsEmulatorShared.js +51 -7
  58. package/lib/emulator/functionsEmulatorShell.js +1 -1
  59. package/lib/emulator/pubsubEmulator.js +61 -40
  60. package/lib/emulator/storage/cloudFunctions.js +37 -7
  61. package/lib/extensions/askUserForConsent.js +16 -13
  62. package/lib/extensions/askUserForParam.js +72 -3
  63. package/lib/extensions/billingMigrationHelper.js +1 -11
  64. package/lib/extensions/changelog.js +2 -1
  65. package/lib/extensions/displayExtensionInfo.js +35 -33
  66. package/lib/extensions/emulator/optionsHelper.js +3 -3
  67. package/lib/extensions/emulator/triggerHelper.js +2 -32
  68. package/lib/extensions/extensionsApi.js +67 -94
  69. package/lib/extensions/extensionsHelper.js +49 -35
  70. package/lib/extensions/paramHelper.js +79 -36
  71. package/lib/extensions/refs.js +59 -0
  72. package/lib/extensions/secretsUtils.js +58 -0
  73. package/lib/extensions/updateHelper.js +21 -45
  74. package/lib/extensions/warnings.js +1 -7
  75. package/lib/functional.js +64 -0
  76. package/lib/functions/env.js +26 -13
  77. package/lib/functions/functionslog.js +40 -0
  78. package/lib/functions/runtimeConfigExport.js +137 -0
  79. package/lib/gcp/cloudfunctions.js +46 -38
  80. package/lib/gcp/cloudfunctionsv2.js +47 -47
  81. package/lib/gcp/cloudlogging.js +27 -21
  82. package/lib/gcp/cloudscheduler.js +22 -16
  83. package/lib/gcp/pubsub.js +1 -9
  84. package/lib/gcp/secretManager.js +111 -0
  85. package/lib/gcp/storage.js +16 -0
  86. package/lib/previews.js +1 -1
  87. package/lib/requireInteractive.js +12 -0
  88. package/lib/utils.js +30 -1
  89. package/package.json +5 -4
  90. package/lib/deploy/functions/deploymentPlanner.js +0 -113
  91. package/lib/deploy/functions/deploymentTimer.js +0 -23
  92. package/lib/deploy/functions/errorHandler.js +0 -75
  93. package/lib/deploy/functions/release.js +0 -116
  94. package/lib/deploy/functions/tasks.js +0 -324
  95. package/lib/functionsDelete.js +0 -60
@@ -8,6 +8,7 @@ const express = require("express");
8
8
  const clc = require("cli-color");
9
9
  const http = require("http");
10
10
  const jwt = require("jsonwebtoken");
11
+ const url_1 = require("url");
11
12
  const api = require("../api");
12
13
  const logger_1 = require("../logger");
13
14
  const track = require("../track");
@@ -26,6 +27,8 @@ const workQueue_1 = require("./workQueue");
26
27
  const utils_1 = require("../utils");
27
28
  const defaultCredentials_1 = require("../defaultCredentials");
28
29
  const adminSdkConfig_1 = require("./adminSdkConfig");
30
+ const functionsEnv = require("../functions/env");
31
+ const types_2 = require("./events/types");
29
32
  const EVENT_INVOKE = "functions:invoke";
30
33
  const DATABASE_PATH_PATTERN = new RegExp("^projects/[^/]+/instances/([^/]+)/refs(/.*)$");
31
34
  class FunctionsEmulator {
@@ -88,11 +91,18 @@ class FunctionsEmulator {
88
91
  const multicastFunctionRoute = `/functions/projects/:project_id/trigger_multicast`;
89
92
  const httpsFunctionRoutes = [httpsFunctionRoute, `${httpsFunctionRoute}/*`];
90
93
  const backgroundHandler = (req, res) => {
94
+ var _a;
91
95
  const region = req.params.region;
92
96
  const triggerId = req.params.trigger_name;
93
97
  const projectId = req.params.project_id;
94
98
  const reqBody = req.rawBody;
95
- const proto = JSON.parse(reqBody.toString());
99
+ let proto = JSON.parse(reqBody.toString());
100
+ if ((_a = req.headers["content-type"]) === null || _a === void 0 ? void 0 : _a.includes("cloudevent")) {
101
+ if (types_2.EventUtils.isBinaryCloudEvent(req)) {
102
+ proto = types_2.EventUtils.extractBinaryCloudEventContext(req);
103
+ proto.data = req.body;
104
+ }
105
+ }
96
106
  this.workQueue.submit(() => {
97
107
  this.logger.log("DEBUG", `Accepted request ${req.method} ${req.url} --> ${triggerId}`);
98
108
  return this.handleBackgroundTrigger(projectId, triggerId, proto)
@@ -113,10 +123,22 @@ class FunctionsEmulator {
113
123
  });
114
124
  };
115
125
  const multicastHandler = (req, res) => {
116
- const reqBody = req.rawBody;
117
- const proto = JSON.parse(reqBody.toString());
118
- const triggers = this.multicastTriggers[`${this.args.projectId}:${proto.eventType}`] || [];
126
+ var _a;
119
127
  const projectId = req.params.project_id;
128
+ const reqBody = req.rawBody;
129
+ let proto = JSON.parse(reqBody.toString());
130
+ let triggerKey;
131
+ if ((_a = req.headers["content-type"]) === null || _a === void 0 ? void 0 : _a.includes("cloudevent")) {
132
+ triggerKey = `${this.args.projectId}:${proto.type}`;
133
+ if (types_2.EventUtils.isBinaryCloudEvent(req)) {
134
+ proto = types_2.EventUtils.extractBinaryCloudEventContext(req);
135
+ proto.data = req.body;
136
+ }
137
+ }
138
+ else {
139
+ triggerKey = `${this.args.projectId}:${proto.eventType}`;
140
+ }
141
+ const triggers = this.multicastTriggers[triggerKey] || [];
120
142
  triggers.forEach((triggerId) => {
121
143
  this.workQueue.submit(() => {
122
144
  this.logger.log("DEBUG", `Accepted multicast request ${req.method} ${req.url} --> ${triggerId}`);
@@ -134,7 +156,7 @@ class FunctionsEmulator {
134
156
  });
135
157
  return hub;
136
158
  }
137
- startFunctionRuntime(triggerId, targetName, triggerType, proto, runtimeOpts) {
159
+ startFunctionRuntime(triggerId, targetName, signatureType, proto, runtimeOpts) {
138
160
  const bundleTemplate = this.getBaseBundle();
139
161
  const runtimeBundle = Object.assign(Object.assign({}, bundleTemplate), { emulators: {
140
162
  firestore: this.getEmulatorInfo(types_1.Emulators.FIRESTORE),
@@ -144,14 +166,12 @@ class FunctionsEmulator {
144
166
  storage: this.getEmulatorInfo(types_1.Emulators.STORAGE),
145
167
  }, nodeMajorVersion: this.args.nodeMajorVersion, proto,
146
168
  triggerId,
147
- targetName,
148
- triggerType });
169
+ targetName });
149
170
  const opts = runtimeOpts || {
150
171
  nodeBinary: this.nodeBinary,
151
- env: this.args.env,
152
172
  extensionTriggers: this.args.predefinedTriggers,
153
173
  };
154
- const worker = this.invokeRuntime(runtimeBundle, opts);
174
+ const worker = this.invokeRuntime(runtimeBundle, opts, this.getRuntimeEnvs({ targetName, signatureType }));
155
175
  return worker;
156
176
  }
157
177
  async start() {
@@ -206,9 +226,8 @@ class FunctionsEmulator {
206
226
  this.workerPool.refresh();
207
227
  const worker = this.invokeRuntime(this.getBaseBundle(), {
208
228
  nodeBinary: this.nodeBinary,
209
- env: this.args.env,
210
229
  extensionTriggers: this.args.predefinedTriggers,
211
- });
230
+ }, Object.assign(Object.assign(Object.assign(Object.assign({}, this.getSystemEnvs()), this.getEmulatorEnvs()), { FIREBASE_CONFIG: this.getFirebaseConfig() }), this.args.env));
212
231
  const triggerParseEvent = await types_1.EmulatorLog.waitForLog(worker.runtime.events, "SYSTEM", "triggers-parsed");
213
232
  const parsedDefinitions = triggerParseEvent.data
214
233
  .triggerDefinitions;
@@ -238,6 +257,7 @@ class FunctionsEmulator {
238
257
  else if (definition.eventTrigger) {
239
258
  const service = functionsEmulatorShared_1.getFunctionService(definition);
240
259
  const key = this.getTriggerKey(definition);
260
+ const signature = functionsEmulatorShared_1.getSignatureType(definition);
241
261
  switch (service) {
242
262
  case constants_1.Constants.SERVICE_FIRESTORE:
243
263
  added = await this.addFirestoreTrigger(this.args.projectId, key, definition.eventTrigger);
@@ -246,7 +266,7 @@ class FunctionsEmulator {
246
266
  added = await this.addRealtimeDatabaseTrigger(this.args.projectId, key, definition.eventTrigger);
247
267
  break;
248
268
  case constants_1.Constants.SERVICE_PUBSUB:
249
- added = await this.addPubsubTrigger(definition.name, key, definition.eventTrigger, definition.schedule);
269
+ added = await this.addPubsubTrigger(definition.name, key, definition.eventTrigger, signature, definition.schedule);
250
270
  break;
251
271
  case constants_1.Constants.SERVICE_AUTH:
252
272
  added = this.addAuthTrigger(this.args.projectId, key, definition.eventTrigger);
@@ -342,7 +362,7 @@ class FunctionsEmulator {
342
362
  throw err;
343
363
  });
344
364
  }
345
- async addPubsubTrigger(triggerName, key, eventTrigger, schedule) {
365
+ async addPubsubTrigger(triggerName, key, eventTrigger, signatureType, schedule) {
346
366
  const pubsubPort = registry_1.EmulatorRegistry.getPort(types_1.Emulators.PUBSUB);
347
367
  if (!pubsubPort) {
348
368
  return false;
@@ -359,7 +379,7 @@ class FunctionsEmulator {
359
379
  topic = resourceParts[resourceParts.length - 1];
360
380
  }
361
381
  try {
362
- await pubsubEmulator.addTrigger(topic, key);
382
+ await pubsubEmulator.addTrigger(topic, key, signatureType);
363
383
  return true;
364
384
  }
365
385
  catch (e) {
@@ -424,7 +444,6 @@ class FunctionsEmulator {
424
444
  projectId: this.args.projectId,
425
445
  triggerId: "",
426
446
  targetName: "",
427
- triggerType: undefined,
428
447
  emulators: {
429
448
  firestore: registry_1.EmulatorRegistry.getInfo(types_1.Emulators.FIRESTORE),
430
449
  database: registry_1.EmulatorRegistry.getInfo(types_1.Emulators.DATABASE),
@@ -473,7 +492,85 @@ class FunctionsEmulator {
473
492
  this.logger.log("WARN", `Your requested "node" version "${requestedMajorVersion}" doesn't match your global version "${hostMajorVersion}"`);
474
493
  return process.execPath;
475
494
  }
476
- invokeRuntime(frb, opts) {
495
+ getUserEnvs() {
496
+ const projectInfo = {
497
+ functionsSource: this.args.functionsDir,
498
+ projectId: this.args.projectId,
499
+ isEmulator: true,
500
+ };
501
+ if (functionsEnv.hasUserEnvs(projectInfo)) {
502
+ try {
503
+ return functionsEnv.loadUserEnvs(projectInfo);
504
+ }
505
+ catch (e) {
506
+ logger_1.logger.debug("Failed to load local environment variables", e);
507
+ }
508
+ }
509
+ return {};
510
+ }
511
+ getSystemEnvs(triggerDef) {
512
+ const envs = {};
513
+ envs.GCLOUD_PROJECT = this.args.projectId;
514
+ envs.K_REVISION = "1";
515
+ envs.PORT = "80";
516
+ if (triggerDef) {
517
+ const service = triggerDef.targetName;
518
+ const target = service.replace(/-/g, ".");
519
+ envs.FUNCTION_TARGET = target;
520
+ envs.FUNCTION_SIGNATURE_TYPE = triggerDef.signatureType;
521
+ envs.K_SERVICE = service;
522
+ }
523
+ return envs;
524
+ }
525
+ getEmulatorEnvs() {
526
+ const envs = {};
527
+ envs.FUNCTIONS_EMULATOR = "true";
528
+ envs.TZ = "UTC";
529
+ const firestoreEmulator = this.getEmulatorInfo(types_1.Emulators.FIRESTORE);
530
+ if (firestoreEmulator != null) {
531
+ envs[constants_1.Constants.FIRESTORE_EMULATOR_HOST] = functionsEmulatorShared_1.formatHost(firestoreEmulator);
532
+ }
533
+ const databaseEmulator = this.getEmulatorInfo(types_1.Emulators.DATABASE);
534
+ if (databaseEmulator) {
535
+ envs[constants_1.Constants.FIREBASE_DATABASE_EMULATOR_HOST] = functionsEmulatorShared_1.formatHost(databaseEmulator);
536
+ }
537
+ const authEmulator = this.getEmulatorInfo(types_1.Emulators.AUTH);
538
+ if (authEmulator) {
539
+ envs[constants_1.Constants.FIREBASE_AUTH_EMULATOR_HOST] = functionsEmulatorShared_1.formatHost(authEmulator);
540
+ }
541
+ const storageEmulator = this.getEmulatorInfo(types_1.Emulators.STORAGE);
542
+ if (storageEmulator) {
543
+ envs[constants_1.Constants.FIREBASE_STORAGE_EMULATOR_HOST] = functionsEmulatorShared_1.formatHost(storageEmulator);
544
+ envs[constants_1.Constants.CLOUD_STORAGE_EMULATOR_HOST] = `http://${functionsEmulatorShared_1.formatHost(storageEmulator)}`;
545
+ }
546
+ const pubsubEmulator = this.getEmulatorInfo(types_1.Emulators.PUBSUB);
547
+ if (pubsubEmulator) {
548
+ const pubsubHost = functionsEmulatorShared_1.formatHost(pubsubEmulator);
549
+ process.env.PUBSUB_EMULATOR_HOST = pubsubHost;
550
+ }
551
+ return envs;
552
+ }
553
+ getFirebaseConfig() {
554
+ const databaseEmulator = this.getEmulatorInfo(types_1.Emulators.DATABASE);
555
+ let emulatedDatabaseURL = undefined;
556
+ if (databaseEmulator) {
557
+ let ns = this.args.projectId;
558
+ if (this.adminSdkConfig.databaseURL) {
559
+ const asUrl = new url_1.URL(this.adminSdkConfig.databaseURL);
560
+ ns = asUrl.hostname.split(".")[0];
561
+ }
562
+ emulatedDatabaseURL = `http://${functionsEmulatorShared_1.formatHost(databaseEmulator)}/?ns=${ns}`;
563
+ }
564
+ return JSON.stringify({
565
+ storageBucket: this.adminSdkConfig.storageBucket,
566
+ databaseURL: emulatedDatabaseURL || this.adminSdkConfig.databaseURL,
567
+ projectId: this.args.projectId,
568
+ });
569
+ }
570
+ getRuntimeEnvs(triggerDef) {
571
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, this.getUserEnvs()), this.getSystemEnvs(triggerDef)), this.getEmulatorEnvs()), { FIREBASE_CONFIG: this.getFirebaseConfig() }), this.args.env);
572
+ }
573
+ invokeRuntime(frb, opts, runtimeEnv) {
477
574
  if (this.workerPool.readyForWork(frb.triggerId)) {
478
575
  return this.workerPool.submitWork(frb.triggerId, frb, opts);
479
576
  }
@@ -499,7 +596,7 @@ class FunctionsEmulator {
499
596
  "See https://yarnpkg.com/getting-started/migration#step-by-step for more information.");
500
597
  }
501
598
  const childProcess = spawn(opts.nodeBinary, args, {
502
- env: Object.assign(Object.assign({ node: opts.nodeBinary }, opts.env), process.env),
599
+ env: Object.assign(Object.assign({ node: opts.nodeBinary }, process.env), (runtimeEnv !== null && runtimeEnv !== void 0 ? runtimeEnv : {})),
503
600
  cwd: frb.cwd,
504
601
  stdio: ["pipe", "pipe", "pipe", "ipc"],
505
602
  });
@@ -559,7 +656,7 @@ class FunctionsEmulator {
559
656
  }
560
657
  const trigger = this.getTriggerDefinitionByKey(triggerKey);
561
658
  const service = functionsEmulatorShared_1.getFunctionService(trigger);
562
- const worker = this.startFunctionRuntime(trigger.id, trigger.name, functionsEmulatorShared_1.EmulatedTriggerType.BACKGROUND, proto);
659
+ const worker = this.startFunctionRuntime(trigger.id, trigger.name, functionsEmulatorShared_1.getSignatureType(trigger), proto);
563
660
  return new Promise((resolve, reject) => {
564
661
  if (projectId !== this.args.projectId) {
565
662
  if (service !== constants_1.Constants.SERVICE_REALTIME_DATABASE) {
@@ -645,7 +742,7 @@ class FunctionsEmulator {
645
742
  req.headers[functionsEmulatorShared_1.HttpConstants.CALLABLE_AUTH_HEADER] = encodeURIComponent(JSON.stringify(contextAuth));
646
743
  }
647
744
  }
648
- const worker = this.startFunctionRuntime(trigger.id, trigger.name, functionsEmulatorShared_1.EmulatedTriggerType.HTTPS, undefined);
745
+ const worker = this.startFunctionRuntime(trigger.id, trigger.name, "http", undefined);
649
746
  worker.onLogs((el) => {
650
747
  if (el.level === "FATAL") {
651
748
  res.status(500).send(el.text);
@@ -660,7 +757,7 @@ class FunctionsEmulator {
660
757
  if (!worker.lastArgs.frb.socketPath) {
661
758
  throw new error_1.FirebaseError(`Cannot execute on a worker without a socketPath: ${JSON.stringify(worker.lastArgs)}`);
662
759
  }
663
- const url = new URL(`${req.protocol}://${req.hostname}${req.url}`);
760
+ const url = new url_1.URL(`${req.protocol}://${req.hostname}${req.url}`);
664
761
  const path = `${url.pathname}${url.search}`.replace(new RegExp(`\/${this.args.projectId}\/[^\/]*\/${triggerName}\/?`), "/");
665
762
  this.logger.log("DEBUG", `[functions] Got req.url=${req.url}, mapping to path=${path}`);
666
763
  const runtimeReq = http.request({
@@ -1,15 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const functionsEnv = require("../functions/env");
4
- const error_1 = require("../error");
5
3
  const types_1 = require("./types");
6
4
  const functionsEmulatorShared_1 = require("./functionsEmulatorShared");
7
- const constants_1 = require("./constants");
8
5
  const functionsEmulatorUtils_1 = require("./functionsEmulatorUtils");
9
6
  const express = require("express");
10
7
  const path = require("path");
11
8
  const bodyParser = require("body-parser");
12
- const fs = require("fs");
13
9
  const url_1 = require("url");
14
10
  const _ = require("lodash");
15
11
  let triggers;
@@ -263,13 +259,35 @@ async function initializeFirebaseFunctionsStubs(frb) {
263
259
  };
264
260
  const onCallInnerMethodName = "_onCallWithOptions";
265
261
  const onCallMethodOriginal = httpsProvider[onCallInnerMethodName];
266
- httpsProvider[onCallInnerMethodName] = (handler, opts) => {
267
- const wrapped = wrapCallableHandler(handler);
268
- const cf = onCallMethodOriginal(wrapped, opts);
269
- return cf;
270
- };
271
- httpsProvider.onCall = (handler) => {
272
- return httpsProvider[onCallInnerMethodName](handler, {});
262
+ if (onCallMethodOriginal.length === 3) {
263
+ httpsProvider[onCallInnerMethodName] = (opts, handler, deployOpts) => {
264
+ const wrapped = wrapCallableHandler(handler);
265
+ const cf = onCallMethodOriginal(opts, wrapped, deployOpts);
266
+ return cf;
267
+ };
268
+ }
269
+ else {
270
+ httpsProvider[onCallInnerMethodName] = (handler, opts) => {
271
+ const wrapped = wrapCallableHandler(handler);
272
+ const cf = onCallMethodOriginal(wrapped, opts);
273
+ return cf;
274
+ };
275
+ }
276
+ httpsProvider.onCall = function (optsOrHandler, handler) {
277
+ if (onCallMethodOriginal.length === 3) {
278
+ let opts;
279
+ if (arguments.length === 1) {
280
+ opts = {};
281
+ handler = optsOrHandler;
282
+ }
283
+ else {
284
+ opts = optsOrHandler;
285
+ }
286
+ return httpsProvider[onCallInnerMethodName](opts, handler, {});
287
+ }
288
+ else {
289
+ return httpsProvider[onCallInnerMethodName](optsOrHandler, {});
290
+ }
273
291
  };
274
292
  }
275
293
  function wrapCallableHandler(handler) {
@@ -393,108 +411,6 @@ function warnAboutAuthProd(frb) {
393
411
  }
394
412
  new types_1.EmulatorLog("WARN_ONCE", "runtime-status", "The Firebase Authentication emulator is not running, so calls to Firebase Authentication will affect production.").log();
395
413
  }
396
- async function initializeEnvironmentalVariables(frb) {
397
- var _a;
398
- process.env.TZ = "UTC";
399
- process.env.GCLOUD_PROJECT = frb.projectId;
400
- process.env.FUNCTIONS_EMULATOR = "true";
401
- if (functionsEnv.hasUserEnvs({ functionsSource: frb.cwd, projectId: "local" })) {
402
- try {
403
- const userEnvs = functionsEnv.loadUserEnvs({ functionsSource: frb.cwd, projectId: "local" });
404
- for (const [k, v] of Object.entries(userEnvs)) {
405
- process.env[k] = v;
406
- }
407
- }
408
- catch (e) {
409
- let message = e.message || `${e}`;
410
- if (e instanceof error_1.FirebaseError) {
411
- for (const child of e.children) {
412
- if (child instanceof Error) {
413
- message += `\n- ${child.message}`;
414
- }
415
- }
416
- }
417
- new types_1.EmulatorLog("SYSTEM", "function-env-load-failed", message).log();
418
- }
419
- }
420
- const configPath = `${frb.cwd}/.runtimeconfig.json`;
421
- try {
422
- const configContent = fs.readFileSync(configPath, "utf8");
423
- if (configContent) {
424
- try {
425
- JSON.parse(configContent.toString());
426
- logDebug(`Found local functions config: ${configPath}`);
427
- process.env.CLOUD_RUNTIME_CONFIG = configContent.toString();
428
- }
429
- catch (e) {
430
- new types_1.EmulatorLog("SYSTEM", "function-runtimeconfig-json-invalid", "").log();
431
- }
432
- }
433
- }
434
- catch (e) {
435
- }
436
- const functionsResolution = await assertResolveDeveloperNodeModule(frb, "firebase-functions");
437
- const functionsGt380 = functionsEmulatorUtils_1.compareVersionStrings(functionsResolution.version, "3.8.0") >= 0;
438
- let emulatedDatabaseURL = undefined;
439
- if (frb.emulators.database && functionsGt380) {
440
- let ns = frb.projectId;
441
- if (frb.adminSdkConfig.databaseURL) {
442
- const asUrl = new url_1.URL(frb.adminSdkConfig.databaseURL);
443
- ns = asUrl.hostname.split(".")[0];
444
- }
445
- emulatedDatabaseURL = `http://${formatHost(frb.emulators.database)}/?ns=${ns}`;
446
- }
447
- process.env.FIREBASE_CONFIG = JSON.stringify({
448
- storageBucket: frb.adminSdkConfig.storageBucket,
449
- databaseURL: emulatedDatabaseURL || frb.adminSdkConfig.databaseURL,
450
- projectId: frb.projectId,
451
- });
452
- if (frb.triggerId) {
453
- const service = frb.targetName || "";
454
- const target = service.replace(/-/g, ".");
455
- const mode = frb.triggerType === functionsEmulatorShared_1.EmulatedTriggerType.BACKGROUND ? "event" : "http";
456
- let nodeVersion = 0;
457
- if (frb.nodeMajorVersion) {
458
- nodeVersion = frb.nodeMajorVersion;
459
- }
460
- else {
461
- const pkg = requirePackageJson(frb);
462
- if ((_a = pkg === null || pkg === void 0 ? void 0 : pkg.engines) === null || _a === void 0 ? void 0 : _a.node) {
463
- const nodeSemVer = functionsEmulatorUtils_1.parseVersionString(pkg.engines.node);
464
- nodeVersion = nodeSemVer.major;
465
- }
466
- }
467
- if (nodeVersion >= 10) {
468
- setNode10EnvVars(target, mode, service);
469
- }
470
- }
471
- if (frb.emulators.firestore) {
472
- process.env[constants_1.Constants.FIRESTORE_EMULATOR_HOST] = formatHost(frb.emulators.firestore);
473
- }
474
- if (frb.emulators.database) {
475
- process.env[constants_1.Constants.FIREBASE_DATABASE_EMULATOR_HOST] = formatHost(frb.emulators.database);
476
- }
477
- if (frb.emulators.auth) {
478
- process.env[constants_1.Constants.FIREBASE_AUTH_EMULATOR_HOST] = formatHost(frb.emulators.auth);
479
- }
480
- if (frb.emulators.storage) {
481
- process.env[constants_1.Constants.FIREBASE_STORAGE_EMULATOR_HOST] = formatHost(frb.emulators.storage);
482
- process.env[constants_1.Constants.CLOUD_STORAGE_EMULATOR_HOST] = `http://${formatHost(frb.emulators.storage)}`;
483
- }
484
- if (frb.emulators.pubsub) {
485
- const pubsubHost = formatHost(frb.emulators.pubsub);
486
- process.env.PUBSUB_EMULATOR_HOST = pubsubHost;
487
- logDebug(`Set PUBSUB_EMULATOR_HOST to ${pubsubHost}`);
488
- }
489
- }
490
- function formatHost(info) {
491
- if (info.host.includes(":")) {
492
- return `[${info.host}]:${info.port}`;
493
- }
494
- else {
495
- return `${info.host}:${info.port}`;
496
- }
497
- }
498
414
  async function initializeFunctionsConfigHelper(frb) {
499
415
  const functionsResolution = await assertResolveDeveloperNodeModule(frb, "firebase-functions");
500
416
  const localFunctionsModule = require(functionsResolution.resolution);
@@ -594,9 +510,12 @@ async function processHTTPS(frb, trigger) {
594
510
  instance.on("error", rejectEphemeralServer);
595
511
  });
596
512
  }
597
- async function processBackground(frb, trigger) {
513
+ async function processBackground(frb, trigger, signature) {
598
514
  const proto = frb.proto;
599
515
  logDebug("ProcessBackground", proto);
516
+ if (signature === "cloudevent") {
517
+ return runCloudEvent(proto, trigger.getRawFunction());
518
+ }
600
519
  const data = proto.data;
601
520
  delete proto.data;
602
521
  const context = proto.context ? proto.context : proto;
@@ -627,6 +546,12 @@ async function runBackground(proto, func) {
627
546
  return func(proto.data, proto.context);
628
547
  });
629
548
  }
549
+ async function runCloudEvent(event, func) {
550
+ logDebug("RunCloudEvent", event);
551
+ await runFunction(() => {
552
+ return func(event);
553
+ });
554
+ }
630
555
  async function runHTTPS(args, func) {
631
556
  if (args.length < 2) {
632
557
  throw new Error("Function must be passed 2 args.");
@@ -665,8 +590,8 @@ async function invokeTrigger(frb, triggers) {
665
590
  }).log();
666
591
  const trigger = triggers[frb.triggerId];
667
592
  logDebug("triggerDefinition", trigger.definition);
668
- const mode = trigger.definition.httpsTrigger ? "HTTPS" : "BACKGROUND";
669
- logDebug(`Running ${frb.triggerId} in mode ${mode}`);
593
+ const signature = functionsEmulatorShared_1.getSignatureType(trigger.definition);
594
+ logDebug(`Running ${frb.triggerId} in signature ${signature}`);
670
595
  let seconds = 0;
671
596
  const timerId = setInterval(() => {
672
597
  seconds++;
@@ -679,11 +604,12 @@ async function invokeTrigger(frb, triggers) {
679
604
  throw new Error("Function timed out.");
680
605
  }, trigger.timeoutMs);
681
606
  }
682
- switch (mode) {
683
- case "BACKGROUND":
684
- await processBackground(frb, triggers[frb.triggerId]);
607
+ switch (signature) {
608
+ case "event":
609
+ case "cloudevent":
610
+ await processBackground(frb, triggers[frb.triggerId], signature);
685
611
  break;
686
- case "HTTPS":
612
+ case "http":
687
613
  await processHTTPS(frb, triggers[frb.triggerId]);
688
614
  break;
689
615
  }
@@ -700,7 +626,6 @@ async function initializeRuntime(frb, serializedFunctionTrigger, extensionTrigge
700
626
  new types_1.EmulatorLog("INFO", "runtime-status", `Your functions could not be parsed due to an issue with your node_modules (see above)`).log();
701
627
  return;
702
628
  }
703
- await initializeEnvironmentalVariables(frb);
704
629
  initializeNetworkFiltering(frb);
705
630
  await initializeFunctionsConfigHelper(frb);
706
631
  await initializeFirebaseFunctionsStubs(frb);
@@ -1,15 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.findModuleRoot = exports.waitForBody = exports.getFunctionService = exports.getTemporarySocketPath = exports.getEmulatedTriggersFromDefinitions = exports.emulatedFunctionsByRegion = exports.EmulatedTrigger = exports.HttpConstants = exports.EmulatedTriggerType = void 0;
3
+ exports.getSignatureType = exports.formatHost = exports.findModuleRoot = exports.waitForBody = exports.getServiceFromEventType = exports.getFunctionService = exports.getTemporarySocketPath = exports.getEmulatedTriggersFromDefinitions = exports.emulatedFunctionsByRegion = exports.EmulatedTrigger = exports.HttpConstants = void 0;
4
4
  const _ = require("lodash");
5
5
  const os = require("os");
6
6
  const path = require("path");
7
7
  const fs = require("fs");
8
- var EmulatedTriggerType;
9
- (function (EmulatedTriggerType) {
10
- EmulatedTriggerType["BACKGROUND"] = "BACKGROUND";
11
- EmulatedTriggerType["HTTPS"] = "HTTPS";
12
- })(EmulatedTriggerType = exports.EmulatedTriggerType || (exports.EmulatedTriggerType = {}));
8
+ const constants_1 = require("./constants");
13
9
  const memoryLookup = {
14
10
  "128MB": 128,
15
11
  "256MB": 256,
@@ -82,12 +78,44 @@ function getTemporarySocketPath(pid, cwd) {
82
78
  }
83
79
  exports.getTemporarySocketPath = getTemporarySocketPath;
84
80
  function getFunctionService(def) {
81
+ var _a;
85
82
  if (def.eventTrigger) {
86
- return def.eventTrigger.service;
83
+ return (_a = def.eventTrigger.service) !== null && _a !== void 0 ? _a : getServiceFromEventType(def.eventTrigger.eventType);
87
84
  }
88
85
  return "unknown";
89
86
  }
90
87
  exports.getFunctionService = getFunctionService;
88
+ function getServiceFromEventType(eventType) {
89
+ if (eventType.includes("firestore")) {
90
+ return constants_1.Constants.SERVICE_FIRESTORE;
91
+ }
92
+ if (eventType.includes("database")) {
93
+ return constants_1.Constants.SERVICE_REALTIME_DATABASE;
94
+ }
95
+ if (eventType.includes("pubsub")) {
96
+ return constants_1.Constants.SERVICE_PUBSUB;
97
+ }
98
+ if (eventType.includes("storage")) {
99
+ return constants_1.Constants.SERVICE_STORAGE;
100
+ }
101
+ if (eventType.includes("analytics")) {
102
+ return constants_1.Constants.SERVICE_ANALYTICS;
103
+ }
104
+ if (eventType.includes("auth")) {
105
+ return constants_1.Constants.SERVICE_AUTH;
106
+ }
107
+ if (eventType.includes("crashlytics")) {
108
+ return constants_1.Constants.SERVICE_CRASHLYTICS;
109
+ }
110
+ if (eventType.includes("remoteconfig")) {
111
+ return constants_1.Constants.SERVICE_REMOTE_CONFIG;
112
+ }
113
+ if (eventType.includes("testing")) {
114
+ return constants_1.Constants.SERVICE_TEST_LAB;
115
+ }
116
+ return "";
117
+ }
118
+ exports.getServiceFromEventType = getServiceFromEventType;
91
119
  function waitForBody(req) {
92
120
  let data = "";
93
121
  return new Promise((resolve) => {
@@ -124,3 +152,19 @@ function findModuleRoot(moduleName, filepath) {
124
152
  return "";
125
153
  }
126
154
  exports.findModuleRoot = findModuleRoot;
155
+ function formatHost(info) {
156
+ if (info.host.includes(":")) {
157
+ return `[${info.host}]:${info.port}`;
158
+ }
159
+ else {
160
+ return `${info.host}:${info.port}`;
161
+ }
162
+ }
163
+ exports.formatHost = formatHost;
164
+ function getSignatureType(def) {
165
+ if (def.httpsTrigger) {
166
+ return "http";
167
+ }
168
+ return def.platform === "gcfv2" ? "cloudevent" : "event";
169
+ }
170
+ exports.getSignatureType = getSignatureType;
@@ -42,7 +42,7 @@ class FunctionsEmulatorShell {
42
42
  auth: opts.auth,
43
43
  data,
44
44
  };
45
- this.emu.startFunctionRuntime(trigger.id, trigger.name, functionsEmulatorShared_1.EmulatedTriggerType.BACKGROUND, proto);
45
+ this.emu.startFunctionRuntime(trigger.id, trigger.name, functionsEmulatorShared_1.getSignatureType(trigger), proto);
46
46
  }
47
47
  getTrigger(name) {
48
48
  const result = this.triggers.find((trigger) => {