aboutsummaryrefslogtreecommitdiffstats
path: root/packages/tslint-config
diff options
context:
space:
mode:
Diffstat (limited to 'packages/tslint-config')
-rw-r--r--packages/tslint-config/CHANGELOG.md13
-rw-r--r--packages/tslint-config/README.md57
-rw-r--r--packages/tslint-config/package.json81
-rw-r--r--packages/tslint-config/rules/asyncSuffixRule.ts10
-rw-r--r--packages/tslint-config/rules/underscorePrivatesRule.ts61
-rw-r--r--packages/tslint-config/rules/walkers/async_suffix.ts26
-rw-r--r--packages/tslint-config/tsconfig.json7
-rw-r--r--packages/tslint-config/tslint.json202
8 files changed, 311 insertions, 146 deletions
diff --git a/packages/tslint-config/CHANGELOG.md b/packages/tslint-config/CHANGELOG.md
index 7a6ba41c0..1d56bca5b 100644
--- a/packages/tslint-config/CHANGELOG.md
+++ b/packages/tslint-config/CHANGELOG.md
@@ -1,6 +1,15 @@
# CHANGELOG
-v0.1.0 - _Nov. 14, 2017_
-------------------------
+## v0.4.0 - _December 28, 2017_
+
+ * Added custom 'underscore-privates' rule, requiring underscores to be prepended to private variable names
+ * Because our tools can be used in both a TS and JS environment, we want to make the private methods of any public facing interface show up at the bottom of auto-complete lists. Additionally, we wanted to remain consistent with respect to our usage of underscores in order to enforce this rule with a linter rule, rather then manual code reviews.
+
+## v0.3.0 - _December 20, 2017_
+
+ * Added rules for unused imports, variables and Async suffixes (#265)
+
+## v0.1.0 - _Nov. 14, 2017_
+
* Re-published TsLintConfig previously published under NPM package `tslint-config-0xproject`
* Updated to TSLint v5.8.0, requiring several rule additions to keep our conventions aligned.
diff --git a/packages/tslint-config/README.md b/packages/tslint-config/README.md
index 38a6bce45..8a6fa8a2f 100644
--- a/packages/tslint-config/README.md
+++ b/packages/tslint-config/README.md
@@ -1,10 +1,57 @@
-tslint-config
--------------
+## @0xproject/tslint-config
-Lint rules related to 0xProject for TSLint.
+TSLint configuration and custom linter rules used by 0xProject.
-## Install:
+## Installation
```bash
-npm install @0xproject/tslint-config --save-dev
+yarn add --dev @0xproject/tslint-config
+```
+
+## Usage
+
+Add the following to your `tslint.json` file
+
+```json
+{
+ "extends": ["@0xproject/tslint-config"]
+}
+```
+
+## Contributing
+
+We strongly encourage that the community help us make improvements and determine the future direction of the protocol. To report bugs within this package, please create an issue in this repository.
+
+Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started.
+
+### Install Dependencies
+
+If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them:
+
+```bash
+yarn config set workspaces-experimental true
+```
+
+Then install dependencies
+
+```bash
+yarn install
+```
+
+### Build
+
+```bash
+yarn build
+```
+
+### Lint
+
+```bash
+yarn lint
+```
+
+### Run Tests
+
+```bash
+yarn test
```
diff --git a/packages/tslint-config/package.json b/packages/tslint-config/package.json
index 2b08d4f56..bcffe5a8e 100644
--- a/packages/tslint-config/package.json
+++ b/packages/tslint-config/package.json
@@ -1,38 +1,47 @@
{
- "name": "@0xproject/tslint-config",
- "version": "0.2.0",
- "description": "Lint rules related to 0xProject for TSLint",
- "main": "tslint.json",
- "files": [
- "tslint.js",
- "README.md",
- "LICENSE"
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/0xProject/0x.js.git"
- },
- "keywords": [
- "tslint",
- "config",
- "0xProject",
- "typescript",
- "ts"
- ],
- "author": {
- "name": "Fabio Berger",
- "email": "fabio@0xproject.com"
- },
- "license": "Apache-2.0",
- "bugs": {
- "url": "https://github.com/0xProject/0x.js/issues"
- },
- "homepage": "https://github.com/0xProject/0x.js/packages/tslint-config/README.md",
- "devDependencies": {
- "tslint": "5.8.0",
- "typescript": "~2.6.1"
- },
- "dependencies": {
- "tslint-react": "^3.2.0"
- }
+ "name": "@0xproject/tslint-config",
+ "version": "0.4.3",
+ "description": "Lint rules related to 0xProject for TSLint",
+ "main": "tslint.json",
+ "scripts": {
+ "build": "tsc",
+ "clean": "shx rm -rf lib",
+ "lint": "tslint --project . 'rules/**/*.ts'"
+ },
+ "files": [
+ "tslint.js",
+ "README.md",
+ "LICENSE"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/0xProject/0x.js.git"
+ },
+ "keywords": [
+ "tslint",
+ "config",
+ "0xProject",
+ "typescript",
+ "ts"
+ ],
+ "author": {
+ "name": "Fabio Berger",
+ "email": "fabio@0xproject.com"
+ },
+ "license": "Apache-2.0",
+ "bugs": {
+ "url": "https://github.com/0xProject/0x.js/issues"
+ },
+ "homepage": "https://github.com/0xProject/0x.js/packages/tslint-config/README.md",
+ "devDependencies": {
+ "@types/lodash": "^4.14.86",
+ "shx": "^0.2.2",
+ "tslint": "5.8.0",
+ "tslint-eslint-rules": "^4.1.1",
+ "typescript": "~2.6.1"
+ },
+ "dependencies": {
+ "lodash": "^4.17.4",
+ "tslint-react": "^3.2.0"
+ }
}
diff --git a/packages/tslint-config/rules/asyncSuffixRule.ts b/packages/tslint-config/rules/asyncSuffixRule.ts
new file mode 100644
index 000000000..5215c7151
--- /dev/null
+++ b/packages/tslint-config/rules/asyncSuffixRule.ts
@@ -0,0 +1,10 @@
+import * as Lint from 'tslint';
+import * as ts from 'typescript';
+
+import { AsyncSuffixWalker } from './walkers/async_suffix';
+
+export class Rule extends Lint.Rules.AbstractRule {
+ public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
+ return this.applyWithWalker(new AsyncSuffixWalker(sourceFile, this.getOptions()));
+ }
+}
diff --git a/packages/tslint-config/rules/underscorePrivatesRule.ts b/packages/tslint-config/rules/underscorePrivatesRule.ts
new file mode 100644
index 000000000..472ea09ff
--- /dev/null
+++ b/packages/tslint-config/rules/underscorePrivatesRule.ts
@@ -0,0 +1,61 @@
+import * as Lint from 'tslint';
+import * as ts from 'typescript';
+
+const UNDERSCORE = '_';
+
+type RelevantClassMember =
+ | ts.MethodDeclaration
+ | ts.PropertyDeclaration
+ | ts.GetAccessorDeclaration
+ | ts.SetAccessorDeclaration;
+
+// Copied from: https://github.com/DanielRosenwasser/underscore-privates-tslint-rule
+// The version on github is not published on npm
+export class Rule extends Lint.Rules.AbstractRule {
+ public static FAILURE_STRING = 'private members must be prefixed with an underscore';
+
+ public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
+ return this.applyWithFunction(sourceFile, walk);
+ }
+}
+function walk(ctx: Lint.WalkContext<void>): void {
+ traverse(ctx.sourceFile);
+
+ function traverse(node: ts.Node): void {
+ checkNodeForViolations(ctx, node);
+ return ts.forEachChild(node, traverse);
+ }
+}
+function checkNodeForViolations(ctx: Lint.WalkContext<void>, node: ts.Node): void {
+ if (!isRelevantClassMember(node)) {
+ return;
+ }
+ // The declaration might have a computed property name or a numeric name.
+ const name = node.name;
+ if (!nameIsIdentifier(name)) {
+ return;
+ }
+ if (!nameStartsWithUnderscore(name.text) && memberIsPrivate(node)) {
+ ctx.addFailureAtNode(name, Rule.FAILURE_STRING);
+ }
+}
+function isRelevantClassMember(node: ts.Node): node is RelevantClassMember {
+ switch (node.kind) {
+ case ts.SyntaxKind.MethodDeclaration:
+ case ts.SyntaxKind.PropertyDeclaration:
+ case ts.SyntaxKind.GetAccessor:
+ case ts.SyntaxKind.SetAccessor:
+ return true;
+ default:
+ return false;
+ }
+}
+function nameStartsWithUnderscore(text: string) {
+ return text.charCodeAt(0) === UNDERSCORE.charCodeAt(0);
+}
+function memberIsPrivate(node: ts.Declaration) {
+ return Lint.hasModifier(node.modifiers, ts.SyntaxKind.PrivateKeyword);
+}
+function nameIsIdentifier(node: ts.Node): node is ts.Identifier {
+ return node.kind === ts.SyntaxKind.Identifier;
+}
diff --git a/packages/tslint-config/rules/walkers/async_suffix.ts b/packages/tslint-config/rules/walkers/async_suffix.ts
new file mode 100644
index 000000000..eaec9c5f6
--- /dev/null
+++ b/packages/tslint-config/rules/walkers/async_suffix.ts
@@ -0,0 +1,26 @@
+import * as _ from 'lodash';
+import * as Lint from 'tslint';
+import * as ts from 'typescript';
+
+export class AsyncSuffixWalker extends Lint.RuleWalker {
+ public static FAILURE_STRING = 'async functions must have an Async suffix';
+ public visitMethodDeclaration(node: ts.MethodDeclaration): void {
+ const methodNameNode = node.name;
+ const methodName = methodNameNode.getText();
+ if (!_.isUndefined(node.type)) {
+ if (node.type.kind === ts.SyntaxKind.TypeReference) {
+ // tslint:disable-next-line:no-unnecessary-type-assertion
+ const returnTypeName = (node.type as ts.TypeReferenceNode).typeName.getText();
+ if (returnTypeName === 'Promise' && !methodName.endsWith('Async')) {
+ const failure = this.createFailure(
+ methodNameNode.getStart(),
+ methodNameNode.getWidth(),
+ AsyncSuffixWalker.FAILURE_STRING,
+ );
+ this.addFailure(failure);
+ }
+ }
+ }
+ super.visitMethodDeclaration(node);
+ }
+}
diff --git a/packages/tslint-config/tsconfig.json b/packages/tslint-config/tsconfig.json
new file mode 100644
index 000000000..15da53092
--- /dev/null
+++ b/packages/tslint-config/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "extends": "../../tsconfig",
+ "compilerOptions": {
+ "outDir": "lib"
+ },
+ "include": ["./rules/**/*"]
+}
diff --git a/packages/tslint-config/tslint.json b/packages/tslint-config/tslint.json
index 0921a3954..971588b08 100644
--- a/packages/tslint-config/tslint.json
+++ b/packages/tslint-config/tslint.json
@@ -1,105 +1,101 @@
{
- "extends": [
- "tslint:latest",
- "tslint-react"
- ],
- "rules": {
- "adjacent-overload-signatures": true,
- "arrow-parens": [true, "ban-single-arg-parens"],
- "arrow-return-shorthand": true,
- "await-promise": true,
- "binary-expression-operand-order": true,
- "callable-types": true,
- "class-name": true,
- "completed-docs": [
- true,
- {
- "functions": {"visibilities": ["exported"]},
- "methods": {"locations": "instance", "privacies": ["public", "protected"]}
- }
- ],
- "curly": true,
- "eofline": true,
- "encoding": true,
- "import-spacing": true,
- "indent": [true, "spaces", 4],
- "interface-name": false,
- "interface-over-type-literal": true,
- "linebreak-style": [true, "LF"],
- "max-classes-per-file": false,
- "max-classes-per-file": [true, 1],
- "max-file-line-count": [true, 500],
- "max-line-length": [true, 120],
- "member-access": true,
- "member-ordering": [true,
- "public-before-private",
- "static-before-instance",
- "variables-before-functions"
- ],
- "newline-before-return": false,
- "new-parens": true,
- "no-angle-bracket-type-assertion": true,
- "no-boolean-literal-compare": true,
- "no-default-export": true,
- "no-empty-interface": false,
- "no-floating-promises": true,
- "no-non-null-assertion": true,
- "no-parameter-reassignment": true,
- "no-redundant-jsdoc": true,
- "no-return-await": true,
- "no-string-throw": true,
- "no-submodule-imports": false,
- "no-unnecessary-type-assertion": true,
- "no-implicit-dependencies": [true, "dev"],
- "number-literal-format": true,
- "object-literal-sort-keys": false,
- "ordered-imports": [
- true,
- {
- "grouped-imports": true
- }
- ],
- "prefer-const": true,
- "prefer-for-of": true,
- "prefer-function-over-method": true,
- "promise-function-async": true,
- "quotemark": [true, "single", "avoid-escape", "jsx-double"],
- "semicolon": [true, "always"],
- "space-before-function-paren": [
- true,
- {
- "anonymous": "never",
- "named": "never",
- "method": "never",
- "constructor": "never",
- "asyncArrow": "always"
- }
- ],
- "space-within-parens": false,
- "type-literal-delimiter": true,
- "variable-name": [true,
- "ban-keywords",
- "allow-pascal-case"
- ],
- "whitespace": [
- true,
- "check-branch",
- "check-decl",
- "check-operator",
- "check-separator",
- "check-rest-spread",
- "check-type",
- "check-typecast",
- "check-preblock"
- ],
- "jsx-alignment": true,
- "jsx-boolean-value": true,
- "jsx-curly-spacing": [true, "never"],
- "jsx-no-lambda": true,
- "jsx-no-multiline-js": false,
- "jsx-no-string-ref": true,
- "jsx-self-close": true,
- "jsx-wrap-multiline": false,
- "jsx-no-bind": false
- }
+ "extends": ["tslint:latest", "tslint-react", "tslint-eslint-rules"],
+ "rules": {
+ "adjacent-overload-signatures": true,
+ "arrow-parens": [true, "ban-single-arg-parens"],
+ "arrow-return-shorthand": true,
+ "async-suffix": true,
+ "await-promise": true,
+ "binary-expression-operand-order": true,
+ "callable-types": true,
+ "class-name": true,
+ "completed-docs": [
+ true,
+ {
+ "functions": { "visibilities": ["exported"] },
+ "methods": { "locations": "instance", "privacies": ["public", "protected"] }
+ }
+ ],
+ "curly": true,
+ "eofline": true,
+ "encoding": true,
+ "import-spacing": true,
+ "indent": [true, "spaces", 4],
+ "interface-name": false,
+ "interface-over-type-literal": true,
+ "linebreak-style": [true, "LF"],
+ "max-classes-per-file": false,
+ "max-classes-per-file": [true, 1],
+ "max-line-length": false,
+ "max-file-line-count": [true, 500],
+ "member-access": true,
+ "member-ordering": [true, "public-before-private", "static-before-instance", "variables-before-functions"],
+ "newline-before-return": false,
+ "new-parens": true,
+ "no-angle-bracket-type-assertion": true,
+ "no-boolean-literal-compare": true,
+ "no-default-export": true,
+ "no-empty-interface": false,
+ "no-floating-promises": true,
+ "no-non-null-assertion": true,
+ "no-parameter-reassignment": true,
+ "no-redundant-jsdoc": true,
+ "no-return-await": true,
+ "no-string-throw": true,
+ "no-submodule-imports": false,
+ "no-unnecessary-type-assertion": true,
+ "no-unused-variable": [true, { "ignore-pattern": "^_\\d*" }],
+ "no-implicit-dependencies": [true, "dev"],
+ "number-literal-format": true,
+ "object-literal-sort-keys": false,
+ "object-literal-key-quotes": false,
+ "ordered-imports": [
+ true,
+ {
+ "grouped-imports": true
+ }
+ ],
+ "prefer-const": true,
+ "prefer-for-of": true,
+ "prefer-function-over-method": true,
+ "promise-function-async": true,
+ "quotemark": [true, "single", "avoid-escape", "jsx-double"],
+ "restrict-plus-operands": true,
+ "semicolon": [true, "always"],
+ "space-before-function-paren": [
+ true,
+ {
+ "anonymous": "never",
+ "named": "never",
+ "method": "never",
+ "constructor": "never",
+ "asyncArrow": "always"
+ }
+ ],
+ "space-within-parens": false,
+ "type-literal-delimiter": true,
+ "underscore-privates": true,
+ "variable-name": [true, "ban-keywords", "allow-pascal-case"],
+ "whitespace": [
+ true,
+ "check-branch",
+ "check-decl",
+ "check-operator",
+ "check-separator",
+ "check-rest-spread",
+ "check-type",
+ "check-typecast",
+ "check-preblock"
+ ],
+ "jsx-alignment": true,
+ "jsx-boolean-value": true,
+ "jsx-curly-spacing": [true, "never"],
+ "jsx-no-lambda": true,
+ "jsx-no-multiline-js": false,
+ "jsx-no-string-ref": true,
+ "jsx-self-close": true,
+ "jsx-wrap-multiline": false,
+ "jsx-no-bind": false
+ },
+ "rulesDirectory": "lib"
}