@adyen/eslint-plugin-bento 2.22.0 → 2.23.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 +15 -0
- package/configs/vue-recommended.js +1 -0
- package/configs/vue-strict.js +2 -1
- package/package.json +3 -3
- package/rules/deprecation-filter-bar-deprecated-props/README.md +7 -0
- package/rules/deprecation-filter-bar-deprecated-props/deprecation-filter-bar-deprecated-props.js +14 -3
- package/rules/deprecation-filter-bar-deprecated-props/deprecation-filter-bar-deprecated-props.test.ts +25 -0
- package/rules/deprecation-tag-default-slot/deprecation-tag-default-slot.test.ts +18 -0
- package/utils/component-slot-migration.js +22 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.23.0 (2026-08-17)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- updated `deprecation-filter-bar-deprecated-props` rule to check also for configs with enums ([5259ab283](https://github.com/Adyen/bento/commit/5259ab283))
|
|
8
|
+
|
|
9
|
+
### Miscellaneous Chores
|
|
10
|
+
|
|
11
|
+
- enabled strict `@adyen/eslint-plugin-bento` plugin ESLint rules to enforce deprecations ([974a8e49e](https://github.com/Adyen/bento/commit/974a8e49e))
|
|
12
|
+
|
|
13
|
+
### ❤️ Thank You
|
|
14
|
+
|
|
15
|
+
- daver
|
|
16
|
+
|
|
17
|
+
|
|
3
18
|
## 2.22.0 (2026-07-29)
|
|
4
19
|
|
|
5
20
|
### Bug Fixes
|
package/configs/vue-strict.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** @type {import('eslint').Linter.Config[]} */
|
|
1
2
|
module.exports = [
|
|
2
3
|
{
|
|
3
4
|
name: '@bento/adyen/strict',
|
|
@@ -12,7 +13,7 @@ module.exports = [
|
|
|
12
13
|
},
|
|
13
14
|
rules: {
|
|
14
15
|
'@adyen/bento/deprecation-bento-data-grid-cell-action-menu-item-handler': 'error',
|
|
15
|
-
'@adyen/bento/deprecation-bento-date-range-picker-has-actions-prop': 'error',
|
|
16
|
+
'@adyen/bento/deprecation-bento-date-range-picker-has-actions-prop': ['error', { action: 'remove' }],
|
|
16
17
|
'@adyen/bento/deprecation-input-filter-dropdown-options': 'error',
|
|
17
18
|
'@adyen/bento/deprecation-bento-dropdown-size-prop': 'error',
|
|
18
19
|
'@adyen/bento/deprecation-bento-timeline-item-variant-prop': 'error',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adyen/eslint-plugin-bento",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.23.0",
|
|
4
4
|
"description": "Adyen Bento ESLint rules",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"@types/eslint": "9.6.1",
|
|
31
31
|
"@types/estree": "1.0.6",
|
|
32
32
|
"@types/node": "24.9.0",
|
|
33
|
-
"@typescript-eslint/eslint-plugin": "8.
|
|
34
|
-
"@typescript-eslint/parser": "8.
|
|
33
|
+
"@typescript-eslint/eslint-plugin": "8.61.0",
|
|
34
|
+
"@typescript-eslint/parser": "8.61.0",
|
|
35
35
|
"@vitest/eslint-plugin": "1.1.25",
|
|
36
36
|
"@vitest/coverage-v8": "3.2.6",
|
|
37
37
|
"eslint": "9.39.0",
|
package/rules/deprecation-filter-bar-deprecated-props/deprecation-filter-bar-deprecated-props.js
CHANGED
|
@@ -20,6 +20,16 @@ function getStaticPropertyName(prop) {
|
|
|
20
20
|
return prop.key.type === 'Identifier' ? prop.key.name : prop.key.type === 'Literal' ? String(prop.key.value) : null;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
function isBentoFilterItemType(node) {
|
|
24
|
+
return (
|
|
25
|
+
node?.type === 'MemberExpression' &&
|
|
26
|
+
!node.computed &&
|
|
27
|
+
node.object.type === 'Identifier' &&
|
|
28
|
+
node.object.name === 'BentoFilterItemType' &&
|
|
29
|
+
node.property.type === 'Identifier'
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
23
33
|
/** @type {RuleModule} */
|
|
24
34
|
module.exports = {
|
|
25
35
|
meta: {
|
|
@@ -88,9 +98,10 @@ module.exports = {
|
|
|
88
98
|
const filterType = propertyMap.type?.value;
|
|
89
99
|
const isFilterConfig =
|
|
90
100
|
propertyMap.field &&
|
|
91
|
-
filterType?.type === 'Literal' &&
|
|
92
|
-
|
|
93
|
-
|
|
101
|
+
((filterType?.type === 'Literal' &&
|
|
102
|
+
typeof filterType.value === 'string' &&
|
|
103
|
+
filterType.value.endsWith('Filter')) ||
|
|
104
|
+
isBentoFilterItemType(filterType));
|
|
94
105
|
if (!isFilterConfig) {
|
|
95
106
|
return;
|
|
96
107
|
}
|
|
@@ -133,6 +133,16 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
133
133
|
<template><div /></template>
|
|
134
134
|
`,
|
|
135
135
|
},
|
|
136
|
+
{
|
|
137
|
+
name: 'Valid: unrelated enum member with a similar name',
|
|
138
|
+
filename: 'test.vue',
|
|
139
|
+
code: `
|
|
140
|
+
<script setup>
|
|
141
|
+
const config = [{ field: 'name', type: OtherFilterItemType.INPUT, value: 'test' }];
|
|
142
|
+
</script>
|
|
143
|
+
<template><bento-filter-bar :config="config" /></template>
|
|
144
|
+
`,
|
|
145
|
+
},
|
|
136
146
|
{
|
|
137
147
|
name: 'Valid: unrelated object with value property (no false positive)',
|
|
138
148
|
filename: 'test.vue',
|
|
@@ -186,6 +196,21 @@ describe('@adyen/bento/deprecation-filter-bar-deprecated-props', () => {
|
|
|
186
196
|
`,
|
|
187
197
|
errors: [{ messageId: 'deprecationConfigValue' }],
|
|
188
198
|
},
|
|
199
|
+
{
|
|
200
|
+
name: 'Invalid: value property in BentoFilterItemType enum config item',
|
|
201
|
+
filename: 'test.vue',
|
|
202
|
+
code: `
|
|
203
|
+
<script setup>
|
|
204
|
+
const config = [{
|
|
205
|
+
field: 'name',
|
|
206
|
+
type: BentoFilterItemType.INPUT,
|
|
207
|
+
value: 'test',
|
|
208
|
+
}];
|
|
209
|
+
</script>
|
|
210
|
+
<template><bento-filter-bar :config="config" /></template>
|
|
211
|
+
`,
|
|
212
|
+
errors: [{ messageId: 'deprecationConfigValue' }],
|
|
213
|
+
},
|
|
189
214
|
// "value" inside filter config items (inline template)
|
|
190
215
|
{
|
|
191
216
|
name: 'Invalid: value property in filter config item (inline template)',
|
|
@@ -42,6 +42,24 @@ describe('@adyen/bento/deprecation-tag-default-slot should suggest the usage of
|
|
|
42
42
|
<bento-tag :label="thisIsMyVariableWithText" variant="blue" />
|
|
43
43
|
`,
|
|
44
44
|
},
|
|
45
|
+
{
|
|
46
|
+
name: 'BentoTag with named "icon" slot',
|
|
47
|
+
filename: 'test.vue',
|
|
48
|
+
code: `
|
|
49
|
+
<template>
|
|
50
|
+
<bento-tag
|
|
51
|
+
v-if="errorCounter != null"
|
|
52
|
+
class="b-tabs__tab-error-counter"
|
|
53
|
+
variant="red"
|
|
54
|
+
:label="errorCounter"
|
|
55
|
+
>
|
|
56
|
+
<template #icon>
|
|
57
|
+
<cross-circle-fill-icon aria-hidden="true" />
|
|
58
|
+
</template>
|
|
59
|
+
</bento-tag>
|
|
60
|
+
</template>
|
|
61
|
+
`,
|
|
62
|
+
},
|
|
45
63
|
],
|
|
46
64
|
invalid: [
|
|
47
65
|
{
|
|
@@ -6,6 +6,7 @@ const j = require('jscodeshift');
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
+
* @typedef {import('vue-eslint-parser').AST.VElement} VElement
|
|
9
10
|
* @typedef {import('vue-eslint-parser').AST.VText} VText
|
|
10
11
|
* @typedef {import('vue-eslint-parser').AST.VExpressionContainer} VExpressionContainer
|
|
11
12
|
*/
|
|
@@ -26,10 +27,23 @@ module.exports = {
|
|
|
26
27
|
*/
|
|
27
28
|
componentSlotMigration({ propertyName, context, template, alwaysExpression = false }) {
|
|
28
29
|
return node => {
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* @param {VElement | VText | VExpressionContainer} child
|
|
32
|
+
* @returns {boolean}
|
|
33
|
+
*/
|
|
34
|
+
function isNamedSlot(child) {
|
|
35
|
+
return (
|
|
36
|
+
child.type === 'VElement' &&
|
|
37
|
+
child.name === 'template' &&
|
|
38
|
+
child.startTag.attributes.some(
|
|
39
|
+
attribute => attribute.directive && attribute.key.name.name === 'slot'
|
|
40
|
+
)
|
|
41
|
+
);
|
|
31
42
|
}
|
|
32
43
|
|
|
44
|
+
// Named slots are not default slot content and should not trigger migration.
|
|
45
|
+
const contentNodes = node.children.filter(child => !isNamedSlot(child));
|
|
46
|
+
|
|
33
47
|
// Turned true if one of the children is an expression
|
|
34
48
|
let hasExpression = false;
|
|
35
49
|
|
|
@@ -72,7 +86,11 @@ module.exports = {
|
|
|
72
86
|
|
|
73
87
|
// Remove empty nodes
|
|
74
88
|
/** @type { Array<VText | VExpressionContainer> } */
|
|
75
|
-
const filteredNodes =
|
|
89
|
+
const filteredNodes = contentNodes.filter(removeEmptyVTextNodes);
|
|
90
|
+
|
|
91
|
+
if (!filteredNodes.length) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
76
94
|
|
|
77
95
|
// Get all content and concat
|
|
78
96
|
const slotContent = (() => {
|
|
@@ -80,7 +98,7 @@ module.exports = {
|
|
|
80
98
|
return transformNodeToText(filteredNodes[0])?.trim();
|
|
81
99
|
}
|
|
82
100
|
|
|
83
|
-
const content =
|
|
101
|
+
const content = contentNodes
|
|
84
102
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
85
103
|
.map((/** @type {VText | VExpressionContainer} */ node) => transformNodeToText(node, true))
|
|
86
104
|
.join('')
|