valid-attribute-name.js 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. /**
  2. * @author Doug Wade <douglas.b.wade@gmail.com>
  3. * See LICENSE file in root directory for full license.
  4. */
  5. 'use strict'
  6. const utils = require('../utils')
  7. const xnv = require('xml-name-validator')
  8. module.exports = {
  9. meta: {
  10. type: 'problem',
  11. docs: {
  12. description: 'require valid attribute names',
  13. categories: ['vue3-essential', 'vue2-essential'],
  14. url: 'https://eslint.vuejs.org/rules/valid-attribute-name.html'
  15. },
  16. fixable: null,
  17. schema: [],
  18. messages: {
  19. attribute: 'Attribute name {{name}} is not valid.'
  20. }
  21. },
  22. /** @param {RuleContext} context */
  23. create(context) {
  24. /**
  25. * @param {string | VIdentifier} key
  26. * @return {string}
  27. */
  28. const getName = (key) => (typeof key === 'string' ? key : key.name)
  29. return utils.defineTemplateBodyVisitor(context, {
  30. /** @param {VDirective | VAttribute} node */
  31. VAttribute(node) {
  32. if (utils.isCustomComponent(node.parent.parent)) {
  33. return
  34. }
  35. const name = getName(node.key.name)
  36. if (
  37. node.directive &&
  38. name === 'bind' &&
  39. node.key.argument &&
  40. node.key.argument.type === 'VIdentifier' &&
  41. !xnv.name(node.key.argument.name)
  42. ) {
  43. context.report({
  44. node,
  45. messageId: 'attribute',
  46. data: {
  47. name: node.key.argument.name
  48. }
  49. })
  50. }
  51. if (!node.directive && !xnv.name(name)) {
  52. context.report({
  53. node,
  54. messageId: 'attribute',
  55. data: {
  56. name
  57. }
  58. })
  59. }
  60. }
  61. })
  62. }
  63. }