no-reserved-keys.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /**
  2. * @fileoverview Prevent overwrite reserved keys
  3. * @author Armano
  4. */
  5. 'use strict'
  6. const utils = require('../utils')
  7. /**
  8. * @typedef {import('../utils').GroupName} GroupName
  9. */
  10. const RESERVED_KEYS = require('../utils/vue-reserved.json')
  11. /** @type {GroupName[]} */
  12. const GROUP_NAMES = [
  13. 'props',
  14. 'computed',
  15. 'data',
  16. 'asyncData',
  17. 'methods',
  18. 'setup'
  19. ]
  20. module.exports = {
  21. meta: {
  22. type: 'suggestion',
  23. docs: {
  24. description: 'disallow overwriting reserved keys',
  25. categories: ['vue3-essential', 'vue2-essential'],
  26. url: 'https://eslint.vuejs.org/rules/no-reserved-keys.html'
  27. },
  28. fixable: null,
  29. schema: [
  30. {
  31. type: 'object',
  32. properties: {
  33. reserved: {
  34. type: 'array'
  35. },
  36. groups: {
  37. type: 'array'
  38. }
  39. },
  40. additionalProperties: false
  41. }
  42. ],
  43. messages: {
  44. reserved: "Key '{{name}}' is reserved.",
  45. startsWithUnderscore:
  46. "Keys starting with '_' are reserved in '{{name}}' group."
  47. }
  48. },
  49. /** @param {RuleContext} context */
  50. create(context) {
  51. const options = context.options[0] || {}
  52. const reservedKeys = new Set([
  53. ...RESERVED_KEYS,
  54. ...(options.reserved || [])
  55. ])
  56. const groups = new Set([...GROUP_NAMES, ...(options.groups || [])])
  57. return utils.compositingVisitors(
  58. utils.defineScriptSetupVisitor(context, {
  59. onDefinePropsEnter(_node, props) {
  60. for (const prop of props) {
  61. if (prop.propName && reservedKeys.has(prop.propName)) {
  62. const { propName, node } = prop
  63. context.report({
  64. node,
  65. messageId: 'reserved',
  66. data: {
  67. name: propName
  68. }
  69. })
  70. }
  71. }
  72. }
  73. }),
  74. utils.executeOnVue(context, (obj) => {
  75. const properties = utils.iterateProperties(obj, groups)
  76. for (const o of properties) {
  77. if (
  78. (o.groupName === 'data' || o.groupName === 'asyncData') &&
  79. o.name[0] === '_'
  80. ) {
  81. context.report({
  82. node: o.node,
  83. messageId: 'startsWithUnderscore',
  84. data: {
  85. name: o.name
  86. }
  87. })
  88. } else if (reservedKeys.has(o.name)) {
  89. context.report({
  90. node: o.node,
  91. messageId: 'reserved',
  92. data: {
  93. name: o.name
  94. }
  95. })
  96. }
  97. }
  98. })
  99. )
  100. }
  101. }