eslint-plugin-primer-react 5.4.0-rc.61b506f → 5.5.0-rc.40574df
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 +6 -0
- package/docs/rules/use-deprecated-from-deprecated.md +25 -0
- package/package-lock.json +28 -28
- package/package.json +1 -1
- package/src/index.js +1 -0
- package/src/rules/__tests__/use-deprecated-from-deprecated.test.js +66 -0
- package/src/rules/use-deprecated-from-deprecated.js +130 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# eslint-plugin-primer-react
|
|
2
2
|
|
|
3
|
+
## 5.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#204](https://github.com/primer/eslint-plugin-primer-react/pull/204) [`e2cab87`](https://github.com/primer/eslint-plugin-primer-react/commit/e2cab872c265f4211750436fad32fe5fd8927c5c) Thanks [@joshblack](https://github.com/joshblack)! - Add use-deprecated-from-deprecated rule
|
|
8
|
+
|
|
3
9
|
## 5.4.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Use Deprecated from Deprecated
|
|
2
|
+
|
|
3
|
+
## Rule Details
|
|
4
|
+
|
|
5
|
+
This rule enforces the usage of deprecated imports from `@primer/react/deprecated`.
|
|
6
|
+
|
|
7
|
+
👎 Examples of **incorrect** code for this rule
|
|
8
|
+
|
|
9
|
+
```jsx
|
|
10
|
+
import {Dialog} from '@primer/react'
|
|
11
|
+
|
|
12
|
+
function ExampleComponent() {
|
|
13
|
+
return <Dialog>{/* ... */}</Dialog>
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
👍 Examples of **correct** code for this rule:
|
|
18
|
+
|
|
19
|
+
```jsx
|
|
20
|
+
import {Dialog} from '@primer/react/deprecated'
|
|
21
|
+
|
|
22
|
+
function ExampleComponent() {
|
|
23
|
+
return <Dialog>{/* ... */}</Dialog>
|
|
24
|
+
}
|
|
25
|
+
```
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-primer-react",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.4.0",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "eslint-plugin-primer-react",
|
|
9
|
-
"version": "5.
|
|
9
|
+
"version": "5.4.0",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@styled-system/props": "^5.1.5",
|
|
@@ -1890,9 +1890,9 @@
|
|
|
1890
1890
|
}
|
|
1891
1891
|
},
|
|
1892
1892
|
"node_modules/@pkgr/core": {
|
|
1893
|
-
"version": "0.1.
|
|
1894
|
-
"resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.
|
|
1895
|
-
"integrity": "sha512-
|
|
1893
|
+
"version": "0.1.1",
|
|
1894
|
+
"resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz",
|
|
1895
|
+
"integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==",
|
|
1896
1896
|
"engines": {
|
|
1897
1897
|
"node": "^12.20.0 || ^14.18.0 || >=16.0.0"
|
|
1898
1898
|
},
|
|
@@ -3862,12 +3862,12 @@
|
|
|
3862
3862
|
}
|
|
3863
3863
|
},
|
|
3864
3864
|
"node_modules/eslint-plugin-prettier": {
|
|
3865
|
-
"version": "5.1
|
|
3866
|
-
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.
|
|
3867
|
-
"integrity": "sha512-
|
|
3865
|
+
"version": "5.2.1",
|
|
3866
|
+
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz",
|
|
3867
|
+
"integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==",
|
|
3868
3868
|
"dependencies": {
|
|
3869
3869
|
"prettier-linter-helpers": "^1.0.0",
|
|
3870
|
-
"synckit": "^0.
|
|
3870
|
+
"synckit": "^0.9.1"
|
|
3871
3871
|
},
|
|
3872
3872
|
"engines": {
|
|
3873
3873
|
"node": "^14.18.0 || >=16.0.0"
|
|
@@ -7631,9 +7631,9 @@
|
|
|
7631
7631
|
}
|
|
7632
7632
|
},
|
|
7633
7633
|
"node_modules/synckit": {
|
|
7634
|
-
"version": "0.
|
|
7635
|
-
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.
|
|
7636
|
-
"integrity": "sha512-
|
|
7634
|
+
"version": "0.9.1",
|
|
7635
|
+
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz",
|
|
7636
|
+
"integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==",
|
|
7637
7637
|
"dependencies": {
|
|
7638
7638
|
"@pkgr/core": "^0.1.0",
|
|
7639
7639
|
"tslib": "^2.6.2"
|
|
@@ -7762,9 +7762,9 @@
|
|
|
7762
7762
|
}
|
|
7763
7763
|
},
|
|
7764
7764
|
"node_modules/tslib": {
|
|
7765
|
-
"version": "2.6.
|
|
7766
|
-
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.
|
|
7767
|
-
"integrity": "sha512-
|
|
7765
|
+
"version": "2.6.3",
|
|
7766
|
+
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
|
|
7767
|
+
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
|
|
7768
7768
|
},
|
|
7769
7769
|
"node_modules/type-detect": {
|
|
7770
7770
|
"version": "4.0.8",
|
|
@@ -9682,9 +9682,9 @@
|
|
|
9682
9682
|
}
|
|
9683
9683
|
},
|
|
9684
9684
|
"@pkgr/core": {
|
|
9685
|
-
"version": "0.1.
|
|
9686
|
-
"resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.
|
|
9687
|
-
"integrity": "sha512-
|
|
9685
|
+
"version": "0.1.1",
|
|
9686
|
+
"resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz",
|
|
9687
|
+
"integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA=="
|
|
9688
9688
|
},
|
|
9689
9689
|
"@sinclair/typebox": {
|
|
9690
9690
|
"version": "0.27.8",
|
|
@@ -11264,12 +11264,12 @@
|
|
|
11264
11264
|
"integrity": "sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw=="
|
|
11265
11265
|
},
|
|
11266
11266
|
"eslint-plugin-prettier": {
|
|
11267
|
-
"version": "5.1
|
|
11268
|
-
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.
|
|
11269
|
-
"integrity": "sha512-
|
|
11267
|
+
"version": "5.2.1",
|
|
11268
|
+
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz",
|
|
11269
|
+
"integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==",
|
|
11270
11270
|
"requires": {
|
|
11271
11271
|
"prettier-linter-helpers": "^1.0.0",
|
|
11272
|
-
"synckit": "^0.
|
|
11272
|
+
"synckit": "^0.9.1"
|
|
11273
11273
|
}
|
|
11274
11274
|
},
|
|
11275
11275
|
"eslint-rule-documentation": {
|
|
@@ -13821,9 +13821,9 @@
|
|
|
13821
13821
|
"integrity": "sha512-Bh05dSOnJBf3miNMqpsormfNtfidA/GxQVakhtn0T4DECWKeXQRQUceYjJ+OxYiiLdGe4Jo9iFV8wICFapFeIA=="
|
|
13822
13822
|
},
|
|
13823
13823
|
"synckit": {
|
|
13824
|
-
"version": "0.
|
|
13825
|
-
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.
|
|
13826
|
-
"integrity": "sha512-
|
|
13824
|
+
"version": "0.9.1",
|
|
13825
|
+
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz",
|
|
13826
|
+
"integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==",
|
|
13827
13827
|
"requires": {
|
|
13828
13828
|
"@pkgr/core": "^0.1.0",
|
|
13829
13829
|
"tslib": "^2.6.2"
|
|
@@ -13919,9 +13919,9 @@
|
|
|
13919
13919
|
}
|
|
13920
13920
|
},
|
|
13921
13921
|
"tslib": {
|
|
13922
|
-
"version": "2.6.
|
|
13923
|
-
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.
|
|
13924
|
-
"integrity": "sha512-
|
|
13922
|
+
"version": "2.6.3",
|
|
13923
|
+
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
|
|
13924
|
+
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
|
|
13925
13925
|
},
|
|
13926
13926
|
"type-detect": {
|
|
13927
13927
|
"version": "4.0.8",
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -10,6 +10,7 @@ module.exports = {
|
|
|
10
10
|
'a11y-link-in-text-block': require('./rules/a11y-link-in-text-block'),
|
|
11
11
|
'a11y-remove-disable-tooltip': require('./rules/a11y-remove-disable-tooltip'),
|
|
12
12
|
'a11y-use-next-tooltip': require('./rules/a11y-use-next-tooltip'),
|
|
13
|
+
'use-deprecated-from-deprecated': require('./rules/use-deprecated-from-deprecated'),
|
|
13
14
|
},
|
|
14
15
|
configs: {
|
|
15
16
|
recommended: require('./configs/recommended'),
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {RuleTester} = require('eslint')
|
|
4
|
+
const rule = require('../use-deprecated-from-deprecated')
|
|
5
|
+
|
|
6
|
+
const ruleTester = new RuleTester({
|
|
7
|
+
parserOptions: {
|
|
8
|
+
ecmaVersion: 'latest',
|
|
9
|
+
sourceType: 'module',
|
|
10
|
+
ecmaFeatures: {
|
|
11
|
+
jsx: true,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
ruleTester.run('use-deprecated-from-deprecated', rule, {
|
|
17
|
+
valid: [],
|
|
18
|
+
invalid: [
|
|
19
|
+
// Single deprecated import
|
|
20
|
+
{
|
|
21
|
+
code: `import {Tooltip} from '@primer/react'`,
|
|
22
|
+
output: `import {Tooltip} from '@primer/react/deprecated'`,
|
|
23
|
+
errors: ['Import deprecated components from @primer/react/deprecated'],
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
// Single deprecated import with existing deprecated entrypoint
|
|
27
|
+
{
|
|
28
|
+
code: `import {Tooltip} from '@primer/react'
|
|
29
|
+
import {Dialog} from '@primer/react/deprecated'`,
|
|
30
|
+
output: `\nimport {Dialog, Tooltip} from '@primer/react/deprecated'`,
|
|
31
|
+
errors: ['Import deprecated components from @primer/react/deprecated'],
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
// Multiple deprecated imports
|
|
35
|
+
{
|
|
36
|
+
code: `import {Dialog, Tooltip} from '@primer/react'`,
|
|
37
|
+
output: `import {Dialog, Tooltip} from '@primer/react/deprecated'`,
|
|
38
|
+
errors: ['Import deprecated components from @primer/react/deprecated'],
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
// Mixed deprecated and non-deprecated imports
|
|
42
|
+
{
|
|
43
|
+
code: `import {Button, Tooltip} from '@primer/react'`,
|
|
44
|
+
output: `import {Button, } from '@primer/react'
|
|
45
|
+
import {Tooltip} from '@primer/react/deprecated'`,
|
|
46
|
+
errors: ['Import deprecated components from @primer/react/deprecated'],
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
// Mixed deprecated and non-deprecated imports with existing deprecated
|
|
50
|
+
{
|
|
51
|
+
code: `import {Button, Tooltip} from '@primer/react'
|
|
52
|
+
import {Dialog} from '@primer/react/deprecated'`,
|
|
53
|
+
output: `import {Button, } from '@primer/react'
|
|
54
|
+
import {Dialog, Tooltip} from '@primer/react/deprecated'`,
|
|
55
|
+
errors: ['Import deprecated components from @primer/react/deprecated'],
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
// Multiple mixed deprecated and non-deprecated imports
|
|
59
|
+
{
|
|
60
|
+
code: `import {Button, Dialog, Tooltip} from '@primer/react'`,
|
|
61
|
+
output: `import {Button, } from '@primer/react'
|
|
62
|
+
import {Dialog, Tooltip} from '@primer/react/deprecated'`,
|
|
63
|
+
errors: ['Import deprecated components from @primer/react/deprecated'],
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
})
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const url = require('../url')
|
|
4
|
+
|
|
5
|
+
const components = [
|
|
6
|
+
{
|
|
7
|
+
identifier: 'Dialog',
|
|
8
|
+
entrypoint: '@primer/react',
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
identifier: 'Octicon',
|
|
12
|
+
entrypoint: '@primer/react',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
identifier: 'Pagehead',
|
|
16
|
+
entrypoint: '@primer/react',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
identifier: 'TabNav',
|
|
20
|
+
entrypoint: '@primer/react',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
identifier: 'Tooltip',
|
|
24
|
+
entrypoint: '@primer/react',
|
|
25
|
+
},
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
const entrypoints = new Map()
|
|
29
|
+
|
|
30
|
+
for (const component of components) {
|
|
31
|
+
if (!entrypoints.has(component.entrypoint)) {
|
|
32
|
+
entrypoints.set(component.entrypoint, new Set())
|
|
33
|
+
}
|
|
34
|
+
entrypoints.get(component.entrypoint).add(component.identifier)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @type {import('eslint').Rule.RuleModule}
|
|
39
|
+
*/
|
|
40
|
+
module.exports = {
|
|
41
|
+
meta: {
|
|
42
|
+
type: 'problem',
|
|
43
|
+
docs: {
|
|
44
|
+
description: 'Use deprecated components from the `@primer/react/deprecated` entrypoint',
|
|
45
|
+
recommended: true,
|
|
46
|
+
url: url(module),
|
|
47
|
+
},
|
|
48
|
+
fixable: true,
|
|
49
|
+
schema: [],
|
|
50
|
+
},
|
|
51
|
+
create(context) {
|
|
52
|
+
const sourceCode = context.getSourceCode()
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
ImportDeclaration(node) {
|
|
56
|
+
if (!entrypoints.has(node.source.value)) {
|
|
57
|
+
return
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const entrypoint = entrypoints.get(node.source.value)
|
|
61
|
+
const deprecated = node.specifiers.filter(specifier => {
|
|
62
|
+
return entrypoint.has(specifier.imported.name)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
if (deprecated.length === 0) {
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const deprecatedEntrypoint = node.parent.body.find(node => {
|
|
70
|
+
if (node.type !== 'ImportDeclaration') {
|
|
71
|
+
return false
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return node.source.value === '@primer/react/deprecated'
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
// All imports are deprecated
|
|
78
|
+
if (deprecated.length === node.specifiers.length) {
|
|
79
|
+
context.report({
|
|
80
|
+
node,
|
|
81
|
+
message: 'Import deprecated components from @primer/react/deprecated',
|
|
82
|
+
*fix(fixer) {
|
|
83
|
+
if (deprecatedEntrypoint) {
|
|
84
|
+
const lastSpecifier = deprecatedEntrypoint.specifiers[deprecatedEntrypoint.specifiers.length - 1]
|
|
85
|
+
|
|
86
|
+
yield fixer.remove(node)
|
|
87
|
+
yield fixer.insertTextAfter(
|
|
88
|
+
lastSpecifier,
|
|
89
|
+
`, ${node.specifiers.map(specifier => specifier.imported.name).join(', ')}`,
|
|
90
|
+
)
|
|
91
|
+
} else {
|
|
92
|
+
yield fixer.replaceText(node.source, `'@primer/react/deprecated'`)
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
})
|
|
96
|
+
} else {
|
|
97
|
+
// There is a mix of deprecated and non-deprecated imports
|
|
98
|
+
context.report({
|
|
99
|
+
node,
|
|
100
|
+
message: 'Import deprecated components from @primer/react/deprecated',
|
|
101
|
+
*fix(fixer) {
|
|
102
|
+
for (const specifier of deprecated) {
|
|
103
|
+
yield fixer.remove(specifier)
|
|
104
|
+
const comma = sourceCode.getTokenAfter(specifier)
|
|
105
|
+
if (comma.value === ',') {
|
|
106
|
+
yield fixer.remove(comma)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (deprecatedEntrypoint) {
|
|
111
|
+
const lastSpecifier = deprecatedEntrypoint.specifiers[deprecatedEntrypoint.specifiers.length - 1]
|
|
112
|
+
yield fixer.insertTextAfter(
|
|
113
|
+
lastSpecifier,
|
|
114
|
+
`, ${deprecated.map(specifier => specifier.imported.name).join(', ')}`,
|
|
115
|
+
)
|
|
116
|
+
} else {
|
|
117
|
+
yield fixer.insertTextAfter(
|
|
118
|
+
node,
|
|
119
|
+
`\nimport {${deprecated
|
|
120
|
+
.map(specifier => specifier.imported.name)
|
|
121
|
+
.join(', ')}} from '@primer/react/deprecated'`,
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
})
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
}
|