@atlaskit/side-navigation 3.2.1 → 3.3.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/README.md +7 -3
  3. package/codemods/0.8.0-change-css-fn-prop.tsx +136 -164
  4. package/codemods/__tests__/0.8.0-change-css-fn-prop.tsx +77 -77
  5. package/codemods/helpers/generic.tsx +528 -564
  6. package/constellation/index/examples.mdx +20 -20
  7. package/constellation/index/props.mdx +8 -8
  8. package/constellation/index/usage.mdx +27 -11
  9. package/dist/cjs/components/Header/index.js +4 -0
  10. package/dist/cjs/components/Item/link-item.js +3 -1
  11. package/dist/cjs/components/LoadingItems/index.js +7 -3
  12. package/dist/cjs/components/NavigationContent/index.js +8 -1
  13. package/dist/cjs/components/NavigationHeader/index.js +4 -0
  14. package/dist/cjs/components/NestableNavigationContent/index.js +5 -0
  15. package/dist/cjs/components/NestableNavigationContent/nesting-motion.js +3 -1
  16. package/dist/cjs/components/NestingItem/index.js +4 -0
  17. package/dist/cjs/components/SideNavigation/index.js +5 -0
  18. package/dist/es2019/components/Header/index.js +5 -0
  19. package/dist/es2019/components/Item/link-item.js +3 -1
  20. package/dist/es2019/components/LoadingItems/index.js +7 -3
  21. package/dist/es2019/components/NavigationContent/index.js +8 -1
  22. package/dist/es2019/components/NavigationHeader/index.js +4 -0
  23. package/dist/es2019/components/NestableNavigationContent/index.js +5 -0
  24. package/dist/es2019/components/NestableNavigationContent/nesting-motion.js +4 -0
  25. package/dist/es2019/components/NestingItem/index.js +5 -0
  26. package/dist/es2019/components/SideNavigation/index.js +5 -0
  27. package/dist/esm/components/Header/index.js +5 -0
  28. package/dist/esm/components/Item/link-item.js +3 -1
  29. package/dist/esm/components/LoadingItems/index.js +7 -3
  30. package/dist/esm/components/NavigationContent/index.js +8 -1
  31. package/dist/esm/components/NavigationHeader/index.js +4 -0
  32. package/dist/esm/components/NestableNavigationContent/index.js +5 -0
  33. package/dist/esm/components/NestableNavigationContent/nesting-motion.js +4 -0
  34. package/dist/esm/components/NestingItem/index.js +5 -0
  35. package/dist/esm/components/SideNavigation/index.js +5 -0
  36. package/dist/types/components/LoadingItems/index.d.ts +1 -1
  37. package/dist/types/components/NavigationContent/index.d.ts +3 -0
  38. package/dist/types/components/NavigationHeader/index.d.ts +3 -0
  39. package/dist/types/components/NestableNavigationContent/nesting-motion.d.ts +3 -0
  40. package/dist/types/components/NestingItem/index.d.ts +3 -0
  41. package/dist/types/components/index.d.ts +2 -2
  42. package/dist/types/index.d.ts +1 -1
  43. package/dist/types-ts4.5/components/LoadingItems/index.d.ts +1 -1
  44. package/dist/types-ts4.5/components/NavigationContent/index.d.ts +3 -0
  45. package/dist/types-ts4.5/components/NavigationHeader/index.d.ts +3 -0
  46. package/dist/types-ts4.5/components/NestableNavigationContent/nesting-motion.d.ts +3 -0
  47. package/dist/types-ts4.5/components/NestingItem/index.d.ts +3 -0
  48. package/dist/types-ts4.5/components/index.d.ts +2 -2
  49. package/dist/types-ts4.5/index.d.ts +1 -1
  50. package/docs/00-intro.tsx +4 -6
  51. package/docs/ert/footer.tsx +6 -6
  52. package/package.json +97 -97
  53. package/report.api.md +102 -123
@@ -1,410 +1,401 @@
1
1
  import { type NodePath } from 'ast-types/lib/node-path';
2
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,
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
12
  } from 'jscodeshift';
13
13
  import { type Collection } from 'jscodeshift/src/Collection';
14
14
 
15
15
  export type Nullable<T> = T | null;
16
16
 
17
17
  export function hasImportDeclaration(
18
- j: core.JSCodeshift,
19
- source: string,
20
- importPath: string,
18
+ j: core.JSCodeshift,
19
+ source: string,
20
+ importPath: string,
21
21
  ): boolean {
22
- return (
23
- j(source)
24
- .find(j.ImportDeclaration)
25
- .filter(
26
- (path: ASTPath<ImportDeclaration>) =>
27
- path.node.source.value === importPath,
28
- ).length > 0
29
- );
22
+ return (
23
+ j(source)
24
+ .find(j.ImportDeclaration)
25
+ .filter((path: ASTPath<ImportDeclaration>) => path.node.source.value === importPath).length >
26
+ 0
27
+ );
30
28
  }
31
29
 
32
30
  export function getDefaultSpecifierName({
33
- j,
34
- base,
35
- packageName,
31
+ j,
32
+ base,
33
+ packageName,
36
34
  }: {
37
- j: core.JSCodeshift;
38
- base: Collection<any>;
39
- packageName: string;
35
+ j: core.JSCodeshift;
36
+ base: Collection<any>;
37
+ packageName: string;
40
38
  }): Nullable<string> {
41
- const specifiers = base
42
- .find(j.ImportDeclaration)
43
- .filter((path) => path.node.source.value === packageName)
44
- .find(j.ImportDefaultSpecifier);
45
-
46
- if (!specifiers.length) {
47
- return null;
48
- }
49
- return specifiers.nodes()[0]!.local!.name;
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;
50
48
  }
51
49
 
52
50
  export function getJSXAttributesByName({
53
- j,
54
- element,
55
- attributeName,
51
+ j,
52
+ element,
53
+ attributeName,
56
54
  }: {
57
- j: core.JSCodeshift;
58
- element: JSXElement;
59
- attributeName: string;
55
+ j: core.JSCodeshift;
56
+ element: JSXElement;
57
+ attributeName: string;
60
58
  }): Collection<JSXAttribute> {
61
- return j(element)
62
- .find(j.JSXOpeningElement)
63
- .find(j.JSXAttribute)
64
- .filter((attribute) => {
65
- const matches = j(attribute)
66
- // This will find identifiers on nested jsx elements
67
- // so we are going to do a filter to ensure we are only
68
- // going one level deep
69
- .find(j.JSXIdentifier)
70
- .filter((identifer) => {
71
- j(identifer).closest(j.JSXOpeningElement);
72
- // Checking we are on the same level as the jsx element
73
- const closest = j(identifer).closest(j.JSXOpeningElement).nodes()[0];
74
-
75
- if (!closest) {
76
- return false;
77
- }
78
- return (
79
- closest.name.type === 'JSXIdentifier' &&
80
- element.openingElement.name.type === 'JSXIdentifier' &&
81
- element.openingElement.name.name === closest.name.name
82
- );
83
- })
84
- .filter((identifier) => identifier.value.name === attributeName);
85
- return Boolean(matches.length);
86
- });
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
+ });
87
85
  }
88
86
 
89
87
  export function hasJSXAttributesByName({
90
- j,
91
- element,
92
- attributeName,
88
+ j,
89
+ element,
90
+ attributeName,
93
91
  }: {
94
- j: core.JSCodeshift;
95
- element: JSXElement;
96
- attributeName: string;
92
+ j: core.JSCodeshift;
93
+ element: JSXElement;
94
+ attributeName: string;
97
95
  }): boolean {
98
- return getJSXAttributesByName({ j, element, attributeName }).length > 0;
96
+ return getJSXAttributesByName({ j, element, attributeName }).length > 0;
99
97
  }
100
98
 
101
99
  export function removeImport({
102
- j,
103
- base,
104
- packageName,
100
+ j,
101
+ base,
102
+ packageName,
105
103
  }: {
106
- j: core.JSCodeshift;
107
- base: Collection<any>;
108
- packageName: string;
104
+ j: core.JSCodeshift;
105
+ base: Collection<any>;
106
+ packageName: string;
109
107
  }) {
110
- base
111
- .find(j.ImportDeclaration)
112
- .filter((path) => path.node.source.value === packageName)
113
- .remove();
108
+ base
109
+ .find(j.ImportDeclaration)
110
+ .filter((path) => path.node.source.value === packageName)
111
+ .remove();
114
112
  }
115
113
 
116
114
  export function tryCreateImport({
117
- j,
118
- base,
119
- relativeToPackage,
120
- packageName,
115
+ j,
116
+ base,
117
+ relativeToPackage,
118
+ packageName,
121
119
  }: {
122
- j: core.JSCodeshift;
123
- base: Collection<any>;
124
- relativeToPackage: string;
125
- packageName: string;
120
+ j: core.JSCodeshift;
121
+ base: Collection<any>;
122
+ relativeToPackage: string;
123
+ packageName: string;
126
124
  }) {
127
- const exists: boolean =
128
- base
129
- .find(j.ImportDeclaration)
130
- .filter((path) => path.value.source.value === packageName).length > 0;
131
-
132
- if (exists) {
133
- return;
134
- }
135
-
136
- base
137
- .find(j.ImportDeclaration)
138
- .filter((path) => path.value.source.value === relativeToPackage)
139
- .insertBefore(j.importDeclaration([], j.literal(packageName)));
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)));
140
137
  }
141
138
 
142
139
  export function addToImport({
143
- j,
144
- base,
145
- importSpecifier,
146
- packageName,
140
+ j,
141
+ base,
142
+ importSpecifier,
143
+ packageName,
147
144
  }: {
148
- j: core.JSCodeshift;
149
- base: Collection<any>;
150
- importSpecifier: ImportSpecifier | ImportDefaultSpecifier;
151
- packageName: string;
145
+ j: core.JSCodeshift;
146
+ base: Collection<any>;
147
+ importSpecifier: ImportSpecifier | ImportDefaultSpecifier;
148
+ packageName: string;
152
149
  }) {
153
- base
154
- .find(j.ImportDeclaration)
155
- .filter((path) => path.value.source.value === packageName)
156
- .replaceWith((declaration) => {
157
- return j.importDeclaration(
158
- [
159
- // we are appending to the existing specifiers
160
- // We are doing a filter hear because sometimes specifiers can be removed
161
- // but they hand around in the declaration
162
- ...(declaration.value.specifiers || []).filter(
163
- (item) => item.type === 'ImportSpecifier' && item.imported != null,
164
- ),
165
- importSpecifier,
166
- ],
167
- j.literal(packageName),
168
- );
169
- });
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
+ });
170
167
  }
171
168
 
172
169
  export function doesIdentifierExist({
173
- j,
174
- base,
175
- name,
170
+ j,
171
+ base,
172
+ name,
176
173
  }: {
177
- j: core.JSCodeshift;
178
- base: Collection<any>;
179
- name: string;
174
+ j: core.JSCodeshift;
175
+ base: Collection<any>;
176
+ name: string;
180
177
  }): boolean {
181
- return (
182
- base.find(j.Identifier).filter((identifer) => identifer.value.name === name)
183
- .length > 0
184
- );
178
+ return base.find(j.Identifier).filter((identifer) => identifer.value.name === name).length > 0;
185
179
  }
186
180
 
187
181
  export function isUsingSupportedSpread({
188
- j,
189
- base,
190
- element,
182
+ j,
183
+ base,
184
+ element,
191
185
  }: {
192
- j: core.JSCodeshift;
193
- base: Collection<any>;
194
- element: NodePath<JSXElement, JSXElement>;
186
+ j: core.JSCodeshift;
187
+ base: Collection<any>;
188
+ element: NodePath<JSXElement, JSXElement>;
195
189
  }): boolean {
196
- const isUsingSpread: boolean =
197
- j(element).find(j.JSXSpreadAttribute).length > 0;
198
-
199
- if (!isUsingSpread) {
200
- return true;
201
- }
202
-
203
- return (
204
- j(element)
205
- .find(j.JSXSpreadAttribute)
206
- .filter((spread) => {
207
- const argument = spread.value.argument;
208
- // in place expression is supported
209
- if (argument.type === 'ObjectExpression') {
210
- return true;
211
- }
212
-
213
- // Supporting identifiers that point to an a local object expression
214
- if (argument.type === 'Identifier') {
215
- return (
216
- base.find(j.VariableDeclarator).filter((declarator): boolean => {
217
- return Boolean(
218
- declarator.value.id.type === 'Identifier' &&
219
- declarator.value.init &&
220
- declarator.value.init.type === 'ObjectExpression',
221
- );
222
- }).length > 0
223
- );
224
- }
225
-
226
- // We don't support anything else
227
- return false;
228
- }).length > 0
229
- );
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
+ );
230
223
  }
231
224
 
232
225
  export function isOnlyUsingNameForJSX({
233
- j,
234
- base,
235
- name,
226
+ j,
227
+ base,
228
+ name,
236
229
  }: {
237
- j: core.JSCodeshift;
238
- base: Collection<any>;
239
- name: string;
230
+ j: core.JSCodeshift;
231
+ base: Collection<any>;
232
+ name: string;
240
233
  }): boolean {
241
- const jsxIdentifierCount: number = base
242
- .find(j.JSXIdentifier)
243
- .filter((identifier) => identifier.value.name === name).length;
244
-
245
- // Not used in JSX at all
246
- if (jsxIdentifierCount === 0) {
247
- return false;
248
- }
249
-
250
- const nonJSXIdentifierCount: number = base
251
- .find(j.Identifier)
252
- .filter((identifier) => {
253
- if (identifier.value.name !== name) {
254
- return false;
255
- }
256
-
257
- // @ts-ignore
258
- if (identifier.value.type === 'JSXIdentifier') {
259
- return false;
260
- }
261
-
262
- // Excluding exports
263
- if (j(identifier).closest(j.ImportDefaultSpecifier).length) {
264
- return false;
265
- }
266
- if (j(identifier).closest(j.ImportSpecifier).length) {
267
- return false;
268
- }
269
-
270
- return true;
271
- }).length;
272
-
273
- if (nonJSXIdentifierCount > 0) {
274
- return false;
275
- }
276
-
277
- return true;
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;
278
269
  }
279
270
 
280
271
  export function getSafeImportName({
281
- j,
282
- base,
283
- currentDefaultSpecifierName,
284
- desiredName,
285
- fallbackName,
272
+ j,
273
+ base,
274
+ currentDefaultSpecifierName,
275
+ desiredName,
276
+ fallbackName,
286
277
  }: {
287
- j: core.JSCodeshift;
288
- base: Collection<any>;
289
- currentDefaultSpecifierName: string;
290
- desiredName: string;
291
- fallbackName: string;
278
+ j: core.JSCodeshift;
279
+ base: Collection<any>;
280
+ currentDefaultSpecifierName: string;
281
+ desiredName: string;
282
+ fallbackName: string;
292
283
  }) {
293
- if (currentDefaultSpecifierName === desiredName) {
294
- return desiredName;
295
- }
284
+ if (currentDefaultSpecifierName === desiredName) {
285
+ return desiredName;
286
+ }
296
287
 
297
- const isUsed: boolean = doesIdentifierExist({ j, base, name: desiredName });
288
+ const isUsed: boolean = doesIdentifierExist({ j, base, name: desiredName });
298
289
 
299
- return isUsed ? fallbackName : desiredName;
290
+ return isUsed ? fallbackName : desiredName;
300
291
  }
301
292
 
302
293
  export function isUsingThroughSpread({
303
- j,
304
- base,
305
- element,
306
- propName,
294
+ j,
295
+ base,
296
+ element,
297
+ propName,
307
298
  }: {
308
- j: core.JSCodeshift;
309
- base: Collection<any>;
310
- element: NodePath<JSXElement, JSXElement>;
311
- propName: string;
299
+ j: core.JSCodeshift;
300
+ base: Collection<any>;
301
+ element: NodePath<JSXElement, JSXElement>;
302
+ propName: string;
312
303
  }): boolean {
313
- if (!isUsingSupportedSpread({ j, base, element })) {
314
- return false;
315
- }
316
-
317
- const isUsedThroughExpression: boolean =
318
- j(element)
319
- .find(j.JSXSpreadAttribute)
320
- .find(j.ObjectExpression)
321
- .filter((item) => {
322
- const match: boolean =
323
- item.value.properties.filter(
324
- (property) =>
325
- property.type === 'ObjectProperty' &&
326
- property.key.type === 'Identifier' &&
327
- property.key.name === propName,
328
- ).length > 0;
329
-
330
- return match;
331
- }).length > 0;
332
-
333
- if (isUsedThroughExpression) {
334
- return true;
335
- }
336
-
337
- const isUsedThroughIdentifier: boolean =
338
- j(element)
339
- .find(j.JSXSpreadAttribute)
340
- .find(j.Identifier)
341
- .filter((identifier): boolean => {
342
- return (
343
- base
344
- .find(j.VariableDeclarator)
345
- .filter(
346
- (declarator) =>
347
- declarator.value.id.type === 'Identifier' &&
348
- declarator.value.id.name === identifier.value.name,
349
- )
350
- .filter((declarator) => {
351
- const value = declarator.value;
352
- if (value.id.type !== 'Identifier') {
353
- return false;
354
- }
355
-
356
- if (value.id.name !== identifier.value.name) {
357
- return false;
358
- }
359
-
360
- if (!value.init) {
361
- return false;
362
- }
363
-
364
- if (value.init.type !== 'ObjectExpression') {
365
- return false;
366
- }
367
-
368
- const match: boolean =
369
- value.init.properties.filter(
370
- (property) =>
371
- property.type === 'ObjectProperty' &&
372
- property.key.type === 'Identifier' &&
373
- property.key.name === propName,
374
- ).length > 0;
375
-
376
- return match;
377
- }).length > 0
378
- );
379
- }).length > 0;
380
-
381
- return isUsedThroughIdentifier;
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;
382
373
  }
383
374
 
384
375
  export function isUsingProp({
385
- j,
386
- base,
387
- element,
388
- propName,
376
+ j,
377
+ base,
378
+ element,
379
+ propName,
389
380
  }: {
390
- j: core.JSCodeshift;
391
- base: Collection<any>;
392
- element: NodePath<JSXElement, JSXElement>;
393
- propName: string;
381
+ j: core.JSCodeshift;
382
+ base: Collection<any>;
383
+ element: NodePath<JSXElement, JSXElement>;
384
+ propName: string;
394
385
  }): boolean {
395
- return (
396
- hasJSXAttributesByName({
397
- j,
398
- element: element.value,
399
- attributeName: propName,
400
- }) ||
401
- isUsingThroughSpread({
402
- j,
403
- base,
404
- element,
405
- propName,
406
- })
407
- );
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
+ );
408
399
  }
409
400
 
410
401
  // not replacing newlines (which \s does)
@@ -412,262 +403,235 @@ const spacesAndTabs: RegExp = /[ \t]{2,}/g;
412
403
  const lineStartWithSpaces: RegExp = /^[ \t]*/gm;
413
404
 
414
405
  function clean(value: string): string {
415
- return (
416
- value
417
- .replace(spacesAndTabs, ' ')
418
- .replace(lineStartWithSpaces, '')
419
- // using .trim() to clear the any newlines before the first text and after last text
420
- .trim()
421
- );
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
+ );
422
413
  }
423
414
 
424
- export function addCommentBeforeJSX(
425
- j: core.JSCodeshift,
426
- element: NodePath,
427
- message: string,
428
- ) {
429
- const content: string = `\nTODO: (from codemod) ${clean(message)}\n`;
415
+ export function addCommentBeforeJSX(j: core.JSCodeshift, element: NodePath, message: string) {
416
+ const content: string = `\nTODO: (from codemod) ${clean(message)}\n`;
430
417
 
431
- const comment = j.commentBlock(content, false, true);
418
+ const comment = j.commentBlock(content, false, true);
432
419
 
433
- element.insertBefore(comment);
420
+ element.insertBefore(comment);
434
421
  }
435
422
 
436
423
  export function addCommentToStartOfFile({
437
- j,
438
- base,
439
- message,
424
+ j,
425
+ base,
426
+ message,
440
427
  }: {
441
- j: core.JSCodeshift;
442
- base: Collection<Node>;
443
- message: string;
428
+ j: core.JSCodeshift;
429
+ base: Collection<Node>;
430
+ message: string;
444
431
  }) {
445
- addCommentBefore({
446
- j,
447
- target: base.find(j.Program),
448
- message,
449
- });
432
+ addCommentBefore({
433
+ j,
434
+ target: base.find(j.Program),
435
+ message,
436
+ });
450
437
  }
451
438
 
452
439
  export function addCommentBefore({
453
- j,
454
- target,
455
- message,
440
+ j,
441
+ target,
442
+ message,
456
443
  }: {
457
- j: core.JSCodeshift;
458
- target:
459
- | Collection<Node>
460
- | Collection<Program>
461
- | Collection<ImportDeclaration>;
462
- message: string;
444
+ j: core.JSCodeshift;
445
+ target: Collection<Node> | Collection<Program> | Collection<ImportDeclaration>;
446
+ message: string;
463
447
  }) {
464
- const content: string = ` TODO: (from codemod) ${clean(message)} `;
465
- target.forEach((path) => {
466
- path.value.comments = path.value.comments || [];
448
+ const content: string = ` TODO: (from codemod) ${clean(message)} `;
449
+ target.forEach((path) => {
450
+ path.value.comments = path.value.comments || [];
467
451
 
468
- const exists = path.value.comments.find(
469
- (comment) => comment.value === content,
470
- );
452
+ const exists = path.value.comments.find((comment) => comment.value === content);
471
453
 
472
- // avoiding duplicates of the same comment
473
- if (exists) {
474
- return;
475
- }
454
+ // avoiding duplicates of the same comment
455
+ if (exists) {
456
+ return;
457
+ }
476
458
 
477
- path.value.comments.push(j.commentBlock(content));
478
- });
459
+ path.value.comments.push(j.commentBlock(content));
460
+ });
479
461
  }
480
462
 
481
463
  export function shiftDefaultImport({
482
- j,
483
- base,
484
- defaultName,
485
- oldPackagePath,
486
- newPackagePath,
464
+ j,
465
+ base,
466
+ defaultName,
467
+ oldPackagePath,
468
+ newPackagePath,
487
469
  }: {
488
- j: core.JSCodeshift;
489
- base: Collection<any>;
490
- defaultName: string;
491
- oldPackagePath: string;
492
- newPackagePath: string;
470
+ j: core.JSCodeshift;
471
+ base: Collection<any>;
472
+ defaultName: string;
473
+ oldPackagePath: string;
474
+ newPackagePath: string;
493
475
  }) {
494
- tryCreateImport({
495
- j,
496
- base,
497
- relativeToPackage: oldPackagePath,
498
- packageName: newPackagePath,
499
- });
500
-
501
- addToImport({
502
- j,
503
- base,
504
- importSpecifier: j.importDefaultSpecifier(j.identifier(defaultName)),
505
- packageName: newPackagePath,
506
- });
507
-
508
- // removing old default specifier
509
- base
510
- .find(j.ImportDeclaration)
511
- .filter((path) => path.node.source.value === oldPackagePath)
512
- .find(j.ImportDefaultSpecifier)
513
- .remove();
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();
514
496
  }
515
497
 
516
498
  type Option =
517
- | {
518
- type: 'change-name';
519
- oldName: string;
520
- newName: string;
521
- fallbackNameAlias: string;
522
- }
523
- | {
524
- type: 'keep-name';
525
- name: string;
526
- behaviour: 'move-to-default-import' | 'keep-as-named-import';
527
- };
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
+ };
528
510
 
529
511
  // try to avoid this one if you can. I'm not super happy with it
530
512
  export function changeImportFor({
531
- j,
532
- base,
533
- option,
534
- oldPackagePath,
535
- newPackagePath,
513
+ j,
514
+ base,
515
+ option,
516
+ oldPackagePath,
517
+ newPackagePath,
536
518
  }: {
537
- j: core.JSCodeshift;
538
- base: Collection<any>;
539
- option: Option;
540
- oldPackagePath: string;
541
- newPackagePath: string;
519
+ j: core.JSCodeshift;
520
+ base: Collection<any>;
521
+ option: Option;
522
+ oldPackagePath: string;
523
+ newPackagePath: string;
542
524
  }) {
543
- const currentName: string =
544
- option.type === 'change-name' ? option.oldName : option.name;
545
- const desiredName: string =
546
- option.type === 'change-name' ? option.newName : option.name;
547
-
548
- const isUsingName: boolean =
549
- base
550
- .find(j.ImportDeclaration)
551
- .filter((path) => path.node.source.value === oldPackagePath)
552
- .find(j.ImportSpecifier)
553
- .find(j.Identifier)
554
- .filter((identifier) => identifier.value.name === currentName).length > 0;
555
-
556
- if (!isUsingName) {
557
- return;
558
- }
559
-
560
- const existingAlias: Nullable<string> =
561
- base
562
- .find(j.ImportDeclaration)
563
- .filter((path) => path.node.source.value === oldPackagePath)
564
- .find(j.ImportSpecifier)
565
- .nodes()
566
- .map((specifier): Nullable<string> => {
567
- if (specifier.imported.name !== currentName) {
568
- return null;
569
- }
570
- // If aliased: return the alias
571
- if (specifier.local && specifier.local.name !== currentName) {
572
- return specifier.local.name;
573
- }
574
-
575
- return null;
576
- })
577
- .filter(Boolean)[0] || null;
578
-
579
- base
580
- .find(j.ImportDeclaration)
581
- .filter((path) => path.node.source.value === oldPackagePath)
582
- .find(j.ImportSpecifier)
583
- .find(j.Identifier)
584
- .filter((identifier) => {
585
- if (identifier.value.name === currentName) {
586
- return true;
587
- }
588
- if (identifier.value.name === existingAlias) {
589
- return true;
590
- }
591
- return false;
592
- })
593
- .remove();
594
-
595
- // Check to see if need to create new package path
596
- // Try create an import declaration just before the old import
597
- tryCreateImport({
598
- j,
599
- base,
600
- relativeToPackage: oldPackagePath,
601
- packageName: newPackagePath,
602
- });
603
-
604
- if (option.type === 'keep-name') {
605
- const newSpecifier: ImportSpecifier | ImportDefaultSpecifier = (() => {
606
- if (option.behaviour === 'keep-as-named-import') {
607
- if (existingAlias) {
608
- return j.importSpecifier(
609
- j.identifier(desiredName),
610
- j.identifier(existingAlias),
611
- );
612
- }
613
-
614
- return j.importSpecifier(j.identifier(desiredName));
615
- }
616
-
617
- // moving to default specifier
618
- return j.importDefaultSpecifier(
619
- j.identifier(existingAlias || desiredName),
620
- );
621
- })();
622
-
623
- // We don't need to touch anything else in the file
624
-
625
- addToImport({
626
- j,
627
- base,
628
- importSpecifier: newSpecifier,
629
- packageName: newPackagePath,
630
- });
631
- return;
632
- }
633
-
634
- const isNewNameAvailable: boolean =
635
- base.find(j.Identifier).filter((i) => i.value.name === option.newName)
636
- .length === 0;
637
-
638
- const newSpecifier: ImportSpecifier = (() => {
639
- if (existingAlias) {
640
- return j.importSpecifier(
641
- j.identifier(desiredName),
642
- j.identifier(existingAlias),
643
- );
644
- }
645
-
646
- if (isNewNameAvailable) {
647
- return j.importSpecifier(j.identifier(desiredName));
648
- }
649
-
650
- // new type name is not available: need to use a new alias
651
- return j.importSpecifier(
652
- j.identifier(desiredName),
653
- j.identifier(option.fallbackNameAlias),
654
- );
655
- })();
656
-
657
- addToImport({
658
- j,
659
- base,
660
- importSpecifier: newSpecifier,
661
- packageName: newPackagePath,
662
- });
663
-
664
- // Change usages of old type in file
665
- base
666
- .find(j.Identifier)
667
- .filter((identifier) => identifier.value.name === option.oldName)
668
- .replaceWith(
669
- j.identifier(
670
- isNewNameAvailable ? option.newName : option.fallbackNameAlias,
671
- ),
672
- );
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));
673
637
  }