firebase-tools 10.7.0 → 10.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.
Files changed (64) hide show
  1. package/lib/commands/ext-configure.js +26 -15
  2. package/lib/commands/ext-export.js +14 -5
  3. package/lib/commands/ext-install.js +31 -2
  4. package/lib/commands/ext-update.js +17 -10
  5. package/lib/commands/functions-delete.js +9 -2
  6. package/lib/commands/functions-secrets-set.js +1 -13
  7. package/lib/deploy/extensions/planner.js +12 -0
  8. package/lib/deploy/extensions/tasks.js +13 -0
  9. package/lib/deploy/functions/backend.js +67 -10
  10. package/lib/deploy/functions/build.js +28 -9
  11. package/lib/deploy/functions/checkIam.js +71 -56
  12. package/lib/deploy/functions/containerCleaner.js +8 -7
  13. package/lib/deploy/functions/deploy.js +49 -27
  14. package/lib/deploy/functions/functionsDeployHelper.js +48 -4
  15. package/lib/deploy/functions/prepare.js +125 -74
  16. package/lib/deploy/functions/pricing.js +2 -2
  17. package/lib/deploy/functions/release/executor.js +1 -1
  18. package/lib/deploy/functions/release/fabricator.js +94 -36
  19. package/lib/deploy/functions/release/index.js +16 -27
  20. package/lib/deploy/functions/release/planner.js +12 -7
  21. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +13 -1
  22. package/lib/deploy/functions/runtimes/golang/index.js +3 -0
  23. package/lib/deploy/functions/runtimes/node/index.js +7 -0
  24. package/lib/deploy/functions/runtimes/node/parseTriggers.js +108 -1
  25. package/lib/deploy/functions/services/storage.js +6 -12
  26. package/lib/deploy/functions/validate.js +58 -8
  27. package/lib/deploy/hosting/convertConfig.js +6 -4
  28. package/lib/emulator/auth/cloudFunctions.js +6 -2
  29. package/lib/emulator/auth/operations.js +0 -1
  30. package/lib/emulator/auth/server.js +8 -1
  31. package/lib/emulator/auth/state.js +27 -24
  32. package/lib/emulator/controller.js +12 -9
  33. package/lib/emulator/databaseEmulator.js +36 -3
  34. package/lib/emulator/downloadableEmulators.js +7 -7
  35. package/lib/emulator/extensionsEmulator.js +3 -0
  36. package/lib/emulator/functionsEmulator.js +11 -9
  37. package/lib/emulator/functionsEmulatorRuntime.js +1 -1
  38. package/lib/emulator/functionsEmulatorShared.js +5 -1
  39. package/lib/emulator/functionsEmulatorShell.js +2 -3
  40. package/lib/emulator/functionsEmulatorUtils.js +5 -1
  41. package/lib/emulator/pubsubEmulator.js +13 -9
  42. package/lib/emulator/storage/apis/firebase.js +26 -4
  43. package/lib/ensureApiEnabled.js +1 -1
  44. package/lib/extensions/askUserForEventsConfig.js +97 -0
  45. package/lib/extensions/export.js +7 -0
  46. package/lib/extensions/extensionsApi.js +47 -7
  47. package/lib/extensions/manifest.js +1 -1
  48. package/lib/extensions/paramHelper.js +2 -0
  49. package/lib/extensions/updateHelper.js +7 -1
  50. package/lib/extensions/warnings.js +11 -4
  51. package/lib/functions/projectConfig.js +13 -8
  52. package/lib/functionsShellCommandAction.js +1 -1
  53. package/lib/gcp/cloudfunctions.js +9 -2
  54. package/lib/gcp/cloudfunctionsv2.js +28 -10
  55. package/lib/gcp/serviceusage.js +24 -0
  56. package/lib/previews.js +1 -1
  57. package/lib/serve/functions.js +16 -19
  58. package/lib/throttler/throttler.js +2 -1
  59. package/npm-shrinkwrap.json +214 -527
  60. package/package.json +3 -3
  61. package/templates/extensions/typescript/package.lint.json +2 -1
  62. package/templates/extensions/typescript/package.nolint.json +2 -1
  63. package/templates/init/functions/typescript/package.lint.json +1 -0
  64. package/templates/init/functions/typescript/package.nolint.json +1 -0
@@ -1,6 +1,6 @@
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.BLOCKING_LABEL = exports.CODEBASE_LABEL = 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.mebibytes = exports.BLOCKING_LABEL = exports.CODEBASE_LABEL = 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");
@@ -39,7 +39,7 @@ const BYTES_PER_UNIT = {
39
39
  Gi: 1 << 30,
40
40
  Ti: 1 << 40,
41
41
  };
42
- function megabytes(memory) {
42
+ function mebibytes(memory) {
43
43
  const re = /^([0-9]+(\.[0-9]*)?)(Ki|Mi|Gi|Ti|k|M|G|T|([eE]([0-9]+)))?$/;
44
44
  const matches = re.exec(memory);
45
45
  if (!matches) {
@@ -54,14 +54,18 @@ function megabytes(memory) {
54
54
  const suffix = matches[3] || "";
55
55
  bytes = quantity * BYTES_PER_UNIT[suffix];
56
56
  }
57
- return bytes / 1e6;
57
+ return bytes / (1 << 20);
58
58
  }
59
- exports.megabytes = megabytes;
59
+ exports.mebibytes = mebibytes;
60
60
  function functionsOpLogReject(funcName, type, err) {
61
61
  var _a, _b;
62
+ utils.logWarning(clc.bold.yellow("functions:") + ` ${err === null || err === void 0 ? void 0 : err.message}`);
62
63
  if (((_b = (_a = err === null || err === void 0 ? void 0 : err.context) === null || _a === void 0 ? void 0 : _a.response) === null || _b === void 0 ? void 0 : _b.statusCode) === 429) {
63
64
  utils.logWarning(`${clc.bold.yellow("functions:")} got "Quota Exceeded" error while trying to ${type} ${funcName}. Waiting to retry...`);
64
65
  }
66
+ else if (err === null || err === void 0 ? void 0 : err.message.includes("If you recently started to use Eventarc, it may take a few minutes before all necessary permissions are propagated to the Service Agent")) {
67
+ utils.logWarning(`${clc.bold.yellow("functions:")} since this is your first time using functions v2, we need a little bit longer to finish setting everything up, please retry the deployment in a few minutes.`);
68
+ }
65
69
  else {
66
70
  utils.logWarning(clc.bold.yellow("functions:") + " failed to " + type + " function " + funcName);
67
71
  }
@@ -133,7 +137,7 @@ async function listFunctionsInternal(projectId, region) {
133
137
  }
134
138
  }
135
139
  async function updateFunction(cloudFunction) {
136
- const fieldMasks = proto.fieldMasks(cloudFunction, "labels", "serviceConfig.environmentVariables");
140
+ const fieldMasks = proto.fieldMasks(cloudFunction, "labels", "serviceConfig.environmentVariables", "serviceConfig.secretEnvironmentVariables");
137
141
  try {
138
142
  const queryParams = {
139
143
  updateMask: fieldMasks.join(","),
@@ -157,6 +161,7 @@ async function deleteFunction(cloudFunction) {
157
161
  }
158
162
  exports.deleteFunction = deleteFunction;
159
163
  function functionFromEndpoint(endpoint, source) {
164
+ var _a;
160
165
  if (endpoint.platform !== "gcfv2") {
161
166
  throw new error_1.FirebaseError("Trying to create a v2 CloudFunction with v1 API. This should never happen");
162
167
  }
@@ -177,8 +182,15 @@ function functionFromEndpoint(endpoint, source) {
177
182
  serviceConfig: {},
178
183
  };
179
184
  proto.copyIfPresent(gcfFunction, endpoint, "labels");
180
- proto.copyIfPresent(gcfFunction.serviceConfig, endpoint, "environmentVariables", "serviceAccountEmail", "ingressSettings", "timeoutSeconds");
181
- proto.renameIfPresent(gcfFunction.serviceConfig, endpoint, "availableMemory", "availableMemoryMb", (mb) => `${mb}M`);
185
+ proto.copyIfPresent(gcfFunction.serviceConfig, endpoint, "environmentVariables", "secretEnvironmentVariables", "serviceAccountEmail", "ingressSettings", "timeoutSeconds");
186
+ proto.renameIfPresent(gcfFunction.serviceConfig, endpoint, "availableMemory", "availableMemoryMb", (mb) => {
187
+ if (mb > 1024) {
188
+ return `${mb / 1024}Gi`;
189
+ }
190
+ else {
191
+ return `${mb}Mi`;
192
+ }
193
+ });
182
194
  proto.renameIfPresent(gcfFunction.serviceConfig, endpoint, "minInstanceCount", "minInstances");
183
195
  proto.renameIfPresent(gcfFunction.serviceConfig, endpoint, "maxInstanceCount", "maxInstances");
184
196
  if (endpoint.vpc) {
@@ -223,7 +235,13 @@ function functionFromEndpoint(endpoint, source) {
223
235
  else if (backend.isBlockingTriggered(endpoint)) {
224
236
  gcfFunction.labels = Object.assign(Object.assign({}, gcfFunction.labels), { [exports.BLOCKING_LABEL]: BLOCKING_EVENT_TO_LABEL_KEY[endpoint.blockingTrigger.eventType] });
225
237
  }
226
- gcfFunction.labels = Object.assign(Object.assign({}, gcfFunction.labels), { [exports.CODEBASE_LABEL]: endpoint.codebase || projectConfig.DEFAULT_CODEBASE });
238
+ const codebase = endpoint.codebase || projectConfig.DEFAULT_CODEBASE;
239
+ if (codebase !== projectConfig.DEFAULT_CODEBASE) {
240
+ gcfFunction.labels = Object.assign(Object.assign({}, gcfFunction.labels), { [exports.CODEBASE_LABEL]: codebase });
241
+ }
242
+ else {
243
+ (_a = gcfFunction.labels) === null || _a === void 0 ? true : delete _a[exports.CODEBASE_LABEL];
244
+ }
227
245
  return gcfFunction;
228
246
  }
229
247
  exports.functionFromEndpoint = functionFromEndpoint;
@@ -281,8 +299,8 @@ function endpointFromFunction(gcfFunction) {
281
299
  const endpoint = Object.assign(Object.assign({ platform: "gcfv2", id,
282
300
  project,
283
301
  region }, trigger), { entryPoint: gcfFunction.buildConfig.entryPoint, runtime: gcfFunction.buildConfig.runtime, uri: gcfFunction.serviceConfig.uri });
284
- proto.copyIfPresent(endpoint, gcfFunction.serviceConfig, "serviceAccountEmail", "ingressSettings", "environmentVariables", "timeoutSeconds");
285
- proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "availableMemoryMb", "availableMemory", megabytes);
302
+ proto.copyIfPresent(endpoint, gcfFunction.serviceConfig, "serviceAccountEmail", "ingressSettings", "environmentVariables", "secretEnvironmentVariables", "timeoutSeconds");
303
+ proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "availableMemoryMb", "availableMemory", mebibytes);
286
304
  proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "minInstances", "minInstanceCount");
287
305
  proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "maxInstances", "maxInstanceCount");
288
306
  proto.copyIfPresent(endpoint, gcfFunction, "labels");
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateServiceIdentity = void 0;
4
+ const cli_color_1 = require("cli-color");
5
+ const api_1 = require("../api");
6
+ const apiv2_1 = require("../apiv2");
7
+ const error_1 = require("../error");
8
+ const utils = require("../utils");
9
+ const apiClient = new apiv2_1.Client({
10
+ urlPrefix: api_1.serviceUsageOrigin,
11
+ apiVersion: "v1beta1",
12
+ });
13
+ async function generateServiceIdentity(projectNumber, service, prefix) {
14
+ utils.logLabeledBullet(prefix, `generating the service identity for ${(0, cli_color_1.bold)(service)}...`);
15
+ try {
16
+ return await apiClient.post(`projects/${projectNumber}/services/${service}:generateServiceIdentity`);
17
+ }
18
+ catch (err) {
19
+ throw new error_1.FirebaseError(`Error generating the service identity for ${service}.`, {
20
+ original: err,
21
+ });
22
+ }
23
+ }
24
+ exports.generateServiceIdentity = generateServiceIdentity;
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, extensionsemulator: false, rtdbmanagement: false, functionsv2: false, golang: false, deletegcfartifacts: false, artifactregistry: false, emulatoruisnapshot: false, frameworkawareness: 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, frameworkawareness: false, functionsparams: 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)) {
@@ -10,28 +10,29 @@ const auth_1 = require("../auth");
10
10
  const projectConfig = require("../functions/projectConfig");
11
11
  const utils = require("../utils");
12
12
  class FunctionsServer {
13
- constructor() {
14
- this.emulatorServer = undefined;
15
- this.backend = undefined;
16
- }
17
13
  assertServer() {
18
- if (!this.emulatorServer || !this.backend) {
14
+ if (!this.emulatorServer || !this.backends) {
19
15
  throw new Error("Must call start() before calling any other operation!");
20
16
  }
21
17
  }
22
18
  async start(options, partialArgs) {
23
19
  const projectId = (0, projectUtils_1.needProjectId)(options);
24
- const config = projectConfig.normalizeAndValidate(options.config.src.functions)[0];
25
- const functionsDir = path.join(options.config.projectDir, config.source);
20
+ const config = projectConfig.normalizeAndValidate(options.config.src.functions);
21
+ const backends = [];
22
+ for (const cfg of config) {
23
+ const functionsDir = path.join(options.config.projectDir, cfg.source);
24
+ const nodeMajorVersion = (0, functionsEmulatorUtils_1.parseRuntimeVersion)(cfg.runtime);
25
+ backends.push({
26
+ functionsDir,
27
+ codebase: cfg.codebase,
28
+ nodeMajorVersion,
29
+ env: {},
30
+ secretEnv: [],
31
+ });
32
+ }
33
+ this.backends = backends;
26
34
  const account = (0, auth_1.getProjectDefaultAccount)(options.config.projectDir);
27
- const nodeMajorVersion = (0, functionsEmulatorUtils_1.parseRuntimeVersion)(config.runtime);
28
- this.backend = {
29
- functionsDir,
30
- nodeMajorVersion,
31
- env: {},
32
- secretEnv: [],
33
- };
34
- const args = Object.assign({ projectId, projectDir: options.config.projectDir, emulatableBackends: [this.backend], projectAlias: options.projectAlias, account }, partialArgs);
35
+ const args = Object.assign({ projectId, projectDir: options.config.projectDir, emulatableBackends: this.backends, projectAlias: options.projectAlias, account }, partialArgs);
35
36
  if (options.host) {
36
37
  utils.assertIsStringOrUndefined(options.host);
37
38
  args.host = options.host;
@@ -59,10 +60,6 @@ class FunctionsServer {
59
60
  this.assertServer();
60
61
  await this.emulatorServer.stop();
61
62
  }
62
- getBackend() {
63
- this.assertServer();
64
- return this.backend;
65
- }
66
63
  get() {
67
64
  this.assertServer();
68
65
  return this.emulatorServer.get();
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Throttler = exports.timeToWait = void 0;
3
+ exports.Throttler = exports.timeToWait = exports.backoff = void 0;
4
4
  const logger_1 = require("../logger");
5
5
  const retries_exhausted_error_1 = require("./errors/retries-exhausted-error");
6
6
  const timeout_error_1 = require("./errors/timeout-error");
@@ -9,6 +9,7 @@ function backoff(retryNumber, delay, maxDelay) {
9
9
  setTimeout(resolve, timeToWait(retryNumber, delay, maxDelay));
10
10
  });
11
11
  }
12
+ exports.backoff = backoff;
12
13
  function timeToWait(retryNumber, delay, maxDelay) {
13
14
  return Math.min(delay * Math.pow(2, retryNumber), maxDelay);
14
15
  }