@appland/scanner
Advanced tools
Comparing version 1.67.0 to 1.68.0
@@ -25,2 +25,3 @@ "use strict"; | ||
const handleWorkingDirectory_1 = require("../handleWorkingDirectory"); | ||
const interactiveScan_1 = __importDefault(require("./interactiveScan")); | ||
exports.default = { | ||
@@ -31,2 +32,6 @@ command: 'scan', | ||
(0, scanArgs_1.default)(args); | ||
args.option('interactive', { | ||
describe: 'scan in interactive mode', | ||
alias: 'i', | ||
}); | ||
args.option('appmap-file', { | ||
@@ -55,3 +60,3 @@ describe: 'single file to scan, or repeat this option to scan multiple specific files', | ||
let { appmapDir } = options; | ||
const { appmapFile, config, directory, verbose: isVerbose, all: reportAllFindings, watch, app: appIdArg, apiKey, ide, reportFile, } = options; | ||
const { appmapFile, directory, interactive, config: configFile, verbose: isVerbose, all: reportAllFindings, watch, app: appIdArg, apiKey, ide, reportFile, } = options; | ||
if (isVerbose) { | ||
@@ -70,5 +75,2 @@ (0, util_1.verbose)(true); | ||
} | ||
if (appIdArg && watch) { | ||
throw new errors_1.ValidationError(`Don't use --app with --watch, because in watch mode all findings are reported`); | ||
} | ||
if (!appmapFile && !appmapDir) { | ||
@@ -79,21 +81,29 @@ appmapDir = (yield (0, appmapDirFromConfig_1.appmapDirFromConfig)()) || '.'; | ||
yield (0, validateFile_1.default)('directory', appmapDir); | ||
let appId = appIdArg; | ||
if (!reportAllFindings) | ||
appId = yield (0, resolveAppId_1.default)(appIdArg, appmapDir); | ||
if (watch) { | ||
const watchAppMapDir = appmapDir; | ||
return (0, watchScan_1.default)({ appmapDir: watchAppMapDir, configFile: config }); | ||
return (0, watchScan_1.default)({ appId, appmapDir: watchAppMapDir, configFile }); | ||
} | ||
else { | ||
let appId = appIdArg; | ||
if (!reportAllFindings) { | ||
appId = yield (0, resolveAppId_1.default)(appIdArg, appmapDir); | ||
const configuration = yield (0, configurationProvider_1.parseConfigFile)(configFile); | ||
if (interactive) { | ||
return (0, interactiveScan_1.default)({ | ||
appmapFile, | ||
appmapDir, | ||
configuration, | ||
}); | ||
} | ||
const configData = yield (0, configurationProvider_1.parseConfigFile)(config); | ||
return (0, singleScan_1.default)({ | ||
appmapFile, | ||
appmapDir, | ||
configData, | ||
reportAllFindings, | ||
appId, | ||
ide, | ||
reportFile, | ||
}); | ||
else { | ||
return (0, singleScan_1.default)({ | ||
appmapFile, | ||
appmapDir, | ||
configuration, | ||
reportAllFindings, | ||
appId, | ||
ide, | ||
reportFile, | ||
}); | ||
} | ||
} | ||
@@ -100,0 +110,0 @@ }); |
@@ -15,6 +15,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const util_1 = require("util"); | ||
const promises_1 = require("fs/promises"); | ||
const glob_1 = require("glob"); | ||
const validateFile_1 = __importDefault(require("../validateFile")); | ||
const scanner_1 = __importDefault(require("./scanner")); | ||
@@ -27,15 +24,10 @@ const errors_1 = require("../../errors"); | ||
const telemetry_1 = __importDefault(require("../../telemetry")); | ||
const util_1 = require("../../rules/lib/util"); | ||
const validateFile_1 = __importDefault(require("../validateFile")); | ||
function singleScan(options) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const { appmapFile, appmapDir, configData, reportAllFindings, appId, ide, reportFile } = options; | ||
let files = []; | ||
if (appmapDir) { | ||
const glob = (0, util_1.promisify)(glob_1.glob); | ||
files = yield glob(`${appmapDir}/**/*.appmap.json`); | ||
} | ||
if (appmapFile) { | ||
files = typeof appmapFile === 'string' ? [appmapFile] : appmapFile; | ||
yield Promise.all(files.map((file) => __awaiter(this, void 0, void 0, function* () { return (0, validateFile_1.default)('file', file); }))); | ||
} | ||
const scanner = yield (0, scanner_1.default)(reportAllFindings, configData, files).catch((error) => { | ||
const { appmapFile, appmapDir, configuration, reportAllFindings, appId, ide, reportFile } = options; | ||
const files = yield (0, util_1.collectAppMapFiles)(appmapFile, appmapDir); | ||
yield Promise.all(files.map((file) => __awaiter(this, void 0, void 0, function* () { return (0, validateFile_1.default)('file', file); }))); | ||
const scanner = yield (0, scanner_1.default)(reportAllFindings, configuration, files).catch((error) => { | ||
throw new errors_1.ValidationError(error.message + '\nUse --all to perform an offline scan.'); | ||
@@ -42,0 +34,0 @@ }); |
@@ -27,3 +27,4 @@ "use strict"; | ||
class RuleChecker { | ||
constructor() { | ||
constructor(progress) { | ||
this.progress = progress; | ||
this.scopes = { | ||
@@ -37,11 +38,10 @@ root: new rootScope_1.default(), | ||
} | ||
check(appMapFile, appMapIndex, check, findings) { | ||
check(appMapFileName, appMapIndex, check, findings) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const scope = check.scope; | ||
if ((0, util_1.verbose)()) { | ||
console.warn(`Checking AppMap ${appMapIndex.appMap.name} with scope ${scope}`); | ||
console.warn(`Checking AppMap ${appMapIndex.appMap.name} with scope ${check.scope}`); | ||
} | ||
const scopeIterator = this.scopes[scope]; | ||
const scopeIterator = this.scopes[check.scope]; | ||
if (!scopeIterator) { | ||
throw new errors_1.AbortError(`Invalid scope name "${scope}"`); | ||
throw new errors_1.AbortError(`Invalid scope name "${check.scope}"`); | ||
} | ||
@@ -58,2 +58,4 @@ const callEvents = function* () { | ||
} | ||
if (this.progress) | ||
yield this.progress.filterScope(check.scope, scope.scope); | ||
const checkInstance = new checkInstance_1.default(check); | ||
@@ -63,14 +65,18 @@ if (!check.filterScope(scope.scope, appMapIndex)) { | ||
} | ||
if (this.progress) | ||
yield this.progress.enterScope(scope.scope); | ||
if (checkInstance.enumerateScope) { | ||
for (const event of scope.events()) { | ||
yield this.checkEvent(event, scope.scope, appMapFile, appMapIndex, checkInstance, findings); | ||
yield this.checkEvent(event, scope.scope, appMapFileName, appMapIndex, checkInstance, findings); | ||
} | ||
} | ||
else { | ||
yield this.checkEvent(scope.scope, scope.scope, appMapFile, appMapIndex, checkInstance, findings); | ||
yield this.checkEvent(scope.scope, scope.scope, appMapFileName, appMapIndex, checkInstance, findings); | ||
} | ||
if (this.progress) | ||
yield this.progress.leaveScope(); | ||
} | ||
}); | ||
} | ||
checkEvent(event, scope, appMapFile, appMapIndex, checkInstance, findings) { | ||
checkEvent(event, scope, appMapFileName, appMapIndex, checkInstance, findings) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -89,2 +95,4 @@ if (!event.isCall()) { | ||
} | ||
if (this.progress) | ||
yield this.progress.filterEvent(event); | ||
if (!checkInstance.filterEvent(event, appMapIndex)) { | ||
@@ -125,3 +133,3 @@ return; | ||
return { | ||
appMapFile, | ||
appMapFile: appMapFileName, | ||
checkId: checkInstance.checkId, | ||
@@ -143,3 +151,7 @@ ruleId: checkInstance.ruleId, | ||
}; | ||
if (this.progress) | ||
yield this.progress.matchEvent(event, appMapIndex); | ||
const matchResult = yield checkInstance.ruleLogic.matcher(event, appMapIndex, checkInstance.filterEvent.bind(checkInstance)); | ||
if (this.progress) | ||
yield this.progress.matchResult(event, matchResult); | ||
const numFindings = findings.length; | ||
@@ -146,0 +158,0 @@ if (matchResult === true) { |
@@ -10,3 +10,6 @@ "use strict"; | ||
function parseRuleDescription(id) { | ||
const content = fs_1.default.readFileSync((0, path_1.join)(__dirname, `../../../doc/rules/${(0, util_1.dasherize)(id)}.md`), 'utf-8'); | ||
const docPath = (0, path_1.join)(__dirname, `../../../doc/rules/${(0, util_1.dasherize)(id)}.md`); | ||
if (!fs_1.default.existsSync(docPath)) | ||
return `No doc exists for rule ${id}`; | ||
const content = fs_1.default.readFileSync(docPath, 'utf-8'); | ||
const propertiesContent = content.match(/---\n((?:.*\n)+)---\n((?:.*\n)+?)##?#?/); | ||
@@ -13,0 +16,0 @@ if (!propertiesContent) { |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.verbose = exports.toRegExpArray = exports.responseContentType = exports.toRegExp = exports.providesAuthentication = exports.pluralize = exports.dasherize = exports.camelize = exports.parseValue = exports.isRoot = exports.ideLink = exports.isTruthy = exports.isFalsey = exports.emptyValue = exports.capitalize = exports.appMapDir = void 0; | ||
exports.verbose = exports.toRegExpArray = exports.responseContentType = exports.toRegExp = exports.providesAuthentication = exports.pluralize = exports.dasherize = exports.camelize = exports.parseValue = exports.isRoot = exports.ideLink = exports.isTruthy = exports.isFalsey = exports.emptyValue = exports.capitalize = exports.appMapDir = exports.collectAppMapFiles = void 0; | ||
const path_1 = require("path"); | ||
const util_1 = require("util"); | ||
const glob_1 = require("glob"); | ||
const assert_1 = __importDefault(require("assert")); | ||
function collectAppMapFiles(appmapFile, appmapDir) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let files = []; | ||
if (appmapDir) { | ||
const glob = (0, util_1.promisify)(glob_1.glob); | ||
files = yield glob(`${appmapDir}/**/*.appmap.json`); | ||
} | ||
else { | ||
(0, assert_1.default)(appmapFile, 'Either appmapDir or appmapFile is required'); | ||
files = typeof appmapFile === 'string' ? [appmapFile] : appmapFile; | ||
} | ||
return files; | ||
}); | ||
} | ||
exports.collectAppMapFiles = collectAppMapFiles; | ||
let isVerbose = false; | ||
@@ -6,0 +36,0 @@ function verbose(v = null) { |
@@ -0,1 +1,14 @@ | ||
# [@appland/scanner-v1.68.0](https://github.com/applandinc/appmap-js/compare/@appland/scanner-v1.67.0...@appland/scanner-v1.68.0) (2022-08-19) | ||
### Bug Fixes | ||
* Allow rule doc to be missing ([85a22fc](https://github.com/applandinc/appmap-js/commit/85a22fcaf777ab3794300d3ad52057be6ace4a87)) | ||
### Features | ||
* Enhanced breakpoints ([b338bc9](https://github.com/applandinc/appmap-js/commit/b338bc9c1beebf3fbc78fb57bb72e4738c0ed5e6)) | ||
* Interactive rule evaluator ([d0a0846](https://github.com/applandinc/appmap-js/commit/d0a08466ed0e92484a4c195c74cbb737a2cb40d6)) | ||
# [@appland/scanner-v1.67.0](https://github.com/applandinc/appmap-js/compare/@appland/scanner-v1.66.0...@appland/scanner-v1.67.0) (2022-08-10) | ||
@@ -2,0 +15,0 @@ |
@@ -11,3 +11,3 @@ --- | ||
Identifies when an HTTP server requset has returned a 500 status code. HTTP 500 status code | ||
Identifies when an HTTP server request has returned a 500 status code. HTTP 500 status code | ||
generally indicate an unanticipated problem in the backend that is not handled in a predictable way. | ||
@@ -14,0 +14,0 @@ 500 status codes are also hard for client code to handle, because they don't indicate any particular |
{ | ||
"name": "@appland/scanner", | ||
"version": "1.67.0", | ||
"version": "1.68.0", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "bin": "built/cli.js", |
Uses eval
Supply chain riskPackage uses eval() which is a dangerous function. This prevents the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
392679
201
6764
54
1