@fabasoad/sarif-to-slack 1.3.1 → 1.3.2
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/.gitattributes +1 -0
- package/.github/workflows/release.yml +3 -3
- package/.github/workflows/send-sarif-to-slack.yml +15 -12
- package/.pre-commit-config.yaml +2 -1
- package/.tool-versions +1 -1
- package/README.md +47 -12
- package/biome.json +5 -52
- package/dist/Logger.js +51 -22
- package/dist/SarifToSlackClient.d.ts +12 -10
- package/dist/SarifToSlackClient.d.ts.map +1 -1
- package/dist/SarifToSlackClient.js +28 -15
- package/dist/index.cjs +603 -237
- package/dist/index.d.ts +1 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -8
- package/dist/model/Finding.js +4 -3
- package/dist/model/SlackMessage.d.ts +0 -16
- package/dist/model/SlackMessage.d.ts.map +1 -1
- package/dist/model/color/ColorIdentification.js +50 -46
- package/dist/model/color/ColorOptions.d.ts +1 -1
- package/dist/model/color/ColorOptions.d.ts.map +1 -1
- package/dist/representations/CompactGroupByRepresentation.js +2 -2
- package/dist/representations/Representation.js +6 -2
- package/dist/representations/RepresentationFactory.js +19 -1
- package/dist/representations/TableGroupByRunPerLevelRepresentation.d.ts +6 -0
- package/dist/representations/TableGroupByRunPerLevelRepresentation.d.ts.map +1 -0
- package/dist/representations/TableGroupByRunPerLevelRepresentation.js +8 -0
- package/dist/representations/TableGroupByRunPerSeverityRepresentation.d.ts +6 -0
- package/dist/representations/TableGroupByRunPerSeverityRepresentation.d.ts.map +1 -0
- package/dist/representations/TableGroupByRunPerSeverityRepresentation.js +8 -0
- package/dist/representations/TableGroupByRunRepresentation.d.ts +7 -0
- package/dist/representations/TableGroupByRunRepresentation.d.ts.map +1 -0
- package/dist/representations/TableGroupByRunRepresentation.js +7 -0
- package/dist/representations/TableGroupBySarifPerLevelRepresentation.d.ts +6 -0
- package/dist/representations/TableGroupBySarifPerLevelRepresentation.d.ts.map +1 -0
- package/dist/representations/TableGroupBySarifPerLevelRepresentation.js +8 -0
- package/dist/representations/TableGroupBySarifPerSeverityRepresentation.d.ts +6 -0
- package/dist/representations/TableGroupBySarifPerSeverityRepresentation.d.ts.map +1 -0
- package/dist/representations/TableGroupBySarifPerSeverityRepresentation.js +8 -0
- package/dist/representations/TableGroupBySarifRepresentation.d.ts +9 -0
- package/dist/representations/TableGroupBySarifRepresentation.d.ts.map +1 -0
- package/dist/representations/TableGroupBySarifRepresentation.js +15 -0
- package/dist/representations/TableGroupByToolNamePerLevelRepresentation.d.ts +6 -0
- package/dist/representations/TableGroupByToolNamePerLevelRepresentation.d.ts.map +1 -0
- package/dist/representations/TableGroupByToolNamePerLevelRepresentation.js +8 -0
- package/dist/representations/TableGroupByToolNamePerSeverityRepresentation.d.ts +6 -0
- package/dist/representations/TableGroupByToolNamePerSeverityRepresentation.d.ts.map +1 -0
- package/dist/representations/TableGroupByToolNamePerSeverityRepresentation.js +8 -0
- package/dist/representations/TableGroupByToolNameRepresentation.d.ts +7 -0
- package/dist/representations/TableGroupByToolNameRepresentation.d.ts.map +1 -0
- package/dist/representations/TableGroupByToolNameRepresentation.js +7 -0
- package/dist/representations/TableGroupRepresentation.d.ts +16 -0
- package/dist/representations/TableGroupRepresentation.d.ts.map +1 -0
- package/dist/representations/TableGroupRepresentation.js +62 -0
- package/dist/representations/table/Cell.d.ts +10 -0
- package/dist/representations/table/Cell.d.ts.map +1 -0
- package/dist/representations/table/Cell.js +23 -0
- package/dist/representations/table/Column.d.ts +11 -0
- package/dist/representations/table/Column.d.ts.map +1 -0
- package/dist/representations/table/Column.js +31 -0
- package/dist/representations/table/Row.d.ts +15 -0
- package/dist/representations/table/Row.d.ts.map +1 -0
- package/dist/representations/table/Row.js +45 -0
- package/dist/representations/table/Table.d.ts +14 -0
- package/dist/representations/table/Table.d.ts.map +1 -0
- package/dist/representations/table/Table.js +66 -0
- package/dist/sarif-to-slack.d.ts +98 -88
- package/dist/system.d.ts +2 -0
- package/dist/system.d.ts.map +1 -0
- package/dist/system.js +24 -0
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/types.d.ts +90 -56
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +89 -42
- package/dist/utils/FileUtils.js +8 -7
- package/dist/utils/StringUtils.d.ts +2 -0
- package/dist/utils/StringUtils.d.ts.map +1 -0
- package/dist/utils/StringUtils.js +5 -0
- package/etc/sarif-to-slack.api.md +8 -36
- package/package.json +10 -10
- package/src/Logger.ts +64 -26
- package/src/SarifToSlackClient.ts +42 -29
- package/src/index.ts +0 -9
- package/src/model/Finding.ts +14 -13
- package/src/model/FindingArray.ts +1 -1
- package/src/model/SlackMessage.ts +5 -5
- package/src/model/color/ColorIdentification.ts +66 -50
- package/src/model/color/ColorOptions.ts +1 -1
- package/src/processors/CodeQLProcessor.ts +1 -1
- package/src/representations/CompactGroupByRepresentation.ts +2 -2
- package/src/representations/CompactGroupByRunRepresentation.ts +2 -2
- package/src/representations/CompactGroupBySarifRepresentation.ts +2 -2
- package/src/representations/CompactGroupByToolNameRepresentation.ts +2 -2
- package/src/representations/CompactTotalRepresentation.ts +1 -1
- package/src/representations/Representation.ts +9 -4
- package/src/representations/RepresentationFactory.ts +26 -2
- package/src/representations/TableGroupByRunPerLevelRepresentation.ts +9 -0
- package/src/representations/TableGroupByRunPerSeverityRepresentation.ts +9 -0
- package/src/representations/TableGroupByRunRepresentation.ts +15 -0
- package/src/representations/TableGroupBySarifPerLevelRepresentation.ts +9 -0
- package/src/representations/TableGroupBySarifPerSeverityRepresentation.ts +9 -0
- package/src/representations/TableGroupBySarifRepresentation.ts +25 -0
- package/src/representations/TableGroupByToolNamePerLevelRepresentation.ts +10 -0
- package/src/representations/TableGroupByToolNamePerSeverityRepresentation.ts +10 -0
- package/src/representations/TableGroupByToolNameRepresentation.ts +15 -0
- package/src/representations/TableGroupRepresentation.ts +78 -0
- package/src/representations/table/Cell.ts +25 -0
- package/src/representations/table/Column.ts +39 -0
- package/src/representations/table/Row.ts +50 -0
- package/src/representations/table/Table.ts +93 -0
- package/src/system.ts +27 -0
- package/src/types.ts +98 -58
- package/src/utils/Comparators.ts +1 -1
- package/src/utils/FileUtils.ts +20 -19
- package/src/utils/StringUtils.ts +7 -0
- package/test-data/sarif/codeql-go.sarif +1 -1
- package/test-data/sarif/runs-1-extensions-1-results-0.sarif +2 -2
- package/test-data/sarif/snyk-hex.sarif +1 -1
- package/tests/integration/SendSarifToSlack.spec.ts +73 -83
- package/tests/representations/table/Table.spec.ts +174 -0
- package/dist/System.d.ts +0 -2
- package/dist/System.d.ts.map +0 -1
- package/dist/System.js +0 -15
- package/src/System.ts +0 -16
- /package/test-data/sarif/{tmp → multiple}/codeql-csharp.sarif +0 -0
- /package/test-data/sarif/{tmp → multiple}/grype-container.sarif +0 -0
- /package/test-data/sarif/{tmp → multiple}/runs-1-tools-1-results-0.sarif +0 -0
- /package/test-data/sarif/{tmp → multiple}/runs-2-tools-2.sarif +0 -0
package/dist/index.cjs
CHANGED
|
@@ -32,7 +32,6 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
Color: () => Color,
|
|
34
34
|
FooterType: () => FooterType,
|
|
35
|
-
LogLevel: () => LogLevel,
|
|
36
35
|
RepresentationType: () => RepresentationType,
|
|
37
36
|
SarifToSlackClient: () => SarifToSlackClient,
|
|
38
37
|
SendIf: () => SendIf
|
|
@@ -165,20 +164,91 @@ function sendIfLogMessage(sendIf) {
|
|
|
165
164
|
}
|
|
166
165
|
}
|
|
167
166
|
|
|
168
|
-
// src/
|
|
169
|
-
var
|
|
167
|
+
// src/SarifToSlackClient.ts
|
|
168
|
+
var import_node_fs2 = require("fs");
|
|
169
|
+
|
|
170
|
+
// src/Logger.ts
|
|
171
|
+
var import_tslog = require("tslog");
|
|
172
|
+
var import_zod2 = require("zod");
|
|
173
|
+
|
|
174
|
+
// src/system.ts
|
|
175
|
+
var import_zod = require("zod");
|
|
176
|
+
|
|
177
|
+
// src/metadata.json
|
|
178
|
+
var version = "1.3.2";
|
|
179
|
+
var sha = "7f304afbd27622223e810bcac958e15bfde8d56d";
|
|
180
|
+
var buildAt = "2025-10-01T12:12:59Z";
|
|
181
|
+
|
|
182
|
+
// src/system.ts
|
|
183
|
+
function logMetadata() {
|
|
184
|
+
const logger = new Logger(logMetadata.name);
|
|
185
|
+
logger.info(`version: ${version}`);
|
|
186
|
+
logger.info(`sha: ${sha}`);
|
|
187
|
+
logger.info(`built at: ${buildAt}`);
|
|
188
|
+
}
|
|
189
|
+
function isDebug() {
|
|
190
|
+
const parseResult = import_zod.z.stringbool().safeParse(
|
|
191
|
+
process.env.ACTIONS_STEP_DEBUG
|
|
192
|
+
);
|
|
193
|
+
return parseResult.success && parseResult.data;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// src/Logger.ts
|
|
197
|
+
var LogLevelItems = ["silly", "trace", "debug", "info", "warning", "error", "fatal"];
|
|
198
|
+
var Logger = class _Logger {
|
|
199
|
+
static APP_NAME = "@fabasoad/sarif-to-slack";
|
|
200
|
+
static DEFAULT_LOG_LEVEL = "info";
|
|
201
|
+
static DEFAULT_LOG_TEMPLATE = "[{{logLevelName}}] [{{name}}] {{dateIsoStr}} ";
|
|
202
|
+
static DEFAULT_LOG_COLORED = true;
|
|
203
|
+
_instance;
|
|
204
|
+
isLogLevel(v) {
|
|
205
|
+
return LogLevelItems.includes(v);
|
|
206
|
+
}
|
|
207
|
+
getMinLevel() {
|
|
208
|
+
let result = _Logger.DEFAULT_LOG_LEVEL;
|
|
209
|
+
if (isDebug()) {
|
|
210
|
+
result = "silly";
|
|
211
|
+
} else {
|
|
212
|
+
const parseResult = import_zod2.z.string().refine((v) => this.isLogLevel(v)).transform((v) => v).safeParse(process.env.SARIF_TO_SLACK_LOG_LEVEL);
|
|
213
|
+
if (parseResult.success) {
|
|
214
|
+
result = parseResult.data;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return LogLevelItems.findIndex((v) => v === result);
|
|
218
|
+
}
|
|
219
|
+
getLogTemplate() {
|
|
220
|
+
const result = import_zod2.z.string().safeParse(process.env.SARIF_TO_SLACK_LOG_TEMPLATE);
|
|
221
|
+
return result.success ? result.data : _Logger.DEFAULT_LOG_TEMPLATE;
|
|
222
|
+
}
|
|
223
|
+
getLogColored() {
|
|
224
|
+
const result = import_zod2.z.stringbool().safeParse(process.env.SARIF_TO_SLACK_LOG_COLORED);
|
|
225
|
+
return result.success ? result.data : _Logger.DEFAULT_LOG_COLORED;
|
|
226
|
+
}
|
|
227
|
+
constructor(memberName) {
|
|
228
|
+
this._instance = new import_tslog.Logger({
|
|
229
|
+
name: `${_Logger.APP_NAME}${memberName === void 0 ? "" : `::${memberName}`}`,
|
|
230
|
+
minLevel: this.getMinLevel(),
|
|
231
|
+
type: "pretty",
|
|
232
|
+
prettyLogTimeZone: "UTC",
|
|
233
|
+
prettyLogTemplate: this.getLogTemplate(),
|
|
234
|
+
stylePrettyLogs: this.getLogColored()
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
info(...args) {
|
|
238
|
+
this._instance.info(...args);
|
|
239
|
+
}
|
|
240
|
+
warn(...args) {
|
|
241
|
+
this._instance.warn(...args);
|
|
242
|
+
}
|
|
243
|
+
trace(...args) {
|
|
244
|
+
this._instance.trace(...args);
|
|
245
|
+
}
|
|
246
|
+
debug(...args) {
|
|
247
|
+
this._instance.debug(...args);
|
|
248
|
+
}
|
|
249
|
+
};
|
|
170
250
|
|
|
171
251
|
// src/types.ts
|
|
172
|
-
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
173
|
-
LogLevel2[LogLevel2["Silly"] = 0] = "Silly";
|
|
174
|
-
LogLevel2[LogLevel2["Trace"] = 1] = "Trace";
|
|
175
|
-
LogLevel2[LogLevel2["Debug"] = 2] = "Debug";
|
|
176
|
-
LogLevel2[LogLevel2["Info"] = 3] = "Info";
|
|
177
|
-
LogLevel2[LogLevel2["Warning"] = 4] = "Warning";
|
|
178
|
-
LogLevel2[LogLevel2["Error"] = 5] = "Error";
|
|
179
|
-
LogLevel2[LogLevel2["Fatal"] = 6] = "Fatal";
|
|
180
|
-
return LogLevel2;
|
|
181
|
-
})(LogLevel || {});
|
|
182
252
|
var FooterType = /* @__PURE__ */ ((FooterType2) => {
|
|
183
253
|
FooterType2["PlainText"] = "plain_text";
|
|
184
254
|
FooterType2["Markdown"] = "mrkdwn";
|
|
@@ -193,6 +263,12 @@ var RepresentationType = /* @__PURE__ */ ((RepresentationType2) => {
|
|
|
193
263
|
RepresentationType2[RepresentationType2["CompactGroupBySarifPerSeverity"] = 5] = "CompactGroupBySarifPerSeverity";
|
|
194
264
|
RepresentationType2[RepresentationType2["CompactTotalPerLevel"] = 6] = "CompactTotalPerLevel";
|
|
195
265
|
RepresentationType2[RepresentationType2["CompactTotalPerSeverity"] = 7] = "CompactTotalPerSeverity";
|
|
266
|
+
RepresentationType2[RepresentationType2["TableGroupByRunPerLevel"] = 8] = "TableGroupByRunPerLevel";
|
|
267
|
+
RepresentationType2[RepresentationType2["TableGroupByRunPerSeverity"] = 9] = "TableGroupByRunPerSeverity";
|
|
268
|
+
RepresentationType2[RepresentationType2["TableGroupByToolNamePerLevel"] = 10] = "TableGroupByToolNamePerLevel";
|
|
269
|
+
RepresentationType2[RepresentationType2["TableGroupByToolNamePerSeverity"] = 11] = "TableGroupByToolNamePerSeverity";
|
|
270
|
+
RepresentationType2[RepresentationType2["TableGroupBySarifPerLevel"] = 12] = "TableGroupBySarifPerLevel";
|
|
271
|
+
RepresentationType2[RepresentationType2["TableGroupBySarifPerSeverity"] = 13] = "TableGroupBySarifPerSeverity";
|
|
196
272
|
return RepresentationType2;
|
|
197
273
|
})(RepresentationType || {});
|
|
198
274
|
var SecuritySeverity = /* @__PURE__ */ ((SecuritySeverity2) => {
|
|
@@ -204,6 +280,9 @@ var SecuritySeverity = /* @__PURE__ */ ((SecuritySeverity2) => {
|
|
|
204
280
|
SecuritySeverity2[SecuritySeverity2["Critical"] = 5] = "Critical";
|
|
205
281
|
return SecuritySeverity2;
|
|
206
282
|
})(SecuritySeverity || {});
|
|
283
|
+
var SecuritySeverityValues = Object.values(SecuritySeverity).filter(
|
|
284
|
+
(v) => typeof v === "string"
|
|
285
|
+
);
|
|
207
286
|
var SecurityLevel = /* @__PURE__ */ ((SecurityLevel2) => {
|
|
208
287
|
SecurityLevel2[SecurityLevel2["Unknown"] = 0] = "Unknown";
|
|
209
288
|
SecurityLevel2[SecurityLevel2["None"] = 1] = "None";
|
|
@@ -212,151 +291,19 @@ var SecurityLevel = /* @__PURE__ */ ((SecurityLevel2) => {
|
|
|
212
291
|
SecurityLevel2[SecurityLevel2["Error"] = 4] = "Error";
|
|
213
292
|
return SecurityLevel2;
|
|
214
293
|
})(SecurityLevel || {});
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
var sha = "fac0524704ae1c62880212a04af4e48ac31297ed";
|
|
219
|
-
var buildAt = "2025-08-25T09:16:54Z";
|
|
220
|
-
|
|
221
|
-
// src/model/SlackMessage.ts
|
|
222
|
-
function createSlackMessage(url, opts) {
|
|
223
|
-
return new SlackMessageImpl(url, opts);
|
|
224
|
-
}
|
|
225
|
-
var SlackMessageImpl = class {
|
|
226
|
-
_webhook;
|
|
227
|
-
_gitHubServerUrl;
|
|
228
|
-
_color;
|
|
229
|
-
_representation;
|
|
230
|
-
_header;
|
|
231
|
-
_footer;
|
|
232
|
-
_actor;
|
|
233
|
-
_runId;
|
|
234
|
-
constructor(url, opts) {
|
|
235
|
-
this._webhook = new import_webhook.IncomingWebhook(url, {
|
|
236
|
-
username: opts.username || "SARIF results",
|
|
237
|
-
icon_url: opts.iconUrl
|
|
238
|
-
});
|
|
239
|
-
this._gitHubServerUrl = process.env.GITHUB_SERVER_URL || "https://github.com";
|
|
240
|
-
this._color = opts.color;
|
|
241
|
-
this._representation = opts.representation;
|
|
242
|
-
}
|
|
243
|
-
withHeader(header) {
|
|
244
|
-
this._header = {
|
|
245
|
-
type: "header",
|
|
246
|
-
text: {
|
|
247
|
-
type: "plain_text",
|
|
248
|
-
text: header || process.env.GITHUB_REPOSITORY || "SARIF results"
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
withActor(actor) {
|
|
253
|
-
this._actor = actor || process.env.GITHUB_ACTOR;
|
|
254
|
-
}
|
|
255
|
-
withRun() {
|
|
256
|
-
this._runId = process.env.GITHUB_RUN_ID;
|
|
257
|
-
}
|
|
258
|
-
withFooter(text, type) {
|
|
259
|
-
const repoName = "fabasoad/sarif-to-slack";
|
|
260
|
-
const element = text ? { type: type || "plain_text" /* PlainText */, text } : { type: "mrkdwn" /* Markdown */, text: `Generated by <${this._gitHubServerUrl}/${repoName}|@${repoName}@${version}>` };
|
|
261
|
-
this._footer = {
|
|
262
|
-
type: "context",
|
|
263
|
-
elements: [element]
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
async send() {
|
|
267
|
-
const blocks = [];
|
|
268
|
-
if (this._header) {
|
|
269
|
-
blocks.push(this._header);
|
|
270
|
-
}
|
|
271
|
-
blocks.push({
|
|
272
|
-
type: "section",
|
|
273
|
-
text: {
|
|
274
|
-
type: "mrkdwn",
|
|
275
|
-
text: this.buildText()
|
|
276
|
-
}
|
|
277
|
-
});
|
|
278
|
-
if (this._footer) {
|
|
279
|
-
blocks.push(this._footer);
|
|
280
|
-
}
|
|
281
|
-
const { text } = await this._webhook.send({
|
|
282
|
-
attachments: [{ color: this._color, blocks }]
|
|
283
|
-
});
|
|
284
|
-
return text;
|
|
285
|
-
}
|
|
286
|
-
buildText() {
|
|
287
|
-
const text = [];
|
|
288
|
-
if (this._actor) {
|
|
289
|
-
const actorUrl = `${this._gitHubServerUrl}/${this._actor}`;
|
|
290
|
-
text.push(`_Triggered by <${actorUrl}|${this._actor}>_`);
|
|
291
|
-
}
|
|
292
|
-
text.push(this._representation.compose());
|
|
293
|
-
if (this._runId) {
|
|
294
|
-
let runText = "Job ";
|
|
295
|
-
if (process.env.GITHUB_REPOSITORY) {
|
|
296
|
-
runText += `<${this._gitHubServerUrl}/${process.env.GITHUB_REPOSITORY}/actions/runs/${this._runId}|#${this._runId}>`;
|
|
297
|
-
} else {
|
|
298
|
-
runText += `#${this._runId}`;
|
|
299
|
-
}
|
|
300
|
-
text.push(runText);
|
|
301
|
-
}
|
|
302
|
-
return text.join("\n\n");
|
|
303
|
-
}
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
// src/SarifToSlackClient.ts
|
|
307
|
-
var import_fs2 = require("fs");
|
|
308
|
-
|
|
309
|
-
// src/Logger.ts
|
|
310
|
-
var import_tslog = require("tslog");
|
|
311
|
-
var Logger = class _Logger {
|
|
312
|
-
static DEFAULT_LOG_LEVEL = 3 /* Info */;
|
|
313
|
-
static DEFAULT_LOG_TEMPLATE = "[{{logLevelName}}] [{{name}}] {{dateIsoStr}} ";
|
|
314
|
-
static DEFAULT_LOG_COLORED = true;
|
|
315
|
-
static instance;
|
|
316
|
-
static initialize(opts) {
|
|
317
|
-
if (!_Logger.instance) {
|
|
318
|
-
_Logger.instance = new import_tslog.Logger({
|
|
319
|
-
name: "@fabasoad/sarif-to-slack",
|
|
320
|
-
minLevel: process.env.ACTIONS_STEP_DEBUG === "true" ? 0 /* Silly */ : opts?.level ?? _Logger.DEFAULT_LOG_LEVEL,
|
|
321
|
-
type: "pretty",
|
|
322
|
-
prettyLogTimeZone: "UTC",
|
|
323
|
-
prettyLogTemplate: opts?.template ?? _Logger.DEFAULT_LOG_TEMPLATE,
|
|
324
|
-
stylePrettyLogs: opts?.colored ?? _Logger.DEFAULT_LOG_COLORED
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
static warn(...args) {
|
|
329
|
-
_Logger.instance.warn(...args);
|
|
330
|
-
}
|
|
331
|
-
static info(...args) {
|
|
332
|
-
_Logger.instance.info(...args);
|
|
333
|
-
}
|
|
334
|
-
static debug(...args) {
|
|
335
|
-
_Logger.instance.debug(...args);
|
|
336
|
-
}
|
|
337
|
-
static trace(...args) {
|
|
338
|
-
_Logger.instance.trace(...args);
|
|
339
|
-
}
|
|
340
|
-
};
|
|
341
|
-
|
|
342
|
-
// src/System.ts
|
|
343
|
-
var System = class {
|
|
344
|
-
static initialize() {
|
|
345
|
-
Logger.info(`@fabasoad/sarif-to-slack version: ${version}`);
|
|
346
|
-
Logger.info(`@fabasoad/sarif-to-slack sha: ${sha}`);
|
|
347
|
-
Logger.info(`@fabasoad/sarif-to-slack built at: ${buildAt}`);
|
|
348
|
-
}
|
|
349
|
-
};
|
|
294
|
+
var SecurityLevelValues = Object.values(SecurityLevel).filter(
|
|
295
|
+
(v) => typeof v === "string"
|
|
296
|
+
);
|
|
350
297
|
|
|
351
298
|
// src/utils/FileUtils.ts
|
|
352
|
-
var
|
|
299
|
+
var import_node_fs = __toESM(require("fs"));
|
|
353
300
|
var path = __toESM(require("path"));
|
|
354
301
|
function listFiles(dir, recursive, extension, fileList = []) {
|
|
355
|
-
if (
|
|
356
|
-
const entries =
|
|
302
|
+
if (import_node_fs.default.statSync(dir).isDirectory()) {
|
|
303
|
+
const entries = import_node_fs.default.readdirSync(dir);
|
|
357
304
|
entries.forEach((entry) => {
|
|
358
305
|
const fullPath = path.join(dir, entry);
|
|
359
|
-
if (recursive &&
|
|
306
|
+
if (recursive && import_node_fs.default.statSync(fullPath).isDirectory()) {
|
|
360
307
|
listFiles(fullPath, recursive, extension, fileList);
|
|
361
308
|
} else if (path.extname(fullPath).toLowerCase() === `.${extension}`) {
|
|
362
309
|
fileList.push(fullPath);
|
|
@@ -366,24 +313,42 @@ function listFiles(dir, recursive, extension, fileList = []) {
|
|
|
366
313
|
return fileList;
|
|
367
314
|
}
|
|
368
315
|
function extractListOfFiles(opts) {
|
|
369
|
-
|
|
316
|
+
const logger = new Logger(extractListOfFiles.name);
|
|
317
|
+
if (!import_node_fs.default.existsSync(opts.path)) {
|
|
370
318
|
throw new Error(`Provided path does not exist: ${opts.path}`);
|
|
371
319
|
}
|
|
372
|
-
const stats =
|
|
320
|
+
const stats = import_node_fs.default.statSync(opts.path);
|
|
373
321
|
if (stats.isDirectory()) {
|
|
374
|
-
|
|
322
|
+
logger.info(`Provided path is a directory: ${opts.path}`);
|
|
375
323
|
const files = listFiles(opts.path, !!opts.recursive, opts.extension ?? "sarif");
|
|
376
|
-
|
|
377
|
-
|
|
324
|
+
logger.info(`Found ${files.length} files in ${opts.path} directory with ${opts.extension} extension`);
|
|
325
|
+
logger.debug(`Found files: ${files.join(", ")}`);
|
|
378
326
|
return files;
|
|
379
327
|
}
|
|
380
328
|
if (stats.isFile()) {
|
|
381
|
-
|
|
329
|
+
logger.info(`Provided path is a file: ${opts.path}`);
|
|
382
330
|
return [opts.path];
|
|
383
331
|
}
|
|
384
332
|
throw new Error(`Provided path is neither a file nor a directory: ${opts.path}`);
|
|
385
333
|
}
|
|
386
334
|
|
|
335
|
+
// src/utils/ExtendedArray.ts
|
|
336
|
+
var ExtendedArray = class extends Array {
|
|
337
|
+
findByProperty(prop, value) {
|
|
338
|
+
return this.find((v) => v[prop] === value);
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
// src/model/FindingArray.ts
|
|
343
|
+
var FindingArray = class extends ExtendedArray {
|
|
344
|
+
hasSeverityOrHigher(severity) {
|
|
345
|
+
return Object.values(SecuritySeverity).filter((v) => typeof v === "number").filter((v) => v >= severity).some((v) => this.findByProperty("severity", v) != null);
|
|
346
|
+
}
|
|
347
|
+
hasLevelOrHigher(level) {
|
|
348
|
+
return Object.values(SecurityLevel).filter((v) => typeof v === "number").filter((v) => v >= level).some((v) => this.findByProperty("level", v) != null);
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
|
|
387
352
|
// src/utils/Comparators.ts
|
|
388
353
|
function findingsComparatorByKey(key) {
|
|
389
354
|
return (a, b) => {
|
|
@@ -402,23 +367,6 @@ function findingsComparatorByKey(key) {
|
|
|
402
367
|
};
|
|
403
368
|
}
|
|
404
369
|
|
|
405
|
-
// src/utils/ExtendedArray.ts
|
|
406
|
-
var ExtendedArray = class extends Array {
|
|
407
|
-
findByProperty(prop, value) {
|
|
408
|
-
return this.find((v) => v[prop] === value);
|
|
409
|
-
}
|
|
410
|
-
};
|
|
411
|
-
|
|
412
|
-
// src/model/FindingArray.ts
|
|
413
|
-
var FindingArray = class extends ExtendedArray {
|
|
414
|
-
hasSeverityOrHigher(severity) {
|
|
415
|
-
return Object.values(SecuritySeverity).filter((v) => typeof v === "number").filter((v) => v >= severity).some((v) => this.findByProperty("severity", v) != null);
|
|
416
|
-
}
|
|
417
|
-
hasLevelOrHigher(level) {
|
|
418
|
-
return Object.values(SecurityLevel).filter((v) => typeof v === "number").filter((v) => v >= level).some((v) => this.findByProperty("level", v) != null);
|
|
419
|
-
}
|
|
420
|
-
};
|
|
421
|
-
|
|
422
370
|
// src/representations/Representation.ts
|
|
423
371
|
var Representation = class {
|
|
424
372
|
_model;
|
|
@@ -435,6 +383,9 @@ var Representation = class {
|
|
|
435
383
|
italic(text) {
|
|
436
384
|
return `_${text}_`;
|
|
437
385
|
}
|
|
386
|
+
codeBlock(text) {
|
|
387
|
+
return "```\n" + text + "\n```";
|
|
388
|
+
}
|
|
438
389
|
};
|
|
439
390
|
|
|
440
391
|
// src/representations/CompactGroupByRepresentation.ts
|
|
@@ -456,7 +407,7 @@ ${summary}`;
|
|
|
456
407
|
const result = [];
|
|
457
408
|
findings.reduce((grouped, f) => {
|
|
458
409
|
if (!grouped.get(f[key])) {
|
|
459
|
-
grouped.set(f[key],
|
|
410
|
+
grouped.set(f[key], []);
|
|
460
411
|
}
|
|
461
412
|
grouped.get(f[key])?.push(f);
|
|
462
413
|
return grouped;
|
|
@@ -608,6 +559,306 @@ var CompactTotalPerLevelRepresentation = class extends CompactTotalRepresentatio
|
|
|
608
559
|
}
|
|
609
560
|
};
|
|
610
561
|
|
|
562
|
+
// src/representations/table/Column.ts
|
|
563
|
+
var Column = class {
|
|
564
|
+
constructor(header, cellsCount) {
|
|
565
|
+
this.header = header;
|
|
566
|
+
this._cells = new Array(cellsCount);
|
|
567
|
+
}
|
|
568
|
+
_logger = new Logger("Column");
|
|
569
|
+
_cells;
|
|
570
|
+
get total() {
|
|
571
|
+
return this._cells.reduce((sum, c) => {
|
|
572
|
+
sum += Number(c.value);
|
|
573
|
+
return sum;
|
|
574
|
+
}, 0);
|
|
575
|
+
}
|
|
576
|
+
get width() {
|
|
577
|
+
return Math.max(
|
|
578
|
+
...this._cells.map((c) => c.getWidth()),
|
|
579
|
+
this.total.toString().length
|
|
580
|
+
);
|
|
581
|
+
}
|
|
582
|
+
setCell(index, value) {
|
|
583
|
+
if (index >= 0 && index < this._cells.length) {
|
|
584
|
+
this._cells[index] = value;
|
|
585
|
+
const width = this.width;
|
|
586
|
+
this._cells.forEach((c) => c.setWidth(width));
|
|
587
|
+
} else {
|
|
588
|
+
this._logger.warn(`Cell index out of range. Requested index: ${index}. Cells count: ${this._cells.length}.`);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
// src/representations/table/Cell.ts
|
|
594
|
+
var Cell = class {
|
|
595
|
+
constructor(_value = 0) {
|
|
596
|
+
this._value = _value;
|
|
597
|
+
this._width = _value.toString().length;
|
|
598
|
+
}
|
|
599
|
+
_width;
|
|
600
|
+
setWidth(width) {
|
|
601
|
+
this._width = width > this._width ? width : this._width;
|
|
602
|
+
}
|
|
603
|
+
getWidth() {
|
|
604
|
+
return this._width;
|
|
605
|
+
}
|
|
606
|
+
get value() {
|
|
607
|
+
return this._value;
|
|
608
|
+
}
|
|
609
|
+
toString() {
|
|
610
|
+
const str = this._value.toString();
|
|
611
|
+
const repeatCount = this._width - str.length;
|
|
612
|
+
return `${str}${repeatCount > 0 ? " ".repeat(repeatCount) : ""}`;
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
|
|
616
|
+
// src/representations/table/Row.ts
|
|
617
|
+
var Row = class {
|
|
618
|
+
constructor(_header, headerWidth, cellsCount) {
|
|
619
|
+
this._header = _header;
|
|
620
|
+
this.headerWidth = headerWidth;
|
|
621
|
+
this._cells = Array.from({ length: cellsCount }, () => new Cell());
|
|
622
|
+
this._totalWidth = 1;
|
|
623
|
+
}
|
|
624
|
+
_logger = new Logger("Row");
|
|
625
|
+
_cells;
|
|
626
|
+
_totalWidth;
|
|
627
|
+
get total() {
|
|
628
|
+
return this._cells.reduce((sum, c) => {
|
|
629
|
+
sum += Number(c.value);
|
|
630
|
+
return sum;
|
|
631
|
+
}, 0);
|
|
632
|
+
}
|
|
633
|
+
setCell(index, value) {
|
|
634
|
+
if (index >= 0 && index < this._cells.length) {
|
|
635
|
+
this._cells[index] = value;
|
|
636
|
+
} else {
|
|
637
|
+
this._logger.warn(`Setting cell failed. Reason: index out of range. Requested index: ${index}. Cells count: ${this._cells.length}.`);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
get totalWidth() {
|
|
641
|
+
return this._totalWidth;
|
|
642
|
+
}
|
|
643
|
+
setTotalWidth(value) {
|
|
644
|
+
this._totalWidth = value;
|
|
645
|
+
}
|
|
646
|
+
toString() {
|
|
647
|
+
const result = [];
|
|
648
|
+
result.push(`${this._header}${this.headerWidth > this._header.length ? " ".repeat(this.headerWidth - this._header.length) : ""}`);
|
|
649
|
+
this._cells.map((c) => c.toString()).forEach((v) => result.push(v));
|
|
650
|
+
const totalStr = this.total.toString();
|
|
651
|
+
result.push(`${totalStr}${this._totalWidth > totalStr.length ? " ".repeat(this._totalWidth - totalStr.length) : ""}`);
|
|
652
|
+
return `|${result.join("|")}|`;
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
|
|
656
|
+
// src/representations/table/Table.ts
|
|
657
|
+
var HEADER_TOTAL = "Total";
|
|
658
|
+
var Table = class {
|
|
659
|
+
header;
|
|
660
|
+
columns;
|
|
661
|
+
rows;
|
|
662
|
+
constructor(headers) {
|
|
663
|
+
this.header = headers.main ?? "";
|
|
664
|
+
this.columns = Array.from(
|
|
665
|
+
{ length: headers.columns.length },
|
|
666
|
+
(_, index) => new Column(headers.columns[index], headers.rows.length)
|
|
667
|
+
);
|
|
668
|
+
const headerWidth = Math.max(
|
|
669
|
+
this.header.length,
|
|
670
|
+
...headers.rows.map((v) => v.length),
|
|
671
|
+
HEADER_TOTAL.length
|
|
672
|
+
);
|
|
673
|
+
this.rows = Array.from(
|
|
674
|
+
{ length: headers.rows.length },
|
|
675
|
+
(_, index) => new Row(headers.rows[index], headerWidth, headers.columns.length)
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
set(rowIndex, columnIndex, v) {
|
|
679
|
+
if (rowIndex >= 0 && rowIndex < this.rows.length && columnIndex >= 0 && columnIndex < this.columns.length) {
|
|
680
|
+
const cell = new Cell(v);
|
|
681
|
+
cell.setWidth(this.columns[columnIndex].header.length);
|
|
682
|
+
this.columns[columnIndex].setCell(rowIndex, cell);
|
|
683
|
+
this.rows[rowIndex].setCell(columnIndex, cell);
|
|
684
|
+
const rowTotalWidth = Math.max(
|
|
685
|
+
// Based on the sum of all total values
|
|
686
|
+
this.rows.reduce((sum, r) => {
|
|
687
|
+
sum += r.total;
|
|
688
|
+
return sum;
|
|
689
|
+
}, 0).toString().length,
|
|
690
|
+
// Based on the width of "Total" header
|
|
691
|
+
HEADER_TOTAL.length
|
|
692
|
+
);
|
|
693
|
+
this.rows.forEach((r) => r.setTotalWidth(rowTotalWidth));
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
toString() {
|
|
697
|
+
const rowsStr = [];
|
|
698
|
+
if (this.rows.length > 0 && this.columns.length > 0) {
|
|
699
|
+
this.rows.forEach((row) => rowsStr.push(row.toString()));
|
|
700
|
+
const rowSeparator = rowsStr[0].replace(/[^|]/g, "-");
|
|
701
|
+
rowsStr.unshift(rowSeparator);
|
|
702
|
+
rowsStr.push(rowSeparator);
|
|
703
|
+
const rowTotal = [];
|
|
704
|
+
let sumTotal = 0;
|
|
705
|
+
for (const column of this.columns) {
|
|
706
|
+
const total = column.total;
|
|
707
|
+
rowTotal.push(`${total}${total.toString().length < column.width ? " ".repeat(column.width - total.toString().length) : ""}`);
|
|
708
|
+
sumTotal += total;
|
|
709
|
+
}
|
|
710
|
+
const column1 = `${HEADER_TOTAL}${this.rows[0].headerWidth > HEADER_TOTAL.length ? " ".repeat(this.rows[0].headerWidth - HEADER_TOTAL.length) : ""}`;
|
|
711
|
+
const columnLast = `${sumTotal}${sumTotal.toString().length < HEADER_TOTAL.length ? " ".repeat(HEADER_TOTAL.length - sumTotal.toString().length) : ""}`;
|
|
712
|
+
rowsStr.push(`|${column1}|${rowTotal.join("|")}|${columnLast}|`);
|
|
713
|
+
const rowTop = [
|
|
714
|
+
this.header + (this.header.length < this.rows[0].headerWidth ? " ".repeat(this.rows[0].headerWidth - this.header.length) : ""),
|
|
715
|
+
this.columns.map((c) => `${c.header}${c.header.length < c.width ? " ".repeat(c.width - c.header.length) : ""}`).join("|"),
|
|
716
|
+
HEADER_TOTAL + (HEADER_TOTAL.length < this.rows[0].totalWidth ? " ".repeat(this.rows[0].totalWidth - HEADER_TOTAL.length) : "")
|
|
717
|
+
];
|
|
718
|
+
rowsStr.unshift(`|${rowTop.join("|")}|`);
|
|
719
|
+
}
|
|
720
|
+
return rowsStr.join("\n").replace(/[|]/g, " | ");
|
|
721
|
+
}
|
|
722
|
+
};
|
|
723
|
+
|
|
724
|
+
// src/representations/TableGroupRepresentation.ts
|
|
725
|
+
var TableGroupRepresentation = class extends Representation {
|
|
726
|
+
constructor(_keyBy, _keyPer, _values, model) {
|
|
727
|
+
super(model, "toolName");
|
|
728
|
+
this._keyBy = _keyBy;
|
|
729
|
+
this._keyPer = _keyPer;
|
|
730
|
+
this._values = _values;
|
|
731
|
+
}
|
|
732
|
+
_logger = new Logger("TableGroupRepresentation");
|
|
733
|
+
groupFindingsPer(findings) {
|
|
734
|
+
return findings.reduce(
|
|
735
|
+
(grouped, f) => {
|
|
736
|
+
grouped[f[this._keyPer]].push(f);
|
|
737
|
+
return grouped;
|
|
738
|
+
},
|
|
739
|
+
Array.from({ length: this._values.length }, () => [])
|
|
740
|
+
);
|
|
741
|
+
}
|
|
742
|
+
keyByToString(key) {
|
|
743
|
+
return key.toString();
|
|
744
|
+
}
|
|
745
|
+
groupFindingsBy(findings) {
|
|
746
|
+
return findings.reduce(
|
|
747
|
+
(grouped, f) => {
|
|
748
|
+
const key = this.keyByToString(f[this._keyBy]);
|
|
749
|
+
if (!grouped.has(key)) {
|
|
750
|
+
grouped.set(key, []);
|
|
751
|
+
}
|
|
752
|
+
grouped.get(key)?.push(f);
|
|
753
|
+
return grouped;
|
|
754
|
+
},
|
|
755
|
+
/* @__PURE__ */ new Map()
|
|
756
|
+
);
|
|
757
|
+
}
|
|
758
|
+
get title() {
|
|
759
|
+
switch (this._keyBy) {
|
|
760
|
+
case "toolName":
|
|
761
|
+
return "Tool";
|
|
762
|
+
case "runId":
|
|
763
|
+
return "Run #";
|
|
764
|
+
case "sarifPath":
|
|
765
|
+
return "File #";
|
|
766
|
+
default:
|
|
767
|
+
return "";
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
compose() {
|
|
771
|
+
const groupedBy = this.groupFindingsBy(this._model.findings);
|
|
772
|
+
const table = new Table({
|
|
773
|
+
main: this.title,
|
|
774
|
+
rows: Array.from(groupedBy.keys()),
|
|
775
|
+
columns: this._values
|
|
776
|
+
});
|
|
777
|
+
let i = 0;
|
|
778
|
+
for (const findings of groupedBy.values()) {
|
|
779
|
+
const grouped = this.groupFindingsPer(findings);
|
|
780
|
+
for (let j = 0; j < grouped.length; j++) {
|
|
781
|
+
table.set(i, j, grouped[j].length);
|
|
782
|
+
}
|
|
783
|
+
i++;
|
|
784
|
+
}
|
|
785
|
+
const result = this.codeBlock(table.toString());
|
|
786
|
+
this._logger.trace(result);
|
|
787
|
+
return result;
|
|
788
|
+
}
|
|
789
|
+
};
|
|
790
|
+
|
|
791
|
+
// src/representations/TableGroupByToolNameRepresentation.ts
|
|
792
|
+
var TableGroupByToolNameRepresentation = class extends TableGroupRepresentation {
|
|
793
|
+
constructor(keyPer, values, model) {
|
|
794
|
+
super("toolName", keyPer, values, model);
|
|
795
|
+
}
|
|
796
|
+
};
|
|
797
|
+
|
|
798
|
+
// src/representations/TableGroupByToolNamePerLevelRepresentation.ts
|
|
799
|
+
var TableGroupByToolNamePerLevelRepresentation = class extends TableGroupByToolNameRepresentation {
|
|
800
|
+
constructor(model) {
|
|
801
|
+
super("level", SecurityLevelValues, model);
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
|
|
805
|
+
// src/representations/TableGroupByToolNamePerSeverityRepresentation.ts
|
|
806
|
+
var TableGroupByToolNamePerSeverityRepresentation = class extends TableGroupByToolNameRepresentation {
|
|
807
|
+
constructor(model) {
|
|
808
|
+
super("severity", SecuritySeverityValues, model);
|
|
809
|
+
}
|
|
810
|
+
};
|
|
811
|
+
|
|
812
|
+
// src/representations/TableGroupByRunRepresentation.ts
|
|
813
|
+
var TableGroupByRunRepresentation = class extends TableGroupRepresentation {
|
|
814
|
+
constructor(keyPer, values, model) {
|
|
815
|
+
super("runId", keyPer, values, model);
|
|
816
|
+
}
|
|
817
|
+
};
|
|
818
|
+
|
|
819
|
+
// src/representations/TableGroupByRunPerLevelRepresentation.ts
|
|
820
|
+
var TableGroupByRunPerLevelRepresentation = class extends TableGroupByRunRepresentation {
|
|
821
|
+
constructor(model) {
|
|
822
|
+
super("level", SecurityLevelValues, model);
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
|
|
826
|
+
// src/representations/TableGroupByRunPerSeverityRepresentation.ts
|
|
827
|
+
var TableGroupByRunPerSeverityRepresentation = class extends TableGroupByRunRepresentation {
|
|
828
|
+
constructor(model) {
|
|
829
|
+
super("severity", SecuritySeverityValues, model);
|
|
830
|
+
}
|
|
831
|
+
};
|
|
832
|
+
|
|
833
|
+
// src/representations/TableGroupBySarifRepresentation.ts
|
|
834
|
+
var TableGroupBySarifRepresentation = class extends TableGroupRepresentation {
|
|
835
|
+
_fileToNumberMap = /* @__PURE__ */ new Map();
|
|
836
|
+
constructor(keyPer, values, model) {
|
|
837
|
+
super("sarifPath", keyPer, values, model);
|
|
838
|
+
}
|
|
839
|
+
keyByToString(key) {
|
|
840
|
+
const keyStr = key.toString();
|
|
841
|
+
if (!this._fileToNumberMap.has(keyStr)) {
|
|
842
|
+
this._fileToNumberMap.set(keyStr, this._fileToNumberMap.size + 1);
|
|
843
|
+
}
|
|
844
|
+
return this._fileToNumberMap.get(keyStr)?.toString();
|
|
845
|
+
}
|
|
846
|
+
};
|
|
847
|
+
|
|
848
|
+
// src/representations/TableGroupBySarifPerLevelRepresentation.ts
|
|
849
|
+
var TableGroupBySarifPerLevelRepresentation = class extends TableGroupBySarifRepresentation {
|
|
850
|
+
constructor(model) {
|
|
851
|
+
super("level", SecurityLevelValues, model);
|
|
852
|
+
}
|
|
853
|
+
};
|
|
854
|
+
|
|
855
|
+
// src/representations/TableGroupBySarifPerSeverityRepresentation.ts
|
|
856
|
+
var TableGroupBySarifPerSeverityRepresentation = class extends TableGroupBySarifRepresentation {
|
|
857
|
+
constructor(model) {
|
|
858
|
+
super("severity", SecuritySeverityValues, model);
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
|
|
611
862
|
// src/representations/RepresentationFactory.ts
|
|
612
863
|
function createRepresentation(model, type = 3 /* CompactGroupByToolNamePerSeverity */) {
|
|
613
864
|
switch (type) {
|
|
@@ -627,6 +878,18 @@ function createRepresentation(model, type = 3 /* CompactGroupByToolNamePerSeveri
|
|
|
627
878
|
return new CompactTotalPerLevelRepresentation(model);
|
|
628
879
|
case 7 /* CompactTotalPerSeverity */:
|
|
629
880
|
return new CompactTotalPerSeverityRepresentation(model);
|
|
881
|
+
case 8 /* TableGroupByRunPerLevel */:
|
|
882
|
+
return new TableGroupByRunPerLevelRepresentation(model);
|
|
883
|
+
case 9 /* TableGroupByRunPerSeverity */:
|
|
884
|
+
return new TableGroupByRunPerSeverityRepresentation(model);
|
|
885
|
+
case 10 /* TableGroupByToolNamePerLevel */:
|
|
886
|
+
return new TableGroupByToolNamePerLevelRepresentation(model);
|
|
887
|
+
case 11 /* TableGroupByToolNamePerSeverity */:
|
|
888
|
+
return new TableGroupByToolNamePerSeverityRepresentation(model);
|
|
889
|
+
case 12 /* TableGroupBySarifPerLevel */:
|
|
890
|
+
return new TableGroupBySarifPerLevelRepresentation(model);
|
|
891
|
+
case 13 /* TableGroupBySarifPerSeverity */:
|
|
892
|
+
return new TableGroupBySarifPerSeverityRepresentation(model);
|
|
630
893
|
default:
|
|
631
894
|
throw new Error(`Unknown representation type: ${type}`);
|
|
632
895
|
}
|
|
@@ -765,6 +1028,7 @@ function createFinding(opts) {
|
|
|
765
1028
|
return new FindingImpl(opts);
|
|
766
1029
|
}
|
|
767
1030
|
var FindingImpl = class {
|
|
1031
|
+
_logger = new Logger("FindingImpl");
|
|
768
1032
|
_runMetadata;
|
|
769
1033
|
_result;
|
|
770
1034
|
_sarifPath;
|
|
@@ -810,7 +1074,7 @@ var FindingImpl = class {
|
|
|
810
1074
|
this._levelCache = this._processor.tryFindLevel();
|
|
811
1075
|
}
|
|
812
1076
|
if (this._levelCache === void 0) {
|
|
813
|
-
|
|
1077
|
+
this._logger.debug(`Unknown level of ${this._rule?.id} rule`);
|
|
814
1078
|
return 0 /* Unknown */;
|
|
815
1079
|
}
|
|
816
1080
|
switch (this._levelCache) {
|
|
@@ -826,7 +1090,7 @@ var FindingImpl = class {
|
|
|
826
1090
|
}
|
|
827
1091
|
get severity() {
|
|
828
1092
|
if (this.cvssScore == null || this.cvssScore < 0 || this.cvssScore > 10) {
|
|
829
|
-
|
|
1093
|
+
this._logger.debug(`Unsupported CVSS score ${this.cvssScore} in ${this._rule?.id} rule`);
|
|
830
1094
|
return 0 /* Unknown */;
|
|
831
1095
|
}
|
|
832
1096
|
if (this.cvssScore >= 9) {
|
|
@@ -846,167 +1110,257 @@ var FindingImpl = class {
|
|
|
846
1110
|
};
|
|
847
1111
|
|
|
848
1112
|
// src/model/color/ColorIdentification.ts
|
|
849
|
-
function logColorTaken(color, prop) {
|
|
850
|
-
|
|
1113
|
+
function logColorTaken(logger, color, prop) {
|
|
1114
|
+
logger.debug(`Message has ${color?.color} color taken from '${prop}' property.`);
|
|
851
1115
|
}
|
|
852
|
-
function logPropDefinedButNoFindings(key, val) {
|
|
1116
|
+
function logPropDefinedButNoFindings(logger, key, val) {
|
|
853
1117
|
const prop = key === "level" ? "byLevel" : "bySeverity";
|
|
854
|
-
|
|
1118
|
+
logger.trace(`'${prop}.${val}' property is defined but no findings with "${val}" ${key} is found. Continue color identification...`);
|
|
855
1119
|
}
|
|
856
|
-
function logPropIsNotDefined(key, val) {
|
|
1120
|
+
function logPropIsNotDefined(logger, key, val) {
|
|
857
1121
|
const prop = key === "level" ? "byLevel" : "bySeverity";
|
|
858
|
-
|
|
1122
|
+
logger.trace(`'${prop}.${val}' property is not defined. Continue color identification...`);
|
|
859
1123
|
}
|
|
860
1124
|
function identifyColorCommon(findings, prop, none, unknown, color) {
|
|
1125
|
+
const logger = new Logger(identifyColorCommon.name);
|
|
861
1126
|
if (color.none) {
|
|
862
1127
|
if (findings.findByProperty(prop, none) != null) {
|
|
863
|
-
logColorTaken(color.none, `${prop === "severity" ? "bySeverity" : "byLevel"}.none`);
|
|
1128
|
+
logColorTaken(logger, color.none, `${prop === "severity" ? "bySeverity" : "byLevel"}.none`);
|
|
864
1129
|
return color.none.color;
|
|
865
1130
|
} else {
|
|
866
|
-
logPropDefinedButNoFindings(prop, "none");
|
|
1131
|
+
logPropDefinedButNoFindings(logger, prop, "none");
|
|
867
1132
|
}
|
|
868
1133
|
} else {
|
|
869
|
-
logPropIsNotDefined(prop, "none");
|
|
1134
|
+
logPropIsNotDefined(logger, prop, "none");
|
|
870
1135
|
}
|
|
871
1136
|
if (color.unknown) {
|
|
872
1137
|
if (findings.findByProperty(prop, unknown) != null) {
|
|
873
|
-
logColorTaken(color.unknown, `${prop === "severity" ? "bySeverity" : "byLevel"}.unknown`);
|
|
1138
|
+
logColorTaken(logger, color.unknown, `${prop === "severity" ? "bySeverity" : "byLevel"}.unknown`);
|
|
874
1139
|
return color.unknown.color;
|
|
875
1140
|
} else {
|
|
876
|
-
logPropDefinedButNoFindings(prop, "unknown");
|
|
1141
|
+
logPropDefinedButNoFindings(logger, prop, "unknown");
|
|
877
1142
|
}
|
|
878
1143
|
} else {
|
|
879
|
-
logPropIsNotDefined(prop, "unknown");
|
|
1144
|
+
logPropIsNotDefined(logger, prop, "unknown");
|
|
880
1145
|
}
|
|
881
1146
|
return void 0;
|
|
882
1147
|
}
|
|
883
1148
|
function identifyColorBySeverity(findings, color) {
|
|
1149
|
+
const logger = new Logger(identifyColorBySeverity.name);
|
|
884
1150
|
if (color.critical) {
|
|
885
1151
|
if (findings.findByProperty("severity", 5 /* Critical */) != null) {
|
|
886
|
-
logColorTaken(color.critical, "bySeverity.critical");
|
|
1152
|
+
logColorTaken(logger, color.critical, "bySeverity.critical");
|
|
887
1153
|
return color.critical.color;
|
|
888
1154
|
} else {
|
|
889
|
-
logPropDefinedButNoFindings("severity", "critical");
|
|
1155
|
+
logPropDefinedButNoFindings(logger, "severity", "critical");
|
|
890
1156
|
}
|
|
891
1157
|
} else {
|
|
892
|
-
logPropIsNotDefined("severity", "critical");
|
|
1158
|
+
logPropIsNotDefined(logger, "severity", "critical");
|
|
893
1159
|
}
|
|
894
1160
|
if (color.high) {
|
|
895
1161
|
if (findings.findByProperty("severity", 4 /* High */) != null) {
|
|
896
|
-
logColorTaken(color.high, "bySeverity.high");
|
|
1162
|
+
logColorTaken(logger, color.high, "bySeverity.high");
|
|
897
1163
|
return color.high.color;
|
|
898
1164
|
} else {
|
|
899
|
-
logPropDefinedButNoFindings("severity", "high");
|
|
1165
|
+
logPropDefinedButNoFindings(logger, "severity", "high");
|
|
900
1166
|
}
|
|
901
1167
|
} else {
|
|
902
|
-
logPropIsNotDefined("severity", "high");
|
|
1168
|
+
logPropIsNotDefined(logger, "severity", "high");
|
|
903
1169
|
}
|
|
904
1170
|
if (color.medium) {
|
|
905
1171
|
if (findings.findByProperty("severity", 3 /* Medium */) != null) {
|
|
906
|
-
logColorTaken(color.medium, "bySeverity.medium");
|
|
1172
|
+
logColorTaken(logger, color.medium, "bySeverity.medium");
|
|
907
1173
|
return color.medium.color;
|
|
908
1174
|
} else {
|
|
909
|
-
logPropDefinedButNoFindings("severity", "medium");
|
|
1175
|
+
logPropDefinedButNoFindings(logger, "severity", "medium");
|
|
910
1176
|
}
|
|
911
1177
|
} else {
|
|
912
|
-
logPropIsNotDefined("severity", "medium");
|
|
1178
|
+
logPropIsNotDefined(logger, "severity", "medium");
|
|
913
1179
|
}
|
|
914
1180
|
if (color.low) {
|
|
915
1181
|
if (findings.findByProperty("severity", 2 /* Low */) != null) {
|
|
916
|
-
logColorTaken(color.low, "bySeverity.low");
|
|
1182
|
+
logColorTaken(logger, color.low, "bySeverity.low");
|
|
917
1183
|
return color.low.color;
|
|
918
1184
|
} else {
|
|
919
|
-
logPropDefinedButNoFindings("severity", "low");
|
|
1185
|
+
logPropDefinedButNoFindings(logger, "severity", "low");
|
|
920
1186
|
}
|
|
921
1187
|
} else {
|
|
922
|
-
logPropIsNotDefined("severity", "low");
|
|
1188
|
+
logPropIsNotDefined(logger, "severity", "low");
|
|
923
1189
|
}
|
|
924
1190
|
return identifyColorCommon(findings, "severity", 1 /* None */, 0 /* Unknown */, color);
|
|
925
1191
|
}
|
|
926
1192
|
function identifyColorByLevel(findings, color) {
|
|
1193
|
+
const logger = new Logger(identifyColorByLevel.name);
|
|
927
1194
|
if (color.error) {
|
|
928
1195
|
if (findings.findByProperty("level", 4 /* Error */) != null) {
|
|
929
|
-
logColorTaken(color.error, "byLevel.error");
|
|
1196
|
+
logColorTaken(logger, color.error, "byLevel.error");
|
|
930
1197
|
return color.error.color;
|
|
931
1198
|
} else {
|
|
932
|
-
logPropDefinedButNoFindings("level", "error");
|
|
1199
|
+
logPropDefinedButNoFindings(logger, "level", "error");
|
|
933
1200
|
}
|
|
934
1201
|
} else {
|
|
935
|
-
logPropIsNotDefined("level", "error");
|
|
1202
|
+
logPropIsNotDefined(logger, "level", "error");
|
|
936
1203
|
}
|
|
937
1204
|
if (color.warning) {
|
|
938
1205
|
if (findings.findByProperty("level", 3 /* Warning */) != null) {
|
|
939
|
-
logColorTaken(color.warning, "byLevel.warning");
|
|
1206
|
+
logColorTaken(logger, color.warning, "byLevel.warning");
|
|
940
1207
|
return color.warning.color;
|
|
941
1208
|
} else {
|
|
942
|
-
logPropDefinedButNoFindings("level", "warning");
|
|
1209
|
+
logPropDefinedButNoFindings(logger, "level", "warning");
|
|
943
1210
|
}
|
|
944
1211
|
} else {
|
|
945
|
-
logPropIsNotDefined("level", "warning");
|
|
1212
|
+
logPropIsNotDefined(logger, "level", "warning");
|
|
946
1213
|
}
|
|
947
1214
|
if (color.note != null) {
|
|
948
1215
|
if (findings.findByProperty("level", 2 /* Note */) != null) {
|
|
949
|
-
logColorTaken(color.note, "byLevel.note");
|
|
1216
|
+
logColorTaken(logger, color.note, "byLevel.note");
|
|
950
1217
|
return color.note.color;
|
|
951
1218
|
} else {
|
|
952
|
-
logPropDefinedButNoFindings("level", "note");
|
|
1219
|
+
logPropDefinedButNoFindings(logger, "level", "note");
|
|
953
1220
|
}
|
|
954
1221
|
} else {
|
|
955
|
-
logPropIsNotDefined("level", "note");
|
|
1222
|
+
logPropIsNotDefined(logger, "level", "note");
|
|
956
1223
|
}
|
|
957
1224
|
return identifyColorCommon(findings, "level", 1 /* None */, 0 /* Unknown */, color);
|
|
958
1225
|
}
|
|
959
1226
|
function identifyColor(findings, colorOpts) {
|
|
1227
|
+
const logger = new Logger(identifyColor.name);
|
|
960
1228
|
if (!colorOpts) {
|
|
961
|
-
|
|
1229
|
+
logger.debug("Message has no color as color options are not defined.");
|
|
962
1230
|
return void 0;
|
|
963
1231
|
}
|
|
964
|
-
|
|
1232
|
+
logger.trace(`Identifying color for ${findings.length} findings and the following color options:`, JSON.stringify(colorOpts, null, 2));
|
|
965
1233
|
if (colorOpts.bySeverity) {
|
|
966
1234
|
const color = identifyColorBySeverity(findings, colorOpts.bySeverity);
|
|
967
1235
|
if (color) {
|
|
968
1236
|
return color;
|
|
969
1237
|
}
|
|
970
|
-
|
|
1238
|
+
logger.trace("None of the properties in 'bySeverity' group is applicable. Continue color identification...");
|
|
971
1239
|
} else {
|
|
972
|
-
|
|
1240
|
+
logger.trace("'bySeverity' group is not defined. Continue color identification...");
|
|
973
1241
|
}
|
|
974
1242
|
if (colorOpts.byLevel) {
|
|
975
1243
|
const color = identifyColorByLevel(findings, colorOpts.byLevel);
|
|
976
1244
|
if (color) {
|
|
977
1245
|
return color;
|
|
978
1246
|
}
|
|
979
|
-
|
|
1247
|
+
logger.trace("None of the properties in 'byLevel' group is applicable. Continue color identification...");
|
|
980
1248
|
} else {
|
|
981
|
-
|
|
1249
|
+
logger.trace("'byLevel' group is not defined. Continue color identification...");
|
|
982
1250
|
}
|
|
983
1251
|
if (findings.length === 0) {
|
|
984
|
-
|
|
1252
|
+
logger.trace('There are no findings in the provided SARIF file(s). Checking if color is defined in "empty" property...');
|
|
985
1253
|
if (colorOpts.empty?.color) {
|
|
986
|
-
logColorTaken(colorOpts.empty, "empty");
|
|
1254
|
+
logColorTaken(logger, colorOpts.empty, "empty");
|
|
987
1255
|
return colorOpts.empty.color;
|
|
988
1256
|
} else {
|
|
989
|
-
|
|
1257
|
+
logger.trace('"empty" color is not defined. Continue color identification...');
|
|
990
1258
|
}
|
|
991
1259
|
} else {
|
|
992
|
-
|
|
1260
|
+
logger.trace(`"empty" color is not taken into account because there are ${findings.length} findings in the provided SARIF file(s). Continue color identification...`);
|
|
993
1261
|
}
|
|
994
1262
|
if (colorOpts.default?.color) {
|
|
995
|
-
logColorTaken(colorOpts.default, "default");
|
|
1263
|
+
logColorTaken(logger, colorOpts.default, "default");
|
|
996
1264
|
} else {
|
|
997
|
-
|
|
1265
|
+
logger.debug("Message has no color as none of the defined color options is applicable.");
|
|
998
1266
|
}
|
|
999
1267
|
return colorOpts?.default?.color;
|
|
1000
1268
|
}
|
|
1001
1269
|
|
|
1270
|
+
// src/model/SlackMessage.ts
|
|
1271
|
+
var import_webhook = require("@slack/webhook");
|
|
1272
|
+
function createSlackMessage(url, opts) {
|
|
1273
|
+
return new SlackMessageImpl(url, opts);
|
|
1274
|
+
}
|
|
1275
|
+
var SlackMessageImpl = class {
|
|
1276
|
+
_webhook;
|
|
1277
|
+
_gitHubServerUrl;
|
|
1278
|
+
_color;
|
|
1279
|
+
_representation;
|
|
1280
|
+
_header;
|
|
1281
|
+
_footer;
|
|
1282
|
+
_actor;
|
|
1283
|
+
_runId;
|
|
1284
|
+
constructor(url, opts) {
|
|
1285
|
+
this._webhook = new import_webhook.IncomingWebhook(url, {
|
|
1286
|
+
username: opts.username || "SARIF results",
|
|
1287
|
+
icon_url: opts.iconUrl
|
|
1288
|
+
});
|
|
1289
|
+
this._gitHubServerUrl = process.env.GITHUB_SERVER_URL || "https://github.com";
|
|
1290
|
+
this._color = opts.color;
|
|
1291
|
+
this._representation = opts.representation;
|
|
1292
|
+
}
|
|
1293
|
+
withHeader(header) {
|
|
1294
|
+
this._header = {
|
|
1295
|
+
type: "header",
|
|
1296
|
+
text: {
|
|
1297
|
+
type: "plain_text",
|
|
1298
|
+
text: header || process.env.GITHUB_REPOSITORY || "SARIF results"
|
|
1299
|
+
}
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1302
|
+
withActor(actor) {
|
|
1303
|
+
this._actor = actor || process.env.GITHUB_ACTOR;
|
|
1304
|
+
}
|
|
1305
|
+
withRun() {
|
|
1306
|
+
this._runId = process.env.GITHUB_RUN_ID;
|
|
1307
|
+
}
|
|
1308
|
+
withFooter(text, type) {
|
|
1309
|
+
const repoName = "fabasoad/sarif-to-slack";
|
|
1310
|
+
const element = text ? { type: type || "plain_text" /* PlainText */, text } : { type: "mrkdwn" /* Markdown */, text: `Generated by <${this._gitHubServerUrl}/${repoName}|@${repoName}@${version}>` };
|
|
1311
|
+
this._footer = {
|
|
1312
|
+
type: "context",
|
|
1313
|
+
elements: [element]
|
|
1314
|
+
};
|
|
1315
|
+
}
|
|
1316
|
+
async send() {
|
|
1317
|
+
const blocks = [];
|
|
1318
|
+
if (this._header) {
|
|
1319
|
+
blocks.push(this._header);
|
|
1320
|
+
}
|
|
1321
|
+
blocks.push({
|
|
1322
|
+
type: "section",
|
|
1323
|
+
text: {
|
|
1324
|
+
type: "mrkdwn",
|
|
1325
|
+
text: this.buildText()
|
|
1326
|
+
}
|
|
1327
|
+
});
|
|
1328
|
+
if (this._footer) {
|
|
1329
|
+
blocks.push(this._footer);
|
|
1330
|
+
}
|
|
1331
|
+
const { text } = await this._webhook.send({
|
|
1332
|
+
attachments: [{ color: this._color, blocks }]
|
|
1333
|
+
});
|
|
1334
|
+
return text;
|
|
1335
|
+
}
|
|
1336
|
+
buildText() {
|
|
1337
|
+
const text = [];
|
|
1338
|
+
if (this._actor) {
|
|
1339
|
+
const actorUrl = `${this._gitHubServerUrl}/${this._actor}`;
|
|
1340
|
+
text.push(`_Triggered by <${actorUrl}|${this._actor}>_`);
|
|
1341
|
+
}
|
|
1342
|
+
text.push(this._representation.compose());
|
|
1343
|
+
if (this._runId) {
|
|
1344
|
+
let runText = "Job ";
|
|
1345
|
+
if (process.env.GITHUB_REPOSITORY) {
|
|
1346
|
+
runText += `<${this._gitHubServerUrl}/${process.env.GITHUB_REPOSITORY}/actions/runs/${this._runId}|#${this._runId}>`;
|
|
1347
|
+
} else {
|
|
1348
|
+
runText += `#${this._runId}`;
|
|
1349
|
+
}
|
|
1350
|
+
text.push(runText);
|
|
1351
|
+
}
|
|
1352
|
+
return text.join("\n\n");
|
|
1353
|
+
}
|
|
1354
|
+
};
|
|
1355
|
+
|
|
1002
1356
|
// src/SarifToSlackClient.ts
|
|
1003
1357
|
var SarifToSlackClient = class _SarifToSlackClient {
|
|
1358
|
+
_logger = new Logger("SarifToSlackClient");
|
|
1004
1359
|
_message;
|
|
1005
1360
|
_sarifModel;
|
|
1006
1361
|
_sendIf = 20 /* Always */;
|
|
1007
|
-
constructor(
|
|
1008
|
-
|
|
1009
|
-
System.initialize();
|
|
1362
|
+
constructor() {
|
|
1363
|
+
logMetadata();
|
|
1010
1364
|
}
|
|
1011
1365
|
static *createRunIdGenerator() {
|
|
1012
1366
|
let runId = 1;
|
|
@@ -1014,11 +1368,22 @@ var SarifToSlackClient = class _SarifToSlackClient {
|
|
|
1014
1368
|
yield runId++;
|
|
1015
1369
|
}
|
|
1016
1370
|
}
|
|
1017
|
-
|
|
1018
|
-
|
|
1371
|
+
/**
|
|
1372
|
+
* Creates an instance of {@link SarifToSlackClient} class. It already has all
|
|
1373
|
+
* properties and fields initialized.
|
|
1374
|
+
* @param webhookUrl - Slack webhook URL.
|
|
1375
|
+
* @param opts - An instance of {@link SarifToSlackClientOptions} type.
|
|
1376
|
+
*
|
|
1377
|
+
* @see SarifToSlackClientOptions
|
|
1378
|
+
*
|
|
1379
|
+
* @public
|
|
1380
|
+
*/
|
|
1381
|
+
static async create(webhookUrl, opts) {
|
|
1382
|
+
const instance = new _SarifToSlackClient();
|
|
1383
|
+
instance._logger.trace(opts);
|
|
1019
1384
|
instance._sendIf = opts.sendIf ?? instance._sendIf;
|
|
1020
1385
|
instance._sarifModel = await _SarifToSlackClient.buildModel(opts.sarif);
|
|
1021
|
-
instance._message = await _SarifToSlackClient.initialize(instance._sarifModel
|
|
1386
|
+
instance._message = await _SarifToSlackClient.initialize(webhookUrl, opts, instance._sarifModel);
|
|
1022
1387
|
return instance;
|
|
1023
1388
|
}
|
|
1024
1389
|
static async buildModel(sarifOpts) {
|
|
@@ -1029,11 +1394,11 @@ var SarifToSlackClient = class _SarifToSlackClient {
|
|
|
1029
1394
|
const model = { sarifFiles, runs: [], findings: new FindingArray() };
|
|
1030
1395
|
const runIdGenerator = _SarifToSlackClient.createRunIdGenerator();
|
|
1031
1396
|
for (const sarifPath of sarifFiles) {
|
|
1032
|
-
const sarifJson = await
|
|
1397
|
+
const sarifJson = await import_node_fs2.promises.readFile(sarifPath, "utf8");
|
|
1033
1398
|
const sarifLog = JSON.parse(sarifJson);
|
|
1034
1399
|
for (const run of sarifLog.runs) {
|
|
1035
1400
|
const runId = runIdGenerator.next();
|
|
1036
|
-
let runMetadata
|
|
1401
|
+
let runMetadata;
|
|
1037
1402
|
for (const result of run.results ?? []) {
|
|
1038
1403
|
runMetadata = {
|
|
1039
1404
|
id: runId.value,
|
|
@@ -1055,13 +1420,15 @@ var SarifToSlackClient = class _SarifToSlackClient {
|
|
|
1055
1420
|
/**
|
|
1056
1421
|
* The main function to initialize a list of {@link SlackMessage} objects based
|
|
1057
1422
|
* on the given SARIF file(s).
|
|
1058
|
-
* @param
|
|
1423
|
+
* @param webhookUrl - Slack webhook URL.
|
|
1059
1424
|
* @param opts - An instance of {@link SarifToSlackClientOptions} object.
|
|
1425
|
+
* @param sarifModel - An instance of SarifModel object.
|
|
1060
1426
|
* @returns A map where key is the SARIF file and value is an instance of
|
|
1061
1427
|
* {@link SlackMessage} object.
|
|
1428
|
+
* @internal
|
|
1062
1429
|
*/
|
|
1063
|
-
static async initialize(
|
|
1064
|
-
const message = createSlackMessage(
|
|
1430
|
+
static async initialize(webhookUrl, opts, sarifModel) {
|
|
1431
|
+
const message = createSlackMessage(webhookUrl, {
|
|
1065
1432
|
username: opts.username,
|
|
1066
1433
|
iconUrl: opts.iconUrl,
|
|
1067
1434
|
color: identifyColor(sarifModel.findings, opts.color),
|
|
@@ -1096,9 +1463,9 @@ var SarifToSlackClient = class _SarifToSlackClient {
|
|
|
1096
1463
|
throw new Error("Slack message was not prepared.");
|
|
1097
1464
|
}
|
|
1098
1465
|
const text = await this._message.send();
|
|
1099
|
-
|
|
1466
|
+
this._logger.info("Message sent. Status:", text);
|
|
1100
1467
|
} else {
|
|
1101
|
-
|
|
1468
|
+
this._logger.info(sendIfLogMessage(this._sendIf));
|
|
1102
1469
|
}
|
|
1103
1470
|
}
|
|
1104
1471
|
get shouldSendMessage() {
|
|
@@ -1163,7 +1530,6 @@ var SarifToSlackClient = class _SarifToSlackClient {
|
|
|
1163
1530
|
0 && (module.exports = {
|
|
1164
1531
|
Color,
|
|
1165
1532
|
FooterType,
|
|
1166
|
-
LogLevel,
|
|
1167
1533
|
RepresentationType,
|
|
1168
1534
|
SarifToSlackClient,
|
|
1169
1535
|
SendIf
|