From 444306249b8a3d04524538f61edca8f6cc10d75f Mon Sep 17 00:00:00 2001 From: Mario Nebl Date: Tue, 18 Feb 2020 19:47:10 +1100 Subject: [PATCH] feat: add async promise based rules methods into lint (#976) * feat(rules): add async promise based rules methods into lint * fix: accomodate async rules in type system * style: apply autoformatting --- @commitlint/lint/src/lint.test.ts | 20 +++++++++++++++++++ @commitlint/lint/src/lint.ts | 19 +++++++++++------- @commitlint/rules/src/body-case.ts | 4 ++-- @commitlint/rules/src/body-empty.ts | 4 ++-- @commitlint/rules/src/body-leading-blank.ts | 4 ++-- @commitlint/rules/src/body-max-length.ts | 4 ++-- @commitlint/rules/src/body-max-line-length.ts | 4 ++-- @commitlint/rules/src/body-min-length.ts | 4 ++-- @commitlint/rules/src/footer-empty.ts | 4 ++-- @commitlint/rules/src/footer-leading-blank.ts | 4 ++-- @commitlint/rules/src/footer-max-length.ts | 4 ++-- .../rules/src/footer-max-line-length.ts | 4 ++-- @commitlint/rules/src/footer-min-length.ts | 4 ++-- @commitlint/rules/src/header-case.ts | 4 ++-- @commitlint/rules/src/header-full-stop.ts | 4 ++-- @commitlint/rules/src/header-max-length.ts | 4 ++-- @commitlint/rules/src/header-min-length.ts | 4 ++-- @commitlint/rules/src/references-empty.ts | 4 ++-- @commitlint/rules/src/scope-case.ts | 4 ++-- @commitlint/rules/src/scope-empty.ts | 4 ++-- @commitlint/rules/src/scope-enum.ts | 4 ++-- @commitlint/rules/src/scope-max-length.ts | 4 ++-- @commitlint/rules/src/scope-min-length.ts | 4 ++-- @commitlint/rules/src/signed-off-by.ts | 4 ++-- @commitlint/rules/src/subject-case.ts | 4 ++-- @commitlint/rules/src/subject-empty.ts | 4 ++-- @commitlint/rules/src/subject-full-stop.ts | 4 ++-- @commitlint/rules/src/subject-max-length.ts | 4 ++-- @commitlint/rules/src/subject-min-length.ts | 4 ++-- @commitlint/rules/src/type-case.ts | 4 ++-- @commitlint/rules/src/type-empty.ts | 4 ++-- @commitlint/rules/src/type-enum.ts | 4 ++-- @commitlint/rules/src/type-max-length.ts | 4 ++-- @commitlint/rules/src/type-min-length.ts | 4 ++-- @commitlint/types/src/rules.ts | 18 ++++++++++++++--- 35 files changed, 111 insertions(+), 74 deletions(-) diff --git a/@commitlint/lint/src/lint.test.ts b/@commitlint/lint/src/lint.test.ts index c8ff6cc123..3104eb5fb7 100644 --- a/@commitlint/lint/src/lint.test.ts +++ b/@commitlint/lint/src/lint.test.ts @@ -283,3 +283,23 @@ test('returns original message with commit header, body and footer, parsing comm expect(report.input).toBe(expected); }); + +test('passes for async rule', async () => { + const report = await lint( + 'somehting #1', + { + 'async-rule': [2, 'never'] + }, + { + plugins: { + 'example-plugin': { + rules: { + 'async-rule': async () => [true, 'all good'] as const + } + } + } + } + ); + + expect(report.valid).toBe(true); +}); diff --git a/@commitlint/lint/src/lint.ts b/@commitlint/lint/src/lint.ts index f216c7996e..873f1484fa 100644 --- a/@commitlint/lint/src/lint.ts +++ b/@commitlint/lint/src/lint.ts @@ -8,7 +8,9 @@ import { LintOptions, LintRuleOutcome, Rule, - RuleSeverity + RuleSeverity, + BaseRule, + RuleType } from '@commitlint/types'; export default async function lint( @@ -35,7 +37,7 @@ export default async function lint( // Parse the commit message const parsed = await parse(message, undefined, opts.parserOpts); - const allRules: Map | Rule> = new Map( + const allRules: Map> = new Map( Object.entries(defaultRules) ); @@ -130,9 +132,9 @@ export default async function lint( } // Validate against all rules - const results = Object.entries(rulesConfig) + const pendingResults = Object.entries(rulesConfig) .filter(([, [level]]) => level > 0) - .map(entry => { + .map(async entry => { const [name, config] = entry; const [level, when, value] = config; @@ -148,7 +150,7 @@ export default async function lint( } const executableRule = rule as Rule; - const [valid, message] = executableRule(parsed, when, value); + const [valid, message] = await executableRule(parsed, when, value); return { level, @@ -156,8 +158,11 @@ export default async function lint( name, message }; - }) - .filter((result): result is LintRuleOutcome => result !== null); + }); + + const results = (await Promise.all(pendingResults)).filter( + (result): result is LintRuleOutcome => result !== null + ); const errors = results.filter(result => result.level === 2 && !result.valid); const warnings = results.filter( diff --git a/@commitlint/rules/src/body-case.ts b/@commitlint/rules/src/body-case.ts index 62473783b9..f5262dede4 100644 --- a/@commitlint/rules/src/body-case.ts +++ b/@commitlint/rules/src/body-case.ts @@ -1,8 +1,8 @@ import {case as ensureCase} from '@commitlint/ensure'; import message from '@commitlint/message'; -import {TargetCaseType, Rule} from '@commitlint/types'; +import {TargetCaseType, SyncRule} from '@commitlint/types'; -export const bodyCase: Rule = ( +export const bodyCase: SyncRule = ( parsed, when = 'always', value = undefined diff --git a/@commitlint/rules/src/body-empty.ts b/@commitlint/rules/src/body-empty.ts index 571563bc9c..1fd787c000 100644 --- a/@commitlint/rules/src/body-empty.ts +++ b/@commitlint/rules/src/body-empty.ts @@ -1,8 +1,8 @@ import * as ensure from '@commitlint/ensure'; import message from '@commitlint/message'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const bodyEmpty: Rule = (parsed, when = 'always') => { +export const bodyEmpty: SyncRule = (parsed, when = 'always') => { const negated = when === 'never'; const notEmpty = ensure.notEmpty(parsed.body || ''); diff --git a/@commitlint/rules/src/body-leading-blank.ts b/@commitlint/rules/src/body-leading-blank.ts index 0b6bdf1d4b..84d6b743c9 100644 --- a/@commitlint/rules/src/body-leading-blank.ts +++ b/@commitlint/rules/src/body-leading-blank.ts @@ -1,8 +1,8 @@ import toLines from '@commitlint/to-lines'; import message from '@commitlint/message'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const bodyLeadingBlank: Rule = (parsed, when) => { +export const bodyLeadingBlank: SyncRule = (parsed, when) => { // Flunk if no body is found if (!parsed.body) { return [true]; diff --git a/@commitlint/rules/src/body-max-length.ts b/@commitlint/rules/src/body-max-length.ts index bc0cc81df3..fa100143cb 100644 --- a/@commitlint/rules/src/body-max-length.ts +++ b/@commitlint/rules/src/body-max-length.ts @@ -1,7 +1,7 @@ import {maxLength} from '@commitlint/ensure'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const bodyMaxLength: Rule = ( +export const bodyMaxLength: SyncRule = ( parsed, _when = undefined, value = 0 diff --git a/@commitlint/rules/src/body-max-line-length.ts b/@commitlint/rules/src/body-max-line-length.ts index 2746993a97..2946e41ec1 100644 --- a/@commitlint/rules/src/body-max-line-length.ts +++ b/@commitlint/rules/src/body-max-line-length.ts @@ -1,7 +1,7 @@ import {maxLineLength} from '@commitlint/ensure'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const bodyMaxLineLength: Rule = ( +export const bodyMaxLineLength: SyncRule = ( parsed, _when = undefined, value = 0 diff --git a/@commitlint/rules/src/body-min-length.ts b/@commitlint/rules/src/body-min-length.ts index 3b50e6c4dc..86d0a72e20 100644 --- a/@commitlint/rules/src/body-min-length.ts +++ b/@commitlint/rules/src/body-min-length.ts @@ -1,7 +1,7 @@ import {minLength} from '@commitlint/ensure'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const bodyMinLength: Rule = ( +export const bodyMinLength: SyncRule = ( parsed, _when = undefined, value = 0 diff --git a/@commitlint/rules/src/footer-empty.ts b/@commitlint/rules/src/footer-empty.ts index 810001e8a5..7be3aaaffe 100644 --- a/@commitlint/rules/src/footer-empty.ts +++ b/@commitlint/rules/src/footer-empty.ts @@ -1,8 +1,8 @@ import * as ensure from '@commitlint/ensure'; import message from '@commitlint/message'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const footerEmpty: Rule = (parsed, when = 'always') => { +export const footerEmpty: SyncRule = (parsed, when = 'always') => { const negated = when === 'never'; const notEmpty = ensure.notEmpty(parsed.footer || ''); diff --git a/@commitlint/rules/src/footer-leading-blank.ts b/@commitlint/rules/src/footer-leading-blank.ts index 094ba93c30..1177b7017a 100644 --- a/@commitlint/rules/src/footer-leading-blank.ts +++ b/@commitlint/rules/src/footer-leading-blank.ts @@ -1,8 +1,8 @@ import toLines from '@commitlint/to-lines'; import message from '@commitlint/message'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const footerLeadingBlank: Rule = (parsed, when = 'always') => { +export const footerLeadingBlank: SyncRule = (parsed, when = 'always') => { // Flunk if no footer is found if (!parsed.footer) { return [true]; diff --git a/@commitlint/rules/src/footer-max-length.ts b/@commitlint/rules/src/footer-max-length.ts index 7c2d771be6..fb07c843e6 100644 --- a/@commitlint/rules/src/footer-max-length.ts +++ b/@commitlint/rules/src/footer-max-length.ts @@ -1,7 +1,7 @@ import {maxLength} from '@commitlint/ensure'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const footerMaxLength: Rule = ( +export const footerMaxLength: SyncRule = ( parsed, _when = undefined, value = 0 diff --git a/@commitlint/rules/src/footer-max-line-length.ts b/@commitlint/rules/src/footer-max-line-length.ts index 9bc1ffe281..532289a2b9 100644 --- a/@commitlint/rules/src/footer-max-line-length.ts +++ b/@commitlint/rules/src/footer-max-line-length.ts @@ -1,7 +1,7 @@ import {maxLineLength} from '@commitlint/ensure'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const footerMaxLineLength: Rule = ( +export const footerMaxLineLength: SyncRule = ( parsed, _when = undefined, value = 0 diff --git a/@commitlint/rules/src/footer-min-length.ts b/@commitlint/rules/src/footer-min-length.ts index cd8571d5c5..ae33033a42 100644 --- a/@commitlint/rules/src/footer-min-length.ts +++ b/@commitlint/rules/src/footer-min-length.ts @@ -1,7 +1,7 @@ import {minLength} from '@commitlint/ensure'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const footerMinLength: Rule = ( +export const footerMinLength: SyncRule = ( parsed, _when = undefined, value = 0 diff --git a/@commitlint/rules/src/header-case.ts b/@commitlint/rules/src/header-case.ts index dedb264df3..4640c227c4 100644 --- a/@commitlint/rules/src/header-case.ts +++ b/@commitlint/rules/src/header-case.ts @@ -1,10 +1,10 @@ import {case as ensureCase} from '@commitlint/ensure'; import message from '@commitlint/message'; -import {TargetCaseType, Rule} from '@commitlint/types'; +import {TargetCaseType, SyncRule} from '@commitlint/types'; const negated = (when?: string) => when === 'never'; -export const headerCase: Rule = ( +export const headerCase: SyncRule = ( parsed, when = 'always', value = [] diff --git a/@commitlint/rules/src/header-full-stop.ts b/@commitlint/rules/src/header-full-stop.ts index c22c1a791d..62a8a03a56 100644 --- a/@commitlint/rules/src/header-full-stop.ts +++ b/@commitlint/rules/src/header-full-stop.ts @@ -1,7 +1,7 @@ import message from '@commitlint/message'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const headerFullStop: Rule = ( +export const headerFullStop: SyncRule = ( parsed, when = 'always', value = '.' diff --git a/@commitlint/rules/src/header-max-length.ts b/@commitlint/rules/src/header-max-length.ts index 4eab3dc50e..07c5f69e79 100644 --- a/@commitlint/rules/src/header-max-length.ts +++ b/@commitlint/rules/src/header-max-length.ts @@ -1,7 +1,7 @@ import {maxLength} from '@commitlint/ensure'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const headerMaxLength: Rule = ( +export const headerMaxLength: SyncRule = ( parsed, _when = undefined, value = 0 diff --git a/@commitlint/rules/src/header-min-length.ts b/@commitlint/rules/src/header-min-length.ts index 10cf63aa2e..9dbea907e8 100644 --- a/@commitlint/rules/src/header-min-length.ts +++ b/@commitlint/rules/src/header-min-length.ts @@ -1,7 +1,7 @@ import {minLength} from '@commitlint/ensure'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const headerMinLength: Rule = ( +export const headerMinLength: SyncRule = ( parsed, _when = undefined, value = 0 diff --git a/@commitlint/rules/src/references-empty.ts b/@commitlint/rules/src/references-empty.ts index 7582c4e555..7c62e4a887 100644 --- a/@commitlint/rules/src/references-empty.ts +++ b/@commitlint/rules/src/references-empty.ts @@ -1,7 +1,7 @@ import message from '@commitlint/message'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const referencesEmpty: Rule = (parsed, when = 'never') => { +export const referencesEmpty: SyncRule = (parsed, when = 'never') => { const negated = when === 'always'; const notEmpty = parsed.references.length > 0; return [ diff --git a/@commitlint/rules/src/scope-case.ts b/@commitlint/rules/src/scope-case.ts index 0d6781e2f5..3c197d002b 100644 --- a/@commitlint/rules/src/scope-case.ts +++ b/@commitlint/rules/src/scope-case.ts @@ -1,10 +1,10 @@ import {case as ensureCase} from '@commitlint/ensure'; import message from '@commitlint/message'; -import {TargetCaseType, Rule} from '@commitlint/types'; +import {TargetCaseType, SyncRule} from '@commitlint/types'; const negated = (when?: string) => when === 'never'; -export const scopeCase: Rule = ( +export const scopeCase: SyncRule = ( parsed, when = 'always', value = [] diff --git a/@commitlint/rules/src/scope-empty.ts b/@commitlint/rules/src/scope-empty.ts index 9d600372de..9d01ade7cb 100644 --- a/@commitlint/rules/src/scope-empty.ts +++ b/@commitlint/rules/src/scope-empty.ts @@ -1,8 +1,8 @@ import * as ensure from '@commitlint/ensure'; import message from '@commitlint/message'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const scopeEmpty: Rule = (parsed, when = 'never') => { +export const scopeEmpty: SyncRule = (parsed, when = 'never') => { const negated = when === 'always'; const notEmpty = ensure.notEmpty(parsed.scope || ''); return [ diff --git a/@commitlint/rules/src/scope-enum.ts b/@commitlint/rules/src/scope-enum.ts index 2aa8e149f1..7185385f59 100644 --- a/@commitlint/rules/src/scope-enum.ts +++ b/@commitlint/rules/src/scope-enum.ts @@ -1,8 +1,8 @@ import * as ensure from '@commitlint/ensure'; import message from '@commitlint/message'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const scopeEnum: Rule = ( +export const scopeEnum: SyncRule = ( parsed, when = 'always', value = [] diff --git a/@commitlint/rules/src/scope-max-length.ts b/@commitlint/rules/src/scope-max-length.ts index 8cdaea7256..b802896cd2 100644 --- a/@commitlint/rules/src/scope-max-length.ts +++ b/@commitlint/rules/src/scope-max-length.ts @@ -1,7 +1,7 @@ import {maxLength} from '@commitlint/ensure'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const scopeMaxLength: Rule = ( +export const scopeMaxLength: SyncRule = ( parsed, _when = undefined, value = 0 diff --git a/@commitlint/rules/src/scope-min-length.ts b/@commitlint/rules/src/scope-min-length.ts index 5492579c8c..bdeafb8eba 100644 --- a/@commitlint/rules/src/scope-min-length.ts +++ b/@commitlint/rules/src/scope-min-length.ts @@ -1,7 +1,7 @@ import {minLength} from '@commitlint/ensure'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const scopeMinLength: Rule = ( +export const scopeMinLength: SyncRule = ( parsed, _when = undefined, value = 0 diff --git a/@commitlint/rules/src/signed-off-by.ts b/@commitlint/rules/src/signed-off-by.ts index 82762fa7cd..ea98db8a42 100644 --- a/@commitlint/rules/src/signed-off-by.ts +++ b/@commitlint/rules/src/signed-off-by.ts @@ -1,8 +1,8 @@ import message from '@commitlint/message'; import toLines from '@commitlint/to-lines'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const signedOffBy: Rule = ( +export const signedOffBy: SyncRule = ( parsed, when = 'always', value = '' diff --git a/@commitlint/rules/src/subject-case.ts b/@commitlint/rules/src/subject-case.ts index fb8a8ab024..282c416d06 100644 --- a/@commitlint/rules/src/subject-case.ts +++ b/@commitlint/rules/src/subject-case.ts @@ -1,10 +1,10 @@ import {case as ensureCase} from '@commitlint/ensure'; import message from '@commitlint/message'; -import {TargetCaseType, Rule} from '@commitlint/types'; +import {TargetCaseType, SyncRule} from '@commitlint/types'; const negated = (when?: string) => when === 'never'; -export const subjectCase: Rule = ( +export const subjectCase: SyncRule = ( parsed, when = 'always', value = [] diff --git a/@commitlint/rules/src/subject-empty.ts b/@commitlint/rules/src/subject-empty.ts index 20e6f4863f..80f9f4ba11 100644 --- a/@commitlint/rules/src/subject-empty.ts +++ b/@commitlint/rules/src/subject-empty.ts @@ -1,8 +1,8 @@ import * as ensure from '@commitlint/ensure'; import message from '@commitlint/message'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const subjectEmpty: Rule = (parsed, when = 'always') => { +export const subjectEmpty: SyncRule = (parsed, when = 'always') => { const negated = when === 'never'; const notEmpty = ensure.notEmpty(parsed.subject || ''); diff --git a/@commitlint/rules/src/subject-full-stop.ts b/@commitlint/rules/src/subject-full-stop.ts index 7faa4910bc..121293ebdb 100644 --- a/@commitlint/rules/src/subject-full-stop.ts +++ b/@commitlint/rules/src/subject-full-stop.ts @@ -1,7 +1,7 @@ import message from '@commitlint/message'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const subjectFullStop: Rule = ( +export const subjectFullStop: SyncRule = ( parsed, when = 'always', value = '.' diff --git a/@commitlint/rules/src/subject-max-length.ts b/@commitlint/rules/src/subject-max-length.ts index db65f1a468..6adc22f6c5 100644 --- a/@commitlint/rules/src/subject-max-length.ts +++ b/@commitlint/rules/src/subject-max-length.ts @@ -1,7 +1,7 @@ import {maxLength} from '@commitlint/ensure'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const subjectMaxLength: Rule = ( +export const subjectMaxLength: SyncRule = ( parsed, _when = undefined, value = 0 diff --git a/@commitlint/rules/src/subject-min-length.ts b/@commitlint/rules/src/subject-min-length.ts index 43fee9701a..171eaa2ca8 100644 --- a/@commitlint/rules/src/subject-min-length.ts +++ b/@commitlint/rules/src/subject-min-length.ts @@ -1,7 +1,7 @@ import {minLength} from '@commitlint/ensure'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const subjectMinLength: Rule = ( +export const subjectMinLength: SyncRule = ( parsed, _when = undefined, value = 0 diff --git a/@commitlint/rules/src/type-case.ts b/@commitlint/rules/src/type-case.ts index 1a5bceef9c..0769c6c18d 100644 --- a/@commitlint/rules/src/type-case.ts +++ b/@commitlint/rules/src/type-case.ts @@ -1,10 +1,10 @@ import {case as ensureCase} from '@commitlint/ensure'; import message from '@commitlint/message'; -import {TargetCaseType, Rule} from '@commitlint/types'; +import {TargetCaseType, SyncRule} from '@commitlint/types'; const negated = (when?: string) => when === 'never'; -export const typeCase: Rule = ( +export const typeCase: SyncRule = ( parsed, when = 'always', value = [] diff --git a/@commitlint/rules/src/type-empty.ts b/@commitlint/rules/src/type-empty.ts index 9d58864299..14d77f56f7 100644 --- a/@commitlint/rules/src/type-empty.ts +++ b/@commitlint/rules/src/type-empty.ts @@ -1,8 +1,8 @@ import * as ensure from '@commitlint/ensure'; import message from '@commitlint/message'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const typeEmpty: Rule = (parsed, when = 'always') => { +export const typeEmpty: SyncRule = (parsed, when = 'always') => { const negated = when === 'never'; const notEmpty = ensure.notEmpty(parsed.type || ''); return [ diff --git a/@commitlint/rules/src/type-enum.ts b/@commitlint/rules/src/type-enum.ts index 1aba3b61fa..58f4735edd 100644 --- a/@commitlint/rules/src/type-enum.ts +++ b/@commitlint/rules/src/type-enum.ts @@ -1,8 +1,8 @@ import * as ensure from '@commitlint/ensure'; import message from '@commitlint/message'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const typeEnum: Rule = ( +export const typeEnum: SyncRule = ( parsed, when = 'always', value = [] diff --git a/@commitlint/rules/src/type-max-length.ts b/@commitlint/rules/src/type-max-length.ts index 29569ed79f..5e54c80dc7 100644 --- a/@commitlint/rules/src/type-max-length.ts +++ b/@commitlint/rules/src/type-max-length.ts @@ -1,7 +1,7 @@ import {maxLength} from '@commitlint/ensure'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const typeMaxLength: Rule = ( +export const typeMaxLength: SyncRule = ( parsed, _when = undefined, value = 0 diff --git a/@commitlint/rules/src/type-min-length.ts b/@commitlint/rules/src/type-min-length.ts index 08ea3150d9..5d70c11bb6 100644 --- a/@commitlint/rules/src/type-min-length.ts +++ b/@commitlint/rules/src/type-min-length.ts @@ -1,7 +1,7 @@ import {minLength} from '@commitlint/ensure'; -import {Rule} from '@commitlint/types'; +import {SyncRule} from '@commitlint/types'; -export const typeMinLength: Rule = ( +export const typeMinLength: SyncRule = ( parsed, _when = undefined, value = 0 diff --git a/@commitlint/types/src/rules.ts b/@commitlint/types/src/rules.ts index b064cb4d32..3d99db4059 100644 --- a/@commitlint/types/src/rules.ts +++ b/@commitlint/types/src/rules.ts @@ -12,14 +12,26 @@ export type RuleCondition = 'always' | 'never'; * 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?]; +export type RuleOutcome = Readonly<[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 = ( +export type RuleType = 'async' | 'sync' | 'either'; + +export type BaseRule = ( parsed: Commit, when?: RuleCondition, value?: Value -) => RuleOutcome; +) => Type extends 'either' + ? RuleOutcome | Promise + : Type extends 'async' + ? Promise + : Type extends 'sync' + ? RuleOutcome + : never; + +export type Rule = BaseRule; +export type AsyncRule = BaseRule; +export type SyncRule = BaseRule;