diff --git a/.gitignore b/.gitignore index 1f274d955..5314662bf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,7 @@ +.npm_cache node_modules npm-debug.log -# TypeScrit temporary/cache files -**/.baseDir.ts -**/.tscache/ -tscommand-*.tmp.txt - -**/dist/ - # IDEA .idea tslint-microsoft-contrib.iml @@ -15,10 +9,6 @@ tslint-microsoft-contrib.iml # vim swap files *.sw* -**/tags - -# local npm cache -.npm_cache - -out.html +# Generated for builds +**/dist/ rule-metadata.json diff --git a/.prettierignore b/.prettierignore index bbdf00961..c98aab7fe 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,15 +1,11 @@ # Build directory dist/ +# Configuration and npm settings +*.json + # Definition files *.d.ts -# NPM files -package.json -package-lock.json - # Test files test-data/NoUnnecessarySemicolonsTestInput.ts - -# Generated files -recommended_ruleset.js diff --git a/README.md b/README.md index 99980dad4..b1a113a99 100644 --- a/README.md +++ b/README.md @@ -40,23 +40,59 @@ Add `"node_modules/tslint-microsoft-contrib"` under your `"rulesDirectory"` conf ### Which Rules Should I Turn On? There certainly are a lot of options! -To start, you can enable our recommended defaults ([recommended_ruleset.js](recommended_ruleset.js)) by adding `"tslint-microsoft-contrib"` under `"extends"` in your `tslint.json`: + +If you extend from one of the following configurations, `rulesDirectory` will have `node_modules/tslint-microsoft-contrib` included for you. + +> Please note, some of the default ruleset rules require the `--project` TSLint option. + +#### Recommended + +To start, you can enable our stable "recommended" defaults that come with tslint-microsoft-contrib ([recommended.json](./recommended.json)) by adding `"tslint-microsoft-contrib/recommended"` under `"extends"` in your `tslint.json`: ```json { - "extends": ["tslint-microsoft-contrib"], - "rulesDirectory": ["node_modules/tslint-microsoft-contrib"], - "rules": { - // ... - } + "extends": ["tslint-microsoft-contrib/recommended"] + // ... } ``` -You can then disable rules you don't find useful. +These rules will not be added to in minor or patch releases, but will be in major releases. + +#### Latest + +To run with the latest and greatest rules ([latest.json](./latest.json)), extend from `tslint-microsoft-contrib/latest`: + +```json +{ + "extends": ["tslint-microsoft-contrib/latest"] + // ... +} +``` + +These rules will not be added to in patch releases, but will be in minor releases. + +#### Legacy + +The old "recommended" ruleset that ships by extending `tslint-microsoft-contrib` itself contains a list of rules that includes core TSLint rules. + +To start, you can enable our recommended defaults ([recommended.json](./recommended.json)) by adding just `"tslint-microsoft-contrib"` under `"extends"` in your `tslint.json`: + +```json +{ + "extends": ["tslint-microsoft-contrib"] + // ... +} +``` + +**This ruleset is considered legacy**; it is generally preferable to extend from the 'recommended' or 'latest' rulesets. +We recommend you instead explicitly include `tslint:recommended`, `tslint:latest`, or `tslint:all` in your `tslint.json` rather than enable core rules through this configuration. + +In the next major version of TSLint, this will instead be an alis for `"tslint-microsoft-contrib/recommended"`. + +### Overriding Configurations -Please note, some of the default rules require the `--project` TSLint option. +You can [disable rules](https://palantir.github.io/tslint/usage/rule-flags) you don't find useful. -Also, please note that adding a rule to the recommended ruleset is considered backwards compatible. If you rely on version ranges in your dependencies then you may find that new rules being added to the product create violations and fail your build. We recommend you specify exact versions of lint libraries, including `tslint-microsoft-contrib`, in your `package.json`. diff --git a/build-tasks/common/files.js b/build-tasks/common/files.js index 5ead290e0..d07b11e66 100644 --- a/build-tasks/common/files.js +++ b/build-tasks/common/files.js @@ -2,6 +2,15 @@ const { red } = require('chalk'); const fs = require('fs'); const stripJsonComments = require('strip-json-comments'); +function readDirectory(directoryName) { + try { + return fs.readdirSync(directoryName); + } catch (e) { + console.log(red(`Unable to read directory: ${directoryName}. Error code: ${e.code}`)); + process.exit(1); + } +} + function readFile(fileName) { try { return fs.readFileSync(fileName, { encoding: 'utf8' }); @@ -39,6 +48,7 @@ function readJSONWithComments(fileName) { } module.exports = { + readDirectory, readFile, readJSON, readJSONWithComments, diff --git a/build-tasks/common/meta.js b/build-tasks/common/meta.js index 57be173b5..6e6f2494c 100644 --- a/build-tasks/common/meta.js +++ b/build-tasks/common/meta.js @@ -2,9 +2,9 @@ const path = require('path'); const glob = require('glob'); const { readJSON } = require('./files'); -function getAllRules() { +function getAllRules({ ignoreTslintRules = false } = {}) { const contribRules = glob.sync('dist/build/*Rule.js'); - const baseRules = glob.sync('node_modules/tslint/lib/rules/*Rule.js'); + const baseRules = ignoreTslintRules ? [] : glob.sync('node_modules/tslint/lib/rules/*Rule.js'); return contribRules.concat(baseRules); } diff --git a/build-tasks/copy-config-json.js b/build-tasks/copy-config-json.js new file mode 100644 index 000000000..c476f567f --- /dev/null +++ b/build-tasks/copy-config-json.js @@ -0,0 +1,21 @@ +/** + * Converts configs/*.json to ./dist/build/*.json. + */ + +const mkdirp = require('mkdirp'); +const path = require('path'); + +const { readDirectory, readFile, writeFile } = require('./common/files'); + +const copyConfigFile = (configFileName, destinationFileName) => { + const resolvedDestination = path.resolve(destinationFileName); + const data = readFile(path.resolve(configFileName)); + + writeFile(resolvedDestination, data.replace(/"rulesDirectory": \[(.*)\]/, `"rulesDirectory": ["./"]`)); +}; + +mkdirp.sync('./dist/build'); + +for (const configFileName of readDirectory('./configs')) { + copyConfigFile(`./configs/${configFileName}`, `./dist/build/${configFileName}`); +} diff --git a/build-tasks/generate-default-tslint-json.js b/build-tasks/generate-default-tslint-json.js deleted file mode 100644 index b9982fc4d..000000000 --- a/build-tasks/generate-default-tslint-json.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Converts recommended_ruleset.js to ./dist/build/tslint.json. - */ - -const path = require('path'); -const { writeFile } = require('./common/files'); - -const data = require(path.resolve('recommended_ruleset.js')); -data.rulesDirectory = './'; - -writeFile('dist/build/tslint.json', JSON.stringify(data, undefined, 4)); diff --git a/build-tasks/generate-latest-config.js b/build-tasks/generate-latest-config.js new file mode 100644 index 000000000..cb59ad46e --- /dev/null +++ b/build-tasks/generate-latest-config.js @@ -0,0 +1,47 @@ +/** + * Generates config/latest.json. + * The `recommended` metadata for each rule is added there, except if... + * - ...the rule's `metadata.group` is `'Ignored'` + * - ...the rule is also mentioned in config/recommended.json + * - ...the recommended setting starts with `false` (the rule is likely deprecated) + */ + +const { writeFile } = require('./common/files'); +const { getAllRules, getMetadataFromFile, getMetadataValue } = require('./common/meta'); + +const recommendations = []; + +const recommendedRules = new Set(Object.keys(require('../configs/recommended.json').rules)); + +getAllRules({ + ignoreTslintRules: true +}).forEach(ruleFile => { + const metadata = getMetadataFromFile(ruleFile); + const ruleName = getMetadataValue(metadata, 'ruleName'); + + const groupName = getMetadataValue(metadata, 'group'); + if (groupName === 'Ignored') { + return; + } + + let recommendation = getMetadataValue(metadata, 'recommendation', true, true); + if (recommendation === '') { + recommendation = 'true'; + } + + // Don't mention rules recommended as disabled + if (recommendation.startsWith('false')) { + return; + } + + // Don't redundantly mention rules added to the 'recommended' preset + if (recommendedRules.has(ruleName)) { + return; + } + + recommendations.push(` "${ruleName}": ${recommendation}`); +}); + +const latestTemplate = require('./templates/latest.json.template'); + +writeFile('configs/latest.json', latestTemplate(recommendations)); diff --git a/build-tasks/generate-recommendations.js b/build-tasks/generate-recommendations.js deleted file mode 100644 index d90845e93..000000000 --- a/build-tasks/generate-recommendations.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Generates the recommended_ruleset.js file. - */ - -const { red } = require('chalk'); -const { writeFile } = require('./common/files'); -const { getAllRules, getMetadataFromFile, getMetadataValue } = require('./common/meta'); -const groupedRows = {}; -const warnings = []; - -/** - * @see https://github.com/Microsoft/tslint-microsoft-contrib/issues/694 - */ -const ignoredRulesNotYetAdded = new Set(['ban-ts-ignore', 'comment-type', 'no-default-import', 'unnecessary-constructor']); - -getAllRules().forEach(ruleFile => { - const metadata = getMetadataFromFile(ruleFile); - - const ruleName = getMetadataValue(metadata, 'ruleName'); - if (ignoredRulesNotYetAdded.has(ruleName)) { - return; - } - - const groupName = getMetadataValue(metadata, 'group'); - if (groupName === 'Ignored') { - return; - } - if (groupName === '') { - warnings.push('Could not generate recommendation for rule file: ' + ruleFile); - } - if (groupedRows[groupName] === undefined) { - groupedRows[groupName] = []; - } - - let recommendation = getMetadataValue(metadata, 'recommendation', true, true); - if (recommendation === '') { - recommendation = 'true,'; - } - // Replace double quotes with single quote - recommendation = recommendation.replace(/"/g, "'"); - - groupedRows[groupName].push(` '${ruleName}': ${recommendation}`); -}); - -if (warnings.length > 0) { - console.log('\n' + red(warnings.join('\n'))); - process.exit(1); -} -Object.keys(groupedRows).forEach(groupName => groupedRows[groupName].sort()); - -const recommendedTemplate = require('./templates/recommended_ruleset.template'); -const data = recommendedTemplate(groupedRows); - -writeFile('recommended_ruleset.js', data); diff --git a/build-tasks/templates/latest.json.template.js b/build-tasks/templates/latest.json.template.js new file mode 100644 index 000000000..bd480177f --- /dev/null +++ b/build-tasks/templates/latest.json.template.js @@ -0,0 +1,8 @@ +module.exports = recommendations => `{ + "extends": ["./recommended.json"], + "rulesDirectory": ["../"], + "rules": { +${[...recommendations].sort().join(',\n')} + } +} +`; diff --git a/build-tasks/templates/recommended_ruleset.template.js b/build-tasks/templates/recommended_ruleset.template.js deleted file mode 100644 index ae230aa94..000000000 --- a/build-tasks/templates/recommended_ruleset.template.js +++ /dev/null @@ -1,49 +0,0 @@ -module.exports = rows => - `/** - * These rule settings are a broad, general recommendation for a good default configuration. - * This file is exported in the npm/nuget package as ./tslint.json. - */ -module.exports = { - 'rules': { - /** - * Security Rules. The following rules should be turned on because they find security issues - * or are recommended in the Microsoft Secure Development Lifecycle (SDL) - */ -${rows.Security.join('\n')} - - /** - * Common Bugs and Correctness. The following rules should be turned on because they find - * common bug patterns in the code or enforce type safety. - */ -${rows.Correctness.join('\n')} - - /** - * Code Clarity. The following rules should be turned on because they make the code - * generally more clear to the reader. - */ -${rows.Clarity.join('\n')} - - /** - * Accessibility. The following rules should be turned on to guarantee the best user - * experience for keyboard and screen reader users. - */ -${rows.Accessibility.join('\n')} - - /** - * Whitespace related rules. The only recommended whitespace strategy is to pick a single format and - * be consistent. - */ -${rows.Whitespace.join('\n')} - - /** - * Controversial/Configurable rules. - */ -${rows.Configurable.join('\n')} - - /** - * Deprecated rules. The following rules are deprecated for various reasons. - */ -${rows.Deprecated.join('\n')} - } -}; -`; diff --git a/build-tasks/validate-config.js b/build-tasks/validate-config.js deleted file mode 100644 index 7cdadfc0d..000000000 --- a/build-tasks/validate-config.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Makes sure all the rules in the project are defined to run during the build. - */ - -const { yellow, yellowBright } = require('chalk'); -const { readJSONWithComments } = require('./common/files'); -const { getContribRuleNames } = require('./common/meta'); - -const tslintConfig = readJSONWithComments('tslint.json'); - -function ruleIsEnabled(value) { - if (value === undefined) { - return false; - } - - if (typeof value === 'boolean') { - return value; - } - - return value[0]; -} - -const disabledRules = new Set([ - 'missing-jsdoc', - 'no-duplicate-case', - 'no-empty-interfaces', - 'no-empty-line-after-opening-brace', - 'no-function-constructor-with-string-args', - 'no-increment-decrement', - 'no-multiline-string', - 'no-reserved-keywords', - 'no-relative-imports', - 'no-stateless-class', - 'no-unexternalized-strings', - 'no-unnecessary-bind', - 'no-unnecessary-semicolons', - 'no-var-self', - 'react-tsx-curly-spacing', - 'valid-typeof' -]); - -const errors = []; -getContribRuleNames().forEach(ruleName => { - if (disabledRules.has(ruleName)) { - return; - } - - if (!ruleIsEnabled(tslintConfig.rules[ruleName])) { - errors.push('A tslint-microsoft-contrib rule was found that is not enabled on the project: ' + ruleName); - } -}); - -if (errors.length > 0) { - console.log(yellow(errors.join('\n'))); - console.log(yellowBright(`Add the missing rule${errors.length === 1 ? '' : 's'} to tslint.json.`)); - process.exit(1); -} diff --git a/configs/latest.json b/configs/latest.json new file mode 100644 index 000000000..8e9892034 --- /dev/null +++ b/configs/latest.json @@ -0,0 +1,8 @@ +{ + "extends": ["./recommended.json"], + "rulesDirectory": ["../"], + "rules": { + "react-a11y-iframes": true, + "void-zero": true + } +} diff --git a/configs/legacy.json b/configs/legacy.json new file mode 100644 index 000000000..2cc617570 --- /dev/null +++ b/configs/legacy.json @@ -0,0 +1,286 @@ +/** + * This "recommended" ruleset is considered legacy; + * it is generally preferable to extend from the 'recommended' or 'latest' rulesets. + * We recommend you instead explicitly include `tslint:recommended`, `tslint:latest`, or `tslint:all` + * in your `tslint.json` rather than enable core rules through this configuration. + * + * These rule settings are a broad, general recommendation for a good default configuration. + * This file is exported in the npm/nuget package as ./tslint.json. + */ +{ + "rulesDirectory": [], + "rules": { + /** + * Security Rules. The following rules should be turned on because they find security issues + * or are recommended in the Microsoft Secure Development Lifecycle (SDL) + */ + "function-constructor": true, + "insecure-random": true, + "no-banned-terms": true, + "no-cookies": true, + "no-delete-expression": true, + "no-disable-auto-sanitization": true, + "no-document-domain": true, + "no-document-write": true, + "no-eval": true, + "no-exec-script": true, + "no-function-constructor-with-string-args": false, // use tslint function-constructor rule intsead + "no-http-string": [true, "http://www.example.com/?.*", "http://localhost:?.*"], + "no-inner-html": true, + "no-octal-literal": true, + "no-string-based-set-immediate": true, + "no-string-based-set-interval": true, + "no-string-based-set-timeout": true, + "non-literal-fs-path": true, + "non-literal-require": true, + "possible-timing-attack": true, + "react-anchor-blank-noopener": true, + "react-iframe-missing-sandbox": true, + "react-no-dangerous-html": true, + + /** + * Common Bugs and Correctness. The following rules should be turned on because they find + * common bug patterns in the code or enforce type safety. + */ + "await-promise": true, + "forin": true, + "increment-decrement": true, + "jquery-deferred-must-complete": true, + "label-position": true, + "match-default-export-name": true, + "mocha-avoid-only": true, + "mocha-no-side-effect-code": true, + "no-any": true, + "no-arg": true, + "no-backbone-get-set-outside-model": true, + "no-bitwise": true, + "no-conditional-assignment": true, + "no-console": [true, "debug", "info", "error", "log", "time", "timeEnd", "trace"], + "no-constant-condition": true, + "no-control-regex": true, + "no-debugger": true, + "no-duplicate-super": true, + "no-duplicate-switch-case": true, + "no-duplicate-variable": true, + "no-empty": true, + "no-floating-promises": true, + "no-for-in-array": true, + "no-implicit-dependencies": true, + "no-import-side-effect": true, + "no-increment-decrement": false, // use tslint increment-decrement rule instead + "no-invalid-regexp": true, + "no-invalid-template-strings": true, + "no-invalid-this": true, + "no-jquery-raw-elements": true, + "no-misused-new": true, + "no-non-null-assertion": true, + "no-object-literal-type-assertion": true, + "no-parameter-reassignment": true, + "no-reference-import": true, + "no-regex-spaces": true, + "no-sparse-arrays": true, + "no-string-literal": true, + "no-string-throw": true, + "no-submodule-imports": true, + "no-unnecessary-bind": false, // use tslint unnecessary-bind rule instead + "no-unnecessary-callback-wrapper": true, + "no-unnecessary-initializer": true, + "no-unnecessary-override": true, + "no-unsafe-any": true, + "no-unsafe-finally": true, + "no-unused-expression": true, + "no-use-before-declare": true, + "no-with-statement": true, + "promise-function-async": true, + "promise-must-complete": true, + "radix": true, + "react-this-binding-issue": true, + "react-unused-props-and-state": true, + "restrict-plus-operands": true, // the plus operand should really only be used for strings and numbers + "strict-boolean-expressions": true, + "switch-default": true, + "switch-final-break": true, + "triple-equals": [true, "allow-null-check"], + "unnecessary-bind": true, + "use-isnan": true, + "use-named-parameter": true, + "use-simple-attributes": true, + + /** + * Code Clarity. The following rules should be turned on because they make the code + * generally more clear to the reader. + */ + "adjacent-overload-signatures": true, + "array-type": [true, "array"], + "arrow-parens": false, // for simple functions the parens on arrow functions are not needed + "ban-comma-operator": true, // possibly controversial + "binary-expression-operand-order": true, + "callable-types": true, + "chai-prefer-contains-to-index-of": true, + "chai-vague-errors": true, + "class-name": true, + "comment-format": true, + "completed-docs": [true, "classes"], + "export-name": true, + "file-name-casing": true, + "function-name": true, + "import-name": true, + "informative-docs": true, + "interface-name": true, + "jsdoc-format": true, + "max-classes-per-file": [true, 3], // we generally recommend making one public class per file + "max-file-line-count": true, + "max-func-body-length": [true, 100, { "ignore-parameters-to-function-regex": "^describe$" }], + "max-line-length": [true, 140], + "member-access": true, + "member-ordering": [true, { "order": "fields-first" }], + "mocha-unneeded-done": true, + "new-parens": true, + "newline-per-chained-call": true, + "no-construct": true, + "no-default-export": true, + "no-duplicate-imports": true, + "no-dynamic-delete": true, + "no-empty-interface": true, + "no-for-in": true, + "no-function-expression": true, + "no-inferrable-types": false, // turn no-inferrable-types off in order to make the code consistent in its use of type decorations + "no-multiline-string": false, + "no-null-keyword": true, + "no-parameter-properties": true, + "no-redundant-jsdoc": true, + "no-relative-imports": true, + "no-require-imports": true, + "no-return-await": true, + "no-shadowed-variable": true, + "no-suspicious-comment": true, + "no-this-assignment": true, + "no-typeof-undefined": true, + "no-unnecessary-field-initialization": true, + "no-unnecessary-local-variable": true, + "no-unnecessary-qualifier": true, + "no-unnecessary-type-assertion": true, + "no-unsupported-browser-code": true, + "no-useless-files": true, + "no-var-keyword": true, + "no-var-requires": true, + "no-void-expression": true, + "number-literal-format": true, + "object-literal-sort-keys": false, // turn object-literal-sort-keys off and sort keys in a meaningful manner + "one-variable-per-declaration": true, + "only-arrow-functions": false, // there are many valid reasons to declare a function + "ordered-imports": true, + "prefer-array-literal": true, + "prefer-const": true, + "prefer-for-of": true, + "prefer-method-signature": true, + "prefer-object-spread": true, + "prefer-readonly": true, + "prefer-template": true, + "prefer-while": true, + "type-literal-delimiter": true, + "typedef": [true, "call-signature", "arrow-call-signature", "parameter", "arrow-parameter", "property-declaration", "variable-declaration", "member-variable-declaration"], + "underscore-consistent-invocation": true, + "unified-signatures": true, + "use-default-type-parameter": true, + "variable-name": true, + "void-zero": true, + + /** + * Accessibility. The following rules should be turned on to guarantee the best user + * experience for keyboard and screen reader users. + */ + "react-a11y-accessible-headings": true, + "react-a11y-anchors": true, + "react-a11y-aria-unsupported-elements": true, + "react-a11y-event-has-role": true, + "react-a11y-image-button-has-alt": true, + "react-a11y-img-has-alt": true, + "react-a11y-input-elements": true, + "react-a11y-lang": true, + "react-a11y-meta": true, + "react-a11y-no-onchange": true, + "react-a11y-props": true, + "react-a11y-proptypes": true, + "react-a11y-required": true, + "react-a11y-role": true, + "react-a11y-role-has-required-aria-props": true, + "react-a11y-role-supports-aria-props": true, + "react-a11y-tabindex-no-positive": true, + "react-a11y-titles": true, + + /** + * Whitespace related rules. The only recommended whitespace strategy is to pick a single format and + * be consistent. + */ + "align": [true, "parameters", "arguments", "statements"], + "curly": true, + "encoding": true, + "eofline": true, + "import-spacing": true, + "indent": [true, "spaces"], + "linebreak-style": true, + "newline-before-return": true, + "no-consecutive-blank-lines": true, + "no-empty-line-after-opening-brace": false, + "no-irregular-whitespace": true, + "no-single-line-block-comment": true, + "no-trailing-whitespace": true, + "no-unnecessary-semicolons": true, + "object-literal-key-quotes": [true, "as-needed"], + "one-line": [true, "check-open-brace", "check-catch", "check-else", "check-whitespace"], + "quotemark": [true, "single"], + "semicolon": [true, "always"], + "space-within-parens": true, + "trailing-comma": [true, { "singleline": "never", "multiline": "never" }], // forcing trailing commas for multi-line + // lists results in lists that are easier to reorder and version control diffs that are more clear. + // Many teams like to have multiline be "always". There is no clear consensus on this rule but the + // internal MS JavaScript coding standard does discourage it. + "typedef-whitespace": false, + "whitespace": [true, "check-branch", "check-decl", "check-operator", "check-separator", "check-type"], + + /** + * Controversial/Configurable rules. + */ + "ban": false, // only enable this if you have some code pattern that you want to ban + "ban-types": true, + "cyclomatic-complexity": true, + "deprecation": false, // deprecated APIs are sometimes unavoidable + "file-header": false, // enable this rule only if you are legally required to add a file header + "import-blacklist": false, // enable and configure this as you desire + "interface-over-type-literal": false, // there are plenty of reasons to prefer interfaces + "no-angle-bracket-type-assertion": false, // pick either type-cast format and use it consistently + "no-inferred-empty-object-type": false, // if the compiler is satisfied then this is probably not an issue + "no-internal-module": false, // only enable this if you are not using internal modules + "no-magic-numbers": false, // by default it will find too many false positives + "no-mergeable-namespace": false, // your project may require mergeable namespaces + "no-namespace": false, // only enable this if you are not using modules/namespaces + "no-reference": true, // in general you should use a module system and not /// reference imports + "no-unexternalized-strings": false, // the VS Code team has a specific localization process that this rule enforces + "object-literal-shorthand": false, // object-literal-shorthand offers an abbreviation not an abstraction + "prefer-conditional-expression": false, // unnecessarily strict + "prefer-switch": false, // more of a style preference + "prefer-type-cast": true, // pick either type-cast format and use it consistently + "return-undefined": false, // this actually affects the readability of the code + "space-before-function-paren": false, // turn this on if this is really your coding standard + + /** + * Deprecated rules. The following rules are deprecated for various reasons. + */ + "missing-jsdoc": false, + "missing-optional-annotation": false, // now supported by TypeScript compiler + "no-duplicate-case": false, + "no-duplicate-parameter-names": false, // now supported by TypeScript compiler + "no-empty-interfaces": false, // use tslint no-empty-interface rule instead + "no-missing-visibility-modifiers": false, // use tslint member-access rule instead + "no-multiple-var-decl": false, // use tslint one-variable-per-declaration rule instead + "no-reserved-keywords": false, + "no-stateless-class": false, + "no-switch-case-fall-through": false, // now supported by TypeScript compiler + "no-unnecessary-class": true, + "no-var-self": false, + "react-tsx-curly-spacing": false, + "typeof-compare": false, // the valid-typeof rule is currently superior to this version + "valid-typeof": false + } +} diff --git a/configs/recommended.json b/configs/recommended.json new file mode 100644 index 000000000..93e0b5651 --- /dev/null +++ b/configs/recommended.json @@ -0,0 +1,81 @@ +{ + "rulesDirectory": ["../"], + "rules": { + "chai-prefer-contains-to-index-of": true, + "chai-vague-errors": true, + "export-name": true, + "function-name": true, + "import-name": true, + "informative-docs": true, + "insecure-random": true, + "jquery-deferred-must-complete": true, + "max-func-body-length": [true, 100, { "ignore-parameters-to-function-regex": "^describe$" }], + "mocha-avoid-only": true, + "mocha-no-side-effect-code": true, + "mocha-unneeded-done": true, + "no-backbone-get-set-outside-model": true, + "no-banned-terms": true, + "no-constant-condition": true, + "no-control-regex": true, + "no-cookies": true, + "no-delete-expression": true, + "no-disable-auto-sanitization": true, + "no-document-domain": true, + "no-document-write": true, + "no-exec-script": true, + "no-for-in": true, + "no-function-expression": true, + "no-http-string": [true, "http://www.example.com/?.*", "http://localhost:?.*"], + "no-inner-html": true, + "no-invalid-regexp": true, + "no-jquery-raw-elements": true, + "no-octal-literal": true, + "no-regex-spaces": true, + "no-relative-imports": true, + "no-single-line-block-comment": true, + "no-string-based-set-immediate": true, + "no-string-based-set-interval": true, + "no-string-based-set-timeout": true, + "no-suspicious-comment": true, + "no-typeof-undefined": true, + "no-unnecessary-field-initialization": true, + "no-unnecessary-local-variable": true, + "no-unnecessary-override": true, + "no-unnecessary-semicolons": true, + "no-unsupported-browser-code": true, + "no-useless-files": true, + "no-with-statement": true, + "non-literal-fs-path": true, + "non-literal-require": true, + "possible-timing-attack": true, + "prefer-array-literal": true, + "prefer-type-cast": true, + "promise-must-complete": true, + "react-a11y-accessible-headings": true, + "react-a11y-anchors": true, + "react-a11y-aria-unsupported-elements": true, + "react-a11y-event-has-role": true, + "react-a11y-image-button-has-alt": true, + "react-a11y-img-has-alt": true, + "react-a11y-input-elements": true, + "react-a11y-lang": true, + "react-a11y-meta": true, + "react-a11y-no-onchange": true, + "react-a11y-props": true, + "react-a11y-proptypes": true, + "react-a11y-required": true, + "react-a11y-role": true, + "react-a11y-role-has-required-aria-props": true, + "react-a11y-role-supports-aria-props": true, + "react-a11y-tabindex-no-positive": true, + "react-a11y-titles": true, + "react-anchor-blank-noopener": true, + "react-iframe-missing-sandbox": true, + "react-no-dangerous-html": true, + "react-this-binding-issue": true, + "react-unused-props-and-state": true, + "underscore-consistent-invocation": true, + "use-named-parameter": true, + "use-simple-attributes": true + } +} diff --git a/package-lock.json b/package-lock.json index dec380380..cc37d684f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2987,6 +2987,12 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, "minimist-options": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", @@ -3025,14 +3031,6 @@ "dev": true, "requires": { "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } } }, "mocha": { diff --git a/package.json b/package.json index 103a2c6d7..27bbb6bae 100644 --- a/package.json +++ b/package.json @@ -49,12 +49,12 @@ }, "scripts": { "clean": "rimraf dist", + "copy:config-json": "node build-tasks/copy-config-json.js", "copy:json": "cpy \"src/**/*.json\" dist --parents", - "copy:meta": "cpy README.md recommended_ruleset.js dist/build --parents", + "copy:meta": "cpy README.md dist/build --parents", "copy:package": "cpy \"**/*.js\" \"**/*.json\" \"!tests/**\" \"!references.js\" \"tests/TestHelper.js\" \"tests/TestHelper.d.ts\" ../build --cwd=\"dist/src\" --parents", "create-rule": "node build-tasks/create-rule.js", - "generate:recommendations": "node build-tasks/generate-recommendations.js", - "generate:default-tslint-json": "node build-tasks/generate-default-tslint-json.js", + "generate:latest-config": "node build-tasks/generate-latest-config.js", "generate:sdl-report": "node build-tasks/generate-sdl-report.js", "generate:rule-metadata": "node build-tasks/generate-rule-metadata.js", "generate:package-json-for-npm": "node build-tasks/generate-package-json-for-npm.js", @@ -64,10 +64,9 @@ "start": "npm-run-all clean copy:json watch:src", "test:mocha": "mocha \"dist/src/tests/**/*.js\" --timeout 5000", "test:rules": "tslint -r dist/src --test \"tests/**\"", - "test": "npm-run-all clean copy:json tsc:src test:* tslint:check lint:* validate:* copy:package copy:meta generate:*", + "test": "npm-run-all clean copy:json tsc:src test:* tslint:check lint:* validate:* copy:package generate:* copy:meta copy:config-json", "tsc:src": "tsc", "tslint:check": "tslint-config-prettier-check ./tslint.json", - "validate:config": "node build-tasks/validate-config.js", "validate:documentation": "node build-tasks/validate-documentation.js", "watch:run-tests": "node build-tasks/watch-run-tests.js", "watch:src": "tsc --watch" @@ -87,6 +86,7 @@ "husky": "^1.1.3", "inquirer": "^6.2.1", "lint-staged": "^8.0.4", + "mkdirp": "^0.5.1", "mocha": "5.2.0", "npm-run-all": "^4.1.5", "prettier": "1.15.0", diff --git a/recommended_ruleset.js b/recommended_ruleset.js deleted file mode 100644 index 2f88ebc8a..000000000 --- a/recommended_ruleset.js +++ /dev/null @@ -1,280 +0,0 @@ -/** - * These rule settings are a broad, general recommendation for a good default configuration. - * This file is exported in the npm/nuget package as ./tslint.json. - */ -module.exports = { - 'rules': { - /** - * Security Rules. The following rules should be turned on because they find security issues - * or are recommended in the Microsoft Secure Development Lifecycle (SDL) - */ - 'function-constructor': true, - 'insecure-random': true, - 'no-banned-terms': true, - 'no-cookies': true, - 'no-delete-expression': true, - 'no-disable-auto-sanitization': true, - 'no-document-domain': true, - 'no-document-write': true, - 'no-eval': true, - 'no-exec-script': true, - 'no-function-constructor-with-string-args': false, // use tslint function-constructor rule intsead - 'no-http-string': [true, 'http://www.example.com/?.*', 'http://localhost:?.*'], - 'no-inner-html': true, - 'no-octal-literal': true, - 'no-string-based-set-immediate': true, - 'no-string-based-set-interval': true, - 'no-string-based-set-timeout': true, - 'non-literal-fs-path': true, - 'non-literal-require': true, - 'possible-timing-attack': true, - 'react-anchor-blank-noopener': true, - 'react-iframe-missing-sandbox': true, - 'react-no-dangerous-html': true, - - /** - * Common Bugs and Correctness. The following rules should be turned on because they find - * common bug patterns in the code or enforce type safety. - */ - 'await-promise': true, - 'forin': true, - 'increment-decrement': true, - 'jquery-deferred-must-complete': true, - 'label-position': true, - 'match-default-export-name': true, - 'mocha-avoid-only': true, - 'mocha-no-side-effect-code': true, - 'no-any': true, - 'no-arg': true, - 'no-backbone-get-set-outside-model': true, - 'no-bitwise': true, - 'no-conditional-assignment': true, - 'no-console': [true, 'debug', 'info', 'error', 'log', 'time', 'timeEnd', 'trace'], - 'no-constant-condition': true, - 'no-control-regex': true, - 'no-debugger': true, - 'no-duplicate-super': true, - 'no-duplicate-switch-case': true, - 'no-duplicate-variable': true, - 'no-empty': true, - 'no-floating-promises': true, - 'no-for-in-array': true, - 'no-implicit-dependencies': true, - 'no-import-side-effect': true, - 'no-increment-decrement': false, // use tslint increment-decrement rule instead - 'no-invalid-regexp': true, - 'no-invalid-template-strings': true, - 'no-invalid-this': true, - 'no-jquery-raw-elements': true, - 'no-misused-new': true, - 'no-non-null-assertion': true, - 'no-object-literal-type-assertion': true, - 'no-parameter-reassignment': true, - 'no-reference-import': true, - 'no-regex-spaces': true, - 'no-sparse-arrays': true, - 'no-string-literal': true, - 'no-string-throw': true, - 'no-submodule-imports': true, - 'no-unnecessary-bind': false, // use tslint unnecessary-bind rule instead - 'no-unnecessary-callback-wrapper': true, - 'no-unnecessary-initializer': true, - 'no-unnecessary-override': true, - 'no-unsafe-any': true, - 'no-unsafe-finally': true, - 'no-unused-expression': true, - 'no-use-before-declare': true, - 'no-with-statement': true, - 'promise-function-async': true, - 'promise-must-complete': true, - 'radix': true, - 'react-this-binding-issue': true, - 'react-unused-props-and-state': true, - 'restrict-plus-operands': true, // the plus operand should really only be used for strings and numbers - 'strict-boolean-expressions': true, - 'switch-default': true, - 'switch-final-break': true, - 'triple-equals': [true, 'allow-null-check'], - 'unnecessary-bind': true, - 'use-isnan': true, - 'use-named-parameter': true, - 'use-simple-attributes': true, - - /** - * Code Clarity. The following rules should be turned on because they make the code - * generally more clear to the reader. - */ - 'adjacent-overload-signatures': true, - 'array-type': [true, 'array'], - 'arrow-parens': false, // for simple functions the parens on arrow functions are not needed - 'ban-comma-operator': true, // possibly controversial - 'binary-expression-operand-order': true, - 'callable-types': true, - 'chai-prefer-contains-to-index-of': true, - 'chai-vague-errors': true, - 'class-name': true, - 'comment-format': true, - 'completed-docs': [true, 'classes'], - 'export-name': true, - 'file-name-casing': true, - 'function-name': true, - 'import-name': true, - 'informative-docs': true, - 'interface-name': true, - 'jsdoc-format': true, - 'max-classes-per-file': [true, 3], // we generally recommend making one public class per file - 'max-file-line-count': true, - 'max-func-body-length': [true, 100, { 'ignore-parameters-to-function-regex': '^describe$' }], - 'max-line-length': [true, 140], - 'member-access': true, - 'member-ordering': [true, { 'order': 'fields-first' }], - 'mocha-unneeded-done': true, - 'new-parens': true, - 'newline-per-chained-call': true, - 'no-construct': true, - 'no-default-export': true, - 'no-duplicate-imports': true, - 'no-dynamic-delete': true, - 'no-empty-interface': true, - 'no-for-in': true, - 'no-function-expression': true, - 'no-inferrable-types': false, // turn no-inferrable-types off in order to make the code consistent in its use of type decorations - 'no-multiline-string': false, - 'no-null-keyword': true, - 'no-parameter-properties': true, - 'no-redundant-jsdoc': true, - 'no-relative-imports': true, - 'no-require-imports': true, - 'no-return-await': true, - 'no-shadowed-variable': true, - 'no-suspicious-comment': true, - 'no-this-assignment': true, - 'no-typeof-undefined': true, - 'no-unnecessary-field-initialization': true, - 'no-unnecessary-local-variable': true, - 'no-unnecessary-qualifier': true, - 'no-unnecessary-type-assertion': true, - 'no-unsupported-browser-code': true, - 'no-useless-files': true, - 'no-var-keyword': true, - 'no-var-requires': true, - 'no-void-expression': true, - 'number-literal-format': true, - 'object-literal-sort-keys': false, // turn object-literal-sort-keys off and sort keys in a meaningful manner - 'one-variable-per-declaration': true, - 'only-arrow-functions': false, // there are many valid reasons to declare a function - 'ordered-imports': true, - 'prefer-array-literal': true, - 'prefer-const': true, - 'prefer-for-of': true, - 'prefer-method-signature': true, - 'prefer-object-spread': true, - 'prefer-readonly': true, - 'prefer-template': true, - 'prefer-while': true, - 'type-literal-delimiter': true, - 'typedef': [true, 'call-signature', 'arrow-call-signature', 'parameter', 'arrow-parameter', 'property-declaration', 'variable-declaration', 'member-variable-declaration'], - 'underscore-consistent-invocation': true, - 'unified-signatures': true, - 'use-default-type-parameter': true, - 'variable-name': true, - 'void-zero': true, - - /** - * Accessibility. The following rules should be turned on to guarantee the best user - * experience for keyboard and screen reader users. - */ - 'react-a11y-accessible-headings': true, - 'react-a11y-anchors': true, - 'react-a11y-aria-unsupported-elements': true, - 'react-a11y-event-has-role': true, - 'react-a11y-image-button-has-alt': true, - 'react-a11y-img-has-alt': true, - 'react-a11y-input-elements': true, - 'react-a11y-lang': true, - 'react-a11y-meta': true, - 'react-a11y-no-onchange': true, - 'react-a11y-props': true, - 'react-a11y-proptypes': true, - 'react-a11y-required': true, - 'react-a11y-role': true, - 'react-a11y-role-has-required-aria-props': true, - 'react-a11y-role-supports-aria-props': true, - 'react-a11y-tabindex-no-positive': true, - 'react-a11y-titles': true, - - /** - * Whitespace related rules. The only recommended whitespace strategy is to pick a single format and - * be consistent. - */ - 'align': [true, 'parameters', 'arguments', 'statements'], - 'curly': true, - 'encoding': true, - 'eofline': true, - 'import-spacing': true, - 'indent': [true, 'spaces'], - 'linebreak-style': true, - 'newline-before-return': true, - 'no-consecutive-blank-lines': true, - 'no-empty-line-after-opening-brace': false, - 'no-irregular-whitespace': true, - 'no-single-line-block-comment': true, - 'no-trailing-whitespace': true, - 'no-unnecessary-semicolons': true, - 'object-literal-key-quotes': [true, 'as-needed'], - 'one-line': [true, 'check-open-brace', 'check-catch', 'check-else', 'check-whitespace'], - 'quotemark': [true, 'single'], - 'semicolon': [true, 'always'], - 'space-within-parens': true, - 'trailing-comma': [true, { 'singleline': 'never', 'multiline': 'never' }], // forcing trailing commas for multi-line - // lists results in lists that are easier to reorder and version control diffs that are more clear. - // Many teams like to have multiline be 'always'. There is no clear consensus on this rule but the - // internal MS JavaScript coding standard does discourage it. - 'typedef-whitespace': false, - 'whitespace': [true, 'check-branch', 'check-decl', 'check-operator', 'check-separator', 'check-type'], - - /** - * Controversial/Configurable rules. - */ - 'ban': false, // only enable this if you have some code pattern that you want to ban - 'ban-types': true, - 'cyclomatic-complexity': true, - 'deprecation': false, // deprecated APIs are sometimes unavoidable - 'file-header': false, // enable this rule only if you are legally required to add a file header - 'import-blacklist': false, // enable and configure this as you desire - 'interface-over-type-literal': false, // there are plenty of reasons to prefer interfaces - 'no-angle-bracket-type-assertion': false, // pick either type-cast format and use it consistently - 'no-inferred-empty-object-type': false, // if the compiler is satisfied then this is probably not an issue - 'no-internal-module': false, // only enable this if you are not using internal modules - 'no-magic-numbers': false, // by default it will find too many false positives - 'no-mergeable-namespace': false, // your project may require mergeable namespaces - 'no-namespace': false, // only enable this if you are not using modules/namespaces - 'no-reference': true, // in general you should use a module system and not /// reference imports - 'no-unexternalized-strings': false, // the VS Code team has a specific localization process that this rule enforces - 'object-literal-shorthand': false, // object-literal-shorthand offers an abbreviation not an abstraction - 'prefer-conditional-expression': false, // unnecessarily strict - 'prefer-switch': false, // more of a style preference - 'prefer-type-cast': true, // pick either type-cast format and use it consistently - 'return-undefined': false, // this actually affects the readability of the code - 'space-before-function-paren': false, // turn this on if this is really your coding standard - - /** - * Deprecated rules. The following rules are deprecated for various reasons. - */ - 'missing-jsdoc': false, - 'missing-optional-annotation': false, // now supported by TypeScript compiler - 'no-duplicate-case': false, - 'no-duplicate-parameter-names': false, // now supported by TypeScript compiler - 'no-empty-interfaces': false, // use tslint no-empty-interface rule instead - 'no-missing-visibility-modifiers': false, // use tslint member-access rule instead - 'no-multiple-var-decl': false, // use tslint one-variable-per-declaration rule instead - 'no-reserved-keywords': false, - 'no-stateless-class': false, - 'no-switch-case-fall-through': false, // now supported by TypeScript compiler - 'no-unnecessary-class': true, - 'no-var-self': false, - 'react-tsx-curly-spacing': false, - 'typeof-compare': false, // the valid-typeof rule is currently superior to this version - 'valid-typeof': false, - } -}; diff --git a/src/informativeDocsRule.ts b/src/informativeDocsRule.ts index 14d3b538f..5d75298b8 100644 --- a/src/informativeDocsRule.ts +++ b/src/informativeDocsRule.ts @@ -57,7 +57,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Moderate', level: 'Opportunity for Excellence', group: 'Clarity', - recommendation: 'true,', + recommendation: 'true', ruleName: 'informative-docs', type: 'maintainability', typescriptOnly: false diff --git a/src/maxFuncBodyLengthRule.ts b/src/maxFuncBodyLengthRule.ts index 1e4b6ff02..2fe5abff0 100644 --- a/src/maxFuncBodyLengthRule.ts +++ b/src/maxFuncBodyLengthRule.ts @@ -31,7 +31,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Moderate', level: 'Opportunity for Excellence', group: 'Clarity', - recommendation: '[true, 100, { "ignore-parameters-to-function-regex": "^describe$" }],', + recommendation: '[true, 100, { "ignore-parameters-to-function-regex": "^describe$" }]', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/missingJsdocRule.ts b/src/missingJsdocRule.ts index 7b4b559fd..9e826eb4e 100644 --- a/src/missingJsdocRule.ts +++ b/src/missingJsdocRule.ts @@ -16,7 +16,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Deprecated', - recommendation: 'false,' + recommendation: 'false' }; public static FAILURE_STRING: string = 'File missing JSDoc comment at the top-level.'; diff --git a/src/missingOptionalAnnotationRule.ts b/src/missingOptionalAnnotationRule.ts index 9e024c685..00cbce4f4 100644 --- a/src/missingOptionalAnnotationRule.ts +++ b/src/missingOptionalAnnotationRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Deprecated', - recommendation: 'false, // now supported by TypeScript compiler' + recommendation: 'false' }; public static FAILURE_STRING: string = 'Argument following optional argument missing optional annotation: '; diff --git a/src/noDuplicateCaseRule.ts b/src/noDuplicateCaseRule.ts index 2b42a1cfc..62c35c6af 100644 --- a/src/noDuplicateCaseRule.ts +++ b/src/noDuplicateCaseRule.ts @@ -16,7 +16,7 @@ export class Rule extends Lint.Rules.AbstractRule { issueType: 'Error', severity: 'Critical', level: 'Opportunity for Excellence', - recommendation: 'false,', + recommendation: 'false', group: 'Deprecated', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/noDuplicateParameterNamesRule.ts b/src/noDuplicateParameterNamesRule.ts index 24298c706..216c71dd5 100644 --- a/src/noDuplicateParameterNamesRule.ts +++ b/src/noDuplicateParameterNamesRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Deprecated', - recommendation: 'false, // now supported by TypeScript compiler' + recommendation: 'false' }; public static FAILURE_STRING: string = 'Duplicate parameter name: '; diff --git a/src/noEmptyInterfacesRule.ts b/src/noEmptyInterfacesRule.ts index 8772844cd..02c2cfd90 100644 --- a/src/noEmptyInterfacesRule.ts +++ b/src/noEmptyInterfacesRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Moderate', level: 'Opportunity for Excellence', group: 'Deprecated', - recommendation: 'false, // use tslint no-empty-interface rule instead', + recommendation: 'false', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/noEmptyLineAfterOpeningBraceRule.ts b/src/noEmptyLineAfterOpeningBraceRule.ts index f9c89df7b..65b68398c 100644 --- a/src/noEmptyLineAfterOpeningBraceRule.ts +++ b/src/noEmptyLineAfterOpeningBraceRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Whitespace', - recommendation: 'false,', + recommendation: 'false', commonWeaknessEnumeration: '710' }; diff --git a/src/noFunctionConstructorWithStringArgsRule.ts b/src/noFunctionConstructorWithStringArgsRule.ts index 3a0f8ee43..4865ea6e7 100644 --- a/src/noFunctionConstructorWithStringArgsRule.ts +++ b/src/noFunctionConstructorWithStringArgsRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { issueType: 'Error', severity: 'Critical', level: 'Mandatory', - recommendation: 'false, // use tslint function-constructor rule intsead', + recommendation: 'false', group: 'Security', commonWeaknessEnumeration: '95, 676, 242, 116' }; diff --git a/src/noHttpStringRule.ts b/src/noHttpStringRule.ts index 161c89152..d9bbcfdb0 100644 --- a/src/noHttpStringRule.ts +++ b/src/noHttpStringRule.ts @@ -24,7 +24,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Critical', level: 'Mandatory', group: 'Security', - recommendation: '[true, "http://www.example.com/?.*", "http://localhost:?.*"],', + recommendation: '[true, "http://www.example.com/?.*", "http://localhost:?.*"]', commonWeaknessEnumeration: '319' }; diff --git a/src/noIncrementDecrementRule.ts b/src/noIncrementDecrementRule.ts index 603569a72..216727eed 100644 --- a/src/noIncrementDecrementRule.ts +++ b/src/noIncrementDecrementRule.ts @@ -34,7 +34,7 @@ export class Rule extends Lint.Rules.AbstractRule { issueType: 'Warning', severity: 'Low', level: 'Opportunity for Excellence', - recommendation: 'false, // use tslint increment-decrement rule instead', + recommendation: 'false', group: 'Correctness', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/noMissingVisibilityModifiersRule.ts b/src/noMissingVisibilityModifiersRule.ts index 658226961..b264ef9b2 100644 --- a/src/noMissingVisibilityModifiersRule.ts +++ b/src/noMissingVisibilityModifiersRule.ts @@ -18,7 +18,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Deprecated', - recommendation: 'false, // use tslint member-access rule instead', + recommendation: 'false', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/noMultilineStringRule.ts b/src/noMultilineStringRule.ts index 1d1434c3e..a0ec822b5 100644 --- a/src/noMultilineStringRule.ts +++ b/src/noMultilineStringRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Clarity', - recommendation: 'false,', + recommendation: 'false', commonWeaknessEnumeration: '710' }; diff --git a/src/noMultipleVarDeclRule.ts b/src/noMultipleVarDeclRule.ts index 176fd1fb6..1f66f1710 100644 --- a/src/noMultipleVarDeclRule.ts +++ b/src/noMultipleVarDeclRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Deprecated', - recommendation: 'false, // use tslint one-variable-per-declaration rule instead', + recommendation: 'false', commonWeaknessEnumeration: '710' }; diff --git a/src/noReservedKeywordsRule.ts b/src/noReservedKeywordsRule.ts index cf1ca4fd7..7ba9c18d6 100644 --- a/src/noReservedKeywordsRule.ts +++ b/src/noReservedKeywordsRule.ts @@ -16,7 +16,7 @@ export class Rule extends Lint.Rules.AbstractRule { typescriptOnly: true, issueClass: 'SDL', issueType: 'Error', - recommendation: 'false,', + recommendation: 'false', severity: 'Critical', level: 'Mandatory', group: 'Deprecated', diff --git a/src/noStatelessClassRule.ts b/src/noStatelessClassRule.ts index f730ac30b..0b83da1a6 100644 --- a/src/noStatelessClassRule.ts +++ b/src/noStatelessClassRule.ts @@ -20,7 +20,7 @@ export class Rule extends Lint.Rules.AbstractRule { issueType: 'Warning', severity: 'Important', level: 'Opportunity for Excellence', - recommendation: 'false,', + recommendation: 'false', group: 'Deprecated', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/noUnexternalizedStringsRule.ts b/src/noUnexternalizedStringsRule.ts index 45584ba7e..7053349df 100644 --- a/src/noUnexternalizedStringsRule.ts +++ b/src/noUnexternalizedStringsRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Configurable', - recommendation: 'false, // the VS Code team has a specific localization process that this rule enforces' + recommendation: 'false' }; public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { diff --git a/src/noUnnecessaryBindRule.ts b/src/noUnnecessaryBindRule.ts index 3225045a6..262c7bedc 100644 --- a/src/noUnnecessaryBindRule.ts +++ b/src/noUnnecessaryBindRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { issueType: 'Warning', severity: 'Important', level: 'Opportunity for Excellence', - recommendation: 'false, // use tslint unnecessary-bind rule instead', + recommendation: 'false', group: 'Correctness', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/noVarSelfRule.ts b/src/noVarSelfRule.ts index 95431251d..c1b1f5350 100644 --- a/src/noVarSelfRule.ts +++ b/src/noVarSelfRule.ts @@ -23,7 +23,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Important', level: 'Opportunity for Excellence', group: 'Deprecated', - recommendation: 'false,', + recommendation: 'false', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/preferTypeCastRule.ts b/src/preferTypeCastRule.ts index 37d979e5c..474aa4a30 100644 --- a/src/preferTypeCastRule.ts +++ b/src/preferTypeCastRule.ts @@ -19,7 +19,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Configurable', - recommendation: 'true, // pick either type-cast format and use it consistently', + recommendation: 'true', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/reactTsxCurlySpacingRule.ts b/src/reactTsxCurlySpacingRule.ts index 5ebf5f299..09a1b9d15 100644 --- a/src/reactTsxCurlySpacingRule.ts +++ b/src/reactTsxCurlySpacingRule.ts @@ -31,7 +31,7 @@ export class Rule extends Lint.Rules.AbstractRule { issueType: 'Warning', severity: 'Low', level: 'Opportunity for Excellence', - recommendation: 'false,', + recommendation: 'false', group: 'Deprecated' }; diff --git a/src/utils/ExtendedMetadata.ts b/src/utils/ExtendedMetadata.ts index b1a955b34..d1f381fd5 100644 --- a/src/utils/ExtendedMetadata.ts +++ b/src/utils/ExtendedMetadata.ts @@ -30,6 +30,6 @@ export type Severity = 'Critical' | 'Important' | 'Moderate' | 'Low'; export type Level = 'Mandatory' | 'Opportunity for Excellence'; /** - * Ignored - Use this value to exclude the rule from recommended_ruleset.js and the deployed tslint.json file. + * Ignored - Use this value to exclude the rule from configuration files. */ export type Group = 'Ignored' | 'Security' | 'Correctness' | 'Accessibility' | 'Clarity' | 'Whitespace' | 'Configurable' | 'Deprecated'; diff --git a/src/validTypeofRule.ts b/src/validTypeofRule.ts index b917ce040..1ab7c7e12 100644 --- a/src/validTypeofRule.ts +++ b/src/validTypeofRule.ts @@ -16,7 +16,7 @@ export class Rule extends Lint.Rules.AbstractRule { issueType: 'Error', severity: 'Critical', level: 'Opportunity for Excellence', - recommendation: 'false,', + recommendation: 'false', group: 'Deprecated' };