@rockcarver/frodo-cli 2.0.6-0 → 2.0.6-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.
package/dist/app.cjs CHANGED
@@ -67475,7 +67475,7 @@ var require_basic_auth = __commonJS2({
67475
67475
  var header = getAuthorization(req);
67476
67476
  return parse7(header);
67477
67477
  }
67478
- function decodeBase643(str2) {
67478
+ function decodeBase644(str2) {
67479
67479
  return Buffer3.from(str2, "base64").toString();
67480
67480
  }
67481
67481
  function getAuthorization(req) {
@@ -67492,7 +67492,7 @@ var require_basic_auth = __commonJS2({
67492
67492
  if (!match2) {
67493
67493
  return void 0;
67494
67494
  }
67495
- var userPass = USER_PASS_REGEXP.exec(decodeBase643(match2[1]));
67495
+ var userPass = USER_PASS_REGEXP.exec(decodeBase644(match2[1]));
67496
67496
  if (!userPass) {
67497
67497
  return void 0;
67498
67498
  }
@@ -177537,9 +177537,12 @@ var {
177537
177537
  isBase64Encoded: isBase64Encoded2,
177538
177538
  getFilePath: getFilePath12,
177539
177539
  getWorkingDirectory: getWorkingDirectory10,
177540
- saveToFile: saveToFile3
177540
+ saveToFile: saveToFile3,
177541
+ decodeBase64
177541
177542
  } = frodo.utils;
177542
177543
  var {
177544
+ readScript: readScript2,
177545
+ readScriptByName: readScriptByName2,
177543
177546
  readScripts: readScripts2,
177544
177547
  exportScript: exportScript2,
177545
177548
  exportScriptByName: exportScriptByName2,
@@ -177549,6 +177552,7 @@ var {
177549
177552
  deleteScriptByName: deleteScriptByName3,
177550
177553
  deleteScripts: deleteScripts3
177551
177554
  } = frodo.script;
177555
+ var langMap = { JAVASCRIPT: "JavaScript", GROOVY: "Groovy" };
177552
177556
  function getOneLineDescription(scriptObj) {
177553
177557
  const description = `[${scriptObj._id["brightCyan"]}] ${scriptObj.context} - ${scriptObj.name}`;
177554
177558
  return description;
@@ -177560,7 +177564,6 @@ function getTableHeaderMd() {
177560
177564
  return markdown;
177561
177565
  }
177562
177566
  function getTableRowMd(scriptObj) {
177563
- const langMap = { JAVASCRIPT: "JavaScript", GROOVY: "Groovy" };
177564
177567
  const description = `| ${scriptObj.name} | ${langMap[scriptObj.language]} | ${titleCase7(scriptObj.context.split("_").join(" "))} | \`${scriptObj._id}\` |`;
177565
177568
  return description;
177566
177569
  }
@@ -177594,6 +177597,7 @@ async function listScripts(long = false, usage = false, file = null) {
177594
177597
  return true;
177595
177598
  }
177596
177599
  let fullExport = null;
177600
+ let scriptExport = null;
177597
177601
  const headers2 = long ? ["Name", "UUID", "Language", "Context", "Description"] : ["Name"];
177598
177602
  if (usage) {
177599
177603
  try {
@@ -177602,11 +177606,10 @@ async function listScripts(long = false, usage = false, file = null) {
177602
177606
  printError2(error2);
177603
177607
  return false;
177604
177608
  }
177605
- delete fullExport.script;
177609
+ scriptExport = separateScriptsFromFullExport(fullExport);
177606
177610
  headers2.push("Used");
177607
177611
  }
177608
177612
  const table = createTable(headers2);
177609
- const langMap = { JAVASCRIPT: "JS", GROOVY: "Groovy" };
177610
177613
  scripts.forEach((script) => {
177611
177614
  const values3 = long ? [
177612
177615
  wordwrap(script.name, 25, " "),
@@ -177616,9 +177619,11 @@ async function listScripts(long = false, usage = false, file = null) {
177616
177619
  wordwrap(script.description, 30)
177617
177620
  ] : [wordwrap(script.name, 25, " ")];
177618
177621
  if (usage) {
177619
- const isScriptUsed = isIdUsed(fullExport, script._id, false);
177622
+ const locations = getIdLocations(fullExport, script._id, false).concat(
177623
+ getScriptLocations(scriptExport, script.name)
177624
+ );
177620
177625
  values3.push(
177621
- isScriptUsed.used ? `${"yes"["brightGreen"]} (at ${isScriptUsed.location})` : "no"["brightRed"]
177626
+ locations.length > 0 ? `${"yes"["brightGreen"]} (${locations.length === 1 ? `at` : `${locations.length} uses, including:`} ${locations[0]})` : "no"["brightRed"]
177622
177627
  );
177623
177628
  }
177624
177629
  table.push(values3);
@@ -177627,6 +177632,87 @@ async function listScripts(long = false, usage = false, file = null) {
177627
177632
  debugMessage2(`Cli.ScriptOps.listScripts: end`);
177628
177633
  return true;
177629
177634
  }
177635
+ async function describeScript(scriptId, scriptName, file, usage = false, json = false) {
177636
+ const spinnerId = createProgressIndicator2(
177637
+ "indeterminate",
177638
+ 0,
177639
+ `Describing script '${scriptId ? scriptId : scriptName}'...`
177640
+ );
177641
+ try {
177642
+ let script;
177643
+ if (scriptId) {
177644
+ script = await readScript2(scriptId);
177645
+ } else {
177646
+ script = await readScriptByName2(scriptName);
177647
+ }
177648
+ if (usage) {
177649
+ try {
177650
+ const fullExport = await getFullExportConfig(file);
177651
+ const scriptExport = separateScriptsFromFullExport(fullExport);
177652
+ script.locations = getIdLocations(fullExport, script._id, false).concat(
177653
+ getScriptLocations(scriptExport, script.name)
177654
+ );
177655
+ } catch (error2) {
177656
+ stopProgressIndicator2(
177657
+ spinnerId,
177658
+ `Error determining usage for script '${scriptId ? scriptId : scriptName}'`,
177659
+ "fail"
177660
+ );
177661
+ printError2(error2);
177662
+ return false;
177663
+ }
177664
+ }
177665
+ stopProgressIndicator2(
177666
+ spinnerId,
177667
+ `Successfully retrieved script '${scriptId ? scriptId : scriptName}'`,
177668
+ "success"
177669
+ );
177670
+ if (json) {
177671
+ printMessage2(script, "data");
177672
+ } else {
177673
+ const table = createKeyValueTable();
177674
+ table.push(["Id"["brightCyan"], script._id]);
177675
+ table.push(["Name"["brightCyan"], script.name]);
177676
+ table.push(["Language"["brightCyan"], langMap[script.language]]);
177677
+ table.push([
177678
+ "Context"["brightCyan"],
177679
+ titleCase7(script.context.split("_").join(" "))
177680
+ ]);
177681
+ table.push(["Description"["brightCyan"], script.description]);
177682
+ table.push([
177683
+ "Default"["brightCyan"],
177684
+ script.default ? "true"["brightGreen"] : "false"["brightRed"]
177685
+ ]);
177686
+ table.push(["Evaluator Version"["brightCyan"], script.evaluatorVersion]);
177687
+ const scriptWrapLength = 80;
177688
+ const wrapRegex = new RegExp(`.{1,${scriptWrapLength + 1}}`, "g");
177689
+ const scriptParts = script.script.match(wrapRegex);
177690
+ table.push(["Script (Base 64)"["brightCyan"], scriptParts[0]]);
177691
+ for (let i2 = 1; i2 < scriptParts.length; i2++) {
177692
+ table.push(["", scriptParts[i2]]);
177693
+ }
177694
+ if (usage) {
177695
+ table.push([
177696
+ `Usage Locations (${script.locations.length} total)`["brightCyan"],
177697
+ script.locations.length > 0 ? script.locations[0] : ""
177698
+ ]);
177699
+ for (let i2 = 1; i2 < script.locations.length; i2++) {
177700
+ table.push(["", script.locations[i2]]);
177701
+ }
177702
+ }
177703
+ printMessage2(table.toString(), "data");
177704
+ }
177705
+ return true;
177706
+ } catch (error2) {
177707
+ stopProgressIndicator2(
177708
+ spinnerId,
177709
+ `Error describing script '${scriptId ? scriptId : scriptName}'`,
177710
+ "fail"
177711
+ );
177712
+ printError2(error2);
177713
+ }
177714
+ return false;
177715
+ }
177630
177716
  async function exportScriptToFile(scriptId, file, includeMeta = true, extract = false, options2) {
177631
177717
  debugMessage2(`Cli.ScriptOps.exportScriptToFile: start`);
177632
177718
  try {
@@ -177966,6 +178052,37 @@ async function deleteAllScripts() {
177966
178052
  }
177967
178053
  return false;
177968
178054
  }
178055
+ function separateScriptsFromFullExport(fullExport) {
178056
+ const scripts = { realm: {} };
178057
+ for (const [realm2, realmExport] of Object.entries(fullExport.realm)) {
178058
+ if (!scripts.realm[realm2]) {
178059
+ scripts.realm[realm2] = {};
178060
+ }
178061
+ scripts.realm[realm2].script = realmExport.script;
178062
+ delete realmExport.script;
178063
+ }
178064
+ return scripts;
178065
+ }
178066
+ function getScriptLocations(configuration, scriptName) {
178067
+ const locations = [];
178068
+ const regex2 = new RegExp(`require\\(['|"]${scriptName}['|"]\\)`);
178069
+ for (const [realm2, realmExport] of Object.entries(configuration.realm)) {
178070
+ for (const scriptData of Object.values(realmExport.script)) {
178071
+ let scriptString = scriptData.script;
178072
+ if (Array.isArray(scriptData.script)) {
178073
+ scriptString = scriptData.script.join("\n");
178074
+ } else if (isBase64Encoded2(scriptData.script)) {
178075
+ scriptString = decodeBase64(scriptData.script);
178076
+ }
178077
+ if (regex2.test(scriptString)) {
178078
+ locations.push(
178079
+ `realm.${realm2}.script.${scriptData._id}(name: '${scriptData.name}').script`
178080
+ );
178081
+ }
178082
+ }
178083
+ }
178084
+ return locations;
178085
+ }
177969
178086
 
177970
178087
  // src/utils/Config.ts
177971
178088
  var { getFilePath: getFilePath13, readFiles: readFiles4 } = frodo.utils;
@@ -178143,8 +178260,8 @@ async function getConfigFromDirectory(directory, exportConfig) {
178143
178260
  });
178144
178261
  }
178145
178262
  }
178146
- function isIdUsed(configuration, id7, isEsv) {
178147
- return isIdUsedRecurse(
178263
+ function getIdLocations(configuration, id7, isEsv) {
178264
+ return getIdLocationsRecurse(
178148
178265
  configuration,
178149
178266
  isEsv ? (
178150
178267
  // For ESV ids, they contain either letters, numbers, dashes, or underscores. The dashes get replaced with periods (escaped with a \ for the regex)
@@ -178160,24 +178277,24 @@ function isIdUsed(configuration, id7, isEsv) {
178160
178277
  )
178161
178278
  );
178162
178279
  }
178163
- function isIdUsedRecurse(configuration, regex2) {
178280
+ function getIdLocationsRecurse(configuration, regex2) {
178281
+ let locations = [];
178164
178282
  const type = typeof configuration;
178165
178283
  if (type === "object" && configuration !== null) {
178166
178284
  for (const [id7, value] of Object.entries(
178167
178285
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
178168
178286
  configuration
178169
178287
  )) {
178170
- const isIdUsed2 = isIdUsedRecurse(value, regex2);
178171
- if (isIdUsed2.used) {
178172
- isIdUsed2.location = id7 + (value.name ? `(name: '${value.name}')` : "") + (isIdUsed2.location === "" ? "" : ".") + isIdUsed2.location;
178173
- return isIdUsed2;
178174
- }
178288
+ const usedLocations = getIdLocationsRecurse(value, regex2);
178289
+ const updatedLocations = usedLocations.map(
178290
+ (loc) => id7 + (value.name ? `(name: '${value.name}')` : "") + (loc === "" ? "" : ".") + loc
178291
+ );
178292
+ locations = locations.concat(updatedLocations);
178175
178293
  }
178294
+ } else if (type === "string" && regex2.test(configuration)) {
178295
+ locations.push("");
178176
178296
  }
178177
- return {
178178
- used: type === "string" && regex2.test(configuration),
178179
- location: ""
178180
- };
178297
+ return locations;
178181
178298
  }
178182
178299
 
178183
178300
  // src/ops/ConfigOps.ts
@@ -180019,8 +180136,8 @@ async function listSecrets(long = false, usage = false, file = null) {
180019
180136
  return false;
180020
180137
  }
180021
180138
  if (!long && !usage) {
180022
- secrets.forEach((variable) => {
180023
- printMessage2(variable._id, "data");
180139
+ secrets.forEach((secret) => {
180140
+ printMessage2(secret._id, "data");
180024
180141
  });
180025
180142
  return true;
180026
180143
  }
@@ -180041,7 +180158,7 @@ async function listSecrets(long = false, usage = false, file = null) {
180041
180158
  printError2(error2);
180042
180159
  return false;
180043
180160
  }
180044
- delete fullExport.secrets;
180161
+ delete fullExport.global.secrets;
180045
180162
  headers2.push("Used"["brightCyan"]);
180046
180163
  }
180047
180164
  const table = createTable(headers2);
@@ -180063,9 +180180,9 @@ async function listSecrets(long = false, usage = false, file = null) {
180063
180180
  new Date(secret.lastChangeDate).toUTCString()
180064
180181
  ] : [secret._id];
180065
180182
  if (usage) {
180066
- const isEsvUsed = isIdUsed(fullExport, secret._id, true);
180183
+ const locations = getIdLocations(fullExport, secret._id, true);
180067
180184
  values3.push(
180068
- isEsvUsed.used ? `${"yes"["brightGreen"]} (at ${isEsvUsed.location})` : "no"["brightRed"]
180185
+ locations.length > 0 ? `${"yes"["brightGreen"]} (${locations.length === 1 ? `at` : `${locations.length} uses, including:`} ${locations[0]})` : "no"["brightRed"]
180069
180186
  );
180070
180187
  }
180071
180188
  table.push(values3);
@@ -180193,7 +180310,7 @@ async function deleteSecrets() {
180193
180310
  }
180194
180311
  return false;
180195
180312
  }
180196
- async function listSecretVersions(secretId) {
180313
+ async function listSecretVersions(secretId, json = false) {
180197
180314
  let spinnerId;
180198
180315
  let versions5 = [];
180199
180316
  try {
@@ -180208,6 +180325,10 @@ async function listSecretVersions(secretId) {
180208
180325
  `Successfully read ${versions5.length} secret versions.`,
180209
180326
  "success"
180210
180327
  );
180328
+ if (json) {
180329
+ printMessage2(versions5, "data");
180330
+ return true;
180331
+ }
180211
180332
  const table = createTable([
180212
180333
  { hAlign: "right", content: "Version"["brightCyan"] },
180213
180334
  "Status"["brightCyan"],
@@ -180235,46 +180356,79 @@ async function listSecretVersions(secretId) {
180235
180356
  }
180236
180357
  return false;
180237
180358
  }
180238
- async function describeSecret(secretId) {
180359
+ async function describeSecret(secretId, file, usage = false, json = false) {
180239
180360
  let spinnerId;
180240
- let secret = null;
180241
180361
  try {
180242
180362
  spinnerId = createProgressIndicator2(
180243
180363
  "indeterminate",
180244
180364
  0,
180245
180365
  `Reading secret ${secretId}...`
180246
180366
  );
180247
- secret = await readSecret2(secretId);
180367
+ const secret = await readSecret2(secretId);
180368
+ if (usage) {
180369
+ try {
180370
+ const fullExport = await getFullExportConfig(file);
180371
+ delete fullExport.global.secrets;
180372
+ secret.locations = getIdLocations(fullExport, secretId, true);
180373
+ } catch (error2) {
180374
+ stopProgressIndicator2(
180375
+ spinnerId,
180376
+ `Error determining usage for secret with id ${secretId}`,
180377
+ "fail"
180378
+ );
180379
+ printError2(error2);
180380
+ return false;
180381
+ }
180382
+ }
180248
180383
  stopProgressIndicator2(
180249
180384
  spinnerId,
180250
180385
  `Successfully read secret ${secretId}.`,
180251
180386
  "success"
180252
180387
  );
180253
- const table = createKeyValueTable();
180254
- table.push(["Name"["brightCyan"], secret._id]);
180255
- table.push(["Active Version"["brightCyan"], secret.activeVersion]);
180256
- table.push(["Loaded Version"["brightCyan"], secret.loadedVersion]);
180257
- table.push([
180258
- "Status"["brightCyan"],
180259
- secret.loaded ? "loaded"["brightGreen"] : "unloaded"["brightRed"]
180260
- ]);
180261
- table.push(["Description"["brightCyan"], wordwrap(secret.description, 60)]);
180262
- table.push([
180263
- "Modified"["brightCyan"],
180264
- new Date(secret.lastChangeDate).toLocaleString()
180265
- ]);
180266
- let lastChangedBy = secret.lastChangedBy;
180267
- try {
180268
- lastChangedBy = state.getUseBearerTokenForAmApis() ? secret.lastChangedBy : await resolveUserName3("teammember", secret.lastChangedBy);
180269
- } catch (error2) {
180388
+ if (json) {
180389
+ printMessage2(secret, "data");
180390
+ } else {
180391
+ const table = createKeyValueTable();
180392
+ table.push(["Name"["brightCyan"], secret._id]);
180393
+ table.push(["Active Version"["brightCyan"], secret.activeVersion]);
180394
+ table.push(["Loaded Version"["brightCyan"], secret.loadedVersion]);
180395
+ table.push([
180396
+ "Status"["brightCyan"],
180397
+ secret.loaded ? "loaded"["brightGreen"] : "unloaded"["brightRed"]
180398
+ ]);
180399
+ table.push([
180400
+ "Description"["brightCyan"],
180401
+ wordwrap(secret.description, 60)
180402
+ ]);
180403
+ table.push([
180404
+ "Modified"["brightCyan"],
180405
+ new Date(secret.lastChangeDate).toLocaleString()
180406
+ ]);
180407
+ let lastChangedBy = secret.lastChangedBy;
180408
+ try {
180409
+ lastChangedBy = state.getUseBearerTokenForAmApis() ? secret.lastChangedBy : await resolveUserName3("teammember", secret.lastChangedBy);
180410
+ } catch (error2) {
180411
+ }
180412
+ table.push(["Modifier"["brightCyan"], lastChangedBy]);
180413
+ table.push(["Modifier UUID"["brightCyan"], secret.lastChangedBy]);
180414
+ table.push(["Encoding"["brightCyan"], secret.encoding]);
180415
+ table.push([
180416
+ "Use In Placeholders"["brightCyan"],
180417
+ secret.useInPlaceholders
180418
+ ]);
180419
+ if (usage) {
180420
+ table.push([
180421
+ `Usage Locations (${secret.locations.length} total)`["brightCyan"],
180422
+ secret.locations.length > 0 ? secret.locations[0] : ""
180423
+ ]);
180424
+ for (let i2 = 1; i2 < secret.locations.length; i2++) {
180425
+ table.push(["", secret.locations[i2]]);
180426
+ }
180427
+ }
180428
+ printMessage2(table.toString(), "data");
180270
180429
  }
180271
- table.push(["Modifier"["brightCyan"], lastChangedBy]);
180272
- table.push(["Modifier UUID"["brightCyan"], secret.lastChangedBy]);
180273
- table.push(["Encoding"["brightCyan"], secret.encoding]);
180274
- table.push(["Use In Placeholders"["brightCyan"], secret.useInPlaceholders]);
180275
- printMessage2(table.toString(), "data");
180276
180430
  printMessage2("\nSecret Versions:", "data");
180277
- await listSecretVersions(secretId);
180431
+ await listSecretVersions(secretId, json);
180278
180432
  return true;
180279
180433
  } catch (error2) {
180280
180434
  stopProgressIndicator2(
@@ -180705,7 +180859,17 @@ function setup89() {
180705
180859
  "-i, --secret-id <secret-id>",
180706
180860
  "Secret id."
180707
180861
  ).makeOptionMandatory()
180708
- ).action(
180862
+ ).addOption(
180863
+ new Option(
180864
+ "-f, --file [file]",
180865
+ "Optional export file to use to determine usage. Overrides -D, --directory. Only used if -u or --usage is provided as well."
180866
+ )
180867
+ ).addOption(
180868
+ new Option(
180869
+ "-u, --usage",
180870
+ "List all uses of the secret. If a file is provided with -f or --file, it will search for usage in the file. If a directory is provided with -D or --directory, it will search for usage in all .json files in the directory and sub-directories. If no file or directory is provided, it will perform a full export automatically to determine usage."
180871
+ ).default(false, "false")
180872
+ ).addOption(new Option("--json", "Output in JSON format.")).action(
180709
180873
  // implement command logic inside action handler
180710
180874
  async (host2, user2, password3, options2, command2) => {
180711
180875
  command2.handleDefaultArgsAndOpts(
@@ -180715,11 +180879,21 @@ function setup89() {
180715
180879
  options2,
180716
180880
  command2
180717
180881
  );
180718
- if (await getTokens2(false, true, deploymentTypes25)) {
180882
+ if (options2.secretId && await getTokens2(false, true, deploymentTypes25)) {
180719
180883
  verboseMessage2(`Describing secret ${options2.secretId}...`);
180720
- const outcome = await describeSecret(options2.secretId);
180884
+ const outcome = await describeSecret(
180885
+ options2.secretId,
180886
+ options2.file,
180887
+ options2.usage,
180888
+ options2.json
180889
+ );
180721
180890
  if (!outcome) process.exitCode = 1;
180722
180891
  } else {
180892
+ printMessage2(
180893
+ "Unrecognized combination of options or no options...",
180894
+ "error"
180895
+ );
180896
+ program3.help();
180723
180897
  process.exitCode = 1;
180724
180898
  }
180725
180899
  }
@@ -181265,7 +181439,7 @@ _chunkMPPKDFVIcjs.init_cjs_shims.call(void 0, );
181265
181439
  _chunkMPPKDFVIcjs.init_cjs_shims.call(void 0, );
181266
181440
 
181267
181441
  var {
181268
- decodeBase64,
181442
+ decodeBase64: decodeBase642,
181269
181443
  getFilePath: getFilePath17,
181270
181444
  getTypedFilename: getTypedFilename16,
181271
181445
  getWorkingDirectory: getWorkingDirectory14,
@@ -181327,7 +181501,7 @@ async function listVariables(long = false, usage = false, file = null) {
181327
181501
  printError2(error2);
181328
181502
  return false;
181329
181503
  }
181330
- delete fullExport.variables;
181504
+ delete fullExport.global.variables;
181331
181505
  headers2.push("Used"["brightCyan"]);
181332
181506
  }
181333
181507
  const table = createTable(headers2);
@@ -181335,7 +181509,7 @@ async function listVariables(long = false, usage = false, file = null) {
181335
181509
  const values3 = long ? [
181336
181510
  variable._id,
181337
181511
  wordwrap(
181338
- variable.valueBase64 ? decodeBase64(variable.valueBase64) : variable.value,
181512
+ variable.valueBase64 ? decodeBase642(variable.valueBase64) : variable.value,
181339
181513
  40
181340
181514
  ),
181341
181515
  variable.loaded ? "loaded"["brightGreen"] : "unloaded"["brightRed"],
@@ -181344,9 +181518,9 @@ async function listVariables(long = false, usage = false, file = null) {
181344
181518
  new Date(variable.lastChangeDate).toUTCString()
181345
181519
  ] : [variable._id];
181346
181520
  if (usage) {
181347
- const isEsvUsed = isIdUsed(fullExport, variable._id, true);
181521
+ const locations = getIdLocations(fullExport, variable._id, true);
181348
181522
  values3.push(
181349
- isEsvUsed.used ? `${"yes"["brightGreen"]} (at ${isEsvUsed.location})` : "no"["brightRed"]
181523
+ locations.length > 0 ? `${"yes"["brightGreen"]} (${locations.length === 1 ? `at` : `${locations.length} uses, including:`} ${locations[0]})` : "no"["brightRed"]
181350
181524
  );
181351
181525
  }
181352
181526
  table.push(values3);
@@ -181481,7 +181655,7 @@ async function deleteVariables() {
181481
181655
  }
181482
181656
  return false;
181483
181657
  }
181484
- async function describeVariable(variableId, json = false) {
181658
+ async function describeVariable(variableId, file, usage = false, json = false) {
181485
181659
  const spinnerId = createProgressIndicator2(
181486
181660
  "indeterminate",
181487
181661
  0,
@@ -181489,6 +181663,21 @@ async function describeVariable(variableId, json = false) {
181489
181663
  );
181490
181664
  try {
181491
181665
  const variable = await readVariable2(variableId);
181666
+ if (usage) {
181667
+ try {
181668
+ const fullExport = await getFullExportConfig(file);
181669
+ delete fullExport.global.variables;
181670
+ variable.locations = getIdLocations(fullExport, variableId, true);
181671
+ } catch (error2) {
181672
+ stopProgressIndicator2(
181673
+ spinnerId,
181674
+ `Error determining usage for variable with id ${variableId}`,
181675
+ "fail"
181676
+ );
181677
+ printError2(error2);
181678
+ return false;
181679
+ }
181680
+ }
181492
181681
  stopProgressIndicator2(
181493
181682
  spinnerId,
181494
181683
  `Successfully retrieved variable ${variableId}`,
@@ -181502,7 +181691,7 @@ async function describeVariable(variableId, json = false) {
181502
181691
  table.push([
181503
181692
  "Value"["brightCyan"],
181504
181693
  wordwrap(
181505
- variable.valueBase64 ? decodeBase64(variable.valueBase64) : variable.value,
181694
+ variable.valueBase64 ? decodeBase642(variable.valueBase64) : variable.value,
181506
181695
  40
181507
181696
  )
181508
181697
  ]);
@@ -181528,6 +181717,15 @@ async function describeVariable(variableId, json = false) {
181528
181717
  table.push(["Modifier"["brightCyan"], modifierName]);
181529
181718
  }
181530
181719
  table.push(["Modifier UUID"["brightCyan"], variable.lastChangedBy]);
181720
+ if (usage) {
181721
+ table.push([
181722
+ `Usage Locations (${variable.locations.length} total)`["brightCyan"],
181723
+ variable.locations.length > 0 ? variable.locations[0] : ""
181724
+ ]);
181725
+ for (let i2 = 1; i2 < variable.locations.length; i2++) {
181726
+ table.push(["", variable.locations[i2]]);
181727
+ }
181728
+ }
181531
181729
  printMessage2(table.toString(), "data");
181532
181730
  }
181533
181731
  return true;
@@ -181856,6 +182054,16 @@ function setup103() {
181856
182054
  "-i, --variable-id <variable-id>",
181857
182055
  "Variable id."
181858
182056
  ).makeOptionMandatory()
182057
+ ).addOption(
182058
+ new Option(
182059
+ "-f, --file [file]",
182060
+ "Optional export file to use to determine usage. Overrides -D, --directory. Only used if -u or --usage is provided as well."
182061
+ )
182062
+ ).addOption(
182063
+ new Option(
182064
+ "-u, --usage",
182065
+ "List all uses of the variable. If a file is provided with -f or --file, it will search for usage in the file. If a directory is provided with -D or --directory, it will search for usage in all .json files in the directory and sub-directories. If no file or directory is provided, it will perform a full export automatically to determine usage."
182066
+ ).default(false, "false")
181859
182067
  ).addOption(new Option("--json", "Output in JSON format.")).action(
181860
182068
  // implement command logic inside action handler
181861
182069
  async (host2, user2, password3, options2, command2) => {
@@ -181866,14 +182074,21 @@ function setup103() {
181866
182074
  options2,
181867
182075
  command2
181868
182076
  );
181869
- if (await getTokens2(false, true, deploymentTypes37)) {
182077
+ if (options2.variableId && await getTokens2(false, true, deploymentTypes37)) {
181870
182078
  verboseMessage2(`Describing variable ${options2.variableId}...`);
181871
182079
  const outcome = await describeVariable(
181872
182080
  options2.variableId,
182081
+ options2.file,
182082
+ options2.usage,
181873
182083
  options2.json
181874
182084
  );
181875
182085
  if (!outcome) process.exitCode = 1;
181876
182086
  } else {
182087
+ printMessage2(
182088
+ "Unrecognized combination of options or no options...",
182089
+ "error"
182090
+ );
182091
+ program3.help();
181877
182092
  process.exitCode = 1;
181878
182093
  }
181879
182094
  }
@@ -183307,7 +183522,7 @@ function getTableRowMd5(nodeObj, nodeRef) {
183307
183522
  // src/ops/Saml2Ops.ts
183308
183523
  _chunkMPPKDFVIcjs.init_cjs_shims.call(void 0, );
183309
183524
 
183310
- var { decodeBase64: decodeBase642, saveTextToFile: saveTextToFile4, getFilePath: getFilePath20, getWorkingDirectory: getWorkingDirectory17 } = frodo.utils;
183525
+ var { decodeBase64: decodeBase643, saveTextToFile: saveTextToFile4, getFilePath: getFilePath20, getWorkingDirectory: getWorkingDirectory17 } = frodo.utils;
183311
183526
  var { getTypedFilename: getTypedFilename19, saveJsonToFile: saveJsonToFile19, getRealmString: getRealmString3 } = frodo.utils;
183312
183527
  var {
183313
183528
  readSaml2ProviderStubs: readSaml2ProviderStubs2,
@@ -183555,7 +183770,7 @@ async function importFirstSaml2ProviderFromFile(file, options2 = { deps: true })
183555
183770
  const data2 = _fs3.default.readFileSync(getFilePath20(file), "utf8");
183556
183771
  const fileData = JSON.parse(data2);
183557
183772
  const entityId64 = Object.keys(fileData.saml.remote)[0] || Object.keys(fileData.saml.hosted)[0];
183558
- const entityId = decodeBase642(entityId64);
183773
+ const entityId = decodeBase643(entityId64);
183559
183774
  indicatorId = createProgressIndicator2(
183560
183775
  "indeterminate",
183561
183776
  0,
@@ -187490,9 +187705,70 @@ function setup165() {
187490
187705
  return program3;
187491
187706
  }
187492
187707
 
187493
- // src/cli/script/script-export.ts
187708
+ // src/cli/script/script-describe.ts
187494
187709
  _chunkMPPKDFVIcjs.init_cjs_shims.call(void 0, );
187495
187710
  function setup166() {
187711
+ const program3 = new FrodoCommand("frodo script describe");
187712
+ program3.description("Describe script.").addOption(
187713
+ new Option(
187714
+ "-i, --script-id <uuid>",
187715
+ "Uuid of the script. If specified, -a and -A are ignored."
187716
+ )
187717
+ ).addOption(
187718
+ new Option(
187719
+ "-n, --script-name <name>",
187720
+ "Name of the script. If specified, -a and -A are ignored."
187721
+ )
187722
+ ).addOption(
187723
+ new Option(
187724
+ "-f, --file [file]",
187725
+ "Optional export file to use to determine usage. Overrides -D, --directory. Only used if -u or --usage is provided as well."
187726
+ )
187727
+ ).addOption(
187728
+ new Option(
187729
+ "-u, --usage",
187730
+ "List all uses of the script. If a file is provided with -f or --file, it will search for usage in the file. If a directory is provided with -D or --directory, it will search for usage in all .json files in the directory and sub-directories. If no file or directory is provided, it will perform a full export automatically to determine usage."
187731
+ ).default(false, "false")
187732
+ ).addOption(new Option("--json", "Output in JSON format.")).action(
187733
+ // implement command logic inside action handler
187734
+ async (host2, realm2, user2, password3, options2, command2) => {
187735
+ command2.handleDefaultArgsAndOpts(
187736
+ host2,
187737
+ realm2,
187738
+ user2,
187739
+ password3,
187740
+ options2,
187741
+ command2
187742
+ );
187743
+ if ((options2.scriptName || options2.scriptId) && await getTokens2()) {
187744
+ verboseMessage2(
187745
+ `Describing script ${options2.scriptName ? options2.scriptName : options2.scriptId}...`
187746
+ );
187747
+ const outcome = await describeScript(
187748
+ options2.scriptId,
187749
+ options2.scriptName,
187750
+ options2.file,
187751
+ options2.usage,
187752
+ options2.json
187753
+ );
187754
+ if (!outcome) process.exitCode = 1;
187755
+ } else {
187756
+ printMessage2(
187757
+ "Unrecognized combination of options or no options...",
187758
+ "error"
187759
+ );
187760
+ program3.help();
187761
+ process.exitCode = 1;
187762
+ }
187763
+ }
187764
+ // end command logic inside action handler
187765
+ );
187766
+ return program3;
187767
+ }
187768
+
187769
+ // src/cli/script/script-export.ts
187770
+ _chunkMPPKDFVIcjs.init_cjs_shims.call(void 0, );
187771
+ function setup167() {
187496
187772
  const program3 = new FrodoCommand("frodo script export");
187497
187773
  program3.description("Export scripts.").addOption(
187498
187774
  new Option(
@@ -187618,7 +187894,7 @@ function setup166() {
187618
187894
 
187619
187895
  // src/cli/script/script-import.ts
187620
187896
  _chunkMPPKDFVIcjs.init_cjs_shims.call(void 0, );
187621
- function setup167() {
187897
+ function setup168() {
187622
187898
  const program3 = new FrodoCommand("frodo script import");
187623
187899
  program3.description("Import scripts.").addOption(new Option("-f, --file <file>", "Name of the file to import.")).addOption(
187624
187900
  new Option(
@@ -187719,7 +187995,7 @@ function setup167() {
187719
187995
 
187720
187996
  // src/cli/script/script-list.ts
187721
187997
  _chunkMPPKDFVIcjs.init_cjs_shims.call(void 0, );
187722
- function setup168() {
187998
+ function setup169() {
187723
187999
  const program3 = new FrodoCommand("frodo script list");
187724
188000
  program3.description("List scripts.").addOption(
187725
188001
  new Option("-l, --long", "Long with all fields besides usage.").default(
@@ -187765,11 +188041,12 @@ function setup168() {
187765
188041
  }
187766
188042
 
187767
188043
  // src/cli/script/script.ts
187768
- function setup169() {
188044
+ function setup170() {
187769
188045
  const program3 = new FrodoStubCommand("script").description("Manage scripts.");
187770
- program3.addCommand(setup168().name("list"));
187771
- program3.addCommand(setup166().name("export"));
187772
- program3.addCommand(setup167().name("import"));
188046
+ program3.addCommand(setup169().name("list"));
188047
+ program3.addCommand(setup166().name("describe"));
188048
+ program3.addCommand(setup167().name("export"));
188049
+ program3.addCommand(setup168().name("import"));
187773
188050
  program3.addCommand(setup165().name("delete"));
187774
188051
  return program3;
187775
188052
  }
@@ -188023,7 +188300,7 @@ async function deleteServices(globalConfig = false) {
188023
188300
  }
188024
188301
 
188025
188302
  // src/cli/service/service-delete.ts
188026
- function setup170() {
188303
+ function setup171() {
188027
188304
  const program3 = new FrodoCommand("frodo service delete");
188028
188305
  program3.description("Delete AM services.").addOption(new Option("-i, --id <id>", "Id of Service to be deleted.")).addOption(new Option("-a, --all", "Delete all services. Ignored with -i.")).addOption(new Option("-g, --global", "Delete global services.")).action(
188029
188306
  async (host2, realm2, user2, password3, options2, command2) => {
@@ -188053,7 +188330,7 @@ function setup170() {
188053
188330
 
188054
188331
  // src/cli/service/service-export.ts
188055
188332
  _chunkMPPKDFVIcjs.init_cjs_shims.call(void 0, );
188056
- function setup171() {
188333
+ function setup172() {
188057
188334
  const program3 = new FrodoCommand("frodo service export");
188058
188335
  program3.description("Export AM services.").addOption(
188059
188336
  new Option(
@@ -188121,7 +188398,7 @@ function setup171() {
188121
188398
 
188122
188399
  // src/cli/service/service-import.ts
188123
188400
  _chunkMPPKDFVIcjs.init_cjs_shims.call(void 0, );
188124
- function setup172() {
188401
+ function setup173() {
188125
188402
  const program3 = new FrodoCommand("frodo service import");
188126
188403
  program3.description("Import AM services.").addOption(
188127
188404
  new Option(
@@ -188217,7 +188494,7 @@ function setup172() {
188217
188494
 
188218
188495
  // src/cli/service/service-list.ts
188219
188496
  _chunkMPPKDFVIcjs.init_cjs_shims.call(void 0, );
188220
- function setup173() {
188497
+ function setup174() {
188221
188498
  const program3 = new FrodoCommand("frodo service list");
188222
188499
  program3.description("List AM services.").addOption(
188223
188500
  new Option("-l, --long", "Long with all fields.").default(false, "false")
@@ -188242,14 +188519,14 @@ function setup173() {
188242
188519
  }
188243
188520
 
188244
188521
  // src/cli/service/service.ts
188245
- function setup174() {
188522
+ function setup175() {
188246
188523
  const program3 = new FrodoStubCommand("service").description(
188247
188524
  "Manage AM services."
188248
188525
  );
188249
- program3.addCommand(setup173().name("list"));
188250
- program3.addCommand(setup171().name("export"));
188251
- program3.addCommand(setup172().name("import"));
188252
- program3.addCommand(setup170().name("delete"));
188526
+ program3.addCommand(setup174().name("list"));
188527
+ program3.addCommand(setup172().name("export"));
188528
+ program3.addCommand(setup173().name("import"));
188529
+ program3.addCommand(setup171().name("delete"));
188253
188530
  return program3;
188254
188531
  }
188255
188532
 
@@ -188271,7 +188548,7 @@ function searchFunctions(_answers, input = "") {
188271
188548
  );
188272
188549
  });
188273
188550
  }
188274
- function setup175() {
188551
+ function setup176() {
188275
188552
  const program = new FrodoCommand("shell");
188276
188553
  program.description("Launch the frodo interactive shell.").addHelpText(
188277
188554
  "after",
@@ -188328,7 +188605,7 @@ _chunkMPPKDFVIcjs.init_cjs_shims.call(void 0, );
188328
188605
  // src/cli/theme/theme-delete.ts
188329
188606
  _chunkMPPKDFVIcjs.init_cjs_shims.call(void 0, );
188330
188607
  var deploymentTypes57 = ["cloud", "forgeops"];
188331
- function setup176() {
188608
+ function setup177() {
188332
188609
  const program3 = new FrodoCommand("frodo theme delete", [], deploymentTypes57);
188333
188610
  program3.description("Delete themes.").addOption(
188334
188611
  new Option(
@@ -188391,7 +188668,7 @@ function setup176() {
188391
188668
  // src/cli/theme/theme-export.ts
188392
188669
  _chunkMPPKDFVIcjs.init_cjs_shims.call(void 0, );
188393
188670
  var deploymentTypes58 = ["cloud", "forgeops"];
188394
- function setup177() {
188671
+ function setup178() {
188395
188672
  const program3 = new FrodoCommand("frodo theme export", [], deploymentTypes58);
188396
188673
  program3.description("Export themes.").addOption(
188397
188674
  new Option(
@@ -188482,7 +188759,7 @@ function setup177() {
188482
188759
  // src/cli/theme/theme-import.ts
188483
188760
  _chunkMPPKDFVIcjs.init_cjs_shims.call(void 0, );
188484
188761
  var deploymentTypes59 = ["cloud", "forgeops"];
188485
- function setup178() {
188762
+ function setup179() {
188486
188763
  const program3 = new FrodoCommand("frodo theme import", [], deploymentTypes59);
188487
188764
  program3.description("Import themes.").addOption(
188488
188765
  new Option(
@@ -188570,7 +188847,7 @@ function setup178() {
188570
188847
  // src/cli/theme/theme-list.ts
188571
188848
  _chunkMPPKDFVIcjs.init_cjs_shims.call(void 0, );
188572
188849
  var deploymentTypes60 = ["cloud", "forgeops"];
188573
- function setup179() {
188850
+ function setup180() {
188574
188851
  const program3 = new FrodoCommand("frodo theme list", [], deploymentTypes60);
188575
188852
  program3.description("List themes.").addOption(
188576
188853
  new Option("-l, --long", "Long with more fields.").default(false, "false")
@@ -188599,12 +188876,12 @@ function setup179() {
188599
188876
  }
188600
188877
 
188601
188878
  // src/cli/theme/theme.ts
188602
- function setup180() {
188879
+ function setup181() {
188603
188880
  const program3 = new FrodoStubCommand("theme").description("Manage themes.");
188604
- program3.addCommand(setup179().name("list"));
188605
- program3.addCommand(setup177().name("export"));
188606
- program3.addCommand(setup178().name("import"));
188607
- program3.addCommand(setup176().name("delete"));
188881
+ program3.addCommand(setup180().name("list"));
188882
+ program3.addCommand(setup178().name("export"));
188883
+ program3.addCommand(setup179().name("import"));
188884
+ program3.addCommand(setup177().name("delete"));
188608
188885
  return program3;
188609
188886
  }
188610
188887
 
@@ -188682,7 +188959,7 @@ var compareVersions = (v12, v2) => {
188682
188959
  // package.json
188683
188960
  var package_default2 = {
188684
188961
  name: "@rockcarver/frodo-cli",
188685
- version: "2.0.6-0",
188962
+ version: "2.0.6-2",
188686
188963
  type: "module",
188687
188964
  description: "A command line interface to manage ForgeRock Identity Cloud tenants, ForgeOps deployments, and classic deployments.",
188688
188965
  keywords: [
@@ -189016,10 +189293,10 @@ var { initTokenCache: initTokenCache2 } = frodo.cache;
189016
189293
  program3.addCommand(setup147());
189017
189294
  program3.addCommand(setup152());
189018
189295
  program3.addCommand(setup164());
189019
- program3.addCommand(setup169());
189020
- program3.addCommand(setup174());
189296
+ program3.addCommand(setup170());
189021
189297
  program3.addCommand(setup175());
189022
- program3.addCommand(setup180());
189298
+ program3.addCommand(setup176());
189299
+ program3.addCommand(setup181());
189023
189300
  program3.showHelpAfterError();
189024
189301
  program3.enablePositionalOptions();
189025
189302
  await program3.parseAsync();