@builder.io/mitosis
Version:
Write components once, run everywhere. Compiles to Vue, React, Solid, and Liquid. Import code from Figma and Builder.io
170 lines (169 loc) • 6.85 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.renderPreComponent = exports.renderImport = exports.transformImportPath = exports.checkIsComponentImport = void 0;
const component_file_extensions_1 = require("./component-file-extensions");
const DEFAULT_IMPORT = 'default';
const STAR_IMPORT = '*';
const getStarImport = ({ theImport }) => {
for (const key in theImport.imports) {
const value = theImport.imports[key];
if (value === STAR_IMPORT) {
return key;
}
}
return null;
};
const getDefaultImport = ({ theImport }) => {
for (const key in theImport.imports) {
const value = theImport.imports[key];
if (value === DEFAULT_IMPORT) {
return key;
}
}
return null;
};
const CONTEXT_IMPORTS = ['context.lite', 'context.lite.ts', 'context.lite.js'];
const checkIsContextImport = (theImport) => CONTEXT_IMPORTS.some((contextPath) => theImport.path.endsWith(contextPath));
const checkIsComponentImport = (theImport) => !checkIsContextImport(theImport) &&
component_file_extensions_1.COMPONENT_IMPORT_EXTENSIONS.some((contextPath) => theImport.path.endsWith(contextPath));
exports.checkIsComponentImport = checkIsComponentImport;
const transformImportPath = ({ theImport, target, preserveFileExtensions, explicitImportFileExtension, }) => {
// We need to drop the `.lite` from context files, because the context generator does so as well.
if (checkIsContextImport(theImport)) {
let path = theImport.path;
CONTEXT_IMPORTS.forEach((contextPath) => {
if (path.endsWith(contextPath)) {
path = path.replace(contextPath, 'context.js');
}
});
return path;
}
if (preserveFileExtensions)
return theImport.path;
if ((0, exports.checkIsComponentImport)(theImport)) {
return theImport.path.replace(component_file_extensions_1.INPUT_EXTENSION_REGEX, (0, component_file_extensions_1.getComponentFileExtensionForTarget)({ target, type: 'import', explicitImportFileExtension }));
}
return theImport.path;
};
exports.transformImportPath = transformImportPath;
const getNamedImports = ({ theImport }) => {
const namedImports = Object.entries(theImport.imports)
.filter(([, value]) => ![DEFAULT_IMPORT, STAR_IMPORT].includes(value))
.map(([key, value]) => {
return key !== value ? `${value} as ${key}` : value;
});
if (namedImports.length > 0) {
return `{ ${namedImports.join(', ')} }`;
}
else {
return null;
}
};
const getImportedValues = ({ theImport }) => {
const starImport = getStarImport({ theImport });
const defaultImport = getDefaultImport({ theImport });
const namedImports = getNamedImports({ theImport });
return { starImport, defaultImport, namedImports };
};
const getImportValue = ({ defaultImport, namedImports, starImport }) => {
if (starImport) {
return ` * as ${starImport} `;
}
else {
return [defaultImport, namedImports].filter(Boolean).join(', ');
}
};
const renderImport = ({ theImport, target, asyncComponentImports, preserveFileExtensions = false, component = undefined, componentsUsed = [], importMapper, explicitImportFileExtension = false, }) => {
const importedValues = getImportedValues({ theImport });
const path = (0, exports.transformImportPath)({
theImport,
target,
preserveFileExtensions,
explicitImportFileExtension,
});
const importValue = getImportValue(importedValues);
const isComponentImport = (0, exports.checkIsComponentImport)(theImport);
const shouldBeAsyncImport = asyncComponentImports && isComponentImport;
const isTypeImport = theImport.importKind === 'type';
// For lit (components) we just want to do a plain import
// https://lit.dev/docs/components/rendering/#composing-templates
if (isComponentImport && target === 'lit') {
return `import '${path}';`;
}
if (shouldBeAsyncImport) {
const isVueImport = target === 'vue';
if (isVueImport && importedValues.namedImports) {
console.warn('Vue: Async Component imports cannot include named imports. Dropping async import. This might break your code.');
}
else {
return `const ${importValue} = () => import('${path}')
.then(x => x.default)
.catch(err => {
console.error('Error while attempting to dynamically import component ${importValue} at ${path}', err);
throw err;
});`;
}
}
if (importMapper) {
const importMapperResult = importMapper(component, theImport, importedValues, componentsUsed);
// If import mapper has no result we skip this
if (importMapperResult) {
return importMapperResult;
}
}
return importValue
? `import ${isTypeImport ? 'type' : ''} ${importValue} from '${path}';`
: `import '${path}';`;
};
exports.renderImport = renderImport;
const renderImports = ({ imports, target, asyncComponentImports, excludeMitosisComponents, preserveFileExtensions = false, component, componentsUsed, importMapper, explicitImportFileExtension, }) => imports
.filter((theImport) => {
if (
// Remove compile away components
theImport.path === '@builder.io/components' ||
// TODO: Mitosis output needs this
theImport.path.startsWith('@builder.io/mitosis')) {
return false;
}
else if (excludeMitosisComponents && theImport.path.includes('.lite')) {
return false;
}
else {
return true;
}
})
.map((theImport) => (0, exports.renderImport)({
theImport,
target,
asyncComponentImports,
preserveFileExtensions,
component,
componentsUsed,
importMapper,
explicitImportFileExtension,
}))
.join('\n');
const renderPreComponent = ({ component, target, excludeMitosisComponents, asyncComponentImports = false, preserveFileExtensions = false, componentsUsed = [], importMapper, explicitImportFileExtension = false, excludeExportAndLocal = false, }) => {
var _a;
return `
${renderImports({
imports: component.imports,
target,
asyncComponentImports,
excludeMitosisComponents,
preserveFileExtensions,
component,
componentsUsed,
importMapper,
explicitImportFileExtension,
})}
${excludeExportAndLocal ? '' : renderExportAndLocal(component)}
${((_a = component.hooks.preComponent) === null || _a === void 0 ? void 0 : _a.code) || ''}
`;
};
exports.renderPreComponent = renderPreComponent;
const renderExportAndLocal = (component) => {
return Object.keys(component.exports || {})
.map((key) => component.exports[key].code)
.join('\n');
};
;