azdo-cli 0.5.0-025-multi-org-support.451 → 0.5.0-025-multi-org-support.455

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.
@@ -186,7 +186,7 @@ function setOrgScopedValue(org, key, value) {
186
186
  const updated = applyValueToScope(existing, key, value);
187
187
  saveConfig({
188
188
  ...config,
189
- organizations: { ...config.organizations ?? {}, [lc]: updated }
189
+ organizations: { ...config.organizations, [lc]: updated }
190
190
  });
191
191
  }
192
192
  function unsetOrgScopedValue(org, key) {
@@ -198,7 +198,7 @@ function unsetOrgScopedValue(org, key) {
198
198
  const { [key]: _, ...rest } = scope;
199
199
  saveConfig({
200
200
  ...config,
201
- organizations: { ...config.organizations ?? {}, [lc]: rest }
201
+ organizations: { ...config.organizations, [lc]: rest }
202
202
  });
203
203
  }
204
204
  function getOrgScopedValue(org, key) {
@@ -232,7 +232,7 @@ function copyOrgScope(from, to, force = false) {
232
232
  saveConfig({
233
233
  ...config,
234
234
  organizations: {
235
- ...config.organizations ?? {},
235
+ ...config.organizations,
236
236
  [toLc]: { ...dest, ...source }
237
237
  }
238
238
  });
@@ -988,7 +988,7 @@ async function deletePat(org) {
988
988
  }
989
989
  try {
990
990
  const { unlinkSync: unlinkSync2 } = await import("fs");
991
- const { lockPath: lockPath2 } = await import("./oauth-token-refresh-KOVYJAKC.js");
991
+ const { lockPath: lockPath2 } = await import("./oauth-token-refresh-7FQ4VAIS.js");
992
992
  unlinkSync2(lockPath2(org));
993
993
  } catch {
994
994
  }
package/dist/index.js CHANGED
@@ -35,7 +35,7 @@ import {
35
35
  tokenResponseToCredential,
36
36
  unsetConfigValue,
37
37
  unsetOrgScopedValue
38
- } from "./chunk-ISUEWHFA.js";
38
+ } from "./chunk-XVXMDWQE.js";
39
39
 
40
40
  // src/index.ts
41
41
  import { Command as Command16 } from "commander";
@@ -264,49 +264,53 @@ async function getOrgFieldNames(context, cred) {
264
264
  const data = await response.json();
265
265
  return (data.value ?? []).map((f) => f.referenceName);
266
266
  }
267
+ function buildCombinedDescription(fields) {
268
+ const parts = [];
269
+ if (fields["System.Description"]) {
270
+ parts.push({ label: "Description", value: fields["System.Description"] });
271
+ }
272
+ if (fields["Microsoft.VSTS.Common.AcceptanceCriteria"]) {
273
+ parts.push({ label: "Acceptance Criteria", value: fields["Microsoft.VSTS.Common.AcceptanceCriteria"] });
274
+ }
275
+ if (fields["Microsoft.VSTS.TCM.ReproSteps"]) {
276
+ parts.push({ label: "Repro Steps", value: fields["Microsoft.VSTS.TCM.ReproSteps"] });
277
+ }
278
+ if (parts.length === 0) return null;
279
+ if (parts.length === 1) return parts[0].value;
280
+ return parts.map((p) => `<h3>${p.label}</h3>${p.value}`).join("");
281
+ }
282
+ async function fetchWorkItemWithFallback(context, id, cred, normalizedExtraFields) {
283
+ try {
284
+ const data = await fetchWorkItemResponse(context, id, cred, {
285
+ fields: normalizeFieldList([...DEFAULT_FIELDS, ...normalizedExtraFields])
286
+ });
287
+ return { data, effectiveExtraFields: normalizedExtraFields };
288
+ } catch (err) {
289
+ const msg = err instanceof Error ? err.message : String(err);
290
+ if (!msg.includes("TF51535")) throw err;
291
+ const orgFields = new Set(await getOrgFieldNames(context, cred));
292
+ const missing = normalizedExtraFields.filter((f) => !orgFields.has(f));
293
+ const effectiveExtraFields = normalizedExtraFields.filter((f) => orgFields.has(f));
294
+ for (const f of missing) {
295
+ process.stderr.write(`Warning: field "${f}" does not exist in this org and will be skipped.
296
+ `);
297
+ }
298
+ const data = await fetchWorkItemResponse(context, id, cred, {
299
+ fields: normalizeFieldList([...DEFAULT_FIELDS, ...effectiveExtraFields])
300
+ });
301
+ return { data, effectiveExtraFields };
302
+ }
303
+ }
267
304
  async function getWorkItem(context, id, cred, extraFields) {
268
305
  const normalizedExtraFields = extraFields ? normalizeFieldList(extraFields) : [];
269
306
  let effectiveExtraFields = normalizedExtraFields;
270
307
  let data;
271
308
  if (normalizedExtraFields.length > 0) {
272
- try {
273
- data = await fetchWorkItemResponse(context, id, cred, {
274
- fields: normalizeFieldList([...DEFAULT_FIELDS, ...normalizedExtraFields])
275
- });
276
- } catch (err) {
277
- const msg = err instanceof Error ? err.message : String(err);
278
- if (!msg.includes("TF51535")) throw err;
279
- const orgFields = new Set(await getOrgFieldNames(context, cred));
280
- const missing = normalizedExtraFields.filter((f) => !orgFields.has(f));
281
- effectiveExtraFields = normalizedExtraFields.filter((f) => orgFields.has(f));
282
- for (const f of missing) {
283
- process.stderr.write(`Warning: field "${f}" does not exist in this org and will be skipped.
284
- `);
285
- }
286
- data = await fetchWorkItemResponse(context, id, cred, {
287
- fields: normalizeFieldList([...DEFAULT_FIELDS, ...effectiveExtraFields])
288
- });
289
- }
309
+ ({ data, effectiveExtraFields } = await fetchWorkItemWithFallback(context, id, cred, normalizedExtraFields));
290
310
  } else {
291
311
  data = await fetchWorkItemResponse(context, id, cred, { includeRelations: true });
292
312
  }
293
313
  const relationsData = normalizedExtraFields.length > 0 ? await fetchWorkItemResponse(context, id, cred, { includeRelations: true }) : data;
294
- const descriptionParts = [];
295
- if (data.fields["System.Description"]) {
296
- descriptionParts.push({ label: "Description", value: data.fields["System.Description"] });
297
- }
298
- if (data.fields["Microsoft.VSTS.Common.AcceptanceCriteria"]) {
299
- descriptionParts.push({ label: "Acceptance Criteria", value: data.fields["Microsoft.VSTS.Common.AcceptanceCriteria"] });
300
- }
301
- if (data.fields["Microsoft.VSTS.TCM.ReproSteps"]) {
302
- descriptionParts.push({ label: "Repro Steps", value: data.fields["Microsoft.VSTS.TCM.ReproSteps"] });
303
- }
304
- let combinedDescription = null;
305
- if (descriptionParts.length === 1) {
306
- combinedDescription = descriptionParts.at(0)?.value ?? null;
307
- } else if (descriptionParts.length > 1) {
308
- combinedDescription = descriptionParts.map((p) => `<h3>${p.label}</h3>${p.value}`).join("");
309
- }
310
314
  return {
311
315
  id: data.id,
312
316
  rev: data.rev,
@@ -314,7 +318,7 @@ async function getWorkItem(context, id, cred, extraFields) {
314
318
  state: data.fields["System.State"],
315
319
  type: data.fields["System.WorkItemType"],
316
320
  assignedTo: data.fields["System.AssignedTo"]?.displayName ?? null,
317
- description: combinedDescription,
321
+ description: buildCombinedDescription(data.fields),
318
322
  areaPath: data.fields["System.AreaPath"],
319
323
  iterationPath: data.fields["System.IterationPath"],
320
324
  url: data._links.html.href,
@@ -840,33 +844,39 @@ var patterns = [
840
844
  /^[^@]+@vs-ssh\.visualstudio\.com:v3\/([^/]+)\/([^/]+)\/([^/]+?)(?:\.git)?$/
841
845
  ];
842
846
  var httpsEmbeddedSecret = /^https?:\/\/[^:@/]+:[^@/]+@/;
847
+ function parseSingleRemoteLine(line) {
848
+ const trimmed = line.trim();
849
+ if (!trimmed) return null;
850
+ const tabIdx = trimmed.indexOf(" ");
851
+ if (tabIdx === -1) return null;
852
+ const remoteName = trimmed.slice(0, tabIdx);
853
+ const afterTab = trimmed.slice(tabIdx + 1);
854
+ const urlEnd = afterTab.lastIndexOf(" (");
855
+ const url = urlEnd === -1 ? afterTab : afterTab.slice(0, urlEnd);
856
+ return { remoteName, url };
857
+ }
858
+ function matchAzdoRemote(remoteName, url) {
859
+ for (const pattern of patterns) {
860
+ const match = pattern.exec(url);
861
+ if (!match) continue;
862
+ const project = match[2];
863
+ if (/^DefaultCollection$/i.test(project)) return null;
864
+ return { remoteName, org: match[1], project, hasEmbeddedSecret: httpsEmbeddedSecret.test(url) };
865
+ }
866
+ return null;
867
+ }
843
868
  function parseAllAzdoRemotes(output) {
844
869
  const seen = /* @__PURE__ */ new Set();
845
870
  const results = [];
846
871
  for (const line of output.split("\n")) {
847
- const trimmed = line.trim();
848
- if (!trimmed) continue;
849
- const tabIdx = trimmed.indexOf(" ");
850
- if (tabIdx === -1) continue;
851
- const remoteName = trimmed.slice(0, tabIdx);
872
+ const parsed = parseSingleRemoteLine(line);
873
+ if (!parsed) continue;
874
+ const { remoteName, url } = parsed;
852
875
  if (seen.has(remoteName)) continue;
853
- const afterTab = trimmed.slice(tabIdx + 1);
854
- const urlEnd = afterTab.lastIndexOf(" (");
855
- const url = urlEnd !== -1 ? afterTab.slice(0, urlEnd) : afterTab;
856
- for (const pattern of patterns) {
857
- const match = pattern.exec(url);
858
- if (match) {
859
- const project = match[2];
860
- if (/^DefaultCollection$/i.test(project)) break;
861
- seen.add(remoteName);
862
- results.push({
863
- remoteName,
864
- org: match[1],
865
- project,
866
- hasEmbeddedSecret: httpsEmbeddedSecret.test(url)
867
- });
868
- break;
869
- }
876
+ const candidate = matchAzdoRemote(remoteName, url);
877
+ if (candidate) {
878
+ seen.add(remoteName);
879
+ results.push(candidate);
870
880
  }
871
881
  }
872
882
  return results;
@@ -925,7 +935,7 @@ function gitConfigToRemoteLines(configContent) {
925
935
  emittedUrl = false;
926
936
  continue;
927
937
  }
928
- if (/^\[/.test(line)) {
938
+ if (line.startsWith("[")) {
929
939
  currentRemote = null;
930
940
  emittedUrl = false;
931
941
  continue;
@@ -5,7 +5,7 @@ import {
5
5
  lockPath,
6
6
  locksDir,
7
7
  refreshIfNeeded
8
- } from "./chunk-ISUEWHFA.js";
8
+ } from "./chunk-XVXMDWQE.js";
9
9
  export {
10
10
  _resetInFlight,
11
11
  classifyRefreshFailure,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "azdo-cli",
3
- "version": "0.5.0-025-multi-org-support.451",
3
+ "version": "0.5.0-025-multi-org-support.455",
4
4
  "description": "Azure DevOps CLI tool",
5
5
  "type": "module",
6
6
  "bin": {