@elisra-devops/docgen-data-provider 0.4.6 → 0.4.13

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.
Files changed (68) hide show
  1. package/.github/sonar-project.properties +4 -4
  2. package/.github/workflows/ci.yml +21 -21
  3. package/.github/workflows/release.yml +45 -40
  4. package/LICENSE +21 -21
  5. package/README.md +39 -38
  6. package/bin/helpers/helper.d.ts +37 -0
  7. package/bin/helpers/helper.js +83 -0
  8. package/bin/helpers/helper.js.map +1 -0
  9. package/bin/helpers/tfs.d.ts +5 -0
  10. package/bin/helpers/tfs.js +100 -0
  11. package/bin/helpers/tfs.js.map +1 -0
  12. package/bin/index.d.ts +16 -0
  13. package/bin/index.js +53 -0
  14. package/bin/index.js.map +1 -0
  15. package/bin/models/tfs-data.d.ts +86 -0
  16. package/bin/models/tfs-data.js +63 -0
  17. package/bin/models/tfs-data.js.map +1 -0
  18. package/bin/modules/GitDataProvider.d.ts +26 -0
  19. package/bin/modules/GitDataProvider.js +301 -0
  20. package/bin/modules/GitDataProvider.js.map +1 -0
  21. package/bin/modules/MangementDataProvider.d.ts +9 -0
  22. package/bin/modules/MangementDataProvider.js +62 -0
  23. package/bin/modules/MangementDataProvider.js.map +1 -0
  24. package/bin/modules/PipelinesDataProvider.d.ts +13 -0
  25. package/bin/modules/PipelinesDataProvider.js +103 -0
  26. package/bin/modules/PipelinesDataProvider.js.map +1 -0
  27. package/bin/modules/TestDataProvider.d.ts +24 -0
  28. package/bin/modules/TestDataProvider.js +294 -0
  29. package/bin/modules/TestDataProvider.js.map +1 -0
  30. package/bin/modules/TicketsDataProvider.d.ts +26 -0
  31. package/bin/modules/TicketsDataProvider.js +385 -0
  32. package/bin/modules/TicketsDataProvider.js.map +1 -0
  33. package/bin/modules/test/gitDataProvider.test.d.ts +1 -0
  34. package/bin/modules/test/gitDataProvider.test.js +138 -0
  35. package/bin/modules/test/gitDataProvider.test.js.map +1 -0
  36. package/bin/modules/test/managmentDataProvider.test.d.ts +1 -0
  37. package/bin/modules/test/managmentDataProvider.test.js +40 -0
  38. package/bin/modules/test/managmentDataProvider.test.js.map +1 -0
  39. package/bin/modules/test/pipelineDataProvider.test.d.ts +1 -0
  40. package/bin/modules/test/pipelineDataProvider.test.js +62 -0
  41. package/bin/modules/test/pipelineDataProvider.test.js.map +1 -0
  42. package/bin/modules/test/testDataProvider.test.d.ts +1 -0
  43. package/bin/modules/test/testDataProvider.test.js +103 -0
  44. package/bin/modules/test/testDataProvider.test.js.map +1 -0
  45. package/bin/modules/test/ticketsDataProvider.test.d.ts +1 -0
  46. package/bin/modules/test/ticketsDataProvider.test.js +103 -0
  47. package/bin/modules/test/ticketsDataProvider.test.js.map +1 -0
  48. package/bin/utils/logger.d.ts +3 -0
  49. package/bin/utils/logger.js +33 -0
  50. package/bin/utils/logger.js.map +1 -0
  51. package/enviroment.d.ts +12 -12
  52. package/package.json +53 -53
  53. package/src/helpers/helper.ts +117 -117
  54. package/src/helpers/tfs.ts +92 -92
  55. package/src/index.ts +36 -36
  56. package/src/models/tfs-data.ts +136 -136
  57. package/src/modules/GitDataProvider.ts +446 -446
  58. package/src/modules/MangementDataProvider.ts +59 -59
  59. package/src/modules/PipelinesDataProvider.ts +142 -142
  60. package/src/modules/TestDataProvider.ts +423 -423
  61. package/src/modules/TicketsDataProvider.ts +435 -435
  62. package/src/modules/test/gitDataProvider.test.ts +207 -207
  63. package/src/modules/test/managmentDataProvider.test.ts +33 -33
  64. package/src/modules/test/pipelineDataProvider.test.ts +79 -79
  65. package/src/modules/test/testDataProvider.test.ts +139 -139
  66. package/src/modules/test/ticketsDataProvider.test.ts +138 -138
  67. package/src/utils/logger.ts +37 -37
  68. package/tsconfig.json +27 -27
@@ -1,435 +1,435 @@
1
- import { TFSServices } from "../helpers/tfs";
2
- import { Workitem } from "../models/tfs-data";
3
- import { Helper, suiteData, Links, Trace, Relations } from "../helpers/helper";
4
- import { Query, TestSteps } from "../models/tfs-data";
5
- import { QueryType } from "../models/tfs-data";
6
- import { QueryAllTypes } from "../models/tfs-data";
7
- import { Column } from "../models/tfs-data";
8
- import { value } from "../models/tfs-data";
9
- import { TestCase } from "../models/tfs-data";
10
- import * as xml2js from "xml2js";
11
-
12
- import logger from "../utils/logger";
13
-
14
- export default class TicketsDataProvider {
15
- orgUrl: string = "";
16
- token: string = "";
17
- queriesList: Array<any> = new Array<any>();
18
-
19
- constructor(orgUrl: string, token: string) {
20
- this.orgUrl = orgUrl;
21
- this.token = token;
22
- }
23
-
24
- async GetWorkItem(
25
- project: string,
26
- id: string
27
- ): Promise<any> {
28
- let url = `${this.orgUrl}${project}/_apis/wit/workitems/${id}?$expand=All`;
29
- return TFSServices.getItemContent(url, this.token);
30
- }
31
- async GetLinksByIds(
32
- project: string,
33
- ids: any
34
- ) {
35
- var trace: Array<Trace> = new Array<Trace>();
36
- let wis = await this.PopulateWorkItemsByIds(ids, project);
37
- let linksMap: any = await this.GetRelationsIds(wis);
38
-
39
- let relations;
40
- for (let i = 0; i < wis.length; i++) {
41
- let traceItem: Trace; //= new Trace();
42
- traceItem = await this.GetParentLink(project, wis[i]);
43
-
44
- if (linksMap.get(wis[i].id).rels.length > 0) {
45
- relations = await this.PopulateWorkItemsByIds(
46
- linksMap.get(wis[i].id).rels,
47
- project
48
- );
49
- traceItem.links = await this.GetLinks(project, wis[i], relations);
50
- }
51
- trace.push(traceItem);
52
- }
53
- return trace;
54
- }
55
- async GetParentLink(
56
- project: string,
57
- wi: any
58
- ) {
59
- let trace: Trace = new Trace();
60
- if (wi != null) {
61
- trace.id = wi.id;
62
- trace.title = wi.fields["System.Title"];
63
- trace.url = this.orgUrl + project + "/_workitems/edit/" + wi.id;
64
- if (
65
- wi.fields["System.CustomerId"] != null &&
66
- wi.fields["System.CustomerId"] != undefined
67
- ) {
68
- trace.customerId = wi.fields["System.CustomerId"];
69
- }
70
- }
71
- return trace;
72
- }
73
- async GetRelationsIds(
74
- ids: any
75
- ) {
76
- let rel = new Map<string, Relations>();
77
- try {
78
- for (let i = 0; i < ids.length; i++) {
79
- var link = new Relations();
80
- link.id = ids[i].id;
81
- if (ids[i].relations != null)
82
- for (let j = 0; j < ids[i].relations.length; j++) {
83
- if (ids[i].relations[j].rel != "AttachedFile") {
84
- let index = ids[i].relations[j].url.lastIndexOf("/");
85
- let id = ids[i].relations[j].url.substring(index + 1);
86
- link.rels.push(id);
87
- }
88
- }
89
- rel.set(ids[i].id, link);
90
- }
91
- } catch (e) {}
92
- return rel;
93
- }
94
- async GetLinks(
95
- project: string,
96
- wi: any,
97
- links: any
98
- ) {
99
- var linkList: Array<Links> = new Array<Links>();
100
- for (let i = 0; i < wi.relations.length; i++) {
101
- for (let j = 0; j < links.length; j++) {
102
- let index = wi.relations[i].url.lastIndexOf("/");
103
- let linkId = wi.relations[i].url.substring(index + 1);
104
- if (linkId == links[j].id) {
105
- var link = new Links();
106
- link.type = wi.relations[i].rel;
107
- link.id = links[j].id;
108
- link.title = links[j].fields["System.Title"];
109
- link.description = links[j].fields["System.Description"];
110
- link.url = this.orgUrl + project + "/_workitems/edit/" + linkId;
111
- linkList.push(link);
112
- break;
113
- }
114
- }
115
- }
116
- return linkList;
117
- }
118
- // gets queries recursiv
119
- async GetSharedQueries(
120
- project: string,
121
- path: string
122
- ): Promise<any> {
123
- let url;
124
- try {
125
- if (path == "")
126
- url = `${this.orgUrl}${project}/_apis/wit/queries/Shared%20Queries?$depth=1`;
127
- else
128
- url = `${this.orgUrl}${project}/_apis/wit/queries/${path}?$depth=1`;
129
- let queries: any = await TFSServices.getItemContent(url, this.token);
130
- for (let i = 0; i < queries.children.length; i++)
131
- if (queries.children[i].isFolder) {
132
- this.queriesList.push(queries.children[i]);
133
- await this.GetSharedQueries(project, queries.children[i].path);
134
- } else {
135
- this.queriesList.push(queries.children[i]);
136
- }
137
- return this.GetModeledQuery(this.queriesList);
138
- } catch (e) {}
139
- }
140
- // get queris structured
141
- GetModeledQuery(
142
- list: Array<any>
143
- ): Array<any> {
144
- let queryListObject: Array<any> = [];
145
- list.forEach((query) => {
146
- let newObj = {
147
- queryName: query.name,
148
- wiql: query._links.wiql != null ? query._links.wiql : null,
149
- id: query.id,
150
- };
151
- queryListObject.push(newObj);
152
- });
153
- return queryListObject;
154
- }
155
- // gets query results
156
- async GetQueryResultsByWiqlHref(
157
- wiqlHref: string,
158
- project: string
159
- ): Promise<any> {
160
- try {
161
- let results: any = await TFSServices.getItemContent(wiqlHref, this.token);
162
- let modeledResult = await this.GetModeledQueryResults(results, project);
163
- if (modeledResult.queryType == "tree") {
164
- let levelResults: Array<Workitem> = Helper.LevelBuilder(
165
- modeledResult,
166
- modeledResult.workItems[0].fields[0].value
167
- );
168
- return levelResults;
169
- }
170
- return modeledResult.workItems;
171
- } catch (e) {}
172
- }
173
- // gets query results
174
- async GetQueryResultsByWiqlString(
175
- wiql: string,
176
- projectName: string
177
- ): Promise<any> {
178
- let res;
179
- let url = `${this.orgUrl}${projectName}/_apis/wit/wiql?$top=2147483646&expand={all}`;
180
- try {
181
- res = await TFSServices.getItemContent(url, this.token, "post", {
182
- query: wiql,
183
- });
184
- } catch (error) {
185
- console.log(error);
186
- return [];
187
- }
188
- return res;
189
- }
190
- async GetQueryResultById(
191
- query: string,
192
- project: string
193
- ): Promise<any> {
194
- var url = `${this.orgUrl}${project}/_apis/wit/queries/${query}`;
195
- let querie: any = await TFSServices.getItemContent(url, this.token);
196
- var wiql = querie._links.wiql;
197
- return await this.GetQueryResultsByWiqlHref(wiql.href, project);
198
- }
199
-
200
- async PopulateWorkItemsByIds(
201
- workItemsArray: any[] = [],
202
- projectName: string = ""
203
- ): Promise<any[]> {
204
- let url = `${this.orgUrl}${projectName}/_apis/wit/workitemsbatch`;
205
- let res: any[] = [];
206
- let divByMax = Math.floor(workItemsArray.length / 200);
207
- let modulusByMax = workItemsArray.length % 200;
208
- //iterating
209
- for (let i = 0; i < divByMax; i++) {
210
- let from = i * 200;
211
- let to = (i + 1) * 200;
212
- let currentIds = workItemsArray.slice(from, to);
213
- try {
214
- let subRes = await TFSServices.getItemContent(url, this.token, "post", {
215
- $expand: "Relations",
216
- ids: currentIds,
217
- });
218
- res = [...res, ...subRes.value];
219
- } catch (error) {
220
- logger.error(`error populating workitems array`);
221
- logger.error(JSON.stringify(error));
222
- return [];
223
- }
224
- }
225
- //compliting the rimainder
226
- if (modulusByMax !== 0) {
227
- try {
228
- let currentIds = workItemsArray.slice(
229
- workItemsArray.length - modulusByMax,
230
- workItemsArray.length
231
- );
232
- let subRes = await TFSServices.getItemContent(url, this.token, "post", {
233
- $expand: "Relations",
234
- ids: currentIds,
235
- });
236
- res = [...res, ...subRes.value];
237
- } catch (error) {
238
- logger.error(`error populating workitems array`);
239
- logger.error(JSON.stringify(error));
240
- return [];
241
- }
242
- } //if
243
-
244
- return res;
245
- }
246
-
247
- async GetModeledQueryResults(
248
- results: any,
249
- project: string
250
- ) {
251
- let ticketsDataProvider = new TicketsDataProvider(
252
- this.orgUrl,
253
- this.token,
254
- );
255
- var queryResult: Query = new Query();
256
- queryResult.asOf = results.asOf;
257
- queryResult.queryResultType = results.queryResultType;
258
- queryResult.queryType = results.queryType;
259
- if (results.queryType == QueryType.Flat) {
260
- // //Flat Query
261
- //TODo: attachment
262
- //TODO:check if wi.relations exist
263
- //TODO: add attachment to any list from 1
264
- for (var j = 0; j < results.workItems.length; j++) {
265
- let wi = await ticketsDataProvider.GetWorkItem(
266
- project,
267
- results.workItems[j].id
268
- );
269
-
270
- queryResult.workItems[j] = new Workitem();
271
- queryResult.workItems[j].url = results.workItems[j].url;
272
- queryResult.workItems[j].fields = new Array(results.columns.length);
273
- if (wi.relations != null) {
274
- queryResult.workItems[j].attachments = wi.relations;
275
- }
276
- var rel = new QueryAllTypes();
277
- for (var i = 0; i < results.columns.length; i++) {
278
- queryResult.columns[i] = new Column();
279
- queryResult.workItems[j].fields[i] = new value();
280
- queryResult.columns[i].name = results.columns[i].name;
281
- queryResult.columns[i].referenceName =
282
- results.columns[i].referenceName;
283
- queryResult.columns[i].url = results.columns[i].url;
284
- if (results.columns[i].referenceName.toUpperCase() == "SYSTEM.ID") {
285
- queryResult.workItems[j].fields[i].value = wi.id.toString();
286
- queryResult.workItems[j].fields[i].name = "ID";
287
- } else if (
288
- results.columns[i].referenceName.toUpperCase() ==
289
- "SYSTEM.ASSIGNEDTO" &&
290
- wi.fields[results.columns[i].referenceName] != null
291
- )
292
- queryResult.workItems[j].fields[i].value =
293
- wi.fields[results.columns[i].referenceName].displayName;
294
- else {
295
- let s: string = wi.fields[results.columns[i].referenceName];
296
- queryResult.workItems[j].fields[i].value =
297
- wi.fields[results.columns[i].referenceName];
298
- queryResult.workItems[j].fields[i].name = results.columns[i].name;
299
- }
300
- }
301
- }
302
- } //Tree Query
303
- else {
304
- this.BuildColumns(results, queryResult);
305
- for (var j = 0; j < results.workItemRelations.length; j++) {
306
- if (results.workItemRelations[j].target != null) {
307
- let wiT = await ticketsDataProvider.GetWorkItem(
308
- project,
309
- results.workItemRelations[j].target.id
310
- );
311
- // var rel = new QueryAllTypes();
312
- queryResult.workItems[j] = new Workitem();
313
- queryResult.workItems[j].url = wiT.url;
314
- queryResult.workItems[j].fields = new Array(results.columns.length);
315
- if (wiT.relations != null) {
316
- queryResult.workItems[j].attachments = wiT.relations;
317
- }
318
- // rel.q = queryResult;
319
- for (i = 0; i < queryResult.columns.length; i++) {
320
- //.. rel.q.workItems[j].fields[i] = new value();
321
- queryResult.workItems[j].fields[i] = new value();
322
- queryResult.workItems[j].fields[i].name =
323
- queryResult.columns[i].name;
324
- if (
325
- results.columns[i].referenceName.toUpperCase() ==
326
- "SYSTEM.ASSIGNEDTO" &&
327
- wiT.fields[results.columns[i].referenceName] != null
328
- )
329
- queryResult.workItems[j].fields[i].value =
330
- wiT.fields[results.columns[i].referenceName].displayName;
331
- else
332
- queryResult.workItems[j].fields[i].value =
333
- wiT.fields[queryResult.columns[i].referenceName];
334
- //}
335
- }
336
- if (results.workItemRelations[j].source != null)
337
- queryResult.workItems[j].Source =
338
- results.workItemRelations[j].source.id;
339
- }
340
- }
341
- }
342
- return queryResult;
343
- }
344
-
345
- BuildColumns(
346
- results: any,
347
- queryResult: Query
348
- ) {
349
- for (var i = 0; i < results.columns.length; i++) {
350
- queryResult.columns[i] = new Column();
351
- queryResult.columns[i].name = results.columns[i].name;
352
- queryResult.columns[i].referenceName = results.columns[i].referenceName;
353
- queryResult.columns[i].url = results.columns[i].url;
354
- }
355
- }
356
-
357
- async GetIterationsByTeamName(
358
- projectName: string,
359
- teamName: string
360
- ): Promise<any[]> {
361
- let res: any;
362
- let url;
363
- if (teamName) {
364
- url = `${this.orgUrl}${projectName}/${teamName}/_apis/work/teamsettings/iterations`;
365
- } else {
366
- url = `${this.orgUrl}${projectName}/_apis/work/teamsettings/iterations`;
367
- }
368
- res = await TFSServices.getItemContent(url, this.token, "get");
369
- return res;
370
- } //GetIterationsByTeamName
371
-
372
- async CreateNewWorkItem(
373
- projectName: string,
374
- wiBody: any,
375
- wiType: string,
376
- byPass: boolean
377
- ) {
378
- let url =
379
- `${this.orgUrl}${projectName}/_apis/wit/workitems/$${wiType}?bypassRules=${String(byPass).toString()}`;
380
- return TFSServices.getItemContent(url,this.token,"POST",wiBody,{"Content-Type": "application/json-patch+json"});
381
- } //CreateNewWorkItem
382
-
383
- async GetWorkitemAttachments(
384
- project: string,
385
- id: string
386
- ) {
387
- let attachmentList: Array<string> = [];
388
- let ticketsDataProvider = new TicketsDataProvider(
389
- this.orgUrl,
390
- this.token,
391
- );
392
- try {
393
- let wi = await ticketsDataProvider.GetWorkItem(project, id);
394
- if (!wi.relations) return [];
395
- await Promise.all(
396
- wi.relations.map(async (relation: any) => {
397
- if (relation.rel == "AttachedFile") {
398
- let attachment = JSON.parse(JSON.stringify(relation));
399
- attachment.downloadUrl = `${relation.url}/${relation.attributes.name}`;
400
- attachmentList.push(attachment);
401
- }
402
- })
403
- );
404
- return attachmentList;
405
- } catch (e) {
406
- logger.error(`error fetching attachments for work item ${id}`);
407
- logger.error(`${JSON.stringify(e)}`);
408
- return [];
409
- }
410
- }
411
-
412
- async GetWorkitemAttachmentsJSONData(
413
- project: string,
414
- attachmentId: string
415
- ) {
416
- let wiuRL =`${this.orgUrl}${project}/_apis/wit/attachments/${attachmentId}`;
417
- let attachment = await TFSServices.getItemContent(wiuRL, this.token);
418
- return attachment;
419
- }
420
-
421
- async UpdateWorkItem(
422
- projectName: string,
423
- wiBody: any,
424
- workItemId: number,
425
- byPass: boolean
426
- ) {
427
- let res: any;
428
- let url: string =
429
- `${this.orgUrl}${projectName}/_apis/wit/workitems/${workItemId}?bypassRules=${String(byPass).toString()}`;
430
- res = await TFSServices.getItemContent(url, this.token, "patch", wiBody, {
431
- "Content-Type": "application/json-patch+json",
432
- });
433
- return res;
434
- } //CreateNewWorkItem
435
- }
1
+ import { TFSServices } from "../helpers/tfs";
2
+ import { Workitem } from "../models/tfs-data";
3
+ import { Helper, suiteData, Links, Trace, Relations } from "../helpers/helper";
4
+ import { Query, TestSteps } from "../models/tfs-data";
5
+ import { QueryType } from "../models/tfs-data";
6
+ import { QueryAllTypes } from "../models/tfs-data";
7
+ import { Column } from "../models/tfs-data";
8
+ import { value } from "../models/tfs-data";
9
+ import { TestCase } from "../models/tfs-data";
10
+ import * as xml2js from "xml2js";
11
+
12
+ import logger from "../utils/logger";
13
+
14
+ export default class TicketsDataProvider {
15
+ orgUrl: string = "";
16
+ token: string = "";
17
+ queriesList: Array<any> = new Array<any>();
18
+
19
+ constructor(orgUrl: string, token: string) {
20
+ this.orgUrl = orgUrl;
21
+ this.token = token;
22
+ }
23
+
24
+ async GetWorkItem(
25
+ project: string,
26
+ id: string
27
+ ): Promise<any> {
28
+ let url = `${this.orgUrl}${project}/_apis/wit/workitems/${id}?$expand=All`;
29
+ return TFSServices.getItemContent(url, this.token);
30
+ }
31
+ async GetLinksByIds(
32
+ project: string,
33
+ ids: any
34
+ ) {
35
+ var trace: Array<Trace> = new Array<Trace>();
36
+ let wis = await this.PopulateWorkItemsByIds(ids, project);
37
+ let linksMap: any = await this.GetRelationsIds(wis);
38
+
39
+ let relations;
40
+ for (let i = 0; i < wis.length; i++) {
41
+ let traceItem: Trace; //= new Trace();
42
+ traceItem = await this.GetParentLink(project, wis[i]);
43
+
44
+ if (linksMap.get(wis[i].id).rels.length > 0) {
45
+ relations = await this.PopulateWorkItemsByIds(
46
+ linksMap.get(wis[i].id).rels,
47
+ project
48
+ );
49
+ traceItem.links = await this.GetLinks(project, wis[i], relations);
50
+ }
51
+ trace.push(traceItem);
52
+ }
53
+ return trace;
54
+ }
55
+ async GetParentLink(
56
+ project: string,
57
+ wi: any
58
+ ) {
59
+ let trace: Trace = new Trace();
60
+ if (wi != null) {
61
+ trace.id = wi.id;
62
+ trace.title = wi.fields["System.Title"];
63
+ trace.url = this.orgUrl + project + "/_workitems/edit/" + wi.id;
64
+ if (
65
+ wi.fields["System.CustomerId"] != null &&
66
+ wi.fields["System.CustomerId"] != undefined
67
+ ) {
68
+ trace.customerId = wi.fields["System.CustomerId"];
69
+ }
70
+ }
71
+ return trace;
72
+ }
73
+ async GetRelationsIds(
74
+ ids: any
75
+ ) {
76
+ let rel = new Map<string, Relations>();
77
+ try {
78
+ for (let i = 0; i < ids.length; i++) {
79
+ var link = new Relations();
80
+ link.id = ids[i].id;
81
+ if (ids[i].relations != null)
82
+ for (let j = 0; j < ids[i].relations.length; j++) {
83
+ if (ids[i].relations[j].rel != "AttachedFile") {
84
+ let index = ids[i].relations[j].url.lastIndexOf("/");
85
+ let id = ids[i].relations[j].url.substring(index + 1);
86
+ link.rels.push(id);
87
+ }
88
+ }
89
+ rel.set(ids[i].id, link);
90
+ }
91
+ } catch (e) {}
92
+ return rel;
93
+ }
94
+ async GetLinks(
95
+ project: string,
96
+ wi: any,
97
+ links: any
98
+ ) {
99
+ var linkList: Array<Links> = new Array<Links>();
100
+ for (let i = 0; i < wi.relations.length; i++) {
101
+ for (let j = 0; j < links.length; j++) {
102
+ let index = wi.relations[i].url.lastIndexOf("/");
103
+ let linkId = wi.relations[i].url.substring(index + 1);
104
+ if (linkId == links[j].id) {
105
+ var link = new Links();
106
+ link.type = wi.relations[i].rel;
107
+ link.id = links[j].id;
108
+ link.title = links[j].fields["System.Title"];
109
+ link.description = links[j].fields["System.Description"];
110
+ link.url = this.orgUrl + project + "/_workitems/edit/" + linkId;
111
+ linkList.push(link);
112
+ break;
113
+ }
114
+ }
115
+ }
116
+ return linkList;
117
+ }
118
+ // gets queries recursiv
119
+ async GetSharedQueries(
120
+ project: string,
121
+ path: string
122
+ ): Promise<any> {
123
+ let url;
124
+ try {
125
+ if (path == "")
126
+ url = `${this.orgUrl}${project}/_apis/wit/queries/Shared%20Queries?$depth=1`;
127
+ else
128
+ url = `${this.orgUrl}${project}/_apis/wit/queries/${path}?$depth=1`;
129
+ let queries: any = await TFSServices.getItemContent(url, this.token);
130
+ for (let i = 0; i < queries.children.length; i++)
131
+ if (queries.children[i].isFolder) {
132
+ this.queriesList.push(queries.children[i]);
133
+ await this.GetSharedQueries(project, queries.children[i].path);
134
+ } else {
135
+ this.queriesList.push(queries.children[i]);
136
+ }
137
+ return this.GetModeledQuery(this.queriesList);
138
+ } catch (e) {}
139
+ }
140
+ // get queris structured
141
+ GetModeledQuery(
142
+ list: Array<any>
143
+ ): Array<any> {
144
+ let queryListObject: Array<any> = [];
145
+ list.forEach((query) => {
146
+ let newObj = {
147
+ queryName: query.name,
148
+ wiql: query._links.wiql != null ? query._links.wiql : null,
149
+ id: query.id,
150
+ };
151
+ queryListObject.push(newObj);
152
+ });
153
+ return queryListObject;
154
+ }
155
+ // gets query results
156
+ async GetQueryResultsByWiqlHref(
157
+ wiqlHref: string,
158
+ project: string
159
+ ): Promise<any> {
160
+ try {
161
+ let results: any = await TFSServices.getItemContent(wiqlHref, this.token);
162
+ let modeledResult = await this.GetModeledQueryResults(results, project);
163
+ if (modeledResult.queryType == "tree") {
164
+ let levelResults: Array<Workitem> = Helper.LevelBuilder(
165
+ modeledResult,
166
+ modeledResult.workItems[0].fields[0].value
167
+ );
168
+ return levelResults;
169
+ }
170
+ return modeledResult.workItems;
171
+ } catch (e) {}
172
+ }
173
+ // gets query results
174
+ async GetQueryResultsByWiqlString(
175
+ wiql: string,
176
+ projectName: string
177
+ ): Promise<any> {
178
+ let res;
179
+ let url = `${this.orgUrl}${projectName}/_apis/wit/wiql?$top=2147483646&expand={all}`;
180
+ try {
181
+ res = await TFSServices.getItemContent(url, this.token, "post", {
182
+ query: wiql,
183
+ });
184
+ } catch (error) {
185
+ console.log(error);
186
+ return [];
187
+ }
188
+ return res;
189
+ }
190
+ async GetQueryResultById(
191
+ query: string,
192
+ project: string
193
+ ): Promise<any> {
194
+ var url = `${this.orgUrl}${project}/_apis/wit/queries/${query}`;
195
+ let querie: any = await TFSServices.getItemContent(url, this.token);
196
+ var wiql = querie._links.wiql;
197
+ return await this.GetQueryResultsByWiqlHref(wiql.href, project);
198
+ }
199
+
200
+ async PopulateWorkItemsByIds(
201
+ workItemsArray: any[] = [],
202
+ projectName: string = ""
203
+ ): Promise<any[]> {
204
+ let url = `${this.orgUrl}${projectName}/_apis/wit/workitemsbatch`;
205
+ let res: any[] = [];
206
+ let divByMax = Math.floor(workItemsArray.length / 200);
207
+ let modulusByMax = workItemsArray.length % 200;
208
+ //iterating
209
+ for (let i = 0; i < divByMax; i++) {
210
+ let from = i * 200;
211
+ let to = (i + 1) * 200;
212
+ let currentIds = workItemsArray.slice(from, to);
213
+ try {
214
+ let subRes = await TFSServices.getItemContent(url, this.token, "post", {
215
+ $expand: "Relations",
216
+ ids: currentIds,
217
+ });
218
+ res = [...res, ...subRes.value];
219
+ } catch (error) {
220
+ logger.error(`error populating workitems array`);
221
+ logger.error(JSON.stringify(error));
222
+ return [];
223
+ }
224
+ }
225
+ //compliting the rimainder
226
+ if (modulusByMax !== 0) {
227
+ try {
228
+ let currentIds = workItemsArray.slice(
229
+ workItemsArray.length - modulusByMax,
230
+ workItemsArray.length
231
+ );
232
+ let subRes = await TFSServices.getItemContent(url, this.token, "post", {
233
+ $expand: "Relations",
234
+ ids: currentIds,
235
+ });
236
+ res = [...res, ...subRes.value];
237
+ } catch (error) {
238
+ logger.error(`error populating workitems array`);
239
+ logger.error(JSON.stringify(error));
240
+ return [];
241
+ }
242
+ } //if
243
+
244
+ return res;
245
+ }
246
+
247
+ async GetModeledQueryResults(
248
+ results: any,
249
+ project: string
250
+ ) {
251
+ let ticketsDataProvider = new TicketsDataProvider(
252
+ this.orgUrl,
253
+ this.token,
254
+ );
255
+ var queryResult: Query = new Query();
256
+ queryResult.asOf = results.asOf;
257
+ queryResult.queryResultType = results.queryResultType;
258
+ queryResult.queryType = results.queryType;
259
+ if (results.queryType == QueryType.Flat) {
260
+ // //Flat Query
261
+ //TODo: attachment
262
+ //TODO:check if wi.relations exist
263
+ //TODO: add attachment to any list from 1
264
+ for (var j = 0; j < results.workItems.length; j++) {
265
+ let wi = await ticketsDataProvider.GetWorkItem(
266
+ project,
267
+ results.workItems[j].id
268
+ );
269
+
270
+ queryResult.workItems[j] = new Workitem();
271
+ queryResult.workItems[j].url = results.workItems[j].url;
272
+ queryResult.workItems[j].fields = new Array(results.columns.length);
273
+ if (wi.relations != null) {
274
+ queryResult.workItems[j].attachments = wi.relations;
275
+ }
276
+ var rel = new QueryAllTypes();
277
+ for (var i = 0; i < results.columns.length; i++) {
278
+ queryResult.columns[i] = new Column();
279
+ queryResult.workItems[j].fields[i] = new value();
280
+ queryResult.columns[i].name = results.columns[i].name;
281
+ queryResult.columns[i].referenceName =
282
+ results.columns[i].referenceName;
283
+ queryResult.columns[i].url = results.columns[i].url;
284
+ if (results.columns[i].referenceName.toUpperCase() == "SYSTEM.ID") {
285
+ queryResult.workItems[j].fields[i].value = wi.id.toString();
286
+ queryResult.workItems[j].fields[i].name = "ID";
287
+ } else if (
288
+ results.columns[i].referenceName.toUpperCase() ==
289
+ "SYSTEM.ASSIGNEDTO" &&
290
+ wi.fields[results.columns[i].referenceName] != null
291
+ )
292
+ queryResult.workItems[j].fields[i].value =
293
+ wi.fields[results.columns[i].referenceName].displayName;
294
+ else {
295
+ let s: string = wi.fields[results.columns[i].referenceName];
296
+ queryResult.workItems[j].fields[i].value =
297
+ wi.fields[results.columns[i].referenceName];
298
+ queryResult.workItems[j].fields[i].name = results.columns[i].name;
299
+ }
300
+ }
301
+ }
302
+ } //Tree Query
303
+ else {
304
+ this.BuildColumns(results, queryResult);
305
+ for (var j = 0; j < results.workItemRelations.length; j++) {
306
+ if (results.workItemRelations[j].target != null) {
307
+ let wiT = await ticketsDataProvider.GetWorkItem(
308
+ project,
309
+ results.workItemRelations[j].target.id
310
+ );
311
+ // var rel = new QueryAllTypes();
312
+ queryResult.workItems[j] = new Workitem();
313
+ queryResult.workItems[j].url = wiT.url;
314
+ queryResult.workItems[j].fields = new Array(results.columns.length);
315
+ if (wiT.relations != null) {
316
+ queryResult.workItems[j].attachments = wiT.relations;
317
+ }
318
+ // rel.q = queryResult;
319
+ for (i = 0; i < queryResult.columns.length; i++) {
320
+ //.. rel.q.workItems[j].fields[i] = new value();
321
+ queryResult.workItems[j].fields[i] = new value();
322
+ queryResult.workItems[j].fields[i].name =
323
+ queryResult.columns[i].name;
324
+ if (
325
+ results.columns[i].referenceName.toUpperCase() ==
326
+ "SYSTEM.ASSIGNEDTO" &&
327
+ wiT.fields[results.columns[i].referenceName] != null
328
+ )
329
+ queryResult.workItems[j].fields[i].value =
330
+ wiT.fields[results.columns[i].referenceName].displayName;
331
+ else
332
+ queryResult.workItems[j].fields[i].value =
333
+ wiT.fields[queryResult.columns[i].referenceName];
334
+ //}
335
+ }
336
+ if (results.workItemRelations[j].source != null)
337
+ queryResult.workItems[j].Source =
338
+ results.workItemRelations[j].source.id;
339
+ }
340
+ }
341
+ }
342
+ return queryResult;
343
+ }
344
+
345
+ BuildColumns(
346
+ results: any,
347
+ queryResult: Query
348
+ ) {
349
+ for (var i = 0; i < results.columns.length; i++) {
350
+ queryResult.columns[i] = new Column();
351
+ queryResult.columns[i].name = results.columns[i].name;
352
+ queryResult.columns[i].referenceName = results.columns[i].referenceName;
353
+ queryResult.columns[i].url = results.columns[i].url;
354
+ }
355
+ }
356
+
357
+ async GetIterationsByTeamName(
358
+ projectName: string,
359
+ teamName: string
360
+ ): Promise<any[]> {
361
+ let res: any;
362
+ let url;
363
+ if (teamName) {
364
+ url = `${this.orgUrl}${projectName}/${teamName}/_apis/work/teamsettings/iterations`;
365
+ } else {
366
+ url = `${this.orgUrl}${projectName}/_apis/work/teamsettings/iterations`;
367
+ }
368
+ res = await TFSServices.getItemContent(url, this.token, "get");
369
+ return res;
370
+ } //GetIterationsByTeamName
371
+
372
+ async CreateNewWorkItem(
373
+ projectName: string,
374
+ wiBody: any,
375
+ wiType: string,
376
+ byPass: boolean
377
+ ) {
378
+ let url =
379
+ `${this.orgUrl}${projectName}/_apis/wit/workitems/$${wiType}?bypassRules=${String(byPass).toString()}`;
380
+ return TFSServices.getItemContent(url,this.token,"POST",wiBody,{"Content-Type": "application/json-patch+json"});
381
+ } //CreateNewWorkItem
382
+
383
+ async GetWorkitemAttachments(
384
+ project: string,
385
+ id: string
386
+ ) {
387
+ let attachmentList: Array<string> = [];
388
+ let ticketsDataProvider = new TicketsDataProvider(
389
+ this.orgUrl,
390
+ this.token,
391
+ );
392
+ try {
393
+ let wi = await ticketsDataProvider.GetWorkItem(project, id);
394
+ if (!wi.relations) return [];
395
+ await Promise.all(
396
+ wi.relations.map(async (relation: any) => {
397
+ if (relation.rel == "AttachedFile") {
398
+ let attachment = JSON.parse(JSON.stringify(relation));
399
+ attachment.downloadUrl = `${relation.url}/${relation.attributes.name}`;
400
+ attachmentList.push(attachment);
401
+ }
402
+ })
403
+ );
404
+ return attachmentList;
405
+ } catch (e) {
406
+ logger.error(`error fetching attachments for work item ${id}`);
407
+ logger.error(`${JSON.stringify(e)}`);
408
+ return [];
409
+ }
410
+ }
411
+
412
+ async GetWorkitemAttachmentsJSONData(
413
+ project: string,
414
+ attachmentId: string
415
+ ) {
416
+ let wiuRL =`${this.orgUrl}${project}/_apis/wit/attachments/${attachmentId}`;
417
+ let attachment = await TFSServices.getItemContent(wiuRL, this.token);
418
+ return attachment;
419
+ }
420
+
421
+ async UpdateWorkItem(
422
+ projectName: string,
423
+ wiBody: any,
424
+ workItemId: number,
425
+ byPass: boolean
426
+ ) {
427
+ let res: any;
428
+ let url: string =
429
+ `${this.orgUrl}${projectName}/_apis/wit/workitems/${workItemId}?bypassRules=${String(byPass).toString()}`;
430
+ res = await TFSServices.getItemContent(url, this.token, "patch", wiBody, {
431
+ "Content-Type": "application/json-patch+json",
432
+ });
433
+ return res;
434
+ } //CreateNewWorkItem
435
+ }