@adyen/eslint-plugin-bento 2.8.0 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/configs/vue-recommended.js +8 -0
- package/configs/vue-strict.js +8 -0
- package/index.js +8 -0
- package/package.json +1 -1
- package/rules/deprecation-bento-dropdown-size-prop/README.md +25 -0
- package/rules/deprecation-bento-dropdown-size-prop/__tests__/deprecation-bento-dropdown-size-prop.vue +9 -0
- package/rules/deprecation-bento-dropdown-size-prop/__tests__/eslint.config.js +26 -0
- package/rules/deprecation-bento-dropdown-size-prop/deprecation-bento-dropdown-size-prop.integration.test.ts +33 -0
- package/rules/deprecation-bento-dropdown-size-prop/deprecation-bento-dropdown-size-prop.js +78 -0
- package/rules/deprecation-bento-dropdown-size-prop/deprecation-bento-dropdown-size-prop.test.ts +101 -0
- package/rules/deprecation-bento-popover-modifiers-prop/README.md +23 -0
- package/rules/deprecation-bento-popover-modifiers-prop/__tests__/deprecation-bento-popover-modifiers-prop.vue +9 -0
- package/rules/deprecation-bento-popover-modifiers-prop/__tests__/eslint.config.js +26 -0
- package/rules/deprecation-bento-popover-modifiers-prop/deprecation-bento-popover-modifiers-prop.integration.test.ts +24 -0
- package/rules/deprecation-bento-popover-modifiers-prop/deprecation-bento-popover-modifiers-prop.js +78 -0
- package/rules/deprecation-bento-popover-modifiers-prop/deprecation-bento-popover-modifiers-prop.test.ts +109 -0
- package/rules/deprecation-bento-timeline-item-variant-prop/README.md +25 -0
- package/rules/deprecation-bento-timeline-item-variant-prop/__tests__/deprecation-bento-timeline-item-variant-prop.vue +9 -0
- package/rules/deprecation-bento-timeline-item-variant-prop/__tests__/eslint.config.js +26 -0
- package/rules/deprecation-bento-timeline-item-variant-prop/deprecation-bento-timeline-item-variant-prop.integration.test.ts +31 -0
- package/rules/deprecation-bento-timeline-item-variant-prop/deprecation-bento-timeline-item-variant-prop.js +78 -0
- package/rules/deprecation-bento-timeline-item-variant-prop/deprecation-bento-timeline-item-variant-prop.test.ts +66 -0
- package/rules/deprecation-components-aria-label-prop/README.md +62 -0
- package/rules/deprecation-components-aria-label-prop/__tests__/deprecation-components-aria-label-prop.vue +25 -0
- package/rules/deprecation-components-aria-label-prop/__tests__/eslint.config.js +26 -0
- package/rules/deprecation-components-aria-label-prop/deprecation-components-aria-label-prop.integration.test.ts +36 -0
- package/rules/deprecation-components-aria-label-prop/deprecation-components-aria-label-prop.js +79 -0
- package/rules/deprecation-components-aria-label-prop/deprecation-components-aria-label-prop.test.ts +194 -0
- package/rules/deprecation-components-error-prop/README.md +43 -0
- package/rules/deprecation-components-error-prop/__tests__/deprecation-components-error-prop.vue +17 -0
- package/rules/deprecation-components-error-prop/__tests__/eslint.config.js +26 -0
- package/rules/deprecation-components-error-prop/deprecation-components-error-prop.integration.test.ts +37 -0
- package/rules/deprecation-components-error-prop/deprecation-components-error-prop.js +79 -0
- package/rules/deprecation-components-error-prop/deprecation-components-error-prop.test.ts +120 -0
- package/rules/deprecation-components-has-error-prop/README.md +34 -0
- package/rules/deprecation-components-has-error-prop/__tests__/deprecation-components-has-error-prop.vue +13 -0
- package/rules/deprecation-components-has-error-prop/__tests__/eslint.config.js +26 -0
- package/rules/deprecation-components-has-error-prop/deprecation-components-has-error-prop.integration.test.ts +29 -0
- package/rules/deprecation-components-has-error-prop/deprecation-components-has-error-prop.js +77 -0
- package/rules/deprecation-components-has-error-prop/deprecation-components-has-error-prop.test.ts +133 -0
- package/rules/deprecation-components-input-emit/__tests__/eslint.config.js +1 -1
- package/rules/deprecation-components-input-emit/deprecation-components-input-emit.js +19 -4
- package/rules/deprecation-components-input-emit/deprecation-components-input-emit.test.ts +40 -0
- package/rules/deprecation-components-value-prop/__tests__/eslint.config.js +1 -1
- package/rules/deprecation-components-value-prop/deprecation-components-value-prop.js +24 -7
- package/rules/deprecation-components-value-prop/deprecation-components-value-prop.test.ts +56 -0
- package/rules/deprecation-filter-bar-deprecated-props/README.md +64 -0
- package/rules/deprecation-filter-bar-deprecated-props/__tests__/deprecation-filter-bar-deprecated-props.vue +48 -0
- package/rules/deprecation-filter-bar-deprecated-props/__tests__/eslint.config.js +25 -0
- package/rules/deprecation-filter-bar-deprecated-props/deprecation-filter-bar-deprecated-props.integration.test.ts +22 -0
- package/rules/deprecation-filter-bar-deprecated-props/deprecation-filter-bar-deprecated-props.js +187 -0
- package/rules/deprecation-filter-bar-deprecated-props/deprecation-filter-bar-deprecated-props.test.ts +421 -0
- package/rules/deprecation-input-filter-dropdown-options/README.md +44 -0
- package/rules/deprecation-input-filter-dropdown-options/__tests__/deprecation-input-filter-dropdown-options.vue +46 -0
- package/rules/deprecation-input-filter-dropdown-options/__tests__/eslint.config.js +26 -0
- package/rules/deprecation-input-filter-dropdown-options/deprecation-input-filter-dropdown-options.integration.test.ts +27 -0
- package/rules/deprecation-input-filter-dropdown-options/deprecation-input-filter-dropdown-options.js +135 -0
- package/rules/deprecation-input-filter-dropdown-options/deprecation-input-filter-dropdown-options.test.ts +392 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# deprecation-components-error-prop
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
The `error` prop in the following components is deprecated:
|
|
6
|
+
|
|
7
|
+
- `bento-dropdown`
|
|
8
|
+
- `bento-input-field`
|
|
9
|
+
- `bento-input-field-phone-number`
|
|
10
|
+
|
|
11
|
+
Please use `error-message` instead.
|
|
12
|
+
|
|
13
|
+
## Rule Details
|
|
14
|
+
|
|
15
|
+
This rule reports usages of the deprecated item.
|
|
16
|
+
|
|
17
|
+
### ❌ Incorrect
|
|
18
|
+
|
|
19
|
+
```html
|
|
20
|
+
<bento-dropdown error="value" /> <bento-dropdown :error="value" />
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<bento-input-field error="value" /> <bento-input-field :error="value" />
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<bento-input-field-phone-number error="value" /> <bento-input-field-phone-number :error="value" />
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### ✅ Correct
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<bento-dropdown error-message="value" />
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
```html
|
|
38
|
+
<bento-input-field error-message="value" />
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```html
|
|
42
|
+
<bento-input-field-phone-number error-message="value" />
|
|
43
|
+
```
|
package/rules/deprecation-components-error-prop/__tests__/deprecation-components-error-prop.vue
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<bento-dropdown error="value" />
|
|
4
|
+
<bento-dropdown :error="value" />
|
|
5
|
+
<bento-dropdown :error="value" />
|
|
6
|
+
|
|
7
|
+
<bento-input-field error="value" />
|
|
8
|
+
<bento-input-field :error="value" />
|
|
9
|
+
<bento-input-field :error="value" />
|
|
10
|
+
|
|
11
|
+
<bento-input-field-phone-number error="value" />
|
|
12
|
+
<bento-input-field-phone-number :error="value" />
|
|
13
|
+
<bento-input-field-phone-number :error="value" />
|
|
14
|
+
</div>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<script setup></script>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// eslint.config.js
|
|
2
|
+
const { defineConfig } = require('eslint/config');
|
|
3
|
+
const vueParser = require('vue-eslint-parser');
|
|
4
|
+
const tsParser = require('@typescript-eslint/parser');
|
|
5
|
+
const adyenBento = require('@adyen/eslint-plugin-bento');
|
|
6
|
+
|
|
7
|
+
module.exports = defineConfig([
|
|
8
|
+
{
|
|
9
|
+
languageOptions: {
|
|
10
|
+
ecmaVersion: 'latest',
|
|
11
|
+
sourceType: 'module',
|
|
12
|
+
parser: vueParser,
|
|
13
|
+
parserOptions: {
|
|
14
|
+
parser: tsParser,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
plugins: {
|
|
18
|
+
'@adyen/bento': adyenBento,
|
|
19
|
+
},
|
|
20
|
+
rules: {
|
|
21
|
+
// Register the specific rule we are testing
|
|
22
|
+
'@adyen/bento/deprecation-components-error-prop': ['warn', { autofix: true }],
|
|
23
|
+
},
|
|
24
|
+
files: ['**/*.vue'],
|
|
25
|
+
},
|
|
26
|
+
]);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { execFileSyncEslintVueFiles } from '../../utils/exec-file-sync-eslint-vue-files';
|
|
3
|
+
|
|
4
|
+
describe('@adyen/bento/deprecation-components-error-prop', () => {
|
|
5
|
+
it('should lint with warning', () => {
|
|
6
|
+
// Load .eslintrc
|
|
7
|
+
const eslintrc = path.resolve(__dirname, '__tests__', 'eslint.config.js');
|
|
8
|
+
// Load the test file generated alongside this one
|
|
9
|
+
const vueFile = path.resolve(__dirname, '__tests__', 'deprecation-components-error-prop.vue');
|
|
10
|
+
|
|
11
|
+
// Execute the linter
|
|
12
|
+
const result = JSON.parse(execFileSyncEslintVueFiles(eslintrc, vueFile));
|
|
13
|
+
|
|
14
|
+
/* ------------------------------------------------ */
|
|
15
|
+
/* CASE 2: SINGLE REPLACEMENT */
|
|
16
|
+
/* ------------------------------------------------ */
|
|
17
|
+
|
|
18
|
+
// For props, we generate 3 examples (static, shorthand, longhand) FOR EACH component.
|
|
19
|
+
// Total = (Number of Components) * 3
|
|
20
|
+
const numberOfComponents = 3;
|
|
21
|
+
expect(result[0].warningCount).toBe(numberOfComponents * 3);
|
|
22
|
+
|
|
23
|
+
// Verify the message structure on the first error found.
|
|
24
|
+
// Since the rule is the same for all components, checking the first one confirms the message is correct.
|
|
25
|
+
expect(result[0].messages[0]).toMatchObject({
|
|
26
|
+
ruleId: '@adyen/bento/deprecation-components-error-prop',
|
|
27
|
+
severity: 1,
|
|
28
|
+
|
|
29
|
+
messageId: 'deprecation',
|
|
30
|
+
message: `The "error" prop is deprecated. Please use "error-message" instead.`,
|
|
31
|
+
|
|
32
|
+
fix: expect.objectContaining({
|
|
33
|
+
text: expect.stringContaining('error-message'),
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('eslint').Rule.RuleContext} RuleContext
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import('eslint-plugin-vue/lib/utils').RuleModule} RuleModule
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const VueUtils = require('eslint-plugin-vue/lib/utils');
|
|
9
|
+
|
|
10
|
+
/** @type {RuleModule} */
|
|
11
|
+
module.exports = {
|
|
12
|
+
meta: {
|
|
13
|
+
type: 'suggestion',
|
|
14
|
+
docs: {
|
|
15
|
+
description:
|
|
16
|
+
'Deprecates usage of error prop in bento-dropdown, bento-input-field, bento-input-field-phone-number',
|
|
17
|
+
category: 'Deprecations',
|
|
18
|
+
url: 'https://github.com/Adyen/bento/blob/main/packages/eslint/rules/deprecation-components-error-prop/README.md',
|
|
19
|
+
recommended: true,
|
|
20
|
+
},
|
|
21
|
+
messages: {
|
|
22
|
+
deprecation: `The "error" prop is deprecated. Please use "error-message" instead.`,
|
|
23
|
+
},
|
|
24
|
+
fixable: 'code',
|
|
25
|
+
schema: [
|
|
26
|
+
{
|
|
27
|
+
type: 'object',
|
|
28
|
+
properties: {
|
|
29
|
+
autofix: {
|
|
30
|
+
type: 'boolean',
|
|
31
|
+
default: false,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
additionalProperties: false,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
/** @param {RuleContext} context */
|
|
40
|
+
create(context) {
|
|
41
|
+
const options = context.options[0] || {};
|
|
42
|
+
const autofix = options.autofix === true;
|
|
43
|
+
|
|
44
|
+
/* ------------------------------------------------ */
|
|
45
|
+
/* CASE 2: PROP DEPRECATION (Multiple Components) */
|
|
46
|
+
/* ------------------------------------------------ */
|
|
47
|
+
return VueUtils.defineTemplateBodyVisitor(context, {
|
|
48
|
+
// 1. STATIC: value="foo"
|
|
49
|
+
[`VElement:matches([name="bento-dropdown"], [name="BentoDropdown"], [name="bento-input-field"], [name="BentoInputField"], [name="bento-input-field-phone-number"], [name="BentoInputFieldPhoneNumber"]) > VStartTag > VAttribute[directive=false][key.name="error"]`](
|
|
50
|
+
node
|
|
51
|
+
) {
|
|
52
|
+
context.report({
|
|
53
|
+
node,
|
|
54
|
+
messageId: 'deprecation',
|
|
55
|
+
...(autofix && {
|
|
56
|
+
fix(fixer) {
|
|
57
|
+
return fixer.replaceText(node.key, 'error-message');
|
|
58
|
+
},
|
|
59
|
+
}),
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
// 2. DYNAMIC: :value="foo" or v-bind:value="foo"
|
|
64
|
+
[`VElement:matches([name="bento-dropdown"], [name="BentoDropdown"], [name="bento-input-field"], [name="BentoInputField"], [name="bento-input-field-phone-number"], [name="BentoInputFieldPhoneNumber"]) > VStartTag > VAttribute[directive=true][key.name.name="bind"][key.argument.name="error"]`](
|
|
65
|
+
node
|
|
66
|
+
) {
|
|
67
|
+
context.report({
|
|
68
|
+
node,
|
|
69
|
+
messageId: 'deprecation',
|
|
70
|
+
...(autofix && {
|
|
71
|
+
fix(fixer) {
|
|
72
|
+
return fixer.replaceText(node.key.argument, 'error-message');
|
|
73
|
+
},
|
|
74
|
+
}),
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
},
|
|
79
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { RuleTester } from 'eslint';
|
|
2
|
+
import vueParser from 'vue-eslint-parser';
|
|
3
|
+
import tsParser from '@typescript-eslint/parser';
|
|
4
|
+
import deprecationComponentsErrorProp from './deprecation-components-error-prop';
|
|
5
|
+
|
|
6
|
+
const ruleTester = new RuleTester({
|
|
7
|
+
languageOptions: {
|
|
8
|
+
ecmaVersion: 'latest',
|
|
9
|
+
sourceType: 'module',
|
|
10
|
+
parser: vueParser,
|
|
11
|
+
parserOptions: {
|
|
12
|
+
parser: tsParser,
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe('@adyen/bento/deprecation-components-error-prop', () => {
|
|
18
|
+
ruleTester.run('deprecation-components-error-prop', deprecationComponentsErrorProp, {
|
|
19
|
+
valid: [
|
|
20
|
+
{
|
|
21
|
+
name: 'Valid usage for bento-dropdown',
|
|
22
|
+
filename: 'test.vue',
|
|
23
|
+
code: `
|
|
24
|
+
<template>
|
|
25
|
+
<bento-dropdown error-message="val" />
|
|
26
|
+
</template>
|
|
27
|
+
`,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'Valid usage for bento-input-field',
|
|
31
|
+
filename: 'test.vue',
|
|
32
|
+
code: `
|
|
33
|
+
<template>
|
|
34
|
+
<bento-input-field error-message="val" />
|
|
35
|
+
</template>
|
|
36
|
+
`,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'Valid usage for bento-input-field-phone-number',
|
|
40
|
+
filename: 'test.vue',
|
|
41
|
+
code: `
|
|
42
|
+
<template>
|
|
43
|
+
<bento-input-field-phone-number error-message="val" />
|
|
44
|
+
</template>
|
|
45
|
+
`,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
invalid: [
|
|
49
|
+
{
|
|
50
|
+
name: 'Invalid: autofix disabled (explicit false)',
|
|
51
|
+
filename: 'test.vue',
|
|
52
|
+
code: `<template><bento-dropdown error="val" /></template>`,
|
|
53
|
+
output: null,
|
|
54
|
+
options: [{ autofix: false }],
|
|
55
|
+
errors: [{ messageId: 'deprecation' }],
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: 'Invalid: autofix disabled (no options)',
|
|
59
|
+
filename: 'test.vue',
|
|
60
|
+
code: `<template><bento-dropdown :error="val" /></template>`,
|
|
61
|
+
output: null,
|
|
62
|
+
errors: [{ messageId: 'deprecation' }],
|
|
63
|
+
},
|
|
64
|
+
// bento-dropdown: Static
|
|
65
|
+
{
|
|
66
|
+
name: 'Invalid: Static prop on bento-dropdown',
|
|
67
|
+
filename: 'test.vue',
|
|
68
|
+
code: `<template><bento-dropdown error="val" /></template>`,
|
|
69
|
+
output: `<template><bento-dropdown error-message="val" /></template>`,
|
|
70
|
+
options: [{ autofix: true }],
|
|
71
|
+
errors: [{ messageId: 'deprecation' }],
|
|
72
|
+
},
|
|
73
|
+
// bento-dropdown: Shorthand
|
|
74
|
+
{
|
|
75
|
+
name: 'Invalid: Dynamic prop on bento-dropdown',
|
|
76
|
+
filename: 'test.vue',
|
|
77
|
+
code: `<template><bento-dropdown :error="val" /></template>`,
|
|
78
|
+
output: `<template><bento-dropdown :error-message="val" /></template>`,
|
|
79
|
+
options: [{ autofix: true }],
|
|
80
|
+
errors: [{ messageId: 'deprecation' }],
|
|
81
|
+
},
|
|
82
|
+
// bento-input-field: Static
|
|
83
|
+
{
|
|
84
|
+
name: 'Invalid: Static prop on bento-input-field',
|
|
85
|
+
filename: 'test.vue',
|
|
86
|
+
code: `<template><bento-input-field error="val" /></template>`,
|
|
87
|
+
output: `<template><bento-input-field error-message="val" /></template>`,
|
|
88
|
+
options: [{ autofix: true }],
|
|
89
|
+
errors: [{ messageId: 'deprecation' }],
|
|
90
|
+
},
|
|
91
|
+
// bento-input-field: Shorthand
|
|
92
|
+
{
|
|
93
|
+
name: 'Invalid: Dynamic prop on bento-input-field',
|
|
94
|
+
filename: 'test.vue',
|
|
95
|
+
code: `<template><bento-input-field :error="val" /></template>`,
|
|
96
|
+
output: `<template><bento-input-field :error-message="val" /></template>`,
|
|
97
|
+
options: [{ autofix: true }],
|
|
98
|
+
errors: [{ messageId: 'deprecation' }],
|
|
99
|
+
},
|
|
100
|
+
// bento-input-field-phone-number: Static
|
|
101
|
+
{
|
|
102
|
+
name: 'Invalid: Static prop on bento-input-field-phone-number',
|
|
103
|
+
filename: 'test.vue',
|
|
104
|
+
code: `<template><bento-input-field-phone-number error="val" /></template>`,
|
|
105
|
+
output: `<template><bento-input-field-phone-number error-message="val" /></template>`,
|
|
106
|
+
options: [{ autofix: true }],
|
|
107
|
+
errors: [{ messageId: 'deprecation' }],
|
|
108
|
+
},
|
|
109
|
+
// bento-input-field-phone-number: Shorthand
|
|
110
|
+
{
|
|
111
|
+
name: 'Invalid: Dynamic prop on bento-input-field-phone-number',
|
|
112
|
+
filename: 'test.vue',
|
|
113
|
+
code: `<template><bento-input-field-phone-number :error="val" /></template>`,
|
|
114
|
+
output: `<template><bento-input-field-phone-number :error-message="val" /></template>`,
|
|
115
|
+
options: [{ autofix: true }],
|
|
116
|
+
errors: [{ messageId: 'deprecation' }],
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
});
|
|
120
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# deprecation-components-has-error-prop
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
The `hasError` prop in the following components is deprecated:
|
|
6
|
+
|
|
7
|
+
- `bento-checkbox-group`
|
|
8
|
+
- `bento-radio-group`
|
|
9
|
+
|
|
10
|
+
Please use `errorMessage` instead.
|
|
11
|
+
|
|
12
|
+
## Rule Details
|
|
13
|
+
|
|
14
|
+
This rule reports usages of the deprecated item.
|
|
15
|
+
|
|
16
|
+
### ❌ Incorrect
|
|
17
|
+
|
|
18
|
+
```html
|
|
19
|
+
<bento-checkbox-group has-error="value" /> <bento-checkbox-group :has-error="value" />
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```html
|
|
23
|
+
<bento-radio-group has-error="value" /> <bento-radio-group :has-error="value" />
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### ✅ Correct
|
|
27
|
+
|
|
28
|
+
```html
|
|
29
|
+
<bento-checkbox-group errorMessage="value" />
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<bento-radio-group errorMessage="value" />
|
|
34
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<bento-checkbox-group has-error="value" />
|
|
4
|
+
<bento-checkbox-group :has-error="value" />
|
|
5
|
+
<bento-checkbox-group :has-error="value" />
|
|
6
|
+
|
|
7
|
+
<bento-radio-group has-error="value" />
|
|
8
|
+
<bento-radio-group :has-error="value" />
|
|
9
|
+
<bento-radio-group :has-error="value" />
|
|
10
|
+
</div>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script setup></script>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// eslint.config.js
|
|
2
|
+
const { defineConfig } = require('eslint/config');
|
|
3
|
+
const vueParser = require('vue-eslint-parser');
|
|
4
|
+
const tsParser = require('@typescript-eslint/parser');
|
|
5
|
+
const adyenBento = require('@adyen/eslint-plugin-bento');
|
|
6
|
+
|
|
7
|
+
module.exports = defineConfig([
|
|
8
|
+
{
|
|
9
|
+
languageOptions: {
|
|
10
|
+
ecmaVersion: 'latest',
|
|
11
|
+
sourceType: 'module',
|
|
12
|
+
parser: vueParser,
|
|
13
|
+
parserOptions: {
|
|
14
|
+
parser: tsParser,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
plugins: {
|
|
18
|
+
'@adyen/bento': adyenBento,
|
|
19
|
+
},
|
|
20
|
+
rules: {
|
|
21
|
+
// Register the specific rule we are testing
|
|
22
|
+
'@adyen/bento/deprecation-components-has-error-prop': 'warn',
|
|
23
|
+
},
|
|
24
|
+
files: ['**/*.vue'],
|
|
25
|
+
},
|
|
26
|
+
]);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { execFileSyncEslintVueFiles } from '../../utils/exec-file-sync-eslint-vue-files';
|
|
3
|
+
|
|
4
|
+
describe('@adyen/bento/deprecation-components-has-error-prop', () => {
|
|
5
|
+
it('should lint with warning', () => {
|
|
6
|
+
// Load .eslintrc
|
|
7
|
+
const eslintrc = path.resolve(__dirname, '__tests__', 'eslint.config.js');
|
|
8
|
+
// Load the test file generated alongside this one
|
|
9
|
+
const vueFile = path.resolve(__dirname, '__tests__', 'deprecation-components-has-error-prop.vue');
|
|
10
|
+
|
|
11
|
+
// Execute the linter
|
|
12
|
+
const result = JSON.parse(execFileSyncEslintVueFiles(eslintrc, vueFile));
|
|
13
|
+
|
|
14
|
+
// 3 examples (static, shorthand, longhand) FOR EACH component.
|
|
15
|
+
// Total = 2 components * 3 = 6
|
|
16
|
+
expect(result[0].warningCount).toBe(6);
|
|
17
|
+
|
|
18
|
+
expect(result[0].messages[0]).toMatchObject({
|
|
19
|
+
ruleId: '@adyen/bento/deprecation-components-has-error-prop',
|
|
20
|
+
severity: 1,
|
|
21
|
+
|
|
22
|
+
messageId: 'deprecation',
|
|
23
|
+
message: `The "has-error" prop is deprecated. Please use "error-message" instead.`,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Without autofix option, no fix should be present
|
|
27
|
+
expect(result[0].messages[0].fix).toBeUndefined();
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('eslint').Rule.RuleContext} RuleContext
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import('eslint-plugin-vue/lib/utils').RuleModule} RuleModule
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const VueUtils = require('eslint-plugin-vue/lib/utils');
|
|
9
|
+
|
|
10
|
+
/** @type {RuleModule} */
|
|
11
|
+
module.exports = {
|
|
12
|
+
meta: {
|
|
13
|
+
type: 'suggestion',
|
|
14
|
+
docs: {
|
|
15
|
+
description: 'Deprecates usage of hasError prop in bento-checkbox-group, bento-radio-group',
|
|
16
|
+
category: 'Deprecations',
|
|
17
|
+
url: 'https://github.com/Adyen/bento/blob/main/packages/eslint/rules/deprecation-components-has-error-prop/README.md',
|
|
18
|
+
recommended: true,
|
|
19
|
+
},
|
|
20
|
+
messages: {
|
|
21
|
+
deprecation: `The "has-error" prop is deprecated. Please use "error-message" instead.`,
|
|
22
|
+
},
|
|
23
|
+
fixable: 'code',
|
|
24
|
+
schema: [
|
|
25
|
+
{
|
|
26
|
+
type: 'object',
|
|
27
|
+
properties: {
|
|
28
|
+
autofix: {
|
|
29
|
+
type: 'boolean',
|
|
30
|
+
default: false,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
additionalProperties: false,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
/** @param {RuleContext} context */
|
|
39
|
+
create(context) {
|
|
40
|
+
const options = context.options[0] || {};
|
|
41
|
+
const autofix = options.autofix === true;
|
|
42
|
+
/* ------------------------------------------------ */
|
|
43
|
+
/* CASE 2: PROP DEPRECATION (Multiple Components) */
|
|
44
|
+
/* ------------------------------------------------ */
|
|
45
|
+
return VueUtils.defineTemplateBodyVisitor(context, {
|
|
46
|
+
// 1. STATIC: value="foo"
|
|
47
|
+
[`VElement:matches([name="bento-checkbox-group"], [name="BentoCheckboxGroup"], [name="bento-radio-group"], [name="BentoRadioGroup"]) > VStartTag > VAttribute[directive=false][key.name="has-error"]`](
|
|
48
|
+
node
|
|
49
|
+
) {
|
|
50
|
+
context.report({
|
|
51
|
+
node,
|
|
52
|
+
messageId: 'deprecation',
|
|
53
|
+
...(autofix && {
|
|
54
|
+
fix(fixer) {
|
|
55
|
+
return fixer.replaceText(node.key, 'error-message');
|
|
56
|
+
},
|
|
57
|
+
}),
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
// 2. DYNAMIC: :value="foo" or v-bind:value="foo"
|
|
62
|
+
[`VElement:matches([name="bento-checkbox-group"], [name="BentoCheckboxGroup"], [name="bento-radio-group"], [name="BentoRadioGroup"]) > VStartTag > VAttribute[directive=true][key.name.name="bind"][key.argument.name="has-error"]`](
|
|
63
|
+
node
|
|
64
|
+
) {
|
|
65
|
+
context.report({
|
|
66
|
+
node,
|
|
67
|
+
messageId: 'deprecation',
|
|
68
|
+
...(autofix && {
|
|
69
|
+
fix(fixer) {
|
|
70
|
+
return fixer.replaceText(node.key.argument, 'error-message');
|
|
71
|
+
},
|
|
72
|
+
}),
|
|
73
|
+
});
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
};
|
package/rules/deprecation-components-has-error-prop/deprecation-components-has-error-prop.test.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { RuleTester } from 'eslint';
|
|
2
|
+
import vueParser from 'vue-eslint-parser';
|
|
3
|
+
import tsParser from '@typescript-eslint/parser';
|
|
4
|
+
import deprecationComponentsHasErrorProp from './deprecation-components-has-error-prop';
|
|
5
|
+
|
|
6
|
+
const ruleTester = new RuleTester({
|
|
7
|
+
languageOptions: {
|
|
8
|
+
ecmaVersion: 'latest',
|
|
9
|
+
sourceType: 'module',
|
|
10
|
+
parser: vueParser,
|
|
11
|
+
parserOptions: {
|
|
12
|
+
parser: tsParser,
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe('@adyen/bento/deprecation-components-has-error-prop', () => {
|
|
18
|
+
ruleTester.run('deprecation-components-has-error-prop', deprecationComponentsHasErrorProp, {
|
|
19
|
+
valid: [
|
|
20
|
+
{
|
|
21
|
+
name: 'Valid usage for bento-checkbox-group',
|
|
22
|
+
filename: 'test.vue',
|
|
23
|
+
code: `
|
|
24
|
+
<template>
|
|
25
|
+
<bento-checkbox-group errorMessage="val" />
|
|
26
|
+
</template>
|
|
27
|
+
`,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'Valid usage for bento-radio-group',
|
|
31
|
+
filename: 'test.vue',
|
|
32
|
+
code: `
|
|
33
|
+
<template>
|
|
34
|
+
<bento-radio-group errorMessage="val" />
|
|
35
|
+
</template>
|
|
36
|
+
`,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
invalid: [
|
|
40
|
+
// bento-checkbox-group: Static
|
|
41
|
+
{
|
|
42
|
+
name: 'Invalid: Static prop on bento-checkbox-group',
|
|
43
|
+
filename: 'test.vue',
|
|
44
|
+
code: `<template><bento-checkbox-group has-error="val" /></template>`,
|
|
45
|
+
errors: [{ messageId: 'deprecation' }],
|
|
46
|
+
},
|
|
47
|
+
// bento-checkbox-group: Shorthand
|
|
48
|
+
{
|
|
49
|
+
name: 'Invalid: Dynamic prop on bento-checkbox-group',
|
|
50
|
+
filename: 'test.vue',
|
|
51
|
+
code: `<template><bento-checkbox-group :has-error="val" /></template>`,
|
|
52
|
+
errors: [{ messageId: 'deprecation' }],
|
|
53
|
+
},
|
|
54
|
+
// bento-radio-group: Static
|
|
55
|
+
{
|
|
56
|
+
name: 'Invalid: Static prop on bento-radio-group',
|
|
57
|
+
filename: 'test.vue',
|
|
58
|
+
code: `<template><bento-radio-group has-error="val" /></template>`,
|
|
59
|
+
errors: [{ messageId: 'deprecation' }],
|
|
60
|
+
},
|
|
61
|
+
// bento-radio-group: Shorthand
|
|
62
|
+
{
|
|
63
|
+
name: 'Invalid: Dynamic prop on bento-radio-group',
|
|
64
|
+
filename: 'test.vue',
|
|
65
|
+
code: `<template><bento-radio-group :has-error="val" /></template>`,
|
|
66
|
+
errors: [{ messageId: 'deprecation' }],
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
/* ------------------------------------------------ */
|
|
72
|
+
/* AUTOFIX TESTS */
|
|
73
|
+
/* ------------------------------------------------ */
|
|
74
|
+
ruleTester.run('deprecation-components-has-error-prop (autofix enabled)', deprecationComponentsHasErrorProp, {
|
|
75
|
+
valid: [
|
|
76
|
+
{
|
|
77
|
+
name: 'Valid: error-message prop on bento-checkbox-group (autofix enabled)',
|
|
78
|
+
filename: 'test.vue',
|
|
79
|
+
options: [{ autofix: true }],
|
|
80
|
+
code: `<template><bento-checkbox-group error-message="val" /></template>`,
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
invalid: [
|
|
84
|
+
{
|
|
85
|
+
name: 'Autofix: static prop on bento-checkbox-group',
|
|
86
|
+
filename: 'test.vue',
|
|
87
|
+
options: [{ autofix: true }],
|
|
88
|
+
code: `<template><bento-checkbox-group has-error="val" /></template>`,
|
|
89
|
+
output: `<template><bento-checkbox-group error-message="val" /></template>`,
|
|
90
|
+
errors: [{ messageId: 'deprecation' }],
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'Autofix: dynamic prop on bento-checkbox-group',
|
|
94
|
+
filename: 'test.vue',
|
|
95
|
+
options: [{ autofix: true }],
|
|
96
|
+
code: `<template><bento-checkbox-group :has-error="val" /></template>`,
|
|
97
|
+
output: `<template><bento-checkbox-group :error-message="val" /></template>`,
|
|
98
|
+
errors: [{ messageId: 'deprecation' }],
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'Autofix: static prop on bento-radio-group',
|
|
102
|
+
filename: 'test.vue',
|
|
103
|
+
options: [{ autofix: true }],
|
|
104
|
+
code: `<template><bento-radio-group has-error="val" /></template>`,
|
|
105
|
+
output: `<template><bento-radio-group error-message="val" /></template>`,
|
|
106
|
+
errors: [{ messageId: 'deprecation' }],
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: 'Autofix: dynamic prop on bento-radio-group',
|
|
110
|
+
filename: 'test.vue',
|
|
111
|
+
options: [{ autofix: true }],
|
|
112
|
+
code: `<template><bento-radio-group :has-error="val" /></template>`,
|
|
113
|
+
output: `<template><bento-radio-group :error-message="val" /></template>`,
|
|
114
|
+
errors: [{ messageId: 'deprecation' }],
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: 'Autofix: v-bind longhand on bento-radio-group',
|
|
118
|
+
filename: 'test.vue',
|
|
119
|
+
options: [{ autofix: true }],
|
|
120
|
+
code: `<template><bento-radio-group v-bind:has-error="val" /></template>`,
|
|
121
|
+
output: `<template><bento-radio-group v-bind:error-message="val" /></template>`,
|
|
122
|
+
errors: [{ messageId: 'deprecation' }],
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
name: 'Autofix: does not fix when autofix is false',
|
|
126
|
+
filename: 'test.vue',
|
|
127
|
+
options: [{ autofix: false }],
|
|
128
|
+
code: `<template><bento-checkbox-group has-error="val" /></template>`,
|
|
129
|
+
errors: [{ messageId: 'deprecation' }],
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
});
|
|
133
|
+
});
|
|
@@ -18,7 +18,7 @@ module.exports = defineConfig([
|
|
|
18
18
|
},
|
|
19
19
|
rules: {
|
|
20
20
|
// Register the specific rule we are testing
|
|
21
|
-
'@adyen/bento/deprecation-components-input-emit': 'warn',
|
|
21
|
+
'@adyen/bento/deprecation-components-input-emit': ['warn', { autofix: true }],
|
|
22
22
|
},
|
|
23
23
|
files: ['**/*.vue'],
|
|
24
24
|
},
|