azdo-cli 0.22.0-develop.868 → 0.22.0-develop.875

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",
@@ -809,6 +812,30 @@ async function getOrgFieldNames(context, cred) {
809
812
  const data = await response.json();
810
813
  return (data.value ?? []).map((f) => f.referenceName);
811
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
+ }
812
839
  function buildCombinedDescription(fields) {
813
840
  const parts = [];
814
841
  if (fields["System.Description"]) {
@@ -864,6 +891,11 @@ async function getWorkItem(context, id, cred, extraFields) {
864
891
  state: data.fields["System.State"],
865
892
  type: data.fields["System.WorkItemType"],
866
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),
867
899
  description: buildCombinedDescription(data.fields),
868
900
  areaPath: data.fields["System.AreaPath"],
869
901
  iterationPath: data.fields["System.IterationPath"],
@@ -2007,6 +2039,20 @@ function convertRichText(html, markdown) {
2007
2039
  if (!html) return "";
2008
2040
  return markdown ? toMarkdown(html) : stripHtml(html);
2009
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
+ }
2010
2056
  function formatMarkdownField(fieldLabel, value) {
2011
2057
  if (value.includes("\n")) {
2012
2058
  return `${fieldLabel}:
@@ -2084,13 +2130,17 @@ function formatWorkItem(workItem, short, markdown = false) {
2084
2130
  }
2085
2131
  function createGetItemCommand() {
2086
2132
  const command = new Command("get-item");
2087
- 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)");
2088
2134
  addImageDownloadOptions(command);
2089
2135
  command.action(
2090
2136
  async (idStr, options) => {
2091
2137
  const id = parseWorkItemId(idStr);
2092
2138
  validateOrgProjectPair(options);
2093
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
+ }
2094
2144
  let context;
2095
2145
  try {
2096
2146
  context = resolveContext(options);
@@ -2098,6 +2148,10 @@ function createGetItemCommand() {
2098
2148
  const scopedCfg = resolveScopedConfig(context.org);
2099
2149
  const fieldsList = options.fields === void 0 ? parseRequestedFields(scopedCfg.fields) : parseRequestedFields(options.fields);
2100
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
+ }
2101
2155
  const markdownEnabled = options.markdown ?? scopedCfg.markdown ?? false;
2102
2156
  const output = formatWorkItem(workItem, options.short ?? false, markdownEnabled);
2103
2157
  process.stdout.write(output + "\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "azdo-cli",
3
- "version": "0.22.0-develop.868",
3
+ "version": "0.22.0-develop.875",
4
4
  "description": "Azure DevOps CLI tool",
5
5
  "type": "module",
6
6
  "bin": {