eslint-plugin-crisp 1.0.14 → 1.0.16
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/index.js +1 -0
- package/package.json +4 -3
- package/recommended-vue.js +24 -8
- package/rules/vue-html-quotes.js +76 -0
package/index.js
CHANGED
|
@@ -28,6 +28,7 @@ module.exports = {
|
|
|
28
28
|
"two-lines-between-class-members": require("./rules/two-lines-between-class-members"),
|
|
29
29
|
"variable-names": require("./rules/variable-names"),
|
|
30
30
|
"align-consecutive-class-assignements": require("./rules/align-consecutive-class-assignements"),
|
|
31
|
+
"vue-html-quotes": require("./rules/vue-html-quotes"),
|
|
31
32
|
"vue-props-declaration-order": require("./rules/vue-props-declaration-order")
|
|
32
33
|
}
|
|
33
34
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-crisp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.16",
|
|
4
4
|
"description": "Custom EsLint Rules for Crisp",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "Crisp IM SAS",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
},
|
|
12
12
|
"peerDependencies": {
|
|
13
13
|
"eslint": "8.45.0",
|
|
14
|
-
"eslint-plugin-vue": "8.
|
|
15
|
-
"eslint-plugin-vue-pug": "0.6.0"
|
|
14
|
+
"eslint-plugin-vue": "8.7.1",
|
|
15
|
+
"eslint-plugin-vue-pug": "0.6.0",
|
|
16
|
+
"vue-eslint-parser": "9.3.1"
|
|
16
17
|
}
|
|
17
18
|
}
|
package/recommended-vue.js
CHANGED
|
@@ -11,7 +11,8 @@ module.exports = {
|
|
|
11
11
|
extends: [
|
|
12
12
|
"eslint:recommended",
|
|
13
13
|
"plugin:jsdoc/recommended",
|
|
14
|
-
"plugin:vue/vue3-recommended"
|
|
14
|
+
"plugin:vue/vue3-recommended",
|
|
15
|
+
"plugin:vue-pug/vue3-recommended"
|
|
15
16
|
],
|
|
16
17
|
|
|
17
18
|
rules: {
|
|
@@ -105,29 +106,43 @@ module.exports = {
|
|
|
105
106
|
"crisp/jsdocs-align-params": "error",
|
|
106
107
|
|
|
107
108
|
// General Vue rules
|
|
108
|
-
"vue/multi-word-component-names": "error",
|
|
109
109
|
"vue/no-v-html": "off",
|
|
110
|
+
"vue/html-quotes": "off",
|
|
111
|
+
"vue/component-tags-order": [
|
|
112
|
+
"error",
|
|
113
|
+
|
|
114
|
+
{
|
|
115
|
+
"order": [ "template", "script", "style" ]
|
|
116
|
+
}
|
|
117
|
+
],
|
|
110
118
|
"vue/attributes-order": [
|
|
111
119
|
"error",
|
|
120
|
+
|
|
112
121
|
{
|
|
113
122
|
order: [
|
|
114
|
-
"
|
|
123
|
+
"RENDER_MODIFIERS",
|
|
115
124
|
"CONDITIONALS",
|
|
125
|
+
"OTHER_DIRECTIVES",
|
|
116
126
|
"LIST_RENDERING",
|
|
117
|
-
"RENDER_MODIFIERS",
|
|
118
127
|
"SLOT",
|
|
119
128
|
"TWO_WAY_BINDING",
|
|
120
129
|
"CONTENT",
|
|
121
130
|
"EVENTS",
|
|
122
|
-
"GLOBAL",
|
|
123
131
|
"DEFINITION",
|
|
124
|
-
"UNIQUE",
|
|
125
|
-
"OTHER_ATTR"
|
|
126
|
-
["ATTR_DYNAMIC", "ATTR_STATIC", "ATTR_SHORTHAND_BOOL"]
|
|
132
|
+
["GLOBAL", "UNIQUE", "OTHER_ATTR"]
|
|
127
133
|
],
|
|
128
134
|
"alphabetical": false
|
|
129
135
|
}
|
|
130
136
|
],
|
|
137
|
+
"vue/v-slot-style": [
|
|
138
|
+
"error",
|
|
139
|
+
|
|
140
|
+
{
|
|
141
|
+
"atComponent": "v-slot",
|
|
142
|
+
"default": "v-slot",
|
|
143
|
+
"named": "longform"
|
|
144
|
+
}
|
|
145
|
+
],
|
|
131
146
|
|
|
132
147
|
// Crisp JS rules
|
|
133
148
|
"crisp/header-check": "error",
|
|
@@ -149,6 +164,7 @@ module.exports = {
|
|
|
149
164
|
],
|
|
150
165
|
|
|
151
166
|
// Crisp Vue rules
|
|
167
|
+
"crisp/vue-html-quotes": "error",
|
|
152
168
|
"crisp/vue-props-declaration-order": "error"
|
|
153
169
|
},
|
|
154
170
|
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
meta: {
|
|
3
|
+
type: "layout",
|
|
4
|
+
docs: {
|
|
5
|
+
description: "enforce quotes style of HTML attributes"
|
|
6
|
+
},
|
|
7
|
+
|
|
8
|
+
schema: [
|
|
9
|
+
{ enum: ["double", "single"] },
|
|
10
|
+
{
|
|
11
|
+
type: "object",
|
|
12
|
+
properties: {
|
|
13
|
+
avoidEscape: {
|
|
14
|
+
type: "boolean"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
additionalProperties: false
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
|
|
21
|
+
messages: {
|
|
22
|
+
expected: "Expected to be enclosed by {{kind}}."
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
create(context) {
|
|
27
|
+
const sourceCode = context.getSourceCode()
|
|
28
|
+
const double = context.options[0] !== "single"
|
|
29
|
+
const avoidEscape =
|
|
30
|
+
context.options[1] && context.options[1].avoidEscape === true
|
|
31
|
+
const quoteChar = double ? '"' : "'"
|
|
32
|
+
const quoteName = double ? "double quotes" : "single quotes"
|
|
33
|
+
|
|
34
|
+
return context.parserServices.defineTemplateBodyVisitor(
|
|
35
|
+
{
|
|
36
|
+
"VAttribute[value!=null]"(node) {
|
|
37
|
+
const text = sourceCode.getText(node.value)
|
|
38
|
+
const firstChar = text[0]
|
|
39
|
+
|
|
40
|
+
if (firstChar !== quoteChar) {
|
|
41
|
+
const contentText = text.slice(1, -1);
|
|
42
|
+
|
|
43
|
+
const quoted = firstChar === "'" || firstChar === '"';
|
|
44
|
+
|
|
45
|
+
if (avoidEscape && quoted) {
|
|
46
|
+
if (contentText.includes(quoteChar)) {
|
|
47
|
+
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Attribute value is an object or an array
|
|
53
|
+
if (firstChar === "[" || firstChar === "{") {
|
|
54
|
+
// Matching quote in the object
|
|
55
|
+
if (contentText.includes(quoteChar)) {
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// No quotes in the object or array
|
|
60
|
+
if (!contentText.includes("'") && !contentText.includes('"')) {
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
context.report({
|
|
66
|
+
node: node.value,
|
|
67
|
+
loc: node.value.loc,
|
|
68
|
+
messageId: "expected",
|
|
69
|
+
data: { kind: quoteName }
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
}
|