/**
|
* @fileoverview require prop type to be a constructor
|
* @author Michał Sajnóg
|
*/
|
'use strict'
|
|
const utils = require('../utils')
|
const { isDef } = require('../utils')
|
|
// ------------------------------------------------------------------------------
|
// Rule Definition
|
// ------------------------------------------------------------------------------
|
|
const message = 'The "{{name}}" property should be a constructor.'
|
|
const forbiddenTypes = [
|
'Literal',
|
'TemplateLiteral',
|
'BinaryExpression',
|
'UpdateExpression'
|
]
|
|
/**
|
* @param {ESNode} node
|
*/
|
function isForbiddenType(node) {
|
return (
|
forbiddenTypes.indexOf(node.type) > -1 &&
|
!(node.type === 'Literal' && node.value == null && !node.bigint)
|
)
|
}
|
|
module.exports = {
|
meta: {
|
type: 'suggestion',
|
docs: {
|
description: 'require prop type to be a constructor',
|
categories: ['vue3-essential', 'essential'],
|
url: 'https://eslint.vuejs.org/rules/require-prop-type-constructor.html'
|
},
|
fixable: 'code', // or "code" or "whitespace"
|
schema: []
|
},
|
|
/** @param {RuleContext} context */
|
create(context) {
|
/**
|
* @param {string} propName
|
* @param {ESNode} node
|
*/
|
function checkPropertyNode(propName, node) {
|
/** @type {ESNode[]} */
|
const nodes =
|
node.type === 'ArrayExpression' ? node.elements.filter(isDef) : [node]
|
|
nodes
|
.filter((prop) => isForbiddenType(prop))
|
.forEach((prop) =>
|
context.report({
|
node: prop,
|
message,
|
data: {
|
name: propName
|
},
|
fix: (fixer) => {
|
if (prop.type === 'Literal' || prop.type === 'TemplateLiteral') {
|
const newText = utils.getStringLiteralValue(prop, true)
|
|
if (newText) {
|
return fixer.replaceText(prop, newText)
|
}
|
}
|
return null
|
}
|
})
|
)
|
}
|
|
return utils.executeOnVueComponent(context, (obj) => {
|
for (const prop of utils.getComponentProps(obj)) {
|
if (!prop.value || prop.propName == null) {
|
continue
|
}
|
if (
|
isForbiddenType(prop.value) ||
|
prop.value.type === 'ArrayExpression'
|
) {
|
checkPropertyNode(prop.propName, prop.value)
|
} else if (prop.value.type === 'ObjectExpression') {
|
const typeProperty = utils.findProperty(prop.value, 'type')
|
|
if (!typeProperty) continue
|
|
checkPropertyNode(prop.propName, typeProperty.value)
|
}
|
}
|
})
|
}
|
}
|