UNPKG

sicua

Version:

A tool for analyzing project structure and dependencies

151 lines (150 loc) 6.41 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.extractPropTypes = extractPropTypes; exports.findPropDefaultValue = findPropDefaultValue; const typescript_1 = __importDefault(require("typescript")); const ASTUtils_1 = require("../../../utils/ast/ASTUtils"); /** * Extracts prop types from a component node * @param node Component AST node * @param sourceFile Source file containing the component * @returns Array of prop signatures */ function extractPropTypes(node, sourceFile) { const props = []; // Handle arrow functions with destructured props if (typescript_1.default.isVariableDeclaration(node) && node.initializer && typescript_1.default.isArrowFunction(node.initializer)) { extractPropsFromArrowFunction(node.initializer, props); } // Handle function declarations else if (typescript_1.default.isFunctionDeclaration(node) && node.parameters.length > 0) { const firstParam = node.parameters[0]; if (typescript_1.default.isParameter(firstParam)) { extractPropsFromParameter(firstParam, props); } } // Also check for interface declarations extractPropsFromInterfaces(sourceFile, props); return props; } /** * Extracts props from arrow function parameters * @param arrowFunc Arrow function node * @param props Props array to populate */ function extractPropsFromArrowFunction(arrowFunc, props) { // Get the first parameter const firstParam = arrowFunc.parameters[0]; if (firstParam && typescript_1.default.isParameter(firstParam)) { extractPropsFromParameter(firstParam, props); } } /** * Extracts props from function parameter * @param param Parameter node * @param props Props array to populate */ function extractPropsFromParameter(param, props) { // Handle destructured parameter if (typescript_1.default.isObjectBindingPattern(param.name)) { const bindingPattern = param.name; // Get the type annotation of the parameter const typeAnnotation = param.type; if (typeAnnotation && typescript_1.default.isTypeLiteralNode(typeAnnotation)) { // Extract props from type literal typeAnnotation.members.forEach((member) => { if (typescript_1.default.isPropertySignature(member)) { const propName = member.name.getText(); const propType = member.type?.getText() ?? "any"; const isOptional = !!member.questionToken; props.push({ name: propName, type: propType, required: !isOptional, }); } }); } // Also check binding elements for default values bindingPattern.elements.forEach((element) => { if (typescript_1.default.isBindingElement(element) && typescript_1.default.isIdentifier(element.name)) { const existingProp = props.find((p) => p.name === element.name.getText()); if (existingProp && element.initializer) { // If there's a default value, mark as optional existingProp.required = false; } else if (!existingProp && element.initializer) { // If prop wasn't found from type but has a binding element, add it props.push({ name: element.name.getText(), type: element.initializer.getText(), required: false, }); } } }); } } /** * Extracts props from interface declarations * @param sourceFile Source file to search * @param props Props array to populate */ function extractPropsFromInterfaces(sourceFile, props) { ASTUtils_1.ASTUtils.findNodes(sourceFile, typescript_1.default.isInterfaceDeclaration).forEach((interfaceDecl) => { if (interfaceDecl.name.text.includes("Props")) { interfaceDecl.members.forEach((member) => { if (typescript_1.default.isPropertySignature(member)) { props.push({ name: member.name.getText(), type: member.type?.getText() ?? "any", required: !member.questionToken, }); } }); } }); } /** * Finds the default value for a prop in a component * @param propName Name of the prop * @param componentNode Component AST node * @returns Default value string if found */ function findPropDefaultValue(propName, componentNode) { if (typescript_1.default.isVariableDeclaration(componentNode) && componentNode.initializer && typescript_1.default.isArrowFunction(componentNode.initializer)) { const param = componentNode.initializer.parameters[0]; if (param && typescript_1.default.isParameter(param) && typescript_1.default.isObjectBindingPattern(param.name)) { const element = param.name.elements.find((el) => typescript_1.default.isBindingElement(el) && typescript_1.default.isIdentifier(el.name) && el.name.text === propName && el.initializer); if (element && typescript_1.default.isBindingElement(element) && element.initializer) { return element.initializer.getText(); } } } else if (typescript_1.default.isFunctionDeclaration(componentNode) && componentNode.parameters.length > 0) { const param = componentNode.parameters[0]; if (typescript_1.default.isParameter(param) && typescript_1.default.isObjectBindingPattern(param.name)) { const element = param.name.elements.find((el) => typescript_1.default.isBindingElement(el) && typescript_1.default.isIdentifier(el.name) && el.name.text === propName && el.initializer); if (element && typescript_1.default.isBindingElement(element) && element.initializer) { return element.initializer.getText(); } } } return undefined; }