no-reserved-keys.js 2.8 KB

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