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 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
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "azdo-cli",
3
- "version": "0.22.0-develop.853",
3
+ "version": "0.22.0-develop.874",
4
4
  "description": "Azure DevOps CLI tool",
5
5
  "type": "module",
6
6
  "bin": {