@oceanbase/codemod 0.2.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.
Files changed (36) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +119 -0
  3. package/package.json +44 -0
  4. package/src/bin/cli.js +271 -0
  5. package/src/bin/codemod.ignore +9 -0
  6. package/src/bin/codemod.js +3 -0
  7. package/src/bin/upgrade-list.json +23 -0
  8. package/src/transforms/__testfixtures__/.eslintrc.js +7 -0
  9. package/src/transforms/__testfixtures__/antd-charts-to-oceanbase-charts/antd-charts.input.tsx +9 -0
  10. package/src/transforms/__testfixtures__/antd-charts-to-oceanbase-charts/antd-charts.output.tsx +9 -0
  11. package/src/transforms/__testfixtures__/antd-to-oceanbase-design/antd.input.tsx +92 -0
  12. package/src/transforms/__testfixtures__/antd-to-oceanbase-design/antd.output.tsx +92 -0
  13. package/src/transforms/__testfixtures__/antd-to-oceanbase-design/bigfish-antd.input.tsx +92 -0
  14. package/src/transforms/__testfixtures__/antd-to-oceanbase-design/bigfish-antd.output.tsx +92 -0
  15. package/src/transforms/__testfixtures__/obui-to-oceanbase-design-and-ui/obui.input.tsx +11 -0
  16. package/src/transforms/__testfixtures__/obui-to-oceanbase-design-and-ui/obui.output.tsx +12 -0
  17. package/src/transforms/__testfixtures__/obutil-to-oceanbase-util/obutil.input.tsx +8 -0
  18. package/src/transforms/__testfixtures__/obutil-to-oceanbase-util/obutil.output.tsx +8 -0
  19. package/src/transforms/__testfixtures__/techui-to-oceanbase-ui/pro-components.input.tsx +9 -0
  20. package/src/transforms/__testfixtures__/techui-to-oceanbase-ui/pro-components.output.tsx +11 -0
  21. package/src/transforms/__testfixtures__/techui-to-oceanbase-ui/techui.input.tsx +9 -0
  22. package/src/transforms/__testfixtures__/techui-to-oceanbase-ui/techui.output.tsx +11 -0
  23. package/src/transforms/__tests__/antd-charts-to-oceanbase-charts.test.ts +10 -0
  24. package/src/transforms/__tests__/antd-to-oceanbase-design.test.ts +10 -0
  25. package/src/transforms/__tests__/obui-to-oceanbase-design-and-ui.test.ts +10 -0
  26. package/src/transforms/__tests__/obutil-to-oceanbase-util.test.ts +10 -0
  27. package/src/transforms/__tests__/techui-to-oceanbase-ui.test.ts +10 -0
  28. package/src/transforms/antd-charts-to-oceanbase-charts.js +17 -0
  29. package/src/transforms/antd-to-oceanbase-design.js +17 -0
  30. package/src/transforms/obui-to-oceanbase-design-and-ui.js +50 -0
  31. package/src/transforms/obutil-to-oceanbase-util.js +15 -0
  32. package/src/transforms/techui-to-oceanbase-ui.js +18 -0
  33. package/src/transforms/utils/config.js +11 -0
  34. package/src/transforms/utils/import-component.js +72 -0
  35. package/src/transforms/utils/index.js +224 -0
  36. package/src/transforms/utils/marker.js +35 -0
@@ -0,0 +1,224 @@
1
+ // some utils extract from https://github.com/reactjs/react-codemod
2
+ function insertImportAfter(j, root, { importStatement, importKind, afterModule }) {
3
+ const firstAfterModuleImport = root
4
+ .find(j.ImportDeclaration, {
5
+ source: { value: afterModule },
6
+ importKind,
7
+ })
8
+ .at(0);
9
+
10
+ if (firstAfterModuleImport.paths()[0]) {
11
+ firstAfterModuleImport.insertAfter(importStatement);
12
+ } else {
13
+ // 保留首行的注释
14
+ // https://github.com/facebook/jscodeshift/blob/master/recipes/retain-first-comment.md
15
+ const firstNode = getFirstNode(j, root);
16
+ const { comments } = firstNode;
17
+ if (comments) {
18
+ delete firstNode.comments;
19
+ importStatement.comments = comments;
20
+ }
21
+
22
+ // insert `import` at body(0)
23
+ root.get().node.program.body.unshift(importStatement);
24
+ }
25
+ }
26
+
27
+ function insertImportBefore(j, root, { importStatement, importKind, beforeModule }) {
28
+ const firstBeforeModuleImport = root
29
+ .find(j.ImportDeclaration, {
30
+ source: { value: beforeModule },
31
+ importKind,
32
+ })
33
+ .at(0);
34
+
35
+ const firstNode = getFirstNode(j, root);
36
+ if (
37
+ (firstBeforeModuleImport.paths()[0] && firstBeforeModuleImport.paths()[0].node === firstNode) ||
38
+ !firstBeforeModuleImport
39
+ ) {
40
+ // 保留首行的注释
41
+ // https://github.com/facebook/jscodeshift/blob/master/recipes/retain-first-comment.md
42
+ const { comments } = firstNode;
43
+ if (comments) {
44
+ delete firstNode.comments;
45
+ importStatement.comments = comments;
46
+ }
47
+ }
48
+
49
+ if (firstBeforeModuleImport.paths()[0]) {
50
+ firstBeforeModuleImport.insertBefore(importStatement);
51
+ } else {
52
+ // insert `import` at body(0)
53
+ root.get().node.program.body.unshift(importStatement);
54
+ }
55
+ }
56
+
57
+ function hasSubmoduleImport(j, root, moduleName, submoduleName, importKind) {
58
+ const collections = root
59
+ .find(j.ImportDeclaration, {
60
+ source: {
61
+ value: moduleName,
62
+ },
63
+ importKind,
64
+ })
65
+ .find(j.ImportSpecifier, {
66
+ imported: {
67
+ name: submoduleName,
68
+ },
69
+ });
70
+
71
+ const targetImport = collections.paths();
72
+
73
+ // local 默认设置为 null
74
+ return targetImport[0]?.value?.local?.name || targetImport[0]?.value?.imported.name;
75
+ }
76
+
77
+ function hasModuleImport(j, root, moduleName, importKind) {
78
+ return (
79
+ root.find(j.ImportDeclaration, {
80
+ source: { value: moduleName },
81
+ importKind,
82
+ }).length > 0
83
+ );
84
+ }
85
+
86
+ function hasModuleDefaultImport(j, root, pkgName, localModuleName) {
87
+ let found = false;
88
+ root
89
+ .find(j.ImportDeclaration, {
90
+ source: { value: pkgName },
91
+ })
92
+ .forEach(nodePath => {
93
+ const defaultImport = nodePath.node.specifiers.filter(
94
+ n => n.type === 'ImportDefaultSpecifier' && n.local.name === localModuleName
95
+ );
96
+ if (defaultImport.length) {
97
+ found = true;
98
+ }
99
+ });
100
+ return found;
101
+ }
102
+
103
+ function removeEmptyModuleImport(j, root, moduleName) {
104
+ root
105
+ .find(j.ImportDeclaration)
106
+ .filter(path => path.node.specifiers.length === 0 && path.node.source.value === moduleName)
107
+ .replaceWith();
108
+ }
109
+
110
+ // Program uses var keywords
111
+ function useVar(j, root) {
112
+ return root.find(j.VariableDeclaration, { kind: 'const' }).length === 0;
113
+ }
114
+
115
+ function getFirstNode(j, root) {
116
+ return root.find(j.Program).get('body', 0).node;
117
+ }
118
+
119
+ function addModuleImport(j, root, { pkgName, importSpecifier, importKind, before, after }) {
120
+ // if has module imported, just import new submodule from existed
121
+ // else just create a new import
122
+ if (hasModuleImport(j, root, pkgName, importKind)) {
123
+ root
124
+ .find(j.ImportDeclaration, {
125
+ source: { value: pkgName },
126
+ importKind,
127
+ })
128
+ .at(0)
129
+ .replaceWith(({ node }) => {
130
+ const mergedImportSpecifiers = node.specifiers.concat(importSpecifier).sort((a, b) => {
131
+ if (a.type === 'ImportDefaultSpecifier') {
132
+ return -1;
133
+ }
134
+
135
+ if (b.type === 'ImportDefaultSpecifier') {
136
+ return 1;
137
+ }
138
+
139
+ return a.imported.name.localeCompare(b.imported.name);
140
+ });
141
+ return j.importDeclaration(mergedImportSpecifiers, j.literal(pkgName));
142
+ });
143
+ return true;
144
+ }
145
+
146
+ const importStatement = j.importDeclaration([importSpecifier], j.literal(pkgName));
147
+ // set importKind for importStatement
148
+ importStatement.importKind = importKind;
149
+
150
+ if (before) {
151
+ insertImportBefore(j, root, { importStatement, importKind, beforeModule: before });
152
+ } else if (after) {
153
+ insertImportAfter(j, root, { importStatement, importKind, afterModule: after });
154
+ }
155
+
156
+ return true;
157
+ }
158
+
159
+ // add default import before one module
160
+ function addModuleDefaultImport(j, root, { moduleName, localName, before }) {
161
+ if (hasModuleDefaultImport(j, root, moduleName, localName)) {
162
+ return;
163
+ }
164
+
165
+ // DefaultImportSpecifier
166
+ const importSpecifier = j.importDefaultSpecifier(j.identifier(localName));
167
+
168
+ if (addModuleImport(j, root, { pkgName: moduleName, importSpecifier, before })) {
169
+ return;
170
+ }
171
+
172
+ throw new Error(`No ${moduleName} import found!`);
173
+ }
174
+
175
+ // add submodule import before one module
176
+ function addSubmoduleImport(
177
+ j,
178
+ root,
179
+ { moduleName, importedName, localName, importKind, before, after }
180
+ ) {
181
+ const importedLocalName = hasSubmoduleImport(j, root, moduleName, importedName, importKind);
182
+ if (importedLocalName) {
183
+ return importedLocalName;
184
+ }
185
+
186
+ const importSpecifier = j.importSpecifier(
187
+ j.identifier(importedName),
188
+ localName ? j.identifier(localName) : null
189
+ );
190
+
191
+ if (
192
+ addModuleImport(j, root, { pkgName: moduleName, importSpecifier, importKind, before, after })
193
+ ) {
194
+ return localName || importedName;
195
+ }
196
+
197
+ throw new Error(`No ${moduleName} import found!`);
198
+ }
199
+
200
+ // add style import after one module
201
+ function addStyleModuleImport(j, root, { moduleName, after }) {
202
+ if (hasModuleImport(j, root, moduleName)) {
203
+ return;
204
+ }
205
+
206
+ const importStatement = j.importDeclaration([], j.literal(moduleName));
207
+ insertImportAfter(j, root, { importStatement, afterModule: after });
208
+ }
209
+
210
+ function parseStrToArray(pkgNames) {
211
+ return (pkgNames || '')
212
+ .split(',')
213
+ .filter(n => n)
214
+ .map(n => n.trim());
215
+ }
216
+
217
+ module.exports = {
218
+ parseStrToArray,
219
+ addModuleDefaultImport,
220
+ addStyleModuleImport,
221
+ addSubmoduleImport,
222
+ removeEmptyModuleImport,
223
+ useVar,
224
+ };
@@ -0,0 +1,35 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const _ = require('lodash');
4
+
5
+ const markerPath = path.join(
6
+ process.env.NODE_ENV === 'local' ? process.cwd() : require('os').tmpdir(),
7
+ './codemod-marker.log'
8
+ );
9
+
10
+ const newline = '\n';
11
+
12
+ function ensureFile() {
13
+ return fs.openSync(markerPath, 'w');
14
+ }
15
+
16
+ async function cleanup() {
17
+ return await fs.promises.unlink(markerPath);
18
+ }
19
+
20
+ function markDependency(depName) {
21
+ ensureFile();
22
+ return fs.appendFileSync(markerPath, depName + newline, 'utf8');
23
+ }
24
+
25
+ async function getDependencies() {
26
+ ensureFile();
27
+ const content = await fs.promises.readFile(markerPath, 'utf8');
28
+ await cleanup();
29
+ return _.uniq((content || '').split(newline));
30
+ }
31
+
32
+ module.exports = {
33
+ markDependency,
34
+ getDependencies,
35
+ };