firebase-tools 11.1.0 → 11.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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-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/secrets.js +3 -3
- package/lib/deploy/functions/build.js +3 -2
- package/lib/deploy/functions/ensure.js +1 -11
- 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 +1 -1
- package/lib/deploy/lifecycleHooks.js +7 -10
- package/lib/deploy/storage/prepare.js +1 -1
- 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/events/types.js +2 -3
- package/lib/emulator/firestoreEmulator.js +2 -2
- package/lib/emulator/functionsEmulator.js +27 -37
- package/lib/emulator/functionsEmulatorRuntime.js +7 -7
- 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/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 +3 -3
- package/lib/firestore/encodeFirestoreValue.js +11 -8
- package/lib/fsAsync.js +3 -3
- package/lib/functionsConfig.js +17 -14
- package/lib/functionsConfigClone.js +10 -12
- package/lib/gcp/cloudfunctions.js +2 -15
- package/lib/gcp/rules.js +1 -1
- package/lib/gcp/runtimeconfig.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/previews.js +1 -1
- package/lib/profileReport.js +10 -10
- package/lib/prompt.js +1 -2
- package/lib/rc.js +1 -1
- 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
|
}
|
|
@@ -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,9 @@ 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 discoveredBuild = await runtimeDelegate.discoverBuild(runtimeConfig, environment);
|
|
276
|
+
const discoveredBackend = (0, build_1.resolveBackend)(discoveredBuild, environment);
|
|
284
277
|
const endpoints = backend.allEndpoints(discoveredBackend);
|
|
285
278
|
(0, functionsEmulatorShared_1.prepareEndpoints)(endpoints);
|
|
286
279
|
for (const e of endpoints) {
|
|
@@ -348,7 +341,7 @@ class FunctionsEmulator {
|
|
|
348
341
|
added = this.addBlockingTrigger(url, definition.blockingTrigger);
|
|
349
342
|
}
|
|
350
343
|
else {
|
|
351
|
-
this.logger.log("WARN", `Unsupported function type on ${definition.name}. Expected either httpsTrigger or
|
|
344
|
+
this.logger.log("WARN", `Unsupported function type on ${definition.name}. Expected either an httpsTrigger, eventTrigger, or blockingTrigger.`);
|
|
352
345
|
}
|
|
353
346
|
const ignored = !added;
|
|
354
347
|
this.addTriggerRecord(definition, { backend: emulatableBackend, ignored, url });
|
|
@@ -371,9 +364,8 @@ class FunctionsEmulator {
|
|
|
371
364
|
}
|
|
372
365
|
}
|
|
373
366
|
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) === "") {
|
|
367
|
+
if (!this.blockingFunctionsConfig.triggers &&
|
|
368
|
+
!this.blockingFunctionsConfig.forwardInboundCredentials) {
|
|
377
369
|
return;
|
|
378
370
|
}
|
|
379
371
|
const authEmu = registry_1.EmulatorRegistry.get(types_1.Emulators.AUTH);
|
|
@@ -500,33 +492,31 @@ class FunctionsEmulator {
|
|
|
500
492
|
addBlockingTrigger(url, blockingTrigger) {
|
|
501
493
|
logger_1.logger.debug(`addBlockingTrigger`, JSON.stringify({ blockingTrigger }));
|
|
502
494
|
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 {
|
|
495
|
+
if (!v1_1.AUTH_BLOCKING_EVENTS.includes(eventType)) {
|
|
521
496
|
return false;
|
|
522
497
|
}
|
|
498
|
+
if (blockingTrigger.eventType === v1_1.BEFORE_CREATE_EVENT) {
|
|
499
|
+
this.blockingFunctionsConfig.triggers = Object.assign(Object.assign({}, this.blockingFunctionsConfig.triggers), { beforeCreate: {
|
|
500
|
+
functionUri: url,
|
|
501
|
+
} });
|
|
502
|
+
}
|
|
503
|
+
else {
|
|
504
|
+
this.blockingFunctionsConfig.triggers = Object.assign(Object.assign({}, this.blockingFunctionsConfig.triggers), { beforeSignIn: {
|
|
505
|
+
functionUri: url,
|
|
506
|
+
} });
|
|
507
|
+
}
|
|
508
|
+
this.blockingFunctionsConfig.forwardInboundCredentials = {
|
|
509
|
+
accessToken: !!blockingTrigger.options.accessToken,
|
|
510
|
+
idToken: !!blockingTrigger.options.idToken,
|
|
511
|
+
refreshToken: !!blockingTrigger.options.refreshToken,
|
|
512
|
+
};
|
|
523
513
|
return true;
|
|
524
514
|
}
|
|
525
515
|
getProjectId() {
|
|
526
516
|
return this.args.projectId;
|
|
527
517
|
}
|
|
528
518
|
getInfo() {
|
|
529
|
-
const host = this.args.host || constants_1.Constants.getDefaultHost(
|
|
519
|
+
const host = this.args.host || constants_1.Constants.getDefaultHost();
|
|
530
520
|
const port = this.args.port || constants_1.Constants.getDefaultPort(types_1.Emulators.FUNCTIONS);
|
|
531
521
|
return {
|
|
532
522
|
name: this.getName(),
|
|
@@ -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();
|
|
@@ -669,8 +669,8 @@ async function initializeRuntime(frb) {
|
|
|
669
669
|
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
670
|
return;
|
|
671
671
|
}
|
|
672
|
-
initializeRuntimeConfig(
|
|
673
|
-
initializeNetworkFiltering(
|
|
672
|
+
initializeRuntimeConfig();
|
|
673
|
+
initializeNetworkFiltering();
|
|
674
674
|
await initializeFunctionsConfigHelper(frb);
|
|
675
675
|
await initializeFirebaseFunctionsStubs(frb);
|
|
676
676
|
await initializeFirebaseAdminStubs(frb);
|
|
@@ -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(),
|
package/lib/emulator/types.js
CHANGED
|
@@ -104,7 +104,7 @@ class EmulatorLog {
|
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
106
|
static waitForLog(emitter, level, type, filter) {
|
|
107
|
-
return new Promise((resolve
|
|
107
|
+
return new Promise((resolve) => {
|
|
108
108
|
const listener = (el) => {
|
|
109
109
|
const levelTypeMatch = el.level === level && el.type === type;
|
|
110
110
|
let filterMatch = true;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.promptForPublisherTOS = exports.displayApis = exports.displayRoles = exports.retrieveRoleInfo = exports.formatDescription = void 0;
|
|
4
|
-
const _ = require("lodash");
|
|
5
4
|
const clc = require("cli-color");
|
|
6
5
|
const { marked } = require("marked");
|
|
7
6
|
const TerminalRenderer = require("marked-terminal");
|
|
@@ -19,7 +18,7 @@ async function formatDescription(extensionName, projectId, roles) {
|
|
|
19
18
|
return retrieveRoleInfo(role);
|
|
20
19
|
}));
|
|
21
20
|
results.unshift(question);
|
|
22
|
-
return
|
|
21
|
+
return results.join("\n");
|
|
23
22
|
}
|
|
24
23
|
exports.formatDescription = formatDescription;
|
|
25
24
|
async function retrieveRoleInfo(role) {
|
|
@@ -4,7 +4,7 @@ exports.getInquirerDefault = exports.promptCreateSecret = exports.askForParam =
|
|
|
4
4
|
const _ = require("lodash");
|
|
5
5
|
const clc = require("cli-color");
|
|
6
6
|
const { marked } = require("marked");
|
|
7
|
-
const
|
|
7
|
+
const types_1 = require("./types");
|
|
8
8
|
const secretManagerApi = require("../gcp/secretManager");
|
|
9
9
|
const secretsUtils = require("./secretsUtils");
|
|
10
10
|
const extensionsHelper_1 = require("./extensionsHelper");
|
|
@@ -24,13 +24,14 @@ var SecretUpdateAction;
|
|
|
24
24
|
SecretUpdateAction[SecretUpdateAction["SET_NEW"] = 2] = "SET_NEW";
|
|
25
25
|
})(SecretUpdateAction || (SecretUpdateAction = {}));
|
|
26
26
|
function checkResponse(response, spec) {
|
|
27
|
+
var _a;
|
|
27
28
|
let valid = true;
|
|
28
29
|
let responses;
|
|
29
30
|
if (spec.required && (response === "" || response === undefined)) {
|
|
30
31
|
utils.logWarning(`Param ${spec.param} is required, but no value was provided.`);
|
|
31
32
|
return false;
|
|
32
33
|
}
|
|
33
|
-
if (spec.type ===
|
|
34
|
+
if (spec.type === types_1.ParamType.MULTISELECT) {
|
|
34
35
|
responses = response.split(",");
|
|
35
36
|
}
|
|
36
37
|
else {
|
|
@@ -38,25 +39,23 @@ function checkResponse(response, spec) {
|
|
|
38
39
|
}
|
|
39
40
|
if (spec.validationRegex && !!response) {
|
|
40
41
|
const re = new RegExp(spec.validationRegex);
|
|
41
|
-
|
|
42
|
+
for (const resp of responses) {
|
|
42
43
|
if ((spec.required || resp !== "") && !re.test(resp)) {
|
|
43
44
|
const genericWarn = `${resp} is not a valid value for ${spec.param} since it` +
|
|
44
45
|
` does not meet the requirements of the regex validation: "${spec.validationRegex}"`;
|
|
45
46
|
utils.logWarning(spec.validationErrorMessage || genericWarn);
|
|
46
47
|
valid = false;
|
|
47
48
|
}
|
|
48
|
-
}
|
|
49
|
+
}
|
|
49
50
|
}
|
|
50
|
-
if (spec.type && (spec.type ===
|
|
51
|
-
|
|
52
|
-
const validChoice =
|
|
53
|
-
|
|
54
|
-
});
|
|
55
|
-
if (!validChoice) {
|
|
51
|
+
if (spec.type && (spec.type === types_1.ParamType.MULTISELECT || spec.type === types_1.ParamType.SELECT)) {
|
|
52
|
+
for (const r of responses) {
|
|
53
|
+
const validChoice = (_a = spec.options) === null || _a === void 0 ? void 0 : _a.some((option) => r === option.value);
|
|
54
|
+
if (r && !validChoice) {
|
|
56
55
|
utils.logWarning(`${r} is not a valid option for ${spec.param}.`);
|
|
57
56
|
valid = false;
|
|
58
57
|
}
|
|
59
|
-
}
|
|
58
|
+
}
|
|
60
59
|
}
|
|
61
60
|
return valid;
|
|
62
61
|
}
|
|
@@ -69,7 +68,7 @@ async function ask(args) {
|
|
|
69
68
|
utils.logLabeledBullet(extensionsHelper_1.logPrefix, "answer the questions below to configure your extension:");
|
|
70
69
|
const substituted = (0, extensionsHelper_1.substituteParams)(args.paramSpecs, args.firebaseProjectParams);
|
|
71
70
|
const result = {};
|
|
72
|
-
const promises =
|
|
71
|
+
const promises = substituted.map((paramSpec) => {
|
|
73
72
|
return async () => {
|
|
74
73
|
result[paramSpec.param] = await askForParam({
|
|
75
74
|
projectId: args.projectId,
|
|
@@ -95,7 +94,7 @@ async function askForParam(args) {
|
|
|
95
94
|
logger_1.logger.info(`\n${clc.bold(label)}${clc.bold(paramSpec.required ? "" : " (Optional)")}: ${marked(description).trim()}`);
|
|
96
95
|
while (!valid) {
|
|
97
96
|
switch (paramSpec.type) {
|
|
98
|
-
case
|
|
97
|
+
case types_1.ParamType.SELECT:
|
|
99
98
|
response = await (0, prompt_1.promptOnce)({
|
|
100
99
|
name: "input",
|
|
101
100
|
type: "list",
|
|
@@ -111,7 +110,7 @@ async function askForParam(args) {
|
|
|
111
110
|
});
|
|
112
111
|
valid = checkResponse(response, paramSpec);
|
|
113
112
|
break;
|
|
114
|
-
case
|
|
113
|
+
case types_1.ParamType.MULTISELECT:
|
|
115
114
|
response = await (0, utils_1.onceWithJoin)({
|
|
116
115
|
name: "input",
|
|
117
116
|
type: "checkbox",
|
|
@@ -129,7 +128,7 @@ async function askForParam(args) {
|
|
|
129
128
|
});
|
|
130
129
|
valid = checkResponse(response, paramSpec);
|
|
131
130
|
break;
|
|
132
|
-
case
|
|
131
|
+
case types_1.ParamType.SECRET:
|
|
133
132
|
do {
|
|
134
133
|
secretLocations = await promptSecretLocations(paramSpec);
|
|
135
134
|
} while (!isValidSecretLocations(secretLocations, paramSpec));
|
|
@@ -302,9 +301,7 @@ async function addNewSecretVersion(projectId, instanceId, secret, paramSpec, sec
|
|
|
302
301
|
return `projects/${version.secret.projectId}/secrets/${version.secret.name}/versions/${version.versionId}`;
|
|
303
302
|
}
|
|
304
303
|
function getInquirerDefault(options, def) {
|
|
305
|
-
const defaultOption =
|
|
306
|
-
return option.value === def;
|
|
307
|
-
});
|
|
304
|
+
const defaultOption = options.find((o) => o.value === def);
|
|
308
305
|
return defaultOption ? defaultOption.label || defaultOption.value : "";
|
|
309
306
|
}
|
|
310
307
|
exports.getInquirerDefault = getInquirerDefault;
|
|
@@ -7,14 +7,14 @@ const paramHelper = require("../paramHelper");
|
|
|
7
7
|
const specHelper = require("./specHelper");
|
|
8
8
|
const localHelper = require("../localHelper");
|
|
9
9
|
const triggerHelper = require("./triggerHelper");
|
|
10
|
-
const
|
|
10
|
+
const types_1 = require("../types");
|
|
11
11
|
const extensionsHelper = require("../extensionsHelper");
|
|
12
12
|
const planner = require("../../deploy/extensions/planner");
|
|
13
13
|
const config_1 = require("../../config");
|
|
14
14
|
const error_1 = require("../../error");
|
|
15
15
|
const emulatorLogger_1 = require("../../emulator/emulatorLogger");
|
|
16
16
|
const projectUtils_1 = require("../../projectUtils");
|
|
17
|
-
const
|
|
17
|
+
const types_2 = require("../../emulator/types");
|
|
18
18
|
async function buildOptions(options) {
|
|
19
19
|
const extDevDir = localHelper.findExtensionYaml(process.cwd());
|
|
20
20
|
options.extDevDir = extDevDir;
|
|
@@ -56,7 +56,7 @@ async function getExtensionFunctionInfo(instance, paramValues) {
|
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
58
|
exports.getExtensionFunctionInfo = getExtensionFunctionInfo;
|
|
59
|
-
const isSecretParam = (p) => p.type === extensionsHelper.SpecParamType.SECRET || p.type ===
|
|
59
|
+
const isSecretParam = (p) => p.type === extensionsHelper.SpecParamType.SECRET || p.type === types_1.ParamType.SECRET;
|
|
60
60
|
function getNonSecretEnv(params, paramValues) {
|
|
61
61
|
const getNonSecretEnv = Object.assign({}, paramValues);
|
|
62
62
|
const secretParams = params.filter(isSecretParam);
|
|
@@ -99,7 +99,7 @@ function getParams(options, extensionSpec) {
|
|
|
99
99
|
}
|
|
100
100
|
exports.getParams = getParams;
|
|
101
101
|
function checkTestConfig(testConfig, functionResources) {
|
|
102
|
-
const logger = emulatorLogger_1.EmulatorLogger.forEmulator(
|
|
102
|
+
const logger = emulatorLogger_1.EmulatorLogger.forEmulator(types_2.Emulators.FUNCTIONS);
|
|
103
103
|
if (!testConfig.functions && functionResources.length) {
|
|
104
104
|
logger.log("WARN", "This extension uses functions," +
|
|
105
105
|
"but 'firebase.json' provided by --test-config is missing a top-level 'functions' object." +
|