azdo-cli 0.2.0-develop.90 → 0.2.0-develop.93

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +88 -71
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -60,7 +60,7 @@ function buildExtraFields(fields, requested) {
60
60
  for (const name of requested) {
61
61
  const val = fields[name];
62
62
  if (val !== void 0 && val !== null) {
63
- result[name] = String(val);
63
+ result[name] = typeof val === "object" ? JSON.stringify(val) : String(val);
64
64
  }
65
65
  }
66
66
  return Object.keys(result).length > 0 ? result : null;
@@ -119,7 +119,7 @@ async function getWorkItem(context, id, pat, extraFields) {
119
119
  }
120
120
  let combinedDescription = null;
121
121
  if (descriptionParts.length === 1) {
122
- combinedDescription = descriptionParts[0].value;
122
+ combinedDescription = descriptionParts.at(0)?.value ?? null;
123
123
  } else if (descriptionParts.length > 1) {
124
124
  combinedDescription = descriptionParts.map((p) => `<h3>${p.label}</h3>${p.value}`).join("");
125
125
  }
@@ -313,7 +313,7 @@ var patterns = [
313
313
  ];
314
314
  function parseAzdoRemote(url) {
315
315
  for (const pattern of patterns) {
316
- const match = url.match(pattern);
316
+ const match = pattern.exec(url);
317
317
  if (match) {
318
318
  const project = match[2];
319
319
  if (/^DefaultCollection$/i.test(project)) {
@@ -609,18 +609,18 @@ function parseRequestedFields(raw) {
609
609
  }
610
610
  function stripHtml(html) {
611
611
  let text = html;
612
- text = text.replace(/<h[1-6][^>]*>(.*?)<\/h[1-6]>/gi, "\n--- $1 ---\n");
613
- text = text.replace(/<br\s*\/?>/gi, "\n");
614
- text = text.replace(/<\/?(p|div)>/gi, "\n");
615
- text = text.replace(/<li>/gi, "\n");
616
- text = text.replace(/<[^>]*>/g, "");
617
- text = text.replace(/&amp;/g, "&");
618
- text = text.replace(/&lt;/g, "<");
619
- text = text.replace(/&gt;/g, ">");
620
- text = text.replace(/&quot;/g, '"');
621
- text = text.replace(/&#39;/g, "'");
622
- text = text.replace(/&nbsp;/g, " ");
623
- text = text.replace(/\n{3,}/g, "\n\n");
612
+ text = text.replaceAll(/<h[1-6][^>]*>(.*?)<\/h[1-6]>/gi, "\n--- $1 ---\n");
613
+ text = text.replaceAll(/<br\s*\/?>/gi, "\n");
614
+ text = text.replaceAll(/<\/?(p|div)>/gi, "\n");
615
+ text = text.replaceAll(/<li>/gi, "\n");
616
+ text = text.replaceAll(/<[^>]*>/g, "");
617
+ text = text.replaceAll("&amp;", "&");
618
+ text = text.replaceAll("&lt;", "<");
619
+ text = text.replaceAll("&gt;", ">");
620
+ text = text.replaceAll("&quot;", '"');
621
+ text = text.replaceAll("&#39;", "'");
622
+ text = text.replaceAll("&nbsp;", " ");
623
+ text = text.replaceAll(/\n{3,}/g, "\n\n");
624
624
  return text.trim();
625
625
  }
626
626
  function convertRichText(html, markdown) {
@@ -641,16 +641,19 @@ function summarizeDescription(text, label) {
641
641
  return [`${label("Description:")}${firstThree.join("\n")}${suffix}`];
642
642
  }
643
643
  function formatWorkItem(workItem, short, markdown = false) {
644
- const lines = [];
645
644
  const label = (name) => name.padEnd(13);
646
- lines.push(`${label("ID:")}${workItem.id}`);
647
- lines.push(`${label("Type:")}${workItem.type}`);
648
- lines.push(`${label("Title:")}${workItem.title}`);
649
- lines.push(`${label("State:")}${workItem.state}`);
650
- lines.push(`${label("Assigned To:")}${workItem.assignedTo ?? "Unassigned"}`);
645
+ const lines = [
646
+ `${label("ID:")}${workItem.id}`,
647
+ `${label("Type:")}${workItem.type}`,
648
+ `${label("Title:")}${workItem.title}`,
649
+ `${label("State:")}${workItem.state}`,
650
+ `${label("Assigned To:")}${workItem.assignedTo ?? "Unassigned"}`
651
+ ];
651
652
  if (!short) {
652
- lines.push(`${label("Area:")}${workItem.areaPath}`);
653
- lines.push(`${label("Iteration:")}${workItem.iterationPath}`);
653
+ lines.push(
654
+ `${label("Area:")}${workItem.areaPath}`,
655
+ `${label("Iteration:")}${workItem.iterationPath}`
656
+ );
654
657
  }
655
658
  lines.push(`${label("URL:")}${workItem.url}`);
656
659
  if (workItem.extraFields) {
@@ -676,7 +679,7 @@ function createGetItemCommand() {
676
679
  try {
677
680
  context = resolveContext(options);
678
681
  const credential = await resolvePat();
679
- const fieldsList = options.fields !== void 0 ? parseRequestedFields(options.fields) : parseRequestedFields(loadConfig().fields);
682
+ const fieldsList = options.fields === void 0 ? parseRequestedFields(loadConfig().fields) : parseRequestedFields(options.fields);
680
683
  const workItem = await getWorkItem(context, id, credential.pat, fieldsList);
681
684
  const markdownEnabled = options.markdown ?? loadConfig().markdown ?? false;
682
685
  const output = formatWorkItem(workItem, options.short ?? false, markdownEnabled);
@@ -707,6 +710,63 @@ function createClearPatCommand() {
707
710
  // src/commands/config.ts
708
711
  import { Command as Command3 } from "commander";
709
712
  import { createInterface as createInterface2 } from "readline";
713
+ function formatConfigValue(value, unsetFallback = "") {
714
+ if (value === void 0) {
715
+ return unsetFallback;
716
+ }
717
+ return Array.isArray(value) ? value.join(",") : value;
718
+ }
719
+ function writeConfigList(cfg) {
720
+ const keyWidth = 10;
721
+ const valueWidth = 30;
722
+ for (const setting of SETTINGS) {
723
+ const raw = cfg[setting.key];
724
+ const value = formatConfigValue(raw, "(not set)");
725
+ const marker = raw === void 0 && setting.required ? " *" : "";
726
+ process.stdout.write(
727
+ `${setting.key.padEnd(keyWidth)}${String(value).padEnd(valueWidth)}${setting.description}${marker}
728
+ `
729
+ );
730
+ }
731
+ const hasUnset = SETTINGS.some((s) => s.required && cfg[s.key] === void 0);
732
+ if (hasUnset) {
733
+ process.stdout.write(
734
+ '\n* = required but not configured. Run "azdo config wizard" to set up.\n'
735
+ );
736
+ }
737
+ }
738
+ function createAsk(rl) {
739
+ return (prompt) => new Promise((resolve2) => rl.question(prompt, resolve2));
740
+ }
741
+ async function promptForSetting(cfg, setting, ask) {
742
+ const currentDisplay = String(formatConfigValue(cfg[setting.key], ""));
743
+ const requiredTag = setting.required ? " (required)" : " (optional)";
744
+ process.stderr.write(`${setting.description}${requiredTag}
745
+ `);
746
+ if (setting.example) {
747
+ process.stderr.write(` Example: ${setting.example}
748
+ `);
749
+ }
750
+ const defaultHint = currentDisplay ? ` [${currentDisplay}]` : "";
751
+ const answer = await ask(` ${setting.key}${defaultHint}: `);
752
+ const trimmed = answer.trim();
753
+ if (trimmed) {
754
+ setConfigValue(setting.key, trimmed);
755
+ process.stderr.write(` -> Set "${setting.key}" to "${trimmed}"
756
+
757
+ `);
758
+ return;
759
+ }
760
+ if (currentDisplay) {
761
+ process.stderr.write(` -> Kept "${setting.key}" as "${currentDisplay}"
762
+
763
+ `);
764
+ return;
765
+ }
766
+ process.stderr.write(` -> Skipped "${setting.key}"
767
+
768
+ `);
769
+ }
710
770
  function createConfigCommand() {
711
771
  const config = new Command3("config");
712
772
  config.description("Manage CLI settings");
@@ -759,27 +819,9 @@ function createConfigCommand() {
759
819
  const cfg = loadConfig();
760
820
  if (options.json) {
761
821
  process.stdout.write(JSON.stringify(cfg) + "\n");
762
- } else {
763
- const keyWidth = 10;
764
- const valueWidth = 30;
765
- for (const setting of SETTINGS) {
766
- const raw = cfg[setting.key];
767
- const value = raw === void 0 ? "(not set)" : Array.isArray(raw) ? raw.join(",") : raw;
768
- const marker = raw === void 0 && setting.required ? " *" : "";
769
- process.stdout.write(
770
- `${setting.key.padEnd(keyWidth)}${String(value).padEnd(valueWidth)}${setting.description}${marker}
771
- `
772
- );
773
- }
774
- const hasUnset = SETTINGS.some(
775
- (s) => s.required && cfg[s.key] === void 0
776
- );
777
- if (hasUnset) {
778
- process.stdout.write(
779
- '\n* = required but not configured. Run "azdo config wizard" to set up.\n'
780
- );
781
- }
822
+ return;
782
823
  }
824
+ writeConfigList(cfg);
783
825
  });
784
826
  const unset = new Command3("unset");
785
827
  unset.description("Remove a configuration value").argument("<key>", "setting key (org, project, fields)").option("--json", "output in JSON format").action((key, options) => {
@@ -811,36 +853,11 @@ function createConfigCommand() {
811
853
  input: process.stdin,
812
854
  output: process.stderr
813
855
  });
814
- const ask = (prompt) => new Promise((resolve2) => rl.question(prompt, resolve2));
856
+ const ask = createAsk(rl);
815
857
  process.stderr.write("Azure DevOps CLI - Configuration Wizard\n");
816
858
  process.stderr.write("=======================================\n\n");
817
859
  for (const setting of SETTINGS) {
818
- const current = cfg[setting.key];
819
- const currentDisplay = current === void 0 ? "" : Array.isArray(current) ? current.join(",") : current;
820
- const requiredTag = setting.required ? " (required)" : " (optional)";
821
- process.stderr.write(`${setting.description}${requiredTag}
822
- `);
823
- if (setting.example) {
824
- process.stderr.write(` Example: ${setting.example}
825
- `);
826
- }
827
- const defaultHint = currentDisplay ? ` [${currentDisplay}]` : "";
828
- const answer = await ask(` ${setting.key}${defaultHint}: `);
829
- const trimmed = answer.trim();
830
- if (trimmed) {
831
- setConfigValue(setting.key, trimmed);
832
- process.stderr.write(` -> Set "${setting.key}" to "${trimmed}"
833
-
834
- `);
835
- } else if (currentDisplay) {
836
- process.stderr.write(` -> Kept "${setting.key}" as "${currentDisplay}"
837
-
838
- `);
839
- } else {
840
- process.stderr.write(` -> Skipped "${setting.key}"
841
-
842
- `);
843
- }
860
+ await promptForSetting(cfg, setting, ask);
844
861
  }
845
862
  rl.close();
846
863
  process.stderr.write("Configuration complete!\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "azdo-cli",
3
- "version": "0.2.0-develop.90",
3
+ "version": "0.2.0-develop.93",
4
4
  "description": "Azure DevOps CLI tool",
5
5
  "type": "module",
6
6
  "bin": {