eslint-plugin-crisp 1.7.13 → 1.7.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/index.js +2 -0
- package/package.json +1 -1
- package/recommended-vue.js +1 -0
- package/rules/vue-event-listener-section.js +87 -0
- package/tests/rules/vue-event-listener-section.test.js +145 -0
package/README.md
CHANGED
|
@@ -228,6 +228,7 @@ Each item has emojis denoting:
|
|
|
228
228
|
| [crisp/vue-define-component](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/vue-define-component.js) | Enforces mixins and components to use the `defineComponent` wrapper | | 🟢 |
|
|
229
229
|
| [crisp/vue-emits-order](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/vue-emits-order.js) | Ensures emits properties are alphabetically ordered | | 🟢 |
|
|
230
230
|
| [crisp/vue-event-listener-jsdoc](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/vue-event-listener-jsdoc.js) | Requires event listener method JSDoc descriptions to start with `Triggers on` | | 🟢 |
|
|
231
|
+
| [crisp/vue-event-listener-section](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/vue-event-listener-section.js) | Requires methods named `on` followed by an uppercase letter to be in the event listeners section | | 🟢 |
|
|
231
232
|
| [crisp/vue-header-check](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/vue-header-check.js) | Ensures `script`, `template` and `style` tags start with corresponding comment block | | 🟢 |
|
|
232
233
|
| [crisp/vue-html-indent](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/vue-html-indent.js) | Enforces consistent indentation in `template` (supports for Pug) | | 🟢 |
|
|
233
234
|
| [crisp/vue-html-quotes](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/vue-html-quotes.js) | Enforces HTML attributes to be enclosed with double quotes | | 🟢 |
|
package/index.js
CHANGED
|
@@ -51,6 +51,7 @@ import ruleVueDataComment from "./rules/vue-data-comment.js";
|
|
|
51
51
|
import ruleVueDefineComponent from "./rules/vue-define-component.js";
|
|
52
52
|
import ruleVueEmitsOrder from "./rules/vue-emits-order.js";
|
|
53
53
|
import ruleVueEventListenerJsdoc from "./rules/vue-event-listener-jsdoc.js";
|
|
54
|
+
import ruleVueEventListenerSection from "./rules/vue-event-listener-section.js";
|
|
54
55
|
import ruleVueHeaderCheck from "./rules/vue-header-check.js";
|
|
55
56
|
import ruleVueHtmlIndent from "./rules/vue-html-indent.js";
|
|
56
57
|
import ruleVueHtmlQuotes from "./rules/vue-html-quotes.js";
|
|
@@ -131,6 +132,7 @@ const plugin = {
|
|
|
131
132
|
"vue-define-component": ruleVueDefineComponent,
|
|
132
133
|
"vue-emits-order": ruleVueEmitsOrder,
|
|
133
134
|
"vue-event-listener-jsdoc": ruleVueEventListenerJsdoc,
|
|
135
|
+
"vue-event-listener-section": ruleVueEventListenerSection,
|
|
134
136
|
"vue-header-check": ruleVueHeaderCheck,
|
|
135
137
|
"vue-html-indent": ruleVueHtmlIndent,
|
|
136
138
|
"vue-html-quotes": ruleVueHtmlQuotes,
|
package/package.json
CHANGED
package/recommended-vue.js
CHANGED
|
@@ -386,6 +386,7 @@ export default function configRecommendedVue(pluginCrisp) {
|
|
|
386
386
|
"crisp/vue-define-component": "error",
|
|
387
387
|
"crisp/vue-emits-order": "error",
|
|
388
388
|
"crisp/vue-event-listener-jsdoc": "error",
|
|
389
|
+
"crisp/vue-event-listener-section": "error",
|
|
389
390
|
"crisp/vue-header-check": "error",
|
|
390
391
|
"crisp/vue-html-indent": "error",
|
|
391
392
|
"crisp/vue-html-quotes": "error",
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const EVENT_LISTENERS_SEPARATOR = "--> EVENT LISTENERS <--";
|
|
2
|
+
const EVENT_LISTENER_NAME_PATTERN = /^on[A-Z]/;
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
meta: {
|
|
6
|
+
type: "suggestion",
|
|
7
|
+
docs: {
|
|
8
|
+
description:
|
|
9
|
+
"require on-prefixed Vue methods to be in the event listeners section",
|
|
10
|
+
category: "Stylistic Issues",
|
|
11
|
+
recommended: false
|
|
12
|
+
},
|
|
13
|
+
fixable: null,
|
|
14
|
+
schema: [],
|
|
15
|
+
messages: {
|
|
16
|
+
wrongSection:
|
|
17
|
+
"Method '{{name}}' must be declared in the EVENT LISTENERS section."
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
create(context) {
|
|
22
|
+
const sourceCode = context.sourceCode;
|
|
23
|
+
|
|
24
|
+
function getPropertyName(property) {
|
|
25
|
+
if (property.type !== "Property" || property.computed) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (property.key.type === "Identifier") {
|
|
30
|
+
return property.key.name;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (
|
|
34
|
+
property.key.type === "Literal" &&
|
|
35
|
+
typeof property.key.value === "string"
|
|
36
|
+
) {
|
|
37
|
+
return property.key.value;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function checkMethods(node) {
|
|
44
|
+
const properties = node.value.properties;
|
|
45
|
+
|
|
46
|
+
if (!properties) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let eventListenersStarted = false;
|
|
51
|
+
|
|
52
|
+
properties.forEach((property) => {
|
|
53
|
+
const comments = sourceCode.getCommentsBefore(property);
|
|
54
|
+
|
|
55
|
+
if (!eventListenersStarted) {
|
|
56
|
+
eventListenersStarted = comments.some((comment) => {
|
|
57
|
+
return (
|
|
58
|
+
comment.type === "Line" &&
|
|
59
|
+
comment.value.trim() === EVENT_LISTENERS_SEPARATOR
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (eventListenersStarted) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const name = getPropertyName(property);
|
|
69
|
+
|
|
70
|
+
if (name && EVENT_LISTENER_NAME_PATTERN.test(name)) {
|
|
71
|
+
context.report({
|
|
72
|
+
node: property.key,
|
|
73
|
+
messageId: "wrongSection",
|
|
74
|
+
data: { name }
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
'ExportDefaultDeclaration > ObjectExpression > Property[key.name="methods"]':
|
|
82
|
+
checkMethods,
|
|
83
|
+
'ExportDefaultDeclaration > CallExpression[callee.name="defineComponent"] > ObjectExpression > Property[key.name="methods"]':
|
|
84
|
+
checkMethods
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import rule from "../../rules/vue-event-listener-section.js";
|
|
2
|
+
import { createVueRuleTester } from "../rule-tester.js";
|
|
3
|
+
|
|
4
|
+
const ruleTester = createVueRuleTester();
|
|
5
|
+
|
|
6
|
+
ruleTester.run("vue-event-listener-section", rule, {
|
|
7
|
+
valid: [
|
|
8
|
+
{
|
|
9
|
+
code: "export default { methods: {} };"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
code: `
|
|
13
|
+
export default {
|
|
14
|
+
methods: {
|
|
15
|
+
// --> ACTIONS <--
|
|
16
|
+
save() {},
|
|
17
|
+
// --> HELPERS <--
|
|
18
|
+
onlyOnce() {},
|
|
19
|
+
onload() {},
|
|
20
|
+
on_save() {},
|
|
21
|
+
on2Factor() {}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
`
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
code: `
|
|
28
|
+
export default defineComponent({
|
|
29
|
+
methods: {
|
|
30
|
+
// --> EVENT LISTENERS <--
|
|
31
|
+
onSave() {},
|
|
32
|
+
onURLChange() {},
|
|
33
|
+
"onClose"() {}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
`
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
code: `
|
|
40
|
+
export default {
|
|
41
|
+
methods: {
|
|
42
|
+
// --> HELPERS <--
|
|
43
|
+
createHandlers() {
|
|
44
|
+
return {
|
|
45
|
+
onSave() {}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
`
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
filename: "Component.vue",
|
|
54
|
+
code: `
|
|
55
|
+
<script>
|
|
56
|
+
export default defineComponent({
|
|
57
|
+
methods: {
|
|
58
|
+
// --> ACTIONS <--
|
|
59
|
+
save() {},
|
|
60
|
+
// --> EVENT LISTENERS <--
|
|
61
|
+
onLoadMore() {}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
</script>
|
|
65
|
+
`
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
|
|
69
|
+
invalid: [
|
|
70
|
+
{
|
|
71
|
+
code: `
|
|
72
|
+
export default {
|
|
73
|
+
methods: {
|
|
74
|
+
// --> ACTIONS <--
|
|
75
|
+
onSave() {}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
`,
|
|
79
|
+
errors: [
|
|
80
|
+
{
|
|
81
|
+
messageId: "wrongSection",
|
|
82
|
+
data: { name: "onSave" }
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
code: `
|
|
88
|
+
export default {
|
|
89
|
+
methods: {
|
|
90
|
+
// --> HELPERS <--
|
|
91
|
+
onLoadMore() {}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
`,
|
|
95
|
+
errors: [
|
|
96
|
+
{
|
|
97
|
+
messageId: "wrongSection",
|
|
98
|
+
data: { name: "onLoadMore" }
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
code: `
|
|
104
|
+
export default {
|
|
105
|
+
methods: {
|
|
106
|
+
"onClose": function() {}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
`,
|
|
110
|
+
errors: [
|
|
111
|
+
{
|
|
112
|
+
messageId: "wrongSection",
|
|
113
|
+
data: { name: "onClose" }
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
filename: "Component.vue",
|
|
119
|
+
code: `
|
|
120
|
+
<script>
|
|
121
|
+
export default defineComponent({
|
|
122
|
+
methods: {
|
|
123
|
+
// --> ACTIONS <--
|
|
124
|
+
onSave() {},
|
|
125
|
+
// --> HELPERS <--
|
|
126
|
+
onFormatComplete() {},
|
|
127
|
+
// --> EVENT LISTENERS <--
|
|
128
|
+
onClose() {}
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
</script>
|
|
132
|
+
`,
|
|
133
|
+
errors: [
|
|
134
|
+
{
|
|
135
|
+
messageId: "wrongSection",
|
|
136
|
+
data: { name: "onSave" }
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
messageId: "wrongSection",
|
|
140
|
+
data: { name: "onFormatComplete" }
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
});
|