Skip to content

Commit

Permalink
fix: issue with "npm run build" for @builder.io/mitosis (#1532)
Browse files Browse the repository at this point in the history
* fix: issue with "npm build" for @builder.io/mitosis

* chore: revert old .lock file

* chore: update tsconfig.json

* f

* f

f

---------

Co-authored-by: Sami Jaber <[email protected]>
  • Loading branch information
nmerget and samijaber authored Aug 22, 2024
1 parent 0f2ab2a commit 6962c36
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 66 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ packages/core/src/__tests__/__snapshots__/local.test.ts.snap

.nx/cache
.nx-cache
.nx/workspace-data
2 changes: 1 addition & 1 deletion packages/core/src/helpers/get-prop-functions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import traverse from 'neotraverse/legacy';
import { MitosisComponent } from '../types/mitosis-component';

const propsRegex = /props\s*\.\s*([a-zA-Z0-9_\4]+)\(/;
const propsRegex = /props\s*\.\s*([a-zA-Z0-9_\x04]+)\(/;
const allPropsMatchesRegex = new RegExp(propsRegex, 'g');

/**
Expand Down
110 changes: 62 additions & 48 deletions packages/core/src/parsers/jsx/state.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,40 @@
import * as babel from '@babel/core';
// import generate from '@babel/generator';
import { babelTransformExpression } from '@/helpers/babel-transform';
import { capitalize } from '@/helpers/capitalize';
import { isMitosisNode } from '@/helpers/is-mitosis-node';
import { createCodeProcessorPlugin } from '@/helpers/plugins/process-code';
import { MitosisComponent, MitosisState, StateValue } from '@/types/mitosis-component';
import { NodePath } from '@babel/core';
import {
BlockStatement,
Expression,
Node,
ObjectExpression,
ObjectMethod,
ObjectProperty,
assignmentExpression,
identifier,
isArrowFunctionExpression,
isDeclaration,
isFunctionDeclaration,
isFunctionExpression,
isIdentifier,
isMemberExpression,
isObjectMethod,
isObjectProperty,
isOptionalMemberExpression,
isPrivateName,
isSpreadElement,
isTSAsExpression,
isTSInterfaceBody,
isTSType,
memberExpression,
objectMethod,
} from '@babel/types';
import { MitosisNode } from '@builder.io/mitosis';
import { pipe } from 'fp-ts/lib/function';
import traverse from 'neotraverse/legacy';
import { babelTransformExpression } from '../../helpers/babel-transform';
import { capitalize } from '../../helpers/capitalize';
import { isMitosisNode } from '../../helpers/is-mitosis-node';
import { createCodeProcessorPlugin } from '../../helpers/plugins/process-code';
import { MitosisComponent, MitosisState, StateValue } from '../../types/mitosis-component';
import { parseCode, uncapitalize } from './helpers';

const { types } = babel;

function mapStateIdentifiersInExpression(expression: string, stateProperties: string[]) {
const setExpressions = stateProperties.map((propertyName) => `set${capitalize(propertyName)}`);

Expand All @@ -21,20 +44,18 @@ function mapStateIdentifiersInExpression(expression: string, stateProperties: st
if (stateProperties.includes(path.node.name)) {
if (
// ignore member expressions, as the `stateProperty` is going to be at the module scope.
!(types.isMemberExpression(path.parent) && path.parent.property === path.node) &&
!(
types.isOptionalMemberExpression(path.parent) && path.parent.property === path.node
) &&
!(isMemberExpression(path.parent) && path.parent.property === path.node) &&
!(isOptionalMemberExpression(path.parent) && path.parent.property === path.node) &&
// ignore declarations of that state property, e.g. `function foo() {}`
!types.isDeclaration(path.parent) &&
!types.isFunctionDeclaration(path.parent) &&
!(types.isFunctionExpression(path.parent) && path.parent.id === path.node) &&
!isDeclaration(path.parent) &&
!isFunctionDeclaration(path.parent) &&
!(isFunctionExpression(path.parent) && path.parent.id === path.node) &&
// ignore object keys
!(types.isObjectProperty(path.parent) && path.parent.key === path.node)
!(isObjectProperty(path.parent) && path.parent.key === path.node)
) {
let hasTypeParent = false;
path.findParent((parent) => {
if (types.isTSType(parent) || types.isTSInterfaceBody(parent)) {
path.findParent((parent: NodePath) => {
if (isTSType(parent as Node) || isTSInterfaceBody(parent as Node)) {
hasTypeParent = true;
return true;
}
Expand All @@ -45,10 +66,7 @@ function mapStateIdentifiersInExpression(expression: string, stateProperties: st
return;
}

const newExpression = types.memberExpression(
types.identifier('state'),
types.identifier(path.node.name),
);
const newExpression = memberExpression(identifier('state'), identifier(path.node.name));
try {
path.replaceWith(newExpression);
} catch (err) {
Expand All @@ -65,16 +83,16 @@ function mapStateIdentifiersInExpression(expression: string, stateProperties: st
}
},
CallExpression(path) {
if (types.isIdentifier(path.node.callee)) {
if (isIdentifier(path.node.callee)) {
if (setExpressions.includes(path.node.callee.name)) {
// setFoo -> foo
const statePropertyName = uncapitalize(path.node.callee.name.slice(3));

// setFoo(...) -> state.foo = ...
path.replaceWith(
types.assignmentExpression(
assignmentExpression(
'=',
types.identifier(`state.${statePropertyName}`),
identifier(`state.${statePropertyName}`),
path.node.arguments[0] as any,
),
);
Expand Down Expand Up @@ -133,21 +151,19 @@ export function mapStateIdentifiers(json: MitosisComponent) {
});
}

const processStateObjectSlice = (
item: babel.types.ObjectMethod | babel.types.ObjectProperty,
): StateValue => {
if (types.isObjectProperty(item)) {
if (types.isFunctionExpression(item.value)) {
const processStateObjectSlice = (item: ObjectMethod | ObjectProperty): StateValue => {
if (isObjectProperty(item)) {
if (isFunctionExpression(item.value)) {
return {
code: parseCode(item.value).trim(),
type: 'function',
};
} else if (types.isArrowFunctionExpression(item.value)) {
const n = babel.types.objectMethod(
} else if (isArrowFunctionExpression(item.value)) {
const n = objectMethod(
'method',
item.key as babel.types.Expression,
item.key as Expression,
item.value.params,
item.value.body as babel.types.BlockStatement,
item.value.body as BlockStatement,
);
const code = parseCode(n).trim();
return {
Expand All @@ -157,7 +173,7 @@ const processStateObjectSlice = (
} else {
// Remove typescript types, e.g. from
// { foo: ('string' as SomeType) }
if (types.isTSAsExpression(item.value)) {
if (isTSAsExpression(item.value)) {
return {
code: parseCode(item.value.expression).trim(),
type: 'property',
Expand All @@ -170,7 +186,7 @@ const processStateObjectSlice = (
propertyType: 'normal',
};
}
} else if (types.isObjectMethod(item)) {
} else if (isObjectMethod(item)) {
const n = parseCode({ ...item, returnType: null }).trim();

const isGetter = item.kind === 'get';
Expand All @@ -184,19 +200,17 @@ const processStateObjectSlice = (
}
};

const processDefaultPropsSlice = (
item: babel.types.ObjectMethod | babel.types.ObjectProperty,
): StateValue => {
if (types.isObjectProperty(item)) {
if (types.isFunctionExpression(item.value) || types.isArrowFunctionExpression(item.value)) {
const processDefaultPropsSlice = (item: ObjectMethod | ObjectProperty): StateValue => {
if (isObjectProperty(item)) {
if (isFunctionExpression(item.value) || isArrowFunctionExpression(item.value)) {
return {
code: parseCode(item.value),
type: 'method',
};
} else {
// Remove typescript types, e.g. from
// { foo: ('string' as SomeType) }
if (types.isTSAsExpression(item.value)) {
if (isTSAsExpression(item.value)) {
return {
code: parseCode(item.value.expression),
type: 'property',
Expand All @@ -209,7 +223,7 @@ const processDefaultPropsSlice = (
propertyType: 'normal',
};
}
} else if (types.isObjectMethod(item)) {
} else if (isObjectMethod(item)) {
const n = parseCode({ ...item, returnType: null });

const isGetter = item.kind === 'get';
Expand All @@ -224,20 +238,20 @@ const processDefaultPropsSlice = (
};

export const parseStateObjectToMitosisState = (
object: babel.types.ObjectExpression,
object: ObjectExpression,
isState: boolean = true, // parse state or defaultProps
): MitosisState => {
const state: MitosisState = {};
object.properties.forEach((x) => {
if (types.isSpreadElement(x)) {
if (isSpreadElement(x)) {
throw new Error('Parse Error: Mitosis cannot consume spread element in state object: ' + x);
}

if (types.isPrivateName(x.key)) {
if (isPrivateName(x.key)) {
throw new Error('Parse Error: Mitosis cannot consume private name in state object: ' + x.key);
}

if (!types.isIdentifier(x.key)) {
if (!isIdentifier(x.key)) {
throw new Error(
'Parse Error: Mitosis cannot consume non-identifier key in state object: ' + x.key,
);
Expand Down
42 changes: 27 additions & 15 deletions packages/core/src/parsers/svelte/instance/functions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { isAssignmentExpression, isIdentifier, isUpdateExpression } from '@babel/types';
import {
AssignmentExpression,
isAssignmentExpression,
isIdentifier,
isUpdateExpression,
Node,
UpdateExpression,
} from '@babel/types';
import { generate } from 'astring';
import type { CallExpression, FunctionDeclaration, Identifier } from 'estree';
import { capitalize } from 'lodash';
Expand All @@ -22,30 +29,35 @@ export function parseFunctions(json: SveltosisComponent, node: FunctionDeclarati
const callee = node_.callee as Identifier;

if (callee?.name === 'dispatch') {
const event = generate(node_.arguments[0]);
dispatchEventName = event;
dispatchEventName = generate(node_.arguments[0]);
}
break;
}
case 'UpdateExpression': {
if (isUpdateExpression(node) && isIdentifier(node.argument)) {
const argument = node.argument.name;
if (node.operator === '++') {
code = code.replace('++', ` = ${argument} + 1`);
} else if (node.operator === '--') {
code = code.replace('--', ` = ${argument} - 1`);
if (isUpdateExpression(node as Node)) {
const expression = node as UpdateExpression;
if (isIdentifier(expression.argument)) {
const argument = expression.argument.name;
if (expression.operator === '++') {
code = code.replace('++', ` = ${argument} + 1`);
} else if (expression.operator === '--') {
code = code.replace('--', ` = ${argument} - 1`);
}
}
}
break;
}
case 'AssignmentExpression': {
if (isAssignmentExpression(node) && isIdentifier(node.left)) {
const argument = node.left.name;
if (isAssignmentExpression(node as Node)) {
const expression = node as AssignmentExpression;
if (isIdentifier(expression.left)) {
const argument = expression.left.name;

if (node.operator === '+=') {
code = code.replace('+=', `= ${argument} +`);
} else if (node.operator === '-=') {
code = code.replace('-=', `= ${argument} -`);
if (expression.operator === '+=') {
code = code.replace('+=', `= ${argument} +`);
} else if (expression.operator === '-=') {
code = code.replace('-=', `= ${argument} -`);
}
}
}
break;
Expand Down
7 changes: 5 additions & 2 deletions packages/core/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@
"skipDefaultLibCheck": true,
"exactOptionalPropertyTypes": false,
"esModuleInterop": true,
"target": "ES5",
"target": "ES2018",
"baseUrl": ".",
"paths": {
"@builder.io/mitosis": ["./src"],
"@/*": ["./src/*"],
// To avoid error from moduleResolution: NodeNext
"svelte/types/compiler/interfaces": ["./node_modules/svelte/types/compiler/interfaces"]
"svelte/types/compiler/interfaces": [
"./node_modules/svelte/types/compiler/interfaces",
"../../node_modules/svelte/types/compiler/interfaces"
]
},
"jsxImportSource": "@builder.io/mitosis",
"types": ["vitest/globals"]
Expand Down

0 comments on commit 6962c36

Please sign in to comment.