@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 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",
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.4",
22
+ "@vitest/coverage-v8": "2.1.9",
22
23
  "eslint": "8.57.1",
23
- "vitest": "2.1.4",
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,8 @@
1
+ module.exports = {
2
+ env: { es2021: true },
3
+ parser: 'vue-eslint-parser',
4
+ plugins: ['@adyen/bento'],
5
+ rules: {
6
+ '@adyen/bento/deprecation-currency-default-slot': 'warn',
7
+ },
8
+ };
@@ -0,0 +1,7 @@
1
+ <template>
2
+ <bento-currency>
3
+ {{ thisIsMyVariableWithCurrencyValue }}
4
+ </bento-currency>
5
+ </template>
6
+
7
+ <script setup></script>
@@ -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,8 @@
1
+ module.exports = {
2
+ env: { es2021: true },
3
+ parser: 'vue-eslint-parser',
4
+ plugins: ['@adyen/bento'],
5
+ rules: {
6
+ '@adyen/bento/deprecation-tag-default-slot': 'warn',
7
+ },
8
+ };
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <bento-tag>Value: {{ thisIsAValue }}</bento-tag>
3
+ </template>
4
+
5
+ <script setup></script>
@@ -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
+ };