'use strict' // ------------------------------------------------------------------------------ // Requirements // ------------------------------------------------------------------------------ // eslint-disable-next-line @typescript-eslint/no-var-requires const utils = require('eslint-plugin-vue/lib/utils') function toPascalCase(str) { const words = str.match(/[a-z]+/gi) if (!words) return '' return words .map(word => { return word.charAt(0).toUpperCase() + word.substr(1).toLowerCase() }) .join('') } function findDemoElement(node) { let el = null node.children.forEach(child => { if (child.children && child.children.length) { const r = findDemoElement(child) if (r) el = r } else { const r = child.type === 'VElement' && child.name.startsWith('demo') if (r) el = child } }) return el } // ------------------------------------------------------------------------------ // Rule Definition // ------------------------------------------------------------------------------ module.exports = { meta: { type: 'problem', docs: { description: 'require valid demo SFC for "AppCardCode" component', categories: ['base'], url: 'https://eslint.vuejs.org/rules/require-component-is.html', }, fixable: null, schema: [], }, /** @param {RuleContext} context */ create(context) { return utils.defineTemplateBodyVisitor(context, { /** @param {VElement} node */ 'VElement[name=\'appcardcode\']': function (node) { const propTitle = utils.getAttribute(node, 'title') const titleValue = propTitle.value.value const pascalCaseTitle = toPascalCase(titleValue) const demoNode = findDemoElement(node) const demoNodeSfcName = demoNode.rawName const pattern = new RegExp(`Demo[a-zA-z]+${pascalCaseTitle}`) const demoSfcMatch = demoNodeSfcName.search(pattern) if (demoSfcMatch !== 0) { context.report({ node, loc: demoNode.loc, message: `Expected Demo SFC to match the pascal case value of title prop value. Expected: 'Demo[a-zA-Z]+${pascalCaseTitle}', Actual: '${demoNodeSfcName}'`, }) } }, }) }, }