firebase-tools 10.1.5 → 10.2.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.
- package/lib/api.js +1 -0
- package/lib/apiv2.js +3 -0
- package/lib/appdistribution/options-parser-util.js +1 -1
- package/lib/auth.js +62 -25
- package/lib/command.js +1 -1
- package/lib/commands/apps-android-sha-create.js +2 -2
- package/lib/commands/apps-sdkconfig.js +1 -1
- package/lib/commands/auth-import.js +1 -1
- package/lib/commands/database-rules-list.js +2 -2
- package/lib/commands/emulators-start.js +1 -1
- package/lib/commands/ext-configure.js +1 -0
- package/lib/commands/ext-dev-init.js +49 -49
- package/lib/commands/ext-export.js +12 -2
- package/lib/commands/ext-install.js +104 -103
- package/lib/commands/ext-uninstall.js +9 -8
- package/lib/commands/ext-update.js +10 -9
- package/lib/commands/functions-config-clone.js +1 -1
- package/lib/commands/functions-config-export.js +1 -1
- package/lib/commands/functions-secrets-access.js +17 -0
- package/lib/commands/functions-secrets-destroy.js +40 -0
- package/lib/commands/functions-secrets-get.js +21 -0
- package/lib/commands/functions-secrets-prune.js +50 -0
- package/lib/commands/functions-secrets-set.js +46 -0
- package/lib/commands/hosting-clone.js +3 -3
- package/lib/commands/index.js +7 -3
- package/lib/commands/login.js +1 -1
- package/lib/commands/remoteconfig-get.js +1 -1
- package/lib/deploy/extensions/deploymentSummary.js +3 -3
- package/lib/deploy/extensions/params.js +3 -0
- package/lib/deploy/extensions/planner.js +2 -1
- package/lib/deploy/extensions/tasks.js +1 -1
- package/lib/deploy/functions/backend.js +20 -5
- package/lib/deploy/functions/checkIam.js +1 -1
- package/lib/deploy/functions/containerCleaner.js +3 -3
- package/lib/deploy/functions/ensure.js +112 -0
- package/lib/deploy/functions/ensureCloudBuildEnabled.js +0 -49
- package/lib/deploy/functions/functionsDeployHelper.js +2 -2
- package/lib/deploy/functions/prepare.js +15 -20
- package/lib/deploy/functions/pricing.js +1 -1
- package/lib/deploy/functions/prompts.js +2 -2
- package/lib/deploy/functions/release/fabricator.js +3 -3
- package/lib/deploy/functions/release/index.js +1 -1
- package/lib/deploy/functions/release/planner.js +11 -8
- package/lib/deploy/functions/release/reporter.js +3 -0
- package/lib/deploy/functions/runtimes/discovery/index.js +6 -6
- package/lib/deploy/functions/runtimes/discovery/parsing.js +1 -1
- package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +17 -11
- package/lib/deploy/functions/runtimes/golang/index.js +2 -2
- package/lib/deploy/functions/runtimes/node/index.js +26 -0
- package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +2 -2
- package/lib/deploy/functions/runtimes/node/parseTriggers.js +40 -7
- package/lib/deploy/functions/runtimes/node/versioning.js +2 -2
- package/lib/deploy/functions/validate.js +58 -3
- package/lib/deploy/hosting/client.js +9 -0
- package/lib/deploy/hosting/convertConfig.js +6 -0
- package/lib/deploy/hosting/deploy.js +2 -2
- package/lib/deploy/hosting/hashcache.js +21 -19
- package/lib/deploy/hosting/index.js +5 -5
- package/lib/deploy/hosting/prepare.js +25 -25
- package/lib/deploy/hosting/release.js +21 -24
- package/lib/deploy/hosting/uploader.js +5 -5
- package/lib/deploy/remoteconfig/functions.js +2 -2
- package/lib/emulator/auth/cloudFunctions.js +1 -1
- package/lib/emulator/auth/operations.js +1 -1
- package/lib/emulator/commandUtils.js +5 -1
- package/lib/emulator/constants.js +3 -0
- package/lib/emulator/controller.js +48 -18
- package/lib/emulator/download.js +18 -1
- package/lib/emulator/downloadableEmulators.js +30 -13
- package/lib/emulator/emulatorLogger.js +19 -1
- package/lib/emulator/extensions/validation.js +35 -0
- package/lib/emulator/extensionsEmulator.js +140 -0
- package/lib/emulator/functionsEmulator.js +175 -86
- package/lib/emulator/functionsEmulatorRuntime.js +108 -83
- package/lib/emulator/functionsEmulatorShared.js +51 -1
- package/lib/emulator/functionsEmulatorShell.js +1 -2
- package/lib/emulator/functionsEmulatorUtils.js +4 -4
- package/lib/emulator/functionsRuntimeWorker.js +3 -3
- package/lib/emulator/hub.js +4 -3
- package/lib/emulator/loggingEmulator.js +1 -1
- package/lib/emulator/pubsubEmulator.js +1 -1
- package/lib/emulator/registry.js +10 -2
- package/lib/emulator/storage/apis/firebase.js +31 -26
- package/lib/emulator/storage/apis/gcloud.js +7 -12
- package/lib/emulator/storage/files.js +36 -34
- package/lib/emulator/storage/index.js +2 -2
- package/lib/emulator/storage/metadata.js +2 -2
- package/lib/emulator/storage/rules/runtime.js +8 -7
- package/lib/emulator/types.js +3 -0
- package/lib/ensureApiEnabled.js +5 -1
- package/lib/error.js +1 -1
- package/lib/extensions/askUserForParam.js +2 -2
- package/lib/extensions/changelog.js +3 -1
- package/lib/extensions/checkProjectBilling.js +1 -1
- package/lib/extensions/diagnose.js +56 -0
- package/lib/extensions/displayExtensionInfo.js +1 -1
- package/lib/extensions/emulator/optionsHelper.js +24 -8
- package/lib/extensions/emulator/specHelper.js +10 -23
- package/lib/extensions/export.js +1 -51
- package/lib/extensions/extensionsApi.js +1 -1
- package/lib/extensions/extensionsHelper.js +23 -10
- package/lib/extensions/listExtensions.js +2 -0
- package/lib/extensions/manifest.js +48 -0
- package/lib/extensions/metricsUtils.js +4 -4
- package/lib/extensions/paramHelper.js +4 -4
- package/lib/extensions/refs.js +1 -1
- package/lib/extensions/secretsUtils.js +4 -4
- package/lib/functional.js +1 -1
- package/lib/functions/env.js +7 -8
- package/lib/functions/secrets.js +112 -0
- package/lib/gcp/cloudfunctions.js +24 -5
- package/lib/gcp/cloudfunctionsv2.js +18 -5
- package/lib/gcp/cloudtasks.js +1 -1
- package/lib/gcp/docker.js +2 -2
- package/lib/gcp/run.js +2 -2
- package/lib/gcp/secretManager.js +128 -46
- package/lib/gcp/storage.js +1 -0
- package/lib/hosting/api.js +1 -1
- package/lib/hosting/functionsProxy.js +15 -5
- package/lib/hosting/proxy.js +2 -2
- package/lib/init/features/account.js +1 -1
- package/lib/management/database.js +1 -1
- package/lib/previews.js +1 -1
- package/lib/responseToError.js +16 -7
- package/lib/serve/functions.js +2 -2
- package/lib/serve/hosting.js +1 -1
- package/lib/utils.js +7 -2
- package/npm-shrinkwrap.json +904 -412
- package/package.json +3 -3
- package/schema/firebase-config.json +32 -0
- package/templates/init/functions/javascript/package.lint.json +3 -3
- package/templates/init/functions/javascript/package.nolint.json +2 -2
- package/templates/init/functions/typescript/package.lint.json +7 -7
- package/templates/init/functions/typescript/package.nolint.json +3 -3
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const fs = require("fs");
|
|
4
|
-
const types_1 = require("./types");
|
|
5
|
-
const functionsEmulatorShared_1 = require("./functionsEmulatorShared");
|
|
6
|
-
const functionsEmulatorUtils_1 = require("./functionsEmulatorUtils");
|
|
7
4
|
const express = require("express");
|
|
8
5
|
const path = require("path");
|
|
9
6
|
const bodyParser = require("body-parser");
|
|
10
7
|
const url_1 = require("url");
|
|
11
8
|
const _ = require("lodash");
|
|
12
|
-
|
|
9
|
+
const types_1 = require("./types");
|
|
10
|
+
const constants_1 = require("./constants");
|
|
11
|
+
const functionsEmulatorShared_1 = require("./functionsEmulatorShared");
|
|
12
|
+
const functionsEmulatorUtils_1 = require("./functionsEmulatorUtils");
|
|
13
|
+
let functionModule;
|
|
14
|
+
let FUNCTION_TARGET_NAME;
|
|
15
|
+
let FUNCTION_SIGNATURE;
|
|
16
|
+
let FUNCTION_DEBUG_MODE;
|
|
13
17
|
let developerPkgJSON;
|
|
14
18
|
const dynamicImport = new Function("modulePath", "return import(modulePath)");
|
|
15
19
|
function isFeatureEnabled(frb, feature) {
|
|
@@ -112,7 +116,7 @@ async function resolveDeveloperNodeModule(frb, name) {
|
|
|
112
116
|
if (!isInPackageJSON) {
|
|
113
117
|
return { declared: false, installed: false };
|
|
114
118
|
}
|
|
115
|
-
const resolveResult = await requireResolveAsync(name, { paths: [
|
|
119
|
+
const resolveResult = await requireResolveAsync(name, { paths: [process.cwd()] }).catch(noOp);
|
|
116
120
|
if (!resolveResult) {
|
|
117
121
|
return { declared: true, installed: false };
|
|
118
122
|
}
|
|
@@ -160,7 +164,7 @@ function requirePackageJson(frb) {
|
|
|
160
164
|
return developerPkgJSON;
|
|
161
165
|
}
|
|
162
166
|
try {
|
|
163
|
-
const pkg = require(`${
|
|
167
|
+
const pkg = require(`${process.cwd()}/package.json`);
|
|
164
168
|
developerPkgJSON = {
|
|
165
169
|
engines: pkg.engines || {},
|
|
166
170
|
dependencies: pkg.dependencies || {},
|
|
@@ -321,7 +325,7 @@ function getDefaultConfig() {
|
|
|
321
325
|
}
|
|
322
326
|
function initializeRuntimeConfig(frb) {
|
|
323
327
|
if (!process.env.CLOUD_RUNTIME_CONFIG) {
|
|
324
|
-
const configPath = `${
|
|
328
|
+
const configPath = `${process.cwd()}/.runtimeconfig.json`;
|
|
325
329
|
try {
|
|
326
330
|
const configContent = fs.readFileSync(configPath, "utf8");
|
|
327
331
|
if (configContent) {
|
|
@@ -359,7 +363,7 @@ async function initializeFirebaseAdminStubs(frb) {
|
|
|
359
363
|
const defaultApp = makeProxiedFirebaseApp(frb, adminModuleTarget.initializeApp(defaultAppOptions));
|
|
360
364
|
logDebug("initializeApp(DEFAULT)", defaultAppOptions);
|
|
361
365
|
localFunctionsModule.app.setEmulatedAdminApp(defaultApp);
|
|
362
|
-
if (
|
|
366
|
+
if (process.env[constants_1.Constants.FIREBASE_AUTH_EMULATOR_HOST]) {
|
|
363
367
|
if ((0, functionsEmulatorUtils_1.compareVersionStrings)(adminResolution.version, "9.3.0") < 0) {
|
|
364
368
|
new types_1.EmulatorLog("WARN_ONCE", "runtime-status", "The Firebase Authentication emulator is running, but your 'firebase-admin' dependency is below version 9.3.0, so calls to Firebase Authentication will affect production.").log();
|
|
365
369
|
}
|
|
@@ -377,16 +381,20 @@ async function initializeFirebaseAdminStubs(frb) {
|
|
|
377
381
|
return defaultApp;
|
|
378
382
|
})
|
|
379
383
|
.when("firestore", (target) => {
|
|
380
|
-
warnAboutFirestoreProd(
|
|
384
|
+
warnAboutFirestoreProd();
|
|
381
385
|
return Proxied.getOriginal(target, "firestore");
|
|
382
386
|
})
|
|
383
387
|
.when("database", (target) => {
|
|
384
|
-
warnAboutDatabaseProd(
|
|
388
|
+
warnAboutDatabaseProd();
|
|
385
389
|
return Proxied.getOriginal(target, "database");
|
|
386
390
|
})
|
|
387
391
|
.when("auth", (target) => {
|
|
388
|
-
warnAboutAuthProd(
|
|
392
|
+
warnAboutAuthProd();
|
|
389
393
|
return Proxied.getOriginal(target, "auth");
|
|
394
|
+
})
|
|
395
|
+
.when("storage", (target) => {
|
|
396
|
+
warnAboutStorageProd();
|
|
397
|
+
return Proxied.getOriginal(target, "storage");
|
|
390
398
|
})
|
|
391
399
|
.finalize();
|
|
392
400
|
require.cache[adminResolution.resolution] = Object.assign(require.cache[adminResolution.resolution], {
|
|
@@ -401,37 +409,47 @@ function makeProxiedFirebaseApp(frb, original) {
|
|
|
401
409
|
const appProxy = new Proxied(original);
|
|
402
410
|
return appProxy
|
|
403
411
|
.when("firestore", (target) => {
|
|
404
|
-
warnAboutFirestoreProd(
|
|
412
|
+
warnAboutFirestoreProd();
|
|
405
413
|
return Proxied.getOriginal(target, "firestore");
|
|
406
414
|
})
|
|
407
415
|
.when("database", (target) => {
|
|
408
|
-
warnAboutDatabaseProd(
|
|
416
|
+
warnAboutDatabaseProd();
|
|
409
417
|
return Proxied.getOriginal(target, "database");
|
|
410
418
|
})
|
|
411
419
|
.when("auth", (target) => {
|
|
412
|
-
warnAboutAuthProd(
|
|
420
|
+
warnAboutAuthProd();
|
|
413
421
|
return Proxied.getOriginal(target, "auth");
|
|
422
|
+
})
|
|
423
|
+
.when("storage", (target) => {
|
|
424
|
+
warnAboutStorageProd();
|
|
425
|
+
return Proxied.getOriginal(target, "storage");
|
|
414
426
|
})
|
|
415
427
|
.finalize();
|
|
416
428
|
}
|
|
417
|
-
function warnAboutFirestoreProd(
|
|
418
|
-
if (
|
|
429
|
+
function warnAboutFirestoreProd() {
|
|
430
|
+
if (process.env[constants_1.Constants.FIRESTORE_EMULATOR_HOST]) {
|
|
419
431
|
return;
|
|
420
432
|
}
|
|
421
433
|
new types_1.EmulatorLog("WARN_ONCE", "runtime-status", "The Cloud Firestore emulator is not running, so calls to Firestore will affect production.").log();
|
|
422
434
|
}
|
|
423
|
-
function warnAboutDatabaseProd(
|
|
424
|
-
if (
|
|
435
|
+
function warnAboutDatabaseProd() {
|
|
436
|
+
if (process.env[constants_1.Constants.FIREBASE_DATABASE_EMULATOR_HOST]) {
|
|
425
437
|
return;
|
|
426
438
|
}
|
|
427
439
|
new types_1.EmulatorLog("WARN_ONCE", "runtime-status", "The Realtime Database emulator is not running, so calls to Realtime Database will affect production.").log();
|
|
428
440
|
}
|
|
429
|
-
function warnAboutAuthProd(
|
|
430
|
-
if (
|
|
441
|
+
function warnAboutAuthProd() {
|
|
442
|
+
if (process.env[constants_1.Constants.FIREBASE_AUTH_EMULATOR_HOST]) {
|
|
431
443
|
return;
|
|
432
444
|
}
|
|
433
445
|
new types_1.EmulatorLog("WARN_ONCE", "runtime-status", "The Firebase Authentication emulator is not running, so calls to Firebase Authentication will affect production.").log();
|
|
434
446
|
}
|
|
447
|
+
function warnAboutStorageProd() {
|
|
448
|
+
if (process.env[constants_1.Constants.FIREBASE_STORAGE_EMULATOR_HOST]) {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
new types_1.EmulatorLog("WARN_ONCE", "runtime-status", "The Firebase Storage emulator is not running, so calls to Firebase Storage will affect production.").log();
|
|
452
|
+
}
|
|
435
453
|
async function initializeFunctionsConfigHelper(frb) {
|
|
436
454
|
const functionsResolution = await assertResolveDeveloperNodeModule(frb, "firebase-functions");
|
|
437
455
|
const localFunctionsModule = require(functionsResolution.resolution);
|
|
@@ -467,7 +485,7 @@ async function initializeFunctionsConfigHelper(frb) {
|
|
|
467
485
|
function rawBodySaver(req, res, buf) {
|
|
468
486
|
req.rawBody = buf;
|
|
469
487
|
}
|
|
470
|
-
async function processHTTPS(
|
|
488
|
+
async function processHTTPS(trigger, frb) {
|
|
471
489
|
const ephemeralServer = express();
|
|
472
490
|
const functionRouter = express.Router();
|
|
473
491
|
const socketPath = frb.socketPath;
|
|
@@ -479,7 +497,6 @@ async function processHTTPS(frb, trigger) {
|
|
|
479
497
|
const handler = async (req, res) => {
|
|
480
498
|
try {
|
|
481
499
|
logDebug(`Ephemeral server handling ${req.method} request`);
|
|
482
|
-
const func = trigger.getRawFunction();
|
|
483
500
|
res.on("finish", () => {
|
|
484
501
|
instance.close((err) => {
|
|
485
502
|
if (err) {
|
|
@@ -490,7 +507,7 @@ async function processHTTPS(frb, trigger) {
|
|
|
490
507
|
}
|
|
491
508
|
});
|
|
492
509
|
});
|
|
493
|
-
await runHTTPS([req, res]
|
|
510
|
+
await runHTTPS(trigger, [req, res]);
|
|
494
511
|
}
|
|
495
512
|
catch (err) {
|
|
496
513
|
rejectEphemeralServer(err);
|
|
@@ -524,11 +541,11 @@ async function processHTTPS(frb, trigger) {
|
|
|
524
541
|
instance.on("error", rejectEphemeralServer);
|
|
525
542
|
});
|
|
526
543
|
}
|
|
527
|
-
async function processBackground(
|
|
544
|
+
async function processBackground(trigger, frb, signature) {
|
|
528
545
|
const proto = frb.proto;
|
|
529
546
|
logDebug("ProcessBackground", proto);
|
|
530
547
|
if (signature === "cloudevent") {
|
|
531
|
-
return runCloudEvent(
|
|
548
|
+
return runCloudEvent(trigger, proto);
|
|
532
549
|
}
|
|
533
550
|
const data = proto.data;
|
|
534
551
|
delete proto.data;
|
|
@@ -539,7 +556,7 @@ async function processBackground(frb, trigger, signature) {
|
|
|
539
556
|
context.resource = context.resource.name;
|
|
540
557
|
}
|
|
541
558
|
}
|
|
542
|
-
await runBackground({ data, context }
|
|
559
|
+
await runBackground(trigger, { data, context });
|
|
543
560
|
}
|
|
544
561
|
async function runFunction(func) {
|
|
545
562
|
let caughtErr;
|
|
@@ -554,30 +571,30 @@ async function runFunction(func) {
|
|
|
554
571
|
throw caughtErr;
|
|
555
572
|
}
|
|
556
573
|
}
|
|
557
|
-
async function runBackground(
|
|
574
|
+
async function runBackground(trigger, proto) {
|
|
558
575
|
logDebug("RunBackground", proto);
|
|
559
576
|
await runFunction(() => {
|
|
560
|
-
return
|
|
577
|
+
return trigger(proto.data, proto.context);
|
|
561
578
|
});
|
|
562
579
|
}
|
|
563
|
-
async function runCloudEvent(
|
|
580
|
+
async function runCloudEvent(trigger, event) {
|
|
564
581
|
logDebug("RunCloudEvent", event);
|
|
565
582
|
await runFunction(() => {
|
|
566
|
-
return
|
|
583
|
+
return trigger(event);
|
|
567
584
|
});
|
|
568
585
|
}
|
|
569
|
-
async function runHTTPS(
|
|
586
|
+
async function runHTTPS(trigger, args) {
|
|
570
587
|
if (args.length < 2) {
|
|
571
588
|
throw new Error("Function must be passed 2 args.");
|
|
572
589
|
}
|
|
573
590
|
await runFunction(() => {
|
|
574
|
-
return
|
|
591
|
+
return trigger(args[0], args[1]);
|
|
575
592
|
});
|
|
576
593
|
}
|
|
577
594
|
async function moduleResolutionDetective(frb, error) {
|
|
578
595
|
const clues = {
|
|
579
|
-
tsconfigJSON: await requireAsync("./tsconfig.json", { paths: [
|
|
580
|
-
packageJSON: await requireAsync("./package.json", { paths: [
|
|
596
|
+
tsconfigJSON: await requireAsync("./tsconfig.json", { paths: [process.cwd()] }).catch(noOp),
|
|
597
|
+
packageJSON: await requireAsync("./package.json", { paths: [process.cwd()] }).catch(noOp),
|
|
581
598
|
};
|
|
582
599
|
const isPotentially = {
|
|
583
600
|
typescript: false,
|
|
@@ -595,45 +612,57 @@ async function moduleResolutionDetective(frb, error) {
|
|
|
595
612
|
function logDebug(msg, data) {
|
|
596
613
|
new types_1.EmulatorLog("DEBUG", "runtime-status", `[${process.pid}] ${msg}`, data).log();
|
|
597
614
|
}
|
|
598
|
-
async function invokeTrigger(
|
|
599
|
-
|
|
600
|
-
throw new Error("frb.triggerId unexpectedly null");
|
|
601
|
-
}
|
|
602
|
-
new types_1.EmulatorLog("INFO", "runtime-status", `Beginning execution of "${frb.triggerId}"`, {
|
|
615
|
+
async function invokeTrigger(trigger, frb) {
|
|
616
|
+
new types_1.EmulatorLog("INFO", "runtime-status", `Beginning execution of "${FUNCTION_TARGET_NAME}"`, {
|
|
603
617
|
frb,
|
|
604
618
|
}).log();
|
|
605
|
-
|
|
606
|
-
logDebug("triggerDefinition", trigger.definition);
|
|
607
|
-
const signature = (0, functionsEmulatorShared_1.getSignatureType)(trigger.definition);
|
|
608
|
-
logDebug(`Running ${frb.triggerId} in signature ${signature}`);
|
|
619
|
+
logDebug(`Running ${FUNCTION_TARGET_NAME} in signature ${FUNCTION_SIGNATURE}`);
|
|
609
620
|
let seconds = 0;
|
|
610
621
|
const timerId = setInterval(() => {
|
|
611
622
|
seconds++;
|
|
612
623
|
}, 1000);
|
|
613
624
|
let timeoutId;
|
|
614
625
|
if (isFeatureEnabled(frb, "timeout")) {
|
|
626
|
+
let timeout = process.env.FUNCTIONS_EMULATOR_TIMEOUT_SECONDS || "60";
|
|
627
|
+
if (timeout.endsWith("s")) {
|
|
628
|
+
timeout = timeout.slice(0, -1);
|
|
629
|
+
}
|
|
630
|
+
const timeoutMs = parseInt(timeout, 10) * 1000;
|
|
615
631
|
timeoutId = setTimeout(() => {
|
|
616
|
-
new types_1.EmulatorLog("WARN", "runtime-status", `Your function timed out after ~${
|
|
632
|
+
new types_1.EmulatorLog("WARN", "runtime-status", `Your function timed out after ~${timeout}s. To configure this timeout, see
|
|
617
633
|
https://firebase.google.com/docs/functions/manage-functions#set_timeout_and_memory_allocation.`).log();
|
|
618
634
|
throw new Error("Function timed out.");
|
|
619
|
-
},
|
|
635
|
+
}, timeoutMs);
|
|
620
636
|
}
|
|
621
|
-
switch (
|
|
637
|
+
switch (FUNCTION_SIGNATURE) {
|
|
622
638
|
case "event":
|
|
623
639
|
case "cloudevent":
|
|
624
|
-
await processBackground(
|
|
640
|
+
await processBackground(trigger, frb, FUNCTION_SIGNATURE);
|
|
625
641
|
break;
|
|
626
642
|
case "http":
|
|
627
|
-
await processHTTPS(
|
|
643
|
+
await processHTTPS(trigger, frb);
|
|
628
644
|
break;
|
|
629
645
|
}
|
|
630
646
|
if (timeoutId) {
|
|
631
647
|
clearTimeout(timeoutId);
|
|
632
648
|
}
|
|
633
649
|
clearInterval(timerId);
|
|
634
|
-
new types_1.EmulatorLog("INFO", "runtime-status", `Finished "${
|
|
635
|
-
}
|
|
636
|
-
async function initializeRuntime(frb
|
|
650
|
+
new types_1.EmulatorLog("INFO", "runtime-status", `Finished "${FUNCTION_TARGET_NAME}" in ~${Math.max(seconds, 1)}s`).log();
|
|
651
|
+
}
|
|
652
|
+
async function initializeRuntime(frb) {
|
|
653
|
+
FUNCTION_DEBUG_MODE = process.env.FUNCTION_DEBUG_MODE || "";
|
|
654
|
+
if (!FUNCTION_DEBUG_MODE) {
|
|
655
|
+
FUNCTION_TARGET_NAME = process.env.FUNCTION_TARGET || "";
|
|
656
|
+
if (!FUNCTION_TARGET_NAME) {
|
|
657
|
+
new types_1.EmulatorLog("FATAL", "runtime-status", `Environment variable FUNCTION_TARGET cannot be empty. This shouldn't happen.`).log();
|
|
658
|
+
await flushAndExit(1);
|
|
659
|
+
}
|
|
660
|
+
FUNCTION_SIGNATURE = process.env.FUNCTION_SIGNATURE_TYPE || "";
|
|
661
|
+
if (!FUNCTION_SIGNATURE) {
|
|
662
|
+
new types_1.EmulatorLog("FATAL", "runtime-status", `Environment variable FUNCTION_SIGNATURE_TYPE cannot be empty. This shouldn't happen.`).log();
|
|
663
|
+
await flushAndExit(1);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
637
666
|
logDebug(`Disabled runtime features: ${JSON.stringify(frb.disabled_features)}`);
|
|
638
667
|
const verified = await verifyDeveloperNodeModules(frb);
|
|
639
668
|
if (!verified) {
|
|
@@ -645,35 +674,27 @@ async function initializeRuntime(frb, serializedFunctionTrigger, extensionTrigge
|
|
|
645
674
|
await initializeFunctionsConfigHelper(frb);
|
|
646
675
|
await initializeFirebaseFunctionsStubs(frb);
|
|
647
676
|
await initializeFirebaseAdminStubs(frb);
|
|
648
|
-
|
|
677
|
+
}
|
|
678
|
+
async function loadTriggers(frb, serializedFunctionTrigger) {
|
|
649
679
|
let triggerModule;
|
|
650
680
|
if (serializedFunctionTrigger) {
|
|
651
681
|
triggerModule = eval(serializedFunctionTrigger)();
|
|
652
682
|
}
|
|
653
683
|
else {
|
|
654
684
|
try {
|
|
655
|
-
triggerModule = require(
|
|
685
|
+
triggerModule = require(process.cwd());
|
|
656
686
|
}
|
|
657
687
|
catch (err) {
|
|
658
688
|
if (err.code !== "ERR_REQUIRE_ESM") {
|
|
659
689
|
await moduleResolutionDetective(frb, err);
|
|
660
|
-
|
|
690
|
+
throw err;
|
|
661
691
|
}
|
|
662
|
-
const modulePath = require.resolve(
|
|
692
|
+
const modulePath = require.resolve(process.cwd());
|
|
663
693
|
const moduleURL = (0, url_1.pathToFileURL)(modulePath).href;
|
|
664
694
|
triggerModule = await dynamicImport(moduleURL);
|
|
665
695
|
}
|
|
666
696
|
}
|
|
667
|
-
|
|
668
|
-
parsedDefinitions = extensionTriggers;
|
|
669
|
-
}
|
|
670
|
-
else {
|
|
671
|
-
require("../deploy/functions/runtimes/node/extractTriggers")(triggerModule, parsedDefinitions);
|
|
672
|
-
}
|
|
673
|
-
const triggerDefinitions = (0, functionsEmulatorShared_1.emulatedFunctionsByRegion)(parsedDefinitions);
|
|
674
|
-
const triggers = (0, functionsEmulatorShared_1.getEmulatedTriggersFromDefinitions)(triggerDefinitions, triggerModule);
|
|
675
|
-
new types_1.EmulatorLog("SYSTEM", "triggers-parsed", "", { triggers, triggerDefinitions }).log();
|
|
676
|
-
return triggers;
|
|
697
|
+
return triggerModule;
|
|
677
698
|
}
|
|
678
699
|
async function flushAndExit(code) {
|
|
679
700
|
await types_1.EmulatorLog.waitForFlush();
|
|
@@ -693,28 +714,32 @@ async function handleMessage(message) {
|
|
|
693
714
|
await flushAndExit(1);
|
|
694
715
|
return;
|
|
695
716
|
}
|
|
696
|
-
if (!
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
717
|
+
if (!functionModule) {
|
|
718
|
+
try {
|
|
719
|
+
await initializeRuntime(runtimeArgs.frb);
|
|
720
|
+
const serializedTriggers = runtimeArgs.opts ? runtimeArgs.opts.serializedTriggers : undefined;
|
|
721
|
+
functionModule = await loadTriggers(runtimeArgs.frb, serializedTriggers);
|
|
722
|
+
}
|
|
723
|
+
catch (e) {
|
|
724
|
+
logDebug(e);
|
|
725
|
+
new types_1.EmulatorLog("FATAL", "runtime-status", `Failed to initialize and load triggers. This shouldn't happen: ${e.message}`).log();
|
|
726
|
+
await flushAndExit(1);
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
708
729
|
}
|
|
709
|
-
if (
|
|
710
|
-
|
|
711
|
-
|
|
730
|
+
if (FUNCTION_DEBUG_MODE) {
|
|
731
|
+
FUNCTION_TARGET_NAME = runtimeArgs.frb.debug.functionTarget;
|
|
732
|
+
FUNCTION_SIGNATURE = runtimeArgs.frb.debug.functionSignature;
|
|
712
733
|
}
|
|
713
|
-
|
|
714
|
-
|
|
734
|
+
const trigger = FUNCTION_TARGET_NAME.split(".").reduce((mod, functionTargetPart) => {
|
|
735
|
+
return mod === null || mod === void 0 ? void 0 : mod[functionTargetPart];
|
|
736
|
+
}, functionModule);
|
|
737
|
+
if (!trigger) {
|
|
738
|
+
throw new Error(`Failed to find function ${FUNCTION_TARGET_NAME} in the loaded module`);
|
|
715
739
|
}
|
|
740
|
+
logDebug(`Beginning invocation function ${FUNCTION_TARGET_NAME}!`);
|
|
716
741
|
try {
|
|
717
|
-
await invokeTrigger(runtimeArgs.frb
|
|
742
|
+
await invokeTrigger(trigger, runtimeArgs.frb);
|
|
718
743
|
if (runtimeArgs.opts && runtimeArgs.opts.serializedTriggers) {
|
|
719
744
|
await flushAndExit(0);
|
|
720
745
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
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;
|
|
3
|
+
exports.getSignatureType = exports.formatHost = exports.findModuleRoot = exports.waitForBody = exports.getServiceFromEventType = exports.getFunctionService = exports.getTemporarySocketPath = exports.getEmulatedTriggersFromDefinitions = exports.emulatedFunctionsByRegion = exports.emulatedFunctionsFromEndpoints = 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
8
|
const constants_1 = require("./constants");
|
|
9
|
+
const backend_1 = require("../deploy/functions/backend");
|
|
10
|
+
const proto_1 = require("../gcp/proto");
|
|
9
11
|
const memoryLookup = {
|
|
10
12
|
"128MB": 128,
|
|
11
13
|
"256MB": 256,
|
|
@@ -44,6 +46,54 @@ class EmulatedTrigger {
|
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
48
|
exports.EmulatedTrigger = EmulatedTrigger;
|
|
49
|
+
function emulatedFunctionsFromEndpoints(endpoints) {
|
|
50
|
+
const regionDefinitions = [];
|
|
51
|
+
for (const endpoint of endpoints) {
|
|
52
|
+
if (!endpoint.region) {
|
|
53
|
+
endpoint.region = "us-central1";
|
|
54
|
+
}
|
|
55
|
+
const def = {
|
|
56
|
+
entryPoint: endpoint.entryPoint,
|
|
57
|
+
platform: endpoint.platform,
|
|
58
|
+
region: endpoint.region,
|
|
59
|
+
name: endpoint.id,
|
|
60
|
+
id: `${endpoint.region}-${endpoint.id}`,
|
|
61
|
+
};
|
|
62
|
+
(0, proto_1.copyIfPresent)(def, endpoint, "timeout", "availableMemoryMb", "labels", "platform", "secretEnvironmentVariables");
|
|
63
|
+
if ((0, backend_1.isHttpsTriggered)(endpoint)) {
|
|
64
|
+
def.httpsTrigger = endpoint.httpsTrigger;
|
|
65
|
+
}
|
|
66
|
+
else if ((0, backend_1.isEventTriggered)(endpoint)) {
|
|
67
|
+
const eventTrigger = endpoint.eventTrigger;
|
|
68
|
+
if (endpoint.platform === "gcfv1") {
|
|
69
|
+
def.eventTrigger = {
|
|
70
|
+
eventType: eventTrigger.eventType,
|
|
71
|
+
resource: eventTrigger.eventFilters.resource,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
const { resource, topic, bucket } = endpoint.eventTrigger.eventFilters;
|
|
76
|
+
const eventResource = resource || topic || bucket;
|
|
77
|
+
if (!eventResource) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
def.eventTrigger = {
|
|
81
|
+
eventType: eventTrigger.eventType,
|
|
82
|
+
resource: eventResource,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else if ((0, backend_1.isScheduleTriggered)(endpoint)) {
|
|
87
|
+
def.eventTrigger = { eventType: "pubsub", resource: "" };
|
|
88
|
+
def.schedule = endpoint.scheduleTrigger;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
}
|
|
92
|
+
regionDefinitions.push(def);
|
|
93
|
+
}
|
|
94
|
+
return regionDefinitions;
|
|
95
|
+
}
|
|
96
|
+
exports.emulatedFunctionsFromEndpoints = emulatedFunctionsFromEndpoints;
|
|
47
97
|
function emulatedFunctionsByRegion(definitions) {
|
|
48
98
|
const regionDefinitions = [];
|
|
49
99
|
for (const def of definitions) {
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.FunctionsEmulatorShell = void 0;
|
|
4
4
|
const uuid = require("uuid");
|
|
5
5
|
const functionsEmulator_1 = require("./functionsEmulator");
|
|
6
|
-
const functionsEmulatorShared_1 = require("./functionsEmulatorShared");
|
|
7
6
|
const utils = require("../utils");
|
|
8
7
|
const logger_1 = require("../logger");
|
|
9
8
|
const error_1 = require("../error");
|
|
@@ -43,7 +42,7 @@ class FunctionsEmulatorShell {
|
|
|
43
42
|
auth: opts.auth,
|
|
44
43
|
data,
|
|
45
44
|
};
|
|
46
|
-
this.emu.
|
|
45
|
+
this.emu.invokeTrigger(this.backend, trigger, proto);
|
|
47
46
|
}
|
|
48
47
|
getTrigger(name) {
|
|
49
48
|
const result = this.triggers.find((trigger) => {
|
|
@@ -52,7 +52,7 @@ function parseRuntimeVersion(runtime) {
|
|
|
52
52
|
return undefined;
|
|
53
53
|
}
|
|
54
54
|
const runtimeRe = /(nodejs)?([0-9]+)/;
|
|
55
|
-
const match =
|
|
55
|
+
const match = runtimeRe.exec(runtime);
|
|
56
56
|
if (match) {
|
|
57
57
|
return Number.parseInt(match[2]);
|
|
58
58
|
}
|
|
@@ -73,13 +73,13 @@ exports.parseVersionString = parseVersionString;
|
|
|
73
73
|
function compareVersionStrings(a, b) {
|
|
74
74
|
const versionA = parseVersionString(a);
|
|
75
75
|
const versionB = parseVersionString(b);
|
|
76
|
-
if (versionA.major
|
|
76
|
+
if (versionA.major !== versionB.major) {
|
|
77
77
|
return versionA.major - versionB.major;
|
|
78
78
|
}
|
|
79
|
-
if (versionA.minor
|
|
79
|
+
if (versionA.minor !== versionB.minor) {
|
|
80
80
|
return versionA.minor - versionB.minor;
|
|
81
81
|
}
|
|
82
|
-
if (versionA.patch
|
|
82
|
+
if (versionA.patch !== versionB.patch) {
|
|
83
83
|
return versionA.patch - versionB.patch;
|
|
84
84
|
}
|
|
85
85
|
return 0;
|
|
@@ -43,7 +43,7 @@ class RuntimeWorker {
|
|
|
43
43
|
execute(frb, opts) {
|
|
44
44
|
const execFrb = Object.assign({}, frb);
|
|
45
45
|
if (!execFrb.socketPath) {
|
|
46
|
-
execFrb.socketPath = (0, functionsEmulatorShared_1.getTemporarySocketPath)(this.runtime.pid,
|
|
46
|
+
execFrb.socketPath = (0, functionsEmulatorShared_1.getTemporarySocketPath)(this.runtime.pid, this.runtime.cwd);
|
|
47
47
|
this.log(`Assigning socketPath: ${execFrb.socketPath}`);
|
|
48
48
|
}
|
|
49
49
|
const args = { frb: execFrb, opts };
|
|
@@ -170,14 +170,14 @@ class RuntimeWorkerPool {
|
|
|
170
170
|
}
|
|
171
171
|
return;
|
|
172
172
|
}
|
|
173
|
-
addWorker(triggerId, runtime) {
|
|
173
|
+
addWorker(triggerId, runtime, extensionLogInfo) {
|
|
174
174
|
const worker = new RuntimeWorker(this.getKey(triggerId), runtime);
|
|
175
175
|
this.log(`addWorker(${worker.key})`);
|
|
176
176
|
const keyWorkers = this.getTriggerWorkers(triggerId);
|
|
177
177
|
keyWorkers.push(worker);
|
|
178
178
|
this.setTriggerWorkers(triggerId, keyWorkers);
|
|
179
179
|
const logger = triggerId
|
|
180
|
-
? emulatorLogger_1.EmulatorLogger.forFunction(triggerId)
|
|
180
|
+
? emulatorLogger_1.EmulatorLogger.forFunction(triggerId, extensionLogInfo)
|
|
181
181
|
: emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.FUNCTIONS);
|
|
182
182
|
worker.onLogs((log) => {
|
|
183
183
|
logger.handleRuntimeLog(log);
|
package/lib/emulator/hub.js
CHANGED
|
@@ -25,9 +25,10 @@ class EmulatorHub {
|
|
|
25
25
|
});
|
|
26
26
|
this.hub.get(EmulatorHub.PATH_EMULATORS, (req, res) => {
|
|
27
27
|
const body = {};
|
|
28
|
-
registry_1.EmulatorRegistry.listRunning()
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
for (const emulator of registry_1.EmulatorRegistry.listRunning()) {
|
|
29
|
+
const info = registry_1.EmulatorRegistry.getInfo(emulator);
|
|
30
|
+
body[emulator] = info;
|
|
31
|
+
}
|
|
31
32
|
res.json(body);
|
|
32
33
|
});
|
|
33
34
|
this.hub.post(EmulatorHub.PATH_EXPORT, async (req, res) => {
|
|
@@ -82,7 +82,7 @@ class WebSocketTransport extends TransportStream {
|
|
|
82
82
|
};
|
|
83
83
|
const splat = [info.message, ...(info[triple_beam_1.SPLAT] || [])]
|
|
84
84
|
.map((value) => {
|
|
85
|
-
if (typeof value
|
|
85
|
+
if (typeof value === "string") {
|
|
86
86
|
try {
|
|
87
87
|
bundle.data = Object.assign(Object.assign({}, bundle.data), JSON.parse(value));
|
|
88
88
|
return null;
|
|
@@ -88,7 +88,7 @@ class PubsubEmulator {
|
|
|
88
88
|
this.subscriptionForTopic.set(topicName, sub);
|
|
89
89
|
}
|
|
90
90
|
ensureFunctionsClient() {
|
|
91
|
-
if (this.client
|
|
91
|
+
if (this.client !== undefined)
|
|
92
92
|
return;
|
|
93
93
|
const funcEmulator = registry_1.EmulatorRegistry.get(types_1.Emulators.FUNCTIONS);
|
|
94
94
|
if (!funcEmulator) {
|
package/lib/emulator/registry.js
CHANGED
|
@@ -17,6 +17,9 @@ class EmulatorRegistry {
|
|
|
17
17
|
const info = instance.getInfo();
|
|
18
18
|
await portUtils.waitForPortClosed(info.port, info.host);
|
|
19
19
|
}
|
|
20
|
+
static registerExtensionsEmulator() {
|
|
21
|
+
this.extensionsEmulatorRegistered = true;
|
|
22
|
+
}
|
|
20
23
|
static async stop(name) {
|
|
21
24
|
emulatorLogger_1.EmulatorLogger.forEmulator(name).logLabeled("BULLET", name, `Stopping ${constants_1.Constants.description(name)}`);
|
|
22
25
|
const instance = this.get(name);
|
|
@@ -29,7 +32,8 @@ class EmulatorRegistry {
|
|
|
29
32
|
static async stopAll() {
|
|
30
33
|
const stopPriority = {
|
|
31
34
|
ui: 0,
|
|
32
|
-
|
|
35
|
+
extensions: 1,
|
|
36
|
+
functions: 1.1,
|
|
33
37
|
hosting: 2,
|
|
34
38
|
database: 3.0,
|
|
35
39
|
firestore: 3.1,
|
|
@@ -52,6 +56,9 @@ class EmulatorRegistry {
|
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
58
|
static isRunning(emulator) {
|
|
59
|
+
if (emulator === types_1.Emulators.EXTENSIONS) {
|
|
60
|
+
return this.extensionsEmulatorRegistered && this.isRunning(types_1.Emulators.FUNCTIONS);
|
|
61
|
+
}
|
|
55
62
|
const instance = this.INSTANCES.get(emulator);
|
|
56
63
|
return instance !== undefined;
|
|
57
64
|
}
|
|
@@ -67,7 +74,7 @@ class EmulatorRegistry {
|
|
|
67
74
|
return this.INSTANCES.get(emulator);
|
|
68
75
|
}
|
|
69
76
|
static getInfo(emulator) {
|
|
70
|
-
const instance = this.INSTANCES.get(emulator);
|
|
77
|
+
const instance = this.INSTANCES.get(emulator === types_1.Emulators.EXTENSIONS ? types_1.Emulators.FUNCTIONS : emulator);
|
|
71
78
|
if (!instance) {
|
|
72
79
|
return undefined;
|
|
73
80
|
}
|
|
@@ -97,4 +104,5 @@ class EmulatorRegistry {
|
|
|
97
104
|
}
|
|
98
105
|
}
|
|
99
106
|
exports.EmulatorRegistry = EmulatorRegistry;
|
|
107
|
+
EmulatorRegistry.extensionsEmulatorRegistered = false;
|
|
100
108
|
EmulatorRegistry.INSTANCES = new Map();
|