@builder.io/mitosis
Version:
Write components once, run everywhere. Compiles to Vue, React, Solid, and Liquid. Import code from Figma and Builder.io
211 lines (208 loc) • 8.33 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateOptionsApiScript = void 0;
const get_components_used_1 = require("../../helpers/get-components-used");
const get_custom_imports_1 = require("../../helpers/get-custom-imports");
const get_state_object_string_1 = require("../../helpers/get-state-object-string");
const nullable_1 = require("../../helpers/nullable");
const render_imports_1 = require("../../helpers/render-imports");
const json5_1 = __importDefault(require("json5"));
const lodash_1 = require("lodash");
const on_mount_1 = require("../helpers/on-mount");
const helpers_1 = require("./helpers");
const getContextProvideString = (json, options) => {
return `{
${Object.values(json.context.set)
.map((setVal) => {
const key = (0, helpers_1.getContextKey)(setVal);
return `[${key}]: ${(0, helpers_1.getContextValue)(setVal)}`;
})
.join(',')}
}`;
};
function getContextInjectString(component, options) {
let str = '{';
const contextGetters = component.context.get;
for (const key in contextGetters) {
const context = contextGetters[key];
str += `
${key}: ${(0, helpers_1.encodeQuotes)((0, helpers_1.getContextKey)(context))},
`;
}
str += '}';
return str;
}
const generateComponentImport = (options) => (componentName) => {
if (options.asyncComponentImports) {
return `'${componentName}': defineAsyncComponent(${componentName})`;
}
else {
return `'${componentName}': ${componentName}`;
}
};
const generateComponents = (componentsUsed, options) => {
if (componentsUsed.length === 0) {
return '';
}
else {
return `components: { ${componentsUsed.map(generateComponentImport(options)).join(',')} },`;
}
};
const appendToDataString = ({ dataString, newContent, }) => dataString.replace(/}$/, `${newContent}}`);
function generateOptionsApiScript(component, options, path, template, props, onUpdateWithDeps, onUpdateWithoutDeps) {
var _a, _b, _c;
const { exports: localExports } = component;
const localVarAsData = [];
const localVarAsFunc = [];
const isTs = options.typescript;
if (localExports) {
Object.keys(localExports).forEach((key) => {
if (localExports[key].usedInLocal) {
if (localExports[key].isFunction) {
localVarAsFunc.push(key);
}
else {
localVarAsData.push(key);
}
}
});
}
let dataString = (0, get_state_object_string_1.getStateObjectStringFromComponent)(component, {
data: true,
functions: false,
getters: false,
});
// Append refs to data as { foo, bar, etc }
dataString = appendToDataString({
dataString,
newContent: (0, get_custom_imports_1.getCustomImports)(component).join(','),
});
if (localVarAsData.length) {
dataString = appendToDataString({ dataString, newContent: localVarAsData.join(',') });
}
const getterString = (0, get_state_object_string_1.getStateObjectStringFromComponent)(component, {
data: false,
getters: true,
functions: false,
});
let functionsString = (0, get_state_object_string_1.getStateObjectStringFromComponent)(component, {
data: false,
getters: false,
functions: true,
});
const includeClassMapHelper = template.includes('_classStringToObject');
if (includeClassMapHelper) {
functionsString = functionsString.replace(/}\s*$/, `_classStringToObject(str${isTs ? ': string' : ''}) {
const obj${isTs ? ': Record<string, boolean>' : ''} = {};
if (typeof str !== 'string') { return obj }
const classNames = str.trim().split(/\\s+/);
for (const name of classNames) {
obj[name] = true;
}
return obj;
} }`);
}
if (localVarAsFunc.length) {
functionsString = functionsString.replace(/}\s*$/, `${localVarAsFunc.join(',')}}`);
}
// Component references to include in `component: { YourComponent, ... }
const componentsUsedInTemplate = Array.from((0, get_components_used_1.getComponentsUsed)(component))
.filter((name) => name.length && !name.includes('.') && name[0].toUpperCase() === name[0])
// Strip out components that compile away
.filter((name) => !['For', 'Show', 'Fragment', 'Slot', component.name].includes(name));
// get default imports from component files
const importedComponents = component.imports
.filter(render_imports_1.checkIsComponentImport)
.map((imp) => { var _a; return (_a = Object.entries(imp.imports).find(([_, value]) => value === 'default')) === null || _a === void 0 ? void 0 : _a[0]; })
.filter(nullable_1.checkIsDefined);
const componentsUsed = (0, lodash_1.uniq)([...componentsUsedInTemplate, ...importedComponents]);
const getPropDefinition = ({ component, props, }) => {
const propsDefinition = Array.from(props).filter((prop) => prop !== 'children' && prop !== 'class');
let str = 'props: ';
if (component.defaultProps) {
const defalutPropsString = propsDefinition
.map((prop) => {
var _a;
const value = component.defaultProps.hasOwnProperty(prop)
? (_a = component.defaultProps[prop]) === null || _a === void 0 ? void 0 : _a.code
: 'undefined';
return `${prop}: { default: ${value} }`;
})
.join(',');
str += `{${defalutPropsString}}`;
}
else {
str += `${json5_1.default.stringify(propsDefinition)}`;
}
return `${str},`;
};
return `
export default ${options.defineComponent ? 'defineComponent(' : ''} {
${!component.name
? ''
: `name: '${path && ((_a = options.namePrefix) === null || _a === void 0 ? void 0 : _a.call(options, path)) ? ((_b = options.namePrefix) === null || _b === void 0 ? void 0 : _b.call(options, path)) + '-' : ''}${(0, lodash_1.kebabCase)(component.name)}',`}
${generateComponents(componentsUsed, options)}
${props.length ? getPropDefinition({ component, props }) : ''}
${dataString.length < 4
? ''
: `
data() {
return ${dataString}
},
`}
${(0, lodash_1.size)(component.context.set)
? `provide() {
const _this = this;
return ${getContextProvideString(component, options)}
},`
: ''}
${(0, lodash_1.size)(component.context.get)
? `inject: ${getContextInjectString(component, options)},`
: ''}
${((_c = component.hooks.onInit) === null || _c === void 0 ? void 0 : _c.code)
? `created() {
${component.hooks.onInit.code}
},`
: ''}
${component.hooks.onMount.length
? `mounted() {
${(0, on_mount_1.stringifySingleScopeOnMount)(component)}
},`
: ''}
${onUpdateWithoutDeps.length
? `updated() {
${onUpdateWithoutDeps.map((hook) => hook.code).join('\n')}
},`
: ''}
${onUpdateWithDeps.length
? `watch: {
${onUpdateWithDeps
.map((hook, index) => `${(0, helpers_1.getOnUpdateHookName)(index)}: { handler() { ${hook.code} }, immediate: true }`)
.join(',')}
},`
: ''}
${component.hooks.onUnMount
? `unmounted() {
${component.hooks.onUnMount.code}
},`
: ''}
${getterString.length < 4
? ''
: `
computed: ${getterString},
`}
${functionsString.length < 4
? ''
: `
methods: ${functionsString},
`}
${Object.entries(component.meta.vueConfig || {})
.map(([k, v]) => `${k}: ${v}`)
.join(',')}
}
${options.defineComponent ? ')' : ''}`;
}
exports.generateOptionsApiScript = generateOptionsApiScript;
;