-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathresolveHocComponents.js
83 lines (70 loc) · 2.12 KB
/
resolveHocComponents.js
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
const { camelCase, upperFirst } = require('lodash');
const { resolver, utils } = require('react-docgen');
const { namedTypes: types, visit } = require('ast-types');
const buildParser = require('react-docgen/dist/babelParser').default;
const parser = buildParser();
module.exports = (ast) => {
let components = resolver.findAllComponentDefinitions(ast);
const getComment = (path) => {
let searchPath = path;
while (searchPath && !types.Statement.check(searchPath.node)) {
searchPath = searchPath.parent;
}
let comment =
(searchPath &&
searchPath.node.leadingComments &&
searchPath.node.leadingComments.map((c) => c.value).pop()) ||
null;
if (comment) comment = `/${comment}*/`;
return comment;
};
visit(ast, {
visitCallExpression(path) {
if (types.ExpressionStatement.check(path.node)) {
path = path.get('expression');
}
if (path.node.type !== 'CallExpression') return false;
const module = utils.resolveToModule(path);
if (!module || !module.endsWith('createWithPrefix')) return false;
const [prefixNode, optionsNode] = path.node.arguments;
const comment = getComment(path);
let type = '"div"';
const property =
optionsNode &&
optionsNode.properties.find((p) => p.key.name === 'Component');
if (property) {
type =
property.value.type === 'Identifier'
? property.value.name
: property.value.raw;
}
const src = `
import React from 'react';
import PropTypes from 'prop-types';
${comment || ''}
export default class ${upperFirst(
camelCase(prefixNode.value),
)} extends React.Component {
static propTypes = {
/** @default ${prefixNode.raw} */
bsPrefix: PropTypes.string.isRequired,
as: PropTypes.elementType,
}
static defaultProps = {
as: ${type}
}
render() {
return null
}
}
`;
let comp = parser.parse(src);
comp.__src = src;
components = components.concat(
resolver.findExportedComponentDefinition(comp),
);
return false;
},
});
return components;
};