Giter Site home page Giter Site logo

mgechev / codelyzer Goto Github PK

View Code? Open in Web Editor NEW
2.4K 46.0 235.0 18.1 MB

Static analysis for Angular projects.

Home Page: http://codelyzer.com/

License: MIT License

TypeScript 99.98% JavaScript 0.02%
codelyzer angular tslint linting static-code-analysis style-guide angular-cli

codelyzer's Introduction

npm version Downloads Build Status code style: prettier Conventional Commits Gitter Chat

codelyzer

A set of tslint rules for static code analysis of Angular TypeScript projects.
(If you are using ESLint check out the new angular-eslint repository.)

You can run the static code analyzer over web apps, NativeScript, Ionic, etc.

Vote for your favorite feature here. For more details about the feature request process see this document

How to use?

Angular CLI

Angular CLI has support for codelyzer. In order to validate your code with CLI and the custom Angular specific rules just use:

ng new codelyzer
ng lint

Note that by default all components are aligned with the style guide so you won't see any errors in the console.

Angular Seed

Another project which has out of the box integration with codelyzer is angular-seed. In order to run the linter you should:

# Skip if you've already cloned Angular Seed
git clone https://github.com/mgechev/angular-seed

# Skip if you've already installed all the dependencies of Angular Seed
cd angular-seed && npm i

# Run all the tslint and codelyzer rules
npm run lint

Note that by default all components are aligned with the style guide so you won't see any errors in the console.

Custom Setup

Preset

You can use the tslint-angular preset. All you need is:

npm i tslint-angular

After that create a tslint.json file with the following configuration:

{
  "extends": ["tslint-angular"]
}

Run the linter with:

./node_modules/.bin/tslint -c tslint.json

TSLint will now complain that there are rules which require type checking. In order to fix this, use the -p config option:

./node_modules/.bin/tslint -p tsconfig.json -c tslint.json

Custom Installation

You can easily use codelyzer with your custom setup:

npm i codelyzer tslint @angular/compiler @angular/core

A. Using codelyzer package in PATH

Create the following tslint.json file like:

{
  "extends": ["codelyzer"],
  "rules": {
    "component-class-suffix": true,
    "component-max-inline-declarations": true,
    "component-selector": [true, "element", "sg", "kebab-case"],
    "contextual-lifecycle": true,
    "directive-class-suffix": true,
    "directive-selector": [true, "attribute", "sg", "camelCase"],
    "no-attribute-decorator": true,
    "no-conflicting-lifecycle": true,
    "no-forward-ref": true,
    "no-host-metadata-property": true,
    "no-input-rename": true,
    "no-inputs-metadata-property": true,
    "no-lifecycle-call": true,
    "no-output-native": true,
    "no-output-on-prefix": true,
    "no-output-rename": true,
    "no-outputs-metadata-property": true,
    "no-pipe-impure": true,
    "no-queries-metadata-property": true,
    "no-unused-css": true,
    "prefer-inline-decorator": true,
    "prefer-output-readonly": true,
    "template-banana-in-box": true,
    "template-conditional-complexity": [true, 4],
    "template-cyclomatic-complexity": [true, 5],
    "template-i18n": [true, "check-id", "check-text"],
    "template-no-negated-async": true,
    "template-use-track-by-function": true,
    "use-component-selector": true,
    "use-component-view-encapsulation": true,
    "use-lifecycle-interface": true,
    "use-pipe-transform-interface": true
  }
}

To run TSLint with this setup you can use one of the following alternatives:

  1. Install codelyzer globally npm install -g codelyzer

  2. Run TSLint from a package.json script by adding a script like tslint . to your package.json, similar to:

"scripts": {
  ...
  "lint": "tslint .",
  ...
},

Then run npm run lint

B. Using codelyzer from node_modules directory

Now create the following tslint.json file where your node_modules directory is:

{
  "rulesDirectory": ["node_modules/codelyzer"],
  "rules": {
    "component-class-suffix": true,
    "component-max-inline-declarations": true,
    "component-selector": [true, "element", "sg", "kebab-case"],
    "contextual-lifecycle": true,
    "directive-class-suffix": true,
    "directive-selector": [true, "attribute", "sg", "camelCase"],
    "no-attribute-decorator": true,
    "no-conflicting-lifecycle": true,
    "no-forward-ref": true,
    "no-host-metadata-property": true,
    "no-input-rename": true,
    "no-inputs-metadata-property": true,
    "no-lifecycle-call": true,
    "no-output-native": true,
    "no-output-on-prefix": true,
    "no-output-rename": true,
    "no-outputs-metadata-property": true,
    "no-pipe-impure": true,
    "no-queries-metadata-property": true,
    "no-unused-css": true,
    "prefer-inline-decorator": true,
    "prefer-output-readonly": true,
    "template-banana-in-box": true,
    "template-conditional-complexity": [true, 4],
    "template-cyclomatic-complexity": [true, 5],
    "template-i18n": [true, "check-id", "check-text"],
    "template-no-negated-async": true,
    "template-use-track-by-function": true,
    "use-component-selector": true,
    "use-component-view-encapsulation": true,
    "use-lifecycle-interface": true,
    "use-pipe-transform-interface": true
  }
}

Next you can create a component file in the same directory with name component.ts and the following content:

import { Component } from '@angular/core';

@Component({
  selector: 'codelyzer',
  template: ` <h1>Hello {{ name }}!</h1> `,
})
class Codelyzer {
  name: string = 'World';

  ngOnInit() {
    console.log('Initialized');
  }
}

As last step you can execute all the rules against your code with tslint:

./node_modules/.bin/tslint -c tslint.json component.ts

You should see the following output:

component.ts[4, 13]: The selector of the component "Codelyzer" should have prefix "sg" (https://goo.gl/cix8BY)
component.ts[12, 3]: Implement lifecycle hook interface OnInit for method ngOnInit in class Codelyzer (https://goo.gl/w1Nwk3)
component.ts[9, 7]: The name of the class Codelyzer should end with the suffix Component (https://goo.gl/5X1TE7)

Editor Configuration

Note that you need to have tslint plugin install on your editor.

Codelyzer should work out of the box with Atom but for VSCode you will have to open Code > Preferences > User Settings, and enter the following config:

{
  "tslint.rulesDirectory": "./node_modules/codelyzer",
  "typescript.tsdk": "node_modules/typescript/lib"
}

Now you should have the following result:

VSCode Codelyzer

Enjoy!

Changelog

You can find it here.

Recommended configuration

Below you can find a recommended configuration which is based on the Angular Style Guide.

{
  // The rules component-selector and directive-selector have the following arguments:
  // [ENABLED, "attribute" | "element", "prefix" | ["listOfPrefixes"], "camelCase" | "kebab-case"]
  "component-selector": [true, "element", ["cmp-prefix1", "cmp-prefix2"], "kebab-case"],
  "directive-selector": [true, "attribute", ["dir-prefix1", "dir-prefix2"], "camelCase"],

  "component-max-inline-declarations": true,
  "contextual-lifecycle": true,
  "no-conflicting-lifecycle": true,
  "no-host-metadata-property": true,
  "no-input-rename": true,
  "no-inputs-metadata-property": true,
  "no-output-native": true,
  "no-output-on-prefix": true,
  "no-output-rename": true,
  "no-outputs-metadata-property": true,
  "no-queries-metadata-property": true,
  "prefer-inline-decorator": true,
  "template-banana-in-box": true,
  "template-no-negated-async": true,
  "use-lifecycle-interface": true,
  "use-pipe-transform-interface": true,

  // The rules component-class-suffix and directive-class-suffix have the following arguments:
  // [ENABLED, "suffix" | ["listOfSuffixes"]]
  // Where "suffix" is/are your custom(s) suffix(es), for instance "Page" for Ionic components.
  "component-class-suffix": [true, "Component"],
  "directive-class-suffix": [true, "Directive"]
}

Rules Status

Rule Status
component-class-suffix Stable
component-max-inline-declarations Stable
component-selector Stable
contextual-decorator Stable
contextual-lifecycle Stable
directive-class-suffix Stable
directive-selector Stable
import-destructuring-spacing Stable
no-attribute-decorator Stable
no-forward-ref Stable
no-host-metadata-property Stable
no-input-prefix Stable
no-input-rename Stable
no-inputs-metadata-property Stable
no-lifecycle-call Stable
no-output-native Stable
no-output-on-prefix Stable
no-output-rename Stable
no-outputs-metadata-property Stable
no-pipe-impure Stable
no-queries-metadata-property Stable
prefer-inline-decorator Stable
prefer-output-readonly Stable
template-banana-in-box Stable
template-cyclomatic-complexity Stable
template-no-call-expression Stable
template-no-negated-async Stable
template-use-track-by-function Stable
use-component-selector Stable
use-component-view-encapsulation Stable
use-lifecycle-interface Stable
use-pipe-decorator Stable
use-pipe-transform-interface Stable
prefer-on-push-component-change-detection Experimental
no-conflicting-lifecycle Experimental
no-unused-css Experimental
pipe-prefix Experimental
relative-url-prefix Experimental
template-accessibility-alt-text Experimental
template-accessibility-elements-content Experimental
template-accessibility-label-for Experimental
template-accessibility-tabindex-no-positive Experimental
template-accessibility-table-scope Experimental
template-accessibility-valid-aria Experimental
template-click-events-have-key-events Experimental
template-conditional-complexity Experimental
template-i18n Experimental
template-mouse-events-have-key-events Experimental
template-no-any Experimental
template-no-autofocus Experimental
template-no-distracting-elements Experimental
angular-whitespace Deprecated

Disable a rule that validates Template or Styles

Lint rules can be disabled by adding a marker in TypeScript files. More information here.

To disable rules that validate templates or styles you'd need to add a marker in the TypeScript file referencing them.

import { Component } from '@angular/core';

/* tslint:disable:template-use-track-by-function */
@Component({
  selector: 'codelyzer',
  templateUrl: './codelyzer.component.html',
})
class Codelyzer {}

Advanced configuration

Codelyzer supports any template and style language by custom hooks. If you're using Sass for instance, you can allow codelyzer to analyze your styles by creating a file .codelyzer.js in the root of your project (where the node_modules directory is). In the configuration file can implement custom pre-processing and template resolution logic:

// Demo of transforming Sass styles
var sass = require('node-sass');

module.exports = {
  // Definition of custom interpolation strings
  interpolation: ['{{', '}}'],

  // You can transform the urls of your external styles and templates
  resolveUrl(url, decorator) {
    return url;
  },

  // Transformation of the templates. This hooks is quite useful
  // if you're using any other templating language, for instance
  // jade, markdown, haml, etc.
  //
  // NOTE that this method WILL NOT throw an error in case of invalid template.
  //
  transformTemplate(code, url, decorator) {
    return { code: code, url: url };
  },

  // Transformation of styles. This hook is useful is you're using
  // any other style language, for instance Sass, Less, etc.
  //
  // NOTE that this method WILL NOT throw an error in case of invalid style.
  //
  transformStyle(code, url, decorator) {
    var result = { code: code, url: url };
    if (url && /\.scss$/.test(url)) {
      var transformed = sass.renderSync({ data: code, sourceMap: true, outFile: '/dev/null' });
      result.source = code;
      result.code = transformed.css.toString();
      result.map = transformed.map.toString();
    }
    return result;
  },

  // Custom predefined directives in case you get error for
  // missing property and you are using a template reference
  predefinedDirectives: [{ selector: 'form', exportAs: 'ngForm' }],

  // None = 0b000, Error = 0b001, Info = 0b011, Debug = 0b111
  logLevel: 0b111,
};

Contributors

mgechev wKoza rafaelss95 preslavsh mohammedzamakhan rokerkony
mgechev wKoza rafaelss95 preslavsh mohammedzamakhan rokerkony
GregOnNet alan-agius4 kevinphelps eppsilon csvn ghsyeung
GregOnNet alan-agius4 kevinphelps eppsilon csvn ghsyeung
Kobzol mattlewis92 lazarljubenovic sagittarius-rev connor4312 Foxandxss
Kobzol mattlewis92 lazarljubenovic sagittarius-rev connor4312 Foxandxss
gbilodeau NagRock Hotell Martin-Wegner comfroels plantain-00
gbilodeau NagRock Hotell Martin-Wegner comfroels plantain-00
nexus-uw alexkpek loktionov129 alisd23 aboyton bmvantunes
nexus-uw alexkpek loktionov129 alisd23 aboyton bmvantunes
Moeriki sneas EmmanuelDemey eromano Manduro karol-depka
Moeriki sneas EmmanuelDemey eromano Manduro karol-depka
leosvelperez muhammadghazali PapsOu rwlogel robzenn92 rtfpessoa
leosvelperez muhammadghazali PapsOu rwlogel robzenn92 rtfpessoa
santoshyadav198613 scttcper stschake tmair YogliB cexbrayat
santoshyadav198613 scttcper stschake tmair YogliB cexbrayat
clydin reduckted someblue
clydin reduckted someblue

License

MIT

codelyzer's People

Contributors

alan-agius4 avatar comfroels avatar connor4312 avatar csvn avatar eppsilon avatar foxandxss avatar gbilodeau avatar ghsyeung avatar hotell avatar kevinphelps avatar kobzol avatar lazarljubenovic avatar mattlewis92 avatar mgechev avatar mohammedzamakhan avatar nagrock avatar nexus-uw avatar papsou avatar plantain-00 avatar rafaelss95 avatar renovate[bot] avatar robzenn92 avatar rokerkony avatar rtfpessoa avatar rwlogel avatar sagittarius-rev avatar santoshyadavdev avatar scttcper avatar stschake avatar wkoza avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

codelyzer's Issues

Could not find the following rules specified in the configuration

first thanks for this I have been struggling on how to enforce this rules, I just installed this and tried it it worked without the Recommended configuration, but once I add those it gives me this error (with tslint cli):
global tslint v: 3.9.0

/home/yahya/.nvm/versions/node/v5.10.1/lib/node_modules/tslint/lib/ruleLoader.js:29
throw new Error(errorMessage);
^
Error: Could not find the following rules specified in the configuration:
directive-selector-prefix
component-selector-prefix
use-input-property-decorator
use-output-property-decorator
use-host-property-decorator
no-attribute-parameter-decorator
no-input-rename
no-output-rename
no-forward-ref
use-life-cycle-interface
use-pipe-transform-interface
pipe-naming
component-class-suffix
directive-class-suffix
at Object.loadRules (/home/yahya/.nvm/versions/node/v5.10.1/lib/node_modules/tslint/lib/ruleLoader.js:29:15)
at Linter.lint (/home/yahya/.nvm/versions/node/v5.10.1/lib/node_modules/tslint/lib/tslint.js:25:44)
at processFile (/home/yahya/.nvm/versions/node/v5.10.1/lib/node_modules/tslint/lib/tslint-cli.js:118:29)
at Array.forEach (native)
at Object. (/home/yahya/.nvm/versions/node/v5.10.1/lib/node_modules/tslint/lib/tslint-cli.js:128:41)
at Module._compile (module.js:413:34)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)

with gulp tslint:

local tslint v: 3.9.0
gulp-tslint v:5.0.0

/var/www/Work/card/node_modules/gulp-tslint/node_modules/tslint/lib/ruleLoader.js:29
throw new Error(errorMessage);
^
Error: Could not find the following rules specified in the configuration:
no-trailing-comma
directive-selector-prefix
component-selector-prefix
use-input-property-decorator
use-output-property-decorator
use-host-property-decorator
no-attribute-parameter-decorator
no-input-rename
no-output-rename
no-forward-ref
use-life-cycle-interface
use-pipe-transform-interface
pipe-naming
component-class-suffix
directive-class-suffix
at Object.loadRules (/var/www/Work/card/node_modules/gulp-tslint/node_modules/tslint/lib/ruleLoader.js:29:15)
at Linter.lint (/var/www/Work/card/node_modules/gulp-tslint/node_modules/tslint/lib/tslint.js:25:44)
at /var/www/Work/card/node_modules/gulp-tslint/index.js:95:34
at respond (/var/www/Work/card/node_modules/gulp-tslint/node_modules/rcloader/index.js:68:7)
at respond (/var/www/Work/card/node_modules/gulp-tslint/node_modules/rcloader/node_modules/rcfinder/index.js:140:7)
at /var/www/Work/card/node_modules/gulp-tslint/node_modules/rcloader/node_modules/rcfinder/index.js:124:17
at /var/www/Work/card/node_modules/gulp-tslint/node_modules/rcloader/node_modules/rcfinder/index.js:77:13
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)

import-destructuring-spacing with alias imports

I was giving a try to the new import-destructuring-spacing rule, and it breaks in our codebase on imports that use an alias:

import * as moment from 'moment';

produces You need to leave whitespaces inside of the import statement's curly braces.

It would be better if that was ignored (but perhaps I'm missing something).

Feature request: Add rule to prohibit use of document and window

As using window and document prevents the app to be run in a web worker there should be a rule to prohibit the use of them.
This aligns with the rule of not using ElementRef.nativeElement for the same reason.
Additionally, but I don't know whether this is possible, the rule should also detect if window is implicitly accessed.

selectors with classes

This selector is not passing the checker:

@Component({
  selector: 'abc.xyz'
})
class Foo {...}

it supposed to target <abc class="xyz"></abc>.

noForwardRefFule throws TypeError

On a code like this one

import {Component, Provider, forwardRef} from "@angular/core";
import {
  ControlValueAccessor,
  NG_VALUE_ACCESSOR,
  CORE_DIRECTIVES
} from "@angular/common";

const noop = () => {
};

const TAGS_INPUT_CONTROL_VALUE_ACCESSOR = new Provider(
  NG_VALUE_ACCESSOR, {
    useExisting: forwardRef(() => TagsInput),
    multi: true
  });

noForwardRefRule throws an exception :

TypeError: Cannot read property 'text' of undefined
    at ExpressionCallMetadataWalker.validateCallExpression
((..)/node_modules/codelyzer/noForwardRefRule.js:36:50)

seems that failureConfig is using a currentNode without name : from codelyzer/noForwardRefRule.js

    ExpressionCallMetadataWalker.prototype.validateCallExpression = function (callExpression) {
        if (callExpression.expression.text === 'forwardRef') {
            var currentNode = callExpression;
            while (currentNode.parent.parent) {
                currentNode = currentNode.parent;
            }
            var failureConfig = [currentNode.name.text];  // <<<<<<<< HERE
            /// quick fix below without understanding of tslint/codelyzer internals :)
            /// var failureConfig = [currentNode.name ? currentNode.name.text : "" ];
            failureConfig.unshift(Rule.FAILURE_STRING);
            this.addFailure(this.createFailure(callExpression.getStart(), callExpression.getWidth(), sprintf_js_1.sprintf.apply(this, failureConfig)));
        }
    };

Feature request: allow kebab-case class selectors for components and directives

I'm sorry if this is already available, but I can't find the right configuration in my tslint.json file to get this working.

For components and directives, when using a class selector, I think it would be better to keep to the Google CSS style guides in mind and not use camelCase but kebab-case, with or without a prefix.

Codelyzer does not work with Typescript@next (2.1.0)

We currently need typescript@next to have a bug with Promise.all fixed (among others). But codelyzer does not work with that Typescript version:

The following error message is printed:

Error: Unsupported TypeScript version: 2.1.0-dev.20160725
    at Object.current (D:\...\node_modules\codelyzer\util\syntaxKind.js:1796:23)
    at ClassMetadataWalker.visitClassDeclaration (D:\...\node_modules\codelyzer\useLifeCycleInterfaceRule.js:40:37)
    at ClassMetadataWalker.SyntaxWalker.visitNode (D:\...\node_modules\tslint\lib\language\walker\syntaxWalker.js:264:22)
    at D:\...\node_modules\tslint\lib\language\walker\syntaxWalker.js:459:63
    at visitEachNode (D:\...\node_modules\typescript\lib\typescript.js:8115:30)
    at Object.forEachChild (D:\...\node_modules\typescript\lib\typescript.js:8273:24)
    at ClassMetadataWalker.SyntaxWalker.walkChildren (D:\...\node_modules\tslint\lib\language\walker\syntaxWalker.js:459:12)
    at ClassMetadataWalker.SyntaxWalker.visitSourceFile (D:\...\node_modules\tslint\lib\language\walker\syntaxWalker.js:190:14)
    at ClassMetadataWalker.SyntaxWalker.visitNode (D:\...\node_modules\tslint\lib\language\walker\syntaxWalker.js:414:22)
    at ClassMetadataWalker.SyntaxWalker.walk (D:\...\node_modules\tslint\lib\language\walker\syntaxWalker.js:7:14)

npm ERR! Windows_NT 6.1.7601
npm ERR! argv "c:\\Program Files\\nodejs\\node.exe" "C:\\Users\\...\\AppData\\Roaming\\npm\\node_modules\\npm\\bin\\npm-cli.js" "run" "tslint"
npm ERR! node v6.3.1
npm ERR! npm  v3.10.6
npm ERR! code ELIFECYCLE
npm ERR! [email protected] tslint: `tslint -c ./node_modules/.../tslint.json --force ./app/**/*.ts`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] tslint script 'tslint -c ./node_modules/.../tslint.json --force ./app/**/*.ts'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the ... package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     tslint -c ./node_modules/.../tslint.json --force ./app/**/*.ts
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs ...
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls ...
npm ERR! There is likely additional logging output above.

docs - usage

It would be cool to have usage in docs, because it is not immediately obvious how to use this tool. :)

Issue parsing ts file

/Users/bsmith/Development/git/qasymphony/kitsune-ui/node_modules/codelyzer/noAttributeParameterDecoratorRule.js:30
        var parentName = node.parent.name.text;
                                         ^

TypeError: Cannot read property 'text' of undefined
    at ConstructorMetadataWalker.visitConstructorDeclaration (/Users/bsmith/Development/git/qasymphony/kitsune-ui/node_modules/codelyzer/noAttributeParameterDecoratorRule.js:30:42)
    at ConstructorMetadataWalker.SyntaxWalker.visitNode (/Users/bsmith/Development/git/qasymphony/kitsune-ui/node_modules/tslint/lib/language/walker/syntaxWalker.js:264:22)
    at /Users/bsmith/Development/git/qasymphony/kitsune-ui/node_modules/tslint/lib/language/walker/syntaxWalker.js:441:63
    at visitEachNode (/Users/bsmith/Development/git/qasymphony/kitsune-ui/node_modules/typescript/lib/typescript.js:7255:30)
    at Object.forEachChild (/Users/bsmith/Development/git/qasymphony/kitsune-ui/node_modules/typescript/lib/typescript.js:7484:21)
    at ConstructorMetadataWalker.SyntaxWalker.walkChildren (/Users/bsmith/Development/git/qasymphony/kitsune-ui/node_modules/tslint/lib/language/walker/syntaxWalker.js:441:12)
    at ConstructorMetadataWalker.SyntaxWalker.visitNode (/Users/bsmith/Development/git/qasymphony/kitsune-ui/node_modules/tslint/lib/language/walker/syntaxWalker.js:435:22)
    at /Users/bsmith/Development/git/qasymphony/kitsune-ui/node_modules/tslint/lib/language/walker/syntaxWalker.js:441:63
    at visitNode (/Users/bsmith/Development/git/qasymphony/kitsune-ui/node_modules/typescript/lib/typescript.js:7243:20)
    at Object.forEachChild (/Users/bsmith/Development/git/qasymphony/kitsune-ui/node_modules/typescript/lib/typescript.js:7303:21)

A gist of the file: here
tslint.json: here

tsc -v
Version 1.8.10
tslint -v
3.9.0

Add validation for Style 03-05 Import Destructuring Spacing

The official Angular Style Guide has a rule called "Import Destructuring Spacing" that says that one space should be present after the opening brace and before the closing brace of import statements. For example:

Bad
import {Component, EventEmitter} from '@angular/core';

Good
import { Component, EventEmitter } from '@angular/core';

This rule should probably also be applied to export statements inside barrels.

[feat] Can we store the default prefix?

Hi @mgechev , thanks for a great Codelyzer!
I would like to integrate it with my starter, so far no issue, but I found some rules value is repetitive, for example:

"directive-selector-prefix": [true, "as"],
"component-selector-prefix": [true, "as"],
"pipe-naming": [true, "camelCase", "as"],

the repetitive part is "as" one, it'd be cool if I can store the prefix default in variable like

"prefix-default": "as",
"directive-selector-prefix": [true],
"component-selector-prefix": [true],
"pipe-naming": [true, "camelCase"]

so I need to change only one part to reflect all of them, of course we can override the default one with usual way

It'd be great to have this feature
Thank you!

Component selector prefix

With the current configuration, this lints all of the components to match only one feature. The Angular2 styleguide encourages use of prefixes for some selectors that may be otherwise ambiguous. These prefixes are supposed to be centered around the specific feature the component is associated with. For example, toh-heroes or admin-users. The current configuration makes the desired prefix static, which doesn't make sense. Instead, it should simply check the presence of a prefix at all and remind the user to name it after the feature, perhaps checking the context making sure other components in the same directory with potentially colliding names across the app also use the same prefix.

There should be some rules covering the templates

There is currently no way to lint the templates and check whether the selectors are correctly written or even if they are closed. for example if I have a component Sample with selector sample and then in a different file I have :

Import Sample from './sample.ts';
@Component({
  selector: 'example',
  template: `<samples></samples>`
})

This currently doesn't produce any linting errors, although samples is neither a native html selector nor the selector of the imported file sample.ts.

another example is having template: '<sampl></sample>' . I believe that there should be simple parsing for the templates (at least the inline ones).

Feature request: allow use of host property in @Component if values are strings

I would like a way to allow using the host property in component/directive decorators as long as the keys are being set to string values. For example, this code:

@Component({
  selector: 'my-component',
  host: {
    class: 'some-base-class some-modifier-class other-modifier-class'
  }
})
class MyComponent {}

seems more readable than:

@Component({
  selector: 'my-component'
})
class MyComponent {
  @HostBinding('class.some-base-class')
  someBaseClass = true;

  @HostBinding('class.some-modifier-class')
  someModifierClass = true;

  @HostBinding('class.other-modifier-class')
  otherModifierClass = true;
}

Show Lint errors when running the ng lint command

Is the ng lint command supposed to tell me what the lint errors actually are? Right now when I run it, it just says "Lint errors found in the listed files" and does not tell me what the lint errors are

Do not rename inputs/outputs

In case the file looks like:

@Directive(...)
class Foo {
  @Input('bar') bar;
}

This is not a rename but the rule will throw an error. The assertion should be slightly refactored.

directive-selector-name rule gives error for "[validateEmail][ngControl],[validateEmail][ngModel],[validateEmail][ngFormControl]" syntax

I have custom email validator like below

@Directive({`
    selector: '[validateEmail][ngControl],[validateEmail][ngModel],[validateEmail][ngFormControl]',
    providers: [
        provide(NG_VALIDATORS, {
            useClass: EmailValidatorDirective, multi: true             
        })
    ]
})

but it gives

The selector of the directive "EmailValidatorDirective" should be named camelCase (https://goo.gl/rdGf2b)

even it is in camel case

component-selector-name: should it really warn for names without dashes?

I'm a fan of concise code and naming (not obscure acronyms , just short names). So I like to keep my component names short. For example:

@Component({
  selector: 'transaction'
})

This throws a no-kebab-case warning. IMO a simple string without any capitalisation or special characters should pass this rule and not fail.

@mgechev, bug or just different opinions?

Attempting to contribute a fileNameBase rule & failing miserably

I've started a fork with some changes around creating a fileNameBase rule with the idea of eventually getting to supporting the styleguide's concept of kebab-case (configurable of course) with .component.ts suffix's.

I've never written any sort of linting rule before so this is all new to me, so I appologize if I seem like a newb but i'm running into some trouble. First off I recognize that my rule right now will just always fail, that's just my first step...

After transpiling the rule and getting it to run i hit the following error:

TypeError: Cannot read property 'call' of undefined
at FileNameValidatorWalker.visitClassDeclaration (C:\extras\projectx\authoring-ui\node_modules\ng2lint\dist\src\fileNameBase.js:44:37)
at FileNameValidatorWalker.SyntaxWalker.visitNode (C:\extras\projectx\authoring-ui\node_modules\tslint\lib\language\walker\syntaxWalker.js:255:22)
at C:\extras\projectx\authoring-ui\node_modules\tslint\lib\language\walker\syntaxWalker.js:441:63
at visitEachNode (C:\extras\projectx\authoring-ui\node_modules\typescript\lib\typescript.js:7209:30)
at Object.forEachChild (C:\extras\projectx\authoring-ui\node_modules\typescript\lib\typescript.js:7360:24)
at FileNameValidatorWalker.SyntaxWalker.walkChildren (C:\extras\projectx\authoring-ui\node_modules\tslint\lib\language\walker\syntaxWalker.js:441:12)
at FileNameValidatorWalker.SyntaxWalker.visitSourceFile (C:\extras\projectx\authoring-ui\node_modules\tslint\lib\language\walker\syntaxWalker.js:181:14)
at FileNameValidatorWalker.SyntaxWalker.visitNode (C:\extras\projectx\authoring-ui\node_modules\tslint\lib\language\walker\syntaxWalker.js:396:22)
at FileNameValidatorWalker.SyntaxWalker.walk (C:\extras\projectx\authoring-ui\node_modules\tslint\lib\language\walker\syntaxWalker.js:7:14)
at Rule.AbstractRule.applyWithWalker (C:\extras\projectx\authoring-ui\node_modules\tslint\lib\language\rule\abstractRule.js:19:16)

which is just:

_super.visitClassDeclaration.call(this, node);

which is exactly the same as what is in (transpiled version of) the selectorNameBase.ts file that I based this on.

Thoughts?

Custom prefix error being confused for kebab-case error

Latest update of this library is confusing the following 2 rules:

  • Custom Prefix for Components (Style 02-07)
  • Components Selector Naming (Style 05-02)

So if you have a selector app, the error you get is the the kebab-case (05-02) error instead of the custom prefix error. Could it be updated so that kebab-case is proper checking where app would not fail? That way if a user would want to turn off the custom prefix rule but keep the kebab case rule, they could.

Prefixes could to be more restrictive

If we force our prefix to be my it will accept mys-foo or any string that starts with my actually.

Perhaps I am a bit nitpick here, but I just realized this when I was trying to report anything else :P

use-life-cycle-interface support for inheritance

If I have the following, would it be possible for the rule use-life-cycle-interface to not throw a lint error?

class Parent implements OnInit {
    public ngOnInit() {
    }
}

class Child extends Parent {
    public ngOnInit() {
        super.ngOnInit();
    }
}

kebab-case shouldn't allow non-hyphened string

As Style Guide says, a component name should be named in kebab-case. And it should follow Custom Elements spec.

Style 05-02
Do use kebab-case for naming the element selectors of our components.
Why? Keeps the element names consistent with the specification for Custom Elements.

Custom Elements spec says the following:

The custom element type identifies a custom element interface and is a sequence of characters that must match the NCName production [XML-NAMES], must contain a U+002D HYPHEN-MINUS character, and must not contain any uppercase ASCII letters [HTML]. The custom element type must not be one of the following values:

But currently codelyzer allows a name doesn't contain hyphen as kebab-case.

  • selector: "foobar" : passed
  • selector: "foo-bar" : passed
  • selector: "fooBar" : invalid

Expected

selector: "foobar" should be an error in kebab-case rule.

Atom Issues

I have a tslint.json in my base directory with
"rulesDirectory": ["node_modules/codelyzer/dist/src"]

But I get constant errors from Atom saying Could not find custom rule directory: /node_modules/codelyzer/dist/src

I saved codelyzer to both global and as a dev dependency

Use metadata reader

@chuckjaz implemented much more advanced metadata reader which soon will land in the Angular 2 official repository angular/angular#7492.

We can use both:

  • MetadataReader, for the module which warns/ensures correctness of the program.
  • Evaluator for the linting module, which can help us get "foldable" values.

// cc @preslavsh

useLifeCycleInterfaceRule failing with a Symbol.iterator

Having this class:

export class Heroes implements Iterable<Hero> {
  ...

  [Symbol.iterator]() {
    return this.currentHeroes.values();
  }

  ...
}

I get this error:

TypeError: Cannot read property 'substr' of undefined at useLifeCycleInterfaceRule.js:58:44

Is not the interface itself, is the Symbol.iterator.

Forbidden Imports

I'd like to forbid imports to a certain file to avoid that too much code is loaded even if not all is used. As an example I want to import rxjs. I do that through

import {Observable} from 'rxjs/Rx';

and wow, I have all the operators available and no further import statement has to be made. But this loads all the 100 operators event if I just need the 'map' operator. What I should import is only

import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/map';

I'd like to tell codelyzer that 'rxjs/Rx' is a forbidden import.

docs: contribution guidelines

contribution guidelines are missing :)

when #31 will be merged, I can add basic guideline, because it will be easy as

  • npm install
  • npm run test:watch

Rules destination

I think node_modules/codelyzer/dist/src is not intuitive. Mainly dist/src part.

I'd like to import rules from node_modules/codelyzer/dist/rules or .../dist/ng2lint

non-ts version?

A non-typescript version would be nice! is this on your roadmap?

noForwardRefRule crash

Using Typescript 1.8.10, tslint 3.10.2 and codelyzer 0.0.19, I get a crash when evaluating the following code:

const CUSTOM_VALUE_ACCESSOR = new Provider(
    NG_VALUE_ACCESSOR, { useExisting: forwardRef(() => CountryListValueAccessor)});

This is what appears in the log, executed via Webstorm:

2016-06-03 09:28:23,062 [421353309]   INFO - avascript.linter.tslint.TsLint - TsLint inner error. TsLint version: 3.10.2

/usr/local/lib/node_modules/codelyzer/noForwardRefRule.js:36
var failureConfig = [currentNode.name.text];
^

TypeError: Cannot read property 'text' of undefined
at ExpressionCallMetadataWalker.validateCallExpression (/usr/local/lib/node_modules/codelyzer/noForwardRefRule.js:36:50)
at ExpressionCallMetadataWalker.visitCallExpression (/usr/local/lib/node_modules/codelyzer/noForwardRefRule.js:27:14)
at ExpressionCallMetadataWalker.SyntaxWalker.visitNode (/usr/local/lib/node_modules/tslint/lib/language/walker/syntaxWalker.js:249:22)
at /usr/local/lib/node_modules/tslint/lib/language/walker/syntaxWalker.js:447:63
at visitNode (/usr/local/lib/node_modules/typescript/lib/typescript.js:7243:20)
at Object.forEachChild (/usr/local/lib/node_modules/typescript/lib/typescript.js:7303:21)
at ExpressionCallMetadataWalker.SyntaxWalker.walkChildren (/usr/local/lib/node_modules/tslint/lib/language/walker/syntaxWalker.js:447:12)
at ExpressionCallMetadataWalker.SyntaxWalker.visitPropertyAssignment (/usr/local/lib/node_modules/tslint/lib/language/walker/syntaxWalker.js:166:14)
at ExpressionCallMetadataWalker.SyntaxWalker.visitNode (/usr/local/lib/node_modules/tslint/lib/language/walker/syntaxWalker.js:384:22)
at /usr/local/lib/node_modules/tslint/lib/language/walker/syntaxWalker.js:447:63

"no-console" rule

I want to enable tslint's "no-console" rule. I tried by adding this line "no-console": [true, ["log", "error"]] to my tslint.json file but it didn't work.

Does codelyzer override tslint's built-in rules or it just adds spcefic rules?

Regards!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.