50416369595001aa259211f724af51520e097d29c238f6e55cce185d8dbdb0256d0dc8723698b20295f94c3c282c6df2495305bf86a0d03de487fc4ae65b73 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /**
  2. * @fileoverview Prop definitions should be detailed
  3. * @author Armano
  4. */
  5. 'use strict'
  6. const utils = require('../utils')
  7. /**
  8. * @typedef {import('../utils').ComponentArrayProp} ComponentArrayProp
  9. * @typedef {import('../utils').ComponentObjectProp} ComponentObjectProp
  10. */
  11. // ------------------------------------------------------------------------------
  12. // Rule Definition
  13. // ------------------------------------------------------------------------------
  14. module.exports = {
  15. meta: {
  16. type: 'suggestion',
  17. docs: {
  18. description: 'require type definitions in props',
  19. categories: ['vue3-strongly-recommended', 'strongly-recommended'],
  20. url: 'https://eslint.vuejs.org/rules/require-prop-types.html'
  21. },
  22. fixable: null, // or "code" or "whitespace"
  23. schema: [
  24. // fill in your schema
  25. ]
  26. },
  27. /** @param {RuleContext} context */
  28. create(context) {
  29. // ----------------------------------------------------------------------
  30. // Helpers
  31. // ----------------------------------------------------------------------
  32. /**
  33. * @param {ObjectExpression} node
  34. * @returns {boolean}
  35. */
  36. function objectHasType(node) {
  37. const typeProperty = node.properties.find(
  38. (p) =>
  39. p.type === 'Property' &&
  40. utils.getStaticPropertyName(p) === 'type' &&
  41. (p.value.type !== 'ArrayExpression' || p.value.elements.length > 0)
  42. )
  43. const validatorProperty = node.properties.find(
  44. (p) =>
  45. p.type === 'Property' &&
  46. utils.getStaticPropertyName(p) === 'validator'
  47. )
  48. return Boolean(typeProperty || validatorProperty)
  49. }
  50. /**
  51. * @param { ComponentArrayProp | ComponentObjectProp } prop
  52. */
  53. function checkProperty({ value, node, propName }) {
  54. let hasType = true
  55. if (!value) {
  56. hasType = false
  57. } else if (value.type === 'ObjectExpression') {
  58. // foo: {
  59. hasType = objectHasType(value)
  60. } else if (value.type === 'ArrayExpression') {
  61. // foo: [
  62. hasType = value.elements.length > 0
  63. } else if (
  64. value.type === 'FunctionExpression' ||
  65. value.type === 'ArrowFunctionExpression'
  66. ) {
  67. hasType = false
  68. }
  69. if (!hasType) {
  70. const name =
  71. propName ||
  72. (node.type === 'Identifier' && node.name) ||
  73. 'Unknown prop'
  74. context.report({
  75. node,
  76. message: 'Prop "{{name}}" should define at least its type.',
  77. data: {
  78. name
  79. }
  80. })
  81. }
  82. }
  83. // ----------------------------------------------------------------------
  84. // Public
  85. // ----------------------------------------------------------------------
  86. return utils.executeOnVue(context, (obj) => {
  87. const props = utils.getComponentProps(obj)
  88. for (const prop of props) {
  89. checkProperty(prop)
  90. }
  91. })
  92. }
  93. }