salesforce-lightning-cliのlintをeslintから実行してみた

Lightning LockerService and Component Inheritance
http://salesforce.stackexchange.com/questions/118270/lightning-lockerservice-and-component-inheritance

で紹介されていた[salesforce-lightning-cli](https://www.npmjs.com/package/salesforce-lightning-cli)について。

なぜかHerokuプラグインとして提供されていたが、中身はeslintのルールなのでeslintから実行してみた。

----

eslintインストール
```$ npm install -g eslint```

salesforce-lightning-cliインストール
```$ npm install salesforce-lightning-cli```

eslint実行コマンド
eslint実行時にsalesforce-lightning-cliがもつルールフォルダを指定
```$ eslint src --rulesdir node_modules/salesforce-lightning-cli/rules```

----

ルールには現在以下がある。

### aura-api

$A配下のプロパティのホワイトリスト

### ecma-intrinsics

組み込みオブジェクトのホワイトリスト
実体は salesforce-lightning-cli/lib/3rdparty/ses/whitelist.js

### no-instanceof

instanceof禁止。

多分LockerService側で組み込みオブジェクトを勝手にラップするつもりなせい。
https://github.com/forcedotcom/aura/tree/master/aura-impl/src/main/resources/aura/locker

### secure-document

documentオブジェクトのホワイトリスト

### secure-window

windowオブジェクトのホワイトリスト


当たり前といえば当たり前だけど、ホワイトリスト系の制限はエイリアス作ると効かなくなる。

```js
$A.undefinedProperty
//=> error  Invalid Aura API                                    aura-api
const $$A = $A;
$$A.undefinedProperty
//=> safe
```


### 実行サンプル

実際に動かしてみたのは以下

.eslintrc

```json
{
    "parserOptions": {
        "ecmaVersion": 6
    },
    "rules": {
        "aura-api": 2,
        "ecma-intrinsics": 2,
        "no-instanceof": 2,
        "secure-document": 2,
        "secure-window": 2
    }
}
```

src/app.js

```js
$A.undefinedProperty;
//=> error  Invalid Aura API                                    aura-api
$A['undefinedProperty'];
//=> error  Invalid Aura API, use dot notation instead          aura-api
$A.log;
//=> safe
$A.util.isEmpty;
//=> safe
window['$A'].undefinedProperty;
//=> error  Invalid SecureWindow API, use dot notation instead  secure-window
const $$A = $A;
$$A.undefinedProperty;
//=> safe
Array.prototype.undefinedProperty
//=> error  Invalid Intrinsic API                               ecma-intrinsics
Array.prototype.slice.call([]);
//=> safe
Array.isArray([]);
//=> safe
Array.from([]);
//=> error  Invalid Intrinsic API                               ecma-intrinsics
Array['isArray'];
//=> error  Invalid Intrinsic API, use dot notation instead     ecma-intrinsics
[...document.querySelector('div')];
//=> safe
String.prototype.substring.call('aaa', 0);
//=> safe
String.prototype.repeat.call('aaa', 1);
//=> error  Invalid Intrinsic API                               ecma-intrinsics
'abc'.substring(1, 2);
//=> error  Invalid SecureWindow API, use dot notation instead  secure-window
'aaa'.repeat(2);
//=> error  Invalid SecureWindow API, use dot notation instead  secure-window
({}) instanceof Object;
//=> error  Check dangerous instanceof use                   no-instanceof
([]) instanceof Array;
//=> error  Check dangerous instanceof use, try Array.isArray() instead  no-instanceof
({}).prototype === Object;
//=> error  Check dangerous comparison with a promitive type Object      no-instanceof
([]).prototype === Array;
//=> error  Check dangerous comparison with a promitive type, try Array.isArray() instead  no-instanceof
document.undefinedProperty;
//=> error  Invalid SecureDocument API                            secure-document
document['body'];
//=> error  Invalid SecureDocument API, use dot notation instead  secure-document
document.onload;
//=> error  Invalid SecureDocument API                            secure-document
const doc = document;
doc.undefinedProperty;
//=> safe
window.onload;
//=> error  Invalid SecureWindow API                              secure-window
onload;
//=> safe
```