@atlaskit/codemod-cli 0.33.2 → 0.34.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.
Files changed (22) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cjs/main.js +1 -1
  3. package/dist/cjs/presets/index.js +2 -1
  4. package/dist/cjs/presets/lozenge-discovery-to-tag-with-fg/codemods/lozenge-discovery-to-tag-with-fg.js +219 -0
  5. package/dist/cjs/presets/lozenge-discovery-to-tag-with-fg/lozenge-discovery-to-tag-with-fg.js +44 -0
  6. package/dist/cjs/presets/remove-token-fallbacks/utils/all-tokens.js +2 -2
  7. package/dist/es2019/presets/index.js +2 -1
  8. package/dist/es2019/presets/lozenge-discovery-to-tag-with-fg/codemods/lozenge-discovery-to-tag-with-fg.js +207 -0
  9. package/dist/es2019/presets/lozenge-discovery-to-tag-with-fg/lozenge-discovery-to-tag-with-fg.js +18 -0
  10. package/dist/es2019/presets/remove-token-fallbacks/utils/all-tokens.js +3 -3
  11. package/dist/esm/main.js +1 -1
  12. package/dist/esm/presets/index.js +2 -1
  13. package/dist/esm/presets/lozenge-discovery-to-tag-with-fg/codemods/lozenge-discovery-to-tag-with-fg.js +213 -0
  14. package/dist/esm/presets/lozenge-discovery-to-tag-with-fg/lozenge-discovery-to-tag-with-fg.js +37 -0
  15. package/dist/esm/presets/remove-token-fallbacks/utils/all-tokens.js +3 -3
  16. package/dist/types/presets/index.d.ts +1 -0
  17. package/dist/types/presets/lozenge-discovery-to-tag-with-fg/codemods/lozenge-discovery-to-tag-with-fg.d.ts +12 -0
  18. package/dist/types/presets/lozenge-discovery-to-tag-with-fg/lozenge-discovery-to-tag-with-fg.d.ts +2 -0
  19. package/dist/types-ts4.5/presets/index.d.ts +1 -0
  20. package/dist/types-ts4.5/presets/lozenge-discovery-to-tag-with-fg/codemods/lozenge-discovery-to-tag-with-fg.d.ts +12 -0
  21. package/dist/types-ts4.5/presets/lozenge-discovery-to-tag-with-fg/lozenge-discovery-to-tag-with-fg.d.ts +2 -0
  22. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @atlaskit/codemod-cli
2
2
 
3
+ ## 0.34.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`f111803c4e253`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/f111803c4e253) -
8
+ Updating typography fallbacks to refreshed typography values as the deprecated legacy typography
9
+ theme has been removed.
10
+ - Updated dependencies
11
+
12
+ ## 0.34.0
13
+
14
+ ### Minor Changes
15
+
16
+ - [`7e8bbc2620251`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7e8bbc2620251) -
17
+ Added a codemod lozenge-discovery-to-tag-with-fg to migrate Lozenge components with
18
+ appearance='new' or 'discovery' to Tag behind feature gate.
19
+
3
20
  ## 0.33.2
4
21
 
5
22
  ### 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.33.1", _PACKAGE_VERSION_ = _process$env$_PACKAGE === void 0 ? '0.0.0-dev' : _process$env$_PACKAGE;
365
+ _process$env$_PACKAGE = "0.34.0", _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) {
@@ -16,6 +16,7 @@ require("./remove-dark-theme-vr-options/remove-dark-theme-vr-options");
16
16
  require("./remove-token-fallbacks/remove-token-fallbacks");
17
17
  require("./lozenge-appearance-semantic-migration/lozenge-appearance-semantic-migration");
18
18
  require("./lozenge-to-tag-migration/lozenge-to-tag-migration");
19
+ require("./lozenge-discovery-to-tag-with-fg/lozenge-discovery-to-tag-with-fg");
19
20
  require("./badge-appearance-semantic-migration/badge-appearance-semantic-migration");
20
21
  require("./tag-to-newTag-migration/tag-to-newTag-migration");
21
22
  require("./migrate-deprecated-icon/migrate-deprecated-icon");
@@ -24,7 +25,7 @@ require("./migrate-deprecated-icon/migrate-deprecated-icon");
24
25
  * in the final bundle.
25
26
  */
26
27
 
27
- var presets = ['styled-to-emotion', 'theme-remove-deprecated-mixins', 'migrate-deprecated-icon', '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', 'lozenge-appearance-semantic-migration', 'lozenge-to-tag-migration', 'badge-appearance-semantic-migration', 'tag-to-newTag-migration'].map(function (preset) {
28
+ var presets = ['styled-to-emotion', 'theme-remove-deprecated-mixins', 'migrate-deprecated-icon', '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', 'lozenge-appearance-semantic-migration', 'lozenge-to-tag-migration', 'lozenge-discovery-to-tag-with-fg', 'badge-appearance-semantic-migration', 'tag-to-newTag-migration'].map(function (preset) {
28
29
  return _path.default.join(__dirname, preset, "".concat(preset, ".@(ts|js|tsx)"));
29
30
  });
30
31
  var _default = exports.default = presets;
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = transformer;
7
+ /* eslint-disable @repo/internal/fs/filename-pattern-match */
8
+
9
+ var LOZENGE_ENTRY_POINT = '@atlaskit/lozenge';
10
+ var TAG_ENTRY_POINT = '@atlaskit/tag';
11
+ var FG_ENTRY_POINT = '@atlassian/jira-feature-gating';
12
+ var FEATURE_GATE_NAME = 'platform-dst-lozenge-tag-badge-visual-uplifts';
13
+ var PRINT_SETTINGS = {
14
+ quote: 'single'
15
+ };
16
+ /**
17
+ * Codemod to migrate Lozenge components with appearance='new' or 'discovery' to Tag behind feature gate.
18
+ *
19
+ * This codemod:
20
+ * 1. Finds Lozenges with appearance="new" or appearance="discovery"
21
+ * 2. Also includes discovery Lozenges with isBold={true} or isBold
22
+ * 3. Wraps them in a feature gate: fg('platform-dst-lozenge-tag-badge-visual-uplifts')
23
+ * 4. Converts to Tag with color="purple" when feature gate is off
24
+ * 5. Adds necessary imports (Tag, fg)
25
+ */
26
+ function transformer(file, api) {
27
+ var j = api.jscodeshift;
28
+ var source;
29
+
30
+ // Try to parse the file
31
+ try {
32
+ source = j(file.source);
33
+ } catch (error) {
34
+ // eslint-disable-next-line no-console
35
+ console.error(error);
36
+ return file.source;
37
+ }
38
+
39
+ // Check if Lozenge is imported from @atlaskit/lozenge
40
+ var hasLozengeImport = source.find(j.ImportDeclaration).some(function (importPath) {
41
+ return importPath.value.source.value === LOZENGE_ENTRY_POINT;
42
+ });
43
+ if (!hasLozengeImport) {
44
+ return file.source;
45
+ }
46
+
47
+ // Get all Lozenge component names (handles renamed imports)
48
+ var lozengeNames = new Set();
49
+ source.find(j.ImportDeclaration).forEach(function (importPath) {
50
+ if (importPath.value.source.value === LOZENGE_ENTRY_POINT) {
51
+ var _importPath$value$spe;
52
+ (_importPath$value$spe = importPath.value.specifiers) === null || _importPath$value$spe === void 0 || _importPath$value$spe.forEach(function (specifier) {
53
+ if (specifier.type === 'ImportDefaultSpecifier') {
54
+ lozengeNames.add(specifier.local.name);
55
+ } else if (specifier.type === 'ImportSpecifier' && specifier.imported.name === 'default') {
56
+ lozengeNames.add(specifier.local.name);
57
+ }
58
+ });
59
+ }
60
+ });
61
+
62
+ // Find all Lozenge elements that should be migrated
63
+ var lozengeElements = [];
64
+ source.find(j.JSXElement).forEach(function (path) {
65
+ var _openingElement$name;
66
+ var openingElement = path.value.openingElement;
67
+ if (((_openingElement$name = openingElement.name) === null || _openingElement$name === void 0 ? void 0 : _openingElement$name.type) === 'JSXIdentifier' && lozengeNames.has(openingElement.name.name)) {
68
+ var _openingElement$attri;
69
+ var element = {
70
+ path: path,
71
+ shouldMigrate: false
72
+ };
73
+
74
+ // Check for appearance and isBold props
75
+ (_openingElement$attri = openingElement.attributes) === null || _openingElement$attri === void 0 || _openingElement$attri.forEach(function (attr) {
76
+ var _attr$name;
77
+ if (attr.type === 'JSXAttribute' && ((_attr$name = attr.name) === null || _attr$name === void 0 ? void 0 : _attr$name.type) === 'JSXIdentifier') {
78
+ if (attr.name.name === 'appearance') {
79
+ var _attr$value, _attr$value2;
80
+ if (((_attr$value = attr.value) === null || _attr$value === void 0 ? void 0 : _attr$value.type) === 'StringLiteral') {
81
+ element.appearanceValue = attr.value.value;
82
+ } else if (((_attr$value2 = attr.value) === null || _attr$value2 === void 0 ? void 0 : _attr$value2.type) === 'JSXExpressionContainer') {
83
+ var expression = attr.value.expression;
84
+ if (expression.type === 'StringLiteral') {
85
+ element.appearanceValue = expression.value;
86
+ }
87
+ }
88
+ } else if (attr.name.name === 'isBold') {
89
+ var _attr$value3;
90
+ if (attr.value === null) {
91
+ element.isBoldValue = true;
92
+ } else if (((_attr$value3 = attr.value) === null || _attr$value3 === void 0 ? void 0 : _attr$value3.type) === 'JSXExpressionContainer') {
93
+ var _expression = attr.value.expression;
94
+ if (_expression.type === 'BooleanLiteral') {
95
+ element.isBoldValue = _expression.value;
96
+ } else if (_expression.type === 'Literal' && typeof _expression.value === 'boolean') {
97
+ element.isBoldValue = _expression.value;
98
+ }
99
+ }
100
+ }
101
+ }
102
+ });
103
+
104
+ // Determine if this Lozenge should be migrated
105
+ // Migrate if: appearance="new" OR appearance="discovery" OR (appearance="discovery" AND isBold={true})
106
+ if (element.appearanceValue === 'new' || element.appearanceValue === 'discovery' || element.appearanceValue === 'discovery' && element.isBoldValue === true) {
107
+ element.shouldMigrate = true;
108
+ }
109
+ if (element.shouldMigrate) {
110
+ lozengeElements.push(element);
111
+ }
112
+ }
113
+ });
114
+
115
+ // If no elements to migrate, return early
116
+ if (lozengeElements.length === 0) {
117
+ return file.source;
118
+ }
119
+
120
+ // Check if Tag import exists
121
+ var hasTagImport = source.find(j.ImportDeclaration).some(function (importPath) {
122
+ return importPath.value.source.value === TAG_ENTRY_POINT;
123
+ });
124
+
125
+ // Check if fg is already imported from @atlassian/jira-feature-gating
126
+ var hasFgImport = source.find(j.ImportDeclaration).some(function (importPath) {
127
+ if (importPath.value.source.value === FG_ENTRY_POINT) {
128
+ var _importPath$value$spe2;
129
+ // Check if 'fg' is in the specifiers
130
+ return (_importPath$value$spe2 = importPath.value.specifiers) === null || _importPath$value$spe2 === void 0 ? void 0 : _importPath$value$spe2.some(function (spec) {
131
+ return spec.type === 'ImportSpecifier' && spec.imported.name === 'fg';
132
+ });
133
+ }
134
+ return false;
135
+ });
136
+
137
+ // Add imports after Lozenge import to avoid blank lines
138
+ var lozengeImport = source.find(j.ImportDeclaration).filter(function (path) {
139
+ return path.value.source.value === LOZENGE_ENTRY_POINT;
140
+ }).at(0);
141
+ if (lozengeImport.length > 0) {
142
+ // Add imports in reverse order so they appear in the right order
143
+ if (!hasFgImport) {
144
+ lozengeImport.insertAfter(j.importDeclaration([j.importSpecifier(j.identifier('fg'))], j.stringLiteral(FG_ENTRY_POINT)));
145
+ }
146
+ if (!hasTagImport) {
147
+ lozengeImport.insertAfter(j.importDeclaration([j.importDefaultSpecifier(j.identifier('Tag'))], j.stringLiteral(TAG_ENTRY_POINT)));
148
+ }
149
+ }
150
+
151
+ // Transform each element
152
+ lozengeElements.forEach(function (element) {
153
+ var _openingElement$attri2;
154
+ var path = element.path;
155
+ var openingElement = path.value.openingElement;
156
+
157
+ // Extract text content or JSX expression from children
158
+ var children = path.value.children;
159
+ var textAttribute = null;
160
+ if (children && children.length > 0) {
161
+ // Check if there's a single JSX expression child (e.g., {formatMessage(...)})
162
+ if (children.length === 1 && children[0].type === 'JSXExpressionContainer') {
163
+ var expression = children[0].expression;
164
+ // Use the expression as the text value
165
+ textAttribute = j.jsxAttribute(j.jsxIdentifier('text'), j.jsxExpressionContainer(expression));
166
+ } else {
167
+ // Extract plain text content from JSXText nodes
168
+ var textContent = children.filter(function (child) {
169
+ return child.type === 'JSXText';
170
+ }).map(function (child) {
171
+ return child.value.trim();
172
+ }).filter(function (text) {
173
+ return text.length > 0;
174
+ }).join(' ');
175
+ if (textContent) {
176
+ textAttribute = j.jsxAttribute(j.jsxIdentifier('text'), j.stringLiteral(textContent));
177
+ }
178
+ }
179
+ }
180
+
181
+ // Create the Tag element
182
+ var tagAttributes = [j.jsxAttribute(j.jsxIdentifier('color'), j.stringLiteral('purple'))];
183
+ if (textAttribute) {
184
+ tagAttributes.unshift(textAttribute);
185
+ }
186
+
187
+ // Copy other props from Lozenge to Tag (except appearance and isBold)
188
+ (_openingElement$attri2 = openingElement.attributes) === null || _openingElement$attri2 === void 0 || _openingElement$attri2.forEach(function (attr) {
189
+ var _attr$name2;
190
+ if (attr.type === 'JSXAttribute' && ((_attr$name2 = attr.name) === null || _attr$name2 === void 0 ? void 0 : _attr$name2.type) === 'JSXIdentifier') {
191
+ if (attr.name.name !== 'appearance' && attr.name.name !== 'isBold') {
192
+ tagAttributes.push(attr);
193
+ }
194
+ }
195
+ });
196
+ var tagElement = j.jsxElement(j.jsxOpeningElement(j.jsxIdentifier('Tag'), tagAttributes, true), null, []);
197
+
198
+ // Keep the original Lozenge element (just the element, without wrapping)
199
+ var lozengeElement = path.value;
200
+
201
+ // Create the conditional expression: fg(FEATURE_GATE_NAME) ? <Tag .../> : <Lozenge .../>
202
+ // When feature gate is ON, show Tag (new behavior)
203
+ // When feature gate is OFF, show Lozenge (old behavior)
204
+ var conditionalExpression = j.conditionalExpression(j.callExpression(j.identifier('fg'), [j.stringLiteral(FEATURE_GATE_NAME)]), tagElement, lozengeElement);
205
+
206
+ // Check if the parent is a JSXElement (means we're inside JSX, need curly braces)
207
+ // Otherwise, it's a regular expression (like in a return statement)
208
+ var parent = path.parent;
209
+ var needsJSXWrapper = parent && (parent.value.type === 'JSXElement' || parent.value.type === 'JSXExpressionContainer');
210
+ if (needsJSXWrapper) {
211
+ // Inside JSX, wrap in expression container
212
+ j(path).replaceWith(j.jsxExpressionContainer(conditionalExpression));
213
+ } else {
214
+ // In regular JS context (like return statement), just use the conditional
215
+ j(path).replaceWith(conditionalExpression);
216
+ }
217
+ });
218
+ return source.toSource(PRINT_SETTINGS);
219
+ }
@@ -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 _lozengeDiscoveryToTagWithFg = _interopRequireDefault(require("./codemods/lozenge-discovery-to-tag-with-fg"));
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 = [_lozengeDiscoveryToTagWithFg.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
+ }
@@ -20,7 +20,7 @@ function buildCombinedMap() {
20
20
  }
21
21
 
22
22
  // Filter the typography tokens based on predefined groups and exclusions
23
- var typographyAdg3ThemeFiltered = _tokensRaw.typographyAdg3.filter(function (token) {
23
+ var typographyThemeFiltered = _tokensRaw.typography.filter(function (token) {
24
24
  return typographyGroups.includes(token.attributes.group);
25
25
  }).filter(function (token) {
26
26
  return token.cleanName !== 'font.body.UNSAFE_small';
@@ -38,7 +38,7 @@ function getTokenMap() {
38
38
  var themeIndex = useLegacyTheme ? 1 : 0;
39
39
  if (!tokenMapCache[themeIndex]) {
40
40
  var selectedTheme = useLegacyTheme ? _tokensRaw.legacyLightTokens : _tokensRaw.light;
41
- tokenMapCache[themeIndex] = buildCombinedMap(selectedTheme, _tokensRaw.spacing, _tokensRaw.shape, typographyAdg3ThemeFiltered);
41
+ tokenMapCache[themeIndex] = buildCombinedMap(selectedTheme, _tokensRaw.spacing, _tokensRaw.shape, typographyThemeFiltered);
42
42
  }
43
43
  return tokenMapCache[themeIndex];
44
44
  }
@@ -14,8 +14,9 @@ import './remove-dark-theme-vr-options/remove-dark-theme-vr-options';
14
14
  import './remove-token-fallbacks/remove-token-fallbacks';
15
15
  import './lozenge-appearance-semantic-migration/lozenge-appearance-semantic-migration';
16
16
  import './lozenge-to-tag-migration/lozenge-to-tag-migration';
17
+ import './lozenge-discovery-to-tag-with-fg/lozenge-discovery-to-tag-with-fg';
17
18
  import './badge-appearance-semantic-migration/badge-appearance-semantic-migration';
18
19
  import './tag-to-newTag-migration/tag-to-newTag-migration';
19
20
  import './migrate-deprecated-icon/migrate-deprecated-icon';
20
- const presets = ['styled-to-emotion', 'theme-remove-deprecated-mixins', 'migrate-deprecated-icon', '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', 'lozenge-appearance-semantic-migration', 'lozenge-to-tag-migration', 'badge-appearance-semantic-migration', 'tag-to-newTag-migration'].map(preset => path.join(__dirname, preset, `${preset}.@(ts|js|tsx)`));
21
+ const presets = ['styled-to-emotion', 'theme-remove-deprecated-mixins', 'migrate-deprecated-icon', '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', 'lozenge-appearance-semantic-migration', 'lozenge-to-tag-migration', 'lozenge-discovery-to-tag-with-fg', 'badge-appearance-semantic-migration', 'tag-to-newTag-migration'].map(preset => path.join(__dirname, preset, `${preset}.@(ts|js|tsx)`));
21
22
  export default presets;
@@ -0,0 +1,207 @@
1
+ /* eslint-disable @repo/internal/fs/filename-pattern-match */
2
+
3
+ const LOZENGE_ENTRY_POINT = '@atlaskit/lozenge';
4
+ const TAG_ENTRY_POINT = '@atlaskit/tag';
5
+ const FG_ENTRY_POINT = '@atlassian/jira-feature-gating';
6
+ const FEATURE_GATE_NAME = 'platform-dst-lozenge-tag-badge-visual-uplifts';
7
+ const PRINT_SETTINGS = {
8
+ quote: 'single'
9
+ };
10
+ /**
11
+ * Codemod to migrate Lozenge components with appearance='new' or 'discovery' to Tag behind feature gate.
12
+ *
13
+ * This codemod:
14
+ * 1. Finds Lozenges with appearance="new" or appearance="discovery"
15
+ * 2. Also includes discovery Lozenges with isBold={true} or isBold
16
+ * 3. Wraps them in a feature gate: fg('platform-dst-lozenge-tag-badge-visual-uplifts')
17
+ * 4. Converts to Tag with color="purple" when feature gate is off
18
+ * 5. Adds necessary imports (Tag, fg)
19
+ */
20
+ export default function transformer(file, api) {
21
+ const j = api.jscodeshift;
22
+ let source;
23
+
24
+ // Try to parse the file
25
+ try {
26
+ source = j(file.source);
27
+ } catch (error) {
28
+ // eslint-disable-next-line no-console
29
+ console.error(error);
30
+ return file.source;
31
+ }
32
+
33
+ // Check if Lozenge is imported from @atlaskit/lozenge
34
+ const hasLozengeImport = source.find(j.ImportDeclaration).some(importPath => {
35
+ return importPath.value.source.value === LOZENGE_ENTRY_POINT;
36
+ });
37
+ if (!hasLozengeImport) {
38
+ return file.source;
39
+ }
40
+
41
+ // Get all Lozenge component names (handles renamed imports)
42
+ const lozengeNames = new Set();
43
+ source.find(j.ImportDeclaration).forEach(importPath => {
44
+ if (importPath.value.source.value === LOZENGE_ENTRY_POINT) {
45
+ var _importPath$value$spe;
46
+ (_importPath$value$spe = importPath.value.specifiers) === null || _importPath$value$spe === void 0 ? void 0 : _importPath$value$spe.forEach(specifier => {
47
+ if (specifier.type === 'ImportDefaultSpecifier') {
48
+ lozengeNames.add(specifier.local.name);
49
+ } else if (specifier.type === 'ImportSpecifier' && specifier.imported.name === 'default') {
50
+ lozengeNames.add(specifier.local.name);
51
+ }
52
+ });
53
+ }
54
+ });
55
+
56
+ // Find all Lozenge elements that should be migrated
57
+ const lozengeElements = [];
58
+ source.find(j.JSXElement).forEach(path => {
59
+ var _openingElement$name;
60
+ const openingElement = path.value.openingElement;
61
+ if (((_openingElement$name = openingElement.name) === null || _openingElement$name === void 0 ? void 0 : _openingElement$name.type) === 'JSXIdentifier' && lozengeNames.has(openingElement.name.name)) {
62
+ var _openingElement$attri;
63
+ const element = {
64
+ path,
65
+ shouldMigrate: false
66
+ };
67
+
68
+ // Check for appearance and isBold props
69
+ (_openingElement$attri = openingElement.attributes) === null || _openingElement$attri === void 0 ? void 0 : _openingElement$attri.forEach(attr => {
70
+ var _attr$name;
71
+ if (attr.type === 'JSXAttribute' && ((_attr$name = attr.name) === null || _attr$name === void 0 ? void 0 : _attr$name.type) === 'JSXIdentifier') {
72
+ if (attr.name.name === 'appearance') {
73
+ var _attr$value, _attr$value2;
74
+ if (((_attr$value = attr.value) === null || _attr$value === void 0 ? void 0 : _attr$value.type) === 'StringLiteral') {
75
+ element.appearanceValue = attr.value.value;
76
+ } else if (((_attr$value2 = attr.value) === null || _attr$value2 === void 0 ? void 0 : _attr$value2.type) === 'JSXExpressionContainer') {
77
+ const expression = attr.value.expression;
78
+ if (expression.type === 'StringLiteral') {
79
+ element.appearanceValue = expression.value;
80
+ }
81
+ }
82
+ } else if (attr.name.name === 'isBold') {
83
+ var _attr$value3;
84
+ if (attr.value === null) {
85
+ element.isBoldValue = true;
86
+ } else if (((_attr$value3 = attr.value) === null || _attr$value3 === void 0 ? void 0 : _attr$value3.type) === 'JSXExpressionContainer') {
87
+ const expression = attr.value.expression;
88
+ if (expression.type === 'BooleanLiteral') {
89
+ element.isBoldValue = expression.value;
90
+ } else if (expression.type === 'Literal' && typeof expression.value === 'boolean') {
91
+ element.isBoldValue = expression.value;
92
+ }
93
+ }
94
+ }
95
+ }
96
+ });
97
+
98
+ // Determine if this Lozenge should be migrated
99
+ // Migrate if: appearance="new" OR appearance="discovery" OR (appearance="discovery" AND isBold={true})
100
+ if (element.appearanceValue === 'new' || element.appearanceValue === 'discovery' || element.appearanceValue === 'discovery' && element.isBoldValue === true) {
101
+ element.shouldMigrate = true;
102
+ }
103
+ if (element.shouldMigrate) {
104
+ lozengeElements.push(element);
105
+ }
106
+ }
107
+ });
108
+
109
+ // If no elements to migrate, return early
110
+ if (lozengeElements.length === 0) {
111
+ return file.source;
112
+ }
113
+
114
+ // Check if Tag import exists
115
+ const hasTagImport = source.find(j.ImportDeclaration).some(importPath => importPath.value.source.value === TAG_ENTRY_POINT);
116
+
117
+ // Check if fg is already imported from @atlassian/jira-feature-gating
118
+ const hasFgImport = source.find(j.ImportDeclaration).some(importPath => {
119
+ if (importPath.value.source.value === FG_ENTRY_POINT) {
120
+ var _importPath$value$spe2;
121
+ // Check if 'fg' is in the specifiers
122
+ return (_importPath$value$spe2 = importPath.value.specifiers) === null || _importPath$value$spe2 === void 0 ? void 0 : _importPath$value$spe2.some(spec => {
123
+ return spec.type === 'ImportSpecifier' && spec.imported.name === 'fg';
124
+ });
125
+ }
126
+ return false;
127
+ });
128
+
129
+ // Add imports after Lozenge import to avoid blank lines
130
+ const lozengeImport = source.find(j.ImportDeclaration).filter(path => {
131
+ return path.value.source.value === LOZENGE_ENTRY_POINT;
132
+ }).at(0);
133
+ if (lozengeImport.length > 0) {
134
+ // Add imports in reverse order so they appear in the right order
135
+ if (!hasFgImport) {
136
+ lozengeImport.insertAfter(j.importDeclaration([j.importSpecifier(j.identifier('fg'))], j.stringLiteral(FG_ENTRY_POINT)));
137
+ }
138
+ if (!hasTagImport) {
139
+ lozengeImport.insertAfter(j.importDeclaration([j.importDefaultSpecifier(j.identifier('Tag'))], j.stringLiteral(TAG_ENTRY_POINT)));
140
+ }
141
+ }
142
+
143
+ // Transform each element
144
+ lozengeElements.forEach(element => {
145
+ var _openingElement$attri2;
146
+ const {
147
+ path
148
+ } = element;
149
+ const openingElement = path.value.openingElement;
150
+
151
+ // Extract text content or JSX expression from children
152
+ const children = path.value.children;
153
+ let textAttribute = null;
154
+ if (children && children.length > 0) {
155
+ // Check if there's a single JSX expression child (e.g., {formatMessage(...)})
156
+ if (children.length === 1 && children[0].type === 'JSXExpressionContainer') {
157
+ const expression = children[0].expression;
158
+ // Use the expression as the text value
159
+ textAttribute = j.jsxAttribute(j.jsxIdentifier('text'), j.jsxExpressionContainer(expression));
160
+ } else {
161
+ // Extract plain text content from JSXText nodes
162
+ const textContent = children.filter(child => child.type === 'JSXText').map(child => child.value.trim()).filter(text => text.length > 0).join(' ');
163
+ if (textContent) {
164
+ textAttribute = j.jsxAttribute(j.jsxIdentifier('text'), j.stringLiteral(textContent));
165
+ }
166
+ }
167
+ }
168
+
169
+ // Create the Tag element
170
+ const tagAttributes = [j.jsxAttribute(j.jsxIdentifier('color'), j.stringLiteral('purple'))];
171
+ if (textAttribute) {
172
+ tagAttributes.unshift(textAttribute);
173
+ }
174
+
175
+ // Copy other props from Lozenge to Tag (except appearance and isBold)
176
+ (_openingElement$attri2 = openingElement.attributes) === null || _openingElement$attri2 === void 0 ? void 0 : _openingElement$attri2.forEach(attr => {
177
+ var _attr$name2;
178
+ if (attr.type === 'JSXAttribute' && ((_attr$name2 = attr.name) === null || _attr$name2 === void 0 ? void 0 : _attr$name2.type) === 'JSXIdentifier') {
179
+ if (attr.name.name !== 'appearance' && attr.name.name !== 'isBold') {
180
+ tagAttributes.push(attr);
181
+ }
182
+ }
183
+ });
184
+ const tagElement = j.jsxElement(j.jsxOpeningElement(j.jsxIdentifier('Tag'), tagAttributes, true), null, []);
185
+
186
+ // Keep the original Lozenge element (just the element, without wrapping)
187
+ const lozengeElement = path.value;
188
+
189
+ // Create the conditional expression: fg(FEATURE_GATE_NAME) ? <Tag .../> : <Lozenge .../>
190
+ // When feature gate is ON, show Tag (new behavior)
191
+ // When feature gate is OFF, show Lozenge (old behavior)
192
+ const conditionalExpression = j.conditionalExpression(j.callExpression(j.identifier('fg'), [j.stringLiteral(FEATURE_GATE_NAME)]), tagElement, lozengeElement);
193
+
194
+ // Check if the parent is a JSXElement (means we're inside JSX, need curly braces)
195
+ // Otherwise, it's a regular expression (like in a return statement)
196
+ const parent = path.parent;
197
+ const needsJSXWrapper = parent && (parent.value.type === 'JSXElement' || parent.value.type === 'JSXExpressionContainer');
198
+ if (needsJSXWrapper) {
199
+ // Inside JSX, wrap in expression container
200
+ j(path).replaceWith(j.jsxExpressionContainer(conditionalExpression));
201
+ } else {
202
+ // In regular JS context (like return statement), just use the conditional
203
+ j(path).replaceWith(conditionalExpression);
204
+ }
205
+ });
206
+ return source.toSource(PRINT_SETTINGS);
207
+ }
@@ -0,0 +1,18 @@
1
+ import lozengeDiscoveryToTagWithFgTransformer from './codemods/lozenge-discovery-to-tag-with-fg';
2
+ export default async function transformer(file, api) {
3
+ const transformers = [lozengeDiscoveryToTagWithFgTransformer];
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
+ }
@@ -1,4 +1,4 @@
1
- import { legacyLightTokens as legacyLightTheme, light as lightTheme, shape as shapeTheme, spacing as spacingTheme, typographyAdg3 as typographyAdg3Theme } from '@atlaskit/tokens/tokens-raw';
1
+ import { legacyLightTokens as legacyLightTheme, light as lightTheme, shape as shapeTheme, spacing as spacingTheme, typography as typographyTheme } from '@atlaskit/tokens/tokens-raw';
2
2
  const typographyGroups = ['typography', 'fontWeight', 'fontFamily'];
3
3
  function buildCombinedMap(...arrays) {
4
4
  const combinedMap = {};
@@ -11,7 +11,7 @@ function buildCombinedMap(...arrays) {
11
11
  }
12
12
 
13
13
  // Filter the typography tokens based on predefined groups and exclusions
14
- const typographyAdg3ThemeFiltered = typographyAdg3Theme.filter(token => typographyGroups.includes(token.attributes.group)).filter(token => token.cleanName !== 'font.body.UNSAFE_small');
14
+ const typographyThemeFiltered = typographyTheme.filter(token => typographyGroups.includes(token.attributes.group)).filter(token => token.cleanName !== 'font.body.UNSAFE_small');
15
15
 
16
16
  // Cache array: [0] for light theme, [1] for legacy light theme
17
17
  const tokenMapCache = [null, null];
@@ -24,7 +24,7 @@ export function getTokenMap(useLegacyTheme = false) {
24
24
  const themeIndex = useLegacyTheme ? 1 : 0;
25
25
  if (!tokenMapCache[themeIndex]) {
26
26
  const selectedTheme = useLegacyTheme ? legacyLightTheme : lightTheme;
27
- tokenMapCache[themeIndex] = buildCombinedMap(selectedTheme, spacingTheme, shapeTheme, typographyAdg3ThemeFiltered);
27
+ tokenMapCache[themeIndex] = buildCombinedMap(selectedTheme, spacingTheme, shapeTheme, typographyThemeFiltered);
28
28
  }
29
29
  return tokenMapCache[themeIndex];
30
30
  }
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.33.1", _PACKAGE_VERSION_ = _process$env$_PACKAGE === void 0 ? '0.0.0-dev' : _process$env$_PACKAGE;
358
+ _process$env$_PACKAGE = "0.34.0", _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) {
@@ -14,10 +14,11 @@ import './remove-dark-theme-vr-options/remove-dark-theme-vr-options';
14
14
  import './remove-token-fallbacks/remove-token-fallbacks';
15
15
  import './lozenge-appearance-semantic-migration/lozenge-appearance-semantic-migration';
16
16
  import './lozenge-to-tag-migration/lozenge-to-tag-migration';
17
+ import './lozenge-discovery-to-tag-with-fg/lozenge-discovery-to-tag-with-fg';
17
18
  import './badge-appearance-semantic-migration/badge-appearance-semantic-migration';
18
19
  import './tag-to-newTag-migration/tag-to-newTag-migration';
19
20
  import './migrate-deprecated-icon/migrate-deprecated-icon';
20
- var presets = ['styled-to-emotion', 'theme-remove-deprecated-mixins', 'migrate-deprecated-icon', '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', 'lozenge-appearance-semantic-migration', 'lozenge-to-tag-migration', 'badge-appearance-semantic-migration', 'tag-to-newTag-migration'].map(function (preset) {
21
+ var presets = ['styled-to-emotion', 'theme-remove-deprecated-mixins', 'migrate-deprecated-icon', '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', 'lozenge-appearance-semantic-migration', 'lozenge-to-tag-migration', 'lozenge-discovery-to-tag-with-fg', 'badge-appearance-semantic-migration', 'tag-to-newTag-migration'].map(function (preset) {
21
22
  return path.join(__dirname, preset, "".concat(preset, ".@(ts|js|tsx)"));
22
23
  });
23
24
  export default presets;
@@ -0,0 +1,213 @@
1
+ /* eslint-disable @repo/internal/fs/filename-pattern-match */
2
+
3
+ var LOZENGE_ENTRY_POINT = '@atlaskit/lozenge';
4
+ var TAG_ENTRY_POINT = '@atlaskit/tag';
5
+ var FG_ENTRY_POINT = '@atlassian/jira-feature-gating';
6
+ var FEATURE_GATE_NAME = 'platform-dst-lozenge-tag-badge-visual-uplifts';
7
+ var PRINT_SETTINGS = {
8
+ quote: 'single'
9
+ };
10
+ /**
11
+ * Codemod to migrate Lozenge components with appearance='new' or 'discovery' to Tag behind feature gate.
12
+ *
13
+ * This codemod:
14
+ * 1. Finds Lozenges with appearance="new" or appearance="discovery"
15
+ * 2. Also includes discovery Lozenges with isBold={true} or isBold
16
+ * 3. Wraps them in a feature gate: fg('platform-dst-lozenge-tag-badge-visual-uplifts')
17
+ * 4. Converts to Tag with color="purple" when feature gate is off
18
+ * 5. Adds necessary imports (Tag, fg)
19
+ */
20
+ export default function transformer(file, api) {
21
+ var j = api.jscodeshift;
22
+ var source;
23
+
24
+ // Try to parse the file
25
+ try {
26
+ source = j(file.source);
27
+ } catch (error) {
28
+ // eslint-disable-next-line no-console
29
+ console.error(error);
30
+ return file.source;
31
+ }
32
+
33
+ // Check if Lozenge is imported from @atlaskit/lozenge
34
+ var hasLozengeImport = source.find(j.ImportDeclaration).some(function (importPath) {
35
+ return importPath.value.source.value === LOZENGE_ENTRY_POINT;
36
+ });
37
+ if (!hasLozengeImport) {
38
+ return file.source;
39
+ }
40
+
41
+ // Get all Lozenge component names (handles renamed imports)
42
+ var lozengeNames = new Set();
43
+ source.find(j.ImportDeclaration).forEach(function (importPath) {
44
+ if (importPath.value.source.value === LOZENGE_ENTRY_POINT) {
45
+ var _importPath$value$spe;
46
+ (_importPath$value$spe = importPath.value.specifiers) === null || _importPath$value$spe === void 0 || _importPath$value$spe.forEach(function (specifier) {
47
+ if (specifier.type === 'ImportDefaultSpecifier') {
48
+ lozengeNames.add(specifier.local.name);
49
+ } else if (specifier.type === 'ImportSpecifier' && specifier.imported.name === 'default') {
50
+ lozengeNames.add(specifier.local.name);
51
+ }
52
+ });
53
+ }
54
+ });
55
+
56
+ // Find all Lozenge elements that should be migrated
57
+ var lozengeElements = [];
58
+ source.find(j.JSXElement).forEach(function (path) {
59
+ var _openingElement$name;
60
+ var openingElement = path.value.openingElement;
61
+ if (((_openingElement$name = openingElement.name) === null || _openingElement$name === void 0 ? void 0 : _openingElement$name.type) === 'JSXIdentifier' && lozengeNames.has(openingElement.name.name)) {
62
+ var _openingElement$attri;
63
+ var element = {
64
+ path: path,
65
+ shouldMigrate: false
66
+ };
67
+
68
+ // Check for appearance and isBold props
69
+ (_openingElement$attri = openingElement.attributes) === null || _openingElement$attri === void 0 || _openingElement$attri.forEach(function (attr) {
70
+ var _attr$name;
71
+ if (attr.type === 'JSXAttribute' && ((_attr$name = attr.name) === null || _attr$name === void 0 ? void 0 : _attr$name.type) === 'JSXIdentifier') {
72
+ if (attr.name.name === 'appearance') {
73
+ var _attr$value, _attr$value2;
74
+ if (((_attr$value = attr.value) === null || _attr$value === void 0 ? void 0 : _attr$value.type) === 'StringLiteral') {
75
+ element.appearanceValue = attr.value.value;
76
+ } else if (((_attr$value2 = attr.value) === null || _attr$value2 === void 0 ? void 0 : _attr$value2.type) === 'JSXExpressionContainer') {
77
+ var expression = attr.value.expression;
78
+ if (expression.type === 'StringLiteral') {
79
+ element.appearanceValue = expression.value;
80
+ }
81
+ }
82
+ } else if (attr.name.name === 'isBold') {
83
+ var _attr$value3;
84
+ if (attr.value === null) {
85
+ element.isBoldValue = true;
86
+ } else if (((_attr$value3 = attr.value) === null || _attr$value3 === void 0 ? void 0 : _attr$value3.type) === 'JSXExpressionContainer') {
87
+ var _expression = attr.value.expression;
88
+ if (_expression.type === 'BooleanLiteral') {
89
+ element.isBoldValue = _expression.value;
90
+ } else if (_expression.type === 'Literal' && typeof _expression.value === 'boolean') {
91
+ element.isBoldValue = _expression.value;
92
+ }
93
+ }
94
+ }
95
+ }
96
+ });
97
+
98
+ // Determine if this Lozenge should be migrated
99
+ // Migrate if: appearance="new" OR appearance="discovery" OR (appearance="discovery" AND isBold={true})
100
+ if (element.appearanceValue === 'new' || element.appearanceValue === 'discovery' || element.appearanceValue === 'discovery' && element.isBoldValue === true) {
101
+ element.shouldMigrate = true;
102
+ }
103
+ if (element.shouldMigrate) {
104
+ lozengeElements.push(element);
105
+ }
106
+ }
107
+ });
108
+
109
+ // If no elements to migrate, return early
110
+ if (lozengeElements.length === 0) {
111
+ return file.source;
112
+ }
113
+
114
+ // Check if Tag import exists
115
+ var hasTagImport = source.find(j.ImportDeclaration).some(function (importPath) {
116
+ return importPath.value.source.value === TAG_ENTRY_POINT;
117
+ });
118
+
119
+ // Check if fg is already imported from @atlassian/jira-feature-gating
120
+ var hasFgImport = source.find(j.ImportDeclaration).some(function (importPath) {
121
+ if (importPath.value.source.value === FG_ENTRY_POINT) {
122
+ var _importPath$value$spe2;
123
+ // Check if 'fg' is in the specifiers
124
+ return (_importPath$value$spe2 = importPath.value.specifiers) === null || _importPath$value$spe2 === void 0 ? void 0 : _importPath$value$spe2.some(function (spec) {
125
+ return spec.type === 'ImportSpecifier' && spec.imported.name === 'fg';
126
+ });
127
+ }
128
+ return false;
129
+ });
130
+
131
+ // Add imports after Lozenge import to avoid blank lines
132
+ var lozengeImport = source.find(j.ImportDeclaration).filter(function (path) {
133
+ return path.value.source.value === LOZENGE_ENTRY_POINT;
134
+ }).at(0);
135
+ if (lozengeImport.length > 0) {
136
+ // Add imports in reverse order so they appear in the right order
137
+ if (!hasFgImport) {
138
+ lozengeImport.insertAfter(j.importDeclaration([j.importSpecifier(j.identifier('fg'))], j.stringLiteral(FG_ENTRY_POINT)));
139
+ }
140
+ if (!hasTagImport) {
141
+ lozengeImport.insertAfter(j.importDeclaration([j.importDefaultSpecifier(j.identifier('Tag'))], j.stringLiteral(TAG_ENTRY_POINT)));
142
+ }
143
+ }
144
+
145
+ // Transform each element
146
+ lozengeElements.forEach(function (element) {
147
+ var _openingElement$attri2;
148
+ var path = element.path;
149
+ var openingElement = path.value.openingElement;
150
+
151
+ // Extract text content or JSX expression from children
152
+ var children = path.value.children;
153
+ var textAttribute = null;
154
+ if (children && children.length > 0) {
155
+ // Check if there's a single JSX expression child (e.g., {formatMessage(...)})
156
+ if (children.length === 1 && children[0].type === 'JSXExpressionContainer') {
157
+ var expression = children[0].expression;
158
+ // Use the expression as the text value
159
+ textAttribute = j.jsxAttribute(j.jsxIdentifier('text'), j.jsxExpressionContainer(expression));
160
+ } else {
161
+ // Extract plain text content from JSXText nodes
162
+ var textContent = children.filter(function (child) {
163
+ return child.type === 'JSXText';
164
+ }).map(function (child) {
165
+ return child.value.trim();
166
+ }).filter(function (text) {
167
+ return text.length > 0;
168
+ }).join(' ');
169
+ if (textContent) {
170
+ textAttribute = j.jsxAttribute(j.jsxIdentifier('text'), j.stringLiteral(textContent));
171
+ }
172
+ }
173
+ }
174
+
175
+ // Create the Tag element
176
+ var tagAttributes = [j.jsxAttribute(j.jsxIdentifier('color'), j.stringLiteral('purple'))];
177
+ if (textAttribute) {
178
+ tagAttributes.unshift(textAttribute);
179
+ }
180
+
181
+ // Copy other props from Lozenge to Tag (except appearance and isBold)
182
+ (_openingElement$attri2 = openingElement.attributes) === null || _openingElement$attri2 === void 0 || _openingElement$attri2.forEach(function (attr) {
183
+ var _attr$name2;
184
+ if (attr.type === 'JSXAttribute' && ((_attr$name2 = attr.name) === null || _attr$name2 === void 0 ? void 0 : _attr$name2.type) === 'JSXIdentifier') {
185
+ if (attr.name.name !== 'appearance' && attr.name.name !== 'isBold') {
186
+ tagAttributes.push(attr);
187
+ }
188
+ }
189
+ });
190
+ var tagElement = j.jsxElement(j.jsxOpeningElement(j.jsxIdentifier('Tag'), tagAttributes, true), null, []);
191
+
192
+ // Keep the original Lozenge element (just the element, without wrapping)
193
+ var lozengeElement = path.value;
194
+
195
+ // Create the conditional expression: fg(FEATURE_GATE_NAME) ? <Tag .../> : <Lozenge .../>
196
+ // When feature gate is ON, show Tag (new behavior)
197
+ // When feature gate is OFF, show Lozenge (old behavior)
198
+ var conditionalExpression = j.conditionalExpression(j.callExpression(j.identifier('fg'), [j.stringLiteral(FEATURE_GATE_NAME)]), tagElement, lozengeElement);
199
+
200
+ // Check if the parent is a JSXElement (means we're inside JSX, need curly braces)
201
+ // Otherwise, it's a regular expression (like in a return statement)
202
+ var parent = path.parent;
203
+ var needsJSXWrapper = parent && (parent.value.type === 'JSXElement' || parent.value.type === 'JSXExpressionContainer');
204
+ if (needsJSXWrapper) {
205
+ // Inside JSX, wrap in expression container
206
+ j(path).replaceWith(j.jsxExpressionContainer(conditionalExpression));
207
+ } else {
208
+ // In regular JS context (like return statement), just use the conditional
209
+ j(path).replaceWith(conditionalExpression);
210
+ }
211
+ });
212
+ return source.toSource(PRINT_SETTINGS);
213
+ }
@@ -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 lozengeDiscoveryToTagWithFgTransformer from './codemods/lozenge-discovery-to-tag-with-fg';
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 = [lozengeDiscoveryToTagWithFgTransformer];
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
+ }
@@ -1,4 +1,4 @@
1
- import { legacyLightTokens as legacyLightTheme, light as lightTheme, shape as shapeTheme, spacing as spacingTheme, typographyAdg3 as typographyAdg3Theme } from '@atlaskit/tokens/tokens-raw';
1
+ import { legacyLightTokens as legacyLightTheme, light as lightTheme, shape as shapeTheme, spacing as spacingTheme, typography as typographyTheme } from '@atlaskit/tokens/tokens-raw';
2
2
  var typographyGroups = ['typography', 'fontWeight', 'fontFamily'];
3
3
  function buildCombinedMap() {
4
4
  var combinedMap = {};
@@ -14,7 +14,7 @@ function buildCombinedMap() {
14
14
  }
15
15
 
16
16
  // Filter the typography tokens based on predefined groups and exclusions
17
- var typographyAdg3ThemeFiltered = typographyAdg3Theme.filter(function (token) {
17
+ var typographyThemeFiltered = typographyTheme.filter(function (token) {
18
18
  return typographyGroups.includes(token.attributes.group);
19
19
  }).filter(function (token) {
20
20
  return token.cleanName !== 'font.body.UNSAFE_small';
@@ -32,7 +32,7 @@ export function getTokenMap() {
32
32
  var themeIndex = useLegacyTheme ? 1 : 0;
33
33
  if (!tokenMapCache[themeIndex]) {
34
34
  var selectedTheme = useLegacyTheme ? legacyLightTheme : lightTheme;
35
- tokenMapCache[themeIndex] = buildCombinedMap(selectedTheme, spacingTheme, shapeTheme, typographyAdg3ThemeFiltered);
35
+ tokenMapCache[themeIndex] = buildCombinedMap(selectedTheme, spacingTheme, shapeTheme, typographyThemeFiltered);
36
36
  }
37
37
  return tokenMapCache[themeIndex];
38
38
  }
@@ -12,6 +12,7 @@ import './remove-dark-theme-vr-options/remove-dark-theme-vr-options';
12
12
  import './remove-token-fallbacks/remove-token-fallbacks';
13
13
  import './lozenge-appearance-semantic-migration/lozenge-appearance-semantic-migration';
14
14
  import './lozenge-to-tag-migration/lozenge-to-tag-migration';
15
+ import './lozenge-discovery-to-tag-with-fg/lozenge-discovery-to-tag-with-fg';
15
16
  import './badge-appearance-semantic-migration/badge-appearance-semantic-migration';
16
17
  import './tag-to-newTag-migration/tag-to-newTag-migration';
17
18
  import './migrate-deprecated-icon/migrate-deprecated-icon';
@@ -0,0 +1,12 @@
1
+ import { type API, type FileInfo } from 'jscodeshift';
2
+ /**
3
+ * Codemod to migrate Lozenge components with appearance='new' or 'discovery' to Tag behind feature gate.
4
+ *
5
+ * This codemod:
6
+ * 1. Finds Lozenges with appearance="new" or appearance="discovery"
7
+ * 2. Also includes discovery Lozenges with isBold={true} or isBold
8
+ * 3. Wraps them in a feature gate: fg('platform-dst-lozenge-tag-badge-visual-uplifts')
9
+ * 4. Converts to Tag with color="purple" when feature gate is off
10
+ * 5. Adds necessary imports (Tag, fg)
11
+ */
12
+ export default function transformer(file: FileInfo, api: API): any;
@@ -0,0 +1,2 @@
1
+ import type { API, FileInfo } from 'jscodeshift';
2
+ export default function transformer(file: FileInfo, api: API): Promise<string>;
@@ -12,6 +12,7 @@ import './remove-dark-theme-vr-options/remove-dark-theme-vr-options';
12
12
  import './remove-token-fallbacks/remove-token-fallbacks';
13
13
  import './lozenge-appearance-semantic-migration/lozenge-appearance-semantic-migration';
14
14
  import './lozenge-to-tag-migration/lozenge-to-tag-migration';
15
+ import './lozenge-discovery-to-tag-with-fg/lozenge-discovery-to-tag-with-fg';
15
16
  import './badge-appearance-semantic-migration/badge-appearance-semantic-migration';
16
17
  import './tag-to-newTag-migration/tag-to-newTag-migration';
17
18
  import './migrate-deprecated-icon/migrate-deprecated-icon';
@@ -0,0 +1,12 @@
1
+ import { type API, type FileInfo } from 'jscodeshift';
2
+ /**
3
+ * Codemod to migrate Lozenge components with appearance='new' or 'discovery' to Tag behind feature gate.
4
+ *
5
+ * This codemod:
6
+ * 1. Finds Lozenges with appearance="new" or appearance="discovery"
7
+ * 2. Also includes discovery Lozenges with isBold={true} or isBold
8
+ * 3. Wraps them in a feature gate: fg('platform-dst-lozenge-tag-badge-visual-uplifts')
9
+ * 4. Converts to Tag with color="purple" when feature gate is off
10
+ * 5. Adds necessary imports (Tag, fg)
11
+ */
12
+ export default function transformer(file: FileInfo, api: API): any;
@@ -0,0 +1,2 @@
1
+ import type { API, FileInfo } from 'jscodeshift';
2
+ export default function transformer(file: FileInfo, api: API): Promise<string>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/codemod-cli",
3
- "version": "0.33.2",
3
+ "version": "0.34.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/"
@@ -29,9 +29,9 @@
29
29
  "bin": "./bin/codemod-cli.js",
30
30
  "dependencies": {
31
31
  "@atlaskit/codemod-utils": "^4.2.0",
32
- "@atlaskit/icon": "^29.3.0",
33
- "@atlaskit/icon-lab": "^5.13.0",
34
- "@atlaskit/tokens": "^9.1.0",
32
+ "@atlaskit/icon": "^29.4.0",
33
+ "@atlaskit/icon-lab": "^5.14.0",
34
+ "@atlaskit/tokens": "^10.0.0",
35
35
  "@babel/runtime": "^7.0.0",
36
36
  "@codeshift/utils": "^0.2.4",
37
37
  "@hypermod/utils": "^0.4.2",