firebase-tools 10.4.1 → 10.4.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.
@@ -35,7 +35,7 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
35
35
  .before(extensionsHelper_1.diagnoseAndFixProject)
36
36
  .action(async (instanceId, options) => {
37
37
  var _a;
38
- const projectId = (0, projectUtils_1.needProjectId)(options);
38
+ const projectId = (0, projectUtils_1.getProjectId)(options);
39
39
  if (options.local) {
40
40
  if (options.nonInteractive) {
41
41
  throw new error_1.FirebaseError(`Command not supported in non-interactive mode, edit ./extensions/${instanceId}.env directly instead`);
@@ -77,7 +77,7 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
77
77
  try {
78
78
  let existingInstance;
79
79
  try {
80
- existingInstance = await extensionsApi.getInstance(projectId, instanceId);
80
+ existingInstance = await extensionsApi.getInstance((0, projectUtils_1.needProjectId)({ projectId }), instanceId);
81
81
  }
82
82
  catch (err) {
83
83
  if (err.status === 404) {
@@ -113,13 +113,13 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
113
113
  }
114
114
  spinner.start();
115
115
  const res = await extensionsApi.configureInstance({
116
- projectId,
116
+ projectId: (0, projectUtils_1.needProjectId)({ projectId }),
117
117
  instanceId,
118
118
  params: paramBindings,
119
119
  });
120
120
  spinner.stop();
121
121
  utils.logLabeledSuccess(extensionsHelper_1.logPrefix, `successfully configured ${clc.bold(instanceId)}.`);
122
- utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked(`You can view your reconfigured instance in the Firebase console: ${utils.consoleUrl(projectId, `/extensions/instances/${instanceId}?tab=config`)}`));
122
+ utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked(`You can view your reconfigured instance in the Firebase console: ${utils.consoleUrl((0, projectUtils_1.needProjectId)({ projectId }), `/extensions/instances/${instanceId}?tab=config`)}`));
123
123
  manifest.showDeprecationWarning();
124
124
  return res;
125
125
  }
@@ -47,7 +47,7 @@ exports.default = new command_1.Command("ext:install [extensionName]")
47
47
  .before(extensionsHelper_1.diagnoseAndFixProject)
48
48
  .action(async (extensionName, options) => {
49
49
  var _a;
50
- const projectId = (0, projectUtils_1.needProjectId)(options);
50
+ const projectId = (0, projectUtils_1.getProjectId)(options);
51
51
  const paramsEnvPath = ((_a = options.params) !== null && _a !== void 0 ? _a : "");
52
52
  let learnMore = false;
53
53
  if (!extensionName) {
@@ -71,7 +71,7 @@ exports.default = new command_1.Command("ext:install [extensionName]")
71
71
  if (options.local) {
72
72
  throw new error_1.FirebaseError("Installing a local source locally is not supported yet, please use ext:dev:emulator commands");
73
73
  }
74
- source = await infoInstallBySource(projectId, extensionName);
74
+ source = await infoInstallBySource((0, projectUtils_1.needProjectId)({ projectId }), extensionName);
75
75
  }
76
76
  else {
77
77
  void (0, track_1.track)("Extension Install", "Install by Extension Ref", options.interactive ? 1 : 0);
@@ -120,7 +120,7 @@ exports.default = new command_1.Command("ext:install [extensionName]")
120
120
  try {
121
121
  return installExtension({
122
122
  paramsEnvPath,
123
- projectId,
123
+ projectId: projectId,
124
124
  extensionName,
125
125
  source,
126
126
  extVersion,
@@ -195,7 +195,8 @@ async function installToManifest(options) {
195
195
  manifest.showPreviewWarning();
196
196
  }
197
197
  async function installExtension(options) {
198
- const { projectId, extensionName, source, extVersion, paramsEnvPath, nonInteractive, force } = options;
198
+ const { extensionName, source, extVersion, paramsEnvPath, nonInteractive, force } = options;
199
+ const projectId = (0, projectUtils_1.needProjectId)({ projectId: options.projectId });
199
200
  const spec = (source === null || source === void 0 ? void 0 : source.spec) || (extVersion === null || extVersion === void 0 ? void 0 : extVersion.spec);
200
201
  if (!spec) {
201
202
  throw new error_1.FirebaseError(`Could not find the extension.yaml for ${extensionName}. Please make sure this is a valid extension and try again.`);
@@ -42,8 +42,8 @@ exports.default = new command_1.Command("ext:update <extensionInstanceId> [updat
42
42
  .option("--local", "save the update to firebase.json rather than directly update an existing Extension instance on a Firebase project")
43
43
  .action(async (instanceId, updateSource, options) => {
44
44
  var _a, _b;
45
- const projectId = (0, projectUtils_1.needProjectId)(options);
46
45
  if (options.local) {
46
+ const projectId = (0, projectUtils_1.getProjectId)(options);
47
47
  const config = manifest.loadConfig(options);
48
48
  const oldRef = manifest.getInstanceRef(instanceId, config);
49
49
  const oldExtensionVersion = await extensionsApi.getExtensionVersion(refs.toExtensionVersionRef(oldRef));
@@ -95,6 +95,7 @@ exports.default = new command_1.Command("ext:update <extensionInstanceId> [updat
95
95
  }
96
96
  const spinner = ora(`Updating ${clc.bold(instanceId)}. This usually takes 3 to 5 minutes...`);
97
97
  try {
98
+ const projectId = (0, projectUtils_1.needProjectId)(options);
98
99
  let existingInstance;
99
100
  try {
100
101
  existingInstance = await extensionsApi.getInstance(projectId, instanceId);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ensureServiceAgentRoles = exports.mergeBindings = exports.checkHttpIam = exports.checkServiceAccountIam = void 0;
3
+ exports.ensureServiceAgentRoles = exports.mergeBindings = exports.obtainEventarcServiceAgentBindings = exports.obtainDefaultComputeServiceAgentBindings = exports.obtainPubSubServiceAgentBindings = exports.obtainBinding = exports.checkHttpIam = exports.checkServiceAccountIam = exports.EVENTARC_SERVICE_AGENT_ROLE = exports.EVENTARC_EVENT_RECEIVER_ROLE = exports.RUN_INVOKER_ROLE = exports.SERVICE_ACCOUNT_TOKEN_CREATOR_ROLE = void 0;
4
4
  const cli_color_1 = require("cli-color");
5
5
  const logger_1 = require("../../logger");
6
6
  const functionsDeployHelper_1 = require("./functionsDeployHelper");
@@ -12,6 +12,10 @@ const utils = require("../../utils");
12
12
  const resourceManager_1 = require("../../gcp/resourceManager");
13
13
  const services_1 = require("./services");
14
14
  const PERMISSION = "cloudfunctions.functions.setIamPolicy";
15
+ exports.SERVICE_ACCOUNT_TOKEN_CREATOR_ROLE = "roles/iam.serviceAccountTokenCreator";
16
+ exports.RUN_INVOKER_ROLE = "roles/run.invoker";
17
+ exports.EVENTARC_EVENT_RECEIVER_ROLE = "roles/eventarc.eventReceiver";
18
+ exports.EVENTARC_SERVICE_AGENT_ROLE = "roles/eventarc.serviceAgent";
15
19
  async function checkServiceAccountIam(projectId) {
16
20
  const saEmail = `${projectId}@appspot.gserviceaccount.com`;
17
21
  let passed = false;
@@ -67,6 +71,37 @@ function reduceEventsToServices(services, endpoint) {
67
71
  }
68
72
  return services;
69
73
  }
74
+ function obtainBinding(existingPolicy, serviceAccount, role) {
75
+ let binding = existingPolicy.bindings.find((b) => b.role === role);
76
+ if (!binding) {
77
+ binding = {
78
+ role,
79
+ members: [],
80
+ };
81
+ }
82
+ if (!binding.members.find((m) => m === serviceAccount)) {
83
+ binding.members.push(serviceAccount);
84
+ }
85
+ return binding;
86
+ }
87
+ exports.obtainBinding = obtainBinding;
88
+ function obtainPubSubServiceAgentBindings(projectNumber, existingPolicy) {
89
+ const pubsubServiceAgent = `serviceAccount:service-${projectNumber}@gcp-sa-pubsub.iam.gserviceaccount.com`;
90
+ return [obtainBinding(existingPolicy, pubsubServiceAgent, exports.SERVICE_ACCOUNT_TOKEN_CREATOR_ROLE)];
91
+ }
92
+ exports.obtainPubSubServiceAgentBindings = obtainPubSubServiceAgentBindings;
93
+ function obtainDefaultComputeServiceAgentBindings(projectNumber, existingPolicy) {
94
+ const defaultComputeServiceAgent = `serviceAccount:${projectNumber}-compute@developer.gserviceaccount.com`;
95
+ const invokerBinding = obtainBinding(existingPolicy, defaultComputeServiceAgent, exports.RUN_INVOKER_ROLE);
96
+ const eventReceiverBinding = obtainBinding(existingPolicy, defaultComputeServiceAgent, exports.EVENTARC_EVENT_RECEIVER_ROLE);
97
+ return [invokerBinding, eventReceiverBinding];
98
+ }
99
+ exports.obtainDefaultComputeServiceAgentBindings = obtainDefaultComputeServiceAgentBindings;
100
+ function obtainEventarcServiceAgentBindings(projectNumber, existingPolicy) {
101
+ const eventarcServiceAgent = `serviceAccount:service-${projectNumber}@gcp-sa-eventarc.iam.gserviceaccount.com`;
102
+ return [obtainBinding(existingPolicy, eventarcServiceAgent, exports.EVENTARC_SERVICE_AGENT_ROLE)];
103
+ }
104
+ exports.obtainEventarcServiceAgentBindings = obtainEventarcServiceAgentBindings;
70
105
  function mergeBindings(policy, allRequiredBindings) {
71
106
  for (const requiredBindings of allRequiredBindings) {
72
107
  if (requiredBindings.length === 0) {
@@ -107,6 +142,14 @@ async function ensureServiceAgentRoles(projectNumber, want, have) {
107
142
  const findRequiredBindings = [];
108
143
  newServices.forEach((service) => findRequiredBindings.push(service.requiredProjectBindings(projectNumber, policy)));
109
144
  const allRequiredBindings = await Promise.all(findRequiredBindings);
145
+ if (haveServices.length === 0) {
146
+ allRequiredBindings.push(obtainPubSubServiceAgentBindings(projectNumber, policy));
147
+ allRequiredBindings.push(obtainDefaultComputeServiceAgentBindings(projectNumber, policy));
148
+ allRequiredBindings.push(obtainEventarcServiceAgentBindings(projectNumber, policy));
149
+ }
150
+ if (!allRequiredBindings.find((bindings) => bindings.length > 0)) {
151
+ return;
152
+ }
110
153
  mergeBindings(policy, allRequiredBindings);
111
154
  try {
112
155
  await (0, resourceManager_1.setIamPolicy)(projectNumber, policy, "bindings");
@@ -1,23 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ensureFirebaseAlertsTriggerRegion = exports.obtainFirebaseAlertsBindings = exports.SERVICE_ACCOUNT_TOKEN_CREATOR_ROLE = void 0;
3
+ exports.ensureFirebaseAlertsTriggerRegion = void 0;
4
4
  const error_1 = require("../../../error");
5
- exports.SERVICE_ACCOUNT_TOKEN_CREATOR_ROLE = "roles/iam.serviceAccountTokenCreator";
6
- function obtainFirebaseAlertsBindings(projectNumber, existingPolicy) {
7
- const pubsubServiceAgent = `serviceAccount:service-${projectNumber}@gcp-sa-pubsub.iam.gserviceaccount.com`;
8
- let pubsubBinding = existingPolicy.bindings.find((b) => b.role === exports.SERVICE_ACCOUNT_TOKEN_CREATOR_ROLE);
9
- if (!pubsubBinding) {
10
- pubsubBinding = {
11
- role: exports.SERVICE_ACCOUNT_TOKEN_CREATOR_ROLE,
12
- members: [],
13
- };
14
- }
15
- if (!pubsubBinding.members.find((m) => m === pubsubServiceAgent)) {
16
- pubsubBinding.members.push(pubsubServiceAgent);
17
- }
18
- return Promise.resolve([pubsubBinding]);
19
- }
20
- exports.obtainFirebaseAlertsBindings = obtainFirebaseAlertsBindings;
21
5
  function ensureFirebaseAlertsTriggerRegion(endpoint) {
22
6
  if (!endpoint.eventTrigger.region) {
23
7
  endpoint.eventTrigger.region = "global";
@@ -5,6 +5,7 @@ const backend = require("../backend");
5
5
  const storage_1 = require("./storage");
6
6
  const firebaseAlerts_1 = require("./firebaseAlerts");
7
7
  const noop = () => Promise.resolve();
8
+ const noopProjectBindings = () => Promise.resolve([]);
8
9
  exports.NoOpService = {
9
10
  name: "noop",
10
11
  api: "",
@@ -26,7 +27,7 @@ exports.StorageService = {
26
27
  exports.FirebaseAlertsService = {
27
28
  name: "firebasealerts",
28
29
  api: "logging.googleapis.com",
29
- requiredProjectBindings: firebaseAlerts_1.obtainFirebaseAlertsBindings,
30
+ requiredProjectBindings: noopProjectBindings,
30
31
  ensureTriggerRegion: firebaseAlerts_1.ensureFirebaseAlertsTriggerRegion,
31
32
  };
32
33
  exports.EVENT_SERVICE_MAPPING = {
@@ -289,7 +289,7 @@ class FunctionsEmulator {
289
289
  });
290
290
  for (const definition of toSetup) {
291
291
  try {
292
- (0, validate_1.functionIdsAreValid)([definition]);
292
+ (0, validate_1.functionIdsAreValid)([Object.assign(Object.assign({}, definition), { id: definition.name })]);
293
293
  }
294
294
  catch (e) {
295
295
  this.logger.logLabeled("WARN", `functions[${definition.id}]`, `Invalid function id: ${e.message}`);
@@ -488,26 +488,16 @@ class FunctionsEmulator {
488
488
  return def.eventTrigger ? `${def.id}-${this.triggerGeneration}` : def.id;
489
489
  }
490
490
  getBackendInfo() {
491
- const cf3Triggers = Object.values(this.triggers)
492
- .filter((t) => !t.backend.extensionInstanceId)
493
- .map((t) => t.def);
491
+ const cf3Triggers = this.getCF3Triggers();
494
492
  return this.args.emulatableBackends.map((e) => {
495
- var _a;
496
- const envWithSecrets = Object.assign({}, e.env);
497
- for (const s of e.secretEnv) {
498
- envWithSecrets[s.key] = backend.secretVersionName(s);
499
- }
500
- return {
501
- directory: e.functionsDir,
502
- env: envWithSecrets,
503
- extensionInstanceId: e.extensionInstanceId,
504
- extension: e.extension,
505
- extensionVersion: e.extensionVersion,
506
- extensionSpec: e.extensionSpec,
507
- functionTriggers: (_a = e.predefinedTriggers) !== null && _a !== void 0 ? _a : cf3Triggers,
508
- };
493
+ return (0, functionsEmulatorShared_1.toBackendInfo)(e, cf3Triggers);
509
494
  });
510
495
  }
496
+ getCF3Triggers() {
497
+ return Object.values(this.triggers)
498
+ .filter((t) => !t.backend.extensionInstanceId)
499
+ .map((t) => t.def);
500
+ }
511
501
  addTriggerRecord(def, opts) {
512
502
  const key = this.getTriggerKey(def);
513
503
  this.triggers[key] = {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSecretLocalPath = exports.getSignatureType = exports.formatHost = exports.findModuleRoot = exports.waitForBody = exports.getServiceFromEventType = exports.getFunctionService = exports.getTemporarySocketPath = exports.getEmulatedTriggersFromDefinitions = exports.emulatedFunctionsByRegion = exports.emulatedFunctionsFromEndpoints = exports.EmulatedTrigger = exports.HttpConstants = void 0;
3
+ exports.toBackendInfo = exports.getSecretLocalPath = exports.getSignatureType = exports.formatHost = exports.findModuleRoot = exports.waitForBody = exports.getServiceFromEventType = exports.getFunctionService = exports.getTemporarySocketPath = exports.getEmulatedTriggersFromDefinitions = exports.emulatedFunctionsByRegion = exports.emulatedFunctionsFromEndpoints = exports.EmulatedTrigger = exports.HttpConstants = void 0;
4
4
  const _ = require("lodash");
5
5
  const os = require("os");
6
6
  const path = require("path");
@@ -10,6 +10,7 @@ const constants_1 = require("./constants");
10
10
  const proto_1 = require("../gcp/proto");
11
11
  const logger_1 = require("../logger");
12
12
  const manifest_1 = require("../extensions/manifest");
13
+ const extensionsHelper_1 = require("../extensions/extensionsHelper");
13
14
  const memoryLookup = {
14
15
  "128MB": 128,
15
16
  "256MB": 256,
@@ -242,3 +243,28 @@ function getSecretLocalPath(backend, projectDir) {
242
243
  return path.join(secretDirectory, secretsFile);
243
244
  }
244
245
  exports.getSecretLocalPath = getSecretLocalPath;
246
+ function toBackendInfo(e, cf3Triggers) {
247
+ var _a;
248
+ const envWithSecrets = Object.assign({}, e.env);
249
+ for (const s of e.secretEnv) {
250
+ envWithSecrets[s.key] = backend.secretVersionName(s);
251
+ }
252
+ let extensionVersion = e.extensionVersion;
253
+ if (extensionVersion) {
254
+ extensionVersion = (0, extensionsHelper_1.substituteParams)(extensionVersion, e.env);
255
+ }
256
+ let extensionSpec = e.extensionSpec;
257
+ if (extensionSpec) {
258
+ extensionSpec = (0, extensionsHelper_1.substituteParams)(extensionSpec, e.env);
259
+ }
260
+ return JSON.parse(JSON.stringify({
261
+ directory: e.functionsDir,
262
+ env: envWithSecrets,
263
+ extensionInstanceId: e.extensionInstanceId,
264
+ extension: e.extension,
265
+ extensionVersion: extensionVersion,
266
+ extensionSpec: extensionSpec,
267
+ functionTriggers: (_a = e.predefinedTriggers) !== null && _a !== void 0 ? _a : cf3Triggers,
268
+ }));
269
+ }
270
+ exports.toBackendInfo = toBackendInfo;
@@ -12,6 +12,7 @@ const utils_1 = require("./utils");
12
12
  const logger_1 = require("../logger");
13
13
  const prompt_1 = require("../prompt");
14
14
  const utils = require("../utils");
15
+ const projectUtils_1 = require("../projectUtils");
15
16
  var SecretLocation;
16
17
  (function (SecretLocation) {
17
18
  SecretLocation[SecretLocation["CLOUD"] = 1] = "CLOUD";
@@ -60,21 +61,21 @@ function checkResponse(response, spec) {
60
61
  return valid;
61
62
  }
62
63
  exports.checkResponse = checkResponse;
63
- async function ask(projectId, instanceId, paramSpecs, firebaseProjectParams, reconfiguring) {
64
- if (_.isEmpty(paramSpecs)) {
64
+ async function ask(args) {
65
+ if (_.isEmpty(args.paramSpecs)) {
65
66
  logger_1.logger.debug("No params were specified for this extension.");
66
67
  return {};
67
68
  }
68
69
  utils.logLabeledBullet(extensionsHelper_1.logPrefix, "answer the questions below to configure your extension:");
69
- const substituted = (0, extensionsHelper_1.substituteParams)(paramSpecs, firebaseProjectParams);
70
+ const substituted = (0, extensionsHelper_1.substituteParams)(args.paramSpecs, args.firebaseProjectParams);
70
71
  const result = {};
71
72
  const promises = _.map(substituted, (paramSpec) => {
72
73
  return async () => {
73
74
  result[paramSpec.param] = await askForParam({
74
- projectId,
75
- instanceId,
76
- paramSpec,
77
- reconfiguring,
75
+ projectId: args.projectId,
76
+ instanceId: args.instanceId,
77
+ paramSpec: paramSpec,
78
+ reconfiguring: args.reconfiguring,
78
79
  });
79
80
  };
80
81
  });
@@ -133,9 +134,10 @@ async function askForParam(args) {
133
134
  secretLocations = await promptSecretLocations(paramSpec);
134
135
  } while (!isValidSecretLocations(secretLocations, paramSpec));
135
136
  if (secretLocations.includes(SecretLocation.CLOUD.toString())) {
137
+ const projectId = (0, projectUtils_1.needProjectId)({ projectId: args.projectId });
136
138
  response = args.reconfiguring
137
- ? await promptReconfigureSecret(args.projectId, args.instanceId, paramSpec)
138
- : await promptCreateSecret(args.projectId, args.instanceId, paramSpec);
139
+ ? await promptReconfigureSecret(projectId, args.instanceId, paramSpec)
140
+ : await promptCreateSecret(projectId, args.instanceId, paramSpec);
139
141
  }
140
142
  if (secretLocations.includes(SecretLocation.LOCAL.toString())) {
141
143
  responseForLocal = await promptLocalSecret(args.instanceId, paramSpec);
@@ -80,6 +80,9 @@ function getDBInstanceFromURL(databaseUrl = "") {
80
80
  exports.getDBInstanceFromURL = getDBInstanceFromURL;
81
81
  async function getFirebaseProjectParams(projectId, emulatorMode = false) {
82
82
  var _a, _b;
83
+ if (!projectId) {
84
+ return {};
85
+ }
83
86
  const body = emulatorMode
84
87
  ? await (0, adminSdkConfig_1.getProjectAdminSdkConfigOrCached)(projectId)
85
88
  : await (0, functionsConfig_1.getFirebaseConfig)({ project: projectId });
@@ -263,7 +266,10 @@ async function promptForValidInstanceId(instanceId) {
263
266
  }
264
267
  exports.promptForValidInstanceId = promptForValidInstanceId;
265
268
  async function ensureExtensionsApiEnabled(options) {
266
- const projectId = (0, projectUtils_1.needProjectId)(options);
269
+ const projectId = (0, projectUtils_1.getProjectId)(options);
270
+ if (!projectId) {
271
+ return;
272
+ }
267
273
  return await (0, ensureApiEnabled_1.ensure)(projectId, "firebaseextensions.googleapis.com", "extensions", options.markdown);
268
274
  }
269
275
  exports.ensureExtensionsApiEnabled = ensureExtensionsApiEnabled;
@@ -519,7 +525,10 @@ async function confirm(args) {
519
525
  }
520
526
  exports.confirm = confirm;
521
527
  async function diagnoseAndFixProject(options) {
522
- const projectId = (0, projectUtils_1.needProjectId)(options);
528
+ const projectId = (0, projectUtils_1.getProjectId)(options);
529
+ if (!projectId) {
530
+ return;
531
+ }
523
532
  const ok = await (0, diagnose_1.diagnose)(projectId);
524
533
  if (!ok) {
525
534
  throw new error_1.FirebaseError("Unable to proceed until all issues are resolved.");
@@ -57,14 +57,19 @@ async function getParams(args) {
57
57
  }
58
58
  else if (args.paramsEnvPath) {
59
59
  params = getParamsFromFile({
60
- projectId: args.projectId,
61
60
  paramSpecs: args.paramSpecs,
62
61
  paramsEnvPath: args.paramsEnvPath,
63
62
  });
64
63
  }
65
64
  else {
66
65
  const firebaseProjectParams = await (0, extensionsHelper_1.getFirebaseProjectParams)(args.projectId);
67
- params = await askUserForParam.ask(args.projectId, args.instanceId, args.paramSpecs, firebaseProjectParams, !!args.reconfiguring);
66
+ params = await askUserForParam.ask({
67
+ projectId: args.projectId,
68
+ instanceId: args.instanceId,
69
+ paramSpecs: args.paramSpecs,
70
+ firebaseProjectParams,
71
+ reconfiguring: !!args.reconfiguring,
72
+ });
68
73
  }
69
74
  void track("Extension Params", _.isEmpty(params) ? "Not Present" : "Present", _.size(params));
70
75
  return params;
@@ -85,7 +90,6 @@ async function getParamsForUpdate(args) {
85
90
  }
86
91
  else if (args.paramsEnvPath) {
87
92
  params = getParamsFromFile({
88
- projectId: args.projectId,
89
93
  paramSpecs: args.newSpec.params,
90
94
  paramsEnvPath: args.paramsEnvPath,
91
95
  });
@@ -9,7 +9,10 @@ const error_1 = require("./error");
9
9
  const iam_1 = require("./gcp/iam");
10
10
  const BASE_PERMISSIONS = ["firebase.projects.get"];
11
11
  async function requirePermissions(options, permissions = []) {
12
- const projectId = (0, projectUtils_1.needProjectId)(options);
12
+ const projectId = (0, projectUtils_1.getProjectId)(options);
13
+ if (!projectId) {
14
+ return;
15
+ }
13
16
  const requiredPermissions = BASE_PERMISSIONS.concat(permissions).sort();
14
17
  await (0, requireAuth_1.requireAuth)(options);
15
18
  logger_1.logger.debug(`[iam] checking project ${projectId} for permissions ${JSON.stringify(requiredPermissions)}`);
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "firebase-tools",
3
- "version": "10.4.1",
3
+ "version": "10.4.2",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "firebase-tools",
9
- "version": "10.4.1",
9
+ "version": "10.4.2",
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.4.1",
3
+ "version": "10.4.2",
4
4
  "description": "Command-Line Interface for Firebase",
5
5
  "main": "./lib/index.js",
6
6
  "bin": {