/
banana-in-box.ts
55 lines (49 loc) · 1.63 KB
/
banana-in-box.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
import type { TmplAstBoundEvent } from '@angular-eslint/bundled-angular-compiler';
import { getTemplateParserServices } from '@angular-eslint/utils';
import { createESLintRule } from '../utils/create-eslint-rule';
type Options = [];
export type MessageIds = 'bananaInBox';
export const RULE_NAME = 'banana-in-box';
const INVALID_PATTERN = /\[(.*)\]/;
const VALID_CLOSE_BOX = ')]';
const VALID_OPEN_BOX = '[(';
export default createESLintRule<Options, MessageIds>({
name: RULE_NAME,
meta: {
type: 'suggestion',
docs: {
description: 'Ensures that the two-way data binding syntax is correct',
recommended: 'error',
},
fixable: 'code',
schema: [],
messages: {
bananaInBox: 'Invalid binding syntax. Use [(expr)] instead',
},
},
defaultOptions: [],
create(context) {
const parserServices = getTemplateParserServices(context);
const sourceCode = context.getSourceCode();
return {
BoundEvent({ name, sourceSpan }: TmplAstBoundEvent) {
const matches = name.match(INVALID_PATTERN);
if (!matches) return;
const loc = parserServices.convertNodeSourceSpanToLoc(sourceSpan);
context.report({
messageId: 'bananaInBox',
loc,
fix: (fixer) => {
const [, textInTheBox] = matches;
const textToReplace = `${VALID_OPEN_BOX}${textInTheBox}${VALID_CLOSE_BOX}`;
const startIndex = sourceCode.getIndexFromLoc(loc.start);
return fixer.replaceTextRange(
[startIndex, startIndex + name.length + 2],
textToReplace,
);
},
});
},
};
},
});