UNPKG

@storybook/addon-docs

Version:
237 lines (185 loc) • 6.98 kB
"use strict"; function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } require("core-js/modules/es.array.filter"); require("core-js/modules/es.function.name"); require("core-js/modules/es.object.assign"); Object.defineProperty(exports, "__esModule", { value: true }); exports.parse = parse; var _acorn = require("acorn"); var _acornJsx = _interopRequireDefault(require("acorn-jsx")); var _lodash = require("lodash"); var acornWalk = _interopRequireWildcard(require("acorn-walk")); var _types = require("./types"); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } // @ts-ignore // @ts-ignore var ACORN_WALK_VISITORS = Object.assign({}, acornWalk.base, { JSXElement: function JSXElement() {} }); var acornParser = _acorn.Parser.extend((0, _acornJsx["default"])()); // Cannot use "estree.Identifier" type because this function also support "JSXIdentifier". function extractIdentifierName(identifierNode) { return !(0, _lodash.isNil)(identifierNode) ? identifierNode.name : null; } function filterAncestors(ancestors) { return ancestors.filter(function (x) { return x.type === 'ObjectExpression' || x.type === 'ArrayExpression'; }); } function calculateNodeDepth(node) { var depths = []; acornWalk.ancestor(node, { ObjectExpression: function ObjectExpression(_, ancestors) { depths.push(filterAncestors(ancestors).length); }, ArrayExpression: function ArrayExpression(_, ancestors) { depths.push(filterAncestors(ancestors).length); } }, ACORN_WALK_VISITORS); return Math.max.apply(Math, depths); } function parseIdentifier(identifierNode) { return { inferedType: { type: _types.InspectionType.IDENTIFIER, identifier: extractIdentifierName(identifierNode) }, ast: identifierNode }; } function parseLiteral(literalNode) { return { inferedType: { type: _types.InspectionType.LITERAL }, ast: literalNode }; } function parseFunction(funcNode) { var innerJsxElementNode; // If there is at least a JSXElement in the body of the function, then it's a React component. acornWalk.simple(funcNode.body, { JSXElement: function JSXElement(node) { innerJsxElementNode = node; } }, ACORN_WALK_VISITORS); var isJsx = !(0, _lodash.isNil)(innerJsxElementNode); var inferedType = { type: isJsx ? _types.InspectionType.ELEMENT : _types.InspectionType.FUNCTION, params: funcNode.params, hasParams: funcNode.params.length !== 0 }; var identifierName = extractIdentifierName(funcNode.id); if (!(0, _lodash.isNil)(identifierName)) { inferedType.identifier = identifierName; } return { inferedType: inferedType, ast: funcNode }; } function parseClass(classNode) { var innerJsxElementNode; // If there is at least a JSXElement in the body of the class, then it's a React component. acornWalk.simple(classNode.body, { JSXElement: function JSXElement(node) { innerJsxElementNode = node; } }, ACORN_WALK_VISITORS); var inferedType = { type: !(0, _lodash.isNil)(innerJsxElementNode) ? _types.InspectionType.ELEMENT : _types.InspectionType.CLASS, identifier: extractIdentifierName(classNode.id) }; return { inferedType: inferedType, ast: classNode }; } function parseJsxElement(jsxElementNode) { var inferedType = { type: _types.InspectionType.ELEMENT }; var identifierName = extractIdentifierName(jsxElementNode.openingElement.name); if (!(0, _lodash.isNil)(identifierName)) { inferedType.identifier = identifierName; } return { inferedType: inferedType, ast: jsxElementNode }; } function parseCall(callNode) { var identifierNode = callNode.callee.type === 'MemberExpression' ? callNode.callee.property : callNode.callee; var identifierName = extractIdentifierName(identifierNode); if (identifierName === 'shape') { return parseObject(callNode.arguments[0]); } return null; } function parseObject(objectNode) { return { inferedType: { type: _types.InspectionType.OBJECT, depth: calculateNodeDepth(objectNode) }, ast: objectNode }; } function parseArray(arrayNode) { return { inferedType: { type: _types.InspectionType.ARRAY, depth: calculateNodeDepth(arrayNode) }, ast: arrayNode }; } // Cannot set "expression" type to "estree.Expression" because the type doesn't include JSX. function parseExpression(expression) { switch (expression.type) { case 'Identifier': return parseIdentifier(expression); case 'Literal': return parseLiteral(expression); case 'FunctionExpression': case 'ArrowFunctionExpression': return parseFunction(expression); case 'ClassExpression': return parseClass(expression); case 'JSXElement': return parseJsxElement(expression); case 'CallExpression': return parseCall(expression); case 'ObjectExpression': return parseObject(expression); case 'ArrayExpression': return parseArray(expression); default: return null; } } function parse(value) { var ast = acornParser.parse("(".concat(value, ")")); var parsingResult = { inferedType: { type: _types.InspectionType.UNKNOWN }, ast: ast }; if (!(0, _lodash.isNil)(ast.body[0])) { var rootNode = ast.body[0]; switch (rootNode.type) { case 'ExpressionStatement': { var expressionResult = parseExpression(rootNode.expression); if (!(0, _lodash.isNil)(expressionResult)) { parsingResult = expressionResult; } break; } default: break; } } return parsingResult; }