Skip to content

Commit 8df0324

Browse files
committed
Split rule to no-dulpe-keys & no-reservered-keys
1 parent 0cd23c4 commit 8df0324

File tree

6 files changed

+283
-95
lines changed

6 files changed

+283
-95
lines changed

docs/rules/no-dupe-keys.md

+2-22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Prevent duplicate field names (no-dupe-keys)
22

3-
This rule prevents to use duplicated names and reserved/internal names from vue.
3+
This rule prevents to use duplicated names.
44

55
## :book: Rule Details
66

@@ -54,29 +54,9 @@ export default {
5454

5555
This rule has an object option:
5656

57-
`"reserved"`: [] (default) array of dissalowed names inside `scopes`.
58-
5957
`"scope"`: [] (default) array of additional scopes to search for duplicates.
6058

61-
### Example 1:
62-
63-
```
64-
vue/no-dupe-keys: [2, {
65-
reserved: ['foo']
66-
}]
67-
```
68-
69-
:-1: Examples of **incorrect** code for this configuration
70-
71-
```js
72-
export default {
73-
computed: {
74-
foo () {}
75-
}
76-
}
77-
```
78-
79-
### Example 2:
59+
### Example:
8060

8161
```
8262
vue/no-dupe-keys: [2, {

docs/rules/no-reservered-keys.md

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Prevent overwrite reserved keys (no-reservered-keys)
2+
3+
This rule prevents to use reserved names from to avoid conflicts and unexpected behavior.
4+
5+
## Rule Details
6+
7+
:-1: Examples of **incorrect** code for this rule:
8+
9+
```js
10+
export default {
11+
props: {
12+
$el: String
13+
},
14+
computed: {
15+
$on: {
16+
get () {
17+
}
18+
}
19+
},
20+
data: {
21+
_foo: null
22+
},
23+
methods: {
24+
$nextTick () {
25+
}
26+
}
27+
}
28+
```
29+
30+
## :wrench: Options
31+
32+
This rule has an object option:
33+
34+
`"reserved"`: [] (default) array of dissalowed names inside `scopes`.
35+
36+
`"scope"`: [] (default) array of additional scopes to search for duplicates.
37+
38+
### Example:
39+
40+
```
41+
vue/no-dupe-keys: [2, {
42+
reserved: ['foo']
43+
}]
44+
```
45+
46+
:-1: Examples of **incorrect** code for this configuration
47+
48+
```js
49+
export default {
50+
computed: {
51+
foo () {}
52+
}
53+
}
54+
```

lib/rules/no-dupe-keys.js

+2-27
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,14 @@
77
const utils = require('../utils')
88
const assert = require('assert')
99

10-
const RESERVER_NAMES = new Set(require('../utils/vue-reserved.json'))
1110
const SCOPE_NAMES = new Set(['props', 'computed', 'data', 'methods'])
1211

1312
function create (context) {
1413
const usedNames = []
15-
const reservedNames = RESERVER_NAMES
1614
const scopeNames = SCOPE_NAMES
1715

1816
const options = context.options[0] || {}
19-
if (options.reserved) {
20-
options.reserved.forEach(name => {
21-
reservedNames.add(name)
22-
})
23-
}
17+
2418
if (options.scope) {
2519
options.scope.forEach(name => {
2620
scopeNames.add(name)
@@ -34,23 +28,7 @@ function create (context) {
3428
function checkUsedNames (name, node, groupName) {
3529
assert(typeof name === 'string')
3630

37-
if (groupName === 'data' && name.substr(0, 1) === '_') {
38-
context.report({
39-
node: node,
40-
message: "Field '{{name}}' which start with _ in data is reserved.",
41-
data: {
42-
name
43-
}
44-
})
45-
} else if (reservedNames.has(name)) {
46-
context.report({
47-
node: node,
48-
message: "Reserved key '{{name}}'.",
49-
data: {
50-
name
51-
}
52-
})
53-
} else if (usedNames.indexOf(name) !== -1) {
31+
if (usedNames.indexOf(name) !== -1) {
5432
context.report({
5533
node: node,
5634
message: "Duplicate key '{{name}}'.",
@@ -125,9 +103,6 @@ module.exports = {
125103
{
126104
type: 'object',
127105
properties: {
128-
reserved: {
129-
type: 'array'
130-
},
131106
scope: {
132107
type: 'array'
133108
}

lib/rules/no-reservered-keys.js

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/**
2+
* @fileoverview Prevent overwrite reserved keys
3+
* @author Armano
4+
*/
5+
'use strict'
6+
7+
const utils = require('../utils')
8+
const assert = require('assert')
9+
10+
// ------------------------------------------------------------------------------
11+
// Rule Definition
12+
// ------------------------------------------------------------------------------
13+
14+
const RESERVER_NAMES = new Set(require('../utils/vue-reserved.json'))
15+
const SCOPE_NAMES = new Set(['props', 'computed', 'data', 'methods'])
16+
17+
function create (context) {
18+
const reservedNames = RESERVER_NAMES
19+
const scopeNames = SCOPE_NAMES
20+
21+
const options = context.options[0] || {}
22+
if (options.reserved) {
23+
options.reserved.forEach(name => {
24+
reservedNames.add(name)
25+
})
26+
}
27+
if (options.scope) {
28+
options.scope.forEach(name => {
29+
scopeNames.add(name)
30+
})
31+
}
32+
33+
// ----------------------------------------------------------------------
34+
// Helpers
35+
// ----------------------------------------------------------------------
36+
37+
function checkUsedNames (name, node, groupName) {
38+
assert(typeof name === 'string')
39+
40+
if (groupName === 'data' && name.substr(0, 1) === '_') {
41+
context.report({
42+
node: node,
43+
message: "Field '{{name}}' which start with _ in data is reserved.",
44+
data: {
45+
name
46+
}
47+
})
48+
} else if (reservedNames.has(name)) {
49+
context.report({
50+
node: node,
51+
message: "Reserved key '{{name}}'.",
52+
data: {
53+
name
54+
}
55+
})
56+
}
57+
}
58+
59+
function checkArrayExpression (node, groupName) {
60+
node.elements.forEach(item => {
61+
const name = utils.getStaticPropertyName(item)
62+
if (name) {
63+
checkUsedNames(name, item, groupName)
64+
}
65+
})
66+
}
67+
68+
function checkObjectExpression (node, groupName) {
69+
node.properties.forEach(item => {
70+
const name = utils.getStaticPropertyName(item)
71+
if (name) {
72+
checkUsedNames(name, item.key, groupName)
73+
}
74+
})
75+
}
76+
77+
function checkFunctionExpression (node, groupName) {
78+
if (node.body.type === 'BlockStatement') {
79+
node.body.body.forEach(item => {
80+
if (item.type === 'ReturnStatement' && item.argument.type === 'ObjectExpression') {
81+
checkObjectExpression(item.argument, groupName)
82+
}
83+
})
84+
}
85+
}
86+
87+
// ----------------------------------------------------------------------
88+
// Public
89+
// ----------------------------------------------------------------------
90+
91+
return utils.executeOnVueComponent(context, (obj) => {
92+
obj.properties
93+
.filter(p => p.type === 'Property' && p.key.type === 'Identifier' && scopeNames.has(p.key.name))
94+
.forEach(node => {
95+
if (node.value.type === 'ArrayExpression') {
96+
checkArrayExpression(node.value, node.key.name)
97+
} else if (node.value.type === 'ObjectExpression') {
98+
checkObjectExpression(node.value, node.key.name)
99+
} else if (node.value.type === 'FunctionExpression') {
100+
checkFunctionExpression(node.value, node.key.name)
101+
}
102+
})
103+
})
104+
}
105+
106+
module.exports = {
107+
meta: {
108+
docs: {
109+
description: 'Prevent overwrite reserved keys',
110+
category: 'Fill me in',
111+
recommended: false
112+
},
113+
fixable: null, // or "code" or "whitespace"
114+
schema: [
115+
{
116+
type: 'object',
117+
properties: {
118+
reserved: {
119+
type: 'array'
120+
},
121+
scope: {
122+
type: 'array'
123+
}
124+
},
125+
additionalProperties: false
126+
}
127+
]
128+
},
129+
130+
create
131+
}

tests/lib/rules/no-dupe-keys.js

-46
Original file line numberDiff line numberDiff line change
@@ -141,52 +141,6 @@ ruleTester.run('no-dupe-keys', rule, {
141141
message: 'Duplicate key \'foo\'.',
142142
line: 16
143143
}]
144-
},
145-
{
146-
filename: 'test.js',
147-
code: `
148-
new Vue({
149-
props: {
150-
$el: String
151-
}
152-
})
153-
`,
154-
parserOptions: { ecmaVersion: 6 },
155-
errors: [{
156-
message: 'Reserved key \'$el\'.',
157-
line: 4
158-
}]
159-
},
160-
{
161-
filename: 'test.js',
162-
code: `
163-
new Vue({
164-
data: {
165-
_foo: String
166-
}
167-
})
168-
`,
169-
parserOptions: { ecmaVersion: 6 },
170-
errors: [{
171-
message: "Field '_foo' which start with _ in data is reserved.",
172-
line: 4
173-
}]
174-
},
175-
{
176-
filename: 'test.js',
177-
code: `
178-
new Vue({
179-
foo: {
180-
bar: String
181-
}
182-
})
183-
`,
184-
options: [{ reserved: ['bar'], scope: ['foo'] }],
185-
parserOptions: { ecmaVersion: 6 },
186-
errors: [{
187-
message: "Reserved key 'bar'.",
188-
line: 4
189-
}]
190144
}
191145
]
192146
})

0 commit comments

Comments
 (0)