firebase-tools 10.1.3 → 10.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/lib/api.js +1 -0
  2. package/lib/apiv2.js +4 -0
  3. package/lib/auth.js +62 -25
  4. package/lib/commands/auth-import.js +1 -1
  5. package/lib/commands/ext-configure.js +1 -0
  6. package/lib/commands/ext-install.js +1 -0
  7. package/lib/commands/ext-uninstall.js +1 -0
  8. package/lib/commands/ext-update.js +1 -0
  9. package/lib/commands/functions-config-clone.js +1 -1
  10. package/lib/commands/functions-secrets-access.js +17 -0
  11. package/lib/commands/functions-secrets-destroy.js +40 -0
  12. package/lib/commands/functions-secrets-get.js +21 -0
  13. package/lib/commands/functions-secrets-prune.js +50 -0
  14. package/lib/commands/functions-secrets-set.js +46 -0
  15. package/lib/commands/index.js +7 -3
  16. package/lib/commands/login.js +1 -1
  17. package/lib/deploy/functions/backend.js +9 -1
  18. package/lib/deploy/functions/ensure.js +112 -0
  19. package/lib/deploy/functions/ensureCloudBuildEnabled.js +0 -49
  20. package/lib/deploy/functions/prepare.js +12 -18
  21. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +1 -0
  22. package/lib/deploy/functions/runtimes/node/parseTriggers.js +12 -0
  23. package/lib/deploy/functions/validate.js +56 -1
  24. package/lib/deploy/hosting/client.js +9 -0
  25. package/lib/deploy/hosting/convertConfig.js +6 -0
  26. package/lib/deploy/hosting/index.js +5 -5
  27. package/lib/deploy/hosting/prepare.js +25 -25
  28. package/lib/deploy/hosting/release.js +21 -24
  29. package/lib/emulator/commandUtils.js +5 -1
  30. package/lib/emulator/controller.js +3 -1
  31. package/lib/emulator/downloadableEmulators.js +29 -12
  32. package/lib/emulator/emulatorLogger.js +7 -0
  33. package/lib/emulator/functionsEmulator.js +122 -80
  34. package/lib/emulator/functionsEmulatorRuntime.js +100 -83
  35. package/lib/emulator/functionsEmulatorShared.js +51 -1
  36. package/lib/emulator/functionsEmulatorShell.js +1 -2
  37. package/lib/emulator/functionsRuntimeWorker.js +1 -1
  38. package/lib/emulator/storage/apis/gcloud.js +2 -2
  39. package/lib/emulator/storage/files.js +8 -3
  40. package/lib/extensions/askUserForParam.js +1 -1
  41. package/lib/extensions/diagnose.js +56 -0
  42. package/lib/extensions/extensionsHelper.js +10 -17
  43. package/lib/extensions/listExtensions.js +2 -0
  44. package/lib/extensions/resolveSource.js +1 -53
  45. package/lib/extensions/secretsUtils.js +1 -1
  46. package/lib/extensions/updateHelper.js +0 -14
  47. package/lib/extensions/utils.js +4 -2
  48. package/lib/functions/env.js +5 -7
  49. package/lib/functions/secrets.js +112 -0
  50. package/lib/gcp/cloudfunctions.js +2 -2
  51. package/lib/gcp/secretManager.js +128 -46
  52. package/lib/gcp/storage.js +5 -3
  53. package/lib/hosting/functionsProxy.js +15 -5
  54. package/lib/previews.js +1 -1
  55. package/lib/responseToError.js +16 -7
  56. package/lib/serve/functions.js +2 -2
  57. package/lib/serve/hosting.js +1 -1
  58. package/lib/utils.js +6 -1
  59. package/npm-shrinkwrap.json +124 -45
  60. package/package.json +4 -4
  61. package/schema/firebase-config.json +27 -0
@@ -27,10 +27,14 @@ const workQueue_1 = require("./workQueue");
27
27
  const utils_1 = require("../utils");
28
28
  const defaultCredentials_1 = require("../defaultCredentials");
29
29
  const adminSdkConfig_1 = require("./adminSdkConfig");
30
- const functionsEnv = require("../functions/env");
31
30
  const types_2 = require("./events/types");
32
31
  const validate_1 = require("../deploy/functions/validate");
32
+ const runtimes_1 = require("../deploy/functions/runtimes");
33
+ const backend = require("../deploy/functions/backend");
34
+ const functionsEnv = require("../functions/env");
35
+ const secretManager_1 = require("../gcp/secretManager");
33
36
  const EVENT_INVOKE = "functions:invoke";
37
+ const LOCAL_SECRETS_FILE = ".secret.local";
34
38
  const DATABASE_PATH_PATTERN = new RegExp("^projects/[^/]+/instances/([^/]+)/refs(/.*)$");
35
39
  class FunctionsEmulator {
36
40
  constructor(args) {
@@ -44,9 +48,7 @@ class FunctionsEmulator {
44
48
  this.args.disabledRuntimeFeatures = this.args.disabledRuntimeFeatures || {};
45
49
  this.args.disabledRuntimeFeatures.timeout = true;
46
50
  }
47
- this.adminSdkConfig = {
48
- projectId: this.args.projectId,
49
- };
51
+ this.adminSdkConfig = Object.assign(Object.assign({}, this.args.adminSdkConfig), { projectId: this.args.projectId });
50
52
  const mode = this.args.debugPort
51
53
  ? types_1.FunctionsExecutionMode.SEQUENTIAL
52
54
  : types_1.FunctionsExecutionMode.AUTO;
@@ -159,25 +161,17 @@ class FunctionsEmulator {
159
161
  });
160
162
  return hub;
161
163
  }
162
- startFunctionRuntime(backend, triggerId, targetName, signatureType, proto, runtimeOpts) {
163
- const bundleTemplate = this.getBaseBundle(backend);
164
- const runtimeBundle = Object.assign(Object.assign({}, bundleTemplate), { emulators: {
165
- firestore: this.getEmulatorInfo(types_1.Emulators.FIRESTORE),
166
- database: this.getEmulatorInfo(types_1.Emulators.DATABASE),
167
- pubsub: this.getEmulatorInfo(types_1.Emulators.PUBSUB),
168
- auth: this.getEmulatorInfo(types_1.Emulators.AUTH),
169
- storage: this.getEmulatorInfo(types_1.Emulators.STORAGE),
170
- }, nodeMajorVersion: backend.nodeMajorVersion, proto,
171
- triggerId,
172
- targetName });
164
+ async startFunctionRuntime(backend, trigger, proto, runtimeOpts) {
165
+ const bundleTemplate = this.getBaseBundle();
166
+ const runtimeBundle = Object.assign(Object.assign({}, bundleTemplate), { proto });
173
167
  if (!backend.nodeBinary) {
174
- throw new error_1.FirebaseError(`No node binary for ${triggerId}. This should never happen.`);
168
+ throw new error_1.FirebaseError(`No node binary for ${trigger.id}. This should never happen.`);
175
169
  }
176
170
  const opts = runtimeOpts || {
177
171
  nodeBinary: backend.nodeBinary,
178
172
  extensionTriggers: backend.predefinedTriggers,
179
173
  };
180
- const worker = this.invokeRuntime(runtimeBundle, opts, this.getRuntimeEnvs(backend, { targetName, signatureType }));
174
+ const worker = await this.invokeRuntime(backend, trigger, runtimeBundle, opts);
181
175
  return worker;
182
176
  }
183
177
  async start() {
@@ -188,13 +182,15 @@ class FunctionsEmulator {
188
182
  for (const e of this.args.emulatableBackends) {
189
183
  e.env = Object.assign(Object.assign({}, credentialEnv), e.env);
190
184
  }
191
- const adminSdkConfig = await (0, adminSdkConfig_1.getProjectAdminSdkConfigOrCached)(this.args.projectId);
192
- if (adminSdkConfig) {
193
- this.adminSdkConfig = adminSdkConfig;
194
- }
195
- else {
196
- this.logger.logLabeled("WARN", "functions", "Unable to fetch project Admin SDK configuration, Admin SDK behavior in Cloud Functions emulator may be incorrect.");
197
- this.adminSdkConfig = (0, adminSdkConfig_1.constructDefaultAdminSdkConfig)(this.args.projectId);
185
+ if (Object.keys(this.adminSdkConfig || {}).length <= 1) {
186
+ const adminSdkConfig = await (0, adminSdkConfig_1.getProjectAdminSdkConfigOrCached)(this.args.projectId);
187
+ if (adminSdkConfig) {
188
+ this.adminSdkConfig = adminSdkConfig;
189
+ }
190
+ else {
191
+ this.logger.logLabeled("WARN", "functions", "Unable to fetch project Admin SDK configuration, Admin SDK behavior in Cloud Functions emulator may be incorrect.");
192
+ this.adminSdkConfig = (0, adminSdkConfig_1.constructDefaultAdminSdkConfig)(this.args.projectId);
193
+ }
198
194
  }
199
195
  const { host, port } = this.getInfo();
200
196
  this.workQueue.start();
@@ -242,14 +238,26 @@ class FunctionsEmulator {
242
238
  if (!emulatableBackend.nodeBinary) {
243
239
  throw new error_1.FirebaseError(`No node binary for ${emulatableBackend.functionsDir}. This should never happen.`);
244
240
  }
245
- const worker = this.invokeRuntime(this.getBaseBundle(emulatableBackend), {
246
- nodeBinary: emulatableBackend.nodeBinary,
247
- extensionTriggers: emulatableBackend.predefinedTriggers,
248
- }, Object.assign(Object.assign(Object.assign(Object.assign({}, this.getSystemEnvs()), this.getEmulatorEnvs()), { FIREBASE_CONFIG: this.getFirebaseConfig() }), emulatableBackend.env));
249
- const triggerParseEvent = await types_1.EmulatorLog.waitForLog(worker.runtime.events, "SYSTEM", "triggers-parsed");
250
- const parsedDefinitions = triggerParseEvent.data
251
- .triggerDefinitions;
252
- const triggerDefinitions = (0, functionsEmulatorShared_1.emulatedFunctionsByRegion)(parsedDefinitions);
241
+ let triggerDefinitions;
242
+ if (emulatableBackend.predefinedTriggers) {
243
+ triggerDefinitions = (0, functionsEmulatorShared_1.emulatedFunctionsByRegion)(emulatableBackend.predefinedTriggers);
244
+ }
245
+ else {
246
+ const runtimeConfig = this.getRuntimeConfig(emulatableBackend);
247
+ const runtimeDelegate = await (0, runtimes_1.getRuntimeDelegate)({
248
+ projectId: this.args.projectId,
249
+ projectDir: this.args.projectDir,
250
+ sourceDir: emulatableBackend.functionsDir,
251
+ });
252
+ logger_1.logger.debug(`Validating ${runtimeDelegate.name} source`);
253
+ await runtimeDelegate.validate();
254
+ logger_1.logger.debug(`Building ${runtimeDelegate.name} source`);
255
+ await runtimeDelegate.build();
256
+ logger_1.logger.debug(`Analyzing ${runtimeDelegate.name} backend spec`);
257
+ const discoveredBackend = await runtimeDelegate.discoverSpec(runtimeConfig, Object.assign(Object.assign(Object.assign(Object.assign({}, this.getSystemEnvs()), this.getEmulatorEnvs()), { FIREBASE_CONFIG: this.getFirebaseConfig() }), emulatableBackend.env));
258
+ const endpoints = backend.allEndpoints(discoveredBackend);
259
+ triggerDefinitions = (0, functionsEmulatorShared_1.emulatedFunctionsFromEndpoints)(endpoints);
260
+ }
253
261
  const toSetup = triggerDefinitions.filter((definition) => {
254
262
  if (force) {
255
263
  return true;
@@ -305,7 +313,7 @@ class FunctionsEmulator {
305
313
  }
306
314
  }
307
315
  else {
308
- this.logger.log("WARN", `Trigger trigger "${definition.name}" has has neither "httpsTrigger" or "eventTrigger" member`);
316
+ this.logger.log("WARN", `Unsupported function type on ${definition.name}. Expected either httpsTrigger or eventTrigger.`);
309
317
  }
310
318
  const ignored = !added;
311
319
  this.addTriggerRecord(definition, { backend: emulatableBackend, ignored, url });
@@ -331,7 +339,7 @@ class FunctionsEmulator {
331
339
  }
332
340
  const result = DATABASE_PATH_PATTERN.exec(eventTrigger.resource);
333
341
  if (result === null || result.length !== 3) {
334
- this.logger.log("WARN", `Event trigger "${key}" has malformed "resource" member. ` + `${eventTrigger.resource}`);
342
+ this.logger.log("WARN", `Event function "${key}" has malformed "resource" member. ` + `${eventTrigger.resource}`);
335
343
  return Promise.reject();
336
344
  }
337
345
  const instance = result[1];
@@ -347,7 +355,7 @@ class FunctionsEmulator {
347
355
  setTriggersPath += `?ns=${instance}`;
348
356
  }
349
357
  else {
350
- this.logger.log("WARN", `No project in use. Registering function trigger for sentinel namespace '${constants_1.Constants.DEFAULT_DATABASE_EMULATOR_NAMESPACE}'`);
358
+ this.logger.log("WARN", `No project in use. Registering function for sentinel namespace '${constants_1.Constants.DEFAULT_DATABASE_EMULATOR_NAMESPACE}'`);
351
359
  }
352
360
  return api
353
361
  .request("POST", setTriggersPath, {
@@ -362,7 +370,7 @@ class FunctionsEmulator {
362
370
  return true;
363
371
  })
364
372
  .catch((err) => {
365
- this.logger.log("WARN", "Error adding trigger: " + err);
373
+ this.logger.log("WARN", "Error adding Realtime Database function: " + err);
366
374
  throw err;
367
375
  });
368
376
  }
@@ -371,7 +379,9 @@ class FunctionsEmulator {
371
379
  if (!firestoreEmu) {
372
380
  return Promise.resolve(false);
373
381
  }
374
- const bundle = JSON.stringify({ eventTrigger });
382
+ const bundle = JSON.stringify({
383
+ eventTrigger: Object.assign(Object.assign({}, eventTrigger), { service: "firestore.googleapis.com" }),
384
+ });
375
385
  logger_1.logger.debug(`addFirestoreTrigger`, JSON.stringify(bundle));
376
386
  return api
377
387
  .request("PUT", `/emulator/v1/projects/${projectId}/triggers/${key}`, {
@@ -383,7 +393,7 @@ class FunctionsEmulator {
383
393
  return true;
384
394
  })
385
395
  .catch((err) => {
386
- this.logger.log("WARN", "Error adding trigger: " + err);
396
+ this.logger.log("WARN", "Error adding firestore function: " + err);
387
397
  throw err;
388
398
  });
389
399
  }
@@ -452,7 +462,7 @@ class FunctionsEmulator {
452
462
  const record = this.triggers[triggerKey];
453
463
  if (!record) {
454
464
  logger_1.logger.debug(`Could not find key=${triggerKey} in ${JSON.stringify(this.triggers)}`);
455
- throw new error_1.FirebaseError(`No trigger with key ${triggerKey}`);
465
+ throw new error_1.FirebaseError(`No function with key ${triggerKey}`);
456
466
  }
457
467
  return record;
458
468
  }
@@ -475,30 +485,12 @@ class FunctionsEmulator {
475
485
  setTriggersForTesting(triggers, backend) {
476
486
  triggers.forEach((def) => this.addTriggerRecord(def, { backend, ignored: false }));
477
487
  }
478
- getBaseBundle(backend) {
488
+ getBaseBundle() {
479
489
  return {
480
- cwd: backend.functionsDir,
481
- projectId: this.args.projectId,
482
- triggerId: "",
483
- targetName: "",
484
- emulators: {
485
- firestore: registry_1.EmulatorRegistry.getInfo(types_1.Emulators.FIRESTORE),
486
- database: registry_1.EmulatorRegistry.getInfo(types_1.Emulators.DATABASE),
487
- pubsub: registry_1.EmulatorRegistry.getInfo(types_1.Emulators.PUBSUB),
488
- auth: registry_1.EmulatorRegistry.getInfo(types_1.Emulators.AUTH),
489
- storage: registry_1.EmulatorRegistry.getInfo(types_1.Emulators.STORAGE),
490
- },
491
- adminSdkConfig: {
492
- databaseURL: this.adminSdkConfig.databaseURL,
493
- storageBucket: this.adminSdkConfig.storageBucket,
494
- },
490
+ proto: {},
495
491
  disabled_features: this.args.disabledRuntimeFeatures,
496
492
  };
497
493
  }
498
- getRequestedNodeRuntimeVersion(frb) {
499
- const pkg = require(path.join(frb.cwd, "package.json"));
500
- return frb.nodeMajorVersion || (pkg.engines && pkg.engines.node);
501
- }
502
494
  getNodeBinary(backend) {
503
495
  const pkg = require(path.join(backend.functionsDir, "package.json"));
504
496
  if ((!pkg.engines || !pkg.engines.node) && !backend.nodeMajorVersion) {
@@ -530,6 +522,16 @@ class FunctionsEmulator {
530
522
  }
531
523
  return process.execPath;
532
524
  }
525
+ getRuntimeConfig(backend) {
526
+ const configPath = `${backend.functionsDir}/.runtimeconfig.json`;
527
+ try {
528
+ const configContent = fs.readFileSync(configPath, "utf8");
529
+ return JSON.parse(configContent.toString());
530
+ }
531
+ catch (e) {
532
+ }
533
+ return {};
534
+ }
533
535
  getUserEnvs(backend) {
534
536
  const projectInfo = {
535
537
  functionsSource: backend.functionsDir,
@@ -546,17 +548,16 @@ class FunctionsEmulator {
546
548
  }
547
549
  return {};
548
550
  }
549
- getSystemEnvs(triggerDef) {
551
+ getSystemEnvs(trigger) {
550
552
  const envs = {};
551
553
  envs.GCLOUD_PROJECT = this.args.projectId;
552
554
  envs.K_REVISION = "1";
553
555
  envs.PORT = "80";
554
- if (triggerDef) {
555
- const service = triggerDef.targetName;
556
- const target = service.replace(/-/g, ".");
556
+ if (trigger) {
557
+ const target = trigger.entryPoint;
557
558
  envs.FUNCTION_TARGET = target;
558
- envs.FUNCTION_SIGNATURE_TYPE = triggerDef.signatureType;
559
- envs.K_SERVICE = service;
559
+ envs.FUNCTION_SIGNATURE_TYPE = (0, functionsEmulatorShared_1.getSignatureType)(trigger);
560
+ envs.K_SERVICE = trigger.name;
560
561
  }
561
562
  return envs;
562
563
  }
@@ -607,12 +608,50 @@ class FunctionsEmulator {
607
608
  projectId: this.args.projectId,
608
609
  });
609
610
  }
610
- getRuntimeEnvs(backend, triggerDef) {
611
- return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, this.getUserEnvs(backend)), this.getSystemEnvs(triggerDef)), this.getEmulatorEnvs()), { FIREBASE_CONFIG: this.getFirebaseConfig() }), backend.env);
611
+ getRuntimeEnvs(backend, trigger) {
612
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, this.getUserEnvs(backend)), this.getSystemEnvs(trigger)), this.getEmulatorEnvs()), { FIREBASE_CONFIG: this.getFirebaseConfig() }), backend.env);
613
+ }
614
+ async resolveSecretEnvs(backend, trigger) {
615
+ let secretEnvs = {};
616
+ try {
617
+ const data = fs.readFileSync(path.join(backend.functionsDir, LOCAL_SECRETS_FILE), "utf8");
618
+ secretEnvs = functionsEnv.parseStrict(data);
619
+ }
620
+ catch (e) {
621
+ if (e.code !== "ENOENT") {
622
+ this.logger.logLabeled("ERROR", "functions", `Failed to read local secrets file ${LOCAL_SECRETS_FILE}: ${e.message}`);
623
+ }
624
+ }
625
+ const secrets = trigger.secretEnvironmentVariables || [];
626
+ const accesses = secrets
627
+ .filter((s) => !secretEnvs[s.secret])
628
+ .map(async (s) => {
629
+ this.logger.logLabeled("INFO", "functions", `Trying to access secret ${s.key}@latest`);
630
+ const value = await (0, secretManager_1.accessSecretVersion)(this.getProjectId(), s.key, "latest");
631
+ return [s.secret, value];
632
+ });
633
+ const accessResults = await (0, utils_1.allSettled)(accesses);
634
+ const errs = [];
635
+ for (const result of accessResults) {
636
+ if (result.status === "rejected") {
637
+ errs.push(result.reason);
638
+ }
639
+ else {
640
+ const [k, v] = result.value;
641
+ secretEnvs[k] = v;
642
+ }
643
+ }
644
+ if (errs.length > 0) {
645
+ this.logger.logLabeled("ERROR", "functions", "Unable to access secret environment variables from Google Cloud Secret Manager. " +
646
+ "Make sure the credential used for the Functions Emulator have access " +
647
+ `or provide override values in ${LOCAL_SECRETS_FILE}:\n\t` +
648
+ errs.join("\n\t"));
649
+ }
650
+ return secretEnvs;
612
651
  }
613
- invokeRuntime(frb, opts, runtimeEnv) {
614
- if (this.workerPool.readyForWork(frb.triggerId)) {
615
- return this.workerPool.submitWork(frb.triggerId, frb, opts);
652
+ async invokeRuntime(backend, trigger, frb, opts) {
653
+ if (this.workerPool.readyForWork(trigger.id)) {
654
+ return this.workerPool.submitWork(trigger.id, frb, opts);
616
655
  }
617
656
  const emitter = new events_1.EventEmitter();
618
657
  const args = [path.join(__dirname, "functionsEmulatorRuntime")];
@@ -621,7 +660,7 @@ class FunctionsEmulator {
621
660
  }
622
661
  if (this.args.debugPort) {
623
662
  if (process.env.FIREPIT_VERSION && process.execPath == opts.nodeBinary) {
624
- const requestedMajorNodeVersion = this.getRequestedNodeRuntimeVersion(frb);
663
+ const requestedMajorNodeVersion = this.getNodeBinary(backend);
625
664
  this.logger.log("WARN", `To enable function inspection, please run "${process.execPath} is:npm i node@${requestedMajorNodeVersion} --save-dev" in your functions directory`);
626
665
  }
627
666
  else {
@@ -629,15 +668,17 @@ class FunctionsEmulator {
629
668
  args.unshift(`--inspect=${host}:${this.args.debugPort}`);
630
669
  }
631
670
  }
632
- const pnpPath = path.join(frb.cwd, ".pnp.js");
671
+ const pnpPath = path.join(backend.functionsDir, ".pnp.js");
633
672
  if (fs.existsSync(pnpPath)) {
634
673
  emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.FUNCTIONS).logLabeled("WARN_ONCE", "functions", "Detected yarn@2 with PnP. " +
635
674
  "Cloud Functions for Firebase requires a node_modules folder to work correctly and is therefore incompatible with PnP. " +
636
675
  "See https://yarnpkg.com/getting-started/migration#step-by-step for more information.");
637
676
  }
677
+ const runtimeEnv = this.getRuntimeEnvs(backend, trigger);
678
+ const secretEnvs = await this.resolveSecretEnvs(backend, trigger);
638
679
  const childProcess = spawn(opts.nodeBinary, args, {
639
- env: Object.assign(Object.assign({ node: opts.nodeBinary }, process.env), (runtimeEnv !== null && runtimeEnv !== void 0 ? runtimeEnv : {})),
640
- cwd: frb.cwd,
680
+ cwd: backend.functionsDir,
681
+ env: Object.assign(Object.assign(Object.assign({ node: opts.nodeBinary }, process.env), runtimeEnv), secretEnvs),
641
682
  stdio: ["pipe", "pipe", "pipe", "ipc"],
642
683
  });
643
684
  if (!childProcess.stderr) {
@@ -668,6 +709,7 @@ class FunctionsEmulator {
668
709
  childProcess.on("exit", resolve);
669
710
  }),
670
711
  events: emitter,
712
+ cwd: backend.functionsDir,
671
713
  shutdown: () => {
672
714
  childProcess.kill();
673
715
  },
@@ -679,8 +721,8 @@ class FunctionsEmulator {
679
721
  return childProcess.send(JSON.stringify(args));
680
722
  },
681
723
  };
682
- this.workerPool.addWorker(frb.triggerId, runtime);
683
- return this.workerPool.submitWork(frb.triggerId, frb, opts);
724
+ this.workerPool.addWorker(trigger.id, runtime);
725
+ return this.workerPool.submitWork(trigger.id, frb, opts);
684
726
  }
685
727
  async disableBackgroundTriggers() {
686
728
  Object.values(this.triggers).forEach((record) => {
@@ -706,7 +748,7 @@ class FunctionsEmulator {
706
748
  }
707
749
  const trigger = record.def;
708
750
  const service = (0, functionsEmulatorShared_1.getFunctionService)(trigger);
709
- const worker = this.startFunctionRuntime(record.backend, trigger.id, trigger.name, (0, functionsEmulatorShared_1.getSignatureType)(trigger), proto);
751
+ const worker = await this.startFunctionRuntime(record.backend, trigger, proto);
710
752
  return new Promise((resolve, reject) => {
711
753
  if (projectId !== this.args.projectId) {
712
754
  if (service !== constants_1.Constants.SERVICE_REALTIME_DATABASE) {
@@ -740,7 +782,7 @@ class FunctionsEmulator {
740
782
  return registry_1.EmulatorRegistry.getInfo(emulator);
741
783
  }
742
784
  tokenFromAuthHeader(authHeader) {
743
- const match = authHeader.match(/^Bearer (.*)$/);
785
+ const match = /^Bearer (.*)$/.exec(authHeader);
744
786
  if (!match) {
745
787
  return;
746
788
  }
@@ -772,7 +814,7 @@ class FunctionsEmulator {
772
814
  if (!this.triggers[triggerId]) {
773
815
  res
774
816
  .status(404)
775
- .send(`Function ${triggerId} does not exist, valid triggers are: ${Object.keys(this.triggers).join(", ")}`);
817
+ .send(`Function ${triggerId} does not exist, valid functions are: ${Object.keys(this.triggers).join(", ")}`);
776
818
  return;
777
819
  }
778
820
  const record = this.getTriggerRecordByKey(triggerId);
@@ -793,7 +835,7 @@ class FunctionsEmulator {
793
835
  req.headers[functionsEmulatorShared_1.HttpConstants.CALLABLE_AUTH_HEADER] = encodeURIComponent(JSON.stringify(contextAuth));
794
836
  }
795
837
  }
796
- const worker = this.startFunctionRuntime(record.backend, trigger.id, trigger.name, "http", undefined);
838
+ const worker = await this.startFunctionRuntime(record.backend, trigger);
797
839
  worker.onLogs((el) => {
798
840
  if (el.level === "FATAL") {
799
841
  res.status(500).send(el.text);