bit-bin
Version:
<a href="https://opensource.org/licenses/Apache-2.0"><img alt="apache" src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"></a> <a href="https://github.com/teambit/bit/blob/master/CONTRIBUTING.md"><img alt="prs" src="https://img.shields.io/b
225 lines (181 loc) • 5.07 kB
JavaScript
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = parse;
function _bluebird() {
const data = require("bluebird");
_bluebird = function () {
return data;
};
return data;
}
function _doctrine() {
const data = _interopRequireDefault(require("doctrine"));
_doctrine = function () {
return data;
};
return data;
}
function reactDocs() {
const data = _interopRequireWildcard(require("react-docgen"));
reactDocs = function () {
return data;
};
return data;
}
function _utils() {
const data = require("../../utils");
_utils = function () {
return data;
};
return data;
}
function _logger() {
const data = _interopRequireDefault(require("../../logger/logger"));
_logger = function () {
return data;
};
return data;
}
function _extractDataRegex() {
const data = _interopRequireDefault(require("../extract-data-regex"));
_extractDataRegex = function () {
return data;
};
return data;
}
function formatProperties(props) {
const parseDescription = description => {
// an extra step is needed to parse the properties description correctly. without this step
// it'd show the entire tag, e.g. `@property {propTypes.string} text - Button text.`
// instead of just `text - Button text.`.
try {
const descriptionAST = _doctrine().default.parse(description, {
unwrap: true,
recoverable: true,
sloppy: true
});
if (descriptionAST && descriptionAST.tags[0]) return descriptionAST.tags[0].description;
} catch (err) {// failed to parse the react property, that's fine, it'll return the original description
}
return description;
};
return Object.keys(props).map(name => {
const {
type,
description,
required,
defaultValue,
flowType,
tsType
} = props[name];
return {
name,
description: parseDescription(description),
required,
type: stringifyType(type || flowType || tsType),
defaultValue
};
});
}
function formatMethods(methods) {
return Object.keys(methods).map(key => {
const {
returns,
modifiers,
params,
docblock,
name
} = methods[key];
return {
name,
description: docblock,
returns,
modifiers,
params
};
});
}
function fromReactDocs({
description,
displayName,
props,
methods
}, filePath) {
return {
filePath: (0, _utils().pathNormalizeToLinux)(filePath),
name: displayName,
description,
properties: formatProperties(props),
access: 'public',
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
methods: formatMethods(methods)
};
}
function stringifyType(prop) {
if (!prop) return '?'; // TODO!
const {
name
} = prop;
let transformed;
switch (name) {
default:
transformed = name;
break;
case 'func':
transformed = 'function';
break;
case 'shape':
transformed = JSON.stringify(Object.keys(prop.value).reduce((acc = {}, current) => {
acc[current] = stringifyType(prop.value[current]);
return acc;
}, {}));
break;
case 'enum':
transformed = prop.value.map(enumProp => enumProp.value).join(' | ');
break;
case 'instanceOf':
transformed = prop.value;
break;
case 'union':
transformed = prop.value ? prop.value.map(p => stringifyType(p)).join(' | ') : prop.raw;
break;
case 'arrayOf':
transformed = `${stringifyType(prop.value)}[]`;
break;
}
return transformed;
}
function parse(_x, _x2) {
return _parse.apply(this, arguments);
}
function _parse() {
_parse = (0, _bluebird().coroutine)(function* (data, filePath) {
const doclets = [];
try {
const componentsInfo = reactDocs().parse(data, reactDocs().resolver.findAllExportedComponentDefinitions, undefined, {
configFile: false,
filename: filePath // should we use pathNormalizeToLinux(filePath) ?
});
if (componentsInfo) {
return componentsInfo.map(componentInfo => {
const formatted = fromReactDocs(componentInfo, filePath);
formatted.args = []; // this is a workaround to get the 'example' tag parsed when using react-docs
// because as of now Docgen doesn't parse @example tag, instead, it shows it inside
// the @description tag.
(0, _extractDataRegex().default)(formatted.description, doclets, filePath, false);
formatted.description = doclets[0].description;
formatted.examples = doclets[0].examples;
return formatted;
});
}
} catch (err) {
_logger().default.silly(`failed parsing docs using docgen on path ${filePath} with error`, err);
}
return undefined;
});
return _parse.apply(this, arguments);
}
;