@adyen/eslint-plugin-bento 1.0.3 → 1.2.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/README.md +20 -0
- package/index.js +6 -0
- package/package.json +5 -3
- package/rules/deprecation-currency-default-slot/README.md +50 -0
- package/rules/deprecation-currency-default-slot/__tests__/.eslintrc.js +8 -0
- package/rules/deprecation-currency-default-slot/__tests__/deprecation-currency-default-slot.vue +7 -0
- package/rules/deprecation-currency-default-slot/deprecation-currency-default-slot.integration.test.ts +36 -0
- package/rules/deprecation-currency-default-slot/deprecation-currency-default-slot.js +34 -0
- package/rules/deprecation-currency-default-slot/deprecation-currency-default-slot.test.ts +127 -0
- package/rules/deprecation-tag-default-slot/README.md +46 -0
- package/rules/deprecation-tag-default-slot/__tests__/.eslintrc.js +8 -0
- package/rules/deprecation-tag-default-slot/__tests__/deprecation-tag-default-slot.vue +5 -0
- package/rules/deprecation-tag-default-slot/deprecation-tag-default-slot.integration.test.ts +36 -0
- package/rules/deprecation-tag-default-slot/deprecation-tag-default-slot.js +33 -0
- package/rules/deprecation-tag-default-slot/deprecation-tag-default-slot.test.ts +136 -0
- package/utils/component-slot-migration.js +90 -0
package/README.md
CHANGED
|
@@ -54,3 +54,23 @@ Disallow the use of ADL space utility classes in favor of Bento _spacer_ utility
|
|
|
54
54
|
The recommended configuration contains pre-configured rules and their severity
|
|
55
55
|
|
|
56
56
|
- `@adyen/bento/vue-old-spacer-tokens`: `warn`
|
|
57
|
+
|
|
58
|
+
### `@adyen/bento/deprecation-currency-default-slot`
|
|
59
|
+
|
|
60
|
+
Disallow the use of the `default` slot in `bento-currency` instances
|
|
61
|
+
|
|
62
|
+
### Recommended
|
|
63
|
+
|
|
64
|
+
The recommended configuration contains pre-configured rules and their severity
|
|
65
|
+
|
|
66
|
+
- `@adyen/bento/deprecation-currency-default-slot`: `warn`
|
|
67
|
+
|
|
68
|
+
### `@adyen/bento/deprecation-tag-default-slot`
|
|
69
|
+
|
|
70
|
+
Disallow the use of the `default` slot in `bento-tag` instances
|
|
71
|
+
|
|
72
|
+
### Recommended
|
|
73
|
+
|
|
74
|
+
The recommended configuration contains pre-configured rules and their severity
|
|
75
|
+
|
|
76
|
+
- `@adyen/bento/deprecation-tag-default-slot`: `warn`
|
package/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
|
+
const deprecationCurrencyDefaultSlot = require('./rules/deprecation-currency-default-slot/deprecation-currency-default-slot');
|
|
3
|
+
const deprecationTagDefaultSlot = require('./rules/deprecation-tag-default-slot/deprecation-tag-default-slot');
|
|
2
4
|
const spacerTokens = require('./rules/vue-old-spacer-tokens/vue-old-spacer-tokens');
|
|
3
5
|
|
|
4
6
|
// The package name and version must be in sync with 'package.json'
|
|
@@ -14,11 +16,15 @@ module.exports = {
|
|
|
14
16
|
parser: 'vue-eslint-parser',
|
|
15
17
|
plugins: ['@adyen/bento'],
|
|
16
18
|
rules: {
|
|
19
|
+
'@adyen/bento/deprecation-currency-default-slot': 'warn',
|
|
20
|
+
'@adyen/bento/deprecation-tag-default-slot': 'warn',
|
|
17
21
|
'@adyen/bento/vue-old-spacer-tokens': 'warn',
|
|
18
22
|
},
|
|
19
23
|
},
|
|
20
24
|
},
|
|
21
25
|
rules: {
|
|
26
|
+
'deprecation-currency-default-slot': deprecationCurrencyDefaultSlot,
|
|
27
|
+
'deprecation-tag-default-slot': deprecationTagDefaultSlot,
|
|
22
28
|
'vue-old-spacer-tokens': spacerTokens,
|
|
23
29
|
},
|
|
24
30
|
};
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adyen/eslint-plugin-bento",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Adyen Bento ESLint rules",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
7
7
|
"index.js",
|
|
8
8
|
"rules/*",
|
|
9
|
+
"utils/*",
|
|
9
10
|
"!**/__tests__",
|
|
10
11
|
"!**/*.test.ts"
|
|
11
12
|
],
|
|
@@ -18,9 +19,10 @@
|
|
|
18
19
|
},
|
|
19
20
|
"license": "MIT",
|
|
20
21
|
"devDependencies": {
|
|
21
|
-
"@vitest/coverage-v8": "2.1.
|
|
22
|
+
"@vitest/coverage-v8": "2.1.9",
|
|
22
23
|
"eslint": "8.57.1",
|
|
23
|
-
"
|
|
24
|
+
"jscodeshift": "17.1.2",
|
|
25
|
+
"vitest": "2.1.9",
|
|
24
26
|
"vue-eslint-parser": "9.3.2"
|
|
25
27
|
},
|
|
26
28
|
"peerDependencies": {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# @adyen/bento/deprecation-currency-default-slot
|
|
2
|
+
|
|
3
|
+
> Disallow the use of the `default` slot in `bento-currency` instances
|
|
4
|
+
|
|
5
|
+
- This rule is included in the `plugin:@adyen/bento/recommended` configuration.
|
|
6
|
+
- 🔧 The `--fix` option can automatically fix the problems reported by this rule.
|
|
7
|
+
|
|
8
|
+
This rule prevents using the deprecated `default` slot within the `Currency` component.
|
|
9
|
+
|
|
10
|
+
## ✗ BAD
|
|
11
|
+
|
|
12
|
+
<!-- prettier-ignore -->
|
|
13
|
+
```html
|
|
14
|
+
<template>
|
|
15
|
+
<bento-currency currency="USD">
|
|
16
|
+
12345
|
|
17
|
+
</bento-currency>
|
|
18
|
+
|
|
19
|
+
<bento-currency currency="USD">
|
|
20
|
+
12345.67
|
|
21
|
+
</bento-currency>
|
|
22
|
+
|
|
23
|
+
<bento-currency>
|
|
24
|
+
{{ thisIsMyVariableWithCurrencyValue }}
|
|
25
|
+
</bento-currency>
|
|
26
|
+
</template>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## ✓ Good
|
|
30
|
+
|
|
31
|
+
<!-- prettier-ignore -->
|
|
32
|
+
```html
|
|
33
|
+
<template>
|
|
34
|
+
<bento-currency
|
|
35
|
+
:value="12345"
|
|
36
|
+
currency="USD"
|
|
37
|
+
/>
|
|
38
|
+
|
|
39
|
+
<bento-currency
|
|
40
|
+
:value="12345.67"
|
|
41
|
+
currency="USD"
|
|
42
|
+
/>
|
|
43
|
+
|
|
44
|
+
<bento-currency
|
|
45
|
+
:value="thisIsMyVariableWithCurrencyValue"
|
|
46
|
+
:currency="BentoCurrencyISOCode.USD"
|
|
47
|
+
major-units
|
|
48
|
+
/>
|
|
49
|
+
</template>
|
|
50
|
+
```
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
// ESLint command
|
|
5
|
+
const ESLINT = 'pnpm eslint';
|
|
6
|
+
|
|
7
|
+
describe('@adyen/bento/deprecation-currency-default-slot', () => {
|
|
8
|
+
it('should lint with warning', () => {
|
|
9
|
+
// Load .eslintrc
|
|
10
|
+
const eslintrc = path.resolve(__dirname, '__tests__', '.eslintrc.js');
|
|
11
|
+
// Load the test file
|
|
12
|
+
const vueFile = path.resolve(__dirname, '__tests__', 'deprecation-currency-default-slot.vue');
|
|
13
|
+
|
|
14
|
+
// Execute the linter
|
|
15
|
+
const result = JSON.parse(
|
|
16
|
+
execSync(`${ESLINT} --format=json -c ${eslintrc} ${vueFile}`, {
|
|
17
|
+
encoding: 'utf8',
|
|
18
|
+
})
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
// Expects a warning with a suggestion/fix and an error message
|
|
22
|
+
expect(result[0].warningCount).toBe(1);
|
|
23
|
+
expect(result[0].messages[0]).toStrictEqual({
|
|
24
|
+
ruleId: '@adyen/bento/deprecation-currency-default-slot',
|
|
25
|
+
severity: 1,
|
|
26
|
+
message: '"default" slot is deprecated in favor of the "value" property',
|
|
27
|
+
messageId: 'migrateDefaultSlot',
|
|
28
|
+
line: 2,
|
|
29
|
+
column: 5,
|
|
30
|
+
nodeType: 'VElement',
|
|
31
|
+
endLine: 4,
|
|
32
|
+
endColumn: 22,
|
|
33
|
+
fix: { range: [30, 101], text: ' :value="thisIsMyVariableWithCurrencyValue" />' },
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const VueUtils = require('eslint-plugin-vue/lib/utils');
|
|
2
|
+
const { componentSlotMigration } = require('../../utils/component-slot-migration');
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
meta: {
|
|
6
|
+
type: 'suggestion',
|
|
7
|
+
docs: {
|
|
8
|
+
description: 'Replaces Currency usage of "default" slot in favor of the "value" property',
|
|
9
|
+
category: 'Best Practices',
|
|
10
|
+
url: 'https://github.com/Adyen/bento/blob/main/packages/eslint/rules/deprecate-currency-default-slot/README.md',
|
|
11
|
+
recommended: true,
|
|
12
|
+
},
|
|
13
|
+
messages: {
|
|
14
|
+
migrateDefaultSlot: '"default" slot is deprecated in favor of the "value" property',
|
|
15
|
+
},
|
|
16
|
+
fixable: 'code',
|
|
17
|
+
schema: [], // No options are needed for this rule
|
|
18
|
+
},
|
|
19
|
+
create(context) {
|
|
20
|
+
const sourceCode = context.getSourceCode();
|
|
21
|
+
const template =
|
|
22
|
+
sourceCode.parserServices.getTemplateBodyTokenStore &&
|
|
23
|
+
sourceCode.parserServices.getTemplateBodyTokenStore();
|
|
24
|
+
|
|
25
|
+
return VueUtils.defineTemplateBodyVisitor(context, {
|
|
26
|
+
'VElement[name=bento-currency]': componentSlotMigration({
|
|
27
|
+
propertyName: 'value',
|
|
28
|
+
context,
|
|
29
|
+
template,
|
|
30
|
+
alwaysExpression: true,
|
|
31
|
+
}),
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { RuleTester } from 'eslint';
|
|
2
|
+
import deprecationCurrencyDefaultSlot from './deprecation-currency-default-slot';
|
|
3
|
+
|
|
4
|
+
const ruleTester = new RuleTester({
|
|
5
|
+
parser: require.resolve('vue-eslint-parser'),
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
describe('@adyen/bento/deprecation-currency-default-slot should suggest the usage of "label" property instead of "default" slot', () => {
|
|
9
|
+
ruleTester.run('deprecation-currency-default-slot', deprecationCurrencyDefaultSlot, {
|
|
10
|
+
valid: [
|
|
11
|
+
{
|
|
12
|
+
name: 'BentoCurrency with "value" property',
|
|
13
|
+
filename: 'test.vue',
|
|
14
|
+
code: `
|
|
15
|
+
<template>
|
|
16
|
+
<bento-currency :value="12345" currency="USD" />
|
|
17
|
+
</template>
|
|
18
|
+
`,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'BentoCurrency with closing tag but no children',
|
|
22
|
+
filename: 'test.vue',
|
|
23
|
+
code: `
|
|
24
|
+
<template>
|
|
25
|
+
<bento-currency :value="12345" :currency="BentoCurrencyISOCode.USD" major-units />
|
|
26
|
+
</template>
|
|
27
|
+
`,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'BentoCurrency with closing tag but no children',
|
|
31
|
+
filename: 'test.vue',
|
|
32
|
+
code: `
|
|
33
|
+
<template>
|
|
34
|
+
<bento-currency
|
|
35
|
+
:value="thisIsMyVariableWithCurrencyValue"
|
|
36
|
+
:currency="BentoCurrencyISOCode.USD"
|
|
37
|
+
major-units
|
|
38
|
+
/>
|
|
39
|
+
</template>
|
|
40
|
+
`,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
invalid: [
|
|
44
|
+
{
|
|
45
|
+
name: 'BentoCurrency with VText child',
|
|
46
|
+
code: `
|
|
47
|
+
<template>
|
|
48
|
+
<bento-currency currency="USD">
|
|
49
|
+
12345
|
|
50
|
+
</bento-currency>
|
|
51
|
+
</template>
|
|
52
|
+
`,
|
|
53
|
+
output: `
|
|
54
|
+
<template>
|
|
55
|
+
<bento-currency currency="USD" :value="12345" />
|
|
56
|
+
</template>
|
|
57
|
+
`,
|
|
58
|
+
errors: [{ message: '"default" slot is deprecated in favor of the "value" property' }],
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: 'BentoCurrency with CallExpression child',
|
|
62
|
+
code: `
|
|
63
|
+
<template>
|
|
64
|
+
<bento-currency :currency="BentoCurrencyISOCode.EUR" major-units
|
|
65
|
+
>{{ myFunction(valueRefs, EnumValues.EURO_AMOUNT) }}
|
|
66
|
+
</bento-currency>
|
|
67
|
+
</template>
|
|
68
|
+
`,
|
|
69
|
+
output: `
|
|
70
|
+
<template>
|
|
71
|
+
<bento-currency :currency="BentoCurrencyISOCode.EUR" major-units
|
|
72
|
+
:value="myFunction(valueRefs, EnumValues.EURO_AMOUNT)" />
|
|
73
|
+
</template>
|
|
74
|
+
`,
|
|
75
|
+
errors: [{ message: '"default" slot is deprecated in favor of the "value" property' }],
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'BentoCurrency with VText child and no attributes',
|
|
79
|
+
code: `
|
|
80
|
+
<template>
|
|
81
|
+
<bento-currency>
|
|
82
|
+
12345.23
|
|
83
|
+
</bento-currency>
|
|
84
|
+
</template>
|
|
85
|
+
`,
|
|
86
|
+
output: `
|
|
87
|
+
<template>
|
|
88
|
+
<bento-currency :value="12345.23" />
|
|
89
|
+
</template>
|
|
90
|
+
`,
|
|
91
|
+
errors: [{ message: '"default" slot is deprecated in favor of the "value" property' }],
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'BentoCurrency with property as child',
|
|
95
|
+
code: `
|
|
96
|
+
<template>
|
|
97
|
+
<bento-currency :key="item.thisIsMyVariableWithCurrencyValue" :currency="BentoCurrencyISOCode.EUR" major-units>
|
|
98
|
+
{{ item.thisIsMyVariableWithCurrencyValue }}
|
|
99
|
+
</bento-currency>
|
|
100
|
+
</template>
|
|
101
|
+
`,
|
|
102
|
+
output: `
|
|
103
|
+
<template>
|
|
104
|
+
<bento-currency :key="item.thisIsMyVariableWithCurrencyValue" :currency="BentoCurrencyISOCode.EUR" major-units :value="item.thisIsMyVariableWithCurrencyValue" />
|
|
105
|
+
</template>
|
|
106
|
+
`,
|
|
107
|
+
errors: [{ message: '"default" slot is deprecated in favor of the "value" property' }],
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: 'BentoCurrency with simple property as child',
|
|
111
|
+
code: `
|
|
112
|
+
<template>
|
|
113
|
+
<bento-currency>
|
|
114
|
+
{{ thisIsMyVariableWithCurrencyValue }}
|
|
115
|
+
</bento-currency>
|
|
116
|
+
</template>
|
|
117
|
+
`,
|
|
118
|
+
output: `
|
|
119
|
+
<template>
|
|
120
|
+
<bento-currency :value="thisIsMyVariableWithCurrencyValue" />
|
|
121
|
+
</template>
|
|
122
|
+
`,
|
|
123
|
+
errors: [{ message: '"default" slot is deprecated in favor of the "value" property' }],
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
});
|
|
127
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# @adyen/bento/deprecation-tag-default-slot
|
|
2
|
+
|
|
3
|
+
> Disallow the use of the slot in `bento-tag` instances
|
|
4
|
+
|
|
5
|
+
- This rule is included in the `plugin:@adyen/bento/recommended` configuration.
|
|
6
|
+
- 🔧 The `--fix` option can automatically fix the problems reported by this rule.
|
|
7
|
+
|
|
8
|
+
This rule prevents using the deprecated `default` slot within the `Tag` component.
|
|
9
|
+
|
|
10
|
+
## ✗ BAD
|
|
11
|
+
|
|
12
|
+
<!-- prettier-ignore -->
|
|
13
|
+
```html
|
|
14
|
+
<template>
|
|
15
|
+
<bento-tag variant="blue">
|
|
16
|
+
Label text
|
|
17
|
+
</bento-tag>
|
|
18
|
+
|
|
19
|
+
<bento-tag>
|
|
20
|
+
Label text
|
|
21
|
+
</bento-tag>
|
|
22
|
+
|
|
23
|
+
<bento-tag>
|
|
24
|
+
{{ thisIsMyVariableWithText }}
|
|
25
|
+
</bento-tag>
|
|
26
|
+
|
|
27
|
+
<bento-tag>
|
|
28
|
+
Value: {{ thisIsAValue }}
|
|
29
|
+
</bento-tag>
|
|
30
|
+
</template>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## ✓ Good
|
|
34
|
+
|
|
35
|
+
<!-- prettier-ignore -->
|
|
36
|
+
```html
|
|
37
|
+
<template>
|
|
38
|
+
<bento-tag label="Label text" variant="blue" />
|
|
39
|
+
|
|
40
|
+
<bento-tag label="Label text" variant="blue" />
|
|
41
|
+
|
|
42
|
+
<bento-tag :label="thisIsMyVariableWithText" variant="blue" />
|
|
43
|
+
|
|
44
|
+
<bento-tag :label="Value: ${thisIsAValue}" />
|
|
45
|
+
</template>
|
|
46
|
+
```
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
// ESLint command
|
|
5
|
+
const ESLINT = 'pnpm eslint';
|
|
6
|
+
|
|
7
|
+
describe('@adyen/bento/deprecation-tag-default-slot', () => {
|
|
8
|
+
it('should lint with warning', () => {
|
|
9
|
+
// Load .eslintrc
|
|
10
|
+
const eslintrc = path.resolve(__dirname, '__tests__', '.eslintrc.js');
|
|
11
|
+
// Load the test file
|
|
12
|
+
const vueFile = path.resolve(__dirname, '__tests__', 'deprecation-tag-default-slot.vue');
|
|
13
|
+
|
|
14
|
+
// Execute the linter
|
|
15
|
+
const result = JSON.parse(
|
|
16
|
+
execSync(`${ESLINT} --format=json -c ${eslintrc} ${vueFile}`, {
|
|
17
|
+
encoding: 'utf8',
|
|
18
|
+
})
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
// Expects a warning with a suggestion/fix and an error message
|
|
22
|
+
expect(result[0].warningCount).toBe(1);
|
|
23
|
+
expect(result[0].messages[0]).toStrictEqual({
|
|
24
|
+
ruleId: '@adyen/bento/deprecation-tag-default-slot',
|
|
25
|
+
severity: 1,
|
|
26
|
+
message: '"default" slot is deprecated in favor of the "label" property',
|
|
27
|
+
messageId: 'migrateDefaultSlot',
|
|
28
|
+
line: 2,
|
|
29
|
+
column: 5,
|
|
30
|
+
nodeType: 'VElement',
|
|
31
|
+
endLine: 2,
|
|
32
|
+
endColumn: 53,
|
|
33
|
+
fix: { range: [25, 63], text: ' :label="`Value: ${thisIsAValue}`" />' },
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const VueUtils = require('eslint-plugin-vue/lib/utils');
|
|
2
|
+
const { componentSlotMigration } = require('../../utils/component-slot-migration');
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
meta: {
|
|
6
|
+
type: 'suggestion',
|
|
7
|
+
docs: {
|
|
8
|
+
description: 'Replaces Tag usage of "default" slot in favor of the "label" property',
|
|
9
|
+
category: 'Best Practices',
|
|
10
|
+
url: 'https://github.com/Adyen/bento/blob/main/packages/eslint/rules/deprecate-tag-default-slot/README.md',
|
|
11
|
+
recommended: true,
|
|
12
|
+
},
|
|
13
|
+
messages: {
|
|
14
|
+
migrateDefaultSlot: '"default" slot is deprecated in favor of the "label" property',
|
|
15
|
+
},
|
|
16
|
+
fixable: 'code',
|
|
17
|
+
schema: [], // No options are needed for this rule
|
|
18
|
+
},
|
|
19
|
+
create(context) {
|
|
20
|
+
const sourceCode = context.getSourceCode();
|
|
21
|
+
const template =
|
|
22
|
+
sourceCode.parserServices.getTemplateBodyTokenStore &&
|
|
23
|
+
sourceCode.parserServices.getTemplateBodyTokenStore();
|
|
24
|
+
|
|
25
|
+
return VueUtils.defineTemplateBodyVisitor(context, {
|
|
26
|
+
'VElement[name=bento-tag]': componentSlotMigration({
|
|
27
|
+
propertyName: 'label',
|
|
28
|
+
context,
|
|
29
|
+
template,
|
|
30
|
+
}),
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { RuleTester } from 'eslint';
|
|
2
|
+
import deprecationTagDefaultSlot from './deprecation-tag-default-slot';
|
|
3
|
+
|
|
4
|
+
const ruleTester = new RuleTester({
|
|
5
|
+
parser: require.resolve('vue-eslint-parser'),
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
describe('@adyen/bento/deprecation-tag-default-slot should suggest the usage of "label" property instead of "default" slot', () => {
|
|
9
|
+
ruleTester.run('deprecation-tag-default-slot', deprecationTagDefaultSlot, {
|
|
10
|
+
valid: [
|
|
11
|
+
{
|
|
12
|
+
name: 'BentoTag with "label" property',
|
|
13
|
+
filename: 'test.vue',
|
|
14
|
+
code: `
|
|
15
|
+
<template>
|
|
16
|
+
<bento-tag label="Label text" variant="blue" />
|
|
17
|
+
</template>
|
|
18
|
+
`,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'BentoTag with closing tag but no children',
|
|
22
|
+
filename: 'test.vue',
|
|
23
|
+
code: `
|
|
24
|
+
<template>
|
|
25
|
+
<bento-tag label="Label text" variant="blue" />
|
|
26
|
+
`,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'BentoTag with expression as value for "label" property',
|
|
30
|
+
filename: 'test.vue',
|
|
31
|
+
code: `
|
|
32
|
+
<template>
|
|
33
|
+
<bento-tag :label="thisIsMyVariableWithText" variant="blue" />
|
|
34
|
+
`,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
invalid: [
|
|
38
|
+
{
|
|
39
|
+
name: 'BentoTag with VText child',
|
|
40
|
+
code: `
|
|
41
|
+
<template>
|
|
42
|
+
<bento-tag variant="blue">
|
|
43
|
+
Label text
|
|
44
|
+
</bento-tag>
|
|
45
|
+
</template>
|
|
46
|
+
`,
|
|
47
|
+
output: `
|
|
48
|
+
<template>
|
|
49
|
+
<bento-tag variant="blue" label="Label text" />
|
|
50
|
+
</template>
|
|
51
|
+
`,
|
|
52
|
+
errors: [{ message: '"default" slot is deprecated in favor of the "label" property' }],
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'BentoTag with VText child and no attributes',
|
|
56
|
+
code: `
|
|
57
|
+
<template>
|
|
58
|
+
<bento-tag>
|
|
59
|
+
Label text
|
|
60
|
+
</bento-tag>
|
|
61
|
+
</template>
|
|
62
|
+
`,
|
|
63
|
+
output: `
|
|
64
|
+
<template>
|
|
65
|
+
<bento-tag label="Label text" />
|
|
66
|
+
</template>
|
|
67
|
+
`,
|
|
68
|
+
errors: [{ message: '"default" slot is deprecated in favor of the "label" property' }],
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: 'BentoTag with property as child',
|
|
72
|
+
code: `
|
|
73
|
+
<template>
|
|
74
|
+
<bento-tag>
|
|
75
|
+
{{ thisIsMyVariableWithText }}
|
|
76
|
+
</bento-tag>
|
|
77
|
+
</template>
|
|
78
|
+
`,
|
|
79
|
+
output: `
|
|
80
|
+
<template>
|
|
81
|
+
<bento-tag :label="thisIsMyVariableWithText" />
|
|
82
|
+
</template>
|
|
83
|
+
`,
|
|
84
|
+
errors: [{ message: '"default" slot is deprecated in favor of the "label" property' }],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: 'BentoTag with text and property as child',
|
|
88
|
+
code: `
|
|
89
|
+
<template>
|
|
90
|
+
<bento-tag>
|
|
91
|
+
Value: {{ thisIsAValue }}
|
|
92
|
+
</bento-tag>
|
|
93
|
+
</template>
|
|
94
|
+
`,
|
|
95
|
+
output: `
|
|
96
|
+
<template>
|
|
97
|
+
<bento-tag :label="\`Value: \${thisIsAValue}\`" />
|
|
98
|
+
</template>
|
|
99
|
+
`,
|
|
100
|
+
errors: [{ message: '"default" slot is deprecated in favor of the "label" property' }],
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: 'BentoTag with text and expression with a call',
|
|
104
|
+
code: `
|
|
105
|
+
<template>
|
|
106
|
+
<bento-tag>
|
|
107
|
+
Value: {{ thisIsAValue() }}
|
|
108
|
+
</bento-tag>
|
|
109
|
+
</template>
|
|
110
|
+
`,
|
|
111
|
+
output: `
|
|
112
|
+
<template>
|
|
113
|
+
<bento-tag :label="\`Value: \${thisIsAValue()}\`" />
|
|
114
|
+
</template>
|
|
115
|
+
`,
|
|
116
|
+
errors: [{ message: '"default" slot is deprecated in favor of the "label" property' }],
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: 'BentoTag with multiple expressions',
|
|
120
|
+
code: `
|
|
121
|
+
<template>
|
|
122
|
+
<bento-tag>
|
|
123
|
+
{{ expression }} {{ thisIsAValue() }}
|
|
124
|
+
</bento-tag>
|
|
125
|
+
</template>
|
|
126
|
+
`,
|
|
127
|
+
output: `
|
|
128
|
+
<template>
|
|
129
|
+
<bento-tag :label="\`\${expression} \${thisIsAValue()}\`" />
|
|
130
|
+
</template>
|
|
131
|
+
`,
|
|
132
|
+
errors: [{ message: '"default" slot is deprecated in favor of the "label" property' }],
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
});
|
|
136
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
const j = require('jscodeshift');
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
/**
|
|
5
|
+
* Generates a report with a fix to those VElements containing a deprecated default slot.
|
|
6
|
+
*
|
|
7
|
+
* It moves the content of the "default" slot into a prop with the "propertyName" value.
|
|
8
|
+
*
|
|
9
|
+
* @param props Contains the name of the property by which it will be replace and the context
|
|
10
|
+
*/
|
|
11
|
+
componentSlotMigration({ propertyName, context, template, alwaysExpression = false }) {
|
|
12
|
+
return node => {
|
|
13
|
+
if (!node.children.length) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Turned true if one of the children is an expression
|
|
18
|
+
let hasExpression = false;
|
|
19
|
+
|
|
20
|
+
function transformNodeToText(node, wrapStringLiteral = false) {
|
|
21
|
+
if (node.type === 'VText') {
|
|
22
|
+
return node.value;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (node.type === 'VExpressionContainer') {
|
|
26
|
+
hasExpression = true;
|
|
27
|
+
if (['CallExpression', 'MemberExpression', 'Identifier'].includes(node.expression?.type || '')) {
|
|
28
|
+
const expression = j(node.expression).toSource();
|
|
29
|
+
return wrapStringLiteral ? `\${${expression}}` : expression;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function removeEmptyVTextNodes(node) {
|
|
35
|
+
if (node.type === 'VText') {
|
|
36
|
+
return !!node.value.trim().length;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Opening tag closing brace ">"
|
|
43
|
+
const closingBrace = template.getLastToken(node.startTag);
|
|
44
|
+
|
|
45
|
+
// Remove empty nodes
|
|
46
|
+
const filteredNodes = node.children.filter(removeEmptyVTextNodes);
|
|
47
|
+
|
|
48
|
+
// Get all content and concat
|
|
49
|
+
const slotContent = (() => {
|
|
50
|
+
if (filteredNodes.length === 1) {
|
|
51
|
+
return transformNodeToText(filteredNodes[0])?.trim();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const content = node.children
|
|
55
|
+
.map(node => transformNodeToText(node, true))
|
|
56
|
+
.join('')
|
|
57
|
+
.trim();
|
|
58
|
+
|
|
59
|
+
return `\`${content}\``;
|
|
60
|
+
})();
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Formats an attribute name into an expression (:attribute) or a value (attribute)
|
|
64
|
+
* for the Vue template.
|
|
65
|
+
* @returns formatted attribute name
|
|
66
|
+
*/
|
|
67
|
+
function attributeFormat() {
|
|
68
|
+
if (alwaysExpression) {
|
|
69
|
+
return `:${propertyName}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return hasExpression ? `:${propertyName}` : propertyName;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
context.report({
|
|
76
|
+
node,
|
|
77
|
+
loc: node.loc,
|
|
78
|
+
messageId: 'migrateDefaultSlot',
|
|
79
|
+
*fix(fixer) {
|
|
80
|
+
const attribute = attributeFormat();
|
|
81
|
+
// Add attribute at the end of opening tag
|
|
82
|
+
yield fixer.insertTextBefore(closingBrace, ` ${attribute}="${slotContent}" /`);
|
|
83
|
+
|
|
84
|
+
// Remove everything after the closing brace
|
|
85
|
+
yield fixer.removeRange([closingBrace.range[0] + 1, node.range[1]]);
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
};
|