@achieveai/azuredevops-mcp 1.2.1 → 1.2.2
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/dist/Interfaces/Pipelines.js +3 -0
- package/dist/Interfaces/Pipelines.js.map +1 -0
- package/dist/Interfaces/Wiki.js +3 -0
- package/dist/Interfaces/Wiki.js.map +1 -0
- package/dist/Services/AzureDevOpsService.js +6 -5
- package/dist/Services/AzureDevOpsService.js.map +1 -1
- package/dist/Services/BuildService.js +172 -0
- package/dist/Services/BuildService.js.map +1 -0
- package/dist/Services/EntraAuthHandler.js +65 -18
- package/dist/Services/EntraAuthHandler.js.map +1 -1
- package/dist/Services/GitService.js +129 -0
- package/dist/Services/GitService.js.map +1 -1
- package/dist/Services/WikiService.js +90 -0
- package/dist/Services/WikiService.js.map +1 -0
- package/dist/Services/WorkItemService.js +123 -0
- package/dist/Services/WorkItemService.js.map +1 -1
- package/dist/Tools/BuildTools.js +402 -0
- package/dist/Tools/BuildTools.js.map +1 -0
- package/dist/Tools/GitTools.js +187 -41
- package/dist/Tools/GitTools.js.map +1 -1
- package/dist/Tools/WikiTools.js +137 -0
- package/dist/Tools/WikiTools.js.map +1 -0
- package/dist/Tools/WorkItemTools.js +120 -0
- package/dist/Tools/WorkItemTools.js.map +1 -1
- package/dist/config.js +27 -10
- package/dist/config.js.map +1 -1
- package/dist/index.js +297 -64
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pipelines.js","sourceRoot":"","sources":["../../src/Interfaces/Pipelines.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Wiki.js","sourceRoot":"","sources":["../../src/Interfaces/Wiki.ts"],"names":[],"mappings":""}
|
|
@@ -40,14 +40,15 @@ class AzureDevOpsService {
|
|
|
40
40
|
constructor(config) {
|
|
41
41
|
this.config = config;
|
|
42
42
|
// Get the appropriate authentication handler
|
|
43
|
-
|
|
43
|
+
const tokenCredentialAuthTypes = ["entra", "azcli", "interactive"];
|
|
44
|
+
if (config.auth?.type && tokenCredentialAuthTypes.includes(config.auth.type)) {
|
|
44
45
|
if (config.isOnPremises) {
|
|
45
|
-
throw new Error(
|
|
46
|
+
throw new Error(`${config.auth.type} authentication is not supported for on-premises Azure DevOps.`);
|
|
46
47
|
}
|
|
47
|
-
if (!config.
|
|
48
|
-
throw new Error(
|
|
48
|
+
if (!config.tokenCredentialAuthHandler) {
|
|
49
|
+
throw new Error(`${config.auth.type} authentication requires a pre-initialized token credential auth handler.`);
|
|
49
50
|
}
|
|
50
|
-
this.authHandler = config.
|
|
51
|
+
this.authHandler = config.tokenCredentialAuthHandler;
|
|
51
52
|
}
|
|
52
53
|
else if (config.isOnPremises && config.auth) {
|
|
53
54
|
switch (config.auth.type) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AzureDevOpsService.js","sourceRoot":"","sources":["../../src/Services/AzureDevOpsService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6DAA+C;AAM/C,yDAIsC;AAMtC,MAAa,kBAAkB;IAK7B,YAAY,MAAyB;QACnC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,6CAA6C;QAE7C,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"AzureDevOpsService.js","sourceRoot":"","sources":["../../src/Services/AzureDevOpsService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6DAA+C;AAM/C,yDAIsC;AAMtC,MAAa,kBAAkB;IAK7B,YAAY,MAAyB;QACnC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,6CAA6C;QAE7C,MAAM,wBAAwB,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;QACnE,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,IAAI,wBAAwB,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7E,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,gEAAgE,CACpF,CAAC;YACJ,CAAC;YACD,IAAG,CAAC,MAAM,CAAC,0BAA0B,EAAE,CAAC;gBACtC,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,2EAA2E,CAC/F,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,0BAA0B,CAAC;QACvD,CAAC;aAAM,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAC9C,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACzB,KAAK,MAAM;oBACT,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACnD,MAAM,IAAI,KAAK,CACb,oDAAoD,CACrD,CAAC;oBACJ,CAAC;oBACD,IAAI,CAAC,WAAW,GAAG,IAAA,uBAAc,EAC/B,MAAM,CAAC,IAAI,CAAC,QAAQ,EACpB,MAAM,CAAC,IAAI,CAAC,QAAQ,EACpB,MAAM,CAAC,IAAI,CAAC,MAAM,CACnB,CAAC;oBACF,MAAM;gBACR,KAAK,OAAO;oBACV,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACnD,MAAM,IAAI,KAAK,CACb,qDAAqD,CACtD,CAAC;oBACJ,CAAC;oBACD,IAAI,CAAC,WAAW,GAAG,IAAA,wBAAe,EAChC,MAAM,CAAC,IAAI,CAAC,QAAQ,EACpB,MAAM,CAAC,IAAI,CAAC,QAAQ,CACrB,CAAC;oBACF,MAAM;gBACR,KAAK,KAAK,CAAC;gBACX,SAAS,yEAAyE;oBAChF,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC;wBAChC,MAAM,IAAI,KAAK,CACb,kGAAkG,CACnG,CAAC;oBACJ,CAAC;oBACD,IAAI,CAAC,WAAW,GAAG,IAAA,sCAA6B,EAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;YACjF,CAAC;QACH,CAAC;aAAM,CAAC;YACN,qCAAqC;YACrC,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;gBAChD,kEAAkE;gBAClE,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC;oBAChC,MAAM,IAAI,KAAK,CACb,oGAAoG,CACrG,CAAC;gBACJ,CAAC;gBACD,IAAI,CAAC,WAAW,GAAG,IAAA,sCAA6B,EAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;YAC/E,CAAC;iBAAM,CAAC;gBACN,2EAA2E;gBAC3E,MAAM,IAAI,KAAK,CACb,oCAAoC,MAAM,CAAC,IAAI,EAAE,IAAI,2BAA2B,CACjF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,sDAAsD;QACtD,IAAI,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YAC7C,gEAAgE;YAChE,OAAO,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACpD,CAAC;QAED,gCAAgC;QAChC,MAAM,cAAc,GAAsC,EAAE,CAAC;QAE7D,kFAAkF;QAClF,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YAC7C,cAAc,CAAC,OAAO,GAAG;gBACvB,MAAM,EAAE,gCAAgC,MAAM,CAAC,UAAU,EAAE;aAC5D,CAAC;QACJ,CAAC;QAED,6BAA6B;QAC7B,6FAA6F;QAC7F,IAAI,CAAC,UAAU,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAChF,CAAC;IAED;;OAEG;IACO,KAAK,CAAC,sBAAsB;QACpC,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,sBAAsB,EAAE,CAAC;IACxD,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,aAAa,CAAC,SAAiB;QAC1C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAEnD,yBAAyB;YACzB,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,WAAW,CAC1C;gBACE,KAAK,EAAE,SAAS;aACjB,EACD;gBACE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;aAC7B,CACF,CAAC;YAEF,wBAAwB;YACxB,OAAO;gBACL,SAAS,EAAE,WAAW,CAAC,SAAS,IAAI,EAAE;gBACtC,KAAK,EAAE,WAAW,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC;aAC1C,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;YAClD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF;AAnID,gDAmIC"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BuildService = void 0;
|
|
4
|
+
const BuildInterfaces_1 = require("azure-devops-node-api/interfaces/BuildInterfaces");
|
|
5
|
+
const AzureDevOpsService_1 = require("./AzureDevOpsService");
|
|
6
|
+
class BuildService extends AzureDevOpsService_1.AzureDevOpsService {
|
|
7
|
+
constructor(config) {
|
|
8
|
+
super(config);
|
|
9
|
+
}
|
|
10
|
+
async getBuildApi() {
|
|
11
|
+
return await this.connection.getBuildApi();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* List builds with optional filters.
|
|
15
|
+
*/
|
|
16
|
+
async getBuilds(params) {
|
|
17
|
+
const buildApi = await this.getBuildApi();
|
|
18
|
+
const project = params.project || this.config.project;
|
|
19
|
+
const statusFilter = params.statusFilter ? this.parseBuildStatus(params.statusFilter) : undefined;
|
|
20
|
+
const resultFilter = params.resultFilter ? this.parseBuildResult(params.resultFilter) : undefined;
|
|
21
|
+
const queryOrder = params.queryOrder === 'startTimeAscending'
|
|
22
|
+
? BuildInterfaces_1.BuildQueryOrder.StartTimeAscending
|
|
23
|
+
: BuildInterfaces_1.BuildQueryOrder.StartTimeDescending;
|
|
24
|
+
const builds = await buildApi.getBuilds(project, params.definitions, // definitions
|
|
25
|
+
undefined, // queues
|
|
26
|
+
undefined, // buildNumber
|
|
27
|
+
undefined, // minTime
|
|
28
|
+
undefined, // maxTime
|
|
29
|
+
params.requestedFor, // requestedFor
|
|
30
|
+
undefined, // reasonFilter
|
|
31
|
+
statusFilter, // statusFilter
|
|
32
|
+
resultFilter, // resultFilter
|
|
33
|
+
params.tagFilters, // tagFilters
|
|
34
|
+
undefined, // properties
|
|
35
|
+
params.top || 25, // top
|
|
36
|
+
undefined, // continuationToken
|
|
37
|
+
undefined, // maxBuildsPerDefinition
|
|
38
|
+
undefined, // deletedFilter
|
|
39
|
+
queryOrder, // queryOrder
|
|
40
|
+
params.branchName, // branchName
|
|
41
|
+
undefined, // buildIds
|
|
42
|
+
params.repositoryId, // repositoryId
|
|
43
|
+
params.repositoryType);
|
|
44
|
+
return builds || [];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get a single build by ID.
|
|
48
|
+
*/
|
|
49
|
+
async getBuild(params) {
|
|
50
|
+
const buildApi = await this.getBuildApi();
|
|
51
|
+
const project = params.project || this.config.project;
|
|
52
|
+
return await buildApi.getBuild(project, params.buildId);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get build logs. If logId is provided, returns specific log lines; otherwise returns log metadata list.
|
|
56
|
+
*/
|
|
57
|
+
async getBuildLogs(params) {
|
|
58
|
+
const buildApi = await this.getBuildApi();
|
|
59
|
+
const project = params.project || this.config.project;
|
|
60
|
+
if (params.logId !== undefined) {
|
|
61
|
+
// Get specific log lines
|
|
62
|
+
const lines = await buildApi.getBuildLogLines(project, params.buildId, params.logId, params.startLine, params.endLine);
|
|
63
|
+
return { logId: params.logId, lines: lines || [] };
|
|
64
|
+
}
|
|
65
|
+
// Get all log metadata
|
|
66
|
+
const logs = await buildApi.getBuildLogs(project, params.buildId);
|
|
67
|
+
return logs || [];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get changes (commits) associated with a build.
|
|
71
|
+
*/
|
|
72
|
+
async getBuildChanges(params) {
|
|
73
|
+
const buildApi = await this.getBuildApi();
|
|
74
|
+
const project = params.project || this.config.project;
|
|
75
|
+
const changes = await buildApi.getBuildChanges(project, params.buildId, undefined, // continuationToken
|
|
76
|
+
params.top || 50);
|
|
77
|
+
return changes || [];
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* List build/pipeline definitions.
|
|
81
|
+
*/
|
|
82
|
+
async getDefinitions(params) {
|
|
83
|
+
const buildApi = await this.getBuildApi();
|
|
84
|
+
const project = params.project || this.config.project;
|
|
85
|
+
const definitions = await buildApi.getDefinitions(project, params.name, // name filter
|
|
86
|
+
params.repositoryId, // repositoryId
|
|
87
|
+
params.repositoryType, // repositoryType
|
|
88
|
+
undefined, // queryOrder
|
|
89
|
+
params.top || 25, // top
|
|
90
|
+
undefined, // continuationToken
|
|
91
|
+
undefined, // minMetricsTime
|
|
92
|
+
undefined, // definitionIds
|
|
93
|
+
params.path, // path
|
|
94
|
+
undefined, // builtAfter
|
|
95
|
+
undefined, // notBuiltAfter
|
|
96
|
+
undefined, // includeAllProperties
|
|
97
|
+
params.includeLatestBuilds);
|
|
98
|
+
return definitions || [];
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get a single build definition by ID.
|
|
102
|
+
*/
|
|
103
|
+
async getDefinition(params) {
|
|
104
|
+
const buildApi = await this.getBuildApi();
|
|
105
|
+
const project = params.project || this.config.project;
|
|
106
|
+
return await buildApi.getDefinition(project, params.definitionId, undefined, // revision
|
|
107
|
+
undefined, // minMetricsTime
|
|
108
|
+
undefined, // propertyFilters
|
|
109
|
+
params.includeLatestBuilds);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Queue/trigger a build run.
|
|
113
|
+
*/
|
|
114
|
+
async runPipeline(params) {
|
|
115
|
+
const buildApi = await this.getBuildApi();
|
|
116
|
+
const project = params.project || this.config.project;
|
|
117
|
+
const build = {
|
|
118
|
+
definition: { id: params.definitionId },
|
|
119
|
+
...(params.sourceBranch && { sourceBranch: params.sourceBranch }),
|
|
120
|
+
...(params.parameters && { parameters: JSON.stringify(params.parameters) }),
|
|
121
|
+
};
|
|
122
|
+
return await buildApi.queueBuild(build, project);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* List artifacts for a build.
|
|
126
|
+
*/
|
|
127
|
+
async getBuildArtifacts(params) {
|
|
128
|
+
const buildApi = await this.getBuildApi();
|
|
129
|
+
const project = params.project || this.config.project;
|
|
130
|
+
const artifacts = await buildApi.getArtifacts(project, params.buildId);
|
|
131
|
+
return artifacts || [];
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get build timeline (stages, jobs, tasks).
|
|
135
|
+
*/
|
|
136
|
+
async getBuildTimeline(params) {
|
|
137
|
+
const buildApi = await this.getBuildApi();
|
|
138
|
+
const project = params.project || this.config.project;
|
|
139
|
+
return await buildApi.getBuildTimeline(project, params.buildId);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get work items associated with a build.
|
|
143
|
+
*/
|
|
144
|
+
async getBuildWorkItems(params) {
|
|
145
|
+
const buildApi = await this.getBuildApi();
|
|
146
|
+
const project = params.project || this.config.project;
|
|
147
|
+
const refs = await buildApi.getBuildWorkItemsRefs(project, params.buildId, params.top || 50);
|
|
148
|
+
return refs || [];
|
|
149
|
+
}
|
|
150
|
+
parseBuildStatus(status) {
|
|
151
|
+
const map = {
|
|
152
|
+
'inprogress': BuildInterfaces_1.BuildStatus.InProgress,
|
|
153
|
+
'completed': BuildInterfaces_1.BuildStatus.Completed,
|
|
154
|
+
'cancelling': BuildInterfaces_1.BuildStatus.Cancelling,
|
|
155
|
+
'postponed': BuildInterfaces_1.BuildStatus.Postponed,
|
|
156
|
+
'notstarted': BuildInterfaces_1.BuildStatus.NotStarted,
|
|
157
|
+
'all': BuildInterfaces_1.BuildStatus.All,
|
|
158
|
+
};
|
|
159
|
+
return map[status.toLowerCase()];
|
|
160
|
+
}
|
|
161
|
+
parseBuildResult(result) {
|
|
162
|
+
const map = {
|
|
163
|
+
'succeeded': BuildInterfaces_1.BuildResult.Succeeded,
|
|
164
|
+
'partiallysucceeded': BuildInterfaces_1.BuildResult.PartiallySucceeded,
|
|
165
|
+
'failed': BuildInterfaces_1.BuildResult.Failed,
|
|
166
|
+
'canceled': BuildInterfaces_1.BuildResult.Canceled,
|
|
167
|
+
};
|
|
168
|
+
return map[result.toLowerCase()];
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
exports.BuildService = BuildService;
|
|
172
|
+
//# sourceMappingURL=BuildService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuildService.js","sourceRoot":"","sources":["../../src/Services/BuildService.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,29 +33,63 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.EntraAuthHandler = void 0;
|
|
36
|
+
exports.EntraAuthHandler = exports.TokenCredentialAuthHandler = void 0;
|
|
37
37
|
const identity_1 = require("@azure/identity");
|
|
38
38
|
const azdev = __importStar(require("azure-devops-node-api"));
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Azure DevOps scope for token requests.
|
|
41
|
+
*/
|
|
42
|
+
const AZURE_DEVOPS_SCOPE = "499b84ac-1321-427f-aa17-267ca6975798/.default";
|
|
43
|
+
/**
|
|
44
|
+
* Generic auth handler that wraps any @azure/identity TokenCredential.
|
|
45
|
+
* Supports automatic token refresh and re-authentication on 401.
|
|
46
|
+
*/
|
|
47
|
+
class TokenCredentialAuthHandler {
|
|
48
|
+
constructor(credential) {
|
|
49
|
+
this.credential = credential;
|
|
43
50
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Create handler from DefaultAzureCredential (Entra).
|
|
53
|
+
*/
|
|
54
|
+
static async createEntra() {
|
|
55
|
+
const handler = new TokenCredentialAuthHandler(new identity_1.DefaultAzureCredential());
|
|
56
|
+
await handler.ensureToken();
|
|
57
|
+
return handler;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Create handler from AzureCliCredential.
|
|
61
|
+
*/
|
|
62
|
+
static async createAzureCli(tenantId) {
|
|
63
|
+
const credential = new identity_1.AzureCliCredential(tenantId ? { tenantId } : undefined);
|
|
64
|
+
const handler = new TokenCredentialAuthHandler(credential);
|
|
65
|
+
await handler.ensureToken();
|
|
66
|
+
return handler;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Create handler from InteractiveBrowserCredential (MSAL).
|
|
70
|
+
* Opens a browser window for user login with token caching and silent re-auth.
|
|
71
|
+
*/
|
|
72
|
+
static async createInteractive(options) {
|
|
73
|
+
const credential = new identity_1.InteractiveBrowserCredential({
|
|
74
|
+
...(options?.tenantId && { tenantId: options.tenantId }),
|
|
75
|
+
...(options?.clientId && { clientId: options.clientId }),
|
|
76
|
+
redirectUri: "http://localhost",
|
|
77
|
+
});
|
|
78
|
+
const handler = new TokenCredentialAuthHandler(credential);
|
|
79
|
+
await handler.ensureToken();
|
|
80
|
+
return handler;
|
|
50
81
|
}
|
|
51
82
|
isTokenExpired() {
|
|
52
83
|
const currentTime = new Date().getTime();
|
|
53
|
-
// Check if the token is expired or will expire in the next 60 seconds
|
|
54
84
|
return this.token.expiresOnTimestamp <= currentTime + 60000;
|
|
55
85
|
}
|
|
56
86
|
async ensureToken() {
|
|
57
87
|
if (!this.token || this.isTokenExpired()) {
|
|
58
|
-
|
|
88
|
+
const token = await this.credential.getToken(AZURE_DEVOPS_SCOPE);
|
|
89
|
+
if (!token) {
|
|
90
|
+
throw new Error("Failed to acquire Azure DevOps access token.");
|
|
91
|
+
}
|
|
92
|
+
this.token = token;
|
|
59
93
|
this.authHandler = azdev.getHandlerFromToken(this.token.token);
|
|
60
94
|
}
|
|
61
95
|
}
|
|
@@ -63,16 +97,11 @@ class EntraAuthHandler {
|
|
|
63
97
|
if (this.authHandler) {
|
|
64
98
|
this.authHandler.prepareRequest(options);
|
|
65
99
|
}
|
|
66
|
-
// If no authHandler, the request will be sent unauthenticated.
|
|
67
|
-
// If it fails with 401, canHandleAuthentication and handleAuthentication will be invoked.
|
|
68
100
|
}
|
|
69
101
|
canHandleAuthentication(response) {
|
|
70
102
|
if (this.authHandler) {
|
|
71
103
|
return this.authHandler.canHandleAuthentication(response);
|
|
72
104
|
}
|
|
73
|
-
// If authHandler is not set, we can handle it if it's a 401 error
|
|
74
|
-
// typically handled by token-based authentication.
|
|
75
|
-
// This condition is standard in azure-devops-node-api handlers.
|
|
76
105
|
return response.message.statusCode === 401 &&
|
|
77
106
|
(response.message.statusMessage || "").toLowerCase().indexOf("non-authoritative") === -1;
|
|
78
107
|
}
|
|
@@ -81,5 +110,23 @@ class EntraAuthHandler {
|
|
|
81
110
|
return this.authHandler.handleAuthentication(httpClient, requestInfo, objs);
|
|
82
111
|
}
|
|
83
112
|
}
|
|
113
|
+
exports.TokenCredentialAuthHandler = TokenCredentialAuthHandler;
|
|
114
|
+
/**
|
|
115
|
+
* @deprecated Use TokenCredentialAuthHandler.createEntra() instead.
|
|
116
|
+
* Kept for backward compatibility.
|
|
117
|
+
*/
|
|
118
|
+
class EntraAuthHandler extends TokenCredentialAuthHandler {
|
|
119
|
+
constructor() {
|
|
120
|
+
super(new identity_1.DefaultAzureCredential());
|
|
121
|
+
}
|
|
122
|
+
static async getInstance() {
|
|
123
|
+
if (!EntraAuthHandler.instance) {
|
|
124
|
+
EntraAuthHandler.instance = new EntraAuthHandler();
|
|
125
|
+
}
|
|
126
|
+
// Ensure initial token is acquired
|
|
127
|
+
await EntraAuthHandler.instance.ensureToken();
|
|
128
|
+
return EntraAuthHandler.instance;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
84
131
|
exports.EntraAuthHandler = EntraAuthHandler;
|
|
85
132
|
//# sourceMappingURL=EntraAuthHandler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntraAuthHandler.js","sourceRoot":"","sources":["../../src/Services/EntraAuthHandler.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"EntraAuthHandler.js","sourceRoot":"","sources":["../../src/Services/EntraAuthHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1326,6 +1326,135 @@ Original error: ${errorMessage}`);
|
|
|
1326
1326
|
// The diff itself is self-explanatory with standard +/- markers
|
|
1327
1327
|
return diffContent;
|
|
1328
1328
|
}
|
|
1329
|
+
// ── New PR Enhancement Methods ─────────────────────────────────
|
|
1330
|
+
/**
|
|
1331
|
+
* Update pull request properties (title, description, status, auto-complete, draft).
|
|
1332
|
+
*/
|
|
1333
|
+
async updatePullRequest(params) {
|
|
1334
|
+
const gitApi = await this.getGitApi();
|
|
1335
|
+
const repositoryId = await this.resolveRepositoryId(params.repository);
|
|
1336
|
+
const updatePayload = {};
|
|
1337
|
+
if (params.title !== undefined)
|
|
1338
|
+
updatePayload.title = params.title;
|
|
1339
|
+
if (params.description !== undefined)
|
|
1340
|
+
updatePayload.description = params.description;
|
|
1341
|
+
if (params.isDraft !== undefined)
|
|
1342
|
+
updatePayload.isDraft = params.isDraft;
|
|
1343
|
+
if (params.targetRefName !== undefined)
|
|
1344
|
+
updatePayload.targetRefName = params.targetRefName;
|
|
1345
|
+
if (params.status !== undefined) {
|
|
1346
|
+
const statusMap = { 'active': 1, 'abandoned': 3, 'completed': 2 };
|
|
1347
|
+
updatePayload.status = statusMap[params.status] || 1;
|
|
1348
|
+
}
|
|
1349
|
+
// Auto-complete configuration
|
|
1350
|
+
if (params.autoCompleteSetBy !== undefined || params.mergeStrategy !== undefined || params.deleteSourceBranch !== undefined) {
|
|
1351
|
+
if (params.autoCompleteSetBy) {
|
|
1352
|
+
// Set auto-complete with completion options
|
|
1353
|
+
updatePayload.autoCompleteSetBy = { id: params.autoCompleteSetBy };
|
|
1354
|
+
}
|
|
1355
|
+
const completionOptions = {};
|
|
1356
|
+
if (params.mergeStrategy) {
|
|
1357
|
+
const mergeMap = {
|
|
1358
|
+
'noFastForward': 1, 'squash': 2, 'rebase': 3, 'rebaseMerge': 4,
|
|
1359
|
+
};
|
|
1360
|
+
completionOptions.mergeStrategy = mergeMap[params.mergeStrategy] || 1;
|
|
1361
|
+
}
|
|
1362
|
+
if (params.deleteSourceBranch !== undefined) {
|
|
1363
|
+
completionOptions.deleteSourceBranch = params.deleteSourceBranch;
|
|
1364
|
+
}
|
|
1365
|
+
if (Object.keys(completionOptions).length > 0) {
|
|
1366
|
+
updatePayload.completionOptions = completionOptions;
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
return await gitApi.updatePullRequest(updatePayload, repositoryId, params.pullRequestId, this.config.project);
|
|
1370
|
+
}
|
|
1371
|
+
/**
|
|
1372
|
+
* Add or remove reviewers on a pull request.
|
|
1373
|
+
*/
|
|
1374
|
+
async updatePullRequestReviewers(params) {
|
|
1375
|
+
const gitApi = await this.getGitApi();
|
|
1376
|
+
const repositoryId = await this.resolveRepositoryId(params.repository);
|
|
1377
|
+
const results = { added: [], removed: [] };
|
|
1378
|
+
if (params.reviewersToAdd && params.reviewersToAdd.length > 0) {
|
|
1379
|
+
for (const reviewer of params.reviewersToAdd) {
|
|
1380
|
+
const reviewerObj = {
|
|
1381
|
+
id: reviewer,
|
|
1382
|
+
isRequired: params.makeRequired || false,
|
|
1383
|
+
};
|
|
1384
|
+
const result = await gitApi.createPullRequestReviewer(reviewerObj, repositoryId, params.pullRequestId, reviewer, this.config.project);
|
|
1385
|
+
results.added.push(result);
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
if (params.reviewersToRemove && params.reviewersToRemove.length > 0) {
|
|
1389
|
+
for (const reviewer of params.reviewersToRemove) {
|
|
1390
|
+
await gitApi.deletePullRequestReviewer(repositoryId, params.pullRequestId, reviewer, this.config.project);
|
|
1391
|
+
results.removed.push(reviewer);
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
return results;
|
|
1395
|
+
}
|
|
1396
|
+
/**
|
|
1397
|
+
* Reply to an existing comment thread on a PR.
|
|
1398
|
+
*/
|
|
1399
|
+
async replyToComment(params) {
|
|
1400
|
+
const gitApi = await this.getGitApi();
|
|
1401
|
+
const repositoryId = await this.resolveRepositoryId(params.repository);
|
|
1402
|
+
const comment = {
|
|
1403
|
+
content: params.comment,
|
|
1404
|
+
parentCommentId: 0, // 0 = reply to thread
|
|
1405
|
+
commentType: 1, // text comment
|
|
1406
|
+
};
|
|
1407
|
+
return await gitApi.createComment(comment, repositoryId, params.pullRequestId, params.threadId, this.config.project);
|
|
1408
|
+
}
|
|
1409
|
+
/**
|
|
1410
|
+
* Update a comment thread's status (resolve/reactivate).
|
|
1411
|
+
*/
|
|
1412
|
+
async updatePullRequestThread(params) {
|
|
1413
|
+
const gitApi = await this.getGitApi();
|
|
1414
|
+
const repositoryId = await this.resolveRepositoryId(params.repository);
|
|
1415
|
+
const statusMap = {
|
|
1416
|
+
'active': 1,
|
|
1417
|
+
'fixed': 2,
|
|
1418
|
+
'wontFix': 3,
|
|
1419
|
+
'closed': 4,
|
|
1420
|
+
'byDesign': 5,
|
|
1421
|
+
'pending': 6,
|
|
1422
|
+
'unknown': 0,
|
|
1423
|
+
};
|
|
1424
|
+
const threadUpdate = {
|
|
1425
|
+
status: statusMap[params.status] ?? 1,
|
|
1426
|
+
};
|
|
1427
|
+
return await gitApi.updateThread(threadUpdate, repositoryId, params.pullRequestId, params.threadId, this.config.project);
|
|
1428
|
+
}
|
|
1429
|
+
/**
|
|
1430
|
+
* Create a new branch from a source ref.
|
|
1431
|
+
*/
|
|
1432
|
+
async createBranch(params) {
|
|
1433
|
+
const gitApi = await this.getGitApi();
|
|
1434
|
+
const repositoryId = await this.resolveRepositoryId(params.repository);
|
|
1435
|
+
// Resolve source ref to a commit ID
|
|
1436
|
+
let sourceObjectId = params.sourceRef;
|
|
1437
|
+
// If sourceRef looks like a branch name, resolve it to commit ID
|
|
1438
|
+
if (!sourceObjectId.match(/^[0-9a-f]{40}$/i)) {
|
|
1439
|
+
const branchName = sourceObjectId.replace(/^refs\/heads\//, '');
|
|
1440
|
+
const branches = await gitApi.getBranches(repositoryId, this.config.project);
|
|
1441
|
+
const branch = branches?.find((b) => b.name === branchName || b.name === `refs/heads/${branchName}`);
|
|
1442
|
+
if (!branch || !branch.commit?.commitId) {
|
|
1443
|
+
throw new Error(`Source branch '${branchName}' not found or has no commits.`);
|
|
1444
|
+
}
|
|
1445
|
+
sourceObjectId = branch.commit.commitId;
|
|
1446
|
+
}
|
|
1447
|
+
const branchRef = params.branchName.startsWith('refs/heads/')
|
|
1448
|
+
? params.branchName
|
|
1449
|
+
: `refs/heads/${params.branchName}`;
|
|
1450
|
+
const refUpdate = [{
|
|
1451
|
+
name: branchRef,
|
|
1452
|
+
oldObjectId: '0000000000000000000000000000000000000000',
|
|
1453
|
+
newObjectId: sourceObjectId,
|
|
1454
|
+
}];
|
|
1455
|
+
const result = await gitApi.updateRefs(refUpdate, repositoryId, this.config.project);
|
|
1456
|
+
return result?.[0];
|
|
1457
|
+
}
|
|
1329
1458
|
}
|
|
1330
1459
|
exports.GitService = GitService;
|
|
1331
1460
|
//# sourceMappingURL=GitService.js.map
|