From 4cd22082b2b4abc0bc370979282c716b3dd40aea Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Sun, 26 Jan 2020 18:17:12 +0100 Subject: [PATCH] refactor(rules): port rules to typescript (#785) * refactor(ensure): expose target case type for rules * refactor(rules): rewrite all rules and tests to typescript * refactor(rules): refactor indentation and readability for case rules * test(rules): ignore types file and use ts extension * test(rules): import non-typed preset with require * chore: remove javascript rules pattern from jest * fix(rules): export rule types for implementing packages --- @commitlint/ensure/src/case.ts | 2 +- @commitlint/ensure/src/index.ts | 1 + @commitlint/rules/package.json | 11 +-- .../{body-case.test.js => body-case.test.ts} | 2 +- .../rules/src/{body-case.js => body-case.ts} | 7 +- ...{body-empty.test.js => body-empty.test.ts} | 2 +- .../src/{body-empty.js => body-empty.ts} | 5 +- ...ank.test.js => body-leading-blank.test.ts} | 2 +- ...leading-blank.js => body-leading-blank.ts} | 3 +- ...length.test.js => body-max-length.test.ts} | 8 +-- ...{body-max-length.js => body-max-length.ts} | 7 +- ...h.test.js => body-max-line-length.test.ts} | 12 ++-- ...line-length.js => body-max-line-length.ts} | 7 +- ...length.test.js => body-min-length.test.ts} | 8 +-- ...{body-min-length.js => body-min-length.ts} | 7 +- ...ter-empty.test.js => footer-empty.test.ts} | 2 +- .../src/{footer-empty.js => footer-empty.ts} | 5 +- ...k.test.js => footer-leading-blank.test.ts} | 2 +- ...ading-blank.js => footer-leading-blank.ts} | 5 +- ...ngth.test.js => footer-max-length.test.ts} | 10 +-- ...ter-max-length.js => footer-max-length.ts} | 7 +- ...test.js => footer-max-line-length.test.ts} | 14 ++-- ...ne-length.js => footer-max-line-length.ts} | 7 +- ...ngth.test.js => footer-min-length.test.ts} | 10 +-- ...ter-min-length.js => footer-min-length.ts} | 8 ++- ...eader-case.test.js => header-case.test.ts} | 2 +- .../src/{header-case.js => header-case.ts} | 13 ++-- ...-stop.test.js => header-full-stop.test.ts} | 10 +-- ...eader-full-stop.js => header-full-stop.ts} | 7 +- ...ngth.test.js => header-max-length.test.ts} | 6 +- ...der-max-length.js => header-max-length.ts} | 7 +- ...ngth.test.js => header-min-length.test.ts} | 6 +- ...der-min-length.js => header-min-length.ts} | 7 +- @commitlint/rules/src/index.js | 67 ------------------ .../src/{index.test.js => index.test.ts} | 10 +-- @commitlint/rules/src/index.ts | 69 +++++++++++++++++++ ...empty.test.js => references-empty.test.ts} | 5 +- ...eferences-empty.js => references-empty.ts} | 3 +- ...{scope-case.test.js => scope-case.test.ts} | 2 +- .../src/{scope-case.js => scope-case.ts} | 13 ++-- ...cope-empty.test.js => scope-empty.test.ts} | 2 +- .../src/{scope-empty.js => scope-empty.ts} | 5 +- ...{scope-enum.test.js => scope-enum.test.ts} | 2 +- .../src/{scope-enum.js => scope-enum.ts} | 7 +- ...ength.test.js => scope-max-length.test.ts} | 8 +-- ...cope-max-length.js => scope-max-length.ts} | 7 +- ...ength.test.js => scope-min-length.test.ts} | 8 +-- ...cope-min-length.js => scope-min-length.ts} | 7 +- ...d-off-by.test.js => signed-off-by.test.ts} | 34 ++++++--- .../{signed-off-by.js => signed-off-by.ts} | 7 +- ...ject-case.test.js => subject-case.test.ts} | 2 +- .../src/{subject-case.js => subject-case.ts} | 13 ++-- ...ct-empty.test.js => subject-empty.test.ts} | 2 +- .../{subject-empty.js => subject-empty.ts} | 5 +- ...stop.test.js => subject-full-stop.test.ts} | 14 ++-- ...ject-full-stop.js => subject-full-stop.ts} | 7 +- ...gth.test.js => subject-max-length.test.ts} | 8 +-- ...ct-max-length.js => subject-max-length.ts} | 7 +- ...gth.test.js => subject-min-length.test.ts} | 8 +-- ...ct-min-length.js => subject-min-length.ts} | 7 +- .../{type-case.test.js => type-case.test.ts} | 2 +- .../rules/src/{type-case.js => type-case.ts} | 13 ++-- ...{type-empty.test.js => type-empty.test.ts} | 2 +- .../src/{type-empty.js => type-empty.ts} | 5 +- .../{type-enum.test.js => type-enum.test.ts} | 38 +++++----- .../rules/src/{type-enum.js => type-enum.ts} | 7 +- ...length.test.js => type-max-length.test.ts} | 8 +-- ...{type-max-length.js => type-max-length.ts} | 7 +- ...length.test.js => type-min-length.test.ts} | 8 +-- ...{type-min-length.js => type-min-length.ts} | 7 +- @commitlint/rules/src/types.ts | 25 +++++++ @commitlint/rules/tsconfig.json | 15 ++++ jest.config.js | 2 +- tsconfig.json | 3 +- 74 files changed, 431 insertions(+), 252 deletions(-) rename @commitlint/rules/src/{body-case.test.js => body-case.test.ts} (98%) rename @commitlint/rules/src/{body-case.js => body-case.ts} (71%) rename @commitlint/rules/src/{body-empty.test.js => body-empty.test.ts} (97%) rename @commitlint/rules/src/{body-empty.js => body-empty.ts} (62%) rename @commitlint/rules/src/{body-leading-blank.test.js => body-leading-blank.test.ts} (97%) rename @commitlint/rules/src/{body-leading-blank.js => body-leading-blank.ts} (83%) rename @commitlint/rules/src/{body-max-length.test.js => body-max-length.test.ts} (71%) rename @commitlint/rules/src/{body-max-length.js => body-max-length.ts} (63%) rename @commitlint/rules/src/{body-max-line-length.test.js => body-max-line-length.test.ts} (71%) rename @commitlint/rules/src/{body-max-line-length.js => body-max-line-length.ts} (64%) rename @commitlint/rules/src/{body-min-length.test.js => body-min-length.test.ts} (71%) rename @commitlint/rules/src/{body-min-length.js => body-min-length.ts} (61%) rename @commitlint/rules/src/{footer-empty.test.js => footer-empty.test.ts} (97%) rename @commitlint/rules/src/{footer-empty.js => footer-empty.ts} (61%) rename @commitlint/rules/src/{footer-leading-blank.test.js => footer-leading-blank.test.ts} (98%) rename @commitlint/rules/src/{footer-leading-blank.js => footer-leading-blank.ts} (78%) rename @commitlint/rules/src/{footer-max-length.test.js => footer-max-length.test.ts} (71%) rename @commitlint/rules/src/{footer-max-length.js => footer-max-length.ts} (63%) rename @commitlint/rules/src/{footer-max-line-length.test.js => footer-max-line-length.test.ts} (70%) rename @commitlint/rules/src/{footer-max-line-length.js => footer-max-line-length.ts} (64%) rename @commitlint/rules/src/{footer-min-length.test.js => footer-min-length.test.ts} (71%) rename @commitlint/rules/src/{footer-min-length.js => footer-min-length.ts} (61%) rename @commitlint/rules/src/{header-case.test.js => header-case.test.ts} (99%) rename @commitlint/rules/src/{header-case.js => header-case.ts} (65%) rename @commitlint/rules/src/{header-full-stop.test.js => header-full-stop.test.ts} (67%) rename @commitlint/rules/src/{header-full-stop.js => header-full-stop.ts} (69%) rename @commitlint/rules/src/{header-max-length.test.js => header-max-length.test.ts} (69%) rename @commitlint/rules/src/{header-max-length.js => header-max-length.ts} (62%) rename @commitlint/rules/src/{header-min-length.test.js => header-min-length.test.ts} (70%) rename @commitlint/rules/src/{header-min-length.js => header-min-length.ts} (62%) delete mode 100644 @commitlint/rules/src/index.js rename @commitlint/rules/src/{index.test.js => index.test.ts} (72%) create mode 100644 @commitlint/rules/src/index.ts rename @commitlint/rules/src/{references-empty.test.js => references-empty.test.ts} (95%) rename @commitlint/rules/src/{references-empty.js => references-empty.ts} (71%) rename @commitlint/rules/src/{scope-case.test.js => scope-case.test.ts} (99%) rename @commitlint/rules/src/{scope-case.js => scope-case.ts} (71%) rename @commitlint/rules/src/{scope-empty.test.js => scope-empty.test.ts} (97%) rename @commitlint/rules/src/{scope-empty.js => scope-empty.ts} (62%) rename @commitlint/rules/src/{scope-enum.test.js => scope-enum.test.ts} (98%) rename @commitlint/rules/src/{scope-enum.js => scope-enum.ts} (76%) rename @commitlint/rules/src/{scope-max-length.test.js => scope-max-length.test.ts} (70%) rename @commitlint/rules/src/{scope-max-length.js => scope-max-length.ts} (63%) rename @commitlint/rules/src/{scope-min-length.test.js => scope-min-length.test.ts} (70%) rename @commitlint/rules/src/{scope-min-length.js => scope-min-length.ts} (63%) rename @commitlint/rules/src/{signed-off-by.test.js => signed-off-by.test.ts} (68%) rename @commitlint/rules/src/{signed-off-by.js => signed-off-by.ts} (76%) rename @commitlint/rules/src/{subject-case.test.js => subject-case.test.ts} (99%) rename @commitlint/rules/src/{subject-case.js => subject-case.ts} (65%) rename @commitlint/rules/src/{subject-empty.test.js => subject-empty.test.ts} (96%) rename @commitlint/rules/src/{subject-empty.js => subject-empty.ts} (61%) rename @commitlint/rules/src/{subject-full-stop.test.js => subject-full-stop.test.ts} (67%) rename @commitlint/rules/src/{subject-full-stop.js => subject-full-stop.ts} (72%) rename @commitlint/rules/src/{subject-max-length.test.js => subject-max-length.test.ts} (70%) rename @commitlint/rules/src/{subject-max-length.js => subject-max-length.ts} (63%) rename @commitlint/rules/src/{subject-min-length.test.js => subject-min-length.test.ts} (70%) rename @commitlint/rules/src/{subject-min-length.js => subject-min-length.ts} (63%) rename @commitlint/rules/src/{type-case.test.js => type-case.test.ts} (99%) rename @commitlint/rules/src/{type-case.js => type-case.ts} (63%) rename @commitlint/rules/src/{type-empty.test.js => type-empty.test.ts} (96%) rename @commitlint/rules/src/{type-empty.js => type-empty.ts} (61%) rename @commitlint/rules/src/{type-enum.test.js => type-enum.test.ts} (65%) rename @commitlint/rules/src/{type-enum.js => type-enum.ts} (76%) rename @commitlint/rules/src/{type-max-length.test.js => type-max-length.test.ts} (70%) rename @commitlint/rules/src/{type-max-length.js => type-max-length.ts} (63%) rename @commitlint/rules/src/{type-min-length.test.js => type-min-length.test.ts} (70%) rename @commitlint/rules/src/{type-min-length.js => type-min-length.ts} (63%) create mode 100644 @commitlint/rules/src/types.ts create mode 100644 @commitlint/rules/tsconfig.json diff --git a/@commitlint/ensure/src/case.ts b/@commitlint/ensure/src/case.ts index 909e73aa68..40d1dde568 100644 --- a/@commitlint/ensure/src/case.ts +++ b/@commitlint/ensure/src/case.ts @@ -2,7 +2,7 @@ import * as _ from 'lodash'; export default ensureCase; -type TargetCaseType = +export type TargetCaseType = | 'camel-case' | 'kebab-case' | 'snake-case' diff --git a/@commitlint/ensure/src/index.ts b/@commitlint/ensure/src/index.ts index 982e128525..143d6d078c 100644 --- a/@commitlint/ensure/src/index.ts +++ b/@commitlint/ensure/src/index.ts @@ -8,3 +8,4 @@ import notEmpty from './not-empty'; export {ensureCase as case}; export {ensureEnum as enum}; export {maxLength, maxLineLength, minLength, notEmpty}; +export {TargetCaseType} from './case'; diff --git a/@commitlint/rules/package.json b/@commitlint/rules/package.json index 8d30d4e0e9..9eab1b36dc 100644 --- a/@commitlint/rules/package.json +++ b/@commitlint/rules/package.json @@ -3,20 +3,13 @@ "version": "8.3.4", "description": "Lint your commit messages", "main": "lib/index.js", + "types": "lib/index.d.ts", "files": [ "lib/" ], "scripts": { - "build": "cross-env NODE_ENV=production babel src --out-dir lib --source-maps", "deps": "dep-check", - "pkg": "pkg-check --skip-import", - "start": "concurrently \"ava -c 4 --verbose --watch\" \"yarn run watch\"", - "watch": "babel src --out-dir lib --watch --source-maps" - }, - "babel": { - "presets": [ - "babel-preset-commitlint" - ] + "pkg": "pkg-check" }, "engines": { "node": ">=4" diff --git a/@commitlint/rules/src/body-case.test.js b/@commitlint/rules/src/body-case.test.ts similarity index 98% rename from @commitlint/rules/src/body-case.test.js rename to @commitlint/rules/src/body-case.test.ts index 3f5dd2f417..e4f1f5f1bd 100644 --- a/@commitlint/rules/src/body-case.test.js +++ b/@commitlint/rules/src/body-case.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import bodyCase from './body-case'; +import {bodyCase} from './body-case'; const messages = { empty: 'test: subject', diff --git a/@commitlint/rules/src/body-case.js b/@commitlint/rules/src/body-case.ts similarity index 71% rename from @commitlint/rules/src/body-case.js rename to @commitlint/rules/src/body-case.ts index dab5e80e60..cef24f86a3 100644 --- a/@commitlint/rules/src/body-case.js +++ b/@commitlint/rules/src/body-case.ts @@ -1,7 +1,12 @@ import * as ensure from '@commitlint/ensure'; import message from '@commitlint/message'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const bodyCase: Rule = ( + parsed, + when = 'always', + value = undefined +) => { const {body} = parsed; if (!body) { diff --git a/@commitlint/rules/src/body-empty.test.js b/@commitlint/rules/src/body-empty.test.ts similarity index 97% rename from @commitlint/rules/src/body-empty.test.js rename to @commitlint/rules/src/body-empty.test.ts index 574cb66db9..bc6f309e72 100644 --- a/@commitlint/rules/src/body-empty.test.js +++ b/@commitlint/rules/src/body-empty.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import bodyEmpty from './body-empty'; +import {bodyEmpty} from './body-empty'; const messages = { empty: 'test: subject', diff --git a/@commitlint/rules/src/body-empty.js b/@commitlint/rules/src/body-empty.ts similarity index 62% rename from @commitlint/rules/src/body-empty.js rename to @commitlint/rules/src/body-empty.ts index 58911a16b9..8df58844ae 100644 --- a/@commitlint/rules/src/body-empty.js +++ b/@commitlint/rules/src/body-empty.ts @@ -1,9 +1,10 @@ import * as ensure from '@commitlint/ensure'; import message from '@commitlint/message'; +import {Rule} from './types'; -export default (parsed, when) => { +export const bodyEmpty: Rule = (parsed, when = 'always') => { const negated = when === 'never'; - const notEmpty = ensure.notEmpty(parsed.body); + const notEmpty = ensure.notEmpty(parsed.body || ''); return [ negated ? notEmpty : !notEmpty, diff --git a/@commitlint/rules/src/body-leading-blank.test.js b/@commitlint/rules/src/body-leading-blank.test.ts similarity index 97% rename from @commitlint/rules/src/body-leading-blank.test.js rename to @commitlint/rules/src/body-leading-blank.test.ts index 5002b6dd25..18bda3783d 100644 --- a/@commitlint/rules/src/body-leading-blank.test.js +++ b/@commitlint/rules/src/body-leading-blank.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import bodyLeadingBlank from './body-leading-blank'; +import {bodyLeadingBlank} from './body-leading-blank'; const messages = { simple: 'test: subject', diff --git a/@commitlint/rules/src/body-leading-blank.js b/@commitlint/rules/src/body-leading-blank.ts similarity index 83% rename from @commitlint/rules/src/body-leading-blank.js rename to @commitlint/rules/src/body-leading-blank.ts index 1065011810..447557b0ff 100644 --- a/@commitlint/rules/src/body-leading-blank.js +++ b/@commitlint/rules/src/body-leading-blank.ts @@ -1,7 +1,8 @@ import toLines from '@commitlint/to-lines'; import message from '@commitlint/message'; +import {Rule} from './types'; -export default (parsed, when) => { +export const bodyLeadingBlank: Rule = (parsed, when) => { // Flunk if no body is found if (!parsed.body) { return [true]; diff --git a/@commitlint/rules/src/body-max-length.test.js b/@commitlint/rules/src/body-max-length.test.ts similarity index 71% rename from @commitlint/rules/src/body-max-length.test.js rename to @commitlint/rules/src/body-max-length.test.ts index c032eb0c84..c26d4ad042 100644 --- a/@commitlint/rules/src/body-max-length.test.js +++ b/@commitlint/rules/src/body-max-length.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './body-max-length'; +import {bodyMaxLength} from './body-max-length'; const short = 'a'; const long = 'ab'; @@ -19,19 +19,19 @@ const parsed = { }; test('with empty should succeed', async () => { - const [actual] = check(await parsed.empty, '', value); + const [actual] = bodyMaxLength(await parsed.empty, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with short should succeed', async () => { - const [actual] = check(await parsed.short, '', value); + const [actual] = bodyMaxLength(await parsed.short, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with long should fail', async () => { - const [actual] = check(await parsed.long, '', value); + const [actual] = bodyMaxLength(await parsed.long, undefined, value); const expected = false; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/body-max-length.js b/@commitlint/rules/src/body-max-length.ts similarity index 63% rename from @commitlint/rules/src/body-max-length.js rename to @commitlint/rules/src/body-max-length.ts index 335cd7bb3e..461fdb84b7 100644 --- a/@commitlint/rules/src/body-max-length.js +++ b/@commitlint/rules/src/body-max-length.ts @@ -1,6 +1,11 @@ import {maxLength} from '@commitlint/ensure'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const bodyMaxLength: Rule = ( + parsed, + when = undefined, + value = 0 +) => { const input = parsed.body; if (!input) { diff --git a/@commitlint/rules/src/body-max-line-length.test.js b/@commitlint/rules/src/body-max-line-length.test.ts similarity index 71% rename from @commitlint/rules/src/body-max-line-length.test.js rename to @commitlint/rules/src/body-max-line-length.test.ts index 64134242c3..32332e46a2 100644 --- a/@commitlint/rules/src/body-max-line-length.test.js +++ b/@commitlint/rules/src/body-max-line-length.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './body-max-line-length'; +import {bodyMaxLineLength} from './body-max-line-length'; const short = 'a'; const long = 'ab'; @@ -21,31 +21,31 @@ const parsed = { }; test('with empty should succeed', async () => { - const [actual] = check(await parsed.empty, '', value); + const [actual] = bodyMaxLineLength(await parsed.empty, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with short should succeed', async () => { - const [actual] = check(await parsed.short, '', value); + const [actual] = bodyMaxLineLength(await parsed.short, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with long should fail', async () => { - const [actual] = check(await parsed.long, '', value); + const [actual] = bodyMaxLineLength(await parsed.long, undefined, value); const expected = false; expect(actual).toEqual(expected); }); test('with short with multiple lines should succeed', async () => { - const [actual] = check(await parsed.short, '', value); + const [actual] = bodyMaxLineLength(await parsed.short, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with long with multiple lines should fail', async () => { - const [actual] = check(await parsed.long, '', value); + const [actual] = bodyMaxLineLength(await parsed.long, undefined, value); const expected = false; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/body-max-line-length.js b/@commitlint/rules/src/body-max-line-length.ts similarity index 64% rename from @commitlint/rules/src/body-max-line-length.js rename to @commitlint/rules/src/body-max-line-length.ts index 9f28f616bf..76d42d2d81 100644 --- a/@commitlint/rules/src/body-max-line-length.js +++ b/@commitlint/rules/src/body-max-line-length.ts @@ -1,6 +1,11 @@ import {maxLineLength} from '@commitlint/ensure'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const bodyMaxLineLength: Rule = ( + parsed, + when = undefined, + value = 0 +) => { const input = parsed.body; if (!input) { diff --git a/@commitlint/rules/src/body-min-length.test.js b/@commitlint/rules/src/body-min-length.test.ts similarity index 71% rename from @commitlint/rules/src/body-min-length.test.js rename to @commitlint/rules/src/body-min-length.test.ts index 3b3129880c..db259bafc0 100644 --- a/@commitlint/rules/src/body-min-length.test.js +++ b/@commitlint/rules/src/body-min-length.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './body-min-length'; +import {bodyMinLength} from './body-min-length'; const short = 'a'; const long = 'ab'; @@ -19,19 +19,19 @@ const parsed = { }; test('with simple should succeed', async () => { - const [actual] = check(await parsed.simple, '', value); + const [actual] = bodyMinLength(await parsed.simple, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with short should fail', async () => { - const [actual] = check(await parsed.short, '', value); + const [actual] = bodyMinLength(await parsed.short, undefined, value); const expected = false; expect(actual).toEqual(expected); }); test('with long should succeed', async () => { - const [actual] = check(await parsed.long, '', value); + const [actual] = bodyMinLength(await parsed.long, undefined, value); const expected = true; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/body-min-length.js b/@commitlint/rules/src/body-min-length.ts similarity index 61% rename from @commitlint/rules/src/body-min-length.js rename to @commitlint/rules/src/body-min-length.ts index 940876038c..a866db8512 100644 --- a/@commitlint/rules/src/body-min-length.js +++ b/@commitlint/rules/src/body-min-length.ts @@ -1,6 +1,11 @@ import {minLength} from '@commitlint/ensure'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const bodyMinLength: Rule = ( + parsed, + when = undefined, + value = 0 +) => { if (!parsed.body) { return [true]; } diff --git a/@commitlint/rules/src/footer-empty.test.js b/@commitlint/rules/src/footer-empty.test.ts similarity index 97% rename from @commitlint/rules/src/footer-empty.test.js rename to @commitlint/rules/src/footer-empty.test.ts index 17f2e29871..fc6525e269 100644 --- a/@commitlint/rules/src/footer-empty.test.js +++ b/@commitlint/rules/src/footer-empty.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import footerEmpty from './footer-empty'; +import {footerEmpty} from './footer-empty'; const messages = { simple: 'test: subject', diff --git a/@commitlint/rules/src/footer-empty.js b/@commitlint/rules/src/footer-empty.ts similarity index 61% rename from @commitlint/rules/src/footer-empty.js rename to @commitlint/rules/src/footer-empty.ts index 7aff4321e7..1f4ac03021 100644 --- a/@commitlint/rules/src/footer-empty.js +++ b/@commitlint/rules/src/footer-empty.ts @@ -1,9 +1,10 @@ import * as ensure from '@commitlint/ensure'; import message from '@commitlint/message'; +import {Rule} from './types'; -export default (parsed, when) => { +export const footerEmpty: Rule = (parsed, when = 'always') => { const negated = when === 'never'; - const notEmpty = ensure.notEmpty(parsed.footer); + const notEmpty = ensure.notEmpty(parsed.footer || ''); return [ negated ? notEmpty : !notEmpty, diff --git a/@commitlint/rules/src/footer-leading-blank.test.js b/@commitlint/rules/src/footer-leading-blank.test.ts similarity index 98% rename from @commitlint/rules/src/footer-leading-blank.test.js rename to @commitlint/rules/src/footer-leading-blank.test.ts index 82cc411243..c7abbf825d 100644 --- a/@commitlint/rules/src/footer-leading-blank.test.js +++ b/@commitlint/rules/src/footer-leading-blank.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import footerLeadingBlank from './footer-leading-blank'; +import {footerLeadingBlank} from './footer-leading-blank'; const messages = { simple: 'test: subject', diff --git a/@commitlint/rules/src/footer-leading-blank.js b/@commitlint/rules/src/footer-leading-blank.ts similarity index 78% rename from @commitlint/rules/src/footer-leading-blank.js rename to @commitlint/rules/src/footer-leading-blank.ts index fdbe09de7e..e4bb637842 100644 --- a/@commitlint/rules/src/footer-leading-blank.js +++ b/@commitlint/rules/src/footer-leading-blank.ts @@ -1,7 +1,8 @@ import toLines from '@commitlint/to-lines'; import message from '@commitlint/message'; +import {Rule} from './types'; -export default (parsed, when) => { +export const footerLeadingBlank: Rule = (parsed, when = 'always') => { // Flunk if no footer is found if (!parsed.footer) { return [true]; @@ -9,7 +10,7 @@ export default (parsed, when) => { const negated = when === 'never'; const rawLines = toLines(parsed.raw); - const bodyLines = toLines(parsed.body); + const bodyLines = parsed.body ? toLines(parsed.body) : []; const bodyOffset = bodyLines.length > 0 ? rawLines.indexOf(bodyLines[0]) : 1; const [leading] = rawLines.slice(bodyLines.length + bodyOffset); diff --git a/@commitlint/rules/src/footer-max-length.test.js b/@commitlint/rules/src/footer-max-length.test.ts similarity index 71% rename from @commitlint/rules/src/footer-max-length.test.js rename to @commitlint/rules/src/footer-max-length.test.ts index aa6a06f01f..9a7755aa5e 100644 --- a/@commitlint/rules/src/footer-max-length.test.js +++ b/@commitlint/rules/src/footer-max-length.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './footer-max-length'; +import {footerMaxLength} from './footer-max-length'; const short = 'BREAKING CHANGE: a'; const long = 'BREAKING CHANGE: ab'; @@ -21,25 +21,25 @@ const parsed = { }; test('with simple should succeed', async () => { - const [actual] = check(await parsed.simple, '', value); + const [actual] = footerMaxLength(await parsed.simple, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with empty should succeed', async () => { - const [actual] = check(await parsed.empty, '', value); + const [actual] = footerMaxLength(await parsed.empty, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with short should succeed', async () => { - const [actual] = check(await parsed.short, '', value); + const [actual] = footerMaxLength(await parsed.short, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with long should fail', async () => { - const [actual] = check(await parsed.long, '', value); + const [actual] = footerMaxLength(await parsed.long, undefined, value); const expected = false; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/footer-max-length.js b/@commitlint/rules/src/footer-max-length.ts similarity index 63% rename from @commitlint/rules/src/footer-max-length.js rename to @commitlint/rules/src/footer-max-length.ts index 36b3a3993c..0b7dfaffbb 100644 --- a/@commitlint/rules/src/footer-max-length.js +++ b/@commitlint/rules/src/footer-max-length.ts @@ -1,6 +1,11 @@ import {maxLength} from '@commitlint/ensure'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const footerMaxLength: Rule = ( + parsed, + when = undefined, + value = 0 +) => { const input = parsed.footer; if (!input) { diff --git a/@commitlint/rules/src/footer-max-line-length.test.js b/@commitlint/rules/src/footer-max-line-length.test.ts similarity index 70% rename from @commitlint/rules/src/footer-max-line-length.test.js rename to @commitlint/rules/src/footer-max-line-length.test.ts index 1c5e4559fd..86663d26c6 100644 --- a/@commitlint/rules/src/footer-max-line-length.test.js +++ b/@commitlint/rules/src/footer-max-line-length.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './footer-max-line-length'; +import {footerMaxLineLength} from './footer-max-line-length'; const short = 'BREAKING CHANGE: a'; const long = 'BREAKING CHANGE: ab'; @@ -23,37 +23,37 @@ const parsed = { }; test('with simple should succeed', async () => { - const [actual] = check(await parsed.simple, '', value); + const [actual] = footerMaxLineLength(await parsed.simple, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with empty should succeed', async () => { - const [actual] = check(await parsed.empty, '', value); + const [actual] = footerMaxLineLength(await parsed.empty, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with short should succeed', async () => { - const [actual] = check(await parsed.short, '', value); + const [actual] = footerMaxLineLength(await parsed.short, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with long should fail', async () => { - const [actual] = check(await parsed.long, '', value); + const [actual] = footerMaxLineLength(await parsed.long, undefined, value); const expected = false; expect(actual).toEqual(expected); }); test('with short with multiple lines should succeed', async () => { - const [actual] = check(await parsed.short, '', value); + const [actual] = footerMaxLineLength(await parsed.short, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with long with multiple lines should fail', async () => { - const [actual] = check(await parsed.long, '', value); + const [actual] = footerMaxLineLength(await parsed.long, undefined, value); const expected = false; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/footer-max-line-length.js b/@commitlint/rules/src/footer-max-line-length.ts similarity index 64% rename from @commitlint/rules/src/footer-max-line-length.js rename to @commitlint/rules/src/footer-max-line-length.ts index 019afeac3c..09a0c58743 100644 --- a/@commitlint/rules/src/footer-max-line-length.js +++ b/@commitlint/rules/src/footer-max-line-length.ts @@ -1,6 +1,11 @@ import {maxLineLength} from '@commitlint/ensure'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const footerMaxLineLength: Rule = ( + parsed, + when = undefined, + value = 0 +) => { const input = parsed.footer; if (!input) { diff --git a/@commitlint/rules/src/footer-min-length.test.js b/@commitlint/rules/src/footer-min-length.test.ts similarity index 71% rename from @commitlint/rules/src/footer-min-length.test.js rename to @commitlint/rules/src/footer-min-length.test.ts index ebf64122a0..fb94e5ae70 100644 --- a/@commitlint/rules/src/footer-min-length.test.js +++ b/@commitlint/rules/src/footer-min-length.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './footer-min-length'; +import {footerMinLength} from './footer-min-length'; const short = 'BREAKING CHANGE: a'; const long = 'BREAKING CHANGE: ab'; @@ -21,25 +21,25 @@ const parsed = { }; test('with simple should succeed', async () => { - const [actual] = check(await parsed.simple, '', value); + const [actual] = footerMinLength(await parsed.simple, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with empty should succeed', async () => { - const [actual] = check(await parsed.empty, '', value); + const [actual] = footerMinLength(await parsed.empty, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with short should fail', async () => { - const [actual] = check(await parsed.short, '', value); + const [actual] = footerMinLength(await parsed.short, undefined, value); const expected = false; expect(actual).toEqual(expected); }); test('with long should succeed', async () => { - const [actual] = check(await parsed.long, '', value); + const [actual] = footerMinLength(await parsed.long, undefined, value); const expected = true; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/footer-min-length.js b/@commitlint/rules/src/footer-min-length.ts similarity index 61% rename from @commitlint/rules/src/footer-min-length.js rename to @commitlint/rules/src/footer-min-length.ts index f0c01b6f00..980a756d25 100644 --- a/@commitlint/rules/src/footer-min-length.js +++ b/@commitlint/rules/src/footer-min-length.ts @@ -1,9 +1,15 @@ import {minLength} from '@commitlint/ensure'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const footerMinLength: Rule = ( + parsed, + when = undefined, + value = 0 +) => { if (!parsed.footer) { return [true]; } + return [ minLength(parsed.footer, value), `footer must not be shorter than ${value} characters` diff --git a/@commitlint/rules/src/header-case.test.js b/@commitlint/rules/src/header-case.test.ts similarity index 99% rename from @commitlint/rules/src/header-case.test.js rename to @commitlint/rules/src/header-case.test.ts index cda26ffb99..18bb83b4c8 100644 --- a/@commitlint/rules/src/header-case.test.js +++ b/@commitlint/rules/src/header-case.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import headerCase from './header-case'; +import {headerCase} from './header-case'; const messages = { numeric: '1.0.0\n', diff --git a/@commitlint/rules/src/header-case.js b/@commitlint/rules/src/header-case.ts similarity index 65% rename from @commitlint/rules/src/header-case.js rename to @commitlint/rules/src/header-case.ts index 779f4a5e97..144ecb39fa 100644 --- a/@commitlint/rules/src/header-case.js +++ b/@commitlint/rules/src/header-case.ts @@ -1,9 +1,14 @@ -import * as ensure from '@commitlint/ensure'; +import {TargetCaseType, case as ensureCase} from '@commitlint/ensure'; import message from '@commitlint/message'; +import {Rule} from './types'; -const negated = when => when === 'never'; +const negated = (when?: string) => when === 'never'; -export default (parsed, when, value) => { +export const headerCase: Rule = ( + parsed, + when = 'always', + value = [] +) => { const {header} = parsed; if (typeof header !== 'string' || !header.match(/^[a-z]/i)) { @@ -21,7 +26,7 @@ export default (parsed, when, value) => { }); const result = checks.some(check => { - const r = ensure.case(header, check.case); + const r = ensureCase(header, check.case); return negated(check.when) ? !r : r; }); diff --git a/@commitlint/rules/src/header-full-stop.test.js b/@commitlint/rules/src/header-full-stop.test.ts similarity index 67% rename from @commitlint/rules/src/header-full-stop.test.js rename to @commitlint/rules/src/header-full-stop.test.ts index 3fb32e07c8..36b7e0d7e9 100644 --- a/@commitlint/rules/src/header-full-stop.test.js +++ b/@commitlint/rules/src/header-full-stop.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './header-full-stop'; +import {headerFullStop} from './header-full-stop'; const messages = { with: `header.\n`, @@ -12,25 +12,25 @@ const parsed = { }; test('with against "always ." should succeed', async () => { - const [actual] = check(await parsed.with, 'always', '.'); + const [actual] = headerFullStop(await parsed.with, 'always', '.'); const expected = true; expect(actual).toEqual(expected); }); test('with against "never ." should fail', async () => { - const [actual] = check(await parsed.with, 'never', '.'); + const [actual] = headerFullStop(await parsed.with, 'never', '.'); const expected = false; expect(actual).toEqual(expected); }); test('without against "always ." should fail', async () => { - const [actual] = check(await parsed.without, 'always', '.'); + const [actual] = headerFullStop(await parsed.without, 'always', '.'); const expected = false; expect(actual).toEqual(expected); }); test('without against "never ." should succeed', async () => { - const [actual] = check(await parsed.without, 'never', '.'); + const [actual] = headerFullStop(await parsed.without, 'never', '.'); const expected = true; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/header-full-stop.js b/@commitlint/rules/src/header-full-stop.ts similarity index 69% rename from @commitlint/rules/src/header-full-stop.js rename to @commitlint/rules/src/header-full-stop.ts index f30ce6d12c..ffecb8d60c 100644 --- a/@commitlint/rules/src/header-full-stop.js +++ b/@commitlint/rules/src/header-full-stop.ts @@ -1,6 +1,11 @@ import message from '@commitlint/message'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const headerFullStop: Rule = ( + parsed, + when = 'always', + value = '.' +) => { const {header} = parsed; const negated = when === 'never'; const hasStop = header[header.length - 1] === value; diff --git a/@commitlint/rules/src/header-max-length.test.js b/@commitlint/rules/src/header-max-length.test.ts similarity index 69% rename from @commitlint/rules/src/header-max-length.test.js rename to @commitlint/rules/src/header-max-length.test.ts index 7b5574b7f6..dc83bba113 100644 --- a/@commitlint/rules/src/header-max-length.test.js +++ b/@commitlint/rules/src/header-max-length.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './header-max-length'; +import {headerMaxLength} from './header-max-length'; const short = 'test: a'; const long = 'test: ab'; @@ -17,13 +17,13 @@ const parsed = { }; test('with short should succeed', async () => { - const [actual] = check(await parsed.short, '', value); + const [actual] = headerMaxLength(await parsed.short, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with long should fail', async () => { - const [actual] = check(await parsed.long, '', value); + const [actual] = headerMaxLength(await parsed.long, undefined, value); const expected = false; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/header-max-length.js b/@commitlint/rules/src/header-max-length.ts similarity index 62% rename from @commitlint/rules/src/header-max-length.js rename to @commitlint/rules/src/header-max-length.ts index 4b54e2e6ad..ea0c3af965 100644 --- a/@commitlint/rules/src/header-max-length.js +++ b/@commitlint/rules/src/header-max-length.ts @@ -1,6 +1,11 @@ import {maxLength} from '@commitlint/ensure'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const headerMaxLength: Rule = ( + parsed, + when = undefined, + value = 0 +) => { return [ maxLength(parsed.header, value), `header must not be longer than ${value} characters, current length is ${ diff --git a/@commitlint/rules/src/header-min-length.test.js b/@commitlint/rules/src/header-min-length.test.ts similarity index 70% rename from @commitlint/rules/src/header-min-length.test.js rename to @commitlint/rules/src/header-min-length.test.ts index def268047b..4eb896e6ca 100644 --- a/@commitlint/rules/src/header-min-length.test.js +++ b/@commitlint/rules/src/header-min-length.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './header-min-length'; +import {headerMinLength} from './header-min-length'; const short = 'BREAKING CHANGE: a'; const long = 'BREAKING CHANGE: ab'; @@ -17,13 +17,13 @@ const parsed = { }; test('with short should fail', async () => { - const [actual] = check(await parsed.short, '', value); + const [actual] = headerMinLength(await parsed.short, undefined, value); const expected = false; expect(actual).toEqual(expected); }); test('with long should succeed', async () => { - const [actual] = check(await parsed.long, '', value); + const [actual] = headerMinLength(await parsed.long, undefined, value); const expected = true; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/header-min-length.js b/@commitlint/rules/src/header-min-length.ts similarity index 62% rename from @commitlint/rules/src/header-min-length.js rename to @commitlint/rules/src/header-min-length.ts index 35b2ed0fa2..82362d2de5 100644 --- a/@commitlint/rules/src/header-min-length.js +++ b/@commitlint/rules/src/header-min-length.ts @@ -1,6 +1,11 @@ import {minLength} from '@commitlint/ensure'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const headerMinLength: Rule = ( + parsed, + when = undefined, + value = 0 +) => { return [ minLength(parsed.header, value), `header must not be shorter than ${value} characters, current length is ${ diff --git a/@commitlint/rules/src/index.js b/@commitlint/rules/src/index.js deleted file mode 100644 index bfdc11ac5e..0000000000 --- a/@commitlint/rules/src/index.js +++ /dev/null @@ -1,67 +0,0 @@ -import bodyCase from './body-case'; -import bodyEmpty from './body-empty'; -import bodyLeadingBlank from './body-leading-blank'; -import bodyMaxLength from './body-max-length'; -import bodyMaxLineLength from './body-max-line-length'; -import bodyMinLength from './body-min-length'; -import footerEmpty from './footer-empty'; -import footerLeadingBlank from './footer-leading-blank'; -import footerMaxLength from './footer-max-length'; -import footerMaxLineLength from './footer-max-line-length'; -import footerMinLength from './footer-min-length'; -import headerCase from './header-case'; -import headerFullStop from './header-full-stop'; -import headerMaxLength from './header-max-length'; -import headerMinLength from './header-min-length'; -import referencesEmpty from './references-empty'; -import scopeCase from './scope-case'; -import scopeEmpty from './scope-empty'; -import scopeEnum from './scope-enum'; -import scopeMaxLength from './scope-max-length'; -import scopeMinLength from './scope-min-length'; -import signedOffBy from './signed-off-by'; -import subjectCase from './subject-case'; -import subjectEmpty from './subject-empty'; -import subjectFullStop from './subject-full-stop'; -import subjectMaxLength from './subject-max-length'; -import subjectMinLength from './subject-min-length'; -import typeCase from './type-case'; -import typeEmpty from './type-empty'; -import typeEnum from './type-enum'; -import typeMaxLength from './type-max-length'; -import typeMinLength from './type-min-length'; - -export default { - 'body-case': bodyCase, - 'body-empty': bodyEmpty, - 'body-leading-blank': bodyLeadingBlank, - 'body-max-length': bodyMaxLength, - 'body-max-line-length': bodyMaxLineLength, - 'body-min-length': bodyMinLength, - 'footer-empty': footerEmpty, - 'footer-leading-blank': footerLeadingBlank, - 'footer-max-length': footerMaxLength, - 'footer-max-line-length': footerMaxLineLength, - 'footer-min-length': footerMinLength, - 'header-case': headerCase, - 'header-full-stop': headerFullStop, - 'header-max-length': headerMaxLength, - 'header-min-length': headerMinLength, - 'references-empty': referencesEmpty, - 'scope-case': scopeCase, - 'scope-empty': scopeEmpty, - 'scope-enum': scopeEnum, - 'scope-max-length': scopeMaxLength, - 'scope-min-length': scopeMinLength, - 'signed-off-by': signedOffBy, - 'subject-case': subjectCase, - 'subject-empty': subjectEmpty, - 'subject-full-stop': subjectFullStop, - 'subject-max-length': subjectMaxLength, - 'subject-min-length': subjectMinLength, - 'type-case': typeCase, - 'type-empty': typeEmpty, - 'type-enum': typeEnum, - 'type-max-length': typeMaxLength, - 'type-min-length': typeMinLength -}; diff --git a/@commitlint/rules/src/index.test.js b/@commitlint/rules/src/index.test.ts similarity index 72% rename from @commitlint/rules/src/index.test.js rename to @commitlint/rules/src/index.test.ts index 4847974abf..75838535bc 100644 --- a/@commitlint/rules/src/index.test.js +++ b/@commitlint/rules/src/index.test.ts @@ -4,7 +4,7 @@ import values from 'lodash/values'; import rules from '.'; test('exports all rules', async () => { - const expected = (await glob('*.js')).sort(); + const expected = (await glob('*.ts')).sort(); const actual = Object.keys(rules).sort(); expect(actual).toEqual(expected); }); @@ -14,18 +14,18 @@ test('rules export functions', () => { expect(actual.every(rule => typeof rule === 'function')).toBe(true); }); -async function glob(pattern) { +async function glob(pattern: string | string[]) { const files = await globby(pattern, { - ignore: ['**/index.js', '**/*.test.js'], + ignore: ['**/index.ts', '**/*.test.ts', '**/types.ts'], cwd: __dirname }); return files.map(relative).map(toExport); } -function relative(filePath) { +function relative(filePath: string) { return path.relative(__dirname, filePath); } -function toExport(fileName) { +function toExport(fileName: string) { return path.basename(fileName, path.extname(fileName)); } diff --git a/@commitlint/rules/src/index.ts b/@commitlint/rules/src/index.ts new file mode 100644 index 0000000000..0a8b1f1f65 --- /dev/null +++ b/@commitlint/rules/src/index.ts @@ -0,0 +1,69 @@ +import {bodyCase} from './body-case'; +import {bodyEmpty} from './body-empty'; +import {bodyLeadingBlank} from './body-leading-blank'; +import {bodyMaxLength} from './body-max-length'; +import {bodyMaxLineLength} from './body-max-line-length'; +import {bodyMinLength} from './body-min-length'; +import {footerEmpty} from './footer-empty'; +import {footerLeadingBlank} from './footer-leading-blank'; +import {footerMaxLength} from './footer-max-length'; +import {footerMaxLineLength} from './footer-max-line-length'; +import {footerMinLength} from './footer-min-length'; +import {headerCase} from './header-case'; +import {headerFullStop} from './header-full-stop'; +import {headerMaxLength} from './header-max-length'; +import {headerMinLength} from './header-min-length'; +import {referencesEmpty} from './references-empty'; +import {scopeCase} from './scope-case'; +import {scopeEmpty} from './scope-empty'; +import {scopeEnum} from './scope-enum'; +import {scopeMaxLength} from './scope-max-length'; +import {scopeMinLength} from './scope-min-length'; +import {signedOffBy} from './signed-off-by'; +import {subjectCase} from './subject-case'; +import {subjectEmpty} from './subject-empty'; +import {subjectFullStop} from './subject-full-stop'; +import {subjectMaxLength} from './subject-max-length'; +import {subjectMinLength} from './subject-min-length'; +import {typeCase} from './type-case'; +import {typeEmpty} from './type-empty'; +import {typeEnum} from './type-enum'; +import {typeMaxLength} from './type-max-length'; +import {typeMinLength} from './type-min-length'; + +export * from './types'; + +export default { + 'body-case': bodyCase, + 'body-empty': bodyEmpty, + 'body-leading-blank': bodyLeadingBlank, + 'body-max-length': bodyMaxLength, + 'body-max-line-length': bodyMaxLineLength, + 'body-min-length': bodyMinLength, + 'footer-empty': footerEmpty, + 'footer-leading-blank': footerLeadingBlank, + 'footer-max-length': footerMaxLength, + 'footer-max-line-length': footerMaxLineLength, + 'footer-min-length': footerMinLength, + 'header-case': headerCase, + 'header-full-stop': headerFullStop, + 'header-max-length': headerMaxLength, + 'header-min-length': headerMinLength, + 'references-empty': referencesEmpty, + 'scope-case': scopeCase, + 'scope-empty': scopeEmpty, + 'scope-enum': scopeEnum, + 'scope-max-length': scopeMaxLength, + 'scope-min-length': scopeMinLength, + 'signed-off-by': signedOffBy, + 'subject-case': subjectCase, + 'subject-empty': subjectEmpty, + 'subject-full-stop': subjectFullStop, + 'subject-max-length': subjectMaxLength, + 'subject-min-length': subjectMinLength, + 'type-case': typeCase, + 'type-empty': typeEmpty, + 'type-enum': typeEnum, + 'type-max-length': typeMaxLength, + 'type-min-length': typeMinLength +}; diff --git a/@commitlint/rules/src/references-empty.test.js b/@commitlint/rules/src/references-empty.test.ts similarity index 95% rename from @commitlint/rules/src/references-empty.test.js rename to @commitlint/rules/src/references-empty.test.ts index b74876f25a..6a3e782dd6 100644 --- a/@commitlint/rules/src/references-empty.test.js +++ b/@commitlint/rules/src/references-empty.test.ts @@ -1,6 +1,7 @@ -import preset from 'conventional-changelog-angular'; import parse from '@commitlint/parse'; -import referencesEmpty from './references-empty'; +import {referencesEmpty} from './references-empty'; + +const preset = require('conventional-changelog-angular'); const messages = { plain: 'foo: bar', diff --git a/@commitlint/rules/src/references-empty.js b/@commitlint/rules/src/references-empty.ts similarity index 71% rename from @commitlint/rules/src/references-empty.js rename to @commitlint/rules/src/references-empty.ts index 87a7f15b74..3e3e483981 100644 --- a/@commitlint/rules/src/references-empty.js +++ b/@commitlint/rules/src/references-empty.ts @@ -1,6 +1,7 @@ import message from '@commitlint/message'; +import {Rule} from './types'; -export default (parsed, when = 'never') => { +export const referencesEmpty: Rule = (parsed, when = 'never') => { const negated = when === 'always'; const notEmpty = parsed.references.length > 0; return [ diff --git a/@commitlint/rules/src/scope-case.test.js b/@commitlint/rules/src/scope-case.test.ts similarity index 99% rename from @commitlint/rules/src/scope-case.test.js rename to @commitlint/rules/src/scope-case.test.ts index 330ece3067..14e6c1e323 100644 --- a/@commitlint/rules/src/scope-case.test.js +++ b/@commitlint/rules/src/scope-case.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import scopeCase from './scope-case'; +import {scopeCase} from './scope-case'; const messages = { empty: 'test: subject', diff --git a/@commitlint/rules/src/scope-case.js b/@commitlint/rules/src/scope-case.ts similarity index 71% rename from @commitlint/rules/src/scope-case.js rename to @commitlint/rules/src/scope-case.ts index b74e9a66d2..fc29fbe288 100644 --- a/@commitlint/rules/src/scope-case.js +++ b/@commitlint/rules/src/scope-case.ts @@ -1,9 +1,14 @@ -import * as ensure from '@commitlint/ensure'; +import {TargetCaseType, case as ensureCase} from '@commitlint/ensure'; import message from '@commitlint/message'; +import {Rule} from './types'; -const negated = when => when === 'never'; +const negated = (when?: string) => when === 'never'; -export default (parsed, when, value) => { +export const scopeCase: Rule = ( + parsed, + when = 'always', + value = [] +) => { const {scope} = parsed; if (!scope) { @@ -27,7 +32,7 @@ export default (parsed, when, value) => { const result = checks.some(check => { const r = scopeSegments.every( - segment => delimiters.test(segment) || ensure.case(segment, check.case) + segment => delimiters.test(segment) || ensureCase(segment, check.case) ); return negated(check.when) ? !r : r; diff --git a/@commitlint/rules/src/scope-empty.test.js b/@commitlint/rules/src/scope-empty.test.ts similarity index 97% rename from @commitlint/rules/src/scope-empty.test.js rename to @commitlint/rules/src/scope-empty.test.ts index d0893989e7..d85d1f1762 100644 --- a/@commitlint/rules/src/scope-empty.test.js +++ b/@commitlint/rules/src/scope-empty.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import scopeEmpty from './scope-empty'; +import {scopeEmpty} from './scope-empty'; const messages = { plain: 'foo(bar): baz', diff --git a/@commitlint/rules/src/scope-empty.js b/@commitlint/rules/src/scope-empty.ts similarity index 62% rename from @commitlint/rules/src/scope-empty.js rename to @commitlint/rules/src/scope-empty.ts index 65a28ac98a..89358a4b6d 100644 --- a/@commitlint/rules/src/scope-empty.js +++ b/@commitlint/rules/src/scope-empty.ts @@ -1,9 +1,10 @@ import * as ensure from '@commitlint/ensure'; import message from '@commitlint/message'; +import {Rule} from './types'; -export default (parsed, when = 'never') => { +export const scopeEmpty: Rule = (parsed, when = 'never') => { const negated = when === 'always'; - const notEmpty = ensure.notEmpty(parsed.scope); + const notEmpty = ensure.notEmpty(parsed.scope || ''); return [ negated ? !notEmpty : notEmpty, message(['scope', negated ? 'must' : 'may not', 'be empty']) diff --git a/@commitlint/rules/src/scope-enum.test.js b/@commitlint/rules/src/scope-enum.test.ts similarity index 98% rename from @commitlint/rules/src/scope-enum.test.js rename to @commitlint/rules/src/scope-enum.test.ts index f9b3f5186d..5054eee6f9 100644 --- a/@commitlint/rules/src/scope-enum.test.js +++ b/@commitlint/rules/src/scope-enum.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import scopeEnum from './scope-enum'; +import {scopeEnum} from './scope-enum'; const messages = { plain: 'foo(bar): baz', diff --git a/@commitlint/rules/src/scope-enum.js b/@commitlint/rules/src/scope-enum.ts similarity index 76% rename from @commitlint/rules/src/scope-enum.js rename to @commitlint/rules/src/scope-enum.ts index 608811c9e7..0753ae0b8d 100644 --- a/@commitlint/rules/src/scope-enum.js +++ b/@commitlint/rules/src/scope-enum.ts @@ -1,7 +1,12 @@ import * as ensure from '@commitlint/ensure'; import message from '@commitlint/message'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const scopeEnum: Rule = ( + parsed, + when = 'always', + value = [] +) => { if (!parsed.scope) { return [true, '']; } diff --git a/@commitlint/rules/src/scope-max-length.test.js b/@commitlint/rules/src/scope-max-length.test.ts similarity index 70% rename from @commitlint/rules/src/scope-max-length.test.js rename to @commitlint/rules/src/scope-max-length.test.ts index 9ad8cd89ed..fb67d69639 100644 --- a/@commitlint/rules/src/scope-max-length.test.js +++ b/@commitlint/rules/src/scope-max-length.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './scope-max-length'; +import {scopeMaxLength} from './scope-max-length'; const short = 'a'; const long = 'ab'; @@ -19,19 +19,19 @@ const parsed = { }; test('with empty should succeed', async () => { - const [actual] = check(await parsed.empty, '', value); + const [actual] = scopeMaxLength(await parsed.empty, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with short should succeed', async () => { - const [actual] = check(await parsed.short, '', value); + const [actual] = scopeMaxLength(await parsed.short, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with long should fail', async () => { - const [actual] = check(await parsed.long, '', value); + const [actual] = scopeMaxLength(await parsed.long, undefined, value); const expected = false; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/scope-max-length.js b/@commitlint/rules/src/scope-max-length.ts similarity index 63% rename from @commitlint/rules/src/scope-max-length.js rename to @commitlint/rules/src/scope-max-length.ts index 3056203049..f6eabaa105 100644 --- a/@commitlint/rules/src/scope-max-length.js +++ b/@commitlint/rules/src/scope-max-length.ts @@ -1,6 +1,11 @@ import {maxLength} from '@commitlint/ensure'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const scopeMaxLength: Rule = ( + parsed, + when = undefined, + value = 0 +) => { const input = parsed.scope; if (!input) { diff --git a/@commitlint/rules/src/scope-min-length.test.js b/@commitlint/rules/src/scope-min-length.test.ts similarity index 70% rename from @commitlint/rules/src/scope-min-length.test.js rename to @commitlint/rules/src/scope-min-length.test.ts index 0167c51d7e..9e9fca8ea8 100644 --- a/@commitlint/rules/src/scope-min-length.test.js +++ b/@commitlint/rules/src/scope-min-length.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './scope-min-length'; +import {scopeMinLength} from './scope-min-length'; const short = 'a'; const long = 'ab'; @@ -19,19 +19,19 @@ const parsed = { }; test('with empty should succeed', async () => { - const [actual] = check(await parsed.empty, '', value); + const [actual] = scopeMinLength(await parsed.empty, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with short should fail', async () => { - const [actual] = check(await parsed.short, '', value); + const [actual] = scopeMinLength(await parsed.short, undefined, value); const expected = false; expect(actual).toEqual(expected); }); test('with long should succeed', async () => { - const [actual] = check(await parsed.long, '', value); + const [actual] = scopeMinLength(await parsed.long, undefined, value); const expected = true; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/scope-min-length.js b/@commitlint/rules/src/scope-min-length.ts similarity index 63% rename from @commitlint/rules/src/scope-min-length.js rename to @commitlint/rules/src/scope-min-length.ts index 4cfae8564e..cf307968ee 100644 --- a/@commitlint/rules/src/scope-min-length.js +++ b/@commitlint/rules/src/scope-min-length.ts @@ -1,6 +1,11 @@ import {minLength} from '@commitlint/ensure'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const scopeMinLength: Rule = ( + parsed, + when = undefined, + value = 0 +) => { const input = parsed.scope; if (!input) { return [true]; diff --git a/@commitlint/rules/src/signed-off-by.test.js b/@commitlint/rules/src/signed-off-by.test.ts similarity index 68% rename from @commitlint/rules/src/signed-off-by.test.js rename to @commitlint/rules/src/signed-off-by.test.ts index fe7b14ea5c..144cfcbc44 100644 --- a/@commitlint/rules/src/signed-off-by.test.js +++ b/@commitlint/rules/src/signed-off-by.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './signed-off-by'; +import {signedOffBy} from './signed-off-by'; const messages = { empty: 'test:\n', @@ -18,61 +18,73 @@ const parsed = { }; test('empty against "always signed-off-by" should fail', async () => { - const [actual] = check(await parsed.empty, 'always', 'Signed-off-by:'); + const [actual] = signedOffBy(await parsed.empty, 'always', 'Signed-off-by:'); const expected = false; expect(actual).toEqual(expected); }); test('empty against "never signed-off-by" should succeed', async () => { - const [actual] = check(await parsed.empty, 'never', 'Signed-off-by:'); + const [actual] = signedOffBy(await parsed.empty, 'never', 'Signed-off-by:'); const expected = true; expect(actual).toEqual(expected); }); test('with against "always signed-off-by" should succeed', async () => { - const [actual] = check(await parsed.with, 'always', 'Signed-off-by:'); + const [actual] = signedOffBy(await parsed.with, 'always', 'Signed-off-by:'); const expected = true; expect(actual).toEqual(expected); }); test('with against "never signed-off-by" should fail', async () => { - const [actual] = check(await parsed.with, 'never', 'Signed-off-by:'); + const [actual] = signedOffBy(await parsed.with, 'never', 'Signed-off-by:'); const expected = false; expect(actual).toEqual(expected); }); test('without against "always signed-off-by" should fail', async () => { - const [actual] = check(await parsed.without, 'always', 'Signed-off-by:'); + const [actual] = signedOffBy( + await parsed.without, + 'always', + 'Signed-off-by:' + ); const expected = false; expect(actual).toEqual(expected); }); test('without against "never signed-off-by" should succeed', async () => { - const [actual] = check(await parsed.without, 'never', 'Signed-off-by:'); + const [actual] = signedOffBy(await parsed.without, 'never', 'Signed-off-by:'); const expected = true; expect(actual).toEqual(expected); }); test('inSubject against "always signed-off-by" should fail', async () => { - const [actual] = check(await parsed.inSubject, 'always', 'Signed-off-by:'); + const [actual] = signedOffBy( + await parsed.inSubject, + 'always', + 'Signed-off-by:' + ); const expected = false; expect(actual).toEqual(expected); }); test('inSubject against "never signed-off-by" should succeed', async () => { - const [actual] = check(await parsed.inSubject, 'never', 'Signed-off-by:'); + const [actual] = signedOffBy( + await parsed.inSubject, + 'never', + 'Signed-off-by:' + ); const expected = true; expect(actual).toEqual(expected); }); test('inBody against "always signed-off-by" should fail', async () => { - const [actual] = check(await parsed.inBody, 'always', 'Signed-off-by:'); + const [actual] = signedOffBy(await parsed.inBody, 'always', 'Signed-off-by:'); const expected = false; expect(actual).toEqual(expected); }); test('inBody against "never signed-off-by" should succeed', async () => { - const [actual] = check(await parsed.inBody, 'never', 'Signed-off-by:'); + const [actual] = signedOffBy(await parsed.inBody, 'never', 'Signed-off-by:'); const expected = true; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/signed-off-by.js b/@commitlint/rules/src/signed-off-by.ts similarity index 76% rename from @commitlint/rules/src/signed-off-by.js rename to @commitlint/rules/src/signed-off-by.ts index a148988f8d..78d844b486 100644 --- a/@commitlint/rules/src/signed-off-by.js +++ b/@commitlint/rules/src/signed-off-by.ts @@ -1,7 +1,12 @@ import message from '@commitlint/message'; import toLines from '@commitlint/to-lines'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const signedOffBy: Rule = ( + parsed, + when = 'always', + value = '' +) => { const lines = toLines(parsed.raw).filter(Boolean); const last = lines[lines.length - 1]; diff --git a/@commitlint/rules/src/subject-case.test.js b/@commitlint/rules/src/subject-case.test.ts similarity index 99% rename from @commitlint/rules/src/subject-case.test.js rename to @commitlint/rules/src/subject-case.test.ts index 73c2051baf..95c2a49b8c 100644 --- a/@commitlint/rules/src/subject-case.test.js +++ b/@commitlint/rules/src/subject-case.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import subjectCase from './subject-case'; +import {subjectCase} from './subject-case'; const messages = { empty: 'test:\n', diff --git a/@commitlint/rules/src/subject-case.js b/@commitlint/rules/src/subject-case.ts similarity index 65% rename from @commitlint/rules/src/subject-case.js rename to @commitlint/rules/src/subject-case.ts index 5f2ad8fdd7..4694cf7194 100644 --- a/@commitlint/rules/src/subject-case.js +++ b/@commitlint/rules/src/subject-case.ts @@ -1,9 +1,14 @@ -import * as ensure from '@commitlint/ensure'; +import {TargetCaseType, case as ensureCase} from '@commitlint/ensure'; import message from '@commitlint/message'; +import {Rule} from './types'; -const negated = when => when === 'never'; +const negated = (when?: string) => when === 'never'; -export default (parsed, when, value) => { +export const subjectCase: Rule = ( + parsed, + when = 'always', + value = [] +) => { const {subject} = parsed; if (typeof subject !== 'string' || !subject.match(/^[a-z]/i)) { @@ -21,7 +26,7 @@ export default (parsed, when, value) => { }); const result = checks.some(check => { - const r = ensure.case(subject, check.case); + const r = ensureCase(subject, check.case); return negated(check.when) ? !r : r; }); diff --git a/@commitlint/rules/src/subject-empty.test.js b/@commitlint/rules/src/subject-empty.test.ts similarity index 96% rename from @commitlint/rules/src/subject-empty.test.js rename to @commitlint/rules/src/subject-empty.test.ts index f8e6ad142b..201e887970 100644 --- a/@commitlint/rules/src/subject-empty.test.js +++ b/@commitlint/rules/src/subject-empty.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import subjectEmpty from './subject-empty'; +import {subjectEmpty} from './subject-empty'; const messages = { empty: 'test: \nbody', diff --git a/@commitlint/rules/src/subject-empty.js b/@commitlint/rules/src/subject-empty.ts similarity index 61% rename from @commitlint/rules/src/subject-empty.js rename to @commitlint/rules/src/subject-empty.ts index 707947f2a3..331adb5a4e 100644 --- a/@commitlint/rules/src/subject-empty.js +++ b/@commitlint/rules/src/subject-empty.ts @@ -1,9 +1,10 @@ import * as ensure from '@commitlint/ensure'; import message from '@commitlint/message'; +import {Rule} from './types'; -export default (parsed, when) => { +export const subjectEmpty: Rule = (parsed, when = 'always') => { const negated = when === 'never'; - const notEmpty = ensure.notEmpty(parsed.subject); + const notEmpty = ensure.notEmpty(parsed.subject || ''); return [ negated ? notEmpty : !notEmpty, diff --git a/@commitlint/rules/src/subject-full-stop.test.js b/@commitlint/rules/src/subject-full-stop.test.ts similarity index 67% rename from @commitlint/rules/src/subject-full-stop.test.js rename to @commitlint/rules/src/subject-full-stop.test.ts index bab1a051ed..f776d9645b 100644 --- a/@commitlint/rules/src/subject-full-stop.test.js +++ b/@commitlint/rules/src/subject-full-stop.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './subject-full-stop'; +import {subjectFullStop} from './subject-full-stop'; const messages = { empty: 'test:\n', @@ -14,37 +14,37 @@ const parsed = { }; test('empty against "always" should succeed', async () => { - const [actual] = check(await parsed.empty, 'always', '.'); + const [actual] = subjectFullStop(await parsed.empty, 'always', '.'); const expected = true; expect(actual).toEqual(expected); }); test('empty against "never ." should succeed', async () => { - const [actual] = check(await parsed.empty, 'never', '.'); + const [actual] = subjectFullStop(await parsed.empty, 'never', '.'); const expected = true; expect(actual).toEqual(expected); }); test('with against "always ." should succeed', async () => { - const [actual] = check(await parsed.with, 'always', '.'); + const [actual] = subjectFullStop(await parsed.with, 'always', '.'); const expected = true; expect(actual).toEqual(expected); }); test('with against "never ." should fail', async () => { - const [actual] = check(await parsed.with, 'never', '.'); + const [actual] = subjectFullStop(await parsed.with, 'never', '.'); const expected = false; expect(actual).toEqual(expected); }); test('without against "always ." should fail', async () => { - const [actual] = check(await parsed.without, 'always', '.'); + const [actual] = subjectFullStop(await parsed.without, 'always', '.'); const expected = false; expect(actual).toEqual(expected); }); test('without against "never ." should succeed', async () => { - const [actual] = check(await parsed.without, 'never', '.'); + const [actual] = subjectFullStop(await parsed.without, 'never', '.'); const expected = true; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/subject-full-stop.js b/@commitlint/rules/src/subject-full-stop.ts similarity index 72% rename from @commitlint/rules/src/subject-full-stop.js rename to @commitlint/rules/src/subject-full-stop.ts index 010a8f4c54..133f03b647 100644 --- a/@commitlint/rules/src/subject-full-stop.js +++ b/@commitlint/rules/src/subject-full-stop.ts @@ -1,6 +1,11 @@ import message from '@commitlint/message'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const subjectFullStop: Rule = ( + parsed, + when = 'always', + value = '.' +) => { const input = parsed.subject; if (!input) { diff --git a/@commitlint/rules/src/subject-max-length.test.js b/@commitlint/rules/src/subject-max-length.test.ts similarity index 70% rename from @commitlint/rules/src/subject-max-length.test.js rename to @commitlint/rules/src/subject-max-length.test.ts index 7765e56c10..b87c8a9318 100644 --- a/@commitlint/rules/src/subject-max-length.test.js +++ b/@commitlint/rules/src/subject-max-length.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './subject-max-length'; +import {subjectMaxLength} from './subject-max-length'; const short = 'a'; const long = 'ab'; @@ -19,19 +19,19 @@ const parsed = { }; test('with empty should succeed', async () => { - const [actual] = check(await parsed.empty, '', value); + const [actual] = subjectMaxLength(await parsed.empty, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with short should succeed', async () => { - const [actual] = check(await parsed.short, '', value); + const [actual] = subjectMaxLength(await parsed.short, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with long should fail', async () => { - const [actual] = check(await parsed.long, '', value); + const [actual] = subjectMaxLength(await parsed.long, undefined, value); const expected = false; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/subject-max-length.js b/@commitlint/rules/src/subject-max-length.ts similarity index 63% rename from @commitlint/rules/src/subject-max-length.js rename to @commitlint/rules/src/subject-max-length.ts index ba0f03e49c..af5000260f 100644 --- a/@commitlint/rules/src/subject-max-length.js +++ b/@commitlint/rules/src/subject-max-length.ts @@ -1,6 +1,11 @@ import {maxLength} from '@commitlint/ensure'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const subjectMaxLength: Rule = ( + parsed, + when = undefined, + value = 0 +) => { const input = parsed.subject; if (!input) { diff --git a/@commitlint/rules/src/subject-min-length.test.js b/@commitlint/rules/src/subject-min-length.test.ts similarity index 70% rename from @commitlint/rules/src/subject-min-length.test.js rename to @commitlint/rules/src/subject-min-length.test.ts index e6b5a78a95..dfb68fd37d 100644 --- a/@commitlint/rules/src/subject-min-length.test.js +++ b/@commitlint/rules/src/subject-min-length.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './subject-min-length'; +import {subjectMinLength} from './subject-min-length'; const short = 'a'; const long = 'ab'; @@ -19,19 +19,19 @@ const parsed = { }; test('with empty should succeed', async () => { - const [actual] = check(await parsed.empty, '', value); + const [actual] = subjectMinLength(await parsed.empty, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with short should fail', async () => { - const [actual] = check(await parsed.short, '', value); + const [actual] = subjectMinLength(await parsed.short, undefined, value); const expected = false; expect(actual).toEqual(expected); }); test('with long should succeed', async () => { - const [actual] = check(await parsed.long, '', value); + const [actual] = subjectMinLength(await parsed.long, undefined, value); const expected = true; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/subject-min-length.js b/@commitlint/rules/src/subject-min-length.ts similarity index 63% rename from @commitlint/rules/src/subject-min-length.js rename to @commitlint/rules/src/subject-min-length.ts index 0161b2ac80..5f86be8949 100644 --- a/@commitlint/rules/src/subject-min-length.js +++ b/@commitlint/rules/src/subject-min-length.ts @@ -1,6 +1,11 @@ import {minLength} from '@commitlint/ensure'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const subjectMinLength: Rule = ( + parsed, + when = undefined, + value = 0 +) => { const input = parsed.subject; if (!input) { return [true]; diff --git a/@commitlint/rules/src/type-case.test.js b/@commitlint/rules/src/type-case.test.ts similarity index 99% rename from @commitlint/rules/src/type-case.test.js rename to @commitlint/rules/src/type-case.test.ts index 0b69aa5500..2795ac610f 100644 --- a/@commitlint/rules/src/type-case.test.js +++ b/@commitlint/rules/src/type-case.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import typeCase from './type-case'; +import {typeCase} from './type-case'; const messages = { empty: '(scope): subject', diff --git a/@commitlint/rules/src/type-case.js b/@commitlint/rules/src/type-case.ts similarity index 63% rename from @commitlint/rules/src/type-case.js rename to @commitlint/rules/src/type-case.ts index c13144f006..2fc37ec35f 100644 --- a/@commitlint/rules/src/type-case.js +++ b/@commitlint/rules/src/type-case.ts @@ -1,9 +1,14 @@ -import * as ensure from '@commitlint/ensure'; +import {TargetCaseType, case as ensureCase} from '@commitlint/ensure'; import message from '@commitlint/message'; +import {Rule} from './types'; -const negated = when => when === 'never'; +const negated = (when?: string) => when === 'never'; -export default (parsed, when, value) => { +export const typeCase: Rule = ( + parsed, + when = 'always', + value = [] +) => { const {type} = parsed; if (!type) { @@ -21,7 +26,7 @@ export default (parsed, when, value) => { }); const result = checks.some(check => { - const r = ensure.case(type, check.case); + const r = ensureCase(type, check.case); return negated(check.when) ? !r : r; }); diff --git a/@commitlint/rules/src/type-empty.test.js b/@commitlint/rules/src/type-empty.test.ts similarity index 96% rename from @commitlint/rules/src/type-empty.test.js rename to @commitlint/rules/src/type-empty.test.ts index 01e29da5e7..1237044498 100644 --- a/@commitlint/rules/src/type-empty.test.js +++ b/@commitlint/rules/src/type-empty.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import typeEmpty from './type-empty'; +import {typeEmpty} from './type-empty'; const messages = { empty: '(scope):', diff --git a/@commitlint/rules/src/type-empty.js b/@commitlint/rules/src/type-empty.ts similarity index 61% rename from @commitlint/rules/src/type-empty.js rename to @commitlint/rules/src/type-empty.ts index bb946a3c82..667f6dfba0 100644 --- a/@commitlint/rules/src/type-empty.js +++ b/@commitlint/rules/src/type-empty.ts @@ -1,9 +1,10 @@ import * as ensure from '@commitlint/ensure'; import message from '@commitlint/message'; +import {Rule} from './types'; -export default (parsed, when) => { +export const typeEmpty: Rule = (parsed, when = 'always') => { const negated = when === 'never'; - const notEmpty = ensure.notEmpty(parsed.type); + const notEmpty = ensure.notEmpty(parsed.type || ''); return [ negated ? notEmpty : !notEmpty, message(['type', negated ? 'may not' : 'must', 'be empty']) diff --git a/@commitlint/rules/src/type-enum.test.js b/@commitlint/rules/src/type-enum.test.ts similarity index 65% rename from @commitlint/rules/src/type-enum.test.js rename to @commitlint/rules/src/type-enum.test.ts index 63957bb5c9..56a28ec26a 100644 --- a/@commitlint/rules/src/type-enum.test.js +++ b/@commitlint/rules/src/type-enum.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './type-enum'; +import {typeEnum} from './type-enum'; const messages = { empty: '(): \n', @@ -14,109 +14,109 @@ const parsed = { }; test('empty succeeds', async () => { - const [actual] = check(await parsed.empty); + const [actual] = typeEnum(await parsed.empty); const expected = true; expect(actual).toEqual(expected); }); test('empty on "a" succeeds', async () => { - const [actual] = check(await parsed.empty, '', ['a']); + const [actual] = typeEnum(await parsed.empty, undefined, ['a']); const expected = true; expect(actual).toEqual(expected); }); test('empty on "always a" succeeds', async () => { - const [actual] = check(await parsed.empty, 'always', ['a']); + const [actual] = typeEnum(await parsed.empty, 'always', ['a']); const expected = true; expect(actual).toEqual(expected); }); test('empty on "never a" succeeds', async () => { - const [actual] = check(await parsed.empty, 'never', ['a']); + const [actual] = typeEnum(await parsed.empty, 'never', ['a']); const expected = true; expect(actual).toEqual(expected); }); test('empty on "always a, b" succeeds', async () => { - const [actual] = check(await parsed.empty, 'always', ['a', 'b']); + const [actual] = typeEnum(await parsed.empty, 'always', ['a', 'b']); const expected = true; expect(actual).toEqual(expected); }); test('empty on "never a, b" succeeds', async () => { - const [actual] = check(await parsed.empty, 'neber', ['a', 'b']); + const [actual] = typeEnum(await parsed.empty, 'never', ['a', 'b']); const expected = true; expect(actual).toEqual(expected); }); test('a on "a" succeeds', async () => { - const [actual] = check(await parsed.a, '', ['a']); + const [actual] = typeEnum(await parsed.a, undefined, ['a']); const expected = true; expect(actual).toEqual(expected); }); test('a on "always a" succeeds', async () => { - const [actual] = check(await parsed.a, 'always', ['a']); + const [actual] = typeEnum(await parsed.a, 'always', ['a']); const expected = true; expect(actual).toEqual(expected); }); test('a on "never a" fails', async () => { - const [actual] = check(await parsed.a, 'never', ['a']); + const [actual] = typeEnum(await parsed.a, 'never', ['a']); const expected = false; expect(actual).toEqual(expected); }); test('b on "b" succeeds', async () => { - const [actual] = check(await parsed.b, '', ['b']); + const [actual] = typeEnum(await parsed.b, undefined, ['b']); const expected = true; expect(actual).toEqual(expected); }); test('b on "always b" succeeds', async () => { - const [actual] = check(await parsed.b, 'always', ['b']); + const [actual] = typeEnum(await parsed.b, 'always', ['b']); const expected = true; expect(actual).toEqual(expected); }); test('b on "never b" fails', async () => { - const [actual] = check(await parsed.b, 'never', ['b']); + const [actual] = typeEnum(await parsed.b, 'never', ['b']); const expected = false; expect(actual).toEqual(expected); }); test('a on "a, b" succeeds', async () => { - const [actual] = check(await parsed.a, '', ['a', 'b']); + const [actual] = typeEnum(await parsed.a, undefined, ['a', 'b']); const expected = true; expect(actual).toEqual(expected); }); test('a on "always a, b" succeeds', async () => { - const [actual] = check(await parsed.a, 'always', ['a', 'b']); + const [actual] = typeEnum(await parsed.a, 'always', ['a', 'b']); const expected = true; expect(actual).toEqual(expected); }); test('a on "never a, b" fails', async () => { - const [actual] = check(await parsed.a, 'never', ['a', 'b']); + const [actual] = typeEnum(await parsed.a, 'never', ['a', 'b']); const expected = false; expect(actual).toEqual(expected); }); test('b on "a, b" succeeds', async () => { - const [actual] = check(await parsed.b, '', ['a', 'b']); + const [actual] = typeEnum(await parsed.b, undefined, ['a', 'b']); const expected = true; expect(actual).toEqual(expected); }); test('b on "always a, b" succeeds', async () => { - const [actual] = check(await parsed.b, 'always', ['a', 'b']); + const [actual] = typeEnum(await parsed.b, 'always', ['a', 'b']); const expected = true; expect(actual).toEqual(expected); }); test('b on "never a, b" fails', async () => { - const [actual] = check(await parsed.b, 'never', ['a', 'b']); + const [actual] = typeEnum(await parsed.b, 'never', ['a', 'b']); const expected = false; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/type-enum.js b/@commitlint/rules/src/type-enum.ts similarity index 76% rename from @commitlint/rules/src/type-enum.js rename to @commitlint/rules/src/type-enum.ts index 7bd662059a..974f94fc6b 100644 --- a/@commitlint/rules/src/type-enum.js +++ b/@commitlint/rules/src/type-enum.ts @@ -1,7 +1,12 @@ import * as ensure from '@commitlint/ensure'; import message from '@commitlint/message'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const typeEnum: Rule = ( + parsed, + when = 'always', + value = [] +) => { const {type: input} = parsed; if (!input) { diff --git a/@commitlint/rules/src/type-max-length.test.js b/@commitlint/rules/src/type-max-length.test.ts similarity index 70% rename from @commitlint/rules/src/type-max-length.test.js rename to @commitlint/rules/src/type-max-length.test.ts index 537317f5f0..297c8210f2 100644 --- a/@commitlint/rules/src/type-max-length.test.js +++ b/@commitlint/rules/src/type-max-length.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './type-max-length'; +import {typeMaxLength} from './type-max-length'; const short = 'a'; const long = 'ab'; @@ -19,19 +19,19 @@ const parsed = { }; test('with empty should succeed', async () => { - const [actual] = check(await parsed.empty, '', value); + const [actual] = typeMaxLength(await parsed.empty, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with short should succeed', async () => { - const [actual] = check(await parsed.short, '', value); + const [actual] = typeMaxLength(await parsed.short, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with long should fail', async () => { - const [actual] = check(await parsed.long, '', value); + const [actual] = typeMaxLength(await parsed.long, undefined, value); const expected = false; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/type-max-length.js b/@commitlint/rules/src/type-max-length.ts similarity index 63% rename from @commitlint/rules/src/type-max-length.js rename to @commitlint/rules/src/type-max-length.ts index eb60ca12f4..fc06da43a6 100644 --- a/@commitlint/rules/src/type-max-length.js +++ b/@commitlint/rules/src/type-max-length.ts @@ -1,6 +1,11 @@ import {maxLength} from '@commitlint/ensure'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const typeMaxLength: Rule = ( + parsed, + when = undefined, + value = 0 +) => { const input = parsed.type; if (!input) { diff --git a/@commitlint/rules/src/type-min-length.test.js b/@commitlint/rules/src/type-min-length.test.ts similarity index 70% rename from @commitlint/rules/src/type-min-length.test.js rename to @commitlint/rules/src/type-min-length.test.ts index 6c9019ddf3..f4468c2fd7 100644 --- a/@commitlint/rules/src/type-min-length.test.js +++ b/@commitlint/rules/src/type-min-length.test.ts @@ -1,5 +1,5 @@ import parse from '@commitlint/parse'; -import check from './type-min-length'; +import {typeMinLength} from './type-min-length'; const short = 'a'; const long = 'ab'; @@ -19,19 +19,19 @@ const parsed = { }; test('with empty should succeed', async () => { - const [actual] = check(await parsed.empty, '', value); + const [actual] = typeMinLength(await parsed.empty, undefined, value); const expected = true; expect(actual).toEqual(expected); }); test('with short should fail', async () => { - const [actual] = check(await parsed.short, '', value); + const [actual] = typeMinLength(await parsed.short, undefined, value); const expected = false; expect(actual).toEqual(expected); }); test('with long should succeed', async () => { - const [actual] = check(await parsed.long, '', value); + const [actual] = typeMinLength(await parsed.long, undefined, value); const expected = true; expect(actual).toEqual(expected); }); diff --git a/@commitlint/rules/src/type-min-length.js b/@commitlint/rules/src/type-min-length.ts similarity index 63% rename from @commitlint/rules/src/type-min-length.js rename to @commitlint/rules/src/type-min-length.ts index 6c3f118f84..663091e989 100644 --- a/@commitlint/rules/src/type-min-length.js +++ b/@commitlint/rules/src/type-min-length.ts @@ -1,6 +1,11 @@ import {minLength} from '@commitlint/ensure'; +import {Rule} from './types'; -export default (parsed, when, value) => { +export const typeMinLength: Rule = ( + parsed, + when = undefined, + value = 0 +) => { const input = parsed.type; if (!input) { return [true]; diff --git a/@commitlint/rules/src/types.ts b/@commitlint/rules/src/types.ts new file mode 100644 index 0000000000..968f80f358 --- /dev/null +++ b/@commitlint/rules/src/types.ts @@ -0,0 +1,25 @@ +import {Commit} from '@commitlint/parse'; + +/** + * Rules always have a condition. + * It can be either "always" (as tested), or "never" (as tested). + * For example, `header-full-stop` can be enforced as "always" or "never". + */ +export type RuleCondition = 'always' | 'never'; + +/** + * Rules match the input either as successful or failed. + * For example, when `header-full-stop` detects a full stop and is set as "always"; it's true. + * If the `header-full-stop` discovers a full stop but is set to "never"; it's false. + */ +export type RuleOutcome = [boolean, string?]; + +/** + * Rules receive a parsed commit, condition, and possible additional settings through value. + * All rules should provide the most sensible rule condition and value. + */ +export type Rule = ( + parsed: Commit, + when?: RuleCondition, + value?: Value +) => RuleOutcome; diff --git a/@commitlint/rules/tsconfig.json b/@commitlint/rules/tsconfig.json new file mode 100644 index 0000000000..f4a57643f0 --- /dev/null +++ b/@commitlint/rules/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.shared.json", + "compilerOptions": { + "composite": true, + "rootDir": "./src", + "outDir": "./lib" + }, + "include": [ + "./src" + ], + "exclude": [ + "./src/**/*.test.ts", + "./lib/**/*" + ] +} diff --git a/jest.config.js b/jest.config.js index cb5fe8fb5d..8ef1d77fda 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,5 +2,5 @@ module.exports = { preset: 'ts-jest/presets/js-with-babel', testEnvironment: 'node', testRegex: undefined, - testMatch: ['**/*.test.ts?(x)', '**/@commitlint/rules/src/*.test.js?(x)'] + testMatch: ['**/*.test.ts?(x)'] }; diff --git a/tsconfig.json b/tsconfig.json index 02b03b0b40..3396fb062b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ { "path": "@commitlint/parse" }, { "path": "@commitlint/resolve-extends" }, { "path": "@commitlint/to-lines" }, - { "path": "@commitlint/top-level" }, + { "path": "@commitlint/top-level" }, + { "path": "@commitlint/rules" } ] }