@fabasoad/sarif-to-slack 1.3.5 → 1.4.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 (142) hide show
  1. package/.github/workflows/security.yml +1 -0
  2. package/.github/workflows/send-sarif-to-slack.yml +39 -15
  3. package/README.md +8 -7
  4. package/dist/Logger.js +40 -30
  5. package/dist/SarifToSlackClient.d.ts +0 -1
  6. package/dist/SarifToSlackClient.d.ts.map +1 -1
  7. package/dist/SarifToSlackClient.js +11 -8
  8. package/dist/globalState.d.ts +2 -0
  9. package/dist/globalState.d.ts.map +1 -0
  10. package/dist/globalState.js +2 -0
  11. package/dist/index.cjs +111 -81
  12. package/dist/index.d.ts +40 -2
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +9 -2
  15. package/dist/model/Finding.js +7 -5
  16. package/dist/model/FindingArray.js +1 -1
  17. package/dist/model/SendIf.js +1 -1
  18. package/dist/model/SlackMessage.js +6 -6
  19. package/dist/model/color/Color.d.ts.map +1 -1
  20. package/dist/model/color/Color.js +1 -1
  21. package/dist/model/color/ColorIdentification.js +5 -5
  22. package/dist/model/color/ColorOptions.d.ts.map +1 -1
  23. package/dist/processors/CodeQLProcessor.js +1 -1
  24. package/dist/processors/CommonProcessor.js +1 -1
  25. package/dist/processors/ProcessorFactory.js +1 -1
  26. package/dist/processors/SnykProcessor.js +2 -1
  27. package/dist/representations/CompactGroupByRepresentation.js +1 -1
  28. package/dist/representations/CompactGroupByRunPerLevelRepresentation.js +1 -1
  29. package/dist/representations/CompactGroupByRunPerSeverityRepresentation.js +1 -1
  30. package/dist/representations/CompactGroupByRunRepresentation.js +1 -1
  31. package/dist/representations/CompactGroupBySarifPerLevelRepresentation.js +1 -1
  32. package/dist/representations/CompactGroupBySarifPerSeverityRepresentation.js +1 -1
  33. package/dist/representations/CompactGroupBySarifRepresentation.js +1 -1
  34. package/dist/representations/CompactGroupByToolNamePerLevelRepresentation.js +1 -1
  35. package/dist/representations/CompactGroupByToolNamePerSeverityRepresentation.js +1 -1
  36. package/dist/representations/CompactGroupByToolNameRepresentation.js +1 -1
  37. package/dist/representations/CompactTotalPerLevelRepresentation.js +1 -1
  38. package/dist/representations/CompactTotalPerSeverityRepresentation.js +1 -1
  39. package/dist/representations/CompactTotalRepresentation.js +1 -1
  40. package/dist/representations/Representation.js +1 -1
  41. package/dist/representations/RepresentationFactory.js +1 -1
  42. package/dist/representations/TableGroupByRunPerLevelRepresentation.d.ts.map +1 -1
  43. package/dist/representations/TableGroupByRunPerLevelRepresentation.js +1 -1
  44. package/dist/representations/TableGroupByRunPerSeverityRepresentation.d.ts.map +1 -1
  45. package/dist/representations/TableGroupByRunPerSeverityRepresentation.js +1 -1
  46. package/dist/representations/TableGroupByRunRepresentation.d.ts.map +1 -1
  47. package/dist/representations/TableGroupByRunRepresentation.js +1 -1
  48. package/dist/representations/TableGroupBySarifPerLevelRepresentation.d.ts.map +1 -1
  49. package/dist/representations/TableGroupBySarifPerLevelRepresentation.js +1 -1
  50. package/dist/representations/TableGroupBySarifPerSeverityRepresentation.d.ts.map +1 -1
  51. package/dist/representations/TableGroupBySarifPerSeverityRepresentation.js +1 -1
  52. package/dist/representations/TableGroupBySarifRepresentation.d.ts.map +1 -1
  53. package/dist/representations/TableGroupBySarifRepresentation.js +1 -1
  54. package/dist/representations/TableGroupByToolNamePerLevelRepresentation.d.ts.map +1 -1
  55. package/dist/representations/TableGroupByToolNamePerLevelRepresentation.js +1 -1
  56. package/dist/representations/TableGroupByToolNamePerSeverityRepresentation.d.ts.map +1 -1
  57. package/dist/representations/TableGroupByToolNamePerSeverityRepresentation.js +1 -1
  58. package/dist/representations/TableGroupByToolNameRepresentation.d.ts.map +1 -1
  59. package/dist/representations/TableGroupByToolNameRepresentation.js +1 -1
  60. package/dist/representations/TableGroupRepresentation.d.ts +0 -1
  61. package/dist/representations/TableGroupRepresentation.d.ts.map +1 -1
  62. package/dist/representations/TableGroupRepresentation.js +3 -3
  63. package/dist/representations/table/Cell.d.ts.map +1 -1
  64. package/dist/representations/table/Cell.js +1 -1
  65. package/dist/representations/table/Column.d.ts +0 -1
  66. package/dist/representations/table/Column.d.ts.map +1 -1
  67. package/dist/representations/table/Column.js +4 -3
  68. package/dist/representations/table/Row.d.ts +0 -1
  69. package/dist/representations/table/Row.d.ts.map +1 -1
  70. package/dist/representations/table/Row.js +3 -3
  71. package/dist/representations/table/Table.d.ts.map +1 -1
  72. package/dist/representations/table/Table.js +1 -1
  73. package/dist/system.js +5 -5
  74. package/dist/tsdoc-metadata.json +1 -1
  75. package/dist/types.d.ts +29 -1
  76. package/dist/types.d.ts.map +1 -1
  77. package/dist/types.js +11 -1
  78. package/dist/utils/Comparators.js +1 -1
  79. package/dist/utils/ExtendedArray.js +1 -1
  80. package/dist/utils/FileUtils.js +2 -2
  81. package/dist/utils/SarifUtils.js +1 -1
  82. package/dist/utils/StringUtils.js +1 -1
  83. package/etc/sarif-to-slack.api.md +21 -1
  84. package/jest.config.json +4 -4
  85. package/package.json +5 -4
  86. package/src/Logger.ts +50 -34
  87. package/src/SarifToSlackClient.ts +73 -68
  88. package/src/globalState.ts +11 -0
  89. package/src/index.ts +23 -12
  90. package/src/model/Finding.ts +36 -35
  91. package/src/model/FindingArray.ts +5 -5
  92. package/src/model/SendIf.ts +25 -25
  93. package/src/model/SlackMessage.ts +49 -49
  94. package/src/model/color/Color.ts +7 -7
  95. package/src/model/color/ColorIdentification.ts +77 -77
  96. package/src/model/color/ColorOptions.ts +1 -1
  97. package/src/processors/CodeQLProcessor.ts +3 -3
  98. package/src/processors/CommonProcessor.ts +24 -24
  99. package/src/processors/ProcessorFactory.ts +9 -9
  100. package/src/processors/SnykProcessor.ts +3 -2
  101. package/src/representations/CompactGroupByRepresentation.ts +20 -20
  102. package/src/representations/CompactGroupByRunPerLevelRepresentation.ts +2 -2
  103. package/src/representations/CompactGroupByRunPerSeverityRepresentation.ts +2 -2
  104. package/src/representations/CompactGroupByRunRepresentation.ts +10 -10
  105. package/src/representations/CompactGroupBySarifPerLevelRepresentation.ts +2 -2
  106. package/src/representations/CompactGroupBySarifPerSeverityRepresentation.ts +2 -2
  107. package/src/representations/CompactGroupBySarifRepresentation.ts +11 -11
  108. package/src/representations/CompactGroupByToolNamePerLevelRepresentation.ts +2 -2
  109. package/src/representations/CompactGroupByToolNamePerSeverityRepresentation.ts +2 -2
  110. package/src/representations/CompactGroupByToolNameRepresentation.ts +10 -10
  111. package/src/representations/CompactTotalPerLevelRepresentation.ts +2 -2
  112. package/src/representations/CompactTotalPerSeverityRepresentation.ts +2 -2
  113. package/src/representations/CompactTotalRepresentation.ts +5 -5
  114. package/src/representations/Representation.ts +8 -8
  115. package/src/representations/RepresentationFactory.ts +32 -32
  116. package/src/representations/TableGroupByRunPerLevelRepresentation.ts +3 -3
  117. package/src/representations/TableGroupByRunPerSeverityRepresentation.ts +3 -3
  118. package/src/representations/TableGroupByRunRepresentation.ts +5 -5
  119. package/src/representations/TableGroupBySarifPerLevelRepresentation.ts +3 -3
  120. package/src/representations/TableGroupBySarifPerSeverityRepresentation.ts +3 -3
  121. package/src/representations/TableGroupBySarifRepresentation.ts +9 -9
  122. package/src/representations/TableGroupByToolNamePerLevelRepresentation.ts +3 -3
  123. package/src/representations/TableGroupByToolNamePerSeverityRepresentation.ts +3 -3
  124. package/src/representations/TableGroupByToolNameRepresentation.ts +4 -4
  125. package/src/representations/TableGroupRepresentation.ts +32 -32
  126. package/src/representations/table/Cell.ts +8 -8
  127. package/src/representations/table/Column.ts +13 -13
  128. package/src/representations/table/Row.ts +17 -17
  129. package/src/representations/table/Table.ts +21 -21
  130. package/src/system.ts +5 -5
  131. package/src/types.ts +43 -13
  132. package/src/utils/Comparators.ts +6 -6
  133. package/src/utils/ExtendedArray.ts +1 -1
  134. package/src/utils/FileUtils.ts +3 -3
  135. package/src/utils/SarifUtils.ts +6 -6
  136. package/src/utils/StringUtils.ts +3 -3
  137. package/tests/integration/SendSarifToSlack.spec.ts +73 -67
  138. package/tests/representations/CompactGroupByRunPerLevelRepresentation.spec.ts +121 -0
  139. package/tests/representations/CompactGroupByRunPerSeverityRepresentation.spec.ts +122 -0
  140. package/tests/representations/CompactGroupBySarifPerLevelRepresentation.spec.ts +132 -0
  141. package/tests/representations/CompactGroupBySarifPerSeverityRepresentation.spec.ts +133 -0
  142. package/tsconfig.json +1 -1
@@ -1,19 +1,19 @@
1
- import type { AnyBlock } from '@slack/types'
2
- import type { ContextBlock, HeaderBlock } from '@slack/types/dist/block-kit/blocks'
3
- import type { TextObject } from '@slack/types/dist/block-kit/composition-objects'
4
- import { IncomingWebhook } from '@slack/webhook'
5
- import { FooterType } from '../types'
6
- import type Representation from '../representations/Representation'
7
- import { version } from '../metadata.json'
1
+ import type { AnyBlock } from '@slack/types';
2
+ import type { ContextBlock, HeaderBlock } from '@slack/types/dist/block-kit/blocks';
3
+ import type { TextObject } from '@slack/types/dist/block-kit/composition-objects';
4
+ import { IncomingWebhook } from '@slack/webhook';
5
+ import { FooterType } from '../types';
6
+ import type Representation from '../representations/Representation';
7
+ import { version } from '../metadata.json';
8
8
 
9
9
  /**
10
10
  * Options for the SlackMessageBuilder.
11
11
  * @internal
12
12
  */
13
13
  export type SlackMessageOptions = {
14
- username?: string
15
- iconUrl?: string
16
- color?: string
14
+ username?: string,
15
+ iconUrl?: string,
16
+ color?: string,
17
17
  representation: Representation,
18
18
  }
19
19
 
@@ -39,7 +39,7 @@ export interface SlackMessage {
39
39
  * @param opts An instance of {@link SlackMessageOptions} type.
40
40
  */
41
41
  export function createSlackMessage(url: string, opts: SlackMessageOptions): SlackMessage {
42
- return new SlackMessageImpl(url, opts)
42
+ return new SlackMessageImpl(url, opts);
43
43
  }
44
44
 
45
45
  /**
@@ -47,24 +47,24 @@ export function createSlackMessage(url: string, opts: SlackMessageOptions): Slac
47
47
  * @internal
48
48
  */
49
49
  class SlackMessageImpl implements SlackMessage {
50
- private readonly _webhook: IncomingWebhook
51
- private readonly _gitHubServerUrl: string
52
- private readonly _color?: string
53
- private readonly _representation: Representation
50
+ private readonly _webhook: IncomingWebhook;
51
+ private readonly _gitHubServerUrl: string;
52
+ private readonly _color?: string;
53
+ private readonly _representation: Representation;
54
54
 
55
- private _header?: HeaderBlock
56
- private _footer?: ContextBlock
57
- private _actor?: string
58
- private _runId?: string
55
+ private _header?: HeaderBlock;
56
+ private _footer?: ContextBlock;
57
+ private _actor?: string;
58
+ private _runId?: string;
59
59
 
60
60
  constructor(url: string, opts: SlackMessageOptions) {
61
61
  this._webhook = new IncomingWebhook(url, {
62
62
  username: opts.username || 'SARIF results',
63
- icon_url: opts.iconUrl
64
- })
65
- this._gitHubServerUrl = process.env.GITHUB_SERVER_URL || 'https://github.com'
66
- this._color = opts.color
67
- this._representation = opts.representation
63
+ icon_url: opts.iconUrl,
64
+ });
65
+ this._gitHubServerUrl = process.env.GITHUB_SERVER_URL || 'https://github.com';
66
+ this._color = opts.color;
67
+ this._representation = opts.representation;
68
68
  }
69
69
 
70
70
  withHeader(header?: string): void {
@@ -72,67 +72,67 @@ class SlackMessageImpl implements SlackMessage {
72
72
  type: 'header',
73
73
  text: {
74
74
  type: 'plain_text',
75
- text: header || process.env.GITHUB_REPOSITORY || 'SARIF results'
76
- }
77
- }
75
+ text: header || process.env.GITHUB_REPOSITORY || 'SARIF results',
76
+ },
77
+ };
78
78
  }
79
79
 
80
80
  withActor(actor?: string): void {
81
- this._actor = actor || process.env.GITHUB_ACTOR
81
+ this._actor = actor || process.env.GITHUB_ACTOR;
82
82
  }
83
83
 
84
84
  withRun(): void {
85
- this._runId = process.env.GITHUB_RUN_ID
85
+ this._runId = process.env.GITHUB_RUN_ID;
86
86
  }
87
87
 
88
88
  withFooter(text?: string, type?: FooterType): void {
89
- const repoName = 'fabasoad/sarif-to-slack'
89
+ const repoName = 'fabasoad/sarif-to-slack';
90
90
  const element: TextObject = text
91
91
  ? { type: type || FooterType.PlainText, text }
92
- : { type: FooterType.Markdown, text: `Generated by <${this._gitHubServerUrl}/${repoName}|@${repoName}@${version}>` }
92
+ : { type: FooterType.Markdown, text: `Generated by <${this._gitHubServerUrl}/${repoName}|@${repoName}@${version}>` };
93
93
  this._footer = {
94
94
  type: 'context',
95
95
  elements: [element],
96
- }
96
+ };
97
97
  }
98
98
 
99
99
  async send(): Promise<string> {
100
- const blocks: AnyBlock[] = []
100
+ const blocks: AnyBlock[] = [];
101
101
  if (this._header) {
102
- blocks.push(this._header)
102
+ blocks.push(this._header);
103
103
  }
104
104
  blocks.push({
105
105
  type: 'section',
106
106
  text: {
107
107
  type: 'mrkdwn',
108
108
  text: this.buildText(),
109
- }
110
- })
109
+ },
110
+ });
111
111
  if (this._footer) {
112
- blocks.push(this._footer)
112
+ blocks.push(this._footer);
113
113
  }
114
114
  const { text } = await this._webhook.send({
115
- attachments: [{ color: this._color, blocks }]
116
- })
117
- return text
115
+ attachments: [{ color: this._color, blocks }],
116
+ });
117
+ return text;
118
118
  }
119
119
 
120
120
  private buildText(): string {
121
- const text: string[] = []
121
+ const text: string[] = [];
122
122
  if (this._actor) {
123
- const actorUrl = `${this._gitHubServerUrl}/${this._actor}`
124
- text.push(`_Triggered by <${actorUrl}|${this._actor}>_`)
123
+ const actorUrl = `${this._gitHubServerUrl}/${this._actor}`;
124
+ text.push(`_Triggered by <${actorUrl}|${this._actor}>_`);
125
125
  }
126
- text.push(this._representation.compose())
126
+ text.push(this._representation.compose());
127
127
  if (this._runId) {
128
- let runText: string = 'Job '
128
+ let runText: string = 'Job ';
129
129
  if (process.env.GITHUB_REPOSITORY) {
130
- runText += `<${this._gitHubServerUrl}/${process.env.GITHUB_REPOSITORY}/actions/runs/${this._runId}|#${this._runId}>`
130
+ runText += `<${this._gitHubServerUrl}/${process.env.GITHUB_REPOSITORY}/actions/runs/${this._runId}|#${this._runId}>`;
131
131
  } else {
132
- runText += `#${this._runId}`
132
+ runText += `#${this._runId}`;
133
133
  }
134
- text.push(runText)
134
+ text.push(runText);
135
135
  }
136
- return text.join('\n\n')
136
+ return text.join('\n\n');
137
137
  }
138
138
  }
@@ -7,11 +7,11 @@ export class Color {
7
7
  * A valid string that represents a color in hex format.
8
8
  * @public
9
9
  */
10
- public readonly color: string
10
+ public readonly color: string;
11
11
 
12
12
  private constructor(color: string) {
13
- this.color = this.mapColor(color)
14
- this.assertHexColor()
13
+ this.color = this.mapColor(color);
14
+ this.assertHexColor();
15
15
  }
16
16
 
17
17
  /**
@@ -25,15 +25,15 @@ export class Color {
25
25
  * @public
26
26
  */
27
27
  public static from(color: string | undefined): Color | undefined {
28
- return color ? new Color(color) : undefined
28
+ return color ? new Color(color) : undefined;
29
29
  }
30
30
 
31
31
  private assertHexColor(): void {
32
32
  if (this.color) {
33
- const hexColorRegex = /^#(?:[0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/
33
+ const hexColorRegex = /^#(?:[0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/;
34
34
 
35
35
  if (!hexColorRegex.test(this.color)) {
36
- throw new Error(`Invalid hex color: "${this.color}"`)
36
+ throw new Error(`Invalid hex color: "${this.color}"`);
37
37
  }
38
38
  }
39
39
  }
@@ -45,6 +45,6 @@ export class Color {
45
45
  ['cancelled', '#0047ab'],
46
46
  ['skipped', '#808080'],
47
47
  ])
48
- return map.get(from) ?? from
48
+ return map.get(from) ?? from;
49
49
  }
50
50
  }
@@ -1,39 +1,39 @@
1
- import type Finding from '../Finding'
2
- import type FindingArray from '../FindingArray'
3
- import { SecurityLevel, SecuritySeverity } from '../../types'
4
- import Logger from '../../Logger'
1
+ import type Finding from '../Finding';
2
+ import type FindingArray from '../FindingArray';
3
+ import { SecurityLevel, SecuritySeverity } from '../../types';
4
+ import Logger from '../../Logger';
5
5
  import type {
6
6
  ColorGroupByLevel,
7
7
  ColorGroupBySeverity,
8
8
  ColorGroupCommon,
9
- ColorOptions
10
- } from './ColorOptions'
9
+ ColorOptions,
10
+ } from './ColorOptions';
11
11
  import type { Color } from './Color';
12
12
 
13
13
  function logColorTaken(
14
14
  logger: Logger,
15
15
  color: Color | undefined,
16
- prop: string
16
+ prop: string,
17
17
  ): void {
18
- logger.debug(`Message has ${color?.color} color taken from '${prop}' property.`)
18
+ logger.debug(`Message has ${color?.color} color taken from '${prop}' property.`);
19
19
  }
20
20
 
21
21
  function logPropDefinedButNoFindings<K extends keyof Pick<Finding, 'level' | 'severity'>>(
22
22
  logger: Logger,
23
23
  key: K,
24
- val: string
24
+ val: string,
25
25
  ): void {
26
- const prop: string = key === 'level' ? 'byLevel' : 'bySeverity'
27
- logger.trace(`'${prop}.${val}' property is defined but no findings with "${val}" ${key} is found. Continue color identification...`)
26
+ const prop: string = key === 'level' ? 'byLevel' : 'bySeverity';
27
+ logger.trace(`'${prop}.${val}' property is defined but no findings with "${val}" ${key} is found. Continue color identification...`);
28
28
  }
29
29
 
30
30
  function logPropIsNotDefined<K extends keyof Pick<Finding, 'level' | 'severity'>>(
31
31
  logger: Logger,
32
32
  key: K,
33
- val: string
33
+ val: string,
34
34
  ): void {
35
- const prop: string = key === 'level' ? 'byLevel' : 'bySeverity'
36
- logger.trace(`'${prop}.${val}' property is not defined. Continue color identification...`)
35
+ const prop: string = key === 'level' ? 'byLevel' : 'bySeverity';
36
+ logger.trace(`'${prop}.${val}' property is not defined. Continue color identification...`);
37
37
  }
38
38
 
39
39
  function identifyColorCommon<K extends keyof Pick<Finding, 'level' | 'severity'>>(
@@ -41,119 +41,119 @@ function identifyColorCommon<K extends keyof Pick<Finding, 'level' | 'severity'>
41
41
  prop: K,
42
42
  none: Finding[K],
43
43
  unknown: Finding[K],
44
- color: ColorGroupCommon
44
+ color: ColorGroupCommon,
45
45
  ): string | undefined {
46
- const logger = new Logger(identifyColorCommon.name);
46
+ const logger = new Logger();
47
47
  if (color.none) {
48
48
  if (findings.findByProperty(prop, none) != null) {
49
- logColorTaken(logger, color.none, `${prop === 'severity' ? 'bySeverity' : 'byLevel'}.none`)
50
- return color.none.color
49
+ logColorTaken(logger, color.none, `${prop === 'severity' ? 'bySeverity' : 'byLevel'}.none`);
50
+ return color.none.color;
51
51
  } else {
52
- logPropDefinedButNoFindings(logger, prop, 'none')
52
+ logPropDefinedButNoFindings(logger, prop, 'none');
53
53
  }
54
54
  } else {
55
- logPropIsNotDefined(logger, prop, 'none')
55
+ logPropIsNotDefined(logger, prop, 'none');
56
56
  }
57
57
 
58
58
  if (color.unknown) {
59
59
  if (findings.findByProperty(prop, unknown) != null) {
60
- logColorTaken(logger, color.unknown, `${prop === 'severity' ? 'bySeverity' : 'byLevel'}.unknown`)
61
- return color.unknown.color
60
+ logColorTaken(logger, color.unknown, `${prop === 'severity' ? 'bySeverity' : 'byLevel'}.unknown`);
61
+ return color.unknown.color;
62
62
  } else {
63
- logPropDefinedButNoFindings(logger, prop, 'unknown')
63
+ logPropDefinedButNoFindings(logger, prop, 'unknown');
64
64
  }
65
65
  } else {
66
- logPropIsNotDefined(logger, prop, 'unknown')
66
+ logPropIsNotDefined(logger, prop, 'unknown');
67
67
  }
68
68
 
69
- return undefined
69
+ return undefined;
70
70
  }
71
71
 
72
72
  function identifyColorBySeverity(findings: FindingArray, color: ColorGroupBySeverity): string | undefined {
73
- const logger = new Logger(identifyColorBySeverity.name);
73
+ const logger = new Logger();
74
74
  if (color.critical) {
75
75
  if (findings.findByProperty('severity', SecuritySeverity.Critical) != null) {
76
- logColorTaken(logger, color.critical, 'bySeverity.critical')
77
- return color.critical.color
76
+ logColorTaken(logger, color.critical, 'bySeverity.critical');
77
+ return color.critical.color;
78
78
  } else {
79
- logPropDefinedButNoFindings(logger, 'severity', 'critical')
79
+ logPropDefinedButNoFindings(logger, 'severity', 'critical');
80
80
  }
81
81
  } else {
82
- logPropIsNotDefined(logger, 'severity', 'critical')
82
+ logPropIsNotDefined(logger, 'severity', 'critical');
83
83
  }
84
84
 
85
85
  if (color.high) {
86
86
  if (findings.findByProperty('severity', SecuritySeverity.High) != null) {
87
- logColorTaken(logger, color.high, 'bySeverity.high')
88
- return color.high.color
87
+ logColorTaken(logger, color.high, 'bySeverity.high');
88
+ return color.high.color;
89
89
  } else {
90
- logPropDefinedButNoFindings(logger, 'severity', 'high')
90
+ logPropDefinedButNoFindings(logger, 'severity', 'high');
91
91
  }
92
92
  } else {
93
- logPropIsNotDefined(logger, 'severity', 'high')
93
+ logPropIsNotDefined(logger, 'severity', 'high');
94
94
  }
95
95
 
96
96
  if (color.medium) {
97
97
  if (findings.findByProperty('severity', SecuritySeverity.Medium) != null) {
98
- logColorTaken(logger, color.medium, 'bySeverity.medium')
99
- return color.medium.color
98
+ logColorTaken(logger, color.medium, 'bySeverity.medium');
99
+ return color.medium.color;
100
100
  } else {
101
- logPropDefinedButNoFindings(logger, 'severity', 'medium')
101
+ logPropDefinedButNoFindings(logger, 'severity', 'medium');
102
102
  }
103
103
  } else {
104
- logPropIsNotDefined(logger, 'severity', 'medium')
104
+ logPropIsNotDefined(logger, 'severity', 'medium');
105
105
  }
106
106
 
107
107
  if (color.low) {
108
108
  if (findings.findByProperty('severity', SecuritySeverity.Low) != null) {
109
- logColorTaken(logger, color.low, 'bySeverity.low')
110
- return color.low.color
109
+ logColorTaken(logger, color.low, 'bySeverity.low');
110
+ return color.low.color;
111
111
  } else {
112
- logPropDefinedButNoFindings(logger, 'severity', 'low')
112
+ logPropDefinedButNoFindings(logger, 'severity', 'low');
113
113
  }
114
114
  } else {
115
- logPropIsNotDefined(logger, 'severity', 'low')
115
+ logPropIsNotDefined(logger, 'severity', 'low');
116
116
  }
117
117
 
118
- return identifyColorCommon(findings, 'severity', SecuritySeverity.None, SecuritySeverity.Unknown, color)
118
+ return identifyColorCommon(findings, 'severity', SecuritySeverity.None, SecuritySeverity.Unknown, color);
119
119
  }
120
120
 
121
121
  function identifyColorByLevel(findings: FindingArray, color: ColorGroupByLevel): string | undefined {
122
- const logger = new Logger(identifyColorByLevel.name);
122
+ const logger = new Logger();
123
123
  if (color.error) {
124
124
  if (findings.findByProperty('level', SecurityLevel.Error) != null) {
125
- logColorTaken(logger, color.error, 'byLevel.error')
126
- return color.error.color
125
+ logColorTaken(logger, color.error, 'byLevel.error');
126
+ return color.error.color;
127
127
  } else {
128
- logPropDefinedButNoFindings(logger, 'level', 'error')
128
+ logPropDefinedButNoFindings(logger, 'level', 'error');
129
129
  }
130
130
  } else {
131
- logPropIsNotDefined(logger, 'level', 'error')
131
+ logPropIsNotDefined(logger, 'level', 'error');
132
132
  }
133
133
 
134
134
  if (color.warning) {
135
135
  if (findings.findByProperty('level', SecurityLevel.Warning) != null) {
136
- logColorTaken(logger, color.warning, 'byLevel.warning')
137
- return color.warning.color
136
+ logColorTaken(logger, color.warning, 'byLevel.warning');
137
+ return color.warning.color;
138
138
  } else {
139
- logPropDefinedButNoFindings(logger, 'level', 'warning')
139
+ logPropDefinedButNoFindings(logger, 'level', 'warning');
140
140
  }
141
141
  } else {
142
- logPropIsNotDefined(logger, 'level', 'warning')
142
+ logPropIsNotDefined(logger, 'level', 'warning');
143
143
  }
144
144
 
145
145
  if (color.note != null) {
146
146
  if (findings.findByProperty('level', SecurityLevel.Note) != null) {
147
- logColorTaken(logger, color.note, 'byLevel.note')
148
- return color.note.color
147
+ logColorTaken(logger, color.note, 'byLevel.note');
148
+ return color.note.color;
149
149
  } else {
150
- logPropDefinedButNoFindings(logger, 'level', 'note')
150
+ logPropDefinedButNoFindings(logger, 'level', 'note');
151
151
  }
152
152
  } else {
153
- logPropIsNotDefined(logger, 'level', 'note')
153
+ logPropIsNotDefined(logger, 'level', 'note');
154
154
  }
155
155
 
156
- return identifyColorCommon(findings, 'level', SecurityLevel.None, SecurityLevel.Unknown, color)
156
+ return identifyColorCommon(findings, 'level', SecurityLevel.None, SecurityLevel.Unknown, color);
157
157
  }
158
158
 
159
159
  /**
@@ -165,50 +165,50 @@ function identifyColorByLevel(findings: FindingArray, color: ColorGroupByLevel):
165
165
  * @internal
166
166
  */
167
167
  export function identifyColor(findings: FindingArray, colorOpts?: ColorOptions): string | undefined {
168
- const logger = new Logger(identifyColor.name);
168
+ const logger = new Logger();
169
169
  if (!colorOpts) {
170
- logger.debug('Message has no color as color options are not defined.')
171
- return undefined
170
+ logger.debug('Message has no color as color options are not defined.');
171
+ return undefined;
172
172
  }
173
- logger.trace(`Identifying color for ${findings.length} findings and the following color options:`, JSON.stringify(colorOpts, null, 2))
173
+ logger.trace(`Identifying color for ${findings.length} findings and the following color options:`, JSON.stringify(colorOpts, null, 2));
174
174
 
175
175
  if (colorOpts.bySeverity) {
176
- const color: string | undefined = identifyColorBySeverity(findings, colorOpts.bySeverity)
176
+ const color: string | undefined = identifyColorBySeverity(findings, colorOpts.bySeverity);
177
177
  if (color) {
178
- return color
178
+ return color;
179
179
  }
180
- logger.trace('None of the properties in \'bySeverity\' group is applicable. Continue color identification...')
180
+ logger.trace('None of the properties in \'bySeverity\' group is applicable. Continue color identification...');
181
181
  } else {
182
- logger.trace('\'bySeverity\' group is not defined. Continue color identification...')
182
+ logger.trace('\'bySeverity\' group is not defined. Continue color identification...');
183
183
  }
184
184
 
185
185
  if (colorOpts.byLevel) {
186
- const color: string | undefined = identifyColorByLevel(findings, colorOpts.byLevel)
186
+ const color: string | undefined = identifyColorByLevel(findings, colorOpts.byLevel);
187
187
  if (color) {
188
- return color
188
+ return color;
189
189
  }
190
- logger.trace('None of the properties in \'byLevel\' group is applicable. Continue color identification...')
190
+ logger.trace('None of the properties in \'byLevel\' group is applicable. Continue color identification...');
191
191
  } else {
192
- logger.trace('\'byLevel\' group is not defined. Continue color identification...')
192
+ logger.trace('\'byLevel\' group is not defined. Continue color identification...');
193
193
  }
194
194
 
195
195
  if (findings.length === 0) {
196
- logger.trace('There are no findings in the provided SARIF file(s). Checking if color is defined in "empty" property...')
196
+ logger.trace('There are no findings in the provided SARIF file(s). Checking if color is defined in "empty" property...');
197
197
  if (colorOpts.empty?.color) {
198
- logColorTaken(logger, colorOpts.empty, 'empty')
199
- return colorOpts.empty.color
198
+ logColorTaken(logger, colorOpts.empty, 'empty');
199
+ return colorOpts.empty.color;
200
200
  } else {
201
- logger.trace('"empty" color is not defined. Continue color identification...')
201
+ logger.trace('"empty" color is not defined. Continue color identification...');
202
202
  }
203
203
  } else {
204
- logger.trace(`"empty" color is not taken into account because there are ${findings.length} findings in the provided SARIF file(s). Continue color identification...`)
204
+ logger.trace(`"empty" color is not taken into account because there are ${findings.length} findings in the provided SARIF file(s). Continue color identification...`);
205
205
  }
206
206
 
207
207
  if (colorOpts.default?.color) {
208
- logColorTaken(logger, colorOpts.default, 'default')
208
+ logColorTaken(logger, colorOpts.default, 'default');
209
209
  } else {
210
- logger.debug('Message has no color as none of the defined color options is applicable.')
210
+ logger.debug('Message has no color as none of the defined color options is applicable.');
211
211
  }
212
212
 
213
- return colorOpts?.default?.color
213
+ return colorOpts?.default?.color;
214
214
  }
@@ -1,4 +1,4 @@
1
- import type { Color } from './Color'
1
+ import type { Color } from './Color';
2
2
 
3
3
  /**
4
4
  * Base type that has common fields for both {@link ColorGroupByLevel} and
@@ -1,5 +1,5 @@
1
- import { CommonProcessor } from './CommonProcessor'
2
- import type { Result } from 'sarif'
1
+ import { CommonProcessor } from './CommonProcessor';
2
+ import type { Result } from 'sarif';
3
3
 
4
4
  /**
5
5
  * This class has extra logic for processing SARIF files produced by CodeQL tool.
@@ -14,6 +14,6 @@ export class CodeQLProcessor extends CommonProcessor {
14
14
  * "problem.severity" property.
15
15
  */
16
16
  public override tryFindLevel(): Result.level | undefined {
17
- return super.tryFindLevel() ?? this.tryFindRuleProperty('problem.severity')
17
+ return super.tryFindLevel() ?? this.tryFindRuleProperty('problem.severity');
18
18
  }
19
19
  }
@@ -1,5 +1,5 @@
1
- import type { ReportingDescriptor, Result, Run, ToolComponent } from 'sarif'
2
- import * as sarifUtils from '../utils/SarifUtils'
1
+ import type { ReportingDescriptor, Result, Run, ToolComponent } from 'sarif';
2
+ import * as sarifUtils from '../utils/SarifUtils';
3
3
 
4
4
  /**
5
5
  * This class has logic of the SARIF file processing, such as finding rule,
@@ -11,8 +11,8 @@ import * as sarifUtils from '../utils/SarifUtils'
11
11
  * @internal
12
12
  */
13
13
  export class CommonProcessor {
14
- protected readonly _run: Run
15
- protected readonly _result: Result
14
+ protected readonly _run: Run;
15
+ protected readonly _result: Result;
16
16
 
17
17
  /**
18
18
  * Creates an instance of {@link CommonProcessor} class.
@@ -20,28 +20,28 @@ export class CommonProcessor {
20
20
  * @param result An instance of {@link Result} object.
21
21
  */
22
22
  public constructor(run: Run, result: Result) {
23
- this._run = run
24
- this._result = result
23
+ this._run = run;
24
+ this._result = result;
25
25
  }
26
26
 
27
27
  public tryFindCvssScore(): number | undefined {
28
- return this.tryFindRuleProperty('security-severity')
28
+ return this.tryFindRuleProperty('security-severity');
29
29
  }
30
30
 
31
31
  public tryFindLevel(): Result.level | undefined {
32
- return this._result.level ?? this.tryFindRule()?.defaultConfiguration?.level
32
+ return this._result.level ?? this.tryFindRule()?.defaultConfiguration?.level;
33
33
  }
34
34
 
35
35
  public findToolComponentDriver(): ToolComponent {
36
- return sarifUtils.findToolComponentDriver(this._run)
36
+ return sarifUtils.findToolComponentDriver(this._run);
37
37
  }
38
38
 
39
39
  public tryFindToolComponentExtension(): ToolComponent | undefined {
40
- return sarifUtils.tryFindToolComponentExtension(this._run, this._result)
40
+ return sarifUtils.tryFindToolComponentExtension(this._run, this._result);
41
41
  }
42
42
 
43
43
  public findToolComponent(): ToolComponent {
44
- return sarifUtils.findToolComponent(this._run, this._result)
44
+ return sarifUtils.findToolComponent(this._run, this._result);
45
45
  }
46
46
 
47
47
  /**
@@ -49,41 +49,41 @@ export class CommonProcessor {
49
49
  * @internal
50
50
  */
51
51
  public tryFindRule(): ReportingDescriptor | undefined {
52
- const ruleData: { id?: string, index?: number } = {}
52
+ const ruleData: { id?: string, index?: number } = {};
53
53
 
54
54
  if (this._result.rule) {
55
55
  if (this._result.rule?.index != null) {
56
- ruleData.index = this._result.rule.index
56
+ ruleData.index = this._result.rule.index;
57
57
  }
58
58
  if (this._result.rule?.id) {
59
- ruleData.id = this._result.rule.id
59
+ ruleData.id = this._result.rule.id;
60
60
  }
61
61
  }
62
62
 
63
63
  if (ruleData.index == null && this._result.ruleIndex != null) {
64
- ruleData.index = this._result.ruleIndex
64
+ ruleData.index = this._result.ruleIndex;
65
65
  }
66
66
 
67
67
  if (!ruleData.id && this._result.ruleId) {
68
- ruleData.id = this._result.ruleId
68
+ ruleData.id = this._result.ruleId;
69
69
  }
70
70
 
71
- const tool: ToolComponent = this.findToolComponent()
71
+ const tool: ToolComponent = this.findToolComponent();
72
72
 
73
73
  if (ruleData.index != null
74
74
  && tool?.rules
75
75
  && ruleData.index < tool.rules.length) {
76
- return tool.rules[ruleData.index]
76
+ return tool.rules[ruleData.index];
77
77
  }
78
78
 
79
79
  // If failed to find rule by index then try to find by ruleId
80
80
  if (ruleData.id && tool?.rules) {
81
81
  return tool.rules.find(
82
- (r: ReportingDescriptor): boolean => r.id === ruleData.id
83
- )
82
+ (r: ReportingDescriptor): boolean => r.id === ruleData.id,
83
+ );
84
84
  }
85
85
 
86
- return undefined
86
+ return undefined;
87
87
  }
88
88
 
89
89
  /**
@@ -93,11 +93,11 @@ export class CommonProcessor {
93
93
  * @protected
94
94
  */
95
95
  protected tryFindRuleProperty<T>(propertyName: string): T | undefined {
96
- const rule: ReportingDescriptor | undefined = this.tryFindRule()
96
+ const rule: ReportingDescriptor | undefined = this.tryFindRule();
97
97
  if (rule?.properties && propertyName in rule.properties) {
98
- return rule.properties[propertyName] as T
98
+ return rule.properties[propertyName] as T;
99
99
  }
100
100
 
101
- return undefined
101
+ return undefined;
102
102
  }
103
103
  }