nitor 1.2.3 → 1.3.1

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/CHANGELOG.md CHANGED
@@ -30,3 +30,11 @@ For a complete list of changes and discussion, see [Issue #1](https://github.com
30
30
  - Added time entry commands.
31
31
 
32
32
  - [Issue #5](https://github.com/codebynithin/nitor/issues/5)
33
+
34
+ ## [1.3.0] - 2025-11-29
35
+
36
+ ### New Features
37
+
38
+ - Added support for task stats and get task commands.
39
+
40
+ - [Issue #7](https://github.com/codebynithin/nitor/issues/7)
package/README.md CHANGED
@@ -26,6 +26,9 @@ A CLI utility toolkit for automating and managing build, deploy, and status oper
26
26
  - Cleanup local git branches
27
27
  - Time entry management with Zoho integration
28
28
  - GitLab activity tracking
29
+ - Task statistics with merge request details
30
+ - Extract Zoho task IDs from GitLab issue descriptions
31
+ - Merge request status tracking for active tasks
29
32
 
30
33
  ## Requirements
31
34
 
@@ -36,6 +39,7 @@ A CLI utility toolkit for automating and managing build, deploy, and status oper
36
39
  - `COOKIE` - Cookie for Gitlab (Copy from browser)
37
40
  - `GITLAB_URI` - GitLab API URL, eg: `https://gitlab.com/`
38
41
  - `GITLAB_TOKEN` - Gitlab token
42
+ - `GITLAB_DEFAULT_PROJECT_ID` - Default GitLab project ID for issue lookups
39
43
  - `MR_PROMPT` - Merge request prompt
40
44
  - `MR_LANG` - Merge request language
41
45
  - `AI_API_KEY` - AI API key
@@ -155,6 +159,26 @@ Once enabled, you can use Tab to autocomplete:
155
159
  ```bash
156
160
  nitor time-zoho
157
161
  ```
162
+ - **Time Entry - GitLab Activities:**
163
+ ```bash
164
+ nitor time-gitlab -from <YYYY-MM-DD> -to <YYYY-MM-DD>
165
+ ```
166
+ - **Time Entry - Merge Request Status:**
167
+ ```bash
168
+ nitor time-merge
169
+ ```
170
+ - **Time Entry - Switch Project:**
171
+ ```bash
172
+ nitor time-switch
173
+ ```
174
+ - **Task Stats:**
175
+ ```bash
176
+ nitor task-stats -task <task numbers with space>
177
+ ```
178
+ - **Get Task (Extract Zoho Task IDs):**
179
+ ```bash
180
+ nitor get-task -task <task numbers with space>
181
+ ```
158
182
 
159
183
  ### Command Reference
160
184
 
@@ -178,6 +202,11 @@ Once enabled, you can use Tab to autocomplete:
178
202
  - `time-entries` : View time entries by date range
179
203
  - `time-stats` : View daily statistics of time entries
180
204
  - `time-zoho` : Sync time entries to Zoho
205
+ - `time-gitlab` : Get GitLab activities for a date range
206
+ - `time-merge` : View merge request status for active tasks
207
+ - `time-switch` : Switch between default projects
208
+ - `task-stats` : View task statistics with GitLab merge request details
209
+ - `get-task` : Extract Zoho task IDs from GitLab issue descriptions
181
210
 
182
211
  ### Options
183
212
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nitor",
3
- "version": "1.2.3",
3
+ "version": "1.3.1",
4
4
  "description": "A comprehensive CLI toolkit for automating GitLab operations, AI-powered code review, build/deploy automation, MongoDB backup/restore, and developer productivity tools",
5
5
  "main": "index.js",
6
6
  "author": "Nithin V <mails2nithin@gmail.com>",
@@ -11,6 +11,8 @@ module.exports = {
11
11
  REFACTOR: 'refactor',
12
12
  REVIEW: 'review',
13
13
  VERSION: 'version',
14
+ TASK_STATS: 'task-stats',
15
+ GET_TASK: 'get-task',
14
16
 
15
17
  // Time entry commands
16
18
  TIME_INIT: 'time-init',
@@ -11,13 +11,19 @@ const { merge } = require('./merge');
11
11
  const { cleanup } = require('./cleanup');
12
12
 
13
13
  // Time entry imports
14
- const { removeEmpty } = require('./time-entry/utils');
14
+ const { removeEmpty, getSprints } = require('./time-entry/utils');
15
15
  const { getStatus, getTasksByDate } = require('./time-entry/get-report');
16
16
  const { logTaskHoursAndSync } = require('./time-entry/log-task-hours-and-sync');
17
17
  const { addNewTask } = require('./time-entry/add-task');
18
18
  const { updateTask, deleteTask } = require('./time-entry/update-delete-task');
19
19
  const { getGitlabActivities } = require('./time-entry/get-gitlab-activities');
20
20
  const { getZohoTasks } = require('./time-entry/get-zoho-tasks');
21
+ const {
22
+ getTaskStats,
23
+ getGitIdStats,
24
+ getGitlabIssueMergeRequests,
25
+ getGitMergeRequestDetails,
26
+ } = require('./task-stats');
21
27
 
22
28
  const processArgs = async (type, value) => {
23
29
  try {
@@ -280,6 +286,105 @@ ${cyan}${bold}╔═════════════════════
280
286
  break;
281
287
  }
282
288
 
289
+ case ACTIONS.TASK_STATS: {
290
+ if (value === '-help' || value === '--h') {
291
+ console.log(`usage: \tnu task-stats [-task <task number>]
292
+ \tnu task-stats [-t <task number>]
293
+
294
+ View task stats
295
+
296
+ Options:
297
+ -t, --task <number> task number`);
298
+
299
+ return;
300
+ }
301
+
302
+ if (values.sprint) {
303
+ const sprints = await getSprints({ params: {} });
304
+ const taskDetails = await getZohoTasks({
305
+ params: { sprint: sprints.find(({ label }) => label === values.sprint)?.value },
306
+ });
307
+
308
+ values.task = taskDetails.map(({ taskId }) => taskId);
309
+ } else {
310
+ values.task = values.task.split(' ');
311
+ }
312
+
313
+ // Process all tasks in parallel
314
+ const taskResults = await Promise.all(
315
+ values.task.map(async (task) => {
316
+ const taskDetail = await getTaskStats(task);
317
+
318
+ if (!taskDetail?.itemIds) {
319
+ return [];
320
+ }
321
+
322
+ const gitIdDetails = await getGitIdStats(taskDetail.itemIds);
323
+
324
+ if (!gitIdDetails?.length) {
325
+ return [];
326
+ }
327
+
328
+ const mrDetails = await getGitlabIssueMergeRequests(gitIdDetails);
329
+
330
+ return mrDetails.map((mrDetail) => ({
331
+ Task: task,
332
+ Owner: taskDetail.owner,
333
+ ...mrDetail,
334
+ }));
335
+ }),
336
+ );
337
+
338
+ // Flatten the results
339
+ const list = taskResults.flat();
340
+
341
+ console.table(list);
342
+
343
+ break;
344
+ }
345
+
346
+ case ACTIONS.GET_TASK: {
347
+ if (value === '-help' || value === '--h') {
348
+ console.log(`usage: \tnu get-task [-task <task numbers with space>]
349
+ \tnu get-task [-t <task numbers with space>]
350
+
351
+ Get task details
352
+
353
+ Options:
354
+ -t, --task <numbers with space> task numbers with space`);
355
+
356
+ return;
357
+ }
358
+
359
+ if (!values.task) {
360
+ console.log('Task number is required');
361
+
362
+ process.exit(1);
363
+ }
364
+
365
+ const tasks = {};
366
+
367
+ for (const task of values.task.split(' ')) {
368
+ const taskDetails = await getGitMergeRequestDetails(task);
369
+
370
+ if (taskDetails.error) {
371
+ console.log(`No merge requests found for task ${task}`);
372
+
373
+ continue;
374
+ }
375
+
376
+ for (const taskDetail of taskDetails) {
377
+ const zohoTaskMatch = taskDetail.description?.match(/itemdetails\/(I\d+)\)/);
378
+
379
+ tasks[task] = zohoTaskMatch ? zohoTaskMatch[1] : 'Not found';
380
+ }
381
+ }
382
+
383
+ console.log(tasks);
384
+
385
+ break;
386
+ }
387
+
283
388
  // Time entry commands
284
389
  case ACTIONS.TIME_ADD: {
285
390
  const timeValues = value ? removeEmpty(value?.split(' -')) : value;
@@ -409,9 +514,11 @@ Available commands:\n
409
514
  completion : Setup shell autocomplete
410
515
  create-branch : Create git branch
411
516
  deploy : Deploy specified components
517
+ get-task : Get task details
412
518
  merge : Merge source branch into target branch
413
519
  refactor : Refactor the provided text for improved clarity, conciseness, and professional quality
414
520
  review : AI Review specified merge request
521
+ task-stats : View task statistics
415
522
  version : Show version info
416
523
  help : Show help
417
524
 
@@ -422,7 +529,7 @@ Time Entry commands:
422
529
  time-entries : View time entries by date
423
530
  time-gitlab : Get GitLab activities
424
531
  time-merge : View merge request status for tasks
425
- time-stats : View daily status of time entries
532
+ time-stats : View daily status of time entries
426
533
  time-switch : Switch between default projects
427
534
  time-update : Update existing time entry
428
535
  time-zoho : Sync time entries to Zoho
@@ -7,6 +7,7 @@ const executeMergeRequestReview = async (values) => {
7
7
  maxBodyLength: Infinity,
8
8
  url: `${mrApiUri}/${projectIdMap[values.project]}/mergeid/${values.mergeId}`,
9
9
  headers: { 'Content-Type': 'application/json' },
10
+ timeout: 10 * 60 * 1000, // 10 minutes
10
11
  data: JSON.stringify({
11
12
  language: mrLang,
12
13
  gitlabToken: gitlabConfig.token,
@@ -0,0 +1,196 @@
1
+ const axios = require('axios');
2
+ const { zohoConfig, gitlabConfig } = require('./utils');
3
+
4
+ const getZohoUrl = (type, taskNumber) => {
5
+ switch (type) {
6
+ case 'task':
7
+ return `${zohoConfig.url}/zsapi/team/${zohoConfig.team}/projects/${zohoConfig.defaultProjectId}/item/no-${taskNumber}/?action=details`;
8
+
9
+ case 'gitId':
10
+ return `${zohoConfig.url}/zsapi/team/${zohoConfig.team}/projects/${zohoConfig.defaultProjectId}/item/${taskNumber}/scm/3/issuedetails/?action=scmissuedetails`;
11
+ }
12
+ };
13
+
14
+ const getZohoConfig = (type, taskNumber) => {
15
+ return {
16
+ method: 'get',
17
+ maxBodyLength: Infinity,
18
+ url: getZohoUrl(type, taskNumber),
19
+ headers: {
20
+ 'User-Agent':
21
+ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0',
22
+ Accept: '*/*',
23
+ 'Accept-Language': 'en-GB,en;q=0.5',
24
+ 'Accept-Encoding': 'gzip, deflate, br, zstd',
25
+ Referer: `${zohoConfig.url}/workspace/4medica/client/wmoku`,
26
+ 'X-ZA-REQSIZE': 'large',
27
+ 'X-Requested-With': 'XMLHttpRequest',
28
+ 'X-ZA-SOURCE': zohoConfig.source,
29
+ 'X-ZA-UI-VERSION': 'v2',
30
+ 'X-ZCSRF-TOKEN': zohoConfig.token,
31
+ 'X-ZA-CLIENTPORTALID': zohoConfig.portalId,
32
+ 'X-ZA-SESSIONID': zohoConfig.sessionId,
33
+ Connection: 'keep-alive',
34
+ Cookie: zohoConfig.cookie,
35
+ 'Sec-Fetch-Dest': 'empty',
36
+ 'Sec-Fetch-Mode': 'cors',
37
+ 'Sec-Fetch-Site': 'same-origin',
38
+ Priority: 'u=0',
39
+ Pragma: 'no-cache',
40
+ 'Cache-Control': 'no-cache',
41
+ TE: 'trailers',
42
+ },
43
+ };
44
+ };
45
+
46
+ const getGitlabConfig = (url) => {
47
+ return {
48
+ method: 'get',
49
+ maxBodyLength: Infinity,
50
+ url,
51
+ headers: {
52
+ 'User-Agent':
53
+ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:145.0) Gecko/20100101 Firefox/145.0',
54
+ Accept: 'application/json',
55
+ 'Accept-Language': 'en-GB,en;q=0.5',
56
+ 'Accept-Encoding': 'gzip, deflate, br, zstd',
57
+ 'PRIVATE-TOKEN': gitlabConfig.token,
58
+ Connection: 'keep-alive',
59
+ Cookie: gitlabConfig.cookie,
60
+ },
61
+ };
62
+ };
63
+
64
+ const getTaskStats = async (task) => {
65
+ try {
66
+ const config = getZohoConfig('task', task);
67
+ const response = await axios.request(config);
68
+
69
+ return {
70
+ itemIds: response.data.itemIds,
71
+ owner: Object.values(response.data.userDisplayName).join(', '),
72
+ };
73
+ } catch (error) {
74
+ console.log(error);
75
+ }
76
+ };
77
+
78
+ const getGitIdStats = async (gitIds) => {
79
+ const gitIdStats = [];
80
+
81
+ for (const gitId of gitIds) {
82
+ try {
83
+ const config = getZohoConfig('gitId', gitId);
84
+ const response = await axios.request(config);
85
+
86
+ gitIdStats.push(response.data);
87
+ } catch (error) {}
88
+ }
89
+
90
+ return gitIdStats;
91
+ };
92
+
93
+ const getGitlabIssueDetails = async (projectId, issueIid) => {
94
+ try {
95
+ const config = getGitlabConfig(`${projectId}/issues/${issueIid}`);
96
+ const response = await axios.request(config);
97
+
98
+ return response.data;
99
+ } catch (error) {
100
+ console.error('Error fetching GitLab issue details:', error.message);
101
+ if (error.response) {
102
+ console.error('Response status:', error.response.status);
103
+ console.error('Response data:', error.response.data);
104
+ }
105
+ throw error;
106
+ }
107
+ };
108
+
109
+ const getGitMergeRequestDetails = async (issueIid, projectId) => {
110
+ try {
111
+ if (!projectId) {
112
+ projectId = `${gitlabConfig.url}/api/v4/projects/${gitlabConfig.defaultProjectId}`;
113
+ }
114
+
115
+ const config = getGitlabConfig(`${projectId}/issues/${issueIid}/related_merge_requests`);
116
+ const response = await axios.request(config);
117
+
118
+ return response.data;
119
+ } catch (error) {
120
+ return { error };
121
+ }
122
+ };
123
+
124
+ const getGitlabIssueMergeRequests = async (gitDetails) => {
125
+ for (const gitDetail of gitDetails) {
126
+ try {
127
+ const mergeRequests = await getGitMergeRequestDetails(
128
+ gitDetail.iid,
129
+ gitDetail._links.project,
130
+ );
131
+ const detailedMRs = await Promise.all(
132
+ mergeRequests.map(async (mr) => {
133
+ try {
134
+ const detailConfig = getGitlabConfig(
135
+ `${gitlabConfig.url}/api/v4/projects/${mr.project_id}/merge_requests/${mr.iid}`,
136
+ );
137
+ const detailResponse = await axios.request(detailConfig);
138
+ const mrData = detailResponse.data;
139
+
140
+ // Fetch approval details separately
141
+ try {
142
+ const approvalConfig = getGitlabConfig(
143
+ `${gitlabConfig.url}/api/v4/projects/${mr.project_id}/merge_requests/${mr.iid}/approvals`,
144
+ );
145
+ const approvalResponse = await axios.request(approvalConfig);
146
+ const approvalData = approvalResponse.data;
147
+
148
+ // Merge approval data with MR data
149
+ return {
150
+ IssueID: gitDetail.iid,
151
+ MRID: mrData.iid,
152
+ MRAssignedTo: mrData.assignee?.name,
153
+ MRPointedTo: mrData.target_branch,
154
+ Repo: mr.reference?.split('!')?.[0],
155
+ ApprovedBy:
156
+ (approvalData.approved_by || [])
157
+ .map((approvedBy) => approvedBy?.user?.name || '')
158
+ ?.join(', ') || 'Not Approved',
159
+ ApprovedCount: approvalData.approved_by?.length || 0,
160
+ MergedBy: mrData.merged_by?.name || 'Not Merged',
161
+ MergedOn: mrData.merged_at?.split('T')?.[0] || 'Not Merged',
162
+ };
163
+ } catch (approvalError) {
164
+ console.error(`Error fetching approvals for MR ${mr.iid}:`, approvalError.message);
165
+ // Return MR data without approval details if approval fetch fails
166
+ return mrData;
167
+ }
168
+ } catch (error) {
169
+ console.error(`Error fetching details for MR ${mr.iid}:`, error.message);
170
+ // Return the basic MR data if detailed fetch fails
171
+ return mr;
172
+ }
173
+ }),
174
+ );
175
+
176
+ return detailedMRs;
177
+ } catch (error) {
178
+ console.error('Error fetching GitLab issue merge requests:', error.message);
179
+
180
+ if (error.response) {
181
+ console.error('Response status:', error.response.status);
182
+ console.error('Response data:', error.response.data);
183
+ }
184
+
185
+ throw error;
186
+ }
187
+ }
188
+ };
189
+
190
+ module.exports = {
191
+ getTaskStats,
192
+ getGitIdStats,
193
+ getGitlabIssueDetails,
194
+ getGitlabIssueMergeRequests,
195
+ getGitMergeRequestDetails,
196
+ };
@@ -2,25 +2,61 @@ const axios = require('axios');
2
2
  const cheerio = require('cheerio');
3
3
  const { gitlabConfig } = require('../utils');
4
4
 
5
+ /**
6
+ * Fetches GitLab activities for a date range
7
+ * Defaults to last one week if no values are provided
8
+ * @param {Array} values - Optional array of filter values (e.g., ['-from 2024-11-21', '-to 2024-11-28'])
9
+ * @returns {Object} Object with dates as keys and activities grouped by action
10
+ */
5
11
  const getGitlabActivities = async (values) => {
6
12
  const resp = {};
13
+ const res = [];
7
14
  const filters = getFilters(values);
8
15
  const startDate = new Date(filters.from);
9
16
 
17
+ // Iterate through each date in the range
10
18
  while (startDate <= new Date(filters.to)) {
11
19
  const date = startDate.toISOString().split('T')[0];
12
20
  const activities = await getGitlabActivitiesByDate(date);
13
21
 
14
- if (activities?.length) {
22
+ /* if (activities?.length) {
15
23
  resp[date] = arrayToObjectByKey(activities, 'action');
16
- }
24
+ } */
25
+ res.push(...activities);
17
26
 
18
27
  startDate.setDate(startDate.getDate() + 1);
19
28
  }
20
29
 
21
- console.log(resp);
30
+ // Format and display each entry in a single line with ellipses
31
+ const truncate = (str, maxLen = 50) => {
32
+ if (!str) return '';
33
+ return str.length > maxLen ? str.substring(0, maxLen - 3) + '...' : str;
34
+ };
35
+
36
+ console.log('\n📊 GitLab Activities (Last Week)\n');
37
+ console.log(
38
+ `\n${'index'.toString().padStart(8)} | ${'date'.toString().padStart(10)} ${'time'.toString().padEnd(8) || ''.padEnd(8)} | ${'action'.toString().padEnd(18)} | ${'text'.toString().padEnd(100)} | ${'project'.toString().padEnd(25)}`,
39
+ );
40
+ res.forEach((activity, index) => {
41
+ const { date, time, action, text, project } = activity;
42
+ const formattedText = truncate(text, 100);
43
+ const formattedAction = action?.padEnd(18) || ''.padEnd(18);
44
+ const formattedProject = truncate(project, 25);
45
+
46
+ console.log(
47
+ `${(index + 1).toString().padStart(8)} | ${date} ${time?.padEnd(8) || ''.padEnd(8)} | ${formattedAction} | ${formattedText.padEnd(100)} | ${formattedProject}`,
48
+ );
49
+ });
50
+ console.log(`\n✅ Total: ${res.length} activities\n`);
51
+
22
52
  return resp;
23
53
  };
54
+
55
+ /**
56
+ * Parses filter values or sets default to last one week
57
+ * @param {Array} values - Array of filter strings
58
+ * @returns {Object} Object with 'from' and 'to' date strings
59
+ */
24
60
  const getFilters = (values) => {
25
61
  const filters = {};
26
62
  const keyMap = {
@@ -31,10 +67,12 @@ const getFilters = (values) => {
31
67
  };
32
68
 
33
69
  if (values?.length) {
70
+ // Parse provided filter values
34
71
  for (const item of values) {
35
72
  let [key, ...itemValues] = item.split(' ');
36
73
  const itemValue = itemValues.join(' ');
37
74
 
75
+ // Remove leading dash if present
38
76
  if (key.charAt(0) === '-') {
39
77
  key = key.substring(1);
40
78
  }
@@ -46,6 +84,7 @@ const getFilters = (values) => {
46
84
  }
47
85
  }
48
86
  } else {
87
+ // Default: last one week
49
88
  filters.from = new Date(new Date().setDate(new Date().getDate() - 7))
50
89
  .toISOString()
51
90
  .split('T')[0];
@@ -54,8 +93,13 @@ const getFilters = (values) => {
54
93
 
55
94
  return filters;
56
95
  };
96
+
97
+ /**
98
+ * Fetches GitLab activities for a specific date
99
+ * @param {string} date - Date in YYYY-MM-DD format
100
+ * @returns {Array} Array of activity objects
101
+ */
57
102
  const getGitlabActivitiesByDate = async (date) => {
58
- const { removeEmpty } = require('./utils');
59
103
  const gitlabUrl = `${gitlabConfig.url}/users/${gitlabConfig.userId}/calendar_activities?date=${date}`;
60
104
  const headers = {
61
105
  accept: 'application/json, text/plain, */*',
@@ -71,7 +115,6 @@ const getGitlabActivitiesByDate = async (date) => {
71
115
  'x-csrf-token': gitlabConfig.xCsrfToken,
72
116
  'x-requested-with': 'XMLHttpRequest',
73
117
  };
74
- // let config = { method: 'get', maxBodyLength: Infinity, url: `${gitlabUrl}2024-5-10`, headers };
75
118
 
76
119
  try {
77
120
  const response = await axios.get(gitlabUrl, { headers });
@@ -79,45 +122,39 @@ const getGitlabActivitiesByDate = async (date) => {
79
122
  const $ = cheerio.load(response.data);
80
123
 
81
124
  // Initialize an empty array to store the JSON objects
82
- let contributions = [];
125
+ const contributions = [];
83
126
 
84
127
  // Iterate over each list item
85
- $('ul.bordered-list li').each((i, element) => {
128
+ $('.event-item').each((i, element) => {
86
129
  const $element = $(element);
87
- const time = $element.find('span.js-localtime').text().trim();
88
- const action = $element
89
- .contents()
90
- .filter(function () {
91
- return this.nodeType === 3; // Text nodes
92
- })
93
- .text()
94
- .trim()
95
- .split(/\n/g)[0]
96
- .trim();
97
- const detailsArray = $element
98
- .find('a')
99
- .map((i, el) => {
100
- return {
101
- title: $(el).attr('title'),
102
- href: $(el).attr('href').split(/\/-\//g)[1],
103
- text: $(el).text().trim().replace(/!/g, ''),
104
- };
105
- })
106
- .get();
107
- const details = detailsArray.reduce((acc, item) => {
108
- if (item.title === 'medica-portal-client') {
109
- acc.repo = item.title;
110
- } else {
111
- acc = removeEmpty(item);
112
- }
113
-
114
- return acc;
115
- }, {});
130
+ const time = $element.find('.event-item-timestamp').text()?.trim();
131
+ const action = $element.find('.event-title-block .event-type').text()?.trim();
132
+ const project = $element.find('.event-title-block .project-name').text()?.trim();
133
+ const $refLink = $element.find('.event-title-block a.ref-name');
134
+ const $targetLink = $element.find('.event-title-block a.event-target-link');
135
+
136
+ let href, text;
137
+
138
+ if ($refLink.length > 0) {
139
+ href = $refLink.attr('href');
140
+ text = $refLink.text()?.trim();
141
+ } else if ($targetLink.length > 0) {
142
+ href = $targetLink.attr('href');
143
+ text = $targetLink.text()?.trim();
144
+ } else {
145
+ const $eventTypeSpan = $element.find('.event-title-block .event-type');
146
+ const nextSpan = $eventTypeSpan.next('span');
147
+
148
+ text = nextSpan.text()?.trim();
149
+ href = undefined;
150
+ }
116
151
 
117
152
  contributions.push({
118
153
  time,
119
154
  action,
120
- ...details,
155
+ text,
156
+ project,
157
+ date,
121
158
  });
122
159
  });
123
160
 
@@ -126,12 +163,5 @@ const getGitlabActivitiesByDate = async (date) => {
126
163
  console.log(error.message);
127
164
  }
128
165
  };
129
- const arrayToObjectByKey = (arr, key) => {
130
- return arr.reduce((acc, obj) => {
131
- acc[obj[key]] = obj;
132
-
133
- return acc;
134
- }, {});
135
- };
136
166
 
137
167
  module.exports = { getGitlabActivities };
@@ -78,4 +78,4 @@ const checkSprintId = async (id, req) => {
78
78
  return sprints.some(({ value }) => value === id);
79
79
  };
80
80
 
81
- module.exports = { getZohoTasks };
81
+ module.exports = { getZohoTasks, getTasksBySprint };
package/services/utils.js CHANGED
@@ -17,6 +17,7 @@ const gitlabConfig = {
17
17
  xCsrfToken: process.env.GITLAB_XCSRF_TOKEN,
18
18
  userId: process.env.GITLAB_USERID,
19
19
  token: process.env.GITLAB_TOKEN,
20
+ defaultProjectId: process.env.GITLAB_DEFAULT_PROJECT_ID,
20
21
  };
21
22
  const zohoConfig = {
22
23
  cookie: process.env.ZOHO_COOKIE,
@@ -58,6 +59,8 @@ const keyMap = {
58
59
  ta: 'target',
59
60
  docker: 'docker',
60
61
  do: 'docker',
62
+ sprint: 'sprint',
63
+ s: 'sprint',
61
64
  };
62
65
  const projectMap = {
63
66
  portal: 'medica-portal',
@@ -299,26 +302,16 @@ const generateDeployConfigs = (values = {}) => {
299
302
  return { configs: removeEmpty(configs, true) };
300
303
  };
301
304
  const convertParamsToMap = async (item, type) => {
302
- const itemsToSkipCheck = [
303
- ACTIONS.CREATE_BRANCH,
304
- ACTIONS.HELP,
305
- ACTIONS.VERSION,
306
- ACTIONS.REFACTOR,
307
- ACTIONS.BACKUP,
305
+ const itemsToCheckLiveness = [
306
+ ACTIONS.BUILD_DEPLOY,
307
+ ACTIONS.BUILD,
308
+ ACTIONS.DEPLOY,
308
309
  ACTIONS.MERGE,
309
- ACTIONS.TIME_ADD,
310
- ACTIONS.TIME_UPDATE,
311
- ACTIONS.TIME_DELETE,
312
- ACTIONS.TIME_STATUS,
313
- ACTIONS.TIME_ENTRIES,
314
- ACTIONS.TIME_ZOHO,
315
- ACTIONS.TIME_GITLAB,
316
- ACTIONS.TIME_MERGE,
310
+ ACTIONS.REVIEW,
317
311
  ];
318
- const skipCheck = itemsToSkipCheck.includes(type);
319
312
  let live = false;
320
313
 
321
- if (!skipCheck) {
314
+ if (itemsToCheckLiveness.includes(type)) {
322
315
  if (!gitlabConfig.token) {
323
316
  console.log('Configurations are missing...!');
324
317
  return null;
@@ -1,16 +0,0 @@
1
- module.exports = {
2
- ACTIONS: {
3
- INIT: 'init',
4
- SWITCH: 'switch',
5
- ADD: 'add',
6
- UPDATE: 'update',
7
- DELETE: 'delete',
8
- STATUS: 'status',
9
- ENTRIES: 'entries',
10
- ZOHO: 'zoho',
11
- GITLAB: 'gitlab',
12
- MERGE: 'merge',
13
- VERSION: 'version',
14
- HELP: 'help',
15
- },
16
- };