@fabasoad/sarif-to-slack 0.2.5 → 1.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 (192) hide show
  1. package/.github/workflows/release.yml +1 -1
  2. package/.github/workflows/security.yml +0 -1
  3. package/.github/workflows/send-sarif-to-slack.yml +145 -73
  4. package/.gitleaksignore +8 -0
  5. package/.pre-commit-config.yaml +3 -3
  6. package/.tool-versions +1 -1
  7. package/dist/Logger.js +4 -1
  8. package/dist/SarifToSlackClient.d.ts +33 -0
  9. package/dist/SarifToSlackClient.d.ts.map +1 -0
  10. package/dist/SarifToSlackClient.js +178 -0
  11. package/dist/SlackMessageBuilder.js +34 -82
  12. package/dist/System.d.ts +1 -3
  13. package/dist/System.d.ts.map +1 -1
  14. package/dist/System.js +10 -3
  15. package/dist/index.cjs +826 -472
  16. package/dist/index.d.ts +35 -12
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +36 -12
  19. package/dist/model/Color.d.ts +80 -0
  20. package/dist/model/Color.d.ts.map +1 -0
  21. package/dist/model/Color.js +106 -0
  22. package/dist/model/Finding.d.ts +2 -0
  23. package/dist/model/Finding.d.ts.map +1 -0
  24. package/dist/model/Finding.js +93 -0
  25. package/dist/model/FindingsArray.d.ts +2 -0
  26. package/dist/model/FindingsArray.d.ts.map +1 -0
  27. package/dist/model/FindingsArray.js +24 -0
  28. package/dist/processors/CodeQLProcessor.d.ts +2 -0
  29. package/dist/processors/CodeQLProcessor.d.ts.map +1 -0
  30. package/dist/processors/CodeQLProcessor.js +17 -0
  31. package/dist/processors/CommonProcessor.d.ts +2 -0
  32. package/dist/processors/CommonProcessor.d.ts.map +1 -0
  33. package/dist/processors/CommonProcessor.js +84 -0
  34. package/dist/processors/ProcessorFactory.d.ts +2 -0
  35. package/dist/processors/ProcessorFactory.d.ts.map +1 -0
  36. package/dist/processors/ProcessorFactory.js +22 -0
  37. package/dist/processors/SnykProcessor.d.ts +2 -0
  38. package/dist/processors/SnykProcessor.d.ts.map +1 -0
  39. package/dist/processors/SnykProcessor.js +18 -0
  40. package/dist/representations/CompactGroupByRepresentation.d.ts +2 -0
  41. package/dist/representations/CompactGroupByRepresentation.d.ts.map +1 -0
  42. package/dist/representations/CompactGroupByRepresentation.js +58 -0
  43. package/dist/representations/CompactGroupByRunPerLevelRepresentation.d.ts +2 -0
  44. package/dist/representations/CompactGroupByRunPerLevelRepresentation.d.ts.map +1 -0
  45. package/dist/representations/CompactGroupByRunPerLevelRepresentation.js +13 -0
  46. package/dist/representations/CompactGroupByRunPerSeverityRepresentation.d.ts +2 -0
  47. package/dist/representations/CompactGroupByRunPerSeverityRepresentation.d.ts.map +1 -0
  48. package/dist/representations/CompactGroupByRunPerSeverityRepresentation.js +13 -0
  49. package/dist/representations/CompactGroupByRunRepresentation.d.ts +2 -0
  50. package/dist/representations/CompactGroupByRunRepresentation.d.ts.map +1 -0
  51. package/dist/representations/CompactGroupByRunRepresentation.js +39 -0
  52. package/dist/representations/CompactGroupBySarifPerLevelRepresentation.d.ts +2 -0
  53. package/dist/representations/CompactGroupBySarifPerLevelRepresentation.d.ts.map +1 -0
  54. package/dist/representations/CompactGroupBySarifPerLevelRepresentation.js +13 -0
  55. package/dist/representations/CompactGroupBySarifPerSeverityRepresentation.d.ts +2 -0
  56. package/dist/representations/CompactGroupBySarifPerSeverityRepresentation.d.ts.map +1 -0
  57. package/dist/representations/CompactGroupBySarifPerSeverityRepresentation.js +13 -0
  58. package/dist/representations/CompactGroupBySarifRepresentation.d.ts +2 -0
  59. package/dist/representations/CompactGroupBySarifRepresentation.d.ts.map +1 -0
  60. package/dist/representations/CompactGroupBySarifRepresentation.js +40 -0
  61. package/dist/representations/CompactGroupByToolNamePerLevelRepresentation.d.ts +2 -0
  62. package/dist/representations/CompactGroupByToolNamePerLevelRepresentation.d.ts.map +1 -0
  63. package/dist/representations/CompactGroupByToolNamePerLevelRepresentation.js +13 -0
  64. package/dist/representations/CompactGroupByToolNamePerSeverityRepresentation.d.ts +2 -0
  65. package/dist/representations/CompactGroupByToolNamePerSeverityRepresentation.d.ts.map +1 -0
  66. package/dist/representations/CompactGroupByToolNamePerSeverityRepresentation.js +13 -0
  67. package/dist/representations/CompactGroupByToolNameRepresentation.d.ts +2 -0
  68. package/dist/representations/CompactGroupByToolNameRepresentation.d.ts.map +1 -0
  69. package/dist/representations/CompactGroupByToolNameRepresentation.js +39 -0
  70. package/dist/representations/CompactTotalPerLevelRepresentation.d.ts +2 -0
  71. package/dist/representations/CompactTotalPerLevelRepresentation.d.ts.map +1 -0
  72. package/dist/representations/CompactTotalPerLevelRepresentation.js +13 -0
  73. package/dist/representations/CompactTotalPerSeverityRepresentation.d.ts +2 -0
  74. package/dist/representations/CompactTotalPerSeverityRepresentation.d.ts.map +1 -0
  75. package/dist/representations/CompactTotalPerSeverityRepresentation.js +13 -0
  76. package/dist/representations/CompactTotalRepresentation.d.ts +2 -0
  77. package/dist/representations/CompactTotalRepresentation.d.ts.map +1 -0
  78. package/dist/representations/CompactTotalRepresentation.js +25 -0
  79. package/dist/representations/Representation.d.ts +2 -0
  80. package/dist/representations/Representation.d.ts.map +1 -0
  81. package/dist/representations/Representation.js +28 -0
  82. package/dist/representations/RepresentationFactory.d.ts +2 -0
  83. package/dist/representations/RepresentationFactory.d.ts.map +1 -0
  84. package/dist/representations/RepresentationFactory.js +37 -0
  85. package/dist/sarif-to-slack.d.ts +347 -85
  86. package/dist/tsdoc-metadata.json +1 -1
  87. package/dist/types.d.ts +215 -51
  88. package/dist/types.d.ts.map +1 -1
  89. package/dist/types.js +225 -33
  90. package/dist/utils/Comparators.d.ts +2 -0
  91. package/dist/utils/Comparators.d.ts.map +1 -0
  92. package/dist/utils/Comparators.js +18 -0
  93. package/dist/utils/ExtendedArray.d.ts +2 -0
  94. package/dist/utils/ExtendedArray.d.ts.map +1 -0
  95. package/dist/utils/ExtendedArray.js +11 -0
  96. package/dist/utils/FileUtils.d.ts +2 -0
  97. package/dist/utils/FileUtils.d.ts.map +1 -0
  98. package/dist/utils/FileUtils.js +51 -0
  99. package/dist/utils/SarifUtils.js +20 -54
  100. package/etc/sarif-to-slack.api.md +162 -99
  101. package/jest.config.json +2 -2
  102. package/package.json +7 -7
  103. package/scripts/save-metadata.sh +12 -10
  104. package/src/Logger.ts +4 -0
  105. package/src/SarifToSlackClient.ts +202 -0
  106. package/src/SlackMessageBuilder.ts +35 -115
  107. package/src/System.ts +9 -2
  108. package/src/index.ts +47 -20
  109. package/src/model/Color.ts +195 -0
  110. package/src/model/Finding.ts +137 -0
  111. package/src/model/FindingsArray.ts +27 -0
  112. package/src/processors/CodeQLProcessor.ts +19 -0
  113. package/src/processors/CommonProcessor.ts +103 -0
  114. package/src/processors/ProcessorFactory.ts +23 -0
  115. package/src/processors/SnykProcessor.ts +19 -0
  116. package/src/representations/CompactGroupByRepresentation.ts +67 -0
  117. package/src/representations/CompactGroupByRunPerLevelRepresentation.ts +14 -0
  118. package/src/representations/CompactGroupByRunPerSeverityRepresentation.ts +14 -0
  119. package/src/representations/CompactGroupByRunRepresentation.ts +44 -0
  120. package/src/representations/CompactGroupBySarifPerLevelRepresentation.ts +15 -0
  121. package/src/representations/CompactGroupBySarifPerSeverityRepresentation.ts +15 -0
  122. package/src/representations/CompactGroupBySarifRepresentation.ts +45 -0
  123. package/src/representations/CompactGroupByToolNamePerLevelRepresentation.ts +15 -0
  124. package/src/representations/CompactGroupByToolNamePerSeverityRepresentation.ts +15 -0
  125. package/src/representations/CompactGroupByToolNameRepresentation.ts +44 -0
  126. package/src/representations/CompactTotalPerLevelRepresentation.ts +14 -0
  127. package/src/representations/CompactTotalPerSeverityRepresentation.ts +14 -0
  128. package/src/representations/CompactTotalRepresentation.ts +27 -0
  129. package/src/representations/Representation.ts +35 -0
  130. package/src/representations/RepresentationFactory.ts +49 -0
  131. package/src/types.ts +270 -53
  132. package/src/utils/Comparators.ts +19 -0
  133. package/src/utils/ExtendedArray.ts +11 -0
  134. package/src/utils/FileUtils.ts +60 -0
  135. package/src/utils/SarifUtils.ts +20 -72
  136. package/test-data/sarif/codeql-python.sarif +1448 -1
  137. package/test-data/sarif/codeql-typescript.sarif +3474 -1
  138. package/test-data/sarif/grype-github-actions.sarif +65 -0
  139. package/test-data/sarif/osv-scanner-composer.sarif +972 -0
  140. package/test-data/sarif/osv-scanner-container.sarif +2278 -0
  141. package/test-data/sarif/osv-scanner-gomodules.sarif +813 -0
  142. package/test-data/sarif/osv-scanner-hex.sarif +147 -0
  143. package/test-data/sarif/osv-scanner-maven.sarif +171 -0
  144. package/test-data/sarif/osv-scanner-npm.sarif +627 -0
  145. package/test-data/sarif/osv-scanner-pip.sarif +206 -0
  146. package/test-data/sarif/osv-scanner-pipenv.sarif +243 -0
  147. package/test-data/sarif/osv-scanner-pnpm.sarif +174 -0
  148. package/test-data/sarif/osv-scanner-poetry.sarif +1893 -0
  149. package/test-data/sarif/osv-scanner-rubygems.sarif +402 -0
  150. package/test-data/sarif/osv-scanner-uv.sarif +206 -0
  151. package/test-data/sarif/osv-scanner-yarn.sarif +5207 -0
  152. package/test-data/sarif/runs-0.sarif +5 -0
  153. package/test-data/sarif/runs-2-tools-2-results-0.sarif +1 -1
  154. package/test-data/sarif/runs-2-tools-2.sarif +1 -1
  155. package/test-data/sarif/runs-3-tools-2-results-0.sarif +1 -1
  156. package/test-data/sarif/runs-3-tools-2.sarif +1 -1
  157. package/test-data/sarif/tmp/codeql-csharp.sarif +1 -0
  158. package/test-data/sarif/tmp/grype-container.sarif +1774 -0
  159. package/test-data/sarif/tmp/runs-1-tools-1-results-0.sarif +18 -0
  160. package/test-data/sarif/tmp/runs-2-tools-2.sarif +686 -0
  161. package/test-data/sarif/trivy-iac.sarif +1 -1
  162. package/tests/integration/SendSarifToSlack.spec.ts +95 -27
  163. package/tsconfig.json +2 -0
  164. package/dist/Processors.d.ts +0 -2
  165. package/dist/Processors.d.ts.map +0 -1
  166. package/dist/Processors.js +0 -61
  167. package/dist/SarifToSlackService.d.ts +0 -39
  168. package/dist/SarifToSlackService.d.ts.map +0 -1
  169. package/dist/SarifToSlackService.js +0 -104
  170. package/dist/metadata.d.ts +0 -2
  171. package/dist/metadata.d.ts.map +0 -1
  172. package/dist/metadata.js +0 -11
  173. package/dist/model/SarifModelPerRun.d.ts +0 -2
  174. package/dist/model/SarifModelPerRun.d.ts.map +0 -1
  175. package/dist/model/SarifModelPerRun.js +0 -90
  176. package/dist/model/SarifModelPerSarif.d.ts +0 -2
  177. package/dist/model/SarifModelPerSarif.d.ts.map +0 -1
  178. package/dist/model/SarifModelPerSarif.js +0 -102
  179. package/dist/model/types.d.ts +0 -2
  180. package/dist/model/types.d.ts.map +0 -1
  181. package/dist/model/types.js +0 -49
  182. package/dist/utils/SortUtils.d.ts +0 -2
  183. package/dist/utils/SortUtils.d.ts.map +0 -1
  184. package/dist/utils/SortUtils.js +0 -20
  185. package/src/Processors.ts +0 -68
  186. package/src/SarifToSlackService.ts +0 -117
  187. package/src/metadata.ts +0 -10
  188. package/src/model/SarifModelPerRun.ts +0 -120
  189. package/src/model/SarifModelPerSarif.ts +0 -126
  190. package/src/model/types.ts +0 -50
  191. package/src/utils/SortUtils.ts +0 -33
  192. package/tests/Processors.spec.ts +0 -76
@@ -0,0 +1,11 @@
1
+ /**
2
+ * This class is an extension for the {@link Array} class. It adds some additional
3
+ * useful methods.
4
+ * @internal
5
+ */
6
+ export default class ExtendedArray<T> extends Array<T> {
7
+
8
+ public findByProperty<K extends keyof T>(prop: K, value: T[K]): T | undefined {
9
+ return this.find((v: T): boolean => v[prop] === value)
10
+ }
11
+ }
@@ -0,0 +1,60 @@
1
+ import fs from 'fs'
2
+ import Logger from '../Logger'
3
+ import { SarifFileExtension, SarifOptions } from '../types'
4
+ import * as path from 'path'
5
+
6
+ /**
7
+ * Traverse directory recursively and returns list of files with the requested
8
+ * extension.
9
+ * @param dir A root directory. Starting point.
10
+ * @param extension An instance of {@link SarifFileExtension} type.
11
+ * @param fileList Collected list of files.
12
+ * @private
13
+ */
14
+ function listFilesRecursively(
15
+ dir: string,
16
+ extension: SarifFileExtension,
17
+ fileList: string[] = []
18
+ ): string[] {
19
+ const entries: string[] = fs.readdirSync(dir)
20
+ entries.forEach((entry: string): void => {
21
+ const fullPath: string = path.join(dir, entry)
22
+ if (fs.statSync(fullPath).isDirectory()) {
23
+ listFilesRecursively(fullPath, extension, fileList)
24
+ } else if (path.extname(fullPath).toLowerCase() === `.${extension}`) {
25
+ fileList.push(fullPath)
26
+ }
27
+ })
28
+ return fileList
29
+ }
30
+
31
+ /**
32
+ * Extract list of files based on the parameters from the given {@link SarifOptions}
33
+ * object.
34
+ * @param opts An instance of {@link SarifOptions} type.
35
+ * @internal
36
+ */
37
+ export function extractListOfFiles(opts: SarifOptions): string[] {
38
+ if (!fs.existsSync(opts.path)) {
39
+ throw new Error(`Provided path does not exist: ${opts.path}`)
40
+ }
41
+
42
+ const stats: fs.Stats = fs.statSync(opts.path)
43
+
44
+ if (stats.isDirectory()) {
45
+ Logger.info(`Provided path is a directory: ${opts.path}`)
46
+ const files: string[] = opts.recursive
47
+ && listFilesRecursively(opts.path, opts.extension ?? 'sarif')
48
+ || fs.readdirSync(opts.path)
49
+ Logger.info(`Found ${files.length} files in ${opts.path} directory with ${opts.extension} extension`)
50
+ Logger.debug(`Found files: ${files.join(', ')}`)
51
+ return files
52
+ }
53
+
54
+ if (stats.isFile()) {
55
+ Logger.info(`Provided path is a file: ${opts.path}`)
56
+ return [opts.path]
57
+ }
58
+
59
+ throw new Error(`Provided path is neither a file nor a directory: ${opts.path}`)
60
+ }
@@ -1,87 +1,35 @@
1
- import type { ReportingDescriptor, Result, Run, ToolComponent } from "sarif";
1
+ import type { Result, Run, ToolComponent } from 'sarif'
2
2
 
3
3
  /**
4
- * This function finds the respective tool for the given result.
5
- * @param run An instance of {@link Run} object.
6
- * @param result An instance of {@link Result} object.
7
- * @private
4
+ * Returns {@link ToolComponent} instance for the given {@link Run}. It does not
5
+ * count extensions but returns {@link ToolComponent} directly from "run.tool.driver",
6
+ * despite the fact if extension exists or not.
7
+ * @internal
8
8
  */
9
- function findToolComponentByResult(run: Run, result: Result): ToolComponent {
10
- let tool: ToolComponent | undefined
11
- if (result.rule?.toolComponent?.index != null) {
12
- tool = run.tool.extensions?.[result.rule.toolComponent.index]
13
- }
14
-
15
- if (!tool) {
16
- tool = run.tool.driver
17
- }
18
-
19
- return tool
9
+ export function findToolComponentDriver(run: Run): ToolComponent {
10
+ return run.tool.driver
20
11
  }
21
12
 
22
13
  /**
23
- * This function tries to find the respective rule for the given result.
24
- * @param run An instance of {@link Run} object.
25
- * @param result An instance of {@link Result} object.
14
+ * Returns {@link ToolComponent} instance for the given {@link Run} from the extensions
15
+ * list if applicable. Returns {@linkcode undefined} if provided {@link Result}
16
+ * does not link to extension.
26
17
  * @internal
27
18
  */
28
- export function findRuleByResult(run: Run, result: Result): ReportingDescriptor | undefined {
29
- const ruleData: { id?: string, index?: number } = {}
30
-
31
- if (result.rule) {
32
- if (result.rule?.index != null) {
33
- ruleData.index = result.rule.index
34
- }
35
- if (result.rule?.id) {
36
- ruleData.id = result.rule.id
37
- }
38
- }
39
-
40
- if (ruleData.index == null && result.ruleIndex != null) {
41
- ruleData.index = result.ruleIndex
42
- }
43
-
44
- if (!ruleData.id && result.ruleId) {
45
- ruleData.id = result.ruleId
46
- }
47
-
48
- const tool: ToolComponent = findToolComponentByResult(run, result)
49
-
50
- if (ruleData.index != null
51
- && tool?.rules
52
- && ruleData.index < tool.rules.length) {
53
- return tool.rules[ruleData.index]
54
- }
55
-
56
- // If failed to find rule by index then try to find by ruleId
57
- if (ruleData.id && tool?.rules) {
58
- return tool.rules.find(
59
- (r: ReportingDescriptor): boolean => r.id === ruleData.id
60
- )
19
+ export function tryFindToolComponentExtension(run: Run, result: Result): ToolComponent | undefined {
20
+ let tool: ToolComponent | undefined
21
+ if (result.rule?.toolComponent?.index != null) {
22
+ tool = run.tool.extensions?.[result.rule.toolComponent.index]
61
23
  }
62
-
63
- return undefined
24
+ return tool
64
25
  }
65
26
 
66
27
  /**
67
- * Allowed property names that we can search for from the rule.
28
+ * It tries to find respective {@link ToolComponent} from the {@link Result}. At
29
+ * first, it tries to find it in the list of extensions if applicable, otherwise
30
+ * it gets it directly from "run.tool.driver".
68
31
  * @internal
69
32
  */
70
- export type RuleProperty = 'security-severity' | 'problem.severity'
71
-
72
- /**
73
- * This function searches respective rule for the given result, and then gets
74
- * the property of interest from it.
75
- * @param run An instance of {@link Run} object.
76
- * @param result An instance of {@link Result} object.
77
- * @param propertyName The property name that you want to get the value from.
78
- * @internal
79
- */
80
- export function tryGetRulePropertyByResult<T>(run: Run, result: Result, propertyName: RuleProperty): T | undefined {
81
- const rule: ReportingDescriptor | undefined = findRuleByResult(run, result)
82
- if (rule && rule.properties && propertyName in rule.properties) {
83
- return rule.properties[propertyName] as T
84
- }
85
-
86
- return undefined
33
+ export function findToolComponent(run: Run, result: Result): ToolComponent {
34
+ return tryFindToolComponentExtension(run, result) ?? findToolComponentDriver(run)
87
35
  }