From ba57494f2b93e8e60d73d828ccb8cb8394d6dd6b Mon Sep 17 00:00:00 2001 From: Patrick Herzberg Date: Sat, 8 Feb 2025 02:31:53 +0100 Subject: [PATCH 1/5] extend prop-name-casing to ignore specific names --- lib/rules/prop-name-casing.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/rules/prop-name-casing.js b/lib/rules/prop-name-casing.js index ba8fcc1b4..bcafc1fa6 100644 --- a/lib/rules/prop-name-casing.js +++ b/lib/rules/prop-name-casing.js @@ -15,6 +15,7 @@ const allowedCaseOptions = ['camelCase', 'snake_case'] /** @param {RuleContext} context */ function create(context) { const options = context.options[0] + const ignores = context.options[1]?.ignores || [] const caseType = allowedCaseOptions.includes(options) ? options : 'camelCase' const checker = casing.getChecker(caseType) @@ -27,7 +28,7 @@ function create(context) { if (propName == null) { continue } - if (!checker(propName)) { + if (!checker(propName) || ignores.includes(propName)) { context.report({ node: item.node, messageId: 'invalidCase', @@ -64,6 +65,12 @@ module.exports = { schema: [ { enum: allowedCaseOptions + }, + { + type: 'object', + properties: { + ignores: { type: 'array' } + } } ], messages: { From efa61828b96fd270eaac8b2f8d03df416fdb5439 Mon Sep 17 00:00:00 2001 From: Patrick Herzberg Date: Sun, 16 Feb 2025 12:30:22 +0100 Subject: [PATCH 2/5] Update lib/rules/prop-name-casing.js Co-authored-by: Flo Edelmann --- lib/rules/prop-name-casing.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/rules/prop-name-casing.js b/lib/rules/prop-name-casing.js index bcafc1fa6..e2739bba9 100644 --- a/lib/rules/prop-name-casing.js +++ b/lib/rules/prop-name-casing.js @@ -69,8 +69,13 @@ module.exports = { { type: 'object', properties: { - ignores: { type: 'array' } - } + ignores: { + type: 'array', + items: { type: 'string' }, + uniqueItems: true + } + }, + additionalProperties: false } ], messages: { From 2ef505360151ab0b2181ee115332192201f36a5d Mon Sep 17 00:00:00 2001 From: Patrick Herzberg Date: Sun, 16 Feb 2025 14:13:40 +0100 Subject: [PATCH 3/5] feat: add ignoreProps option --- docs/rules/prop-name-casing.md | 33 +++++++++++++- lib/rules/prop-name-casing.js | 8 ++-- tests/lib/rules/prop-name-casing.js | 71 +++++++++++++++++++++++++++-- 3 files changed, 105 insertions(+), 7 deletions(-) diff --git a/docs/rules/prop-name-casing.md b/docs/rules/prop-name-casing.md index 1f9f82624..07ad1ed8b 100644 --- a/docs/rules/prop-name-casing.md +++ b/docs/rules/prop-name-casing.md @@ -39,12 +39,18 @@ export default { ```json { - "vue/prop-name-casing": ["error", "camelCase" | "snake_case"] + "vue/prop-name-casing": ["error", + "camelCase" | "snake_case", + { + "ignoreProps": [] + } + ] } ``` - `"camelCase"` (default) ... Enforce property names in `props` to camel case. - `"snake_case"` ... Enforce property names in `props` to snake case. +- `ignoreProps` (`string[]`) ... An array of prop names (or patterns) that should be exempt from the case rule check. Use this option for prop names that are intentionally non-compliant, have special naming requirements for Vue components, or are defined by Vue libraries. You can define these entries as literal strings or as regular expressions (written as strings, e.g., `"/^name/"`). ### `"snake_case"` @@ -67,6 +73,31 @@ export default { +### `"ignoreProps": ["foo-bar", "/^_[a-z]+/u"]` + + + +```vue + +``` + + + ## :couple: Related Rules - [vue/attribute-hyphenation](./attribute-hyphenation.md) diff --git a/lib/rules/prop-name-casing.js b/lib/rules/prop-name-casing.js index e2739bba9..fd4f0dc31 100644 --- a/lib/rules/prop-name-casing.js +++ b/lib/rules/prop-name-casing.js @@ -6,6 +6,7 @@ const utils = require('../utils') const casing = require('../utils/casing') +const { toRegExp } = require('../utils/regexp') const allowedCaseOptions = ['camelCase', 'snake_case'] /** @@ -15,7 +16,8 @@ const allowedCaseOptions = ['camelCase', 'snake_case'] /** @param {RuleContext} context */ function create(context) { const options = context.options[0] - const ignores = context.options[1]?.ignores || [] + /** @type {RegExp[]} */ + const ignoreProps = (context.options[1]?.ignoreProps || []).map(toRegExp) const caseType = allowedCaseOptions.includes(options) ? options : 'camelCase' const checker = casing.getChecker(caseType) @@ -28,7 +30,7 @@ function create(context) { if (propName == null) { continue } - if (!checker(propName) || ignores.includes(propName)) { + if (!checker(propName) && !ignoreProps.some((re) => re.test(propName))) { context.report({ node: item.node, messageId: 'invalidCase', @@ -69,7 +71,7 @@ module.exports = { { type: 'object', properties: { - ignores: { + ignoreProps: { type: 'array', items: { type: 'string' }, uniqueItems: true diff --git a/tests/lib/rules/prop-name-casing.js b/tests/lib/rules/prop-name-casing.js index 65748dc49..a83893a5a 100644 --- a/tests/lib/rules/prop-name-casing.js +++ b/tests/lib/rules/prop-name-casing.js @@ -149,7 +149,7 @@ ruleTester.run('prop-name-casing', rule, { languageOptions }, { - // valiable computed property name does not warn + // variable computed property name does not warn filename: 'test.vue', code: ` export default { @@ -161,7 +161,7 @@ ruleTester.run('prop-name-casing', rule, { languageOptions }, { - // valiable computed property name does not warn + // variable computed property name does not warn filename: 'test.vue', code: ` export default { @@ -359,6 +359,23 @@ ruleTester.run('prop-name-casing', rule, { parser: require.resolve('@typescript-eslint/parser') } } + }, + { + filename: 'test.vue', + code: ` + export default { + props: { + 'ignored-pattern-test': String, + ignored_prop: Number, + validProp: Boolean + } + } + `, + options: [ + 'camelCase', + { ignoreProps: ['ignored_prop', '/^ignored-pattern-/'] } + ], + languageOptions } ], @@ -686,6 +703,54 @@ ruleTester.run('prop-name-casing', rule, { } ] } - ]) + ]), + { + filename: 'test.vue', + code: ` + export default { + props: { + notIgnored_prop: String, + 'other-pattern': Number, + 'pattern-valid': String + } + } + `, + options: ['camelCase', { ignoreProps: ['ignored_prop', '/^pattern-/'] }], + languageOptions, + errors: [ + { + message: 'Prop "notIgnored_prop" is not in camelCase.', + type: 'Property', + line: 4 + }, + { + message: 'Prop "other-pattern" is not in camelCase.', + type: 'Property', + line: 5 + } + ] + }, + { + filename: 'test.vue', + code: ` + export default { + props: ['notIgnored_prop', 'pattern_invalid', 'validProp', 'pattern-valid'] + } + `, + options: ['camelCase', { ignoreProps: ['ignored_prop', '/^pattern-/'] }], + languageOptions, + errors: [ + { + message: 'Prop "notIgnored_prop" is not in camelCase.', + type: 'Literal', + line: 3 + }, + { + message: 'Prop "pattern_invalid" is not in camelCase.', + type: 'Literal', + line: 3 + } + ] + } ] }) From e56e4cdfaace76b7d4ccea9aa4a80fb38126071d Mon Sep 17 00:00:00 2001 From: Patrick Herzberg Date: Thu, 20 Feb 2025 09:01:33 +0100 Subject: [PATCH 4/5] update argument description Co-authored-by: Wayne Zhang --- docs/rules/prop-name-casing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/prop-name-casing.md b/docs/rules/prop-name-casing.md index 07ad1ed8b..4b19bcae1 100644 --- a/docs/rules/prop-name-casing.md +++ b/docs/rules/prop-name-casing.md @@ -50,7 +50,7 @@ export default { - `"camelCase"` (default) ... Enforce property names in `props` to camel case. - `"snake_case"` ... Enforce property names in `props` to snake case. -- `ignoreProps` (`string[]`) ... An array of prop names (or patterns) that should be exempt from the case rule check. Use this option for prop names that are intentionally non-compliant, have special naming requirements for Vue components, or are defined by Vue libraries. You can define these entries as literal strings or as regular expressions (written as strings, e.g., `"/^name/"`). +- `ignoreProps` (`string[]`) ... An array of prop names (or patterns) that don't need to follow the specified casing. ### `"snake_case"` From 8915bb977c63110f66107e596f95092e99137f2d Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Thu, 20 Feb 2025 09:33:50 +0100 Subject: [PATCH 5/5] Fix docs syntax --- docs/rules/prop-name-casing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/prop-name-casing.md b/docs/rules/prop-name-casing.md index 4b19bcae1..43598c783 100644 --- a/docs/rules/prop-name-casing.md +++ b/docs/rules/prop-name-casing.md @@ -84,7 +84,7 @@ export default { props: { /* ✓ GOOD */ greetingText: String, - foo-bar: String, + 'foo-bar': String, _uid: String, /* ✗ BAD */