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.
Files changed (82) hide show
  1. package/CHANGELOG.md +1 -3
  2. package/lib/api.js +1 -0
  3. package/lib/apiv2.js +1 -1
  4. package/lib/appdistribution/client.js +84 -72
  5. package/lib/appdistribution/distribution.js +8 -26
  6. package/lib/appdistribution/options-parser-util.js +51 -0
  7. package/lib/command.js +8 -6
  8. package/lib/commands/appdistribution-distribute.js +74 -91
  9. package/lib/commands/appdistribution-testers-add.js +18 -0
  10. package/lib/commands/appdistribution-testers-remove.js +32 -0
  11. package/lib/commands/crashlytics-symbols-upload.js +146 -0
  12. package/lib/commands/ext-configure.js +9 -1
  13. package/lib/commands/ext-dev-extension-delete.js +2 -1
  14. package/lib/commands/ext-dev-init.js +18 -9
  15. package/lib/commands/ext-dev-publish.js +11 -4
  16. package/lib/commands/ext-dev-unpublish.js +2 -1
  17. package/lib/commands/ext-install.js +115 -48
  18. package/lib/commands/ext-uninstall.js +6 -0
  19. package/lib/commands/ext-update.js +67 -43
  20. package/lib/commands/functions-config-export.js +115 -0
  21. package/lib/commands/functions-delete.js +44 -35
  22. package/lib/commands/functions-list.js +54 -0
  23. package/lib/commands/functions-log.js +5 -22
  24. package/lib/commands/hosting-channel-deploy.js +6 -4
  25. package/lib/commands/index.js +12 -0
  26. package/lib/deploy/functions/backend.js +47 -12
  27. package/lib/deploy/functions/containerCleaner.js +5 -1
  28. package/lib/deploy/functions/deploy.js +7 -5
  29. package/lib/deploy/functions/prepare.js +9 -7
  30. package/lib/deploy/functions/prompts.js +3 -21
  31. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +2 -1
  32. package/lib/deploy/functions/runtimes/index.js +2 -1
  33. package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +4 -3
  34. package/lib/deploy/functions/runtimes/node/parseTriggers.js +14 -9
  35. package/lib/deploy/functions/triggerRegionHelper.js +32 -0
  36. package/lib/downloadUtils.js +37 -0
  37. package/lib/emulator/auth/apiSpec.js +1758 -404
  38. package/lib/emulator/auth/handlers.js +6 -5
  39. package/lib/emulator/auth/operations.js +429 -40
  40. package/lib/emulator/auth/server.js +18 -11
  41. package/lib/emulator/auth/state.js +186 -5
  42. package/lib/emulator/auth/widget_ui.js +2 -2
  43. package/lib/emulator/download.js +2 -31
  44. package/lib/emulator/downloadableEmulators.js +7 -7
  45. package/lib/emulator/emulatorLogger.js +0 -3
  46. package/lib/emulator/events/types.js +16 -0
  47. package/lib/emulator/functionsEmulator.js +102 -17
  48. package/lib/emulator/functionsEmulatorRuntime.js +46 -121
  49. package/lib/emulator/functionsEmulatorShared.js +51 -7
  50. package/lib/emulator/functionsEmulatorShell.js +1 -1
  51. package/lib/emulator/pubsubEmulator.js +61 -40
  52. package/lib/extensions/askUserForConsent.js +16 -13
  53. package/lib/extensions/askUserForParam.js +72 -3
  54. package/lib/extensions/billingMigrationHelper.js +1 -11
  55. package/lib/extensions/changelog.js +93 -0
  56. package/lib/extensions/displayExtensionInfo.js +38 -38
  57. package/lib/extensions/emulator/optionsHelper.js +3 -3
  58. package/lib/extensions/emulator/triggerHelper.js +2 -32
  59. package/lib/extensions/extensionsApi.js +69 -95
  60. package/lib/extensions/extensionsHelper.js +75 -50
  61. package/lib/extensions/paramHelper.js +79 -36
  62. package/lib/extensions/refs.js +59 -0
  63. package/lib/extensions/resolveSource.js +2 -20
  64. package/lib/extensions/secretsUtils.js +58 -0
  65. package/lib/extensions/updateHelper.js +39 -105
  66. package/lib/extensions/warnings.js +1 -7
  67. package/lib/functional.js +64 -0
  68. package/lib/functions/env.js +26 -13
  69. package/lib/functions/functionslog.js +40 -0
  70. package/lib/functions/listFunctions.js +10 -0
  71. package/lib/functions/runtimeConfigExport.js +137 -0
  72. package/lib/gcp/cloudfunctions.js +84 -9
  73. package/lib/gcp/cloudfunctionsv2.js +99 -7
  74. package/lib/gcp/cloudlogging.js +27 -21
  75. package/lib/gcp/secretManager.js +111 -0
  76. package/lib/gcp/storage.js +16 -0
  77. package/lib/previews.js +1 -1
  78. package/lib/requireInteractive.js +12 -0
  79. package/package.json +5 -4
  80. package/schema/firebase-config.json +2 -1
  81. package/templates/extensions/CHANGELOG.md +7 -0
  82. 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("[functions] failed to list functions for " + projectId);
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
- return Promise.reject(err === null || err === void 0 ? void 0 : err.message);
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;
@@ -1,22 +1,28 @@
1
1
  "use strict";
2
- var api = require("../api");
3
- var version = "v2beta1";
4
- var _listEntries = function (projectId, filter, pageSize, order) {
5
- return api
6
- .request("POST", "/" + version + "/entries:list", {
7
- auth: true,
8
- data: {
9
- projectIds: [projectId],
10
- filter: filter,
11
- orderBy: "timestamp " + order,
12
- pageSize: pageSize,
13
- },
14
- origin: api.cloudloggingOrigin,
15
- })
16
- .then(function (result) {
17
- return Promise.resolve(result.body.entries);
18
- });
19
- };
20
- module.exports = {
21
- listEntries: _listEntries,
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;
@@ -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.16.6",
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": "^4.0.0",
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.11.0",
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",
@@ -350,7 +350,8 @@
350
350
  "enum": [
351
351
  "nodejs10",
352
352
  "nodejs12",
353
- "nodejs14"
353
+ "nodejs14",
354
+ "nodejs16"
354
355
  ],
355
356
  "type": "string"
356
357
  },
@@ -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.