From 37e971afae701ff92aea865bca6ec7013dc9d63f Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Thu, 1 Aug 2024 10:28:26 +0200 Subject: [PATCH 001/126] Update development dependencies and formatting (#2518) --- lib/rules/require-prop-types.js | 2 +- package.json | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/rules/require-prop-types.js b/lib/rules/require-prop-types.js index 4102ad039..af2a956a4 100644 --- a/lib/rules/require-prop-types.js +++ b/lib/rules/require-prop-types.js @@ -75,7 +75,7 @@ module.exports = { return } const hasType = - prop.type === 'array' ? false : optionHasType(prop.value) ?? true + prop.type === 'array' ? false : (optionHasType(prop.value) ?? true) if (!hasType) { const { node, propName } = prop diff --git a/package.json b/package.json index 4816e225f..153ebe94f 100644 --- a/package.json +++ b/package.json @@ -60,41 +60,41 @@ "natural-compare": "^1.4.0", "nth-check": "^2.1.1", "postcss-selector-parser": "^6.0.15", - "semver": "^7.6.0", + "semver": "^7.6.3", "vue-eslint-parser": "^9.4.3", "xml-name-validator": "^4.0.0" }, "devDependencies": { - "@ota-meshi/site-kit-eslint-editor-vue": "^0.2.0", - "@stylistic/eslint-plugin": "^2.2.2", + "@ota-meshi/site-kit-eslint-editor-vue": "^0.2.4", + "@stylistic/eslint-plugin": "^2.6.0", "@types/eslint": "^8.56.2", "@types/eslint-visitor-keys": "^3.3.0", "@types/natural-compare": "^1.4.3", "@types/node": "^14.18.63", - "@types/semver": "^7.5.7", + "@types/semver": "^7.5.8", "@types/xml-name-validator": "^4.0.3", - "@typescript-eslint/parser": "^7.13.1", - "@typescript-eslint/types": "^7.13.1", + "@typescript-eslint/parser": "^7.18.0", + "@typescript-eslint/types": "^7.18.0", "assert": "^2.1.0", "env-cmd": "^10.1.0", - "esbuild": "^0.21.5", - "eslint": "^8.56.0", + "esbuild": "^0.23.0", + "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-eslint-plugin": "~6.1.0", + "eslint-plugin-eslint-plugin": "~6.2.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-jsonc": "^2.16.0", "eslint-plugin-node-dependencies": "^0.12.0", - "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-unicorn": "^54.0.0", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-unicorn": "^55.0.0", "eslint-plugin-vue": "file:.", "espree": "^9.6.1", "events": "^3.3.0", "markdownlint-cli": "^0.41.0", - "mocha": "^10.3.0", + "mocha": "^10.7.0", "nyc": "^17.0.0", "pathe": "^1.1.2", - "prettier": "^3.2.5", - "typescript": "^5.3.3", - "vitepress": "^1.0.0-rc.42" + "prettier": "^3.3.3", + "typescript": "^5.5.4", + "vitepress": "^1.3.1" } } From 66e3201e17eee2bb45d2e0e98018e7de5481cb0c Mon Sep 17 00:00:00 2001 From: Kiina Date: Thu, 1 Aug 2024 10:31:07 +0200 Subject: [PATCH 002/126] Fix options in docs for no-template-shadow (#2517) --- docs/rules/no-template-shadow.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/no-template-shadow.md b/docs/rules/no-template-shadow.md index 29eacacc0..9d74e1f12 100644 --- a/docs/rules/no-template-shadow.md +++ b/docs/rules/no-template-shadow.md @@ -55,7 +55,7 @@ This rule takes one optional object option, with the property `"allow"`. ```json { - "no-template-shadow": ["error", { "allow": [] }] + "vue/no-template-shadow": ["error", { "allow": [] }] } ``` From 705d262bcaf15499a3d94943e43e9df5e8cd0614 Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Wed, 14 Aug 2024 17:17:21 +0200 Subject: [PATCH 003/126] Fix code example in `vue/define-props-declaration` docs (#2527) --- docs/rules/define-props-declaration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/define-props-declaration.md b/docs/rules/define-props-declaration.md index 5c72d538a..40c5ea0b0 100644 --- a/docs/rules/define-props-declaration.md +++ b/docs/rules/define-props-declaration.md @@ -47,7 +47,7 @@ const props = defineProps({ ### `"runtime"` - + ```vue +``` + + + + + +```vue + + +``` + + + ### `{ "defineExposeLast": true }` diff --git a/docs/rules/index.md b/docs/rules/index.md index 113ff416b..16a195125 100644 --- a/docs/rules/index.md +++ b/docs/rules/index.md @@ -213,7 +213,7 @@ For example: | [vue/component-options-name-casing](./component-options-name-casing.md) | enforce the casing of component name in `components` options | :wrench::bulb: | :hammer: | | [vue/custom-event-name-casing](./custom-event-name-casing.md) | enforce specific casing for custom event name | | :hammer: | | [vue/define-emits-declaration](./define-emits-declaration.md) | enforce declaration style of `defineEmits` | | :hammer: | -| [vue/define-macros-order](./define-macros-order.md) | enforce order of `defineEmits` and `defineProps` compiler macros | :wrench::bulb: | :lipstick: | +| [vue/define-macros-order](./define-macros-order.md) | enforce order of compiler macros (`defineProps`, `defineEmits`, etc.) | :wrench::bulb: | :lipstick: | | [vue/define-props-declaration](./define-props-declaration.md) | enforce declaration style of `defineProps` | | :hammer: | | [vue/enforce-style-attribute](./enforce-style-attribute.md) | enforce or forbid the use of the `scoped` and `module` attributes in SFC top level style tags | | :hammer: | | [vue/html-button-has-type](./html-button-has-type.md) | disallow usage of button without an explicit type attribute | | :hammer: | diff --git a/lib/rules/define-macros-order.js b/lib/rules/define-macros-order.js index f24c58af7..920b5c294 100644 --- a/lib/rules/define-macros-order.js +++ b/lib/rules/define-macros-order.js @@ -11,13 +11,15 @@ const MACROS_PROPS = 'defineProps' const MACROS_OPTIONS = 'defineOptions' const MACROS_SLOTS = 'defineSlots' const MACROS_MODEL = 'defineModel' -const ORDER_SCHEMA = [ +const MACROS_EXPOSE = 'defineExpose' +const KNOWN_MACROS = new Set([ MACROS_EMITS, MACROS_PROPS, MACROS_OPTIONS, MACROS_SLOTS, - MACROS_MODEL -] + MACROS_MODEL, + MACROS_EXPOSE +]) const DEFAULT_ORDER = [MACROS_PROPS, MACROS_EMITS] /** @@ -109,6 +111,12 @@ function create(context) { /** @type {ASTNode} */ let defineExposeNode + if (order.includes(MACROS_EXPOSE) && defineExposeLast) { + throw new Error( + "`defineExpose` macro can't be in the `order` array if `defineExposeLast` is true." + ) + } + return utils.compositingVisitors( utils.defineScriptSetupVisitor(context, { onDefinePropsExit(node) { @@ -130,6 +138,20 @@ function create(context) { }, onDefineExposeExit(node) { defineExposeNode = getDefineMacrosStatement(node) + }, + + /** @param {CallExpression} node */ + 'Program > ExpressionStatement > CallExpression, Program > VariableDeclaration > VariableDeclarator > CallExpression'( + node + ) { + if ( + node.callee && + node.callee.type === 'Identifier' && + order.includes(node.callee.name) && + !KNOWN_MACROS.has(node.callee.name) + ) { + macrosNodes.set(node.callee.name, [getDefineMacrosStatement(node)]) + } } }), { @@ -333,7 +355,7 @@ module.exports = { type: 'layout', docs: { description: - 'enforce order of `defineEmits` and `defineProps` compiler macros', + 'enforce order of compiler macros (`defineProps`, `defineEmits`, etc.)', categories: undefined, url: 'https://eslint.vuejs.org/rules/define-macros-order.html' }, @@ -346,7 +368,8 @@ module.exports = { order: { type: 'array', items: { - enum: ORDER_SCHEMA + type: 'string', + minLength: 1 }, uniqueItems: true, additionalItems: false diff --git a/tests/lib/rules/define-macros-order.js b/tests/lib/rules/define-macros-order.js index 3aa2e434d..72b359866 100644 --- a/tests/lib/rules/define-macros-order.js +++ b/tests/lib/rules/define-macros-order.js @@ -195,6 +195,65 @@ tester.run('define-macros-order', rule, { } ] }, + { + filename: 'test.vue', + code: ` + + `, + options: [ + { + order: ['definePage', 'defineModel', 'defineEmits'] + } + ] + }, + { + filename: 'test.vue', + code: ` + + `, + options: [ + { + order: ['definePage', 'defineModel', 'defineEmits'] + } + ] + }, + { + filename: 'test.vue', + code: ` + + `, + options: [ + { + order: ['definePage', 'defineModel', 'defineEmits'] + } + ] + }, { filename: 'test.vue', code: ` @@ -254,6 +313,22 @@ tester.run('define-macros-order', rule, { order: ['defineModel', 'defineSlots'] } ] + }, + { + filename: 'test.vue', + code: ` + + `, + options: [ + { + order: ['definePage', 'defineModel'] + } + ] } ], invalid: [ @@ -382,6 +457,40 @@ tester.run('define-macros-order', rule, { } ] }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + options: [{ order: ['definePage', 'defineProps'] }], + errors: [ + { + message: message('definePage'), + line: 8 + } + ] + }, { filename: 'test.vue', code: ` @@ -425,6 +534,61 @@ tester.run('define-macros-order', rule, { } ] }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + options: [ + { order: ['definePage', 'defineCustom', 'defineProps', 'defineEmits'] } + ], + languageOptions: { + parserOptions: { + parser: require.resolve('@typescript-eslint/parser') + } + }, + errors: [ + { + message: message('definePage'), + line: 15 + } + ] + }, { filename: 'test.vue', code: ` @@ -537,6 +701,25 @@ tester.run('define-macros-order', rule, { } ] }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + options: [{ order: ['definePage', 'defineProps'] }], + errors: [ + { + message: message('definePage'), + line: 3 + } + ] + }, { filename: 'test.vue', code: ` @@ -633,6 +816,54 @@ tester.run('define-macros-order', rule, { } ] }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + options: [{ order: ['defineCustom', 'definePage'] }], + errors: [ + { + message: message('defineCustom'), + line: 5 + } + ] + }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + options: [{ order: ['defineCustom', 'definePage'] }], + errors: [ + { + message: message('defineCustom'), + line: 5 + } + ] + }, { filename: 'test.vue', code: ` @@ -895,6 +1126,44 @@ tester.run('define-macros-order', rule, { } ] }, + { + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + options: [ + { + order: [ + 'defineSomething', + 'defineCustom', + 'defineModel', + 'defineOptions', + 'definePage' + ] + } + ], + errors: [ + { + message: message('defineSomething'), + line: 5 + } + ] + }, { filename: 'test.vue', code: ` From a4aed0afb0a02e9acb56ae2210dcfc849b4b8a33 Mon Sep 17 00:00:00 2001 From: Kevin Sommer <37016102+kevsommer@users.noreply.github.com> Date: Mon, 2 Sep 2024 11:47:21 +0200 Subject: [PATCH 006/126] Implements proposed max-template-depth rule (#2525) --- docs/rules/index.md | 1 + docs/rules/max-template-depth.md | 67 ++++++++++ lib/index.js | 1 + lib/rules/max-template-depth.js | 82 +++++++++++++ tests/lib/rules/max-template-depth.js | 168 ++++++++++++++++++++++++++ 5 files changed, 319 insertions(+) create mode 100644 docs/rules/max-template-depth.md create mode 100644 lib/rules/max-template-depth.js create mode 100644 tests/lib/rules/max-template-depth.js diff --git a/docs/rules/index.md b/docs/rules/index.md index 16a195125..9624111c6 100644 --- a/docs/rules/index.md +++ b/docs/rules/index.md @@ -224,6 +224,7 @@ For example: | [vue/match-component-import-name](./match-component-import-name.md) | require the registered component name to match the imported component name | | :warning: | | [vue/max-lines-per-block](./max-lines-per-block.md) | enforce maximum number of lines in Vue SFC blocks | | :warning: | | [vue/max-props](./max-props.md) | enforce maximum number of props in Vue component | | :warning: | +| [vue/max-template-depth](./max-template-depth.md) | enforce maximum depth of template | | :warning: | | [vue/new-line-between-multi-line-property](./new-line-between-multi-line-property.md) | enforce new lines between multi-line properties in Vue components | :wrench: | :lipstick: | | [vue/next-tick-style](./next-tick-style.md) | enforce Promise or callback style in `nextTick` | :wrench: | :hammer: | | [vue/no-bare-strings-in-template](./no-bare-strings-in-template.md) | disallow the use of bare strings in `