sonar-sweep 0.1.0

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 (47) hide show
  1. package/README.md +70 -0
  2. package/dist/cli/commands/issue-accept.d.ts +13 -0
  3. package/dist/cli/commands/issue-accept.js +49 -0
  4. package/dist/cli/commands/issue-accept.js.map +1 -0
  5. package/dist/cli/commands/pr-coverage.d.ts +16 -0
  6. package/dist/cli/commands/pr-coverage.js +79 -0
  7. package/dist/cli/commands/pr-coverage.js.map +1 -0
  8. package/dist/cli/commands/pr-issues.d.ts +15 -0
  9. package/dist/cli/commands/pr-issues.js +78 -0
  10. package/dist/cli/commands/pr-issues.js.map +1 -0
  11. package/dist/cli/commands/pr-report.d.ts +13 -0
  12. package/dist/cli/commands/pr-report.js +94 -0
  13. package/dist/cli/commands/pr-report.js.map +1 -0
  14. package/dist/cli/commands/pr-review.d.ts +16 -0
  15. package/dist/cli/commands/pr-review.js +93 -0
  16. package/dist/cli/commands/pr-review.js.map +1 -0
  17. package/dist/cli/index.d.ts +1 -0
  18. package/dist/cli/index.js +28 -0
  19. package/dist/cli/index.js.map +1 -0
  20. package/dist/cli/project-key.d.ts +1 -0
  21. package/dist/cli/project-key.js +32 -0
  22. package/dist/cli/project-key.js.map +1 -0
  23. package/dist/cli.d.ts +2 -0
  24. package/dist/cli.js +8 -0
  25. package/dist/cli.js.map +1 -0
  26. package/dist/index.d.ts +6 -0
  27. package/dist/index.js +7 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/service/issue-transition.d.ts +12 -0
  30. package/dist/service/issue-transition.js +20 -0
  31. package/dist/service/issue-transition.js.map +1 -0
  32. package/dist/service/pr-coverage.d.ts +22 -0
  33. package/dist/service/pr-coverage.js +48 -0
  34. package/dist/service/pr-coverage.js.map +1 -0
  35. package/dist/service/pr-issues.d.ts +29 -0
  36. package/dist/service/pr-issues.js +45 -0
  37. package/dist/service/pr-issues.js.map +1 -0
  38. package/dist/service/pr-report.d.ts +27 -0
  39. package/dist/service/pr-report.js +59 -0
  40. package/dist/service/pr-report.js.map +1 -0
  41. package/dist/service/pr-review.d.ts +39 -0
  42. package/dist/service/pr-review.js +81 -0
  43. package/dist/service/pr-review.js.map +1 -0
  44. package/dist/service/sonarcloud-client.d.ts +100 -0
  45. package/dist/service/sonarcloud-client.js +112 -0
  46. package/dist/service/sonarcloud-client.js.map +1 -0
  47. package/package.json +34 -0
@@ -0,0 +1,112 @@
1
+ export class SonarCloudClient {
2
+ token;
3
+ baseUrl;
4
+ fetchImpl;
5
+ constructor(options) {
6
+ if (!options.token?.trim()) {
7
+ throw new Error('Missing Sonar token');
8
+ }
9
+ this.token = options.token.trim();
10
+ this.baseUrl = (options.baseUrl ?? 'https://sonarcloud.io').replace(/\/$/, '');
11
+ this.fetchImpl = options.fetchImpl ?? fetch;
12
+ }
13
+ async getProjectStatus(projectKey, pullRequest) {
14
+ return this.get('/api/qualitygates/project_status', {
15
+ projectKey,
16
+ pullRequest,
17
+ });
18
+ }
19
+ async getIssuesFacets(projectKey, pullRequest) {
20
+ return this.get('/api/issues/search', {
21
+ componentKeys: projectKey,
22
+ pullRequest,
23
+ inNewCodePeriod: 'true',
24
+ facets: 'issueStatuses',
25
+ ps: '1',
26
+ });
27
+ }
28
+ async getPullRequestIssues(projectKey, pullRequest, page = 1, pageSize = 100) {
29
+ return this.get('/api/issues/search', {
30
+ componentKeys: projectKey,
31
+ pullRequest,
32
+ inNewCodePeriod: 'true',
33
+ resolved: 'false',
34
+ p: String(page),
35
+ ps: String(pageSize),
36
+ });
37
+ }
38
+ async getMeasures(projectKey, pullRequest) {
39
+ return this.get('/api/measures/component', {
40
+ component: projectKey,
41
+ pullRequest,
42
+ metricKeys: 'new_security_hotspots,new_coverage,new_duplicated_lines_density',
43
+ });
44
+ }
45
+ async getCoverageComponentTree(projectKey, pullRequest, page = 1, pageSize = 100) {
46
+ return this.get('/api/measures/component_tree', {
47
+ component: projectKey,
48
+ pullRequest,
49
+ qualifiers: 'FIL',
50
+ metricKeys: 'new_coverage,new_lines_to_cover,new_uncovered_lines',
51
+ p: String(page),
52
+ ps: String(pageSize),
53
+ });
54
+ }
55
+ async getSourceRaw(componentKey, pullRequest) {
56
+ const url = new URL('/api/sources/raw', this.baseUrl);
57
+ url.searchParams.set('key', componentKey);
58
+ url.searchParams.set('pullRequest', pullRequest);
59
+ const response = await this.fetchImpl(url, {
60
+ method: 'GET',
61
+ headers: {
62
+ Authorization: `Bearer ${this.token}`,
63
+ },
64
+ });
65
+ if (!response.ok) {
66
+ const body = await response.text();
67
+ throw new Error(`Sonar API request failed (${response.status}) for /api/sources/raw: ${body}`);
68
+ }
69
+ return response.text();
70
+ }
71
+ async doIssueTransition(issueKey, transition, comment) {
72
+ await this.post('/api/issues/do_transition', {
73
+ issue: issueKey,
74
+ transition,
75
+ ...(comment ? { comment } : {}),
76
+ });
77
+ }
78
+ async get(path, query) {
79
+ const url = new URL(path, this.baseUrl);
80
+ for (const [key, value] of Object.entries(query)) {
81
+ url.searchParams.set(key, value);
82
+ }
83
+ const response = await this.fetchImpl(url, {
84
+ method: 'GET',
85
+ headers: {
86
+ Authorization: `Bearer ${this.token}`,
87
+ },
88
+ });
89
+ if (!response.ok) {
90
+ const body = await response.text();
91
+ throw new Error(`Sonar API request failed (${response.status}) for ${path}: ${body}`);
92
+ }
93
+ return (await response.json());
94
+ }
95
+ async post(path, form) {
96
+ const url = new URL(path, this.baseUrl);
97
+ const body = new URLSearchParams(form);
98
+ const response = await this.fetchImpl(url, {
99
+ method: 'POST',
100
+ headers: {
101
+ Authorization: `Bearer ${this.token}`,
102
+ 'content-type': 'application/x-www-form-urlencoded',
103
+ },
104
+ body,
105
+ });
106
+ if (!response.ok) {
107
+ const responseBody = await response.text();
108
+ throw new Error(`Sonar API request failed (${response.status}) for ${path}: ${responseBody}`);
109
+ }
110
+ }
111
+ }
112
+ //# sourceMappingURL=sonarcloud-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sonarcloud-client.js","sourceRoot":"","sources":["../../src/service/sonarcloud-client.ts"],"names":[],"mappings":"AA8FA,MAAM,OAAO,gBAAgB;IACV,KAAK,CAAQ;IACb,OAAO,CAAQ;IACf,SAAS,CAAc;IAExC,YAAY,OAAgC;QAC1C,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAA;QACxC,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAA;QACjC,IAAI,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,uBAAuB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;QAC9E,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAA;IAC7C,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,UAAkB,EAAE,WAAmB;QAC5D,OAAO,IAAI,CAAC,GAAG,CAAC,kCAAkC,EAAE;YAClD,UAAU;YACV,WAAW;SACZ,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,UAAkB,EAAE,WAAmB;QAC3D,OAAO,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE;YACpC,aAAa,EAAE,UAAU;YACzB,WAAW;YACX,eAAe,EAAE,MAAM;YACvB,MAAM,EAAE,eAAe;YACvB,EAAE,EAAE,GAAG;SACR,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,oBAAoB,CACxB,UAAkB,EAClB,WAAmB,EACnB,IAAI,GAAG,CAAC,EACR,QAAQ,GAAG,GAAG;QAEd,OAAO,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE;YACpC,aAAa,EAAE,UAAU;YACzB,WAAW;YACX,eAAe,EAAE,MAAM;YACvB,QAAQ,EAAE,OAAO;YACjB,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC;YACf,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC;SACrB,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,UAAkB,EAAE,WAAmB;QACvD,OAAO,IAAI,CAAC,GAAG,CAAC,yBAAyB,EAAE;YACzC,SAAS,EAAE,UAAU;YACrB,WAAW;YACX,UAAU,EAAE,iEAAiE;SAC9E,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,wBAAwB,CAC5B,UAAkB,EAClB,WAAmB,EACnB,IAAI,GAAG,CAAC,EACR,QAAQ,GAAG,GAAG;QAEd,OAAO,IAAI,CAAC,GAAG,CAAC,8BAA8B,EAAE;YAC9C,SAAS,EAAE,UAAU;YACrB,WAAW;YACX,UAAU,EAAE,KAAK;YACjB,UAAU,EAAE,qDAAqD;YACjE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC;YACf,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC;SACrB,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,YAAoB,EAAE,WAAmB;QAC1D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;QACrD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,CAAA;QACzC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,aAAa,EAAE,WAAW,CAAC,CAAA;QAEhD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;YACzC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;aACtC;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;YAClC,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,CAAC,MAAM,2BAA2B,IAAI,EAAE,CAAC,CAAA;QAChG,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAA;IACxB,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,QAAgB,EAAE,UAAkB,EAAE,OAAgB;QAC5E,MAAM,IAAI,CAAC,IAAI,CAAC,2BAA2B,EAAE;YAC3C,KAAK,EAAE,QAAQ;YACf,UAAU;YACV,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChC,CAAC,CAAA;IACJ,CAAC;IAEO,KAAK,CAAC,GAAG,CAAI,IAAY,EAAE,KAA6B;QAC9D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;QACvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QAClC,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;YACzC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;aACtC;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;YAClC,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,CAAC,MAAM,SAAS,IAAI,KAAK,IAAI,EAAE,CAAC,CAAA;QACvF,CAAC;QAED,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAA;IACrC,CAAC;IAEO,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,IAA4B;QAC3D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;QACvC,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,CAAA;QAEtC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;YACzC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;gBACrC,cAAc,EAAE,mCAAmC;aACpD;YACD,IAAI;SACL,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;YAC1C,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,CAAC,MAAM,SAAS,IAAI,KAAK,YAAY,EAAE,CAAC,CAAA;QAC/F,CAAC;IACH,CAAC;CACF"}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "sonar-sweep",
3
+ "version": "0.1.0",
4
+ "description": "CLI for fetching SonarQube Cloud pull request details",
5
+ "type": "module",
6
+ "bin": {
7
+ "sonar-sweep": "dist/cli.js"
8
+ },
9
+ "main": "dist/index.js",
10
+ "types": "dist/index.d.ts",
11
+ "files": [
12
+ "dist",
13
+ "README.md"
14
+ ],
15
+ "engines": {
16
+ "node": ">=20"
17
+ },
18
+ "scripts": {
19
+ "build": "tsc -p tsconfig.json",
20
+ "test": "vitest run",
21
+ "test:e2e": "npm run build && vitest run --config vitest.e2e.config.ts",
22
+ "type-check": "tsc -p tsconfig.json --noEmit",
23
+ "start": "node dist/cli.js"
24
+ },
25
+ "dependencies": {
26
+ "yargs": "17.7.2"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "22.13.10",
30
+ "@types/yargs": "17.0.33",
31
+ "typescript": "5.8.2",
32
+ "vitest": "4.0.15"
33
+ }
34
+ }