@fabasoad/sarif-to-slack 0.2.5 → 1.0.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 +840 -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 +70 -0
  20. package/dist/model/Color.d.ts.map +1 -0
  21. package/dist/model/Color.js +119 -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 +337 -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 +161 -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 +201 -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
@@ -27,7 +27,7 @@ jobs:
27
27
  ref-name: ${{ steps.metadata.outputs.ref-name }}
28
28
  steps:
29
29
  - name: Checkout ${{ github.repository }}
30
- uses: actions/checkout@v4
30
+ uses: actions/checkout@v5
31
31
  with:
32
32
  token: "${{ secrets.GH_TOKEN }}"
33
33
 
@@ -11,7 +11,6 @@ jobs:
11
11
  sast:
12
12
  name: SAST
13
13
  permissions:
14
- actions: read
15
14
  contents: read
16
15
  security-events: write
17
16
  uses: fabasoad/reusable-workflows/.github/workflows/wf-security-sast.yml@main
@@ -7,33 +7,48 @@ on: # yamllint disable-line rule:truthy
7
7
  sarif:
8
8
  description: SARIF to send
9
9
  required: true
10
- default: "Snyk Yarn (Error: 30, Warning: 16, Note: 3)"
10
+ default: "OSV Scanner Yarn (Critical: 17, High: 39, Medium: 31, Low: 4, Unknown: 6)"
11
11
  type: choice
12
12
  options:
13
- - "CodeQL C# (Unknown: 1)"
14
- - "CodeQL Go (Unknown: 1)"
15
- - "CodeQL Python (Unknown: 1)"
16
- - "CodeQL Ruby (Unknown: 4)"
17
- - "CodeQL TypeScript (Unknown: 1)"
18
- - "Grype Container (Error: 10, Warning: 20, Note: 9)"
19
- - "Snyk Composer (Error: 15, Warning: 5)"
20
- - "Snyk Container (Error: 1, Note: 3)"
21
- - "Snyk Gomodules (Error: 4, Warning: 4)"
22
- - "Snyk Gradle (Error: 3, Warning: 1)"
23
- - "Snyk Hex (Error: 1)"
24
- - "Snyk Maven (Error: 3, Warning: 1)"
25
- - "Snyk NPM (Error: 6, Warning: 6, Note: 2)"
26
- - "Snyk Nuget (Error: 1)"
27
- - "Snyk Pip (Warning: 1)"
28
- - "Snyk PNPM (Error: 1)"
29
- - "Snyk Poetry (Error: 6, Warning: 21, Note: 2)"
30
- - "Snyk Rubygems (Error: 1, Warning: 5)"
31
- - "Snyk Sbt (Error: 2, Warning: 1)"
32
- - "Snyk Swift (Warning: 2)"
33
- - "Snyk Yarn (Error: 30, Warning: 16, Note: 3)"
34
- - "Trivy IaC (Error: 1, Note: 1)"
35
- - "Wiz Container (Error: 12, Warning: 369, Note: 191)"
36
- - "Wiz IaC (Warning: 5, Note: 5)"
13
+ - "CodeQL C# (High: 1)"
14
+ - "CodeQL Go (Critical: 1)"
15
+ - "CodeQL Python (Medium: 1)"
16
+ - "CodeQL Ruby (Critical: 3, High: 1)"
17
+ - "CodeQL TypeScript (Critical: 1)"
18
+ - "Grype Container (Critical: 4, High: 6, Medium: 20, Low: 9)"
19
+ - "Grype GitHub Actions (High: 1)"
20
+ - "OSV Scanner Composer (Critical: 5, High: 4, Medium: 7)"
21
+ - "OSV Scanner Container (Critical: 2, High: 7, Medium: 7, Low: 6, Unknown: 26)"
22
+ - "OSV Scanner Gomodules (Critical: 1, High: 6, Medium: 9)"
23
+ - "OSV Scanner Hex (Unknown: 2)"
24
+ - "OSV Scanner Maven (Critical: 1, Unknown: 1)"
25
+ - "OSV Scanner NPM (High: 4, Medium: 5, Unknown: 1)"
26
+ - "OSV Scanner Pip (High: 2, Unknown: 1)"
27
+ - "OSV Scanner Pipenv (High: 4)"
28
+ - "OSV Scanner PNPM (High: 2)"
29
+ - "OSV Scanner Poetry (High: 21, Medium: 13, Low: 2, Unknown: 1)"
30
+ - "OSV Scanner Rubygems (High: 4, Medium: 2)"
31
+ - "OSV Scanner UV (High: 2, Unknown: 1)"
32
+ - "OSV Scanner Yarn (Critical: 17, High: 39, Medium: 31, Low: 4, Unknown: 6)"
33
+ - "Snyk Composer (Critical: 4, High: 7, Medium: 5, Low: 1, None: 3)"
34
+ - "Snyk Container (High: 1, None: 3)"
35
+ - "Snyk Gomodules (High: 4, Medium: 4)"
36
+ - "Snyk Gradle (Critical: 2, Medium: 1, None: 1)"
37
+ - "Snyk Hex (Critical: 1)"
38
+ - "Snyk Maven (Critical: 2, Medium: 1, None: 1)"
39
+ - "Snyk NPM (High: 2, Medium: 6, Low: 2, None: 4)"
40
+ - "Snyk Nuget (High: 1)"
41
+ - "Snyk Pip (Medium: 1)"
42
+ - "Snyk PNPM (High: 1)"
43
+ - "Snyk Poetry (High: 5, Medium: 21, Low: 2, None: 1)"
44
+ - "Snyk Rubygems (High: 1, Medium: 5)"
45
+ - "Snyk Sbt (Medium: 1, None: 2)"
46
+ - "Snyk Swift (Medium: 2)"
47
+ - "Snyk Yarn (High: 19, Medium: 16, Low: 3, None: 11)"
48
+ - "Trivy IaC (High: 1, Low: 1)"
49
+ - "Wiz Container (Critical: 48, High: 209, Medium: 245, Low: 70)"
50
+ - "Wiz IaC (Medium: 5, Low: 5)"
51
+ - "Runs: 0"
37
52
  - "Runs: 1, Extensions: 1, Results: 0"
38
53
  - "Runs: 1, Extensions: 1, Results > 0"
39
54
  - "Runs: 1, Tools: 1, Results: 0"
@@ -44,36 +59,63 @@ on: # yamllint disable-line rule:truthy
44
59
  - "Runs: 3, Tools: 2, Results > 0"
45
60
  - "Runs: 3, Tools: 2, Results: 0"
46
61
  - "All"
47
- group-by:
48
- description: "Group results by:"
62
+ representation:
63
+ description: "Representation:"
49
64
  required: false
50
- default: "Tool name"
65
+ default: "compact-group-by-tool-name-per-severity"
51
66
  type: choice
52
67
  options:
53
- - "Tool name"
54
- - "Run"
55
- - "Total"
56
- calculate-by:
57
- description: "Calculate results by:"
68
+ - "compact-group-by-run-per-level"
69
+ - "compact-group-by-run-per-severity"
70
+ - "compact-group-by-tool-name-per-level"
71
+ - "compact-group-by-tool-name-per-severity"
72
+ - "compact-group-by-sarif-per-level"
73
+ - "compact-group-by-sarif-per-severity"
74
+ - "compact-total-per-level"
75
+ - "compact-total-per-severity"
76
+ log-level:
77
+ description: "Log level:"
58
78
  required: false
59
- default: "Level"
79
+ default: "info"
60
80
  type: choice
61
81
  options:
62
- - "Level"
63
- - "Severity"
64
- log-level:
65
- description: "Log level:"
82
+ - "silly"
83
+ - "trace"
84
+ - "debug"
85
+ - "info"
86
+ - "warning"
87
+ - "error"
88
+ - "fatal"
89
+ send-if:
90
+ description: "Send if:"
66
91
  required: false
67
- default: info
92
+ default: "always"
68
93
  type: choice
69
94
  options:
70
- - silly
71
- - trace
72
- - debug
73
- - info
74
- - warning
75
- - error
76
- - fatal
95
+ - "severity-critical"
96
+ - "severity-high"
97
+ - "severity-high-or-higher"
98
+ - "severity-medium"
99
+ - "severity-medium-or-higher"
100
+ - "severity-low"
101
+ - "severity-low-or-higher"
102
+ - "severity-none"
103
+ - "severity-none-or-higher"
104
+ - "severity-unknown"
105
+ - "severity-unknown-or-higher"
106
+ - "level-error"
107
+ - "level-warning"
108
+ - "level-warning-or-higher"
109
+ - "level-note"
110
+ - "level-note-or-higher"
111
+ - "level-none"
112
+ - "level-none-or-higher"
113
+ - "level-unknown"
114
+ - "level-unknown-or-higher"
115
+ - "always"
116
+ - "some"
117
+ - "empty"
118
+ - "never"
77
119
  color:
78
120
  description: "Slack message color (hex):"
79
121
  required: false
@@ -120,60 +162,90 @@ jobs:
120
162
  runs-on: ubuntu-latest
121
163
  steps:
122
164
  - name: Checkout ${{ github.repository }}
123
- uses: actions/checkout@v4
165
+ uses: actions/checkout@v5
124
166
  - name: Determine SARIF file
125
167
  id: sarif-file
126
168
  env:
127
169
  INPUT_SARIF: "${{ inputs.sarif }}"
128
170
  run: |
129
- if [ "${INPUT_SARIF}" = "CodeQL C# (Unknown: 1)" ]; then
171
+ if [ "${INPUT_SARIF}" = "CodeQL C# (High: 1)1)" ]; then
130
172
  value="codeql-csharp.sarif"
131
- elif [ "${INPUT_SARIF}" = "CodeQL Go (Unknown: 1)" ]; then
173
+ elif [ "${INPUT_SARIF}" = "CodeQL Go (Critical: 1)" ]; then
132
174
  value="codeql-go.sarif"
133
- elif [ "${INPUT_SARIF}" = "CodeQL Python (Unknown: 1)" ]; then
175
+ elif [ "${INPUT_SARIF}" = "CodeQL Python (Medium: 1)" ]; then
134
176
  value="codeql-python.sarif"
135
- elif [ "${INPUT_SARIF}" = "CodeQL Ruby (Unknown: 4)" ]; then
177
+ elif [ "${INPUT_SARIF}" = "CodeQL Ruby (Critical: 3, High: 1)" ]; then
136
178
  value="codeql-ruby.sarif"
137
- elif [ "${INPUT_SARIF}" = "CodeQL TypeScript (Unknown: 1)" ]; then
179
+ elif [ "${INPUT_SARIF}" = "CodeQL TypeScript (Critical: 1)" ]; then
138
180
  value="codeql-typescript.sarif"
139
- elif [ "${INPUT_SARIF}" = "Grype Container (Error: 10, Warning: 20, Note: 9)" ]; then
181
+ elif [ "${INPUT_SARIF}" = "Grype Container (Critical: 4, High: 6, Medium: 20, Low: 9)" ]; then
140
182
  value="grype-container.sarif"
141
- elif [ "${INPUT_SARIF}" = "Snyk Composer (Error: 15, Warning: 5)" ]; then
183
+ elif [ "${INPUT_SARIF}" = "Grype GitHub Actions (High: 1)" ]; then
184
+ value="grype-github-actions.sarif"
185
+ elif [ "${INPUT_SARIF}" = "OSV Scanner Composer (Critical: 5, High: 4, Medium: 7)" ]; then
186
+ value="osv-scanner-composer.sarif"
187
+ elif [ "${INPUT_SARIF}" = "OSV Scanner Container (Critical: 2, High: 7, Medium: 7, Low: 6, Unknown: 26)" ]; then
188
+ value="osv-scanner-container.sarif"
189
+ elif [ "${INPUT_SARIF}" = "OSV Scanner Gomodules (Critical: 1, High: 6, Medium: 9)" ]; then
190
+ value="osv-scanner-gomodules.sarif"
191
+ elif [ "${INPUT_SARIF}" = "OSV Scanner Hex (Unknown: 2)" ]; then
192
+ value="osv-scanner-hex.sarif"
193
+ elif [ "${INPUT_SARIF}" = "OSV Scanner Maven (Critical: 1, Unknown: 1)" ]; then
194
+ value="osv-scanner-maven.sarif"
195
+ elif [ "${INPUT_SARIF}" = "OSV Scanner NPM (High: 4, Medium: 5, Unknown: 1)" ]; then
196
+ value="osv-scanner-npm.sarif"
197
+ elif [ "${INPUT_SARIF}" = "OSV Scanner Pip (High: 2, Unknown: 1)" ]; then
198
+ value="osv-scanner-pip.sarif"
199
+ elif [ "${INPUT_SARIF}" = "OSV Scanner Pipenv (High: 4)" ]; then
200
+ value="osv-scanner-pipenv.sarif"
201
+ elif [ "${INPUT_SARIF}" = "OSV Scanner PNPM (High: 2)" ]; then
202
+ value="osv-scanner-pnpm.sarif"
203
+ elif [ "${INPUT_SARIF}" = "OSV Scanner Poetry (High: 21, Medium: 13, Low: 2, Unknown: 1)" ]; then
204
+ value="osv-scanner-poetry.sarif"
205
+ elif [ "${INPUT_SARIF}" = "OSV Scanner Rubygems (High: 4, Medium: 2)" ]; then
206
+ value="osv-scanner-rubygems.sarif"
207
+ elif [ "${INPUT_SARIF}" = "OSV Scanner UV (High: 2, Unknown: 1)" ]; then
208
+ value="osv-scanner-uv.sarif"
209
+ elif [ "${INPUT_SARIF}" = "OSV Scanner Yarn (Critical: 17, High: 39, Medium: 31, Low: 4, Unknown: 6)" ]; then
210
+ value="osv-scanner-yarn.sarif"
211
+ elif [ "${INPUT_SARIF}" = "Snyk Composer (Critical: 4, High: 7, Medium: 5, Low: 1, None: 3)" ]; then
142
212
  value="snyk-composer.sarif"
143
- elif [ "${INPUT_SARIF}" = "Snyk Container (Error: 1, Note: 3)" ]; then
213
+ elif [ "${INPUT_SARIF}" = "Snyk Container (High: 1, None: 3)" ]; then
144
214
  value="snyk-container.sarif"
145
- elif [ "${INPUT_SARIF}" = "Snyk Gomodules (Error: 4, Warning: 4)" ]; then
215
+ elif [ "${INPUT_SARIF}" = "Snyk Gomodules (High: 4, Medium: 4)" ]; then
146
216
  value="snyk-gomodules.sarif"
147
- elif [ "${INPUT_SARIF}" = "Snyk Gradle (Error: 3, Warning: 1)" ]; then
217
+ elif [ "${INPUT_SARIF}" = "Snyk Gradle (Critical: 2, Medium: 1, None: 1)" ]; then
148
218
  value="snyk-gradle.sarif"
149
- elif [ "${INPUT_SARIF}" = "Snyk Hex (Error: 1)" ]; then
219
+ elif [ "${INPUT_SARIF}" = "Snyk Hex (Critical: 1)" ]; then
150
220
  value="snyk-hex.sarif"
151
- elif [ "${INPUT_SARIF}" = "Snyk Maven (Error: 3, Warning: 1)" ]; then
221
+ elif [ "${INPUT_SARIF}" = "Snyk Maven (Critical: 2, Medium: 1, None: 1)" ]; then
152
222
  value="snyk-maven.sarif"
153
- elif [ "${INPUT_SARIF}" = "Snyk NPM (Error: 6, Warning: 6, Note: 2)" ]; then
223
+ elif [ "${INPUT_SARIF}" = "Snyk NPM (High: 2, Medium: 6, Low: 2, None: 4)" ]; then
154
224
  value="snyk-npm.sarif"
155
- elif [ "${INPUT_SARIF}" = "Snyk Nuget (Error: 1)" ]; then
225
+ elif [ "${INPUT_SARIF}" = "Snyk Nuget (High: 1)" ]; then
156
226
  value="snyk-nuget.sarif"
157
- elif [ "${INPUT_SARIF}" = "Snyk Pip (Warning: 1)" ]; then
227
+ elif [ "${INPUT_SARIF}" = "Snyk Pip (Medium: 1)" ]; then
158
228
  value="snyk-pip.sarif"
159
- elif [ "${INPUT_SARIF}" = "Snyk PNPM (Error: 1)" ]; then
229
+ elif [ "${INPUT_SARIF}" = "Snyk PNPM (High: 1)" ]; then
160
230
  value="snyk-pnpm.sarif"
161
- elif [ "${INPUT_SARIF}" = "Snyk Poetry (Error: 6, Warning: 21, Note: 2)" ]; then
231
+ elif [ "${INPUT_SARIF}" = "Snyk Poetry (High: 5, Medium: 21, Low: 2, None: 1)" ]; then
162
232
  value="snyk-poetry.sarif"
163
- elif [ "${INPUT_SARIF}" = "Snyk Rubygems (Error: 1, Warning: 5)" ]; then
233
+ elif [ "${INPUT_SARIF}" = "Snyk Rubygems (High: 1, Medium: 5)" ]; then
164
234
  value="snyk-rubygems.sarif"
165
- elif [ "${INPUT_SARIF}" = "Snyk Sbt (Error: 2, Warning: 1)" ]; then
235
+ elif [ "${INPUT_SARIF}" = "Snyk Sbt (Medium: 1, None: 2)" ]; then
166
236
  value="snyk-sbt.sarif"
167
- elif [ "${INPUT_SARIF}" = "Snyk Swift (Warning: 2)" ]; then
237
+ elif [ "${INPUT_SARIF}" = "Snyk Swift (Medium: 2)" ]; then
168
238
  value="snyk-swift.sarif"
169
- elif [ "${INPUT_SARIF}" = "Snyk Yarn (Error: 30, Warning: 16, Note: 3)" ]; then
239
+ elif [ "${INPUT_SARIF}" = "Snyk Yarn (High: 19, Medium: 16, Low: 3, None: 11)" ]; then
170
240
  value="snyk-yarn.sarif"
171
- elif [ "${INPUT_SARIF}" = "Trivy IaC (Error: 1, Note: 1)" ]; then
241
+ elif [ "${INPUT_SARIF}" = "Trivy IaC (High: 1, Low: 1)" ]; then
172
242
  value="trivy-iac.sarif"
173
- elif [ "${INPUT_SARIF}" = "Wiz Container (Error: 12, Warning: 369, Note: 191)" ]; then
243
+ elif [ "${INPUT_SARIF}" = "Wiz Container (Critical: 48, High: 209, Medium: 245, Low: 70)" ]; then
174
244
  value="wiz-container.sarif"
175
- elif [ "${INPUT_SARIF}" = "Wiz IaC (Warning: 5, Note: 5)" ]; then
245
+ elif [ "${INPUT_SARIF}" = "Wiz IaC (Medium: 5, Low: 5)" ]; then
176
246
  value="wiz-iac.sarif"
247
+ elif [ "${INPUT_SARIF}" = "Runs: 0" ]; then
248
+ value="runs-0.sarif"
177
249
  elif [ "${INPUT_SARIF}" = "Runs: 1, Extensions: 1, Results: 0" ]; then
178
250
  value="runs-1-extensions-1-results-0.sarif"
179
251
  elif [ "${INPUT_SARIF}" = "Runs: 1, Extensions: 1, Results > 0" ]; then
@@ -215,6 +287,6 @@ jobs:
215
287
  SARIF_TO_SLACK_FOOTER: "${{ inputs.footer }}"
216
288
  SARIF_TO_SLACK_ACTOR: "${{ inputs.actor }}"
217
289
  SARIF_TO_SLACK_INCLUDE_RUN: "${{ inputs.include-run }}"
218
- SARIF_TO_SLACK_GROUP_BY: "${{ inputs.group-by}}"
219
- SARIF_TO_SLACK_CALCULATE_BY: "${{ inputs.calculate-by}}"
290
+ SARIF_TO_SLACK_REPRESENTATION: "${{ inputs.representation }}"
291
+ SARIF_TO_SLACK_SEND_IF: "${{ inputs.send-if }}"
220
292
  run: make test/integration
@@ -0,0 +1,8 @@
1
+ test-data/sarif/osv-scanner-poetry.sarif:curl-auth-user:1347
2
+ test-data/sarif/osv-scanner-poetry.sarif:curl-auth-user:1348
3
+ test-data/sarif/osv-scanner-poetry.sarif:curl-auth-user:1351
4
+ test-data/sarif/osv-scanner-poetry.sarif:curl-auth-user:1352
5
+ test-data/sarif/osv-scanner-yarn.sarif:aws-access-token:4181
6
+ test-data/sarif/osv-scanner-yarn.sarif:aws-access-token:4182
7
+ test-data/sarif/osv-scanner-yarn.sarif:aws-access-token:4185
8
+ test-data/sarif/osv-scanner-yarn.sarif:aws-access-token:4186
@@ -60,7 +60,7 @@ repos:
60
60
  - --hook-args=--log-level debug
61
61
  stages: ["pre-push"]
62
62
  - repo: https://github.com/google/osv-scanner
63
- rev: v2.1.0
63
+ rev: v2.2.1
64
64
  hooks:
65
65
  - id: osv-scanner
66
66
  args:
@@ -84,11 +84,11 @@ repos:
84
84
  rev: v1.7.7
85
85
  hooks:
86
86
  - id: actionlint
87
- args: ["-pyflakes="]
87
+ args: ["-pyflakes=", "-shellcheck="]
88
88
  stages: ["pre-commit"]
89
89
  # Other
90
90
  - repo: https://github.com/pre-commit/pre-commit-hooks
91
- rev: v5.0.0
91
+ rev: v6.0.0
92
92
  hooks:
93
93
  - id: check-merge-conflict
94
94
  - id: check-json
package/.tool-versions CHANGED
@@ -1 +1 @@
1
- nodejs 24.4.1
1
+ nodejs 24.5.0
package/dist/Logger.js CHANGED
@@ -30,5 +30,8 @@ export default class Logger {
30
30
  static debug(...args) {
31
31
  Logger.instance.debug(...args);
32
32
  }
33
+ static trace(...args) {
34
+ Logger.instance.trace(...args);
35
+ }
33
36
  }
34
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTG9nZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0xvZ2dlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQVcsTUFBTSxJQUFJLFFBQVEsRUFBRSxNQUFNLE9BQU8sQ0FBQTtBQUNuRCxPQUFPLEVBQUUsUUFBUSxFQUFjLE1BQU0sU0FBUyxDQUFBO0FBRTlDOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sTUFBTTtJQUNqQixNQUFNLENBQUMsaUJBQWlCLEdBQWEsUUFBUSxDQUFDLElBQUksQ0FBQTtJQUNsRCxNQUFNLENBQUMsb0JBQW9CLEdBQVcsK0NBQStDLENBQUE7SUFDckYsTUFBTSxDQUFDLG1CQUFtQixHQUFZLElBQUksQ0FBQTtJQUUxQyxNQUFNLENBQUMsUUFBUSxDQUFtQjtJQUVuQyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQWlCO1FBQ3hDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDckIsTUFBTSxDQUFDLFFBQVEsR0FBRyxJQUFJLFFBQVEsQ0FBQztnQkFDN0IsSUFBSSxFQUFFLDBCQUEwQjtnQkFDaEMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLElBQUksTUFBTSxDQUFDLGlCQUFpQixDQUFDO2dCQUNoSCxJQUFJLEVBQUUsUUFBUTtnQkFDZCxpQkFBaUIsRUFBRSxLQUFLO2dCQUN4QixpQkFBaUIsRUFBRSxJQUFJLEVBQUUsUUFBUSxJQUFJLE1BQU0sQ0FBQyxvQkFBb0I7Z0JBQ2hFLGVBQWUsRUFBRSxJQUFJLEVBQUUsT0FBTyxJQUFJLE1BQU0sQ0FBQyxtQkFBbUI7YUFDN0QsQ0FBQyxDQUFBO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFTSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBZTtRQUNuQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFBO0lBQy9CLENBQUM7SUFFTSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBZTtRQUNuQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFBO0lBQy9CLENBQUM7SUFFTSxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBZTtRQUNwQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFBO0lBQ2hDLENBQUMifQ==
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTG9nZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0xvZ2dlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQVcsTUFBTSxJQUFJLFFBQVEsRUFBRSxNQUFNLE9BQU8sQ0FBQTtBQUNuRCxPQUFPLEVBQUUsUUFBUSxFQUFjLE1BQU0sU0FBUyxDQUFBO0FBRTlDOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sTUFBTTtJQUNqQixNQUFNLENBQUMsaUJBQWlCLEdBQWEsUUFBUSxDQUFDLElBQUksQ0FBQTtJQUNsRCxNQUFNLENBQUMsb0JBQW9CLEdBQVcsK0NBQStDLENBQUE7SUFDckYsTUFBTSxDQUFDLG1CQUFtQixHQUFZLElBQUksQ0FBQTtJQUUxQyxNQUFNLENBQUMsUUFBUSxDQUFtQjtJQUVuQyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQWlCO1FBQ3hDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDckIsTUFBTSxDQUFDLFFBQVEsR0FBRyxJQUFJLFFBQVEsQ0FBQztnQkFDN0IsSUFBSSxFQUFFLDBCQUEwQjtnQkFDaEMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLElBQUksTUFBTSxDQUFDLGlCQUFpQixDQUFDO2dCQUNoSCxJQUFJLEVBQUUsUUFBUTtnQkFDZCxpQkFBaUIsRUFBRSxLQUFLO2dCQUN4QixpQkFBaUIsRUFBRSxJQUFJLEVBQUUsUUFBUSxJQUFJLE1BQU0sQ0FBQyxvQkFBb0I7Z0JBQ2hFLGVBQWUsRUFBRSxJQUFJLEVBQUUsT0FBTyxJQUFJLE1BQU0sQ0FBQyxtQkFBbUI7YUFDN0QsQ0FBQyxDQUFBO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFTSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBZTtRQUNuQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFBO0lBQy9CLENBQUM7SUFFTSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBZTtRQUNuQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFBO0lBQy9CLENBQUM7SUFFTSxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBZTtRQUNwQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFBO0lBQ2hDLENBQUM7SUFFTSxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBZTtRQUNwQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFBO0lBQ2hDLENBQUMifQ==
@@ -0,0 +1,33 @@
1
+ import { SarifToSlackClientOptions } from './types';
2
+ /**
3
+ * Service to convert SARIF files to Slack messages and send them.
4
+ * @public
5
+ */
6
+ export declare class SarifToSlackClient {
7
+ private _message?;
8
+ private _sarifModel?;
9
+ private _sendIf;
10
+ private constructor();
11
+ private static createRunIdGenerator;
12
+ static create(opts: SarifToSlackClientOptions): Promise<SarifToSlackClient>;
13
+ private static buildModel;
14
+ /**
15
+ * The main function to initialize a list of {@link SlackMessage} objects based
16
+ * on the given SARIF file(s).
17
+ * @param sarifModel An instance of {@link SarifModel} object.
18
+ * @param opts An instance of {@link SarifToSlackClientOptions} object.
19
+ * @returns A map where key is the SARIF file and value is an instance of
20
+ * {@link SlackMessage} object
21
+ * @private
22
+ */
23
+ private static initialize;
24
+ /**
25
+ * Sends a Slack message.
26
+ * @returns A promise that resolves when the message has been sent.
27
+ * @throws Error if a Slack message was not prepared for the given SARIF path.
28
+ * @public
29
+ */
30
+ send(): Promise<void>;
31
+ private get shouldSendMessage();
32
+ }
33
+ //# sourceMappingURL=SarifToSlackClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SarifToSlackClient.d.ts","sourceRoot":"","sources":["../src/SarifToSlackClient.ts"],"names":[],"mappings":"AAIA,OAAO,EAKL,yBAAyB,EAK1B,MAAM,SAAS,CAAA;AAShB;;;GAGG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,CAAc;IAC/B,OAAO,CAAC,WAAW,CAAC,CAAY;IAEhC,OAAO,CAAC,OAAO,CAAwB;IAEvC,OAAO;IAKP,OAAO,CAAC,MAAM,CAAE,oBAAoB;WAOhB,MAAM,CAAC,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,kBAAkB,CAAC;mBAWnE,UAAU;IAgC/B;;;;;;;;OAQG;mBACkB,UAAU;IAyB/B;;;;;OAKG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAelC,OAAO,KAAK,iBAAiB,GAyD5B;CACF"}
@@ -0,0 +1,178 @@
1
+ import { promises as fs } from 'fs';
2
+ import Logger from './Logger';
3
+ import { SlackMessageBuilder } from './SlackMessageBuilder';
4
+ import { SecurityLevel, SecuritySeverity, SendIf } from './types';
5
+ import System from './System';
6
+ import { extractListOfFiles } from './utils/FileUtils';
7
+ import { createRepresentation } from './representations/RepresentationFactory';
8
+ import { createFinding } from './model/Finding';
9
+ import { findToolComponent, findToolComponentDriver } from './utils/SarifUtils';
10
+ import { identifyColor } from './model/Color';
11
+ import FindingsArray from './model/FindingsArray';
12
+ /**
13
+ * Service to convert SARIF files to Slack messages and send them.
14
+ * @public
15
+ */
16
+ export class SarifToSlackClient {
17
+ _message;
18
+ _sarifModel;
19
+ _sendIf = SendIf.Always;
20
+ constructor(log) {
21
+ Logger.initialize(log);
22
+ System.initialize();
23
+ }
24
+ static *createRunIdGenerator() {
25
+ let runId = 1;
26
+ while (true) {
27
+ yield runId++;
28
+ }
29
+ }
30
+ static async create(opts) {
31
+ const instance = new SarifToSlackClient(opts.log);
32
+ Logger.trace('opts', opts);
33
+ instance._sendIf = opts.sendIf ?? instance._sendIf;
34
+ instance._sarifModel = await SarifToSlackClient.buildModel(opts.sarif);
35
+ Logger.trace('instance._sarifModel', instance._sarifModel);
36
+ instance._message = await SarifToSlackClient.initialize(instance._sarifModel, opts);
37
+ Logger.trace('instance._message', instance._message);
38
+ return instance;
39
+ }
40
+ static async buildModel(sarifOpts) {
41
+ const sarifFiles = extractListOfFiles(sarifOpts);
42
+ if (sarifFiles.length === 0) {
43
+ throw new Error(`No SARIF files found at the provided path: ${sarifOpts.path}`);
44
+ }
45
+ const model = { sarifFiles, runs: [], findings: new FindingsArray() };
46
+ const runIdGenerator = SarifToSlackClient.createRunIdGenerator();
47
+ for (const sarifPath of sarifFiles) {
48
+ const sarifJson = await fs.readFile(sarifPath, 'utf8');
49
+ const sarifLog = JSON.parse(sarifJson);
50
+ for (const run of sarifLog.runs) {
51
+ const runId = runIdGenerator.next();
52
+ let runMetadata = undefined;
53
+ for (const result of run.results ?? []) {
54
+ runMetadata = {
55
+ id: runId.value,
56
+ run,
57
+ toolName: findToolComponent(run, result).name
58
+ };
59
+ model.findings.push(createFinding({ sarifPath, result, runMetadata }));
60
+ }
61
+ runMetadata ??= {
62
+ id: runId.value, run, toolName: findToolComponentDriver(run).name
63
+ };
64
+ model.runs.push(runMetadata);
65
+ }
66
+ }
67
+ return model;
68
+ }
69
+ /**
70
+ * The main function to initialize a list of {@link SlackMessage} objects based
71
+ * on the given SARIF file(s).
72
+ * @param sarifModel An instance of {@link SarifModel} object.
73
+ * @param opts An instance of {@link SarifToSlackClientOptions} object.
74
+ * @returns A map where key is the SARIF file and value is an instance of
75
+ * {@link SlackMessage} object
76
+ * @private
77
+ */
78
+ static async initialize(sarifModel, opts) {
79
+ const message = new SlackMessageBuilder(opts.webhookUrl, {
80
+ username: opts.username,
81
+ iconUrl: opts.iconUrl,
82
+ color: identifyColor(sarifModel.findings, opts.color),
83
+ representation: createRepresentation(sarifModel, opts.representation),
84
+ });
85
+ if (opts.header?.include) {
86
+ message.withHeader(opts.header?.value);
87
+ }
88
+ if (opts.footer?.include) {
89
+ message.withFooter(opts.footer?.value, opts.footer?.type);
90
+ }
91
+ if (opts.actor?.include) {
92
+ message.withActor(opts.actor?.value);
93
+ }
94
+ if (opts.run?.include) {
95
+ message.withRun();
96
+ }
97
+ return message;
98
+ }
99
+ /**
100
+ * Sends a Slack message.
101
+ * @returns A promise that resolves when the message has been sent.
102
+ * @throws Error if a Slack message was not prepared for the given SARIF path.
103
+ * @public
104
+ */
105
+ async send() {
106
+ if (this._sarifModel == null) {
107
+ throw new Error('Could not parse SARIF file(s).');
108
+ }
109
+ if (this.shouldSendMessage) {
110
+ if (this._message == null) {
111
+ throw new Error('Slack message was not prepared.');
112
+ }
113
+ const text = await this._message.send();
114
+ Logger.info('Message sent. Status:', text);
115
+ }
116
+ else {
117
+ Logger.info('Message was not sent based on the sendIf parameter:', SendIf[this._sendIf]);
118
+ }
119
+ }
120
+ get shouldSendMessage() {
121
+ if (this._sendIf == null) {
122
+ return true;
123
+ }
124
+ switch (this._sendIf) {
125
+ case SendIf.SeverityCritical:
126
+ return this._sarifModel?.findings.findByProperty('severity', SecuritySeverity.Critical) != null;
127
+ case SendIf.SeverityHigh:
128
+ return this._sarifModel?.findings.findByProperty('severity', SecuritySeverity.High) != null;
129
+ case SendIf.SeverityHighOrHigher:
130
+ return !!this._sarifModel?.findings.hasSeverityOrHigher(SecuritySeverity.High);
131
+ case SendIf.SeverityMedium:
132
+ return this._sarifModel?.findings.findByProperty('severity', SecuritySeverity.Medium) != null;
133
+ case SendIf.SeverityMediumOrHigher:
134
+ return !!this._sarifModel?.findings.hasSeverityOrHigher(SecuritySeverity.Medium);
135
+ case SendIf.SeverityLow:
136
+ return this._sarifModel?.findings.findByProperty('severity', SecuritySeverity.Low) != null;
137
+ case SendIf.SeverityLowOrHigher:
138
+ return !!this._sarifModel?.findings.hasSeverityOrHigher(SecuritySeverity.Low);
139
+ case SendIf.SeverityNone:
140
+ return this._sarifModel?.findings.findByProperty('severity', SecuritySeverity.None) != null;
141
+ case SendIf.SeverityNoneOrHigher:
142
+ return !!this._sarifModel?.findings.hasSeverityOrHigher(SecuritySeverity.None);
143
+ case SendIf.SeverityUnknown:
144
+ return this._sarifModel?.findings.findByProperty('severity', SecuritySeverity.Unknown) != null;
145
+ case SendIf.SeverityUnknownOrHigher:
146
+ return !!this._sarifModel?.findings.hasSeverityOrHigher(SecuritySeverity.Unknown);
147
+ case SendIf.LevelError:
148
+ return this._sarifModel?.findings.findByProperty('level', SecurityLevel.Error) != null;
149
+ case SendIf.LevelWarning:
150
+ return this._sarifModel?.findings.findByProperty('level', SecurityLevel.Warning) != null;
151
+ case SendIf.LevelWarningOrHigher:
152
+ return !!this._sarifModel?.findings.hasLevelOrHigher(SecurityLevel.Warning);
153
+ case SendIf.LevelNote:
154
+ return this._sarifModel?.findings.findByProperty('level', SecurityLevel.Note) != null;
155
+ case SendIf.LevelNoteOrHigher:
156
+ return !!this._sarifModel?.findings.hasLevelOrHigher(SecurityLevel.Note);
157
+ case SendIf.LevelNone:
158
+ return this._sarifModel?.findings.findByProperty('level', SecurityLevel.None) != null;
159
+ case SendIf.LevelNoneOrHigher:
160
+ return !!this._sarifModel?.findings.hasLevelOrHigher(SecurityLevel.None);
161
+ case SendIf.LevelUnknown:
162
+ return this._sarifModel?.findings.findByProperty('level', SecurityLevel.Unknown) != null;
163
+ case SendIf.LevelUnknownOrHigher:
164
+ return !!this._sarifModel?.findings.hasLevelOrHigher(SecurityLevel.Unknown);
165
+ case SendIf.Always:
166
+ return true;
167
+ case SendIf.Some:
168
+ return (this._sarifModel?.findings.length ?? 0) > 0;
169
+ case SendIf.Empty:
170
+ return (this._sarifModel?.findings.length ?? 0) === 0;
171
+ case SendIf.Never:
172
+ return false;
173
+ default:
174
+ throw new Error(`Unknown sendIf parameter: ${this._sendIf}`);
175
+ }
176
+ }
177
+ }
178
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2FyaWZUb1NsYWNrQ2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1NhcmlmVG9TbGFja0NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxJQUFJLEVBQUUsRUFBRSxNQUFNLElBQUksQ0FBQTtBQUVuQyxPQUFPLE1BQU0sTUFBTSxVQUFVLENBQUE7QUFDN0IsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sdUJBQXVCLENBQUE7QUFDM0QsT0FBTyxFQU1MLGFBQWEsRUFDYixnQkFBZ0IsRUFDaEIsTUFBTSxFQUVQLE1BQU0sU0FBUyxDQUFBO0FBQ2hCLE9BQU8sTUFBTSxNQUFNLFVBQVUsQ0FBQTtBQUM3QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUN0RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQTtBQUM5RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFDL0MsT0FBTyxFQUFFLGlCQUFpQixFQUFFLHVCQUF1QixFQUFFLE1BQU0sb0JBQW9CLENBQUE7QUFDL0UsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUM3QyxPQUFPLGFBQWEsTUFBTSx1QkFBdUIsQ0FBQTtBQUVqRDs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sa0JBQWtCO0lBQ3JCLFFBQVEsQ0FBZTtJQUN2QixXQUFXLENBQWE7SUFFeEIsT0FBTyxHQUFXLE1BQU0sQ0FBQyxNQUFNLENBQUE7SUFFdkMsWUFBb0IsR0FBZ0I7UUFDbEMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUN0QixNQUFNLENBQUMsVUFBVSxFQUFFLENBQUE7SUFDckIsQ0FBQztJQUVPLE1BQU0sQ0FBQyxDQUFDLG9CQUFvQjtRQUNsQyxJQUFJLEtBQUssR0FBVyxDQUFDLENBQUE7UUFDckIsT0FBTyxJQUFJLEVBQUUsQ0FBQztZ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