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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.compareFunctions = exports.missingEndpoint = exports.hasEndpoint = exports.regionalEndpoints = exports.matchingBackend = exports.findEndpoint = exports.someEndpoint = exports.allEndpoints = exports.checkAvailability = exports.existingBackend = exports.scheduleIdForFunction = exports.functionName = exports.isEmptyBackend = exports.of = exports.empty = exports.isTaskQueueTriggered = exports.isScheduleTriggered = exports.isEventTriggered = exports.isHttpsTriggered = exports.SCHEDULED_FUNCTION_LABEL = exports.MIN_MEMORY_FOR_CONCURRENCY = exports.DEFAULT_MEMORY = exports.memoryOptionDisplayName = exports.endpointTriggerType = void 0;
|
|
3
|
+
exports.compareFunctions = exports.findEventFilter = exports.missingEndpoint = exports.hasEndpoint = exports.regionalEndpoints = exports.matchingBackend = exports.findEndpoint = exports.someEndpoint = exports.allEndpoints = exports.checkAvailability = exports.existingBackend = exports.scheduleIdForFunction = exports.functionName = exports.isEmptyBackend = exports.of = exports.empty = exports.isTaskQueueTriggered = exports.isScheduleTriggered = exports.isEventTriggered = exports.isCallableTriggered = exports.isHttpsTriggered = exports.secretVersionName = exports.SCHEDULED_FUNCTION_LABEL = exports.MIN_MEMORY_FOR_CONCURRENCY = exports.DEFAULT_MEMORY = exports.memoryOptionDisplayName = exports.endpointTriggerType = void 0;
|
|
4
4
|
const gcf = require("../../gcp/cloudfunctions");
|
|
5
5
|
const gcfV2 = require("../../gcp/cloudfunctionsv2");
|
|
6
6
|
const utils = require("../../utils");
|
|
@@ -13,6 +13,9 @@ function endpointTriggerType(endpoint) {
|
|
|
13
13
|
else if (isHttpsTriggered(endpoint)) {
|
|
14
14
|
return "https";
|
|
15
15
|
}
|
|
16
|
+
else if (isCallableTriggered(endpoint)) {
|
|
17
|
+
return "callable";
|
|
18
|
+
}
|
|
16
19
|
else if (isEventTriggered(endpoint)) {
|
|
17
20
|
return endpoint.eventTrigger.eventType;
|
|
18
21
|
}
|
|
@@ -39,10 +42,19 @@ exports.memoryOptionDisplayName = memoryOptionDisplayName;
|
|
|
39
42
|
exports.DEFAULT_MEMORY = 256;
|
|
40
43
|
exports.MIN_MEMORY_FOR_CONCURRENCY = 2048;
|
|
41
44
|
exports.SCHEDULED_FUNCTION_LABEL = Object.freeze({ deployment: "firebase-schedule" });
|
|
45
|
+
function secretVersionName(s) {
|
|
46
|
+
var _a;
|
|
47
|
+
return `projects/${s.projectId}/secrets/${s.secret}/versions/${(_a = s.version) !== null && _a !== void 0 ? _a : "latest"}`;
|
|
48
|
+
}
|
|
49
|
+
exports.secretVersionName = secretVersionName;
|
|
42
50
|
function isHttpsTriggered(triggered) {
|
|
43
51
|
return {}.hasOwnProperty.call(triggered, "httpsTrigger");
|
|
44
52
|
}
|
|
45
53
|
exports.isHttpsTriggered = isHttpsTriggered;
|
|
54
|
+
function isCallableTriggered(triggered) {
|
|
55
|
+
return {}.hasOwnProperty.call(triggered, "callableTrigger");
|
|
56
|
+
}
|
|
57
|
+
exports.isCallableTriggered = isCallableTriggered;
|
|
46
58
|
function isEventTriggered(triggered) {
|
|
47
59
|
return {}.hasOwnProperty.call(triggered, "eventTrigger");
|
|
48
60
|
}
|
|
@@ -57,7 +69,7 @@ function isTaskQueueTriggered(triggered) {
|
|
|
57
69
|
exports.isTaskQueueTriggered = isTaskQueueTriggered;
|
|
58
70
|
function empty() {
|
|
59
71
|
return {
|
|
60
|
-
requiredAPIs:
|
|
72
|
+
requiredAPIs: [],
|
|
61
73
|
endpoints: {},
|
|
62
74
|
environmentVariables: {},
|
|
63
75
|
};
|
|
@@ -76,7 +88,7 @@ function of(...endpoints) {
|
|
|
76
88
|
}
|
|
77
89
|
exports.of = of;
|
|
78
90
|
function isEmptyBackend(backend) {
|
|
79
|
-
return (Object.keys(backend.requiredAPIs).length
|
|
91
|
+
return (Object.keys(backend.requiredAPIs).length === 0 && Object.keys(backend.endpoints).length === 0);
|
|
80
92
|
}
|
|
81
93
|
exports.isEmptyBackend = isEmptyBackend;
|
|
82
94
|
function functionName(cloudFunction) {
|
|
@@ -140,7 +152,7 @@ async function checkAvailability(context, want) {
|
|
|
140
152
|
const gcfV1Regions = new Set();
|
|
141
153
|
const gcfV2Regions = new Set();
|
|
142
154
|
for (const ep of allEndpoints(want)) {
|
|
143
|
-
if (ep.platform
|
|
155
|
+
if (ep.platform === "gcfv1") {
|
|
144
156
|
gcfV1Regions.add(ep.region);
|
|
145
157
|
}
|
|
146
158
|
else {
|
|
@@ -218,8 +230,12 @@ const missingEndpoint = (backend) => (endpoint) => {
|
|
|
218
230
|
return !(0, exports.hasEndpoint)(backend)(endpoint);
|
|
219
231
|
};
|
|
220
232
|
exports.missingEndpoint = missingEndpoint;
|
|
233
|
+
function findEventFilter(endpoint, attribute) {
|
|
234
|
+
return endpoint.eventTrigger.eventFilters.find((ef) => ef.attribute === attribute);
|
|
235
|
+
}
|
|
236
|
+
exports.findEventFilter = findEventFilter;
|
|
221
237
|
function compareFunctions(left, right) {
|
|
222
|
-
if (left.platform
|
|
238
|
+
if (left.platform !== right.platform) {
|
|
223
239
|
return right.platform < left.platform ? -1 : 1;
|
|
224
240
|
}
|
|
225
241
|
if (left.region < right.region) {
|
|
@@ -52,7 +52,7 @@ async function checkHttpIam(context, options, payload) {
|
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
if (!passed) {
|
|
55
|
-
track("Error (User)", "deploy:functions:http_create_missing_iam");
|
|
55
|
+
void track("Error (User)", "deploy:functions:http_create_missing_iam");
|
|
56
56
|
throw new error_1.FirebaseError(`Missing required permission on project ${(0, cli_color_1.bold)(context.projectId)} to deploy new HTTPS functions. The permission ${(0, cli_color_1.bold)(PERMISSION)} is required to deploy the following functions:\n\n- ` +
|
|
57
57
|
newHttpsEndpoints.map((func) => func.id).join("\n- ") +
|
|
58
58
|
`\n\nTo address this error, please ask a project Owner to assign your account the "Cloud Functions Admin" role at the following URL:\n\nhttps://console.cloud.google.com/iam-admin/iam?project=${context.projectId}`);
|
|
@@ -87,7 +87,7 @@ function mergeBindings(policy, allRequiredBindings) {
|
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
exports.mergeBindings = mergeBindings;
|
|
90
|
-
async function ensureServiceAgentRoles(
|
|
90
|
+
async function ensureServiceAgentRoles(projectNumber, want, have) {
|
|
91
91
|
const wantServices = backend.allEndpoints(want).reduce(reduceEventsToServices, []);
|
|
92
92
|
const haveServices = backend.allEndpoints(have).reduce(reduceEventsToServices, []);
|
|
93
93
|
const newServices = wantServices.filter((wantS) => !haveServices.find((haveS) => wantS.name === haveS.name));
|
|
@@ -96,7 +96,7 @@ async function ensureServiceAgentRoles(projectId, want, have) {
|
|
|
96
96
|
}
|
|
97
97
|
let policy;
|
|
98
98
|
try {
|
|
99
|
-
policy = await (0, resourceManager_1.getIamPolicy)(
|
|
99
|
+
policy = await (0, resourceManager_1.getIamPolicy)(projectNumber);
|
|
100
100
|
}
|
|
101
101
|
catch (err) {
|
|
102
102
|
utils.logLabeledBullet("functions", "Could not verify the necessary IAM configuration for the following newly-integrated services: " +
|
|
@@ -105,11 +105,11 @@ async function ensureServiceAgentRoles(projectId, want, have) {
|
|
|
105
105
|
return;
|
|
106
106
|
}
|
|
107
107
|
const findRequiredBindings = [];
|
|
108
|
-
newServices.forEach((service) => findRequiredBindings.push(service.requiredProjectBindings(
|
|
108
|
+
newServices.forEach((service) => findRequiredBindings.push(service.requiredProjectBindings(projectNumber, policy)));
|
|
109
109
|
const allRequiredBindings = await Promise.all(findRequiredBindings);
|
|
110
110
|
mergeBindings(policy, allRequiredBindings);
|
|
111
111
|
try {
|
|
112
|
-
await (0, resourceManager_1.setIamPolicy)(
|
|
112
|
+
await (0, resourceManager_1.setIamPolicy)(projectNumber, policy, "bindings");
|
|
113
113
|
}
|
|
114
114
|
catch (err) {
|
|
115
115
|
throw new error_1.FirebaseError("We failed to modify the IAM policy for the project. The functions " +
|
|
@@ -71,7 +71,7 @@ async function cleanupBuildImages(haveFunctions, deletedFunctions, cleaners = {}
|
|
|
71
71
|
let message = "Unhandled error cleaning up build images. This could result in a small monthly bill if not corrected. ";
|
|
72
72
|
message +=
|
|
73
73
|
"You can attempt to delete these images by redeploying or you can delete them manually at";
|
|
74
|
-
if (failedDomains.size
|
|
74
|
+
if (failedDomains.size === 1) {
|
|
75
75
|
message += " " + failedDomains.values().next().value;
|
|
76
76
|
}
|
|
77
77
|
else {
|
|
@@ -205,7 +205,7 @@ async function listGcfPaths(projectId, locations, dockerHelpers = {}) {
|
|
|
205
205
|
.map((results) => results.children)
|
|
206
206
|
.reduce((acc, val) => [...acc, ...val], [])
|
|
207
207
|
.filter((loc) => locationsSet.has(loc));
|
|
208
|
-
if (failedSubdomains.length
|
|
208
|
+
if (failedSubdomains.length === subdomains.size) {
|
|
209
209
|
throw new error_1.FirebaseError("Failed to search all subdomains.");
|
|
210
210
|
}
|
|
211
211
|
else if (failedSubdomains.length > 0) {
|
|
@@ -237,7 +237,7 @@ async function deleteGcfArtifacts(projectId, locations, dockerHelpers = {}) {
|
|
|
237
237
|
}
|
|
238
238
|
});
|
|
239
239
|
await Promise.all(deleteLocations);
|
|
240
|
-
if (failedSubdomains.length
|
|
240
|
+
if (failedSubdomains.length === subdomains.size) {
|
|
241
241
|
throw new error_1.FirebaseError("Failed to search all subdomains.");
|
|
242
242
|
}
|
|
243
243
|
else if (failedSubdomains.length > 0) {
|
|
@@ -26,7 +26,7 @@ async function defaultServiceAccount(e) {
|
|
|
26
26
|
}
|
|
27
27
|
exports.defaultServiceAccount = defaultServiceAccount;
|
|
28
28
|
function nodeBillingError(projectId) {
|
|
29
|
-
track("functions_runtime_notices", "nodejs10_billing_error");
|
|
29
|
+
void track("functions_runtime_notices", "nodejs10_billing_error");
|
|
30
30
|
return new error_1.FirebaseError(`Cloud Functions deployment requires the pay-as-you-go (Blaze) billing plan. To upgrade your project, visit the following URL:
|
|
31
31
|
|
|
32
32
|
https://console.firebase.google.com/project/${projectId}/usage/details
|
|
@@ -36,7 +36,7 @@ For additional information about this requirement, see Firebase FAQs:
|
|
|
36
36
|
${FAQ_URL}`, { exit: 1 });
|
|
37
37
|
}
|
|
38
38
|
function nodePermissionError(projectId) {
|
|
39
|
-
track("functions_runtime_notices", "nodejs10_permission_error");
|
|
39
|
+
void track("functions_runtime_notices", "nodejs10_permission_error");
|
|
40
40
|
return new error_1.FirebaseError(`Cloud Functions deployment requires the Cloud Build API to be enabled. The current credentials do not have permission to enable APIs for project ${clc.bold(projectId)}.
|
|
41
41
|
|
|
42
42
|
Please ask a project owner to visit the following URL to enable Cloud Build:
|
|
@@ -99,7 +99,7 @@ async function secretAccess(projectId, wantBackend, haveBackend) {
|
|
|
99
99
|
for (const serviceAccount of serviceAccounts) {
|
|
100
100
|
(_a = wantSecrets[secret]) === null || _a === void 0 ? void 0 : _a.delete(serviceAccount);
|
|
101
101
|
}
|
|
102
|
-
if (((_b = wantSecrets[secret]) === null || _b === void 0 ? void 0 : _b.size)
|
|
102
|
+
if (((_b = wantSecrets[secret]) === null || _b === void 0 ? void 0 : _b.size) === 0) {
|
|
103
103
|
delete wantSecrets[secret];
|
|
104
104
|
}
|
|
105
105
|
}
|
|
@@ -10,7 +10,7 @@ function functionMatchesAnyGroup(func, filterGroups) {
|
|
|
10
10
|
exports.functionMatchesAnyGroup = functionMatchesAnyGroup;
|
|
11
11
|
function functionMatchesGroup(func, groupChunks) {
|
|
12
12
|
const functionNameChunks = func.id.split("-").slice(0, groupChunks.length);
|
|
13
|
-
if (functionNameChunks.length
|
|
13
|
+
if (functionNameChunks.length !== groupChunks.length) {
|
|
14
14
|
return false;
|
|
15
15
|
}
|
|
16
16
|
for (let i = 0; i < groupChunks.length; i += 1) {
|
|
@@ -28,7 +28,7 @@ function getFilterGroups(options) {
|
|
|
28
28
|
const only = options.only.split(",");
|
|
29
29
|
const onlyFunctions = only.filter((filter) => {
|
|
30
30
|
const opts = filter.split(":");
|
|
31
|
-
return opts[0]
|
|
31
|
+
return opts[0] === "functions" && opts[1];
|
|
32
32
|
});
|
|
33
33
|
return onlyFunctions.map((filter) => {
|
|
34
34
|
return filter.split(":")[1].split(/[.-]/);
|
|
@@ -27,6 +27,7 @@ function hasDotenv(opts) {
|
|
|
27
27
|
}
|
|
28
28
|
async function prepare(context, options, payload) {
|
|
29
29
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
30
|
+
const projectNumber = await (0, projectUtils_1.needProjectNumber)(options);
|
|
30
31
|
const sourceDirName = options.config.get("functions.source");
|
|
31
32
|
if (!sourceDirName) {
|
|
32
33
|
throw new error_1.FirebaseError(`No functions code detected at default location (./functions), and no functions.source defined in firebase.json`);
|
|
@@ -69,7 +70,7 @@ async function prepare(context, options, payload) {
|
|
|
69
70
|
: usedDotenv
|
|
70
71
|
? "dotenv"
|
|
71
72
|
: "none";
|
|
72
|
-
|
|
73
|
+
void (0, track_1.track)("functions_codebase_deploy_env_method", tag);
|
|
73
74
|
logger_1.logger.debug(`Analyzing ${runtimeDelegate.name} backend spec`);
|
|
74
75
|
const wantBackend = await runtimeDelegate.discoverSpec(runtimeConfig, firebaseEnvs);
|
|
75
76
|
wantBackend.environmentVariables = Object.assign(Object.assign({}, userEnvs), firebaseEnvs);
|
|
@@ -102,7 +103,7 @@ async function prepare(context, options, payload) {
|
|
|
102
103
|
for (const endpoint of backend.allEndpoints(wantBackend)) {
|
|
103
104
|
endpoint.environmentVariables = wantBackend.environmentVariables;
|
|
104
105
|
}
|
|
105
|
-
await Promise.all(Object.values(wantBackend.requiredAPIs).map((api) => {
|
|
106
|
+
await Promise.all(Object.values(wantBackend.requiredAPIs).map(({ api }) => {
|
|
106
107
|
return ensureApiEnabled.ensure(projectId, api, "functions", false);
|
|
107
108
|
}));
|
|
108
109
|
validate.endpointsAreValid(wantBackend);
|
|
@@ -111,7 +112,7 @@ async function prepare(context, options, payload) {
|
|
|
111
112
|
return (0, functionsDeployHelper_1.functionMatchesAnyGroup)(endpoint, context.filters);
|
|
112
113
|
});
|
|
113
114
|
const haveBackend = await backend.existingBackend(context);
|
|
114
|
-
await (0, checkIam_1.ensureServiceAgentRoles)(
|
|
115
|
+
await (0, checkIam_1.ensureServiceAgentRoles)(projectNumber, wantBackend, haveBackend);
|
|
115
116
|
inferDetailsFromExisting(wantBackend, haveBackend, usedDotenv);
|
|
116
117
|
await (0, triggerRegionHelper_1.ensureTriggerRegions)(wantBackend);
|
|
117
118
|
await (0, prompts_1.promptForFailurePolicies)(options, matchingBackend, haveBackend);
|
|
@@ -134,6 +135,7 @@ function inferDetailsFromExisting(want, have, usedDotenv) {
|
|
|
134
135
|
if (!wantE.availableMemoryMb && haveE.availableMemoryMb) {
|
|
135
136
|
wantE.availableMemoryMb = haveE.availableMemoryMb;
|
|
136
137
|
}
|
|
138
|
+
wantE.securityLevel = haveE.securityLevel ? haveE.securityLevel : "SECURE_ALWAYS";
|
|
137
139
|
maybeCopyTriggerRegion(wantE, haveE);
|
|
138
140
|
}
|
|
139
141
|
}
|
|
@@ -106,7 +106,7 @@ function canCalculateMinInstanceCost(endpoint) {
|
|
|
106
106
|
if (!endpoint.minInstances) {
|
|
107
107
|
return true;
|
|
108
108
|
}
|
|
109
|
-
if (endpoint.platform
|
|
109
|
+
if (endpoint.platform === "gcfv1") {
|
|
110
110
|
if (!MB_TO_GHZ[endpoint.availableMemoryMb || 256]) {
|
|
111
111
|
return false;
|
|
112
112
|
}
|
|
@@ -21,7 +21,7 @@ async function promptForFailurePolicies(options, want, have) {
|
|
|
21
21
|
const existing = (_a = have.endpoints[endpoint.region]) === null || _a === void 0 ? void 0 : _a[endpoint.id];
|
|
22
22
|
return !(existing && backend.isEventTriggered(existing) && existing.eventTrigger.retry);
|
|
23
23
|
});
|
|
24
|
-
if (newRetryEndpoints.length
|
|
24
|
+
if (newRetryEndpoints.length === 0) {
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
const warnMessage = "The following functions will newly be retried in case of failure: " +
|
|
@@ -137,7 +137,7 @@ async function promptForMinInstances(options, want, have) {
|
|
|
137
137
|
costLine = `With these options, your minimum bill will be $${cost} in a 30-day month`;
|
|
138
138
|
}
|
|
139
139
|
let cudAnnotation = "";
|
|
140
|
-
if (backend.someEndpoint(want, (fn) => fn.platform
|
|
140
|
+
if (backend.someEndpoint(want, (fn) => fn.platform === "gcfv2" && !!fn.minInstances)) {
|
|
141
141
|
cudAnnotation =
|
|
142
142
|
"\nThis bill can be lowered with a one year commitment. See https://cloud.google.com/run/cud for more";
|
|
143
143
|
}
|
|
@@ -51,12 +51,12 @@ class Fabricator {
|
|
|
51
51
|
totalTime: 0,
|
|
52
52
|
results: [],
|
|
53
53
|
};
|
|
54
|
-
const
|
|
55
|
-
const results = await this.
|
|
54
|
+
const deployChangesets = Object.values(plan).map(async (changes) => {
|
|
55
|
+
const results = await this.applyChangeset(changes);
|
|
56
56
|
summary.results.push(...results);
|
|
57
57
|
return;
|
|
58
58
|
});
|
|
59
|
-
const promiseResults = await utils.allSettled(
|
|
59
|
+
const promiseResults = await utils.allSettled(deployChangesets);
|
|
60
60
|
const errs = promiseResults
|
|
61
61
|
.filter((r) => r.status === "rejected")
|
|
62
62
|
.map((r) => r.reason);
|
|
@@ -66,7 +66,7 @@ class Fabricator {
|
|
|
66
66
|
summary.totalTime = timer.stop();
|
|
67
67
|
return summary;
|
|
68
68
|
}
|
|
69
|
-
async
|
|
69
|
+
async applyChangeset(changes) {
|
|
70
70
|
const deployResults = [];
|
|
71
71
|
const handle = async (op, endpoint, fn) => {
|
|
72
72
|
const timer = new timer_1.Timer();
|
|
@@ -216,12 +216,12 @@ class Fabricator {
|
|
|
216
216
|
})
|
|
217
217
|
.catch(rethrowAs(endpoint, "create topic"));
|
|
218
218
|
}
|
|
219
|
-
const resultFunction =
|
|
219
|
+
const resultFunction = await this.functionExecutor
|
|
220
220
|
.run(async () => {
|
|
221
221
|
const op = await gcfV2.createFunction(apiFunction);
|
|
222
222
|
return await poller.pollOperation(Object.assign(Object.assign({}, gcfV2PollerOptions), { pollerName: `create-${endpoint.region}-${endpoint.id}`, operationResourceName: op.name }));
|
|
223
223
|
})
|
|
224
|
-
.catch(rethrowAs(endpoint, "create"))
|
|
224
|
+
.catch(rethrowAs(endpoint, "create"));
|
|
225
225
|
endpoint.uri = resultFunction.serviceConfig.uri;
|
|
226
226
|
const serviceName = resultFunction.serviceConfig.service;
|
|
227
227
|
if (backend.isHttpsTriggered(endpoint)) {
|
|
@@ -243,7 +243,7 @@ class Fabricator {
|
|
|
243
243
|
}
|
|
244
244
|
}
|
|
245
245
|
const mem = endpoint.availableMemoryMb || backend.DEFAULT_MEMORY;
|
|
246
|
-
if (mem >= backend.MIN_MEMORY_FOR_CONCURRENCY && endpoint.concurrency
|
|
246
|
+
if (mem >= backend.MIN_MEMORY_FOR_CONCURRENCY && endpoint.concurrency !== 1) {
|
|
247
247
|
await this.setConcurrency(endpoint, serviceName, endpoint.concurrency || DEFAULT_GCFV2_CONCURRENCY);
|
|
248
248
|
}
|
|
249
249
|
}
|
|
@@ -56,7 +56,7 @@ async function release(context, options, payload) {
|
|
|
56
56
|
await containerCleaner.cleanupBuildImages(haveEndpoints, deletedEndpoints, opts);
|
|
57
57
|
const allErrors = summary.results.filter((r) => r.error).map((r) => r.error);
|
|
58
58
|
if (allErrors.length) {
|
|
59
|
-
const opts = allErrors.length
|
|
59
|
+
const opts = allErrors.length === 1 ? { original: allErrors[0] } : { children: allErrors };
|
|
60
60
|
throw new error_1.FirebaseError("There was an error deploying functions", Object.assign(Object.assign({}, opts), { exit: 2 }));
|
|
61
61
|
}
|
|
62
62
|
}
|
|
@@ -1,27 +1,39 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkForV2Upgrade = exports.checkForIllegalUpdate = exports.upgradedScheduleFromV1ToV2 = exports.changedV2PubSubTopic = exports.changedTriggerRegion = exports.upgradedToGCFv2WithoutSettingConcurrency = exports.createDeploymentPlan = exports.calculateUpdate = exports.
|
|
3
|
+
exports.checkForV2Upgrade = exports.checkForIllegalUpdate = exports.upgradedScheduleFromV1ToV2 = exports.changedV2PubSubTopic = exports.changedTriggerRegion = exports.upgradedToGCFv2WithoutSettingConcurrency = exports.createDeploymentPlan = exports.calculateUpdate = exports.calculateChangesets = void 0;
|
|
4
4
|
const functionsDeployHelper_1 = require("../functionsDeployHelper");
|
|
5
|
-
const functionsDeployHelper_2 = require("../functionsDeployHelper");
|
|
6
5
|
const deploymentTool_1 = require("../../../deploymentTool");
|
|
7
6
|
const error_1 = require("../../../error");
|
|
8
7
|
const utils = require("../../../utils");
|
|
9
8
|
const backend = require("../backend");
|
|
10
|
-
const
|
|
11
|
-
function
|
|
12
|
-
const
|
|
9
|
+
const v2events = require("../../../functions/events/v2");
|
|
10
|
+
function calculateChangesets(want, have, keyFn, options) {
|
|
11
|
+
const toCreate = utils.groupBy(Object.keys(want)
|
|
13
12
|
.filter((id) => !have[id])
|
|
14
|
-
.map((id) => want[id]);
|
|
15
|
-
const
|
|
13
|
+
.map((id) => want[id]), keyFn);
|
|
14
|
+
const toDelete = utils.groupBy(Object.keys(have)
|
|
16
15
|
.filter((id) => !want[id])
|
|
17
16
|
.filter((id) => options.deleteAll || (0, deploymentTool_1.isFirebaseManaged)(have[id].labels || {}))
|
|
18
|
-
.map((id) => have[id]);
|
|
19
|
-
const
|
|
17
|
+
.map((id) => have[id]), keyFn);
|
|
18
|
+
const toUpdate = utils.groupBy(Object.keys(want)
|
|
20
19
|
.filter((id) => have[id])
|
|
21
|
-
.map((id) => calculateUpdate(want[id], have[id]));
|
|
22
|
-
|
|
20
|
+
.map((id) => calculateUpdate(want[id], have[id])), (eu) => keyFn(eu.endpoint));
|
|
21
|
+
const result = {};
|
|
22
|
+
const keys = new Set([
|
|
23
|
+
...Object.keys(toCreate),
|
|
24
|
+
...Object.keys(toDelete),
|
|
25
|
+
...Object.keys(toUpdate),
|
|
26
|
+
]);
|
|
27
|
+
for (const key of keys) {
|
|
28
|
+
result[key] = {
|
|
29
|
+
endpointsToCreate: toCreate[key] || [],
|
|
30
|
+
endpointsToUpdate: toUpdate[key] || [],
|
|
31
|
+
endpointsToDelete: toDelete[key] || [],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
23
35
|
}
|
|
24
|
-
exports.
|
|
36
|
+
exports.calculateChangesets = calculateChangesets;
|
|
25
37
|
function calculateUpdate(want, have) {
|
|
26
38
|
checkForIllegalUpdate(want, have);
|
|
27
39
|
const update = {
|
|
@@ -37,7 +49,7 @@ function calculateUpdate(want, have) {
|
|
|
37
49
|
}
|
|
38
50
|
exports.calculateUpdate = calculateUpdate;
|
|
39
51
|
function createDeploymentPlan(want, have, options = {}) {
|
|
40
|
-
|
|
52
|
+
let deployment = {};
|
|
41
53
|
want = backend.matchingBackend(want, (endpoint) => {
|
|
42
54
|
return (0, functionsDeployHelper_1.functionMatchesAnyGroup)(endpoint, options.filters || []);
|
|
43
55
|
});
|
|
@@ -46,7 +58,8 @@ function createDeploymentPlan(want, have, options = {}) {
|
|
|
46
58
|
});
|
|
47
59
|
const regions = new Set([...Object.keys(want.endpoints), ...Object.keys(have.endpoints)]);
|
|
48
60
|
for (const region of regions) {
|
|
49
|
-
|
|
61
|
+
const changesets = calculateChangesets(want.endpoints[region] || {}, have.endpoints[region] || {}, (e) => `${e.region}-${e.availableMemoryMb || "default"}`, options);
|
|
62
|
+
deployment = Object.assign(Object.assign({}, deployment), changesets);
|
|
50
63
|
}
|
|
51
64
|
if (upgradedToGCFv2WithoutSettingConcurrency(want, have)) {
|
|
52
65
|
utils.logLabeledBullet("functions", "You are updating one or more functions to Google Cloud Functions v2, " +
|
|
@@ -74,10 +87,10 @@ function upgradedToGCFv2WithoutSettingConcurrency(want, have) {
|
|
|
74
87
|
}
|
|
75
88
|
exports.upgradedToGCFv2WithoutSettingConcurrency = upgradedToGCFv2WithoutSettingConcurrency;
|
|
76
89
|
function changedTriggerRegion(want, have) {
|
|
77
|
-
if (want.platform
|
|
90
|
+
if (want.platform !== "gcfv2") {
|
|
78
91
|
return false;
|
|
79
92
|
}
|
|
80
|
-
if (have.platform
|
|
93
|
+
if (have.platform !== "gcfv2") {
|
|
81
94
|
return false;
|
|
82
95
|
}
|
|
83
96
|
if (!backend.isEventTriggered(want)) {
|
|
@@ -86,10 +99,11 @@ function changedTriggerRegion(want, have) {
|
|
|
86
99
|
if (!backend.isEventTriggered(have)) {
|
|
87
100
|
return false;
|
|
88
101
|
}
|
|
89
|
-
return want.eventTrigger.region
|
|
102
|
+
return want.eventTrigger.region !== have.eventTrigger.region;
|
|
90
103
|
}
|
|
91
104
|
exports.changedTriggerRegion = changedTriggerRegion;
|
|
92
105
|
function changedV2PubSubTopic(want, have) {
|
|
106
|
+
var _a, _b;
|
|
93
107
|
if (want.platform !== "gcfv2") {
|
|
94
108
|
return false;
|
|
95
109
|
}
|
|
@@ -102,13 +116,13 @@ function changedV2PubSubTopic(want, have) {
|
|
|
102
116
|
if (!backend.isEventTriggered(have)) {
|
|
103
117
|
return false;
|
|
104
118
|
}
|
|
105
|
-
if (want.eventTrigger.eventType
|
|
119
|
+
if (want.eventTrigger.eventType !== v2events.PUBSUB_PUBLISH_EVENT) {
|
|
106
120
|
return false;
|
|
107
121
|
}
|
|
108
|
-
if (have.eventTrigger.eventType !==
|
|
122
|
+
if (have.eventTrigger.eventType !== v2events.PUBSUB_PUBLISH_EVENT) {
|
|
109
123
|
return false;
|
|
110
124
|
}
|
|
111
|
-
return have
|
|
125
|
+
return (((_a = backend.findEventFilter(have, "topic")) === null || _a === void 0 ? void 0 : _a.value) !== ((_b = backend.findEventFilter(want, "topic")) === null || _b === void 0 ? void 0 : _b.value));
|
|
112
126
|
}
|
|
113
127
|
exports.changedV2PubSubTopic = changedV2PubSubTopic;
|
|
114
128
|
function upgradedScheduleFromV1ToV2(want, have) {
|
|
@@ -132,6 +146,9 @@ function checkForIllegalUpdate(want, have) {
|
|
|
132
146
|
if (backend.isHttpsTriggered(e)) {
|
|
133
147
|
return "an HTTPS";
|
|
134
148
|
}
|
|
149
|
+
else if (backend.isCallableTriggered(e)) {
|
|
150
|
+
return "a callable";
|
|
151
|
+
}
|
|
135
152
|
else if (backend.isEventTriggered(e)) {
|
|
136
153
|
return "a background triggered";
|
|
137
154
|
}
|
|
@@ -145,18 +162,18 @@ function checkForIllegalUpdate(want, have) {
|
|
|
145
162
|
};
|
|
146
163
|
const wantType = triggerType(want);
|
|
147
164
|
const haveType = triggerType(have);
|
|
148
|
-
if (wantType
|
|
149
|
-
throw new error_1.FirebaseError(`[${(0,
|
|
165
|
+
if (wantType !== haveType) {
|
|
166
|
+
throw new error_1.FirebaseError(`[${(0, functionsDeployHelper_1.getFunctionLabel)(want)}] Changing from ${haveType} function to ${wantType} function is not allowed. Please delete your function and create a new one instead.`);
|
|
150
167
|
}
|
|
151
|
-
if (want.platform
|
|
152
|
-
throw new error_1.FirebaseError(`[${(0,
|
|
168
|
+
if (want.platform === "gcfv1" && have.platform === "gcfv2") {
|
|
169
|
+
throw new error_1.FirebaseError(`[${(0, functionsDeployHelper_1.getFunctionLabel)(want)}] Functions cannot be downgraded from GCFv2 to GCFv1`);
|
|
153
170
|
}
|
|
154
171
|
exports.checkForV2Upgrade(want, have);
|
|
155
172
|
}
|
|
156
173
|
exports.checkForIllegalUpdate = checkForIllegalUpdate;
|
|
157
174
|
function checkForV2Upgrade(want, have) {
|
|
158
|
-
if (want.platform
|
|
159
|
-
throw new error_1.FirebaseError(`[${(0,
|
|
175
|
+
if (want.platform === "gcfv2" && have.platform === "gcfv1") {
|
|
176
|
+
throw new error_1.FirebaseError(`[${(0, functionsDeployHelper_1.getFunctionLabel)(have)}] Upgrading from GCFv1 to GCFv2 is not yet supported. Please delete your old function or wait for this feature to be ready.`);
|
|
160
177
|
}
|
|
161
178
|
}
|
|
162
179
|
exports.checkForV2Upgrade = checkForV2Upgrade;
|
|
@@ -162,6 +162,9 @@ function triggerTag(endpoint) {
|
|
|
162
162
|
if (backend.isTaskQueueTriggered(endpoint)) {
|
|
163
163
|
return `${prefix}.taskQueue`;
|
|
164
164
|
}
|
|
165
|
+
if (backend.isCallableTriggered(endpoint)) {
|
|
166
|
+
return `${prefix}.callable`;
|
|
167
|
+
}
|
|
165
168
|
if (backend.isHttpsTriggered(endpoint)) {
|
|
166
169
|
if ((_a = endpoint.labels) === null || _a === void 0 ? void 0 : _a["deployment-callable"]) {
|
|
167
170
|
return `${prefix}.callable`;
|
|
@@ -29,18 +29,18 @@ exports.yamlToBackend = yamlToBackend;
|
|
|
29
29
|
async function detectFromYaml(directory, project, runtime) {
|
|
30
30
|
let text;
|
|
31
31
|
try {
|
|
32
|
-
text = await exports.readFileAsync(path.join(directory, "
|
|
32
|
+
text = await exports.readFileAsync(path.join(directory, "functions.yaml"), "utf8");
|
|
33
33
|
}
|
|
34
34
|
catch (err) {
|
|
35
35
|
if (err.code === "ENOENT") {
|
|
36
|
-
logger_1.logger.debug("Could not find
|
|
36
|
+
logger_1.logger.debug("Could not find functions.yaml. Must use http discovery");
|
|
37
37
|
}
|
|
38
38
|
else {
|
|
39
|
-
logger_1.logger.debug("Unexpected error looking for
|
|
39
|
+
logger_1.logger.debug("Unexpected error looking for functions.yaml file:", err);
|
|
40
40
|
}
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
|
-
logger_1.logger.debug("Found
|
|
43
|
+
logger_1.logger.debug("Found functions.yaml. Got spec:", text);
|
|
44
44
|
const parsed = yaml.load(text);
|
|
45
45
|
return yamlToBackend(parsed, project, api.functionsDefaultRegion, runtime);
|
|
46
46
|
}
|
|
@@ -54,7 +54,7 @@ async function detectFromPort(port, project, runtime, timeout = 30000) {
|
|
|
54
54
|
});
|
|
55
55
|
while (true) {
|
|
56
56
|
try {
|
|
57
|
-
res = await Promise.race([(0, node_fetch_1.default)(`http://localhost:${port}/
|
|
57
|
+
res = await Promise.race([(0, node_fetch_1.default)(`http://localhost:${port}/__/functions.yaml`), timedOut]);
|
|
58
58
|
break;
|
|
59
59
|
}
|
|
60
60
|
catch (err) {
|
|
@@ -65,7 +65,7 @@ async function detectFromPort(port, project, runtime, timeout = 30000) {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
const text = await res.text();
|
|
68
|
-
logger_1.logger.debug("Got response from /
|
|
68
|
+
logger_1.logger.debug("Got response from /__/functions.yaml", text);
|
|
69
69
|
let parsed;
|
|
70
70
|
try {
|
|
71
71
|
parsed = yaml.load(text);
|
|
@@ -21,7 +21,7 @@ function assertKeyTypes(prefix, yaml, schema) {
|
|
|
21
21
|
const key = keyAsString;
|
|
22
22
|
const fullKey = prefix ? prefix + "." + key : key;
|
|
23
23
|
if (!schema[key] || schema[key] === "omit") {
|
|
24
|
-
throw new error_1.FirebaseError(`Unexpected key ${fullKey}. You may need to install a newer version of the Firebase CLI
|
|
24
|
+
throw new error_1.FirebaseError(`Unexpected key ${fullKey}. You may need to install a newer version of the Firebase CLI.`);
|
|
25
25
|
}
|
|
26
26
|
if (schema[key] === "string") {
|
|
27
27
|
if (typeof value !== "string") {
|
|
@@ -12,7 +12,7 @@ function backendFromV1Alpha1(yaml, project, region, runtime) {
|
|
|
12
12
|
(0, parsing_1.requireKeys)("", manifest, "endpoints");
|
|
13
13
|
(0, parsing_1.assertKeyTypes)("", manifest, {
|
|
14
14
|
specVersion: "string",
|
|
15
|
-
requiredAPIs: "
|
|
15
|
+
requiredAPIs: "array",
|
|
16
16
|
endpoints: "object",
|
|
17
17
|
});
|
|
18
18
|
for (const id of Object.keys(manifest.endpoints)) {
|
|
@@ -25,15 +25,14 @@ function backendFromV1Alpha1(yaml, project, region, runtime) {
|
|
|
25
25
|
}
|
|
26
26
|
exports.backendFromV1Alpha1 = backendFromV1Alpha1;
|
|
27
27
|
function parseRequiredAPIs(manifest) {
|
|
28
|
-
const requiredAPIs =
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
const requiredAPIs = manifest.requiredAPIs || [];
|
|
29
|
+
for (const { api, reason } of requiredAPIs) {
|
|
30
|
+
if (typeof api !== "string") {
|
|
31
|
+
throw new error_1.FirebaseError(`Invalid api "${JSON.stringify(api)}. Expected string`);
|
|
32
|
+
}
|
|
33
33
|
if (typeof reason !== "string") {
|
|
34
34
|
throw new error_1.FirebaseError(`Invalid reason "${JSON.stringify(reason)} for API ${api}. Expected string`);
|
|
35
35
|
}
|
|
36
|
-
requiredAPIs[api] = reason;
|
|
37
36
|
}
|
|
38
37
|
return requiredAPIs;
|
|
39
38
|
}
|
|
@@ -51,13 +50,13 @@ function parseEndpoints(manifest, id, project, defaultRegion, runtime) {
|
|
|
51
50
|
concurrency: "number",
|
|
52
51
|
serviceAccountEmail: "string",
|
|
53
52
|
timeout: "string",
|
|
54
|
-
|
|
55
|
-
vpcConnectorEgressSettings: "string",
|
|
53
|
+
vpc: "object",
|
|
56
54
|
labels: "object",
|
|
57
55
|
ingressSettings: "string",
|
|
58
56
|
environmentVariables: "object",
|
|
59
57
|
secretEnvironmentVariables: "array",
|
|
60
58
|
httpsTrigger: "object",
|
|
59
|
+
callableTrigger: "object",
|
|
61
60
|
eventTrigger: "object",
|
|
62
61
|
scheduleTrigger: "object",
|
|
63
62
|
taskQueueTrigger: "object",
|
|
@@ -66,6 +65,9 @@ function parseEndpoints(manifest, id, project, defaultRegion, runtime) {
|
|
|
66
65
|
if (ep.httpsTrigger) {
|
|
67
66
|
triggerCount++;
|
|
68
67
|
}
|
|
68
|
+
if (ep.callableTrigger) {
|
|
69
|
+
triggerCount++;
|
|
70
|
+
}
|
|
69
71
|
if (ep.eventTrigger) {
|
|
70
72
|
triggerCount++;
|
|
71
73
|
}
|
|
@@ -76,7 +78,7 @@ function parseEndpoints(manifest, id, project, defaultRegion, runtime) {
|
|
|
76
78
|
triggerCount++;
|
|
77
79
|
}
|
|
78
80
|
if (!triggerCount) {
|
|
79
|
-
throw new error_1.FirebaseError("Expected trigger in endpoint" + id);
|
|
81
|
+
throw new error_1.FirebaseError("Expected trigger in endpoint " + id);
|
|
80
82
|
}
|
|
81
83
|
if (triggerCount > 1) {
|
|
82
84
|
throw new error_1.FirebaseError("Multiple triggers defined for endpoint" + id);
|
|
@@ -86,13 +88,18 @@ function parseEndpoints(manifest, id, project, defaultRegion, runtime) {
|
|
|
86
88
|
if (backend.isEventTriggered(ep)) {
|
|
87
89
|
(0, parsing_1.requireKeys)(prefix + ".eventTrigger", ep.eventTrigger, "eventType", "eventFilters");
|
|
88
90
|
(0, parsing_1.assertKeyTypes)(prefix + ".eventTrigger", ep.eventTrigger, {
|
|
89
|
-
eventFilters: "
|
|
91
|
+
eventFilters: "array",
|
|
90
92
|
eventType: "string",
|
|
91
93
|
retry: "boolean",
|
|
92
94
|
region: "string",
|
|
93
95
|
serviceAccountEmail: "string",
|
|
94
96
|
});
|
|
95
97
|
triggered = { eventTrigger: ep.eventTrigger };
|
|
98
|
+
for (const eventFilter of triggered.eventTrigger.eventFilters) {
|
|
99
|
+
if (eventFilter.attribute === "topic" && !eventFilter.value.startsWith("projects/")) {
|
|
100
|
+
eventFilter.value = `projects/${project}/topics/${eventFilter.value}`;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
96
103
|
}
|
|
97
104
|
else if (backend.isHttpsTriggered(ep)) {
|
|
98
105
|
(0, parsing_1.assertKeyTypes)(prefix + ".httpsTrigger", ep.httpsTrigger, {
|
|
@@ -101,6 +108,9 @@ function parseEndpoints(manifest, id, project, defaultRegion, runtime) {
|
|
|
101
108
|
triggered = { httpsTrigger: {} };
|
|
102
109
|
(0, proto_1.copyIfPresent)(triggered.httpsTrigger, ep.httpsTrigger, "invoker");
|
|
103
110
|
}
|
|
111
|
+
else if (backend.isCallableTriggered(ep)) {
|
|
112
|
+
triggered = { callableTrigger: {} };
|
|
113
|
+
}
|
|
104
114
|
else if (backend.isScheduleTriggered(ep)) {
|
|
105
115
|
(0, parsing_1.assertKeyTypes)(prefix + ".scheduleTrigger", ep.scheduleTrigger, {
|
|
106
116
|
schedule: "string",
|
|
@@ -149,7 +159,7 @@ function parseEndpoints(manifest, id, project, defaultRegion, runtime) {
|
|
|
149
159
|
region,
|
|
150
160
|
project,
|
|
151
161
|
runtime, entryPoint: ep.entryPoint }, triggered);
|
|
152
|
-
(0, proto_1.copyIfPresent)(parsed, ep, "availableMemoryMb", "maxInstances", "minInstances", "concurrency", "serviceAccountEmail", "timeout", "
|
|
162
|
+
(0, proto_1.copyIfPresent)(parsed, ep, "availableMemoryMb", "maxInstances", "minInstances", "concurrency", "serviceAccountEmail", "timeout", "vpc", "labels", "ingressSettings", "environmentVariables");
|
|
153
163
|
allParsed.push(parsed);
|
|
154
164
|
}
|
|
155
165
|
return allParsed;
|