@atlaskit/codemod-cli 0.28.3 → 0.29.1
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 +16 -0
- package/dist/cjs/main.js +1 -1
- package/dist/cjs/presets/index.js +2 -1
- package/dist/cjs/presets/migrate-icon-object-to-object/codemods/migrate-icon-object-to-object.js +138 -0
- package/dist/cjs/presets/migrate-icon-object-to-object/migrate-icon-object-to-object.js +44 -0
- package/dist/cjs/presets/migrate-icon-object-to-object/utils/constants.js +33 -0
- package/dist/cjs/presets/migrate-icon-object-to-object/utils/icon-mappings.js +81 -0
- package/dist/es2019/presets/index.js +2 -1
- package/dist/es2019/presets/migrate-icon-object-to-object/codemods/migrate-icon-object-to-object.js +130 -0
- package/dist/es2019/presets/migrate-icon-object-to-object/migrate-icon-object-to-object.js +18 -0
- package/dist/es2019/presets/migrate-icon-object-to-object/utils/constants.js +27 -0
- package/dist/es2019/presets/migrate-icon-object-to-object/utils/icon-mappings.js +67 -0
- package/dist/esm/main.js +1 -1
- package/dist/esm/presets/index.js +2 -1
- package/dist/esm/presets/migrate-icon-object-to-object/codemods/migrate-icon-object-to-object.js +132 -0
- package/dist/esm/presets/migrate-icon-object-to-object/migrate-icon-object-to-object.js +37 -0
- package/dist/esm/presets/migrate-icon-object-to-object/utils/constants.js +27 -0
- package/dist/esm/presets/migrate-icon-object-to-object/utils/icon-mappings.js +72 -0
- package/dist/types/presets/index.d.ts +1 -0
- package/dist/types/presets/migrate-icon-object-to-object/codemods/migrate-icon-object-to-object.d.ts +3 -0
- package/dist/types/presets/migrate-icon-object-to-object/migrate-icon-object-to-object.d.ts +2 -0
- package/dist/types/presets/migrate-icon-object-to-object/utils/constants.d.ts +19 -0
- package/dist/types/presets/migrate-icon-object-to-object/utils/icon-mappings.d.ts +29 -0
- package/dist/types-ts4.5/presets/index.d.ts +1 -0
- package/dist/types-ts4.5/presets/migrate-icon-object-to-object/codemods/migrate-icon-object-to-object.d.ts +3 -0
- package/dist/types-ts4.5/presets/migrate-icon-object-to-object/migrate-icon-object-to-object.d.ts +2 -0
- package/dist/types-ts4.5/presets/migrate-icon-object-to-object/utils/constants.d.ts +19 -0
- package/dist/types-ts4.5/presets/migrate-icon-object-to-object/utils/icon-mappings.d.ts +29 -0
- package/package.json +2 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atlaskit/codemod-cli
|
|
2
2
|
|
|
3
|
+
## 0.29.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`e1c9823b0b420`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e1c9823b0b420) -
|
|
8
|
+
Updated `migrate-icon-object-to-object` to use new object name "Work item"
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
11
|
+
## 0.29.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- [`e1d1e430b2dbb`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e1d1e430b2dbb) -
|
|
16
|
+
Created a new codemod called "migrate-icon-object-to-object" to migrate the
|
|
17
|
+
`@atlaskit/icon-object` package to `@atlaskit/object`.
|
|
18
|
+
|
|
3
19
|
## 0.28.3
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/dist/cjs/main.js
CHANGED
|
@@ -362,7 +362,7 @@ function _main() {
|
|
|
362
362
|
case 4:
|
|
363
363
|
_yield$parseArgs = _context6.sent;
|
|
364
364
|
packages = _yield$parseArgs.packages;
|
|
365
|
-
_process$env$_PACKAGE = "0.
|
|
365
|
+
_process$env$_PACKAGE = "0.0.0-development", _PACKAGE_VERSION_ = _process$env$_PACKAGE === void 0 ? '0.0.0-dev' : _process$env$_PACKAGE;
|
|
366
366
|
logger.log(_chalk.default.bgBlue(_chalk.default.black("\uD83D\uDCDA Atlassian-Frontend codemod library @ ".concat(_PACKAGE_VERSION_, " \uD83D\uDCDA"))));
|
|
367
367
|
if (packages && packages.length > 0) {
|
|
368
368
|
logger.log(_chalk.default.gray("Searching for codemods for newer versions of the following packages: ".concat(packages.map(function (pkg) {
|
|
@@ -10,6 +10,7 @@ require("./styled-to-emotion/styled-to-emotion");
|
|
|
10
10
|
require("./theme-remove-deprecated-mixins/theme-remove-deprecated-mixins");
|
|
11
11
|
require("./migrate-to-link/migrate-to-link");
|
|
12
12
|
require("./migrate-to-new-buttons/migrate-to-new-buttons");
|
|
13
|
+
require("./migrate-icon-object-to-object/migrate-icon-object-to-object");
|
|
13
14
|
require("./upgrade-pragmatic-drag-and-drop-to-stable/upgrade-pragmatic-drag-and-drop-to-stable");
|
|
14
15
|
require("./remove-dark-theme-vr-options/remove-dark-theme-vr-options");
|
|
15
16
|
require("./remove-token-fallbacks/remove-token-fallbacks");
|
|
@@ -18,7 +19,7 @@ require("./remove-token-fallbacks/remove-token-fallbacks");
|
|
|
18
19
|
* in the final bundle.
|
|
19
20
|
*/
|
|
20
21
|
|
|
21
|
-
var presets = ['styled-to-emotion', 'theme-remove-deprecated-mixins', 'migrate-to-link', 'migrate-to-new-buttons', 'upgrade-pragmatic-drag-and-drop-to-stable', 'remove-dark-theme-vr-options', 'remove-token-fallbacks'].map(function (preset) {
|
|
22
|
+
var presets = ['styled-to-emotion', 'theme-remove-deprecated-mixins', 'migrate-to-link', 'migrate-to-new-buttons', 'migrate-icon-object-to-object', 'upgrade-pragmatic-drag-and-drop-to-stable', 'remove-dark-theme-vr-options', 'remove-token-fallbacks'].map(function (preset) {
|
|
22
23
|
return _path.default.join(__dirname, preset, "".concat(preset, ".@(ts|js|tsx)"));
|
|
23
24
|
});
|
|
24
25
|
var _default = exports.default = presets;
|
package/dist/cjs/presets/migrate-icon-object-to-object/codemods/migrate-icon-object-to-object.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _constants = require("../utils/constants");
|
|
8
|
+
var _iconMappings = require("../utils/icon-mappings");
|
|
9
|
+
/* eslint-disable @repo/internal/fs/filename-pattern-match */
|
|
10
|
+
|
|
11
|
+
var transformer = function transformer(file, api) {
|
|
12
|
+
var j = api.jscodeshift;
|
|
13
|
+
var fileSource = j(file.source);
|
|
14
|
+
|
|
15
|
+
// Find all icon-object imports
|
|
16
|
+
var iconObjectImports = fileSource.find(j.ImportDeclaration).filter(function (path) {
|
|
17
|
+
var source = path.node.source.value;
|
|
18
|
+
return typeof source === 'string' && source.startsWith(_constants.OLD_ICON_OBJECT_ENTRY_POINT);
|
|
19
|
+
});
|
|
20
|
+
if (!iconObjectImports.length) {
|
|
21
|
+
return fileSource.toSource();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Track import name mappings (old name -> new name) and new imports to create
|
|
25
|
+
var importNameMappings = new Map();
|
|
26
|
+
var newImportsToCreate = [];
|
|
27
|
+
|
|
28
|
+
// Process each icon-object import
|
|
29
|
+
iconObjectImports.forEach(function (importPath) {
|
|
30
|
+
var _importDeclaration$sp;
|
|
31
|
+
var importDeclaration = importPath.node;
|
|
32
|
+
var source = importDeclaration.source.value;
|
|
33
|
+
var parsedImport = (0, _iconMappings.parseIconObjectImport)(source);
|
|
34
|
+
if (!parsedImport) {
|
|
35
|
+
return; // Skip invalid imports
|
|
36
|
+
}
|
|
37
|
+
var iconName = parsedImport.iconName,
|
|
38
|
+
size = parsedImport.size;
|
|
39
|
+
var _getNewImportInfo = (0, _iconMappings.getNewImportInfo)(iconName, size),
|
|
40
|
+
newImportPath = _getNewImportInfo.importPath,
|
|
41
|
+
componentName = _getNewImportInfo.componentName;
|
|
42
|
+
|
|
43
|
+
// Get the current import name (could be default import or renamed)
|
|
44
|
+
var defaultSpecifier = (_importDeclaration$sp = importDeclaration.specifiers) === null || _importDeclaration$sp === void 0 ? void 0 : _importDeclaration$sp.find(function (spec) {
|
|
45
|
+
return spec.type === 'ImportDefaultSpecifier';
|
|
46
|
+
});
|
|
47
|
+
if (defaultSpecifier) {
|
|
48
|
+
var _defaultSpecifier$loc;
|
|
49
|
+
var currentImportName = (_defaultSpecifier$loc = defaultSpecifier.local) === null || _defaultSpecifier$loc === void 0 ? void 0 : _defaultSpecifier$loc.name;
|
|
50
|
+
if (currentImportName) {
|
|
51
|
+
// Map the old import name to the new component name
|
|
52
|
+
importNameMappings.set(currentImportName, componentName);
|
|
53
|
+
|
|
54
|
+
// Track the new import to create
|
|
55
|
+
newImportsToCreate.push({
|
|
56
|
+
componentName: componentName,
|
|
57
|
+
importPath: newImportPath
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Update JSX elements to use new component names
|
|
64
|
+
importNameMappings.forEach(function (newName, oldName) {
|
|
65
|
+
fileSource.find(j.JSXElement).filter(function (path) {
|
|
66
|
+
var openingElement = path.value.openingElement;
|
|
67
|
+
return openingElement.name.type === 'JSXIdentifier' && openingElement.name.name === oldName;
|
|
68
|
+
}).forEach(function (elementPath) {
|
|
69
|
+
var _element$closingEleme;
|
|
70
|
+
var element = elementPath.value;
|
|
71
|
+
|
|
72
|
+
// Update opening tag
|
|
73
|
+
if (element.openingElement.name.type === 'JSXIdentifier') {
|
|
74
|
+
element.openingElement.name.name = newName;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Update closing tag if it exists
|
|
78
|
+
if (((_element$closingEleme = element.closingElement) === null || _element$closingEleme === void 0 ? void 0 : _element$closingEleme.name.type) === 'JSXIdentifier') {
|
|
79
|
+
element.closingElement.name.name = newName;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// For 24px icons (now object tiles), add size="small" prop
|
|
83
|
+
if (newName.endsWith('ObjectTile')) {
|
|
84
|
+
var attributes = element.openingElement.attributes;
|
|
85
|
+
if (attributes) {
|
|
86
|
+
// Add size="small" (24px icons should be small tiles)
|
|
87
|
+
attributes.push(j.jsxAttribute(j.jsxIdentifier('size'), j.stringLiteral('small')));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Update other references (like in render calls, etc.)
|
|
94
|
+
importNameMappings.forEach(function (newName, oldName) {
|
|
95
|
+
fileSource.find(j.Identifier).filter(function (path) {
|
|
96
|
+
return path.node.name === oldName;
|
|
97
|
+
}).forEach(function (path) {
|
|
98
|
+
var _parent$value, _parent$value2;
|
|
99
|
+
// Only update if it's not part of an import declaration or JSX element
|
|
100
|
+
// (those are handled separately)
|
|
101
|
+
var parent = path.parent;
|
|
102
|
+
if ((parent === null || parent === void 0 || (_parent$value = parent.value) === null || _parent$value === void 0 ? void 0 : _parent$value.type) !== 'ImportDefaultSpecifier' && (parent === null || parent === void 0 || (_parent$value2 = parent.value) === null || _parent$value2 === void 0 ? void 0 : _parent$value2.type) !== 'JSXIdentifier') {
|
|
103
|
+
path.node.name = newName;
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Remove old icon-object imports
|
|
109
|
+
iconObjectImports.remove();
|
|
110
|
+
|
|
111
|
+
// Create new individual default imports
|
|
112
|
+
var newImports = newImportsToCreate.map(function (_ref) {
|
|
113
|
+
var componentName = _ref.componentName,
|
|
114
|
+
importPath = _ref.importPath;
|
|
115
|
+
return (0, _iconMappings.createDefaultImportDeclaration)(j, componentName, importPath);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// Insert new imports at the top of the file
|
|
119
|
+
if (newImports.length > 0) {
|
|
120
|
+
var firstImport = fileSource.find(j.ImportDeclaration).at(0);
|
|
121
|
+
if (firstImport.length > 0) {
|
|
122
|
+
// Insert before the first existing import
|
|
123
|
+
// insertBefore adds in reverse order, so we need to reverse the array
|
|
124
|
+
newImports.reverse().forEach(function (importDecl) {
|
|
125
|
+
firstImport.insertBefore(importDecl);
|
|
126
|
+
});
|
|
127
|
+
} else {
|
|
128
|
+
// No existing imports, add at the top of the file
|
|
129
|
+
var body = fileSource.find(j.Program).get('body');
|
|
130
|
+
// For unshift, we also need to reverse to maintain correct order
|
|
131
|
+
newImports.reverse().forEach(function (importDecl) {
|
|
132
|
+
body.unshift(importDecl);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return fileSource.toSource(_constants.PRINT_SETTINGS);
|
|
137
|
+
};
|
|
138
|
+
var _default = exports.default = transformer;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = transformer;
|
|
8
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
9
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
10
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
11
|
+
var _migrateIconObjectToObject = _interopRequireDefault(require("./codemods/migrate-icon-object-to-object"));
|
|
12
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
13
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
14
|
+
function transformer(_x, _x2) {
|
|
15
|
+
return _transformer.apply(this, arguments);
|
|
16
|
+
}
|
|
17
|
+
function _transformer() {
|
|
18
|
+
_transformer = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(file, api) {
|
|
19
|
+
var transformers, src;
|
|
20
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
21
|
+
while (1) switch (_context.prev = _context.next) {
|
|
22
|
+
case 0:
|
|
23
|
+
transformers = [_migrateIconObjectToObject.default];
|
|
24
|
+
src = file.source;
|
|
25
|
+
transformers.forEach(function (transformer) {
|
|
26
|
+
if (typeof src === 'undefined') {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
var nextSrc = transformer(_objectSpread(_objectSpread({}, file), {}, {
|
|
30
|
+
source: src
|
|
31
|
+
}), api);
|
|
32
|
+
if (nextSrc) {
|
|
33
|
+
src = nextSrc;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return _context.abrupt("return", src);
|
|
37
|
+
case 4:
|
|
38
|
+
case "end":
|
|
39
|
+
return _context.stop();
|
|
40
|
+
}
|
|
41
|
+
}, _callee);
|
|
42
|
+
}));
|
|
43
|
+
return _transformer.apply(this, arguments);
|
|
44
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.PRINT_SETTINGS = exports.OLD_ICON_OBJECT_ENTRY_POINT = exports.NEW_OBJECT_TILE_ENTRY_POINT = exports.NEW_OBJECT_ENTRY_POINT = exports.ICON_TO_OBJECT_NAME_MAPPINGS = exports.AVAILABLE_ICON_NAMES = void 0;
|
|
7
|
+
/* eslint-disable @repo/internal/fs/filename-pattern-match */
|
|
8
|
+
|
|
9
|
+
// Entry points
|
|
10
|
+
var OLD_ICON_OBJECT_ENTRY_POINT = exports.OLD_ICON_OBJECT_ENTRY_POINT = '@atlaskit/icon-object';
|
|
11
|
+
var NEW_OBJECT_ENTRY_POINT = exports.NEW_OBJECT_ENTRY_POINT = '@atlaskit/object';
|
|
12
|
+
var NEW_OBJECT_TILE_ENTRY_POINT = exports.NEW_OBJECT_TILE_ENTRY_POINT = '@atlaskit/object/tile';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Mappings for icon-object names that change when migrating to object.
|
|
16
|
+
* Key: old icon-object name (kebab-case)
|
|
17
|
+
* Value: new object name (kebab-case)
|
|
18
|
+
*
|
|
19
|
+
* Use this when the icon name in icon-object doesn't match the object name.
|
|
20
|
+
* For example, 'issue' icon-object becomes 'work-item' object.
|
|
21
|
+
*
|
|
22
|
+
* Icons not listed here will use their original name (converted to PascalCase automatically).
|
|
23
|
+
*/
|
|
24
|
+
var ICON_TO_OBJECT_NAME_MAPPINGS = exports.ICON_TO_OBJECT_NAME_MAPPINGS = {
|
|
25
|
+
issue: 'work-item'
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Available icon names (kebab-case) - icons supported in icon-object
|
|
29
|
+
var AVAILABLE_ICON_NAMES = exports.AVAILABLE_ICON_NAMES = ['blog', 'branch', 'bug', 'calendar', 'changes', 'code', 'commit', 'epic', 'improvement', 'incident', 'issue', 'new-feature', 'page', 'page-live-doc', 'problem', 'pull-request', 'question', 'story', 'subtask', 'task', 'whiteboard'];
|
|
30
|
+
var PRINT_SETTINGS = exports.PRINT_SETTINGS = {
|
|
31
|
+
quote: 'single',
|
|
32
|
+
trailingComma: true
|
|
33
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.createDefaultImportDeclaration = createDefaultImportDeclaration;
|
|
8
|
+
exports.getNewImportInfo = getNewImportInfo;
|
|
9
|
+
exports.kebabToPascalCase = kebabToPascalCase;
|
|
10
|
+
exports.parseIconObjectImport = parseIconObjectImport;
|
|
11
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
12
|
+
var _constants = require("./constants");
|
|
13
|
+
/* eslint-disable @repo/internal/fs/filename-pattern-match */
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Converts a kebab-case string to PascalCase
|
|
17
|
+
* @param str - The kebab-case string (e.g., 'new-feature', 'work-item')
|
|
18
|
+
* @returns PascalCase string (e.g., 'NewFeature', 'WorkItem')
|
|
19
|
+
*/
|
|
20
|
+
function kebabToPascalCase(str) {
|
|
21
|
+
return str.split('-').map(function (word) {
|
|
22
|
+
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
23
|
+
}).join('');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Extracts icon name and size from an icon-object import path
|
|
28
|
+
* @param importPath - The import path like '@atlaskit/icon-object/glyph/new-feature/16'
|
|
29
|
+
* @returns Object with iconName and size, or null if not a valid icon-object import
|
|
30
|
+
*/
|
|
31
|
+
function parseIconObjectImport(importPath) {
|
|
32
|
+
var match = importPath.match(/^@atlaskit\/icon-object\/glyph\/([^/]+)\/(16|24)$/);
|
|
33
|
+
if (!match) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
var _match = (0, _slicedToArray2.default)(match, 3),
|
|
37
|
+
iconName = _match[1],
|
|
38
|
+
size = _match[2];
|
|
39
|
+
|
|
40
|
+
// Check if this is a valid icon name we support
|
|
41
|
+
if (!_constants.AVAILABLE_ICON_NAMES.includes(iconName)) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
iconName: iconName,
|
|
46
|
+
size: size
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Gets the new import specifier for an icon based on its name and size
|
|
52
|
+
* @param iconName - The kebab-case icon name from icon-object (e.g., 'new-feature', 'issue')
|
|
53
|
+
* @param size - The size ('16' or '24')
|
|
54
|
+
* @returns Object with the new import path and component name
|
|
55
|
+
*/
|
|
56
|
+
function getNewImportInfo(iconName, size) {
|
|
57
|
+
// Check if this icon name needs to be mapped to a different object name
|
|
58
|
+
var objectName = _constants.ICON_TO_OBJECT_NAME_MAPPINGS[iconName] || iconName;
|
|
59
|
+
|
|
60
|
+
// Convert the object name to PascalCase
|
|
61
|
+
var pascalCaseName = kebabToPascalCase(objectName);
|
|
62
|
+
if (size === '16') {
|
|
63
|
+
return {
|
|
64
|
+
importPath: "@atlaskit/object/".concat(objectName),
|
|
65
|
+
componentName: "".concat(pascalCaseName, "Object")
|
|
66
|
+
};
|
|
67
|
+
} else {
|
|
68
|
+
return {
|
|
69
|
+
importPath: "@atlaskit/object/tile/".concat(objectName),
|
|
70
|
+
componentName: "".concat(pascalCaseName, "ObjectTile")
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Creates a new default import declaration for the transformed component
|
|
77
|
+
*/
|
|
78
|
+
function createDefaultImportDeclaration(j, componentName, importPath) {
|
|
79
|
+
var defaultSpecifier = j.importDefaultSpecifier(j.identifier(componentName));
|
|
80
|
+
return j.importDeclaration([defaultSpecifier], j.stringLiteral(importPath));
|
|
81
|
+
}
|
|
@@ -8,8 +8,9 @@ import './styled-to-emotion/styled-to-emotion';
|
|
|
8
8
|
import './theme-remove-deprecated-mixins/theme-remove-deprecated-mixins';
|
|
9
9
|
import './migrate-to-link/migrate-to-link';
|
|
10
10
|
import './migrate-to-new-buttons/migrate-to-new-buttons';
|
|
11
|
+
import './migrate-icon-object-to-object/migrate-icon-object-to-object';
|
|
11
12
|
import './upgrade-pragmatic-drag-and-drop-to-stable/upgrade-pragmatic-drag-and-drop-to-stable';
|
|
12
13
|
import './remove-dark-theme-vr-options/remove-dark-theme-vr-options';
|
|
13
14
|
import './remove-token-fallbacks/remove-token-fallbacks';
|
|
14
|
-
const presets = ['styled-to-emotion', 'theme-remove-deprecated-mixins', 'migrate-to-link', 'migrate-to-new-buttons', 'upgrade-pragmatic-drag-and-drop-to-stable', 'remove-dark-theme-vr-options', 'remove-token-fallbacks'].map(preset => path.join(__dirname, preset, `${preset}.@(ts|js|tsx)`));
|
|
15
|
+
const presets = ['styled-to-emotion', 'theme-remove-deprecated-mixins', 'migrate-to-link', 'migrate-to-new-buttons', 'migrate-icon-object-to-object', 'upgrade-pragmatic-drag-and-drop-to-stable', 'remove-dark-theme-vr-options', 'remove-token-fallbacks'].map(preset => path.join(__dirname, preset, `${preset}.@(ts|js|tsx)`));
|
|
15
16
|
export default presets;
|
package/dist/es2019/presets/migrate-icon-object-to-object/codemods/migrate-icon-object-to-object.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/* eslint-disable @repo/internal/fs/filename-pattern-match */
|
|
2
|
+
|
|
3
|
+
import { OLD_ICON_OBJECT_ENTRY_POINT, PRINT_SETTINGS } from '../utils/constants';
|
|
4
|
+
import { createDefaultImportDeclaration, getNewImportInfo, parseIconObjectImport } from '../utils/icon-mappings';
|
|
5
|
+
const transformer = (file, api) => {
|
|
6
|
+
const j = api.jscodeshift;
|
|
7
|
+
const fileSource = j(file.source);
|
|
8
|
+
|
|
9
|
+
// Find all icon-object imports
|
|
10
|
+
const iconObjectImports = fileSource.find(j.ImportDeclaration).filter(path => {
|
|
11
|
+
const source = path.node.source.value;
|
|
12
|
+
return typeof source === 'string' && source.startsWith(OLD_ICON_OBJECT_ENTRY_POINT);
|
|
13
|
+
});
|
|
14
|
+
if (!iconObjectImports.length) {
|
|
15
|
+
return fileSource.toSource();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Track import name mappings (old name -> new name) and new imports to create
|
|
19
|
+
const importNameMappings = new Map();
|
|
20
|
+
const newImportsToCreate = [];
|
|
21
|
+
|
|
22
|
+
// Process each icon-object import
|
|
23
|
+
iconObjectImports.forEach(importPath => {
|
|
24
|
+
var _importDeclaration$sp;
|
|
25
|
+
const importDeclaration = importPath.node;
|
|
26
|
+
const source = importDeclaration.source.value;
|
|
27
|
+
const parsedImport = parseIconObjectImport(source);
|
|
28
|
+
if (!parsedImport) {
|
|
29
|
+
return; // Skip invalid imports
|
|
30
|
+
}
|
|
31
|
+
const {
|
|
32
|
+
iconName,
|
|
33
|
+
size
|
|
34
|
+
} = parsedImport;
|
|
35
|
+
const {
|
|
36
|
+
importPath: newImportPath,
|
|
37
|
+
componentName
|
|
38
|
+
} = getNewImportInfo(iconName, size);
|
|
39
|
+
|
|
40
|
+
// Get the current import name (could be default import or renamed)
|
|
41
|
+
const defaultSpecifier = (_importDeclaration$sp = importDeclaration.specifiers) === null || _importDeclaration$sp === void 0 ? void 0 : _importDeclaration$sp.find(spec => spec.type === 'ImportDefaultSpecifier');
|
|
42
|
+
if (defaultSpecifier) {
|
|
43
|
+
var _defaultSpecifier$loc;
|
|
44
|
+
const currentImportName = (_defaultSpecifier$loc = defaultSpecifier.local) === null || _defaultSpecifier$loc === void 0 ? void 0 : _defaultSpecifier$loc.name;
|
|
45
|
+
if (currentImportName) {
|
|
46
|
+
// Map the old import name to the new component name
|
|
47
|
+
importNameMappings.set(currentImportName, componentName);
|
|
48
|
+
|
|
49
|
+
// Track the new import to create
|
|
50
|
+
newImportsToCreate.push({
|
|
51
|
+
componentName,
|
|
52
|
+
importPath: newImportPath
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Update JSX elements to use new component names
|
|
59
|
+
importNameMappings.forEach((newName, oldName) => {
|
|
60
|
+
fileSource.find(j.JSXElement).filter(path => {
|
|
61
|
+
const openingElement = path.value.openingElement;
|
|
62
|
+
return openingElement.name.type === 'JSXIdentifier' && openingElement.name.name === oldName;
|
|
63
|
+
}).forEach(elementPath => {
|
|
64
|
+
var _element$closingEleme;
|
|
65
|
+
const element = elementPath.value;
|
|
66
|
+
|
|
67
|
+
// Update opening tag
|
|
68
|
+
if (element.openingElement.name.type === 'JSXIdentifier') {
|
|
69
|
+
element.openingElement.name.name = newName;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Update closing tag if it exists
|
|
73
|
+
if (((_element$closingEleme = element.closingElement) === null || _element$closingEleme === void 0 ? void 0 : _element$closingEleme.name.type) === 'JSXIdentifier') {
|
|
74
|
+
element.closingElement.name.name = newName;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// For 24px icons (now object tiles), add size="small" prop
|
|
78
|
+
if (newName.endsWith('ObjectTile')) {
|
|
79
|
+
const attributes = element.openingElement.attributes;
|
|
80
|
+
if (attributes) {
|
|
81
|
+
// Add size="small" (24px icons should be small tiles)
|
|
82
|
+
attributes.push(j.jsxAttribute(j.jsxIdentifier('size'), j.stringLiteral('small')));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Update other references (like in render calls, etc.)
|
|
89
|
+
importNameMappings.forEach((newName, oldName) => {
|
|
90
|
+
fileSource.find(j.Identifier).filter(path => path.node.name === oldName).forEach(path => {
|
|
91
|
+
var _parent$value, _parent$value2;
|
|
92
|
+
// Only update if it's not part of an import declaration or JSX element
|
|
93
|
+
// (those are handled separately)
|
|
94
|
+
const parent = path.parent;
|
|
95
|
+
if ((parent === null || parent === void 0 ? void 0 : (_parent$value = parent.value) === null || _parent$value === void 0 ? void 0 : _parent$value.type) !== 'ImportDefaultSpecifier' && (parent === null || parent === void 0 ? void 0 : (_parent$value2 = parent.value) === null || _parent$value2 === void 0 ? void 0 : _parent$value2.type) !== 'JSXIdentifier') {
|
|
96
|
+
path.node.name = newName;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Remove old icon-object imports
|
|
102
|
+
iconObjectImports.remove();
|
|
103
|
+
|
|
104
|
+
// Create new individual default imports
|
|
105
|
+
const newImports = newImportsToCreate.map(({
|
|
106
|
+
componentName,
|
|
107
|
+
importPath
|
|
108
|
+
}) => createDefaultImportDeclaration(j, componentName, importPath));
|
|
109
|
+
|
|
110
|
+
// Insert new imports at the top of the file
|
|
111
|
+
if (newImports.length > 0) {
|
|
112
|
+
const firstImport = fileSource.find(j.ImportDeclaration).at(0);
|
|
113
|
+
if (firstImport.length > 0) {
|
|
114
|
+
// Insert before the first existing import
|
|
115
|
+
// insertBefore adds in reverse order, so we need to reverse the array
|
|
116
|
+
newImports.reverse().forEach(importDecl => {
|
|
117
|
+
firstImport.insertBefore(importDecl);
|
|
118
|
+
});
|
|
119
|
+
} else {
|
|
120
|
+
// No existing imports, add at the top of the file
|
|
121
|
+
const body = fileSource.find(j.Program).get('body');
|
|
122
|
+
// For unshift, we also need to reverse to maintain correct order
|
|
123
|
+
newImports.reverse().forEach(importDecl => {
|
|
124
|
+
body.unshift(importDecl);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return fileSource.toSource(PRINT_SETTINGS);
|
|
129
|
+
};
|
|
130
|
+
export default transformer;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import migrateIconObjectToObjectTransformer from './codemods/migrate-icon-object-to-object';
|
|
2
|
+
export default async function transformer(file, api) {
|
|
3
|
+
const transformers = [migrateIconObjectToObjectTransformer];
|
|
4
|
+
let src = file.source;
|
|
5
|
+
transformers.forEach(transformer => {
|
|
6
|
+
if (typeof src === 'undefined') {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const nextSrc = transformer({
|
|
10
|
+
...file,
|
|
11
|
+
source: src
|
|
12
|
+
}, api);
|
|
13
|
+
if (nextSrc) {
|
|
14
|
+
src = nextSrc;
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return src;
|
|
18
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/* eslint-disable @repo/internal/fs/filename-pattern-match */
|
|
2
|
+
|
|
3
|
+
// Entry points
|
|
4
|
+
export const OLD_ICON_OBJECT_ENTRY_POINT = '@atlaskit/icon-object';
|
|
5
|
+
export const NEW_OBJECT_ENTRY_POINT = '@atlaskit/object';
|
|
6
|
+
export const NEW_OBJECT_TILE_ENTRY_POINT = '@atlaskit/object/tile';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Mappings for icon-object names that change when migrating to object.
|
|
10
|
+
* Key: old icon-object name (kebab-case)
|
|
11
|
+
* Value: new object name (kebab-case)
|
|
12
|
+
*
|
|
13
|
+
* Use this when the icon name in icon-object doesn't match the object name.
|
|
14
|
+
* For example, 'issue' icon-object becomes 'work-item' object.
|
|
15
|
+
*
|
|
16
|
+
* Icons not listed here will use their original name (converted to PascalCase automatically).
|
|
17
|
+
*/
|
|
18
|
+
export const ICON_TO_OBJECT_NAME_MAPPINGS = {
|
|
19
|
+
issue: 'work-item'
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Available icon names (kebab-case) - icons supported in icon-object
|
|
23
|
+
export const AVAILABLE_ICON_NAMES = ['blog', 'branch', 'bug', 'calendar', 'changes', 'code', 'commit', 'epic', 'improvement', 'incident', 'issue', 'new-feature', 'page', 'page-live-doc', 'problem', 'pull-request', 'question', 'story', 'subtask', 'task', 'whiteboard'];
|
|
24
|
+
export const PRINT_SETTINGS = {
|
|
25
|
+
quote: 'single',
|
|
26
|
+
trailingComma: true
|
|
27
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/* eslint-disable @repo/internal/fs/filename-pattern-match */
|
|
2
|
+
|
|
3
|
+
import { AVAILABLE_ICON_NAMES, ICON_TO_OBJECT_NAME_MAPPINGS } from './constants';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Converts a kebab-case string to PascalCase
|
|
7
|
+
* @param str - The kebab-case string (e.g., 'new-feature', 'work-item')
|
|
8
|
+
* @returns PascalCase string (e.g., 'NewFeature', 'WorkItem')
|
|
9
|
+
*/
|
|
10
|
+
export function kebabToPascalCase(str) {
|
|
11
|
+
return str.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join('');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Extracts icon name and size from an icon-object import path
|
|
16
|
+
* @param importPath - The import path like '@atlaskit/icon-object/glyph/new-feature/16'
|
|
17
|
+
* @returns Object with iconName and size, or null if not a valid icon-object import
|
|
18
|
+
*/
|
|
19
|
+
export function parseIconObjectImport(importPath) {
|
|
20
|
+
const match = importPath.match(/^@atlaskit\/icon-object\/glyph\/([^/]+)\/(16|24)$/);
|
|
21
|
+
if (!match) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const [, iconName, size] = match;
|
|
25
|
+
|
|
26
|
+
// Check if this is a valid icon name we support
|
|
27
|
+
if (!AVAILABLE_ICON_NAMES.includes(iconName)) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
iconName,
|
|
32
|
+
size: size
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Gets the new import specifier for an icon based on its name and size
|
|
38
|
+
* @param iconName - The kebab-case icon name from icon-object (e.g., 'new-feature', 'issue')
|
|
39
|
+
* @param size - The size ('16' or '24')
|
|
40
|
+
* @returns Object with the new import path and component name
|
|
41
|
+
*/
|
|
42
|
+
export function getNewImportInfo(iconName, size) {
|
|
43
|
+
// Check if this icon name needs to be mapped to a different object name
|
|
44
|
+
const objectName = ICON_TO_OBJECT_NAME_MAPPINGS[iconName] || iconName;
|
|
45
|
+
|
|
46
|
+
// Convert the object name to PascalCase
|
|
47
|
+
const pascalCaseName = kebabToPascalCase(objectName);
|
|
48
|
+
if (size === '16') {
|
|
49
|
+
return {
|
|
50
|
+
importPath: `@atlaskit/object/${objectName}`,
|
|
51
|
+
componentName: `${pascalCaseName}Object`
|
|
52
|
+
};
|
|
53
|
+
} else {
|
|
54
|
+
return {
|
|
55
|
+
importPath: `@atlaskit/object/tile/${objectName}`,
|
|
56
|
+
componentName: `${pascalCaseName}ObjectTile`
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Creates a new default import declaration for the transformed component
|
|
63
|
+
*/
|
|
64
|
+
export function createDefaultImportDeclaration(j, componentName, importPath) {
|
|
65
|
+
const defaultSpecifier = j.importDefaultSpecifier(j.identifier(componentName));
|
|
66
|
+
return j.importDeclaration([defaultSpecifier], j.stringLiteral(importPath));
|
|
67
|
+
}
|
package/dist/esm/main.js
CHANGED
|
@@ -355,7 +355,7 @@ function _main() {
|
|
|
355
355
|
case 4:
|
|
356
356
|
_yield$parseArgs = _context6.sent;
|
|
357
357
|
packages = _yield$parseArgs.packages;
|
|
358
|
-
_process$env$_PACKAGE = "0.
|
|
358
|
+
_process$env$_PACKAGE = "0.0.0-development", _PACKAGE_VERSION_ = _process$env$_PACKAGE === void 0 ? '0.0.0-dev' : _process$env$_PACKAGE;
|
|
359
359
|
logger.log(chalk.bgBlue(chalk.black("\uD83D\uDCDA Atlassian-Frontend codemod library @ ".concat(_PACKAGE_VERSION_, " \uD83D\uDCDA"))));
|
|
360
360
|
if (packages && packages.length > 0) {
|
|
361
361
|
logger.log(chalk.gray("Searching for codemods for newer versions of the following packages: ".concat(packages.map(function (pkg) {
|
|
@@ -8,10 +8,11 @@ import './styled-to-emotion/styled-to-emotion';
|
|
|
8
8
|
import './theme-remove-deprecated-mixins/theme-remove-deprecated-mixins';
|
|
9
9
|
import './migrate-to-link/migrate-to-link';
|
|
10
10
|
import './migrate-to-new-buttons/migrate-to-new-buttons';
|
|
11
|
+
import './migrate-icon-object-to-object/migrate-icon-object-to-object';
|
|
11
12
|
import './upgrade-pragmatic-drag-and-drop-to-stable/upgrade-pragmatic-drag-and-drop-to-stable';
|
|
12
13
|
import './remove-dark-theme-vr-options/remove-dark-theme-vr-options';
|
|
13
14
|
import './remove-token-fallbacks/remove-token-fallbacks';
|
|
14
|
-
var presets = ['styled-to-emotion', 'theme-remove-deprecated-mixins', 'migrate-to-link', 'migrate-to-new-buttons', 'upgrade-pragmatic-drag-and-drop-to-stable', 'remove-dark-theme-vr-options', 'remove-token-fallbacks'].map(function (preset) {
|
|
15
|
+
var presets = ['styled-to-emotion', 'theme-remove-deprecated-mixins', 'migrate-to-link', 'migrate-to-new-buttons', 'migrate-icon-object-to-object', 'upgrade-pragmatic-drag-and-drop-to-stable', 'remove-dark-theme-vr-options', 'remove-token-fallbacks'].map(function (preset) {
|
|
15
16
|
return path.join(__dirname, preset, "".concat(preset, ".@(ts|js|tsx)"));
|
|
16
17
|
});
|
|
17
18
|
export default presets;
|
package/dist/esm/presets/migrate-icon-object-to-object/codemods/migrate-icon-object-to-object.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/* eslint-disable @repo/internal/fs/filename-pattern-match */
|
|
2
|
+
|
|
3
|
+
import { OLD_ICON_OBJECT_ENTRY_POINT, PRINT_SETTINGS } from '../utils/constants';
|
|
4
|
+
import { createDefaultImportDeclaration, getNewImportInfo, parseIconObjectImport } from '../utils/icon-mappings';
|
|
5
|
+
var transformer = function transformer(file, api) {
|
|
6
|
+
var j = api.jscodeshift;
|
|
7
|
+
var fileSource = j(file.source);
|
|
8
|
+
|
|
9
|
+
// Find all icon-object imports
|
|
10
|
+
var iconObjectImports = fileSource.find(j.ImportDeclaration).filter(function (path) {
|
|
11
|
+
var source = path.node.source.value;
|
|
12
|
+
return typeof source === 'string' && source.startsWith(OLD_ICON_OBJECT_ENTRY_POINT);
|
|
13
|
+
});
|
|
14
|
+
if (!iconObjectImports.length) {
|
|
15
|
+
return fileSource.toSource();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Track import name mappings (old name -> new name) and new imports to create
|
|
19
|
+
var importNameMappings = new Map();
|
|
20
|
+
var newImportsToCreate = [];
|
|
21
|
+
|
|
22
|
+
// Process each icon-object import
|
|
23
|
+
iconObjectImports.forEach(function (importPath) {
|
|
24
|
+
var _importDeclaration$sp;
|
|
25
|
+
var importDeclaration = importPath.node;
|
|
26
|
+
var source = importDeclaration.source.value;
|
|
27
|
+
var parsedImport = parseIconObjectImport(source);
|
|
28
|
+
if (!parsedImport) {
|
|
29
|
+
return; // Skip invalid imports
|
|
30
|
+
}
|
|
31
|
+
var iconName = parsedImport.iconName,
|
|
32
|
+
size = parsedImport.size;
|
|
33
|
+
var _getNewImportInfo = getNewImportInfo(iconName, size),
|
|
34
|
+
newImportPath = _getNewImportInfo.importPath,
|
|
35
|
+
componentName = _getNewImportInfo.componentName;
|
|
36
|
+
|
|
37
|
+
// Get the current import name (could be default import or renamed)
|
|
38
|
+
var defaultSpecifier = (_importDeclaration$sp = importDeclaration.specifiers) === null || _importDeclaration$sp === void 0 ? void 0 : _importDeclaration$sp.find(function (spec) {
|
|
39
|
+
return spec.type === 'ImportDefaultSpecifier';
|
|
40
|
+
});
|
|
41
|
+
if (defaultSpecifier) {
|
|
42
|
+
var _defaultSpecifier$loc;
|
|
43
|
+
var currentImportName = (_defaultSpecifier$loc = defaultSpecifier.local) === null || _defaultSpecifier$loc === void 0 ? void 0 : _defaultSpecifier$loc.name;
|
|
44
|
+
if (currentImportName) {
|
|
45
|
+
// Map the old import name to the new component name
|
|
46
|
+
importNameMappings.set(currentImportName, componentName);
|
|
47
|
+
|
|
48
|
+
// Track the new import to create
|
|
49
|
+
newImportsToCreate.push({
|
|
50
|
+
componentName: componentName,
|
|
51
|
+
importPath: newImportPath
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Update JSX elements to use new component names
|
|
58
|
+
importNameMappings.forEach(function (newName, oldName) {
|
|
59
|
+
fileSource.find(j.JSXElement).filter(function (path) {
|
|
60
|
+
var openingElement = path.value.openingElement;
|
|
61
|
+
return openingElement.name.type === 'JSXIdentifier' && openingElement.name.name === oldName;
|
|
62
|
+
}).forEach(function (elementPath) {
|
|
63
|
+
var _element$closingEleme;
|
|
64
|
+
var element = elementPath.value;
|
|
65
|
+
|
|
66
|
+
// Update opening tag
|
|
67
|
+
if (element.openingElement.name.type === 'JSXIdentifier') {
|
|
68
|
+
element.openingElement.name.name = newName;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Update closing tag if it exists
|
|
72
|
+
if (((_element$closingEleme = element.closingElement) === null || _element$closingEleme === void 0 ? void 0 : _element$closingEleme.name.type) === 'JSXIdentifier') {
|
|
73
|
+
element.closingElement.name.name = newName;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// For 24px icons (now object tiles), add size="small" prop
|
|
77
|
+
if (newName.endsWith('ObjectTile')) {
|
|
78
|
+
var attributes = element.openingElement.attributes;
|
|
79
|
+
if (attributes) {
|
|
80
|
+
// Add size="small" (24px icons should be small tiles)
|
|
81
|
+
attributes.push(j.jsxAttribute(j.jsxIdentifier('size'), j.stringLiteral('small')));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Update other references (like in render calls, etc.)
|
|
88
|
+
importNameMappings.forEach(function (newName, oldName) {
|
|
89
|
+
fileSource.find(j.Identifier).filter(function (path) {
|
|
90
|
+
return path.node.name === oldName;
|
|
91
|
+
}).forEach(function (path) {
|
|
92
|
+
var _parent$value, _parent$value2;
|
|
93
|
+
// Only update if it's not part of an import declaration or JSX element
|
|
94
|
+
// (those are handled separately)
|
|
95
|
+
var parent = path.parent;
|
|
96
|
+
if ((parent === null || parent === void 0 || (_parent$value = parent.value) === null || _parent$value === void 0 ? void 0 : _parent$value.type) !== 'ImportDefaultSpecifier' && (parent === null || parent === void 0 || (_parent$value2 = parent.value) === null || _parent$value2 === void 0 ? void 0 : _parent$value2.type) !== 'JSXIdentifier') {
|
|
97
|
+
path.node.name = newName;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Remove old icon-object imports
|
|
103
|
+
iconObjectImports.remove();
|
|
104
|
+
|
|
105
|
+
// Create new individual default imports
|
|
106
|
+
var newImports = newImportsToCreate.map(function (_ref) {
|
|
107
|
+
var componentName = _ref.componentName,
|
|
108
|
+
importPath = _ref.importPath;
|
|
109
|
+
return createDefaultImportDeclaration(j, componentName, importPath);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Insert new imports at the top of the file
|
|
113
|
+
if (newImports.length > 0) {
|
|
114
|
+
var firstImport = fileSource.find(j.ImportDeclaration).at(0);
|
|
115
|
+
if (firstImport.length > 0) {
|
|
116
|
+
// Insert before the first existing import
|
|
117
|
+
// insertBefore adds in reverse order, so we need to reverse the array
|
|
118
|
+
newImports.reverse().forEach(function (importDecl) {
|
|
119
|
+
firstImport.insertBefore(importDecl);
|
|
120
|
+
});
|
|
121
|
+
} else {
|
|
122
|
+
// No existing imports, add at the top of the file
|
|
123
|
+
var body = fileSource.find(j.Program).get('body');
|
|
124
|
+
// For unshift, we also need to reverse to maintain correct order
|
|
125
|
+
newImports.reverse().forEach(function (importDecl) {
|
|
126
|
+
body.unshift(importDecl);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return fileSource.toSource(PRINT_SETTINGS);
|
|
131
|
+
};
|
|
132
|
+
export default transformer;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
3
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
4
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
5
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
6
|
+
import migrateIconObjectToObjectTransformer from './codemods/migrate-icon-object-to-object';
|
|
7
|
+
export default function transformer(_x, _x2) {
|
|
8
|
+
return _transformer.apply(this, arguments);
|
|
9
|
+
}
|
|
10
|
+
function _transformer() {
|
|
11
|
+
_transformer = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(file, api) {
|
|
12
|
+
var transformers, src;
|
|
13
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
14
|
+
while (1) switch (_context.prev = _context.next) {
|
|
15
|
+
case 0:
|
|
16
|
+
transformers = [migrateIconObjectToObjectTransformer];
|
|
17
|
+
src = file.source;
|
|
18
|
+
transformers.forEach(function (transformer) {
|
|
19
|
+
if (typeof src === 'undefined') {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
var nextSrc = transformer(_objectSpread(_objectSpread({}, file), {}, {
|
|
23
|
+
source: src
|
|
24
|
+
}), api);
|
|
25
|
+
if (nextSrc) {
|
|
26
|
+
src = nextSrc;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
return _context.abrupt("return", src);
|
|
30
|
+
case 4:
|
|
31
|
+
case "end":
|
|
32
|
+
return _context.stop();
|
|
33
|
+
}
|
|
34
|
+
}, _callee);
|
|
35
|
+
}));
|
|
36
|
+
return _transformer.apply(this, arguments);
|
|
37
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/* eslint-disable @repo/internal/fs/filename-pattern-match */
|
|
2
|
+
|
|
3
|
+
// Entry points
|
|
4
|
+
export var OLD_ICON_OBJECT_ENTRY_POINT = '@atlaskit/icon-object';
|
|
5
|
+
export var NEW_OBJECT_ENTRY_POINT = '@atlaskit/object';
|
|
6
|
+
export var NEW_OBJECT_TILE_ENTRY_POINT = '@atlaskit/object/tile';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Mappings for icon-object names that change when migrating to object.
|
|
10
|
+
* Key: old icon-object name (kebab-case)
|
|
11
|
+
* Value: new object name (kebab-case)
|
|
12
|
+
*
|
|
13
|
+
* Use this when the icon name in icon-object doesn't match the object name.
|
|
14
|
+
* For example, 'issue' icon-object becomes 'work-item' object.
|
|
15
|
+
*
|
|
16
|
+
* Icons not listed here will use their original name (converted to PascalCase automatically).
|
|
17
|
+
*/
|
|
18
|
+
export var ICON_TO_OBJECT_NAME_MAPPINGS = {
|
|
19
|
+
issue: 'work-item'
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Available icon names (kebab-case) - icons supported in icon-object
|
|
23
|
+
export var AVAILABLE_ICON_NAMES = ['blog', 'branch', 'bug', 'calendar', 'changes', 'code', 'commit', 'epic', 'improvement', 'incident', 'issue', 'new-feature', 'page', 'page-live-doc', 'problem', 'pull-request', 'question', 'story', 'subtask', 'task', 'whiteboard'];
|
|
24
|
+
export var PRINT_SETTINGS = {
|
|
25
|
+
quote: 'single',
|
|
26
|
+
trailingComma: true
|
|
27
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
+
/* eslint-disable @repo/internal/fs/filename-pattern-match */
|
|
3
|
+
|
|
4
|
+
import { AVAILABLE_ICON_NAMES, ICON_TO_OBJECT_NAME_MAPPINGS } from './constants';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Converts a kebab-case string to PascalCase
|
|
8
|
+
* @param str - The kebab-case string (e.g., 'new-feature', 'work-item')
|
|
9
|
+
* @returns PascalCase string (e.g., 'NewFeature', 'WorkItem')
|
|
10
|
+
*/
|
|
11
|
+
export function kebabToPascalCase(str) {
|
|
12
|
+
return str.split('-').map(function (word) {
|
|
13
|
+
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
14
|
+
}).join('');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Extracts icon name and size from an icon-object import path
|
|
19
|
+
* @param importPath - The import path like '@atlaskit/icon-object/glyph/new-feature/16'
|
|
20
|
+
* @returns Object with iconName and size, or null if not a valid icon-object import
|
|
21
|
+
*/
|
|
22
|
+
export function parseIconObjectImport(importPath) {
|
|
23
|
+
var match = importPath.match(/^@atlaskit\/icon-object\/glyph\/([^/]+)\/(16|24)$/);
|
|
24
|
+
if (!match) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
var _match = _slicedToArray(match, 3),
|
|
28
|
+
iconName = _match[1],
|
|
29
|
+
size = _match[2];
|
|
30
|
+
|
|
31
|
+
// Check if this is a valid icon name we support
|
|
32
|
+
if (!AVAILABLE_ICON_NAMES.includes(iconName)) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
iconName: iconName,
|
|
37
|
+
size: size
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Gets the new import specifier for an icon based on its name and size
|
|
43
|
+
* @param iconName - The kebab-case icon name from icon-object (e.g., 'new-feature', 'issue')
|
|
44
|
+
* @param size - The size ('16' or '24')
|
|
45
|
+
* @returns Object with the new import path and component name
|
|
46
|
+
*/
|
|
47
|
+
export function getNewImportInfo(iconName, size) {
|
|
48
|
+
// Check if this icon name needs to be mapped to a different object name
|
|
49
|
+
var objectName = ICON_TO_OBJECT_NAME_MAPPINGS[iconName] || iconName;
|
|
50
|
+
|
|
51
|
+
// Convert the object name to PascalCase
|
|
52
|
+
var pascalCaseName = kebabToPascalCase(objectName);
|
|
53
|
+
if (size === '16') {
|
|
54
|
+
return {
|
|
55
|
+
importPath: "@atlaskit/object/".concat(objectName),
|
|
56
|
+
componentName: "".concat(pascalCaseName, "Object")
|
|
57
|
+
};
|
|
58
|
+
} else {
|
|
59
|
+
return {
|
|
60
|
+
importPath: "@atlaskit/object/tile/".concat(objectName),
|
|
61
|
+
componentName: "".concat(pascalCaseName, "ObjectTile")
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Creates a new default import declaration for the transformed component
|
|
68
|
+
*/
|
|
69
|
+
export function createDefaultImportDeclaration(j, componentName, importPath) {
|
|
70
|
+
var defaultSpecifier = j.importDefaultSpecifier(j.identifier(componentName));
|
|
71
|
+
return j.importDeclaration([defaultSpecifier], j.stringLiteral(importPath));
|
|
72
|
+
}
|
|
@@ -6,6 +6,7 @@ import './styled-to-emotion/styled-to-emotion';
|
|
|
6
6
|
import './theme-remove-deprecated-mixins/theme-remove-deprecated-mixins';
|
|
7
7
|
import './migrate-to-link/migrate-to-link';
|
|
8
8
|
import './migrate-to-new-buttons/migrate-to-new-buttons';
|
|
9
|
+
import './migrate-icon-object-to-object/migrate-icon-object-to-object';
|
|
9
10
|
import './upgrade-pragmatic-drag-and-drop-to-stable/upgrade-pragmatic-drag-and-drop-to-stable';
|
|
10
11
|
import './remove-dark-theme-vr-options/remove-dark-theme-vr-options';
|
|
11
12
|
import './remove-token-fallbacks/remove-token-fallbacks';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const OLD_ICON_OBJECT_ENTRY_POINT = "@atlaskit/icon-object";
|
|
2
|
+
export declare const NEW_OBJECT_ENTRY_POINT = "@atlaskit/object";
|
|
3
|
+
export declare const NEW_OBJECT_TILE_ENTRY_POINT = "@atlaskit/object/tile";
|
|
4
|
+
/**
|
|
5
|
+
* Mappings for icon-object names that change when migrating to object.
|
|
6
|
+
* Key: old icon-object name (kebab-case)
|
|
7
|
+
* Value: new object name (kebab-case)
|
|
8
|
+
*
|
|
9
|
+
* Use this when the icon name in icon-object doesn't match the object name.
|
|
10
|
+
* For example, 'issue' icon-object becomes 'work-item' object.
|
|
11
|
+
*
|
|
12
|
+
* Icons not listed here will use their original name (converted to PascalCase automatically).
|
|
13
|
+
*/
|
|
14
|
+
export declare const ICON_TO_OBJECT_NAME_MAPPINGS: Record<string, string>;
|
|
15
|
+
export declare const AVAILABLE_ICON_NAMES: string[];
|
|
16
|
+
export declare const PRINT_SETTINGS: {
|
|
17
|
+
quote: "single";
|
|
18
|
+
trailingComma: boolean;
|
|
19
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a kebab-case string to PascalCase
|
|
3
|
+
* @param str - The kebab-case string (e.g., 'new-feature', 'work-item')
|
|
4
|
+
* @returns PascalCase string (e.g., 'NewFeature', 'WorkItem')
|
|
5
|
+
*/
|
|
6
|
+
export declare function kebabToPascalCase(str: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Extracts icon name and size from an icon-object import path
|
|
9
|
+
* @param importPath - The import path like '@atlaskit/icon-object/glyph/new-feature/16'
|
|
10
|
+
* @returns Object with iconName and size, or null if not a valid icon-object import
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseIconObjectImport(importPath: string): {
|
|
13
|
+
iconName: string;
|
|
14
|
+
size: '16' | '24';
|
|
15
|
+
} | null;
|
|
16
|
+
/**
|
|
17
|
+
* Gets the new import specifier for an icon based on its name and size
|
|
18
|
+
* @param iconName - The kebab-case icon name from icon-object (e.g., 'new-feature', 'issue')
|
|
19
|
+
* @param size - The size ('16' or '24')
|
|
20
|
+
* @returns Object with the new import path and component name
|
|
21
|
+
*/
|
|
22
|
+
export declare function getNewImportInfo(iconName: string, size: '16' | '24'): {
|
|
23
|
+
importPath: string;
|
|
24
|
+
componentName: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Creates a new default import declaration for the transformed component
|
|
28
|
+
*/
|
|
29
|
+
export declare function createDefaultImportDeclaration(j: any, componentName: string, importPath: string): any;
|
|
@@ -6,6 +6,7 @@ import './styled-to-emotion/styled-to-emotion';
|
|
|
6
6
|
import './theme-remove-deprecated-mixins/theme-remove-deprecated-mixins';
|
|
7
7
|
import './migrate-to-link/migrate-to-link';
|
|
8
8
|
import './migrate-to-new-buttons/migrate-to-new-buttons';
|
|
9
|
+
import './migrate-icon-object-to-object/migrate-icon-object-to-object';
|
|
9
10
|
import './upgrade-pragmatic-drag-and-drop-to-stable/upgrade-pragmatic-drag-and-drop-to-stable';
|
|
10
11
|
import './remove-dark-theme-vr-options/remove-dark-theme-vr-options';
|
|
11
12
|
import './remove-token-fallbacks/remove-token-fallbacks';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const OLD_ICON_OBJECT_ENTRY_POINT = "@atlaskit/icon-object";
|
|
2
|
+
export declare const NEW_OBJECT_ENTRY_POINT = "@atlaskit/object";
|
|
3
|
+
export declare const NEW_OBJECT_TILE_ENTRY_POINT = "@atlaskit/object/tile";
|
|
4
|
+
/**
|
|
5
|
+
* Mappings for icon-object names that change when migrating to object.
|
|
6
|
+
* Key: old icon-object name (kebab-case)
|
|
7
|
+
* Value: new object name (kebab-case)
|
|
8
|
+
*
|
|
9
|
+
* Use this when the icon name in icon-object doesn't match the object name.
|
|
10
|
+
* For example, 'issue' icon-object becomes 'work-item' object.
|
|
11
|
+
*
|
|
12
|
+
* Icons not listed here will use their original name (converted to PascalCase automatically).
|
|
13
|
+
*/
|
|
14
|
+
export declare const ICON_TO_OBJECT_NAME_MAPPINGS: Record<string, string>;
|
|
15
|
+
export declare const AVAILABLE_ICON_NAMES: string[];
|
|
16
|
+
export declare const PRINT_SETTINGS: {
|
|
17
|
+
quote: "single";
|
|
18
|
+
trailingComma: boolean;
|
|
19
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a kebab-case string to PascalCase
|
|
3
|
+
* @param str - The kebab-case string (e.g., 'new-feature', 'work-item')
|
|
4
|
+
* @returns PascalCase string (e.g., 'NewFeature', 'WorkItem')
|
|
5
|
+
*/
|
|
6
|
+
export declare function kebabToPascalCase(str: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Extracts icon name and size from an icon-object import path
|
|
9
|
+
* @param importPath - The import path like '@atlaskit/icon-object/glyph/new-feature/16'
|
|
10
|
+
* @returns Object with iconName and size, or null if not a valid icon-object import
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseIconObjectImport(importPath: string): {
|
|
13
|
+
iconName: string;
|
|
14
|
+
size: '16' | '24';
|
|
15
|
+
} | null;
|
|
16
|
+
/**
|
|
17
|
+
* Gets the new import specifier for an icon based on its name and size
|
|
18
|
+
* @param iconName - The kebab-case icon name from icon-object (e.g., 'new-feature', 'issue')
|
|
19
|
+
* @param size - The size ('16' or '24')
|
|
20
|
+
* @returns Object with the new import path and component name
|
|
21
|
+
*/
|
|
22
|
+
export declare function getNewImportInfo(iconName: string, size: '16' | '24'): {
|
|
23
|
+
importPath: string;
|
|
24
|
+
componentName: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Creates a new default import declaration for the transformed component
|
|
28
|
+
*/
|
|
29
|
+
export declare function createDefaultImportDeclaration(j: any, componentName: string, importPath: string): any;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/codemod-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.1",
|
|
4
4
|
"description": "A cli for distributing codemods for atlassian-frontend components and services",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -19,16 +19,6 @@
|
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
"atlaskit:src": "src/index.ts",
|
|
22
|
-
"af:exports": {
|
|
23
|
-
".": "./src/index.ts",
|
|
24
|
-
"./cli": "./src/cli.ts",
|
|
25
|
-
"./filepath": "./src/filepath.ts",
|
|
26
|
-
"./main": "./src/main.ts",
|
|
27
|
-
"./sinceRef": "./src/sinceRef.ts",
|
|
28
|
-
"./transforms": "./src/transforms.ts",
|
|
29
|
-
"./types": "./src/types.ts",
|
|
30
|
-
"./utils": "./src/utils.ts"
|
|
31
|
-
},
|
|
32
22
|
"atlassian": {
|
|
33
23
|
"team": "Design System Team"
|
|
34
24
|
},
|
|
@@ -39,7 +29,7 @@
|
|
|
39
29
|
"bin": "./bin/codemod-cli.js",
|
|
40
30
|
"dependencies": {
|
|
41
31
|
"@atlaskit/codemod-utils": "^4.2.0",
|
|
42
|
-
"@atlaskit/tokens": "^6.
|
|
32
|
+
"@atlaskit/tokens": "^6.5.0",
|
|
43
33
|
"@babel/runtime": "^7.0.0",
|
|
44
34
|
"@codeshift/utils": "^0.2.4",
|
|
45
35
|
"@hypermod/utils": "^0.4.2",
|