firebase-tools 10.7.2 → 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 (36) 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-secrets-set.js +1 -13
  6. package/lib/deploy/extensions/planner.js +12 -0
  7. package/lib/deploy/extensions/tasks.js +13 -0
  8. package/lib/deploy/functions/backend.js +47 -10
  9. package/lib/deploy/functions/build.js +9 -1
  10. package/lib/deploy/functions/checkIam.js +65 -46
  11. package/lib/deploy/functions/functionsDeployHelper.js +1 -1
  12. package/lib/deploy/functions/prepare.js +42 -6
  13. package/lib/deploy/functions/pricing.js +2 -2
  14. package/lib/deploy/functions/release/fabricator.js +66 -11
  15. package/lib/deploy/functions/release/index.js +0 -21
  16. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +13 -1
  17. package/lib/deploy/functions/services/storage.js +6 -12
  18. package/lib/deploy/functions/validate.js +33 -6
  19. package/lib/emulator/extensionsEmulator.js +3 -0
  20. package/lib/extensions/askUserForEventsConfig.js +97 -0
  21. package/lib/extensions/export.js +7 -0
  22. package/lib/extensions/extensionsApi.js +47 -7
  23. package/lib/extensions/manifest.js +1 -1
  24. package/lib/extensions/updateHelper.js +7 -1
  25. package/lib/extensions/warnings.js +3 -3
  26. package/lib/gcp/cloudfunctions.js +1 -1
  27. package/lib/gcp/cloudfunctionsv2.js +7 -3
  28. package/lib/gcp/serviceusage.js +24 -0
  29. package/lib/previews.js +1 -1
  30. package/lib/throttler/throttler.js +2 -1
  31. package/npm-shrinkwrap.json +2 -2
  32. package/package.json +1 -1
  33. package/templates/extensions/typescript/package.lint.json +2 -1
  34. package/templates/extensions/typescript/package.nolint.json +2 -1
  35. package/templates/init/functions/typescript/package.lint.json +1 -0
  36. package/templates/init/functions/typescript/package.nolint.json +1 -0
@@ -59,13 +59,16 @@ async function displayChanges(args) {
59
59
  }
60
60
  exports.displayChanges = displayChanges;
61
61
  async function update(updateOptions) {
62
- const { projectId, instanceId, source, extRef, params } = updateOptions;
62
+ const { projectId, instanceId, source, extRef, params, canEmitEvents, allowedEventTypes, eventarcChannel, } = updateOptions;
63
63
  if (extRef) {
64
64
  return await extensionsApi.updateInstanceFromRegistry({
65
65
  projectId,
66
66
  instanceId,
67
67
  extRef,
68
68
  params,
69
+ canEmitEvents,
70
+ allowedEventTypes,
71
+ eventarcChannel,
69
72
  });
70
73
  }
71
74
  else if (source) {
@@ -74,6 +77,9 @@ async function update(updateOptions) {
74
77
  instanceId,
75
78
  extensionSource: source,
76
79
  params,
80
+ canEmitEvents,
81
+ allowedEventTypes,
82
+ eventarcChannel,
77
83
  });
78
84
  }
79
85
  throw new error_1.FirebaseError(`Neither a source nor a version of the extension was supplied for ${instanceId}. Please make sure this is a valid extension and try again.`);
@@ -58,13 +58,13 @@ async function displayWarningsForDeploy(instancesToCreate) {
58
58
  const experimental = nonEapExtensions.filter((i) => i.extension.registryLaunchStage === extensionsApi_1.RegistryLaunchStage.EXPERIMENTAL);
59
59
  if (experimental.length) {
60
60
  const humanReadableList = experimental.map((i) => `\t${(0, deploymentSummary_1.humanReadable)(i)}`).join("\n");
61
- utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked(`The following are instances of ${clc.bold("experimental")} extensions.They may not be production-ready. Their functionality may change in backward-incompatible ways before their official release, or they may be discontinued.\n${humanReadableList}\n`));
61
+ utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked(`The following are instances of ${clc.bold("experimental")} extensions.They may not be production-ready. Their functionality may change in backward-incompatible ways before their official release, or they may be discontinued.\n${humanReadableList}\n`, { gfm: false }));
62
62
  }
63
63
  if (eapExtensions.length) {
64
64
  const humanReadableList = eapExtensions.map(toListEntry).join("\n");
65
- utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked(`These extensions are in preview and are built by a developer in the Extensions Publisher Early Access Program (http://bit.ly/firex-provider. Their functionality might change in backwards-incompatible ways. Since these extensions aren't built by Firebase, reach out to their publisher with questions about them.` +
65
+ utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked(`These extensions are in preview and are built by a developer in the Extensions Publisher Early Access Program (http://bit.ly/firex-provider). Their functionality might change in backwards-incompatible ways. Since these extensions aren't built by Firebase, reach out to their publisher with questions about them.` +
66
66
  ` They are provided “AS IS”, without any warranty, express or implied, from Google.` +
67
- ` Google disclaims all liability for any damages, direct or indirect, resulting from the use of these extensions\n${humanReadableList}`));
67
+ ` Google disclaims all liability for any damages, direct or indirect, resulting from the use of these extensions\n${humanReadableList}`, { gfm: false }));
68
68
  }
69
69
  return experimental.length > 0 || eapExtensions.length > 0;
70
70
  }
@@ -145,7 +145,7 @@ async function setInvokerUpdate(projectId, fnName, invoker) {
145
145
  exports.setInvokerUpdate = setInvokerUpdate;
146
146
  async function updateFunction(cloudFunction) {
147
147
  const endpoint = `/${cloudFunction.name}`;
148
- const fieldMasks = proto.fieldMasks(cloudFunction, "labels", "environmentVariables");
148
+ const fieldMasks = proto.fieldMasks(cloudFunction, "labels", "environmentVariables", "secretEnvironmentVariables");
149
149
  try {
150
150
  const headers = {};
151
151
  if (previews_1.previews.artifactregistry) {
@@ -59,9 +59,13 @@ function mebibytes(memory) {
59
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(","),
@@ -178,7 +182,7 @@ function functionFromEndpoint(endpoint, source) {
178
182
  serviceConfig: {},
179
183
  };
180
184
  proto.copyIfPresent(gcfFunction, endpoint, "labels");
181
- proto.copyIfPresent(gcfFunction.serviceConfig, endpoint, "environmentVariables", "serviceAccountEmail", "ingressSettings", "timeoutSeconds");
185
+ proto.copyIfPresent(gcfFunction.serviceConfig, endpoint, "environmentVariables", "secretEnvironmentVariables", "serviceAccountEmail", "ingressSettings", "timeoutSeconds");
182
186
  proto.renameIfPresent(gcfFunction.serviceConfig, endpoint, "availableMemory", "availableMemoryMb", (mb) => {
183
187
  if (mb > 1024) {
184
188
  return `${mb / 1024}Gi`;
@@ -295,7 +299,7 @@ function endpointFromFunction(gcfFunction) {
295
299
  const endpoint = Object.assign(Object.assign({ platform: "gcfv2", id,
296
300
  project,
297
301
  region }, trigger), { entryPoint: gcfFunction.buildConfig.entryPoint, runtime: gcfFunction.buildConfig.runtime, uri: gcfFunction.serviceConfig.uri });
298
- proto.copyIfPresent(endpoint, gcfFunction.serviceConfig, "serviceAccountEmail", "ingressSettings", "environmentVariables", "timeoutSeconds");
302
+ proto.copyIfPresent(endpoint, gcfFunction.serviceConfig, "serviceAccountEmail", "ingressSettings", "environmentVariables", "secretEnvironmentVariables", "timeoutSeconds");
299
303
  proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "availableMemoryMb", "availableMemory", mebibytes);
300
304
  proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "minInstances", "minInstanceCount");
301
305
  proto.renameIfPresent(endpoint, gcfFunction.serviceConfig, "maxInstances", "maxInstanceCount");
@@ -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)) {
@@ -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
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "firebase-tools",
3
- "version": "10.7.2",
3
+ "version": "10.8.0",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "firebase-tools",
9
- "version": "10.7.2",
9
+ "version": "10.8.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@google-cloud/pubsub": "^2.18.4",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-tools",
3
- "version": "10.7.2",
3
+ "version": "10.8.0",
4
4
  "description": "Command-Line Interface for Firebase",
5
5
  "main": "./lib/index.js",
6
6
  "bin": {
@@ -2,7 +2,8 @@
2
2
  "name": "functions",
3
3
  "scripts": {
4
4
  "lint": "eslint \"src/**/*\"",
5
- "build": "tsc"
5
+ "build": "tsc",
6
+ "build:watch": "tsc --watch"
6
7
  },
7
8
  "main": "lib/index.js",
8
9
  "dependencies": {
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "functions",
3
3
  "scripts": {
4
- "build": "tsc"
4
+ "build": "tsc",
5
+ "build:watch": "tsc --watch"
5
6
  },
6
7
  "main": "lib/index.js",
7
8
  "dependencies": {
@@ -3,6 +3,7 @@
3
3
  "scripts": {
4
4
  "lint": "eslint --ext .js,.ts .",
5
5
  "build": "tsc",
6
+ "build:watch": "tsc --watch",
6
7
  "serve": "npm run build && firebase emulators:start --only functions",
7
8
  "shell": "npm run build && firebase functions:shell",
8
9
  "start": "npm run shell",
@@ -2,6 +2,7 @@
2
2
  "name": "functions",
3
3
  "scripts": {
4
4
  "build": "tsc",
5
+ "build:watch": "tsc --watch",
5
6
  "serve": "npm run build && firebase emulators:start --only functions",
6
7
  "shell": "npm run build && firebase functions:shell",
7
8
  "start": "npm run shell",