@volue/wave-codemod__react 0.1.0-next.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/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file. See [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) for commit guidelines.
4
+
5
+ <!-- MONODEPLOY:BELOW -->
package/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # `@volue/wave-codemod__react`
2
+
3
+ Codemods for migration to the newer version of the `@volue/wave-react` library.
4
+
5
+ These codemods utilize [jscodeshift](https://github.com/facebook/jscodeshift) library for transformations and [Hypermod.io CLI tool](https://www.hypermod.io/docs/tools/cli) for downloading and running them against your codebase.
6
+
7
+ ## Install
8
+
9
+ No installation of this package is necessary.
10
+ Downloading and running codemods can be done via `npx @hypermod/cli`.
11
+
12
+ ## Usage
13
+
14
+ ### Considerations
15
+
16
+ - You should run codemods on a separate Git branch, then manually review the changes before deploying them.
17
+ - Codemods are designed to do the heavy lifting, but they may not be perfect, so some manual work may still be required in order to successfully migrate.
18
+ - Codemods might output code that doesn’t follow your coding style. Make sure to run your code formatter and/or linter before committing the changes.
19
+
20
+ ### Examples
21
+
22
+ To run a transform for version `1.0.0` of `@volue/wave-react`, use one of the following commands:
23
+
24
+ ```sh
25
+ # Transform multiple files
26
+ npx @hypermod/cli --packages @volue/wave-codemod__react@1.0.0 --experimental-loader /project/src/**/*.tsx
27
+
28
+ # Transform single file
29
+ npx @hypermod/cli --packages @volue/wave-codemod__react@1.0.0 --experimental-loader /project/src/path/to/file
30
+ ```
31
+
32
+ To run all transforms for `@volue/wave-react` in sequence from version `1.0.0` to the latest, add `--sequence` flag:
33
+
34
+ ```sh
35
+ npx @hypermod/cli --sequence --packages @volue/wave-codemod__react@1.0.0 --experimental-loader /project/src/**/*.tsx
36
+ ```
37
+
38
+ [See the Hypermod CLI docs for more information and examples](https://www.hypermod.io/docs/tools/cli)
package/dist/index.cjs ADDED
@@ -0,0 +1,136 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var utils = require('@hypermod/utils');
6
+
7
+ const componentsSet = /* @__PURE__ */ new Set([
8
+ "ActionBar",
9
+ "Anchor",
10
+ "AppFrame",
11
+ "Avatar",
12
+ "ButtonGroup",
13
+ "Card",
14
+ "Checkbox",
15
+ "Collapsible",
16
+ "CollapsibleCard",
17
+ "Combobox",
18
+ "DataItem",
19
+ "DataList",
20
+ "DatePicker",
21
+ "Dialog",
22
+ "Drawer",
23
+ "FormField",
24
+ "HeaderNavList",
25
+ "Menu",
26
+ "MultiSelectMenu",
27
+ "Notification",
28
+ "Pagination",
29
+ "Popover",
30
+ "Positioner",
31
+ "Radio",
32
+ "RovingFocusGroup",
33
+ "SelectMenu",
34
+ "SidebarNavigation",
35
+ "SingleSelectMenu",
36
+ "Switch",
37
+ "Table",
38
+ "Tabs",
39
+ "ToggleButtonGroup",
40
+ "TreeView"
41
+ ]);
42
+ function addRootToMultipartComps(j, ast) {
43
+ const componentsToTransform = [];
44
+ ast.find(j.ImportDeclaration, { source: { value: "@volue/wave-react" } }).forEach((path) => {
45
+ path.node.specifiers?.forEach((specifier) => {
46
+ if (specifier.type === "ImportSpecifier") {
47
+ const importedName = specifier.imported.name;
48
+ if (componentsSet.has(importedName)) {
49
+ componentsToTransform.push(importedName);
50
+ }
51
+ }
52
+ });
53
+ });
54
+ if (componentsToTransform.length === 0) {
55
+ return;
56
+ }
57
+ componentsToTransform.forEach((componentName) => {
58
+ ast.find(j.JSXOpeningElement, {
59
+ name: {
60
+ type: "JSXIdentifier",
61
+ name: componentName
62
+ }
63
+ }).forEach((openingTagPath) => {
64
+ if (openingTagPath.node.name.type === "JSXIdentifier") {
65
+ openingTagPath.node.name.name = `${componentName}.Root`;
66
+ }
67
+ });
68
+ ast.find(j.JSXClosingElement, {
69
+ name: {
70
+ type: "JSXIdentifier",
71
+ name: componentName
72
+ }
73
+ }).forEach((closingTagPath) => {
74
+ if (closingTagPath.node.name.type === "JSXIdentifier") {
75
+ closingTagPath.node.name.name = `${componentName}.Root`;
76
+ }
77
+ });
78
+ ast.find(j.TSTypeQuery, {
79
+ exprName: {
80
+ type: "Identifier",
81
+ name: componentName
82
+ }
83
+ }).replaceWith(
84
+ j.tsTypeQuery(
85
+ j.tsQualifiedName(j.identifier(componentName), j.identifier("Root"))
86
+ )
87
+ );
88
+ });
89
+ }
90
+
91
+ const REG_RETURN = /return\s+\((\s+)\(<([^\s>]+)/g;
92
+ function removeParentheses(string) {
93
+ const matches = string.matchAll(REG_RETURN);
94
+ let result = "";
95
+ const allMatches = [...matches];
96
+ if (allMatches.length === 0) return string;
97
+ allMatches.forEach((match) => {
98
+ const [, spaces, componentName] = match;
99
+ const sl = spaces.length;
100
+ const REG_DOUBLE_TAG = `(return\\s+\\(\\s{${sl}})\\((<${componentName}.+?\\s{${sl}}<\\/${componentName}>)\\)(\\s+\\))`;
101
+ const REG_SELF_CLOSING = `(return\\s+\\(\\s{${sl}})\\((<${componentName}.+?\\/>)\\)(\\s+\\))`;
102
+ const regexp = new RegExp(`${REG_DOUBLE_TAG}|${REG_SELF_CLOSING}`, "gs");
103
+ result = string.replace(
104
+ regexp,
105
+ (match2, doubleTagStart, doubleTagContent, doubleTagEnd, selfTagStart, selfTagContent, selfTagEnd) => {
106
+ if (doubleTagStart && doubleTagContent && doubleTagEnd) {
107
+ return doubleTagStart + doubleTagContent + doubleTagEnd;
108
+ }
109
+ if (selfTagStart && selfTagContent && selfTagEnd) {
110
+ return selfTagStart + selfTagContent + selfTagEnd;
111
+ }
112
+ return match2;
113
+ }
114
+ );
115
+ });
116
+ return result;
117
+ }
118
+
119
+ function transformer(file, api, options) {
120
+ const { jscodeshift: j } = api;
121
+ const ast = j(file.source);
122
+ if (!utils.hasImportDeclaration(j, ast, "@volue/wave-react")) {
123
+ return file.source;
124
+ }
125
+ utils.applyMotions(j, ast, [addRootToMultipartComps]);
126
+ return removeParentheses(ast.toSource(options.printOptions));
127
+ }
128
+
129
+ var index = {
130
+ transforms: {
131
+ "1.0.0": transformer
132
+ }
133
+ };
134
+
135
+ exports.default = index;
136
+ exports.v1 = transformer;
@@ -0,0 +1,11 @@
1
+ import { FileInfo, API, Options } from 'jscodeshift';
2
+
3
+ declare function transformer(file: FileInfo, api: API, options: Options): string;
4
+
5
+ declare const _default: {
6
+ transforms: {
7
+ '1.0.0': typeof transformer;
8
+ };
9
+ };
10
+
11
+ export { _default as default, transformer as v1 };
@@ -0,0 +1,11 @@
1
+ import { FileInfo, API, Options } from 'jscodeshift';
2
+
3
+ declare function transformer(file: FileInfo, api: API, options: Options): string;
4
+
5
+ declare const _default: {
6
+ transforms: {
7
+ '1.0.0': typeof transformer;
8
+ };
9
+ };
10
+
11
+ export { _default as default, transformer as v1 };
package/dist/index.mjs ADDED
@@ -0,0 +1,131 @@
1
+ import { hasImportDeclaration, applyMotions } from '@hypermod/utils';
2
+
3
+ const componentsSet = /* @__PURE__ */ new Set([
4
+ "ActionBar",
5
+ "Anchor",
6
+ "AppFrame",
7
+ "Avatar",
8
+ "ButtonGroup",
9
+ "Card",
10
+ "Checkbox",
11
+ "Collapsible",
12
+ "CollapsibleCard",
13
+ "Combobox",
14
+ "DataItem",
15
+ "DataList",
16
+ "DatePicker",
17
+ "Dialog",
18
+ "Drawer",
19
+ "FormField",
20
+ "HeaderNavList",
21
+ "Menu",
22
+ "MultiSelectMenu",
23
+ "Notification",
24
+ "Pagination",
25
+ "Popover",
26
+ "Positioner",
27
+ "Radio",
28
+ "RovingFocusGroup",
29
+ "SelectMenu",
30
+ "SidebarNavigation",
31
+ "SingleSelectMenu",
32
+ "Switch",
33
+ "Table",
34
+ "Tabs",
35
+ "ToggleButtonGroup",
36
+ "TreeView"
37
+ ]);
38
+ function addRootToMultipartComps(j, ast) {
39
+ const componentsToTransform = [];
40
+ ast.find(j.ImportDeclaration, { source: { value: "@volue/wave-react" } }).forEach((path) => {
41
+ path.node.specifiers?.forEach((specifier) => {
42
+ if (specifier.type === "ImportSpecifier") {
43
+ const importedName = specifier.imported.name;
44
+ if (componentsSet.has(importedName)) {
45
+ componentsToTransform.push(importedName);
46
+ }
47
+ }
48
+ });
49
+ });
50
+ if (componentsToTransform.length === 0) {
51
+ return;
52
+ }
53
+ componentsToTransform.forEach((componentName) => {
54
+ ast.find(j.JSXOpeningElement, {
55
+ name: {
56
+ type: "JSXIdentifier",
57
+ name: componentName
58
+ }
59
+ }).forEach((openingTagPath) => {
60
+ if (openingTagPath.node.name.type === "JSXIdentifier") {
61
+ openingTagPath.node.name.name = `${componentName}.Root`;
62
+ }
63
+ });
64
+ ast.find(j.JSXClosingElement, {
65
+ name: {
66
+ type: "JSXIdentifier",
67
+ name: componentName
68
+ }
69
+ }).forEach((closingTagPath) => {
70
+ if (closingTagPath.node.name.type === "JSXIdentifier") {
71
+ closingTagPath.node.name.name = `${componentName}.Root`;
72
+ }
73
+ });
74
+ ast.find(j.TSTypeQuery, {
75
+ exprName: {
76
+ type: "Identifier",
77
+ name: componentName
78
+ }
79
+ }).replaceWith(
80
+ j.tsTypeQuery(
81
+ j.tsQualifiedName(j.identifier(componentName), j.identifier("Root"))
82
+ )
83
+ );
84
+ });
85
+ }
86
+
87
+ const REG_RETURN = /return\s+\((\s+)\(<([^\s>]+)/g;
88
+ function removeParentheses(string) {
89
+ const matches = string.matchAll(REG_RETURN);
90
+ let result = "";
91
+ const allMatches = [...matches];
92
+ if (allMatches.length === 0) return string;
93
+ allMatches.forEach((match) => {
94
+ const [, spaces, componentName] = match;
95
+ const sl = spaces.length;
96
+ const REG_DOUBLE_TAG = `(return\\s+\\(\\s{${sl}})\\((<${componentName}.+?\\s{${sl}}<\\/${componentName}>)\\)(\\s+\\))`;
97
+ const REG_SELF_CLOSING = `(return\\s+\\(\\s{${sl}})\\((<${componentName}.+?\\/>)\\)(\\s+\\))`;
98
+ const regexp = new RegExp(`${REG_DOUBLE_TAG}|${REG_SELF_CLOSING}`, "gs");
99
+ result = string.replace(
100
+ regexp,
101
+ (match2, doubleTagStart, doubleTagContent, doubleTagEnd, selfTagStart, selfTagContent, selfTagEnd) => {
102
+ if (doubleTagStart && doubleTagContent && doubleTagEnd) {
103
+ return doubleTagStart + doubleTagContent + doubleTagEnd;
104
+ }
105
+ if (selfTagStart && selfTagContent && selfTagEnd) {
106
+ return selfTagStart + selfTagContent + selfTagEnd;
107
+ }
108
+ return match2;
109
+ }
110
+ );
111
+ });
112
+ return result;
113
+ }
114
+
115
+ function transformer(file, api, options) {
116
+ const { jscodeshift: j } = api;
117
+ const ast = j(file.source);
118
+ if (!hasImportDeclaration(j, ast, "@volue/wave-react")) {
119
+ return file.source;
120
+ }
121
+ applyMotions(j, ast, [addRootToMultipartComps]);
122
+ return removeParentheses(ast.toSource(options.printOptions));
123
+ }
124
+
125
+ var index = {
126
+ transforms: {
127
+ "1.0.0": transformer
128
+ }
129
+ };
130
+
131
+ export { index as default, transformer as v1 };
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@volue/wave-codemod__react",
3
+ "version": "0.1.0-next.0",
4
+ "description": "Codemods for Wave React library",
5
+ "license": "",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/Volue/wave",
9
+ "directory": "codemods/react"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "engines": {
15
+ "node": ">=18"
16
+ },
17
+ "main": "./dist/index.cjs",
18
+ "module": "./dist/index.mjs",
19
+ "types": "./dist/index.d.cts",
20
+ "exports": {
21
+ ".": {
22
+ "require": {
23
+ "types": "./dist/index.d.cts",
24
+ "default": "./dist/index.cjs"
25
+ },
26
+ "import": {
27
+ "types": "./dist/index.d.mts",
28
+ "default": "./dist/index.mjs"
29
+ }
30
+ },
31
+ "./package.json": "./package.json"
32
+ },
33
+ "sideEffects": false,
34
+ "files": [
35
+ "dist"
36
+ ],
37
+ "scripts": {
38
+ "jest": "jest",
39
+ "lint": "eslint . --cache",
40
+ "lint:fix": "yarn run lint --fix",
41
+ "lint:types": "tsc",
42
+ "_prettier": "prettier \"**/*.{json,md,yml}\"",
43
+ "format": "yarn run _prettier --write",
44
+ "test": "run-p lint:types lint \"_prettier --check\" jest",
45
+ "clean": "premove dist",
46
+ "build": "yarn run clean && pkgroll",
47
+ "prepack": "yarn run build"
48
+ },
49
+ "devDependencies": {
50
+ "@jest/types": "29.6.3",
51
+ "@types/jest": "29.5.14",
52
+ "@volue/eslint-config": "1.3.11",
53
+ "eslint": "9.20.1",
54
+ "jest": "29.7.0",
55
+ "npm-run-all2": "7.0.2",
56
+ "pkgroll": "2.11.0",
57
+ "premove": "4.0.0",
58
+ "prettier": "3.5.1",
59
+ "ts-jest": "29.2.6",
60
+ "typescript": "5.7.3"
61
+ },
62
+ "dependencies": {
63
+ "@hypermod/utils": "0.5.0",
64
+ "@types/jscodeshift": "0.12.0",
65
+ "jscodeshift": "17.1.2"
66
+ }
67
+ }