@atlaskit/side-navigation 6.0.1 → 6.0.2
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
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @atlaskit/side-navigation
|
|
2
2
|
|
|
3
|
+
## 6.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#124556](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/124556)
|
|
8
|
+
[`48adeb70784c5`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/48adeb70784c5) -
|
|
9
|
+
Updated dependencies and removed old codemods.
|
|
10
|
+
|
|
3
11
|
## 6.0.1
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/side-navigation",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.2",
|
|
4
4
|
"description": "A highly composable side navigation component that supports nested views.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
"@atlaskit/ds-lib": "^4.0.0",
|
|
37
37
|
"@atlaskit/icon": "^24.1.0",
|
|
38
38
|
"@atlaskit/menu": "^3.1.0",
|
|
39
|
-
"@atlaskit/motion": "^5.
|
|
39
|
+
"@atlaskit/motion": "^5.1.0",
|
|
40
40
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
41
41
|
"@atlaskit/primitives": "^14.1.0",
|
|
42
42
|
"@atlaskit/theme": "^18.0.0",
|
|
43
|
-
"@atlaskit/tokens": "^4.
|
|
43
|
+
"@atlaskit/tokens": "^4.4.0",
|
|
44
44
|
"@babel/runtime": "^7.0.0",
|
|
45
45
|
"@compiled/react": "^0.18.2"
|
|
46
46
|
},
|
|
@@ -48,18 +48,28 @@
|
|
|
48
48
|
"react": "^18.2.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@af/accessibility-testing": "
|
|
52
|
-
"@af/integration-testing": "
|
|
53
|
-
"@af/visual-regression": "
|
|
54
|
-
"@atlaskit/
|
|
55
|
-
"@
|
|
51
|
+
"@af/accessibility-testing": "^2.0.0",
|
|
52
|
+
"@af/integration-testing": "^0.5.0",
|
|
53
|
+
"@af/visual-regression": "^1.3.0",
|
|
54
|
+
"@atlaskit/atlassian-navigation": "^5.0.0",
|
|
55
|
+
"@atlaskit/button": "^21.1.0",
|
|
56
|
+
"@atlaskit/docs": "^10.0.0",
|
|
57
|
+
"@atlaskit/dropdown-menu": "^13.0.0",
|
|
58
|
+
"@atlaskit/form": "^12.0.0",
|
|
59
|
+
"@atlaskit/image": "^2.0.0",
|
|
60
|
+
"@atlaskit/link": "^3.0.0",
|
|
61
|
+
"@atlaskit/logo": "^16.0.0",
|
|
62
|
+
"@atlaskit/onboarding": "^13.0.0",
|
|
63
|
+
"@atlaskit/pragmatic-drag-and-drop": "^1.5.0",
|
|
64
|
+
"@atlaskit/pragmatic-drag-and-drop-live-region": "^1.3.0",
|
|
65
|
+
"@atlaskit/pragmatic-drag-and-drop-react-accessibility": "^2.0.0",
|
|
66
|
+
"@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^2.2.0",
|
|
67
|
+
"@atlaskit/section-message": "^8.1.0",
|
|
68
|
+
"@atlaskit/select": "^20.0.0",
|
|
69
|
+
"@atlaskit/visual-regression": "^0.10.0",
|
|
56
70
|
"@testing-library/react": "^13.4.0",
|
|
57
|
-
"@types/jest-axe": "^3.5.5",
|
|
58
|
-
"ast-types": "^0.13.3",
|
|
59
|
-
"jest-axe": "^8.0.0",
|
|
60
|
-
"jest-emotion": "^10.0.32",
|
|
61
|
-
"jscodeshift": "^0.13.0",
|
|
62
71
|
"raf-stub": "^2.0.1",
|
|
72
|
+
"tiny-invariant": "^1.2.0",
|
|
63
73
|
"typescript": "~5.4.2"
|
|
64
74
|
},
|
|
65
75
|
"techstack": {
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import { type NodePath } from 'ast-types/lib/node-path';
|
|
2
|
-
import {
|
|
3
|
-
type API,
|
|
4
|
-
type ASTPath,
|
|
5
|
-
type default as core,
|
|
6
|
-
type FileInfo,
|
|
7
|
-
type ImportDeclaration,
|
|
8
|
-
type ImportSpecifier,
|
|
9
|
-
type Options,
|
|
10
|
-
} from 'jscodeshift';
|
|
11
|
-
|
|
12
|
-
import { addCommentBeforeJSX, getDefaultSpecifierName } from './helpers/generic';
|
|
13
|
-
|
|
14
|
-
function getJSXAttributesByName(j: core.JSCodeshift, element: ASTPath<any>, attributeName: string) {
|
|
15
|
-
return j(element)
|
|
16
|
-
.find(j.JSXOpeningElement)
|
|
17
|
-
.find(j.JSXAttribute)
|
|
18
|
-
.filter((attribute) => {
|
|
19
|
-
const matches = j(attribute)
|
|
20
|
-
.find(j.JSXIdentifier)
|
|
21
|
-
.filter((identifier) => identifier.value.name === attributeName);
|
|
22
|
-
return Boolean(matches.length);
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function getImportSpecifier(
|
|
27
|
-
j: core.JSCodeshift,
|
|
28
|
-
source: ReturnType<typeof j>,
|
|
29
|
-
specifier: string,
|
|
30
|
-
imported: string,
|
|
31
|
-
) {
|
|
32
|
-
const specifiers = source
|
|
33
|
-
.find(j.ImportDeclaration)
|
|
34
|
-
.filter((path: ASTPath<ImportDeclaration>) => path.node.source.value === specifier)
|
|
35
|
-
.find(j.ImportSpecifier)
|
|
36
|
-
.filter((path: ASTPath<ImportSpecifier>) => path.value.imported.name === imported);
|
|
37
|
-
|
|
38
|
-
if (!specifiers.length) {
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return specifiers.nodes()[0]!.local!.name;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function updateCssFnProp(j: core.JSCodeshift, source: ReturnType<typeof j>, specifier: string) {
|
|
46
|
-
source.findJSXElements(specifier).forEach((element) => {
|
|
47
|
-
const cssFnPropCollection = getJSXAttributesByName(j, element, 'cssFn');
|
|
48
|
-
|
|
49
|
-
// no cssProp usage for this element
|
|
50
|
-
if (!cssFnPropCollection.length) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const cssFnProp = cssFnPropCollection.get();
|
|
55
|
-
|
|
56
|
-
const cssFnExpression: NodePath = j(cssFnProp)
|
|
57
|
-
.find(j.JSXExpressionContainer)
|
|
58
|
-
.find(j.Expression)
|
|
59
|
-
.get();
|
|
60
|
-
|
|
61
|
-
if (cssFnExpression) {
|
|
62
|
-
// just remove the state styles param
|
|
63
|
-
try {
|
|
64
|
-
const [stylePropName] = cssFnExpression!.value.params;
|
|
65
|
-
j(cssFnExpression)
|
|
66
|
-
.find(j.SpreadElement)
|
|
67
|
-
.forEach((n) => {
|
|
68
|
-
// discerns whether there are multiple identifiers here
|
|
69
|
-
const isComplexIdentifier = j(n).find(j.Identifier).length > 1;
|
|
70
|
-
|
|
71
|
-
if (isComplexIdentifier) {
|
|
72
|
-
throw new Error('CSSFn Prop codemod: Unable to parse spread element');
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const hasStyleProp = !!j(n)
|
|
76
|
-
.find(j.Identifier)
|
|
77
|
-
.filter((node) => node.value.name === stylePropName.name).length;
|
|
78
|
-
if (hasStyleProp) {
|
|
79
|
-
j(n).remove();
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
cssFnExpression!.value.params.shift();
|
|
84
|
-
} catch (e) {
|
|
85
|
-
addCommentBeforeJSX(
|
|
86
|
-
j,
|
|
87
|
-
cssFnProp,
|
|
88
|
-
`
|
|
89
|
-
The usage of the 'cssFn' prop in this component could not be transformed and requires manual intervention.
|
|
90
|
-
The 'cssFn' prop has been simplified so that users no longer need to merge the inherited styles with their own overrides.
|
|
91
|
-
For more info please reach out to #help-design-system-code.
|
|
92
|
-
`,
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function hasImportDeclaration(
|
|
100
|
-
j: core.JSCodeshift,
|
|
101
|
-
source: ReturnType<typeof j>,
|
|
102
|
-
importPath: string,
|
|
103
|
-
) {
|
|
104
|
-
return !!source.find(j.ImportDeclaration).filter((path) => path.node.source.value === importPath)
|
|
105
|
-
.length;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export default function transformer(fileInfo: FileInfo, { jscodeshift: j }: API, options: Options) {
|
|
109
|
-
const source = j(fileInfo.source);
|
|
110
|
-
|
|
111
|
-
if (hasImportDeclaration(j, source, '@atlaskit/side-navigation')) {
|
|
112
|
-
const defaultSpecifier = getDefaultSpecifierName({
|
|
113
|
-
j,
|
|
114
|
-
base: source,
|
|
115
|
-
packageName: '@atlaskit/side-navigation',
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
if (defaultSpecifier != null) {
|
|
119
|
-
updateCssFnProp(j, source, defaultSpecifier);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
[
|
|
123
|
-
'SideNavigation',
|
|
124
|
-
'Header',
|
|
125
|
-
'NavigationHeader',
|
|
126
|
-
'NavigationContent',
|
|
127
|
-
'Section',
|
|
128
|
-
'HeadingItem',
|
|
129
|
-
'SkeletonHeadingItem',
|
|
130
|
-
'NestableNavigationContent',
|
|
131
|
-
'NestingItem',
|
|
132
|
-
'ButtonItem',
|
|
133
|
-
'LinkItem',
|
|
134
|
-
'GoBackItem',
|
|
135
|
-
'CustomItem',
|
|
136
|
-
'SkeletonItem',
|
|
137
|
-
'Footer',
|
|
138
|
-
'NavigationFooter',
|
|
139
|
-
'LoadingItems',
|
|
140
|
-
].forEach((pkg) => {
|
|
141
|
-
const importSpecifier = getImportSpecifier(j, source, '@atlaskit/side-navigation', pkg);
|
|
142
|
-
|
|
143
|
-
if (importSpecifier != null) {
|
|
144
|
-
updateCssFnProp(j, source, importSpecifier);
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
return source.toSource(
|
|
149
|
-
options.printOptions || {
|
|
150
|
-
quote: 'single',
|
|
151
|
-
trailingComma: true,
|
|
152
|
-
},
|
|
153
|
-
);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return fileInfo.source;
|
|
157
|
-
}
|
|
@@ -1,360 +0,0 @@
|
|
|
1
|
-
jest.autoMockOff();
|
|
2
|
-
|
|
3
|
-
import * as transformer from '../0.8.0-change-css-fn-prop';
|
|
4
|
-
|
|
5
|
-
const defineInlineTest = require('jscodeshift/dist/testUtils').defineInlineTest;
|
|
6
|
-
|
|
7
|
-
describe('Updates and removes current inline styles', () => {
|
|
8
|
-
defineInlineTest(
|
|
9
|
-
{ ...transformer, parser: 'tsx' },
|
|
10
|
-
{},
|
|
11
|
-
`
|
|
12
|
-
import { ButtonItem } from '@atlaskit/something';
|
|
13
|
-
|
|
14
|
-
const App = () => {
|
|
15
|
-
return <ButtonItem />;
|
|
16
|
-
}
|
|
17
|
-
`,
|
|
18
|
-
`
|
|
19
|
-
import { ButtonItem } from '@atlaskit/something';
|
|
20
|
-
|
|
21
|
-
const App = () => {
|
|
22
|
-
return <ButtonItem />;
|
|
23
|
-
}
|
|
24
|
-
`,
|
|
25
|
-
'leaves unrelated code untouched',
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
defineInlineTest(
|
|
29
|
-
{ ...transformer, parser: 'tsx' },
|
|
30
|
-
{},
|
|
31
|
-
`
|
|
32
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
33
|
-
|
|
34
|
-
const App = () => {
|
|
35
|
-
return <ButtonItem cssFn={(styles, state) => ({
|
|
36
|
-
|
|
37
|
-
})} />;
|
|
38
|
-
}
|
|
39
|
-
`,
|
|
40
|
-
`
|
|
41
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
42
|
-
|
|
43
|
-
const App = () => {
|
|
44
|
-
return (
|
|
45
|
-
<ButtonItem cssFn={state => {
|
|
46
|
-
|
|
47
|
-
}} />
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
`,
|
|
51
|
-
'should remove current styles from inline function',
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
defineInlineTest(
|
|
55
|
-
{ ...transformer, parser: 'tsx' },
|
|
56
|
-
{},
|
|
57
|
-
`
|
|
58
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
59
|
-
|
|
60
|
-
const App = () => {
|
|
61
|
-
return (
|
|
62
|
-
<div cssFn={(styles, state) => ({
|
|
63
|
-
...styles,
|
|
64
|
-
})}>
|
|
65
|
-
<ButtonItem
|
|
66
|
-
cssFn={(styles, state) => ({
|
|
67
|
-
...styles,
|
|
68
|
-
})}
|
|
69
|
-
/>
|
|
70
|
-
</div>
|
|
71
|
-
);
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
`,
|
|
75
|
-
`
|
|
76
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
77
|
-
|
|
78
|
-
const App = () => {
|
|
79
|
-
return (
|
|
80
|
-
<div cssFn={(styles, state) => ({
|
|
81
|
-
...styles,
|
|
82
|
-
})}>
|
|
83
|
-
<ButtonItem
|
|
84
|
-
cssFn={state => ({})}
|
|
85
|
-
/>
|
|
86
|
-
</div>
|
|
87
|
-
);
|
|
88
|
-
};
|
|
89
|
-
`,
|
|
90
|
-
'should remove current styles from scope',
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
defineInlineTest(
|
|
94
|
-
{ ...transformer, parser: 'tsx' },
|
|
95
|
-
{},
|
|
96
|
-
`
|
|
97
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
98
|
-
|
|
99
|
-
const App = () => {
|
|
100
|
-
return <ButtonItem cssFn={(styles, state) => ({
|
|
101
|
-
...styles,
|
|
102
|
-
color: 'red',
|
|
103
|
-
})} />;
|
|
104
|
-
}
|
|
105
|
-
`,
|
|
106
|
-
`
|
|
107
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
108
|
-
|
|
109
|
-
const App = () => {
|
|
110
|
-
return (
|
|
111
|
-
<ButtonItem cssFn={state => ({
|
|
112
|
-
color: 'red',
|
|
113
|
-
})} />
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
`,
|
|
117
|
-
'correctly removes spread styles',
|
|
118
|
-
);
|
|
119
|
-
|
|
120
|
-
defineInlineTest(
|
|
121
|
-
{ ...transformer, parser: 'tsx' },
|
|
122
|
-
{},
|
|
123
|
-
`
|
|
124
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
125
|
-
|
|
126
|
-
const App = () => {
|
|
127
|
-
return <ButtonItem cssFn={(styles, state) => ({
|
|
128
|
-
...styles,
|
|
129
|
-
color: 'red',
|
|
130
|
-
':hover': {
|
|
131
|
-
...styles[':hover'],
|
|
132
|
-
color: 'blue',
|
|
133
|
-
}
|
|
134
|
-
})} />;
|
|
135
|
-
}
|
|
136
|
-
`,
|
|
137
|
-
`
|
|
138
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
139
|
-
|
|
140
|
-
const App = () => {
|
|
141
|
-
return (
|
|
142
|
-
<ButtonItem cssFn={state => ({
|
|
143
|
-
color: 'red',
|
|
144
|
-
|
|
145
|
-
':hover': {
|
|
146
|
-
color: 'blue',
|
|
147
|
-
},
|
|
148
|
-
})} />
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
`,
|
|
152
|
-
'correctly removes spread styles with pseudo-selector access',
|
|
153
|
-
);
|
|
154
|
-
|
|
155
|
-
defineInlineTest(
|
|
156
|
-
{ ...transformer, parser: 'tsx' },
|
|
157
|
-
{},
|
|
158
|
-
`
|
|
159
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
160
|
-
|
|
161
|
-
const App = () => {
|
|
162
|
-
return (
|
|
163
|
-
<ButtonItem cssFn={(styles, state) => ({
|
|
164
|
-
...(state.x ? styles : {}),
|
|
165
|
-
color: 'red',
|
|
166
|
-
})} />
|
|
167
|
-
);
|
|
168
|
-
}
|
|
169
|
-
`,
|
|
170
|
-
`
|
|
171
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
172
|
-
|
|
173
|
-
const App = () => {
|
|
174
|
-
return (
|
|
175
|
-
<ButtonItem
|
|
176
|
-
/*
|
|
177
|
-
TODO: (from codemod) The usage of the 'cssFn' prop in this component could not be transformed and requires manual intervention.
|
|
178
|
-
The 'cssFn' prop has been simplified so that users no longer need to merge the inherited styles with their own overrides.
|
|
179
|
-
For more info please reach out to #help-design-system-code.
|
|
180
|
-
*/
|
|
181
|
-
cssFn={(styles, state) => ({
|
|
182
|
-
...(state.x ? styles : {}),
|
|
183
|
-
color: 'red',
|
|
184
|
-
})} />
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
`,
|
|
188
|
-
'fail smoothly if the current styles are being used in a non-trivial way',
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
defineInlineTest(
|
|
192
|
-
{ ...transformer, parser: 'tsx' },
|
|
193
|
-
{},
|
|
194
|
-
`
|
|
195
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
196
|
-
|
|
197
|
-
const App = () => {
|
|
198
|
-
return <ButtonItem cssFn={() => ({
|
|
199
|
-
color: 'red',
|
|
200
|
-
})} />;
|
|
201
|
-
}
|
|
202
|
-
`,
|
|
203
|
-
`
|
|
204
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
205
|
-
|
|
206
|
-
const App = () => {
|
|
207
|
-
return <ButtonItem cssFn={() => ({
|
|
208
|
-
color: 'red',
|
|
209
|
-
})} />;
|
|
210
|
-
}
|
|
211
|
-
`,
|
|
212
|
-
'not change anything if user is not using the current state or styles',
|
|
213
|
-
);
|
|
214
|
-
|
|
215
|
-
defineInlineTest(
|
|
216
|
-
{ ...transformer, parser: 'tsx' },
|
|
217
|
-
{},
|
|
218
|
-
`
|
|
219
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
220
|
-
|
|
221
|
-
const App = () => {
|
|
222
|
-
return <ButtonItem cssFn={(styles, state) => ({
|
|
223
|
-
...styles,
|
|
224
|
-
color: 'red',
|
|
225
|
-
})}>
|
|
226
|
-
<ButtonItem cssFn={(styles, state) => ({
|
|
227
|
-
...styles,
|
|
228
|
-
color: 'red',
|
|
229
|
-
})}/>
|
|
230
|
-
</ButtonItem>;
|
|
231
|
-
}
|
|
232
|
-
`,
|
|
233
|
-
`
|
|
234
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
235
|
-
|
|
236
|
-
const App = () => {
|
|
237
|
-
return (
|
|
238
|
-
<ButtonItem cssFn={state => ({
|
|
239
|
-
color: 'red',
|
|
240
|
-
})}>
|
|
241
|
-
<ButtonItem cssFn={state => ({
|
|
242
|
-
color: 'red',
|
|
243
|
-
})}/>
|
|
244
|
-
</ButtonItem>
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
`,
|
|
248
|
-
'should remove styles in nested children',
|
|
249
|
-
);
|
|
250
|
-
|
|
251
|
-
defineInlineTest(
|
|
252
|
-
{ ...transformer, parser: 'tsx' },
|
|
253
|
-
{},
|
|
254
|
-
`
|
|
255
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
256
|
-
|
|
257
|
-
const App = () => {
|
|
258
|
-
return <ButtonItem />;
|
|
259
|
-
}
|
|
260
|
-
`,
|
|
261
|
-
`
|
|
262
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
263
|
-
|
|
264
|
-
const App = () => {
|
|
265
|
-
return <ButtonItem />;
|
|
266
|
-
}
|
|
267
|
-
`,
|
|
268
|
-
'should leave affected items with no use of cssFn untouched',
|
|
269
|
-
);
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
describe('Updates and removes current styles', () => {
|
|
273
|
-
defineInlineTest(
|
|
274
|
-
{ ...transformer, parser: 'tsx' },
|
|
275
|
-
{},
|
|
276
|
-
`
|
|
277
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
278
|
-
|
|
279
|
-
const cssFn = (styles, state) => ({
|
|
280
|
-
...styles,
|
|
281
|
-
color: 'red',
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
const App = () => {
|
|
285
|
-
return <ButtonItem cssFn={cssFn} />;
|
|
286
|
-
}
|
|
287
|
-
`,
|
|
288
|
-
`
|
|
289
|
-
import { ButtonItem } from '@atlaskit/side-navigation';
|
|
290
|
-
|
|
291
|
-
const cssFn = (styles, state) => ({
|
|
292
|
-
...styles,
|
|
293
|
-
color: 'red',
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
const App = () => {
|
|
297
|
-
return (
|
|
298
|
-
<ButtonItem
|
|
299
|
-
/*
|
|
300
|
-
TODO: (from codemod) The usage of the 'cssFn' prop in this component could not be transformed and requires manual intervention.
|
|
301
|
-
The 'cssFn' prop has been simplified so that users no longer need to merge the inherited styles with their own overrides.
|
|
302
|
-
For more info please reach out to #help-design-system-code.
|
|
303
|
-
*/
|
|
304
|
-
cssFn={cssFn} />
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
`,
|
|
308
|
-
'should add prompt for non-inline function',
|
|
309
|
-
);
|
|
310
|
-
|
|
311
|
-
defineInlineTest(
|
|
312
|
-
{ ...transformer, parser: 'tsx' },
|
|
313
|
-
{},
|
|
314
|
-
`
|
|
315
|
-
import { ButtonItem, LinkItem } from '@atlaskit/side-navigation';
|
|
316
|
-
|
|
317
|
-
const cssFunction = (styles, state) => ({
|
|
318
|
-
...styles,
|
|
319
|
-
color: 'red',
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
const App = () => {
|
|
323
|
-
return (
|
|
324
|
-
<ButtonItem cssFn={cssFunction}>
|
|
325
|
-
<LinkItem cssFn={cssFunction} />
|
|
326
|
-
</ButtonItem>
|
|
327
|
-
);
|
|
328
|
-
};
|
|
329
|
-
`,
|
|
330
|
-
`
|
|
331
|
-
import { ButtonItem, LinkItem } from '@atlaskit/side-navigation';
|
|
332
|
-
|
|
333
|
-
const cssFunction = (styles, state) => ({
|
|
334
|
-
...styles,
|
|
335
|
-
color: 'red',
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
const App = () => {
|
|
339
|
-
return (
|
|
340
|
-
<ButtonItem
|
|
341
|
-
/*
|
|
342
|
-
TODO: (from codemod) The usage of the 'cssFn' prop in this component could not be transformed and requires manual intervention.
|
|
343
|
-
The 'cssFn' prop has been simplified so that users no longer need to merge the inherited styles with their own overrides.
|
|
344
|
-
For more info please reach out to #help-design-system-code.
|
|
345
|
-
*/
|
|
346
|
-
cssFn={cssFunction}>
|
|
347
|
-
<LinkItem
|
|
348
|
-
/*
|
|
349
|
-
TODO: (from codemod) The usage of the 'cssFn' prop in this component could not be transformed and requires manual intervention.
|
|
350
|
-
The 'cssFn' prop has been simplified so that users no longer need to merge the inherited styles with their own overrides.
|
|
351
|
-
For more info please reach out to #help-design-system-code.
|
|
352
|
-
*/
|
|
353
|
-
cssFn={cssFunction} />
|
|
354
|
-
</ButtonItem>
|
|
355
|
-
);
|
|
356
|
-
};
|
|
357
|
-
`,
|
|
358
|
-
'should add prompt for non-inline function to multiple instances',
|
|
359
|
-
);
|
|
360
|
-
});
|
|
@@ -1,637 +0,0 @@
|
|
|
1
|
-
import { type NodePath } from 'ast-types/lib/node-path';
|
|
2
|
-
import {
|
|
3
|
-
type ASTPath,
|
|
4
|
-
type default as core,
|
|
5
|
-
type ImportDeclaration,
|
|
6
|
-
type ImportDefaultSpecifier,
|
|
7
|
-
type ImportSpecifier,
|
|
8
|
-
type JSXAttribute,
|
|
9
|
-
type JSXElement,
|
|
10
|
-
type Node,
|
|
11
|
-
type Program,
|
|
12
|
-
} from 'jscodeshift';
|
|
13
|
-
import { type Collection } from 'jscodeshift/src/Collection';
|
|
14
|
-
|
|
15
|
-
export type Nullable<T> = T | null;
|
|
16
|
-
|
|
17
|
-
export function hasImportDeclaration(
|
|
18
|
-
j: core.JSCodeshift,
|
|
19
|
-
source: string,
|
|
20
|
-
importPath: string,
|
|
21
|
-
): boolean {
|
|
22
|
-
return (
|
|
23
|
-
j(source)
|
|
24
|
-
.find(j.ImportDeclaration)
|
|
25
|
-
.filter((path: ASTPath<ImportDeclaration>) => path.node.source.value === importPath).length >
|
|
26
|
-
0
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function getDefaultSpecifierName({
|
|
31
|
-
j,
|
|
32
|
-
base,
|
|
33
|
-
packageName,
|
|
34
|
-
}: {
|
|
35
|
-
j: core.JSCodeshift;
|
|
36
|
-
base: Collection<any>;
|
|
37
|
-
packageName: string;
|
|
38
|
-
}): Nullable<string> {
|
|
39
|
-
const specifiers = base
|
|
40
|
-
.find(j.ImportDeclaration)
|
|
41
|
-
.filter((path) => path.node.source.value === packageName)
|
|
42
|
-
.find(j.ImportDefaultSpecifier);
|
|
43
|
-
|
|
44
|
-
if (!specifiers.length) {
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
return specifiers.nodes()[0]!.local!.name;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function getJSXAttributesByName({
|
|
51
|
-
j,
|
|
52
|
-
element,
|
|
53
|
-
attributeName,
|
|
54
|
-
}: {
|
|
55
|
-
j: core.JSCodeshift;
|
|
56
|
-
element: JSXElement;
|
|
57
|
-
attributeName: string;
|
|
58
|
-
}): Collection<JSXAttribute> {
|
|
59
|
-
return j(element)
|
|
60
|
-
.find(j.JSXOpeningElement)
|
|
61
|
-
.find(j.JSXAttribute)
|
|
62
|
-
.filter((attribute) => {
|
|
63
|
-
const matches = j(attribute)
|
|
64
|
-
// This will find identifiers on nested jsx elements
|
|
65
|
-
// so we are going to do a filter to ensure we are only
|
|
66
|
-
// going one level deep
|
|
67
|
-
.find(j.JSXIdentifier)
|
|
68
|
-
.filter((identifer) => {
|
|
69
|
-
j(identifer).closest(j.JSXOpeningElement);
|
|
70
|
-
// Checking we are on the same level as the jsx element
|
|
71
|
-
const closest = j(identifer).closest(j.JSXOpeningElement).nodes()[0];
|
|
72
|
-
|
|
73
|
-
if (!closest) {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
return (
|
|
77
|
-
closest.name.type === 'JSXIdentifier' &&
|
|
78
|
-
element.openingElement.name.type === 'JSXIdentifier' &&
|
|
79
|
-
element.openingElement.name.name === closest.name.name
|
|
80
|
-
);
|
|
81
|
-
})
|
|
82
|
-
.filter((identifier) => identifier.value.name === attributeName);
|
|
83
|
-
return Boolean(matches.length);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export function hasJSXAttributesByName({
|
|
88
|
-
j,
|
|
89
|
-
element,
|
|
90
|
-
attributeName,
|
|
91
|
-
}: {
|
|
92
|
-
j: core.JSCodeshift;
|
|
93
|
-
element: JSXElement;
|
|
94
|
-
attributeName: string;
|
|
95
|
-
}): boolean {
|
|
96
|
-
return getJSXAttributesByName({ j, element, attributeName }).length > 0;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export function removeImport({
|
|
100
|
-
j,
|
|
101
|
-
base,
|
|
102
|
-
packageName,
|
|
103
|
-
}: {
|
|
104
|
-
j: core.JSCodeshift;
|
|
105
|
-
base: Collection<any>;
|
|
106
|
-
packageName: string;
|
|
107
|
-
}) {
|
|
108
|
-
base
|
|
109
|
-
.find(j.ImportDeclaration)
|
|
110
|
-
.filter((path) => path.node.source.value === packageName)
|
|
111
|
-
.remove();
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
export function tryCreateImport({
|
|
115
|
-
j,
|
|
116
|
-
base,
|
|
117
|
-
relativeToPackage,
|
|
118
|
-
packageName,
|
|
119
|
-
}: {
|
|
120
|
-
j: core.JSCodeshift;
|
|
121
|
-
base: Collection<any>;
|
|
122
|
-
relativeToPackage: string;
|
|
123
|
-
packageName: string;
|
|
124
|
-
}) {
|
|
125
|
-
const exists: boolean =
|
|
126
|
-
base.find(j.ImportDeclaration).filter((path) => path.value.source.value === packageName)
|
|
127
|
-
.length > 0;
|
|
128
|
-
|
|
129
|
-
if (exists) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
base
|
|
134
|
-
.find(j.ImportDeclaration)
|
|
135
|
-
.filter((path) => path.value.source.value === relativeToPackage)
|
|
136
|
-
.insertBefore(j.importDeclaration([], j.literal(packageName)));
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export function addToImport({
|
|
140
|
-
j,
|
|
141
|
-
base,
|
|
142
|
-
importSpecifier,
|
|
143
|
-
packageName,
|
|
144
|
-
}: {
|
|
145
|
-
j: core.JSCodeshift;
|
|
146
|
-
base: Collection<any>;
|
|
147
|
-
importSpecifier: ImportSpecifier | ImportDefaultSpecifier;
|
|
148
|
-
packageName: string;
|
|
149
|
-
}) {
|
|
150
|
-
base
|
|
151
|
-
.find(j.ImportDeclaration)
|
|
152
|
-
.filter((path) => path.value.source.value === packageName)
|
|
153
|
-
.replaceWith((declaration) => {
|
|
154
|
-
return j.importDeclaration(
|
|
155
|
-
[
|
|
156
|
-
// we are appending to the existing specifiers
|
|
157
|
-
// We are doing a filter hear because sometimes specifiers can be removed
|
|
158
|
-
// but they hand around in the declaration
|
|
159
|
-
...(declaration.value.specifiers || []).filter(
|
|
160
|
-
(item) => item.type === 'ImportSpecifier' && item.imported != null,
|
|
161
|
-
),
|
|
162
|
-
importSpecifier,
|
|
163
|
-
],
|
|
164
|
-
j.literal(packageName),
|
|
165
|
-
);
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
export function doesIdentifierExist({
|
|
170
|
-
j,
|
|
171
|
-
base,
|
|
172
|
-
name,
|
|
173
|
-
}: {
|
|
174
|
-
j: core.JSCodeshift;
|
|
175
|
-
base: Collection<any>;
|
|
176
|
-
name: string;
|
|
177
|
-
}): boolean {
|
|
178
|
-
return base.find(j.Identifier).filter((identifer) => identifer.value.name === name).length > 0;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
export function isUsingSupportedSpread({
|
|
182
|
-
j,
|
|
183
|
-
base,
|
|
184
|
-
element,
|
|
185
|
-
}: {
|
|
186
|
-
j: core.JSCodeshift;
|
|
187
|
-
base: Collection<any>;
|
|
188
|
-
element: NodePath<JSXElement, JSXElement>;
|
|
189
|
-
}): boolean {
|
|
190
|
-
const isUsingSpread: boolean = j(element).find(j.JSXSpreadAttribute).length > 0;
|
|
191
|
-
|
|
192
|
-
if (!isUsingSpread) {
|
|
193
|
-
return true;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return (
|
|
197
|
-
j(element)
|
|
198
|
-
.find(j.JSXSpreadAttribute)
|
|
199
|
-
.filter((spread) => {
|
|
200
|
-
const argument = spread.value.argument;
|
|
201
|
-
// in place expression is supported
|
|
202
|
-
if (argument.type === 'ObjectExpression') {
|
|
203
|
-
return true;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Supporting identifiers that point to an a local object expression
|
|
207
|
-
if (argument.type === 'Identifier') {
|
|
208
|
-
return (
|
|
209
|
-
base.find(j.VariableDeclarator).filter((declarator): boolean => {
|
|
210
|
-
return Boolean(
|
|
211
|
-
declarator.value.id.type === 'Identifier' &&
|
|
212
|
-
declarator.value.init &&
|
|
213
|
-
declarator.value.init.type === 'ObjectExpression',
|
|
214
|
-
);
|
|
215
|
-
}).length > 0
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// We don't support anything else
|
|
220
|
-
return false;
|
|
221
|
-
}).length > 0
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
export function isOnlyUsingNameForJSX({
|
|
226
|
-
j,
|
|
227
|
-
base,
|
|
228
|
-
name,
|
|
229
|
-
}: {
|
|
230
|
-
j: core.JSCodeshift;
|
|
231
|
-
base: Collection<any>;
|
|
232
|
-
name: string;
|
|
233
|
-
}): boolean {
|
|
234
|
-
const jsxIdentifierCount: number = base
|
|
235
|
-
.find(j.JSXIdentifier)
|
|
236
|
-
.filter((identifier) => identifier.value.name === name).length;
|
|
237
|
-
|
|
238
|
-
// Not used in JSX at all
|
|
239
|
-
if (jsxIdentifierCount === 0) {
|
|
240
|
-
return false;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
const nonJSXIdentifierCount: number = base.find(j.Identifier).filter((identifier) => {
|
|
244
|
-
if (identifier.value.name !== name) {
|
|
245
|
-
return false;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// @ts-ignore
|
|
249
|
-
if (identifier.value.type === 'JSXIdentifier') {
|
|
250
|
-
return false;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// Excluding exports
|
|
254
|
-
if (j(identifier).closest(j.ImportDefaultSpecifier).length) {
|
|
255
|
-
return false;
|
|
256
|
-
}
|
|
257
|
-
if (j(identifier).closest(j.ImportSpecifier).length) {
|
|
258
|
-
return false;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
return true;
|
|
262
|
-
}).length;
|
|
263
|
-
|
|
264
|
-
if (nonJSXIdentifierCount > 0) {
|
|
265
|
-
return false;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
return true;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
export function getSafeImportName({
|
|
272
|
-
j,
|
|
273
|
-
base,
|
|
274
|
-
currentDefaultSpecifierName,
|
|
275
|
-
desiredName,
|
|
276
|
-
fallbackName,
|
|
277
|
-
}: {
|
|
278
|
-
j: core.JSCodeshift;
|
|
279
|
-
base: Collection<any>;
|
|
280
|
-
currentDefaultSpecifierName: string;
|
|
281
|
-
desiredName: string;
|
|
282
|
-
fallbackName: string;
|
|
283
|
-
}) {
|
|
284
|
-
if (currentDefaultSpecifierName === desiredName) {
|
|
285
|
-
return desiredName;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
const isUsed: boolean = doesIdentifierExist({ j, base, name: desiredName });
|
|
289
|
-
|
|
290
|
-
return isUsed ? fallbackName : desiredName;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
export function isUsingThroughSpread({
|
|
294
|
-
j,
|
|
295
|
-
base,
|
|
296
|
-
element,
|
|
297
|
-
propName,
|
|
298
|
-
}: {
|
|
299
|
-
j: core.JSCodeshift;
|
|
300
|
-
base: Collection<any>;
|
|
301
|
-
element: NodePath<JSXElement, JSXElement>;
|
|
302
|
-
propName: string;
|
|
303
|
-
}): boolean {
|
|
304
|
-
if (!isUsingSupportedSpread({ j, base, element })) {
|
|
305
|
-
return false;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
const isUsedThroughExpression: boolean =
|
|
309
|
-
j(element)
|
|
310
|
-
.find(j.JSXSpreadAttribute)
|
|
311
|
-
.find(j.ObjectExpression)
|
|
312
|
-
.filter((item) => {
|
|
313
|
-
const match: boolean =
|
|
314
|
-
item.value.properties.filter(
|
|
315
|
-
(property) =>
|
|
316
|
-
property.type === 'ObjectProperty' &&
|
|
317
|
-
property.key.type === 'Identifier' &&
|
|
318
|
-
property.key.name === propName,
|
|
319
|
-
).length > 0;
|
|
320
|
-
|
|
321
|
-
return match;
|
|
322
|
-
}).length > 0;
|
|
323
|
-
|
|
324
|
-
if (isUsedThroughExpression) {
|
|
325
|
-
return true;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
const isUsedThroughIdentifier: boolean =
|
|
329
|
-
j(element)
|
|
330
|
-
.find(j.JSXSpreadAttribute)
|
|
331
|
-
.find(j.Identifier)
|
|
332
|
-
.filter((identifier): boolean => {
|
|
333
|
-
return (
|
|
334
|
-
base
|
|
335
|
-
.find(j.VariableDeclarator)
|
|
336
|
-
.filter(
|
|
337
|
-
(declarator) =>
|
|
338
|
-
declarator.value.id.type === 'Identifier' &&
|
|
339
|
-
declarator.value.id.name === identifier.value.name,
|
|
340
|
-
)
|
|
341
|
-
.filter((declarator) => {
|
|
342
|
-
const value = declarator.value;
|
|
343
|
-
if (value.id.type !== 'Identifier') {
|
|
344
|
-
return false;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
if (value.id.name !== identifier.value.name) {
|
|
348
|
-
return false;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
if (!value.init) {
|
|
352
|
-
return false;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
if (value.init.type !== 'ObjectExpression') {
|
|
356
|
-
return false;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
const match: boolean =
|
|
360
|
-
value.init.properties.filter(
|
|
361
|
-
(property) =>
|
|
362
|
-
property.type === 'ObjectProperty' &&
|
|
363
|
-
property.key.type === 'Identifier' &&
|
|
364
|
-
property.key.name === propName,
|
|
365
|
-
).length > 0;
|
|
366
|
-
|
|
367
|
-
return match;
|
|
368
|
-
}).length > 0
|
|
369
|
-
);
|
|
370
|
-
}).length > 0;
|
|
371
|
-
|
|
372
|
-
return isUsedThroughIdentifier;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
export function isUsingProp({
|
|
376
|
-
j,
|
|
377
|
-
base,
|
|
378
|
-
element,
|
|
379
|
-
propName,
|
|
380
|
-
}: {
|
|
381
|
-
j: core.JSCodeshift;
|
|
382
|
-
base: Collection<any>;
|
|
383
|
-
element: NodePath<JSXElement, JSXElement>;
|
|
384
|
-
propName: string;
|
|
385
|
-
}): boolean {
|
|
386
|
-
return (
|
|
387
|
-
hasJSXAttributesByName({
|
|
388
|
-
j,
|
|
389
|
-
element: element.value,
|
|
390
|
-
attributeName: propName,
|
|
391
|
-
}) ||
|
|
392
|
-
isUsingThroughSpread({
|
|
393
|
-
j,
|
|
394
|
-
base,
|
|
395
|
-
element,
|
|
396
|
-
propName,
|
|
397
|
-
})
|
|
398
|
-
);
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
// not replacing newlines (which \s does)
|
|
402
|
-
const spacesAndTabs: RegExp = /[ \t]{2,}/g;
|
|
403
|
-
const lineStartWithSpaces: RegExp = /^[ \t]*/gm;
|
|
404
|
-
|
|
405
|
-
function clean(value: string): string {
|
|
406
|
-
return (
|
|
407
|
-
value
|
|
408
|
-
.replace(spacesAndTabs, ' ')
|
|
409
|
-
.replace(lineStartWithSpaces, '')
|
|
410
|
-
// using .trim() to clear the any newlines before the first text and after last text
|
|
411
|
-
.trim()
|
|
412
|
-
);
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
export function addCommentBeforeJSX(j: core.JSCodeshift, element: NodePath, message: string) {
|
|
416
|
-
const content: string = `\nTODO: (from codemod) ${clean(message)}\n`;
|
|
417
|
-
|
|
418
|
-
const comment = j.commentBlock(content, false, true);
|
|
419
|
-
|
|
420
|
-
element.insertBefore(comment);
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
export function addCommentToStartOfFile({
|
|
424
|
-
j,
|
|
425
|
-
base,
|
|
426
|
-
message,
|
|
427
|
-
}: {
|
|
428
|
-
j: core.JSCodeshift;
|
|
429
|
-
base: Collection<Node>;
|
|
430
|
-
message: string;
|
|
431
|
-
}) {
|
|
432
|
-
addCommentBefore({
|
|
433
|
-
j,
|
|
434
|
-
target: base.find(j.Program),
|
|
435
|
-
message,
|
|
436
|
-
});
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
export function addCommentBefore({
|
|
440
|
-
j,
|
|
441
|
-
target,
|
|
442
|
-
message,
|
|
443
|
-
}: {
|
|
444
|
-
j: core.JSCodeshift;
|
|
445
|
-
target: Collection<Node> | Collection<Program> | Collection<ImportDeclaration>;
|
|
446
|
-
message: string;
|
|
447
|
-
}) {
|
|
448
|
-
const content: string = ` TODO: (from codemod) ${clean(message)} `;
|
|
449
|
-
target.forEach((path) => {
|
|
450
|
-
path.value.comments = path.value.comments || [];
|
|
451
|
-
|
|
452
|
-
const exists = path.value.comments.find((comment) => comment.value === content);
|
|
453
|
-
|
|
454
|
-
// avoiding duplicates of the same comment
|
|
455
|
-
if (exists) {
|
|
456
|
-
return;
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
path.value.comments.push(j.commentBlock(content));
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
export function shiftDefaultImport({
|
|
464
|
-
j,
|
|
465
|
-
base,
|
|
466
|
-
defaultName,
|
|
467
|
-
oldPackagePath,
|
|
468
|
-
newPackagePath,
|
|
469
|
-
}: {
|
|
470
|
-
j: core.JSCodeshift;
|
|
471
|
-
base: Collection<any>;
|
|
472
|
-
defaultName: string;
|
|
473
|
-
oldPackagePath: string;
|
|
474
|
-
newPackagePath: string;
|
|
475
|
-
}) {
|
|
476
|
-
tryCreateImport({
|
|
477
|
-
j,
|
|
478
|
-
base,
|
|
479
|
-
relativeToPackage: oldPackagePath,
|
|
480
|
-
packageName: newPackagePath,
|
|
481
|
-
});
|
|
482
|
-
|
|
483
|
-
addToImport({
|
|
484
|
-
j,
|
|
485
|
-
base,
|
|
486
|
-
importSpecifier: j.importDefaultSpecifier(j.identifier(defaultName)),
|
|
487
|
-
packageName: newPackagePath,
|
|
488
|
-
});
|
|
489
|
-
|
|
490
|
-
// removing old default specifier
|
|
491
|
-
base
|
|
492
|
-
.find(j.ImportDeclaration)
|
|
493
|
-
.filter((path) => path.node.source.value === oldPackagePath)
|
|
494
|
-
.find(j.ImportDefaultSpecifier)
|
|
495
|
-
.remove();
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
type Option =
|
|
499
|
-
| {
|
|
500
|
-
type: 'change-name';
|
|
501
|
-
oldName: string;
|
|
502
|
-
newName: string;
|
|
503
|
-
fallbackNameAlias: string;
|
|
504
|
-
}
|
|
505
|
-
| {
|
|
506
|
-
type: 'keep-name';
|
|
507
|
-
name: string;
|
|
508
|
-
behaviour: 'move-to-default-import' | 'keep-as-named-import';
|
|
509
|
-
};
|
|
510
|
-
|
|
511
|
-
// try to avoid this one if you can. I'm not super happy with it
|
|
512
|
-
export function changeImportFor({
|
|
513
|
-
j,
|
|
514
|
-
base,
|
|
515
|
-
option,
|
|
516
|
-
oldPackagePath,
|
|
517
|
-
newPackagePath,
|
|
518
|
-
}: {
|
|
519
|
-
j: core.JSCodeshift;
|
|
520
|
-
base: Collection<any>;
|
|
521
|
-
option: Option;
|
|
522
|
-
oldPackagePath: string;
|
|
523
|
-
newPackagePath: string;
|
|
524
|
-
}) {
|
|
525
|
-
const currentName: string = option.type === 'change-name' ? option.oldName : option.name;
|
|
526
|
-
const desiredName: string = option.type === 'change-name' ? option.newName : option.name;
|
|
527
|
-
|
|
528
|
-
const isUsingName: boolean =
|
|
529
|
-
base
|
|
530
|
-
.find(j.ImportDeclaration)
|
|
531
|
-
.filter((path) => path.node.source.value === oldPackagePath)
|
|
532
|
-
.find(j.ImportSpecifier)
|
|
533
|
-
.find(j.Identifier)
|
|
534
|
-
.filter((identifier) => identifier.value.name === currentName).length > 0;
|
|
535
|
-
|
|
536
|
-
if (!isUsingName) {
|
|
537
|
-
return;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
const existingAlias: Nullable<string> =
|
|
541
|
-
base
|
|
542
|
-
.find(j.ImportDeclaration)
|
|
543
|
-
.filter((path) => path.node.source.value === oldPackagePath)
|
|
544
|
-
.find(j.ImportSpecifier)
|
|
545
|
-
.nodes()
|
|
546
|
-
.map((specifier): Nullable<string> => {
|
|
547
|
-
if (specifier.imported.name !== currentName) {
|
|
548
|
-
return null;
|
|
549
|
-
}
|
|
550
|
-
// If aliased: return the alias
|
|
551
|
-
if (specifier.local && specifier.local.name !== currentName) {
|
|
552
|
-
return specifier.local.name;
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
return null;
|
|
556
|
-
})
|
|
557
|
-
.filter(Boolean)[0] || null;
|
|
558
|
-
|
|
559
|
-
base
|
|
560
|
-
.find(j.ImportDeclaration)
|
|
561
|
-
.filter((path) => path.node.source.value === oldPackagePath)
|
|
562
|
-
.find(j.ImportSpecifier)
|
|
563
|
-
.find(j.Identifier)
|
|
564
|
-
.filter((identifier) => {
|
|
565
|
-
if (identifier.value.name === currentName) {
|
|
566
|
-
return true;
|
|
567
|
-
}
|
|
568
|
-
if (identifier.value.name === existingAlias) {
|
|
569
|
-
return true;
|
|
570
|
-
}
|
|
571
|
-
return false;
|
|
572
|
-
})
|
|
573
|
-
.remove();
|
|
574
|
-
|
|
575
|
-
// Check to see if need to create new package path
|
|
576
|
-
// Try create an import declaration just before the old import
|
|
577
|
-
tryCreateImport({
|
|
578
|
-
j,
|
|
579
|
-
base,
|
|
580
|
-
relativeToPackage: oldPackagePath,
|
|
581
|
-
packageName: newPackagePath,
|
|
582
|
-
});
|
|
583
|
-
|
|
584
|
-
if (option.type === 'keep-name') {
|
|
585
|
-
const newSpecifier: ImportSpecifier | ImportDefaultSpecifier = (() => {
|
|
586
|
-
if (option.behaviour === 'keep-as-named-import') {
|
|
587
|
-
if (existingAlias) {
|
|
588
|
-
return j.importSpecifier(j.identifier(desiredName), j.identifier(existingAlias));
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
return j.importSpecifier(j.identifier(desiredName));
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
// moving to default specifier
|
|
595
|
-
return j.importDefaultSpecifier(j.identifier(existingAlias || desiredName));
|
|
596
|
-
})();
|
|
597
|
-
|
|
598
|
-
// We don't need to touch anything else in the file
|
|
599
|
-
|
|
600
|
-
addToImport({
|
|
601
|
-
j,
|
|
602
|
-
base,
|
|
603
|
-
importSpecifier: newSpecifier,
|
|
604
|
-
packageName: newPackagePath,
|
|
605
|
-
});
|
|
606
|
-
return;
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
const isNewNameAvailable: boolean =
|
|
610
|
-
base.find(j.Identifier).filter((i) => i.value.name === option.newName).length === 0;
|
|
611
|
-
|
|
612
|
-
const newSpecifier: ImportSpecifier = (() => {
|
|
613
|
-
if (existingAlias) {
|
|
614
|
-
return j.importSpecifier(j.identifier(desiredName), j.identifier(existingAlias));
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
if (isNewNameAvailable) {
|
|
618
|
-
return j.importSpecifier(j.identifier(desiredName));
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
// new type name is not available: need to use a new alias
|
|
622
|
-
return j.importSpecifier(j.identifier(desiredName), j.identifier(option.fallbackNameAlias));
|
|
623
|
-
})();
|
|
624
|
-
|
|
625
|
-
addToImport({
|
|
626
|
-
j,
|
|
627
|
-
base,
|
|
628
|
-
importSpecifier: newSpecifier,
|
|
629
|
-
packageName: newPackagePath,
|
|
630
|
-
});
|
|
631
|
-
|
|
632
|
-
// Change usages of old type in file
|
|
633
|
-
base
|
|
634
|
-
.find(j.Identifier)
|
|
635
|
-
.filter((identifier) => identifier.value.name === option.oldName)
|
|
636
|
-
.replaceWith(j.identifier(isNewNameAvailable ? option.newName : option.fallbackNameAlias));
|
|
637
|
-
}
|