firebase-tools 9.16.6 → 9.20.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/CHANGELOG.md +1 -3
- package/lib/api.js +1 -0
- package/lib/apiv2.js +1 -1
- package/lib/appdistribution/client.js +84 -72
- package/lib/appdistribution/distribution.js +8 -26
- package/lib/appdistribution/options-parser-util.js +51 -0
- package/lib/command.js +8 -6
- package/lib/commands/appdistribution-distribute.js +74 -91
- package/lib/commands/appdistribution-testers-add.js +18 -0
- package/lib/commands/appdistribution-testers-remove.js +32 -0
- package/lib/commands/crashlytics-symbols-upload.js +146 -0
- package/lib/commands/ext-configure.js +9 -1
- package/lib/commands/ext-dev-extension-delete.js +2 -1
- package/lib/commands/ext-dev-init.js +18 -9
- package/lib/commands/ext-dev-publish.js +11 -4
- package/lib/commands/ext-dev-unpublish.js +2 -1
- package/lib/commands/ext-install.js +115 -48
- package/lib/commands/ext-uninstall.js +6 -0
- package/lib/commands/ext-update.js +67 -43
- package/lib/commands/functions-config-export.js +115 -0
- package/lib/commands/functions-delete.js +44 -35
- package/lib/commands/functions-list.js +54 -0
- package/lib/commands/functions-log.js +5 -22
- package/lib/commands/hosting-channel-deploy.js +6 -4
- package/lib/commands/index.js +12 -0
- package/lib/deploy/functions/backend.js +47 -12
- package/lib/deploy/functions/containerCleaner.js +5 -1
- package/lib/deploy/functions/deploy.js +7 -5
- package/lib/deploy/functions/prepare.js +9 -7
- package/lib/deploy/functions/prompts.js +3 -21
- package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +2 -1
- package/lib/deploy/functions/runtimes/index.js +2 -1
- package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +4 -3
- package/lib/deploy/functions/runtimes/node/parseTriggers.js +14 -9
- package/lib/deploy/functions/triggerRegionHelper.js +32 -0
- package/lib/downloadUtils.js +37 -0
- package/lib/emulator/auth/apiSpec.js +1758 -404
- package/lib/emulator/auth/handlers.js +6 -5
- package/lib/emulator/auth/operations.js +429 -40
- package/lib/emulator/auth/server.js +18 -11
- package/lib/emulator/auth/state.js +186 -5
- package/lib/emulator/auth/widget_ui.js +2 -2
- package/lib/emulator/download.js +2 -31
- package/lib/emulator/downloadableEmulators.js +7 -7
- package/lib/emulator/emulatorLogger.js +0 -3
- package/lib/emulator/events/types.js +16 -0
- package/lib/emulator/functionsEmulator.js +102 -17
- package/lib/emulator/functionsEmulatorRuntime.js +46 -121
- package/lib/emulator/functionsEmulatorShared.js +51 -7
- package/lib/emulator/functionsEmulatorShell.js +1 -1
- package/lib/emulator/pubsubEmulator.js +61 -40
- package/lib/extensions/askUserForConsent.js +16 -13
- package/lib/extensions/askUserForParam.js +72 -3
- package/lib/extensions/billingMigrationHelper.js +1 -11
- package/lib/extensions/changelog.js +93 -0
- package/lib/extensions/displayExtensionInfo.js +38 -38
- package/lib/extensions/emulator/optionsHelper.js +3 -3
- package/lib/extensions/emulator/triggerHelper.js +2 -32
- package/lib/extensions/extensionsApi.js +69 -95
- package/lib/extensions/extensionsHelper.js +75 -50
- package/lib/extensions/paramHelper.js +79 -36
- package/lib/extensions/refs.js +59 -0
- package/lib/extensions/resolveSource.js +2 -20
- package/lib/extensions/secretsUtils.js +58 -0
- package/lib/extensions/updateHelper.js +39 -105
- package/lib/extensions/warnings.js +1 -7
- package/lib/functional.js +64 -0
- package/lib/functions/env.js +26 -13
- package/lib/functions/functionslog.js +40 -0
- package/lib/functions/listFunctions.js +10 -0
- package/lib/functions/runtimeConfigExport.js +137 -0
- package/lib/gcp/cloudfunctions.js +84 -9
- package/lib/gcp/cloudfunctionsv2.js +99 -7
- package/lib/gcp/cloudlogging.js +27 -21
- package/lib/gcp/secretManager.js +111 -0
- package/lib/gcp/storage.js +16 -0
- package/lib/previews.js +1 -1
- package/lib/requireInteractive.js +12 -0
- package/package.json +5 -4
- package/schema/firebase-config.json +2 -1
- package/templates/extensions/CHANGELOG.md +7 -0
- package/templates/init/hosting/index.html +10 -10
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.functionFromSpec = exports.specFromFunction = exports.listAllFunctions = exports.listFunctions = exports.deleteFunction = exports.updateFunction = exports.setInvokerUpdate = exports.setInvokerCreate = exports.getIamPolicy = exports.setIamPolicy = exports.createFunction = exports.generateUploadUrl = exports.API_VERSION = void 0;
|
|
3
|
+
exports.functionFromEndpoint = exports.endpointFromFunction = exports.functionFromSpec = exports.specFromFunction = exports.listAllFunctions = exports.listFunctions = exports.deleteFunction = exports.updateFunction = exports.setInvokerUpdate = exports.setInvokerCreate = exports.getIamPolicy = exports.setIamPolicy = exports.createFunction = exports.generateUploadUrl = exports.API_VERSION = void 0;
|
|
4
4
|
const clc = require("cli-color");
|
|
5
5
|
const error_1 = require("../error");
|
|
6
6
|
const logger_1 = require("../logger");
|
|
@@ -198,9 +198,11 @@ async function list(projectId, region) {
|
|
|
198
198
|
};
|
|
199
199
|
}
|
|
200
200
|
catch (err) {
|
|
201
|
-
logger_1.logger.debug(
|
|
201
|
+
logger_1.logger.debug(`[functions] failed to list functions for ${projectId}`);
|
|
202
202
|
logger_1.logger.debug(`[functions] ${err === null || err === void 0 ? void 0 : err.message}`);
|
|
203
|
-
|
|
203
|
+
throw new error_1.FirebaseError(`Failed to list functions for ${projectId}`, {
|
|
204
|
+
original: err,
|
|
205
|
+
});
|
|
204
206
|
}
|
|
205
207
|
}
|
|
206
208
|
async function listFunctions(projectId, region) {
|
|
@@ -218,9 +220,7 @@ function specFromFunction(gcfFunction) {
|
|
|
218
220
|
let trigger;
|
|
219
221
|
let uri;
|
|
220
222
|
if (gcfFunction.httpsTrigger) {
|
|
221
|
-
trigger = {
|
|
222
|
-
allowInsecure: gcfFunction.httpsTrigger.securityLevel !== "SECURE_ALWAYS",
|
|
223
|
-
};
|
|
223
|
+
trigger = {};
|
|
224
224
|
uri = gcfFunction.httpsTrigger.url;
|
|
225
225
|
}
|
|
226
226
|
else {
|
|
@@ -275,11 +275,86 @@ function functionFromSpec(cloudFunction, sourceUploadUrl) {
|
|
|
275
275
|
: undefined;
|
|
276
276
|
}
|
|
277
277
|
else {
|
|
278
|
-
gcfFunction.httpsTrigger = {
|
|
279
|
-
securityLevel: cloudFunction.trigger.allowInsecure ? "SECURE_OPTIONAL" : "SECURE_ALWAYS",
|
|
280
|
-
};
|
|
278
|
+
gcfFunction.httpsTrigger = {};
|
|
281
279
|
}
|
|
282
280
|
proto.copyIfPresent(gcfFunction, cloudFunction, "serviceAccountEmail", "timeout", "availableMemoryMb", "minInstances", "maxInstances", "vpcConnector", "vpcConnectorEgressSettings", "ingressSettings", "labels", "environmentVariables");
|
|
283
281
|
return gcfFunction;
|
|
284
282
|
}
|
|
285
283
|
exports.functionFromSpec = functionFromSpec;
|
|
284
|
+
function endpointFromFunction(gcfFunction) {
|
|
285
|
+
var _a, _b;
|
|
286
|
+
const [, project, , region, , id] = gcfFunction.name.split("/");
|
|
287
|
+
let trigger;
|
|
288
|
+
let uri;
|
|
289
|
+
if (gcfFunction.httpsTrigger) {
|
|
290
|
+
trigger = { httpsTrigger: {} };
|
|
291
|
+
uri = gcfFunction.httpsTrigger.url;
|
|
292
|
+
}
|
|
293
|
+
else if ((_a = gcfFunction.labels) === null || _a === void 0 ? void 0 : _a["deployment-scheduled"]) {
|
|
294
|
+
trigger = {
|
|
295
|
+
scheduleTrigger: {},
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
trigger = {
|
|
300
|
+
eventTrigger: {
|
|
301
|
+
eventType: gcfFunction.eventTrigger.eventType,
|
|
302
|
+
eventFilters: {
|
|
303
|
+
resource: gcfFunction.eventTrigger.resource,
|
|
304
|
+
},
|
|
305
|
+
retry: !!((_b = gcfFunction.eventTrigger.failurePolicy) === null || _b === void 0 ? void 0 : _b.retry),
|
|
306
|
+
},
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
if (!runtimes.isValidRuntime(gcfFunction.runtime)) {
|
|
310
|
+
logger_1.logger.debug("GCFv1 function has a deprecated runtime:", JSON.stringify(gcfFunction, null, 2));
|
|
311
|
+
}
|
|
312
|
+
const endpoint = Object.assign(Object.assign({ platform: "gcfv1", id,
|
|
313
|
+
project,
|
|
314
|
+
region }, trigger), { entryPoint: gcfFunction.entryPoint, runtime: gcfFunction.runtime });
|
|
315
|
+
if (uri) {
|
|
316
|
+
endpoint.uri = uri;
|
|
317
|
+
}
|
|
318
|
+
proto.copyIfPresent(endpoint, gcfFunction, "serviceAccountEmail", "availableMemoryMb", "timeout", "minInstances", "maxInstances", "vpcConnector", "vpcConnectorEgressSettings", "ingressSettings", "labels", "environmentVariables", "sourceUploadUrl");
|
|
319
|
+
return endpoint;
|
|
320
|
+
}
|
|
321
|
+
exports.endpointFromFunction = endpointFromFunction;
|
|
322
|
+
function functionFromEndpoint(endpoint, sourceUploadUrl) {
|
|
323
|
+
if (endpoint.platform != "gcfv1") {
|
|
324
|
+
throw new error_1.FirebaseError("Trying to create a v1 CloudFunction with v2 API. This should never happen");
|
|
325
|
+
}
|
|
326
|
+
if (!runtimes.isValidRuntime(endpoint.runtime)) {
|
|
327
|
+
throw new error_1.FirebaseError("Failed internal assertion. Trying to deploy a new function with a deprecated runtime." +
|
|
328
|
+
" This should never happen");
|
|
329
|
+
}
|
|
330
|
+
const gcfFunction = {
|
|
331
|
+
name: backend.functionName(endpoint),
|
|
332
|
+
sourceUploadUrl: sourceUploadUrl,
|
|
333
|
+
entryPoint: endpoint.entryPoint,
|
|
334
|
+
runtime: endpoint.runtime,
|
|
335
|
+
};
|
|
336
|
+
proto.copyIfPresent(gcfFunction, endpoint, "labels");
|
|
337
|
+
if (backend.isEventTriggered(endpoint)) {
|
|
338
|
+
gcfFunction.eventTrigger = {
|
|
339
|
+
eventType: endpoint.eventTrigger.eventType,
|
|
340
|
+
resource: endpoint.eventTrigger.eventFilters.resource,
|
|
341
|
+
};
|
|
342
|
+
gcfFunction.eventTrigger.failurePolicy = endpoint.eventTrigger.retry
|
|
343
|
+
? { retry: {} }
|
|
344
|
+
: undefined;
|
|
345
|
+
}
|
|
346
|
+
else if (backend.isScheduleTriggered(endpoint)) {
|
|
347
|
+
const id = backend.scheduleIdForFunction(endpoint);
|
|
348
|
+
gcfFunction.eventTrigger = {
|
|
349
|
+
eventType: "google.pubsub.topic.publish",
|
|
350
|
+
resource: `projects/${endpoint.project}/topics/${id}`,
|
|
351
|
+
};
|
|
352
|
+
gcfFunction.labels = Object.assign(Object.assign({}, gcfFunction.labels), { "deployment-scheduled": "true" });
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
gcfFunction.httpsTrigger = {};
|
|
356
|
+
}
|
|
357
|
+
proto.copyIfPresent(gcfFunction, endpoint, "serviceAccountEmail", "timeout", "availableMemoryMb", "minInstances", "maxInstances", "vpcConnector", "vpcConnectorEgressSettings", "ingressSettings", "environmentVariables");
|
|
358
|
+
return gcfFunction;
|
|
359
|
+
}
|
|
360
|
+
exports.functionFromEndpoint = functionFromEndpoint;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.specFromFunction = exports.functionFromSpec = exports.deleteFunction = exports.updateFunction = exports.listAllFunctions = exports.listFunctions = exports.getFunction = exports.createFunction = exports.generateUploadUrl = exports.PUBSUB_PUBLISH_EVENT = exports.API_VERSION = void 0;
|
|
3
|
+
exports.endpointFromFunction = exports.functionFromEndpoint = exports.specFromFunction = exports.functionFromSpec = exports.deleteFunction = exports.updateFunction = exports.listAllFunctions = exports.listFunctions = exports.getFunction = exports.createFunction = exports.generateUploadUrl = exports.PUBSUB_PUBLISH_EVENT = exports.API_VERSION = void 0;
|
|
4
4
|
const clc = require("cli-color");
|
|
5
5
|
const apiv2_1 = require("../apiv2");
|
|
6
6
|
const error_1 = require("../error");
|
|
@@ -143,6 +143,9 @@ function functionFromSpec(cloudFunction, source) {
|
|
|
143
143
|
gcfFunction.eventTrigger = {
|
|
144
144
|
eventType: cloudFunction.trigger.eventType,
|
|
145
145
|
};
|
|
146
|
+
if (cloudFunction.trigger.region) {
|
|
147
|
+
gcfFunction.eventTrigger.triggerRegion = cloudFunction.trigger.region;
|
|
148
|
+
}
|
|
146
149
|
if (gcfFunction.eventTrigger.eventType === exports.PUBSUB_PUBLISH_EVENT) {
|
|
147
150
|
gcfFunction.eventTrigger.pubsubTopic = cloudFunction.trigger.eventFilters.resource;
|
|
148
151
|
}
|
|
@@ -156,9 +159,6 @@ function functionFromSpec(cloudFunction, source) {
|
|
|
156
159
|
logger_1.logger.warn("Cannot set a retry policy on Cloud Function", cloudFunction.id);
|
|
157
160
|
}
|
|
158
161
|
}
|
|
159
|
-
else if (cloudFunction.trigger.allowInsecure) {
|
|
160
|
-
logger_1.logger.warn("Cannot enable insecure traffic for Cloud Function", cloudFunction.id);
|
|
161
|
-
}
|
|
162
162
|
proto.copyIfPresent(gcfFunction, cloudFunction, "labels");
|
|
163
163
|
return gcfFunction;
|
|
164
164
|
}
|
|
@@ -172,6 +172,9 @@ function specFromFunction(gcfFunction) {
|
|
|
172
172
|
eventFilters: {},
|
|
173
173
|
retry: false,
|
|
174
174
|
};
|
|
175
|
+
if (gcfFunction.eventTrigger.triggerRegion) {
|
|
176
|
+
trigger.region = gcfFunction.eventTrigger.triggerRegion;
|
|
177
|
+
}
|
|
175
178
|
if (gcfFunction.eventTrigger.pubsubTopic) {
|
|
176
179
|
trigger.eventFilters.resource = gcfFunction.eventTrigger.pubsubTopic;
|
|
177
180
|
}
|
|
@@ -182,9 +185,7 @@ function specFromFunction(gcfFunction) {
|
|
|
182
185
|
}
|
|
183
186
|
}
|
|
184
187
|
else {
|
|
185
|
-
trigger = {
|
|
186
|
-
allowInsecure: false,
|
|
187
|
-
};
|
|
188
|
+
trigger = {};
|
|
188
189
|
}
|
|
189
190
|
if (!runtimes.isValidRuntime(gcfFunction.buildConfig.runtime)) {
|
|
190
191
|
logger_1.logger.debug("GCFv2 function has a deprecated runtime:", JSON.stringify(gcfFunction, null, 2));
|
|
@@ -207,3 +208,94 @@ function specFromFunction(gcfFunction) {
|
|
|
207
208
|
return cloudFunction;
|
|
208
209
|
}
|
|
209
210
|
exports.specFromFunction = specFromFunction;
|
|
211
|
+
function functionFromEndpoint(endpoint, source) {
|
|
212
|
+
if (endpoint.platform != "gcfv2") {
|
|
213
|
+
throw new error_1.FirebaseError("Trying to create a v2 CloudFunction with v1 API. This should never happen");
|
|
214
|
+
}
|
|
215
|
+
if (!runtimes.isValidRuntime(endpoint.runtime)) {
|
|
216
|
+
throw new error_1.FirebaseError("Failed internal assertion. Trying to deploy a new function with a deprecated runtime." +
|
|
217
|
+
" This should never happen");
|
|
218
|
+
}
|
|
219
|
+
const gcfFunction = {
|
|
220
|
+
name: backend.functionName(endpoint),
|
|
221
|
+
buildConfig: {
|
|
222
|
+
runtime: endpoint.runtime,
|
|
223
|
+
entryPoint: endpoint.entryPoint,
|
|
224
|
+
source: {
|
|
225
|
+
storageSource: source,
|
|
226
|
+
},
|
|
227
|
+
environmentVariables: {},
|
|
228
|
+
},
|
|
229
|
+
serviceConfig: {},
|
|
230
|
+
};
|
|
231
|
+
proto.copyIfPresent(gcfFunction, endpoint, "labels");
|
|
232
|
+
proto.copyIfPresent(gcfFunction.serviceConfig, endpoint, "availableMemoryMb", "environmentVariables", "vpcConnector", "vpcConnectorEgressSettings", "serviceAccountEmail", "ingressSettings");
|
|
233
|
+
proto.renameIfPresent(gcfFunction.serviceConfig, endpoint, "timeoutSeconds", "timeout", proto.secondsFromDuration);
|
|
234
|
+
proto.renameIfPresent(gcfFunction.serviceConfig, endpoint, "minInstanceCount", "minInstances");
|
|
235
|
+
proto.renameIfPresent(gcfFunction.serviceConfig, endpoint, "maxInstanceCount", "maxInstances");
|
|
236
|
+
if (backend.isEventTriggered(endpoint)) {
|
|
237
|
+
gcfFunction.eventTrigger = {
|
|
238
|
+
eventType: endpoint.eventTrigger.eventType,
|
|
239
|
+
};
|
|
240
|
+
if (gcfFunction.eventTrigger.eventType === exports.PUBSUB_PUBLISH_EVENT) {
|
|
241
|
+
gcfFunction.eventTrigger.pubsubTopic = endpoint.eventTrigger.eventFilters.resource;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
gcfFunction.eventTrigger.eventFilters = [];
|
|
245
|
+
for (const [attribute, value] of Object.entries(endpoint.eventTrigger.eventFilters)) {
|
|
246
|
+
gcfFunction.eventTrigger.eventFilters.push({ attribute, value });
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
if (endpoint.eventTrigger.retry) {
|
|
250
|
+
logger_1.logger.warn("Cannot set a retry policy on Cloud Function", endpoint.id);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
else if (backend.isScheduleTriggered(endpoint)) {
|
|
254
|
+
gcfFunction.labels = Object.assign(Object.assign({}, gcfFunction.labels), { ["deployment-scheduled"]: "true" });
|
|
255
|
+
}
|
|
256
|
+
return gcfFunction;
|
|
257
|
+
}
|
|
258
|
+
exports.functionFromEndpoint = functionFromEndpoint;
|
|
259
|
+
function endpointFromFunction(gcfFunction) {
|
|
260
|
+
var _a;
|
|
261
|
+
const [, project, , region, , id] = gcfFunction.name.split("/");
|
|
262
|
+
let trigger;
|
|
263
|
+
if (((_a = gcfFunction.labels) === null || _a === void 0 ? void 0 : _a["deployment-scheduled"]) === "true") {
|
|
264
|
+
trigger = {
|
|
265
|
+
scheduleTrigger: {},
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
else if (gcfFunction.eventTrigger) {
|
|
269
|
+
trigger = {
|
|
270
|
+
eventTrigger: {
|
|
271
|
+
eventType: gcfFunction.eventTrigger.eventType,
|
|
272
|
+
eventFilters: {},
|
|
273
|
+
retry: false,
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
if (gcfFunction.eventTrigger.pubsubTopic) {
|
|
277
|
+
trigger.eventTrigger.eventFilters.resource = gcfFunction.eventTrigger.pubsubTopic;
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
for (const { attribute, value } of gcfFunction.eventTrigger.eventFilters || []) {
|
|
281
|
+
trigger.eventTrigger.eventFilters[attribute] = value;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
trigger = { httpsTrigger: {} };
|
|
287
|
+
}
|
|
288
|
+
if (!runtimes.isValidRuntime(gcfFunction.buildConfig.runtime)) {
|
|
289
|
+
logger_1.logger.debug("GCFv2 function has a deprecated runtime:", JSON.stringify(gcfFunction, null, 2));
|
|
290
|
+
}
|
|
291
|
+
const endpoint = Object.assign(Object.assign({ platform: "gcfv2", id,
|
|
292
|
+
project,
|
|
293
|
+
region }, trigger), { entryPoint: gcfFunction.buildConfig.entryPoint, runtime: gcfFunction.buildConfig.runtime, uri: gcfFunction.serviceConfig.uri });
|
|
294
|
+
proto.copyIfPresent(endpoint, gcfFunction.serviceConfig, "serviceAccountEmail", "availableMemoryMb", "vpcConnector", "vpcConnectorEgressSettings", "ingressSettings", "environmentVariables");
|
|
295
|
+
proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "timeout", "timeoutSeconds", proto.durationFromSeconds);
|
|
296
|
+
proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "minInstances", "minInstanceCount");
|
|
297
|
+
proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "maxInstances", "maxInstanceCount");
|
|
298
|
+
proto.copyIfPresent(endpoint, gcfFunction, "labels");
|
|
299
|
+
return endpoint;
|
|
300
|
+
}
|
|
301
|
+
exports.endpointFromFunction = endpointFromFunction;
|
package/lib/gcp/cloudlogging.js
CHANGED
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listEntries = void 0;
|
|
4
|
+
const api = require("../api");
|
|
5
|
+
const error_1 = require("../error");
|
|
6
|
+
const API_VERSION = "v2";
|
|
7
|
+
async function listEntries(projectId, filter, pageSize, order) {
|
|
8
|
+
const endpoint = `/${API_VERSION}/entries:list`;
|
|
9
|
+
try {
|
|
10
|
+
const result = await api.request("POST", endpoint, {
|
|
11
|
+
auth: true,
|
|
12
|
+
data: {
|
|
13
|
+
resourceNames: [`projects/${projectId}`],
|
|
14
|
+
filter: filter,
|
|
15
|
+
orderBy: "timestamp " + order,
|
|
16
|
+
pageSize: pageSize,
|
|
17
|
+
},
|
|
18
|
+
origin: api.cloudloggingOrigin,
|
|
19
|
+
});
|
|
20
|
+
return result.body.entries;
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
throw new error_1.FirebaseError("Failed to retrieve log entries from Google Cloud.", {
|
|
24
|
+
original: err,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.listEntries = listEntries;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.grantServiceAgentRole = exports.addVersion = exports.createSecret = exports.parseSecretResourceName = exports.secretExists = exports.getSecretLabels = exports.getSecret = exports.listSecrets = void 0;
|
|
4
|
+
const api = require("../api");
|
|
5
|
+
async function listSecrets(projectId) {
|
|
6
|
+
const listRes = await api.request("GET", `/v1beta1/projects/${projectId}/secrets`, {
|
|
7
|
+
auth: true,
|
|
8
|
+
origin: api.secretManagerOrigin,
|
|
9
|
+
});
|
|
10
|
+
return listRes.body.secrets.map((s) => parseSecretResourceName(s.name));
|
|
11
|
+
}
|
|
12
|
+
exports.listSecrets = listSecrets;
|
|
13
|
+
async function getSecret(projectId, name) {
|
|
14
|
+
const getRes = await api.request("GET", `/v1beta1/projects/${projectId}/secrets/${name}`, {
|
|
15
|
+
auth: true,
|
|
16
|
+
origin: api.secretManagerOrigin,
|
|
17
|
+
});
|
|
18
|
+
return parseSecretResourceName(getRes.body.name);
|
|
19
|
+
}
|
|
20
|
+
exports.getSecret = getSecret;
|
|
21
|
+
async function getSecretLabels(projectId, name) {
|
|
22
|
+
const getRes = await api.request("GET", `/v1beta1/projects/${projectId}/secrets/${name}`, {
|
|
23
|
+
auth: true,
|
|
24
|
+
origin: api.secretManagerOrigin,
|
|
25
|
+
});
|
|
26
|
+
return getRes.body.labels;
|
|
27
|
+
}
|
|
28
|
+
exports.getSecretLabels = getSecretLabels;
|
|
29
|
+
async function secretExists(projectId, name) {
|
|
30
|
+
try {
|
|
31
|
+
await getSecret(projectId, name);
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
if (err.status === 404) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
throw err;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.secretExists = secretExists;
|
|
42
|
+
function parseSecretResourceName(resourceName) {
|
|
43
|
+
const nameTokens = resourceName.split("/");
|
|
44
|
+
return {
|
|
45
|
+
projectId: nameTokens[1],
|
|
46
|
+
name: nameTokens[3],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
exports.parseSecretResourceName = parseSecretResourceName;
|
|
50
|
+
async function createSecret(projectId, name, labels) {
|
|
51
|
+
const createRes = await api.request("POST", `/v1beta1/projects/${projectId}/secrets?secretId=${name}`, {
|
|
52
|
+
auth: true,
|
|
53
|
+
origin: api.secretManagerOrigin,
|
|
54
|
+
data: {
|
|
55
|
+
replication: {
|
|
56
|
+
automatic: {},
|
|
57
|
+
},
|
|
58
|
+
labels,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
return parseSecretResourceName(createRes.body.name);
|
|
62
|
+
}
|
|
63
|
+
exports.createSecret = createSecret;
|
|
64
|
+
async function addVersion(secret, payloadData) {
|
|
65
|
+
const res = await api.request("POST", `/v1beta1/projects/${secret.projectId}/secrets/${secret.name}:addVersion`, {
|
|
66
|
+
auth: true,
|
|
67
|
+
origin: api.secretManagerOrigin,
|
|
68
|
+
data: {
|
|
69
|
+
payload: {
|
|
70
|
+
data: Buffer.from(payloadData).toString("base64"),
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
const nameTokens = res.body.name.split("/");
|
|
75
|
+
return {
|
|
76
|
+
secret: {
|
|
77
|
+
projectId: nameTokens[1],
|
|
78
|
+
name: nameTokens[3],
|
|
79
|
+
},
|
|
80
|
+
versionId: nameTokens[5],
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
exports.addVersion = addVersion;
|
|
84
|
+
async function grantServiceAgentRole(secret, serviceAccountEmail, role) {
|
|
85
|
+
const getPolicyRes = await api.request("GET", `/v1beta1/projects/${secret.projectId}/secrets/${secret.name}:getIamPolicy`, {
|
|
86
|
+
auth: true,
|
|
87
|
+
origin: api.secretManagerOrigin,
|
|
88
|
+
});
|
|
89
|
+
const bindings = getPolicyRes.body.bindings || [];
|
|
90
|
+
if (bindings.find((b) => b.role == role &&
|
|
91
|
+
b.members.find((m) => m == `serviceAccount:${serviceAccountEmail}`))) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
bindings.push({
|
|
95
|
+
role: role,
|
|
96
|
+
members: [`serviceAccount:${serviceAccountEmail}`],
|
|
97
|
+
});
|
|
98
|
+
await api.request("POST", `/v1beta1/projects/${secret.projectId}/secrets/${secret.name}:setIamPolicy`, {
|
|
99
|
+
auth: true,
|
|
100
|
+
origin: api.secretManagerOrigin,
|
|
101
|
+
data: {
|
|
102
|
+
policy: {
|
|
103
|
+
bindings,
|
|
104
|
+
},
|
|
105
|
+
updateMask: {
|
|
106
|
+
paths: "bindings",
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
exports.grantServiceAgentRole = grantServiceAgentRole;
|
package/lib/gcp/storage.js
CHANGED
|
@@ -61,9 +61,25 @@ function _deleteObject(location) {
|
|
|
61
61
|
origin: api.storageOrigin,
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
|
+
async function _getBucket(bucketName) {
|
|
65
|
+
try {
|
|
66
|
+
const result = await api.request("GET", `/storage/v1/b/${bucketName}`, {
|
|
67
|
+
auth: true,
|
|
68
|
+
origin: api.storageOrigin,
|
|
69
|
+
});
|
|
70
|
+
return result.body;
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
logger.debug(err);
|
|
74
|
+
throw new FirebaseError("Failed to obtain the storage bucket", {
|
|
75
|
+
original: err,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
64
79
|
module.exports = {
|
|
65
80
|
getDefaultBucket: _getDefaultBucket,
|
|
66
81
|
deleteObject: _deleteObject,
|
|
67
82
|
upload: _uploadSource,
|
|
68
83
|
uploadObject: _uploadObject,
|
|
84
|
+
getBucket: _getBucket,
|
|
69
85
|
};
|
package/lib/previews.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.previews = void 0;
|
|
4
4
|
const lodash_1 = require("lodash");
|
|
5
5
|
const configstore_1 = require("./configstore");
|
|
6
|
-
exports.previews = Object.assign({ rtdbrules: false, ext: false, extdev: false, rtdbmanagement: false, functionsv2: false, golang: false, deletegcfartifacts: false, dotenv: false }, configstore_1.configstore.get("previews"));
|
|
6
|
+
exports.previews = Object.assign({ rtdbrules: false, ext: false, extdev: false, rtdbmanagement: false, functionsv2: false, golang: false, deletegcfartifacts: false, dotenv: false, crashlyticsSymbolsUpload: false }, configstore_1.configstore.get("previews"));
|
|
7
7
|
if (process.env.FIREBASE_CLI_PREVIEWS) {
|
|
8
8
|
process.env.FIREBASE_CLI_PREVIEWS.split(",").forEach((feature) => {
|
|
9
9
|
if (lodash_1.has(exports.previews, feature)) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const error_1 = require("./error");
|
|
4
|
+
function requireInteractive(options) {
|
|
5
|
+
if (options.nonInteractive) {
|
|
6
|
+
return Promise.reject(new error_1.FirebaseError("This command cannot run in non-interactive mode", {
|
|
7
|
+
exit: 1,
|
|
8
|
+
}));
|
|
9
|
+
}
|
|
10
|
+
return Promise.resolve();
|
|
11
|
+
}
|
|
12
|
+
exports.default = requireInteractive;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "firebase-tools",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.20.0",
|
|
4
4
|
"description": "Command-Line Interface for Firebase",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -85,6 +85,7 @@
|
|
|
85
85
|
"dependencies": {
|
|
86
86
|
"@google-cloud/pubsub": "^2.7.0",
|
|
87
87
|
"@types/archiver": "^5.1.0",
|
|
88
|
+
"JSONStream": "^1.2.1",
|
|
88
89
|
"abort-controller": "^3.0.0",
|
|
89
90
|
"ajv": "^6.12.6",
|
|
90
91
|
"archiver": "^5.0.0",
|
|
@@ -110,7 +111,6 @@
|
|
|
110
111
|
"google-auth-library": "^6.1.3",
|
|
111
112
|
"inquirer": "~6.3.1",
|
|
112
113
|
"js-yaml": "^3.13.1",
|
|
113
|
-
"JSONStream": "^1.2.1",
|
|
114
114
|
"jsonwebtoken": "^8.5.1",
|
|
115
115
|
"leven": "^3.1.0",
|
|
116
116
|
"lodash": "^4.17.21",
|
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
"ora": "^3.4.0",
|
|
125
125
|
"portfinder": "^1.0.23",
|
|
126
126
|
"progress": "^2.0.3",
|
|
127
|
-
"proxy-agent": "^
|
|
127
|
+
"proxy-agent": "^5.0.0",
|
|
128
128
|
"request": "^2.87.0",
|
|
129
129
|
"rimraf": "^3.0.0",
|
|
130
130
|
"semver": "^5.7.1",
|
|
@@ -143,6 +143,7 @@
|
|
|
143
143
|
"ws": "^7.2.3"
|
|
144
144
|
},
|
|
145
145
|
"devDependencies": {
|
|
146
|
+
"@google/events": "^5.1.1",
|
|
146
147
|
"@manifoldco/swagger-to-ts": "^2.0.0",
|
|
147
148
|
"@types/body-parser": "^1.17.0",
|
|
148
149
|
"@types/chai": "^4.2.12",
|
|
@@ -194,7 +195,7 @@
|
|
|
194
195
|
"eslint-plugin-prettier": "^3.3.1",
|
|
195
196
|
"firebase": "^7.24.0",
|
|
196
197
|
"firebase-admin": "^9.4.2",
|
|
197
|
-
"firebase-functions": "^3.
|
|
198
|
+
"firebase-functions": "^3.15.0",
|
|
198
199
|
"google-discovery-to-swagger": "^2.1.0",
|
|
199
200
|
"mocha": "^8.2.1",
|
|
200
201
|
"nock": "^13.0.5",
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
CHANGELOG.md is how you tell users what has changed in each version of your extension.
|
|
2
|
+
When you release a new version, add a new header and release notes for that version.
|
|
3
|
+
When users update their instance, they will see the release notes for all versions
|
|
4
|
+
between the one they were on and the one they are updating to.
|
|
5
|
+
|
|
6
|
+
## Version 0.0.1
|
|
7
|
+
First version
|
|
@@ -6,17 +6,17 @@
|
|
|
6
6
|
<title>Welcome to Firebase Hosting</title>
|
|
7
7
|
|
|
8
8
|
<!-- update the version number as needed -->
|
|
9
|
-
<script defer src="/__/firebase/{{VERSION}}/firebase-app.js"></script>
|
|
9
|
+
<script defer src="/__/firebase/{{VERSION}}/firebase-app-compat.js"></script>
|
|
10
10
|
<!-- include only the Firebase features as you need -->
|
|
11
|
-
<script defer src="/__/firebase/{{VERSION}}/firebase-auth.js"></script>
|
|
12
|
-
<script defer src="/__/firebase/{{VERSION}}/firebase-database.js"></script>
|
|
13
|
-
<script defer src="/__/firebase/{{VERSION}}/firebase-firestore.js"></script>
|
|
14
|
-
<script defer src="/__/firebase/{{VERSION}}/firebase-functions.js"></script>
|
|
15
|
-
<script defer src="/__/firebase/{{VERSION}}/firebase-messaging.js"></script>
|
|
16
|
-
<script defer src="/__/firebase/{{VERSION}}/firebase-storage.js"></script>
|
|
17
|
-
<script defer src="/__/firebase/{{VERSION}}/firebase-analytics.js"></script>
|
|
18
|
-
<script defer src="/__/firebase/{{VERSION}}/firebase-remote-config.js"></script>
|
|
19
|
-
<script defer src="/__/firebase/{{VERSION}}/firebase-performance.js"></script>
|
|
11
|
+
<script defer src="/__/firebase/{{VERSION}}/firebase-auth-compat.js"></script>
|
|
12
|
+
<script defer src="/__/firebase/{{VERSION}}/firebase-database-compat.js"></script>
|
|
13
|
+
<script defer src="/__/firebase/{{VERSION}}/firebase-firestore-compat.js"></script>
|
|
14
|
+
<script defer src="/__/firebase/{{VERSION}}/firebase-functions-compat.js"></script>
|
|
15
|
+
<script defer src="/__/firebase/{{VERSION}}/firebase-messaging-compat.js"></script>
|
|
16
|
+
<script defer src="/__/firebase/{{VERSION}}/firebase-storage-compat.js"></script>
|
|
17
|
+
<script defer src="/__/firebase/{{VERSION}}/firebase-analytics-compat.js"></script>
|
|
18
|
+
<script defer src="/__/firebase/{{VERSION}}/firebase-remote-config-compat.js"></script>
|
|
19
|
+
<script defer src="/__/firebase/{{VERSION}}/firebase-performance-compat.js"></script>
|
|
20
20
|
<!--
|
|
21
21
|
initialize the SDK after all desired features are loaded, set useEmulator to false
|
|
22
22
|
to avoid connecting the SDK to running emulators.
|