firebase-tools 10.9.0 → 11.0.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.
package/README.md CHANGED
@@ -136,15 +136,21 @@ Detailed doc is [here](https://firebase.google.com/docs/cli/auth).
136
136
 
137
137
  ### Cloud Functions Commands
138
138
 
139
- | Command | Description |
140
- | -------------------------- | ------------------------------------------------------------------------------------------------------------ |
141
- | **functions:log** | Read logs from deployed Cloud Functions. |
142
- | **functions:config:set** | Store runtime configuration values for the current project's Cloud Functions. |
143
- | **functions:config:get** | Retrieve existing configuration values for the current project's Cloud Functions. |
144
- | **functions:config:unset** | Remove values from the current project's runtime configuration. |
145
- | **functions:config:clone** | Copy runtime configuration from one project environment to another. |
146
- | **functions:delete** | Delete one or more Cloud Functions by name or group name. |
147
- | **functions:shell** | Locally emulate functions and start Node.js shell where these local functions can be invoked with test data. |
139
+ | Command | Description |
140
+ | ----------------------------- | ------------------------------------------------------------------------------------------------------------ |
141
+ | **functions:log** | Read logs from deployed Cloud Functions. |
142
+ | **functions:list** | List all deployed functions in your Firebase project. |
143
+ | **functions:config:set** | Store runtime configuration values for the current project's Cloud Functions. |
144
+ | **functions:config:get** | Retrieve existing configuration values for the current project's Cloud Functions. |
145
+ | **functions:config:unset** | Remove values from the current project's runtime configuration. |
146
+ | **functions:config:clone** | Copy runtime configuration from one project environment to another. |
147
+ | **functions:secrets:set** | Create or update a secret for use in Cloud Functions for Firebase. |
148
+ | **functions:secrets:get** | Get metadata for secret and its versions. |
149
+ | **functions:secrets:access** | Access secret value given secret and its version. Defaults to accessing the latest version. |
150
+ | **functions:secrets:prune** | Destroys unused secrets. |
151
+ | **functions:secrets:destroy** | Destroy a secret. Defaults to destroying the latest version. |
152
+ | **functions:delete** | Delete one or more Cloud Functions by name or group name. |
153
+ | **functions:shell** | Locally emulate functions and start Node.js shell where these local functions can be invoked with test data. |
148
154
 
149
155
  ### Hosting Commands
150
156
 
@@ -10,11 +10,14 @@ const error_1 = require("../error");
10
10
  const requireAuth_1 = require("../requireAuth");
11
11
  const logger_1 = require("../logger");
12
12
  const prompt_1 = require("../prompt");
13
- async function selectAppInteractively(apps, appPlatform) {
14
- if (apps.length === 0) {
13
+ function checkForApps(apps, appPlatform) {
14
+ if (!apps.length) {
15
15
  throw new error_1.FirebaseError(`There are no ${appPlatform === apps_1.AppPlatform.ANY ? "" : appPlatform + " "}apps ` +
16
16
  "associated with this Firebase project");
17
17
  }
18
+ }
19
+ async function selectAppInteractively(apps, appPlatform) {
20
+ checkForApps(apps, appPlatform);
18
21
  const choices = apps.map((app) => {
19
22
  return {
20
23
  name: `${app.displayName || app.bundleId || app.packageName}` +
@@ -46,6 +49,7 @@ module.exports = new command_1.Command("apps:sdkconfig [platform] [appId]")
46
49
  projectId = result.projectId;
47
50
  }
48
51
  const apps = await (0, apps_1.listFirebaseApps)(projectId, appPlatform);
52
+ checkForApps(apps, appPlatform);
49
53
  if (apps.length === 1) {
50
54
  appId = apps[0].appId;
51
55
  appPlatform = apps[0].platform;
@@ -1,9 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const _ = require("lodash");
4
- const clc = require("cli-color");
5
3
  const { marked } = require("marked");
6
- const ora = require("ora");
7
4
  const TerminalRenderer = require("marked-terminal");
8
5
  const checkMinRequiredVersion_1 = require("../checkMinRequiredVersion");
9
6
  const command_1 = require("../command");
@@ -26,8 +23,6 @@ marked.setOptions({
26
23
  exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
27
24
  .description("configure an existing extension instance")
28
25
  .withForce()
29
- .option("--params <paramsFile>", "path of params file with .env format.")
30
- .option("--local", "save to firebase.json rather than directly install to a Firebase project")
31
26
  .before(requirePermissions_1.requirePermissions, [
32
27
  "firebaseextensions.instances.update",
33
28
  "firebaseextensions.instances.get",
@@ -35,126 +30,62 @@ exports.default = new command_1.Command("ext:configure <extensionInstanceId>")
35
30
  .before(checkMinRequiredVersion_1.checkMinRequiredVersion, "extMinVersion")
36
31
  .before(extensionsHelper_1.diagnoseAndFixProject)
37
32
  .action(async (instanceId, options) => {
38
- var _a;
39
33
  const projectId = (0, projectUtils_1.getProjectId)(options);
40
- if (options.local) {
41
- if (options.nonInteractive) {
42
- throw new error_1.FirebaseError(`Command not supported in non-interactive mode, edit ./extensions/${instanceId}.env directly instead`);
43
- }
44
- const config = manifest.loadConfig(options);
45
- const refOrPath = manifest.getInstanceTarget(instanceId, config);
46
- const isLocalSource = (0, extensionsHelper_1.isLocalPath)(refOrPath);
47
- let spec;
48
- if (isLocalSource) {
49
- const source = await (0, extensionsHelper_1.createSourceFromLocation)((0, projectUtils_1.needProjectId)({ projectId }), refOrPath);
50
- spec = source.spec;
51
- }
52
- else {
53
- const extensionVersion = await extensionsApi.getExtensionVersion(refOrPath);
54
- spec = extensionVersion.spec;
55
- }
56
- const oldParamValues = manifest.readInstanceParam({
57
- instanceId,
58
- projectDir: config.projectDir,
59
- });
60
- const [immutableParams, tbdParams] = (0, functional_1.partition)(spec.params, (param) => { var _a; return (_a = param.immutable) !== null && _a !== void 0 ? _a : false; });
61
- infoImmutableParams(immutableParams, oldParamValues);
62
- paramHelper.setNewDefaults(tbdParams, oldParamValues);
63
- const mutableParamsBindingOptions = await paramHelper.getParams({
64
- projectId,
65
- paramSpecs: tbdParams,
66
- nonInteractive: false,
67
- paramsEnvPath: ((_a = options.params) !== null && _a !== void 0 ? _a : ""),
68
- instanceId,
69
- reconfiguring: true,
70
- });
71
- const eventsConfig = spec.events
72
- ? await askUserForEventsConfig.askForEventsConfig(spec.events, "${param:PROJECT_ID}", instanceId)
73
- : undefined;
74
- if (eventsConfig) {
75
- mutableParamsBindingOptions.EVENTARC_CHANNEL = { baseValue: eventsConfig.channel };
76
- mutableParamsBindingOptions.ALLOWED_EVENT_TYPES = {
77
- baseValue: eventsConfig.allowedEventTypes.join(","),
78
- };
79
- }
80
- const newParamOptions = Object.assign(Object.assign({}, (0, paramHelper_1.buildBindingOptionsWithBaseValue)(oldParamValues)), mutableParamsBindingOptions);
81
- await manifest.writeToManifest([
82
- {
83
- instanceId,
84
- ref: !isLocalSource ? refs.parse(refOrPath) : undefined,
85
- localPath: isLocalSource ? refOrPath : undefined,
86
- params: newParamOptions,
87
- extensionSpec: spec,
88
- },
89
- ], config, {
90
- nonInteractive: false,
91
- force: true,
92
- });
93
- manifest.showPreviewWarning();
94
- return;
34
+ if (options.nonInteractive) {
35
+ throw new error_1.FirebaseError(`Command not supported in non-interactive mode, edit ./extensions/${instanceId}.env directly instead. ` +
36
+ `See https://firebase.google.com/docs/extensions/manifest for more details.`);
95
37
  }
96
- if (!projectId) {
97
- throw new error_1.FirebaseError(`Project ID must be provided when re-configuring an instance outside of local mode.`);
38
+ const config = manifest.loadConfig(options);
39
+ const refOrPath = manifest.getInstanceTarget(instanceId, config);
40
+ const isLocalSource = (0, extensionsHelper_1.isLocalPath)(refOrPath);
41
+ let spec;
42
+ if (isLocalSource) {
43
+ const source = await (0, extensionsHelper_1.createSourceFromLocation)((0, projectUtils_1.needProjectId)({ projectId }), refOrPath);
44
+ spec = source.spec;
98
45
  }
99
- const spinner = ora(`Configuring ${clc.bold(instanceId)}. This usually takes 3 to 5 minutes...`);
100
- try {
101
- const existingInstance = await extensionsApi.getInstance((0, projectUtils_1.needProjectId)({ projectId }), instanceId);
102
- const paramSpecWithNewDefaults = paramHelper.getParamsWithCurrentValuesAsDefaults(existingInstance);
103
- const immutableParams = _.remove(paramSpecWithNewDefaults, (param) => param.immutable);
104
- const paramBindingOptions = await paramHelper.getParams({
105
- projectId,
106
- paramSpecs: paramSpecWithNewDefaults,
107
- nonInteractive: options.nonInteractive,
108
- paramsEnvPath: options.params,
109
- instanceId,
110
- reconfiguring: true,
111
- });
112
- const paramBindings = (0, paramHelper_1.getBaseParamBindings)(paramBindingOptions);
113
- if (immutableParams.length) {
114
- const plural = immutableParams.length > 1;
115
- logger_1.logger.info(`The following param${plural ? "s are" : " is"} immutable:`);
116
- for (const { param } of immutableParams) {
117
- const value = _.get(existingInstance, `config.params.${param}`);
118
- logger_1.logger.info(`param: ${param}, value: ${value}`);
119
- paramBindings[param] = value;
120
- }
121
- logger_1.logger.info((plural
122
- ? "To set different values for these params"
123
- : "To set a different value for this param") +
124
- ", uninstall the extension, then install a new instance of this extension.");
125
- }
126
- const pId = (0, projectUtils_1.needProjectId)({ projectId });
127
- const spec = existingInstance ? existingInstance.config.source.spec : undefined;
128
- const eventsConfig = spec.events
129
- ? await askUserForEventsConfig.askForEventsConfig(spec.events, pId, instanceId)
130
- : undefined;
131
- spinner.start();
132
- const configureOptions = {
133
- projectId: pId,
134
- instanceId,
135
- params: paramBindings,
136
- canEmitEvents: eventsConfig ? true : false,
137
- eventarcChannel: eventsConfig === null || eventsConfig === void 0 ? void 0 : eventsConfig.channel,
138
- allowedEventTypes: eventsConfig === null || eventsConfig === void 0 ? void 0 : eventsConfig.allowedEventTypes,
139
- };
140
- const res = await extensionsApi.configureInstance(configureOptions);
141
- spinner.stop();
142
- utils.logLabeledSuccess(extensionsHelper_1.logPrefix, `successfully configured ${clc.bold(instanceId)}.`);
143
- 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`)}`));
144
- manifest.showDeprecationWarning();
145
- return res;
46
+ else {
47
+ const extensionVersion = await extensionsApi.getExtensionVersion(refOrPath);
48
+ spec = extensionVersion.spec;
146
49
  }
147
- catch (err) {
148
- if (spinner.isSpinning) {
149
- spinner.fail();
150
- }
151
- if (!(err instanceof error_1.FirebaseError)) {
152
- throw new error_1.FirebaseError(`Error occurred while configuring the instance: ${err.message}`, {
153
- original: err,
154
- });
155
- }
156
- throw err;
50
+ const oldParamValues = manifest.readInstanceParam({
51
+ instanceId,
52
+ projectDir: config.projectDir,
53
+ });
54
+ const [immutableParams, tbdParams] = (0, functional_1.partition)(spec.params, (param) => { var _a; return (_a = param.immutable) !== null && _a !== void 0 ? _a : false; });
55
+ infoImmutableParams(immutableParams, oldParamValues);
56
+ paramHelper.setNewDefaults(tbdParams, oldParamValues);
57
+ const mutableParamsBindingOptions = await paramHelper.getParams({
58
+ projectId,
59
+ paramSpecs: tbdParams,
60
+ nonInteractive: false,
61
+ paramsEnvPath: "",
62
+ instanceId,
63
+ reconfiguring: true,
64
+ });
65
+ const eventsConfig = spec.events
66
+ ? await askUserForEventsConfig.askForEventsConfig(spec.events, "${param:PROJECT_ID}", instanceId)
67
+ : undefined;
68
+ if (eventsConfig) {
69
+ mutableParamsBindingOptions.EVENTARC_CHANNEL = { baseValue: eventsConfig.channel };
70
+ mutableParamsBindingOptions.ALLOWED_EVENT_TYPES = {
71
+ baseValue: eventsConfig.allowedEventTypes.join(","),
72
+ };
157
73
  }
74
+ const newParamOptions = Object.assign(Object.assign({}, (0, paramHelper_1.buildBindingOptionsWithBaseValue)(oldParamValues)), mutableParamsBindingOptions);
75
+ await manifest.writeToManifest([
76
+ {
77
+ instanceId,
78
+ ref: !isLocalSource ? refs.parse(refOrPath) : undefined,
79
+ localPath: isLocalSource ? refOrPath : undefined,
80
+ params: newParamOptions,
81
+ extensionSpec: spec,
82
+ },
83
+ ], config, {
84
+ nonInteractive: false,
85
+ force: true,
86
+ });
87
+ manifest.showPostDeprecationNotice();
88
+ return;
158
89
  });
159
90
  function infoImmutableParams(immutableParams, paramValues) {
160
91
  if (!immutableParams.length) {
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const clc = require("cli-color");
3
4
  const checkMinRequiredVersion_1 = require("../checkMinRequiredVersion");
4
5
  const command_1 = require("../command");
6
+ const error_1 = require("../error");
5
7
  const commandUtils = require("../emulator/commandUtils");
6
- const optionsHelper = require("../extensions/emulator/optionsHelper");
7
8
  module.exports = new command_1.Command("ext:dev:emulators:exec <script>")
8
- .description("emulate an extension, run a test script, then shut down the emulators")
9
+ .description("deprecated: please use `firebase emulators:exec` instead")
9
10
  .before(commandUtils.setExportOnExitOptions)
10
11
  .option(commandUtils.FLAG_INSPECT_FUNCTIONS, commandUtils.DESC_INSPECT_FUNCTIONS)
11
12
  .option(commandUtils.FLAG_TEST_CONFIG, commandUtils.DESC_TEST_CONFIG)
@@ -14,8 +15,12 @@ module.exports = new command_1.Command("ext:dev:emulators:exec <script>")
14
15
  .option(commandUtils.FLAG_EXPORT_ON_EXIT, commandUtils.DESC_EXPORT_ON_EXIT)
15
16
  .option(commandUtils.FLAG_UI, commandUtils.DESC_UI)
16
17
  .before(checkMinRequiredVersion_1.checkMinRequiredVersion, "extDevMinVersion")
17
- .action(async (script, options) => {
18
- const emulatorOptions = await optionsHelper.buildOptions(options);
19
- commandUtils.beforeEmulatorCommand(emulatorOptions);
20
- await commandUtils.emulatorExec(script, emulatorOptions);
18
+ .action((script, options) => {
19
+ const localInstallCommand = `firebase ext:install ${process.cwd()}`;
20
+ const emulatorsExecCommand = `firebase emulators:exec '${script}`;
21
+ throw new error_1.FirebaseError("ext:dev:emulators:exec is no longer supported. " +
22
+ "Instead, navigate to a Firebase project directory and add this extension to the extensions manifest by running:\n" +
23
+ clc.bold(localInstallCommand) +
24
+ "\nThen, you can emulate this extension as part of that project by running:\n" +
25
+ clc.bold(emulatorsExecCommand));
21
26
  });
@@ -1,39 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const checkMinRequiredVersion_1 = require("../checkMinRequiredVersion");
3
+ const clc = require("cli-color");
4
4
  const command_1 = require("../command");
5
- const controller = require("../emulator/controller");
6
5
  const commandUtils = require("../emulator/commandUtils");
7
- const optionsHelper = require("../extensions/emulator/optionsHelper");
8
- const utils = require("../utils");
9
6
  const error_1 = require("../error");
10
7
  module.exports = new command_1.Command("ext:dev:emulators:start")
11
- .description("start the local Firebase extension emulator")
8
+ .description("deprecated: please use `firebase emulators:start`")
12
9
  .before(commandUtils.setExportOnExitOptions)
13
10
  .option(commandUtils.FLAG_INSPECT_FUNCTIONS, commandUtils.DESC_INSPECT_FUNCTIONS)
14
11
  .option(commandUtils.FLAG_TEST_CONFIG, commandUtils.DESC_TEST_CONFIG)
15
12
  .option(commandUtils.FLAG_TEST_PARAMS, commandUtils.DESC_TEST_PARAMS)
16
13
  .option(commandUtils.FLAG_IMPORT, commandUtils.DESC_IMPORT)
17
14
  .option(commandUtils.FLAG_EXPORT_ON_EXIT, commandUtils.DESC_EXPORT_ON_EXIT)
18
- .before(checkMinRequiredVersion_1.checkMinRequiredVersion, "extDevMinVersion")
19
- .action(async (options) => {
20
- const killSignalPromise = commandUtils.shutdownWhenKilled(options);
21
- const emulatorOptions = await optionsHelper.buildOptions(options);
22
- let deprecationNotices;
23
- try {
24
- commandUtils.beforeEmulatorCommand(emulatorOptions);
25
- ({ deprecationNotices } = await controller.startAll(emulatorOptions));
26
- }
27
- catch (e) {
28
- await controller.cleanShutdown();
29
- if (!(e instanceof error_1.FirebaseError)) {
30
- throw new error_1.FirebaseError("Error in ext:dev:emulator:start", e);
31
- }
32
- throw e;
33
- }
34
- utils.logSuccess("All emulators ready, it is now safe to connect.");
35
- for (const notice of deprecationNotices) {
36
- utils.logLabeledWarning("emulators", notice, "warn");
37
- }
38
- await killSignalPromise;
15
+ .action((options) => {
16
+ const localInstallCommand = `firebase ext:install ${process.cwd()}`;
17
+ const emulatorsStartCommand = "firebase emulators:start";
18
+ throw new error_1.FirebaseError("ext:dev:emulators:start is no longer supported. " +
19
+ "Instead, navigate to a Firebase project directory and add this extension to the extensions manifest by running:\n" +
20
+ clc.bold(localInstallCommand) +
21
+ "\nThen, you can emulate this extension as part of that project by running:\n" +
22
+ clc.bold(emulatorsStartCommand));
39
23
  });
@@ -2,34 +2,24 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const clc = require("cli-color");
4
4
  const { marked } = require("marked");
5
- const ora = require("ora");
6
5
  const TerminalRenderer = require("marked-terminal");
7
- const askUserForConsent = require("../extensions/askUserForConsent");
8
6
  const displayExtensionInfo_1 = require("../extensions/displayExtensionInfo");
9
7
  const askUserForEventsConfig = require("../extensions/askUserForEventsConfig");
10
- const billingMigrationHelper_1 = require("../extensions/billingMigrationHelper");
11
- const checkProjectBilling_1 = require("../extensions/checkProjectBilling");
12
- const cloudbilling_1 = require("../gcp/cloudbilling");
13
8
  const checkMinRequiredVersion_1 = require("../checkMinRequiredVersion");
14
9
  const command_1 = require("../command");
15
10
  const error_1 = require("../error");
16
11
  const projectUtils_1 = require("../projectUtils");
17
12
  const extensionsApi = require("../extensions/extensionsApi");
18
- const secretsUtils = require("../extensions/secretsUtils");
19
- const provisioningHelper = require("../extensions/provisioningHelper");
20
13
  const refs = require("../extensions/refs");
21
14
  const warnings_1 = require("../extensions/warnings");
22
15
  const paramHelper = require("../extensions/paramHelper");
23
16
  const extensionsHelper_1 = require("../extensions/extensionsHelper");
24
- const updateHelper_1 = require("../extensions/updateHelper");
25
17
  const utils_1 = require("../extensions/utils");
26
18
  const requirePermissions_1 = require("../requirePermissions");
27
19
  const utils = require("../utils");
28
20
  const track_1 = require("../track");
29
- const logger_1 = require("../logger");
30
21
  const previews_1 = require("../previews");
31
22
  const manifest = require("../extensions/manifest");
32
- const paramHelper_1 = require("../extensions/paramHelper");
33
23
  marked.setOptions({
34
24
  renderer: new TerminalRenderer(),
35
25
  });
@@ -40,16 +30,14 @@ exports.default = new command_1.Command("ext:install [extensionName]")
40
30
  : "") +
41
31
  "or run with `-i` to see all available extensions.")
42
32
  .withForce()
43
- .option("--params <paramsFile>", "name of params variables file with .env format.")
44
- .option("--local", "save to firebase.json rather than directly install to a Firebase project")
45
33
  .before(requirePermissions_1.requirePermissions, ["firebaseextensions.instances.create"])
46
34
  .before(extensionsHelper_1.ensureExtensionsApiEnabled)
47
35
  .before(checkMinRequiredVersion_1.checkMinRequiredVersion, "extMinVersion")
48
36
  .before(extensionsHelper_1.diagnoseAndFixProject)
49
37
  .action(async (extensionName, options) => {
50
- var _a, _b;
38
+ var _a;
51
39
  const projectId = (0, projectUtils_1.getProjectId)(options);
52
- const paramsEnvPath = ((_a = options.params) !== null && _a !== void 0 ? _a : "");
40
+ const paramsEnvPath = "";
53
41
  let learnMore = false;
54
42
  if (!extensionName) {
55
43
  if (options.interactive) {
@@ -74,7 +62,7 @@ exports.default = new command_1.Command("ext:install [extensionName]")
74
62
  }
75
63
  else {
76
64
  void (0, track_1.track)("Extension Install", "Install by Extension Ref", options.interactive ? 1 : 0);
77
- extensionName = (0, extensionsHelper_1.canonicalizeRefInput)(extensionName);
65
+ extensionName = await (0, extensionsHelper_1.canonicalizeRefInput)(extensionName);
78
66
  extensionVersion = await extensionsApi.getExtensionVersion(extensionName);
79
67
  await infoExtensionVersion({
80
68
  extensionName,
@@ -91,7 +79,7 @@ exports.default = new command_1.Command("ext:install [extensionName]")
91
79
  if (!source && !extensionVersion) {
92
80
  throw new error_1.FirebaseError("Could not find a source. Please specify a valid source to continue.");
93
81
  }
94
- const spec = (_b = source === null || source === void 0 ? void 0 : source.spec) !== null && _b !== void 0 ? _b : extensionVersion === null || extensionVersion === void 0 ? void 0 : extensionVersion.spec;
82
+ const spec = (_a = source === null || source === void 0 ? void 0 : source.spec) !== null && _a !== void 0 ? _a : extensionVersion === null || extensionVersion === void 0 ? void 0 : extensionVersion.spec;
95
83
  if (!spec) {
96
84
  throw new error_1.FirebaseError(`Could not find the extension.yaml for extension '${clc.bold(extensionName)}'. Please make sure this is a valid extension and try again.`);
97
85
  }
@@ -100,31 +88,10 @@ exports.default = new command_1.Command("ext:install [extensionName]")
100
88
  `${spec.description}\n` +
101
89
  `View details: https://firebase.google.com/products/extensions/${spec.name}\n`);
102
90
  }
103
- if (options.local) {
104
- try {
105
- return installToManifest({
106
- paramsEnvPath,
107
- projectId,
108
- extensionName,
109
- source,
110
- extVersion: extensionVersion,
111
- nonInteractive: options.nonInteractive,
112
- force: options.force,
113
- });
114
- }
115
- catch (err) {
116
- if (!(err instanceof error_1.FirebaseError)) {
117
- throw new error_1.FirebaseError(`Error occurred saving the extension to manifest: ${err.message}`, {
118
- original: err,
119
- });
120
- }
121
- throw err;
122
- }
123
- }
124
91
  try {
125
- return installExtension({
92
+ return installToManifest({
126
93
  paramsEnvPath,
127
- projectId: projectId,
94
+ projectId,
128
95
  extensionName,
129
96
  source,
130
97
  extVersion: extensionVersion,
@@ -134,7 +101,7 @@ exports.default = new command_1.Command("ext:install [extensionName]")
134
101
  }
135
102
  catch (err) {
136
103
  if (!(err instanceof error_1.FirebaseError)) {
137
- throw new error_1.FirebaseError(`Error occurred installing the extension: ${err.message}`, {
104
+ throw new error_1.FirebaseError(`Error occurred saving the extension to manifest: ${err.message}`, {
138
105
  original: err,
139
106
  });
140
107
  }
@@ -186,161 +153,5 @@ async function installToManifest(options) {
186
153
  extensionSpec: spec,
187
154
  },
188
155
  ], config, { nonInteractive, force: force !== null && force !== void 0 ? force : false });
189
- manifest.showPreviewWarning();
190
- }
191
- async function installExtension(options) {
192
- const { extensionName, source, extVersion, paramsEnvPath, nonInteractive, force } = options;
193
- const projectId = (0, projectUtils_1.needProjectId)({ projectId: options.projectId });
194
- const spec = (source === null || source === void 0 ? void 0 : source.spec) || (extVersion === null || extVersion === void 0 ? void 0 : extVersion.spec);
195
- if (!spec) {
196
- throw new error_1.FirebaseError(`Could not find the extension.yaml for ${extensionName}. Please make sure this is a valid extension and try again.`);
197
- }
198
- const spinner = ora();
199
- try {
200
- await provisioningHelper.checkProductsProvisioned(projectId, spec);
201
- const usesSecrets = secretsUtils.usesSecrets(spec);
202
- if (spec.billingRequired || usesSecrets) {
203
- const enabled = await (0, cloudbilling_1.checkBillingEnabled)(projectId);
204
- if (!enabled && nonInteractive) {
205
- throw new error_1.FirebaseError(`This extension requires the Blaze plan, but project ${projectId} is not on the Blaze plan. ` +
206
- marked("Please visit https://console.cloud.google.com/billing/linkedaccount?project=${projectId} to upgrade your project."));
207
- }
208
- else if (!enabled) {
209
- await (0, billingMigrationHelper_1.displayNode10CreateBillingNotice)(spec, false);
210
- await (0, checkProjectBilling_1.enableBilling)(projectId);
211
- }
212
- else {
213
- await (0, billingMigrationHelper_1.displayNode10CreateBillingNotice)(spec, !nonInteractive);
214
- }
215
- }
216
- const apis = spec.apis || [];
217
- if (usesSecrets) {
218
- apis.push({
219
- apiName: "secretmanager.googleapis.com",
220
- reason: `To access and manage secrets which are used by this extension. By using this product you agree to the terms and conditions of the following license: https://console.cloud.google.com/tos?id=cloud&project=${projectId}`,
221
- });
222
- }
223
- if (spec.events && spec.events.length > 0) {
224
- apis.push({
225
- apiName: "eventarc.googleapis.com",
226
- reason: `When events are enabled, the Eventarc API is required to provision an event channel and publish events.`,
227
- });
228
- }
229
- if (apis.length) {
230
- askUserForConsent.displayApis(spec.displayName || spec.name, projectId, apis);
231
- const consented = await (0, extensionsHelper_1.confirm)({ nonInteractive, force, default: true });
232
- if (!consented) {
233
- throw new error_1.FirebaseError("Without explicit consent for the APIs listed, we cannot deploy this extension.");
234
- }
235
- }
236
- if (usesSecrets) {
237
- await secretsUtils.ensureSecretManagerApiEnabled(options);
238
- }
239
- const roles = spec.roles ? spec.roles.map((role) => role.role) : [];
240
- if (roles.length) {
241
- await askUserForConsent.displayRoles(spec.displayName || spec.name, projectId, roles);
242
- const consented = await (0, extensionsHelper_1.confirm)({ nonInteractive, force, default: true });
243
- if (!consented) {
244
- throw new error_1.FirebaseError("Without explicit consent for the roles listed, we cannot deploy this extension.");
245
- }
246
- }
247
- let instanceId = spec.name;
248
- let choice;
249
- const anotherInstanceExists = await (0, extensionsHelper_1.instanceIdExists)(projectId, instanceId);
250
- if (anotherInstanceExists) {
251
- if (!nonInteractive) {
252
- choice = await (0, extensionsHelper_1.promptForRepeatInstance)(projectId, spec.name);
253
- }
254
- else if (nonInteractive && force) {
255
- choice = "updateExisting";
256
- }
257
- else {
258
- throw new error_1.FirebaseError(`An extension with the ID '${clc.bold(extensionName)}' already exists in the project '${clc.bold(projectId)}'.` +
259
- ` To update or reconfigure this instance instead, rerun this command with the --force flag.`);
260
- }
261
- }
262
- else {
263
- choice = "installNew";
264
- }
265
- let paramBindingOptions;
266
- let paramBindings;
267
- let eventsConfig;
268
- switch (choice) {
269
- case "installNew":
270
- instanceId = await (0, extensionsHelper_1.promptForValidInstanceId)(`${instanceId}-${(0, utils_1.getRandomString)(4)}`);
271
- paramBindingOptions = await paramHelper.getParams({
272
- projectId,
273
- paramSpecs: spec.params,
274
- nonInteractive,
275
- paramsEnvPath,
276
- instanceId,
277
- });
278
- eventsConfig = spec.events
279
- ? await askUserForEventsConfig.askForEventsConfig(spec.events, projectId, instanceId)
280
- : undefined;
281
- paramBindings = (0, paramHelper_1.getBaseParamBindings)(paramBindingOptions);
282
- spinner.text = "Installing your extension instance. This usually takes 3 to 5 minutes...";
283
- spinner.start();
284
- await extensionsApi.createInstance({
285
- projectId,
286
- instanceId,
287
- extensionSource: source,
288
- extensionVersionRef: extVersion === null || extVersion === void 0 ? void 0 : extVersion.ref,
289
- params: paramBindings,
290
- allowedEventTypes: eventsConfig === null || eventsConfig === void 0 ? void 0 : eventsConfig.allowedEventTypes,
291
- eventarcChannel: eventsConfig === null || eventsConfig === void 0 ? void 0 : eventsConfig.channel,
292
- });
293
- spinner.stop();
294
- utils.logLabeledSuccess(extensionsHelper_1.logPrefix, `Successfully installed your instance of ${clc.bold(spec.displayName || spec.name)}! ` +
295
- `Its Instance ID is ${clc.bold(instanceId)}.`);
296
- break;
297
- case "updateExisting":
298
- paramBindingOptions = await paramHelper.getParams({
299
- projectId,
300
- paramSpecs: spec.params,
301
- nonInteractive,
302
- paramsEnvPath,
303
- instanceId,
304
- });
305
- eventsConfig = spec.events
306
- ? await askUserForEventsConfig.askForEventsConfig(spec.events, projectId, instanceId)
307
- : undefined;
308
- paramBindings = (0, paramHelper_1.getBaseParamBindings)(paramBindingOptions);
309
- spinner.text = "Updating your extension instance. This usually takes 3 to 5 minutes...";
310
- spinner.start();
311
- const updateOptions = {
312
- projectId,
313
- instanceId,
314
- source,
315
- canEmitEvents: eventsConfig ? true : false,
316
- eventarcChannel: eventsConfig === null || eventsConfig === void 0 ? void 0 : eventsConfig.channel,
317
- allowedEventTypes: eventsConfig === null || eventsConfig === void 0 ? void 0 : eventsConfig.allowedEventTypes,
318
- extRef: extVersion === null || extVersion === void 0 ? void 0 : extVersion.ref,
319
- params: paramBindings,
320
- };
321
- await (0, updateHelper_1.update)(updateOptions);
322
- spinner.stop();
323
- utils.logLabeledSuccess(extensionsHelper_1.logPrefix, `Successfully updated your instance of ${clc.bold(spec.displayName || spec.name)}! ` +
324
- `Its Instance ID is ${clc.bold(instanceId)}.`);
325
- break;
326
- case "cancel":
327
- return;
328
- }
329
- utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked("Go to the Firebase console to view instructions for using your extension, " +
330
- `which may include some required post-installation tasks: ${utils.consoleUrl(projectId, `/extensions/instances/${instanceId}?tab=usage`)}`));
331
- logger_1.logger.info(marked("You can run `firebase ext` to view available Firebase Extensions commands, " +
332
- "including those to update, reconfigure, or delete your installed extension."));
333
- manifest.showDeprecationWarning();
334
- }
335
- catch (err) {
336
- if (spinner.isSpinning) {
337
- spinner.fail();
338
- }
339
- if (err instanceof error_1.FirebaseError) {
340
- throw err;
341
- }
342
- throw new error_1.FirebaseError(`Error occurred installing extension: ${err.message}`, {
343
- original: err,
344
- });
345
- }
156
+ manifest.showPostDeprecationNotice();
346
157
  }