projectpulse-mcp 1.5.0 → 1.5.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.
Files changed (45) hide show
  1. package/package.json +6 -4
  2. package/dist/analytics/dora.test.d.ts +0 -2
  3. package/dist/analytics/dora.test.d.ts.map +0 -1
  4. package/dist/analytics/dora.test.js +0 -164
  5. package/dist/analytics/dora.test.js.map +0 -1
  6. package/dist/scoring/health-score.test.d.ts +0 -2
  7. package/dist/scoring/health-score.test.d.ts.map +0 -1
  8. package/dist/scoring/health-score.test.js +0 -249
  9. package/dist/scoring/health-score.test.js.map +0 -1
  10. package/dist/security/openssf-client.test.d.ts +0 -2
  11. package/dist/security/openssf-client.test.d.ts.map +0 -1
  12. package/dist/security/openssf-client.test.js +0 -70
  13. package/dist/security/openssf-client.test.js.map +0 -1
  14. package/dist/tools/analyze-code-scanning.test.d.ts +0 -2
  15. package/dist/tools/analyze-code-scanning.test.d.ts.map +0 -1
  16. package/dist/tools/analyze-code-scanning.test.js +0 -72
  17. package/dist/tools/analyze-code-scanning.test.js.map +0 -1
  18. package/dist/tools/analyze-dependencies.test.d.ts +0 -2
  19. package/dist/tools/analyze-dependencies.test.d.ts.map +0 -1
  20. package/dist/tools/analyze-dependencies.test.js +0 -65
  21. package/dist/tools/analyze-dependencies.test.js.map +0 -1
  22. package/dist/tools/check-ci-status.test.d.ts +0 -2
  23. package/dist/tools/check-ci-status.test.d.ts.map +0 -1
  24. package/dist/tools/check-ci-status.test.js +0 -90
  25. package/dist/tools/check-ci-status.test.js.map +0 -1
  26. package/dist/tools/compare-repos.test.d.ts +0 -2
  27. package/dist/tools/compare-repos.test.d.ts.map +0 -1
  28. package/dist/tools/compare-repos.test.js +0 -138
  29. package/dist/tools/compare-repos.test.js.map +0 -1
  30. package/dist/tools/get-dora-metrics.test.d.ts +0 -2
  31. package/dist/tools/get-dora-metrics.test.d.ts.map +0 -1
  32. package/dist/tools/get-dora-metrics.test.js +0 -71
  33. package/dist/tools/get-dora-metrics.test.js.map +0 -1
  34. package/dist/tools/get-health-score.test.d.ts +0 -2
  35. package/dist/tools/get-health-score.test.d.ts.map +0 -1
  36. package/dist/tools/get-health-score.test.js +0 -130
  37. package/dist/tools/get-health-score.test.js.map +0 -1
  38. package/dist/tools/get-repo-health.test.d.ts +0 -2
  39. package/dist/tools/get-repo-health.test.d.ts.map +0 -1
  40. package/dist/tools/get-repo-health.test.js +0 -80
  41. package/dist/tools/get-repo-health.test.js.map +0 -1
  42. package/dist/vitest.config.d.ts +0 -3
  43. package/dist/vitest.config.d.ts.map +0 -1
  44. package/dist/vitest.config.js +0 -7
  45. package/dist/vitest.config.js.map +0 -1
@@ -1,72 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
- import { getOctokit } from '../github/client.js';
3
- import { executeAnalyzeCodeScanning } from './analyze-code-scanning.js';
4
- vi.mock('../github/client.js');
5
- describe('executeAnalyzeCodeScanning', () => {
6
- beforeEach(() => {
7
- vi.resetAllMocks();
8
- });
9
- it('should return code scanning alerts', async () => {
10
- const mockAlerts = [
11
- {
12
- number: 1,
13
- created_at: '2026-08-28T10:00:00Z',
14
- rule: { id: 'js/sql-injection', severity: 'error', description: 'SQL Injection' },
15
- state: 'open',
16
- most_recent_instance: {
17
- message: { text: 'SQL query built from user input' },
18
- location: { path: 'src/db.ts', start_line: 10, end_line: 15 }
19
- },
20
- html_url: 'https://github.com/test/repo/security/code-scanning/1'
21
- }
22
- ];
23
- const mockListAlerts = vi.fn().mockResolvedValue({ data: mockAlerts });
24
- vi.mocked(getOctokit).mockReturnValue({
25
- codeScanning: { listAlertsForRepo: mockListAlerts }
26
- });
27
- const result = await executeAnalyzeCodeScanning({ owner: 'test', repo: 'repo', trigger_scan: false, poll_timeout_seconds: 300, poll_interval_seconds: 15 });
28
- expect(mockListAlerts).toHaveBeenCalledWith({ owner: 'test', repo: 'repo', state: 'open' });
29
- expect(result.content).toHaveLength(1);
30
- expect(result.content[0].type).toBe('text');
31
- const parsedText = JSON.parse(result.content[0].text);
32
- expect(parsedText.alerts).toHaveLength(1);
33
- expect(parsedText.alerts[0]).toEqual({
34
- alert_number: 1,
35
- rule_id: 'js/sql-injection',
36
- severity: 'error',
37
- rule_description: 'SQL Injection',
38
- state: 'open',
39
- message_text: 'SQL query built from user input',
40
- most_recent_instance_path: 'src/db.ts',
41
- most_recent_instance_start_line: 10,
42
- end_line: 15,
43
- created_at: '2026-08-28T10:00:00Z',
44
- html_url: 'https://github.com/test/repo/security/code-scanning/1'
45
- });
46
- });
47
- it('should handle 404 when code scanning is not configured', async () => {
48
- const notFoundError = new Error('Not Found');
49
- notFoundError.status = 404;
50
- const mockListAlerts = vi.fn().mockRejectedValue(notFoundError);
51
- vi.mocked(getOctokit).mockReturnValue({
52
- codeScanning: { listAlertsForRepo: mockListAlerts }
53
- });
54
- const result = await executeAnalyzeCodeScanning({ owner: 'test', repo: 'repo', trigger_scan: false, poll_timeout_seconds: 300, poll_interval_seconds: 15 });
55
- expect(result.content).toHaveLength(1);
56
- expect(result.content[0].type).toBe('text');
57
- const parsedText = JSON.parse(result.content[0].text);
58
- expect(parsedText.message).toBe("Code scanning not configured on this repo");
59
- });
60
- it('should throw error for non-404 API failures', async () => {
61
- const serverError = new Error('Server Error');
62
- serverError.status = 500;
63
- const mockListAlerts = vi.fn().mockRejectedValue(serverError);
64
- vi.mocked(getOctokit).mockReturnValue({
65
- codeScanning: { listAlertsForRepo: mockListAlerts }
66
- });
67
- await expect(executeAnalyzeCodeScanning({ owner: 'test', repo: 'repo', trigger_scan: false, poll_timeout_seconds: 300, poll_interval_seconds: 15 }))
68
- .rejects
69
- .toThrow('Server Error');
70
- });
71
- });
72
- //# sourceMappingURL=analyze-code-scanning.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"analyze-code-scanning.test.js","sourceRoot":"","sources":["../../src/tools/analyze-code-scanning.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=analyze-dependencies.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"analyze-dependencies.test.d.ts","sourceRoot":"","sources":["../../src/tools/analyze-dependencies.test.ts"],"names":[],"mappings":""}
@@ -1,65 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
- import { getOctokit } from '../github/client.js';
3
- import { executeAnalyzeDependencies } from './analyze-dependencies.js';
4
- vi.mock('../github/client.js');
5
- describe('executeAnalyzeDependencies', () => {
6
- beforeEach(() => {
7
- vi.resetAllMocks();
8
- });
9
- const mockAlerts = [
10
- {
11
- security_advisory: { summary: 'Critical bug', severity: 'critical' },
12
- dependency: { package: { name: 'lodash' } },
13
- state: 'open',
14
- html_url: 'https://github.com/advisory/1'
15
- },
16
- {
17
- security_advisory: { summary: 'High bug', severity: 'high' },
18
- dependency: { package: { name: 'express' } },
19
- state: 'fixed',
20
- html_url: 'https://github.com/advisory/2'
21
- },
22
- {
23
- security_advisory: { summary: 'Another High bug', severity: 'high' },
24
- dependency: { package: { name: 'react' } },
25
- state: 'open',
26
- html_url: 'https://github.com/advisory/3'
27
- }
28
- ];
29
- it('should return all dependencies if no severity is provided', async () => {
30
- const mockListAlerts = vi.fn().mockResolvedValue({ data: mockAlerts });
31
- vi.mocked(getOctokit).mockReturnValue({
32
- dependabot: { listAlertsForRepo: mockListAlerts }
33
- });
34
- const result = await executeAnalyzeDependencies({ owner: 'test', repo: 'repo' });
35
- expect(mockListAlerts).toHaveBeenCalledWith({ owner: 'test', repo: 'repo' });
36
- expect(result.content).toHaveLength(1);
37
- expect(result.content[0].type).toBe('text');
38
- const parsedText = JSON.parse(result.content[0].text);
39
- expect(parsedText).toHaveLength(3);
40
- expect(parsedText[0].severity).toBe('critical');
41
- expect(parsedText[1].severity).toBe('high');
42
- expect(parsedText[2].severity).toBe('high');
43
- });
44
- it('should return filtered dependencies if severity is provided', async () => {
45
- const mockListAlerts = vi.fn().mockResolvedValue({ data: mockAlerts });
46
- vi.mocked(getOctokit).mockReturnValue({
47
- dependabot: { listAlertsForRepo: mockListAlerts }
48
- });
49
- const result = await executeAnalyzeDependencies({ owner: 'test', repo: 'repo', severity: 'high' });
50
- const parsedText = JSON.parse(result.content[0].text);
51
- expect(parsedText).toHaveLength(2);
52
- expect(parsedText[0].package_name).toBe('express');
53
- expect(parsedText[1].package_name).toBe('react');
54
- });
55
- it('should throw an error if API fails', async () => {
56
- const mockListAlerts = vi.fn().mockRejectedValue(new Error('API Error'));
57
- vi.mocked(getOctokit).mockReturnValue({
58
- dependabot: { listAlertsForRepo: mockListAlerts }
59
- });
60
- await expect(executeAnalyzeDependencies({ owner: 'test', repo: 'repo' }))
61
- .rejects
62
- .toThrow('API Error');
63
- });
64
- });
65
- //# sourceMappingURL=analyze-dependencies.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"analyze-dependencies.test.js","sourceRoot":"","sources":["../../src/tools/analyze-dependencies.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=check-ci-status.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"check-ci-status.test.d.ts","sourceRoot":"","sources":["../../src/tools/check-ci-status.test.ts"],"names":[],"mappings":""}
@@ -1,90 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
- import { getOctokit } from '../github/client.js';
3
- import { executeCheckCiStatus } from './check-ci-status.js';
4
- vi.mock('../github/client.js');
5
- describe('executeCheckCiStatus', () => {
6
- beforeEach(() => {
7
- vi.resetAllMocks();
8
- });
9
- it('should return recent workflow runs', async () => {
10
- const mockListRuns = vi.fn().mockResolvedValue({
11
- data: {
12
- workflow_runs: [
13
- {
14
- name: 'CI',
15
- status: 'completed',
16
- conclusion: 'success',
17
- head_branch: 'main',
18
- created_at: '2023-10-01T00:00:00Z',
19
- updated_at: '2023-10-01T00:05:00Z',
20
- html_url: 'https://github.com/test/repo/actions/runs/1',
21
- id: 123
22
- },
23
- {
24
- name: 'CI',
25
- status: 'completed',
26
- conclusion: 'failure',
27
- head_branch: 'feature-branch',
28
- created_at: '2023-10-02T00:00:00Z',
29
- updated_at: '2023-10-02T00:05:00Z',
30
- html_url: 'https://github.com/test/repo/actions/runs/2',
31
- id: 124
32
- }
33
- ]
34
- }
35
- });
36
- vi.mocked(getOctokit).mockReturnValue({
37
- actions: { listWorkflowRunsForRepo: mockListRuns }
38
- });
39
- const result = await executeCheckCiStatus({ owner: 'test', repo: 'repo', limit: 10 });
40
- expect(mockListRuns).toHaveBeenCalledWith({ owner: 'test', repo: 'repo', per_page: 10 });
41
- expect(result.content).toHaveLength(1);
42
- expect(result.content[0].type).toBe('text');
43
- const parsedText = JSON.parse(result.content[0].text);
44
- expect(parsedText).toEqual([
45
- {
46
- name: 'CI',
47
- status: 'completed',
48
- conclusion: 'success',
49
- head_branch: 'main',
50
- created_at: '2023-10-01T00:00:00Z',
51
- updated_at: '2023-10-01T00:05:00Z',
52
- html_url: 'https://github.com/test/repo/actions/runs/1'
53
- },
54
- {
55
- name: 'CI',
56
- status: 'completed',
57
- conclusion: 'failure',
58
- head_branch: 'feature-branch',
59
- created_at: '2023-10-02T00:00:00Z',
60
- updated_at: '2023-10-02T00:05:00Z',
61
- html_url: 'https://github.com/test/repo/actions/runs/2'
62
- }
63
- ]);
64
- });
65
- it('should handle empty workflow runs', async () => {
66
- const mockListRuns = vi.fn().mockResolvedValue({
67
- data: {
68
- workflow_runs: []
69
- }
70
- });
71
- vi.mocked(getOctokit).mockReturnValue({
72
- actions: { listWorkflowRunsForRepo: mockListRuns }
73
- });
74
- const result = await executeCheckCiStatus({ owner: 'test', repo: 'empty-repo', limit: 5 });
75
- expect(mockListRuns).toHaveBeenCalledWith({ owner: 'test', repo: 'empty-repo', per_page: 5 });
76
- const parsedText = JSON.parse(result.content[0].text);
77
- expect(parsedText).toEqual([]);
78
- });
79
- it('should throw error if API fails', async () => {
80
- const error = new Error('API Error');
81
- const mockListRuns = vi.fn().mockRejectedValue(error);
82
- vi.mocked(getOctokit).mockReturnValue({
83
- actions: { listWorkflowRunsForRepo: mockListRuns }
84
- });
85
- await expect(executeCheckCiStatus({ owner: 'test', repo: 'error-repo', limit: 10 }))
86
- .rejects
87
- .toThrow('API Error');
88
- });
89
- });
90
- //# sourceMappingURL=check-ci-status.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"check-ci-status.test.js","sourceRoot":"","sources":["../../src/tools/check-ci-status.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=compare-repos.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"compare-repos.test.d.ts","sourceRoot":"","sources":["../../src/tools/compare-repos.test.ts"],"names":[],"mappings":""}
@@ -1,138 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
- import { executeCompareRepos, inputSchema } from './compare-repos.js';
3
- import { executeGetHealthScore } from './get-health-score.js';
4
- vi.mock('./get-health-score.js');
5
- describe('executeCompareRepos', () => {
6
- beforeEach(() => {
7
- vi.resetAllMocks();
8
- });
9
- it('should retrieve scores, rank repositories correctly including ties, and handle failures gracefully', async () => {
10
- // Mock executeGetHealthScore behavior:
11
- // repo-a: 85 score
12
- // repo-b: 85 score (tie with repo-a)
13
- // repo-c: 70 score (should be rank 3 in standard competition ranking)
14
- // repo-fail: fails
15
- vi.mocked(executeGetHealthScore).mockImplementation(async (repo) => {
16
- if (repo.repo === 'repo-a') {
17
- return {
18
- content: [{
19
- type: 'text',
20
- text: JSON.stringify({
21
- repo: 'test/repo-a',
22
- score: 85,
23
- grade: 'B',
24
- breakdown: {},
25
- suggestions: [],
26
- checkedAt: '2023-10-01T00:00:00Z'
27
- })
28
- }]
29
- };
30
- }
31
- if (repo.repo === 'repo-b') {
32
- return {
33
- content: [{
34
- type: 'text',
35
- text: JSON.stringify({
36
- repo: 'test/repo-b',
37
- score: 85,
38
- grade: 'B',
39
- breakdown: {},
40
- suggestions: [],
41
- checkedAt: '2023-10-01T00:00:00Z'
42
- })
43
- }]
44
- };
45
- }
46
- if (repo.repo === 'repo-c') {
47
- return {
48
- content: [{
49
- type: 'text',
50
- text: JSON.stringify({
51
- repo: 'test/repo-c',
52
- score: 70,
53
- grade: 'C',
54
- breakdown: {},
55
- suggestions: [],
56
- checkedAt: '2023-10-01T00:00:00Z'
57
- })
58
- }]
59
- };
60
- }
61
- throw new Error('API Rate Limit or Repository not found');
62
- });
63
- const repos = [
64
- { owner: 'test', repo: 'repo-a' },
65
- { owner: 'test', repo: 'repo-fail' },
66
- { owner: 'test', repo: 'repo-b' },
67
- { owner: 'test', repo: 'repo-c' }
68
- ];
69
- const result = await executeCompareRepos({ repos });
70
- expect(result.content).toHaveLength(1);
71
- expect(result.content[0].type).toBe('text');
72
- const comparison = JSON.parse(result.content[0].text);
73
- expect(comparison.compared_at).toBeDefined();
74
- expect(comparison.repos).toHaveLength(4);
75
- // Verify sorting order: success ordered by score desc, then failures
76
- expect(comparison.repos[0].repo).toMatch(/repo-a|repo-b/);
77
- expect(comparison.repos[1].repo).toMatch(/repo-a|repo-b/);
78
- expect(comparison.repos[2].repo).toBe('repo-c');
79
- expect(comparison.repos[3].repo).toBe('repo-fail');
80
- const repoA = comparison.repos.find((r) => r.repo === 'repo-a');
81
- const repoB = comparison.repos.find((r) => r.repo === 'repo-b');
82
- const repoC = comparison.repos.find((r) => r.repo === 'repo-c');
83
- const repoFail = comparison.repos.find((r) => r.repo === 'repo-fail');
84
- expect(repoA.rank).toBe(1);
85
- expect(repoA.health.score).toBe(85);
86
- expect(repoA.error).toBeNull();
87
- expect(repoB.rank).toBe(1);
88
- expect(repoB.health.score).toBe(85);
89
- expect(repoB.error).toBeNull();
90
- // repo-c should be rank 3 (since 2 repos share rank 1)
91
- expect(repoC.rank).toBe(3);
92
- expect(repoC.health.score).toBe(70);
93
- expect(repoC.error).toBeNull();
94
- // repo-fail should be rank 0 with error details
95
- expect(repoFail.rank).toBe(0);
96
- expect(repoFail.health).toBeNull();
97
- expect(repoFail.error).toContain('API Rate Limit');
98
- });
99
- describe('inputSchema validation', () => {
100
- it('should validate correctly with 2 to 5 repos', () => {
101
- const valid = inputSchema.safeParse({
102
- repos: [
103
- { owner: 'owner1', repo: 'repo1' },
104
- { owner: 'owner2', repo: 'repo2' }
105
- ]
106
- });
107
- expect(valid.success).toBe(true);
108
- });
109
- it('should fail validation with less than 2 repos', () => {
110
- const invalid = inputSchema.safeParse({
111
- repos: [
112
- { owner: 'owner1', repo: 'repo1' }
113
- ]
114
- });
115
- expect(invalid.success).toBe(false);
116
- if (!invalid.success) {
117
- expect(invalid.error.issues[0].message).toBe('At least 2 repositories are required');
118
- }
119
- });
120
- it('should fail validation with more than 5 repos', () => {
121
- const invalid = inputSchema.safeParse({
122
- repos: [
123
- { owner: 'owner1', repo: 'repo1' },
124
- { owner: 'owner2', repo: 'repo2' },
125
- { owner: 'owner3', repo: 'repo3' },
126
- { owner: 'owner4', repo: 'repo4' },
127
- { owner: 'owner5', repo: 'repo5' },
128
- { owner: 'owner6', repo: 'repo6' }
129
- ]
130
- });
131
- expect(invalid.success).toBe(false);
132
- if (!invalid.success) {
133
- expect(invalid.error.issues[0].message).toBe('At most 5 repositories are allowed');
134
- }
135
- });
136
- });
137
- });
138
- //# sourceMappingURL=compare-repos.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"compare-repos.test.js","sourceRoot":"","sources":["../../src/tools/compare-repos.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,EAAE,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;AAEjC,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACjC,UAAU,CAAC,GAAG,EAAE;QACZ,EAAE,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oGAAoG,EAAE,KAAK,IAAI,EAAE;QAChH,uCAAuC;QACvC,mBAAmB;QACnB,qCAAqC;QACrC,sEAAsE;QACtE,mBAAmB;QAEnB,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YAC/D,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACzB,OAAO;oBACH,OAAO,EAAE,CAAC;4BACN,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACjB,IAAI,EAAE,aAAa;gCACnB,KAAK,EAAE,EAAE;gCACT,KAAK,EAAE,GAAG;gCACV,SAAS,EAAE,EAAE;gCACb,WAAW,EAAE,EAAE;gCACf,SAAS,EAAE,sBAAsB;6BACpC,CAAC;yBACL,CAAC;iBACL,CAAC;YACN,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACzB,OAAO;oBACH,OAAO,EAAE,CAAC;4BACN,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACjB,IAAI,EAAE,aAAa;gCACnB,KAAK,EAAE,EAAE;gCACT,KAAK,EAAE,GAAG;gCACV,SAAS,EAAE,EAAE;gCACb,WAAW,EAAE,EAAE;gCACf,SAAS,EAAE,sBAAsB;6BACpC,CAAC;yBACL,CAAC;iBACL,CAAC;YACN,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACzB,OAAO;oBACH,OAAO,EAAE,CAAC;4BACN,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACjB,IAAI,EAAE,aAAa;gCACnB,KAAK,EAAE,EAAE;gCACT,KAAK,EAAE,GAAG;gCACV,SAAS,EAAE,EAAE;gCACb,WAAW,EAAE,EAAE;gCACf,SAAS,EAAE,sBAAsB;6BACpC,CAAC;yBACL,CAAC;iBACL,CAAC;YACN,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG;YACV,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;YACjC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE;YACpC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;YACjC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;SACpC,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAEpD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE5C,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7C,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAEzC,qEAAqE;QACrE,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAC1D,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAC1D,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAEnD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;QACrE,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;QACrE,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;QACrE,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;QAE3E,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;QAE/B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;QAE/B,uDAAuD;QACvD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;QAE/B,gDAAgD;QAChD,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;QACnC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACpC,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACnD,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC;gBAChC,KAAK,EAAE;oBACH,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE;oBAClC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE;iBACrC;aACJ,CAAC,CAAC;YACH,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACrD,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,CAAC;gBAClC,KAAK,EAAE;oBACH,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE;iBACrC;aACJ,CAAC,CAAC;YACH,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBACnB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;YACzF,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACrD,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,CAAC;gBAClC,KAAK,EAAE;oBACH,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE;oBAClC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE;oBAClC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE;oBAClC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE;oBAClC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE;oBAClC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE;iBACrC;aACJ,CAAC,CAAC;YACH,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBACnB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;YACvF,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=get-dora-metrics.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"get-dora-metrics.test.d.ts","sourceRoot":"","sources":["../../src/tools/get-dora-metrics.test.ts"],"names":[],"mappings":""}
@@ -1,71 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
- import { listMergedPulls, listReleases, listWorkflowRuns } from '../github/client.js';
3
- import { executeGetDoraMetrics } from './get-dora-metrics.js';
4
- vi.mock('../github/client.js');
5
- describe('executeGetDoraMetrics', () => {
6
- beforeEach(() => {
7
- vi.resetAllMocks();
8
- });
9
- it('should fetch data and return metrics as JSON text', async () => {
10
- // mock return values for the client functions
11
- vi.mocked(listReleases).mockResolvedValue([
12
- { id: 1, tag_name: 'v1.0', published_at: '2026-08-01T00:00:00Z' }
13
- ]);
14
- vi.mocked(listWorkflowRuns).mockResolvedValue([
15
- { id: 1, name: 'CI', head_branch: 'main', conclusion: 'success', created_at: '2026-08-01T00:00:00Z' }
16
- ]);
17
- vi.mocked(listMergedPulls).mockResolvedValue([
18
- { number: 1, created_at: '2026-08-01T00:00:00Z', merged_at: '2026-08-02T00:00:00Z' }
19
- ]);
20
- const result = await executeGetDoraMetrics({ owner: 'testowner', repo: 'testrepo', days: 14 });
21
- expect(listReleases).toHaveBeenCalledWith('testowner', 'testrepo', expect.any(Date));
22
- expect(listWorkflowRuns).toHaveBeenCalledWith('testowner', 'testrepo', expect.any(Date));
23
- expect(listMergedPulls).toHaveBeenCalledWith('testowner', 'testrepo', expect.any(Date));
24
- expect(result.content).toHaveLength(1);
25
- expect(result.content[0].type).toBe('text');
26
- const parsedText = JSON.parse(result.content[0].text);
27
- expect(parsedText.owner).toBe('testowner');
28
- expect(parsedText.repo).toBe('testrepo');
29
- expect(parsedText.period_days).toBe(14);
30
- // Assert some metric outputs based on the mocked input
31
- expect(parsedText.deployment_frequency.releases_count).toBe(1);
32
- expect(parsedText.lead_time.pr_count).toBe(1);
33
- expect(parsedText.change_failure_rate.total_runs).toBe(1);
34
- expect(parsedText.change_failure_rate.failed_runs).toBe(0);
35
- });
36
- it('should handle empty data correctly (zero releases, PRs, runs)', async () => {
37
- vi.mocked(listReleases).mockResolvedValue([]);
38
- vi.mocked(listWorkflowRuns).mockResolvedValue([]);
39
- vi.mocked(listMergedPulls).mockResolvedValue([]);
40
- const result = await executeGetDoraMetrics({ owner: 'testowner', repo: 'testrepo', days: 30 });
41
- const parsedText = JSON.parse(result.content[0].text);
42
- expect(parsedText.deployment_frequency.releases_count).toBe(0);
43
- expect(parsedText.deployment_frequency.per_week).toBeNull();
44
- expect(parsedText.lead_time.pr_count).toBe(0);
45
- expect(parsedText.lead_time.median_hours).toBeNull();
46
- expect(parsedText.change_failure_rate.total_runs).toBe(0);
47
- expect(parsedText.change_failure_rate.rate_percent).toBeNull();
48
- expect(parsedText.mttr.incidents_count).toBe(0);
49
- expect(parsedText.mttr.median_hours).toBeNull();
50
- });
51
- it('should pass the correct since Date to client functions', async () => {
52
- vi.mocked(listReleases).mockResolvedValue([]);
53
- vi.mocked(listWorkflowRuns).mockResolvedValue([]);
54
- vi.mocked(listMergedPulls).mockResolvedValue([]);
55
- const days = 14;
56
- await executeGetDoraMetrics({ owner: 'testowner', repo: 'testrepo', days });
57
- const expectedSince = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
58
- const callArg = vi.mocked(listReleases).mock.calls[0][2];
59
- const diffMs = Math.abs(callArg.getTime() - expectedSince.getTime());
60
- expect(diffMs).toBeLessThan(1000); // Tolleranza di 1 secondo per l'esecuzione
61
- });
62
- it('should fail if any client call fails', async () => {
63
- vi.mocked(listReleases).mockRejectedValue(new Error('API Error'));
64
- vi.mocked(listWorkflowRuns).mockResolvedValue([]);
65
- vi.mocked(listMergedPulls).mockResolvedValue([]);
66
- await expect(executeGetDoraMetrics({ owner: 'testowner', repo: 'testrepo', days: 30 }))
67
- .rejects
68
- .toThrow('API Error');
69
- });
70
- });
71
- //# sourceMappingURL=get-dora-metrics.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"get-dora-metrics.test.js","sourceRoot":"","sources":["../../src/tools/get-dora-metrics.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACtF,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;AAE/B,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACnC,UAAU,CAAC,GAAG,EAAE;QACZ,EAAE,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QAC/D,8CAA8C;QAC9C,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,iBAAiB,CAAC;YACtC,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,sBAAsB,EAAE;SACpE,CAAC,CAAC;QAEH,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;YAC1C,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,sBAAsB,EAAE;SACxG,CAAC,CAAC;QAEH,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,iBAAiB,CAAC;YACzC,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,sBAAsB,EAAE,SAAS,EAAE,sBAAsB,EAAE;SACvF,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAE/F,MAAM,CAAC,YAAY,CAAC,CAAC,oBAAoB,CAAC,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QACrF,MAAM,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAAC,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QACzF,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAAC,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QAExF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE5C,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC3C,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACzC,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAExC,uDAAuD;QACvD,MAAM,CAAC,UAAU,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/D,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,CAAC,UAAU,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1D,MAAM,CAAC,UAAU,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC3E,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAC9C,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAClD,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAEjD,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/F,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEtD,MAAM,CAAC,UAAU,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/D,MAAM,CAAC,UAAU,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5D,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;QACrD,MAAM,CAAC,UAAU,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1D,MAAM,CAAC,UAAU,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC/D,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACpE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAC9C,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAClD,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAEjD,MAAM,IAAI,GAAG,EAAE,CAAC;QAChB,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAE5E,MAAM,aAAa,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QACxE,MAAM,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEzD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACrE,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,2CAA2C;IAClF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QAClD,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;QAClE,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAClD,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAEjD,MAAM,MAAM,CAAC,qBAAqB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;aAClF,OAAO;aACP,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=get-health-score.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"get-health-score.test.d.ts","sourceRoot":"","sources":["../../src/tools/get-health-score.test.ts"],"names":[],"mappings":""}