@@ -4,6 +4,31 @@ const API_VERSION = "7.1"
44const FETCH_MAX_ATTEMPTS = 3
55const FETCH_RETRY_DELAY_MS = 1000
66
7+ const DEFAULT_COLLECTION_URL = "https://dev.azure.com"
8+
9+ function isCloudCollectionUrl ( collectionUrl : string ) : boolean {
10+ return collectionUrl . includes ( "dev.azure.com" ) || collectionUrl . includes ( "visualstudio.com" )
11+ }
12+
13+ function buildApiUrl (
14+ collectionUrl : string | undefined ,
15+ organization : string ,
16+ project : string ,
17+ path : string
18+ ) : string {
19+ const base = collectionUrl || DEFAULT_COLLECTION_URL
20+
21+ // For on-prem Azure DevOps Server (both old /tfs/ and new format),
22+ // the collection is already in the base URL
23+ // e.g., http://server:8080/tfs/Collection or http://server:8080/Collection
24+ if ( ! isCloudCollectionUrl ( base ) ) {
25+ return `${ base } /${ project } /${ path } `
26+ }
27+
28+ // For cloud Azure DevOps Services
29+ return `${ base } /${ organization } /${ project } /${ path } `
30+ }
31+
732function isRetryableStatus ( status : number ) : boolean {
833 return status === 408 || status === 429 || status >= 500
934}
@@ -198,7 +223,7 @@ export async function getPullRequest(
198223 project : string ,
199224 pullRequestId : number ,
200225 personalAccessToken : string ,
201- options ?: GetPullRequestOptions
226+ options ?: GetPullRequestOptions & { collectionUrl ?: string }
202227) : Promise < PullRequest > {
203228 const queryParams = new URLSearchParams ( {
204229 "api-version" : API_VERSION ,
@@ -208,7 +233,12 @@ export async function getPullRequest(
208233 queryParams . set ( "includeCommits" , "true" )
209234 }
210235
211- const url = `https://dev.azure.com/${ organization } /${ project } /_apis/git/pullrequests/${ pullRequestId } ?${ queryParams . toString ( ) } `
236+ const url = buildApiUrl (
237+ options ?. collectionUrl ,
238+ organization ,
239+ project ,
240+ `_apis/git/pullrequests/${ pullRequestId } ?${ queryParams . toString ( ) } `
241+ )
212242 return makeRequest < PullRequest > ( url , { method : "GET" } , personalAccessToken )
213243}
214244
@@ -220,7 +250,7 @@ export async function createPullRequest(
220250 sourceRefName : string ,
221251 targetRefName : string ,
222252 title : string ,
223- options ?: CreatePullRequestOptions
253+ options ?: CreatePullRequestOptions & { collectionUrl ?: string }
224254) : Promise < PullRequest > {
225255 const queryParams = new URLSearchParams ( {
226256 "api-version" : API_VERSION ,
@@ -230,7 +260,12 @@ export async function createPullRequest(
230260 queryParams . set ( "supportsIterations" , String ( options . supportsIterations ) )
231261 }
232262
233- const url = `https://dev.azure.com/${ organization } /${ project } /_apis/git/repositories/${ repositoryId } /pullrequests?${ queryParams . toString ( ) } `
263+ const url = buildApiUrl (
264+ options ?. collectionUrl ,
265+ organization ,
266+ project ,
267+ `_apis/git/repositories/${ repositoryId } /pullrequests?${ queryParams . toString ( ) } `
268+ )
234269
235270 const body = {
236271 sourceRefName,
@@ -255,7 +290,8 @@ export async function listPullRequests(
255290 project : string ,
256291 personalAccessToken : string ,
257292 repositoryId ?: string ,
258- searchCriteria ?: SearchPullRequestsCriteria
293+ searchCriteria ?: SearchPullRequestsCriteria ,
294+ collectionUrl ?: string
259295) : Promise < { value : PullRequest [ ] ; count : number } > {
260296 const queryParams = new URLSearchParams ( {
261297 "api-version" : API_VERSION ,
@@ -285,7 +321,12 @@ export async function listPullRequests(
285321 queryParams . set ( "searchCriteria.repositoryId" , repositoryId )
286322 }
287323
288- const url = `https://dev.azure.com/${ organization } /${ project } /_apis/git/repositories/${ repositoryId || "" } /pullrequests?${ queryParams . toString ( ) } `
324+ const url = buildApiUrl (
325+ collectionUrl ,
326+ organization ,
327+ project ,
328+ `_apis/git/repositories/${ repositoryId || "" } /pullrequests?${ queryParams . toString ( ) } `
329+ )
289330 return makeRequest < { value : PullRequest [ ] ; count : number } > (
290331 url ,
291332 { method : "GET" } ,
@@ -300,9 +341,14 @@ export async function createPullRequestThread(
300341 pullRequestId : number ,
301342 personalAccessToken : string ,
302343 content : string ,
303- options ?: CreateThreadOptions
344+ options ?: CreateThreadOptions & { collectionUrl ?: string }
304345) : Promise < PullRequestThread > {
305- const url = `https://dev.azure.com/${ organization } /${ project } /_apis/git/repositories/${ repositoryId } /pullRequests/${ pullRequestId } /threads?api-version=${ API_VERSION } `
346+ const url = buildApiUrl (
347+ options ?. collectionUrl ,
348+ organization ,
349+ project ,
350+ `_apis/git/repositories/${ repositoryId } /pullRequests/${ pullRequestId } /threads?api-version=${ API_VERSION } `
351+ )
306352
307353 const body : ThreadRequestBody = {
308354 comments : [
@@ -353,9 +399,15 @@ export async function addPullRequestComment(
353399 threadId : number ,
354400 personalAccessToken : string ,
355401 content : string ,
356- parentCommentId ?: number
402+ parentCommentId ?: number ,
403+ collectionUrl ?: string
357404) : Promise < Comment > {
358- const url = `https://dev.azure.com/${ organization } /${ project } /_apis/git/repositories/${ repositoryId } /pullRequests/${ pullRequestId } /threads/${ threadId } /comments?api-version=${ API_VERSION } `
405+ const url = buildApiUrl (
406+ collectionUrl ,
407+ organization ,
408+ project ,
409+ `_apis/git/repositories/${ repositoryId } /pullRequests/${ pullRequestId } /threads/${ threadId } /comments?api-version=${ API_VERSION } `
410+ )
359411
360412 const body = {
361413 content,
@@ -381,9 +433,15 @@ export async function editPullRequestComment(
381433 threadId : number ,
382434 commentId : number ,
383435 personalAccessToken : string ,
384- content : string
436+ content : string ,
437+ collectionUrl ?: string
385438) : Promise < Comment > {
386- const url = `https://dev.azure.com/${ organization } /${ project } /_apis/git/repositories/${ repositoryId } /pullRequests/${ pullRequestId } /threads/${ threadId } /comments/${ commentId } ?api-version=${ API_VERSION } `
439+ const url = buildApiUrl (
440+ collectionUrl ,
441+ organization ,
442+ project ,
443+ `_apis/git/repositories/${ repositoryId } /pullRequests/${ pullRequestId } /threads/${ threadId } /comments/${ commentId } ?api-version=${ API_VERSION } `
444+ )
387445
388446 return makeRequest < Comment > (
389447 url ,
@@ -400,9 +458,15 @@ export async function getPullRequestThreads(
400458 project : string ,
401459 repositoryId : string ,
402460 pullRequestId : number ,
403- personalAccessToken : string
461+ personalAccessToken : string ,
462+ collectionUrl ?: string
404463) : Promise < { value : PullRequestThread [ ] ; count : number } > {
405- const url = `https://dev.azure.com/${ organization } /${ project } /_apis/git/repositories/${ repositoryId } /pullRequests/${ pullRequestId } /threads?api-version=${ API_VERSION } `
464+ const url = buildApiUrl (
465+ collectionUrl ,
466+ organization ,
467+ project ,
468+ `_apis/git/repositories/${ repositoryId } /pullRequests/${ pullRequestId } /threads?api-version=${ API_VERSION } `
469+ )
406470 return makeRequest < { value : PullRequestThread [ ] ; count : number } > (
407471 url ,
408472 { method : "GET" } ,
@@ -416,9 +480,15 @@ export async function getPullRequestThread(
416480 repositoryId : string ,
417481 pullRequestId : number ,
418482 threadId : number ,
419- personalAccessToken : string
483+ personalAccessToken : string ,
484+ collectionUrl ?: string
420485) : Promise < PullRequestThread > {
421- const url = `https://dev.azure.com/${ organization } /${ project } /_apis/git/repositories/${ repositoryId } /pullRequests/${ pullRequestId } /threads/${ threadId } ?api-version=${ API_VERSION } `
486+ const url = buildApiUrl (
487+ collectionUrl ,
488+ organization ,
489+ project ,
490+ `_apis/git/repositories/${ repositoryId } /pullRequests/${ pullRequestId } /threads/${ threadId } ?api-version=${ API_VERSION } `
491+ )
422492 return makeRequest < PullRequestThread > ( url , { method : "GET" } , personalAccessToken )
423493}
424494
@@ -427,9 +497,15 @@ export async function getPullRequestCommits(
427497 project : string ,
428498 repositoryId : string ,
429499 pullRequestId : number ,
430- personalAccessToken : string
500+ personalAccessToken : string ,
501+ collectionUrl ?: string
431502) : Promise < GitCommitRef [ ] > {
432- const url = `https://dev.azure.com/${ organization } /${ project } /_apis/git/repositories/${ repositoryId } /pullRequests/${ pullRequestId } /commits?api-version=${ API_VERSION } `
503+ const url = buildApiUrl (
504+ collectionUrl ,
505+ organization ,
506+ project ,
507+ `_apis/git/repositories/${ repositoryId } /pullRequests/${ pullRequestId } /commits?api-version=${ API_VERSION } `
508+ )
433509 return makeRequest < GitCommitRef [ ] > ( url , { method : "GET" } , personalAccessToken )
434510}
435511
@@ -439,9 +515,15 @@ export async function getPullRequestIterationChanges(
439515 repositoryId : string ,
440516 pullRequestId : number ,
441517 iterationId : number ,
442- personalAccessToken : string
518+ personalAccessToken : string ,
519+ collectionUrl ?: string
443520) : Promise < { changeEntries : GitPullRequestChange [ ] } > {
444- const url = `https://dev.azure.com/${ organization } /${ project } /_apis/git/repositories/${ repositoryId } /pullRequests/${ pullRequestId } /iterations/${ iterationId } /changes?api-version=${ API_VERSION } `
521+ const url = buildApiUrl (
522+ collectionUrl ,
523+ organization ,
524+ project ,
525+ `_apis/git/repositories/${ repositoryId } /pullRequests/${ pullRequestId } /iterations/${ iterationId } /changes?api-version=${ API_VERSION } `
526+ )
445527 return makeRequest < { changeEntries : GitPullRequestChange [ ] } > (
446528 url ,
447529 { method : "GET" } ,
@@ -454,9 +536,15 @@ export async function getPullRequestIterations(
454536 project : string ,
455537 repositoryId : string ,
456538 pullRequestId : number ,
457- personalAccessToken : string
539+ personalAccessToken : string ,
540+ collectionUrl ?: string
458541) : Promise < { value : Array < { id : number ; description : string } > ; count : number } > {
459- const url = `https://dev.azure.com/${ organization } /${ project } /_apis/git/repositories/${ repositoryId } /pullRequests/${ pullRequestId } /iterations?api-version=${ API_VERSION } `
542+ const url = buildApiUrl (
543+ collectionUrl ,
544+ organization ,
545+ project ,
546+ `_apis/git/repositories/${ repositoryId } /pullRequests/${ pullRequestId } /iterations?api-version=${ API_VERSION } `
547+ )
460548 return makeRequest < { value : Array < { id : number ; description : string } > ; count : number } > (
461549 url ,
462550 { method : "GET" } ,
0 commit comments