diff --git a/package.json b/package.json index 3ebe362..734b966 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "scripts": { "prerelease": "npm run build", "pretest": "npm run build -- --sourceMap", - "test": "nyc ava dist/test", + "test": "npm run lint && nyc ava dist/test", + "lint": "tslint --type-check -p tsconfig.json \"source/**/*.ts\"", "build": "del dist && tsc -p tsconfig.json --declaration" }, "files": [ @@ -52,6 +53,7 @@ "codecov": "^2.3.0", "del-cli": "^1.1.0", "nyc": "^11.2.1", + "tslint": "^5.7.0", "typescript": "^2.5.3" } } diff --git a/source/lib/argument-error.ts b/source/lib/argument-error.ts index 50b11f6..91249b2 100644 --- a/source/lib/argument-error.ts +++ b/source/lib/argument-error.ts @@ -2,7 +2,7 @@ export class ArgumentError extends Error { constructor(message, context) { super(message); // TODO: Node does not preserve the error name in output when using the below, why? - //Error.captureStackTrace(this, context); + // Error.captureStackTrace(this, context); this.name = 'ArgumentError'; } } diff --git a/source/lib/predicates/predicate.ts b/source/lib/predicates/predicate.ts index db8a6d9..d7249fd 100644 --- a/source/lib/predicates/predicate.ts +++ b/source/lib/predicates/predicate.ts @@ -1,8 +1,8 @@ import * as is from '@sindresorhus/is'; export interface Validator { - message: (value: T) => string; - validator: (value: T) => boolean; + message(value: T): string; + validator(value: T): boolean; } export interface Context { @@ -26,6 +26,11 @@ export class Predicate { return this.context.validators; } + /** + * Register a new validator. + * + * @param validator Validator to register. + */ protected addValidator(validator: Validator) { this.context.validators.push(validator); diff --git a/source/lib/predicates/string.ts b/source/lib/predicates/string.ts index 6992c2d..d75dcb8 100644 --- a/source/lib/predicates/string.ts +++ b/source/lib/predicates/string.ts @@ -9,12 +9,12 @@ export class StringPredicate extends Predicate { /** * Test a string to have a minimum length. * - * @param number The minimum length of the string. + * @param length The minimum length of the string. */ - minLength(number: number) { + minLength(length: number) { return this.addValidator({ - message: () => `Expected string length to be minimum ${number}`, - validator: value => value.length >= number + message: () => `Expected string length to be minimum ${length}`, + validator: value => value.length >= length }); } diff --git a/source/ow.ts b/source/ow.ts index 1d13c08..e50827d 100644 --- a/source/ow.ts +++ b/source/ow.ts @@ -1,4 +1,3 @@ -import * as is from '@sindresorhus/is'; import { ArgumentError } from './lib/argument-error'; import { Predicate, validatorSymbol } from './lib/predicates/predicate'; import { StringPredicate } from './lib/predicates/string'; @@ -8,18 +7,19 @@ export interface Ow { /** * Test the value to be a string. */ - string?: StringPredicate; + string: StringPredicate; } -export const ow: Ow = (value: any, predicate: Predicate) => { - for (const { validator, message } of predicate[validatorSymbol]) { - if (!validator(value)) { - // TODO: Modify the stack output to show the original `ow()` call instead of this `throw` statement - throw new ArgumentError(message(value), ow); +export const ow: Ow = Object.assign( + (value: any, predicate: Predicate) => { + for (const { validator, message } of predicate[validatorSymbol]) { + if (!validator(value)) { + // TODO: Modify the stack output to show the original `ow()` call instead of this `throw` statement + throw new ArgumentError(message(value), ow); + } } + }, + { + string: new StringPredicate() } -}; - -Object.defineProperty(ow, 'string', { - get: () => new StringPredicate() -}); +); diff --git a/tsconfig.json b/tsconfig.json index b5dec0d..621ffda 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "noImplicitUseStrict": false, "noFallthroughCasesInSwitch": true, "allowSyntheticDefaultImports": true, + "strictNullChecks": true, "outDir": "dist" }, "exclude": [ diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..4cc6fe3 --- /dev/null +++ b/tslint.json @@ -0,0 +1,114 @@ +{ + "rules": { + "adjacent-overload-signatures": true, + "no-empty-interface": true, + "no-import-side-effect": true, + "no-internal-module": true, + "no-namespace": true, + "no-non-null-assertion": true, + "no-parameter-reassignment": true, + "no-reference": true, + "no-unnecessary-type-assertion": true, + "no-var-requires": true, + "only-arrow-functions": true, + "prefer-for-of": true, + "promise-function-async": true, + "await-promise": true, + "curly": true, + "no-arg": true, + "no-conditional-assignment": true, + "no-construct": true, + "no-debugger": true, + "no-duplicate-super": true, + "no-duplicate-variable": true, + "no-empty": true, + "no-eval": true, + "no-floating-promises": true, + "no-for-in-array": true, + "no-invalid-template-strings": true, + "no-invalid-this": false, + "no-misused-new": true, + "no-shadowed-variable": true, + "no-sparse-arrays": true, + "no-string-literal": true, + "no-string-throw": true, + "no-switch-case-fall-through": true, + "no-this-assignment": true, + "no-unsafe-finally": true, + "no-unused-expression": true, + "no-unused-variable": true, + "no-use-before-declare": true, + "no-var-keyword": true, + "prefer-object-spread": true, + "radix": true, + "restrict-plus-operands": true, + "strict-type-predicates": true, + "switch-default": true, + "triple-equals": true, + "typeof-compare": true, + "use-default-type-parameter": true, + "use-isnan": true, + "deprecation": true, + "eofline": true, + "indent": [true, "tabs"], + "no-default-export": true, + "no-duplicate-imports": true, + "no-require-imports": true, + "prefer-const": true, + "trailing-comma": false, + "array-type": [true, "array"], + "arrow-parens": [true, "ban-single-arg-parens"], + "arrow-return-shorthand": true, + "binary-expression-operand-order": true, + "callable-types": true, + "class-name": true, + "comment-format": [true, "check-space", "check-uppercase"], + "completed-docs": [true, "methods"], + "encoding": true, + "import-spacing": true, + "interface-over-type-literal": true, + "newline-before-return": true, + "new-parens": true, + "no-angle-bracket-type-assertion": true, + "no-boolean-literal-compare": true, + "no-consecutive-blank-lines": true, + "no-irregular-whitespace": true, + "no-reference-import": true, + "no-trailing-whitespace": true, + "no-unnecessary-initializer": true, + "no-unnecessary-qualifier": true, + "number-literal-format": true, + "object-literal-key-quotes": [true, "as-needed"], + "object-literal-shorthand": true, + "one-variable-per-declaration": true, + "prefer-method-signature": true, + "prefer-template": [true, "allow-single-concat"], + "quotemark": [true, "single", "avoid-template"], + "semicolon": true, + "space-before-function-paren": [ + true, + { + "anonymous": "never", + "named": "never", + "asyncArrow": "always" + } + ], + "space-within-parens": [true, 0], + "switch-final-break": true, + "type-literal-delimiter": true, + "variable-name": [true, "check-format", "ban-keywords"], + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-module", + "check-separator", + "check-rest-spread", + "check-type", + "check-typecast", + "check-type-operator", + "check-preblock" + ] + } +}