Skip to content

Commit e436ded

Browse files
committed
update forked component-name-in-template-casing rule with upstream to also work with script setup
1 parent d21be93 commit e436ded

File tree

2 files changed

+60
-32
lines changed

2 files changed

+60
-32
lines changed

lib/rules/component-name-in-template-casing.js

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,14 @@ const { toRegExp } = require('eslint-plugin-vue/lib/utils/regexp')
1919
const allowedCaseOptions = ['PascalCase', 'kebab-case']
2020
const defaultCase = 'PascalCase'
2121

22-
// ------------------------------------------------------------------------------
23-
// Rule Definition
24-
// ------------------------------------------------------------------------------
25-
2622
module.exports = {
2723
meta: {
2824
type: 'suggestion',
2925
docs: {
3026
description:
3127
'enforce specific casing for the component naming style in template',
3228
categories: undefined,
33-
url: 'https://eslint.vuejs.org/rules/component-name-in-template-casing.html',
34-
dropIn: true
29+
url: 'https://eslint-plugin-vue-pug.rash.codes/rules/component-name-in-template-casing.html'
3530
},
3631
fixable: 'code',
3732
schema: [
@@ -41,6 +36,11 @@ module.exports = {
4136
{
4237
type: 'object',
4338
properties: {
39+
globals: {
40+
type: 'array',
41+
items: { type: 'string' },
42+
uniqueItems: true
43+
},
4444
ignores: {
4545
type: 'array',
4646
items: { type: 'string' },
@@ -59,18 +59,34 @@ module.exports = {
5959
create(context) {
6060
const caseOption = context.options[0]
6161
const options = context.options[1] || {}
62-
const caseType =
63-
allowedCaseOptions.indexOf(caseOption) !== -1 ? caseOption : defaultCase
62+
const caseType = allowedCaseOptions.includes(caseOption)
63+
? caseOption
64+
: defaultCase
6465
/** @type {RegExp[]} */
6566
const ignores = (options.ignores || []).map(toRegExp)
67+
/** @type {string[]} */
68+
const globals = (options.globals || []).map(casing.pascalCase)
6669
const registeredComponentsOnly = options.registeredComponentsOnly !== false
6770
const tokens =
6871
context.parserServices.getTemplateBodyTokenStore &&
6972
context.parserServices.getTemplateBodyTokenStore()
7073

71-
/** @type { string[] } */
72-
const registeredComponents = []
74+
/** @type { Set<string> } */
75+
const registeredComponents = new Set(globals)
7376

77+
if (utils.isScriptSetup(context)) {
78+
// For <script setup>
79+
const globalScope = context.getSourceCode().scopeManager.globalScope
80+
if (globalScope) {
81+
// Only check find the import module
82+
const moduleScope = globalScope.childScopes.find(
83+
(scope) => scope.type === 'module'
84+
)
85+
for (const variable of (moduleScope && moduleScope.variables) || []) {
86+
registeredComponents.add(variable.name)
87+
}
88+
}
89+
}
7490
/**
7591
* Checks whether the given node is the verification target node.
7692
* @param {VElement} node element node
@@ -82,30 +98,21 @@ module.exports = {
8298
return false
8399
}
84100

85-
if (!registeredComponentsOnly) {
86-
// If the user specifies registeredComponentsOnly as false, it checks all component tags.
87-
if (
88-
(!utils.isHtmlElementNode(node) && !utils.isSvgElementNode(node)) ||
89-
utils.isHtmlWellKnownElementName(node.rawName) ||
90-
utils.isSvgWellKnownElementName(node.rawName)
91-
) {
92-
return false
93-
}
94-
return true
95-
}
96-
// We only verify the components registered in the component.
97101
if (
98-
registeredComponents
99-
.filter((name) => casing.isPascalCase(name)) // When defining a component with PascalCase, you can use either case
100-
.some(
101-
(name) =>
102-
node.rawName === name || casing.pascalCase(node.rawName) === name
103-
)
102+
(!utils.isHtmlElementNode(node) && !utils.isSvgElementNode(node)) ||
103+
utils.isHtmlWellKnownElementName(node.rawName) ||
104+
utils.isSvgWellKnownElementName(node.rawName)
104105
) {
106+
return false
107+
}
108+
109+
if (!registeredComponentsOnly) {
110+
// If the user specifies registeredComponentsOnly as false, it checks all component tags.
105111
return true
106112
}
107113

108-
return false
114+
// We only verify the registered components.
115+
return registeredComponents.has(casing.pascalCase(node.rawName))
109116
}
110117

111118
let hasInvalidEOF = false
@@ -148,9 +155,9 @@ module.exports = {
148155
},
149156
...(registeredComponentsOnly
150157
? utils.executeOnVue(context, (obj) => {
151-
registeredComponents.push(
152-
...utils.getRegisteredComponents(obj).map((n) => n.name)
153-
)
158+
for (const n of utils.getRegisteredComponents(obj)) {
159+
registeredComponents.add(n.name)
160+
}
154161
})
155162
: {})
156163
}

tests/rules/component-name-in-template-casing.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,27 @@ KeepAlive
628628
'Component name "client-only" is not PascalCase.',
629629
'Component name "keep-alive" is not PascalCase.'
630630
]
631+
},
632+
{
633+
code: `
634+
<script setup="" lang="ts">
635+
import TheComponent from './TheComponent.vue'
636+
</script>
637+
<template lang="pug">
638+
the-component
639+
</template>
640+
`,
641+
filename: 'test.vue',
642+
output: `
643+
<script setup="" lang="ts">
644+
import TheComponent from './TheComponent.vue'
645+
</script>
646+
<template lang="pug">
647+
TheComponent
648+
</template>
649+
`,
650+
options: ['PascalCase'],
651+
errors: ['Component name "the-component" is not PascalCase.']
631652
}
632653
]
633654
})

0 commit comments

Comments
 (0)