Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Socket
Sign inDemoInstall

react-docgen

Package Overview
Dependencies
Maintainers
3
Versions
93
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-docgen - npm Package Compare versions

Comparing version 2.20.0 to 2.20.1

dist/utils/postProcessDocumentation.js

6

dist/handlers/displayNameHandler.js

@@ -50,2 +50,8 @@ 'use strict';

documentation.set('displayName', (0, _getNameOrValue2.default)(path.get('id')));
} else if (types.ArrowFunctionExpression.check(path.node) || types.FunctionExpression.check(path.node)) {
if (types.VariableDeclarator.check(path.parentPath.node)) {
documentation.set('displayName', (0, _getNameOrValue2.default)(path.parentPath.get('id')));
} else if (types.AssignmentExpression.check(path.parentPath.node)) {
documentation.set('displayName', (0, _getNameOrValue2.default)(path.parentPath.get('left')));
}
}

@@ -52,0 +58,0 @@ return;

30

dist/parse.js

@@ -13,2 +13,6 @@ 'use strict';

var _postProcessDocumentation = require('./utils/postProcessDocumentation');
var _postProcessDocumentation2 = _interopRequireDefault(_postProcessDocumentation);
var _babylon = require('./babylon');

@@ -24,14 +28,16 @@

var ERROR_MISSING_DEFINITION = 'No suitable component definition found.'; /*
* Copyright (c) 2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*
*/
/*
* Copyright (c) 2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*
*/
var ERROR_MISSING_DEFINITION = 'No suitable component definition found.';
function executeHandlers(handlers, componentDefinitions) {

@@ -43,3 +49,3 @@ return componentDefinitions.map(function (componentDefinition) {

});
return documentation.toObject();
return (0, _postProcessDocumentation2.default)(documentation.toObject());
});

@@ -46,0 +52,0 @@ }

81

dist/utils/getFlowType.js

@@ -7,2 +7,6 @@ 'use strict';

var _typeof2 = require('babel-runtime/helpers/typeof');
var _typeof3 = _interopRequireDefault(_typeof2);
var _extends2 = require('babel-runtime/helpers/extends');

@@ -71,2 +75,3 @@

var namedTypes = {
ArrayTypeAnnotation: handleArrayTypeAnnotation,
GenericTypeAnnotation: handleGenericTypeAnnotation,

@@ -83,3 +88,3 @@ ObjectTypeAnnotation: handleObjectTypeAnnotation,

function getFlowTypeWithRequirements(path) {
var type = getFlowType(path);
var type = getFlowTypeWithResolvedTypes(path);

@@ -114,2 +119,10 @@ type.required = !path.parentPath.node.optional;

function handleArrayTypeAnnotation(path) {
return {
name: 'Array',
elements: [getFlowTypeWithResolvedTypes(path.get('elementType'))],
raw: (0, _printValue2.default)(path)
};
}
function handleGenericTypeAnnotation(path) {

@@ -132,3 +145,3 @@ if (path.node.id.name === '$Keys' && path.node.typeParameters) {

elements: params.map(function (param) {
return getFlowType(param);
return getFlowTypeWithResolvedTypes(param);
}),

@@ -140,3 +153,3 @@ raw: (0, _printValue2.default)(path)

if (resolvedPath && resolvedPath.node.right) {
type = getFlowType(resolvedPath.get('right'));
type = getFlowTypeWithResolvedTypes(resolvedPath.get('right'));
}

@@ -157,3 +170,3 @@ }

path.get('callProperties').each(function (param) {
type.signature.constructor = getFlowType(param.get('value'));
type.signature.constructor = getFlowTypeWithResolvedTypes(param.get('value'));
});

@@ -163,3 +176,3 @@

type.signature.properties.push({
key: getFlowType(param.get('key')),
key: getFlowTypeWithResolvedTypes(param.get('key')),
value: getFlowTypeWithRequirements(param.get('value'))

@@ -184,3 +197,3 @@ });

elements: path.get('types').map(function (subType) {
return getFlowType(subType);
return getFlowTypeWithResolvedTypes(subType);
})

@@ -195,3 +208,3 @@ };

elements: path.get('types').map(function (subType) {
return getFlowType(subType);
return getFlowTypeWithResolvedTypes(subType);
})

@@ -206,3 +219,3 @@ };

var type = getFlowType(typeAnnotation);
var type = getFlowTypeWithResolvedTypes(typeAnnotation);
type.nullable = true;

@@ -220,3 +233,3 @@

arguments: [],
return: getFlowType(path.get('returnType'))
return: getFlowTypeWithResolvedTypes(path.get('returnType'))
}

@@ -231,3 +244,3 @@ };

name: (0, _getPropertyName2.default)(param.get('name')),
type: getFlowType(typeAnnotation)
type: getFlowTypeWithResolvedTypes(typeAnnotation)
});

@@ -243,3 +256,3 @@ });

path.get('types').each(function (param) {
type.elements.push(getFlowType(param));
type.elements.push(getFlowTypeWithResolvedTypes(param));
});

@@ -251,3 +264,3 @@

function handleTypeofTypeAnnotation(path) {
return getFlowType(path.get('argument'));
return getFlowTypeWithResolvedTypes(path.get('argument'));
}

@@ -261,13 +274,24 @@

/**
* Tries to identify the flow type by inspecting the path for known
* flow type names. This method doesn't check whether the found type is actually
* existing. It simply assumes that a match is always valid.
*
* If there is no match, "unknown" is returned.
*/
function getFlowType(path) {
var visitedTypes = {};
function getFlowTypeWithResolvedTypes(path) {
var node = path.node;
var type = void 0;
var isTypeAlias = types.TypeAlias.check(path.parentPath.node);
// When we see a typealias mark it as visited so that the next
// call of this function does not run into an endless loop
if (isTypeAlias) {
if (visitedTypes[path.parentPath.node.id.name] === true) {
// if we are currently visiting this node then just return the name
// as we are starting to endless loop
return { name: path.parentPath.node.id.name };
} else if ((0, _typeof3.default)(visitedTypes[path.parentPath.node.id.name]) === 'object') {
// if we already resolved the type simple return it
return visitedTypes[path.parentPath.node.id.name];
}
// mark the type as visited
visitedTypes[path.parentPath.node.id.name] = true;
}
if (types.Type.check(node)) {

@@ -283,2 +307,7 @@ if (node.type in flowTypes) {

if (isTypeAlias) {
// mark the type as unvisited so that further calls can resolve the type again
visitedTypes[path.parentPath.node.id.name] = type;
}
if (!type) {

@@ -289,2 +318,14 @@ type = { name: 'unknown' };

return type;
}
/**
* Tries to identify the flow type by inspecting the path for known
* flow type names. This method doesn't check whether the found type is actually
* existing. It simply assumes that a match is always valid.
*
* If there is no match, "unknown" is returned.
*/
function getFlowType(path) {
visitedTypes = {};
return getFlowTypeWithResolvedTypes(path);
}

@@ -56,90 +56,107 @@ 'use strict';

var reNonLexicalBlocks = /^If|^Else|^Switch/;
var validPossibleStatelessComponentTypes = ['Property', 'FunctionDeclaration', 'FunctionExpression', 'ArrowFunctionExpression'];
function isJSXElementOrReactCreateElement(path) {
function isJSXElementOrReactCall(path) {
return path.node.type === 'JSXElement' || path.node.type === 'CallExpression' && (0, _isReactCreateElementCall2.default)(path) || path.node.type === 'CallExpression' && (0, _isReactCloneElementCall2.default)(path) || path.node.type === 'CallExpression' && (0, _isReactChildrenElementCall2.default)(path);
}
function returnsJSXElementOrReactCreateElementCall(path) {
var visited = false;
function resolvesToJSXElementOrReactCall(path) {
// Is the path is already a JSX element or a call to one of the React.* functions
if (isJSXElementOrReactCall(path)) {
return true;
}
// early exit for ArrowFunctionExpressions
if (isJSXElementOrReactCreateElement(path.get('body'))) {
var resolvedPath = (0, _resolveToValue2.default)(path);
// If the path points to a conditional expression, then we need to look only at
// the two possible paths
if (resolvedPath.node.type === 'ConditionalExpression') {
return resolvesToJSXElementOrReactCall(resolvedPath.get('consequent')) || resolvesToJSXElementOrReactCall(resolvedPath.get('alternate'));
}
// If the path points to a logical expression (AND, OR, ...), then we need to look only at
// the two possible paths
if (resolvedPath.node.type === 'LogicalExpression') {
return resolvesToJSXElementOrReactCall(resolvedPath.get('left')) || resolvesToJSXElementOrReactCall(resolvedPath.get('right'));
}
// Is the resolved path is already a JSX element or a call to one of the React.* functions
// Only do this if the resolvedPath actually resolved something as otherwise we did this check already
if (resolvedPath !== path && isJSXElementOrReactCall(resolvedPath)) {
return true;
}
function isSameBlockScope(p) {
var block = p;
do {
block = block.parent;
// jump over non-lexical blocks
if (reNonLexicalBlocks.test(block.parent.node.type)) {
block = block.parent;
}
} while (!types.BlockStatement.check(block.node) && /Function|Property/.test(block.parent.parent.node.type) && !reNonLexicalBlocks.test(block.parent.node.type));
// If we have a call expression, lets try to follow it
if (resolvedPath.node.type === 'CallExpression') {
// special case properties
if (types.Property.check(path.node)) {
return block.node === path.get('value', 'body').node;
var calleeValue = (0, _resolveToValue2.default)(resolvedPath.get('callee'));
if (returnsJSXElementOrReactCall(calleeValue)) {
return true;
}
return block.node === path.get('body').node;
}
var resolvedValue = void 0;
_recast2.default.visit(path, {
visitReturnStatement: function visitReturnStatement(returnPath) {
var resolvedPath = (0, _resolveToValue2.default)(returnPath.get('argument'));
if (isJSXElementOrReactCreateElement(resolvedPath) && isSameBlockScope(returnPath)) {
visited = true;
return false;
var namesToResolve = [calleeValue.get('property')];
if (calleeValue.node.type === 'MemberExpression') {
if (calleeValue.get('object').node.type === 'Identifier') {
resolvedValue = (0, _resolveToValue2.default)(calleeValue.get('object'));
} else if (types.MemberExpression.check(calleeValue.node)) {
do {
calleeValue = calleeValue.get('object');
namesToResolve.unshift(calleeValue.get('property'));
} while (types.MemberExpression.check(calleeValue.node));
resolvedValue = (0, _resolveToValue2.default)(calleeValue.get('object'));
}
}
if (resolvedPath.node.type === 'CallExpression') {
var calleeValue = (0, _resolveToValue2.default)(resolvedPath.get('callee'));
if (resolvedValue && types.ObjectExpression.check(resolvedValue.node)) {
var resolvedMemberExpression = namesToResolve.reduce(function (result, path) {
// eslint-disable-line no-shadow
if (!path) {
return result;
}
if (returnsJSXElementOrReactCreateElementCall(calleeValue)) {
visited = true;
return false;
if (result) {
result = (0, _getPropertyValuePath2.default)(result, path.node.name);
if (result && types.Identifier.check(result.node)) {
return (0, _resolveToValue2.default)(result);
}
}
return result;
}, resolvedValue);
var resolvedValue = void 0;
if (!resolvedMemberExpression || returnsJSXElementOrReactCall(resolvedMemberExpression)) {
return true;
}
}
}
var namesToResolve = [calleeValue.get('property')];
return false;
}
if (calleeValue.node.type === 'MemberExpression') {
if (calleeValue.get('object').node.type === 'Identifier') {
resolvedValue = (0, _resolveToValue2.default)(calleeValue.get('object'));
} else if (types.MemberExpression.check(calleeValue.node)) {
do {
calleeValue = calleeValue.get('object');
namesToResolve.unshift(calleeValue.get('property'));
} while (types.MemberExpression.check(calleeValue.node));
function returnsJSXElementOrReactCall(path) {
var visited = false;
resolvedValue = (0, _resolveToValue2.default)(calleeValue.get('object'));
}
}
// early exit for ArrowFunctionExpressions
if (path.node.type === 'ArrowFunctionExpression' && path.get('body').node.type !== 'BlockStatement' && resolvesToJSXElementOrReactCall(path.get('body'))) {
return true;
}
if (resolvedValue && types.ObjectExpression.check(resolvedValue.node)) {
var resolvedMemberExpression = namesToResolve.reduce(function (result, path) {
// eslint-disable-line no-shadow
if (!path) {
return result;
}
var scope = path.scope;
// If we get a property we want the function scope it holds and not its outer scope
if (path.node.type === 'Property') {
scope = path.get('value').scope;
}
if (result) {
result = (0, _getPropertyValuePath2.default)(result, path.node.name);
if (result && types.Identifier.check(result.node)) {
return (0, _resolveToValue2.default)(result);
}
}
return result;
}, resolvedValue);
_recast2.default.visit(path, {
visitReturnStatement: function visitReturnStatement(returnPath) {
// Only check return statements which are part of the checked function scope
if (returnPath.scope !== scope) return false;
if (!resolvedMemberExpression || returnsJSXElementOrReactCreateElementCall(resolvedMemberExpression)) {
visited = true;
return false;
}
}
if (resolvesToJSXElementOrReactCall(returnPath.get('argument'))) {
visited = true;
return false;
}

@@ -170,3 +187,3 @@

if (returnsJSXElementOrReactCreateElementCall(path)) {
if (returnsJSXElementOrReactCall(path)) {
return true;

@@ -173,0 +190,0 @@ }

{
"name": "react-docgen",
"version": "2.20.0",
"version": "2.20.1",
"description": "A CLI and toolkit to extract information from React components for documentation generation.",

@@ -22,4 +22,4 @@ "repository": {

"lint": "eslint src/ bin/",
"prepublish": "yarn run build",
"preversion": "yarn run lint",
"prepublish": "yarn build",
"preversion": "yarn lint",
"test": "jest",

@@ -26,0 +26,0 @@ "test:ci": "yarn lint && yarn flow && yarn test --runInBand",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc