firebase-tools 10.2.0 → 10.3.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 (139) hide show
  1. package/lib/apiv2.js +3 -0
  2. package/lib/appdistribution/options-parser-util.js +1 -1
  3. package/lib/auth.js +3 -3
  4. package/lib/command.js +1 -1
  5. package/lib/commands/apps-android-sha-create.js +2 -2
  6. package/lib/commands/apps-sdkconfig.js +1 -1
  7. package/lib/commands/auth-import.js +1 -1
  8. package/lib/commands/database-rules-list.js +2 -2
  9. package/lib/commands/emulators-start.js +1 -1
  10. package/lib/commands/ext-configure.js +58 -4
  11. package/lib/commands/ext-dev-init.js +49 -49
  12. package/lib/commands/ext-export.js +7 -2
  13. package/lib/commands/ext-install.js +163 -104
  14. package/lib/commands/ext-uninstall.js +17 -8
  15. package/lib/commands/ext-update.js +64 -11
  16. package/lib/commands/functions-config-clone.js +1 -1
  17. package/lib/commands/functions-config-export.js +1 -1
  18. package/lib/commands/hosting-clone.js +3 -3
  19. package/lib/commands/remoteconfig-get.js +1 -1
  20. package/lib/config.js +6 -3
  21. package/lib/deploy/extensions/deploymentSummary.js +3 -3
  22. package/lib/deploy/extensions/planner.js +7 -6
  23. package/lib/deploy/extensions/tasks.js +1 -1
  24. package/lib/deploy/functions/backend.js +21 -5
  25. package/lib/deploy/functions/checkIam.js +5 -5
  26. package/lib/deploy/functions/containerCleaner.js +3 -3
  27. package/lib/deploy/functions/ensure.js +3 -3
  28. package/lib/deploy/functions/functionsDeployHelper.js +2 -2
  29. package/lib/deploy/functions/prepare.js +5 -3
  30. package/lib/deploy/functions/pricing.js +1 -1
  31. package/lib/deploy/functions/prompts.js +2 -2
  32. package/lib/deploy/functions/release/fabricator.js +7 -7
  33. package/lib/deploy/functions/release/index.js +1 -1
  34. package/lib/deploy/functions/release/planner.js +43 -26
  35. package/lib/deploy/functions/release/reporter.js +3 -0
  36. package/lib/deploy/functions/runtimes/discovery/index.js +6 -6
  37. package/lib/deploy/functions/runtimes/discovery/parsing.js +1 -1
  38. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +22 -12
  39. package/lib/deploy/functions/runtimes/golang/index.js +2 -2
  40. package/lib/deploy/functions/runtimes/node/index.js +53 -0
  41. package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +2 -2
  42. package/lib/deploy/functions/runtimes/node/parseTriggers.js +52 -15
  43. package/lib/deploy/functions/runtimes/node/versioning.js +2 -2
  44. package/lib/deploy/functions/services/firebaseAlerts.js +30 -0
  45. package/lib/deploy/functions/services/index.js +9 -1
  46. package/lib/deploy/functions/services/storage.js +10 -4
  47. package/lib/deploy/functions/triggerRegionHelper.js +1 -1
  48. package/lib/deploy/functions/validate.js +3 -3
  49. package/lib/deploy/hosting/client.js +9 -0
  50. package/lib/deploy/hosting/convertConfig.js +6 -0
  51. package/lib/deploy/hosting/deploy.js +2 -2
  52. package/lib/deploy/hosting/hashcache.js +21 -19
  53. package/lib/deploy/hosting/index.js +5 -5
  54. package/lib/deploy/hosting/prepare.js +25 -25
  55. package/lib/deploy/hosting/release.js +21 -24
  56. package/lib/deploy/hosting/uploader.js +5 -5
  57. package/lib/deploy/remoteconfig/functions.js +2 -2
  58. package/lib/emulator/auth/cloudFunctions.js +1 -1
  59. package/lib/emulator/auth/operations.js +1 -1
  60. package/lib/emulator/commandUtils.js +5 -1
  61. package/lib/emulator/constants.js +4 -0
  62. package/lib/emulator/controller.js +54 -24
  63. package/lib/emulator/download.js +18 -1
  64. package/lib/emulator/downloadableEmulators.js +30 -13
  65. package/lib/emulator/emulatorLogger.js +12 -1
  66. package/lib/emulator/extensions/validation.js +70 -0
  67. package/lib/emulator/extensionsEmulator.js +175 -0
  68. package/lib/emulator/functionsEmulator.js +106 -44
  69. package/lib/emulator/functionsEmulatorRuntime.js +44 -36
  70. package/lib/emulator/functionsEmulatorShared.js +17 -10
  71. package/lib/emulator/functionsEmulatorShell.js +1 -1
  72. package/lib/emulator/functionsEmulatorUtils.js +4 -4
  73. package/lib/emulator/functionsRuntimeWorker.js +2 -2
  74. package/lib/emulator/hub.js +4 -3
  75. package/lib/emulator/loggingEmulator.js +1 -1
  76. package/lib/emulator/pubsubEmulator.js +1 -1
  77. package/lib/emulator/registry.js +10 -2
  78. package/lib/emulator/storage/apis/firebase.js +314 -332
  79. package/lib/emulator/storage/apis/gcloud.js +241 -121
  80. package/lib/emulator/storage/crc.js +5 -1
  81. package/lib/emulator/storage/errors.js +9 -0
  82. package/lib/emulator/storage/files.js +159 -300
  83. package/lib/emulator/storage/index.js +27 -73
  84. package/lib/emulator/storage/metadata.js +65 -51
  85. package/lib/emulator/storage/multipart.js +62 -0
  86. package/lib/emulator/storage/persistence.js +78 -0
  87. package/lib/emulator/storage/rules/config.js +33 -0
  88. package/lib/emulator/storage/rules/manager.js +81 -0
  89. package/lib/emulator/storage/rules/runtime.js +8 -7
  90. package/lib/emulator/storage/rules/utils.js +48 -0
  91. package/lib/emulator/storage/server.js +2 -2
  92. package/lib/emulator/storage/upload.js +106 -0
  93. package/lib/emulator/types.js +3 -0
  94. package/lib/ensureApiEnabled.js +5 -1
  95. package/lib/error.js +1 -1
  96. package/lib/extensions/askUserForParam.js +1 -1
  97. package/lib/extensions/changelog.js +3 -1
  98. package/lib/extensions/checkProjectBilling.js +1 -1
  99. package/lib/extensions/displayExtensionInfo.js +1 -1
  100. package/lib/extensions/emulator/optionsHelper.js +56 -8
  101. package/lib/extensions/emulator/specHelper.js +10 -23
  102. package/lib/extensions/export.js +1 -51
  103. package/lib/extensions/extensionsApi.js +1 -1
  104. package/lib/extensions/extensionsHelper.js +32 -19
  105. package/lib/extensions/listExtensions.js +2 -0
  106. package/lib/extensions/manifest.js +144 -0
  107. package/lib/extensions/metricsUtils.js +4 -4
  108. package/lib/extensions/paramHelper.js +9 -8
  109. package/lib/extensions/refs.js +1 -1
  110. package/lib/extensions/secretsUtils.js +3 -3
  111. package/lib/functional.js +1 -1
  112. package/lib/functions/env.js +6 -7
  113. package/lib/functions/events/v2.js +11 -0
  114. package/lib/gcp/cloudfunctions.js +42 -11
  115. package/lib/gcp/cloudfunctionsv2.js +48 -17
  116. package/lib/gcp/cloudtasks.js +1 -1
  117. package/lib/gcp/docker.js +2 -2
  118. package/lib/gcp/resourceManager.js +4 -4
  119. package/lib/gcp/run.js +2 -2
  120. package/lib/gcp/storage.js +1 -0
  121. package/lib/hosting/api.js +1 -1
  122. package/lib/hosting/functionsProxy.js +15 -5
  123. package/lib/hosting/proxy.js +2 -2
  124. package/lib/init/features/account.js +1 -1
  125. package/lib/management/database.js +1 -1
  126. package/lib/previews.js +1 -1
  127. package/lib/responseToError.js +16 -7
  128. package/lib/serve/functions.js +2 -1
  129. package/lib/serve/hosting.js +1 -1
  130. package/lib/utils.js +15 -2
  131. package/npm-shrinkwrap.json +904 -412
  132. package/package.json +3 -3
  133. package/schema/firebase-config.json +32 -0
  134. package/templates/init/functions/javascript/package.lint.json +3 -3
  135. package/templates/init/functions/javascript/package.nolint.json +2 -2
  136. package/templates/init/functions/typescript/package.lint.json +7 -7
  137. package/templates/init/functions/typescript/package.nolint.json +3 -3
  138. package/lib/deploy/extensions/params.js +0 -39
  139. package/lib/deploy/functions/eventTypes.js +0 -10
@@ -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);
@@ -29,6 +29,7 @@ async function upload(source, uploadUrl, extraHeaders) {
29
29
  method: "PUT",
30
30
  path: url.pathname,
31
31
  queryParams: url.searchParams,
32
+ responseType: "xml",
32
33
  headers: Object.assign({ "content-type": "application/zip" }, extraHeaders),
33
34
  body: source.stream,
34
35
  skipLog: { resBody: true },
@@ -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;
@@ -1,26 +1,36 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.functionsProxy = void 0;
3
4
  const lodash_1 = require("lodash");
4
5
  const proxy_1 = require("./proxy");
5
6
  const projectUtils_1 = require("../projectUtils");
6
7
  const registry_1 = require("../emulator/registry");
7
8
  const types_1 = require("../emulator/types");
8
9
  const functionsEmulator_1 = require("../emulator/functionsEmulator");
9
- function default_1(options) {
10
+ const error_1 = require("../error");
11
+ function functionsProxy(options) {
10
12
  return (rewrite) => {
11
13
  return new Promise((resolve) => {
12
14
  const projectId = (0, projectUtils_1.needProjectId)(options);
13
- let url = `https://us-central1-${projectId}.cloudfunctions.net/${rewrite.function}`;
15
+ if (!("function" in rewrite)) {
16
+ throw new error_1.FirebaseError(`A non-function rewrite cannot be used in functionsProxy`, {
17
+ exit: 2,
18
+ });
19
+ }
20
+ if (!rewrite.region) {
21
+ rewrite.region = "us-central1";
22
+ }
23
+ let url = `https://${rewrite.region}-${projectId}.cloudfunctions.net/${rewrite.function}`;
14
24
  let destLabel = "live";
15
25
  if ((0, lodash_1.includes)(options.targets, "functions")) {
16
26
  destLabel = "local";
17
27
  const functionsEmu = registry_1.EmulatorRegistry.get(types_1.Emulators.FUNCTIONS);
18
28
  if (functionsEmu) {
19
- url = functionsEmulator_1.FunctionsEmulator.getHttpFunctionUrl(functionsEmu.getInfo().host, functionsEmu.getInfo().port, projectId, rewrite.function, "us-central1");
29
+ url = functionsEmulator_1.FunctionsEmulator.getHttpFunctionUrl(functionsEmu.getInfo().host, functionsEmu.getInfo().port, projectId, rewrite.function, rewrite.region);
20
30
  }
21
31
  }
22
- resolve((0, proxy_1.proxyRequestHandler)(url, `${destLabel} Function ${rewrite.function}`));
32
+ resolve((0, proxy_1.proxyRequestHandler)(url, `${destLabel} Function ${rewrite.region}/${rewrite.function}`));
23
33
  });
24
34
  };
25
35
  }
26
- exports.default = default_1;
36
+ exports.functionsProxy = functionsProxy;
@@ -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 }, 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)) {
@@ -2,16 +2,25 @@
2
2
  const _ = require("lodash");
3
3
  const { FirebaseError } = require("./error");
4
4
  module.exports = function (response, body) {
5
- if (typeof body === "string" && response.statusCode === 404) {
6
- body = {
7
- error: {
8
- message: "Not Found",
9
- },
10
- };
11
- }
12
5
  if (response.statusCode < 400) {
13
6
  return null;
14
7
  }
8
+ if (typeof body === "string") {
9
+ if (response.statusCode === 404) {
10
+ body = {
11
+ error: {
12
+ message: "Not Found",
13
+ },
14
+ };
15
+ }
16
+ else {
17
+ body = {
18
+ error: {
19
+ message: body,
20
+ },
21
+ };
22
+ }
23
+ }
15
24
  if (typeof body !== "object") {
16
25
  try {
17
26
  body = JSON.parse(body);
@@ -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;
@@ -46,7 +46,7 @@ function startServer(options, config, port, init) {
46
46
  },
47
47
  },
48
48
  rewriters: {
49
- function: (0, functionsProxy_1.default)(options),
49
+ function: (0, functionsProxy_1.functionsProxy)(options),
50
50
  run: (0, cloudRunProxy_1.default)(options),
51
51
  },
52
52
  }).listen(() => {
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;