-
Notifications
You must be signed in to change notification settings - Fork 4
/
transform-component-props.ts
106 lines (93 loc) · 2.93 KB
/
transform-component-props.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/**
* 1. Find all react components
* 2. Find all component props
* 3. Check if prop variable was async function
* 4. Find in component's children, all async function props usages
* 4.1. Add async/await to all usages
* 5. Find in component's children, other component
* 5.1 Each component, check if props variable was async function (goto 3)
*/
import { FileInfo, API, Options } from "jscodeshift";
const debug = require("debug")("transform:component-props");
const debug2 = require("debug")("transform:print:component-props");
import {
findImportNodeByVariableName,
findVariableDeclarator,
getRealImportSource,
} from "./utils";
import {
getComponentName,
getComponentProps,
handleComponent,
} from "./utils-component";
module.exports = function (fileInfo: FileInfo, { j }: API, options: Options) {
debug(
`\n**************************************************
*** ${fileInfo.path}
**************************************************\n`
);
let fileChanged = false;
const rootCollection = j(fileInfo.source);
// find all react elements
const elements = rootCollection.find(j.JSXElement).paths();
// debug(elements);
// must use this for loop because we don't want a file being opened at the same time.
for (let i = 0; i < elements.length; i += 1) {
const p = elements[i];
debug("_jsx element", p.value.loc?.start);
const componentName = getComponentName(p);
// debug("_component name:", componentName);
// component name must start with a capital letter.
if (!componentName || !/^[A-Z]/.test(componentName)) {
continue;
}
const props = getComponentProps(p, j);
// debug("_props:", props);
debug("_component name:", componentName);
// debug("_props:", props);
// find the component declaration
let theComponent = findVariableDeclarator(componentName, p, j);
if (theComponent) {
// debug("_component:", theComponent?.value);
handleComponent({
componentName,
filePath: fileInfo.path,
props,
j,
options,
});
}
if (!theComponent) {
// find the component from import declarations
const { importSource, importSpecType } = findImportNodeByVariableName(
componentName,
rootCollection,
j
);
if (importSource) {
// check if not from local file
if (/^[^./]/.test(importSource)) {
debug("It looks like a library:", importSource);
} else {
// debug("_import from source:", importSource);
const realImportSource = getRealImportSource(
importSource,
fileInfo.path
);
handleComponent({
componentName,
filePath: realImportSource,
props,
j,
options,
importSpecType,
});
}
}
}
}
if (fileChanged) {
debug2("file changed: ", fileInfo.path);
return rootCollection.toSource();
}
};