Skip to content

Commit b91728d

Browse files
committed
feat(no-reserved-component-names): add case sensitive option
1 parent 50bde65 commit b91728d

File tree

2 files changed

+68
-24
lines changed

2 files changed

+68
-24
lines changed

lib/rules/no-reserved-component-names.js

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,6 @@ function isLowercase(word) {
3434
return /^[a-z]*$/.test(word)
3535
}
3636

37-
const RESERVED_NAMES_IN_HTML = new Set([
38-
...htmlElements,
39-
...htmlElements.map(casing.capitalize)
40-
])
41-
const RESERVED_NAMES_IN_OTHERS = new Set([
42-
...deprecatedHtmlElements,
43-
...deprecatedHtmlElements.map(casing.capitalize),
44-
...kebabCaseElements,
45-
...kebabCaseElements.map(casing.pascalCase),
46-
...svgElements,
47-
...svgElements.filter(isLowercase).map(casing.capitalize)
48-
])
49-
5037
/**
5138
* @param {Expression | SpreadElement} node
5239
* @returns {node is (Literal | TemplateLiteral)}
@@ -60,17 +47,6 @@ function canVerify(node) {
6047
)
6148
}
6249

63-
/**
64-
* @param {string} name
65-
* @returns {string}
66-
*/
67-
function getMessageId(name) {
68-
if (RESERVED_NAMES_IN_HTML.has(name)) return 'reservedInHtml'
69-
if (RESERVED_NAMES_IN_VUE.has(name)) return 'reservedInVue'
70-
if (RESERVED_NAMES_IN_VUE3.has(name)) return 'reservedInVue3'
71-
return 'reserved'
72-
}
73-
7450
module.exports = {
7551
meta: {
7652
type: 'suggestion',
@@ -90,6 +66,9 @@ module.exports = {
9066
},
9167
disallowVue3BuiltInComponents: {
9268
type: 'boolean'
69+
},
70+
htmlElementCaseSensitive: {
71+
type: 'boolean'
9372
}
9473
},
9574
additionalProperties: false
@@ -109,6 +88,26 @@ module.exports = {
10988
options.disallowVueBuiltInComponents === true
11089
const disallowVue3BuiltInComponents =
11190
options.disallowVue3BuiltInComponents === true
91+
const htmlElementCaseSensitive = options.htmlElementCaseSensitive === true
92+
93+
const RESERVED_NAMES_IN_HTML = new Set([
94+
...htmlElements,
95+
...(htmlElementCaseSensitive ? [] : htmlElements.map(casing.capitalize))
96+
])
97+
const RESERVED_NAMES_IN_OTHERS = new Set([
98+
...deprecatedHtmlElements,
99+
...(htmlElementCaseSensitive
100+
? []
101+
: deprecatedHtmlElements.map(casing.capitalize)),
102+
...kebabCaseElements,
103+
...(htmlElementCaseSensitive
104+
? []
105+
: kebabCaseElements.map(casing.pascalCase)),
106+
...svgElements,
107+
...(htmlElementCaseSensitive
108+
? []
109+
: svgElements.filter(isLowercase).map(casing.capitalize))
110+
])
112111

113112
const reservedNames = new Set([
114113
...RESERVED_NAMES_IN_HTML,
@@ -133,6 +132,17 @@ module.exports = {
133132
}
134133
}
135134

135+
/**
136+
* @param {string} name
137+
* @returns {string}
138+
*/
139+
function getMessageId(name) {
140+
if (RESERVED_NAMES_IN_HTML.has(name)) return 'reservedInHtml'
141+
if (RESERVED_NAMES_IN_VUE.has(name)) return 'reservedInVue'
142+
if (RESERVED_NAMES_IN_VUE3.has(name)) return 'reservedInVue3'
143+
return 'reserved'
144+
}
145+
136146
/**
137147
* @param {ESNode} node
138148
* @param {string} name

tests/lib/rules/no-reserved-component-names.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,12 @@ const invalidElements = [
410410
'xmp',
411411
'Xmp'
412412
]
413+
const invalidLowerCaseElements = invalidElements.filter(
414+
(element) => element === element.toLowerCase()
415+
)
416+
const invalidUpperCaseElements = invalidElements.filter(
417+
(element) => element === element.toUpperCase()
418+
)
413419

414420
const vue2BuiltInComponents = [
415421
'component',
@@ -559,6 +565,16 @@ ruleTester.run('no-reserved-component-names', rule, {
559565
languageOptions,
560566
options: [{ disallowVueBuiltInComponents: true }]
561567
})),
568+
...invalidUpperCaseElements.map((name) => ({
569+
filename: `${name}.vue`,
570+
code: `
571+
export default {
572+
name: '${name}'
573+
}
574+
`,
575+
languageOptions,
576+
options: [{ htmlElementCaseSensitive: true }]
577+
})),
562578
{
563579
filename: 'test.vue',
564580
code: `<script setup> defineOptions({}) </script>`,
@@ -701,6 +717,24 @@ ruleTester.run('no-reserved-component-names', rule, {
701717
}
702718
]
703719
})),
720+
...invalidLowerCaseElements.map((name) => ({
721+
filename: `${name}.vue`,
722+
code: `<script setup> defineOptions({name: '${name}'}) </script>`,
723+
languageOptions: {
724+
parser: require('vue-eslint-parser'),
725+
...languageOptions
726+
},
727+
options: [{ htmlElementCaseSensitive: true }],
728+
errors: [
729+
{
730+
messageId: RESERVED_NAMES_IN_HTML.has(name)
731+
? 'reservedInHtml'
732+
: 'reserved',
733+
data: { name },
734+
line: 1
735+
}
736+
]
737+
})),
704738
...vue2BuiltInComponents.map((name) => ({
705739
filename: `${name}.vue`,
706740
code: `

0 commit comments

Comments
 (0)