no-reserved-props.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /**
  2. * @author Yosuke Ota
  3. * See LICENSE file in root directory for full license.
  4. */
  5. 'use strict'
  6. // ------------------------------------------------------------------------------
  7. // Requirements
  8. // ------------------------------------------------------------------------------
  9. const utils = require('../utils')
  10. const casing = require('../utils/casing')
  11. /**
  12. * @typedef {import('../utils').ComponentProp} ComponentProp
  13. */
  14. // ------------------------------------------------------------------------------
  15. // Helpers
  16. // ------------------------------------------------------------------------------
  17. const RESERVED = {
  18. 3: ['key', 'ref'],
  19. 2: ['key', 'ref', 'is', 'slot', 'slot-scope', 'slotScope', 'class', 'style']
  20. }
  21. // ------------------------------------------------------------------------------
  22. // Rule Definition
  23. // ------------------------------------------------------------------------------
  24. module.exports = {
  25. meta: {
  26. type: 'problem',
  27. docs: {
  28. description: 'disallow reserved names in props',
  29. categories: ['vue3-essential', 'essential'],
  30. url: 'https://eslint.vuejs.org/rules/no-reserved-props.html',
  31. defaultOptions: {
  32. vue2: [{ vueVersion: 2 }]
  33. }
  34. },
  35. fixable: null,
  36. schema: [
  37. {
  38. type: 'object',
  39. properties: {
  40. vueVersion: {
  41. enum: [2, 3]
  42. }
  43. },
  44. additionalProperties: false
  45. }
  46. ],
  47. messages: {
  48. reserved:
  49. "'{{propName}}' is a reserved attribute and cannot be used as props."
  50. }
  51. },
  52. /** @param {RuleContext} context */
  53. create(context) {
  54. const options = context.options[0] || {}
  55. /** @type {2|3} */
  56. const vueVersion = options.vueVersion || 3
  57. const reserved = new Set(RESERVED[vueVersion])
  58. /**
  59. * @param {ComponentProp[]} props
  60. */
  61. function processProps(props) {
  62. for (const prop of props) {
  63. if (prop.propName != null && reserved.has(prop.propName)) {
  64. context.report({
  65. node: prop.node,
  66. messageId: `reserved`,
  67. data: {
  68. propName: casing.kebabCase(prop.propName)
  69. }
  70. })
  71. }
  72. }
  73. }
  74. return utils.compositingVisitors(
  75. utils.defineScriptSetupVisitor(context, {
  76. onDefinePropsEnter(_node, props) {
  77. processProps(props)
  78. }
  79. }),
  80. utils.executeOnVue(context, (obj) => {
  81. processProps(utils.getComponentPropsFromOptions(obj))
  82. })
  83. )
  84. }
  85. }