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.
- package/dist/index.js +88 -71
- 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
|
|
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 =
|
|
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.
|
|
613
|
-
text = text.
|
|
614
|
-
text = text.
|
|
615
|
-
text = text.
|
|
616
|
-
text = text.
|
|
617
|
-
text = text.
|
|
618
|
-
text = text.
|
|
619
|
-
text = text.
|
|
620
|
-
text = text.
|
|
621
|
-
text = text.
|
|
622
|
-
text = text.
|
|
623
|
-
text = text.
|
|
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("&", "&");
|
|
618
|
+
text = text.replaceAll("<", "<");
|
|
619
|
+
text = text.replaceAll(">", ">");
|
|
620
|
+
text = text.replaceAll(""", '"');
|
|
621
|
+
text = text.replaceAll("'", "'");
|
|
622
|
+
text = text.replaceAll(" ", " ");
|
|
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
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
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(
|
|
653
|
-
|
|
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
|
|
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
|
-
|
|
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 = (
|
|
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
|
-
|
|
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");
|