@carbon/upgrade 11.20.0-rc.0 → 11.21.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 +59 -1
- package/package.json +2 -2
- package/transforms/__testfixtures__/ibm-products-update-userprofileimage.input.js +48 -0
- package/transforms/__testfixtures__/ibm-products-update-userprofileimage.output.js +41 -0
- package/transforms/__testfixtures__/refactor-light-to-layer.input.js +14 -0
- package/transforms/__testfixtures__/refactor-light-to-layer.output.js +14 -0
- package/transforms/__tests__/ibm-products-update-userprofileimage-test.js +12 -0
- package/transforms/__tests__/refactor-light-to-layer-test.js +5 -0
- package/transforms/ibm-products-update-userprofileimage.js +125 -0
- package/transforms/refactor-light-to-layer.js +108 -0
package/cli.js
CHANGED
|
@@ -52641,6 +52641,38 @@ var upgrades = [
|
|
|
52641
52641
|
});
|
|
52642
52642
|
}
|
|
52643
52643
|
},
|
|
52644
|
+
{
|
|
52645
|
+
name: "refactor-light-to-layer",
|
|
52646
|
+
description: `
|
|
52647
|
+
Refactor 'light' prop usage to instead wrap components with Layer
|
|
52648
|
+
Transforms:
|
|
52649
|
+
<Button light>Click me</Button>
|
|
52650
|
+
Into:
|
|
52651
|
+
<Layer><Button>Click me</Button></Layer>
|
|
52652
|
+
`,
|
|
52653
|
+
migrate: async (options) => {
|
|
52654
|
+
const transform = import_path2.default.join(
|
|
52655
|
+
TRANSFORM_DIR,
|
|
52656
|
+
"refactor-light-to-layer.js"
|
|
52657
|
+
);
|
|
52658
|
+
const paths = Array.isArray(options.paths) && options.paths.length > 0 ? options.paths : await (0, import_fast_glob2.default)(["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"], {
|
|
52659
|
+
cwd: options.workspaceDir,
|
|
52660
|
+
ignore: [
|
|
52661
|
+
"**/es/**",
|
|
52662
|
+
"**/lib/**",
|
|
52663
|
+
"**/umd/**",
|
|
52664
|
+
"**/node_modules/**",
|
|
52665
|
+
"**/storybook-static/**"
|
|
52666
|
+
]
|
|
52667
|
+
});
|
|
52668
|
+
await run2({
|
|
52669
|
+
dry: !options.write,
|
|
52670
|
+
transform,
|
|
52671
|
+
paths,
|
|
52672
|
+
verbose: options.verbose
|
|
52673
|
+
});
|
|
52674
|
+
}
|
|
52675
|
+
},
|
|
52644
52676
|
{
|
|
52645
52677
|
name: "refactor-to-callout",
|
|
52646
52678
|
description: "Rewrites imports and usages of StaticNotification to Callout",
|
|
@@ -52663,6 +52695,32 @@ var upgrades = [
|
|
|
52663
52695
|
verbose: options.verbose
|
|
52664
52696
|
});
|
|
52665
52697
|
}
|
|
52698
|
+
},
|
|
52699
|
+
{
|
|
52700
|
+
name: "ibm-products-update-userprofileimage",
|
|
52701
|
+
description: "Rewrites UserProfileImage to UserAvatar",
|
|
52702
|
+
migrate: async (options) => {
|
|
52703
|
+
const transform = import_path2.default.join(
|
|
52704
|
+
TRANSFORM_DIR,
|
|
52705
|
+
"ibm-products-update-userprofileimage.js"
|
|
52706
|
+
);
|
|
52707
|
+
const paths = Array.isArray(options.paths) && options.paths.length > 0 ? options.paths : await (0, import_fast_glob2.default)(["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"], {
|
|
52708
|
+
cwd: options.workspaceDir,
|
|
52709
|
+
ignore: [
|
|
52710
|
+
"**/es/**",
|
|
52711
|
+
"**/lib/**",
|
|
52712
|
+
"**/umd/**",
|
|
52713
|
+
"**/node_modules/**",
|
|
52714
|
+
"**/storybook-static/**"
|
|
52715
|
+
]
|
|
52716
|
+
});
|
|
52717
|
+
await run2({
|
|
52718
|
+
dry: !options.write,
|
|
52719
|
+
transform,
|
|
52720
|
+
paths,
|
|
52721
|
+
verbose: options.verbose
|
|
52722
|
+
});
|
|
52723
|
+
}
|
|
52666
52724
|
}
|
|
52667
52725
|
]
|
|
52668
52726
|
},
|
|
@@ -52691,7 +52749,7 @@ var upgrades = [
|
|
|
52691
52749
|
var package_default = {
|
|
52692
52750
|
name: "@carbon/upgrade",
|
|
52693
52751
|
description: "A tool for upgrading Carbon versions",
|
|
52694
|
-
version: "11.
|
|
52752
|
+
version: "11.21.0",
|
|
52695
52753
|
license: "Apache-2.0",
|
|
52696
52754
|
bin: {
|
|
52697
52755
|
"carbon-upgrade": "./bin/carbon-upgrade.js"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carbon/upgrade",
|
|
3
3
|
"description": "A tool for upgrading Carbon versions",
|
|
4
|
-
"version": "11.
|
|
4
|
+
"version": "11.21.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"bin": {
|
|
7
7
|
"carbon-upgrade": "./bin/carbon-upgrade.js"
|
|
@@ -61,5 +61,5 @@
|
|
|
61
61
|
"@ibm/telemetry-js": "^1.5.0",
|
|
62
62
|
"jscodeshift": "^17.0.0"
|
|
63
63
|
},
|
|
64
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "ab3eba8531c341d5ee5d956b962d7cce04944ac3"
|
|
65
65
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { UserProfileImage } from '@carbon/ibm-products';
|
|
3
|
+
import { Add } from '@carbon/react/icons';
|
|
4
|
+
|
|
5
|
+
const ImageUrl =
|
|
6
|
+
'https://img.freepik.com/free-photo/portrait-man-cartoon-style_23-2151133939.jpg?semt=ais_hybrid';
|
|
7
|
+
|
|
8
|
+
export const Example = () => (
|
|
9
|
+
<>
|
|
10
|
+
<UserProfileImage
|
|
11
|
+
size="md"
|
|
12
|
+
tooltipAlignment="bottom"
|
|
13
|
+
backgroundColor="light-purple"
|
|
14
|
+
theme="light"
|
|
15
|
+
tooltipText="Thomas Watson"
|
|
16
|
+
className="myClass"
|
|
17
|
+
initials="thomas j. watson"
|
|
18
|
+
/>
|
|
19
|
+
<UserProfileImage
|
|
20
|
+
size="md"
|
|
21
|
+
tooltipAlignment="bottom"
|
|
22
|
+
backgroundColor="light-purple"
|
|
23
|
+
theme="light"
|
|
24
|
+
tooltipText="Thomas Watson"
|
|
25
|
+
className="myClass"
|
|
26
|
+
kind="user"
|
|
27
|
+
/>
|
|
28
|
+
<UserProfileImage
|
|
29
|
+
size="md"
|
|
30
|
+
tooltipAlignment="bottom"
|
|
31
|
+
backgroundColor="light-purple"
|
|
32
|
+
theme="light"
|
|
33
|
+
tooltipText="Thomas Watson"
|
|
34
|
+
className="myClass"
|
|
35
|
+
icon={() => <Add size={20} />}
|
|
36
|
+
/>
|
|
37
|
+
<UserProfileImage
|
|
38
|
+
size="md"
|
|
39
|
+
tooltipAlignment="bottom"
|
|
40
|
+
backgroundColor="light-purple"
|
|
41
|
+
theme="light"
|
|
42
|
+
tooltipText="Thomas Watson"
|
|
43
|
+
className="myClass"
|
|
44
|
+
image={ImageUrl}
|
|
45
|
+
imageDescription="Avatar of Thomas Watson"
|
|
46
|
+
/>
|
|
47
|
+
</>
|
|
48
|
+
);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { User } from "@carbon/react/icons";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { UserAvatar } from '@carbon/ibm-products';
|
|
4
|
+
import { Add } from '@carbon/react/icons';
|
|
5
|
+
|
|
6
|
+
const ImageUrl =
|
|
7
|
+
'https://img.freepik.com/free-photo/portrait-man-cartoon-style_23-2151133939.jpg?semt=ais_hybrid';
|
|
8
|
+
|
|
9
|
+
export const Example = () => (
|
|
10
|
+
<>
|
|
11
|
+
<UserAvatar
|
|
12
|
+
size="md"
|
|
13
|
+
tooltipAlignment="bottom"
|
|
14
|
+
backgroundColor="order-5-purple"
|
|
15
|
+
tooltipText="Thomas Watson"
|
|
16
|
+
className="myClass"
|
|
17
|
+
name="thomas j. watson" />
|
|
18
|
+
<UserAvatar
|
|
19
|
+
size="md"
|
|
20
|
+
tooltipAlignment="bottom"
|
|
21
|
+
backgroundColor="order-5-purple"
|
|
22
|
+
tooltipText="Thomas Watson"
|
|
23
|
+
className="myClass"
|
|
24
|
+
renderIcon={User} />
|
|
25
|
+
<UserAvatar
|
|
26
|
+
size="md"
|
|
27
|
+
tooltipAlignment="bottom"
|
|
28
|
+
backgroundColor="order-5-purple"
|
|
29
|
+
tooltipText="Thomas Watson"
|
|
30
|
+
className="myClass"
|
|
31
|
+
renderIcon={() => <Add size={20} />} />
|
|
32
|
+
<UserAvatar
|
|
33
|
+
size="md"
|
|
34
|
+
tooltipAlignment="bottom"
|
|
35
|
+
backgroundColor="order-5-purple"
|
|
36
|
+
tooltipText="Thomas Watson"
|
|
37
|
+
className="myClass"
|
|
38
|
+
image={ImageUrl}
|
|
39
|
+
imageDescription="Avatar of Thomas Watson" />
|
|
40
|
+
</>
|
|
41
|
+
);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Button, Layer } from '@carbon/react';
|
|
3
|
+
|
|
4
|
+
function TestComponent() {
|
|
5
|
+
<div>
|
|
6
|
+
<Button light>Click me</Button>
|
|
7
|
+
<Button>Another button</Button>
|
|
8
|
+
<Layer>
|
|
9
|
+
<Button light>Nested light button</Button>
|
|
10
|
+
</Layer>
|
|
11
|
+
</div>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default TestComponent;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Button, Layer } from '@carbon/react';
|
|
3
|
+
|
|
4
|
+
function TestComponent() {
|
|
5
|
+
<div>
|
|
6
|
+
<Layer><Button>Click me</Button></Layer>
|
|
7
|
+
<Button>Another button</Button>
|
|
8
|
+
<Layer>
|
|
9
|
+
<Layer><Button>Nested light button</Button></Layer>
|
|
10
|
+
</Layer>
|
|
11
|
+
</div>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default TestComponent;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2021, 2024
|
|
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
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
const { defineTest } = require('jscodeshift/dist/testUtils');
|
|
11
|
+
|
|
12
|
+
defineTest(__dirname, 'ibm-products-update-userprofileimage');
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2021, 2024
|
|
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
|
+
* Rewrites UserProfileImage to UserAvatar
|
|
8
|
+
*
|
|
9
|
+
* Transforms:
|
|
10
|
+
*
|
|
11
|
+
* <UserProfileImage />
|
|
12
|
+
*
|
|
13
|
+
* Into:
|
|
14
|
+
*
|
|
15
|
+
* <UserAvatar />
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
'use strict';
|
|
19
|
+
|
|
20
|
+
const transform = (fileInfo, api) => {
|
|
21
|
+
const j = api.jscodeshift;
|
|
22
|
+
const root = j(fileInfo.source);
|
|
23
|
+
let shouldImportUser = false;
|
|
24
|
+
let shouldImportGroup = false;
|
|
25
|
+
|
|
26
|
+
const ensureImport = (identifierName) => {
|
|
27
|
+
const importDeclaration = j.importDeclaration(
|
|
28
|
+
[j.importSpecifier(j.identifier(identifierName))],
|
|
29
|
+
j.literal('@carbon/react/icons')
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const existingImport = root
|
|
33
|
+
.find(j.ImportDeclaration, {
|
|
34
|
+
source: { value: '@carbon/react/icons' },
|
|
35
|
+
})
|
|
36
|
+
.filter((path) => {
|
|
37
|
+
return path.node.specifiers.some(
|
|
38
|
+
(specifier) => specifier.imported.name === identifierName
|
|
39
|
+
);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
if (existingImport.size() === 0) {
|
|
43
|
+
root.find(j.Program).get('body', 0).insertBefore(importDeclaration);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
// Transform UserProfileImage to UserAvatar
|
|
47
|
+
root
|
|
48
|
+
.find(j.JSXElement, {
|
|
49
|
+
openingElement: { name: { name: 'UserProfileImage' } },
|
|
50
|
+
})
|
|
51
|
+
.forEach((path) => {
|
|
52
|
+
// Change the component name
|
|
53
|
+
path.node.openingElement.name.name = 'UserAvatar';
|
|
54
|
+
if (path.node.closingElement) {
|
|
55
|
+
path.node.closingElement.name.name = 'UserAvatar';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const colorMapping = {
|
|
59
|
+
'light-cyan': 'order-1-cyan',
|
|
60
|
+
'dark-cyan': 'order-7-cyan',
|
|
61
|
+
'light-gray': 'order-2-gray',
|
|
62
|
+
'dark-gray': 'order-8-gray',
|
|
63
|
+
'light-green': 'order-3-green',
|
|
64
|
+
'dark-green': 'order-9-green',
|
|
65
|
+
'light-magenta': 'order-10-magenta',
|
|
66
|
+
'dark-magenta': 'order-10-magenta',
|
|
67
|
+
'light-purple': 'order-5-purple',
|
|
68
|
+
'dark-purple': 'order-11-purple',
|
|
69
|
+
'light-teal': 'order-6-teal',
|
|
70
|
+
'dark-teal': 'order-12-teal',
|
|
71
|
+
};
|
|
72
|
+
const updatedAttributes = [];
|
|
73
|
+
// Update attributes
|
|
74
|
+
path.node.openingElement.attributes.forEach((attr) => {
|
|
75
|
+
if (attr.name.name === 'backgroundColor') {
|
|
76
|
+
if (colorMapping[attr.value.value]) {
|
|
77
|
+
attr.value.value = colorMapping[attr.value.value];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (attr.name.name === 'theme') {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (attr.name.name === 'initials') {
|
|
84
|
+
attr.name.name = 'name';
|
|
85
|
+
}
|
|
86
|
+
if (attr.name.name === 'kind' || attr.name.name === 'icon') {
|
|
87
|
+
const originalName = attr.name.name;
|
|
88
|
+
attr.name.name = 'renderIcon';
|
|
89
|
+
if (originalName === 'kind') {
|
|
90
|
+
if (attr.value.value === 'user') {
|
|
91
|
+
attr.value = j.jsxExpressionContainer(j.identifier('User'));
|
|
92
|
+
shouldImportUser = true;
|
|
93
|
+
} else if (attr.value.value === 'group') {
|
|
94
|
+
attr.value = j.jsxExpressionContainer(j.identifier('Group'));
|
|
95
|
+
shouldImportGroup = true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
updatedAttributes.push(attr);
|
|
100
|
+
});
|
|
101
|
+
path.node.openingElement.attributes = updatedAttributes;
|
|
102
|
+
});
|
|
103
|
+
// Update import statement
|
|
104
|
+
root
|
|
105
|
+
.find(j.ImportDeclaration)
|
|
106
|
+
.filter((path) => path.node.source.value === '@carbon/ibm-products')
|
|
107
|
+
.forEach((path) => {
|
|
108
|
+
path.node.specifiers.forEach((specifier) => {
|
|
109
|
+
if (specifier.imported.name === 'UserProfileImage') {
|
|
110
|
+
specifier.imported.name = 'UserAvatar';
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
if (shouldImportUser) {
|
|
116
|
+
ensureImport('User');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (shouldImportGroup) {
|
|
120
|
+
ensureImport('Group');
|
|
121
|
+
}
|
|
122
|
+
return root.toSource();
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
module.exports = transform;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2024
|
|
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
|
+
* Deprecate the `light` prop and wrap components with `Layer`
|
|
8
|
+
*
|
|
9
|
+
* Transforms:
|
|
10
|
+
*
|
|
11
|
+
* <Button light>Click me</Button>
|
|
12
|
+
*
|
|
13
|
+
* Into:
|
|
14
|
+
*
|
|
15
|
+
* <Layer>
|
|
16
|
+
* <Button>Click me</Button>
|
|
17
|
+
* </Layer>
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
'use strict';
|
|
21
|
+
|
|
22
|
+
const defaultOptions = {
|
|
23
|
+
quote: 'single',
|
|
24
|
+
trailingComma: true,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
function transform(fileInfo, api, options) {
|
|
28
|
+
const { jscodeshift: j } = api;
|
|
29
|
+
const root = j(fileInfo.source);
|
|
30
|
+
const printOptions = options.printOptions || defaultOptions;
|
|
31
|
+
|
|
32
|
+
// Check if there are any components with the 'light' prop
|
|
33
|
+
const hasLightProp =
|
|
34
|
+
root.find(j.JSXAttribute, { name: { name: 'light' } }).size() > 0;
|
|
35
|
+
|
|
36
|
+
if (!hasLightProp) {
|
|
37
|
+
return null; // if no 'light' prop found, don't modify & return the file
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Import Layer component if not already imported
|
|
41
|
+
const layerImport = root.find(j.ImportDeclaration, {
|
|
42
|
+
source: { value: '@carbon/react' },
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
if (layerImport.length) {
|
|
46
|
+
const specifiers = layerImport.get('specifiers');
|
|
47
|
+
const hasLayerImport = specifiers.value.some(
|
|
48
|
+
(specifier) => specifier.imported && specifier.imported.name === 'Layer'
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
if (!hasLayerImport) {
|
|
52
|
+
specifiers.value.push(j.importSpecifier(j.identifier('Layer')));
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
const newImport = j.importDeclaration(
|
|
56
|
+
[j.importSpecifier(j.identifier('Layer'))],
|
|
57
|
+
j.literal('@carbon/react')
|
|
58
|
+
);
|
|
59
|
+
// Find the first import declaration
|
|
60
|
+
const firstImport = root.find(j.ImportDeclaration).at(0);
|
|
61
|
+
|
|
62
|
+
if (firstImport.length) {
|
|
63
|
+
// Insert the new import before the first existing import
|
|
64
|
+
firstImport.insertAfter(newImport);
|
|
65
|
+
} else {
|
|
66
|
+
// If no imports, find the first non-comment node
|
|
67
|
+
const firstNonCommentNode = root
|
|
68
|
+
.find(j.Program)
|
|
69
|
+
.get('body')
|
|
70
|
+
.filter(
|
|
71
|
+
(path) =>
|
|
72
|
+
path.value.type !== 'CommentBlock' &&
|
|
73
|
+
path.value.type !== 'CommentLine'
|
|
74
|
+
)[0];
|
|
75
|
+
|
|
76
|
+
// Insert the new import before the first non-comment node
|
|
77
|
+
j(firstNonCommentNode).insertBefore(newImport);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Find all JSX elements with a 'light' prop
|
|
82
|
+
root.find(j.JSXElement).forEach((path) => {
|
|
83
|
+
const lightProp = path.node.openingElement.attributes.find(
|
|
84
|
+
(attr) => attr.type === 'JSXAttribute' && attr.name.name === 'light'
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
if (lightProp) {
|
|
88
|
+
// Remove the 'light' prop
|
|
89
|
+
path.node.openingElement.attributes =
|
|
90
|
+
path.node.openingElement.attributes.filter(
|
|
91
|
+
(attr) => attr !== lightProp
|
|
92
|
+
);
|
|
93
|
+
// Wrap the component with Layer
|
|
94
|
+
const layerElement = j.jsxElement(
|
|
95
|
+
j.jsxOpeningElement(j.jsxIdentifier('Layer'), []),
|
|
96
|
+
j.jsxClosingElement(j.jsxIdentifier('Layer')),
|
|
97
|
+
[path.node]
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
// Replace the original element with the wrapped version
|
|
101
|
+
j(path).replaceWith(layerElement);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return root.toSource(printOptions);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
module.exports = transform;
|