diff --git a/docs/rules/no-invalid-model-keys.md b/docs/rules/no-invalid-model-keys.md new file mode 100644 index 000000000..b69cbf952 --- /dev/null +++ b/docs/rules/no-invalid-model-keys.md @@ -0,0 +1,103 @@ +--- +pageClass: rule-details +sidebarDepth: 0 +title: vue/no-invalid-model-keys +description: require valid keys in model option +--- +# vue/no-invalid-model-keys + +> require valid keys in model option + + +## :book: Rule Details + +This rule is aimed at preventing invalid keys in model option. + + +```vue + +``` + + + +```vue + +``` + + + +```vue + +``` + + + +```vue + +``` + + + +```vue + +``` + + + +```vue + +``` + + + +## :mag: Implementation + +- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-invalid-model-keys.js) +- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-invalid-model-keys.js) diff --git a/lib/index.js b/lib/index.js index cc18e3055..a5f632314 100644 --- a/lib/index.js +++ b/lib/index.js @@ -81,6 +81,7 @@ module.exports = { 'no-empty-component-block': require('./rules/no-empty-component-block'), 'no-empty-pattern': require('./rules/no-empty-pattern'), 'no-extra-parens': require('./rules/no-extra-parens'), + 'no-invalid-model-keys': require('./rules/no-invalid-model-keys'), 'no-irregular-whitespace': require('./rules/no-irregular-whitespace'), 'no-lifecycle-after-await': require('./rules/no-lifecycle-after-await'), 'no-lone-template': require('./rules/no-lone-template'), diff --git a/lib/rules/no-invalid-model-keys.js b/lib/rules/no-invalid-model-keys.js new file mode 100644 index 000000000..3a4b7ccf6 --- /dev/null +++ b/lib/rules/no-invalid-model-keys.js @@ -0,0 +1,56 @@ +/** + * @fileoverview Requires valid keys in model option. + * @author Alex Sokolov + */ +'use strict' + +const utils = require('../utils') + +/** + * @typedef {import('../utils').GroupName} GroupName + */ + +// ------------------------------------------------------------------------------ +// Rule Definition +// ------------------------------------------------------------------------------ +/** @type {GroupName[]} */ +const GROUP_NAMES = ['model'] + +const VALID_MODEL_KEYS = ['prop', 'event'] + +module.exports = { + meta: { + type: 'problem', + docs: { + description: 'require valid keys in model option', + categories: undefined, + url: 'https://eslint.vuejs.org/rules/no-invalid-model-keys.html' + }, + fixable: null, + schema: [] + }, + /** @param {RuleContext} context */ + create(context) { + const groups = new Set(GROUP_NAMES) + + // ---------------------------------------------------------------------- + // Public + // ---------------------------------------------------------------------- + + return utils.executeOnVue(context, (obj) => { + const properties = utils.iterateProperties(obj, groups) + + for (const o of properties) { + if (VALID_MODEL_KEYS.indexOf(o.name) === -1) { + context.report({ + node: o.node, + message: "Invalid key '{{name}}' in model option.", + data: { + name: o.name + } + }) + } + } + }) + } +} diff --git a/tests/lib/rules/no-invalid-model-keys.js b/tests/lib/rules/no-invalid-model-keys.js new file mode 100644 index 000000000..ebe4de973 --- /dev/null +++ b/tests/lib/rules/no-invalid-model-keys.js @@ -0,0 +1,151 @@ +/** + * @fileoverview Prevents invalid keys in model option. + * @author Alex Sokolov + */ +'use strict' + +// ------------------------------------------------------------------------------ +// Requirements +// ------------------------------------------------------------------------------ + +const rule = require('../../../lib/rules/no-invalid-model-keys') +const RuleTester = require('eslint').RuleTester + +// ------------------------------------------------------------------------------ +// Tests +// ------------------------------------------------------------------------------ + +const ruleTester = new RuleTester({ + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module' + } +}) +ruleTester.run('no-invalid-model-keys', rule, { + valid: [ + { + filename: 'test.vue', + code: ` + export default { + model: { + prop: 'list' + } + } + ` + }, + { + filename: 'test.vue', + code: ` + export default { + model: { + event: 'update' + } + } + ` + }, + { + filename: 'test.vue', + code: ` + export default { + model: { + prop: 'list', + event: 'update' + } + } + ` + } + ], + + invalid: [ + { + filename: 'test.vue', + code: ` + export default { + model: { + props: 'list' + } + } + `, + errors: ["Invalid key 'props' in model option."] + }, + { + filename: 'test.vue', + code: ` + export default { + model: { + events: 'update' + } + } + `, + errors: ["Invalid key 'events' in model option."] + }, + { + filename: 'test.vue', + code: ` + export default { + model: { + props: 'list', + event: 'update' + } + } + `, + errors: ["Invalid key 'props' in model option."] + }, + { + filename: 'test.vue', + code: ` + export default { + model: { + prop: 'list', + events: 'update' + } + } + `, + errors: ["Invalid key 'events' in model option."] + }, + { + filename: 'test.vue', + code: ` + export default { + model: { + props: 'list', + events: 'update' + } + } + `, + errors: [ + "Invalid key 'props' in model option.", + "Invalid key 'events' in model option." + ] + }, + { + filename: 'test.vue', + code: ` + export default { + model: { + prop: 'checked', + props: 'list', + event: 'update' + } + } + `, + errors: ["Invalid key 'props' in model option."] + }, + { + filename: 'test.vue', + code: ` + export default { + model: { + name: 'checked', + props: 'list', + event: 'update' + } + } + `, + errors: [ + "Invalid key 'name' in model option.", + "Invalid key 'props' in model option." + ] + } + ] +})