@coalescesoftware/coa 1.0.114 → 1.0.115

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/bin/CLIProfile.js CHANGED
@@ -114,6 +114,8 @@ const GetFinalCLIProfile = (commandLineOverrides, configFileLocation) => {
114
114
  return finalCLIProfile;
115
115
  });
116
116
  };
117
+ //Get CLI Config given command line overrides and a config file
118
+ //config file location can be null - which means to use default location
117
119
  const GetCLIConfig = (commandLineOverrides, configFileLocation) => {
118
120
  return GetFinalCLIProfile(commandLineOverrides, configFileLocation).then((cliProfile) => {
119
121
  CLILogger.info("got final cli profile configFileLocation:", configFileLocation, JSON.stringify(RemoveCredentialsFromCLIProfile(cliProfile)));
@@ -134,7 +136,7 @@ const GetCLIConfig = (commandLineOverrides, configFileLocation) => {
134
136
  snowflakeUsername: cliProfile.snowflakeUsername,
135
137
  snowflakeWarehouse: cliProfile.snowflakeWarehouse
136
138
  },
137
- runtimeParameters: cliProfile.parameters,
139
+ runtimeParameters: cliProfile.parameters
138
140
  };
139
141
  Shared.Common.CleanupUndefinedValuesFromObject(cliConfig);
140
142
  return cliConfig;
package/bin/CommonCLI.js CHANGED
@@ -19,7 +19,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
19
19
  return result;
20
20
  };
21
21
  Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.FinishWithOutputFile = exports.GetUserConnectionForCLI = exports.CleanupCLIJob = void 0;
22
+ exports.FinishWithOutputFile = exports.ValidateRuntimeParameters = exports.GetRuntimeParametersFromFirestore = exports.GetUserConnectionForCLI = exports.CleanupCLIJob = void 0;
23
23
  const Shared = __importStar(require("@coalescesoftware/shared"));
24
24
  const fs = __importStar(require("fs"));
25
25
  const crypto = __importStar(require("crypto"));
@@ -105,6 +105,27 @@ const GetUserConnectionForCLI = (userID, runInfo) => {
105
105
  });
106
106
  };
107
107
  exports.GetUserConnectionForCLI = GetUserConnectionForCLI;
108
+ ////////
109
+ // Runtime Parameters
110
+ ///////
111
+ const GetRuntimeParametersFromFirestore = (firestore, teamID, environmentID) => {
112
+ return Shared.CommonOperations.getWorkspaceDocumentRefAdmin(firestore, teamID, environmentID).get().then((workspace) => {
113
+ return workspace.get("runTimeParameters");
114
+ });
115
+ };
116
+ exports.GetRuntimeParametersFromFirestore = GetRuntimeParametersFromFirestore;
117
+ const ValidateRuntimeParameters = (runtimeParameters) => {
118
+ try {
119
+ JSON.parse(runtimeParameters);
120
+ }
121
+ catch (error) {
122
+ throw new Error(`Failed to parse runtime parameters: ${error.message}`);
123
+ }
124
+ };
125
+ exports.ValidateRuntimeParameters = ValidateRuntimeParameters;
126
+ ////////
127
+ // Output File
128
+ ///////
108
129
  const FinishWithOutputFile = (logContextToUse, outputFilePath, runCounter, token) => {
109
130
  if (!outputFilePath) {
110
131
  return Promise.resolve();
package/bin/Package.js CHANGED
@@ -22,7 +22,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
22
22
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
23
  };
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.GetPackageSupportedEntityTypes = exports.RemoveNamespacedWorkspaceData_Testing = exports.NamespaceWorkspaceData_Testing = exports.UninstallPackage = exports.InstallPackage = exports.PackageProvider = exports.GetPackageListMessageCLI = exports.InitializePackageContext = exports.localInstallKeyword = void 0;
25
+ exports.GetPackageSupportedEntityTypes = exports.RemoveNamespacedWorkspaceData_Testing = exports.NamespaceWorkspaceData_Testing = exports.UninstallPackage = exports.InstallPackage = exports.PackageProvider = exports.GetPackageListMessageCLI = exports.IsPackageAlreadyInstalled = exports.InitializePackageContext = exports.localInstallKeyword = void 0;
26
26
  /* eslint-disable multiline-comment-style */
27
27
  const Shared = __importStar(require("@coalescesoftware/shared"));
28
28
  const fs_1 = __importDefault(require("fs"));
@@ -332,7 +332,7 @@ const GetAllWorkspaceDataAndCommitHashFromRemoteRepository = (location) => {
332
332
  })
333
333
  .then((workspaceData) => {
334
334
  const additionalLogInfo = commitOrBranch ? ` at commit or branch: "${commitOrBranch}"` : "";
335
- PackagesLogger.info(`Reading data from Coalesce package ${workspaceData.projectName || GetRepoNameFromURL(locationToUse)}${additionalLogInfo}...`);
335
+ PackagesLogger.info(`Reading Coalesce package data from repo "${GetRepoNameFromURL(locationToUse)}"${additionalLogInfo}...`);
336
336
  resolve({
337
337
  workspaceData,
338
338
  hashFromRemote: commitHashToReturn
@@ -432,6 +432,15 @@ const BuildManifest = (workspaceData) => {
432
432
  });
433
433
  return manifest;
434
434
  };
435
+ /**
436
+ * Returns a boolean telling whether the package being installed is already installed - note, does not differentiate by commit or branch, but detects by package name
437
+ * @param packages
438
+ * @param version
439
+ */
440
+ const IsPackageAlreadyInstalled = (installedPackages, packageID) => {
441
+ return packageID in installedPackages;
442
+ };
443
+ exports.IsPackageAlreadyInstalled = IsPackageAlreadyInstalled;
435
444
  ////////////////////////////////////////////////////
436
445
  ///////////// Firestore read/write funcs
437
446
  ////////////////////////////////////////////////////
@@ -452,6 +461,12 @@ const RemovePackageInformationFS = (packageInfo, packageContext) => {
452
461
  const { environmentID, teamID, firestore } = packageContext;
453
462
  return Shared.CommonOperations.getOrgConfigDocRefAdmin(firestore, teamID).collection("workspaces").doc(environmentID.toString()).collection("packages").doc(packageInfo.id).delete();
454
463
  };
464
+ const FlushFirestoreWorkspaceWithAllWorkspaceDataForCLIPackages = (firestore, teamID, workspaceIDForTargetFlush, desiredWorkspaceDataState, workspaceDataToReplace) => {
465
+ // we do not want to compare packages when installing a package
466
+ delete desiredWorkspaceDataState.packages;
467
+ delete workspaceDataToReplace.packages;
468
+ return Shared.Workspaces.FlushFirestoreWorkspaceWithAllWorkspaceData(firestore, teamID, workspaceIDForTargetFlush, desiredWorkspaceDataState, workspaceDataToReplace);
469
+ };
455
470
  const GetPackageListMessageCLI = (packageContext) => {
456
471
  const { environmentID, teamID, firestore } = packageContext;
457
472
  return Shared.Workspaces.getAllWorkspaceDataFromFirebase(firestore, teamID, environmentID)
@@ -459,11 +474,11 @@ const GetPackageListMessageCLI = (packageContext) => {
459
474
  const packages = Shared.Common.getValueSafe(wsData, ["packages"], null);
460
475
  if (packages && Object.keys(packages).length) {
461
476
  const listForCLI = Object.keys(packages).map(packageID => `${packageID} \n`);
462
- listForCLI.unshift(`\nPackages added to environment ${environmentID}: \n`);
477
+ listForCLI.unshift(`\nPackages on workspace ${environmentID}: \n`);
463
478
  return listForCLI.join("");
464
479
  }
465
480
  else {
466
- return `No packages added to environment ${environmentID}`;
481
+ return `No packages added to workspace ${environmentID}`;
467
482
  }
468
483
  });
469
484
  };
@@ -539,18 +554,30 @@ class PackageProvider {
539
554
  }
540
555
  return wsDataFunc
541
556
  .then((workspaceData) => {
542
- // ensure package ID
543
- if (!workspaceData.projectName) {
557
+ const projects = workspaceData.projects;
558
+ if (!projects || !Object.keys(projects)) {
559
+ PackagesLogger.errorContext(this.loggerContext, `Invalid Package: Missing projects, cannot generate package ID`);
560
+ throw new Error(`Invalid Package: Missing projects, cannot generate package ID; Package owner must add a project name in Coalesce project settings and commit`);
561
+ }
562
+ // ensure package ID to be used as namespace, which is gathered from the default project name as of Lhotse 4.0
563
+ const projectName = Shared.ProjectOperations.GetDefaultProjectName(projects);
564
+ if (!projectName) {
544
565
  PackagesLogger.errorContext(this.loggerContext, `Invalid Package: Missing project name`);
545
- PackagesLogger.errorContext(this.loggerContext, `Package owner must add a project name in Coalesce git settings before deploying commit for Package`);
546
- throw new Error(`Invalid Package: Missing package ID; Package owner must add a package name in Coalesce git settings before deploying commit for Package`);
566
+ throw new Error(`Invalid Package: Missing package ID; Package owner must add a project name in Coalesce project settings and commit`);
567
+ }
568
+ const defaultProject = projects[Shared.ProjectOperations.defaultProjectID]; // currently only one default project
569
+ const isDefaultProjectValid = Shared.ProjectOperations.ValidateProjectAsRunType(defaultProject);
570
+ if (!isDefaultProjectValid.success) {
571
+ const errorMessage = `Invalid Package: projects failed Run Type validation - projects["1"]: ${defaultProject}`;
572
+ PackagesLogger.errorContext(this.loggerContext, errorMessage, isDefaultProjectValid.errorString);
573
+ throw new Error(errorMessage);
547
574
  }
548
575
  // validate project name
549
- if (!this._isProjectNameValid(workspaceData.projectName)) {
576
+ if (!this._isProjectNameValid(projectName)) {
550
577
  PackagesLogger.errorContext(this.loggerContext, `Invalid Package: Project name contains reserved namespacing characters "::"`);
551
- throw new Error(`${workspaceData.projectName} contains "::" and is not a valid project name`);
578
+ throw new Error(`${projectName} contains "::" and is not a valid project name`);
552
579
  }
553
- this.id = workspaceData.projectName.toUpperCase(); // should be uppercase
580
+ this.id = projectName.toUpperCase(); // should be uppercase
554
581
  this.workspaceData = workspaceData;
555
582
  this.versionInfo = InitializeVersionInfo(this.commitHash, this.version);
556
583
  return this.workspaceData;
@@ -587,7 +614,7 @@ const InstallPackage = (packageProvider, packageContext) => {
587
614
  const { desiredState, namespacedData } = GetNamespacedDataAndDesiredStateForFSFlush(packageDependencyInfo, packageProvider.workspaceData, projectWorkspaceData, packageContext);
588
615
  manifest = BuildManifest(namespacedData);
589
616
  PackagesLogger.infoContext(loggerContext, "Applying updates to firestore...");
590
- return Shared.Workspaces.FlushFirestoreWorkspaceWithAllWorkspaceData(firestore, teamID, environmentID, desiredState, projectWorkspaceData);
617
+ return FlushFirestoreWorkspaceWithAllWorkspaceDataForCLIPackages(firestore, teamID, environmentID, desiredState, projectWorkspaceData);
591
618
  })
592
619
  .then(() => {
593
620
  return UpdatePackageInformationFS(Object.assign(Object.assign({}, packageDependencyInfo), { manifest }), EPackageStatus.added, packageContext, true);
@@ -642,7 +669,7 @@ const UninstallPackage = (packageID, packageContext) => {
642
669
  return UpdatePackageInformationFS(thisDependencyInfo, EPackageStatus.removing, packageContext, false)
643
670
  .then(() => {
644
671
  PackagesLogger.infoContext(loggerContext, `Applying updates to firestore...`);
645
- return Shared.Workspaces.FlushFirestoreWorkspaceWithAllWorkspaceData(firestore, teamID, environmentID, prunedWorkspaceData, projectWorkspaceData);
672
+ return FlushFirestoreWorkspaceWithAllWorkspaceDataForCLIPackages(firestore, teamID, environmentID, prunedWorkspaceData, projectWorkspaceData);
646
673
  })
647
674
  .then(() => {
648
675
  return RemovePackageInformationFS(thisDependencyInfo, packageContext);
package/bin/index.js CHANGED
@@ -27,16 +27,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
27
27
  const Deploy = __importStar(require("./Deploy"));
28
28
  const Plan = __importStar(require("./Plan"));
29
29
  const Refresh = __importStar(require("./Refresh"));
30
+ const Package = __importStar(require("./Package"));
30
31
  const Shared = __importStar(require("@coalescesoftware/shared"));
31
32
  const CLIProfile = __importStar(require("./CLIProfile"));
32
33
  const chalk_1 = __importDefault(require("chalk"));
33
34
  const commander_1 = require("commander");
34
35
  const CommonCLI = __importStar(require("./CommonCLI"));
35
36
  const fs_1 = __importDefault(require("fs"));
37
+ const inquirer_1 = __importDefault(require("inquirer"));
36
38
  // setting this needs to be first!
37
39
  Shared.Logging.SetHTTPTransportOptions(Shared.Logging.EHttpServices.CLI);
38
40
  const LogCLI = Shared.Logging.GetLogger(Shared.Logging.LoggingArea.CLI);
39
41
  const LogCLIInternal = Shared.Logging.GetLogger(Shared.Logging.LoggingArea.CLI_INTERNAL);
42
+ const ChalkLogger = {
43
+ error: (message) => LogCLI.error(chalk_1.default.redBright(message)),
44
+ green: (message) => LogCLI.info(chalk_1.default.green(message)),
45
+ white: (message) => LogCLI.info(chalk_1.default.whiteBright(message)),
46
+ blue: (message) => LogCLI.info(chalk_1.default.blueBright(message)),
47
+ };
40
48
  const program = new commander_1.Command();
41
49
  program.version(require("../package.json").version, "-v, --version");
42
50
  program.option("-b, --debug", "Output extra debugging", false);
@@ -90,9 +98,14 @@ AddOverridesToCommand(program.command(Shared.CLIOperations.ECLICommands.Plan))
90
98
  Shared.CLIOperations.DisableNonCLIConsoleLogs();
91
99
  }
92
100
  let config;
93
- return CLIProfile.GetCLIConfig(cliOverrides, optsWithGlobals.config)
101
+ return Promise.resolve().then(() => {
102
+ return CLIProfile.GetCLIConfig(cliOverrides, optsWithGlobals.config);
103
+ })
94
104
  .then((configResult) => {
95
105
  config = configResult;
106
+ if (config.runtimeParameters) {
107
+ CommonCLI.ValidateRuntimeParameters(config.runtimeParameters);
108
+ }
96
109
  return Shared.SchedulerOperations.AuthenticateFirebaseTokenAndRetrieveTeamInfoForCLI(config.token, undefined);
97
110
  })
98
111
  .then(({ teamInfo, firebase }) => {
@@ -149,7 +162,9 @@ AddOverridesToCommand(program.command(Shared.CLIOperations.ECLICommands.Deploy))
149
162
  let logContextToUse;
150
163
  let runInfo;
151
164
  let config;
152
- return CLIProfile.GetCLIConfig(cliOverrides, optsWithGlobals.config)
165
+ return Promise.resolve().then(() => {
166
+ return CLIProfile.GetCLIConfig(cliOverrides, optsWithGlobals.config);
167
+ })
153
168
  .then((configResult) => {
154
169
  config = configResult;
155
170
  return Shared.SchedulerOperations.AuthenticateFirebaseTokenAndRetrieveTeamInfoForCLI(config.token, undefined);
@@ -178,11 +193,10 @@ AddOverridesToCommand(program.command(Shared.CLIOperations.ECLICommands.Deploy))
178
193
  .then(() => {
179
194
  LogCLI.infoContext(logContextToUse, "Deployment successful!");
180
195
  Shared.CLIOperations.ExitCLISafe(0);
181
- })
182
- .catch(error => {
183
- LogCLI.errorContext(logContextToUse, chalk_1.default.redBright(`An error occurred during deployment ${error.toString()}`));
184
- Shared.CLIOperations.ExitCLISafe(1);
185
196
  });
197
+ }).catch(error => {
198
+ LogCLI.errorContext(logContextToUse, chalk_1.default.redBright(`An error occurred during deployment ${error.toString()}`));
199
+ Shared.CLIOperations.ExitCLISafe(1);
186
200
  });
187
201
  });
188
202
  /**
@@ -194,16 +208,6 @@ AddOverridesToCommand(program.command(Shared.CLIOperations.ECLICommands.Refresh)
194
208
  .action((options, command) => {
195
209
  const cliOverrides = ComputeCLIOverrides(command);
196
210
  const optsWithGlobals = command.optsWithGlobals();
197
- //const token = fs.readFileSync(cmd.token, { encoding: "utf8" })
198
- //const config = JSON.parse(fs.readFileSync(cmd.config, { encoding: "utf8" }))
199
- /*
200
- try {
201
- Shared.CLIOperations.VerifyAllRefreshItems(config, token)
202
- } catch (error) {
203
- LogCLI.error(Chalk.redBright(`Error with required option values: ${error}`))
204
- Shared.CLIOperations.ExitCLISafe(1)
205
- }
206
- */
207
211
  const debugMode = optsWithGlobals.debug;
208
212
  if (!debugMode) {
209
213
  Shared.CLIOperations.DisableNonCLIConsoleLogs();
@@ -214,7 +218,9 @@ AddOverridesToCommand(program.command(Shared.CLIOperations.ECLICommands.Refresh)
214
218
  //WHY DO WE HAVE THIS CONFIG?
215
219
  let runInfo;
216
220
  let config;
217
- return CLIProfile.GetCLIConfig(cliOverrides, optsWithGlobals.config)
221
+ return Promise.resolve().then(() => {
222
+ return CLIProfile.GetCLIConfig(cliOverrides, optsWithGlobals.config);
223
+ })
218
224
  .then((configResult) => {
219
225
  config = configResult;
220
226
  return Shared.SchedulerOperations.AuthenticateFirebaseTokenAndRetrieveTeamInfoForCLI(config.token, undefined);
@@ -256,11 +262,221 @@ AddOverridesToCommand(program.command(Shared.CLIOperations.ECLICommands.Refresh)
256
262
  LogCLI.infoContext(logContextToUse, "Refresh successful!");
257
263
  Shared.CLIOperations.ExitCLISafe(0);
258
264
  });
265
+ });
266
+ }).catch(error => {
267
+ LogCLI.errorContext(logContextToUse, chalk_1.default.redBright(`Error during refresh!: ${error.toString()}`));
268
+ Shared.CLIOperations.ExitCLISafe(1);
269
+ });
270
+ });
271
+ //////////////////////////////////////
272
+ ///// COA PACKAGES
273
+ //////////////////////////////////////
274
+ const PackageInit = program.command(Shared.CLIOperations.ECLICommands.Package)
275
+ .description("experimental feature")
276
+ // removing description until Lhotse 4.0 release
277
+ // .description(`\n--------------------------------------\n*** Experimental Feature ***\n--------------------------------------\nImport workspace information (aka Coalesce Package) from other Coalesce repositories into your the environment provided in your COA config, or --environmentID override.
278
+ // \nSubcommands:
279
+ // add <location> imports data from <location> (either URL with optional #commit, #branch, or file path)
280
+ // remove <packageID> removes imported package with <packageID> from your Coalesce project\n--------------------------------------\n`)
281
+ .option("--list [workspaceID]", "Lists installed package names for default or specified workspace")
282
+ // .command("none", { hidden: true, isDefault: true }) // removing description until Lhotse 4.0 release
283
+ .action((opts, cmd) => {
284
+ const cliOverrides = ComputeCLIOverrides(cmd);
285
+ const optsWithGlobals = cmd.optsWithGlobals();
286
+ const list = optsWithGlobals.list;
287
+ const debugMode = optsWithGlobals.debug;
288
+ if (!debugMode) {
289
+ Shared.CLIOperations.DisableNonCLIConsoleLogs();
290
+ }
291
+ let environmentID;
292
+ if (list) {
293
+ return CLIProfile.GetCLIConfig(cliOverrides, optsWithGlobals.config)
294
+ .then((configResult) => {
295
+ // if list is a boolean, then --list had no workspaceID arg, so use workspaceID from coaConfig, else use provided workspaceID
296
+ environmentID = typeof list === "boolean" ? configResult.runDetails.environmentID : list;
297
+ return Shared.SchedulerOperations.AuthenticateFirebaseTokenAndRetrieveTeamInfoForCLI(configResult.token, undefined);
259
298
  })
260
- .catch(error => {
261
- LogCLI.errorContext(logContextToUse, chalk_1.default.redBright(`Error during refresh!: ${error.toString()}`));
299
+ .then((authInfo) => {
300
+ const packageContext = Package.InitializePackageContext(authInfo, environmentID);
301
+ return Package.GetPackageListMessageCLI(packageContext);
302
+ })
303
+ .then((packageListCLI) => {
304
+ Shared.Logging.GetLogger(Shared.Logging.LoggingArea.CLI).info(chalk_1.default.bgBlueBright(packageListCLI));
305
+ Shared.CLIOperations.ExitCLISafe(0);
306
+ })
307
+ .catch((error) => {
308
+ Shared.Logging.GetLogger(Shared.Logging.LoggingArea.CLI).error(chalk_1.default.red(`CLI Package listing error`, error));
262
309
  Shared.CLIOperations.ExitCLISafe(1);
263
310
  });
311
+ }
312
+ else {
313
+ program.help();
314
+ }
315
+ });
316
+ // removing description until Lhotse 4.0 release - also todo: do this better anyway
317
+ // PackageInit.command("none", { hidden: true, isDefault: true })
318
+ // .action(() => {
319
+ // PackageInit.help()
320
+ // })
321
+ const throwForbiddenExperimentalError = () => {
322
+ const errorMessage = ` 403 - Forbidden: You do not have permission to access this experimental feature`;
323
+ throw new Error(errorMessage);
324
+ };
325
+ const AddPackage = AddOverridesToCommand(PackageInit.command(`${Shared.CLIOperations.ECLICommands.Add} <location>`))
326
+ // .description("imports data from <location> (either URL with optional #commit or dir path) to your Coalesce project for given environment ID") // removing description until Lhotse 4.0 release
327
+ .option("-y", "Auto-confirm all overwrite prompts");
328
+ AddPackage
329
+ .action((location, options, cmd) => {
330
+ const cliOverrides = ComputeCLIOverrides(cmd);
331
+ const optsWithGlobals = cmd.optsWithGlobals();
332
+ const debugMode = optsWithGlobals.debug;
333
+ const packageLocation = location;
334
+ const confirmPrompts = options.y || false;
335
+ if (!debugMode) {
336
+ Shared.CLIOperations.DisableNonCLIConsoleLogs();
337
+ }
338
+ ChalkLogger.green(`Initializing package installation...`);
339
+ let loggerContext;
340
+ let token;
341
+ let cliConfig;
342
+ let environmentID;
343
+ let packageContext;
344
+ let packageProvider;
345
+ return CLIProfile.GetCLIConfig(cliOverrides, optsWithGlobals.config)
346
+ .then((configResult) => {
347
+ cliConfig = configResult;
348
+ token = cliConfig.token;
349
+ environmentID = cliConfig.runDetails.environmentID;
350
+ return Shared.SchedulerOperations.AuthenticateFirebaseTokenAndRetrieveTeamInfoForCLI(token, undefined);
351
+ })
352
+ .then((authInfo) => {
353
+ // this feature only available to SuperUsers until Lhotse release
354
+ if (!authInfo.teamInfo.fbHasSuperUserAccess) {
355
+ throwForbiddenExperimentalError();
356
+ }
357
+ packageContext = Package.InitializePackageContext(authInfo, environmentID);
358
+ packageProvider = new Package.PackageProvider(packageLocation, loggerContext);
359
+ // need to getWorkspaceDataFS here in order to get package ID from package provider
360
+ return packageProvider.getWorkspaceDataFS()
361
+ .then(() => Shared.Workspaces.getAllWorkspaceDataFromFirebase(authInfo.firebase.firestore(), authInfo.teamInfo.fbTeamID, environmentID));
362
+ })
363
+ .then(workspaceData => {
364
+ const isPackageAlreadyInstalled = Package.IsPackageAlreadyInstalled(workspaceData.packages || {}, packageProvider.id);
365
+ const install = () => {
366
+ return Package.InstallPackage(packageProvider, packageContext)
367
+ .then(() => {
368
+ Shared.Logging.GetLogger(Shared.Logging.LoggingArea.CLI).info(chalk_1.default.green(`CLI Package Installation complete`));
369
+ Shared.CLIOperations.ExitCLISafe(0);
370
+ });
371
+ };
372
+ if (isPackageAlreadyInstalled) {
373
+ if (confirmPrompts) {
374
+ return install();
375
+ }
376
+ else {
377
+ const promptData = [
378
+ {
379
+ name: "confirmOverwrite",
380
+ type: "confirm",
381
+ message: `Package "${packageProvider.id}" already exists. Continuing with installation will remove any changes you might have made and overwrite the data previously imported from this package.
382
+ \n\nWould you like to continue installation and overwrite any previously installed package data from "${packageProvider.id}"?`,
383
+ default: false
384
+ },
385
+ ];
386
+ return inquirer_1.default.prompt(promptData)
387
+ .then(answers => {
388
+ const shouldOverwrite = answers.confirmOverwrite;
389
+ if (shouldOverwrite) {
390
+ return install();
391
+ }
392
+ else {
393
+ Shared.Logging.GetLogger(Shared.Logging.LoggingArea.CLI).info(`CLI Package installation aborted`);
394
+ Shared.CLIOperations.ExitCLISafe(0);
395
+ }
396
+ });
397
+ }
398
+ }
399
+ else {
400
+ return install();
401
+ }
402
+ })
403
+ .catch(error => {
404
+ if (error.isTtyError) {
405
+ // Prompt couldn't be rendered in the current environment
406
+ Shared.Logging.GetLogger(Shared.Logging.LoggingArea.CLI).errorContext(loggerContext, chalk_1.default.red(`There was a problem rendering the overwrite confirmation prompt in your environment. \n\n To overwrite package without prompts, add the -y param to the end of the command and try again.`, error));
407
+ }
408
+ Shared.Logging.GetLogger(Shared.Logging.LoggingArea.CLI).errorContext(loggerContext, chalk_1.default.red(`CLI Package Installation error`, error));
409
+ Shared.CLIOperations.ExitCLISafe(1);
410
+ });
411
+ });
412
+ const RemovePackage = AddOverridesToCommand(PackageInit.command(`${Shared.CLIOperations.ECLICommands.Remove} <id>`))
413
+ // .description("removes imported package with <id> from your Coalesce project for given environment ID") // removing description until Lhotse 4.0 release
414
+ .option("-y", "Auto-confirm all remove prompts");
415
+ RemovePackage
416
+ .action((id, options, cmd) => {
417
+ const cliOverrides = ComputeCLIOverrides(cmd);
418
+ const optsWithGlobals = cmd.optsWithGlobals();
419
+ const debugMode = optsWithGlobals.debug;
420
+ const packageID = id.toUpperCase();
421
+ const confirmPrompts = options.y || false;
422
+ if (!debugMode) {
423
+ Shared.CLIOperations.DisableNonCLIConsoleLogs();
424
+ }
425
+ ChalkLogger.green(`Initializing package removal...`);
426
+ let loggerContext;
427
+ let token;
428
+ let cliConfig;
429
+ let environmentID;
430
+ return CLIProfile.GetCLIConfig(cliOverrides, optsWithGlobals.config)
431
+ .then((configResult) => {
432
+ cliConfig = configResult;
433
+ token = cliConfig.token;
434
+ environmentID = cliConfig.runDetails.environmentID;
435
+ return Shared.SchedulerOperations.AuthenticateFirebaseTokenAndRetrieveTeamInfoForCLI(token, undefined);
436
+ })
437
+ .then((authInfo) => {
438
+ // this feature only available to SuperUsers until Lhotse release
439
+ if (!authInfo.teamInfo.fbHasSuperUserAccess) {
440
+ throwForbiddenExperimentalError();
441
+ }
442
+ const packageContext = Package.InitializePackageContext(authInfo, environmentID);
443
+ const uninstall = () => Package.UninstallPackage(packageID, packageContext)
444
+ .then(() => {
445
+ ChalkLogger.green("Package removal completed successfully!");
446
+ Shared.CLIOperations.ExitCLISafe(0);
447
+ });
448
+ if (confirmPrompts) {
449
+ return uninstall();
450
+ }
451
+ else {
452
+ const promptData = [
453
+ {
454
+ name: "confirmRemove",
455
+ type: "confirm",
456
+ message: `Removing a package will remove all imported data from that package, including any edits you have made on that imported data. \n\nAre you sure you'd like to remove package "${packageID}"?`,
457
+ default: false
458
+ },
459
+ ];
460
+ return inquirer_1.default.prompt(promptData)
461
+ .then(answers => {
462
+ const shouldRemove = answers.confirmRemove;
463
+ if (shouldRemove) {
464
+ return uninstall();
465
+ }
466
+ else {
467
+ Shared.Logging.GetLogger(Shared.Logging.LoggingArea.CLI).info(`CLI Package removal aborted`);
468
+ Shared.CLIOperations.ExitCLISafe(0);
469
+ }
470
+ });
471
+ }
472
+ })
473
+ .catch(error => {
474
+ if (error.isTtyError) {
475
+ // Prompt couldn't be rendered in the current environment
476
+ Shared.Logging.GetLogger(Shared.Logging.LoggingArea.CLI).errorContext(loggerContext, chalk_1.default.red(`There was a problem rendering the removal confirmation prompt in your environment. \n\n To remove without prompts, add the -y param to the end of the command and try again.`, error));
477
+ }
478
+ Shared.Logging.GetLogger(Shared.Logging.LoggingArea.CLI).errorContext(loggerContext, chalk_1.default.red(`CLI Package removal error`, error));
479
+ Shared.CLIOperations.ExitCLISafe(1);
264
480
  });
265
481
  });
266
482
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coalescesoftware/coa",
3
- "version": "1.0.114",
3
+ "version": "1.0.115",
4
4
  "license": "ISC",
5
5
  "author": "Coalesce Automation, Inc.",
6
6
  "main": "index.js",
@@ -12,13 +12,14 @@
12
12
  "start-cli-debug": "yarn run start --debug"
13
13
  },
14
14
  "dependencies": {
15
- "@coalescesoftware/shared": "^1.0.114",
15
+ "@coalescesoftware/shared": "^1.0.115",
16
16
  "chalk": "^4.1.2",
17
17
  "commander": "^9.2.0",
18
18
  "firebase": "8.2.0",
19
19
  "immer": "^9.0.12",
20
20
  "ini": "^3.0.0",
21
21
  "ink": "^3.2.0",
22
+ "inquirer": "^8.2.4",
22
23
  "react": "^17.0.2",
23
24
  "react-redux": "^7.2.6"
24
25
  },