UNPKG

@builder.io/mitosis

Version:

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

185 lines (184 loc) 8.11 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.resolveMetadata = void 0; const mitosis_imports_1 = require("../../../helpers/mitosis-imports"); const helpers_1 = require("../../../parsers/jsx/helpers"); const babel = __importStar(require("@babel/core")); const fs_1 = require("fs"); const path = __importStar(require("path")); const getCodeFromImport = (importObject, currentFile) => { if (currentFile) { // resolve path of import const originFile = path.basename(currentFile); const typescript = (0, helpers_1.isTypescriptFile)(originFile); const importFile = (0, helpers_1.isTypescriptFile)(importObject.path) || importObject.path.endsWith('.js') ? importObject.path : `${importObject.path}.${typescript ? 'ts' : 'js'}`; const importFilePath = path.resolve(path.dirname(currentFile), importFile); if ((0, fs_1.existsSync)(importFilePath)) { return { code: (0, fs_1.readFileSync)(importFilePath).toString(), typescript, importFilePath }; } return { typescript }; } return {}; }; const fillDeclarations = ({ declaration, valueToResolve, currentFilePath, nodePath, }) => { let result = {}; for (const variable of declaration.declarations) { if (babel.types.isIdentifier(variable.id)) { if (variable.id.name === valueToResolve && variable.init) { const filled = resolveObjectsRecursive({ node: variable.init, nodePath, currentFilePath, }); result = { ...result, ...filled, }; } } } return result; }; const resolve = ({ nodePath, currentFilePath, valueToResolve, resolvedImports, }) => { let result = {}; const programNodes = nodePath.node.body; for (const statement of programNodes) { if (babel.types.isImportDeclaration(statement)) { const importObject = (0, mitosis_imports_1.mapImportDeclarationToMitosisImport)(statement); if (Object.keys(importObject.imports).includes(valueToResolve)) { if (resolvedImports) { // We add this statement, to remove it from imports of generated file resolvedImports.push({ path: importObject.path, value: valueToResolve }); } // In this case the variable was imported const { code, typescript, importFilePath } = getCodeFromImport(importObject, currentFilePath); if (code) { const jsxToUse = (0, helpers_1.babelStripTypes)(code, typescript); (0, helpers_1.babelDefaultTransform)(jsxToUse, { Program(path) { const statements = path.node.body; for (const pStatement of statements) { if (babel.types.isExportNamedDeclaration(pStatement)) { const declaration = pStatement.declaration; if (babel.types.isVariableDeclaration(declaration)) { const filledDeclaration = fillDeclarations({ declaration, valueToResolve, currentFilePath: importFilePath, nodePath: path, }); result = { ...result, ...filledDeclaration, }; } } } }, }); } } } else if (babel.types.isVariableDeclaration(statement)) { // In this case the variable is inside the same file const filledDeclaration = fillDeclarations({ declaration: statement, valueToResolve, currentFilePath, nodePath, }); result = { ...result, ...filledDeclaration, }; } } return result; }; const resolveObjectsRecursive = ({ node, nodePath, currentFilePath, resolvedImports, }) => { let result = {}; if (babel.types.isObjectExpression(node)) { for (const prop of node.properties) { if (babel.types.isObjectProperty(prop)) { if (babel.types.isIdentifier(prop.key)) { const objectKey = prop.key.name; if (babel.types.isIdentifier(prop.value)) { const valueToResolve = prop.value.name; // In this case we have some variable defined in the same or another file const resolved = resolve({ nodePath, currentFilePath, valueToResolve, resolvedImports, }); result = { ...result, [objectKey]: { ...resolved }, }; } else { // In this case we have a primitive value const json = (0, helpers_1.parseCodeJson)(prop.value); result = { ...result, [objectKey]: json, }; } } } else if (babel.types.isSpreadElement(prop)) { if (babel.types.isIdentifier(prop.argument)) { const valueToResolve = prop.argument.name; result = { ...result, ...resolve({ nodePath, currentFilePath, valueToResolve }), }; } } else { // In this case we have a primitive value result = { ...result, ...(0, helpers_1.parseCodeJson)(prop), }; } } } return result; }; const resolveMetadata = ({ context, node, nodePath, options, }) => { if (context.cwd && (options === null || options === void 0 ? void 0 : options.filePath)) { const resolvedImports = []; const currentFilePath = `${context.cwd}/${options.filePath}`; const metadata = resolveObjectsRecursive({ node, nodePath, currentFilePath, resolvedImports }); context.builder.resolvedImports = resolvedImports; return metadata; } return {}; }; exports.resolveMetadata = resolveMetadata;