firebase-tools 10.2.1 → 10.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/lib/appdistribution/options-parser-util.js +1 -1
  2. package/lib/auth.js +3 -3
  3. package/lib/command.js +1 -1
  4. package/lib/commands/apps-android-sha-create.js +2 -2
  5. package/lib/commands/apps-sdkconfig.js +1 -1
  6. package/lib/commands/database-rules-list.js +2 -2
  7. package/lib/commands/emulators-start.js +1 -1
  8. package/lib/commands/ext-configure.js +67 -7
  9. package/lib/commands/ext-dev-init.js +49 -49
  10. package/lib/commands/ext-export.js +7 -2
  11. package/lib/commands/ext-install.js +173 -109
  12. package/lib/commands/ext-uninstall.js +17 -8
  13. package/lib/commands/ext-update.js +67 -12
  14. package/lib/commands/functions-config-export.js +1 -1
  15. package/lib/commands/hosting-clone.js +3 -3
  16. package/lib/commands/remoteconfig-get.js +1 -1
  17. package/lib/config.js +6 -3
  18. package/lib/deploy/extensions/deploymentSummary.js +3 -3
  19. package/lib/deploy/extensions/planner.js +7 -6
  20. package/lib/deploy/extensions/tasks.js +1 -1
  21. package/lib/deploy/functions/backend.js +21 -5
  22. package/lib/deploy/functions/checkIam.js +5 -5
  23. package/lib/deploy/functions/containerCleaner.js +3 -3
  24. package/lib/deploy/functions/ensure.js +3 -3
  25. package/lib/deploy/functions/functionsDeployHelper.js +2 -2
  26. package/lib/deploy/functions/prepare.js +5 -3
  27. package/lib/deploy/functions/pricing.js +1 -1
  28. package/lib/deploy/functions/prompts.js +2 -2
  29. package/lib/deploy/functions/release/fabricator.js +7 -7
  30. package/lib/deploy/functions/release/index.js +1 -1
  31. package/lib/deploy/functions/release/planner.js +43 -26
  32. package/lib/deploy/functions/release/reporter.js +3 -0
  33. package/lib/deploy/functions/runtimes/discovery/index.js +6 -6
  34. package/lib/deploy/functions/runtimes/discovery/parsing.js +1 -1
  35. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +22 -12
  36. package/lib/deploy/functions/runtimes/golang/index.js +2 -2
  37. package/lib/deploy/functions/runtimes/node/index.js +53 -0
  38. package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +2 -2
  39. package/lib/deploy/functions/runtimes/node/parseTriggers.js +64 -20
  40. package/lib/deploy/functions/runtimes/node/versioning.js +2 -2
  41. package/lib/deploy/functions/services/firebaseAlerts.js +30 -0
  42. package/lib/deploy/functions/services/index.js +9 -1
  43. package/lib/deploy/functions/services/storage.js +10 -4
  44. package/lib/deploy/functions/triggerRegionHelper.js +1 -1
  45. package/lib/deploy/functions/validate.js +3 -3
  46. package/lib/deploy/hosting/deploy.js +2 -2
  47. package/lib/deploy/hosting/hashcache.js +21 -19
  48. package/lib/deploy/hosting/uploader.js +5 -5
  49. package/lib/deploy/remoteconfig/functions.js +2 -2
  50. package/lib/emulator/auth/cloudFunctions.js +1 -1
  51. package/lib/emulator/auth/operations.js +1 -1
  52. package/lib/emulator/constants.js +4 -0
  53. package/lib/emulator/controller.js +54 -24
  54. package/lib/emulator/download.js +18 -1
  55. package/lib/emulator/downloadableEmulators.js +1 -1
  56. package/lib/emulator/emulatorLogger.js +12 -1
  57. package/lib/emulator/extensions/validation.js +70 -0
  58. package/lib/emulator/extensionsEmulator.js +175 -0
  59. package/lib/emulator/functionsEmulator.js +95 -43
  60. package/lib/emulator/functionsEmulatorRuntime.js +44 -36
  61. package/lib/emulator/functionsEmulatorShared.js +30 -11
  62. package/lib/emulator/functionsEmulatorShell.js +1 -1
  63. package/lib/emulator/functionsEmulatorUtils.js +4 -4
  64. package/lib/emulator/functionsRuntimeWorker.js +2 -2
  65. package/lib/emulator/hub.js +4 -3
  66. package/lib/emulator/loggingEmulator.js +1 -1
  67. package/lib/emulator/pubsubEmulator.js +1 -1
  68. package/lib/emulator/registry.js +10 -2
  69. package/lib/emulator/storage/apis/firebase.js +314 -332
  70. package/lib/emulator/storage/apis/gcloud.js +241 -121
  71. package/lib/emulator/storage/crc.js +5 -1
  72. package/lib/emulator/storage/errors.js +9 -0
  73. package/lib/emulator/storage/files.js +159 -300
  74. package/lib/emulator/storage/index.js +27 -73
  75. package/lib/emulator/storage/metadata.js +65 -51
  76. package/lib/emulator/storage/multipart.js +62 -0
  77. package/lib/emulator/storage/persistence.js +78 -0
  78. package/lib/emulator/storage/rules/config.js +33 -0
  79. package/lib/emulator/storage/rules/manager.js +81 -0
  80. package/lib/emulator/storage/rules/runtime.js +8 -7
  81. package/lib/emulator/storage/rules/utils.js +48 -0
  82. package/lib/emulator/storage/server.js +2 -2
  83. package/lib/emulator/storage/upload.js +106 -0
  84. package/lib/emulator/types.js +3 -0
  85. package/lib/ensureApiEnabled.js +5 -1
  86. package/lib/error.js +1 -1
  87. package/lib/extensions/askUserForParam.js +31 -25
  88. package/lib/extensions/changelog.js +3 -1
  89. package/lib/extensions/checkProjectBilling.js +1 -1
  90. package/lib/extensions/displayExtensionInfo.js +1 -1
  91. package/lib/extensions/emulator/optionsHelper.js +56 -8
  92. package/lib/extensions/emulator/specHelper.js +10 -23
  93. package/lib/extensions/export.js +1 -51
  94. package/lib/extensions/extensionsApi.js +1 -1
  95. package/lib/extensions/extensionsHelper.js +32 -19
  96. package/lib/extensions/manifest.js +144 -0
  97. package/lib/extensions/metricsUtils.js +4 -4
  98. package/lib/extensions/paramHelper.js +34 -12
  99. package/lib/extensions/refs.js +1 -1
  100. package/lib/extensions/secretsUtils.js +3 -3
  101. package/lib/functional.js +1 -1
  102. package/lib/functions/env.js +6 -7
  103. package/lib/functions/events/v2.js +11 -0
  104. package/lib/gcp/cloudfunctions.js +43 -11
  105. package/lib/gcp/cloudfunctionsv2.js +48 -17
  106. package/lib/gcp/cloudtasks.js +1 -1
  107. package/lib/gcp/docker.js +2 -2
  108. package/lib/gcp/resourceManager.js +4 -4
  109. package/lib/gcp/run.js +2 -2
  110. package/lib/hosting/api.js +1 -1
  111. package/lib/hosting/proxy.js +2 -2
  112. package/lib/init/features/account.js +1 -1
  113. package/lib/management/database.js +1 -1
  114. package/lib/previews.js +1 -1
  115. package/lib/serve/functions.js +2 -1
  116. package/lib/utils.js +15 -2
  117. package/npm-shrinkwrap.json +786 -393
  118. package/package.json +1 -1
  119. package/schema/firebase-config.json +5 -0
  120. package/templates/init/functions/javascript/package.lint.json +3 -3
  121. package/templates/init/functions/javascript/package.nolint.json +2 -2
  122. package/templates/init/functions/typescript/package.lint.json +7 -7
  123. package/templates/init/functions/typescript/package.nolint.json +3 -3
  124. package/lib/deploy/extensions/params.js +0 -39
  125. package/lib/deploy/functions/eventTypes.js +0 -10
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.endpointFromFunction = exports.functionFromEndpoint = exports.deleteFunction = exports.updateFunction = exports.listAllFunctions = exports.listFunctions = exports.getFunction = exports.createFunction = exports.generateUploadUrl = exports.megabytes = exports.PUBSUB_PUBLISH_EVENT = exports.API_VERSION = void 0;
3
+ exports.endpointFromFunction = exports.functionFromEndpoint = exports.deleteFunction = exports.updateFunction = exports.listAllFunctions = exports.listFunctions = exports.getFunction = exports.createFunction = exports.generateUploadUrl = exports.megabytes = 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");
7
7
  const api_1 = require("../api");
8
8
  const logger_1 = require("../logger");
9
+ const v2_1 = require("../functions/events/v2");
9
10
  const backend = require("../deploy/functions/backend");
10
11
  const runtimes = require("../deploy/functions/runtimes");
11
12
  const proto = require("./proto");
@@ -16,7 +17,6 @@ const client = new apiv2_1.Client({
16
17
  auth: true,
17
18
  apiVersion: exports.API_VERSION,
18
19
  });
19
- exports.PUBSUB_PUBLISH_EVENT = "google.cloud.pubsub.topic.v1.messagePublished";
20
20
  const BYTES_PER_UNIT = {
21
21
  "": 1,
22
22
  k: 1e3,
@@ -106,7 +106,7 @@ async function listFunctionsInternal(projectId, region) {
106
106
  let pageToken = "";
107
107
  while (true) {
108
108
  const url = `projects/${projectId}/locations/${region}/functions`;
109
- const opts = pageToken == "" ? {} : { queryParams: { pageToken } };
109
+ const opts = pageToken === "" ? {} : { queryParams: { pageToken } };
110
110
  const res = await client.get(url, opts);
111
111
  functions.push(...(res.body.functions || []));
112
112
  for (const region of res.body.unreachable || []) {
@@ -122,9 +122,10 @@ async function listFunctionsInternal(projectId, region) {
122
122
  }
123
123
  }
124
124
  async function updateFunction(cloudFunction) {
125
+ const fieldMasks = proto.fieldMasks(cloudFunction, "labels", "serviceConfig.environmentVariables");
125
126
  try {
126
127
  const queryParams = {
127
- updateMask: proto.fieldMasks(cloudFunction).join(","),
128
+ updateMask: fieldMasks.join(","),
128
129
  };
129
130
  const res = await client.patch(cloudFunction.name, cloudFunction, { queryParams });
130
131
  return res.body;
@@ -145,7 +146,7 @@ async function deleteFunction(cloudFunction) {
145
146
  }
146
147
  exports.deleteFunction = deleteFunction;
147
148
  function functionFromEndpoint(endpoint, source) {
148
- if (endpoint.platform != "gcfv2") {
149
+ if (endpoint.platform !== "gcfv2") {
149
150
  throw new error_1.FirebaseError("Trying to create a v2 CloudFunction with v1 API. This should never happen");
150
151
  }
151
152
  if (!runtimes.isValidRuntime(endpoint.runtime)) {
@@ -165,28 +166,43 @@ function functionFromEndpoint(endpoint, source) {
165
166
  serviceConfig: {},
166
167
  };
167
168
  proto.copyIfPresent(gcfFunction, endpoint, "labels");
168
- proto.copyIfPresent(gcfFunction.serviceConfig, endpoint, "environmentVariables", "vpcConnector", "vpcConnectorEgressSettings", "serviceAccountEmail", "ingressSettings");
169
+ proto.copyIfPresent(gcfFunction.serviceConfig, endpoint, "environmentVariables", "serviceAccountEmail", "ingressSettings");
169
170
  proto.renameIfPresent(gcfFunction.serviceConfig, endpoint, "availableMemory", "availableMemoryMb", (mb) => `${mb}M`);
170
171
  proto.renameIfPresent(gcfFunction.serviceConfig, endpoint, "timeoutSeconds", "timeout", proto.secondsFromDuration);
171
172
  proto.renameIfPresent(gcfFunction.serviceConfig, endpoint, "minInstanceCount", "minInstances");
172
173
  proto.renameIfPresent(gcfFunction.serviceConfig, endpoint, "maxInstanceCount", "maxInstances");
174
+ if (endpoint.vpc) {
175
+ proto.renameIfPresent(gcfFunction.serviceConfig, endpoint.vpc, "vpcConnector", "connector");
176
+ proto.renameIfPresent(gcfFunction.serviceConfig, endpoint.vpc, "vpcConnectorEgressSettings", "egressSettings");
177
+ }
173
178
  if (backend.isEventTriggered(endpoint)) {
174
179
  gcfFunction.eventTrigger = {
175
180
  eventType: endpoint.eventTrigger.eventType,
176
181
  };
177
- if (gcfFunction.eventTrigger.eventType === exports.PUBSUB_PUBLISH_EVENT) {
178
- gcfFunction.eventTrigger.pubsubTopic = endpoint.eventTrigger.eventFilters.resource;
182
+ if (gcfFunction.eventTrigger.eventType === v2_1.PUBSUB_PUBLISH_EVENT) {
183
+ const pubsubFilter = backend.findEventFilter(endpoint, "topic");
184
+ if (!pubsubFilter) {
185
+ throw new error_1.FirebaseError("Invalid pubsub endpoint. Expected eventFilter with 'topic' attribute but found none.");
186
+ }
187
+ gcfFunction.eventTrigger.pubsubTopic = pubsubFilter.value;
188
+ for (const filter of endpoint.eventTrigger.eventFilters) {
189
+ if (filter.attribute === "topic") {
190
+ continue;
191
+ }
192
+ if (!gcfFunction.eventTrigger.eventFilters) {
193
+ gcfFunction.eventTrigger.eventFilters = [];
194
+ }
195
+ gcfFunction.eventTrigger.eventFilters.push(filter);
196
+ }
179
197
  }
180
198
  else {
181
- gcfFunction.eventTrigger.eventFilters = [];
182
- for (const [attribute, value] of Object.entries(endpoint.eventTrigger.eventFilters)) {
183
- gcfFunction.eventTrigger.eventFilters.push({ attribute, value });
184
- }
199
+ gcfFunction.eventTrigger.eventFilters = endpoint.eventTrigger.eventFilters;
185
200
  }
186
201
  proto.renameIfPresent(gcfFunction.eventTrigger, endpoint.eventTrigger, "triggerRegion", "region");
187
202
  if (endpoint.eventTrigger.retry) {
188
203
  logger_1.logger.warn("Cannot set a retry policy on Cloud Function", endpoint.id);
189
204
  }
205
+ gcfFunction.serviceConfig.environmentVariables = Object.assign(Object.assign({}, gcfFunction.serviceConfig.environmentVariables), { FUNCTION_SIGNATURE_TYPE: "cloudevent" });
190
206
  }
191
207
  else if (backend.isScheduleTriggered(endpoint)) {
192
208
  gcfFunction.labels = Object.assign(Object.assign({}, gcfFunction.labels), { "deployment-scheduled": "true" });
@@ -194,11 +210,14 @@ function functionFromEndpoint(endpoint, source) {
194
210
  else if (backend.isTaskQueueTriggered(endpoint)) {
195
211
  gcfFunction.labels = Object.assign(Object.assign({}, gcfFunction.labels), { "deployment-taskqueue": "true" });
196
212
  }
213
+ else if (backend.isCallableTriggered(endpoint)) {
214
+ gcfFunction.labels = Object.assign(Object.assign({}, gcfFunction.labels), { "deployment-callable": "true" });
215
+ }
197
216
  return gcfFunction;
198
217
  }
199
218
  exports.functionFromEndpoint = functionFromEndpoint;
200
219
  function endpointFromFunction(gcfFunction) {
201
- var _a, _b;
220
+ var _a, _b, _c;
202
221
  const [, project, , region, , id] = gcfFunction.name.split("/");
203
222
  let trigger;
204
223
  if (((_a = gcfFunction.labels) === null || _a === void 0 ? void 0 : _a["deployment-scheduled"]) === "true") {
@@ -211,20 +230,28 @@ function endpointFromFunction(gcfFunction) {
211
230
  taskQueueTrigger: {},
212
231
  };
213
232
  }
233
+ else if (((_c = gcfFunction.labels) === null || _c === void 0 ? void 0 : _c["deployment-callable"]) === "true") {
234
+ trigger = {
235
+ callableTrigger: {},
236
+ };
237
+ }
214
238
  else if (gcfFunction.eventTrigger) {
215
239
  trigger = {
216
240
  eventTrigger: {
217
241
  eventType: gcfFunction.eventTrigger.eventType,
218
- eventFilters: {},
242
+ eventFilters: [],
219
243
  retry: false,
220
244
  },
221
245
  };
222
246
  if (gcfFunction.eventTrigger.pubsubTopic) {
223
- trigger.eventTrigger.eventFilters.resource = gcfFunction.eventTrigger.pubsubTopic;
247
+ trigger.eventTrigger.eventFilters.push({
248
+ attribute: "topic",
249
+ value: gcfFunction.eventTrigger.pubsubTopic,
250
+ });
224
251
  }
225
252
  else {
226
253
  for (const { attribute, value } of gcfFunction.eventTrigger.eventFilters || []) {
227
- trigger.eventTrigger.eventFilters[attribute] = value;
254
+ trigger.eventTrigger.eventFilters.push({ attribute, value });
228
255
  }
229
256
  }
230
257
  proto.renameIfPresent(trigger.eventTrigger, gcfFunction.eventTrigger, "region", "triggerRegion");
@@ -238,12 +265,16 @@ function endpointFromFunction(gcfFunction) {
238
265
  const endpoint = Object.assign(Object.assign({ platform: "gcfv2", id,
239
266
  project,
240
267
  region }, trigger), { entryPoint: gcfFunction.buildConfig.entryPoint, runtime: gcfFunction.buildConfig.runtime, uri: gcfFunction.serviceConfig.uri });
241
- proto.copyIfPresent(endpoint, gcfFunction.serviceConfig, "serviceAccountEmail", "vpcConnector", "vpcConnectorEgressSettings", "ingressSettings", "environmentVariables");
268
+ proto.copyIfPresent(endpoint, gcfFunction.serviceConfig, "serviceAccountEmail", "ingressSettings", "environmentVariables");
242
269
  proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "availableMemoryMb", "availableMemory", megabytes);
243
270
  proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "timeout", "timeoutSeconds", proto.durationFromSeconds);
244
271
  proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "minInstances", "minInstanceCount");
245
272
  proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "maxInstances", "maxInstanceCount");
246
273
  proto.copyIfPresent(endpoint, gcfFunction, "labels");
274
+ if (gcfFunction.serviceConfig.vpcConnector) {
275
+ endpoint.vpc = { connector: gcfFunction.serviceConfig.vpcConnector };
276
+ proto.renameIfPresent(endpoint.vpc, gcfFunction.serviceConfig, "egressSettings", "vpcConnectorEgressSettings");
277
+ }
247
278
  return endpoint;
248
279
  }
249
280
  exports.endpointFromFunction = endpointFromFunction;
@@ -102,7 +102,7 @@ async function setEnqueuer(name, invoker, assumeEmpty = false) {
102
102
  const invokerMembers = proto.getInvokerMembers(invoker, project);
103
103
  while (true) {
104
104
  const policy = {
105
- bindings: existing.bindings.filter((binding) => binding.role != ENQUEUER_ROLE),
105
+ bindings: existing.bindings.filter((binding) => binding.role !== ENQUEUER_ROLE),
106
106
  etag: existing.etag,
107
107
  version: existing.version,
108
108
  };
package/lib/gcp/docker.js CHANGED
@@ -58,7 +58,7 @@ class Client {
58
58
  if (!response.body) {
59
59
  return;
60
60
  }
61
- if (((_a = response.body.errors) === null || _a === void 0 ? void 0 : _a.length) != 0) {
61
+ if (((_a = response.body.errors) === null || _a === void 0 ? void 0 : _a.length) !== 0) {
62
62
  throw new error_1.FirebaseError(`Failed to delete tag ${tag} at path ${path}`, {
63
63
  children: response.body.errors,
64
64
  });
@@ -70,7 +70,7 @@ class Client {
70
70
  if (!response.body) {
71
71
  return;
72
72
  }
73
- if (((_a = response.body.errors) === null || _a === void 0 ? void 0 : _a.length) != 0) {
73
+ if (((_a = response.body.errors) === null || _a === void 0 ? void 0 : _a.length) !== 0) {
74
74
  throw new error_1.FirebaseError(`Failed to delete image ${digest} at path ${path}`, {
75
75
  children: response.body.errors,
76
76
  });
@@ -13,13 +13,13 @@ exports.firebaseRoles = {
13
13
  hostingAdmin: "roles/firebasehosting.admin",
14
14
  runViewer: "roles/run.viewer",
15
15
  };
16
- async function getIamPolicy(projectId) {
17
- const response = await apiClient.post(`/projects/${projectId}:getIamPolicy`);
16
+ async function getIamPolicy(projectIdOrNumber) {
17
+ const response = await apiClient.post(`/projects/${projectIdOrNumber}:getIamPolicy`);
18
18
  return response.body;
19
19
  }
20
20
  exports.getIamPolicy = getIamPolicy;
21
- async function setIamPolicy(projectId, newPolicy, updateMask = "") {
22
- const response = await apiClient.post(`/projects/${projectId}:setIamPolicy`, {
21
+ async function setIamPolicy(projectIdOrNumber, newPolicy, updateMask = "") {
22
+ const response = await apiClient.post(`/projects/${projectIdOrNumber}:setIamPolicy`, {
23
23
  policy: newPolicy,
24
24
  updateMask: updateMask,
25
25
  });
package/lib/gcp/run.js CHANGED
@@ -63,7 +63,7 @@ async function getIamPolicy(serviceName, httpClient = client) {
63
63
  }
64
64
  exports.getIamPolicy = getIamPolicy;
65
65
  async function setInvokerCreate(projectId, serviceName, invoker, httpClient = client) {
66
- if (invoker.length == 0) {
66
+ if (invoker.length === 0) {
67
67
  throw new error_1.FirebaseError("Invoker cannot be an empty array");
68
68
  }
69
69
  const invokerMembers = proto.getInvokerMembers(invoker, projectId);
@@ -79,7 +79,7 @@ async function setInvokerCreate(projectId, serviceName, invoker, httpClient = cl
79
79
  exports.setInvokerCreate = setInvokerCreate;
80
80
  async function setInvokerUpdate(projectId, serviceName, invoker, httpClient = client) {
81
81
  var _a;
82
- if (invoker.length == 0) {
82
+ if (invoker.length === 0) {
83
83
  throw new error_1.FirebaseError("Invoker cannot be an empty array");
84
84
  }
85
85
  const invokerMembers = proto.getInvokerMembers(invoker, projectId);
@@ -192,7 +192,7 @@ async function removeAuthDomain(project, url) {
192
192
  return domains;
193
193
  }
194
194
  const targetDomain = url.replace("https://", "");
195
- const authDomains = domains.filter((domain) => domain != targetDomain);
195
+ const authDomains = domains.filter((domain) => domain !== targetDomain);
196
196
  return (0, auth_1.updateAuthDomains)(project, authDomains);
197
197
  }
198
198
  exports.removeAuthDomain = removeAuthDomain;
@@ -54,7 +54,7 @@ function proxyRequestHandler(url, rewriteIdentifier) {
54
54
  continue;
55
55
  }
56
56
  const value = req.headers[key];
57
- if (value == undefined) {
57
+ if (value === undefined) {
58
58
  headers.delete(key);
59
59
  }
60
60
  else if (Array.isArray(value)) {
@@ -115,7 +115,7 @@ function proxyRequestHandler(url, rewriteIdentifier) {
115
115
  if (location) {
116
116
  try {
117
117
  const locationURL = new url_1.URL(location);
118
- if (locationURL.origin == u.origin) {
118
+ if (locationURL.origin === u.origin) {
119
119
  const unborkedLocation = location.replace(locationURL.origin, "");
120
120
  proxyRes.response.headers.set("location", unborkedLocation);
121
121
  }
@@ -27,7 +27,7 @@ async function promptForAccount() {
27
27
  message: "Please select an option:",
28
28
  choices,
29
29
  });
30
- if (emailChoice == "__add__") {
30
+ if (emailChoice === "__add__") {
31
31
  const newAccount = await (0, auth_1.loginAdditionalAccount)(true);
32
32
  if (!newAccount) {
33
33
  throw new error_1.FirebaseError("Failed to add new account", { exit: 1 });
@@ -168,7 +168,7 @@ function convertDatabaseInstance(serverInstance) {
168
168
  throw new error_1.FirebaseError(`DatabaseInstance response is missing field "name"`);
169
169
  }
170
170
  const m = serverInstance.name.match(INSTANCE_RESOURCE_NAME_REGEX);
171
- if (!m || m.length != 4) {
171
+ if (!m || m.length !== 4) {
172
172
  throw new error_1.FirebaseError(`Error parsing instance resource name: ${serverInstance.name}, matches: ${m}`);
173
173
  }
174
174
  return {
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, artifactregistry: false, emulatoruisnapshot: false }, configstore_1.configstore.get("previews"));
6
+ exports.previews = Object.assign({ rtdbrules: false, ext: false, extdev: false, extensionsemulator: false, rtdbmanagement: false, functionsv2: false, golang: false, deletegcfartifacts: false, artifactregistry: false, emulatoruisnapshot: 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 ((0, lodash_1.has)(exports.previews, feature)) {
@@ -29,8 +29,9 @@ class FunctionsServer {
29
29
  functionsDir,
30
30
  nodeMajorVersion,
31
31
  env: {},
32
+ secretEnv: [],
32
33
  };
33
- const args = Object.assign({ projectId, projectDir: options.config.projectDir, emulatableBackends: [this.backend], account }, partialArgs);
34
+ const args = Object.assign({ projectId, projectDir: options.config.projectDir, emulatableBackends: [this.backend], projectAlias: options.projectAlias, account }, partialArgs);
34
35
  if (options.host) {
35
36
  utils.assertIsStringOrUndefined(options.host);
36
37
  args.host = options.host;
package/lib/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.assertIsStringOrUndefined = exports.assertIsNumber = exports.assertIsString = exports.assertDefined = exports.thirtyDaysFromNow = exports.isRunningInWSL = exports.isCloudEnvironment = exports.datetimeString = exports.createDestroyer = exports.promiseWithSpinner = exports.setupLoggers = exports.tryParse = exports.tryStringify = exports.promiseProps = exports.promiseWhile = exports.promiseAllSettled = exports.getFunctionsEventProvider = exports.endpoint = exports.makeActiveProject = exports.streamToString = exports.stringToStream = exports.explainStdin = exports.allSettled = exports.reject = exports.logLabeledError = exports.logLabeledWarning = exports.logWarning = exports.logLabeledBullet = exports.logBullet = exports.logLabeledSuccess = exports.logSuccess = exports.addSubdomain = exports.addDatabaseNamespace = exports.getDatabaseViewDataUrl = exports.getDatabaseUrl = exports.envOverride = exports.getInheritedOption = exports.consoleUrl = exports.envOverrides = void 0;
3
+ exports.groupBy = exports.assertIsStringOrUndefined = exports.assertIsNumber = exports.assertIsString = exports.assertDefined = exports.thirtyDaysFromNow = exports.isRunningInWSL = exports.isCloudEnvironment = exports.datetimeString = exports.createDestroyer = exports.promiseWithSpinner = exports.setupLoggers = exports.tryParse = exports.tryStringify = exports.promiseProps = exports.promiseWhile = exports.promiseAllSettled = exports.getFunctionsEventProvider = exports.endpoint = exports.makeActiveProject = exports.streamToString = exports.stringToStream = exports.explainStdin = exports.allSettled = exports.reject = exports.logLabeledError = exports.logLabeledWarning = exports.logWarning = exports.logLabeledBullet = exports.logBullet = exports.logLabeledSuccess = exports.logSuccess = exports.addSubdomain = exports.addDatabaseNamespace = exports.getDatabaseViewDataUrl = exports.getDatabaseUrl = exports.envOverride = exports.getInheritedOption = exports.consoleUrl = exports.envOverrides = void 0;
4
4
  const _ = require("lodash");
5
5
  const url = require("url");
6
6
  const clc = require("cli-color");
@@ -295,7 +295,7 @@ function setupLoggers() {
295
295
  logger_1.logger.add(new winston.transports.Console({
296
296
  level: "info",
297
297
  format: winston.format.printf((info) => [info.message, ...(info[triple_beam_1.SPLAT] || [])]
298
- .filter((chunk) => typeof chunk == "string")
298
+ .filter((chunk) => typeof chunk === "string")
299
299
  .join(" ")),
300
300
  }));
301
301
  }
@@ -393,3 +393,16 @@ function assertIsStringOrUndefined(val, message) {
393
393
  }
394
394
  }
395
395
  exports.assertIsStringOrUndefined = assertIsStringOrUndefined;
396
+ function groupBy(arr, f) {
397
+ return arr.reduce((result, item) => {
398
+ const key = f(item);
399
+ if (result[key]) {
400
+ result[key].push(item);
401
+ }
402
+ else {
403
+ result[key] = [item];
404
+ }
405
+ return result;
406
+ }, {});
407
+ }
408
+ exports.groupBy = groupBy;