@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.
- package/LICENSE +22 -0
- package/README.md +119 -0
- package/package.json +44 -0
- package/src/bin/cli.js +271 -0
- package/src/bin/codemod.ignore +9 -0
- package/src/bin/codemod.js +3 -0
- package/src/bin/upgrade-list.json +23 -0
- package/src/transforms/__testfixtures__/.eslintrc.js +7 -0
- package/src/transforms/__testfixtures__/antd-charts-to-oceanbase-charts/antd-charts.input.tsx +9 -0
- package/src/transforms/__testfixtures__/antd-charts-to-oceanbase-charts/antd-charts.output.tsx +9 -0
- package/src/transforms/__testfixtures__/antd-to-oceanbase-design/antd.input.tsx +92 -0
- package/src/transforms/__testfixtures__/antd-to-oceanbase-design/antd.output.tsx +92 -0
- package/src/transforms/__testfixtures__/antd-to-oceanbase-design/bigfish-antd.input.tsx +92 -0
- package/src/transforms/__testfixtures__/antd-to-oceanbase-design/bigfish-antd.output.tsx +92 -0
- package/src/transforms/__testfixtures__/obui-to-oceanbase-design-and-ui/obui.input.tsx +11 -0
- package/src/transforms/__testfixtures__/obui-to-oceanbase-design-and-ui/obui.output.tsx +12 -0
- package/src/transforms/__testfixtures__/obutil-to-oceanbase-util/obutil.input.tsx +8 -0
- package/src/transforms/__testfixtures__/obutil-to-oceanbase-util/obutil.output.tsx +8 -0
- package/src/transforms/__testfixtures__/techui-to-oceanbase-ui/pro-components.input.tsx +9 -0
- package/src/transforms/__testfixtures__/techui-to-oceanbase-ui/pro-components.output.tsx +11 -0
- package/src/transforms/__testfixtures__/techui-to-oceanbase-ui/techui.input.tsx +9 -0
- package/src/transforms/__testfixtures__/techui-to-oceanbase-ui/techui.output.tsx +11 -0
- package/src/transforms/__tests__/antd-charts-to-oceanbase-charts.test.ts +10 -0
- package/src/transforms/__tests__/antd-to-oceanbase-design.test.ts +10 -0
- package/src/transforms/__tests__/obui-to-oceanbase-design-and-ui.test.ts +10 -0
- package/src/transforms/__tests__/obutil-to-oceanbase-util.test.ts +10 -0
- package/src/transforms/__tests__/techui-to-oceanbase-ui.test.ts +10 -0
- package/src/transforms/antd-charts-to-oceanbase-charts.js +17 -0
- package/src/transforms/antd-to-oceanbase-design.js +17 -0
- package/src/transforms/obui-to-oceanbase-design-and-ui.js +50 -0
- package/src/transforms/obutil-to-oceanbase-util.js +15 -0
- package/src/transforms/techui-to-oceanbase-ui.js +18 -0
- package/src/transforms/utils/config.js +11 -0
- package/src/transforms/utils/import-component.js +72 -0
- package/src/transforms/utils/index.js +224 -0
- 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
|
+
};
|