firebase-tools 11.1.0 → 11.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/accountExporter.js +11 -4
- package/lib/accountImporter.js +5 -6
- package/lib/appdistribution/client.js +7 -9
- package/lib/auth.js +3 -5
- package/lib/checkValidTargetFilters.js +28 -18
- package/lib/commands/database-profile.js +2 -3
- package/lib/commands/database-push.js +2 -3
- package/lib/commands/database-remove.js +1 -2
- package/lib/commands/database-set.js +1 -2
- package/lib/commands/deploy.js +5 -6
- package/lib/commands/ext-dev-emulators-exec.js +1 -1
- package/lib/commands/ext-dev-emulators-start.js +1 -1
- package/lib/commands/ext-dev-list.js +6 -7
- package/lib/commands/ext-export.js +2 -0
- package/lib/commands/ext-info.js +12 -13
- package/lib/commands/ext.js +2 -3
- package/lib/commands/functions-delete.js +1 -7
- package/lib/commands/open.js +5 -6
- package/lib/commands/serve.js +3 -5
- package/lib/commands/use.js +2 -3
- package/lib/config.js +4 -3
- package/lib/deploy/database/prepare.js +2 -3
- package/lib/deploy/extensions/planner.js +1 -0
- package/lib/deploy/extensions/prepare.js +18 -1
- package/lib/deploy/extensions/release.js +4 -0
- package/lib/deploy/extensions/secrets.js +3 -3
- package/lib/deploy/functions/build.js +35 -53
- package/lib/deploy/functions/ensure.js +1 -11
- package/lib/deploy/functions/params.js +189 -0
- package/lib/deploy/functions/prepare.js +3 -13
- package/lib/deploy/functions/prepareFunctionsUpload.js +2 -3
- package/lib/deploy/functions/release/fabricator.js +0 -1
- package/lib/deploy/functions/release/index.js +1 -5
- package/lib/deploy/functions/runtimes/discovery/index.js +18 -3
- package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +3 -2
- package/lib/deploy/functions/runtimes/golang/index.js +2 -22
- package/lib/deploy/functions/runtimes/node/index.js +3 -7
- package/lib/deploy/functions/runtimes/node/parseTriggers.js +2 -2
- package/lib/deploy/lifecycleHooks.js +8 -11
- package/lib/deploy/storage/prepare.js +2 -2
- package/lib/emulator/auth/index.js +1 -1
- package/lib/emulator/auth/operations.js +336 -64
- package/lib/emulator/auth/server.js +2 -2
- package/lib/emulator/auth/state.js +32 -7
- package/lib/emulator/commandUtils.js +1 -1
- package/lib/emulator/constants.js +1 -1
- package/lib/emulator/controller.js +6 -5
- package/lib/emulator/databaseEmulator.js +2 -2
- package/lib/emulator/download.js +1 -1
- package/lib/emulator/downloadableEmulators.js +6 -6
- package/lib/emulator/events/types.js +2 -3
- package/lib/emulator/firestoreEmulator.js +2 -2
- package/lib/emulator/functionsEmulator.js +36 -45
- package/lib/emulator/functionsEmulatorRuntime.js +12 -16
- package/lib/emulator/functionsEmulatorShared.js +7 -5
- package/lib/emulator/functionsRuntimeWorker.js +0 -6
- package/lib/emulator/hostingEmulator.js +1 -1
- package/lib/emulator/hub.js +1 -1
- package/lib/emulator/loggingEmulator.js +1 -1
- package/lib/emulator/pubsubEmulator.js +1 -1
- package/lib/emulator/storage/crc.js +4 -4
- package/lib/emulator/storage/index.js +1 -1
- package/lib/emulator/types.js +1 -1
- package/lib/extensions/askUserForConsent.js +1 -2
- package/lib/extensions/askUserForParam.js +15 -18
- package/lib/extensions/emulator/optionsHelper.js +4 -4
- package/lib/extensions/etags.js +28 -0
- package/lib/extensions/extensionsApi.js +1 -22
- package/lib/extensions/extensionsHelper.js +6 -6
- package/lib/extensions/listExtensions.js +9 -10
- package/lib/extensions/manifest.js +2 -2
- package/lib/extensions/resolveSource.js +11 -7
- package/lib/extensions/secretsUtils.js +3 -3
- package/lib/extensions/types.js +24 -0
- package/lib/extensions/updateHelper.js +1 -1
- package/lib/extensions/utils.js +1 -2
- package/lib/extensions/warnings.js +10 -4
- package/lib/firestore/encodeFirestoreValue.js +11 -8
- package/lib/fsAsync.js +3 -3
- package/lib/functions/env.js +5 -1
- package/lib/functionsConfig.js +18 -15
- package/lib/functionsConfigClone.js +10 -12
- package/lib/gcp/cloudfunctions.js +2 -15
- package/lib/gcp/rules.js +3 -4
- package/lib/gcp/runtimeconfig.js +2 -2
- package/lib/hosting/api.js +9 -11
- package/lib/hosting/expireUtils.js +2 -2
- package/lib/hosting/proxy.js +1 -1
- package/lib/init/features/hosting/github.js +1 -1
- package/lib/init/features/hosting/index.js +2 -2
- package/lib/localFunction.js +4 -4
- package/lib/management/projects.js +6 -7
- package/lib/previews.js +1 -1
- package/lib/profileReport.js +24 -22
- package/lib/prompt.js +1 -2
- package/lib/rc.js +12 -2
- package/lib/rulesDeploy.js +2 -2
- package/lib/serve/index.js +4 -5
- package/lib/utils.js +30 -6
- package/npm-shrinkwrap.json +2 -2
- package/package.json +10 -9
|
@@ -22,16 +22,17 @@ class ProjectState {
|
|
|
22
22
|
this.oobs = new Map();
|
|
23
23
|
this.verificationCodes = new Map();
|
|
24
24
|
this.temporaryProofs = new Map();
|
|
25
|
+
this.pendingLocalIds = new Set();
|
|
25
26
|
}
|
|
26
27
|
get projectNumber() {
|
|
27
28
|
return "12345";
|
|
28
29
|
}
|
|
29
|
-
|
|
30
|
+
generateLocalId() {
|
|
30
31
|
for (let i = 0; i < 10; i++) {
|
|
31
32
|
const localId = (0, utils_1.randomId)(28);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return
|
|
33
|
+
if (!this.users.has(localId) && !this.pendingLocalIds.has(localId)) {
|
|
34
|
+
this.pendingLocalIds.add(localId);
|
|
35
|
+
return localId;
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
throw new Error("Cannot generate a random unique localId after 10 tries.");
|
|
@@ -40,12 +41,10 @@ class ProjectState {
|
|
|
40
41
|
if (this.users.has(localId)) {
|
|
41
42
|
return undefined;
|
|
42
43
|
}
|
|
43
|
-
const timestamp = new Date();
|
|
44
44
|
this.users.set(localId, {
|
|
45
45
|
localId,
|
|
46
|
-
createdAt: props.createdAt || timestamp.getTime().toString(),
|
|
47
|
-
lastLoginAt: timestamp.getTime().toString(),
|
|
48
46
|
});
|
|
47
|
+
this.pendingLocalIds.delete(localId);
|
|
49
48
|
const user = this.updateUserByLocalId(localId, props, {
|
|
50
49
|
upsertProviders: props.providerUserInfo,
|
|
51
50
|
});
|
|
@@ -448,6 +447,26 @@ class AgentProjectState extends ProjectState {
|
|
|
448
447
|
set blockingFunctionsConfig(blockingFunctions) {
|
|
449
448
|
this._config.blockingFunctions = blockingFunctions;
|
|
450
449
|
}
|
|
450
|
+
shouldForwardCredentialToBlockingFunction(type) {
|
|
451
|
+
var _a, _b, _c, _d, _e, _f;
|
|
452
|
+
switch (type) {
|
|
453
|
+
case "accessToken":
|
|
454
|
+
return (_b = (_a = this._config.blockingFunctions.forwardInboundCredentials) === null || _a === void 0 ? void 0 : _a.accessToken) !== null && _b !== void 0 ? _b : false;
|
|
455
|
+
case "idToken":
|
|
456
|
+
return (_d = (_c = this._config.blockingFunctions.forwardInboundCredentials) === null || _c === void 0 ? void 0 : _c.idToken) !== null && _d !== void 0 ? _d : false;
|
|
457
|
+
case "refreshToken":
|
|
458
|
+
return (_f = (_e = this._config.blockingFunctions.forwardInboundCredentials) === null || _e === void 0 ? void 0 : _e.refreshToken) !== null && _f !== void 0 ? _f : false;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
getBlockingFunctionUri(event) {
|
|
462
|
+
const triggers = this.blockingFunctionsConfig.triggers;
|
|
463
|
+
if (triggers) {
|
|
464
|
+
return Object.prototype.hasOwnProperty.call(triggers, event)
|
|
465
|
+
? triggers[event].functionUri
|
|
466
|
+
: undefined;
|
|
467
|
+
}
|
|
468
|
+
return undefined;
|
|
469
|
+
}
|
|
451
470
|
updateConfig(update, updateMask) {
|
|
452
471
|
var _a, _b, _c;
|
|
453
472
|
if (!updateMask) {
|
|
@@ -546,6 +565,12 @@ class TenantProjectState extends ProjectState {
|
|
|
546
565
|
get enableEmailLinkSignin() {
|
|
547
566
|
return this._tenantConfig.enableEmailLinkSignin;
|
|
548
567
|
}
|
|
568
|
+
shouldForwardCredentialToBlockingFunction(type) {
|
|
569
|
+
return this.parentProject.shouldForwardCredentialToBlockingFunction(type);
|
|
570
|
+
}
|
|
571
|
+
getBlockingFunctionUri(event) {
|
|
572
|
+
return this.parentProject.getBlockingFunctionUri(event);
|
|
573
|
+
}
|
|
549
574
|
delete() {
|
|
550
575
|
this.parentProject.deleteTenant(this.tenantId);
|
|
551
576
|
}
|
|
@@ -76,7 +76,7 @@ function warnEmulatorNotSupported(options, emulator) {
|
|
|
76
76
|
type: "confirm",
|
|
77
77
|
default: false,
|
|
78
78
|
message: "Do you want to continue?",
|
|
79
|
-
}).then((
|
|
79
|
+
}).then(() => {
|
|
80
80
|
if (!opts.confirm) {
|
|
81
81
|
return utils.reject("Command aborted.", { exit: 1 });
|
|
82
82
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.exportEmulatorData = exports.startAll = exports.shouldStart = exports.filterEmulatorTargets = exports.cleanShutdown = exports.onExit = exports.exportOnExit = exports.startEmulator = void 0;
|
|
4
|
-
const _ = require("lodash");
|
|
5
4
|
const clc = require("cli-color");
|
|
6
5
|
const fs = require("fs");
|
|
7
6
|
const path = require("path");
|
|
@@ -47,7 +46,7 @@ async function getAndCheckAddress(emulator, options) {
|
|
|
47
46
|
if (emulator === types_1.Emulators.EXTENSIONS) {
|
|
48
47
|
emulator = types_1.Emulators.FUNCTIONS;
|
|
49
48
|
}
|
|
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(
|
|
49
|
+
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
50
|
if (host === "localhost" && utils.isRunningInWSL()) {
|
|
52
51
|
host = "127.0.0.1";
|
|
53
52
|
}
|
|
@@ -135,7 +134,7 @@ function filterEmulatorTargets(options) {
|
|
|
135
134
|
const only = onlyOptions.split(",").map((o) => {
|
|
136
135
|
return o.split(":")[0];
|
|
137
136
|
});
|
|
138
|
-
targets =
|
|
137
|
+
targets = targets.filter((t) => only.includes(t));
|
|
139
138
|
}
|
|
140
139
|
return targets;
|
|
141
140
|
}
|
|
@@ -234,7 +233,7 @@ async function startAll(options, showUI = true) {
|
|
|
234
233
|
const requested = onlyOptions.split(",").map((o) => {
|
|
235
234
|
return o.split(":")[0];
|
|
236
235
|
});
|
|
237
|
-
const ignored =
|
|
236
|
+
const ignored = requested.filter((k) => !targets.includes(k));
|
|
238
237
|
for (const name of ignored) {
|
|
239
238
|
if ((0, types_1.isEmulator)(name)) {
|
|
240
239
|
emulatorLogger_1.EmulatorLogger.forEmulator(name).logLabeled("WARN", name, `Not starting the ${clc.bold(name)} emulator, make sure you have run ${clc.bold("firebase init")}.`);
|
|
@@ -473,7 +472,9 @@ async function startAll(options, showUI = true) {
|
|
|
473
472
|
await startEmulator(hostingEmulator);
|
|
474
473
|
}
|
|
475
474
|
if (showUI && !shouldStart(options, types_1.Emulators.UI)) {
|
|
476
|
-
hubLogger.logLabeled("WARN", "emulators", "The Emulator UI
|
|
475
|
+
hubLogger.logLabeled("WARN", "emulators", "The Emulator UI is not starting, either because none of the emulated " +
|
|
476
|
+
"products have an interaction layer in Emulator UI or it cannot " +
|
|
477
|
+
"determine the Project ID. Pass the --project flag to specify a project.");
|
|
477
478
|
}
|
|
478
479
|
if (showUI && (shouldStart(options, types_1.Emulators.UI) || START_LOGGING_EMULATOR)) {
|
|
479
480
|
const loggingAddr = await getAndCheckAddress(types_1.Emulators.LOGGING, options);
|
|
@@ -34,7 +34,7 @@ class DatabaseEmulator {
|
|
|
34
34
|
continue;
|
|
35
35
|
}
|
|
36
36
|
this.rulesWatcher = chokidar.watch(c.rules, { persistent: true, ignoreInitial: true });
|
|
37
|
-
this.rulesWatcher.on("change", async (
|
|
37
|
+
this.rulesWatcher.on("change", async () => {
|
|
38
38
|
await new Promise((res) => setTimeout(res, 5));
|
|
39
39
|
this.logger.logLabeled("BULLET", "database", `Change detected, updating rules for ${c.instance}...`);
|
|
40
40
|
try {
|
|
@@ -72,7 +72,7 @@ class DatabaseEmulator {
|
|
|
72
72
|
return downloadableEmulators.stop(types_1.Emulators.DATABASE);
|
|
73
73
|
}
|
|
74
74
|
getInfo() {
|
|
75
|
-
const host = this.args.host || constants_1.Constants.getDefaultHost(
|
|
75
|
+
const host = this.args.host || constants_1.Constants.getDefaultHost();
|
|
76
76
|
const port = this.args.port || constants_1.Constants.getDefaultPort(types_1.Emulators.DATABASE);
|
|
77
77
|
return {
|
|
78
78
|
name: this.getName(),
|
package/lib/emulator/download.js
CHANGED
|
@@ -34,7 +34,7 @@ async function downloadEmulator(name) {
|
|
|
34
34
|
exports.downloadEmulator = downloadEmulator;
|
|
35
35
|
async function downloadExtensionVersion(extensionVersionRef, sourceDownloadUri, targetDir) {
|
|
36
36
|
const emulatorLogger = emulatorLogger_1.EmulatorLogger.forExtension({ ref: extensionVersionRef });
|
|
37
|
-
emulatorLogger.logLabeled("BULLET", "extensions", `Starting download for ${extensionVersionRef} source code
|
|
37
|
+
emulatorLogger.logLabeled("BULLET", "extensions", `Starting download for ${extensionVersionRef} source code to ${targetDir}..`);
|
|
38
38
|
try {
|
|
39
39
|
fs.mkdirSync(targetDir);
|
|
40
40
|
}
|
|
@@ -29,13 +29,13 @@ exports.DownloadDetails = {
|
|
|
29
29
|
},
|
|
30
30
|
},
|
|
31
31
|
firestore: {
|
|
32
|
-
downloadPath: path.join(CACHE_DIR, "cloud-firestore-emulator-v1.14.
|
|
33
|
-
version: "1.14.
|
|
32
|
+
downloadPath: path.join(CACHE_DIR, "cloud-firestore-emulator-v1.14.4.jar"),
|
|
33
|
+
version: "1.14.4",
|
|
34
34
|
opts: {
|
|
35
35
|
cacheDir: CACHE_DIR,
|
|
36
|
-
remoteUrl: "https://storage.googleapis.com/firebase-preview-drop/emulator/cloud-firestore-emulator-v1.14.
|
|
37
|
-
expectedSize:
|
|
38
|
-
expectedChecksum: "
|
|
36
|
+
remoteUrl: "https://storage.googleapis.com/firebase-preview-drop/emulator/cloud-firestore-emulator-v1.14.4.jar",
|
|
37
|
+
expectedSize: 61017177,
|
|
38
|
+
expectedChecksum: "953d10e73798484aa0b84c45005faadb",
|
|
39
39
|
namePrefix: "cloud-firestore-emulator",
|
|
40
40
|
},
|
|
41
41
|
},
|
|
@@ -164,7 +164,7 @@ const Commands = {
|
|
|
164
164
|
},
|
|
165
165
|
ui: {
|
|
166
166
|
binary: "node",
|
|
167
|
-
args: [
|
|
167
|
+
args: [getExecPath(types_1.Emulators.UI)],
|
|
168
168
|
optionalArgs: [],
|
|
169
169
|
joinArgs: false,
|
|
170
170
|
},
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EventUtils = void 0;
|
|
4
|
-
const _ = require("lodash");
|
|
5
4
|
class EventUtils {
|
|
6
5
|
static isEvent(proto) {
|
|
7
|
-
return
|
|
6
|
+
return proto.context && proto.data;
|
|
8
7
|
}
|
|
9
8
|
static isLegacyEvent(proto) {
|
|
10
|
-
return
|
|
9
|
+
return proto.data && proto.resource;
|
|
11
10
|
}
|
|
12
11
|
static isBinaryCloudEvent(req) {
|
|
13
12
|
return !!(req.header("ce-type") &&
|
|
@@ -23,7 +23,7 @@ class FirestoreEmulator {
|
|
|
23
23
|
if (this.args.rules && this.args.projectId) {
|
|
24
24
|
const rulesPath = this.args.rules;
|
|
25
25
|
this.rulesWatcher = chokidar.watch(rulesPath, { persistent: true, ignoreInitial: true });
|
|
26
|
-
this.rulesWatcher.on("change", async (
|
|
26
|
+
this.rulesWatcher.on("change", async () => {
|
|
27
27
|
await new Promise((res) => setTimeout(res, 5));
|
|
28
28
|
utils.logLabeledBullet("firestore", "Change detected, updating rules...");
|
|
29
29
|
const newContent = fs.readFileSync(rulesPath, "utf8").toString();
|
|
@@ -53,7 +53,7 @@ class FirestoreEmulator {
|
|
|
53
53
|
return downloadableEmulators.stop(types_1.Emulators.FIRESTORE);
|
|
54
54
|
}
|
|
55
55
|
getInfo() {
|
|
56
|
-
const host = this.args.host || constants_1.Constants.getDefaultHost(
|
|
56
|
+
const host = this.args.host || constants_1.Constants.getDefaultHost();
|
|
57
57
|
const port = this.args.port || constants_1.Constants.getDefaultPort(types_1.Emulators.FIRESTORE);
|
|
58
58
|
return {
|
|
59
59
|
name: this.getName(),
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FunctionsEmulator = void 0;
|
|
4
|
-
const _ = require("lodash");
|
|
5
4
|
const fs = require("fs");
|
|
6
5
|
const path = require("path");
|
|
7
6
|
const express = require("express");
|
|
@@ -34,6 +33,7 @@ const backend = require("../deploy/functions/backend");
|
|
|
34
33
|
const functionsEnv = require("../functions/env");
|
|
35
34
|
const v1_1 = require("../functions/events/v1");
|
|
36
35
|
const apiv2_1 = require("../apiv2");
|
|
36
|
+
const build_1 = require("../deploy/functions/build");
|
|
37
37
|
const EVENT_INVOKE = "functions:invoke";
|
|
38
38
|
const DATABASE_PATH_PATTERN = new RegExp("^projects/[^/]+/instances/([^/]+)/refs(/.*)$");
|
|
39
39
|
class FunctionsEmulator {
|
|
@@ -43,6 +43,7 @@ class FunctionsEmulator {
|
|
|
43
43
|
this.triggerGeneration = 0;
|
|
44
44
|
this.logger = emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.FUNCTIONS);
|
|
45
45
|
this.multicastTriggers = {};
|
|
46
|
+
this.blockingFunctionsConfig = {};
|
|
46
47
|
emulatorLogger_1.EmulatorLogger.verbosity = this.args.quiet ? emulatorLogger_1.Verbosity.QUIET : emulatorLogger_1.Verbosity.DEBUG;
|
|
47
48
|
if (this.args.debugPort) {
|
|
48
49
|
this.args.disabledRuntimeFeatures = this.args.disabledRuntimeFeatures || {};
|
|
@@ -54,16 +55,6 @@ class FunctionsEmulator {
|
|
|
54
55
|
: types_1.FunctionsExecutionMode.AUTO;
|
|
55
56
|
this.workerPool = new functionsRuntimeWorker_1.RuntimeWorkerPool(mode);
|
|
56
57
|
this.workQueue = new workQueue_1.WorkQueue(mode);
|
|
57
|
-
this.blockingFunctionsConfig = {
|
|
58
|
-
triggers: {
|
|
59
|
-
beforeCreate: {
|
|
60
|
-
functionUri: "",
|
|
61
|
-
},
|
|
62
|
-
beforeSignIn: {
|
|
63
|
-
functionUri: "",
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
58
|
}
|
|
68
59
|
static getHttpFunctionUrl(host, port, projectId, name, region) {
|
|
69
60
|
return `http://${host}:${port}/${projectId}/${region}/${name}`;
|
|
@@ -105,7 +96,6 @@ class FunctionsEmulator {
|
|
|
105
96
|
const listBackendsRoute = `/backends`;
|
|
106
97
|
const backgroundHandler = (req, res) => {
|
|
107
98
|
var _a;
|
|
108
|
-
const region = req.params.region;
|
|
109
99
|
const triggerId = req.params.trigger_name;
|
|
110
100
|
const projectId = req.params.project_id;
|
|
111
101
|
const reqBody = req.rawBody;
|
|
@@ -232,7 +222,7 @@ class FunctionsEmulator {
|
|
|
232
222
|
],
|
|
233
223
|
persistent: true,
|
|
234
224
|
});
|
|
235
|
-
const debouncedLoadTriggers =
|
|
225
|
+
const debouncedLoadTriggers = (0, utils_1.debounce)(() => this.loadTriggers(backend), 1000);
|
|
236
226
|
watcher.on("change", (filePath) => {
|
|
237
227
|
this.logger.log("DEBUG", `File ${filePath} changed, reloading triggers`);
|
|
238
228
|
return debouncedLoadTriggers();
|
|
@@ -260,6 +250,7 @@ class FunctionsEmulator {
|
|
|
260
250
|
if (!emulatableBackend.nodeBinary) {
|
|
261
251
|
throw new error_1.FirebaseError(`No node binary for ${emulatableBackend.functionsDir}. This should never happen.`);
|
|
262
252
|
}
|
|
253
|
+
this.blockingFunctionsConfig = {};
|
|
263
254
|
let triggerDefinitions;
|
|
264
255
|
if (emulatableBackend.predefinedTriggers) {
|
|
265
256
|
triggerDefinitions = (0, functionsEmulatorShared_1.emulatedFunctionsByRegion)(emulatableBackend.predefinedTriggers, emulatableBackend.secretEnv);
|
|
@@ -280,7 +271,14 @@ class FunctionsEmulator {
|
|
|
280
271
|
logger_1.logger.debug(`Building ${runtimeDelegate.name} source`);
|
|
281
272
|
await runtimeDelegate.build();
|
|
282
273
|
logger_1.logger.debug(`Analyzing ${runtimeDelegate.name} backend spec`);
|
|
283
|
-
const
|
|
274
|
+
const environment = Object.assign(Object.assign(Object.assign(Object.assign({}, this.getSystemEnvs()), this.getEmulatorEnvs()), { FIREBASE_CONFIG: this.getFirebaseConfig() }), emulatableBackend.env);
|
|
275
|
+
const userEnvOpt = {
|
|
276
|
+
functionsSource: emulatableBackend.functionsDir,
|
|
277
|
+
projectId: this.args.projectId,
|
|
278
|
+
projectAlias: this.args.projectAlias,
|
|
279
|
+
};
|
|
280
|
+
const discoveredBuild = await runtimeDelegate.discoverBuild(runtimeConfig, environment);
|
|
281
|
+
const discoveredBackend = await (0, build_1.resolveBackend)(discoveredBuild, userEnvOpt, environment);
|
|
284
282
|
const endpoints = backend.allEndpoints(discoveredBackend);
|
|
285
283
|
(0, functionsEmulatorShared_1.prepareEndpoints)(endpoints);
|
|
286
284
|
for (const e of endpoints) {
|
|
@@ -348,7 +346,7 @@ class FunctionsEmulator {
|
|
|
348
346
|
added = this.addBlockingTrigger(url, definition.blockingTrigger);
|
|
349
347
|
}
|
|
350
348
|
else {
|
|
351
|
-
this.logger.log("WARN", `Unsupported function type on ${definition.name}. Expected either httpsTrigger or
|
|
349
|
+
this.logger.log("WARN", `Unsupported function type on ${definition.name}. Expected either an httpsTrigger, eventTrigger, or blockingTrigger.`);
|
|
352
350
|
}
|
|
353
351
|
const ignored = !added;
|
|
354
352
|
this.addTriggerRecord(definition, { backend: emulatableBackend, ignored, url });
|
|
@@ -371,9 +369,8 @@ class FunctionsEmulator {
|
|
|
371
369
|
}
|
|
372
370
|
}
|
|
373
371
|
async performPostLoadOperations() {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
((_d = (_c = this.blockingFunctionsConfig.triggers) === null || _c === void 0 ? void 0 : _c.beforeSignIn) === null || _d === void 0 ? void 0 : _d.functionUri) === "") {
|
|
372
|
+
if (!this.blockingFunctionsConfig.triggers &&
|
|
373
|
+
!this.blockingFunctionsConfig.forwardInboundCredentials) {
|
|
377
374
|
return;
|
|
378
375
|
}
|
|
379
376
|
const authEmu = registry_1.EmulatorRegistry.get(types_1.Emulators.AUTH);
|
|
@@ -500,33 +497,31 @@ class FunctionsEmulator {
|
|
|
500
497
|
addBlockingTrigger(url, blockingTrigger) {
|
|
501
498
|
logger_1.logger.debug(`addBlockingTrigger`, JSON.stringify({ blockingTrigger }));
|
|
502
499
|
const eventType = blockingTrigger.eventType;
|
|
503
|
-
if (v1_1.AUTH_BLOCKING_EVENTS.includes(eventType)) {
|
|
504
|
-
if (blockingTrigger.eventType === v1_1.BEFORE_CREATE_EVENT) {
|
|
505
|
-
this.blockingFunctionsConfig.triggers = Object.assign(Object.assign({}, this.blockingFunctionsConfig.triggers), { beforeCreate: {
|
|
506
|
-
functionUri: url,
|
|
507
|
-
} });
|
|
508
|
-
}
|
|
509
|
-
else {
|
|
510
|
-
this.blockingFunctionsConfig.triggers = Object.assign(Object.assign({}, this.blockingFunctionsConfig.triggers), { beforeSignIn: {
|
|
511
|
-
functionUri: url,
|
|
512
|
-
} });
|
|
513
|
-
}
|
|
514
|
-
this.blockingFunctionsConfig.forwardInboundCredentials = {
|
|
515
|
-
accessToken: blockingTrigger.options.accessToken,
|
|
516
|
-
idToken: blockingTrigger.options.idToken,
|
|
517
|
-
refreshToken: blockingTrigger.options.refreshToken,
|
|
518
|
-
};
|
|
519
|
-
}
|
|
520
|
-
else {
|
|
500
|
+
if (!v1_1.AUTH_BLOCKING_EVENTS.includes(eventType)) {
|
|
521
501
|
return false;
|
|
522
502
|
}
|
|
503
|
+
if (blockingTrigger.eventType === v1_1.BEFORE_CREATE_EVENT) {
|
|
504
|
+
this.blockingFunctionsConfig.triggers = Object.assign(Object.assign({}, this.blockingFunctionsConfig.triggers), { beforeCreate: {
|
|
505
|
+
functionUri: url,
|
|
506
|
+
} });
|
|
507
|
+
}
|
|
508
|
+
else {
|
|
509
|
+
this.blockingFunctionsConfig.triggers = Object.assign(Object.assign({}, this.blockingFunctionsConfig.triggers), { beforeSignIn: {
|
|
510
|
+
functionUri: url,
|
|
511
|
+
} });
|
|
512
|
+
}
|
|
513
|
+
this.blockingFunctionsConfig.forwardInboundCredentials = {
|
|
514
|
+
accessToken: !!blockingTrigger.options.accessToken,
|
|
515
|
+
idToken: !!blockingTrigger.options.idToken,
|
|
516
|
+
refreshToken: !!blockingTrigger.options.refreshToken,
|
|
517
|
+
};
|
|
523
518
|
return true;
|
|
524
519
|
}
|
|
525
520
|
getProjectId() {
|
|
526
521
|
return this.args.projectId;
|
|
527
522
|
}
|
|
528
523
|
getInfo() {
|
|
529
|
-
const host = this.args.host || constants_1.Constants.getDefaultHost(
|
|
524
|
+
const host = this.args.host || constants_1.Constants.getDefaultHost();
|
|
530
525
|
const port = this.args.port || constants_1.Constants.getDefaultPort(types_1.Emulators.FUNCTIONS);
|
|
531
526
|
return {
|
|
532
527
|
name: this.getName(),
|
|
@@ -788,9 +783,10 @@ class FunctionsEmulator {
|
|
|
788
783
|
}
|
|
789
784
|
const runtimeEnv = this.getRuntimeEnvs(backend, trigger);
|
|
790
785
|
const secretEnvs = await this.resolveSecretEnvs(backend, trigger);
|
|
786
|
+
const socketPath = (0, functionsEmulatorShared_1.getTemporarySocketPath)();
|
|
791
787
|
const childProcess = spawn(opts.nodeBinary, args, {
|
|
792
788
|
cwd: backend.functionsDir,
|
|
793
|
-
env: Object.assign(Object.assign(Object.assign({ node: opts.nodeBinary }, process.env), runtimeEnv), secretEnvs),
|
|
789
|
+
env: Object.assign(Object.assign(Object.assign(Object.assign({ node: opts.nodeBinary }, process.env), runtimeEnv), secretEnvs), { PORT: socketPath }),
|
|
794
790
|
stdio: ["pipe", "pipe", "pipe", "ipc"],
|
|
795
791
|
});
|
|
796
792
|
if (!childProcess.stderr) {
|
|
@@ -822,6 +818,7 @@ class FunctionsEmulator {
|
|
|
822
818
|
}),
|
|
823
819
|
events: emitter,
|
|
824
820
|
cwd: backend.functionsDir,
|
|
821
|
+
socketPath,
|
|
825
822
|
shutdown: () => {
|
|
826
823
|
childProcess.kill();
|
|
827
824
|
},
|
|
@@ -960,12 +957,6 @@ class FunctionsEmulator {
|
|
|
960
957
|
await worker.waitForSocketReady();
|
|
961
958
|
void (0, track_1.track)(EVENT_INVOKE, "https");
|
|
962
959
|
this.logger.log("DEBUG", `[functions] Runtime ready! Sending request!`);
|
|
963
|
-
if (!worker.lastArgs) {
|
|
964
|
-
throw new error_1.FirebaseError("Cannot execute on a worker with no arguments");
|
|
965
|
-
}
|
|
966
|
-
if (!worker.lastArgs.frb.socketPath) {
|
|
967
|
-
throw new error_1.FirebaseError(`Cannot execute on a worker without a socketPath: ${JSON.stringify(worker.lastArgs)}`);
|
|
968
|
-
}
|
|
969
960
|
const url = new url_1.URL(`${req.protocol}://${req.hostname}${req.url}`);
|
|
970
961
|
const path = `${url.pathname}${url.search}`.replace(new RegExp(`\/${this.args.projectId}\/[^\/]*\/${triggerName}\/?`), "/");
|
|
971
962
|
this.logger.log("DEBUG", `[functions] Got req.url=${req.url}, mapping to path=${path}`);
|
|
@@ -973,7 +964,7 @@ class FunctionsEmulator {
|
|
|
973
964
|
method,
|
|
974
965
|
path,
|
|
975
966
|
headers: req.headers,
|
|
976
|
-
socketPath: worker.
|
|
967
|
+
socketPath: worker.runtime.socketPath,
|
|
977
968
|
}, (runtimeRes) => {
|
|
978
969
|
function forwardStatusAndHeaders() {
|
|
979
970
|
res.status(runtimeRes.statusCode || 200);
|
|
@@ -105,7 +105,7 @@ class Proxied {
|
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
async function resolveDeveloperNodeModule(frb, name) {
|
|
108
|
-
const pkg = requirePackageJson(
|
|
108
|
+
const pkg = requirePackageJson();
|
|
109
109
|
if (!pkg) {
|
|
110
110
|
new types_1.EmulatorLog("SYSTEM", "missing-package-json", "").log();
|
|
111
111
|
throw new Error("Could not find package.json");
|
|
@@ -159,7 +159,7 @@ async function verifyDeveloperNodeModules(frb) {
|
|
|
159
159
|
}
|
|
160
160
|
return true;
|
|
161
161
|
}
|
|
162
|
-
function requirePackageJson(
|
|
162
|
+
function requirePackageJson() {
|
|
163
163
|
if (developerPkgJSON) {
|
|
164
164
|
return developerPkgJSON;
|
|
165
165
|
}
|
|
@@ -176,7 +176,7 @@ function requirePackageJson(frb) {
|
|
|
176
176
|
return;
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
|
-
function initializeNetworkFiltering(
|
|
179
|
+
function initializeNetworkFiltering() {
|
|
180
180
|
const networkingModules = [
|
|
181
181
|
{ name: "http", module: require("http"), path: ["request"] },
|
|
182
182
|
{ name: "http", module: require("http"), path: ["get"] },
|
|
@@ -323,7 +323,7 @@ function wrapCallableHandler(handler) {
|
|
|
323
323
|
function getDefaultConfig() {
|
|
324
324
|
return JSON.parse(process.env.FIREBASE_CONFIG || "{}");
|
|
325
325
|
}
|
|
326
|
-
function initializeRuntimeConfig(
|
|
326
|
+
function initializeRuntimeConfig() {
|
|
327
327
|
if (!process.env.CLOUD_RUNTIME_CONFIG) {
|
|
328
328
|
const configPath = `${process.cwd()}/.runtimeconfig.json`;
|
|
329
329
|
try {
|
|
@@ -470,7 +470,7 @@ async function initializeFunctionsConfigHelper(frb) {
|
|
|
470
470
|
.finalize();
|
|
471
471
|
const functionsModuleProxy = new Proxied(localFunctionsModule);
|
|
472
472
|
const proxiedFunctionsModule = functionsModuleProxy
|
|
473
|
-
.when("config", (
|
|
473
|
+
.when("config", () => () => {
|
|
474
474
|
return proxiedConfig;
|
|
475
475
|
})
|
|
476
476
|
.finalize();
|
|
@@ -485,14 +485,9 @@ async function initializeFunctionsConfigHelper(frb) {
|
|
|
485
485
|
function rawBodySaver(req, res, buf) {
|
|
486
486
|
req.rawBody = buf;
|
|
487
487
|
}
|
|
488
|
-
async function processHTTPS(trigger
|
|
488
|
+
async function processHTTPS(trigger) {
|
|
489
489
|
const ephemeralServer = express();
|
|
490
490
|
const functionRouter = express.Router();
|
|
491
|
-
const socketPath = frb.socketPath;
|
|
492
|
-
if (!socketPath) {
|
|
493
|
-
new types_1.EmulatorLog("FATAL", "runtime-error", "Called processHTTPS with no socketPath").log();
|
|
494
|
-
return;
|
|
495
|
-
}
|
|
496
491
|
await new Promise((resolveEphemeralServer, rejectEphemeralServer) => {
|
|
497
492
|
const handler = async (req, res) => {
|
|
498
493
|
try {
|
|
@@ -534,8 +529,9 @@ async function processHTTPS(trigger, frb) {
|
|
|
534
529
|
}));
|
|
535
530
|
functionRouter.all("*", handler);
|
|
536
531
|
ephemeralServer.use([`/`, `/*`], functionRouter);
|
|
537
|
-
logDebug(`Attempting to listen to
|
|
538
|
-
const instance = ephemeralServer.listen(
|
|
532
|
+
logDebug(`Attempting to listen to port: ${process.env.PORT}`);
|
|
533
|
+
const instance = ephemeralServer.listen(process.env.PORT, () => {
|
|
534
|
+
logDebug(`Listening to port: ${process.env.PORT}`);
|
|
539
535
|
new types_1.EmulatorLog("SYSTEM", "runtime-status", "ready", { state: "ready" }).log();
|
|
540
536
|
});
|
|
541
537
|
instance.on("error", rejectEphemeralServer);
|
|
@@ -640,7 +636,7 @@ async function invokeTrigger(trigger, frb) {
|
|
|
640
636
|
await processBackground(trigger, frb, FUNCTION_SIGNATURE);
|
|
641
637
|
break;
|
|
642
638
|
case "http":
|
|
643
|
-
await processHTTPS(trigger
|
|
639
|
+
await processHTTPS(trigger);
|
|
644
640
|
break;
|
|
645
641
|
}
|
|
646
642
|
if (timeoutId) {
|
|
@@ -669,8 +665,8 @@ async function initializeRuntime(frb) {
|
|
|
669
665
|
new types_1.EmulatorLog("INFO", "runtime-status", `Your functions could not be parsed due to an issue with your node_modules (see above)`).log();
|
|
670
666
|
return;
|
|
671
667
|
}
|
|
672
|
-
initializeRuntimeConfig(
|
|
673
|
-
initializeNetworkFiltering(
|
|
668
|
+
initializeRuntimeConfig();
|
|
669
|
+
initializeNetworkFiltering();
|
|
674
670
|
await initializeFunctionsConfigHelper(frb);
|
|
675
671
|
await initializeFirebaseFunctionsStubs(frb);
|
|
676
672
|
await initializeFirebaseAdminStubs(frb);
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.toBackendInfo = exports.getSecretLocalPath = exports.getSignatureType = exports.formatHost = exports.findModuleRoot = exports.waitForBody = exports.getServiceFromEventType = exports.getFunctionService = exports.getTemporarySocketPath = exports.getEmulatedTriggersFromDefinitions = exports.emulatedFunctionsByRegion = exports.emulatedFunctionsFromEndpoints = exports.prepareEndpoints = exports.EmulatedTrigger = exports.HttpConstants = void 0;
|
|
4
|
-
const _ = require("lodash");
|
|
5
4
|
const os = require("os");
|
|
6
5
|
const path = require("path");
|
|
7
6
|
const fs = require("fs");
|
|
7
|
+
const crypto_1 = require("crypto");
|
|
8
|
+
const _ = require("lodash");
|
|
8
9
|
const backend = require("../deploy/functions/backend");
|
|
9
10
|
const constants_1 = require("./constants");
|
|
10
11
|
const proto_1 = require("../gcp/proto");
|
|
@@ -142,12 +143,13 @@ function getEmulatedTriggersFromDefinitions(definitions, module) {
|
|
|
142
143
|
}, {});
|
|
143
144
|
}
|
|
144
145
|
exports.getEmulatedTriggersFromDefinitions = getEmulatedTriggersFromDefinitions;
|
|
145
|
-
function getTemporarySocketPath(
|
|
146
|
+
function getTemporarySocketPath() {
|
|
147
|
+
const rand = (0, crypto_1.randomBytes)(8).toString("hex");
|
|
146
148
|
if (process.platform === "win32") {
|
|
147
|
-
return path.join("\\\\?\\pipe",
|
|
149
|
+
return path.join("\\\\?\\pipe", `fire_emu_${rand}`);
|
|
148
150
|
}
|
|
149
151
|
else {
|
|
150
|
-
return path.join(os.tmpdir(), `fire_emu_${
|
|
152
|
+
return path.join(os.tmpdir(), `fire_emu_${rand}.sock`);
|
|
151
153
|
}
|
|
152
154
|
}
|
|
153
155
|
exports.getTemporarySocketPath = getTemporarySocketPath;
|
|
@@ -239,7 +241,7 @@ function formatHost(info) {
|
|
|
239
241
|
}
|
|
240
242
|
exports.formatHost = formatHost;
|
|
241
243
|
function getSignatureType(def) {
|
|
242
|
-
if (def.httpsTrigger) {
|
|
244
|
+
if (def.httpsTrigger || def.blockingTrigger) {
|
|
243
245
|
return "http";
|
|
244
246
|
}
|
|
245
247
|
return def.platform === "gcfv2" ? "cloudevent" : "event";
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.RuntimeWorkerPool = exports.RuntimeWorker = exports.RuntimeWorkerState = void 0;
|
|
4
4
|
const uuid = require("uuid");
|
|
5
5
|
const types_1 = require("./types");
|
|
6
|
-
const functionsEmulatorShared_1 = require("./functionsEmulatorShared");
|
|
7
6
|
const events_1 = require("events");
|
|
8
7
|
const emulatorLogger_1 = require("./emulatorLogger");
|
|
9
8
|
const error_1 = require("../error");
|
|
@@ -42,13 +41,8 @@ class RuntimeWorker {
|
|
|
42
41
|
}
|
|
43
42
|
execute(frb, opts) {
|
|
44
43
|
const execFrb = Object.assign({}, frb);
|
|
45
|
-
if (!execFrb.socketPath) {
|
|
46
|
-
execFrb.socketPath = (0, functionsEmulatorShared_1.getTemporarySocketPath)(this.runtime.pid, this.runtime.cwd);
|
|
47
|
-
this.log(`Assigning socketPath: ${execFrb.socketPath}`);
|
|
48
|
-
}
|
|
49
44
|
const args = { frb: execFrb, opts };
|
|
50
45
|
this.state = RuntimeWorkerState.BUSY;
|
|
51
|
-
this.lastArgs = args;
|
|
52
46
|
this.runtime.send(args);
|
|
53
47
|
}
|
|
54
48
|
get state() {
|
|
@@ -20,7 +20,7 @@ class HostingEmulator {
|
|
|
20
20
|
return serveHosting.stop();
|
|
21
21
|
}
|
|
22
22
|
getInfo() {
|
|
23
|
-
const host = this.args.host || constants_1.Constants.getDefaultHost(
|
|
23
|
+
const host = this.args.host || constants_1.Constants.getDefaultHost();
|
|
24
24
|
const port = this.args.port || constants_1.Constants.getDefaultPort(types_1.Emulators.HOSTING);
|
|
25
25
|
return {
|
|
26
26
|
name: this.getName(),
|
package/lib/emulator/hub.js
CHANGED
|
@@ -105,7 +105,7 @@ class EmulatorHub {
|
|
|
105
105
|
await this.deleteLocatorFile();
|
|
106
106
|
}
|
|
107
107
|
getInfo() {
|
|
108
|
-
const host = this.args.host || constants_1.Constants.getDefaultHost(
|
|
108
|
+
const host = this.args.host || constants_1.Constants.getDefaultHost();
|
|
109
109
|
const port = this.args.port || constants_1.Constants.getDefaultPort(types_1.Emulators.HUB);
|
|
110
110
|
return {
|
|
111
111
|
name: this.getName(),
|
|
@@ -28,7 +28,7 @@ class LoggingEmulator {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
getInfo() {
|
|
31
|
-
const host = this.args.host || constants_1.Constants.getDefaultHost(
|
|
31
|
+
const host = this.args.host || constants_1.Constants.getDefaultHost();
|
|
32
32
|
const port = this.args.port || constants_1.Constants.getDefaultPort(types_1.Emulators.LOGGING);
|
|
33
33
|
return {
|
|
34
34
|
name: this.getName(),
|
|
@@ -32,7 +32,7 @@ class PubsubEmulator {
|
|
|
32
32
|
await downloadableEmulators.stop(types_1.Emulators.PUBSUB);
|
|
33
33
|
}
|
|
34
34
|
getInfo() {
|
|
35
|
-
const host = this.args.host || constants_1.Constants.getDefaultHost(
|
|
35
|
+
const host = this.args.host || constants_1.Constants.getDefaultHost();
|
|
36
36
|
const port = this.args.port || constants_1.Constants.getDefaultPort(types_1.Emulators.PUBSUB);
|
|
37
37
|
return {
|
|
38
38
|
name: this.getName(),
|
|
@@ -25,9 +25,9 @@ function crc32c(bytes) {
|
|
|
25
25
|
}
|
|
26
26
|
exports.crc32c = crc32c;
|
|
27
27
|
function crc32cToString(crc32cValue) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return
|
|
28
|
+
const value = typeof crc32cValue === "string" ? Number.parseInt(crc32cValue) : crc32cValue;
|
|
29
|
+
const buffer = Buffer.alloc(4);
|
|
30
|
+
buffer.writeUint32BE(value);
|
|
31
|
+
return buffer.toString("base64");
|
|
32
32
|
}
|
|
33
33
|
exports.crc32cToString = crc32cToString;
|
|
@@ -68,7 +68,7 @@ class StorageEmulator {
|
|
|
68
68
|
return this.destroyServer ? this.destroyServer() : Promise.resolve();
|
|
69
69
|
}
|
|
70
70
|
getInfo() {
|
|
71
|
-
const host = this.args.host || constants_1.Constants.getDefaultHost(
|
|
71
|
+
const host = this.args.host || constants_1.Constants.getDefaultHost();
|
|
72
72
|
const port = this.args.port || constants_1.Constants.getDefaultPort(types_1.Emulators.STORAGE);
|
|
73
73
|
return {
|
|
74
74
|
name: this.getName(),
|