firebase-tools 11.4.1 → 11.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/deploy/functions/backend.js +6 -4
- package/lib/deploy/functions/build.js +107 -95
- package/lib/deploy/functions/ensure.js +1 -1
- package/lib/deploy/functions/params.js +5 -2
- package/lib/deploy/functions/prepare.js +3 -3
- package/lib/deploy/functions/pricing.js +3 -2
- package/lib/deploy/functions/prompts.js +1 -1
- package/lib/deploy/functions/release/fabricator.js +8 -7
- package/lib/deploy/functions/runtimes/discovery/parsing.js +19 -8
- package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +112 -107
- package/lib/deploy/functions/runtimes/node/parseTriggers.js +53 -21
- package/lib/deploy/functions/services/storage.js +6 -0
- package/lib/deploy/hosting/convertConfig.js +8 -1
- package/lib/emulator/functionsEmulatorShared.js +6 -11
- package/lib/emulator/storage/files.js +4 -0
- package/lib/emulator/storage/metadata.js +6 -6
- package/lib/extensions/displayExtensionInfo.js +1 -101
- package/lib/extensions/emulator/triggerHelper.js +2 -2
- package/lib/extensions/updateHelper.js +1 -7
- package/lib/functional.js +16 -1
- package/lib/gcp/cloudfunctions.js +21 -8
- package/lib/gcp/cloudfunctionsv2.js +43 -19
- package/lib/gcp/cloudscheduler.js +25 -13
- package/lib/gcp/cloudtasks.js +4 -3
- package/lib/gcp/proto.js +18 -6
- package/lib/gcp/resourceManager.js +25 -3
- package/lib/previews.js +1 -1
- package/lib/rulesDeploy.js +39 -2
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -1,15 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
-
var t = {};
|
|
4
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
-
t[p] = s[p];
|
|
6
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
-
t[p[i]] = s[p[i]];
|
|
10
|
-
}
|
|
11
|
-
return t;
|
|
12
|
-
};
|
|
13
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
3
|
exports.backendFromV1Alpha1 = exports.buildFromV1Alpha1 = void 0;
|
|
15
4
|
const backend = require("../../backend");
|
|
@@ -17,6 +6,7 @@ const build = require("../../build");
|
|
|
17
6
|
const proto_1 = require("../../../../gcp/proto");
|
|
18
7
|
const parsing_1 = require("./parsing");
|
|
19
8
|
const error_1 = require("../../../../error");
|
|
9
|
+
const functional_1 = require("../../../../functional");
|
|
20
10
|
const CHANNEL_NAME_REGEX = new RegExp("(projects\\/" +
|
|
21
11
|
"(?<project>(?:\\d+)|(?:[A-Za-z]+[A-Za-z\\d-]*[A-Za-z\\d]?))\\/)?" +
|
|
22
12
|
"locations\\/" +
|
|
@@ -82,29 +72,30 @@ function assertManifestEndpoint(ep, id) {
|
|
|
82
72
|
region: "array",
|
|
83
73
|
platform: (platform) => backend.AllFunctionsPlatforms.includes(platform),
|
|
84
74
|
entryPoint: "string",
|
|
85
|
-
availableMemoryMb: (mem) => backend.
|
|
86
|
-
maxInstances: "number",
|
|
87
|
-
minInstances: "number",
|
|
88
|
-
concurrency: "number",
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
75
|
+
availableMemoryMb: (mem) => mem === null || backend.isValidMemoryOption(mem),
|
|
76
|
+
maxInstances: "number?",
|
|
77
|
+
minInstances: "number?",
|
|
78
|
+
concurrency: "number?",
|
|
79
|
+
serviceAccount: "string?",
|
|
80
|
+
serviceAccountEmail: "string?",
|
|
81
|
+
timeoutSeconds: "number?",
|
|
82
|
+
vpc: "object?",
|
|
83
|
+
labels: "object?",
|
|
84
|
+
ingressSettings: (setting) => setting === null || backend.AllIngressSettings.includes(setting),
|
|
85
|
+
environmentVariables: "object?",
|
|
86
|
+
secretEnvironmentVariables: "array?",
|
|
96
87
|
httpsTrigger: "object",
|
|
97
88
|
callableTrigger: "object",
|
|
98
89
|
eventTrigger: "object",
|
|
99
90
|
scheduleTrigger: "object",
|
|
100
91
|
taskQueueTrigger: "object",
|
|
101
92
|
blockingTrigger: "object",
|
|
102
|
-
cpu: (cpu) => typeof cpu === "number" || cpu === "gcf_gen1",
|
|
93
|
+
cpu: (cpu) => cpu === null || typeof cpu === "number" || cpu === "gcf_gen1",
|
|
103
94
|
});
|
|
104
95
|
if (ep.vpc) {
|
|
105
96
|
(0, parsing_1.assertKeyTypes)(prefix + ".vpc", ep.vpc, {
|
|
106
97
|
connector: "string",
|
|
107
|
-
egressSettings: (setting) => backend.AllVpcEgressSettings.includes(setting),
|
|
98
|
+
egressSettings: (setting) => setting === null || backend.AllVpcEgressSettings.includes(setting),
|
|
108
99
|
});
|
|
109
100
|
(0, parsing_1.requireKeys)(prefix + ".vpc", ep.vpc, "connector");
|
|
110
101
|
}
|
|
@@ -141,13 +132,14 @@ function assertManifestEndpoint(ep, id) {
|
|
|
141
132
|
eventType: "string",
|
|
142
133
|
retry: "boolean",
|
|
143
134
|
region: "string",
|
|
144
|
-
|
|
135
|
+
serviceAccount: "string?",
|
|
136
|
+
serviceAccountEmail: "string?",
|
|
145
137
|
channel: "string",
|
|
146
138
|
});
|
|
147
139
|
}
|
|
148
140
|
else if (backend.isHttpsTriggered(ep)) {
|
|
149
141
|
(0, parsing_1.assertKeyTypes)(prefix + ".httpsTrigger", ep.httpsTrigger, {
|
|
150
|
-
invoker: "array",
|
|
142
|
+
invoker: "array?",
|
|
151
143
|
});
|
|
152
144
|
}
|
|
153
145
|
else if (backend.isCallableTriggered(ep)) {
|
|
@@ -155,36 +147,39 @@ function assertManifestEndpoint(ep, id) {
|
|
|
155
147
|
else if (backend.isScheduleTriggered(ep)) {
|
|
156
148
|
(0, parsing_1.assertKeyTypes)(prefix + ".scheduleTrigger", ep.scheduleTrigger, {
|
|
157
149
|
schedule: "string",
|
|
158
|
-
timeZone: "string",
|
|
159
|
-
retryConfig: "object",
|
|
150
|
+
timeZone: "string?",
|
|
151
|
+
retryConfig: "object?",
|
|
160
152
|
});
|
|
161
|
-
(0, parsing_1.assertKeyTypes)(prefix + ".scheduleTrigger.retryConfig", ep.scheduleTrigger.retryConfig, {
|
|
162
|
-
retryCount: "number",
|
|
163
|
-
maxDoublings: "number",
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
153
|
+
(0, parsing_1.assertKeyTypes)(prefix + ".scheduleTrigger.retryConfig", ep.scheduleTrigger.retryConfig || {}, {
|
|
154
|
+
retryCount: "number?",
|
|
155
|
+
maxDoublings: "number?",
|
|
156
|
+
minBackoffSeconds: "number?",
|
|
157
|
+
maxBackoffSeconds: "number?",
|
|
158
|
+
maxRetrySeconds: "number?",
|
|
159
|
+
minBackoffDuration: "string?",
|
|
160
|
+
maxBackoffDuration: "string?",
|
|
161
|
+
maxRetryDuration: "string?",
|
|
167
162
|
});
|
|
168
163
|
}
|
|
169
164
|
else if (backend.isTaskQueueTriggered(ep)) {
|
|
170
165
|
(0, parsing_1.assertKeyTypes)(prefix + ".taskQueueTrigger", ep.taskQueueTrigger, {
|
|
171
|
-
rateLimits: "object",
|
|
172
|
-
retryConfig: "object",
|
|
173
|
-
invoker: "array",
|
|
166
|
+
rateLimits: "object?",
|
|
167
|
+
retryConfig: "object?",
|
|
168
|
+
invoker: "array?",
|
|
174
169
|
});
|
|
175
170
|
if (ep.taskQueueTrigger.rateLimits) {
|
|
176
171
|
(0, parsing_1.assertKeyTypes)(prefix + ".taskQueueTrigger.rateLimits", ep.taskQueueTrigger.rateLimits, {
|
|
177
|
-
maxConcurrentDispatches: "number",
|
|
178
|
-
maxDispatchesPerSecond: "number",
|
|
172
|
+
maxConcurrentDispatches: "number?",
|
|
173
|
+
maxDispatchesPerSecond: "number?",
|
|
179
174
|
});
|
|
180
175
|
}
|
|
181
176
|
if (ep.taskQueueTrigger.retryConfig) {
|
|
182
177
|
(0, parsing_1.assertKeyTypes)(prefix + ".taskQueueTrigger.retryConfig", ep.taskQueueTrigger.retryConfig, {
|
|
183
|
-
maxAttempts: "number",
|
|
184
|
-
maxRetrySeconds: "number",
|
|
185
|
-
minBackoffSeconds: "number",
|
|
186
|
-
maxBackoffSeconds: "number",
|
|
187
|
-
maxDoublings: "number",
|
|
178
|
+
maxAttempts: "number?",
|
|
179
|
+
maxRetrySeconds: "number?",
|
|
180
|
+
minBackoffSeconds: "number?",
|
|
181
|
+
maxBackoffSeconds: "number?",
|
|
182
|
+
maxDoublings: "number?",
|
|
188
183
|
});
|
|
189
184
|
}
|
|
190
185
|
}
|
|
@@ -201,18 +196,24 @@ function assertManifestEndpoint(ep, id) {
|
|
|
201
196
|
}
|
|
202
197
|
}
|
|
203
198
|
function parseEndpointForBuild(id, ep, project, defaultRegion, runtime) {
|
|
199
|
+
var _a;
|
|
204
200
|
let triggered;
|
|
205
201
|
if (backend.isEventTriggered(ep)) {
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
(0, proto_1.renameIfPresent)(
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
202
|
+
const eventTrigger = {
|
|
203
|
+
eventType: ep.eventTrigger.eventType,
|
|
204
|
+
retry: ep.eventTrigger.retry,
|
|
205
|
+
};
|
|
206
|
+
(0, proto_1.renameIfPresent)(eventTrigger, ep.eventTrigger, "serviceAccount", "serviceAccountEmail");
|
|
207
|
+
(0, proto_1.copyIfPresent)(eventTrigger, ep.eventTrigger, "serviceAccount", "eventFilterPathPatterns", "region");
|
|
208
|
+
(0, proto_1.convertIfPresent)(eventTrigger, ep.eventTrigger, "channel", (c) => resolveChannelName(project, c, defaultRegion));
|
|
209
|
+
(0, proto_1.convertIfPresent)(eventTrigger, ep.eventTrigger, "eventFilters", (filters) => {
|
|
210
|
+
const copy = Object.assign({}, filters);
|
|
211
|
+
if (copy["topic"] && !copy["topic"].startsWith("projects/")) {
|
|
212
|
+
copy["topic"] = `projects/${project}/topics/${copy["topic"]}`;
|
|
214
213
|
}
|
|
215
|
-
|
|
214
|
+
return copy;
|
|
215
|
+
});
|
|
216
|
+
triggered = { eventTrigger };
|
|
216
217
|
}
|
|
217
218
|
else if (backend.isHttpsTriggered(ep)) {
|
|
218
219
|
triggered = { httpsTrigger: {} };
|
|
@@ -224,39 +225,39 @@ function parseEndpointForBuild(id, ep, project, defaultRegion, runtime) {
|
|
|
224
225
|
else if (backend.isScheduleTriggered(ep)) {
|
|
225
226
|
const st = {
|
|
226
227
|
schedule: ep.scheduleTrigger.schedule || "",
|
|
227
|
-
timeZone: ep.scheduleTrigger.timeZone
|
|
228
|
-
retryConfig: {},
|
|
228
|
+
timeZone: (_a = ep.scheduleTrigger.timeZone) !== null && _a !== void 0 ? _a : null,
|
|
229
229
|
};
|
|
230
230
|
if (ep.scheduleTrigger.retryConfig) {
|
|
231
|
-
st.retryConfig = {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
st.retryConfig.maxBackoffSeconds = (0, proto_1.secondsFromDuration)(ep.scheduleTrigger.retryConfig.maxBackoffDuration);
|
|
240
|
-
}
|
|
241
|
-
if (ep.scheduleTrigger.retryConfig.minBackoffDuration) {
|
|
242
|
-
st.retryConfig.minBackoffSeconds = (0, proto_1.secondsFromDuration)(ep.scheduleTrigger.retryConfig.minBackoffDuration);
|
|
243
|
-
}
|
|
231
|
+
st.retryConfig = {};
|
|
232
|
+
(0, proto_1.copyIfPresent)(st.retryConfig, ep.scheduleTrigger.retryConfig, "retryCount", "minBackoffSeconds", "maxBackoffSeconds", "maxRetrySeconds", "maxDoublings");
|
|
233
|
+
(0, proto_1.convertIfPresent)(st.retryConfig, ep.scheduleTrigger.retryConfig, "minBackoffSeconds", "minBackoffDuration", (0, functional_1.nullsafeVisitor)(proto_1.secondsFromDuration));
|
|
234
|
+
(0, proto_1.convertIfPresent)(st.retryConfig, ep.scheduleTrigger.retryConfig, "maxBackoffSeconds", "maxBackoffDuration", (0, functional_1.nullsafeVisitor)(proto_1.secondsFromDuration));
|
|
235
|
+
(0, proto_1.convertIfPresent)(st.retryConfig, ep.scheduleTrigger.retryConfig, "maxRetrySeconds", "maxRetryDuration", (0, functional_1.nullsafeVisitor)(proto_1.secondsFromDuration));
|
|
236
|
+
}
|
|
237
|
+
else if (ep.scheduleTrigger.retryConfig === null) {
|
|
238
|
+
st.retryConfig = null;
|
|
244
239
|
}
|
|
245
240
|
triggered = { scheduleTrigger: st };
|
|
246
241
|
}
|
|
247
242
|
else if (backend.isTaskQueueTriggered(ep)) {
|
|
248
|
-
const tq = {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
}
|
|
243
|
+
const tq = {};
|
|
244
|
+
if (ep.taskQueueTrigger.invoker) {
|
|
245
|
+
tq.invoker = ep.taskQueueTrigger.invoker;
|
|
246
|
+
}
|
|
247
|
+
else if (ep.taskQueueTrigger.invoker === null) {
|
|
248
|
+
tq.invoker = null;
|
|
249
|
+
}
|
|
252
250
|
if (ep.taskQueueTrigger.retryConfig) {
|
|
253
|
-
tq.retryConfig = {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
};
|
|
251
|
+
tq.retryConfig = Object.assign({}, ep.taskQueueTrigger.retryConfig);
|
|
252
|
+
}
|
|
253
|
+
else if (ep.taskQueueTrigger.retryConfig === null) {
|
|
254
|
+
tq.retryConfig = null;
|
|
255
|
+
}
|
|
256
|
+
if (ep.taskQueueTrigger.rateLimits) {
|
|
257
|
+
tq.rateLimits = Object.assign({}, ep.taskQueueTrigger.rateLimits);
|
|
258
|
+
}
|
|
259
|
+
else if (ep.taskQueueTrigger.rateLimits === null) {
|
|
260
|
+
tq.rateLimits = null;
|
|
260
261
|
}
|
|
261
262
|
triggered = { taskQueueTrigger: tq };
|
|
262
263
|
}
|
|
@@ -268,18 +269,16 @@ function parseEndpointForBuild(id, ep, project, defaultRegion, runtime) {
|
|
|
268
269
|
"firebase-tools with npm install -g firebase-tools@latest");
|
|
269
270
|
}
|
|
270
271
|
const parsed = Object.assign({ platform: ep.platform || "gcfv2", region: ep.region || [defaultRegion], project,
|
|
271
|
-
runtime, entryPoint: ep.entryPoint
|
|
272
|
-
(0, proto_1.
|
|
273
|
-
(0, proto_1.
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
key,
|
|
278
|
-
secret: secret || key,
|
|
279
|
-
projectId: project,
|
|
280
|
-
});
|
|
272
|
+
runtime, entryPoint: ep.entryPoint }, triggered);
|
|
273
|
+
(0, proto_1.renameIfPresent)(parsed, ep, "serviceAccount", "serviceAccountEmail");
|
|
274
|
+
(0, proto_1.copyIfPresent)(parsed, ep, "availableMemoryMb", "cpu", "maxInstances", "minInstances", "concurrency", "timeoutSeconds", "vpc", "labels", "ingressSettings", "environmentVariables", "serviceAccount");
|
|
275
|
+
(0, proto_1.convertIfPresent)(parsed, ep, "secretEnvironmentVariables", (senvs) => {
|
|
276
|
+
if (!senvs) {
|
|
277
|
+
return null;
|
|
281
278
|
}
|
|
282
|
-
return
|
|
279
|
+
return senvs.map(({ key, secret }) => {
|
|
280
|
+
return { key, secret: secret || key, projectId: project };
|
|
281
|
+
});
|
|
283
282
|
});
|
|
284
283
|
return parsed;
|
|
285
284
|
}
|
|
@@ -287,17 +286,25 @@ function parseEndpoints(manifest, id, project, defaultRegion, runtime) {
|
|
|
287
286
|
const allParsed = [];
|
|
288
287
|
const prefix = `endpoints[${id}]`;
|
|
289
288
|
const ep = manifest.endpoints[id];
|
|
290
|
-
assertManifestEndpoint(ep,
|
|
289
|
+
assertManifestEndpoint(ep, id);
|
|
291
290
|
for (const region of ep.region || [defaultRegion]) {
|
|
292
291
|
let triggered;
|
|
293
292
|
if (backend.isEventTriggered(ep)) {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
293
|
+
const eventTrigger = {
|
|
294
|
+
eventType: ep.eventTrigger.eventType,
|
|
295
|
+
retry: false,
|
|
296
|
+
};
|
|
297
|
+
(0, proto_1.renameIfPresent)(eventTrigger, ep.eventTrigger, "serviceAccount", "serviceAccountEmail");
|
|
298
|
+
(0, proto_1.copyIfPresent)(eventTrigger, ep.eventTrigger, "eventFilterPathPatterns", "retry", "serviceAccount", "region");
|
|
299
|
+
(0, proto_1.convertIfPresent)(eventTrigger, ep.eventTrigger, "channel", (c) => resolveChannelName(project, c, defaultRegion));
|
|
300
|
+
(0, proto_1.convertIfPresent)(eventTrigger, ep.eventTrigger, "eventFilters", (filters) => {
|
|
301
|
+
const copy = Object.assign({}, filters);
|
|
302
|
+
if (copy["topic"] && !copy["topic"].startsWith("projects/")) {
|
|
303
|
+
copy["topic"] = `projects/${project}/topics/${copy["topic"]}`;
|
|
299
304
|
}
|
|
300
|
-
|
|
305
|
+
return copy;
|
|
306
|
+
});
|
|
307
|
+
triggered = { eventTrigger };
|
|
301
308
|
}
|
|
302
309
|
else if (backend.isHttpsTriggered(ep)) {
|
|
303
310
|
triggered = { httpsTrigger: {} };
|
|
@@ -324,17 +331,15 @@ function parseEndpoints(manifest, id, project, defaultRegion, runtime) {
|
|
|
324
331
|
region,
|
|
325
332
|
project,
|
|
326
333
|
runtime, entryPoint: ep.entryPoint }, triggered);
|
|
327
|
-
(0, proto_1.
|
|
328
|
-
(0, proto_1.
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
key,
|
|
333
|
-
secret: secret || key,
|
|
334
|
-
projectId: project,
|
|
335
|
-
});
|
|
334
|
+
(0, proto_1.renameIfPresent)(parsed, ep, "serviceAccount", "serviceAccountEmail");
|
|
335
|
+
(0, proto_1.copyIfPresent)(parsed, ep, "availableMemoryMb", "maxInstances", "minInstances", "concurrency", "serviceAccount", "timeoutSeconds", "vpc", "labels", "ingressSettings", "environmentVariables", "cpu");
|
|
336
|
+
(0, proto_1.convertIfPresent)(parsed, ep, "secretEnvironmentVariables", (senvs) => {
|
|
337
|
+
if (!senvs) {
|
|
338
|
+
return null;
|
|
336
339
|
}
|
|
337
|
-
return
|
|
340
|
+
return senvs.map(({ key, secret }) => {
|
|
341
|
+
return { key, secret: secret || key, projectId: project };
|
|
342
|
+
});
|
|
338
343
|
});
|
|
339
344
|
allParsed.push(parsed);
|
|
340
345
|
}
|
|
@@ -10,6 +10,7 @@ const backend = require("../../backend");
|
|
|
10
10
|
const api = require("../../../../api");
|
|
11
11
|
const proto = require("../../../../gcp/proto");
|
|
12
12
|
const events = require("../../../../functions/events");
|
|
13
|
+
const functional_1 = require("../../../../functional");
|
|
13
14
|
const TRIGGER_PARSER = path.resolve(__dirname, "./triggerParser.js");
|
|
14
15
|
function removeInspectOptions(options) {
|
|
15
16
|
return options.filter((opt) => !opt.startsWith("--inspect"));
|
|
@@ -88,8 +89,9 @@ function mergeRequiredAPIs(backend) {
|
|
|
88
89
|
}
|
|
89
90
|
exports.mergeRequiredAPIs = mergeRequiredAPIs;
|
|
90
91
|
function addResourcesToBuild(projectId, runtime, annotation, want) {
|
|
91
|
-
var _a;
|
|
92
|
+
var _a, _b;
|
|
92
93
|
Object.freeze(annotation);
|
|
94
|
+
const toSeconds = (0, functional_1.nullsafeVisitor)(proto.secondsFromDuration);
|
|
93
95
|
const regions = annotation.regions || [api.functionsDefaultRegion];
|
|
94
96
|
let triggered;
|
|
95
97
|
const triggerCount = +!!annotation.httpsTrigger +
|
|
@@ -110,9 +112,11 @@ function addResourcesToBuild(projectId, runtime, annotation, want) {
|
|
|
110
112
|
proto.copyIfPresent(triggered.taskQueueTrigger, annotation.taskQueueTrigger, "invoker");
|
|
111
113
|
proto.copyIfPresent(triggered.taskQueueTrigger, annotation.taskQueueTrigger, "rateLimits");
|
|
112
114
|
if (annotation.taskQueueTrigger.retryConfig) {
|
|
113
|
-
triggered.taskQueueTrigger.retryConfig =
|
|
114
|
-
|
|
115
|
-
|
|
115
|
+
triggered.taskQueueTrigger.retryConfig = {};
|
|
116
|
+
proto.copyIfPresent(triggered.taskQueueTrigger.retryConfig, annotation.taskQueueTrigger.retryConfig, "maxAttempts", "maxDoublings");
|
|
117
|
+
proto.convertIfPresent(triggered.taskQueueTrigger.retryConfig, annotation.taskQueueTrigger.retryConfig, "minBackoffSeconds", "minBackoff", toSeconds);
|
|
118
|
+
proto.convertIfPresent(triggered.taskQueueTrigger.retryConfig, annotation.taskQueueTrigger.retryConfig, "maxBackoffSeconds", "maxBackoff", toSeconds);
|
|
119
|
+
proto.convertIfPresent(triggered.taskQueueTrigger.retryConfig, annotation.taskQueueTrigger.retryConfig, "maxRetryDurationSeconds", "maxRetryDuration", toSeconds);
|
|
116
120
|
}
|
|
117
121
|
}
|
|
118
122
|
else if (annotation.httpsTrigger) {
|
|
@@ -139,21 +143,16 @@ function addResourcesToBuild(projectId, runtime, annotation, want) {
|
|
|
139
143
|
triggered = {
|
|
140
144
|
scheduleTrigger: {
|
|
141
145
|
schedule: annotation.schedule.schedule,
|
|
142
|
-
timeZone: annotation.schedule.timeZone
|
|
146
|
+
timeZone: (_b = annotation.schedule.timeZone) !== null && _b !== void 0 ? _b : null,
|
|
143
147
|
retryConfig: {},
|
|
144
148
|
},
|
|
145
149
|
};
|
|
146
150
|
if (annotation.schedule.retryConfig) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
if (annotation.schedule.retryConfig.maxRetryDuration) {
|
|
154
|
-
triggered.scheduleTrigger.retryConfig.maxRetrySeconds = proto.secondsFromDuration(annotation.schedule.retryConfig.maxRetryDuration);
|
|
155
|
-
}
|
|
156
|
-
proto.copyIfPresent(triggered.scheduleTrigger.retryConfig, annotation.schedule.retryConfig, "maxDoublings", "retryCount");
|
|
151
|
+
triggered.scheduleTrigger.retryConfig = {};
|
|
152
|
+
proto.copyIfPresent(triggered.scheduleTrigger.retryConfig, annotation.schedule.retryConfig, "retryCount", "maxDoublings");
|
|
153
|
+
proto.convertIfPresent(triggered.scheduleTrigger.retryConfig, annotation.schedule.retryConfig, "maxRetrySeconds", "maxRetryDuration", toSeconds);
|
|
154
|
+
proto.convertIfPresent(triggered.scheduleTrigger.retryConfig, annotation.schedule.retryConfig, "minBackoffSeconds", "minBackoffDuration", toSeconds);
|
|
155
|
+
proto.convertIfPresent(triggered.scheduleTrigger.retryConfig, annotation.schedule.retryConfig, "maxBackoffSeconds", "maxBackoffDuration", toSeconds);
|
|
157
156
|
}
|
|
158
157
|
}
|
|
159
158
|
else if (annotation.blockingTrigger) {
|
|
@@ -169,7 +168,7 @@ function addResourcesToBuild(projectId, runtime, annotation, want) {
|
|
|
169
168
|
},
|
|
170
169
|
};
|
|
171
170
|
}
|
|
172
|
-
else {
|
|
171
|
+
else if (annotation.eventTrigger) {
|
|
173
172
|
triggered = {
|
|
174
173
|
eventTrigger: {
|
|
175
174
|
eventType: annotation.eventTrigger.eventType,
|
|
@@ -178,8 +177,13 @@ function addResourcesToBuild(projectId, runtime, annotation, want) {
|
|
|
178
177
|
},
|
|
179
178
|
};
|
|
180
179
|
}
|
|
180
|
+
else {
|
|
181
|
+
throw new error_1.FirebaseError("Do not understand Cloud Function annotation without a trigger" +
|
|
182
|
+
JSON.stringify(annotation, null, 2));
|
|
183
|
+
}
|
|
181
184
|
const endpointId = annotation.name;
|
|
182
|
-
const endpoint = Object.assign({ platform: annotation.platform || "gcfv1", region: regions, project: projectId, entryPoint: annotation.entryPoint, runtime: runtime
|
|
185
|
+
const endpoint = Object.assign({ platform: annotation.platform || "gcfv1", region: regions, project: projectId, entryPoint: annotation.entryPoint, runtime: runtime }, triggered);
|
|
186
|
+
proto.renameIfPresent(endpoint, annotation, "serviceAccount", "serviceAccountEmail");
|
|
183
187
|
if (annotation.vpcConnector != null) {
|
|
184
188
|
let maybeId = annotation.vpcConnector;
|
|
185
189
|
if (maybeId && !maybeId.includes("/")) {
|
|
@@ -188,8 +192,17 @@ function addResourcesToBuild(projectId, runtime, annotation, want) {
|
|
|
188
192
|
endpoint.vpc = { connector: maybeId };
|
|
189
193
|
proto.renameIfPresent(endpoint.vpc, annotation, "egressSettings", "vpcConnectorEgressSettings");
|
|
190
194
|
}
|
|
191
|
-
proto.copyIfPresent(endpoint, annotation, "concurrency", "labels", "
|
|
192
|
-
proto.
|
|
195
|
+
proto.copyIfPresent(endpoint, annotation, "concurrency", "labels", "maxInstances", "minInstances", "availableMemoryMb");
|
|
196
|
+
proto.convertIfPresent(endpoint, annotation, "ingressSettings", (str) => {
|
|
197
|
+
if (str === null) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
if (!backend.AllIngressSettings.includes(str)) {
|
|
201
|
+
throw new Error(`Invalid ingress setting ${str}`);
|
|
202
|
+
}
|
|
203
|
+
return str;
|
|
204
|
+
});
|
|
205
|
+
proto.convertIfPresent(endpoint, annotation, "timeoutSeconds", "timeout", proto.secondsFromDuration);
|
|
193
206
|
want.endpoints[endpointId] = endpoint;
|
|
194
207
|
}
|
|
195
208
|
exports.addResourcesToBuild = addResourcesToBuild;
|
|
@@ -285,8 +298,27 @@ function addResourcesToBackend(projectId, runtime, annotation, want) {
|
|
|
285
298
|
}
|
|
286
299
|
endpoint.secretEnvironmentVariables = secretEnvs;
|
|
287
300
|
}
|
|
288
|
-
proto.copyIfPresent(endpoint, annotation, "concurrency", "
|
|
289
|
-
proto.renameIfPresent(endpoint, annotation, "
|
|
301
|
+
proto.copyIfPresent(endpoint, annotation, "concurrency", "labels", "maxInstances", "minInstances");
|
|
302
|
+
proto.renameIfPresent(endpoint, annotation, "serviceAccount", "serviceAccountEmail");
|
|
303
|
+
proto.convertIfPresent(endpoint, annotation, "ingressSettings", (ingress) => {
|
|
304
|
+
if (ingress == null) {
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
if (!backend.AllIngressSettings.includes(ingress)) {
|
|
308
|
+
throw new error_1.FirebaseError(`Invalid ingress setting ${ingress}`);
|
|
309
|
+
}
|
|
310
|
+
return ingress;
|
|
311
|
+
});
|
|
312
|
+
proto.convertIfPresent(endpoint, annotation, "availableMemoryMb", (mem) => {
|
|
313
|
+
if (mem === null) {
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
if (!backend.isValidMemoryOption(mem)) {
|
|
317
|
+
throw new error_1.FirebaseError(`This version of firebase-tools does not know about the memory option ${mem}. Is an upgrade necessary?`);
|
|
318
|
+
}
|
|
319
|
+
return mem;
|
|
320
|
+
});
|
|
321
|
+
proto.convertIfPresent(endpoint, annotation, "timeoutSeconds", "timeout", proto.secondsFromDuration);
|
|
290
322
|
want.endpoints[region] = want.endpoints[region] || {};
|
|
291
323
|
want.endpoints[region][endpoint.id] = endpoint;
|
|
292
324
|
mergeRequiredAPIs(want);
|
|
@@ -17,8 +17,14 @@ async function obtainStorageBindings(projectNumber) {
|
|
|
17
17
|
}
|
|
18
18
|
exports.obtainStorageBindings = obtainStorageBindings;
|
|
19
19
|
async function ensureStorageTriggerRegion(endpoint) {
|
|
20
|
+
var _a;
|
|
20
21
|
const { eventTrigger } = endpoint;
|
|
21
22
|
if (!eventTrigger.region) {
|
|
23
|
+
logger_1.logger.debug("Looking up bucket region for the storage event trigger");
|
|
24
|
+
if (!((_a = eventTrigger.eventFilters) === null || _a === void 0 ? void 0 : _a.bucket)) {
|
|
25
|
+
throw new error_1.FirebaseError("Error: storage event trigger is missing bucket filter: " +
|
|
26
|
+
JSON.stringify(eventTrigger, null, 2));
|
|
27
|
+
}
|
|
22
28
|
logger_1.logger.debug(`Looking up bucket region for the storage event trigger on bucket ${eventTrigger.eventFilters.bucket}`);
|
|
23
29
|
try {
|
|
24
30
|
const bucket = await storage.getBucket(eventTrigger.eventFilters.bucket);
|
|
@@ -50,11 +50,18 @@ async function convertConfig(context, payload, config, finalize) {
|
|
|
50
50
|
(!functionsEndpointInfo.platform || endpoint.platform === functionsEndpointInfo.platform));
|
|
51
51
|
});
|
|
52
52
|
if (matchingBackends.length > 1) {
|
|
53
|
+
for (const endpoint of matchingBackends) {
|
|
54
|
+
if (endpoint.region === "us-central1") {
|
|
55
|
+
(0, utils_1.logLabeledBullet)(`hosting[${config.site}]`, `Function \`${functionsEndpointInfo.serviceId}\` found in multiple regions, defaulting to \`us-central1\`. ` +
|
|
56
|
+
`To rewrite to a different region, specify a \`region\` for the rewrite in \`firebase.json\`.`);
|
|
57
|
+
return endpoint;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
53
60
|
throw new error_1.FirebaseError(`More than one backend found for function name: ${functionsEndpointInfo.serviceId}. If the function is deployed in multiple regions, you must specify a region.`);
|
|
54
61
|
}
|
|
55
62
|
if (matchingBackends.length === 1) {
|
|
56
63
|
const endpoint = matchingBackends[0];
|
|
57
|
-
if (endpoint && (0, backend_1.isHttpsTriggered)(endpoint)) {
|
|
64
|
+
if (endpoint && ((0, backend_1.isHttpsTriggered)(endpoint) || (0, backend_1.isCallableTriggered)(endpoint))) {
|
|
58
65
|
return endpoint;
|
|
59
66
|
}
|
|
60
67
|
}
|
|
@@ -8,20 +8,11 @@ const crypto_1 = require("crypto");
|
|
|
8
8
|
const _ = require("lodash");
|
|
9
9
|
const backend = require("../deploy/functions/backend");
|
|
10
10
|
const constants_1 = require("./constants");
|
|
11
|
-
const proto_1 = require("../gcp/proto");
|
|
12
11
|
const manifest_1 = require("../extensions/manifest");
|
|
13
12
|
const extensionsHelper_1 = require("../extensions/extensionsHelper");
|
|
14
13
|
const postinstall_1 = require("./extensions/postinstall");
|
|
15
14
|
const services_1 = require("../deploy/functions/services");
|
|
16
15
|
const prepare_1 = require("../deploy/functions/prepare");
|
|
17
|
-
const memoryLookup = {
|
|
18
|
-
"128MB": 128,
|
|
19
|
-
"256MB": 256,
|
|
20
|
-
"512MB": 512,
|
|
21
|
-
"1GB": 1024,
|
|
22
|
-
"2GB": 2048,
|
|
23
|
-
"4GB": 4096,
|
|
24
|
-
};
|
|
25
16
|
class HttpConstants {
|
|
26
17
|
}
|
|
27
18
|
exports.HttpConstants = HttpConstants;
|
|
@@ -33,7 +24,7 @@ class EmulatedTrigger {
|
|
|
33
24
|
this.module = module;
|
|
34
25
|
}
|
|
35
26
|
get memoryLimitBytes() {
|
|
36
|
-
return
|
|
27
|
+
return (this.definition.availableMemoryMb || 128) * 1024 * 1024;
|
|
37
28
|
}
|
|
38
29
|
get timeoutMs() {
|
|
39
30
|
return (this.definition.timeoutSeconds || 60) * 1000;
|
|
@@ -69,7 +60,11 @@ function emulatedFunctionsFromEndpoints(endpoints) {
|
|
|
69
60
|
id: `${endpoint.region}-${endpoint.id}`,
|
|
70
61
|
codebase: endpoint.codebase,
|
|
71
62
|
};
|
|
72
|
-
|
|
63
|
+
def.availableMemoryMb = endpoint.availableMemoryMb || 256;
|
|
64
|
+
def.labels = endpoint.labels || {};
|
|
65
|
+
def.timeoutSeconds = endpoint.timeoutSeconds || 60;
|
|
66
|
+
def.secretEnvironmentVariables = endpoint.secretEnvironmentVariables || [];
|
|
67
|
+
def.platform = endpoint.platform;
|
|
73
68
|
if (backend.isHttpsTriggered(endpoint)) {
|
|
74
69
|
def.httpsTrigger = endpoint.httpsTrigger;
|
|
75
70
|
}
|
|
@@ -327,6 +327,10 @@ class StorageLayer {
|
|
|
327
327
|
}
|
|
328
328
|
const metadataDir = path.join(storageExportPath, "metadata");
|
|
329
329
|
const blobsDir = path.join(storageExportPath, "blobs");
|
|
330
|
+
if (!(0, fs_1.existsSync)(metadataDir) || !(0, fs_1.existsSync)(blobsDir)) {
|
|
331
|
+
logger_1.logger.warn(`Could not find metadata directory at "${metadataDir}" and/or blobs directory at "${blobsDir}".`);
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
330
334
|
const metadataList = this.walkDirSync(metadataDir);
|
|
331
335
|
const dotJson = ".json";
|
|
332
336
|
for (const f of metadataList) {
|
|
@@ -287,15 +287,15 @@ class CloudStorageObjectMetadata {
|
|
|
287
287
|
}
|
|
288
288
|
exports.CloudStorageObjectMetadata = CloudStorageObjectMetadata;
|
|
289
289
|
function toSerializedDate(d) {
|
|
290
|
-
const day = `${d.
|
|
291
|
-
.
|
|
290
|
+
const day = `${d.getUTCFullYear()}-${(d.getUTCMonth() + 1).toString().padStart(2, "0")}-${d
|
|
291
|
+
.getUTCDate()
|
|
292
292
|
.toString()
|
|
293
293
|
.padStart(2, "0")}`;
|
|
294
|
-
const time = `${d.
|
|
295
|
-
.
|
|
294
|
+
const time = `${d.getUTCHours().toString().padStart(2, "0")}:${d
|
|
295
|
+
.getUTCMinutes()
|
|
296
296
|
.toString()
|
|
297
|
-
.padStart(2, "0")}:${d.
|
|
298
|
-
.
|
|
297
|
+
.padStart(2, "0")}:${d.getUTCSeconds().toString().padStart(2, "0")}.${d
|
|
298
|
+
.getUTCMilliseconds()
|
|
299
299
|
.toString()
|
|
300
300
|
.padStart(3, "0")}`;
|
|
301
301
|
return `${day}T${time}Z`;
|