@atlaskit/button 20.5.0 → 20.5.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,19 @@
1
1
  # @atlaskit/button
2
2
 
3
+ ## 20.5.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#113702](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/113702)
8
+ [`6ac2c34162d59`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/6ac2c34162d59) -
9
+ Remove old codemods.
10
+
11
+ ## 20.5.1
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies
16
+
3
17
  ## 20.5.0
4
18
 
5
19
  ### Minor Changes
@@ -133,7 +133,7 @@ var ButtonBase = /*#__PURE__*/_react.default.forwardRef(function ButtonBase(prop
133
133
  action: 'clicked',
134
134
  componentName: 'button',
135
135
  packageName: "@atlaskit/button",
136
- packageVersion: "20.5.0",
136
+ packageVersion: "20.5.2",
137
137
  analyticsData: analyticsContext
138
138
  });
139
139
 
@@ -119,7 +119,7 @@ const ButtonBase = /*#__PURE__*/React.forwardRef(function ButtonBase(props, ref)
119
119
  action: 'clicked',
120
120
  componentName: 'button',
121
121
  packageName: "@atlaskit/button",
122
- packageVersion: "20.5.0",
122
+ packageVersion: "20.5.2",
123
123
  analyticsData: analyticsContext
124
124
  });
125
125
 
@@ -125,7 +125,7 @@ var ButtonBase = /*#__PURE__*/React.forwardRef(function ButtonBase(props, ref) {
125
125
  action: 'clicked',
126
126
  componentName: 'button',
127
127
  packageName: "@atlaskit/button",
128
- packageVersion: "20.5.0",
128
+ packageVersion: "20.5.2",
129
129
  analyticsData: analyticsContext
130
130
  });
131
131
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/button",
3
- "version": "20.5.0",
3
+ "version": "20.5.2",
4
4
  "description": "A button triggers an event or action. They let users know what will happen next.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -87,12 +87,12 @@
87
87
  "@atlaskit/analytics-next": "^10.3.0",
88
88
  "@atlaskit/ds-lib": "^3.5.0",
89
89
  "@atlaskit/focus-ring": "^2.1.0",
90
- "@atlaskit/icon": "^23.6.0",
90
+ "@atlaskit/icon": "^23.9.0",
91
91
  "@atlaskit/interaction-context": "^2.6.0",
92
92
  "@atlaskit/platform-feature-flags": "^1.0.0",
93
- "@atlaskit/primitives": "^13.4.0",
93
+ "@atlaskit/primitives": "^13.5.0",
94
94
  "@atlaskit/spinner": "^17.1.0",
95
- "@atlaskit/theme": "^14.1.0",
95
+ "@atlaskit/theme": "^15.0.0",
96
96
  "@atlaskit/tokens": "^3.3.0",
97
97
  "@atlaskit/tooltip": "^19.1.0",
98
98
  "@atlaskit/visually-hidden": "^1.6.0",
@@ -1,165 +0,0 @@
1
- import type { API, default as core, FileInfo, Options } from 'jscodeshift';
2
- import { type Collection } from 'jscodeshift/src/Collection';
3
-
4
- import {
5
- addCommentToStartOfFile,
6
- getDefaultSpecifierName,
7
- getJSXAttributesByName,
8
- hasImportDeclaration,
9
- type Nullable,
10
- } from './helpers/helpers-generic';
11
- const relevantEntryPoints = [
12
- '@atlaskit/button',
13
- '@atlaskit/button/standard-button',
14
- '@atlaskit/button/loading-button',
15
- '@atlaskit/button/custom-theme-button',
16
- ];
17
-
18
- function isRelevant(j: core.JSCodeshift, source: string): boolean {
19
- return relevantEntryPoints.some((entryPoint) => hasImportDeclaration(j, source, entryPoint));
20
- }
21
-
22
- function renameProp({
23
- j,
24
- base,
25
- component,
26
- attributeFrom,
27
- attributeTo,
28
- }: {
29
- j: core.JSCodeshift;
30
- base: Collection<any>;
31
- component: string;
32
- attributeFrom: string;
33
- attributeTo: string;
34
- }) {
35
- base.findJSXElements(component).forEach((element) => {
36
- const first = getJSXAttributesByName({
37
- j,
38
- element: element.value,
39
- attributeName: attributeFrom,
40
- });
41
-
42
- // not using attribute
43
- if (!first.length) {
44
- return;
45
- }
46
-
47
- // let's check to see if they are using the to attribute
48
- const second = getJSXAttributesByName({
49
- j,
50
- element: element.value,
51
- attributeName: attributeTo,
52
- });
53
-
54
- // if the attribute we are moving to already exists we are in trouble
55
- if (second.length) {
56
- addCommentToStartOfFile({
57
- j,
58
- base,
59
- message: `
60
- Cannot rename ${attributeFrom} to ${attributeTo} on ${component}.
61
- A ${component} was detected with both ${attributeFrom} and ${attributeTo} props.
62
- Please remove the ${attributeFrom} prop and check your tests`,
63
- });
64
- return;
65
- }
66
-
67
- first.find(j.JSXIdentifier).replaceWith(j.jsxIdentifier(attributeTo));
68
- });
69
- }
70
-
71
- export function getNamedImportName({
72
- j,
73
- base,
74
- importPath,
75
- originalName,
76
- }: {
77
- j: core.JSCodeshift;
78
- base: Collection<any>;
79
- originalName: string;
80
- importPath: string;
81
- }): Nullable<string> {
82
- const name: Nullable<string> =
83
- base
84
- .find(j.ImportDeclaration)
85
- .filter((path) => path.node.source.value === importPath)
86
- .find(j.ImportSpecifier)
87
- .nodes()
88
- .map((specifier): Nullable<string> => {
89
- if (specifier.imported.name === originalName) {
90
- // aliased
91
- if (specifier.local) {
92
- return specifier.local.name;
93
- }
94
- // not aliased
95
- return originalName;
96
- }
97
-
98
- return null;
99
- })
100
- .filter(Boolean)[0] || null;
101
- return name;
102
- }
103
-
104
- export default function transformer(file: FileInfo, { jscodeshift: j }: API, options: Options) {
105
- if (!isRelevant(j, file.source)) {
106
- return file.source;
107
- }
108
-
109
- const base: Collection<any> = j(file.source);
110
-
111
- // renaming default imports for entry points
112
- relevantEntryPoints.forEach((importPath) => {
113
- const defaultName: Nullable<string> = getDefaultSpecifierName({
114
- j,
115
- base,
116
- packageName: importPath,
117
- });
118
-
119
- if (defaultName != null) {
120
- renameProp({
121
- j,
122
- base,
123
- component: defaultName,
124
- attributeFrom: 'data-testid',
125
- attributeTo: 'testId',
126
- });
127
- }
128
- });
129
-
130
- // named imports
131
- const standard = getNamedImportName({
132
- j,
133
- base,
134
- importPath: '@atlaskit/button',
135
- originalName: 'StandardButton',
136
- });
137
- const loading = getNamedImportName({
138
- j,
139
- base,
140
- importPath: '@atlaskit/button',
141
- originalName: 'LoadingButton',
142
- });
143
- const customTheme = getNamedImportName({
144
- j,
145
- base,
146
- importPath: '@atlaskit/button',
147
- originalName: 'CustomThemeButton',
148
- });
149
- [standard, loading, customTheme].forEach((name) => {
150
- if (name != null) {
151
- renameProp({
152
- j,
153
- base,
154
- component: name,
155
- attributeFrom: 'data-testid',
156
- attributeTo: 'testId',
157
- });
158
- }
159
- });
160
-
161
- return base.toSource({ quote: 'single' });
162
- }
163
-
164
- // Note: not exporting a 'parser' because doing so
165
- // will prevent consumers overriding it
@@ -1,185 +0,0 @@
1
- jest.autoMockOff();
2
-
3
- import transformer from '../../15.1.1-data-testid';
4
- import { check } from '../_framework';
5
-
6
- check({
7
- transformer,
8
- it: 'should rename data-testid to testId (default import)',
9
- original: `
10
- import DSButton from '@atlaskit/button';
11
-
12
- function App() {
13
- return <DSButton data-testid="my-testid">click me</DSButton>;
14
- }
15
- `,
16
- expected: `
17
- import DSButton from '@atlaskit/button';
18
-
19
- function App() {
20
- return <DSButton testId="my-testid">click me</DSButton>;
21
- }
22
- `,
23
- });
24
-
25
- check({
26
- transformer,
27
- it: 'should rename data-testid to testId (standard button)',
28
- original: `
29
- import Button from '@atlaskit/button/standard-button';
30
-
31
- function App() {
32
- return <Button data-testid="my-testid">click me</Button>;
33
- }
34
- `,
35
- expected: `
36
- import Button from '@atlaskit/button/standard-button';
37
-
38
- function App() {
39
- return <Button testId="my-testid">click me</Button>;
40
- }
41
- `,
42
- });
43
-
44
- check({
45
- transformer,
46
- it: 'should rename data-testid to testId (loading button)',
47
- original: `
48
- import Button from '@atlaskit/button/loading-button';
49
-
50
- function App() {
51
- return <Button data-testid="my-testid">click me</Button>;
52
- }
53
- `,
54
- expected: `
55
- import Button from '@atlaskit/button/loading-button';
56
-
57
- function App() {
58
- return <Button testId="my-testid">click me</Button>;
59
- }
60
- `,
61
- });
62
-
63
- check({
64
- transformer,
65
- it: 'should rename data-testid to testId (custom theme button)',
66
- original: `
67
- import Button from '@atlaskit/button/custom-theme-button';
68
-
69
- function App() {
70
- return <Button data-testid="my-testid">click me</Button>;
71
- }
72
- `,
73
- expected: `
74
- import Button from '@atlaskit/button/custom-theme-button';
75
-
76
- function App() {
77
- return <Button testId="my-testid">click me</Button>;
78
- }
79
- `,
80
- });
81
-
82
- check({
83
- transformer,
84
- it: 'should rename data-testid to testId (named imports)',
85
- original: `
86
- import { StandardButton, LoadingButton, CustomThemeButton } from '@atlaskit/button';
87
-
88
- function App() {
89
- return <>
90
- <StandardButton data-testid="my-testid">click me</StandardButton>
91
- <LoadingButton data-testid="my-testid">click me</LoadingButton>
92
- <CustomThemeButton data-testid="my-testid">click me</CustomThemeButton>
93
- </>;
94
- }
95
- `,
96
- expected: `
97
- import { StandardButton, LoadingButton, CustomThemeButton } from '@atlaskit/button';
98
-
99
- function App() {
100
- return <>
101
- <StandardButton testId="my-testid">click me</StandardButton>
102
- <LoadingButton testId="my-testid">click me</LoadingButton>
103
- <CustomThemeButton testId="my-testid">click me</CustomThemeButton>
104
- </>;
105
- }
106
- `,
107
- });
108
-
109
- check({
110
- transformer,
111
- it: 'should rename data-testid to testId (named imports with alias)',
112
- original: `
113
- import { StandardButton as SB, LoadingButton as LB, CustomThemeButton as CTB } from '@atlaskit/button';
114
-
115
- function App() {
116
- return <>
117
- <SB data-testid="my-testid">click me</SB>
118
- <LB data-testid="my-testid">click me</LB>
119
- <CTB data-testid="my-testid">click me</CTB>
120
- </>;
121
- }
122
- `,
123
- expected: `
124
- import { StandardButton as SB, LoadingButton as LB, CustomThemeButton as CTB } from '@atlaskit/button';
125
-
126
- function App() {
127
- return <>
128
- <SB testId="my-testid">click me</SB>
129
- <LB testId="my-testid">click me</LB>
130
- <CTB testId="my-testid">click me</CTB>
131
- </>;
132
- }
133
- `,
134
- });
135
-
136
- check({
137
- transformer,
138
- it: 'should add a warning when both the testId and data-testid props are being used',
139
- original: `
140
- import StandardButton from '@atlaskit/button';
141
-
142
- function App() {
143
- return <StandardButton testId="oh-my" data-testid="oh-dear">Click me</StandardButton>
144
- }
145
- `,
146
- expected: `
147
- /* TODO: (from codemod) Cannot rename data-testid to testId on StandardButton.
148
- A StandardButton was detected with both data-testid and testId props.
149
- Please remove the data-testid prop and check your tests */
150
- import StandardButton from '@atlaskit/button';
151
-
152
- function App() {
153
- return <StandardButton testId="oh-my" data-testid="oh-dear">Click me</StandardButton>
154
- }
155
- `,
156
- });
157
-
158
- check({
159
- transformer,
160
- it: 'should not touch unrelated testids',
161
- original: `
162
- import DSButton from '@atlaskit/button';
163
- import Something from '@atlaskit/foobar';
164
-
165
- function App() {
166
- return <>
167
- <DSButton data-testid="my-testid">
168
- <Something data-testid="hello">click me</Something>
169
- </DSButton>
170
- </>;
171
- }
172
- `,
173
- expected: `
174
- import DSButton from '@atlaskit/button';
175
- import Something from '@atlaskit/foobar';
176
-
177
- function App() {
178
- return <>
179
- <DSButton testId="my-testid">
180
- <Something data-testid="hello">click me</Something>
181
- </DSButton>
182
- </>;
183
- }
184
- `,
185
- });
@@ -1,47 +0,0 @@
1
- import { type API, type FileInfo, type Options } from 'jscodeshift';
2
-
3
- import noop from '@atlaskit/ds-lib/noop';
4
-
5
- const applyTransform = require('jscodeshift/dist/testUtils').applyTransform;
6
-
7
- type Transformer = (file: FileInfo, jscodeshift: API, options: Options) => void;
8
-
9
- type TestArgs = {
10
- it: string;
11
- original: string;
12
- expected: string;
13
- transformer: Transformer;
14
- mode?: 'only' | 'skip' | 'standard';
15
- before?: () => void;
16
- after?: () => void;
17
- };
18
-
19
- export function check({
20
- it: name,
21
- original,
22
- expected,
23
- transformer,
24
- before = noop,
25
- after = noop,
26
- mode = 'standard',
27
- }: TestArgs) {
28
- const run = mode === 'only' ? it.only : mode === 'skip' ? it.skip : it;
29
-
30
- run(name, () => {
31
- before();
32
- try {
33
- const output: string = applyTransform(
34
- { default: transformer, parser: 'tsx' },
35
- {},
36
- { source: original },
37
- );
38
- expect(output).toBe(expected.trim());
39
- } catch (e) {
40
- // a failed assertion will throw
41
- after();
42
- throw e;
43
- }
44
- // will only be hit if we don't throw
45
- after();
46
- });
47
- }
@@ -1,629 +0,0 @@
1
- import { type NodePath } from 'ast-types/lib/node-path';
2
- import type {
3
- ASTPath,
4
- default as core,
5
- ImportDeclaration,
6
- ImportDefaultSpecifier,
7
- ImportSpecifier,
8
- JSXAttribute,
9
- JSXElement,
10
- Node,
11
- 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 addCommentToStartOfFile({
416
- j,
417
- base,
418
- message,
419
- }: {
420
- j: core.JSCodeshift;
421
- base: Collection<Node>;
422
- message: string;
423
- }) {
424
- addCommentBefore({
425
- j,
426
- target: base.find(j.Program),
427
- message,
428
- });
429
- }
430
-
431
- export function addCommentBefore({
432
- j,
433
- target,
434
- message,
435
- }: {
436
- j: core.JSCodeshift;
437
- target: Collection<Node> | Collection<Program> | Collection<ImportDeclaration>;
438
- message: string;
439
- }) {
440
- const content: string = ` TODO: (from codemod) ${clean(message)} `;
441
- target.forEach((path) => {
442
- path.value.comments = path.value.comments || [];
443
-
444
- const exists = path.value.comments.find((comment) => comment.value === content);
445
-
446
- // avoiding duplicates of the same comment
447
- if (exists) {
448
- return;
449
- }
450
-
451
- path.value.comments.push(j.commentBlock(content));
452
- });
453
- }
454
-
455
- export function shiftDefaultImport({
456
- j,
457
- base,
458
- defaultName,
459
- oldPackagePath,
460
- newPackagePath,
461
- }: {
462
- j: core.JSCodeshift;
463
- base: Collection<any>;
464
- defaultName: string;
465
- oldPackagePath: string;
466
- newPackagePath: string;
467
- }) {
468
- tryCreateImport({
469
- j,
470
- base,
471
- relativeToPackage: oldPackagePath,
472
- packageName: newPackagePath,
473
- });
474
-
475
- addToImport({
476
- j,
477
- base,
478
- importSpecifier: j.importDefaultSpecifier(j.identifier(defaultName)),
479
- packageName: newPackagePath,
480
- });
481
-
482
- // removing old default specifier
483
- base
484
- .find(j.ImportDeclaration)
485
- .filter((path) => path.node.source.value === oldPackagePath)
486
- .find(j.ImportDefaultSpecifier)
487
- .remove();
488
- }
489
-
490
- type Option =
491
- | {
492
- type: 'change-name';
493
- oldName: string;
494
- newName: string;
495
- fallbackNameAlias: string;
496
- }
497
- | {
498
- type: 'keep-name';
499
- name: string;
500
- behaviour: 'move-to-default-import' | 'keep-as-named-import';
501
- };
502
-
503
- // try to avoid this one if you can. I'm not super happy with it
504
- export function changeImportFor({
505
- j,
506
- base,
507
- option,
508
- oldPackagePath,
509
- newPackagePath,
510
- }: {
511
- j: core.JSCodeshift;
512
- base: Collection<any>;
513
- option: Option;
514
- oldPackagePath: string;
515
- newPackagePath: string;
516
- }) {
517
- const currentName: string = option.type === 'change-name' ? option.oldName : option.name;
518
- const desiredName: string = option.type === 'change-name' ? option.newName : option.name;
519
-
520
- const isUsingName: boolean =
521
- base
522
- .find(j.ImportDeclaration)
523
- .filter((path) => path.node.source.value === oldPackagePath)
524
- .find(j.ImportSpecifier)
525
- .find(j.Identifier)
526
- .filter((identifier) => identifier.value.name === currentName).length > 0;
527
-
528
- if (!isUsingName) {
529
- return;
530
- }
531
-
532
- const existingAlias: Nullable<string> =
533
- base
534
- .find(j.ImportDeclaration)
535
- .filter((path) => path.node.source.value === oldPackagePath)
536
- .find(j.ImportSpecifier)
537
- .nodes()
538
- .map((specifier): Nullable<string> => {
539
- if (specifier.imported.name !== currentName) {
540
- return null;
541
- }
542
- // If aliased: return the alias
543
- if (specifier.local && specifier.local.name !== currentName) {
544
- return specifier.local.name;
545
- }
546
-
547
- return null;
548
- })
549
- .filter(Boolean)[0] || null;
550
-
551
- base
552
- .find(j.ImportDeclaration)
553
- .filter((path) => path.node.source.value === oldPackagePath)
554
- .find(j.ImportSpecifier)
555
- .find(j.Identifier)
556
- .filter((identifier) => {
557
- if (identifier.value.name === currentName) {
558
- return true;
559
- }
560
- if (identifier.value.name === existingAlias) {
561
- return true;
562
- }
563
- return false;
564
- })
565
- .remove();
566
-
567
- // Check to see if need to create new package path
568
- // Try create an import declaration just before the old import
569
- tryCreateImport({
570
- j,
571
- base,
572
- relativeToPackage: oldPackagePath,
573
- packageName: newPackagePath,
574
- });
575
-
576
- if (option.type === 'keep-name') {
577
- const newSpecifier: ImportSpecifier | ImportDefaultSpecifier = (() => {
578
- if (option.behaviour === 'keep-as-named-import') {
579
- if (existingAlias) {
580
- return j.importSpecifier(j.identifier(desiredName), j.identifier(existingAlias));
581
- }
582
-
583
- return j.importSpecifier(j.identifier(desiredName));
584
- }
585
-
586
- // moving to default specifier
587
- return j.importDefaultSpecifier(j.identifier(existingAlias || desiredName));
588
- })();
589
-
590
- // We don't need to touch anything else in the file
591
-
592
- addToImport({
593
- j,
594
- base,
595
- importSpecifier: newSpecifier,
596
- packageName: newPackagePath,
597
- });
598
- return;
599
- }
600
-
601
- const isNewNameAvailable: boolean =
602
- base.find(j.Identifier).filter((i) => i.value.name === option.newName).length === 0;
603
-
604
- const newSpecifier: ImportSpecifier = (() => {
605
- if (existingAlias) {
606
- return j.importSpecifier(j.identifier(desiredName), j.identifier(existingAlias));
607
- }
608
-
609
- if (isNewNameAvailable) {
610
- return j.importSpecifier(j.identifier(desiredName));
611
- }
612
-
613
- // new type name is not available: need to use a new alias
614
- return j.importSpecifier(j.identifier(desiredName), j.identifier(option.fallbackNameAlias));
615
- })();
616
-
617
- addToImport({
618
- j,
619
- base,
620
- importSpecifier: newSpecifier,
621
- packageName: newPackagePath,
622
- });
623
-
624
- // Change usages of old type in file
625
- base
626
- .find(j.Identifier)
627
- .filter((identifier) => identifier.value.name === option.oldName)
628
- .replaceWith(j.identifier(isNewNameAvailable ? option.newName : option.fallbackNameAlias));
629
- }
@@ -1 +0,0 @@
1
- We are using the `optimistic-` prefix so that the optimistic codemod won't be run in branch deploys