@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.
Files changed (244) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/built/algorithms/dataStructures/graph/Graph.js +53 -62
  3. package/built/algorithms/dataStructures/graph/GraphEdge.js +13 -16
  4. package/built/algorithms/dataStructures/graph/GraphVertex.js +37 -42
  5. package/built/algorithms/dataStructures/linked-list/LinkedList.js +33 -38
  6. package/built/algorithms/dataStructures/linked-list/LinkedListNode.js +6 -10
  7. package/built/algorithms/graph/depth-first-search/index.js +7 -8
  8. package/built/algorithms/graph/detect-cycle/index.js +15 -16
  9. package/built/algorithms/utils/Comparator.js +19 -21
  10. package/built/analyzer/recordSecrets.js +7 -30
  11. package/built/analyzer/secretsRegexes.js +8 -9
  12. package/built/appMapIndex.js +19 -21
  13. package/built/check.js +17 -21
  14. package/built/checkInstance.js +26 -48
  15. package/built/cli/ci/command.js +61 -156
  16. package/built/cli/ci/options.js +0 -1
  17. package/built/cli/codeVersionArgs.js +0 -1
  18. package/built/cli/exitCode.js +0 -1
  19. package/built/cli/fail.js +2 -3
  20. package/built/cli/merge/command.js +21 -63
  21. package/built/cli/merge/options.js +0 -1
  22. package/built/cli/reportUploadURL.js +2 -3
  23. package/built/cli/resolveAppId.js +34 -85
  24. package/built/cli/scan/command.js +57 -242
  25. package/built/cli/scan/formatReport.js +44 -0
  26. package/built/cli/scan/options.js +0 -1
  27. package/built/cli/scan/scanner.js +38 -117
  28. package/built/cli/scan/singleScan.js +80 -0
  29. package/built/cli/scan/watchScan.js +102 -0
  30. package/built/cli/scan.js +39 -132
  31. package/built/cli/scanArgs.js +0 -1
  32. package/built/cli/scanOptions.js +0 -1
  33. package/built/cli/updateCommitStatus.js +10 -47
  34. package/built/cli/upload/command.js +20 -64
  35. package/built/cli/upload/options.js +0 -1
  36. package/built/cli/upload/pruneAppMap.js +16 -0
  37. package/built/cli/upload.js +91 -172
  38. package/built/cli/validateFile.js +13 -48
  39. package/built/cli.js +34 -21
  40. package/built/configuration/configurationProvider.js +151 -233
  41. package/built/configuration/schema/options.json +76 -76
  42. package/built/configuration/types/checkConfig.js +0 -1
  43. package/built/configuration/types/configuration.js +0 -1
  44. package/built/configuration/types/matchEventConfig.js +0 -1
  45. package/built/configuration/types/matchPatternConfig.js +0 -1
  46. package/built/database/index.js +35 -128
  47. package/built/database/visit.js +20 -68
  48. package/built/errors.js +4 -30
  49. package/built/eventUtil.js +10 -35
  50. package/built/findings.js +3 -4
  51. package/built/integration/appland/app/exists.js +33 -76
  52. package/built/integration/appland/app/listFindingStatus.js +5 -38
  53. package/built/integration/appland/appMap/create.js +38 -89
  54. package/built/integration/appland/location.js +0 -1
  55. package/built/integration/appland/mapset/create.js +34 -85
  56. package/built/integration/appland/retry.js +10 -11
  57. package/built/integration/appland/retryOptions.js +0 -1
  58. package/built/integration/appland/scannerJob/create.js +34 -84
  59. package/built/integration/appland/scannerJob/merge.js +28 -74
  60. package/built/integration/appland/scannerJob.js +0 -1
  61. package/built/integration/github/commitStatus.js +3 -4
  62. package/built/integration/vars.js +1 -2
  63. package/built/openapi/index.js +39 -83
  64. package/built/report/appMapMetadata.js +0 -1
  65. package/built/report/findingSummary.js +0 -1
  66. package/built/report/findingsReport.js +14 -16
  67. package/built/report/scanResults.js +50 -72
  68. package/built/report/scanSummary.js +0 -1
  69. package/built/report/summaryReport.js +12 -13
  70. package/built/ruleChecker.js +146 -297
  71. package/built/rules/authzBeforeAuthn.js +25 -59
  72. package/built/rules/circularDependency.js +69 -101
  73. package/built/rules/deserializationOfUntrustedData.js +29 -63
  74. package/built/rules/execOfUntrustedCommand.js +28 -62
  75. package/built/rules/http-500/metadata.js +0 -1
  76. package/built/rules/http-500/rule.js +2 -3
  77. package/built/rules/illegalPackageDependency.js +16 -18
  78. package/built/rules/incompatibleHttpClientRequest.js +30 -69
  79. package/built/rules/insecureCompare.js +12 -13
  80. package/built/rules/jobNotCancelled.js +13 -45
  81. package/built/rules/lib/hasParameterOrReceiver.js +4 -7
  82. package/built/rules/lib/matchEvent.js +12 -13
  83. package/built/rules/lib/matchPattern.js +6 -7
  84. package/built/rules/lib/metadata.js +0 -1
  85. package/built/rules/lib/parseRuleDescription.js +5 -6
  86. package/built/rules/lib/precedingEvents.js +7 -75
  87. package/built/rules/lib/rpcWithoutProtection.js +5 -28
  88. package/built/rules/lib/sanitizesData.js +0 -1
  89. package/built/rules/lib/util.js +34 -73
  90. package/built/rules/logoutWithoutSessionReset.js +24 -58
  91. package/built/rules/missingAuthentication.js +28 -28
  92. package/built/rules/missingContentType.js +8 -9
  93. package/built/rules/nPlusOneQuery.js +35 -87
  94. package/built/rules/queryFromInvalidPackage.js +17 -19
  95. package/built/rules/queryFromView.js +13 -16
  96. package/built/rules/rpcWithoutCircuitBreaker.js +14 -84
  97. package/built/rules/saveWithoutValidation.js +8 -9
  98. package/built/rules/secretInLog.js +30 -93
  99. package/built/rules/slowFunctionCall.js +16 -20
  100. package/built/rules/slowHttpServerRequest.js +9 -11
  101. package/built/rules/slowQuery.js +9 -12
  102. package/built/rules/tooManyJoins.js +26 -51
  103. package/built/rules/tooManyUpdates.js +25 -105
  104. package/built/rules/unbatchedMaterializedQuery.js +26 -30
  105. package/built/rules/updateInGetRequest.js +30 -45
  106. package/built/scope/commandScope.js +24 -144
  107. package/built/scope/httpClientRequestScope.js +11 -98
  108. package/built/scope/httpServerRequestScope.js +11 -98
  109. package/built/scope/rootScope.js +11 -98
  110. package/built/scope/scopeImpl.js +10 -82
  111. package/built/scope/scopeIterator.js +6 -10
  112. package/built/scope/sqlTransactionScope.js +24 -122
  113. package/built/sqlWarning.js +9 -35
  114. package/built/telemetry.js +215 -0
  115. package/built/wellKnownLabels.js +0 -1
  116. package/package.json +10 -3
  117. package/built/algorithms/dataStructures/graph/Graph.js.map +0 -1
  118. package/built/algorithms/dataStructures/graph/GraphEdge.js.map +0 -1
  119. package/built/algorithms/dataStructures/graph/GraphVertex.js.map +0 -1
  120. package/built/algorithms/dataStructures/linked-list/LinkedList.js.map +0 -1
  121. package/built/algorithms/dataStructures/linked-list/LinkedListNode.js.map +0 -1
  122. package/built/algorithms/graph/depth-first-search/index.js.map +0 -1
  123. package/built/algorithms/graph/detect-cycle/index.js.map +0 -1
  124. package/built/algorithms/utils/Comparator.js.map +0 -1
  125. package/built/analyzer/recordSecrets.js.map +0 -1
  126. package/built/analyzer/secretsRegexes.js.map +0 -1
  127. package/built/appMapIndex.js.map +0 -1
  128. package/built/check.js.map +0 -1
  129. package/built/checkInstance.js.map +0 -1
  130. package/built/cli/ci/command.js.map +0 -1
  131. package/built/cli/ci/options.js.map +0 -1
  132. package/built/cli/codeVersionArgs.js.map +0 -1
  133. package/built/cli/exitCode.js.map +0 -1
  134. package/built/cli/fail.js.map +0 -1
  135. package/built/cli/merge/command.js.map +0 -1
  136. package/built/cli/merge/options.js.map +0 -1
  137. package/built/cli/reportUploadURL.js.map +0 -1
  138. package/built/cli/resolveAppId.js.map +0 -1
  139. package/built/cli/scan/command.js.map +0 -1
  140. package/built/cli/scan/options.js.map +0 -1
  141. package/built/cli/scan/scanner.js.map +0 -1
  142. package/built/cli/scan.js.map +0 -1
  143. package/built/cli/scanArgs.js.map +0 -1
  144. package/built/cli/scanOptions.js.map +0 -1
  145. package/built/cli/updateCommitStatus.js.map +0 -1
  146. package/built/cli/upload/command.js.map +0 -1
  147. package/built/cli/upload/options.js.map +0 -1
  148. package/built/cli/upload.js.map +0 -1
  149. package/built/cli/validateFile.js.map +0 -1
  150. package/built/cli.js.map +0 -1
  151. package/built/configuration/configurationProvider.js.map +0 -1
  152. package/built/configuration/types/checkConfig.js.map +0 -1
  153. package/built/configuration/types/configuration.js.map +0 -1
  154. package/built/configuration/types/matchEventConfig.js.map +0 -1
  155. package/built/configuration/types/matchPatternConfig.js.map +0 -1
  156. package/built/database/index.js.map +0 -1
  157. package/built/database/visit.js.map +0 -1
  158. package/built/errors.js.map +0 -1
  159. package/built/eventUtil.js.map +0 -1
  160. package/built/findings.js.map +0 -1
  161. package/built/integration/appland/app/exists.js.map +0 -1
  162. package/built/integration/appland/app/listFindingStatus.js.map +0 -1
  163. package/built/integration/appland/appMap/create.js.map +0 -1
  164. package/built/integration/appland/location.js.map +0 -1
  165. package/built/integration/appland/mapset/create.js.map +0 -1
  166. package/built/integration/appland/retry.js.map +0 -1
  167. package/built/integration/appland/retryOptions.js.map +0 -1
  168. package/built/integration/appland/scannerJob/create.js.map +0 -1
  169. package/built/integration/appland/scannerJob/merge.js.map +0 -1
  170. package/built/integration/appland/scannerJob.js.map +0 -1
  171. package/built/integration/github/commitStatus.js.map +0 -1
  172. package/built/integration/vars.js.map +0 -1
  173. package/built/openapi/index.js.map +0 -1
  174. package/built/openapi/method.js +0 -120
  175. package/built/openapi/method.js.map +0 -1
  176. package/built/openapi/model.js +0 -49
  177. package/built/openapi/model.js.map +0 -1
  178. package/built/openapi/path.js +0 -36
  179. package/built/openapi/path.js.map +0 -1
  180. package/built/openapi/provider.js +0 -133
  181. package/built/openapi/provider.js.map +0 -1
  182. package/built/openapi/response.js +0 -59
  183. package/built/openapi/response.js.map +0 -1
  184. package/built/openapi/rpcRequest.js +0 -130
  185. package/built/openapi/rpcRequest.js.map +0 -1
  186. package/built/openapi/schema.js +0 -42
  187. package/built/openapi/schema.js.map +0 -1
  188. package/built/openapi/securitySchemes.js +0 -32
  189. package/built/openapi/securitySchemes.js.map +0 -1
  190. package/built/openapi/statusCodes.js +0 -68
  191. package/built/openapi/statusCodes.js.map +0 -1
  192. package/built/openapi/util.js +0 -91
  193. package/built/openapi/util.js.map +0 -1
  194. package/built/report/appMapMetadata.js.map +0 -1
  195. package/built/report/findingSummary.js.map +0 -1
  196. package/built/report/findingsReport.js.map +0 -1
  197. package/built/report/scanResults.js.map +0 -1
  198. package/built/report/scanSummary.js.map +0 -1
  199. package/built/report/summaryReport.js.map +0 -1
  200. package/built/ruleChecker.js.map +0 -1
  201. package/built/rules/authzBeforeAuthn.js.map +0 -1
  202. package/built/rules/circularDependency.js.map +0 -1
  203. package/built/rules/deserializationOfUntrustedData.js.map +0 -1
  204. package/built/rules/execOfUntrustedCommand.js.map +0 -1
  205. package/built/rules/http-500/metadata.js.map +0 -1
  206. package/built/rules/http-500/rule.js.map +0 -1
  207. package/built/rules/illegalPackageDependency.js.map +0 -1
  208. package/built/rules/incompatibleHttpClientRequest.js.map +0 -1
  209. package/built/rules/insecureCompare.js.map +0 -1
  210. package/built/rules/jobNotCancelled.js.map +0 -1
  211. package/built/rules/lib/hasParameterOrReceiver.js.map +0 -1
  212. package/built/rules/lib/matchEvent.js.map +0 -1
  213. package/built/rules/lib/matchPattern.js.map +0 -1
  214. package/built/rules/lib/metadata.js.map +0 -1
  215. package/built/rules/lib/parseRuleDescription.js.map +0 -1
  216. package/built/rules/lib/precedingEvents.js.map +0 -1
  217. package/built/rules/lib/rpcWithoutProtection.js.map +0 -1
  218. package/built/rules/lib/sanitizesData.js.map +0 -1
  219. package/built/rules/lib/util.js.map +0 -1
  220. package/built/rules/logoutWithoutSessionReset.js.map +0 -1
  221. package/built/rules/missingAuthentication.js.map +0 -1
  222. package/built/rules/missingContentType.js.map +0 -1
  223. package/built/rules/nPlusOneQuery.js.map +0 -1
  224. package/built/rules/queryFromInvalidPackage.js.map +0 -1
  225. package/built/rules/queryFromView.js.map +0 -1
  226. package/built/rules/rpcWithoutCircuitBreaker.js.map +0 -1
  227. package/built/rules/saveWithoutValidation.js.map +0 -1
  228. package/built/rules/secretInLog.js.map +0 -1
  229. package/built/rules/slowFunctionCall.js.map +0 -1
  230. package/built/rules/slowHttpServerRequest.js.map +0 -1
  231. package/built/rules/slowQuery.js.map +0 -1
  232. package/built/rules/tooManyJoins.js.map +0 -1
  233. package/built/rules/tooManyUpdates.js.map +0 -1
  234. package/built/rules/unbatchedMaterializedQuery.js.map +0 -1
  235. package/built/rules/updateInGetRequest.js.map +0 -1
  236. package/built/scope/commandScope.js.map +0 -1
  237. package/built/scope/httpClientRequestScope.js.map +0 -1
  238. package/built/scope/httpServerRequestScope.js.map +0 -1
  239. package/built/scope/rootScope.js.map +0 -1
  240. package/built/scope/scopeImpl.js.map +0 -1
  241. package/built/scope/scopeIterator.js.map +0 -1
  242. package/built/scope/sqlTransactionScope.js.map +0 -1
  243. package/built/sqlWarning.js.map +0 -1
  244. 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
- var util_1 = require("../../rules/lib/util");
43
- var merge_1 = require("../../integration/appland/scannerJob/merge");
44
- var resolveAppId_1 = __importDefault(require("../resolveAppId"));
45
- var updateCommitStatus_1 = __importDefault(require("../updateCommitStatus"));
46
- var fail_1 = __importDefault(require("../fail"));
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: function (args) {
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: function (options) {
71
- return __awaiter(this, void 0, void 0, function () {
72
- var _a, isVerbose, appIdArg, failOption, updateCommitStatusOption, mergeKey, appId, mergeResults;
73
- return __generator(this, function (_b) {
74
- switch (_b.label) {
75
- case 0:
76
- _a = options, isVerbose = _a.verbose, appIdArg = _a.app, failOption = _a.fail, updateCommitStatusOption = _a.updateCommitStatus, mergeKey = _a.mergeKey;
77
- if (isVerbose) {
78
- (0, util_1.verbose)(true);
79
- }
80
- return [4 /*yield*/, (0, resolveAppId_1.default)(appIdArg, '.')];
81
- case 1:
82
- appId = _b.sent();
83
- return [4 /*yield*/, (0, merge_1.merge)(appId, mergeKey)];
84
- case 2:
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,3 +1,2 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=options.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
- var message = "Uploaded ".concat(numFindings, " findings");
4
+ let message = `Uploaded ${numFindings} findings`;
5
5
  if (url) {
6
- message += " to ".concat(url);
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
- var fs_1 = require("fs");
40
- var promises_1 = require("fs/promises");
41
- var js_yaml_1 = require("js-yaml");
42
- var path_1 = require("path");
43
- var exists_1 = require("../integration/appland/app/exists");
44
- var errors_1 = require("../errors");
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
- var searchPath, configPath, _a, configContent, config;
48
- return __generator(this, function (_b) {
49
- switch (_b.label) {
50
- case 0:
51
- if (appIdArg) {
52
- return [2 /*return*/, appIdArg];
53
- }
54
- if (!appMapDir) return [3 /*break*/, 7];
55
- searchPath = (0, path_1.resolve)(appMapDir);
56
- _b.label = 1;
57
- case 1:
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
- return [3 /*break*/, 1];
71
- case 5: return [4 /*yield*/, (0, promises_1.readFile)(configPath, 'utf-8')];
72
- case 6:
73
- configContent = _b.sent();
74
- config = (0, js_yaml_1.load)(configContent);
75
- if (config.name)
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
- var appId, appExists;
86
- return __generator(this, function (_a) {
87
- switch (_a.label) {
88
- case 0: return [4 /*yield*/, resolveAppId(appIdArg, appMapDir)];
89
- case 1:
90
- appId = _a.sent();
91
- if (!appId)
92
- throw new errors_1.ValidationError('App was not provided and could not be resolved');
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
- var glob_1 = require("glob");
90
- var promises_1 = require("fs/promises");
91
- var util_1 = require("util");
92
- var configurationProvider_1 = require("../../configuration/configurationProvider");
93
- var errors_1 = require("../../errors");
94
- var util_2 = require("../../rules/lib/util");
95
- var findings_1 = require("../../findings");
96
- var findingsReport_1 = __importDefault(require("../../report/findingsReport"));
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: function (args) {
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: function (options) {
123
- return __awaiter(this, void 0, void 0, function () {
124
- var appmapDir, _a, appmapFile, config, isVerbose, reportAllFindings, appIdArg, apiKey, ide, reportFile, appId, files, glob, configData, scanner, startTime, _b, rawScanResults, findingStatuses, scanResults, elapsed, numChecks;
125
- var _this = this;
126
- return __generator(this, function (_c) {
127
- switch (_c.label) {
128
- case 0:
129
- appmapDir = options.appmapDir;
130
- _a = options, appmapFile = _a.appmapFile, config = _a.config, isVerbose = _a.verbose, reportAllFindings = _a.all, appIdArg = _a.app, apiKey = _a.apiKey, ide = _a.ide, reportFile = _a.reportFile;
131
- if (isVerbose) {
132
- (0, util_2.verbose)(true);
133
- }
134
- if (apiKey) {
135
- process.env.APPLAND_API_KEY = apiKey;
136
- }
137
- if (appmapFile && appmapDir) {
138
- throw new errors_1.ValidationError('Use --appmap-dir or --appmap-file, but not both');
139
- }
140
- if (!(!appmapFile && !appmapDir)) return [3 /*break*/, 2];
141
- return [4 /*yield*/, (0, util_2.appmapDirFromConfig)()];
142
- case 1:
143
- appmapDir = _c.sent();
144
- _c.label = 2;
145
- case 2:
146
- if (!appmapFile && !appmapDir) {
147
- throw new errors_1.ValidationError('Either --appmap-dir or --appmap-file is required');
148
- }
149
- appId = appIdArg;
150
- if (!!reportAllFindings) return [3 /*break*/, 4];
151
- return [4 /*yield*/, (0, resolveAppId_1.default)(appIdArg, appmapDir)];
152
- case 3:
153
- appId = _c.sent();
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
+ }
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=options.js.map