UNPKG

tslint-filter

Version:

Suppress and extend TSLint linting errors, before they get returned to the console or your code editor

138 lines (137 loc) 5.18 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const toRegexRange = require("to-regex-range"); const Lint = require("tslint"); function addFilter(ruleFile, options = {}) { const linterOrError = getLinter(ruleFile); if (linterOrError instanceof Error) { const error = linterOrError; class Rule extends Lint.Rules.AbstractRule { apply(sourceFile) { return [getFailureByError(error, ruleFile, this.ruleName, sourceFile)]; } } Rule.metadata = { ruleName: getRuleNameByFileName(ruleFile), type: 'functionality', description: `Error while loading '${ruleFile}'.`, optionsDescription: 'Not configurable.', options: null, typescriptOnly: false }; return { Rule }; } const linter = linterOrError; const RulePrototype = linter.Rule.prototype; if (Lint.isTypedRule(RulePrototype)) { RulePrototype.applyWithProgram = applyWithFilter(linter, RulePrototype.applyWithProgram, ruleFile, options); } else { RulePrototype.apply = applyWithFilter(linter, RulePrototype.apply, ruleFile, options); } return linter; } addFilter.rulesDirectory = '../rules'; module.exports = addFilter; function getLinter(ruleFile) { try { return require(ruleFile); } catch (error) { if (error instanceof Error) { return error; } return new Error(`Unable to load ${ruleFile}.`); } } function applyWithFilter(linter, originalApplyMethod, ruleFile, options) { const ruleName = linter.Rule.metadata.ruleName; return function (sourceFile, program) { this.options.ruleName = ruleName; this.ruleName = ruleName; const ignorePatternsOrFailure = extractIgnorePatterns(this, sourceFile); let failures; try { if (program === undefined) { failures = originalApplyMethod.call(this, sourceFile); } else { failures = originalApplyMethod.call(this, sourceFile, program); } } catch (error) { failures = [getFailureByError(error, ruleFile, this.ruleName, sourceFile)]; } if (typeof options.modifyFailure === 'function') { const modifyFailure = options.modifyFailure.bind(this); failures = failures .map((failure) => updateFailure(sourceFile, failure, modifyFailure(failure, sourceFile, program))) .filter(isFailure); } if (ignorePatternsOrFailure instanceof Lint.RuleFailure) { failures.push(ignorePatternsOrFailure); } else if (ignorePatternsOrFailure !== undefined) { failures = failures.filter((failure) => (!ignorePatternsOrFailure.some((regex) => regex.test(failure.getFailure())))); } return failures; }; } function getRuleNameByFileName(ruleFile) { return ruleFile.replace(/^.*\/|Rule\.?.*$/g, '').replace(/([A-Z])/g, '-$1').toLowerCase(); } function extractIgnorePatterns(rule, sourceFile) { const ruleArguments = rule.getOptions().ruleArguments; const lastRuleArgument = ruleArguments[ruleArguments.length - 1]; if (!Array.isArray(lastRuleArgument)) { return undefined; } let ignorePatterns; try { ignorePatterns = lastRuleArgument.map(stringToRegExp); } catch (error) { if (error instanceof Error) { return new Lint.RuleFailure(sourceFile, 0, 1, `TSLint-Filter ignore pattern: ${error.message}`, rule.ruleName); } return undefined; } rule.ruleArguments = ruleArguments.slice(0, -1); rule.options.ruleArguments = rule.ruleArguments; return ignorePatterns; } function stringToRegExp(str) { return new RegExp(str.replace(/\[(\d*)\.\.\.(\d*)\]/g, (_match, p1, p2) => toRegexRange(p1 !== '' ? p1 : -999999999999999, p2 !== '' ? p2 : 999999999999999, { shorthand: true }))); } function getFailureByError(error, ruleFile, originalRuleName, sourceFile) { let title; let message; if (error instanceof Error) { title = error.name; message = error.message.replace(/\n.+/g, ''); } else if (typeof error === 'string') { title = 'Error'; message = error; } else { title = 'Unhandled error'; if (error !== null && error !== undefined) { message = `Unknown error of type ${error.constructor.name}`; } else { message = `Unknown error of type '${typeof error}'`; } } return new Lint.RuleFailure(sourceFile, 0, 1, `${title} in '${ruleFile}': ${message}. Rule is disabled for this file`, originalRuleName); } function updateFailure(sourceFile, failure, newFailure) { if (typeof newFailure === 'string') { return new Lint.RuleFailure(sourceFile, failure.getStartPosition().getPosition(), failure.getEndPosition().getPosition(), newFailure, failure.getRuleName(), failure.getFix()); } return newFailure; } function isFailure(failure) { return failure !== undefined; }