@mui/codemod 5.15.6 → 5.15.8

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/README.md CHANGED
@@ -60,9 +60,40 @@ npx @mui/codemod@latest <transform> <path> --jscodeshift="--printOptions='{\"quo
60
60
 
61
61
  ## Included scripts
62
62
 
63
+ - [Deprecation](#deprecations)
64
+ - [v5](#v500)
65
+ - [v4](#v400)
66
+ - [v1](#v100)
67
+ - [v0.15](#v0150)
68
+
69
+ ### Deprecations
70
+
71
+ ```bash
72
+ npx @mui/codemod@latest deprecations/all <path>
73
+ ```
74
+
75
+ #### `all`
76
+
77
+ A combination of all deprecations.
78
+
79
+ #### `accordion-props`
80
+
81
+ ```diff
82
+ <Accordion
83
+ - TransitionComponent={CustomTransition}
84
+ - TransitionProps={{ unmountOnExit: true }}
85
+ + slots={{ transition: CustomTransition }}
86
+ + slotProps={{ transition: { unmountOnExit: true } }}
87
+ />
88
+ ```
89
+
90
+ ```bash
91
+ npx @mui/codemod@latest deprecations/accordion-props <path>
92
+ ```
93
+
63
94
  ### v5.0.0
64
95
 
65
- ### `base-use-named-exports`
96
+ #### `base-use-named-exports`
66
97
 
67
98
  Base UI default exports were changed to named ones. Previously we had a mix of default and named ones.
68
99
  This was changed to improve consistency and avoid problems some bundlers have with default exports.
@@ -81,7 +112,7 @@ This codemod updates the import and re-export statements.
81
112
  npx @mui/codemod@latest v5.0.0/base-use-named-exports <path>
82
113
  ```
83
114
 
84
- ### `base-remove-unstyled-suffix`
115
+ #### `base-remove-unstyled-suffix`
85
116
 
86
117
  The `Unstyled` suffix has been removed from all Base UI component names, including names of types and other related identifiers.
87
118
 
package/codemod.js CHANGED
@@ -10,27 +10,39 @@ const jscodeshiftDirectory = path.dirname(require.resolve('jscodeshift'));
10
10
  const jscodeshiftExecutable = path.join(jscodeshiftDirectory, jscodeshiftPackage.bin.jscodeshift);
11
11
 
12
12
  async function runTransform(transform, files, flags, codemodFlags) {
13
- const transformerSrcPath = path.resolve(__dirname, './src', `${transform}.js`);
14
- const transformerBuildPath = path.resolve(__dirname, './node', `${transform}.js`);
13
+ const paths = [
14
+ path.resolve(__dirname, './src', `${transform}/index.js`),
15
+ path.resolve(__dirname, './src', `${transform}.js`),
16
+ path.resolve(__dirname, './node', `${transform}/index.js`),
17
+ path.resolve(__dirname, './node', `${transform}.js`),
18
+ ];
19
+
15
20
  let transformerPath;
16
- try {
17
- await fs.stat(transformerSrcPath);
18
- transformerPath = transformerSrcPath;
19
- } catch (srcPathError) {
21
+ let error;
22
+ // eslint-disable-next-line no-restricted-syntax
23
+ for (const item of paths) {
20
24
  try {
21
- await fs.stat(transformerBuildPath);
22
- transformerPath = transformerBuildPath;
23
- } catch (buildPathError) {
24
- if (buildPathError.code === 'ENOENT') {
25
- throw new Error(
26
- `Transform '${transform}' not found. Check out ${path.resolve(
27
- __dirname,
28
- './README.md for a list of available codemods.',
29
- )}`,
30
- );
31
- }
32
- throw buildPathError;
25
+ // eslint-disable-next-line no-await-in-loop
26
+ await fs.stat(item);
27
+ error = undefined;
28
+ transformerPath = item;
29
+ break;
30
+ } catch (srcPathError) {
31
+ error = srcPathError;
32
+ continue;
33
+ }
34
+ }
35
+
36
+ if (error) {
37
+ if (error?.code === 'ENOENT') {
38
+ throw new Error(
39
+ `Transform '${transform}' not found. Check out ${path.resolve(
40
+ __dirname,
41
+ './README.md for a list of available codemods.',
42
+ )}`,
43
+ );
33
44
  }
45
+ throw error;
34
46
  }
35
47
 
36
48
  const args = [
@@ -0,0 +1,91 @@
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 _findComponentJSX = _interopRequireDefault(require("../../util/findComponentJSX"));
9
+ var _assignObject = _interopRequireDefault(require("../../util/assignObject"));
10
+ var _appendAttribute = _interopRequireDefault(require("../../util/appendAttribute"));
11
+ /**
12
+ * @param {import('jscodeshift').FileInfo} file
13
+ * @param {import('jscodeshift').API} api
14
+ */
15
+ function transformer(file, api, options) {
16
+ const j = api.jscodeshift;
17
+ const root = j(file.source);
18
+ const printOptions = options.printOptions;
19
+ (0, _findComponentJSX.default)(j, {
20
+ root,
21
+ componentName: 'Accordion'
22
+ }, elementPath => {
23
+ let index = elementPath.node.openingElement.attributes.findIndex(attr => attr.type === 'JSXAttribute' && attr.name.name === 'TransitionComponent');
24
+ if (index !== -1) {
25
+ const removed = elementPath.node.openingElement.attributes.splice(index, 1);
26
+ let hasNode = false;
27
+ elementPath.node.openingElement.attributes.forEach(attr => {
28
+ var _attr$name;
29
+ if (((_attr$name = attr.name) == null ? void 0 : _attr$name.name) === 'slots') {
30
+ hasNode = true;
31
+ (0, _assignObject.default)(j, {
32
+ target: attr,
33
+ key: 'transition',
34
+ expression: removed[0].value.expression
35
+ });
36
+ }
37
+ });
38
+ if (!hasNode) {
39
+ (0, _appendAttribute.default)(j, {
40
+ target: elementPath.node,
41
+ attributeName: 'slots',
42
+ expression: j.objectExpression([j.objectProperty(j.identifier('transition'), removed[0].value.expression)])
43
+ });
44
+ }
45
+ }
46
+ index = elementPath.node.openingElement.attributes.findIndex(attr => attr.type === 'JSXAttribute' && attr.name.name === 'TransitionProps');
47
+ if (index !== -1) {
48
+ const removed = elementPath.node.openingElement.attributes.splice(index, 1);
49
+ let hasNode = false;
50
+ elementPath.node.openingElement.attributes.forEach(attr => {
51
+ var _attr$name2;
52
+ if (((_attr$name2 = attr.name) == null ? void 0 : _attr$name2.name) === 'slotProps') {
53
+ hasNode = true;
54
+ (0, _assignObject.default)(j, {
55
+ target: attr,
56
+ key: 'transition',
57
+ expression: removed[0].value.expression
58
+ });
59
+ }
60
+ });
61
+ if (!hasNode) {
62
+ (0, _appendAttribute.default)(j, {
63
+ target: elementPath.node,
64
+ attributeName: 'slotProps',
65
+ expression: j.objectExpression([j.objectProperty(j.identifier('transition'), removed[0].value.expression)])
66
+ });
67
+ }
68
+ }
69
+ });
70
+ root.find(j.ObjectProperty, {
71
+ key: {
72
+ name: 'TransitionComponent'
73
+ }
74
+ }).forEach(path => {
75
+ var _path$parent;
76
+ if (((_path$parent = path.parent) == null || (_path$parent = _path$parent.parent) == null || (_path$parent = _path$parent.parent) == null || (_path$parent = _path$parent.parent) == null || (_path$parent = _path$parent.node.key) == null ? void 0 : _path$parent.name) === 'MuiAccordion') {
77
+ path.replace(j.property('init', j.identifier('slots'), j.objectExpression([j.objectProperty(j.identifier('transition'), path.node.value)])));
78
+ }
79
+ });
80
+ root.find(j.ObjectProperty, {
81
+ key: {
82
+ name: 'TransitionProps'
83
+ }
84
+ }).forEach(path => {
85
+ var _path$parent2;
86
+ if (((_path$parent2 = path.parent) == null || (_path$parent2 = _path$parent2.parent) == null || (_path$parent2 = _path$parent2.parent) == null || (_path$parent2 = _path$parent2.parent) == null || (_path$parent2 = _path$parent2.node.key) == null ? void 0 : _path$parent2.name) === 'MuiAccordion') {
87
+ path.replace(j.property('init', j.identifier('slotProps'), j.objectExpression([j.objectProperty(j.identifier('transition'), path.node.value)])));
88
+ }
89
+ });
90
+ return root.toSource(printOptions);
91
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ Object.defineProperty(exports, "default", {
8
+ enumerable: true,
9
+ get: function () {
10
+ return _accordionProps.default;
11
+ }
12
+ });
13
+ var _accordionProps = _interopRequireDefault(require("./accordion-props"));
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
5
+ var _Accordion = _interopRequireDefault(require("@mui/material/Accordion"));
6
+ var _material = require("@mui/material");
7
+ var _jsxRuntime = require("react/jsx-runtime");
8
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(_Accordion.default, {
9
+ TransitionComponent: CustomTransition,
10
+ TransitionProps: {
11
+ unmountOnExit: true
12
+ }
13
+ });
14
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Accordion, {
15
+ TransitionComponent: CustomTransition,
16
+ TransitionProps: transitionVars
17
+ });
18
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(_Accordion.default, {
19
+ TransitionComponent: CustomTransition,
20
+ TransitionProps: {
21
+ unmountOnExit: true
22
+ },
23
+ slots: {
24
+ root: 'div'
25
+ },
26
+ slotProps: {
27
+ root: {
28
+ className: 'foo'
29
+ }
30
+ }
31
+ });
32
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Accordion, {
33
+ TransitionComponent: CustomTransition,
34
+ TransitionProps: {
35
+ unmountOnExit: true
36
+ },
37
+ slots: (0, _extends2.default)({}, outerSlots),
38
+ slotProps: (0, _extends2.default)({}, outerSlotProps)
39
+ });
40
+ // should skip non MUI components
41
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(NonMuiAccordion, {
42
+ TransitionComponent: CustomTransition,
43
+ TransitionProps: {
44
+ unmountOnExit: true
45
+ }
46
+ });
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
5
+ var _Accordion = _interopRequireDefault(require("@mui/material/Accordion"));
6
+ var _material = require("@mui/material");
7
+ var _jsxRuntime = require("react/jsx-runtime");
8
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(_Accordion.default, {
9
+ slots: {
10
+ transition: CustomTransition
11
+ },
12
+ slotProps: {
13
+ transition: {
14
+ unmountOnExit: true
15
+ }
16
+ }
17
+ });
18
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Accordion, {
19
+ slots: {
20
+ transition: CustomTransition
21
+ },
22
+ slotProps: {
23
+ transition: transitionVars
24
+ }
25
+ });
26
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(_Accordion.default, {
27
+ slots: {
28
+ root: 'div',
29
+ transition: CustomTransition
30
+ },
31
+ slotProps: {
32
+ root: {
33
+ className: 'foo'
34
+ },
35
+ transition: {
36
+ unmountOnExit: true
37
+ }
38
+ }
39
+ });
40
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Accordion, {
41
+ slots: (0, _extends2.default)({}, outerSlots, {
42
+ transition: CustomTransition
43
+ }),
44
+ slotProps: (0, _extends2.default)({}, outerSlotProps, {
45
+ transition: {
46
+ unmountOnExit: true
47
+ }
48
+ })
49
+ });
50
+ // should skip non MUI components
51
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(NonMuiAccordion, {
52
+ TransitionComponent: CustomTransition,
53
+ TransitionProps: {
54
+ unmountOnExit: true
55
+ }
56
+ });
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ fn({
4
+ MuiAccordion: {
5
+ defaultProps: {
6
+ TransitionComponent: CustomTransition,
7
+ TransitionProps: {
8
+ unmountOnExit: true
9
+ }
10
+ }
11
+ }
12
+ });
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ fn({
4
+ MuiAccordion: {
5
+ defaultProps: {
6
+ slots: {
7
+ transition: CustomTransition
8
+ },
9
+ slotProps: {
10
+ transition: {
11
+ unmountOnExit: true
12
+ }
13
+ }
14
+ }
15
+ }
16
+ });
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = deprecationsAll;
8
+ var _accordionProps = _interopRequireDefault(require("../accordion-props/accordion-props"));
9
+ /**
10
+ * @param {import('jscodeshift').FileInfo} file
11
+ * @param {import('jscodeshift').API} api
12
+ */
13
+ function deprecationsAll(file, api, options) {
14
+ file.source = (0, _accordionProps.default)(file, api, options);
15
+ return file.source;
16
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ Object.defineProperty(exports, "default", {
8
+ enumerable: true,
9
+ get: function () {
10
+ return _deprecationsAll.default;
11
+ }
12
+ });
13
+ var _deprecationsAll = _interopRequireDefault(require("./deprecations-all"));
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = appendAttribute;
7
+ /**
8
+ * @param {import('jscodeshift')} j
9
+ * @param {{ target: import('jscodeshift').JSXElement; attributeName: string; expression: import('ast-types/gen/kinds').ExpressionKind | import('ast-types/gen/kinds').JSXEmptyExpressionKind; }} options
10
+ */
11
+ function appendAttribute(j, options) {
12
+ const {
13
+ target,
14
+ attributeName,
15
+ expression
16
+ } = options;
17
+ target.openingElement.attributes.push(j.jsxAttribute(j.jsxIdentifier(attributeName), j.jsxExpressionContainer(expression)));
18
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = assignObject;
7
+ /**
8
+ * Pushes an expression to a known object. handles local object and variable declaration.
9
+ *
10
+ * @param {import('jscodeshift')} j
11
+ * @param {{ target: import('jscodeshift').JSXAttribute; expression: import('ast-types/gen/kinds').ExpressionKind; key: string }} options
12
+ *
13
+ * @example push expression to `slots.transition` => <Component slots={{ transition: <expression> }} />
14
+ * @example push expression to `slots.transition` => <Component slots={{ ...slots, transition: <expression> }} />
15
+ */
16
+ function assignObject(j, options) {
17
+ const {
18
+ target,
19
+ expression,
20
+ key
21
+ } = options;
22
+ if (target && target.type === 'JSXAttribute') {
23
+ const expContainer = /** @type import('jscodeshift').JSXExpressionContainer */target.value;
24
+ if (expContainer.expression.type === 'ObjectExpression') {
25
+ // case `<prop>={{ ... }}`
26
+ expContainer.expression.properties.push(j.objectProperty(j.identifier(key), expression));
27
+ } else if (expContainer.expression.type === 'Identifier') {
28
+ // case `<prop>={outerVariable}
29
+ expContainer.expression = j.objectExpression([j.spreadElement(j.identifier(expContainer.expression.name)), j.objectProperty(j.identifier(key), expression)]);
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = findComponentJSX;
7
+ /**
8
+ * Find all the JSXElements of a given component name.
9
+ *
10
+ * @param {import('jscodeshift')} j
11
+ * @param {{ root: import('jscodeshift').Collection; componentName: string }} options
12
+ * @param {(path: import('jscodeshift').ASTPath<import('jscodeshift').JSXElement>) => void} callback
13
+ *
14
+ */
15
+ function findComponentJSX(j, options, callback) {
16
+ const {
17
+ root,
18
+ componentName
19
+ } = options;
20
+
21
+ // case 1: import ComponentName from '@mui/material/ComponentName';
22
+ // case 2: import { ComponentName } from '@mui/material';
23
+ // case 3: import { ComponentName as SomethingElse } from '@mui/material';
24
+
25
+ const importName = new Set();
26
+ root.find(j.ImportDeclaration).filter(path => path.node.source.value.match(new RegExp(`^@mui/material(/${componentName})?$`))).forEach(path => {
27
+ path.node.specifiers.forEach(specifier => {
28
+ if (specifier.type === 'ImportDefaultSpecifier') {
29
+ importName.add(specifier.local.name);
30
+ }
31
+ if (specifier.type === 'ImportSpecifier' && specifier.imported.name === componentName) {
32
+ importName.add(specifier.local.name);
33
+ }
34
+ });
35
+ });
36
+ [...importName].forEach(name => {
37
+ root.findJSXElements(name).forEach(elementPath => {
38
+ callback(elementPath);
39
+ });
40
+ });
41
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/codemod",
3
- "version": "5.15.6",
3
+ "version": "5.15.8",
4
4
  "bin": "./codemod.js",
5
5
  "private": false,
6
6
  "author": "MUI Team",
@@ -24,9 +24,9 @@
24
24
  "url": "https://opencollective.com/mui-org"
25
25
  },
26
26
  "dependencies": {
27
- "@babel/core": "^7.23.7",
28
- "@babel/runtime": "^7.23.8",
29
- "@babel/traverse": "^7.23.7",
27
+ "@babel/core": "^7.23.9",
28
+ "@babel/runtime": "^7.23.9",
29
+ "@babel/traverse": "^7.23.9",
30
30
  "jscodeshift": "^0.13.1",
31
31
  "jscodeshift-add-imports": "^1.0.10",
32
32
  "yargs": "^17.7.2"