azdo-cli 0.22.0-develop.853 → 0.22.0-develop.874
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 +1 -0
- package/dist/index.js +67 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -45,6 +45,7 @@ azdo config set credentialStore dpapi --copy-credentials
|
|
|
45
45
|
|
|
46
46
|
# Read a work item
|
|
47
47
|
azdo get-item 12345
|
|
48
|
+
azdo get-item 12345 --json # machine-readable: identities, tags and all relations incl. pull requests
|
|
48
49
|
|
|
49
50
|
# Download images embedded in a work item's rich-text fields (opt-in)
|
|
50
51
|
azdo get-item 12345 --download-images # saved to the system temp dir
|
package/dist/index.js
CHANGED
|
@@ -475,6 +475,9 @@ var DEFAULT_FIELDS = [
|
|
|
475
475
|
"System.State",
|
|
476
476
|
"System.WorkItemType",
|
|
477
477
|
"System.AssignedTo",
|
|
478
|
+
"System.CreatedBy",
|
|
479
|
+
"System.CreatedDate",
|
|
480
|
+
"System.Tags",
|
|
478
481
|
"System.Description",
|
|
479
482
|
"Microsoft.VSTS.Common.AcceptanceCriteria",
|
|
480
483
|
"Microsoft.VSTS.TCM.ReproSteps",
|
|
@@ -698,6 +701,8 @@ function mapWorkItemComment(comment, fallbackWorkItemId) {
|
|
|
698
701
|
workItemId: comment.workItemId ?? fallbackWorkItemId,
|
|
699
702
|
text: typeof comment.text === "string" ? comment.text : "",
|
|
700
703
|
author: comment.createdBy?.displayName ?? null,
|
|
704
|
+
authorUniqueName: comment.createdBy?.uniqueName ?? null,
|
|
705
|
+
authorId: comment.createdBy?.id ?? null,
|
|
701
706
|
createdAt: comment.createdDate ?? null,
|
|
702
707
|
modifiedAt: comment.modifiedDate ?? null,
|
|
703
708
|
isDeleted: comment.isDeleted === true
|
|
@@ -807,6 +812,30 @@ async function getOrgFieldNames(context, cred) {
|
|
|
807
812
|
const data = await response.json();
|
|
808
813
|
return (data.value ?? []).map((f) => f.referenceName);
|
|
809
814
|
}
|
|
815
|
+
function toIdentity(ref) {
|
|
816
|
+
if (!ref) return null;
|
|
817
|
+
return {
|
|
818
|
+
displayName: ref.displayName ?? null,
|
|
819
|
+
uniqueName: ref.uniqueName ?? null,
|
|
820
|
+
id: ref.id ?? null
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
var PULL_REQUEST_ARTIFACT = /^vstfs:\/\/\/Git\/PullRequestId\/(.+)$/i;
|
|
824
|
+
function mapRelations(relations) {
|
|
825
|
+
return (relations ?? []).map((r) => {
|
|
826
|
+
const entry = { rel: r.rel, name: r.attributes?.name ?? null, url: r.url };
|
|
827
|
+
const workItemMatch = /\/workItems\/(\d+)$/i.exec(r.url);
|
|
828
|
+
if (workItemMatch) entry.workItemId = Number(workItemMatch[1]);
|
|
829
|
+
const prMatch = PULL_REQUEST_ARTIFACT.exec(r.url);
|
|
830
|
+
if (prMatch) {
|
|
831
|
+
const [projectId, repositoryId, prId] = prMatch[1].split(/%2F|\//i);
|
|
832
|
+
if (projectId && repositoryId && /^\d+$/.test(prId ?? "")) {
|
|
833
|
+
entry.pullRequest = { id: Number(prId), repositoryId, projectId };
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
return entry;
|
|
837
|
+
});
|
|
838
|
+
}
|
|
810
839
|
function buildCombinedDescription(fields) {
|
|
811
840
|
const parts = [];
|
|
812
841
|
if (fields["System.Description"]) {
|
|
@@ -862,6 +891,11 @@ async function getWorkItem(context, id, cred, extraFields) {
|
|
|
862
891
|
state: data.fields["System.State"],
|
|
863
892
|
type: data.fields["System.WorkItemType"],
|
|
864
893
|
assignedTo: data.fields["System.AssignedTo"]?.displayName ?? null,
|
|
894
|
+
assignedToIdentity: toIdentity(data.fields["System.AssignedTo"]),
|
|
895
|
+
createdBy: toIdentity(data.fields["System.CreatedBy"]),
|
|
896
|
+
createdDate: data.fields["System.CreatedDate"] ?? null,
|
|
897
|
+
tags: parseTags(data.fields["System.Tags"]),
|
|
898
|
+
relations: mapRelations(relationsData.relations),
|
|
865
899
|
description: buildCombinedDescription(data.fields),
|
|
866
900
|
areaPath: data.fields["System.AreaPath"],
|
|
867
901
|
iterationPath: data.fields["System.IterationPath"],
|
|
@@ -940,6 +974,8 @@ async function writeCommentText(url, cred, method, text, format, fallback) {
|
|
|
940
974
|
commentId: data.commentId ?? data.id ?? fallback.commentId,
|
|
941
975
|
text: typeof data.text === "string" ? data.text : text,
|
|
942
976
|
author: data.createdBy?.displayName ?? null,
|
|
977
|
+
authorUniqueName: data.createdBy?.uniqueName ?? null,
|
|
978
|
+
authorId: data.createdBy?.id ?? null,
|
|
943
979
|
createdAt: data.createdDate ?? null,
|
|
944
980
|
modifiedAt: data.modifiedDate ?? null,
|
|
945
981
|
url: data.url ?? null
|
|
@@ -959,6 +995,8 @@ async function addWorkItemComment(context, id, cred, text, format = "html") {
|
|
|
959
995
|
commentId: written.commentId,
|
|
960
996
|
text: written.text,
|
|
961
997
|
author: written.author,
|
|
998
|
+
authorUniqueName: written.authorUniqueName,
|
|
999
|
+
authorId: written.authorId,
|
|
962
1000
|
createdAt: written.createdAt,
|
|
963
1001
|
url: written.url
|
|
964
1002
|
};
|
|
@@ -2001,6 +2039,20 @@ function convertRichText(html, markdown) {
|
|
|
2001
2039
|
if (!html) return "";
|
|
2002
2040
|
return markdown ? toMarkdown(html) : stripHtml(html);
|
|
2003
2041
|
}
|
|
2042
|
+
function toJsonDocument(workItem) {
|
|
2043
|
+
return {
|
|
2044
|
+
id: workItem.id,
|
|
2045
|
+
title: workItem.title,
|
|
2046
|
+
description: workItem.description ? toMarkdown(workItem.description) : "",
|
|
2047
|
+
state: workItem.state,
|
|
2048
|
+
tags: workItem.tags ?? [],
|
|
2049
|
+
assignedTo: workItem.assignedToIdentity ?? null,
|
|
2050
|
+
createdBy: workItem.createdBy ?? null,
|
|
2051
|
+
createdDate: workItem.createdDate ?? null,
|
|
2052
|
+
url: workItem.url,
|
|
2053
|
+
relations: workItem.relations ?? []
|
|
2054
|
+
};
|
|
2055
|
+
}
|
|
2004
2056
|
function formatMarkdownField(fieldLabel, value) {
|
|
2005
2057
|
if (value.includes("\n")) {
|
|
2006
2058
|
return `${fieldLabel}:
|
|
@@ -2078,13 +2130,17 @@ function formatWorkItem(workItem, short, markdown = false) {
|
|
|
2078
2130
|
}
|
|
2079
2131
|
function createGetItemCommand() {
|
|
2080
2132
|
const command = new Command("get-item");
|
|
2081
|
-
command.description("Retrieve an Azure DevOps work item by ID").argument("<id>", "work item ID").option("--org <org>", "Azure DevOps organization").option("--project <project>", "Azure DevOps project").option("--short", "show abbreviated output").option("--fields <fields>", "comma-separated additional field reference names").option("--markdown", "convert rich text fields to markdown");
|
|
2133
|
+
command.description("Retrieve an Azure DevOps work item by ID").argument("<id>", "work item ID").option("--org <org>", "Azure DevOps organization").option("--project <project>", "Azure DevOps project").option("--short", "show abbreviated output").option("--fields <fields>", "comma-separated additional field reference names").option("--markdown", "convert rich text fields to markdown").option("--json", "output { id, title, description (markdown), state, tags, assignedTo, createdBy, createdDate, url, relations } (assignedTo/createdBy: { displayName, uniqueName, id }; relations include pull requests)");
|
|
2082
2134
|
addImageDownloadOptions(command);
|
|
2083
2135
|
command.action(
|
|
2084
2136
|
async (idStr, options) => {
|
|
2085
2137
|
const id = parseWorkItemId(idStr);
|
|
2086
2138
|
validateOrgProjectPair(options);
|
|
2087
2139
|
const imageOptions = resolveImageDownloadOptionsOrExit(options);
|
|
2140
|
+
if (options.json && (imageOptions.enabled || options.downloadImages || options.resizeImages !== void 0 || options.imagesPath !== void 0)) {
|
|
2141
|
+
process.stderr.write("Error: --json cannot be combined with image download options.\n");
|
|
2142
|
+
process.exit(1);
|
|
2143
|
+
}
|
|
2088
2144
|
let context;
|
|
2089
2145
|
try {
|
|
2090
2146
|
context = resolveContext(options);
|
|
@@ -2092,6 +2148,10 @@ function createGetItemCommand() {
|
|
|
2092
2148
|
const scopedCfg = resolveScopedConfig(context.org);
|
|
2093
2149
|
const fieldsList = options.fields === void 0 ? parseRequestedFields(scopedCfg.fields) : parseRequestedFields(options.fields);
|
|
2094
2150
|
const workItem = await getWorkItem(context, id, credential, fieldsList);
|
|
2151
|
+
if (options.json) {
|
|
2152
|
+
process.stdout.write(JSON.stringify(toJsonDocument(workItem)) + "\n");
|
|
2153
|
+
return;
|
|
2154
|
+
}
|
|
2095
2155
|
const markdownEnabled = options.markdown ?? scopedCfg.markdown ?? false;
|
|
2096
2156
|
const output = formatWorkItem(workItem, options.short ?? false, markdownEnabled);
|
|
2097
2157
|
process.stdout.write(output + "\n");
|
|
@@ -4021,6 +4081,8 @@ function mapComment(comment) {
|
|
|
4021
4081
|
return {
|
|
4022
4082
|
id: comment.id,
|
|
4023
4083
|
author: comment.author?.displayName ?? null,
|
|
4084
|
+
authorUniqueName: comment.author?.uniqueName ?? null,
|
|
4085
|
+
authorId: comment.author?.id ?? null,
|
|
4024
4086
|
content,
|
|
4025
4087
|
publishedAt: comment.publishedDate ?? null,
|
|
4026
4088
|
commentType: comment.commentType ?? null
|
|
@@ -4361,6 +4423,8 @@ async function updateThreadComment(context, repo, cred, prId, threadId, commentI
|
|
|
4361
4423
|
return {
|
|
4362
4424
|
id: data.id,
|
|
4363
4425
|
author: data.author?.displayName ?? null,
|
|
4426
|
+
authorUniqueName: data.author?.uniqueName ?? null,
|
|
4427
|
+
authorId: data.author?.id ?? null,
|
|
4364
4428
|
content: data.content ?? content,
|
|
4365
4429
|
publishedAt: data.publishedDate ?? null
|
|
4366
4430
|
};
|
|
@@ -4391,6 +4455,8 @@ async function postThreadComment(context, repo, cred, prId, threadId, content) {
|
|
|
4391
4455
|
return {
|
|
4392
4456
|
id: data.id,
|
|
4393
4457
|
author: data.author?.displayName ?? null,
|
|
4458
|
+
authorUniqueName: data.author?.uniqueName ?? null,
|
|
4459
|
+
authorId: data.author?.id ?? null,
|
|
4394
4460
|
content: data.content ?? content,
|
|
4395
4461
|
publishedAt: data.publishedDate ?? null
|
|
4396
4462
|
};
|