firebase-tools 10.2.1 → 10.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/appdistribution/options-parser-util.js +1 -1
- package/lib/auth.js +3 -3
- 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/database-rules-list.js +2 -2
- package/lib/commands/emulators-start.js +1 -1
- package/lib/commands/ext-configure.js +67 -7
- package/lib/commands/ext-dev-init.js +49 -49
- package/lib/commands/ext-export.js +7 -2
- package/lib/commands/ext-install.js +173 -109
- package/lib/commands/ext-uninstall.js +17 -8
- package/lib/commands/ext-update.js +67 -12
- package/lib/commands/functions-config-export.js +1 -1
- package/lib/commands/hosting-clone.js +3 -3
- package/lib/commands/remoteconfig-get.js +1 -1
- package/lib/config.js +6 -3
- package/lib/deploy/extensions/deploymentSummary.js +3 -3
- package/lib/deploy/extensions/planner.js +7 -6
- package/lib/deploy/extensions/tasks.js +1 -1
- package/lib/deploy/functions/backend.js +21 -5
- package/lib/deploy/functions/checkIam.js +5 -5
- package/lib/deploy/functions/containerCleaner.js +3 -3
- package/lib/deploy/functions/ensure.js +3 -3
- package/lib/deploy/functions/functionsDeployHelper.js +2 -2
- package/lib/deploy/functions/prepare.js +5 -3
- package/lib/deploy/functions/pricing.js +1 -1
- package/lib/deploy/functions/prompts.js +2 -2
- package/lib/deploy/functions/release/fabricator.js +7 -7
- package/lib/deploy/functions/release/index.js +1 -1
- package/lib/deploy/functions/release/planner.js +43 -26
- 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 +22 -12
- package/lib/deploy/functions/runtimes/golang/index.js +2 -2
- package/lib/deploy/functions/runtimes/node/index.js +53 -0
- package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +2 -2
- package/lib/deploy/functions/runtimes/node/parseTriggers.js +64 -20
- package/lib/deploy/functions/runtimes/node/versioning.js +2 -2
- package/lib/deploy/functions/services/firebaseAlerts.js +30 -0
- package/lib/deploy/functions/services/index.js +9 -1
- package/lib/deploy/functions/services/storage.js +10 -4
- package/lib/deploy/functions/triggerRegionHelper.js +1 -1
- package/lib/deploy/functions/validate.js +3 -3
- package/lib/deploy/hosting/deploy.js +2 -2
- package/lib/deploy/hosting/hashcache.js +21 -19
- 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/constants.js +4 -0
- package/lib/emulator/controller.js +54 -24
- package/lib/emulator/download.js +18 -1
- package/lib/emulator/downloadableEmulators.js +1 -1
- package/lib/emulator/emulatorLogger.js +12 -1
- package/lib/emulator/extensions/validation.js +70 -0
- package/lib/emulator/extensionsEmulator.js +175 -0
- package/lib/emulator/functionsEmulator.js +95 -43
- package/lib/emulator/functionsEmulatorRuntime.js +44 -36
- package/lib/emulator/functionsEmulatorShared.js +30 -11
- package/lib/emulator/functionsEmulatorShell.js +1 -1
- package/lib/emulator/functionsEmulatorUtils.js +4 -4
- package/lib/emulator/functionsRuntimeWorker.js +2 -2
- 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 +314 -332
- package/lib/emulator/storage/apis/gcloud.js +241 -121
- package/lib/emulator/storage/crc.js +5 -1
- package/lib/emulator/storage/errors.js +9 -0
- package/lib/emulator/storage/files.js +159 -300
- package/lib/emulator/storage/index.js +27 -73
- package/lib/emulator/storage/metadata.js +65 -51
- package/lib/emulator/storage/multipart.js +62 -0
- package/lib/emulator/storage/persistence.js +78 -0
- package/lib/emulator/storage/rules/config.js +33 -0
- package/lib/emulator/storage/rules/manager.js +81 -0
- package/lib/emulator/storage/rules/runtime.js +8 -7
- package/lib/emulator/storage/rules/utils.js +48 -0
- package/lib/emulator/storage/server.js +2 -2
- package/lib/emulator/storage/upload.js +106 -0
- package/lib/emulator/types.js +3 -0
- package/lib/ensureApiEnabled.js +5 -1
- package/lib/error.js +1 -1
- package/lib/extensions/askUserForParam.js +31 -25
- package/lib/extensions/changelog.js +3 -1
- package/lib/extensions/checkProjectBilling.js +1 -1
- package/lib/extensions/displayExtensionInfo.js +1 -1
- package/lib/extensions/emulator/optionsHelper.js +56 -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 +32 -19
- package/lib/extensions/manifest.js +144 -0
- package/lib/extensions/metricsUtils.js +4 -4
- package/lib/extensions/paramHelper.js +34 -12
- package/lib/extensions/refs.js +1 -1
- package/lib/extensions/secretsUtils.js +3 -3
- package/lib/functional.js +1 -1
- package/lib/functions/env.js +6 -7
- package/lib/functions/events/v2.js +11 -0
- package/lib/gcp/cloudfunctions.js +43 -11
- package/lib/gcp/cloudfunctionsv2.js +48 -17
- package/lib/gcp/cloudtasks.js +1 -1
- package/lib/gcp/docker.js +2 -2
- package/lib/gcp/resourceManager.js +4 -4
- package/lib/gcp/run.js +2 -2
- package/lib/hosting/api.js +1 -1
- 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/serve/functions.js +2 -1
- package/lib/utils.js +15 -2
- package/npm-shrinkwrap.json +786 -393
- package/package.json +1 -1
- package/schema/firebase-config.json +5 -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
- package/lib/deploy/extensions/params.js +0 -39
- package/lib/deploy/functions/eventTypes.js +0 -10
|
@@ -14,6 +14,7 @@ const api_1 = require("../api");
|
|
|
14
14
|
const archiveDirectory_1 = require("../archiveDirectory");
|
|
15
15
|
const utils_1 = require("./utils");
|
|
16
16
|
const functionsConfig_1 = require("../functionsConfig");
|
|
17
|
+
const adminSdkConfig_1 = require("../emulator/adminSdkConfig");
|
|
17
18
|
const resolveSource_1 = require("./resolveSource");
|
|
18
19
|
const error_1 = require("../error");
|
|
19
20
|
const diagnose_1 = require("./diagnose");
|
|
@@ -29,6 +30,7 @@ const logger_1 = require("../logger");
|
|
|
29
30
|
const utils_2 = require("../utils");
|
|
30
31
|
const changelog_1 = require("./changelog");
|
|
31
32
|
const getProjectNumber_1 = require("../getProjectNumber");
|
|
33
|
+
const constants_1 = require("../emulator/constants");
|
|
32
34
|
var SpecParamType;
|
|
33
35
|
(function (SpecParamType) {
|
|
34
36
|
SpecParamType["SELECT"] = "select";
|
|
@@ -76,21 +78,28 @@ function getDBInstanceFromURL(databaseUrl = "") {
|
|
|
76
78
|
return "";
|
|
77
79
|
}
|
|
78
80
|
exports.getDBInstanceFromURL = getDBInstanceFromURL;
|
|
79
|
-
async function getFirebaseProjectParams(projectId) {
|
|
80
|
-
|
|
81
|
-
const
|
|
81
|
+
async function getFirebaseProjectParams(projectId, emulatorMode = false) {
|
|
82
|
+
var _a, _b;
|
|
83
|
+
const body = emulatorMode
|
|
84
|
+
? await (0, adminSdkConfig_1.getProjectAdminSdkConfigOrCached)(projectId)
|
|
85
|
+
: await (0, functionsConfig_1.getFirebaseConfig)({ project: projectId });
|
|
86
|
+
const projectNumber = emulatorMode && constants_1.Constants.isDemoProject(projectId)
|
|
87
|
+
? constants_1.Constants.FAKE_PROJECT_NUMBER
|
|
88
|
+
: await (0, getProjectNumber_1.getProjectNumber)({ projectId });
|
|
89
|
+
const databaseURL = (_a = body === null || body === void 0 ? void 0 : body.databaseURL) !== null && _a !== void 0 ? _a : `https://${projectId}.firebaseio.com`;
|
|
90
|
+
const storageBucket = (_b = body === null || body === void 0 ? void 0 : body.storageBucket) !== null && _b !== void 0 ? _b : `${projectId}.appspot.com`;
|
|
82
91
|
const FIREBASE_CONFIG = JSON.stringify({
|
|
83
|
-
projectId
|
|
84
|
-
databaseURL
|
|
85
|
-
storageBucket
|
|
92
|
+
projectId,
|
|
93
|
+
databaseURL,
|
|
94
|
+
storageBucket,
|
|
86
95
|
});
|
|
87
96
|
return {
|
|
88
|
-
PROJECT_ID:
|
|
97
|
+
PROJECT_ID: projectId,
|
|
89
98
|
PROJECT_NUMBER: projectNumber,
|
|
90
|
-
DATABASE_URL:
|
|
91
|
-
STORAGE_BUCKET:
|
|
99
|
+
DATABASE_URL: databaseURL,
|
|
100
|
+
STORAGE_BUCKET: storageBucket,
|
|
92
101
|
FIREBASE_CONFIG,
|
|
93
|
-
DATABASE_INSTANCE: getDBInstanceFromURL(
|
|
102
|
+
DATABASE_INSTANCE: getDBInstanceFromURL(databaseURL),
|
|
94
103
|
};
|
|
95
104
|
}
|
|
96
105
|
exports.getFirebaseProjectParams = getFirebaseProjectParams;
|
|
@@ -112,7 +121,7 @@ function populateDefaultParams(paramVars, paramSpecs) {
|
|
|
112
121
|
const newParams = paramVars;
|
|
113
122
|
for (const param of paramSpecs) {
|
|
114
123
|
if (!paramVars[param.param]) {
|
|
115
|
-
if (param.default
|
|
124
|
+
if (param.default !== undefined && param.required) {
|
|
116
125
|
newParams[param.param] = param.default;
|
|
117
126
|
}
|
|
118
127
|
else if (param.required) {
|
|
@@ -197,13 +206,13 @@ function validateSpec(spec) {
|
|
|
197
206
|
if (param.type && !_.includes(SpecParamType, param.type)) {
|
|
198
207
|
errors.push(`Invalid type ${param.type} for param${param.param ? ` ${param.param}` : ""}. Valid types are ${_.values(SpecParamType).join(", ")}`);
|
|
199
208
|
}
|
|
200
|
-
if (!param.type || param.type
|
|
209
|
+
if (!param.type || param.type === SpecParamType.STRING) {
|
|
201
210
|
if (param.options) {
|
|
202
211
|
errors.push(`Param${param.param ? ` ${param.param}` : ""} cannot have options because it is type STRING`);
|
|
203
212
|
}
|
|
204
213
|
}
|
|
205
214
|
if (param.type &&
|
|
206
|
-
(param.type
|
|
215
|
+
(param.type === SpecParamType.SELECT || param.type === SpecParamType.MULTISELECT)) {
|
|
207
216
|
if (param.validationRegex) {
|
|
208
217
|
errors.push(`Param${param.param ? ` ${param.param}` : ""} cannot have validationRegex because it is type ${param.type}`);
|
|
209
218
|
}
|
|
@@ -211,12 +220,12 @@ function validateSpec(spec) {
|
|
|
211
220
|
errors.push(`Param${param.param ? ` ${param.param}` : ""} requires options because it is type ${param.type}`);
|
|
212
221
|
}
|
|
213
222
|
for (const opt of param.options || []) {
|
|
214
|
-
if (opt.value
|
|
223
|
+
if (opt.value === undefined) {
|
|
215
224
|
errors.push(`Option for param${param.param ? ` ${param.param}` : ""} is missing required field: value`);
|
|
216
225
|
}
|
|
217
226
|
}
|
|
218
227
|
}
|
|
219
|
-
if (param.type && param.type
|
|
228
|
+
if (param.type && param.type === SpecParamType.SELECTRESOURCE) {
|
|
220
229
|
if (!param.resourceType) {
|
|
221
230
|
errors.push(`Param${param.param ? ` ${param.param}` : ""} must have resourceType because it is type ${param.type}`);
|
|
222
231
|
}
|
|
@@ -268,7 +277,7 @@ async function archiveAndUploadSource(extPath, bucketName) {
|
|
|
268
277
|
}
|
|
269
278
|
async function publishExtensionVersionFromLocalSource(args) {
|
|
270
279
|
const extensionSpec = await (0, localHelper_1.getLocalExtensionSpec)(args.rootDirectory);
|
|
271
|
-
if (extensionSpec.name
|
|
280
|
+
if (extensionSpec.name !== args.extensionId) {
|
|
272
281
|
throw new error_1.FirebaseError(`Extension ID '${clc.bold(args.extensionId)}' does not match the name in extension.yaml '${clc.bold(extensionSpec.name)}'.`);
|
|
273
282
|
}
|
|
274
283
|
const subbedSpec = JSON.parse(JSON.stringify(extensionSpec));
|
|
@@ -325,7 +334,9 @@ async function publishExtensionVersionFromLocalSource(args) {
|
|
|
325
334
|
}
|
|
326
335
|
catch (err) {
|
|
327
336
|
uploadSpinner.fail();
|
|
328
|
-
throw err
|
|
337
|
+
throw new error_1.FirebaseError(`Failed to archive and upload extension source, ${err}`, {
|
|
338
|
+
original: err,
|
|
339
|
+
});
|
|
329
340
|
}
|
|
330
341
|
const publishSpinner = ora(`Publishing ${clc.bold(ref)}`);
|
|
331
342
|
let res;
|
|
@@ -336,7 +347,7 @@ async function publishExtensionVersionFromLocalSource(args) {
|
|
|
336
347
|
}
|
|
337
348
|
catch (err) {
|
|
338
349
|
publishSpinner.fail();
|
|
339
|
-
if (err.status
|
|
350
|
+
if (err.status === 404) {
|
|
340
351
|
throw new error_1.FirebaseError(marked(`Couldn't find publisher ID '${clc.bold(args.publisherId)}'. Please ensure that you have registered this ID. To register as a publisher, you can check out the [Firebase documentation](https://firebase.google.com/docs/extensions/alpha/share#register_as_an_extensions_publisher) for step-by-step instructions.`));
|
|
341
352
|
}
|
|
342
353
|
throw err;
|
|
@@ -360,7 +371,9 @@ async function createSourceFromLocation(projectId, sourceUri) {
|
|
|
360
371
|
}
|
|
361
372
|
catch (err) {
|
|
362
373
|
uploadSpinner.fail();
|
|
363
|
-
throw err
|
|
374
|
+
throw new error_1.FirebaseError(`Failed to archive and upload extension source, ${err}`, {
|
|
375
|
+
original: err,
|
|
376
|
+
});
|
|
364
377
|
}
|
|
365
378
|
}
|
|
366
379
|
else {
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.showPreviewWarning = exports.showDeprecationWarning = exports.readInstanceParam = exports.getInstanceRef = exports.instanceExists = exports.loadConfig = exports.removeFromManifest = exports.writeToManifest = exports.ENV_DIRECTORY = void 0;
|
|
4
|
+
const clc = require("cli-color");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const refs = require("./refs");
|
|
7
|
+
const config_1 = require("../config");
|
|
8
|
+
const logger_1 = require("../logger");
|
|
9
|
+
const prompt_1 = require("../prompt");
|
|
10
|
+
const paramHelper_1 = require("./paramHelper");
|
|
11
|
+
const error_1 = require("../error");
|
|
12
|
+
const utils = require("../utils");
|
|
13
|
+
const extensionsHelper_1 = require("./extensionsHelper");
|
|
14
|
+
exports.ENV_DIRECTORY = "extensions";
|
|
15
|
+
async function writeToManifest(specs, config, options, allowOverwrite = false) {
|
|
16
|
+
if (config.has("extensions") &&
|
|
17
|
+
Object.keys(config.get("extensions")).length &&
|
|
18
|
+
!options.nonInteractive &&
|
|
19
|
+
!options.force) {
|
|
20
|
+
const currentExtensions = Object.entries(config.get("extensions"))
|
|
21
|
+
.map((i) => `${i[0]}: ${i[1]}`)
|
|
22
|
+
.join("\n\t");
|
|
23
|
+
if (allowOverwrite) {
|
|
24
|
+
const overwrite = await (0, prompt_1.promptOnce)({
|
|
25
|
+
type: "list",
|
|
26
|
+
message: `firebase.json already contains extensions:\n${currentExtensions}\nWould you like to overwrite or merge?`,
|
|
27
|
+
choices: [
|
|
28
|
+
{ name: "Overwrite", value: true },
|
|
29
|
+
{ name: "Merge", value: false },
|
|
30
|
+
],
|
|
31
|
+
});
|
|
32
|
+
if (overwrite) {
|
|
33
|
+
config.set("extensions", {});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
writeExtensionsToFirebaseJson(specs, config);
|
|
38
|
+
await writeEnvFiles(specs, config, options.force);
|
|
39
|
+
}
|
|
40
|
+
exports.writeToManifest = writeToManifest;
|
|
41
|
+
function removeFromManifest(instanceId, config) {
|
|
42
|
+
if (!instanceExists(instanceId, config)) {
|
|
43
|
+
throw new error_1.FirebaseError(`Extension instance ${instanceId} not found in firebase.json.`);
|
|
44
|
+
}
|
|
45
|
+
const extensions = config.get("extensions", {});
|
|
46
|
+
extensions[instanceId] = undefined;
|
|
47
|
+
config.set("extensions", extensions);
|
|
48
|
+
config.writeProjectFile("firebase.json", config.src);
|
|
49
|
+
logger_1.logger.info(`Removed extension instance ${instanceId} from firebase.json`);
|
|
50
|
+
config.deleteProjectFile(`extensions/${instanceId}.env`);
|
|
51
|
+
logger_1.logger.info(`Removed extension instance environment config extensions/${instanceId}.env`);
|
|
52
|
+
config.deleteProjectFile(`extensions/${instanceId}.env.local`);
|
|
53
|
+
logger_1.logger.info(`Removed extension instance environment config extensions/${instanceId}.env.local`);
|
|
54
|
+
}
|
|
55
|
+
exports.removeFromManifest = removeFromManifest;
|
|
56
|
+
function loadConfig(options) {
|
|
57
|
+
const existingConfig = config_1.Config.load(options, true);
|
|
58
|
+
if (!existingConfig) {
|
|
59
|
+
throw new error_1.FirebaseError("Not currently in a Firebase directory. Run `firebase init` to create a Firebase directory.");
|
|
60
|
+
}
|
|
61
|
+
return existingConfig;
|
|
62
|
+
}
|
|
63
|
+
exports.loadConfig = loadConfig;
|
|
64
|
+
function instanceExists(instanceId, config) {
|
|
65
|
+
return !!config.get("extensions", {})[instanceId];
|
|
66
|
+
}
|
|
67
|
+
exports.instanceExists = instanceExists;
|
|
68
|
+
function getInstanceRef(instanceId, config) {
|
|
69
|
+
if (!instanceExists(instanceId, config)) {
|
|
70
|
+
throw new error_1.FirebaseError(`Could not find extension instance ${instanceId} in firebase.json`);
|
|
71
|
+
}
|
|
72
|
+
const ref = config.get("extensions", {})[instanceId];
|
|
73
|
+
return refs.parse(ref);
|
|
74
|
+
}
|
|
75
|
+
exports.getInstanceRef = getInstanceRef;
|
|
76
|
+
function writeExtensionsToFirebaseJson(specs, config) {
|
|
77
|
+
const extensions = config.get("extensions", {});
|
|
78
|
+
for (const s of specs) {
|
|
79
|
+
extensions[s.instanceId] = refs.toExtensionVersionRef(s.ref);
|
|
80
|
+
}
|
|
81
|
+
config.set("extensions", extensions);
|
|
82
|
+
config.writeProjectFile("firebase.json", config.src);
|
|
83
|
+
utils.logSuccess("Wrote extensions to " + clc.bold("firebase.json") + "...");
|
|
84
|
+
}
|
|
85
|
+
async function writeEnvFiles(specs, config, force) {
|
|
86
|
+
for (const spec of specs) {
|
|
87
|
+
const content = Object.entries(spec.params)
|
|
88
|
+
.sort((a, b) => {
|
|
89
|
+
return a[0].localeCompare(b[0]);
|
|
90
|
+
})
|
|
91
|
+
.map((r) => `${r[0]}=${r[1]}`)
|
|
92
|
+
.join("\n");
|
|
93
|
+
await config.askWriteProjectFile(`extensions/${spec.instanceId}.env`, content, force);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function readInstanceParam(args) {
|
|
97
|
+
var _a;
|
|
98
|
+
const aliases = (_a = args.aliases) !== null && _a !== void 0 ? _a : [];
|
|
99
|
+
const filesToCheck = [
|
|
100
|
+
`${args.instanceId}.env`,
|
|
101
|
+
...aliases.map((alias) => `${args.instanceId}.env.${alias}`),
|
|
102
|
+
...(args.projectNumber ? [`${args.instanceId}.env.${args.projectNumber}`] : []),
|
|
103
|
+
...(args.projectId ? [`${args.instanceId}.env.${args.projectId}`] : []),
|
|
104
|
+
];
|
|
105
|
+
if (args.checkLocal) {
|
|
106
|
+
filesToCheck.push(`${args.instanceId}.env.local`);
|
|
107
|
+
}
|
|
108
|
+
let noFilesFound = true;
|
|
109
|
+
const combinedParams = {};
|
|
110
|
+
for (const fileToCheck of filesToCheck) {
|
|
111
|
+
try {
|
|
112
|
+
const params = readParamsFile(args.projectDir, fileToCheck);
|
|
113
|
+
logger_1.logger.debug(`Successfully read params from ${fileToCheck}`);
|
|
114
|
+
noFilesFound = false;
|
|
115
|
+
Object.assign(combinedParams, params);
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
logger_1.logger.debug(`${err}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (noFilesFound) {
|
|
122
|
+
throw new error_1.FirebaseError(`No params file found for ${args.instanceId}`);
|
|
123
|
+
}
|
|
124
|
+
return combinedParams;
|
|
125
|
+
}
|
|
126
|
+
exports.readInstanceParam = readInstanceParam;
|
|
127
|
+
function readParamsFile(projectDir, fileName) {
|
|
128
|
+
const paramPath = path.join(projectDir, exports.ENV_DIRECTORY, fileName);
|
|
129
|
+
const params = (0, paramHelper_1.readEnvFile)(paramPath);
|
|
130
|
+
return params;
|
|
131
|
+
}
|
|
132
|
+
function showDeprecationWarning() {
|
|
133
|
+
utils.logLabeledWarning(extensionsHelper_1.logPrefix, "The behavior of ext:install, ext:update, ext:configure, and ext:uninstall will change in firebase-tools@11.0.0. " +
|
|
134
|
+
"Instead of deploying extensions directly, " +
|
|
135
|
+
"changes to extension instances will be written to firebase.json and ./extensions/*.env. " +
|
|
136
|
+
`Then ${clc.bold("firebase deploy (--only extensions)")} will deploy the changes to your Firebase project. ` +
|
|
137
|
+
`To access this behavior now, pass the ${clc.bold("--local")} flag.`);
|
|
138
|
+
}
|
|
139
|
+
exports.showDeprecationWarning = showDeprecationWarning;
|
|
140
|
+
function showPreviewWarning() {
|
|
141
|
+
utils.logLabeledWarning(extensionsHelper_1.logPrefix, "These changes will be reflected in your Firebase Emulator after restart. " +
|
|
142
|
+
`Run ${clc.bold("firebase deploy (--only extensions)")} to deploy the changes to your Firebase project. `);
|
|
143
|
+
}
|
|
144
|
+
exports.showPreviewWarning = showPreviewWarning;
|
|
@@ -7,19 +7,19 @@ function parseTimeseriesResponse(series) {
|
|
|
7
7
|
const ret = [];
|
|
8
8
|
for (const s of series) {
|
|
9
9
|
const ref = buildRef(s);
|
|
10
|
-
if (ref
|
|
10
|
+
if (ref === undefined) {
|
|
11
11
|
continue;
|
|
12
12
|
}
|
|
13
13
|
let valueToday;
|
|
14
14
|
let value7dAgo;
|
|
15
15
|
let value28dAgo;
|
|
16
|
-
if (s.points.length >= 28 && s.points[27].value.int64Value
|
|
16
|
+
if (s.points.length >= 28 && s.points[27].value.int64Value !== undefined) {
|
|
17
17
|
value28dAgo = parseBucket(s.points[27].value.int64Value);
|
|
18
18
|
}
|
|
19
|
-
if (s.points.length >= 7 && s.points[6].value.int64Value
|
|
19
|
+
if (s.points.length >= 7 && s.points[6].value.int64Value !== undefined) {
|
|
20
20
|
value7dAgo = parseBucket(s.points[6].value.int64Value);
|
|
21
21
|
}
|
|
22
|
-
if (s.points.length >= 1 && s.points[0].value.int64Value
|
|
22
|
+
if (s.points.length >= 1 && s.points[0].value.int64Value !== undefined) {
|
|
23
23
|
valueToday = parseBucket(s.points[0].value.int64Value);
|
|
24
24
|
}
|
|
25
25
|
ret.push({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.readEnvFile = exports.
|
|
3
|
+
exports.readEnvFile = exports.promptForNewParams = exports.getParamsForUpdate = exports.getParams = exports.getParamsWithCurrentValuesAsDefaults = exports.setNewDefaults = exports.buildBindingOptionsWithBaseValue = exports.getBaseParamBindings = void 0;
|
|
4
4
|
const _ = require("lodash");
|
|
5
5
|
const path = require("path");
|
|
6
6
|
const clc = require("cli-color");
|
|
@@ -11,6 +11,22 @@ const extensionsHelper_1 = require("./extensionsHelper");
|
|
|
11
11
|
const askUserForParam = require("./askUserForParam");
|
|
12
12
|
const track = require("../track");
|
|
13
13
|
const env = require("../functions/env");
|
|
14
|
+
function getBaseParamBindings(params) {
|
|
15
|
+
let ret = {};
|
|
16
|
+
for (const [k, v] of Object.entries(params)) {
|
|
17
|
+
ret = Object.assign(Object.assign({}, ret), { [k]: v.baseValue });
|
|
18
|
+
}
|
|
19
|
+
return ret;
|
|
20
|
+
}
|
|
21
|
+
exports.getBaseParamBindings = getBaseParamBindings;
|
|
22
|
+
function buildBindingOptionsWithBaseValue(baseParams) {
|
|
23
|
+
let paramOptions = {};
|
|
24
|
+
for (const [k, v] of Object.entries(baseParams)) {
|
|
25
|
+
paramOptions = Object.assign(Object.assign({}, paramOptions), { [k]: { baseValue: v } });
|
|
26
|
+
}
|
|
27
|
+
return paramOptions;
|
|
28
|
+
}
|
|
29
|
+
exports.buildBindingOptionsWithBaseValue = buildBindingOptionsWithBaseValue;
|
|
14
30
|
function setNewDefaults(params, newDefaults) {
|
|
15
31
|
params.forEach((param) => {
|
|
16
32
|
if (newDefaults[param.param.toUpperCase()]) {
|
|
@@ -19,6 +35,7 @@ function setNewDefaults(params, newDefaults) {
|
|
|
19
35
|
});
|
|
20
36
|
return params;
|
|
21
37
|
}
|
|
38
|
+
exports.setNewDefaults = setNewDefaults;
|
|
22
39
|
function getParamsWithCurrentValuesAsDefaults(extensionInstance) {
|
|
23
40
|
const specParams = _.cloneDeep(_.get(extensionInstance, "config.source.spec.params", []));
|
|
24
41
|
const currentParams = _.cloneDeep(_.get(extensionInstance, "config.params", {}));
|
|
@@ -49,7 +66,7 @@ async function getParams(args) {
|
|
|
49
66
|
const firebaseProjectParams = await (0, extensionsHelper_1.getFirebaseProjectParams)(args.projectId);
|
|
50
67
|
params = await askUserForParam.ask(args.projectId, args.instanceId, args.paramSpecs, firebaseProjectParams, !!args.reconfiguring);
|
|
51
68
|
}
|
|
52
|
-
track("Extension Params", _.isEmpty(params) ? "Not Present" : "Present", _.size(params));
|
|
69
|
+
void track("Extension Params", _.isEmpty(params) ? "Not Present" : "Present", _.size(params));
|
|
53
70
|
return params;
|
|
54
71
|
}
|
|
55
72
|
exports.getParams = getParams;
|
|
@@ -82,7 +99,7 @@ async function getParamsForUpdate(args) {
|
|
|
82
99
|
instanceId: args.instanceId,
|
|
83
100
|
});
|
|
84
101
|
}
|
|
85
|
-
track("Extension Params", _.isEmpty(params) ? "Not Present" : "Present", _.size(params));
|
|
102
|
+
void track("Extension Params", _.isEmpty(params) ? "Not Present" : "Present", _.size(params));
|
|
86
103
|
return params;
|
|
87
104
|
}
|
|
88
105
|
exports.getParamsForUpdate = getParamsForUpdate;
|
|
@@ -91,9 +108,10 @@ async function promptForNewParams(args) {
|
|
|
91
108
|
const comparer = (param1, param2) => {
|
|
92
109
|
return param1.type === param2.type && param1.param === param2.param;
|
|
93
110
|
};
|
|
94
|
-
|
|
111
|
+
const oldParams = args.spec.params.filter((p) => Object.keys(args.currentParams).includes(p.param));
|
|
112
|
+
let paramsDiffDeletions = _.differenceWith(oldParams, args.newSpec.params, comparer);
|
|
95
113
|
paramsDiffDeletions = (0, extensionsHelper_1.substituteParams)(paramsDiffDeletions, firebaseProjectParams);
|
|
96
|
-
let paramsDiffAdditions = _.differenceWith(args.newSpec.params,
|
|
114
|
+
let paramsDiffAdditions = _.differenceWith(args.newSpec.params, oldParams, comparer);
|
|
97
115
|
paramsDiffAdditions = (0, extensionsHelper_1.substituteParams)(paramsDiffAdditions, firebaseProjectParams);
|
|
98
116
|
if (paramsDiffDeletions.length) {
|
|
99
117
|
logger_1.logger.info("The following params will no longer be used:");
|
|
@@ -105,29 +123,33 @@ async function promptForNewParams(args) {
|
|
|
105
123
|
if (paramsDiffAdditions.length) {
|
|
106
124
|
logger_1.logger.info("To update this instance, configure the following new parameters:");
|
|
107
125
|
for (const param of paramsDiffAdditions) {
|
|
108
|
-
const chosenValue = await askUserForParam.askForParam(
|
|
109
|
-
|
|
126
|
+
const chosenValue = await askUserForParam.askForParam({
|
|
127
|
+
projectId: args.projectId,
|
|
128
|
+
instanceId: args.instanceId,
|
|
129
|
+
paramSpec: param,
|
|
130
|
+
reconfiguring: false,
|
|
131
|
+
});
|
|
132
|
+
args.currentParams[param.param] = chosenValue.baseValue;
|
|
110
133
|
}
|
|
111
134
|
}
|
|
112
|
-
return args.currentParams;
|
|
135
|
+
return buildBindingOptionsWithBaseValue(args.currentParams);
|
|
113
136
|
}
|
|
114
137
|
exports.promptForNewParams = promptForNewParams;
|
|
115
138
|
function getParamsFromFile(args) {
|
|
116
139
|
let envParams;
|
|
117
140
|
try {
|
|
118
141
|
envParams = readEnvFile(args.paramsEnvPath);
|
|
119
|
-
track("Extension Env File", "Present");
|
|
142
|
+
void track("Extension Env File", "Present");
|
|
120
143
|
}
|
|
121
144
|
catch (err) {
|
|
122
|
-
track("Extension Env File", "Invalid");
|
|
145
|
+
void track("Extension Env File", "Invalid");
|
|
123
146
|
throw new error_1.FirebaseError(`Error reading env file: ${err.message}\n`, { original: err });
|
|
124
147
|
}
|
|
125
148
|
const params = (0, extensionsHelper_1.populateDefaultParams)(envParams, args.paramSpecs);
|
|
126
149
|
(0, extensionsHelper_1.validateCommandLineParams)(params, args.paramSpecs);
|
|
127
150
|
logger_1.logger.info(`Using param values from ${args.paramsEnvPath}`);
|
|
128
|
-
return params;
|
|
151
|
+
return buildBindingOptionsWithBaseValue(params);
|
|
129
152
|
}
|
|
130
|
-
exports.getParamsFromFile = getParamsFromFile;
|
|
131
153
|
function readEnvFile(envPath) {
|
|
132
154
|
const buf = fs.readFileSync(path.resolve(envPath), "utf8");
|
|
133
155
|
const result = env.parse(buf.toString().trim());
|
package/lib/extensions/refs.js
CHANGED
|
@@ -20,7 +20,7 @@ function parse(refOrName) {
|
|
|
20
20
|
exports.parse = parse;
|
|
21
21
|
function parseRef(ref) {
|
|
22
22
|
const parts = refRegex.exec(ref);
|
|
23
|
-
if (parts && (parts.length
|
|
23
|
+
if (parts && (parts.length === 5 || parts.length === 7)) {
|
|
24
24
|
const publisherId = parts[1];
|
|
25
25
|
const extensionId = parts[2];
|
|
26
26
|
const version = parts[4];
|
|
@@ -15,7 +15,7 @@ async function ensureSecretManagerApiEnabled(options) {
|
|
|
15
15
|
}
|
|
16
16
|
exports.ensureSecretManagerApiEnabled = ensureSecretManagerApiEnabled;
|
|
17
17
|
function usesSecrets(spec) {
|
|
18
|
-
return spec.params && !!spec.params.find((p) => p.type
|
|
18
|
+
return spec.params && !!spec.params.find((p) => p.type === extensionsApi.ParamType.SECRET);
|
|
19
19
|
}
|
|
20
20
|
exports.usesSecrets = usesSecrets;
|
|
21
21
|
async function grantFirexServiceAgentSecretAdminRole(secret) {
|
|
@@ -38,7 +38,7 @@ async function getManagedSecrets(instance) {
|
|
|
38
38
|
exports.getManagedSecrets = getManagedSecrets;
|
|
39
39
|
function getActiveSecrets(spec, params) {
|
|
40
40
|
return spec.params
|
|
41
|
-
.map((p) => (p.type
|
|
41
|
+
.map((p) => (p.type === extensionsApi.ParamType.SECRET ? params[p.param] : ""))
|
|
42
42
|
.filter((pv) => !!pv);
|
|
43
43
|
}
|
|
44
44
|
exports.getActiveSecrets = getActiveSecrets;
|
|
@@ -50,7 +50,7 @@ function getSecretLabels(instanceId) {
|
|
|
50
50
|
exports.getSecretLabels = getSecretLabels;
|
|
51
51
|
function prettySecretName(secretResourceName) {
|
|
52
52
|
const nameTokens = secretResourceName.split("/");
|
|
53
|
-
if (nameTokens.length
|
|
53
|
+
if (nameTokens.length !== 4 && nameTokens.length !== 6) {
|
|
54
54
|
logger_1.logger.debug(`unable to parse secret secretResourceName: ${secretResourceName}`);
|
|
55
55
|
return secretResourceName;
|
|
56
56
|
}
|
package/lib/functional.js
CHANGED
|
@@ -40,7 +40,7 @@ function reduceFlat(accum, next) {
|
|
|
40
40
|
}
|
|
41
41
|
exports.reduceFlat = reduceFlat;
|
|
42
42
|
function* zip(left, right) {
|
|
43
|
-
if (left.length
|
|
43
|
+
if (left.length !== right.length) {
|
|
44
44
|
throw new Error("Cannot zip between two lists of differen lengths");
|
|
45
45
|
}
|
|
46
46
|
for (let i = 0; i < left.length; i++) {
|
package/lib/functions/env.js
CHANGED
|
@@ -12,6 +12,7 @@ const RESERVED_PREFIXES = ["X_GOOGLE_", "FIREBASE_", "EXT_"];
|
|
|
12
12
|
const RESERVED_KEYS = [
|
|
13
13
|
"FIREBASE_CONFIG",
|
|
14
14
|
"CLOUD_RUNTIME_CONFIG",
|
|
15
|
+
"EVENTARC_CLOUD_EVENT_SOURCE",
|
|
15
16
|
"ENTRY_POINT",
|
|
16
17
|
"GCP_PROJECT",
|
|
17
18
|
"GCLOUD_PROJECT",
|
|
@@ -120,15 +121,13 @@ function parseStrict(data) {
|
|
|
120
121
|
exports.parseStrict = parseStrict;
|
|
121
122
|
function findEnvfiles(functionsSource, projectId, projectAlias, isEmulator) {
|
|
122
123
|
const files = [".env"];
|
|
124
|
+
files.push(`.env.${projectId}`);
|
|
125
|
+
if (projectAlias) {
|
|
126
|
+
files.push(`.env.${projectAlias}`);
|
|
127
|
+
}
|
|
123
128
|
if (isEmulator) {
|
|
124
129
|
files.push(FUNCTIONS_EMULATOR_DOTENV);
|
|
125
130
|
}
|
|
126
|
-
else {
|
|
127
|
-
files.push(`.env.${projectId}`);
|
|
128
|
-
if (projectAlias && projectAlias.length) {
|
|
129
|
-
files.push(`.env.${projectAlias}`);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
131
|
return files
|
|
133
132
|
.map((f) => path.join(functionsSource, f))
|
|
134
133
|
.filter(fs.existsSync)
|
|
@@ -141,7 +140,7 @@ exports.hasUserEnvs = hasUserEnvs;
|
|
|
141
140
|
function loadUserEnvs({ functionsSource, projectId, projectAlias, isEmulator, }) {
|
|
142
141
|
var _a;
|
|
143
142
|
const envFiles = findEnvfiles(functionsSource, projectId, projectAlias, isEmulator);
|
|
144
|
-
if (envFiles.length
|
|
143
|
+
if (envFiles.length === 0) {
|
|
145
144
|
return {};
|
|
146
145
|
}
|
|
147
146
|
if (projectAlias) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FIREBASE_ALERTS_PUBLISH_EVENT = exports.STORAGE_EVENTS = exports.PUBSUB_PUBLISH_EVENT = void 0;
|
|
4
|
+
exports.PUBSUB_PUBLISH_EVENT = "google.cloud.pubsub.topic.v1.messagePublished";
|
|
5
|
+
exports.STORAGE_EVENTS = [
|
|
6
|
+
"google.cloud.storage.object.v1.finalized",
|
|
7
|
+
"google.cloud.storage.object.v1.archived",
|
|
8
|
+
"google.cloud.storage.object.v1.deleted",
|
|
9
|
+
"google.cloud.storage.object.v1.metadataUpdated",
|
|
10
|
+
];
|
|
11
|
+
exports.FIREBASE_ALERTS_PUBLISH_EVENT = "google.firebase.firebasealerts.alerts.v1.published";
|
|
@@ -92,7 +92,7 @@ async function getIamPolicy(fnName) {
|
|
|
92
92
|
}
|
|
93
93
|
exports.getIamPolicy = getIamPolicy;
|
|
94
94
|
async function setInvokerCreate(projectId, fnName, invoker) {
|
|
95
|
-
if (invoker.length
|
|
95
|
+
if (invoker.length === 0) {
|
|
96
96
|
throw new error_1.FirebaseError("Invoker cannot be an empty array");
|
|
97
97
|
}
|
|
98
98
|
const invokerMembers = proto.getInvokerMembers(invoker, projectId);
|
|
@@ -108,7 +108,7 @@ async function setInvokerCreate(projectId, fnName, invoker) {
|
|
|
108
108
|
exports.setInvokerCreate = setInvokerCreate;
|
|
109
109
|
async function setInvokerUpdate(projectId, fnName, invoker) {
|
|
110
110
|
var _a;
|
|
111
|
-
if (invoker.length
|
|
111
|
+
if (invoker.length === 0) {
|
|
112
112
|
throw new error_1.FirebaseError("Invoker cannot be an empty array");
|
|
113
113
|
}
|
|
114
114
|
const invokerMembers = proto.getInvokerMembers(invoker, projectId);
|
|
@@ -202,10 +202,11 @@ async function listAllFunctions(projectId) {
|
|
|
202
202
|
}
|
|
203
203
|
exports.listAllFunctions = listAllFunctions;
|
|
204
204
|
function endpointFromFunction(gcfFunction) {
|
|
205
|
-
var _a, _b, _c;
|
|
205
|
+
var _a, _b, _c, _d, _e;
|
|
206
206
|
const [, project, , region, , id] = gcfFunction.name.split("/");
|
|
207
207
|
let trigger;
|
|
208
208
|
let uri;
|
|
209
|
+
let securityLevel;
|
|
209
210
|
if ((_a = gcfFunction.labels) === null || _a === void 0 ? void 0 : _a["deployment-scheduled"]) {
|
|
210
211
|
trigger = {
|
|
211
212
|
scheduleTrigger: {},
|
|
@@ -216,18 +217,28 @@ function endpointFromFunction(gcfFunction) {
|
|
|
216
217
|
taskQueueTrigger: {},
|
|
217
218
|
};
|
|
218
219
|
}
|
|
220
|
+
else if (((_c = gcfFunction.labels) === null || _c === void 0 ? void 0 : _c["deployment-callable"]) ||
|
|
221
|
+
((_d = gcfFunction.labels) === null || _d === void 0 ? void 0 : _d["deployment-callabled"])) {
|
|
222
|
+
trigger = {
|
|
223
|
+
callableTrigger: {},
|
|
224
|
+
};
|
|
225
|
+
}
|
|
219
226
|
else if (gcfFunction.httpsTrigger) {
|
|
220
227
|
trigger = { httpsTrigger: {} };
|
|
221
228
|
uri = gcfFunction.httpsTrigger.url;
|
|
229
|
+
securityLevel = gcfFunction.httpsTrigger.securityLevel;
|
|
222
230
|
}
|
|
223
231
|
else {
|
|
224
232
|
trigger = {
|
|
225
233
|
eventTrigger: {
|
|
226
234
|
eventType: gcfFunction.eventTrigger.eventType,
|
|
227
|
-
eventFilters:
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
235
|
+
eventFilters: [
|
|
236
|
+
{
|
|
237
|
+
attribute: "resource",
|
|
238
|
+
value: gcfFunction.eventTrigger.resource,
|
|
239
|
+
},
|
|
240
|
+
],
|
|
241
|
+
retry: !!((_e = gcfFunction.eventTrigger.failurePolicy) === null || _e === void 0 ? void 0 : _e.retry),
|
|
231
242
|
},
|
|
232
243
|
};
|
|
233
244
|
}
|
|
@@ -240,12 +251,19 @@ function endpointFromFunction(gcfFunction) {
|
|
|
240
251
|
if (uri) {
|
|
241
252
|
endpoint.uri = uri;
|
|
242
253
|
}
|
|
243
|
-
|
|
254
|
+
if (securityLevel) {
|
|
255
|
+
endpoint.securityLevel = securityLevel;
|
|
256
|
+
}
|
|
257
|
+
proto.copyIfPresent(endpoint, gcfFunction, "serviceAccountEmail", "availableMemoryMb", "timeout", "minInstances", "maxInstances", "ingressSettings", "labels", "environmentVariables", "secretEnvironmentVariables", "sourceUploadUrl");
|
|
258
|
+
if (gcfFunction.vpcConnector) {
|
|
259
|
+
endpoint.vpc = { connector: gcfFunction.vpcConnector };
|
|
260
|
+
proto.renameIfPresent(endpoint.vpc, gcfFunction, "egressSettings", "vpcConnectorEgressSettings");
|
|
261
|
+
}
|
|
244
262
|
return endpoint;
|
|
245
263
|
}
|
|
246
264
|
exports.endpointFromFunction = endpointFromFunction;
|
|
247
265
|
function functionFromEndpoint(endpoint, sourceUploadUrl) {
|
|
248
|
-
if (endpoint.platform
|
|
266
|
+
if (endpoint.platform !== "gcfv1") {
|
|
249
267
|
throw new error_1.FirebaseError("Trying to create a v1 CloudFunction with v2 API. This should never happen");
|
|
250
268
|
}
|
|
251
269
|
if (!runtimes.isValidRuntime(endpoint.runtime)) {
|
|
@@ -260,9 +278,13 @@ function functionFromEndpoint(endpoint, sourceUploadUrl) {
|
|
|
260
278
|
};
|
|
261
279
|
proto.copyIfPresent(gcfFunction, endpoint, "labels");
|
|
262
280
|
if (backend.isEventTriggered(endpoint)) {
|
|
281
|
+
const resourceFilter = backend.findEventFilter(endpoint, "resource");
|
|
282
|
+
if (!resourceFilter) {
|
|
283
|
+
throw new error_1.FirebaseError("Invalid event trigger definition. Expected event filter with 'resource' attribute.");
|
|
284
|
+
}
|
|
263
285
|
gcfFunction.eventTrigger = {
|
|
264
286
|
eventType: endpoint.eventTrigger.eventType,
|
|
265
|
-
resource:
|
|
287
|
+
resource: resourceFilter.value,
|
|
266
288
|
};
|
|
267
289
|
gcfFunction.eventTrigger.failurePolicy = endpoint.eventTrigger.retry
|
|
268
290
|
? { retry: {} }
|
|
@@ -282,8 +304,18 @@ function functionFromEndpoint(endpoint, sourceUploadUrl) {
|
|
|
282
304
|
}
|
|
283
305
|
else {
|
|
284
306
|
gcfFunction.httpsTrigger = {};
|
|
307
|
+
if (backend.isCallableTriggered(endpoint)) {
|
|
308
|
+
gcfFunction.labels = Object.assign(Object.assign({}, gcfFunction.labels), { "deployment-callable": "true" });
|
|
309
|
+
}
|
|
310
|
+
if (endpoint.securityLevel) {
|
|
311
|
+
gcfFunction.httpsTrigger.securityLevel = endpoint.securityLevel;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
proto.copyIfPresent(gcfFunction, endpoint, "serviceAccountEmail", "timeout", "availableMemoryMb", "minInstances", "maxInstances", "ingressSettings", "environmentVariables", "secretEnvironmentVariables");
|
|
315
|
+
if (endpoint.vpc) {
|
|
316
|
+
proto.renameIfPresent(gcfFunction, endpoint.vpc, "vpcConnector", "connector");
|
|
317
|
+
proto.renameIfPresent(gcfFunction, endpoint.vpc, "vpcConnectorEgressSettings", "egressSettings");
|
|
285
318
|
}
|
|
286
|
-
proto.copyIfPresent(gcfFunction, endpoint, "serviceAccountEmail", "timeout", "availableMemoryMb", "minInstances", "maxInstances", "vpcConnector", "vpcConnectorEgressSettings", "ingressSettings", "environmentVariables", "secretEnvironmentVariables");
|
|
287
319
|
return gcfFunction;
|
|
288
320
|
}
|
|
289
321
|
exports.functionFromEndpoint = functionFromEndpoint;
|