@atlaskit/codemod-cli 0.24.2 → 0.24.4

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 (54) hide show
  1. package/CHANGELOG.md +338 -323
  2. package/dist/cjs/main.js +1 -1
  3. package/dist/cjs/presets/migrate-to-new-buttons/codemods/next-migrate-to-new-button-variants.js +154 -56
  4. package/dist/cjs/presets/migrate-to-new-buttons/codemods/next-split-imports.js +18 -4
  5. package/dist/cjs/presets/migrate-to-new-buttons/utils/add-comment-for-custom-theme-buttons.js +1 -1
  6. package/dist/cjs/presets/migrate-to-new-buttons/utils/constants.js +16 -3
  7. package/dist/cjs/presets/migrate-to-new-buttons/utils/get-default-imports.js +14 -0
  8. package/dist/cjs/presets/migrate-to-new-buttons/utils/get-specifier-names.js +14 -0
  9. package/dist/cjs/presets/migrate-to-new-buttons/utils/if-variant-already-imported.js +15 -7
  10. package/dist/cjs/presets/migrate-to-new-buttons/utils/rename-elements.js +18 -0
  11. package/dist/es2019/presets/migrate-to-new-buttons/codemods/next-migrate-to-new-button-variants.js +143 -52
  12. package/dist/es2019/presets/migrate-to-new-buttons/codemods/next-split-imports.js +18 -4
  13. package/dist/es2019/presets/migrate-to-new-buttons/utils/add-comment-for-custom-theme-buttons.js +1 -1
  14. package/dist/es2019/presets/migrate-to-new-buttons/utils/constants.js +16 -2
  15. package/dist/es2019/presets/migrate-to-new-buttons/utils/get-default-imports.js +6 -0
  16. package/dist/es2019/presets/migrate-to-new-buttons/utils/get-specifier-names.js +6 -0
  17. package/dist/es2019/presets/migrate-to-new-buttons/utils/if-variant-already-imported.js +9 -3
  18. package/dist/es2019/presets/migrate-to-new-buttons/utils/rename-elements.js +12 -0
  19. package/dist/esm/main.js +1 -1
  20. package/dist/esm/presets/migrate-to-new-buttons/codemods/next-migrate-to-new-button-variants.js +154 -57
  21. package/dist/esm/presets/migrate-to-new-buttons/codemods/next-split-imports.js +18 -4
  22. package/dist/esm/presets/migrate-to-new-buttons/utils/add-comment-for-custom-theme-buttons.js +1 -1
  23. package/dist/esm/presets/migrate-to-new-buttons/utils/constants.js +15 -2
  24. package/dist/esm/presets/migrate-to-new-buttons/utils/get-default-imports.js +8 -0
  25. package/dist/esm/presets/migrate-to-new-buttons/utils/get-specifier-names.js +8 -0
  26. package/dist/esm/presets/migrate-to-new-buttons/utils/if-variant-already-imported.js +14 -6
  27. package/dist/esm/presets/migrate-to-new-buttons/utils/rename-elements.js +12 -0
  28. package/dist/types/main.d.ts +1 -1
  29. package/dist/types/presets/migrate-to-new-buttons/utils/constants.d.ts +11 -1
  30. package/dist/types/presets/migrate-to-new-buttons/utils/get-default-imports.d.ts +5 -0
  31. package/dist/types/presets/migrate-to-new-buttons/utils/get-specifier-names.d.ts +5 -0
  32. package/dist/types/presets/migrate-to-new-buttons/utils/if-variant-already-imported.d.ts +2 -1
  33. package/dist/types/presets/migrate-to-new-buttons/utils/migrate-fit-container-icon-button.d.ts +1 -1
  34. package/dist/types/presets/migrate-to-new-buttons/utils/rename-elements.d.ts +2 -0
  35. package/dist/types/presets/styled-to-emotion/styled-to-emotion.d.ts +1 -1
  36. package/dist/types/presets/theme-remove-deprecated-mixins/theme-remove-deprecated-mixins.d.ts +1 -1
  37. package/dist/types/presets/upgrade-pragmatic-drag-and-drop-to-stable/upgrade-pragmatic-drag-and-drop-to-stable.d.ts +1 -1
  38. package/dist/types/sinceRef.d.ts +1 -1
  39. package/dist/types/transforms.d.ts +2 -2
  40. package/dist/types/types.d.ts +1 -1
  41. package/dist/types-ts4.5/main.d.ts +1 -1
  42. package/dist/types-ts4.5/presets/migrate-to-new-buttons/utils/constants.d.ts +11 -1
  43. package/dist/types-ts4.5/presets/migrate-to-new-buttons/utils/get-default-imports.d.ts +5 -0
  44. package/dist/types-ts4.5/presets/migrate-to-new-buttons/utils/get-specifier-names.d.ts +5 -0
  45. package/dist/types-ts4.5/presets/migrate-to-new-buttons/utils/if-variant-already-imported.d.ts +2 -1
  46. package/dist/types-ts4.5/presets/migrate-to-new-buttons/utils/migrate-fit-container-icon-button.d.ts +1 -1
  47. package/dist/types-ts4.5/presets/migrate-to-new-buttons/utils/rename-elements.d.ts +2 -0
  48. package/dist/types-ts4.5/presets/styled-to-emotion/styled-to-emotion.d.ts +1 -1
  49. package/dist/types-ts4.5/presets/theme-remove-deprecated-mixins/theme-remove-deprecated-mixins.d.ts +1 -1
  50. package/dist/types-ts4.5/presets/upgrade-pragmatic-drag-and-drop-to-stable/upgrade-pragmatic-drag-and-drop-to-stable.d.ts +1 -1
  51. package/dist/types-ts4.5/sinceRef.d.ts +1 -1
  52. package/dist/types-ts4.5/transforms.d.ts +2 -2
  53. package/dist/types-ts4.5/types.d.ts +1 -1
  54. package/package.json +2 -4
package/dist/cjs/main.js CHANGED
@@ -305,7 +305,7 @@ function _main() {
305
305
  case 4:
306
306
  _yield$parseArgs = _context5.sent;
307
307
  packages = _yield$parseArgs.packages;
308
- _process$env$_PACKAGE = "0.24.2", _PACKAGE_VERSION_ = _process$env$_PACKAGE === void 0 ? '0.0.0-dev' : _process$env$_PACKAGE;
308
+ _process$env$_PACKAGE = "0.24.4", _PACKAGE_VERSION_ = _process$env$_PACKAGE === void 0 ? '0.0.0-dev' : _process$env$_PACKAGE;
309
309
  logger.log(_chalk.default.bgBlue(_chalk.default.black("\uD83D\uDCDA Atlassian-Frontend codemod library @ ".concat(_PACKAGE_VERSION_, " \uD83D\uDCDA"))));
310
310
  if (packages && packages.length > 0) {
311
311
  logger.log(_chalk.default.gray("Searching for codemods for newer versions of the following packages: ".concat(packages.map(function (pkg) {
@@ -1,12 +1,16 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
7
  exports.default = void 0;
8
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
7
9
  var _codemodUtils = require("@atlaskit/codemod-utils");
8
10
  var _utils = require("@hypermod/utils");
9
11
  var _constants = require("../utils/constants");
12
+ var _getDefaultImports = _interopRequireDefault(require("../utils/get-default-imports"));
13
+ var _getSpecifierNames = _interopRequireDefault(require("../utils/get-specifier-names"));
10
14
  var _generateNewButtonElement = require("../utils/generate-new-button-element");
11
15
  var _hasUnsupportedProps = require("../utils/has-unsupported-props");
12
16
  var _ifVariantAlreadyImported = require("../utils/if-variant-already-imported");
@@ -18,31 +22,44 @@ var transformer = function transformer(file, api) {
18
22
  var j = api.jscodeshift;
19
23
  var fileSource = j(file.source);
20
24
  (0, _addCommentForCustomThemeButtons.addCommentForCustomThemeButtons)(fileSource, j);
21
- var buttonImports = fileSource.find(j.ImportDeclaration).filter(function (path) {
22
- return path.node.source.value === _constants.entryPointsMapping.Button || path.node.source.value === _constants.entryPointsMapping.LoadingButton || path.node.source.value === _constants.NEW_BUTTON_ENTRY_POINT;
25
+
26
+ // Find old buttons
27
+ var oldButtonImports = fileSource.find(j.ImportDeclaration).filter(function (path) {
28
+ return path.node.source.value === _constants.entryPointsMapping.Button || path.node.source.value === _constants.entryPointsMapping.LoadingButton || path.node.source.value === _constants.OLD_BUTTON_ENTRY_POINT;
23
29
  });
24
- if (!buttonImports.length) {
30
+ if (!oldButtonImports.length) {
25
31
  return fileSource.toSource();
26
32
  }
27
- var defaultButtonImport = buttonImports.find(j.Specifier).filter(function (path) {
28
- return path.node.type === 'ImportDefaultSpecifier';
33
+ var oldDefaultDefaultImports = (0, _getDefaultImports.default)(oldButtonImports, j);
34
+ var oldDefaultImportSpecifiers = (0, _getSpecifierNames.default)(oldDefaultDefaultImports);
35
+
36
+ // Find new buttons
37
+ var newButtonImports = fileSource.find(j.ImportDeclaration).filter(function (path) {
38
+ return path.node.source.value === _constants.NEW_BUTTON_ENTRY_POINT;
29
39
  });
30
- if (defaultButtonImport.length === 0) {
31
- return fileSource.toSource();
32
- }
33
- var specifierIdentifier = defaultButtonImport.get(0).node.local.name;
34
- var hasLinkIconButton = (0, _ifVariantAlreadyImported.checkIfVariantAlreadyImported)(_constants.NEW_BUTTON_VARIANTS.linkIcon, fileSource, j);
35
- var hasLinkButton = (0, _ifVariantAlreadyImported.checkIfVariantAlreadyImported)(_constants.NEW_BUTTON_VARIANTS.link, fileSource, j);
36
- var hasIconButton = (0, _ifVariantAlreadyImported.checkIfVariantAlreadyImported)(_constants.NEW_BUTTON_VARIANTS.icon, fileSource, j);
37
- var hasDefaultLoadingButton = false;
38
- var allButtons = fileSource.find(j.JSXElement).filter(function (path) {
39
- return path.value.openingElement.name.type === 'JSXIdentifier' && path.value.openingElement.name.name === specifierIdentifier;
40
+ var newDefaultDefaultImports = (0, _getDefaultImports.default)(newButtonImports, j);
41
+ var newDefaultImportSpecifiers = (0, _getSpecifierNames.default)(newDefaultDefaultImports);
42
+ var loadingButtonDirectImportName = (0, _utils.getDefaultImportSpecifierName)(j, fileSource, _constants.entryPointsMapping.LoadingButton);
43
+
44
+ /**
45
+ * Which variants should be in this file?
46
+ *
47
+ * Any variants enabled here will be added to the final import statement.
48
+ * Initial values check if the variant is already imported in the file.
49
+ */
50
+ var hasVariant = {
51
+ defaultButton: (0, _ifVariantAlreadyImported.checkIfVariantAlreadyImported)(_constants.NEW_BUTTON_VARIANTS.default, _constants.NEW_BUTTON_ENTRY_POINT, fileSource, j, true),
52
+ linkButton: (0, _ifVariantAlreadyImported.checkIfVariantAlreadyImported)(_constants.NEW_BUTTON_VARIANTS.link, _constants.NEW_BUTTON_ENTRY_POINT, fileSource, j),
53
+ iconButton: (0, _ifVariantAlreadyImported.checkIfVariantAlreadyImported)(_constants.NEW_BUTTON_VARIANTS.icon, _constants.NEW_BUTTON_ENTRY_POINT, fileSource, j),
54
+ linkIconButton: (0, _ifVariantAlreadyImported.checkIfVariantAlreadyImported)(_constants.NEW_BUTTON_VARIANTS.linkIcon, _constants.NEW_BUTTON_ENTRY_POINT, fileSource, j)
55
+ };
56
+ var oldButtonElements = fileSource.find(j.JSXElement).filter(function (path) {
57
+ return path.value.openingElement.name.type === 'JSXIdentifier' && ((oldDefaultImportSpecifiers === null || oldDefaultImportSpecifiers === void 0 ? void 0 : oldDefaultImportSpecifiers.includes(path.value.openingElement.name.name)) || Object.values(_constants.OLD_BUTTON_VARIANTS).includes(path.value.openingElement.name.name));
40
58
  });
41
- var buttonsWithoutUnsupportedProps = allButtons.filter(function (path) {
59
+ var oldButtonsWithoutUnsupportedProps = oldButtonElements.filter(function (path) {
42
60
  return !(0, _hasUnsupportedProps.ifHasUnsupportedProps)(path.value.openingElement.attributes);
43
61
  });
44
- var loadingButtonImportName = (0, _utils.getDefaultImportSpecifierName)(j, fileSource, _constants.entryPointsMapping.LoadingButton);
45
- buttonsWithoutUnsupportedProps.forEach(function (element) {
62
+ oldButtonsWithoutUnsupportedProps.forEach(function (element) {
46
63
  var _element$value$childr;
47
64
  var attributes = element.value.openingElement.attributes;
48
65
  if (!attributes) {
@@ -58,9 +75,14 @@ var transformer = function transformer(file, api) {
58
75
  var isLinkIconButton = hasHref && hasIcon && hasNoChildren && !isFitContainerIconButton;
59
76
  var isLinkButton = hasHref && !isLinkIconButton;
60
77
  var isIconButton = !hasHref && hasIcon && hasNoChildren && !isFitContainerIconButton;
61
- var isDefaultButtonWithAnIcon = !isLinkIconButton && !isIconButton && !isFitContainerIconButton && hasIcon;
62
- var isLoadingButton = element.value.openingElement.name.type === 'JSXIdentifier' && element.value.openingElement.name.name === loadingButtonImportName;
63
- if (isDefaultButtonWithAnIcon) {
78
+ var isDefaultButton = !isLinkButton && !isLinkIconButton && !isIconButton && !isFitContainerIconButton;
79
+ var isDefaultVariantWithAnIcon = !isLinkIconButton && !isIconButton && !isFitContainerIconButton && hasIcon;
80
+ var isLoadingButton = element.value.openingElement.name.type === 'JSXIdentifier' && element.value.openingElement.name.name === loadingButtonDirectImportName;
81
+ var linkAppearanceAttribute = attributes.find(function (node) {
82
+ var _node$value, _node$name, _node$value2, _node$value3;
83
+ return node.type === 'JSXAttribute' && ((_node$value = node.value) === null || _node$value === void 0 ? void 0 : _node$value.type) === 'StringLiteral' && (node === null || node === void 0 || (_node$name = node.name) === null || _node$name === void 0 ? void 0 : _node$name.name) === 'appearance' && ((node === null || node === void 0 || (_node$value2 = node.value) === null || _node$value2 === void 0 ? void 0 : _node$value2.value) === 'link' || (node === null || node === void 0 || (_node$value3 = node.value) === null || _node$value3 === void 0 ? void 0 : _node$value3.value) === 'subtle-link');
84
+ });
85
+ if (isDefaultVariantWithAnIcon) {
64
86
  (0, _generateNewButtonElement.handleIconAttributes)(element.value, j);
65
87
  }
66
88
  if (isFitContainerIconButton) {
@@ -69,78 +91,113 @@ var transformer = function transformer(file, api) {
69
91
  isIconButton = true;
70
92
  }
71
93
  }
72
- if (isLinkIconButton) {
73
- hasLinkIconButton = true;
94
+ if (isLinkIconButton && !isLoadingButton) {
95
+ hasVariant.linkIconButton = true;
74
96
  j(element).replaceWith((0, _generateNewButtonElement.generateNewElement)(_constants.NEW_BUTTON_VARIANTS.linkIcon, element.value, j));
75
97
  }
76
- if (isIconButton) {
77
- hasIconButton = true;
98
+ if (isIconButton && !isLoadingButton) {
99
+ hasVariant.iconButton = true;
78
100
  j(element).replaceWith((0, _generateNewButtonElement.generateNewElement)(_constants.NEW_BUTTON_VARIANTS.icon, element.value, j));
79
101
  }
80
- if (isLinkButton) {
81
- hasLinkButton = true;
102
+ if (isLinkButton && !isLoadingButton) {
103
+ hasVariant.linkButton = true;
82
104
  j(element).replaceWith((0, _generateNewButtonElement.generateNewElement)(_constants.NEW_BUTTON_VARIANTS.link, element.value, j));
83
105
  }
84
- if (isLoadingButton && !isIconButton) {
85
- hasDefaultLoadingButton = true;
86
- j(element).replaceWith((0, _generateNewButtonElement.generateNewElement)(_constants.NEW_BUTTON_VARIANTS.default, element.value, j));
106
+ if (isDefaultButton && !isLoadingButton) {
107
+ hasVariant.defaultButton = true;
108
+ j(element).replaceWith((0, _generateNewButtonElement.generateNewElement)(newDefaultImportSpecifiers !== null && newDefaultImportSpecifiers !== void 0 && newDefaultImportSpecifiers.length ?
109
+ // If new button already has a default import, use that incase it's aliased
110
+ newDefaultImportSpecifiers[0] : _constants.NEW_BUTTON_VARIANTS.default, element.value, j));
87
111
  }
88
- var linkAppearanceAttribute = attributes.find(function (node) {
89
- var _node$value, _node$name, _node$value2, _node$value3;
90
- return node.type === 'JSXAttribute' && ((_node$value = node.value) === null || _node$value === void 0 ? void 0 : _node$value.type) === 'StringLiteral' && (node === null || node === void 0 || (_node$name = node.name) === null || _node$name === void 0 ? void 0 : _node$name.name) === 'appearance' && ((node === null || node === void 0 || (_node$value2 = node.value) === null || _node$value2 === void 0 ? void 0 : _node$value2.value) === 'link' || (node === null || node === void 0 || (_node$value3 = node.value) === null || _node$value3 === void 0 ? void 0 : _node$value3.value) === 'subtle-link');
91
- });
92
- if (!hasHref && linkAppearanceAttribute) {
112
+ if (isLoadingButton) {
113
+ var newElement = (0, _generateNewButtonElement.generateNewElement)(_constants.NEW_BUTTON_VARIANTS[isIconButton || isLinkIconButton ? 'icon' : 'default'], element.value, j);
114
+ if (isIconButton || isLinkIconButton) {
115
+ hasVariant.iconButton = true;
116
+ } else {
117
+ hasVariant.defaultButton = true;
118
+
119
+ // rename existing Button to LegacyButton
120
+ var existingDefaultButtonSpecifier = fileSource.find(j.ImportDefaultSpecifier).filter(function (path) {
121
+ var _path$value$local;
122
+ return ((_path$value$local = path.value.local) === null || _path$value$local === void 0 ? void 0 : _path$value$local.name) === _constants.NEW_BUTTON_VARIANTS.default;
123
+ });
124
+ if (existingDefaultButtonSpecifier.length > 0) {
125
+ fileSource.find(j.JSXElement).filter(function (path) {
126
+ return path.value.openingElement.name.type === 'JSXIdentifier' && path.value.openingElement.name.name === _constants.NEW_BUTTON_VARIANTS.default;
127
+ }).forEach(function (element) {
128
+ var _element$value$childr2, _element$value$childr3;
129
+ // find all default <Button> JSX elements and replace with <LegacyButton>
130
+ j(element).replaceWith(j.jsxElement(j.jsxOpeningElement(j.jsxIdentifier('LegacyButton'), element.value.openingElement.attributes, ((_element$value$childr2 = element.value.children) === null || _element$value$childr2 === void 0 ? void 0 : _element$value$childr2.length) === 0), ((_element$value$childr3 = element.value.children) === null || _element$value$childr3 === void 0 ? void 0 : _element$value$childr3.length) === 0 ? null : j.jsxClosingElement(j.jsxIdentifier('LegacyButton')), element.value.children));
131
+ });
132
+
133
+ // rename Button to LegacyButton in all call expressions i.e. render(Button), find(Button)
134
+ fileSource.find(j.CallExpression).find(j.Identifier).forEach(function (path) {
135
+ if (path.node.name === _constants.NEW_BUTTON_VARIANTS.default) {
136
+ path.node.name = 'LegacyButton';
137
+ }
138
+ });
139
+
140
+ // rename Button to LegacyButton in import declaration
141
+ existingDefaultButtonSpecifier.forEach(function (specifier) {
142
+ return j(specifier).replaceWith(j.importDefaultSpecifier(j.identifier('LegacyButton')));
143
+ });
144
+ }
145
+ }
146
+ j(element).replaceWith(newElement);
147
+ if (hasHref || linkAppearanceAttribute) {
148
+ (0, _codemodUtils.addCommentBefore)(j, j(newElement), (0, _constants.loadingButtonComment)({
149
+ hasHref: hasHref,
150
+ hasLinkAppearance: Boolean(linkAppearanceAttribute)
151
+ }), 'block');
152
+ }
153
+ } else if (!hasHref && linkAppearanceAttribute) {
93
154
  (0, _codemodUtils.addCommentBefore)(j, j(linkAppearanceAttribute), _constants.linkButtonMissingHrefComment, 'line');
94
155
  }
95
156
  });
96
157
 
97
158
  // modify import declarations
98
159
  var specifiers = [];
99
- [hasLinkButton ? 'link' : null, hasIconButton ? 'icon' : null, hasLinkIconButton ? 'linkIcon' : null].forEach(function (variant) {
160
+ [hasVariant.linkButton ? 'link' : null, hasVariant.iconButton ? 'icon' : null, hasVariant.linkIconButton ? 'linkIcon' : null].forEach(function (variant) {
100
161
  if (variant) {
101
162
  specifiers.push(j.importSpecifier(j.identifier(_constants.NEW_BUTTON_VARIANTS[variant])));
102
163
  }
103
164
  });
104
- var oldButtonImport = fileSource.find(j.ImportDeclaration).filter(function (path) {
105
- return path.node.source.value === _constants.NEW_BUTTON_ENTRY_POINT || path.node.source.value === _constants.entryPointsMapping.Button || path.node.source.value === _constants.entryPointsMapping.LoadingButton;
106
- });
107
165
  var remainingDefaultButtons = fileSource.find(j.JSXElement).filter(function (path) {
108
- return path.value.openingElement.name.type === 'JSXIdentifier' && path.value.openingElement.name.name === specifierIdentifier && !(0, _hasUnsupportedProps.ifHasUnsupportedProps)(path.value.openingElement.attributes);
166
+ return path.value.openingElement.name.type === 'JSXIdentifier' && Boolean(oldDefaultImportSpecifiers === null || oldDefaultImportSpecifiers === void 0 ? void 0 : oldDefaultImportSpecifiers.includes(path.value.openingElement.name.name)) && !(0, _hasUnsupportedProps.ifHasUnsupportedProps)(path.value.openingElement.attributes);
109
167
  }).length > 0 || fileSource.find(j.CallExpression).filter(function (path) {
110
168
  return path.node.arguments.map(function (argument) {
111
169
  return argument.type === 'Identifier' && (argument === null || argument === void 0 ? void 0 : argument.name);
112
- }).includes(specifierIdentifier);
170
+ }).some(function (name) {
171
+ return name && (oldDefaultImportSpecifiers === null || oldDefaultImportSpecifiers === void 0 ? void 0 : oldDefaultImportSpecifiers.includes(name));
172
+ });
113
173
  }).length > 0;
114
174
 
115
175
  // Loading buttons map back to default imports
116
- if (specifierIdentifier === loadingButtonImportName) {
176
+ if (loadingButtonDirectImportName && oldDefaultImportSpecifiers !== null && oldDefaultImportSpecifiers !== void 0 && oldDefaultImportSpecifiers.includes(loadingButtonDirectImportName)) {
117
177
  fileSource
118
178
  // rename LoadingButton to Button in all call expressions i.e. render(LoadingButton), find(LoadingButton)
119
179
  .find(j.CallExpression).find(j.Identifier).forEach(function (path) {
120
- if (path.node.name === loadingButtonImportName) {
180
+ if (path.node.name === loadingButtonDirectImportName) {
121
181
  path.node.name = _constants.NEW_BUTTON_VARIANTS.default;
122
182
  }
123
183
  });
124
-
125
- // Only add the Button import if we found a default button, not icon only
126
- if (hasDefaultLoadingButton) {
127
- specifiers.push(j.importDefaultSpecifier(j.identifier(_constants.NEW_BUTTON_VARIANTS.default)));
128
- }
129
184
  }
130
- if (!specifiers.find(function (specifier) {
185
+
186
+ // Only add the Button import if we found a default button, not icon only
187
+ if (hasVariant.defaultButton || !specifiers.find(function (specifier) {
131
188
  return specifier.type === 'ImportDefaultSpecifier';
132
189
  }) && remainingDefaultButtons) {
133
190
  specifiers.push(j.importDefaultSpecifier(j.identifier(_constants.NEW_BUTTON_VARIANTS.default)));
134
191
  }
135
192
 
136
193
  // update import path for types imports
137
- specifiers = (0, _importTypesFromNewEntryPoint.importTypesFromNewEntryPoint)(buttonImports, specifiers, j, fileSource);
138
- var buttonsWithUnsupportedProps = allButtons.filter(function (path) {
194
+ specifiers = (0, _importTypesFromNewEntryPoint.importTypesFromNewEntryPoint)(oldButtonImports, specifiers, j, fileSource);
195
+ var oldButtonsWithUnsupportedProps = oldButtonElements.filter(function (path) {
139
196
  return (0, _hasUnsupportedProps.ifHasUnsupportedProps)(path.value.openingElement.attributes);
140
197
  });
141
- if (buttonsWithUnsupportedProps.length) {
198
+ if (oldButtonsWithUnsupportedProps.length) {
142
199
  // add comment to all buttons with unsupported props: "component", "style", "css"
143
- buttonsWithUnsupportedProps.forEach(function (element) {
200
+ oldButtonsWithUnsupportedProps.forEach(function (element) {
144
201
  var _element$value$openin;
145
202
  var attribute = (_element$value$openin = element.value.openingElement.attributes) === null || _element$value$openin === void 0 ? void 0 : _element$value$openin.find(function (node) {
146
203
  return node.type === 'JSXAttribute' && typeof node.name.name === 'string' && _constants.unsupportedProps.includes(node.name.name);
@@ -154,22 +211,63 @@ var transformer = function transformer(file, api) {
154
211
  if (specifiers.find(function (specifier) {
155
212
  return specifier.type === 'ImportDefaultSpecifier';
156
213
  })) {
157
- (0, _renameDefaultButtonToLegacyButton.renameDefaultButtonToLegacyButtonImport)(oldButtonImport, buttonsWithUnsupportedProps, j);
214
+ (0, _renameDefaultButtonToLegacyButton.renameDefaultButtonToLegacyButtonImport)(oldButtonImports, oldButtonsWithUnsupportedProps, j);
158
215
  }
159
216
  }
160
217
  if (specifiers.length) {
218
+ var existingNewButtonImports = fileSource.find(j.ImportDeclaration).filter(function (path) {
219
+ return path.node.source.value === _constants.NEW_BUTTON_ENTRY_POINT;
220
+ });
161
221
  var newButtonImport = j.importDeclaration(specifiers, j.stringLiteral(_constants.NEW_BUTTON_ENTRY_POINT));
162
- oldButtonImport.forEach(function (path) {
222
+ oldButtonImports.forEach(function (path) {
163
223
  var _path$node;
164
224
  newButtonImport.comments = path !== null && path !== void 0 && (_path$node = path.node) !== null && _path$node !== void 0 && _path$node.comments ? path.node.comments : undefined;
165
225
  });
166
- oldButtonImport.replaceWith(newButtonImport);
226
+ if (existingNewButtonImports.length) {
227
+ existingNewButtonImports.forEach(function (path) {
228
+ // Merge specifiers from existing new button import with added specifiers
229
+ var mergedSpecifiers = [].concat((0, _toConsumableArray2.default)(specifiers.filter(function (specifier) {
230
+ var _path$node$specifiers;
231
+ if (specifier.type !== 'ImportDefaultSpecifier') {
232
+ return true;
233
+ }
234
+
235
+ // Ensure we don't add a duplicate default specifier if one is already imported
236
+ return !((_path$node$specifiers = path.node.specifiers) !== null && _path$node$specifiers !== void 0 && _path$node$specifiers.find(function (s) {
237
+ return s.type === 'ImportDefaultSpecifier';
238
+ }));
239
+ })), (0, _toConsumableArray2.default)(path.node.specifiers ? path.node.specifiers : [])) // Filter duplicates
240
+ .filter(function (specifier) {
241
+ if (specifier.type === 'ImportDefaultSpecifier') {
242
+ return true;
243
+ }
244
+ var isAlreadyImported = specifiers.find(function (s) {
245
+ var _specifier$local;
246
+ return s.type === 'ImportSpecifier' && s.imported.name === ((_specifier$local = specifier.local) === null || _specifier$local === void 0 ? void 0 : _specifier$local.name);
247
+ });
248
+ return !isAlreadyImported;
249
+ });
250
+ newButtonImport = j.importDeclaration(mergedSpecifiers, j.stringLiteral(_constants.NEW_BUTTON_ENTRY_POINT));
251
+ });
252
+ oldButtonImports.remove();
253
+ existingNewButtonImports.replaceWith(newButtonImport);
254
+ } else {
255
+ oldButtonImports.replaceWith(function (_, index) {
256
+ // Only replace the first import
257
+ if (index === 0) {
258
+ return newButtonImport;
259
+ }
260
+ // Remove the rest
261
+ return null;
262
+ });
263
+ }
167
264
  }
168
265
 
169
266
  // remove empty import declarations
170
267
  fileSource.find(j.ImportDeclaration).filter(function (path) {
171
268
  return (path.node.source.value === '@atlaskit/button' || path.node.source.value === '@atlaskit/button/types') && !!path.node.specifiers && path.node.specifiers.length === 0;
172
269
  }).remove();
270
+ (0, _addCommentForCustomThemeButtons.addCommentForCustomThemeButtons)(fileSource, j);
173
271
  return fileSource.toSource(_constants.PRINT_SETTINGS);
174
272
  };
175
273
  var _default = exports.default = transformer;
@@ -7,6 +7,8 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.default = void 0;
8
8
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
9
  var _constants = require("../utils/constants");
10
+ var _renameElements = _interopRequireDefault(require("../utils/rename-elements"));
11
+ var _utils = require("@hypermod/utils");
10
12
  var transformer = function transformer(file, api) {
11
13
  var j = api.jscodeshift;
12
14
  var fileSource = j(file.source);
@@ -32,8 +34,14 @@ var transformer = function transformer(file, api) {
32
34
  return specifier.type === 'ImportDefaultSpecifier';
33
35
  });
34
36
  if (defaultSpecifier && defaultSpecifier.local) {
35
- var defaultButtonImport = j.importDeclaration([j.importDefaultSpecifier(j.identifier(defaultSpecifier.local.name))], j.stringLiteral(_constants.entryPointsMapping.Button));
36
- j(node).insertAfter(defaultButtonImport);
37
+ var existingSpecifier = (0, _utils.getDefaultImportSpecifierName)(j, fileSource, _constants.entryPointsMapping.Button);
38
+ if (existingSpecifier) {
39
+ var _defaultSpecifier$loc;
40
+ (0, _renameElements.default)((_defaultSpecifier$loc = defaultSpecifier.local) === null || _defaultSpecifier$loc === void 0 ? void 0 : _defaultSpecifier$loc.name, existingSpecifier, fileSource, j);
41
+ } else {
42
+ var newImport = j.importDeclaration([j.importDefaultSpecifier(j.identifier(defaultSpecifier.local.name))], j.stringLiteral(_constants.entryPointsMapping.Button));
43
+ j(node).insertAfter(newImport);
44
+ }
37
45
  }
38
46
  var namedSpecifiers = specifiers === null || specifiers === void 0 ? void 0 : specifiers.filter(function (specifier) {
39
47
  return specifier.type === 'ImportSpecifier';
@@ -55,8 +63,14 @@ var transformer = function transformer(file, api) {
55
63
  if (namedSpecifiers !== null && namedSpecifiers !== void 0 && namedSpecifiers.length) {
56
64
  namedSpecifiers.forEach(function (specifier) {
57
65
  if (specifier.local && specifier.type === 'ImportSpecifier' && specifier.local.name && _constants.entryPointsMapping[specifier.imported.name]) {
58
- var newImport = j.importDeclaration([j.importDefaultSpecifier(j.identifier(specifier.local.name))], j.stringLiteral(_constants.entryPointsMapping[specifier.imported.name]));
59
- j(node).insertAfter(newImport);
66
+ var _existingSpecifier = (0, _utils.getDefaultImportSpecifierName)(j, fileSource, _constants.entryPointsMapping[specifier.imported.name]);
67
+ if (_existingSpecifier) {
68
+ var _specifier$local;
69
+ (0, _renameElements.default)((_specifier$local = specifier.local) === null || _specifier$local === void 0 ? void 0 : _specifier$local.name, _existingSpecifier, fileSource, j);
70
+ } else {
71
+ var _newImport = j.importDeclaration([j.importDefaultSpecifier(j.identifier(specifier.local.name))], j.stringLiteral(_constants.entryPointsMapping[specifier.imported.name]));
72
+ j(node).insertAfter(_newImport);
73
+ }
60
74
  }
61
75
  });
62
76
  }
@@ -29,5 +29,5 @@ var addCommentForCustomThemeButtons = exports.addCommentForCustomThemeButtons =
29
29
  if (!customThemeButtonElement.length) {
30
30
  return;
31
31
  }
32
- (0, _codemodUtils.addCommentBefore)(j, j(customThemeButtonElement.get(0).node.openingElement), _constants.customThemeButtonComment, 'line');
32
+ (0, _codemodUtils.addCommentBefore)(j, j(customThemeButtonElement.get(0).node.openingElement), _constants.customThemeButtonComment, 'block');
33
33
  };
@@ -3,17 +3,25 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.unsupportedProps = exports.migrateFitContainerButtonToIconButtonComment = exports.migrateFitContainerButtonToDefaultButtonComment = exports.linkButtonMissingHrefComment = exports.entryPointsMapping = exports.customThemeButtonComment = exports.buttonPropsNoLongerSupportedComment = exports.UNSAFE_SIZE_PROPS_MAP = exports.PRINT_SETTINGS = exports.NEW_BUTTON_VARIANTS = exports.NEW_BUTTON_ENTRY_POINT = exports.BUTTON_TYPES = void 0;
6
+ exports.unsupportedProps = exports.migrateFitContainerButtonToIconButtonComment = exports.migrateFitContainerButtonToDefaultButtonComment = exports.loadingButtonComment = exports.linkButtonMissingHrefComment = exports.entryPointsMapping = exports.customThemeButtonComment = exports.buttonPropsNoLongerSupportedComment = exports.UNSAFE_SIZE_PROPS_MAP = exports.PRINT_SETTINGS = exports.OLD_BUTTON_VARIANTS = exports.OLD_BUTTON_ENTRY_POINT = exports.NEW_BUTTON_VARIANTS = exports.NEW_BUTTON_ENTRY_POINT = exports.BUTTON_TYPES = void 0;
7
7
  var PRINT_SETTINGS = exports.PRINT_SETTINGS = {
8
8
  quote: 'single'
9
9
  };
10
+
11
+ /** NEW button **/
12
+ var NEW_BUTTON_ENTRY_POINT = exports.NEW_BUTTON_ENTRY_POINT = '@atlaskit/button/new';
10
13
  var NEW_BUTTON_VARIANTS = exports.NEW_BUTTON_VARIANTS = {
11
14
  default: 'Button',
12
15
  link: 'LinkButton',
13
16
  icon: 'IconButton',
14
17
  linkIcon: 'LinkIconButton'
15
18
  };
16
- var NEW_BUTTON_ENTRY_POINT = exports.NEW_BUTTON_ENTRY_POINT = '@atlaskit/button/new';
19
+
20
+ /** OLD button **/
21
+ var OLD_BUTTON_ENTRY_POINT = exports.OLD_BUTTON_ENTRY_POINT = '@atlaskit/button';
22
+ var OLD_BUTTON_VARIANTS = exports.OLD_BUTTON_VARIANTS = {
23
+ loading: 'LoadingButton'
24
+ };
17
25
  var entryPointsMapping = exports.entryPointsMapping = {
18
26
  Button: '@atlaskit/button/standard-button',
19
27
  LoadingButton: '@atlaskit/button/loading-button',
@@ -31,4 +39,9 @@ var linkButtonMissingHrefComment = exports.linkButtonMissingHrefComment = "\"lin
31
39
  var buttonPropsNoLongerSupportedComment = exports.buttonPropsNoLongerSupportedComment = "Buttons with \"component\", \"css\" or \"style\" prop can't be automatically migrated with codemods. Please migrate it manually.";
32
40
  var migrateFitContainerButtonToDefaultButtonComment = exports.migrateFitContainerButtonToDefaultButtonComment = "Migrated to a default button with text which is from the icon label.";
33
41
  var migrateFitContainerButtonToIconButtonComment = exports.migrateFitContainerButtonToIconButtonComment = "\"shouldFitContainer\" is not available in icon buttons, please consider using a default button with text.";
34
- var customThemeButtonComment = exports.customThemeButtonComment = "CustomThemeButton will be deprecated. Please consider migrating to Pressable or Anchor Primitives with custom styles.";
42
+ var customThemeButtonComment = exports.customThemeButtonComment = "CustomThemeButton will be deprecated. Please consider migrating to Pressable or Anchor Primitives with custom styles.";
43
+ var loadingButtonComment = exports.loadingButtonComment = function loadingButtonComment(_ref) {
44
+ var hasLinkAppearance = _ref.hasLinkAppearance,
45
+ hasHref = _ref.hasHref;
46
+ return "This should be migrated to a new Button with a `isLoading` prop. ".concat(hasLinkAppearance ? "\"link\" and \"subtle-link\" appearances are not available for new loading buttons.\"" : '').concat(hasHref ? "The `href` attribute it not compatible with new loading buttons, because links should not need loading states." : '', " Please reconsider the design or change the appearance of the button.");
47
+ };
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = getDefaultImports;
7
+ /**
8
+ * Returns default import specifiers from the given import declarations.
9
+ */
10
+ function getDefaultImports(importDeclarations, j) {
11
+ return importDeclarations.find(j.Specifier).filter(function (path) {
12
+ return path.node.type === 'ImportDefaultSpecifier';
13
+ });
14
+ }
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = getSpecifierNames;
7
+ /**
8
+ * Returns a list of specifier names from the given specifiers.
9
+ */
10
+ function getSpecifierNames(specifiers) {
11
+ return specifiers.length ? specifiers.paths().map(function (path) {
12
+ return path.get().value.local.name;
13
+ }) : undefined;
14
+ }
@@ -3,12 +3,20 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.checkIfVariantAlreadyImported = void 0;
7
- var _constants = require("./constants");
8
- var checkIfVariantAlreadyImported = exports.checkIfVariantAlreadyImported = function checkIfVariantAlreadyImported(variant, fileSource, j) {
9
- return fileSource.find(j.ImportDeclaration).filter(function (path) {
10
- return path.node.source.value === _constants.NEW_BUTTON_ENTRY_POINT;
11
- }).find(j.ImportSpecifier).filter(function (path) {
6
+ exports.findVariantAlreadyImported = exports.checkIfVariantAlreadyImported = void 0;
7
+ var findVariantAlreadyImported = exports.findVariantAlreadyImported = function findVariantAlreadyImported(variant, entryPoint, fileSource, j) {
8
+ var isDefaultSpecifier = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
9
+ var imports = fileSource.find(j.ImportDeclaration).filter(function (path) {
10
+ return path.node.source.value === entryPoint;
11
+ });
12
+ if (isDefaultSpecifier) {
13
+ return imports.find(j.ImportDefaultSpecifier);
14
+ }
15
+ return imports.find(j.ImportSpecifier).filter(function (path) {
12
16
  return path.node.imported.name === variant;
13
- }).length > 0;
17
+ });
18
+ };
19
+ var checkIfVariantAlreadyImported = exports.checkIfVariantAlreadyImported = function checkIfVariantAlreadyImported(variant, entryPoint, fileSource, j) {
20
+ var isDefaultSpecifier = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
21
+ return findVariantAlreadyImported(variant, entryPoint, fileSource, j, isDefaultSpecifier).length > 0;
14
22
  };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = renameElements;
7
+ function renameElements(elementName, newElementName, fileSource, j) {
8
+ var oldElements = fileSource.find(j.JSXElement).filter(function (path) {
9
+ return path.value.openingElement.name.type === 'JSXIdentifier' && path.value.openingElement.name.name === elementName;
10
+ });
11
+
12
+ // Rename elements to match existing import name
13
+ oldElements.forEach(function (element) {
14
+ var _element$value$childr, _element$value$childr2;
15
+ var newElement = j.jsxElement(j.jsxOpeningElement(j.jsxIdentifier(newElementName), element.value.openingElement.attributes, ((_element$value$childr = element.value.children) === null || _element$value$childr === void 0 ? void 0 : _element$value$childr.length) === 0), ((_element$value$childr2 = element.value.children) === null || _element$value$childr2 === void 0 ? void 0 : _element$value$childr2.length) === 0 ? null : j.jsxClosingElement(j.jsxIdentifier(newElementName)), element.value.children);
16
+ j(element).replaceWith(newElement);
17
+ });
18
+ }