/
RuleCreator.ts
58 lines (55 loc) · 1.6 KB
/
RuleCreator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import {
RuleMetaData,
RuleMetaDataDocs,
RuleListener,
RuleContext,
RuleModule,
} from '../ts-eslint/Rule';
import { applyDefault } from './applyDefault';
// we automatically add the url
type CreateRuleMetaDocs = Omit<RuleMetaDataDocs, 'url'>;
type CreateRuleMeta<TMessageIds extends string> = {
docs: CreateRuleMetaDocs;
} & Omit<RuleMetaData<TMessageIds>, 'docs'>;
function RuleCreator(urlCreator: (ruleName: string) => string) {
// This function will get much easier to call when this is merged https://github.com/Microsoft/TypeScript/pull/26349
// TODO - when the above PR lands; add type checking for the context.report `data` property
return function createRule<
TOptions extends readonly unknown[],
TMessageIds extends string,
TRuleListener extends RuleListener = RuleListener
>({
name,
meta,
defaultOptions,
create,
}: Readonly<{
name: string;
meta: CreateRuleMeta<TMessageIds>;
defaultOptions: Readonly<TOptions>;
create: (
context: Readonly<RuleContext<TMessageIds, TOptions>>,
optionsWithDefault: Readonly<TOptions>,
) => TRuleListener;
}>): RuleModule<TMessageIds, TOptions, TRuleListener> {
return {
meta: {
...meta,
docs: {
...meta.docs,
url: urlCreator(name),
},
},
create(
context: Readonly<RuleContext<TMessageIds, TOptions>>,
): TRuleListener {
const optionsWithDefault = applyDefault(
defaultOptions,
context.options,
);
return create(context, optionsWithDefault);
},
};
};
}
export { RuleCreator };