From 366dae43ca8f21f9917b10ae89cea0ab6cc56849 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Thu, 14 Apr 2022 13:22:35 +0900 Subject: [PATCH 1/7] Change presets configs and remove unused internal methods --- docs/rules/README.md | 8 +++++--- docs/rules/no-expose-after-await.md | 2 ++ docs/rules/no-v-text-v-html-on-component.md | 2 ++ docs/rules/prefer-import-from-vue.md | 1 + lib/configs/essential.js | 1 + lib/configs/vue3-essential.js | 3 +++ lib/rules/no-expose-after-await.js | 3 +-- lib/rules/no-v-text-v-html-on-component.js | 4 +--- lib/rules/prefer-import-from-vue.js | 4 +--- lib/utils/index.js | 12 ------------ 10 files changed, 17 insertions(+), 23 deletions(-) diff --git a/docs/rules/README.md b/docs/rules/README.md index 3d2d113d7..791b4e6c3 100644 --- a/docs/rules/README.md +++ b/docs/rules/README.md @@ -12,6 +12,7 @@ sidebarDepth: 0 :bulb: Indicates that some problems reported by the rule are manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions). ::: + ## Base Rules (Enabling Correct ESLint Parsing) Enforce all the rules in this category, as well as all higher priority rules, with: @@ -67,6 +68,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi | [vue/no-dupe-v-else-if](./no-dupe-v-else-if.md) | disallow duplicate conditions in `v-if` / `v-else-if` chains | | | [vue/no-duplicate-attributes](./no-duplicate-attributes.md) | disallow duplication of attributes | | | [vue/no-export-in-script-setup](./no-export-in-script-setup.md) | disallow `export` in ` +``` + + + + + +```vue + +``` + + + + + +```vue + +``` + + + + + +```vue + +``` + + + + + +```vue + +``` + + + + + +```vue + +``` + + + +## :mag: Implementation + +- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/valid-model-definition.js) +- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/valid-model-definition.js) diff --git a/eslint-internal-rules/no-invalid-meta-docs-categories.js b/eslint-internal-rules/no-invalid-meta-docs-categories.js index 5a86d16ab..363e13698 100644 --- a/eslint-internal-rules/no-invalid-meta-docs-categories.js +++ b/eslint-internal-rules/no-invalid-meta-docs-categories.js @@ -18,11 +18,9 @@ */ function getPropertyFromObject(property, node) { if (node && node.type === 'ObjectExpression') { - const properties = node.properties - - for (let i = 0; i < properties.length; i++) { - if (properties[i].key.name === property) { - return properties[i] + for (const prop of node.properties) { + if (prop.type === 'Property' && prop.key.name === property) { + return prop } } } diff --git a/eslint-internal-rules/no-invalid-meta.js b/eslint-internal-rules/no-invalid-meta.js index e96435cf9..905d7297f 100644 --- a/eslint-internal-rules/no-invalid-meta.js +++ b/eslint-internal-rules/no-invalid-meta.js @@ -18,11 +18,9 @@ */ function getPropertyFromObject(property, node) { if (node && node.type === 'ObjectExpression') { - const properties = node.properties - - for (let i = 0; i < properties.length; i++) { - if (properties[i].key.name === property) { - return properties[i] + for (const prop of node.properties) { + if (prop.type === 'Property' && prop.key.name === property) { + return prop } } } diff --git a/lib/index.js b/lib/index.js index d412a6bf1..8f1239ca5 100644 --- a/lib/index.js +++ b/lib/index.js @@ -201,6 +201,7 @@ module.exports = { 'v-slot-style': require('./rules/v-slot-style'), 'valid-define-emits': require('./rules/valid-define-emits'), 'valid-define-props': require('./rules/valid-define-props'), + 'valid-model-definition': require('./rules/valid-model-definition'), 'valid-next-tick': require('./rules/valid-next-tick'), 'valid-template-root': require('./rules/valid-template-root'), 'valid-v-bind-sync': require('./rules/valid-v-bind-sync'), diff --git a/lib/rules/no-invalid-model-keys.js b/lib/rules/no-invalid-model-keys.js index f86587ff1..1695e6fa9 100644 --- a/lib/rules/no-invalid-model-keys.js +++ b/lib/rules/no-invalid-model-keys.js @@ -1,57 +1,22 @@ -/** - * @fileoverview Requires valid keys in model option. - * @author Alex Sokolov - */ 'use strict' -const utils = require('../utils') - -// ------------------------------------------------------------------------------ -// Rule Definition -// ------------------------------------------------------------------------------ -const VALID_MODEL_KEYS = ['prop', 'event'] +const baseRule = require('./valid-model-definition') module.exports = { meta: { - type: 'problem', + ...baseRule.meta, + type: baseRule.meta.type, docs: { - description: 'require valid keys in model option', + description: baseRule.meta.docs.description, categories: undefined, url: 'https://eslint.vuejs.org/rules/no-invalid-model-keys.html' }, - fixable: null, + deprecated: true, + replacedBy: ['valid-model-definition'], schema: [] }, /** @param {RuleContext} context */ create(context) { - // ---------------------------------------------------------------------- - // Public - // ---------------------------------------------------------------------- - - return utils.executeOnVue(context, (obj) => { - const modelProperty = utils.findProperty(obj, 'model') - if (!modelProperty || modelProperty.value.type !== 'ObjectExpression') { - return - } - - for (const p of modelProperty.value.properties) { - if (p.type !== 'Property') { - continue - } - const name = utils.getStaticPropertyName(p) - if (!name) { - continue - } - if (VALID_MODEL_KEYS.indexOf(name) === -1) { - context.report({ - node: p, - message: "Invalid key '{{name}}' in model option.", - data: { - name - } - }) - } - } - }) + return baseRule.create(context) } } diff --git a/lib/rules/valid-model-definition.js b/lib/rules/valid-model-definition.js new file mode 100644 index 000000000..c00370d25 --- /dev/null +++ b/lib/rules/valid-model-definition.js @@ -0,0 +1,57 @@ +/** + * @fileoverview Requires valid keys in model option. + * @author Alex Sokolov + */ +'use strict' + +const utils = require('../utils') + +// ------------------------------------------------------------------------------ +// Rule Definition +// ------------------------------------------------------------------------------ +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/valid-model-definition.html' + }, + fixable: null, + schema: [] + }, + /** @param {RuleContext} context */ + create(context) { + // ---------------------------------------------------------------------- + // Public + // ---------------------------------------------------------------------- + + return utils.executeOnVue(context, (obj) => { + const modelProperty = utils.findProperty(obj, 'model') + if (!modelProperty || modelProperty.value.type !== 'ObjectExpression') { + return + } + + for (const p of modelProperty.value.properties) { + if (p.type !== 'Property') { + continue + } + const name = utils.getStaticPropertyName(p) + if (!name) { + continue + } + if (VALID_MODEL_KEYS.indexOf(name) === -1) { + context.report({ + node: p, + message: "Invalid key '{{name}}' in model option.", + data: { + name + } + }) + } + } + }) + } +} diff --git a/tests/lib/rules/valid-model-definition.js b/tests/lib/rules/valid-model-definition.js new file mode 100644 index 000000000..d9d8263ab --- /dev/null +++ b/tests/lib/rules/valid-model-definition.js @@ -0,0 +1,151 @@ +/** + * @fileoverview Prevents invalid keys in model option. + * @author Alex Sokolov + */ +'use strict' + +// ------------------------------------------------------------------------------ +// Requirements +// ------------------------------------------------------------------------------ + +const rule = require('../../../lib/rules/valid-model-definition') +const RuleTester = require('eslint').RuleTester + +// ------------------------------------------------------------------------------ +// Tests +// ------------------------------------------------------------------------------ + +const ruleTester = new RuleTester({ + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module' + } +}) +ruleTester.run('valid-model-definition', 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." + ] + } + ] +}) From 79981d0a85e9118b4b04011f04c0624540abfdd7 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Thu, 14 Apr 2022 18:46:38 +0900 Subject: [PATCH 5/7] Update preset --- docs/rules/README.md | 11 +++++++---- docs/rules/no-child-content.md | 1 + docs/rules/no-reserved-component-names.md | 2 ++ docs/rules/no-use-computed-property-like-method.md | 2 ++ docs/rules/valid-model-definition.md | 1 + lib/configs/essential.js | 4 ++++ lib/configs/vue3-essential.js | 3 +++ lib/rules/no-child-content.js | 2 +- lib/rules/no-reserved-component-names.js | 2 +- lib/rules/no-use-computed-property-like-method.js | 2 +- lib/rules/valid-model-definition.js | 2 +- 11 files changed, 24 insertions(+), 8 deletions(-) diff --git a/docs/rules/README.md b/docs/rules/README.md index fd1e725b4..8959b0eb7 100644 --- a/docs/rules/README.md +++ b/docs/rules/README.md @@ -43,6 +43,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi | [vue/multi-word-component-names](./multi-word-component-names.md) | require component names to be always multi-word | | | [vue/no-arrow-functions-in-watch](./no-arrow-functions-in-watch.md) | disallow using arrow functions to define watcher | | | [vue/no-async-in-computed-properties](./no-async-in-computed-properties.md) | disallow asynchronous actions in computed properties | | +| [vue/no-child-content](./no-child-content.md) | disallow element's child contents which would be overwritten by a directive like `v-html` or `v-text` | :bulb: | | [vue/no-computed-properties-in-data](./no-computed-properties-in-data.md) | disallow accessing computed properties in `data`. | | | [vue/no-deprecated-data-object-declaration](./no-deprecated-data-object-declaration.md) | disallow using deprecated object declaration on data (in Vue.js 3.0.0+) | :wrench: | | [vue/no-deprecated-destroyed-lifecycle](./no-deprecated-destroyed-lifecycle.md) | disallow using deprecated `destroyed` and `beforeDestroy` lifecycle hooks (in Vue.js 3.0.0+) | :wrench: | @@ -72,6 +73,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi | [vue/no-mutating-props](./no-mutating-props.md) | disallow mutation of component props | | | [vue/no-parsing-error](./no-parsing-error.md) | disallow parsing errors in `