@appland/scanner 1.55.0 → 1.58.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/built/algorithms/dataStructures/graph/Graph.js +53 -62
- package/built/algorithms/dataStructures/graph/GraphEdge.js +13 -16
- package/built/algorithms/dataStructures/graph/GraphVertex.js +37 -42
- package/built/algorithms/dataStructures/linked-list/LinkedList.js +33 -38
- package/built/algorithms/dataStructures/linked-list/LinkedListNode.js +6 -10
- package/built/algorithms/graph/depth-first-search/index.js +7 -8
- package/built/algorithms/graph/detect-cycle/index.js +15 -16
- package/built/algorithms/utils/Comparator.js +19 -21
- package/built/analyzer/recordSecrets.js +7 -30
- package/built/analyzer/secretsRegexes.js +8 -9
- package/built/appMapIndex.js +19 -21
- package/built/check.js +17 -21
- package/built/checkInstance.js +26 -48
- package/built/cli/ci/command.js +61 -156
- package/built/cli/ci/options.js +0 -1
- package/built/cli/codeVersionArgs.js +0 -1
- package/built/cli/exitCode.js +0 -1
- package/built/cli/fail.js +2 -3
- package/built/cli/merge/command.js +21 -63
- package/built/cli/merge/options.js +0 -1
- package/built/cli/reportUploadURL.js +2 -3
- package/built/cli/resolveAppId.js +34 -85
- package/built/cli/scan/command.js +57 -242
- package/built/cli/scan/formatReport.js +44 -0
- package/built/cli/scan/options.js +0 -1
- package/built/cli/scan/scanner.js +38 -117
- package/built/cli/scan/singleScan.js +80 -0
- package/built/cli/scan/watchScan.js +102 -0
- package/built/cli/scan.js +39 -132
- package/built/cli/scanArgs.js +0 -1
- package/built/cli/scanOptions.js +0 -1
- package/built/cli/updateCommitStatus.js +10 -47
- package/built/cli/upload/command.js +20 -64
- package/built/cli/upload/options.js +0 -1
- package/built/cli/upload/pruneAppMap.js +16 -0
- package/built/cli/upload.js +91 -172
- package/built/cli/validateFile.js +13 -48
- package/built/cli.js +34 -21
- package/built/configuration/configurationProvider.js +151 -233
- package/built/configuration/schema/options.json +76 -76
- package/built/configuration/types/checkConfig.js +0 -1
- package/built/configuration/types/configuration.js +0 -1
- package/built/configuration/types/matchEventConfig.js +0 -1
- package/built/configuration/types/matchPatternConfig.js +0 -1
- package/built/database/index.js +35 -128
- package/built/database/visit.js +20 -68
- package/built/errors.js +4 -30
- package/built/eventUtil.js +10 -35
- package/built/findings.js +3 -4
- package/built/integration/appland/app/exists.js +33 -76
- package/built/integration/appland/app/listFindingStatus.js +5 -38
- package/built/integration/appland/appMap/create.js +38 -89
- package/built/integration/appland/location.js +0 -1
- package/built/integration/appland/mapset/create.js +34 -85
- package/built/integration/appland/retry.js +10 -11
- package/built/integration/appland/retryOptions.js +0 -1
- package/built/integration/appland/scannerJob/create.js +34 -84
- package/built/integration/appland/scannerJob/merge.js +28 -74
- package/built/integration/appland/scannerJob.js +0 -1
- package/built/integration/github/commitStatus.js +3 -4
- package/built/integration/vars.js +1 -2
- package/built/openapi/index.js +39 -83
- package/built/report/appMapMetadata.js +0 -1
- package/built/report/findingSummary.js +0 -1
- package/built/report/findingsReport.js +14 -16
- package/built/report/scanResults.js +50 -72
- package/built/report/scanSummary.js +0 -1
- package/built/report/summaryReport.js +12 -13
- package/built/ruleChecker.js +146 -297
- package/built/rules/authzBeforeAuthn.js +25 -59
- package/built/rules/circularDependency.js +69 -101
- package/built/rules/deserializationOfUntrustedData.js +29 -63
- package/built/rules/execOfUntrustedCommand.js +28 -62
- package/built/rules/http-500/metadata.js +0 -1
- package/built/rules/http-500/rule.js +2 -3
- package/built/rules/illegalPackageDependency.js +16 -18
- package/built/rules/incompatibleHttpClientRequest.js +30 -69
- package/built/rules/insecureCompare.js +12 -13
- package/built/rules/jobNotCancelled.js +13 -45
- package/built/rules/lib/hasParameterOrReceiver.js +4 -7
- package/built/rules/lib/matchEvent.js +12 -13
- package/built/rules/lib/matchPattern.js +6 -7
- package/built/rules/lib/metadata.js +0 -1
- package/built/rules/lib/parseRuleDescription.js +5 -6
- package/built/rules/lib/precedingEvents.js +7 -75
- package/built/rules/lib/rpcWithoutProtection.js +5 -28
- package/built/rules/lib/sanitizesData.js +0 -1
- package/built/rules/lib/util.js +34 -73
- package/built/rules/logoutWithoutSessionReset.js +24 -58
- package/built/rules/missingAuthentication.js +28 -28
- package/built/rules/missingContentType.js +8 -9
- package/built/rules/nPlusOneQuery.js +35 -87
- package/built/rules/queryFromInvalidPackage.js +17 -19
- package/built/rules/queryFromView.js +13 -16
- package/built/rules/rpcWithoutCircuitBreaker.js +14 -84
- package/built/rules/saveWithoutValidation.js +8 -9
- package/built/rules/secretInLog.js +30 -93
- package/built/rules/slowFunctionCall.js +16 -20
- package/built/rules/slowHttpServerRequest.js +9 -11
- package/built/rules/slowQuery.js +9 -12
- package/built/rules/tooManyJoins.js +26 -51
- package/built/rules/tooManyUpdates.js +25 -105
- package/built/rules/unbatchedMaterializedQuery.js +26 -30
- package/built/rules/updateInGetRequest.js +30 -45
- package/built/scope/commandScope.js +24 -144
- package/built/scope/httpClientRequestScope.js +11 -98
- package/built/scope/httpServerRequestScope.js +11 -98
- package/built/scope/rootScope.js +11 -98
- package/built/scope/scopeImpl.js +10 -82
- package/built/scope/scopeIterator.js +6 -10
- package/built/scope/sqlTransactionScope.js +24 -122
- package/built/sqlWarning.js +9 -35
- package/built/telemetry.js +215 -0
- package/built/wellKnownLabels.js +0 -1
- package/package.json +10 -3
- package/built/algorithms/dataStructures/graph/Graph.js.map +0 -1
- package/built/algorithms/dataStructures/graph/GraphEdge.js.map +0 -1
- package/built/algorithms/dataStructures/graph/GraphVertex.js.map +0 -1
- package/built/algorithms/dataStructures/linked-list/LinkedList.js.map +0 -1
- package/built/algorithms/dataStructures/linked-list/LinkedListNode.js.map +0 -1
- package/built/algorithms/graph/depth-first-search/index.js.map +0 -1
- package/built/algorithms/graph/detect-cycle/index.js.map +0 -1
- package/built/algorithms/utils/Comparator.js.map +0 -1
- package/built/analyzer/recordSecrets.js.map +0 -1
- package/built/analyzer/secretsRegexes.js.map +0 -1
- package/built/appMapIndex.js.map +0 -1
- package/built/check.js.map +0 -1
- package/built/checkInstance.js.map +0 -1
- package/built/cli/ci/command.js.map +0 -1
- package/built/cli/ci/options.js.map +0 -1
- package/built/cli/codeVersionArgs.js.map +0 -1
- package/built/cli/exitCode.js.map +0 -1
- package/built/cli/fail.js.map +0 -1
- package/built/cli/merge/command.js.map +0 -1
- package/built/cli/merge/options.js.map +0 -1
- package/built/cli/reportUploadURL.js.map +0 -1
- package/built/cli/resolveAppId.js.map +0 -1
- package/built/cli/scan/command.js.map +0 -1
- package/built/cli/scan/options.js.map +0 -1
- package/built/cli/scan/scanner.js.map +0 -1
- package/built/cli/scan.js.map +0 -1
- package/built/cli/scanArgs.js.map +0 -1
- package/built/cli/scanOptions.js.map +0 -1
- package/built/cli/updateCommitStatus.js.map +0 -1
- package/built/cli/upload/command.js.map +0 -1
- package/built/cli/upload/options.js.map +0 -1
- package/built/cli/upload.js.map +0 -1
- package/built/cli/validateFile.js.map +0 -1
- package/built/cli.js.map +0 -1
- package/built/configuration/configurationProvider.js.map +0 -1
- package/built/configuration/types/checkConfig.js.map +0 -1
- package/built/configuration/types/configuration.js.map +0 -1
- package/built/configuration/types/matchEventConfig.js.map +0 -1
- package/built/configuration/types/matchPatternConfig.js.map +0 -1
- package/built/database/index.js.map +0 -1
- package/built/database/visit.js.map +0 -1
- package/built/errors.js.map +0 -1
- package/built/eventUtil.js.map +0 -1
- package/built/findings.js.map +0 -1
- package/built/integration/appland/app/exists.js.map +0 -1
- package/built/integration/appland/app/listFindingStatus.js.map +0 -1
- package/built/integration/appland/appMap/create.js.map +0 -1
- package/built/integration/appland/location.js.map +0 -1
- package/built/integration/appland/mapset/create.js.map +0 -1
- package/built/integration/appland/retry.js.map +0 -1
- package/built/integration/appland/retryOptions.js.map +0 -1
- package/built/integration/appland/scannerJob/create.js.map +0 -1
- package/built/integration/appland/scannerJob/merge.js.map +0 -1
- package/built/integration/appland/scannerJob.js.map +0 -1
- package/built/integration/github/commitStatus.js.map +0 -1
- package/built/integration/vars.js.map +0 -1
- package/built/openapi/index.js.map +0 -1
- package/built/openapi/method.js +0 -120
- package/built/openapi/method.js.map +0 -1
- package/built/openapi/model.js +0 -49
- package/built/openapi/model.js.map +0 -1
- package/built/openapi/path.js +0 -36
- package/built/openapi/path.js.map +0 -1
- package/built/openapi/provider.js +0 -133
- package/built/openapi/provider.js.map +0 -1
- package/built/openapi/response.js +0 -59
- package/built/openapi/response.js.map +0 -1
- package/built/openapi/rpcRequest.js +0 -130
- package/built/openapi/rpcRequest.js.map +0 -1
- package/built/openapi/schema.js +0 -42
- package/built/openapi/schema.js.map +0 -1
- package/built/openapi/securitySchemes.js +0 -32
- package/built/openapi/securitySchemes.js.map +0 -1
- package/built/openapi/statusCodes.js +0 -68
- package/built/openapi/statusCodes.js.map +0 -1
- package/built/openapi/util.js +0 -91
- package/built/openapi/util.js.map +0 -1
- package/built/report/appMapMetadata.js.map +0 -1
- package/built/report/findingSummary.js.map +0 -1
- package/built/report/findingsReport.js.map +0 -1
- package/built/report/scanResults.js.map +0 -1
- package/built/report/scanSummary.js.map +0 -1
- package/built/report/summaryReport.js.map +0 -1
- package/built/ruleChecker.js.map +0 -1
- package/built/rules/authzBeforeAuthn.js.map +0 -1
- package/built/rules/circularDependency.js.map +0 -1
- package/built/rules/deserializationOfUntrustedData.js.map +0 -1
- package/built/rules/execOfUntrustedCommand.js.map +0 -1
- package/built/rules/http-500/metadata.js.map +0 -1
- package/built/rules/http-500/rule.js.map +0 -1
- package/built/rules/illegalPackageDependency.js.map +0 -1
- package/built/rules/incompatibleHttpClientRequest.js.map +0 -1
- package/built/rules/insecureCompare.js.map +0 -1
- package/built/rules/jobNotCancelled.js.map +0 -1
- package/built/rules/lib/hasParameterOrReceiver.js.map +0 -1
- package/built/rules/lib/matchEvent.js.map +0 -1
- package/built/rules/lib/matchPattern.js.map +0 -1
- package/built/rules/lib/metadata.js.map +0 -1
- package/built/rules/lib/parseRuleDescription.js.map +0 -1
- package/built/rules/lib/precedingEvents.js.map +0 -1
- package/built/rules/lib/rpcWithoutProtection.js.map +0 -1
- package/built/rules/lib/sanitizesData.js.map +0 -1
- package/built/rules/lib/util.js.map +0 -1
- package/built/rules/logoutWithoutSessionReset.js.map +0 -1
- package/built/rules/missingAuthentication.js.map +0 -1
- package/built/rules/missingContentType.js.map +0 -1
- package/built/rules/nPlusOneQuery.js.map +0 -1
- package/built/rules/queryFromInvalidPackage.js.map +0 -1
- package/built/rules/queryFromView.js.map +0 -1
- package/built/rules/rpcWithoutCircuitBreaker.js.map +0 -1
- package/built/rules/saveWithoutValidation.js.map +0 -1
- package/built/rules/secretInLog.js.map +0 -1
- package/built/rules/slowFunctionCall.js.map +0 -1
- package/built/rules/slowHttpServerRequest.js.map +0 -1
- package/built/rules/slowQuery.js.map +0 -1
- package/built/rules/tooManyJoins.js.map +0 -1
- package/built/rules/tooManyUpdates.js.map +0 -1
- package/built/rules/unbatchedMaterializedQuery.js.map +0 -1
- package/built/rules/updateInGetRequest.js.map +0 -1
- package/built/scope/commandScope.js.map +0 -1
- package/built/scope/httpClientRequestScope.js.map +0 -1
- package/built/scope/httpServerRequestScope.js.map +0 -1
- package/built/scope/rootScope.js.map +0 -1
- package/built/scope/scopeImpl.js.map +0 -1
- package/built/scope/scopeIterator.js.map +0 -1
- package/built/scope/sqlTransactionScope.js.map +0 -1
- package/built/sqlWarning.js.map +0 -1
- package/built/wellKnownLabels.js.map +0 -1
|
@@ -8,46 +8,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
13
|
};
|
|
41
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
15
|
+
const util_1 = require("../../rules/lib/util");
|
|
16
|
+
const merge_1 = require("../../integration/appland/scannerJob/merge");
|
|
17
|
+
const resolveAppId_1 = __importDefault(require("../resolveAppId"));
|
|
18
|
+
const updateCommitStatus_1 = __importDefault(require("../updateCommitStatus"));
|
|
19
|
+
const fail_1 = __importDefault(require("../fail"));
|
|
47
20
|
exports.default = {
|
|
48
21
|
command: 'merge <merge-key>',
|
|
49
22
|
describe: 'Merge scan results from parallel scans',
|
|
50
|
-
builder
|
|
23
|
+
builder(args) {
|
|
51
24
|
args.option('app', {
|
|
52
25
|
describe: 'name of the app to publish the findings for. By default, this is determined by looking in appmap.yml',
|
|
53
26
|
});
|
|
@@ -67,36 +40,21 @@ exports.default = {
|
|
|
67
40
|
});
|
|
68
41
|
return args.strict();
|
|
69
42
|
},
|
|
70
|
-
handler
|
|
71
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
mergeResults = _b.sent();
|
|
86
|
-
console.warn("Merged results to ".concat(mergeResults.url));
|
|
87
|
-
if (!updateCommitStatusOption) return [3 /*break*/, 4];
|
|
88
|
-
return [4 /*yield*/, (0, updateCommitStatus_1.default)(mergeResults.summary.numFindings, mergeResults.summary.numChecks)];
|
|
89
|
-
case 3:
|
|
90
|
-
_b.sent();
|
|
91
|
-
_b.label = 4;
|
|
92
|
-
case 4:
|
|
93
|
-
if (failOption) {
|
|
94
|
-
(0, fail_1.default)(mergeResults.summary.numFindings);
|
|
95
|
-
}
|
|
96
|
-
return [2 /*return*/];
|
|
97
|
-
}
|
|
98
|
-
});
|
|
43
|
+
handler(options) {
|
|
44
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
+
const { verbose: isVerbose, app: appIdArg, fail: failOption, updateCommitStatus: updateCommitStatusOption, mergeKey, } = options;
|
|
46
|
+
if (isVerbose) {
|
|
47
|
+
(0, util_1.verbose)(true);
|
|
48
|
+
}
|
|
49
|
+
const appId = yield (0, resolveAppId_1.default)(appIdArg, '.');
|
|
50
|
+
const mergeResults = yield (0, merge_1.merge)(appId, mergeKey);
|
|
51
|
+
console.warn(`Merged results to ${mergeResults.url}`);
|
|
52
|
+
if (updateCommitStatusOption) {
|
|
53
|
+
yield (0, updateCommitStatus_1.default)(mergeResults.summary.numFindings, mergeResults.summary.numChecks);
|
|
54
|
+
}
|
|
55
|
+
if (failOption) {
|
|
56
|
+
(0, fail_1.default)(mergeResults.summary.numFindings);
|
|
57
|
+
}
|
|
99
58
|
});
|
|
100
59
|
},
|
|
101
60
|
};
|
|
102
|
-
//# sourceMappingURL=command.js.map
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
function reportUploadURL(numFindings, url) {
|
|
4
|
-
|
|
4
|
+
let message = `Uploaded ${numFindings} findings`;
|
|
5
5
|
if (url) {
|
|
6
|
-
message +=
|
|
6
|
+
message += ` to ${url}`;
|
|
7
7
|
}
|
|
8
8
|
console.log(message);
|
|
9
9
|
}
|
|
10
10
|
exports.default = reportUploadURL;
|
|
11
|
-
//# sourceMappingURL=reportUploadURL.js.map
|
|
@@ -8,98 +8,47 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
12
|
+
const fs_1 = require("fs");
|
|
13
|
+
const promises_1 = require("fs/promises");
|
|
14
|
+
const js_yaml_1 = require("js-yaml");
|
|
15
|
+
const path_1 = require("path");
|
|
16
|
+
const exists_1 = require("../integration/appland/app/exists");
|
|
17
|
+
const errors_1 = require("../errors");
|
|
45
18
|
function resolveAppId(appIdArg, appMapDir) {
|
|
46
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (!(searchPath !== '/' && searchPath !== '.')) return [3 /*break*/, 7];
|
|
59
|
-
configPath = (0, path_1.join)(searchPath, 'appmap.yml');
|
|
60
|
-
_b.label = 2;
|
|
61
|
-
case 2:
|
|
62
|
-
_b.trys.push([2, 4, , 5]);
|
|
63
|
-
return [4 /*yield*/, (0, promises_1.access)(configPath, fs_1.constants.R_OK)];
|
|
64
|
-
case 3:
|
|
65
|
-
_b.sent();
|
|
66
|
-
return [3 /*break*/, 5];
|
|
67
|
-
case 4:
|
|
68
|
-
_a = _b.sent();
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
if (appIdArg) {
|
|
21
|
+
return appIdArg;
|
|
22
|
+
}
|
|
23
|
+
if (appMapDir) {
|
|
24
|
+
let searchPath = (0, path_1.resolve)(appMapDir);
|
|
25
|
+
while (searchPath !== '/' && searchPath !== '.') {
|
|
26
|
+
const configPath = (0, path_1.join)(searchPath, 'appmap.yml');
|
|
27
|
+
try {
|
|
28
|
+
yield (0, promises_1.access)(configPath, fs_1.constants.R_OK);
|
|
29
|
+
}
|
|
30
|
+
catch (_a) {
|
|
69
31
|
searchPath = (0, path_1.dirname)(searchPath);
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return [2 /*return*/, config.name];
|
|
77
|
-
return [3 /*break*/, 1];
|
|
78
|
-
case 7: return [2 /*return*/];
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const configContent = yield (0, promises_1.readFile)(configPath, 'utf-8');
|
|
35
|
+
const config = (0, js_yaml_1.load)(configContent);
|
|
36
|
+
if (config.name)
|
|
37
|
+
return config.name;
|
|
79
38
|
}
|
|
80
|
-
}
|
|
39
|
+
}
|
|
81
40
|
});
|
|
82
41
|
}
|
|
83
42
|
function default_1(appIdArg, appMapDir) {
|
|
84
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return [4 /*yield*/, (0, exists_1.exists)(appId)];
|
|
94
|
-
case 2:
|
|
95
|
-
appExists = _a.sent();
|
|
96
|
-
if (!appExists) {
|
|
97
|
-
throw new errors_1.ValidationError("App \"".concat(appId, "\" is not valid or does not exist.\nPlease fix the app name in the appmap.yml file, or override it with the --app option."));
|
|
98
|
-
}
|
|
99
|
-
return [2 /*return*/, appId];
|
|
100
|
-
}
|
|
101
|
-
});
|
|
43
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
const appId = yield resolveAppId(appIdArg, appMapDir);
|
|
45
|
+
if (!appId)
|
|
46
|
+
throw new errors_1.ValidationError('App was not provided and could not be resolved');
|
|
47
|
+
const appExists = yield (0, exists_1.exists)(appId);
|
|
48
|
+
if (!appExists) {
|
|
49
|
+
throw new errors_1.ValidationError(`App "${appId}" is not valid or does not exist.\nPlease fix the app name in the appmap.yml file, or override it with the --app option.`);
|
|
50
|
+
}
|
|
51
|
+
return appId;
|
|
102
52
|
});
|
|
103
53
|
}
|
|
104
54
|
exports.default = default_1;
|
|
105
|
-
//# sourceMappingURL=resolveAppId.js.map
|
|
@@ -1,15 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
2
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
3
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
4
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -19,90 +8,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
19
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
9
|
});
|
|
21
10
|
};
|
|
22
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
24
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
-
function step(op) {
|
|
27
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
-
while (_) try {
|
|
29
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
30
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
-
switch (op[0]) {
|
|
32
|
-
case 0: case 1: t = op; break;
|
|
33
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
-
default:
|
|
37
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
-
if (t[2]) _.ops.pop();
|
|
42
|
-
_.trys.pop(); continue;
|
|
43
|
-
}
|
|
44
|
-
op = body.call(thisArg, _);
|
|
45
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
var __read = (this && this.__read) || function (o, n) {
|
|
50
|
-
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
51
|
-
if (!m) return o;
|
|
52
|
-
var i = m.call(o), r, ar = [], e;
|
|
53
|
-
try {
|
|
54
|
-
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
55
|
-
}
|
|
56
|
-
catch (error) { e = { error: error }; }
|
|
57
|
-
finally {
|
|
58
|
-
try {
|
|
59
|
-
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
60
|
-
}
|
|
61
|
-
finally { if (e) throw e.error; }
|
|
62
|
-
}
|
|
63
|
-
return ar;
|
|
64
|
-
};
|
|
65
|
-
var __values = (this && this.__values) || function(o) {
|
|
66
|
-
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
67
|
-
if (m) return m.call(o);
|
|
68
|
-
if (o && typeof o.length === "number") return {
|
|
69
|
-
next: function () {
|
|
70
|
-
if (o && i >= o.length) o = void 0;
|
|
71
|
-
return { value: o && o[i++], done: !o };
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
75
|
-
};
|
|
76
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
77
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
78
|
-
if (ar || !(i in from)) {
|
|
79
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
80
|
-
ar[i] = from[i];
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
84
|
-
};
|
|
85
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
86
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
87
13
|
};
|
|
88
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
var summaryReport_1 = __importDefault(require("../../report/summaryReport"));
|
|
98
|
-
var validateFile_1 = __importDefault(require("../validateFile"));
|
|
99
|
-
var scanner_1 = __importDefault(require("./scanner"));
|
|
100
|
-
var scanArgs_1 = __importDefault(require("../scanArgs"));
|
|
101
|
-
var resolveAppId_1 = __importDefault(require("../resolveAppId"));
|
|
15
|
+
const errors_1 = require("../../errors");
|
|
16
|
+
const util_1 = require("../../rules/lib/util");
|
|
17
|
+
const validateFile_1 = __importDefault(require("../validateFile"));
|
|
18
|
+
const scanArgs_1 = __importDefault(require("../scanArgs"));
|
|
19
|
+
const resolveAppId_1 = __importDefault(require("../resolveAppId"));
|
|
20
|
+
const singleScan_1 = __importDefault(require("./singleScan"));
|
|
21
|
+
const watchScan_1 = __importDefault(require("./watchScan"));
|
|
22
|
+
const configurationProvider_1 = require("../../configuration/configurationProvider");
|
|
102
23
|
exports.default = {
|
|
103
24
|
command: 'scan',
|
|
104
25
|
describe: 'Scan AppMaps for code behavior findings',
|
|
105
|
-
builder
|
|
26
|
+
builder(args) {
|
|
106
27
|
(0, scanArgs_1.default)(args);
|
|
107
28
|
args.option('appmap-file', {
|
|
108
29
|
describe: 'single file to scan, or repeat this option to scan multiple specific files',
|
|
@@ -117,163 +38,57 @@ exports.default = {
|
|
|
117
38
|
default: false,
|
|
118
39
|
type: 'boolean',
|
|
119
40
|
});
|
|
41
|
+
args.option('watch', {
|
|
42
|
+
describe: 'scan code changes and report findings on changed files',
|
|
43
|
+
default: false,
|
|
44
|
+
type: 'boolean',
|
|
45
|
+
});
|
|
120
46
|
return args.strict();
|
|
121
47
|
},
|
|
122
|
-
handler
|
|
123
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
_c.label = 4;
|
|
155
|
-
case 4:
|
|
156
|
-
files = [];
|
|
157
|
-
if (!appmapDir) return [3 /*break*/, 7];
|
|
158
|
-
return [4 /*yield*/, (0, validateFile_1.default)('directory', appmapDir)];
|
|
159
|
-
case 5:
|
|
160
|
-
_c.sent();
|
|
161
|
-
glob = (0, util_1.promisify)(glob_1.glob);
|
|
162
|
-
return [4 /*yield*/, glob("".concat(appmapDir, "/**/*.appmap.json"))];
|
|
163
|
-
case 6:
|
|
164
|
-
files = _c.sent();
|
|
165
|
-
_c.label = 7;
|
|
166
|
-
case 7:
|
|
167
|
-
if (!appmapFile) return [3 /*break*/, 9];
|
|
168
|
-
files = typeof appmapFile === 'string' ? [appmapFile] : appmapFile;
|
|
169
|
-
return [4 /*yield*/, Promise.all(files.map(function (file) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
170
|
-
return [2 /*return*/, (0, validateFile_1.default)('file', file)];
|
|
171
|
-
}); }); }))];
|
|
172
|
-
case 8:
|
|
173
|
-
_c.sent();
|
|
174
|
-
_c.label = 9;
|
|
175
|
-
case 9: return [4 /*yield*/, (0, configurationProvider_1.parseConfigFile)(config)];
|
|
176
|
-
case 10:
|
|
177
|
-
configData = _c.sent();
|
|
178
|
-
return [4 /*yield*/, (0, scanner_1.default)(reportAllFindings, configData, files).catch(function (error) {
|
|
179
|
-
throw new errors_1.ValidationError(error.message + '\nUse --all to perform an offline scan.');
|
|
180
|
-
})];
|
|
181
|
-
case 11:
|
|
182
|
-
scanner = _c.sent();
|
|
183
|
-
startTime = Date.now();
|
|
184
|
-
return [4 /*yield*/, Promise.all([
|
|
185
|
-
scanner.scan(),
|
|
186
|
-
scanner.fetchFindingStatus(appId, appmapDir),
|
|
187
|
-
])];
|
|
188
|
-
case 12:
|
|
189
|
-
_b = __read.apply(void 0, [_c.sent(), 2]), rawScanResults = _b[0], findingStatuses = _b[1];
|
|
190
|
-
// Always report the raw data
|
|
191
|
-
return [4 /*yield*/, (0, promises_1.writeFile)(reportFile, formatReport(rawScanResults))];
|
|
192
|
-
case 13:
|
|
193
|
-
// Always report the raw data
|
|
194
|
-
_c.sent();
|
|
195
|
-
if (reportAllFindings) {
|
|
196
|
-
scanResults = rawScanResults;
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
199
|
-
scanResults = rawScanResults.withFindings((0, findings_1.newFindings)(rawScanResults.findings, findingStatuses));
|
|
200
|
-
}
|
|
201
|
-
(0, findingsReport_1.default)(scanResults.findings, scanResults.appMapMetadata, ide);
|
|
202
|
-
console.log();
|
|
203
|
-
(0, summaryReport_1.default)(scanResults, true);
|
|
204
|
-
console.log('\n');
|
|
205
|
-
elapsed = Date.now() - startTime;
|
|
206
|
-
numChecks = scanResults.checks.length * scanResults.summary.numAppMaps;
|
|
207
|
-
console.log("Performed ".concat(numChecks, " checks in ").concat(elapsed, "ms (").concat(Math.floor(numChecks / (elapsed / 1000.0)), " checks/sec)"));
|
|
208
|
-
return [2 /*return*/];
|
|
48
|
+
handler(options) {
|
|
49
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
50
|
+
let { appmapDir } = options;
|
|
51
|
+
const { appmapFile, config, verbose: isVerbose, all: reportAllFindings, watch, app: appIdArg, apiKey, ide, reportFile, } = options;
|
|
52
|
+
if (isVerbose) {
|
|
53
|
+
(0, util_1.verbose)(true);
|
|
54
|
+
}
|
|
55
|
+
if (apiKey) {
|
|
56
|
+
process.env.APPLAND_API_KEY = apiKey;
|
|
57
|
+
}
|
|
58
|
+
if (appmapFile && watch) {
|
|
59
|
+
throw new errors_1.ValidationError('Use --appmap-file or --watch, but not both');
|
|
60
|
+
}
|
|
61
|
+
if (reportAllFindings && watch) {
|
|
62
|
+
throw new errors_1.ValidationError(`Don't use --all with --watch, because in watch mode all findings are reported`);
|
|
63
|
+
}
|
|
64
|
+
if (appIdArg && watch) {
|
|
65
|
+
throw new errors_1.ValidationError(`Don't use --app with --watch, because in watch mode all findings are reported`);
|
|
66
|
+
}
|
|
67
|
+
if (!appmapFile && !appmapDir) {
|
|
68
|
+
appmapDir = (yield (0, util_1.appmapDirFromConfig)()) || '.';
|
|
69
|
+
}
|
|
70
|
+
if (appmapDir)
|
|
71
|
+
yield (0, validateFile_1.default)('directory', appmapDir);
|
|
72
|
+
if (watch) {
|
|
73
|
+
const watchAppMapDir = appmapDir;
|
|
74
|
+
return (0, watchScan_1.default)({ appmapDir: watchAppMapDir, configFile: config });
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
let appId = appIdArg;
|
|
78
|
+
if (!reportAllFindings) {
|
|
79
|
+
appId = yield (0, resolveAppId_1.default)(appIdArg, appmapDir);
|
|
209
80
|
}
|
|
210
|
-
|
|
81
|
+
const configData = yield (0, configurationProvider_1.parseConfigFile)(config);
|
|
82
|
+
return (0, singleScan_1.default)({
|
|
83
|
+
appmapFile,
|
|
84
|
+
appmapDir,
|
|
85
|
+
configData,
|
|
86
|
+
reportAllFindings,
|
|
87
|
+
appId,
|
|
88
|
+
ide,
|
|
89
|
+
reportFile,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
211
92
|
});
|
|
212
93
|
},
|
|
213
94
|
};
|
|
214
|
-
function metadataFilter(_a) {
|
|
215
|
-
var apps = _a.apps.length, clients = _a.clients.length, frameworks = _a.frameworks.length, git = _a.git.length, languages = _a.languages.length, recorders = _a.recorders.length;
|
|
216
|
-
var filtered = Object.entries({
|
|
217
|
-
app: apps < 2,
|
|
218
|
-
client: clients < 2,
|
|
219
|
-
git: git < 2,
|
|
220
|
-
language: languages < 2,
|
|
221
|
-
recorder: recorders < 2,
|
|
222
|
-
})
|
|
223
|
-
.filter(function (_a) {
|
|
224
|
-
var _b = __read(_a, 2), v = _b[1];
|
|
225
|
-
return v;
|
|
226
|
-
})
|
|
227
|
-
.map(function (_a) {
|
|
228
|
-
var _b = __read(_a, 1), k = _b[0];
|
|
229
|
-
return k;
|
|
230
|
-
});
|
|
231
|
-
return function (metadata) {
|
|
232
|
-
return Object.fromEntries(Object.entries(metadata).filter(function (_a) {
|
|
233
|
-
var _b = __read(_a, 2), k = _b[0], v = _b[1];
|
|
234
|
-
if (filtered.includes(k))
|
|
235
|
-
return false;
|
|
236
|
-
if (k === 'frameworks')
|
|
237
|
-
return (v || []).length !== frameworks;
|
|
238
|
-
return true;
|
|
239
|
-
}));
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
function uniq(entries, key) {
|
|
243
|
-
var e_1, _a;
|
|
244
|
-
var result = new Map();
|
|
245
|
-
try {
|
|
246
|
-
for (var entries_1 = __values(entries), entries_1_1 = entries_1.next(); !entries_1_1.done; entries_1_1 = entries_1.next()) {
|
|
247
|
-
var entry = entries_1_1.value;
|
|
248
|
-
var k = key(entry);
|
|
249
|
-
if (result.has(k))
|
|
250
|
-
continue;
|
|
251
|
-
result.set(k, entry);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
255
|
-
finally {
|
|
256
|
-
try {
|
|
257
|
-
if (entries_1_1 && !entries_1_1.done && (_a = entries_1.return)) _a.call(entries_1);
|
|
258
|
-
}
|
|
259
|
-
finally { if (e_1) throw e_1.error; }
|
|
260
|
-
}
|
|
261
|
-
return result.values();
|
|
262
|
-
}
|
|
263
|
-
// Formats a report to JSON. Does some data deduplication.
|
|
264
|
-
function formatReport(rawScanResults) {
|
|
265
|
-
var _a = __assign({}, rawScanResults), summary = _a.summary, appMapMetadata = _a.appMapMetadata, findings = _a.findings;
|
|
266
|
-
// remove metadata that's common between appmaps
|
|
267
|
-
var filter = metadataFilter(summary.appMapMetadata);
|
|
268
|
-
var metadata = Object.fromEntries(Object.entries(appMapMetadata).map(function (_a) {
|
|
269
|
-
var _b = __read(_a, 2), id = _b[0], metadata = _b[1];
|
|
270
|
-
return [id, filter(metadata)];
|
|
271
|
-
}));
|
|
272
|
-
// only keep one finding of the same hash
|
|
273
|
-
var uniqueFindings = __spreadArray([], __read(uniq(findings, function (_a) {
|
|
274
|
-
var hash = _a.hash;
|
|
275
|
-
return hash;
|
|
276
|
-
})), false);
|
|
277
|
-
return JSON.stringify(__assign(__assign({}, rawScanResults), { summary: __assign(__assign({}, summary), { numFindings: uniqueFindings.length }), appMapMetadata: metadata, findings: uniqueFindings }), null, 2);
|
|
278
|
-
}
|
|
279
|
-
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatReport = void 0;
|
|
4
|
+
// Formats a report to JSON. Does some data deduplication.
|
|
5
|
+
function formatReport(rawScanResults) {
|
|
6
|
+
const { summary, appMapMetadata, findings } = Object.assign({}, rawScanResults);
|
|
7
|
+
// remove metadata that's common between appmaps
|
|
8
|
+
const filter = metadataFilter(summary.appMapMetadata);
|
|
9
|
+
const metadata = Object.fromEntries(Object.entries(appMapMetadata).map(([id, metadata]) => [id, filter(metadata)]));
|
|
10
|
+
// only keep one finding of the same hash
|
|
11
|
+
const uniqueFindings = [...uniq(findings, ({ hash }) => hash)];
|
|
12
|
+
return JSON.stringify(Object.assign(Object.assign({}, rawScanResults), { summary: Object.assign(Object.assign({}, summary), { numFindings: uniqueFindings.length }), appMapMetadata: metadata, findings: uniqueFindings }), null, 2);
|
|
13
|
+
}
|
|
14
|
+
exports.formatReport = formatReport;
|
|
15
|
+
function metadataFilter({ apps: { length: apps }, clients: { length: clients }, frameworks: { length: frameworks }, git: { length: git }, languages: { length: languages }, recorders: { length: recorders }, }) {
|
|
16
|
+
const filtered = Object.entries({
|
|
17
|
+
app: apps < 2,
|
|
18
|
+
client: clients < 2,
|
|
19
|
+
git: git < 2,
|
|
20
|
+
language: languages < 2,
|
|
21
|
+
recorder: recorders < 2,
|
|
22
|
+
})
|
|
23
|
+
.filter(([, v]) => v)
|
|
24
|
+
.map(([k]) => k);
|
|
25
|
+
return function (metadata) {
|
|
26
|
+
return Object.fromEntries(Object.entries(metadata).filter(([k, v]) => {
|
|
27
|
+
if (filtered.includes(k))
|
|
28
|
+
return false;
|
|
29
|
+
if (k === 'frameworks')
|
|
30
|
+
return (v || []).length !== frameworks;
|
|
31
|
+
return true;
|
|
32
|
+
}));
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function uniq(entries, key) {
|
|
36
|
+
const result = new Map();
|
|
37
|
+
for (const entry of entries) {
|
|
38
|
+
const k = key(entry);
|
|
39
|
+
if (result.has(k))
|
|
40
|
+
continue;
|
|
41
|
+
result.set(k, entry);
|
|
42
|
+
}
|
|
43
|
+
return result.values();
|
|
44
|
+
}
|