firebase-tools 11.5.0 → 11.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/command.js +33 -7
- package/lib/commands/crashlytics-mappingfile-generateid.js +26 -0
- package/lib/commands/crashlytics-mappingfile-upload.js +46 -0
- package/lib/commands/crashlytics-symbols-upload.js +18 -87
- package/lib/commands/emulators-exec.js +4 -1
- package/lib/commands/emulators-export.js +5 -2
- package/lib/commands/emulators-start.js +23 -17
- package/lib/commands/ext-dev-publish.js +3 -0
- package/lib/commands/functions-delete.js +2 -0
- package/lib/commands/functions-secrets-get.js +2 -0
- package/lib/commands/index.js +3 -0
- package/lib/commands/login.js +2 -2
- package/lib/crashlytics/buildToolsJarHelper.js +51 -0
- package/lib/deploy/functions/backend.js +4 -4
- package/lib/deploy/functions/build.js +76 -9
- package/lib/deploy/functions/checkIam.js +6 -5
- package/lib/deploy/functions/params.js +22 -16
- package/lib/deploy/functions/prepare.js +1 -1
- package/lib/deploy/functions/release/fabricator.js +22 -5
- package/lib/deploy/functions/release/index.js +2 -0
- package/lib/deploy/functions/runtimes/discovery/index.js +1 -16
- package/lib/deploy/functions/runtimes/discovery/parsing.js +16 -0
- package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +59 -131
- package/lib/deploy/functions/runtimes/node/parseTriggers.js +1 -1
- package/lib/emulator/auth/index.js +7 -2
- package/lib/emulator/auth/operations.js +10 -10
- package/lib/emulator/commandUtils.js +32 -15
- package/lib/emulator/constants.js +14 -6
- package/lib/emulator/controller.js +49 -17
- package/lib/emulator/downloadableEmulators.js +7 -7
- package/lib/emulator/eventarcEmulator.js +148 -0
- package/lib/emulator/extensionsEmulator.js +3 -1
- package/lib/emulator/functionsEmulator.js +44 -4
- package/lib/emulator/functionsEmulatorRuntime.js +12 -23
- package/lib/emulator/functionsEmulatorShared.js +6 -1
- package/lib/emulator/hub.js +7 -3
- package/lib/emulator/hubClient.js +2 -2
- package/lib/emulator/hubExport.js +22 -2
- package/lib/emulator/registry.js +1 -0
- package/lib/emulator/storage/apis/firebase.js +145 -129
- package/lib/emulator/storage/apis/gcloud.js +102 -42
- package/lib/emulator/storage/files.js +39 -17
- package/lib/emulator/storage/metadata.js +76 -55
- package/lib/emulator/storage/multipart.js +2 -2
- package/lib/emulator/storage/rules/runtime.js +12 -4
- package/lib/emulator/storage/server.js +2 -1
- package/lib/emulator/storage/upload.js +46 -9
- package/lib/emulator/types.js +3 -0
- package/lib/emulator/ui.js +7 -2
- package/lib/extensions/extensionsApi.js +2 -1
- package/lib/extensions/extensionsHelper.js +29 -1
- package/lib/functions/constants.js +14 -0
- package/lib/functions/env.js +9 -9
- package/lib/gcp/cloudfunctions.js +15 -18
- package/lib/gcp/cloudfunctionsv2.js +15 -18
- package/lib/gcp/cloudscheduler.js +32 -14
- package/lib/serve/index.js +15 -0
- package/lib/track.js +122 -3
- package/lib/utils.js +14 -1
- package/npm-shrinkwrap.json +542 -9
- package/package.json +5 -4
- package/schema/firebase-config.json +12 -0
- package/templates/extensions/CHANGELOG.md +1 -7
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toBackend = exports.resolveBackend = exports.of = exports.empty = void 0;
|
|
3
|
+
exports.toBackend = exports.resolveBackend = exports.AllIngressSettings = exports.AllVpcEgressSettings = exports.AllFunctionsPlatforms = exports.isValidMemoryOption = exports.isBlockingTriggered = exports.isTaskQueueTriggered = exports.isScheduleTriggered = exports.isEventTriggered = exports.isCallableTriggered = exports.isHttpsTriggered = exports.of = exports.empty = void 0;
|
|
4
4
|
const backend = require("./backend");
|
|
5
5
|
const proto = require("../../gcp/proto");
|
|
6
6
|
const api = require("../../.../../api");
|
|
@@ -8,6 +8,7 @@ const params = require("./params");
|
|
|
8
8
|
const previews_1 = require("../../previews");
|
|
9
9
|
const error_1 = require("../../error");
|
|
10
10
|
const functional_1 = require("../../functional");
|
|
11
|
+
const env_1 = require("../../functions/env");
|
|
11
12
|
const logger_1 = require("../../logger");
|
|
12
13
|
function empty() {
|
|
13
14
|
return {
|
|
@@ -23,15 +24,79 @@ function of(endpoints) {
|
|
|
23
24
|
return build;
|
|
24
25
|
}
|
|
25
26
|
exports.of = of;
|
|
26
|
-
|
|
27
|
+
function isHttpsTriggered(triggered) {
|
|
28
|
+
return {}.hasOwnProperty.call(triggered, "httpsTrigger");
|
|
29
|
+
}
|
|
30
|
+
exports.isHttpsTriggered = isHttpsTriggered;
|
|
31
|
+
function isCallableTriggered(triggered) {
|
|
32
|
+
return {}.hasOwnProperty.call(triggered, "callableTrigger");
|
|
33
|
+
}
|
|
34
|
+
exports.isCallableTriggered = isCallableTriggered;
|
|
35
|
+
function isEventTriggered(triggered) {
|
|
36
|
+
return {}.hasOwnProperty.call(triggered, "eventTrigger");
|
|
37
|
+
}
|
|
38
|
+
exports.isEventTriggered = isEventTriggered;
|
|
39
|
+
function isScheduleTriggered(triggered) {
|
|
40
|
+
return {}.hasOwnProperty.call(triggered, "scheduleTrigger");
|
|
41
|
+
}
|
|
42
|
+
exports.isScheduleTriggered = isScheduleTriggered;
|
|
43
|
+
function isTaskQueueTriggered(triggered) {
|
|
44
|
+
return {}.hasOwnProperty.call(triggered, "taskQueueTrigger");
|
|
45
|
+
}
|
|
46
|
+
exports.isTaskQueueTriggered = isTaskQueueTriggered;
|
|
47
|
+
function isBlockingTriggered(triggered) {
|
|
48
|
+
return {}.hasOwnProperty.call(triggered, "blockingTrigger");
|
|
49
|
+
}
|
|
50
|
+
exports.isBlockingTriggered = isBlockingTriggered;
|
|
51
|
+
const allMemoryOptions = [128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768];
|
|
52
|
+
function isValidMemoryOption(mem) {
|
|
53
|
+
return allMemoryOptions.includes(mem);
|
|
54
|
+
}
|
|
55
|
+
exports.isValidMemoryOption = isValidMemoryOption;
|
|
56
|
+
exports.AllFunctionsPlatforms = ["gcfv1", "gcfv2"];
|
|
57
|
+
exports.AllVpcEgressSettings = ["PRIVATE_RANGES_ONLY", "ALL_TRAFFIC"];
|
|
58
|
+
exports.AllIngressSettings = [
|
|
59
|
+
"ALLOW_ALL",
|
|
60
|
+
"ALLOW_INTERNAL_ONLY",
|
|
61
|
+
"ALLOW_INTERNAL_AND_GCLB",
|
|
62
|
+
];
|
|
63
|
+
async function resolveBackend(build, userEnvOpt, userEnvs, nonInteractive) {
|
|
64
|
+
var _a;
|
|
27
65
|
const projectId = userEnvOpt.projectId;
|
|
28
66
|
let paramValues = {};
|
|
29
67
|
if (previews_1.previews.functionsparams) {
|
|
30
|
-
paramValues = await params.resolveParams(build.params, projectId, userEnvs);
|
|
68
|
+
paramValues = await params.resolveParams(build.params, projectId, envWithTypes(userEnvs), nonInteractive);
|
|
69
|
+
const toWrite = {};
|
|
70
|
+
for (const paramName of Object.keys(paramValues)) {
|
|
71
|
+
if (userEnvs.hasOwnProperty(paramName)) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
toWrite[paramName] = ((_a = paramValues[paramName]) === null || _a === void 0 ? void 0 : _a.toString()) || "";
|
|
75
|
+
}
|
|
76
|
+
(0, env_1.writeUserEnvs)(toWrite, userEnvOpt);
|
|
31
77
|
}
|
|
32
78
|
return toBackend(build, paramValues);
|
|
33
79
|
}
|
|
34
80
|
exports.resolveBackend = resolveBackend;
|
|
81
|
+
function envWithTypes(rawEnvs) {
|
|
82
|
+
const out = {};
|
|
83
|
+
for (const envName of Object.keys(rawEnvs)) {
|
|
84
|
+
const value = rawEnvs[envName];
|
|
85
|
+
if (!isNaN(+value) && isFinite(+value) && !value.includes("e")) {
|
|
86
|
+
out[envName] = +value;
|
|
87
|
+
}
|
|
88
|
+
else if (value === "true") {
|
|
89
|
+
out[envName] = true;
|
|
90
|
+
}
|
|
91
|
+
else if (value === "false") {
|
|
92
|
+
out[envName] = false;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
out[envName] = value;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
35
100
|
class Resolver {
|
|
36
101
|
constructor(paramValues) {
|
|
37
102
|
this.paramValues = paramValues;
|
|
@@ -127,7 +192,7 @@ function toBackend(build, paramValues) {
|
|
|
127
192
|
}
|
|
128
193
|
exports.toBackend = toBackend;
|
|
129
194
|
function discoverTrigger(endpoint, region, r) {
|
|
130
|
-
if (
|
|
195
|
+
if (isHttpsTriggered(endpoint)) {
|
|
131
196
|
const httpsTrigger = {};
|
|
132
197
|
if (endpoint.httpsTrigger.invoker === null) {
|
|
133
198
|
httpsTrigger.invoker = null;
|
|
@@ -137,13 +202,13 @@ function discoverTrigger(endpoint, region, r) {
|
|
|
137
202
|
}
|
|
138
203
|
return { httpsTrigger };
|
|
139
204
|
}
|
|
140
|
-
else if (
|
|
205
|
+
else if (isCallableTriggered(endpoint)) {
|
|
141
206
|
return { callableTrigger: {} };
|
|
142
207
|
}
|
|
143
|
-
else if (
|
|
208
|
+
else if (isBlockingTriggered(endpoint)) {
|
|
144
209
|
return { blockingTrigger: endpoint.blockingTrigger };
|
|
145
210
|
}
|
|
146
|
-
else if (
|
|
211
|
+
else if (isEventTriggered(endpoint)) {
|
|
147
212
|
const eventTrigger = {
|
|
148
213
|
eventType: endpoint.eventTrigger.eventType,
|
|
149
214
|
retry: r.resolveBoolean(endpoint.eventTrigger.retry) || false,
|
|
@@ -157,11 +222,13 @@ function discoverTrigger(endpoint, region, r) {
|
|
|
157
222
|
r.resolveStrings(eventTrigger, endpoint.eventTrigger, "serviceAccount", "region", "channel");
|
|
158
223
|
return { eventTrigger };
|
|
159
224
|
}
|
|
160
|
-
else if (
|
|
225
|
+
else if (isScheduleTriggered(endpoint)) {
|
|
161
226
|
const bkSchedule = {
|
|
162
227
|
schedule: r.resolveString(endpoint.scheduleTrigger.schedule),
|
|
163
|
-
timeZone: r.resolveString(endpoint.scheduleTrigger.timeZone),
|
|
164
228
|
};
|
|
229
|
+
if (endpoint.scheduleTrigger.timeZone !== undefined) {
|
|
230
|
+
bkSchedule.timeZone = r.resolveString(endpoint.scheduleTrigger.timeZone);
|
|
231
|
+
}
|
|
165
232
|
if (endpoint.scheduleTrigger.retryConfig) {
|
|
166
233
|
const bkRetry = {};
|
|
167
234
|
r.resolveInts(bkRetry, endpoint.scheduleTrigger.retryConfig, "maxBackoffSeconds", "minBackoffSeconds", "maxRetrySeconds", "retryCount", "maxDoublings");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ensureServiceAgentRoles = exports.mergeBindings = exports.obtainDefaultComputeServiceAgentBindings = exports.obtainPubSubServiceAgentBindings = exports.checkHttpIam = exports.checkServiceAccountIam = exports.EVENTARC_EVENT_RECEIVER_ROLE = exports.RUN_INVOKER_ROLE = exports.SERVICE_ACCOUNT_TOKEN_CREATOR_ROLE = void 0;
|
|
3
|
+
exports.ensureServiceAgentRoles = exports.mergeBindings = exports.obtainDefaultComputeServiceAgentBindings = exports.obtainPubSubServiceAgentBindings = exports.getDefaultComputeServiceAgent = exports.checkHttpIam = exports.checkServiceAccountIam = exports.EVENTARC_EVENT_RECEIVER_ROLE = exports.RUN_INVOKER_ROLE = exports.SERVICE_ACCOUNT_TOKEN_CREATOR_ROLE = void 0;
|
|
4
4
|
const colorette_1 = require("colorette");
|
|
5
5
|
const logger_1 = require("../../logger");
|
|
6
6
|
const functionsDeployHelper_1 = require("./functionsDeployHelper");
|
|
@@ -68,11 +68,12 @@ async function checkHttpIam(context, options, payload) {
|
|
|
68
68
|
}
|
|
69
69
|
exports.checkHttpIam = checkHttpIam;
|
|
70
70
|
function getPubsubServiceAgent(projectNumber) {
|
|
71
|
-
return `
|
|
71
|
+
return `service-${projectNumber}@gcp-sa-pubsub.iam.gserviceaccount.com`;
|
|
72
72
|
}
|
|
73
73
|
function getDefaultComputeServiceAgent(projectNumber) {
|
|
74
|
-
return
|
|
74
|
+
return `${projectNumber}-compute@developer.gserviceaccount.com`;
|
|
75
75
|
}
|
|
76
|
+
exports.getDefaultComputeServiceAgent = getDefaultComputeServiceAgent;
|
|
76
77
|
function reduceEventsToServices(services, endpoint) {
|
|
77
78
|
const service = (0, services_1.serviceForEndpoint)(endpoint);
|
|
78
79
|
if (service.requiredProjectBindings && !services.find((s) => s.name === service.name)) {
|
|
@@ -83,13 +84,13 @@ function reduceEventsToServices(services, endpoint) {
|
|
|
83
84
|
function obtainPubSubServiceAgentBindings(projectNumber) {
|
|
84
85
|
const serviceAccountTokenCreatorBinding = {
|
|
85
86
|
role: exports.SERVICE_ACCOUNT_TOKEN_CREATOR_ROLE,
|
|
86
|
-
members: [getPubsubServiceAgent(projectNumber)],
|
|
87
|
+
members: [`serviceAccount:${getPubsubServiceAgent(projectNumber)}`],
|
|
87
88
|
};
|
|
88
89
|
return [serviceAccountTokenCreatorBinding];
|
|
89
90
|
}
|
|
90
91
|
exports.obtainPubSubServiceAgentBindings = obtainPubSubServiceAgentBindings;
|
|
91
92
|
function obtainDefaultComputeServiceAgentBindings(projectNumber) {
|
|
92
|
-
const defaultComputeServiceAgent = getDefaultComputeServiceAgent(projectNumber)
|
|
93
|
+
const defaultComputeServiceAgent = `serviceAccount:${getDefaultComputeServiceAgent(projectNumber)}`;
|
|
93
94
|
const runInvokerBinding = {
|
|
94
95
|
role: exports.RUN_INVOKER_ROLE,
|
|
95
96
|
members: [defaultComputeServiceAgent],
|
|
@@ -21,7 +21,7 @@ function resolveInt(from, paramValues) {
|
|
|
21
21
|
if (typeof from === "number") {
|
|
22
22
|
return from;
|
|
23
23
|
}
|
|
24
|
-
const match =
|
|
24
|
+
const match = /{{ params\.(\w+) }}/.exec(from);
|
|
25
25
|
if (!match) {
|
|
26
26
|
throw new error_1.FirebaseError("CEL evaluation of expression '" + from + "' not yet supported");
|
|
27
27
|
}
|
|
@@ -102,20 +102,26 @@ function canSatisfyParam(param, value) {
|
|
|
102
102
|
}
|
|
103
103
|
(0, functional_1.assertExhaustive)(param);
|
|
104
104
|
}
|
|
105
|
-
async function resolveParams(params, projectId, userEnvs) {
|
|
105
|
+
async function resolveParams(params, projectId, userEnvs, nonInteractive) {
|
|
106
106
|
const paramValues = {};
|
|
107
107
|
const [provided, outstanding] = (0, functional_1.partition)(params, (param) => {
|
|
108
|
-
return {}.hasOwnProperty.call(userEnvs, param.
|
|
108
|
+
return {}.hasOwnProperty.call(userEnvs, param.name);
|
|
109
109
|
});
|
|
110
110
|
for (const param of provided) {
|
|
111
|
-
if (!canSatisfyParam(param, userEnvs[param.
|
|
111
|
+
if (!canSatisfyParam(param, userEnvs[param.name])) {
|
|
112
112
|
throw new error_1.FirebaseError("Parameter " +
|
|
113
|
-
param.
|
|
113
|
+
param.name +
|
|
114
114
|
" resolved to value from dotenv files " +
|
|
115
|
-
userEnvs[param.
|
|
115
|
+
userEnvs[param.name] +
|
|
116
116
|
" of wrong type");
|
|
117
117
|
}
|
|
118
|
-
paramValues[param.
|
|
118
|
+
paramValues[param.name] = userEnvs[param.name];
|
|
119
|
+
}
|
|
120
|
+
if (nonInteractive && outstanding.length > 0) {
|
|
121
|
+
const envNames = outstanding.map((p) => p.name).join(", ");
|
|
122
|
+
throw new error_1.FirebaseError(`In non-interactive mode but have no value for the following environment variables: ${envNames}\n` +
|
|
123
|
+
"To continue, either run `firebase deploy` with an interactive terminal, or add values to a dotenv file. " +
|
|
124
|
+
"For information regarding how to use dotenv files, see https://firebase.google.com/docs/functions/config-env");
|
|
119
125
|
}
|
|
120
126
|
for (const param of outstanding) {
|
|
121
127
|
let paramDefault = param.default;
|
|
@@ -123,9 +129,9 @@ async function resolveParams(params, projectId, userEnvs) {
|
|
|
123
129
|
paramDefault = resolveDefaultCEL(param.type, paramDefault, paramValues);
|
|
124
130
|
}
|
|
125
131
|
if (paramDefault && !canSatisfyParam(param, paramDefault)) {
|
|
126
|
-
throw new error_1.FirebaseError("Parameter " + param.
|
|
132
|
+
throw new error_1.FirebaseError("Parameter " + param.name + " has default value " + paramDefault + " of wrong type");
|
|
127
133
|
}
|
|
128
|
-
paramValues[param.
|
|
134
|
+
paramValues[param.name] = await promptParam(param, paramDefault);
|
|
129
135
|
}
|
|
130
136
|
return paramValues;
|
|
131
137
|
}
|
|
@@ -146,15 +152,15 @@ async function promptStringParam(param, resolvedDefault) {
|
|
|
146
152
|
}
|
|
147
153
|
switch (param.input.type) {
|
|
148
154
|
case "select":
|
|
149
|
-
throw new error_1.FirebaseError("Build specified string parameter " + param.
|
|
155
|
+
throw new error_1.FirebaseError("Build specified string parameter " + param.name + " with unsupported input type 'select'");
|
|
150
156
|
case "text":
|
|
151
157
|
default:
|
|
152
|
-
let prompt = `Enter a value for ${param.label || param.
|
|
158
|
+
let prompt = `Enter a value for ${param.label || param.name}:`;
|
|
153
159
|
if (param.description) {
|
|
154
160
|
prompt += ` \n(${param.description})`;
|
|
155
161
|
}
|
|
156
162
|
return await (0, prompt_1.promptOnce)({
|
|
157
|
-
name: param.
|
|
163
|
+
name: param.name,
|
|
158
164
|
type: "input",
|
|
159
165
|
default: resolvedDefault,
|
|
160
166
|
message: prompt,
|
|
@@ -168,17 +174,17 @@ async function promptIntParam(param, resolvedDefault) {
|
|
|
168
174
|
}
|
|
169
175
|
switch (param.input.type) {
|
|
170
176
|
case "select":
|
|
171
|
-
throw new error_1.FirebaseError("Build specified int parameter " + param.
|
|
177
|
+
throw new error_1.FirebaseError("Build specified int parameter " + param.name + " with unsupported input type 'select'");
|
|
172
178
|
case "text":
|
|
173
179
|
default:
|
|
174
|
-
let prompt = `Enter a value for ${param.label || param.
|
|
180
|
+
let prompt = `Enter a value for ${param.label || param.name}:`;
|
|
175
181
|
if (param.description) {
|
|
176
182
|
prompt += ` \n(${param.description})`;
|
|
177
183
|
}
|
|
178
184
|
let res;
|
|
179
185
|
while (true) {
|
|
180
186
|
res = await (0, prompt_1.promptOnce)({
|
|
181
|
-
name: param.
|
|
187
|
+
name: param.name,
|
|
182
188
|
type: "number",
|
|
183
189
|
default: resolvedDefault,
|
|
184
190
|
message: prompt,
|
|
@@ -186,7 +192,7 @@ async function promptIntParam(param, resolvedDefault) {
|
|
|
186
192
|
if (Number.isInteger(res)) {
|
|
187
193
|
return res;
|
|
188
194
|
}
|
|
189
|
-
logger_1.logger.error(`${param.label || param.
|
|
195
|
+
logger_1.logger.error(`${param.label || param.name} must be an integer; retrying...`);
|
|
190
196
|
}
|
|
191
197
|
}
|
|
192
198
|
}
|
|
@@ -78,7 +78,7 @@ async function prepare(context, options, payload) {
|
|
|
78
78
|
const userEnvs = functionsEnv.loadUserEnvs(userEnvOpt);
|
|
79
79
|
const envs = Object.assign(Object.assign({}, userEnvs), firebaseEnvs);
|
|
80
80
|
const wantBuild = await runtimeDelegate.discoverBuild(runtimeConfig, firebaseEnvs);
|
|
81
|
-
const wantBackend = await build.resolveBackend(wantBuild, userEnvOpt, userEnvs);
|
|
81
|
+
const wantBackend = await build.resolveBackend(wantBuild, userEnvOpt, userEnvs, options.nonInteractive);
|
|
82
82
|
wantBackend.environmentVariables = envs;
|
|
83
83
|
for (const endpoint of backend.allEndpoints(wantBackend)) {
|
|
84
84
|
endpoint.environmentVariables = wantBackend.environmentVariables;
|
|
@@ -24,6 +24,7 @@ const utils = require("../../../utils");
|
|
|
24
24
|
const services = require("../services");
|
|
25
25
|
const v1_1 = require("../../../functions/events/v1");
|
|
26
26
|
const throttler_1 = require("../../../throttler/throttler");
|
|
27
|
+
const checkIam_1 = require("../checkIam");
|
|
27
28
|
const gcfV1PollerOptions = {
|
|
28
29
|
apiOrigin: api_1.functionsOrigin,
|
|
29
30
|
apiVersion: gcf.API_VERSION,
|
|
@@ -46,6 +47,7 @@ class Fabricator {
|
|
|
46
47
|
this.functionExecutor = args.functionExecutor;
|
|
47
48
|
this.sources = args.sources;
|
|
48
49
|
this.appEngineLocation = args.appEngineLocation;
|
|
50
|
+
this.projectNumber = args.projectNumber;
|
|
49
51
|
}
|
|
50
52
|
async applyPlan(plan) {
|
|
51
53
|
const timer = new timer_1.Timer();
|
|
@@ -270,6 +272,12 @@ class Fabricator {
|
|
|
270
272
|
.run(() => run.setInvokerCreate(endpoint.project, serviceName, ["public"]))
|
|
271
273
|
.catch(rethrowAs(endpoint, "set invoker"));
|
|
272
274
|
}
|
|
275
|
+
else if (backend.isScheduleTriggered(endpoint)) {
|
|
276
|
+
const invoker = [(0, checkIam_1.getDefaultComputeServiceAgent)(this.projectNumber)];
|
|
277
|
+
await this.executor
|
|
278
|
+
.run(() => run.setInvokerCreate(endpoint.project, serviceName, invoker))
|
|
279
|
+
.catch(rethrowAs(endpoint, "set invoker"));
|
|
280
|
+
}
|
|
273
281
|
const mem = endpoint.availableMemoryMb || backend.DEFAULT_MEMORY;
|
|
274
282
|
const hasCustomCPU = endpoint.cpu !== backend.memoryToGen1Cpu(mem);
|
|
275
283
|
if (!endpoint.concurrency) {
|
|
@@ -346,6 +354,9 @@ class Fabricator {
|
|
|
346
354
|
v1_1.AUTH_BLOCKING_EVENTS.includes(endpoint.blockingTrigger.eventType)) {
|
|
347
355
|
invoker = ["public"];
|
|
348
356
|
}
|
|
357
|
+
else if (backend.isScheduleTriggered(endpoint)) {
|
|
358
|
+
invoker = [(0, checkIam_1.getDefaultComputeServiceAgent)(this.projectNumber)];
|
|
359
|
+
}
|
|
349
360
|
if (invoker) {
|
|
350
361
|
await this.executor
|
|
351
362
|
.run(() => run.setInvokerUpdate(endpoint.project, serviceName, invoker))
|
|
@@ -452,13 +463,16 @@ class Fabricator {
|
|
|
452
463
|
}
|
|
453
464
|
}
|
|
454
465
|
async upsertScheduleV1(endpoint) {
|
|
455
|
-
const job = scheduler.jobFromEndpoint(endpoint, this.appEngineLocation);
|
|
466
|
+
const job = scheduler.jobFromEndpoint(endpoint, this.appEngineLocation, this.projectNumber);
|
|
456
467
|
await this.executor
|
|
457
468
|
.run(() => scheduler.createOrReplaceJob(job))
|
|
458
469
|
.catch(rethrowAs(endpoint, "upsert schedule"));
|
|
459
470
|
}
|
|
460
|
-
upsertScheduleV2(endpoint) {
|
|
461
|
-
|
|
471
|
+
async upsertScheduleV2(endpoint) {
|
|
472
|
+
const job = scheduler.jobFromEndpoint(endpoint, endpoint.region, this.projectNumber);
|
|
473
|
+
await this.executor
|
|
474
|
+
.run(() => scheduler.createOrReplaceJob(job))
|
|
475
|
+
.catch(rethrowAs(endpoint, "upsert schedule"));
|
|
462
476
|
}
|
|
463
477
|
async upsertTaskQueue(endpoint) {
|
|
464
478
|
const queue = cloudtasks.queueFromEndpoint(endpoint);
|
|
@@ -486,8 +500,11 @@ class Fabricator {
|
|
|
486
500
|
.run(() => pubsub.deleteTopic(topicName))
|
|
487
501
|
.catch(rethrowAs(endpoint, "delete topic"));
|
|
488
502
|
}
|
|
489
|
-
deleteScheduleV2(endpoint) {
|
|
490
|
-
|
|
503
|
+
async deleteScheduleV2(endpoint) {
|
|
504
|
+
const jobName = scheduler.jobNameForEndpoint(endpoint, endpoint.region);
|
|
505
|
+
await this.executor
|
|
506
|
+
.run(() => scheduler.deleteJob(jobName))
|
|
507
|
+
.catch(rethrowAs(endpoint, "delete schedule"));
|
|
491
508
|
}
|
|
492
509
|
async disableTaskQueue(endpoint) {
|
|
493
510
|
const update = {
|
|
@@ -14,6 +14,7 @@ const prompts = require("../prompts");
|
|
|
14
14
|
const functionsConfig_1 = require("../../../functionsConfig");
|
|
15
15
|
const functionsDeployHelper_1 = require("../functionsDeployHelper");
|
|
16
16
|
const error_1 = require("../../../error");
|
|
17
|
+
const getProjectNumber_1 = require("../../../getProjectNumber");
|
|
17
18
|
async function release(context, options, payload) {
|
|
18
19
|
if (!context.config) {
|
|
19
20
|
return;
|
|
@@ -53,6 +54,7 @@ async function release(context, options, payload) {
|
|
|
53
54
|
executor: new executor.QueueExecutor({}),
|
|
54
55
|
sources: context.sources,
|
|
55
56
|
appEngineLocation: (0, functionsConfig_1.getAppEngineLocation)(context.firebaseConfig),
|
|
57
|
+
projectNumber: options.projectNumber || (await (0, getProjectNumber_1.getProjectNumber)(context.projectId)),
|
|
56
58
|
});
|
|
57
59
|
const summary = await fab.applyPlan(plan);
|
|
58
60
|
await reporter.logAndTrackDeployStats(summary);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.detectFromPort = exports.detectFromYaml = exports.yamlToBuild = exports.
|
|
3
|
+
exports.detectFromPort = exports.detectFromYaml = exports.yamlToBuild = exports.readFileAsync = void 0;
|
|
4
4
|
const node_fetch_1 = require("node-fetch");
|
|
5
5
|
const fs = require("fs");
|
|
6
6
|
const path = require("path");
|
|
@@ -11,21 +11,6 @@ const api = require("../../.../../../../api");
|
|
|
11
11
|
const v1alpha1 = require("./v1alpha1");
|
|
12
12
|
const error_1 = require("../../../../error");
|
|
13
13
|
exports.readFileAsync = (0, util_1.promisify)(fs.readFile);
|
|
14
|
-
function yamlToBackend(yaml, project, region, runtime) {
|
|
15
|
-
try {
|
|
16
|
-
if (!yaml.specVersion) {
|
|
17
|
-
throw new error_1.FirebaseError("Expect backend yaml to specify a version number");
|
|
18
|
-
}
|
|
19
|
-
if (yaml.specVersion === "v1alpha1") {
|
|
20
|
-
return v1alpha1.backendFromV1Alpha1(yaml, project, region, runtime);
|
|
21
|
-
}
|
|
22
|
-
throw new error_1.FirebaseError("It seems you are using a newer SDK than this version of the CLI can handle. Please update your CLI with `npm install -g firebase-tools`");
|
|
23
|
-
}
|
|
24
|
-
catch (err) {
|
|
25
|
-
throw new error_1.FirebaseError("Failed to parse backend specification", { children: [err] });
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
exports.yamlToBackend = yamlToBackend;
|
|
29
14
|
function yamlToBuild(yaml, project, region, runtime) {
|
|
30
15
|
try {
|
|
31
16
|
if (!yaml.specVersion) {
|
|
@@ -31,6 +31,22 @@ function assertKeyTypes(prefix, yaml, schema) {
|
|
|
31
31
|
}
|
|
32
32
|
continue;
|
|
33
33
|
}
|
|
34
|
+
if (value === null) {
|
|
35
|
+
if (schemaType.endsWith("?")) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
throw new error_1.FirebaseError(`Expected ${fullKey} to be type ${schemaType}; was null`);
|
|
39
|
+
}
|
|
40
|
+
if (schemaType.endsWith("?")) {
|
|
41
|
+
schemaType = schemaType.slice(0, schemaType.length - 1);
|
|
42
|
+
}
|
|
43
|
+
if (schemaType.includes("Field")) {
|
|
44
|
+
const match = /^Field<(\w+)>$/.exec(schemaType);
|
|
45
|
+
if (match && typeof value !== "string" && typeof value !== match[1]) {
|
|
46
|
+
throw new error_1.FirebaseError(`Expected ${fullKey} to be Field<${match[1]}>; was ${typeof value}`);
|
|
47
|
+
}
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
34
50
|
if (value === null) {
|
|
35
51
|
if (schemaType.endsWith("?")) {
|
|
36
52
|
continue;
|