@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
JavaScript
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;
;