firebase-tools 11.1.0 → 11.2.2

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 (101) hide show
  1. package/lib/accountExporter.js +11 -4
  2. package/lib/accountImporter.js +5 -6
  3. package/lib/appdistribution/client.js +7 -9
  4. package/lib/auth.js +3 -5
  5. package/lib/checkValidTargetFilters.js +28 -18
  6. package/lib/commands/database-profile.js +2 -3
  7. package/lib/commands/database-push.js +2 -3
  8. package/lib/commands/database-remove.js +1 -2
  9. package/lib/commands/database-set.js +1 -2
  10. package/lib/commands/deploy.js +5 -6
  11. package/lib/commands/ext-dev-emulators-exec.js +1 -1
  12. package/lib/commands/ext-dev-emulators-start.js +1 -1
  13. package/lib/commands/ext-dev-list.js +6 -7
  14. package/lib/commands/ext-export.js +2 -0
  15. package/lib/commands/ext-info.js +12 -13
  16. package/lib/commands/ext.js +2 -3
  17. package/lib/commands/functions-delete.js +1 -7
  18. package/lib/commands/open.js +5 -6
  19. package/lib/commands/serve.js +3 -5
  20. package/lib/commands/use.js +2 -3
  21. package/lib/config.js +4 -3
  22. package/lib/deploy/database/prepare.js +2 -3
  23. package/lib/deploy/extensions/planner.js +1 -0
  24. package/lib/deploy/extensions/prepare.js +18 -1
  25. package/lib/deploy/extensions/release.js +4 -0
  26. package/lib/deploy/extensions/secrets.js +3 -3
  27. package/lib/deploy/functions/build.js +35 -53
  28. package/lib/deploy/functions/ensure.js +1 -11
  29. package/lib/deploy/functions/params.js +189 -0
  30. package/lib/deploy/functions/prepare.js +3 -13
  31. package/lib/deploy/functions/prepareFunctionsUpload.js +2 -3
  32. package/lib/deploy/functions/release/fabricator.js +0 -1
  33. package/lib/deploy/functions/release/index.js +1 -5
  34. package/lib/deploy/functions/runtimes/discovery/index.js +18 -3
  35. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +3 -2
  36. package/lib/deploy/functions/runtimes/golang/index.js +2 -22
  37. package/lib/deploy/functions/runtimes/node/index.js +3 -7
  38. package/lib/deploy/functions/runtimes/node/parseTriggers.js +2 -2
  39. package/lib/deploy/lifecycleHooks.js +8 -11
  40. package/lib/deploy/storage/prepare.js +2 -2
  41. package/lib/emulator/auth/index.js +1 -1
  42. package/lib/emulator/auth/operations.js +336 -64
  43. package/lib/emulator/auth/server.js +2 -2
  44. package/lib/emulator/auth/state.js +32 -7
  45. package/lib/emulator/commandUtils.js +1 -1
  46. package/lib/emulator/constants.js +1 -1
  47. package/lib/emulator/controller.js +6 -5
  48. package/lib/emulator/databaseEmulator.js +2 -2
  49. package/lib/emulator/download.js +1 -1
  50. package/lib/emulator/downloadableEmulators.js +6 -6
  51. package/lib/emulator/events/types.js +2 -3
  52. package/lib/emulator/firestoreEmulator.js +2 -2
  53. package/lib/emulator/functionsEmulator.js +36 -45
  54. package/lib/emulator/functionsEmulatorRuntime.js +12 -16
  55. package/lib/emulator/functionsEmulatorShared.js +7 -5
  56. package/lib/emulator/functionsRuntimeWorker.js +0 -6
  57. package/lib/emulator/hostingEmulator.js +1 -1
  58. package/lib/emulator/hub.js +1 -1
  59. package/lib/emulator/loggingEmulator.js +1 -1
  60. package/lib/emulator/pubsubEmulator.js +1 -1
  61. package/lib/emulator/storage/crc.js +4 -4
  62. package/lib/emulator/storage/index.js +1 -1
  63. package/lib/emulator/types.js +1 -1
  64. package/lib/extensions/askUserForConsent.js +1 -2
  65. package/lib/extensions/askUserForParam.js +15 -18
  66. package/lib/extensions/emulator/optionsHelper.js +4 -4
  67. package/lib/extensions/etags.js +28 -0
  68. package/lib/extensions/extensionsApi.js +1 -22
  69. package/lib/extensions/extensionsHelper.js +6 -6
  70. package/lib/extensions/listExtensions.js +9 -10
  71. package/lib/extensions/manifest.js +2 -2
  72. package/lib/extensions/resolveSource.js +11 -7
  73. package/lib/extensions/secretsUtils.js +3 -3
  74. package/lib/extensions/types.js +24 -0
  75. package/lib/extensions/updateHelper.js +1 -1
  76. package/lib/extensions/utils.js +1 -2
  77. package/lib/extensions/warnings.js +10 -4
  78. package/lib/firestore/encodeFirestoreValue.js +11 -8
  79. package/lib/fsAsync.js +3 -3
  80. package/lib/functions/env.js +5 -1
  81. package/lib/functionsConfig.js +18 -15
  82. package/lib/functionsConfigClone.js +10 -12
  83. package/lib/gcp/cloudfunctions.js +2 -15
  84. package/lib/gcp/rules.js +3 -4
  85. package/lib/gcp/runtimeconfig.js +2 -2
  86. package/lib/hosting/api.js +9 -11
  87. package/lib/hosting/expireUtils.js +2 -2
  88. package/lib/hosting/proxy.js +1 -1
  89. package/lib/init/features/hosting/github.js +1 -1
  90. package/lib/init/features/hosting/index.js +2 -2
  91. package/lib/localFunction.js +4 -4
  92. package/lib/management/projects.js +6 -7
  93. package/lib/previews.js +1 -1
  94. package/lib/profileReport.js +24 -22
  95. package/lib/prompt.js +1 -2
  96. package/lib/rc.js +12 -2
  97. package/lib/rulesDeploy.js +2 -2
  98. package/lib/serve/index.js +4 -5
  99. package/lib/utils.js +30 -6
  100. package/npm-shrinkwrap.json +2 -2
  101. package/package.json +10 -9
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.serialExportUsers = exports.validateOptions = void 0;
4
- const _ = require("lodash");
5
4
  const os = require("os");
6
5
  const path = require("path");
7
6
  const apiv2_1 = require("./apiv2");
@@ -83,10 +82,14 @@ function transUserToArray(user) {
83
82
  }
84
83
  function transUserJson(user) {
85
84
  const newUser = {};
86
- _.each(_.pick(user, EXPORTED_JSON_KEYS), (value, key) => {
85
+ const pickedUser = {};
86
+ for (const k of EXPORTED_JSON_KEYS) {
87
+ pickedUser[k] = user[k];
88
+ }
89
+ for (const [key, value] of Object.entries(pickedUser)) {
87
90
  const newKey = EXPORTED_JSON_KEYS_RENAMING[key] || key;
88
91
  newUser[newKey] = value;
89
- });
92
+ }
90
93
  if (newUser.passwordHash) {
91
94
  newUser.passwordHash = convertToNormalBase64(newUser.passwordHash);
92
95
  }
@@ -97,7 +100,11 @@ function transUserJson(user) {
97
100
  newUser.providerUserInfo = [];
98
101
  for (const providerInfo of user.providerUserInfo) {
99
102
  if (PROVIDER_ID_INDEX_MAP.has(providerInfo.providerId)) {
100
- newUser.providerUserInfo.push(_.pick(providerInfo, EXPORTED_PROVIDER_USER_INFO_KEYS));
103
+ const picked = {};
104
+ for (const k of EXPORTED_PROVIDER_USER_INFO_KEYS) {
105
+ picked[k] = providerInfo[k];
106
+ }
107
+ newUser.providerUserInfo.push(picked);
101
108
  }
102
109
  }
103
110
  }
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.serialImportUsers = exports.validateUserJson = exports.validateOptions = exports.transArrayToUser = void 0;
4
4
  const clc = require("cli-color");
5
- const _ = require("lodash");
6
5
  const apiv2_1 = require("./apiv2");
7
6
  const api_1 = require("./api");
8
7
  const logger_1 = require("./logger");
@@ -61,12 +60,12 @@ function genUploadAccountPostBody(projectId, accounts, hashOptions) {
61
60
  if (account.salt) {
62
61
  account.salt = toWebSafeBase64(account.salt);
63
62
  }
64
- _.each(ALLOWED_JSON_KEYS_RENAMING, (value, key) => {
63
+ for (const [key, value] of Object.entries(ALLOWED_JSON_KEYS_RENAMING)) {
65
64
  if (account[key]) {
66
65
  account[value] = account[key];
67
66
  delete account[key];
68
67
  }
69
- });
68
+ }
70
69
  return account;
71
70
  }),
72
71
  };
@@ -231,12 +230,12 @@ function validateRequiredParameters(options) {
231
230
  }
232
231
  }
233
232
  function validateProviderUserInfo(providerUserInfo) {
234
- if (!_.includes(ALLOWED_PROVIDER_IDS, providerUserInfo.providerId)) {
233
+ if (!ALLOWED_PROVIDER_IDS.includes(providerUserInfo.providerId)) {
235
234
  return {
236
235
  error: JSON.stringify(providerUserInfo, null, 2) + " has unsupported providerId",
237
236
  };
238
237
  }
239
- const keydiff = _.difference(_.keys(providerUserInfo), ALLOWED_PROVIDER_USER_INFO_KEYS);
238
+ const keydiff = Object.keys(providerUserInfo).filter((k) => !ALLOWED_PROVIDER_USER_INFO_KEYS.includes(k));
240
239
  if (keydiff.length) {
241
240
  return {
242
241
  error: JSON.stringify(providerUserInfo, null, 2) + " has unsupported keys: " + keydiff.join(","),
@@ -245,7 +244,7 @@ function validateProviderUserInfo(providerUserInfo) {
245
244
  return {};
246
245
  }
247
246
  function validateUserJson(userJson) {
248
- const keydiff = _.difference(_.keys(userJson), ALLOWED_JSON_KEYS);
247
+ const keydiff = Object.keys(userJson).filter((k) => !ALLOWED_JSON_KEYS.includes(k));
249
248
  if (keydiff.length) {
250
249
  return {
251
250
  error: JSON.stringify(userJson, null, 2) + " has unsupported keys: " + keydiff.join(","),
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AppDistributionClient = exports.UploadReleaseResult = exports.IntegrationState = void 0;
4
- const _ = require("lodash");
5
4
  const utils = require("../utils");
6
5
  const operationPoller = require("../operation-poller");
7
6
  const error_1 = require("../error");
@@ -83,6 +82,7 @@ class AppDistributionClient {
83
82
  utils.logSuccess("added release notes successfully");
84
83
  }
85
84
  async distribute(releaseName, testerEmails = [], groupAliases = []) {
85
+ var _a, _b, _c;
86
86
  if (testerEmails.length === 0 && groupAliases.length === 0) {
87
87
  utils.logWarning("no testers or groups specified, skipping");
88
88
  return;
@@ -97,14 +97,12 @@ class AppDistributionClient {
97
97
  }
98
98
  catch (err) {
99
99
  let errorMessage = err.message;
100
- if (_.has(err, "context.body.error")) {
101
- const errorStatus = _.get(err, "context.body.error.status");
102
- if (errorStatus === "FAILED_PRECONDITION") {
103
- errorMessage = "invalid testers";
104
- }
105
- else if (errorStatus === "INVALID_ARGUMENT") {
106
- errorMessage = "invalid groups";
107
- }
100
+ const errorStatus = (_c = (_b = (_a = err === null || err === void 0 ? void 0 : err.context) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.error) === null || _c === void 0 ? void 0 : _c.status;
101
+ if (errorStatus === "FAILED_PRECONDITION") {
102
+ errorMessage = "invalid testers";
103
+ }
104
+ else if (errorStatus === "INVALID_ARGUMENT") {
105
+ errorMessage = "invalid groups";
108
106
  }
109
107
  throw new error_1.FirebaseError(`failed to distribute to testers/groups: ${errorMessage}`, {
110
108
  exit: 1,
package/lib/auth.js CHANGED
@@ -276,7 +276,7 @@ async function respondWithFile(req, res, statusCode, filename) {
276
276
  function urlsafeBase64(base64string) {
277
277
  return base64string.replace(/\+/g, "-").replace(/=+$/, "").replace(/\//g, "_");
278
278
  }
279
- async function loginRemotely(userHint) {
279
+ async function loginRemotely() {
280
280
  var _a;
281
281
  const authProxyClient = new apiv2.Client({
282
282
  urlPrefix: api_1.authProxyOrigin,
@@ -342,7 +342,6 @@ async function loginWithLocalhostGitHub(port) {
342
342
  async function loginWithLocalhost(port, callbackUrl, authUrl, successTemplate, getTokens) {
343
343
  return new Promise((resolve, reject) => {
344
344
  const server = http.createServer(async (req, res) => {
345
- let tokens;
346
345
  const query = url.parse(`${req.url}`, true).query || {};
347
346
  const queryState = query.state;
348
347
  const queryCode = query.code;
@@ -379,16 +378,15 @@ async function loginWithLocalhost(port, callbackUrl, authUrl, successTemplate, g
379
378
  }
380
379
  async function loginGoogle(localhost, userHint) {
381
380
  if (localhost) {
382
- const port = await getPort();
383
381
  try {
384
382
  const port = await getPort();
385
383
  return await loginWithLocalhostGoogle(port, userHint);
386
384
  }
387
385
  catch (_a) {
388
- return await loginRemotely(userHint);
386
+ return await loginRemotely();
389
387
  }
390
388
  }
391
- return await loginRemotely(userHint);
389
+ return await loginRemotely();
392
390
  }
393
391
  exports.loginGoogle = loginGoogle;
394
392
  async function loginGithub() {
@@ -1,32 +1,42 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.checkValidTargetFilters = void 0;
4
- const _ = require("lodash");
4
+ const deploy_1 = require("./commands/deploy");
5
5
  const error_1 = require("./error");
6
- function checkValidTargetFilters(options) {
7
- function numFilters(targetTypes) {
8
- return _.filter(options.only, (opt) => {
9
- const optChunks = opt.split(":");
10
- return _.includes(targetTypes, optChunks[0]) && optChunks.length > 1;
11
- }).length;
12
- }
13
- function targetContainsFilter(targetTypes) {
14
- return numFilters(targetTypes) > 1;
15
- }
16
- function targetDoesNotContainFilter(targetTypes) {
17
- return numFilters(targetTypes) === 0;
18
- }
6
+ function targetsForTypes(only, ...types) {
7
+ return only.filter((t) => {
8
+ if (t.includes(":")) {
9
+ return types.includes(t.split(":")[0]);
10
+ }
11
+ else {
12
+ return types.includes(t);
13
+ }
14
+ });
15
+ }
16
+ function targetsHaveFilters(...targets) {
17
+ return targets.some((t) => t.includes(":"));
18
+ }
19
+ function targetsHaveNoFilters(...targets) {
20
+ return targets.some((t) => !t.includes(":"));
21
+ }
22
+ async function checkValidTargetFilters(options) {
23
+ const only = !options.only ? [] : options.only.split(",");
19
24
  return new Promise((resolve, reject) => {
20
- if (!options.only) {
25
+ if (!only.length) {
21
26
  return resolve();
22
27
  }
23
28
  if (options.except) {
24
29
  return reject(new error_1.FirebaseError("Cannot specify both --only and --except"));
25
30
  }
26
- if (targetContainsFilter(["database", "storage", "hosting"])) {
27
- return reject(new error_1.FirebaseError("Filters specified with colons (e.g. --only functions:func1,functions:func2) are only supported for functions"));
31
+ const nonFilteredTypes = deploy_1.VALID_DEPLOY_TARGETS.filter((t) => !["hosting", "functions", "firestore"].includes(t));
32
+ const targetsForNonFilteredTypes = targetsForTypes(only, ...nonFilteredTypes);
33
+ if (targetsForNonFilteredTypes.length && targetsHaveFilters(...targetsForNonFilteredTypes)) {
34
+ return reject(new error_1.FirebaseError("Filters specified with colons (e.g. --only functions:func1,functions:func2) are only supported for functions, hosting, and firestore"));
28
35
  }
29
- if (targetContainsFilter(["functions"]) && targetDoesNotContainFilter(["functions"])) {
36
+ const targetsForFunctions = targetsForTypes(only, "functions");
37
+ if (targetsForFunctions.length &&
38
+ targetsHaveFilters(...targetsForFunctions) &&
39
+ targetsHaveNoFilters(...targetsForFunctions)) {
30
40
  return reject(new error_1.FirebaseError('Cannot specify "--only functions" and "--only functions:<filter>" at the same time'));
31
41
  }
32
42
  return resolve();
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
- const _ = require("lodash");
5
4
  const command_1 = require("../command");
6
5
  const requireDatabaseInstance_1 = require("../requireDatabaseInstance");
7
6
  const database_1 = require("../management/database");
@@ -33,12 +32,12 @@ exports.command = new command_1.Command("database:profile")
33
32
  else if (options.parent.json && options.raw) {
34
33
  return utils.reject("Cannot output raw data in json format", { exit: 1 });
35
34
  }
36
- else if (options.input && _.has(options, "duration")) {
35
+ else if (options.input && options.duration !== undefined) {
37
36
  return utils.reject("Cannot specify a duration for input files", {
38
37
  exit: 1,
39
38
  });
40
39
  }
41
- else if (_.has(options, "duration") && options.duration <= 0) {
40
+ else if (options.duration !== undefined && options.duration <= 0) {
42
41
  return utils.reject("Must specify a positive number of seconds", {
43
42
  exit: 1,
44
43
  });
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
- const _ = require("lodash");
5
4
  const clc = require("cli-color");
6
5
  const fs = require("fs");
7
6
  const apiv2_1 = require("../apiv2");
@@ -25,7 +24,7 @@ exports.command = new command_1.Command("database:push <path> [infile]")
25
24
  .before(database_1.populateInstanceDetails)
26
25
  .before(commandUtils_1.printNoticeIfEmulated, types_1.Emulators.DATABASE)
27
26
  .action(async (path, infile, options) => {
28
- if (!_.startsWith(path, "/")) {
27
+ if (!path.startsWith("/")) {
29
28
  throw new error_1.FirebaseError("Path must begin with /");
30
29
  }
31
30
  const inStream = utils.stringToStream(options.data) || (infile ? fs.createReadStream(infile) : process.stdin);
@@ -48,7 +47,7 @@ exports.command = new command_1.Command("database:push <path> [infile]")
48
47
  logger_1.logger.debug(err);
49
48
  throw new error_1.FirebaseError(`Unexpected error while pushing data: ${err}`, { exit: 2 });
50
49
  }
51
- if (!_.endsWith(path, "/")) {
50
+ if (!path.endsWith("/")) {
52
51
  path += "/";
53
52
  }
54
53
  const consoleUrl = utils.getDatabaseViewDataUrl(origin, options.project, options.instance, path + res.body.name);
@@ -12,7 +12,6 @@ const api_1 = require("../database/api");
12
12
  const utils = require("../utils");
13
13
  const prompt_1 = require("../prompt");
14
14
  const clc = require("cli-color");
15
- const _ = require("lodash");
16
15
  exports.command = new command_1.Command("database:remove <path>")
17
16
  .description("remove data from your Firebase at the specified path")
18
17
  .option("-f, --force", "pass this option to bypass confirmation prompt")
@@ -22,7 +21,7 @@ exports.command = new command_1.Command("database:remove <path>")
22
21
  .before(database_1.populateInstanceDetails)
23
22
  .before(commandUtils_1.warnEmulatorNotSupported, types_1.Emulators.DATABASE)
24
23
  .action(async (path, options) => {
25
- if (!_.startsWith(path, "/")) {
24
+ if (!path.startsWith("/")) {
26
25
  return utils.reject("Path must begin with /", { exit: 1 });
27
26
  }
28
27
  const origin = (0, api_1.realtimeOriginOrEmulatorOrCustomUrl)(options.instanceDetails.databaseUrl);
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
- const _ = require("lodash");
5
4
  const clc = require("cli-color");
6
5
  const fs = require("fs");
7
6
  const apiv2_1 = require("../apiv2");
@@ -27,7 +26,7 @@ exports.command = new command_1.Command("database:set <path> [infile]")
27
26
  .before(database_1.populateInstanceDetails)
28
27
  .before(commandUtils_1.printNoticeIfEmulated, types_1.Emulators.DATABASE)
29
28
  .action(async (path, infile, options) => {
30
- if (!_.startsWith(path, "/")) {
29
+ if (!path.startsWith("/")) {
31
30
  throw new error_1.FirebaseError("Path must begin with /");
32
31
  }
33
32
  const origin = (0, api_1.realtimeOriginOrEmulatorOrCustomUrl)(options.instanceDetails.databaseUrl);
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.command = void 0;
4
- const _ = require("lodash");
3
+ exports.command = exports.VALID_DEPLOY_TARGETS = void 0;
5
4
  const requireDatabaseInstance_1 = require("../requireDatabaseInstance");
6
5
  const requirePermissions_1 = require("../requirePermissions");
7
6
  const checkIam_1 = require("../deploy/functions/checkIam");
@@ -11,7 +10,7 @@ const deploy_1 = require("../deploy");
11
10
  const requireConfig_1 = require("../requireConfig");
12
11
  const filterTargets_1 = require("../filterTargets");
13
12
  const requireHostingSite_1 = require("../requireHostingSite");
14
- const VALID_TARGETS = [
13
+ exports.VALID_DEPLOY_TARGETS = [
15
14
  "database",
16
15
  "storage",
17
16
  "firestore",
@@ -56,7 +55,7 @@ exports.command = new command_1.Command("deploy")
56
55
  .option("--except <targets>", 'deploy to all targets except specified (e.g. "database")')
57
56
  .before(requireConfig_1.requireConfig)
58
57
  .before((options) => {
59
- options.filteredTargets = (0, filterTargets_1.filterTargets)(options, VALID_TARGETS);
58
+ options.filteredTargets = (0, filterTargets_1.filterTargets)(options, exports.VALID_DEPLOY_TARGETS);
60
59
  const permissions = options.filteredTargets.reduce((perms, target) => {
61
60
  return perms.concat(TARGET_PERMISSIONS[target]);
62
61
  }, []);
@@ -68,10 +67,10 @@ exports.command = new command_1.Command("deploy")
68
67
  }
69
68
  })
70
69
  .before(async (options) => {
71
- if (_.includes(options.filteredTargets, "database")) {
70
+ if (options.filteredTargets.includes("database")) {
72
71
  await (0, requireDatabaseInstance_1.requireDatabaseInstance)(options);
73
72
  }
74
- if (_.includes(options.filteredTargets, "hosting")) {
73
+ if (options.filteredTargets.includes("hosting")) {
75
74
  await (0, requireHostingSite_1.requireHostingSite)(options);
76
75
  }
77
76
  })
@@ -16,7 +16,7 @@ exports.command = new command_1.Command("ext:dev:emulators:exec <script>")
16
16
  .option(commandUtils.FLAG_EXPORT_ON_EXIT, commandUtils.DESC_EXPORT_ON_EXIT)
17
17
  .option(commandUtils.FLAG_UI, commandUtils.DESC_UI)
18
18
  .before(checkMinRequiredVersion_1.checkMinRequiredVersion, "extDevMinVersion")
19
- .action((script, options) => {
19
+ .action((script) => {
20
20
  const localInstallCommand = `firebase ext:install ${process.cwd()}`;
21
21
  const emulatorsExecCommand = `firebase emulators:exec '${script}`;
22
22
  throw new error_1.FirebaseError("ext:dev:emulators:exec is no longer supported. " +
@@ -13,7 +13,7 @@ exports.command = new command_1.Command("ext:dev:emulators:start")
13
13
  .option(commandUtils.FLAG_TEST_PARAMS, commandUtils.DESC_TEST_PARAMS)
14
14
  .option(commandUtils.FLAG_IMPORT, commandUtils.DESC_IMPORT)
15
15
  .option(commandUtils.FLAG_EXPORT_ON_EXIT, commandUtils.DESC_EXPORT_ON_EXIT)
16
- .action((options) => {
16
+ .action(() => {
17
17
  const localInstallCommand = `firebase ext:install ${process.cwd()}`;
18
18
  const emulatorsStartCommand = "firebase emulators:start";
19
19
  throw new error_1.FirebaseError("ext:dev:emulators:start is no longer supported. " +
@@ -3,15 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
4
  const clc = require("cli-color");
5
5
  const Table = require("cli-table");
6
- const _ = require("lodash");
7
6
  const command_1 = require("../command");
8
- const extensionsHelper_1 = require("../extensions/extensionsHelper");
9
7
  const error_1 = require("../error");
10
- const utils = require("../utils");
11
- const extensionsUtils = require("../extensions/utils");
8
+ const utils_1 = require("../utils");
12
9
  const extensionsApi_1 = require("../extensions/extensionsApi");
13
10
  const logger_1 = require("../logger");
11
+ const extensionsHelper_1 = require("../extensions/extensionsHelper");
14
12
  const requireAuth_1 = require("../requireAuth");
13
+ const extensionsUtils = require("../extensions/utils");
15
14
  exports.command = new command_1.Command("ext:dev:list <publisherId>")
16
15
  .description("list all published extensions associated with this publisher ID")
17
16
  .before(requireAuth_1.requireAuth)
@@ -33,15 +32,15 @@ exports.command = new command_1.Command("ext:dev:list <publisherId>")
33
32
  head: ["Extension ID", "Version", "Published"],
34
33
  style: { head: ["yellow"] },
35
34
  });
36
- const sorted = _.sortBy(extensions, "createTime", "asc").reverse();
35
+ const sorted = extensions.sort((a, b) => new Date(b.createTime).valueOf() - new Date(a.createTime).valueOf());
37
36
  sorted.forEach((extension) => {
38
37
  table.push([
39
- _.last(extension.ref.split("/")),
38
+ (0, utils_1.last)(extension.ref.split("/")),
40
39
  extension.latestVersion,
41
40
  extension.createTime ? extensionsUtils.formatTimestamp(extension.createTime) : "",
42
41
  ]);
43
42
  });
44
- utils.logLabeledBullet(extensionsHelper_1.logPrefix, `list of published extensions for publisher ${clc.bold(publisherId)}:`);
43
+ (0, utils_1.logLabeledBullet)(extensionsHelper_1.logPrefix, `list of published extensions for publisher ${clc.bold(publisherId)}:`);
45
44
  logger_1.logger.info(table.toString());
46
45
  return { extensions: sorted };
47
46
  });
@@ -4,6 +4,7 @@ exports.command = void 0;
4
4
  const checkMinRequiredVersion_1 = require("../checkMinRequiredVersion");
5
5
  const command_1 = require("../command");
6
6
  const planner = require("../deploy/extensions/planner");
7
+ const etags_1 = require("../extensions/etags");
7
8
  const export_1 = require("../extensions/export");
8
9
  const extensionsHelper_1 = require("../extensions/extensionsHelper");
9
10
  const manifest = require("../extensions/manifest");
@@ -63,4 +64,5 @@ exports.command = new command_1.Command("ext:export")
63
64
  nonInteractive: options.nonInteractive,
64
65
  force: options.force,
65
66
  }, true);
67
+ (0, etags_1.saveEtags)(options.rc, projectId, have);
66
68
  });
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
4
  const clc = require("cli-color");
5
- const _ = require("lodash");
6
5
  const checkMinRequiredVersion_1 = require("../checkMinRequiredVersion");
7
6
  const command_1 = require("../command");
8
7
  const extensionsApi = require("../extensions/extensionsApi");
@@ -66,44 +65,44 @@ exports.command = new command_1.Command("ext:info <extensionName>")
66
65
  }
67
66
  if (spec.params && Array.isArray(spec.params) && spec.params.length > 0) {
68
67
  lines.push("", "**Configuration Parameters:**");
69
- _.forEach(spec.params, (param) => {
68
+ for (const param of spec.params) {
70
69
  lines.push(`* ${param.label}` + (param.description ? `: ${param.description}` : ""));
71
- });
70
+ }
72
71
  }
73
72
  const functions = [];
74
73
  const otherResources = [];
75
- _.forEach(spec.resources, (resource) => {
74
+ for (const resource of spec.resources) {
76
75
  if (FUNCTION_TYPE_REGEX.test(resource.type)) {
77
76
  functions.push(resource);
78
77
  }
79
78
  else {
80
79
  otherResources.push(resource);
81
80
  }
82
- });
81
+ }
83
82
  if (functions.length > 0) {
84
83
  lines.push("", "**Cloud Functions:**");
85
- _.forEach(functions, (func) => {
84
+ for (const func of functions) {
86
85
  lines.push(`* **${func.name}:** ${func.description}`);
87
- });
86
+ }
88
87
  }
89
88
  if (otherResources.length > 0) {
90
89
  lines.push("", "**Other Resources**:");
91
- _.forEach(otherResources, (resource) => {
90
+ for (const resource of otherResources) {
92
91
  lines.push(`* ${resource.name} (${resource.type})`);
93
- });
92
+ }
94
93
  }
95
94
  if (spec.apis) {
96
95
  lines.push("", "**APIs Used**:");
97
- _.forEach(spec.apis, (api) => {
96
+ for (const api of spec.apis) {
98
97
  lines.push(`* ${api.apiName}` + (api.reason ? ` (Reason: ${api.reason})` : ""));
99
- });
98
+ }
100
99
  }
101
100
  if (spec.roles) {
102
101
  lines.push("", "**Access Required**:");
103
102
  lines.push("", "This extension will operate with the following project IAM roles:");
104
- _.forEach(spec.roles, (role) => {
103
+ for (const role of spec.roles) {
105
104
  lines.push(`* ${role.role}` + (role.reason ? ` (Reason: ${role.reason})` : ""));
106
- });
105
+ }
107
106
  }
108
107
  if (options.markdown) {
109
108
  logger_1.logger.info(lines.join("\n\n"));
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
- const _ = require("lodash");
5
4
  const clc = require("cli-color");
6
5
  const checkMinRequiredVersion_1 = require("../checkMinRequiredVersion");
7
6
  const command_1 = require("../command");
@@ -25,11 +24,11 @@ exports.command = new command_1.Command("ext")
25
24
  "ext:update",
26
25
  "ext:uninstall",
27
26
  ];
28
- _.forEach(commandNames, (commandName) => {
27
+ for (const commandName of commandNames) {
29
28
  const command = firebaseTools.getCommand(commandName);
30
29
  logger_1.logger.info(clc.bold("\n" + command.name()));
31
30
  command.outputHelp();
32
- });
31
+ }
33
32
  logger_1.logger.info();
34
33
  try {
35
34
  await (0, requirePermissions_1.requirePermissions)(options, ["firebaseextensions.instances.list"]);
@@ -9,7 +9,6 @@ const projectUtils_1 = require("../projectUtils");
9
9
  const prompt_1 = require("../prompt");
10
10
  const functional_1 = require("../functional");
11
11
  const requirePermissions_1 = require("../requirePermissions");
12
- const ensure = require("../ensureApiEnabled");
13
12
  const helper = require("../deploy/functions/functionsDeployHelper");
14
13
  const utils = require("../utils");
15
14
  const backend = require("../deploy/functions/backend");
@@ -90,10 +89,5 @@ exports.command = new command_1.Command("functions:delete [filters...]")
90
89
  exit: 1,
91
90
  });
92
91
  }
93
- const opts = {};
94
- const arEnabled = await ensure.check((0, projectUtils_1.needProjectId)(options), "artifactregistry.googleapis.com", "functions", true);
95
- if (!arEnabled) {
96
- opts.ar = new containerCleaner.NoopArtifactRegistryCleaner();
97
- }
98
- await containerCleaner.cleanupBuildImages([], allEpToDelete, opts);
92
+ await containerCleaner.cleanupBuildImages([], allEpToDelete);
99
93
  });
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
- const _ = require("lodash");
5
4
  const clc = require("cli-color");
6
5
  const open = require("open");
7
6
  const error_1 = require("../error");
@@ -42,15 +41,15 @@ const LINKS = [
42
41
  { name: "Storage: Rules", arg: "storage:rules", consolePath: "/storage/rules" },
43
42
  { name: "Test Lab", arg: "testlab", consolePath: "/testlab/histories/" },
44
43
  ];
45
- const CHOICES = _.map(LINKS, "name");
44
+ const CHOICES = LINKS.map((l) => l.name);
46
45
  exports.command = new command_1.Command("open [link]")
47
46
  .description("quickly open a browser to relevant project resources")
48
47
  .before(requirePermissions_1.requirePermissions)
49
48
  .before(requireDatabaseInstance_1.requireDatabaseInstance)
50
49
  .action(async (linkName, options) => {
51
- let link = _.find(LINKS, { arg: linkName });
50
+ let link = LINKS.find((l) => l.arg === linkName);
52
51
  if (linkName && !link) {
53
- throw new error_1.FirebaseError("Unrecognized link name. Valid links are:\n\n" + _.map(LINKS, "arg").join("\n"));
52
+ throw new error_1.FirebaseError("Unrecognized link name. Valid links are:\n\n" + LINKS.map((l) => l.arg).join("\n"));
54
53
  }
55
54
  if (!link) {
56
55
  const name = await (0, prompt_1.promptOnce)({
@@ -58,10 +57,10 @@ exports.command = new command_1.Command("open [link]")
58
57
  message: "What link would you like to open?",
59
58
  choices: CHOICES,
60
59
  });
61
- link = _.find(LINKS, { name });
60
+ link = LINKS.find((l) => l.name === name);
62
61
  }
63
62
  if (!link) {
64
- throw new error_1.FirebaseError("Unrecognized link name. Valid links are:\n\n" + _.map(LINKS, "arg").join("\n"));
63
+ throw new error_1.FirebaseError("Unrecognized link name. Valid links are:\n\n" + LINKS.map((l) => l.arg).join("\n"));
65
64
  }
66
65
  let url;
67
66
  if (link.consolePath) {
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
4
  const clc = require("cli-color");
5
- const _ = require("lodash");
6
5
  const command_1 = require("../command");
7
6
  const logger_1 = require("../logger");
8
7
  const utils = require("../utils");
@@ -14,14 +13,13 @@ const projectUtils_1 = require("../projectUtils");
14
13
  const error_1 = require("../error");
15
14
  const VALID_TARGETS = ["hosting", "functions"];
16
15
  const REQUIRES_AUTH = ["hosting", "functions"];
17
- const ALL_TARGETS = _.union(VALID_TARGETS, ["database", "firestore"]);
16
+ const ALL_TARGETS = Array.from(new Set(["database", "firestore", ...VALID_TARGETS]));
18
17
  function filterOnly(list, only = "") {
19
18
  if (!only) {
20
19
  return [];
21
20
  }
22
- return _.intersection(list, only.split(",").map((opt) => {
23
- return opt.split(":")[0];
24
- }));
21
+ const targets = only.split(",").map((o) => o.split(":")[0]);
22
+ return targets.filter((t) => list.includes(t));
25
23
  }
26
24
  exports.command = new command_1.Command("serve")
27
25
  .description("start a local server for your static assets")
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
- const _ = require("lodash");
5
4
  const clc = require("cli-color");
6
5
  const command_1 = require("../command");
7
6
  const projects_1 = require("../management/projects");
@@ -14,7 +13,7 @@ function listAliases(options) {
14
13
  if (options.rc.hasProjects) {
15
14
  logger_1.logger.info("Project aliases for", clc.bold(options.projectRoot) + ":");
16
15
  logger_1.logger.info();
17
- _.forEach(options.rc.projects, (projectId, alias) => {
16
+ for (const [alias, projectId] of Object.entries(options.rc.projects)) {
18
17
  const listing = alias + " (" + projectId + ")";
19
18
  if (options.project === projectId || options.projectAlias === alias) {
20
19
  logger_1.logger.info(clc.cyan.bold("* " + listing));
@@ -22,7 +21,7 @@ function listAliases(options) {
22
21
  else {
23
22
  logger_1.logger.info(" " + listing);
24
23
  }
25
- });
24
+ }
26
25
  logger_1.logger.info();
27
26
  }
28
27
  logger_1.logger.info("Run", clc.bold("firebase use --add"), "to define a new project alias.");