@fabasoad/sarif-to-slack 1.3.0 → 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 +612 -244
- 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 +23 -21
- 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 +11 -11
- 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 +30 -27
- 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,176 +291,64 @@ var SecurityLevel = /* @__PURE__ */ ((SecurityLevel2) => {
|
|
|
212
291
|
SecurityLevel2[SecurityLevel2["Error"] = 4] = "Error";
|
|
213
292
|
return SecurityLevel2;
|
|
214
293
|
})(SecurityLevel || {});
|
|
294
|
+
var SecurityLevelValues = Object.values(SecurityLevel).filter(
|
|
295
|
+
(v) => typeof v === "string"
|
|
296
|
+
);
|
|
215
297
|
|
|
216
|
-
// src/
|
|
217
|
-
var
|
|
218
|
-
var
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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()
|
|
298
|
+
// src/utils/FileUtils.ts
|
|
299
|
+
var import_node_fs = __toESM(require("fs"));
|
|
300
|
+
var path = __toESM(require("path"));
|
|
301
|
+
function listFiles(dir, recursive, extension, fileList = []) {
|
|
302
|
+
if (import_node_fs.default.statSync(dir).isDirectory()) {
|
|
303
|
+
const entries = import_node_fs.default.readdirSync(dir);
|
|
304
|
+
entries.forEach((entry) => {
|
|
305
|
+
const fullPath = path.join(dir, entry);
|
|
306
|
+
if (recursive && import_node_fs.default.statSync(fullPath).isDirectory()) {
|
|
307
|
+
listFiles(fullPath, recursive, extension, fileList);
|
|
308
|
+
} else if (path.extname(fullPath).toLowerCase() === `.${extension}`) {
|
|
309
|
+
fileList.push(fullPath);
|
|
276
310
|
}
|
|
277
311
|
});
|
|
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
312
|
}
|
|
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
|
-
};
|
|
350
|
-
|
|
351
|
-
// src/utils/FileUtils.ts
|
|
352
|
-
var import_fs = __toESM(require("fs"));
|
|
353
|
-
var path = __toESM(require("path"));
|
|
354
|
-
function listFilesRecursively(dir, extension, fileList = []) {
|
|
355
|
-
const entries = import_fs.default.readdirSync(dir);
|
|
356
|
-
entries.forEach((entry) => {
|
|
357
|
-
const fullPath = path.join(dir, entry);
|
|
358
|
-
if (import_fs.default.statSync(fullPath).isDirectory()) {
|
|
359
|
-
listFilesRecursively(fullPath, extension, fileList);
|
|
360
|
-
} else if (path.extname(fullPath).toLowerCase() === `.${extension}`) {
|
|
361
|
-
fileList.push(fullPath);
|
|
362
|
-
}
|
|
363
|
-
});
|
|
364
313
|
return fileList;
|
|
365
314
|
}
|
|
366
315
|
function extractListOfFiles(opts) {
|
|
367
|
-
|
|
316
|
+
const logger = new Logger(extractListOfFiles.name);
|
|
317
|
+
if (!import_node_fs.default.existsSync(opts.path)) {
|
|
368
318
|
throw new Error(`Provided path does not exist: ${opts.path}`);
|
|
369
319
|
}
|
|
370
|
-
const stats =
|
|
320
|
+
const stats = import_node_fs.default.statSync(opts.path);
|
|
371
321
|
if (stats.isDirectory()) {
|
|
372
|
-
|
|
373
|
-
const files = opts.
|
|
374
|
-
|
|
375
|
-
|
|
322
|
+
logger.info(`Provided path is a directory: ${opts.path}`);
|
|
323
|
+
const files = listFiles(opts.path, !!opts.recursive, opts.extension ?? "sarif");
|
|
324
|
+
logger.info(`Found ${files.length} files in ${opts.path} directory with ${opts.extension} extension`);
|
|
325
|
+
logger.debug(`Found files: ${files.join(", ")}`);
|
|
376
326
|
return files;
|
|
377
327
|
}
|
|
378
328
|
if (stats.isFile()) {
|
|
379
|
-
|
|
329
|
+
logger.info(`Provided path is a file: ${opts.path}`);
|
|
380
330
|
return [opts.path];
|
|
381
331
|
}
|
|
382
332
|
throw new Error(`Provided path is neither a file nor a directory: ${opts.path}`);
|
|
383
333
|
}
|
|
384
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
|
+
|
|
385
352
|
// src/utils/Comparators.ts
|
|
386
353
|
function findingsComparatorByKey(key) {
|
|
387
354
|
return (a, b) => {
|
|
@@ -400,23 +367,6 @@ function findingsComparatorByKey(key) {
|
|
|
400
367
|
};
|
|
401
368
|
}
|
|
402
369
|
|
|
403
|
-
// src/utils/ExtendedArray.ts
|
|
404
|
-
var ExtendedArray = class extends Array {
|
|
405
|
-
findByProperty(prop, value) {
|
|
406
|
-
return this.find((v) => v[prop] === value);
|
|
407
|
-
}
|
|
408
|
-
};
|
|
409
|
-
|
|
410
|
-
// src/model/FindingArray.ts
|
|
411
|
-
var FindingArray = class extends ExtendedArray {
|
|
412
|
-
hasSeverityOrHigher(severity) {
|
|
413
|
-
return Object.values(SecuritySeverity).filter((v) => typeof v === "number").filter((v) => v >= severity).some((v) => this.findByProperty("severity", v) != null);
|
|
414
|
-
}
|
|
415
|
-
hasLevelOrHigher(level) {
|
|
416
|
-
return Object.values(SecurityLevel).filter((v) => typeof v === "number").filter((v) => v >= level).some((v) => this.findByProperty("level", v) != null);
|
|
417
|
-
}
|
|
418
|
-
};
|
|
419
|
-
|
|
420
370
|
// src/representations/Representation.ts
|
|
421
371
|
var Representation = class {
|
|
422
372
|
_model;
|
|
@@ -433,6 +383,9 @@ var Representation = class {
|
|
|
433
383
|
italic(text) {
|
|
434
384
|
return `_${text}_`;
|
|
435
385
|
}
|
|
386
|
+
codeBlock(text) {
|
|
387
|
+
return "```\n" + text + "\n```";
|
|
388
|
+
}
|
|
436
389
|
};
|
|
437
390
|
|
|
438
391
|
// src/representations/CompactGroupByRepresentation.ts
|
|
@@ -454,7 +407,7 @@ ${summary}`;
|
|
|
454
407
|
const result = [];
|
|
455
408
|
findings.reduce((grouped, f) => {
|
|
456
409
|
if (!grouped.get(f[key])) {
|
|
457
|
-
grouped.set(f[key],
|
|
410
|
+
grouped.set(f[key], []);
|
|
458
411
|
}
|
|
459
412
|
grouped.get(f[key])?.push(f);
|
|
460
413
|
return grouped;
|
|
@@ -606,6 +559,306 @@ var CompactTotalPerLevelRepresentation = class extends CompactTotalRepresentatio
|
|
|
606
559
|
}
|
|
607
560
|
};
|
|
608
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
|
+
|
|
609
862
|
// src/representations/RepresentationFactory.ts
|
|
610
863
|
function createRepresentation(model, type = 3 /* CompactGroupByToolNamePerSeverity */) {
|
|
611
864
|
switch (type) {
|
|
@@ -625,6 +878,18 @@ function createRepresentation(model, type = 3 /* CompactGroupByToolNamePerSeveri
|
|
|
625
878
|
return new CompactTotalPerLevelRepresentation(model);
|
|
626
879
|
case 7 /* CompactTotalPerSeverity */:
|
|
627
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);
|
|
628
893
|
default:
|
|
629
894
|
throw new Error(`Unknown representation type: ${type}`);
|
|
630
895
|
}
|
|
@@ -763,6 +1028,7 @@ function createFinding(opts) {
|
|
|
763
1028
|
return new FindingImpl(opts);
|
|
764
1029
|
}
|
|
765
1030
|
var FindingImpl = class {
|
|
1031
|
+
_logger = new Logger("FindingImpl");
|
|
766
1032
|
_runMetadata;
|
|
767
1033
|
_result;
|
|
768
1034
|
_sarifPath;
|
|
@@ -808,7 +1074,7 @@ var FindingImpl = class {
|
|
|
808
1074
|
this._levelCache = this._processor.tryFindLevel();
|
|
809
1075
|
}
|
|
810
1076
|
if (this._levelCache === void 0) {
|
|
811
|
-
|
|
1077
|
+
this._logger.debug(`Unknown level of ${this._rule?.id} rule`);
|
|
812
1078
|
return 0 /* Unknown */;
|
|
813
1079
|
}
|
|
814
1080
|
switch (this._levelCache) {
|
|
@@ -824,7 +1090,7 @@ var FindingImpl = class {
|
|
|
824
1090
|
}
|
|
825
1091
|
get severity() {
|
|
826
1092
|
if (this.cvssScore == null || this.cvssScore < 0 || this.cvssScore > 10) {
|
|
827
|
-
|
|
1093
|
+
this._logger.debug(`Unsupported CVSS score ${this.cvssScore} in ${this._rule?.id} rule`);
|
|
828
1094
|
return 0 /* Unknown */;
|
|
829
1095
|
}
|
|
830
1096
|
if (this.cvssScore >= 9) {
|
|
@@ -844,167 +1110,257 @@ var FindingImpl = class {
|
|
|
844
1110
|
};
|
|
845
1111
|
|
|
846
1112
|
// src/model/color/ColorIdentification.ts
|
|
847
|
-
function logColorTaken(color, prop) {
|
|
848
|
-
|
|
1113
|
+
function logColorTaken(logger, color, prop) {
|
|
1114
|
+
logger.debug(`Message has ${color?.color} color taken from '${prop}' property.`);
|
|
849
1115
|
}
|
|
850
|
-
function logPropDefinedButNoFindings(key, val) {
|
|
1116
|
+
function logPropDefinedButNoFindings(logger, key, val) {
|
|
851
1117
|
const prop = key === "level" ? "byLevel" : "bySeverity";
|
|
852
|
-
|
|
1118
|
+
logger.trace(`'${prop}.${val}' property is defined but no findings with "${val}" ${key} is found. Continue color identification...`);
|
|
853
1119
|
}
|
|
854
|
-
function logPropIsNotDefined(key, val) {
|
|
1120
|
+
function logPropIsNotDefined(logger, key, val) {
|
|
855
1121
|
const prop = key === "level" ? "byLevel" : "bySeverity";
|
|
856
|
-
|
|
1122
|
+
logger.trace(`'${prop}.${val}' property is not defined. Continue color identification...`);
|
|
857
1123
|
}
|
|
858
1124
|
function identifyColorCommon(findings, prop, none, unknown, color) {
|
|
1125
|
+
const logger = new Logger(identifyColorCommon.name);
|
|
859
1126
|
if (color.none) {
|
|
860
1127
|
if (findings.findByProperty(prop, none) != null) {
|
|
861
|
-
logColorTaken(color.none, `${prop === "severity" ? "bySeverity" : "byLevel"}.none`);
|
|
1128
|
+
logColorTaken(logger, color.none, `${prop === "severity" ? "bySeverity" : "byLevel"}.none`);
|
|
862
1129
|
return color.none.color;
|
|
863
1130
|
} else {
|
|
864
|
-
logPropDefinedButNoFindings(prop, "none");
|
|
1131
|
+
logPropDefinedButNoFindings(logger, prop, "none");
|
|
865
1132
|
}
|
|
866
1133
|
} else {
|
|
867
|
-
logPropIsNotDefined(prop, "none");
|
|
1134
|
+
logPropIsNotDefined(logger, prop, "none");
|
|
868
1135
|
}
|
|
869
1136
|
if (color.unknown) {
|
|
870
1137
|
if (findings.findByProperty(prop, unknown) != null) {
|
|
871
|
-
logColorTaken(color.unknown, `${prop === "severity" ? "bySeverity" : "byLevel"}.unknown`);
|
|
1138
|
+
logColorTaken(logger, color.unknown, `${prop === "severity" ? "bySeverity" : "byLevel"}.unknown`);
|
|
872
1139
|
return color.unknown.color;
|
|
873
1140
|
} else {
|
|
874
|
-
logPropDefinedButNoFindings(prop, "unknown");
|
|
1141
|
+
logPropDefinedButNoFindings(logger, prop, "unknown");
|
|
875
1142
|
}
|
|
876
1143
|
} else {
|
|
877
|
-
logPropIsNotDefined(prop, "unknown");
|
|
1144
|
+
logPropIsNotDefined(logger, prop, "unknown");
|
|
878
1145
|
}
|
|
879
1146
|
return void 0;
|
|
880
1147
|
}
|
|
881
1148
|
function identifyColorBySeverity(findings, color) {
|
|
1149
|
+
const logger = new Logger(identifyColorBySeverity.name);
|
|
882
1150
|
if (color.critical) {
|
|
883
1151
|
if (findings.findByProperty("severity", 5 /* Critical */) != null) {
|
|
884
|
-
logColorTaken(color.critical, "bySeverity.critical");
|
|
1152
|
+
logColorTaken(logger, color.critical, "bySeverity.critical");
|
|
885
1153
|
return color.critical.color;
|
|
886
1154
|
} else {
|
|
887
|
-
logPropDefinedButNoFindings("severity", "critical");
|
|
1155
|
+
logPropDefinedButNoFindings(logger, "severity", "critical");
|
|
888
1156
|
}
|
|
889
1157
|
} else {
|
|
890
|
-
logPropIsNotDefined("severity", "critical");
|
|
1158
|
+
logPropIsNotDefined(logger, "severity", "critical");
|
|
891
1159
|
}
|
|
892
1160
|
if (color.high) {
|
|
893
1161
|
if (findings.findByProperty("severity", 4 /* High */) != null) {
|
|
894
|
-
logColorTaken(color.high, "bySeverity.high");
|
|
1162
|
+
logColorTaken(logger, color.high, "bySeverity.high");
|
|
895
1163
|
return color.high.color;
|
|
896
1164
|
} else {
|
|
897
|
-
logPropDefinedButNoFindings("severity", "high");
|
|
1165
|
+
logPropDefinedButNoFindings(logger, "severity", "high");
|
|
898
1166
|
}
|
|
899
1167
|
} else {
|
|
900
|
-
logPropIsNotDefined("severity", "high");
|
|
1168
|
+
logPropIsNotDefined(logger, "severity", "high");
|
|
901
1169
|
}
|
|
902
1170
|
if (color.medium) {
|
|
903
1171
|
if (findings.findByProperty("severity", 3 /* Medium */) != null) {
|
|
904
|
-
logColorTaken(color.medium, "bySeverity.medium");
|
|
1172
|
+
logColorTaken(logger, color.medium, "bySeverity.medium");
|
|
905
1173
|
return color.medium.color;
|
|
906
1174
|
} else {
|
|
907
|
-
logPropDefinedButNoFindings("severity", "medium");
|
|
1175
|
+
logPropDefinedButNoFindings(logger, "severity", "medium");
|
|
908
1176
|
}
|
|
909
1177
|
} else {
|
|
910
|
-
logPropIsNotDefined("severity", "medium");
|
|
1178
|
+
logPropIsNotDefined(logger, "severity", "medium");
|
|
911
1179
|
}
|
|
912
1180
|
if (color.low) {
|
|
913
1181
|
if (findings.findByProperty("severity", 2 /* Low */) != null) {
|
|
914
|
-
logColorTaken(color.low, "bySeverity.low");
|
|
1182
|
+
logColorTaken(logger, color.low, "bySeverity.low");
|
|
915
1183
|
return color.low.color;
|
|
916
1184
|
} else {
|
|
917
|
-
logPropDefinedButNoFindings("severity", "low");
|
|
1185
|
+
logPropDefinedButNoFindings(logger, "severity", "low");
|
|
918
1186
|
}
|
|
919
1187
|
} else {
|
|
920
|
-
logPropIsNotDefined("severity", "low");
|
|
1188
|
+
logPropIsNotDefined(logger, "severity", "low");
|
|
921
1189
|
}
|
|
922
1190
|
return identifyColorCommon(findings, "severity", 1 /* None */, 0 /* Unknown */, color);
|
|
923
1191
|
}
|
|
924
1192
|
function identifyColorByLevel(findings, color) {
|
|
1193
|
+
const logger = new Logger(identifyColorByLevel.name);
|
|
925
1194
|
if (color.error) {
|
|
926
1195
|
if (findings.findByProperty("level", 4 /* Error */) != null) {
|
|
927
|
-
logColorTaken(color.error, "byLevel.error");
|
|
1196
|
+
logColorTaken(logger, color.error, "byLevel.error");
|
|
928
1197
|
return color.error.color;
|
|
929
1198
|
} else {
|
|
930
|
-
logPropDefinedButNoFindings("level", "error");
|
|
1199
|
+
logPropDefinedButNoFindings(logger, "level", "error");
|
|
931
1200
|
}
|
|
932
1201
|
} else {
|
|
933
|
-
logPropIsNotDefined("level", "error");
|
|
1202
|
+
logPropIsNotDefined(logger, "level", "error");
|
|
934
1203
|
}
|
|
935
1204
|
if (color.warning) {
|
|
936
1205
|
if (findings.findByProperty("level", 3 /* Warning */) != null) {
|
|
937
|
-
logColorTaken(color.warning, "byLevel.warning");
|
|
1206
|
+
logColorTaken(logger, color.warning, "byLevel.warning");
|
|
938
1207
|
return color.warning.color;
|
|
939
1208
|
} else {
|
|
940
|
-
logPropDefinedButNoFindings("level", "warning");
|
|
1209
|
+
logPropDefinedButNoFindings(logger, "level", "warning");
|
|
941
1210
|
}
|
|
942
1211
|
} else {
|
|
943
|
-
logPropIsNotDefined("level", "warning");
|
|
1212
|
+
logPropIsNotDefined(logger, "level", "warning");
|
|
944
1213
|
}
|
|
945
1214
|
if (color.note != null) {
|
|
946
1215
|
if (findings.findByProperty("level", 2 /* Note */) != null) {
|
|
947
|
-
logColorTaken(color.note, "byLevel.note");
|
|
1216
|
+
logColorTaken(logger, color.note, "byLevel.note");
|
|
948
1217
|
return color.note.color;
|
|
949
1218
|
} else {
|
|
950
|
-
logPropDefinedButNoFindings("level", "note");
|
|
1219
|
+
logPropDefinedButNoFindings(logger, "level", "note");
|
|
951
1220
|
}
|
|
952
1221
|
} else {
|
|
953
|
-
logPropIsNotDefined("level", "note");
|
|
1222
|
+
logPropIsNotDefined(logger, "level", "note");
|
|
954
1223
|
}
|
|
955
1224
|
return identifyColorCommon(findings, "level", 1 /* None */, 0 /* Unknown */, color);
|
|
956
1225
|
}
|
|
957
1226
|
function identifyColor(findings, colorOpts) {
|
|
1227
|
+
const logger = new Logger(identifyColor.name);
|
|
958
1228
|
if (!colorOpts) {
|
|
959
|
-
|
|
1229
|
+
logger.debug("Message has no color as color options are not defined.");
|
|
960
1230
|
return void 0;
|
|
961
1231
|
}
|
|
962
|
-
|
|
1232
|
+
logger.trace(`Identifying color for ${findings.length} findings and the following color options:`, JSON.stringify(colorOpts, null, 2));
|
|
963
1233
|
if (colorOpts.bySeverity) {
|
|
964
1234
|
const color = identifyColorBySeverity(findings, colorOpts.bySeverity);
|
|
965
1235
|
if (color) {
|
|
966
1236
|
return color;
|
|
967
1237
|
}
|
|
968
|
-
|
|
1238
|
+
logger.trace("None of the properties in 'bySeverity' group is applicable. Continue color identification...");
|
|
969
1239
|
} else {
|
|
970
|
-
|
|
1240
|
+
logger.trace("'bySeverity' group is not defined. Continue color identification...");
|
|
971
1241
|
}
|
|
972
1242
|
if (colorOpts.byLevel) {
|
|
973
1243
|
const color = identifyColorByLevel(findings, colorOpts.byLevel);
|
|
974
1244
|
if (color) {
|
|
975
1245
|
return color;
|
|
976
1246
|
}
|
|
977
|
-
|
|
1247
|
+
logger.trace("None of the properties in 'byLevel' group is applicable. Continue color identification...");
|
|
978
1248
|
} else {
|
|
979
|
-
|
|
1249
|
+
logger.trace("'byLevel' group is not defined. Continue color identification...");
|
|
980
1250
|
}
|
|
981
1251
|
if (findings.length === 0) {
|
|
982
|
-
|
|
1252
|
+
logger.trace('There are no findings in the provided SARIF file(s). Checking if color is defined in "empty" property...');
|
|
983
1253
|
if (colorOpts.empty?.color) {
|
|
984
|
-
logColorTaken(colorOpts.empty, "empty");
|
|
1254
|
+
logColorTaken(logger, colorOpts.empty, "empty");
|
|
985
1255
|
return colorOpts.empty.color;
|
|
986
1256
|
} else {
|
|
987
|
-
|
|
1257
|
+
logger.trace('"empty" color is not defined. Continue color identification...');
|
|
988
1258
|
}
|
|
989
1259
|
} else {
|
|
990
|
-
|
|
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...`);
|
|
991
1261
|
}
|
|
992
1262
|
if (colorOpts.default?.color) {
|
|
993
|
-
logColorTaken(colorOpts.default, "default");
|
|
1263
|
+
logColorTaken(logger, colorOpts.default, "default");
|
|
994
1264
|
} else {
|
|
995
|
-
|
|
1265
|
+
logger.debug("Message has no color as none of the defined color options is applicable.");
|
|
996
1266
|
}
|
|
997
1267
|
return colorOpts?.default?.color;
|
|
998
1268
|
}
|
|
999
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
|
+
|
|
1000
1356
|
// src/SarifToSlackClient.ts
|
|
1001
1357
|
var SarifToSlackClient = class _SarifToSlackClient {
|
|
1358
|
+
_logger = new Logger("SarifToSlackClient");
|
|
1002
1359
|
_message;
|
|
1003
1360
|
_sarifModel;
|
|
1004
1361
|
_sendIf = 20 /* Always */;
|
|
1005
|
-
constructor(
|
|
1006
|
-
|
|
1007
|
-
System.initialize();
|
|
1362
|
+
constructor() {
|
|
1363
|
+
logMetadata();
|
|
1008
1364
|
}
|
|
1009
1365
|
static *createRunIdGenerator() {
|
|
1010
1366
|
let runId = 1;
|
|
@@ -1012,11 +1368,22 @@ var SarifToSlackClient = class _SarifToSlackClient {
|
|
|
1012
1368
|
yield runId++;
|
|
1013
1369
|
}
|
|
1014
1370
|
}
|
|
1015
|
-
|
|
1016
|
-
|
|
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);
|
|
1017
1384
|
instance._sendIf = opts.sendIf ?? instance._sendIf;
|
|
1018
1385
|
instance._sarifModel = await _SarifToSlackClient.buildModel(opts.sarif);
|
|
1019
|
-
instance._message = await _SarifToSlackClient.initialize(instance._sarifModel
|
|
1386
|
+
instance._message = await _SarifToSlackClient.initialize(webhookUrl, opts, instance._sarifModel);
|
|
1020
1387
|
return instance;
|
|
1021
1388
|
}
|
|
1022
1389
|
static async buildModel(sarifOpts) {
|
|
@@ -1027,11 +1394,11 @@ var SarifToSlackClient = class _SarifToSlackClient {
|
|
|
1027
1394
|
const model = { sarifFiles, runs: [], findings: new FindingArray() };
|
|
1028
1395
|
const runIdGenerator = _SarifToSlackClient.createRunIdGenerator();
|
|
1029
1396
|
for (const sarifPath of sarifFiles) {
|
|
1030
|
-
const sarifJson = await
|
|
1397
|
+
const sarifJson = await import_node_fs2.promises.readFile(sarifPath, "utf8");
|
|
1031
1398
|
const sarifLog = JSON.parse(sarifJson);
|
|
1032
1399
|
for (const run of sarifLog.runs) {
|
|
1033
1400
|
const runId = runIdGenerator.next();
|
|
1034
|
-
let runMetadata
|
|
1401
|
+
let runMetadata;
|
|
1035
1402
|
for (const result of run.results ?? []) {
|
|
1036
1403
|
runMetadata = {
|
|
1037
1404
|
id: runId.value,
|
|
@@ -1053,13 +1420,15 @@ var SarifToSlackClient = class _SarifToSlackClient {
|
|
|
1053
1420
|
/**
|
|
1054
1421
|
* The main function to initialize a list of {@link SlackMessage} objects based
|
|
1055
1422
|
* on the given SARIF file(s).
|
|
1056
|
-
* @param
|
|
1423
|
+
* @param webhookUrl - Slack webhook URL.
|
|
1057
1424
|
* @param opts - An instance of {@link SarifToSlackClientOptions} object.
|
|
1425
|
+
* @param sarifModel - An instance of SarifModel object.
|
|
1058
1426
|
* @returns A map where key is the SARIF file and value is an instance of
|
|
1059
1427
|
* {@link SlackMessage} object.
|
|
1428
|
+
* @internal
|
|
1060
1429
|
*/
|
|
1061
|
-
static async initialize(
|
|
1062
|
-
const message = createSlackMessage(
|
|
1430
|
+
static async initialize(webhookUrl, opts, sarifModel) {
|
|
1431
|
+
const message = createSlackMessage(webhookUrl, {
|
|
1063
1432
|
username: opts.username,
|
|
1064
1433
|
iconUrl: opts.iconUrl,
|
|
1065
1434
|
color: identifyColor(sarifModel.findings, opts.color),
|
|
@@ -1094,9 +1463,9 @@ var SarifToSlackClient = class _SarifToSlackClient {
|
|
|
1094
1463
|
throw new Error("Slack message was not prepared.");
|
|
1095
1464
|
}
|
|
1096
1465
|
const text = await this._message.send();
|
|
1097
|
-
|
|
1466
|
+
this._logger.info("Message sent. Status:", text);
|
|
1098
1467
|
} else {
|
|
1099
|
-
|
|
1468
|
+
this._logger.info(sendIfLogMessage(this._sendIf));
|
|
1100
1469
|
}
|
|
1101
1470
|
}
|
|
1102
1471
|
get shouldSendMessage() {
|
|
@@ -1161,7 +1530,6 @@ var SarifToSlackClient = class _SarifToSlackClient {
|
|
|
1161
1530
|
0 && (module.exports = {
|
|
1162
1531
|
Color,
|
|
1163
1532
|
FooterType,
|
|
1164
|
-
LogLevel,
|
|
1165
1533
|
RepresentationType,
|
|
1166
1534
|
SarifToSlackClient,
|
|
1167
1535
|
SendIf
|