@carbon/upgrade 11.22.0 → 11.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.js +155 -1
- package/package.json +2 -2
- package/transforms/__testfixtures__/enable-v12-tile-default-icons.input.js +70 -0
- package/transforms/__testfixtures__/enable-v12-tile-default-icons.input.tsx +72 -0
- package/transforms/__testfixtures__/enable-v12-tile-default-icons.output.js +89 -0
- package/transforms/__testfixtures__/enable-v12-tile-default-icons.output.tsx +67 -0
- package/transforms/__testfixtures__/enable-v12-tile-radio-icons.input.js +87 -0
- package/transforms/__testfixtures__/enable-v12-tile-radio-icons.input.tsx +87 -0
- package/transforms/__testfixtures__/enable-v12-tile-radio-icons.output.js +87 -0
- package/transforms/__testfixtures__/enable-v12-tile-radio-icons.output.tsx +87 -0
- package/transforms/__testfixtures__/slug-prop-to-decorator-prop.input.js +41 -0
- package/transforms/__testfixtures__/slug-prop-to-decorator-prop.input.tsx +41 -0
- package/transforms/__testfixtures__/slug-prop-to-decorator-prop.output.js +41 -0
- package/transforms/__testfixtures__/slug-prop-to-decorator-prop.output.tsx +41 -0
- package/transforms/__tests__/enable-v12-tile-default-icons-test.js +12 -0
- package/transforms/__tests__/enable-v12-tile-radio-icons-test.js +12 -0
- package/transforms/__tests__/slug-prop-to-decorator-prop-test.js +12 -0
- package/transforms/enable-v12-tile-default-icons.js +183 -0
- package/transforms/enable-v12-tile-radio-icons.js +183 -0
- package/transforms/slug-prop-to-decorator-prop.js +47 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2025
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* Migrate RadioTile components by wrapping them with FeatureFlags
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
const defaultOptions = {
|
|
13
|
+
quote: 'single',
|
|
14
|
+
trailingComma: true,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function transform(fileInfo, api, options) {
|
|
18
|
+
const j = api.jscodeshift;
|
|
19
|
+
const root = j(fileInfo.source);
|
|
20
|
+
const printOptions = options.printOptions || defaultOptions;
|
|
21
|
+
|
|
22
|
+
// Early return if no RadioTile components found
|
|
23
|
+
if (
|
|
24
|
+
!root
|
|
25
|
+
.find(j.JSXElement, { openingElement: { name: { name: 'RadioTile' } } })
|
|
26
|
+
.size()
|
|
27
|
+
) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let needsFeatureFlagsImport = false;
|
|
32
|
+
|
|
33
|
+
// First update all existing FeatureFlags wrappers that need the attribute
|
|
34
|
+
root
|
|
35
|
+
.find(j.JSXElement, {
|
|
36
|
+
openingElement: { name: { name: 'FeatureFlags' } },
|
|
37
|
+
})
|
|
38
|
+
.forEach((path) => {
|
|
39
|
+
const hasRadioTileInside =
|
|
40
|
+
j(path)
|
|
41
|
+
.find(j.JSXElement, {
|
|
42
|
+
openingElement: { name: { name: 'RadioTile' } },
|
|
43
|
+
})
|
|
44
|
+
.size() > 0;
|
|
45
|
+
|
|
46
|
+
const hasTileGroupWithRadioTile =
|
|
47
|
+
j(path)
|
|
48
|
+
.find(j.JSXElement, {
|
|
49
|
+
openingElement: { name: { name: 'TileGroup' } },
|
|
50
|
+
})
|
|
51
|
+
.filter((tileGroupPath) => {
|
|
52
|
+
return (
|
|
53
|
+
j(tileGroupPath)
|
|
54
|
+
.find(j.JSXElement, {
|
|
55
|
+
openingElement: { name: { name: 'RadioTile' } },
|
|
56
|
+
})
|
|
57
|
+
.size() > 0
|
|
58
|
+
);
|
|
59
|
+
})
|
|
60
|
+
.size() > 0;
|
|
61
|
+
|
|
62
|
+
if (hasRadioTileInside || hasTileGroupWithRadioTile) {
|
|
63
|
+
const hasAttribute = path.node.openingElement.attributes.some(
|
|
64
|
+
(attr) =>
|
|
65
|
+
attr.type === 'JSXAttribute' &&
|
|
66
|
+
attr.name.name === 'enableV12TileRadioIcons'
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
if (!hasAttribute) {
|
|
70
|
+
path.node.openingElement.attributes.push(
|
|
71
|
+
j.jsxAttribute(j.jsxIdentifier('enableV12TileRadioIcons'))
|
|
72
|
+
);
|
|
73
|
+
needsFeatureFlagsImport = true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Handle RadioTiles within TileGroups
|
|
79
|
+
root
|
|
80
|
+
.find(j.JSXElement, {
|
|
81
|
+
openingElement: { name: { name: 'TileGroup' } },
|
|
82
|
+
})
|
|
83
|
+
.forEach((path) => {
|
|
84
|
+
const hasRadioTile =
|
|
85
|
+
j(path)
|
|
86
|
+
.find(j.JSXElement, {
|
|
87
|
+
openingElement: { name: { name: 'RadioTile' } },
|
|
88
|
+
})
|
|
89
|
+
.size() > 0;
|
|
90
|
+
|
|
91
|
+
const wrappingFeatureFlags = j(path).closest(j.JSXElement, {
|
|
92
|
+
openingElement: { name: { name: 'FeatureFlags' } },
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (hasRadioTile) {
|
|
96
|
+
if (wrappingFeatureFlags.size() === 0) {
|
|
97
|
+
// Not wrapped, add wrapper
|
|
98
|
+
const featureFlagsWrapper = j.jsxElement(
|
|
99
|
+
j.jsxOpeningElement(
|
|
100
|
+
j.jsxIdentifier('FeatureFlags'),
|
|
101
|
+
[j.jsxAttribute(j.jsxIdentifier('enableV12TileRadioIcons'))],
|
|
102
|
+
false
|
|
103
|
+
),
|
|
104
|
+
j.jsxClosingElement(j.jsxIdentifier('FeatureFlags')),
|
|
105
|
+
[path.node]
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
j(path).replaceWith(featureFlagsWrapper);
|
|
109
|
+
needsFeatureFlagsImport = true;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Handle standalone RadioTiles
|
|
115
|
+
root
|
|
116
|
+
.find(j.JSXElement, {
|
|
117
|
+
openingElement: { name: { name: 'RadioTile' } },
|
|
118
|
+
})
|
|
119
|
+
.forEach((path) => {
|
|
120
|
+
const isInsideTileGroup =
|
|
121
|
+
j(path)
|
|
122
|
+
.closest(j.JSXElement, {
|
|
123
|
+
openingElement: { name: { name: 'TileGroup' } },
|
|
124
|
+
})
|
|
125
|
+
.size() > 0;
|
|
126
|
+
|
|
127
|
+
const wrappingFeatureFlags = j(path).closest(j.JSXElement, {
|
|
128
|
+
openingElement: { name: { name: 'FeatureFlags' } },
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
if (!isInsideTileGroup) {
|
|
132
|
+
if (wrappingFeatureFlags.size() === 0) {
|
|
133
|
+
// Not wrapped, add wrapper
|
|
134
|
+
const featureFlagsWrapper = j.jsxElement(
|
|
135
|
+
j.jsxOpeningElement(
|
|
136
|
+
j.jsxIdentifier('FeatureFlags'),
|
|
137
|
+
[j.jsxAttribute(j.jsxIdentifier('enableV12TileRadioIcons'))],
|
|
138
|
+
false
|
|
139
|
+
),
|
|
140
|
+
j.jsxClosingElement(j.jsxIdentifier('FeatureFlags')),
|
|
141
|
+
[path.node]
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
j(path).replaceWith(featureFlagsWrapper);
|
|
145
|
+
needsFeatureFlagsImport = true;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// Add FeatureFlags import only if we've added wrappers or attributes
|
|
151
|
+
if (needsFeatureFlagsImport) {
|
|
152
|
+
const hasFeatureFlagsImport =
|
|
153
|
+
root
|
|
154
|
+
.find(j.ImportDeclaration, {
|
|
155
|
+
source: { value: '@carbon/feature-flags' },
|
|
156
|
+
})
|
|
157
|
+
.size() > 0;
|
|
158
|
+
|
|
159
|
+
if (!hasFeatureFlagsImport) {
|
|
160
|
+
// Find the last import declaration
|
|
161
|
+
const lastImport = root.find(j.ImportDeclaration).at(-1);
|
|
162
|
+
const featureFlagsImport = j.importDeclaration(
|
|
163
|
+
[j.importSpecifier(j.identifier('FeatureFlags'))],
|
|
164
|
+
j.literal('@carbon/feature-flags')
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
if (lastImport.size() > 0) {
|
|
168
|
+
// Add newline after the last import
|
|
169
|
+
const newline = j.template.statement`\n`;
|
|
170
|
+
lastImport.insertAfter(newline);
|
|
171
|
+
lastImport.insertAfter(featureFlagsImport);
|
|
172
|
+
} else {
|
|
173
|
+
// If no imports exist, add at the beginning of the file
|
|
174
|
+
root.get().node.program.body.unshift(featureFlagsImport);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return root.toSource(printOptions);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
module.exports = transform;
|
|
183
|
+
module.exports.parser = 'tsx';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2025
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* Replace slug prop with decorator
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
const defaultOptions = {
|
|
13
|
+
quote: 'single',
|
|
14
|
+
trailingComma: true,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function transform(fileInfo, api, options) {
|
|
18
|
+
const j = api.jscodeshift;
|
|
19
|
+
const root = j(fileInfo.source);
|
|
20
|
+
const printOptions = options.printOptions || defaultOptions;
|
|
21
|
+
|
|
22
|
+
// Early return if no JSX elements with slug prop found
|
|
23
|
+
if (!root.find(j.JSXAttribute, { name: { name: 'slug' } }).size()) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Replace slug with decorator
|
|
28
|
+
root
|
|
29
|
+
.find(j.JSXAttribute, {
|
|
30
|
+
name: { name: 'slug' },
|
|
31
|
+
})
|
|
32
|
+
.forEach((path) => {
|
|
33
|
+
// Create new decorator attribute with same value as slug
|
|
34
|
+
const newAttribute = j.jsxAttribute(
|
|
35
|
+
j.jsxIdentifier('decorator'),
|
|
36
|
+
path.node.value
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
// Replace the slug attribute with decorator
|
|
40
|
+
j(path).replaceWith(newAttribute);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
return root.toSource(printOptions);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = transform;
|
|
47
|
+
module.exports.parser = 'tsx';
|