@carbon/upgrade 11.20.0 → 11.22.0-rc.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 CHANGED
@@ -40483,9 +40483,9 @@ var require_braces = __commonJS({
40483
40483
  }
40484
40484
  });
40485
40485
 
40486
- // ../../node_modules/micromatch/node_modules/picomatch/lib/constants.js
40486
+ // ../../node_modules/picomatch/lib/constants.js
40487
40487
  var require_constants3 = __commonJS({
40488
- "../../node_modules/micromatch/node_modules/picomatch/lib/constants.js"(exports2, module2) {
40488
+ "../../node_modules/picomatch/lib/constants.js"(exports2, module2) {
40489
40489
  "use strict";
40490
40490
  var path3 = require("path");
40491
40491
  var WIN_SLASH = "\\\\/";
@@ -40680,9 +40680,9 @@ var require_constants3 = __commonJS({
40680
40680
  }
40681
40681
  });
40682
40682
 
40683
- // ../../node_modules/micromatch/node_modules/picomatch/lib/utils.js
40683
+ // ../../node_modules/picomatch/lib/utils.js
40684
40684
  var require_utils5 = __commonJS({
40685
- "../../node_modules/micromatch/node_modules/picomatch/lib/utils.js"(exports2) {
40685
+ "../../node_modules/picomatch/lib/utils.js"(exports2) {
40686
40686
  "use strict";
40687
40687
  var path3 = require("path");
40688
40688
  var win32 = process.platform === "win32";
@@ -40741,9 +40741,9 @@ var require_utils5 = __commonJS({
40741
40741
  }
40742
40742
  });
40743
40743
 
40744
- // ../../node_modules/micromatch/node_modules/picomatch/lib/scan.js
40744
+ // ../../node_modules/picomatch/lib/scan.js
40745
40745
  var require_scan2 = __commonJS({
40746
- "../../node_modules/micromatch/node_modules/picomatch/lib/scan.js"(exports2, module2) {
40746
+ "../../node_modules/picomatch/lib/scan.js"(exports2, module2) {
40747
40747
  "use strict";
40748
40748
  var utils = require_utils5();
40749
40749
  var {
@@ -41071,9 +41071,9 @@ var require_scan2 = __commonJS({
41071
41071
  }
41072
41072
  });
41073
41073
 
41074
- // ../../node_modules/micromatch/node_modules/picomatch/lib/parse.js
41074
+ // ../../node_modules/picomatch/lib/parse.js
41075
41075
  var require_parse4 = __commonJS({
41076
- "../../node_modules/micromatch/node_modules/picomatch/lib/parse.js"(exports2, module2) {
41076
+ "../../node_modules/picomatch/lib/parse.js"(exports2, module2) {
41077
41077
  "use strict";
41078
41078
  var constants = require_constants3();
41079
41079
  var utils = require_utils5();
@@ -41844,9 +41844,9 @@ var require_parse4 = __commonJS({
41844
41844
  }
41845
41845
  });
41846
41846
 
41847
- // ../../node_modules/micromatch/node_modules/picomatch/lib/picomatch.js
41847
+ // ../../node_modules/picomatch/lib/picomatch.js
41848
41848
  var require_picomatch = __commonJS({
41849
- "../../node_modules/micromatch/node_modules/picomatch/lib/picomatch.js"(exports2, module2) {
41849
+ "../../node_modules/picomatch/lib/picomatch.js"(exports2, module2) {
41850
41850
  "use strict";
41851
41851
  var path3 = require("path");
41852
41852
  var scan = require_scan2();
@@ -41985,9 +41985,9 @@ var require_picomatch = __commonJS({
41985
41985
  }
41986
41986
  });
41987
41987
 
41988
- // ../../node_modules/micromatch/node_modules/picomatch/index.js
41988
+ // ../../node_modules/picomatch/index.js
41989
41989
  var require_picomatch2 = __commonJS({
41990
- "../../node_modules/micromatch/node_modules/picomatch/index.js"(exports2, module2) {
41990
+ "../../node_modules/picomatch/index.js"(exports2, module2) {
41991
41991
  "use strict";
41992
41992
  module2.exports = require_picomatch();
41993
41993
  }
@@ -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,58 @@ var upgrades = [
52663
52695
  verbose: options.verbose
52664
52696
  });
52665
52697
  }
52698
+ },
52699
+ {
52700
+ name: "ibm-products-update-http-errors",
52701
+ description: "Rewrites HttpError403, HttpError404, HttpErrorOther to FullPageError",
52702
+ migrate: async (options) => {
52703
+ const transform = import_path2.default.join(
52704
+ TRANSFORM_DIR,
52705
+ "ibm-products-update-http-errors.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
+ }
52724
+ },
52725
+ {
52726
+ name: "ibm-products-update-userprofileimage",
52727
+ description: "Rewrites UserProfileImage to UserAvatar",
52728
+ migrate: async (options) => {
52729
+ const transform = import_path2.default.join(
52730
+ TRANSFORM_DIR,
52731
+ "ibm-products-update-userprofileimage.js"
52732
+ );
52733
+ const paths = Array.isArray(options.paths) && options.paths.length > 0 ? options.paths : await (0, import_fast_glob2.default)(["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"], {
52734
+ cwd: options.workspaceDir,
52735
+ ignore: [
52736
+ "**/es/**",
52737
+ "**/lib/**",
52738
+ "**/umd/**",
52739
+ "**/node_modules/**",
52740
+ "**/storybook-static/**"
52741
+ ]
52742
+ });
52743
+ await run2({
52744
+ dry: !options.write,
52745
+ transform,
52746
+ paths,
52747
+ verbose: options.verbose
52748
+ });
52749
+ }
52666
52750
  }
52667
52751
  ]
52668
52752
  },
@@ -52691,7 +52775,7 @@ var upgrades = [
52691
52775
  var package_default = {
52692
52776
  name: "@carbon/upgrade",
52693
52777
  description: "A tool for upgrading Carbon versions",
52694
- version: "11.20.0",
52778
+ version: "11.22.0-rc.0",
52695
52779
  license: "Apache-2.0",
52696
52780
  bin: {
52697
52781
  "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.20.0",
4
+ "version": "11.22.0-rc.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": "3141442e5ef367667c8f1d379a1b4a23f67992ad"
64
+ "gitHead": "7b6d921583ff275baace5baa66da9d9b31740fa8"
65
65
  }
@@ -0,0 +1,82 @@
1
+ import React from 'react';
2
+ import {
3
+ HTTPError403,
4
+ HTTPError404,
5
+ HTTPErrorOther,
6
+ } from '@carbon/ibm-products';
7
+ import './_example.scss';
8
+
9
+ export const Example = () => (
10
+ <>
11
+ <HTTPError403
12
+ description="You are not authorized to access this resource."
13
+ errorCodeLabel="Error 403"
14
+ links={[
15
+ {
16
+ href: 'https://www.carbondesignsystem.com',
17
+ text: 'Carbon Design System',
18
+ },
19
+ {
20
+ href: 'https://github.com/carbon-design-system/ibm-products',
21
+ text: 'Carbon for IBM Products component library',
22
+ },
23
+ {
24
+ href: 'https://github.com/carbon-design-system/ibm-products',
25
+ text: 'Carbon for IBM Products component library',
26
+ },
27
+ {
28
+ href: 'https://github.com/carbon-design-system/ibm-products',
29
+ text: 'Carbon for IBM Products component library',
30
+ },
31
+ {
32
+ href: 'https://github.com/carbon-design-system/ibm-products',
33
+ text: 'Carbon for IBM Products component library',
34
+ },
35
+ ]}
36
+ title="Forbidden"
37
+ />
38
+ <HTTPError404
39
+ description="The page you are looking for was not found."
40
+ errorCodeLabel="Error 404"
41
+ links={[
42
+ {
43
+ href: 'https://www.carbondesignsystem.com',
44
+ text: 'Carbon Design System',
45
+ },
46
+ {
47
+ href: 'https://github.com/carbon-design-system/ibm-products',
48
+ text: 'Carbon for IBM Products component library',
49
+ },
50
+ ]}
51
+ title="Page not found"
52
+ />
53
+ <HTTPErrorOther
54
+ description="Received an invalid response."
55
+ errorCodeLabel="Error 502"
56
+ links={[
57
+ {
58
+ href: 'https://www.carbondesignsystem.com',
59
+ text: 'Carbon Design System',
60
+ },
61
+ {
62
+ href: 'https://github.com/carbon-design-system/ibm-products',
63
+ text: 'Carbon for IBM Products component library',
64
+ },
65
+ ]}
66
+ title="Bad gateway"
67
+ />
68
+ <MyComponent
69
+ errorCodeLabel="error"
70
+ links={[
71
+ {
72
+ href: 'https://www.carbondesignsystem.com',
73
+ text: 'Carbon Design System',
74
+ },
75
+ {
76
+ href: 'https://github.com/carbon-design-system/ibm-products',
77
+ text: 'Carbon for IBM Products component library',
78
+ },
79
+ ]}
80
+ />
81
+ </>
82
+ );
@@ -0,0 +1,40 @@
1
+ import { Link } from "@carbon/react";
2
+ import React from 'react';
3
+ import { FullPageError } from '@carbon/ibm-products';
4
+ import './_example.scss';
5
+
6
+ export const Example = () => (
7
+ <>
8
+ <FullPageError
9
+ description="You are not authorized to access this resource."
10
+ label="Error 403"
11
+ children={<><Link href={"https://www.carbondesignsystem.com"}>Carbon Design System</Link><br /><Link href={"https://github.com/carbon-design-system/ibm-products"}>Carbon for IBM Products component library</Link><br /><Link href={"https://github.com/carbon-design-system/ibm-products"}>Carbon for IBM Products component library</Link><br /><Link href={"https://github.com/carbon-design-system/ibm-products"}>Carbon for IBM Products component library</Link><br /><Link href={"https://github.com/carbon-design-system/ibm-products"}>Carbon for IBM Products component library</Link></>}
12
+ title="Forbidden"
13
+ kind="403" />
14
+ <FullPageError
15
+ description="The page you are looking for was not found."
16
+ label="Error 404"
17
+ children={<><Link href={"https://www.carbondesignsystem.com"}>Carbon Design System</Link><br /><Link href={"https://github.com/carbon-design-system/ibm-products"}>Carbon for IBM Products component library</Link></>}
18
+ title="Page not found"
19
+ kind="404" />
20
+ <FullPageError
21
+ description="Received an invalid response."
22
+ label="Error 502"
23
+ children={<><Link href={"https://www.carbondesignsystem.com"}>Carbon Design System</Link><br /><Link href={"https://github.com/carbon-design-system/ibm-products"}>Carbon for IBM Products component library</Link></>}
24
+ title="Bad gateway"
25
+ kind="custom" />
26
+ <MyComponent
27
+ errorCodeLabel="error"
28
+ links={[
29
+ {
30
+ href: 'https://www.carbondesignsystem.com',
31
+ text: 'Carbon Design System',
32
+ },
33
+ {
34
+ href: 'https://github.com/carbon-design-system/ibm-products',
35
+ text: 'Carbon for IBM Products component library',
36
+ },
37
+ ]}
38
+ />
39
+ </>
40
+ );
@@ -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-http-errors');
@@ -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,5 @@
1
+ 'use strict';
2
+
3
+ const { defineTest } = require('jscodeshift/dist/testUtils');
4
+
5
+ defineTest(__dirname, 'refactor-light-to-layer');
@@ -0,0 +1,192 @@
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 HttpError403, HttpError404, HttpErrorOther to FullPageError
8
+ *
9
+ * Transforms:
10
+ *
11
+ * <HttpError403 />, <HttpError404 />, <HttpErrorOther />
12
+ *
13
+ * Into:
14
+ *
15
+ * <FullPageError />
16
+ */
17
+
18
+ 'use strict';
19
+
20
+ const transform = (file, api) => {
21
+ const j = api.jscodeshift;
22
+ const root = j(file.source);
23
+ let dirtyFlag = false;
24
+
25
+ const componentKindMap = {
26
+ HTTPError403: '403',
27
+ HTTPError404: '404',
28
+ HTTPErrorOther: 'custom',
29
+ };
30
+ const NEW_COMPONENT = 'FullPageError';
31
+ const LINK_COMPONENT = 'Link';
32
+
33
+ root.find(j.JSXElement).forEach((element) => {
34
+ const openingElement = element.node.openingElement;
35
+ const componentName = openingElement.name.name;
36
+
37
+ if (componentKindMap[componentName]) {
38
+ dirtyFlag = true;
39
+ // Opening tag
40
+ openingElement.name.name = NEW_COMPONENT;
41
+
42
+ if (element.node.closingElement) {
43
+ // Closing tag
44
+ element.node.closingElement.name.name = NEW_COMPONENT;
45
+ }
46
+
47
+ // Attach new 'kind' attribute
48
+ const kindAttribute = j.jsxAttribute(
49
+ j.jsxIdentifier('kind'),
50
+ j.literal(componentKindMap[componentName])
51
+ );
52
+ openingElement.attributes.push(kindAttribute);
53
+
54
+ // Change errorCodeLabel attribute to label
55
+ const errorCodeLabelProp = openingElement.attributes.find(
56
+ (attr) => attr.name.name === 'errorCodeLabel'
57
+ );
58
+ if (errorCodeLabelProp) {
59
+ errorCodeLabelProp.name.name = 'label';
60
+ }
61
+
62
+ // Convert 'links' prop to 'children' with <Link></Link> tags
63
+ const linksProp = openingElement.attributes.find(
64
+ (attr) => attr.name.name === 'links'
65
+ );
66
+ if (linksProp) {
67
+ linksProp.name.name = 'children';
68
+
69
+ // Convert link value elements
70
+ const linkValues = linksProp.value.expression.elements;
71
+ let linksLen = linkValues.length;
72
+ const linkElements = [];
73
+
74
+ linkValues.forEach((link) => {
75
+ const linkTag = j.jsxElement(
76
+ j.jsxOpeningElement(j.jsxIdentifier(LINK_COMPONENT), [
77
+ j.jsxAttribute(
78
+ j.jsxIdentifier('href'),
79
+ j.jsxExpressionContainer(
80
+ j.literal(link.properties[0].value.value)
81
+ ),
82
+ j.jsxClosingElement(j.jsxIdentifier(LINK_COMPONENT))
83
+ ),
84
+ ]),
85
+ j.jsxClosingElement(j.jsxIdentifier(LINK_COMPONENT)),
86
+ [j.jsxText(link.properties[1].value.value)]
87
+ );
88
+ linkElements.push(linkTag);
89
+ linksLen--;
90
+ if (linksLen) {
91
+ const brTag = j.jsxElement(
92
+ j.jsxOpeningElement(j.jsxIdentifier('br'), [], true)
93
+ );
94
+
95
+ linkElements.push(brTag);
96
+ }
97
+ });
98
+
99
+ const linksFragment = j.jsxFragment(
100
+ j.jsxOpeningFragment(),
101
+ j.jsxClosingFragment(),
102
+ linkElements
103
+ );
104
+
105
+ linksProp.value = j.jsxExpressionContainer(linksFragment);
106
+ }
107
+ }
108
+ });
109
+
110
+ // Transform import statements if necessary
111
+ if (dirtyFlag) {
112
+ const importDeclarations = root.find(j.ImportDeclaration);
113
+ const CARBON_PATH = '@carbon/react';
114
+ const linkComponentSpecifier = j.importSpecifier(
115
+ j.identifier(LINK_COMPONENT),
116
+ j.identifier(LINK_COMPONENT)
117
+ );
118
+
119
+ // Check for '@carbon/react' import statement exists
120
+ const existCarbonImport = importDeclarations.some(
121
+ (importDeclaration) => importDeclaration.node.source.value === CARBON_PATH
122
+ );
123
+
124
+ // Update @carbon/imb-products import statement
125
+ importDeclarations.forEach((statement) => {
126
+ const specifiers = statement.node.specifiers;
127
+ const source = statement.node.source;
128
+ const PRODUCTS_PATH = '@carbon/ibm-products';
129
+
130
+ if (source.value === PRODUCTS_PATH) {
131
+ // Check new component name already imported
132
+ const isNewIdExists = specifiers.some(
133
+ (spec) => spec.imported.name === NEW_COMPONENT
134
+ );
135
+
136
+ // If the new component not already imported, import it
137
+ if (!isNewIdExists) {
138
+ const newSpecifier = j.importSpecifier(
139
+ j.identifier(NEW_COMPONENT),
140
+ j.identifier(NEW_COMPONENT)
141
+ );
142
+ // Including the new specifier into @carbon/ibm-products import statement
143
+ specifiers.push(newSpecifier);
144
+ }
145
+
146
+ Object.keys(componentKindMap).forEach((key) => {
147
+ // Check the old component names exists
148
+ const identifierIndex = specifiers.findIndex(
149
+ (spec) => spec.imported.name === key
150
+ );
151
+
152
+ // Remove all old components' import
153
+ if (identifierIndex !== -1) {
154
+ specifiers.splice(identifierIndex, 1);
155
+ }
156
+ });
157
+ }
158
+
159
+ // if the @carbon/react import statement already exists update the import
160
+ if (existCarbonImport && source.value === CARBON_PATH) {
161
+ // Check Link component already imported
162
+ const linkIdIndex = specifiers.findIndex(
163
+ (spec) => spec.imported.name === LINK_COMPONENT
164
+ );
165
+
166
+ // if Link component does not in the imported components list
167
+ if (linkIdIndex === -1) {
168
+ // Include the Link component in imported components list
169
+ specifiers.push(linkComponentSpecifier);
170
+ }
171
+ }
172
+ });
173
+
174
+ // If @carbon/react import statement not exists
175
+ if (!existCarbonImport) {
176
+ const carbonImportDeclaration = j.importDeclaration(
177
+ [linkComponentSpecifier],
178
+ j.literal(CARBON_PATH)
179
+ );
180
+
181
+ root
182
+ .find(j.Program)
183
+ .forEach((program) =>
184
+ program.node.body.unshift(carbonImportDeclaration)
185
+ );
186
+ }
187
+ }
188
+
189
+ return root.toSource();
190
+ };
191
+
192
+ module.exports = transform;
@@ -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;