UNPKG

@builder.io/mitosis

Version:

Write components once, run everywhere. Compiles to Vue, React, Solid, and Liquid. Import code from Figma and Builder.io

100 lines (99 loc) 3.86 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.findSignals = void 0; const ts_morph_1 = require("ts-morph"); const typescript_project_1 = require("../../helpers/typescript-project"); const MITOSIS_IMPORT_PATHS = [ // actual production path '/node_modules/@builder.io/mitosis/', // possible path if symlinking mitosis locally '/mitosis/packages/core/', ]; const findSignals = ({ filePath, project }) => { const ast = project.getSourceFileOrThrow(filePath); if (ast === undefined) { throw new Error('Could not find AST. Please provide a correct `filePath`.'); } const reactiveValues = { props: new Set(), state: new Set(), context: new Set(), }; const propsSymbol = (0, typescript_project_1.getPropsSymbol)(ast); const contextSymbols = (0, typescript_project_1.getContextSymbols)(ast); const checkIsSignalSymbol = (type) => { var _a; const symbol = (_a = type.getTargetType()) === null || _a === void 0 ? void 0 : _a.getAliasSymbol(); if (!symbol || symbol.getName() !== 'Signal') return false; const compilerSymbol = symbol === null || symbol === void 0 ? void 0 : symbol.compilerSymbol; const parent = compilerSymbol.parent; if (!parent) return false; if (MITOSIS_IMPORT_PATHS.some((path) => parent.getName().includes(path))) { return true; } return false; }; const checkIsOptionalSignal = (node) => { let hasUndefined = false; let hasSignal = false; const perfectMatch = node .getType() .getUnionTypes() .every((type) => { if (type.isUndefined()) { hasUndefined = true; return true; } else if (checkIsSignalSymbol(type)) { hasSignal = true; return true; } return false; }); return perfectMatch && hasUndefined && hasSignal; }; ast.forEachDescendant((parentNode) => { if (ts_morph_1.Node.isPropertyAccessExpression(parentNode)) { const node = parentNode.getExpression(); const isOptionalAccess = parentNode.hasQuestionDotToken(); const isSignal = isOptionalAccess ? checkIsOptionalSignal(node) : checkIsSignalSymbol(node.getType()); if (!isSignal) return; let isInsideType = false; let isInsideDeclaration = false; node.getParentWhile((parent, child) => { // stop once we hit the function block if (ts_morph_1.Node.isBlock(child) || ts_morph_1.Node.isBlock(parent)) { return false; } // crawl up parents to make sure we're not inside a type if (ts_morph_1.Node.isTypeNode(parent) || ts_morph_1.Node.isTypeAliasDeclaration(parent)) { isInsideType = true; return false; } return true; }); if (isInsideType) return; if (isInsideDeclaration) return; const nodeSymbol = node.getSymbol(); if (ts_morph_1.Node.isPropertyAccessExpression(node) && node.getExpression().getSymbol() === propsSymbol) { reactiveValues.props.add(node.getNameNode().getText()); } else if (nodeSymbol && contextSymbols.has(nodeSymbol)) { reactiveValues.context.add(node.getText()); } else { reactiveValues.state.add(node.getText()); } } }); return reactiveValues; }; exports.findSignals = findSignals;