2
recast = require('recast'),
3
parser = require('recast/parsers/babel')
6
module.exports.evaluate = (source, lookup, callback) => {
7
const ast = recast.parse(source, { parser })
8
for (const node of ast.program.body) {
9
if (node.type === 'ExportDefaultDeclaration') {
11
= node.declaration.properties
12
|| node.declaration.arguments[ 0 ].properties
13
for (const property of properties) {
14
const propName = property.key.name
15
if (lookup.includes(propName)) {
16
const innerProps = property.value.properties
17
if (innerProps !== void 0) {
18
for (const innerProp of innerProps) {
20
if (propName === 'props' && innerProp.value) {
21
definition = getPropDefinition(innerProp)
23
innerProp.key !== void 0 && callback(propName, innerProp.key.name, definition)
32
function getPropDefinition (innerProp) {
34
if (innerProp.value.type === 'Identifier') {
35
definition.type = innerProp.value.name
37
else if (innerProp.value.type === 'ArrayExpression') {
38
definition.type = innerProp.value.elements.map(e => e.name)
40
else if (innerProp.value.type !== 'ConditionalExpression') {
41
const jsonContent = innerProp.value.properties.map(p => {
44
if (p.value.name || p.value.value) {
45
value = `"${ p.value.name || p.value.value }"`
47
else if (p.value.type === 'ArrowFunctionExpression') {
48
if (p.value.body.type === 'ArrayExpression') {
49
value = `[${ p.value.body.elements.map(e => e.extra.raw || e.value).join(', ') }]`
51
else if (!p.value.body.callee || !p.value.body.callee.object || !p.value.body.callee.object.elements) {
55
value = `[${ p.value.body.callee.object.elements.map(e => e.extra.raw || e.value).join(', ') }]`
58
else if (p.value.type === 'FunctionExpression') {
59
value = `[${ p.value.body.body.argument.callee.object.elements.map(e => e.extra.raw || e.value).join(', ') }]`
65
if (value === void 0) {
68
return `"${ p.key.name }": ${ value }`
69
}).filter(c => !!c).map(c => c.replace(/'/g, '"')).join(', ')
70
definition = JSON.parse(`{${ jsonContent }}`)
73
if (Array.isArray(innerProp.value.properties) === true) {
74
const defaultVal = innerProp.value.properties.find(p => p.key.name === 'default')
75
if (defaultVal !== void 0 && defaultVal.value !== void 0 && defaultVal.value.type === 'NullLiteral') {
76
if (Array.isArray(definition.type) === true && definition.type.indexOf('null') === -1) {
77
definition.type.push('null')
79
else if (typeof definition.type === 'string') {
80
definition.type = [ definition.type, 'null' ]