@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.
- package/.github/workflows/release.yml +1 -1
- package/.github/workflows/security.yml +0 -1
- package/.github/workflows/send-sarif-to-slack.yml +145 -73
- package/.gitleaksignore +8 -0
- package/.pre-commit-config.yaml +3 -3
- package/.tool-versions +1 -1
- package/dist/Logger.js +4 -1
- package/dist/SarifToSlackClient.d.ts +33 -0
- package/dist/SarifToSlackClient.d.ts.map +1 -0
- package/dist/SarifToSlackClient.js +178 -0
- package/dist/SlackMessageBuilder.js +34 -82
- package/dist/System.d.ts +1 -3
- package/dist/System.d.ts.map +1 -1
- package/dist/System.js +10 -3
- package/dist/index.cjs +826 -472
- package/dist/index.d.ts +35 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +36 -12
- package/dist/model/Color.d.ts +80 -0
- package/dist/model/Color.d.ts.map +1 -0
- package/dist/model/Color.js +106 -0
- package/dist/model/Finding.d.ts +2 -0
- package/dist/model/Finding.d.ts.map +1 -0
- package/dist/model/Finding.js +93 -0
- package/dist/model/FindingsArray.d.ts +2 -0
- package/dist/model/FindingsArray.d.ts.map +1 -0
- package/dist/model/FindingsArray.js +24 -0
- package/dist/processors/CodeQLProcessor.d.ts +2 -0
- package/dist/processors/CodeQLProcessor.d.ts.map +1 -0
- package/dist/processors/CodeQLProcessor.js +17 -0
- package/dist/processors/CommonProcessor.d.ts +2 -0
- package/dist/processors/CommonProcessor.d.ts.map +1 -0
- package/dist/processors/CommonProcessor.js +84 -0
- package/dist/processors/ProcessorFactory.d.ts +2 -0
- package/dist/processors/ProcessorFactory.d.ts.map +1 -0
- package/dist/processors/ProcessorFactory.js +22 -0
- package/dist/processors/SnykProcessor.d.ts +2 -0
- package/dist/processors/SnykProcessor.d.ts.map +1 -0
- package/dist/processors/SnykProcessor.js +18 -0
- package/dist/representations/CompactGroupByRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupByRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupByRepresentation.js +58 -0
- package/dist/representations/CompactGroupByRunPerLevelRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupByRunPerLevelRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupByRunPerLevelRepresentation.js +13 -0
- package/dist/representations/CompactGroupByRunPerSeverityRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupByRunPerSeverityRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupByRunPerSeverityRepresentation.js +13 -0
- package/dist/representations/CompactGroupByRunRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupByRunRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupByRunRepresentation.js +39 -0
- package/dist/representations/CompactGroupBySarifPerLevelRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupBySarifPerLevelRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupBySarifPerLevelRepresentation.js +13 -0
- package/dist/representations/CompactGroupBySarifPerSeverityRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupBySarifPerSeverityRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupBySarifPerSeverityRepresentation.js +13 -0
- package/dist/representations/CompactGroupBySarifRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupBySarifRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupBySarifRepresentation.js +40 -0
- package/dist/representations/CompactGroupByToolNamePerLevelRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupByToolNamePerLevelRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupByToolNamePerLevelRepresentation.js +13 -0
- package/dist/representations/CompactGroupByToolNamePerSeverityRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupByToolNamePerSeverityRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupByToolNamePerSeverityRepresentation.js +13 -0
- package/dist/representations/CompactGroupByToolNameRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupByToolNameRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupByToolNameRepresentation.js +39 -0
- package/dist/representations/CompactTotalPerLevelRepresentation.d.ts +2 -0
- package/dist/representations/CompactTotalPerLevelRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactTotalPerLevelRepresentation.js +13 -0
- package/dist/representations/CompactTotalPerSeverityRepresentation.d.ts +2 -0
- package/dist/representations/CompactTotalPerSeverityRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactTotalPerSeverityRepresentation.js +13 -0
- package/dist/representations/CompactTotalRepresentation.d.ts +2 -0
- package/dist/representations/CompactTotalRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactTotalRepresentation.js +25 -0
- package/dist/representations/Representation.d.ts +2 -0
- package/dist/representations/Representation.d.ts.map +1 -0
- package/dist/representations/Representation.js +28 -0
- package/dist/representations/RepresentationFactory.d.ts +2 -0
- package/dist/representations/RepresentationFactory.d.ts.map +1 -0
- package/dist/representations/RepresentationFactory.js +37 -0
- package/dist/sarif-to-slack.d.ts +347 -85
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/types.d.ts +215 -51
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +225 -33
- package/dist/utils/Comparators.d.ts +2 -0
- package/dist/utils/Comparators.d.ts.map +1 -0
- package/dist/utils/Comparators.js +18 -0
- package/dist/utils/ExtendedArray.d.ts +2 -0
- package/dist/utils/ExtendedArray.d.ts.map +1 -0
- package/dist/utils/ExtendedArray.js +11 -0
- package/dist/utils/FileUtils.d.ts +2 -0
- package/dist/utils/FileUtils.d.ts.map +1 -0
- package/dist/utils/FileUtils.js +51 -0
- package/dist/utils/SarifUtils.js +20 -54
- package/etc/sarif-to-slack.api.md +162 -99
- package/jest.config.json +2 -2
- package/package.json +7 -7
- package/scripts/save-metadata.sh +12 -10
- package/src/Logger.ts +4 -0
- package/src/SarifToSlackClient.ts +202 -0
- package/src/SlackMessageBuilder.ts +35 -115
- package/src/System.ts +9 -2
- package/src/index.ts +47 -20
- package/src/model/Color.ts +195 -0
- package/src/model/Finding.ts +137 -0
- package/src/model/FindingsArray.ts +27 -0
- package/src/processors/CodeQLProcessor.ts +19 -0
- package/src/processors/CommonProcessor.ts +103 -0
- package/src/processors/ProcessorFactory.ts +23 -0
- package/src/processors/SnykProcessor.ts +19 -0
- package/src/representations/CompactGroupByRepresentation.ts +67 -0
- package/src/representations/CompactGroupByRunPerLevelRepresentation.ts +14 -0
- package/src/representations/CompactGroupByRunPerSeverityRepresentation.ts +14 -0
- package/src/representations/CompactGroupByRunRepresentation.ts +44 -0
- package/src/representations/CompactGroupBySarifPerLevelRepresentation.ts +15 -0
- package/src/representations/CompactGroupBySarifPerSeverityRepresentation.ts +15 -0
- package/src/representations/CompactGroupBySarifRepresentation.ts +45 -0
- package/src/representations/CompactGroupByToolNamePerLevelRepresentation.ts +15 -0
- package/src/representations/CompactGroupByToolNamePerSeverityRepresentation.ts +15 -0
- package/src/representations/CompactGroupByToolNameRepresentation.ts +44 -0
- package/src/representations/CompactTotalPerLevelRepresentation.ts +14 -0
- package/src/representations/CompactTotalPerSeverityRepresentation.ts +14 -0
- package/src/representations/CompactTotalRepresentation.ts +27 -0
- package/src/representations/Representation.ts +35 -0
- package/src/representations/RepresentationFactory.ts +49 -0
- package/src/types.ts +270 -53
- package/src/utils/Comparators.ts +19 -0
- package/src/utils/ExtendedArray.ts +11 -0
- package/src/utils/FileUtils.ts +60 -0
- package/src/utils/SarifUtils.ts +20 -72
- package/test-data/sarif/codeql-python.sarif +1448 -1
- package/test-data/sarif/codeql-typescript.sarif +3474 -1
- package/test-data/sarif/grype-github-actions.sarif +65 -0
- package/test-data/sarif/osv-scanner-composer.sarif +972 -0
- package/test-data/sarif/osv-scanner-container.sarif +2278 -0
- package/test-data/sarif/osv-scanner-gomodules.sarif +813 -0
- package/test-data/sarif/osv-scanner-hex.sarif +147 -0
- package/test-data/sarif/osv-scanner-maven.sarif +171 -0
- package/test-data/sarif/osv-scanner-npm.sarif +627 -0
- package/test-data/sarif/osv-scanner-pip.sarif +206 -0
- package/test-data/sarif/osv-scanner-pipenv.sarif +243 -0
- package/test-data/sarif/osv-scanner-pnpm.sarif +174 -0
- package/test-data/sarif/osv-scanner-poetry.sarif +1893 -0
- package/test-data/sarif/osv-scanner-rubygems.sarif +402 -0
- package/test-data/sarif/osv-scanner-uv.sarif +206 -0
- package/test-data/sarif/osv-scanner-yarn.sarif +5207 -0
- package/test-data/sarif/runs-0.sarif +5 -0
- package/test-data/sarif/runs-2-tools-2-results-0.sarif +1 -1
- package/test-data/sarif/runs-2-tools-2.sarif +1 -1
- package/test-data/sarif/runs-3-tools-2-results-0.sarif +1 -1
- package/test-data/sarif/runs-3-tools-2.sarif +1 -1
- package/test-data/sarif/tmp/codeql-csharp.sarif +1 -0
- package/test-data/sarif/tmp/grype-container.sarif +1774 -0
- package/test-data/sarif/tmp/runs-1-tools-1-results-0.sarif +18 -0
- package/test-data/sarif/tmp/runs-2-tools-2.sarif +686 -0
- package/test-data/sarif/trivy-iac.sarif +1 -1
- package/tests/integration/SendSarifToSlack.spec.ts +95 -27
- package/tsconfig.json +2 -0
- package/dist/Processors.d.ts +0 -2
- package/dist/Processors.d.ts.map +0 -1
- package/dist/Processors.js +0 -61
- package/dist/SarifToSlackService.d.ts +0 -39
- package/dist/SarifToSlackService.d.ts.map +0 -1
- package/dist/SarifToSlackService.js +0 -104
- package/dist/metadata.d.ts +0 -2
- package/dist/metadata.d.ts.map +0 -1
- package/dist/metadata.js +0 -11
- package/dist/model/SarifModelPerRun.d.ts +0 -2
- package/dist/model/SarifModelPerRun.d.ts.map +0 -1
- package/dist/model/SarifModelPerRun.js +0 -90
- package/dist/model/SarifModelPerSarif.d.ts +0 -2
- package/dist/model/SarifModelPerSarif.d.ts.map +0 -1
- package/dist/model/SarifModelPerSarif.js +0 -102
- package/dist/model/types.d.ts +0 -2
- package/dist/model/types.d.ts.map +0 -1
- package/dist/model/types.js +0 -49
- package/dist/utils/SortUtils.d.ts +0 -2
- package/dist/utils/SortUtils.d.ts.map +0 -1
- package/dist/utils/SortUtils.js +0 -20
- package/src/Processors.ts +0 -68
- package/src/SarifToSlackService.ts +0 -117
- package/src/metadata.ts +0 -10
- package/src/model/SarifModelPerRun.ts +0 -120
- package/src/model/SarifModelPerSarif.ts +0 -126
- package/src/model/types.ts +0 -50
- package/src/utils/SortUtils.ts +0 -33
- 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
|
+
}
|
package/src/utils/SarifUtils.ts
CHANGED
|
@@ -1,87 +1,35 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Result, Run, ToolComponent } from 'sarif'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* @
|
|
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
|
|
10
|
-
|
|
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
|
-
*
|
|
24
|
-
* @
|
|
25
|
-
*
|
|
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
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
*
|
|
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
|
|
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
|
}
|