-
-
Notifications
You must be signed in to change notification settings - Fork 207
/
create-eslint-rule.ts
79 lines (74 loc) · 2.51 KB
/
create-eslint-rule.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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import type {
ParseSourceSpan,
TmplAstElement,
} from '@angular-eslint/bundled-angular-compiler';
import type {
ESLintUtils,
TSESLint,
TSESTree,
} from '@typescript-eslint/experimental-utils';
import { applyDefault } from '@typescript-eslint/experimental-utils/dist/eslint-utils';
/**
* We need to patch the RuleCreator in order to preserve the defaultOptions
* to use as part of documentation generation.
*/
const patchedRuleCreator: typeof ESLintUtils.RuleCreator = (urlCreator) => {
return function createRule({ name, meta, defaultOptions, create }) {
return {
meta: Object.assign(Object.assign({}, meta), {
docs: Object.assign(Object.assign({}, meta.docs), {
url: urlCreator(name),
}),
}),
defaultOptions,
create(context) {
const optionsWithDefault = applyDefault(
defaultOptions,
context.options,
);
return create(context, optionsWithDefault);
},
};
};
};
export const createESLintRule = patchedRuleCreator(
(ruleName) =>
`https://github.com/angular-eslint/angular-eslint/blob/master/packages/eslint-plugin/docs/rules/${ruleName}.md`,
);
interface ParserServices {
convertNodeSourceSpanToLoc: (
sourceSpan: ParseSourceSpan,
) => TSESTree.SourceLocation;
convertElementSourceSpanToLoc: (
context: Readonly<TSESLint.RuleContext<string, readonly unknown[]>>,
node: TmplAstElement,
) => TSESTree.SourceLocation;
}
export function getTemplateParserServices(
context: Readonly<TSESLint.RuleContext<string, readonly unknown[]>>,
): ParserServices {
ensureTemplateParser(context);
return context.parserServices as unknown as ParserServices;
}
/**
* Utility for rule authors to ensure that their rule is correctly being used with @angular-eslint/template-parser
* If @angular-eslint/template-parser is not the configured parser when the function is invoked it will throw
*/
export function ensureTemplateParser(
context: Readonly<TSESLint.RuleContext<string, readonly unknown[]>>,
): void {
if (
!(context.parserServices as unknown as ParserServices)
?.convertNodeSourceSpanToLoc ||
!(context.parserServices as unknown as ParserServices)
?.convertElementSourceSpanToLoc
) {
/**
* The user needs to have configured "parser" in their eslint config and set it
* to @angular-eslint/template-parser
*/
throw new Error(
"You have used a rule which requires '@angular-eslint/template-parser' to be used as the 'parser' in your ESLint config.",
);
}
}