Skip to content

Commit

Permalink
feat: Serialize Personalized Container in a JSX friendly way (#1566)
Browse files Browse the repository at this point in the history
  • Loading branch information
manucorporat authored Sep 27, 2024
1 parent b3d79af commit d15e0d6
Show file tree
Hide file tree
Showing 4 changed files with 403 additions and 2 deletions.
213 changes: 213 additions & 0 deletions packages/core/src/__tests__/__snapshots__/builder.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,219 @@ exports[`Builder > Section 1`] = `
"
`;
exports[`Builder > Snapshot PersonalizedContainer 1`] = `
{
"@type": "@builder.io/sdk:Element",
"actions": {},
"children": [
{
"@type": "@builder.io/sdk:Element",
"actions": {},
"bindings": {},
"children": [
{
"@type": "@builder.io/sdk:Element",
"bindings": {},
"component": {
"name": "Text",
"options": {
"text": "Default",
},
},
"tagName": "span",
},
],
"code": {
"actions": {},
"bindings": {},
},
"properties": {},
"tagName": "div",
},
{
"@type": "@builder.io/sdk:Element",
"actions": {},
"bindings": {},
"children": [
{
"@type": "@builder.io/sdk:Element",
"bindings": {},
"component": {
"name": "Text",
"options": {
"text": "More tree",
},
},
"tagName": "span",
},
],
"code": {
"actions": {},
"bindings": {},
},
"properties": {},
"tagName": "div",
},
],
"code": {
"actions": {},
"bindings": {},
},
"component": {
"name": "PersonalizationContainer",
"options": {
"variants": [
{
"blocks": [
{
"@type": "@builder.io/sdk:Element",
"actions": {},
"bindings": {},
"children": [
{
"@type": "@builder.io/sdk:Element",
"bindings": {},
"component": {
"name": "Text",
"options": {
"text": "Home",
},
},
"tagName": "span",
},
],
"code": {
"actions": {},
"bindings": {},
},
"properties": {},
"tagName": "div",
},
{
"@type": "@builder.io/sdk:Element",
"actions": {},
"bindings": {},
"children": [
{
"@type": "@builder.io/sdk:Element",
"bindings": {},
"component": {
"name": "Text",
"options": {
"text": "Div",
},
},
"tagName": "span",
},
],
"code": {
"actions": {},
"bindings": {},
},
"properties": {},
"tagName": "div",
},
],
"name": "variant1",
"query": [
{
"@type": "@builder.io/core:Query",
"operation": "is",
"property": "urlPath",
"value": "/home",
},
],
"startDate": "2024-01-01",
},
{
"blocks": [
{
"@type": "@builder.io/sdk:Element",
"actions": {},
"bindings": {},
"children": [
{
"@type": "@builder.io/sdk:Element",
"bindings": {},
"component": {
"name": "Text",
"options": {
"text": "Male",
},
},
"tagName": "span",
},
],
"code": {
"actions": {},
"bindings": {},
},
"component": {
"name": "Fragment",
"options": {},
},
},
],
"name": "2",
"query": [
{
"@type": "@builder.io/core:Query",
"operation": "is",
"property": "gendr",
"value": [
"male",
"female",
],
},
],
},
],
},
},
}
`;
exports[`Builder > Snapshot PersonalizedContainer 2`] = `
"import { PersonalizationContainer, Variant, Fragment } from \\"@components\\";
export default function MyComponent(props) {
return (
<PersonalizationContainer>
<Variant
name=\\"variant1\\"
startDate=\\"2024-01-01\\"
query={[
{
property: \\"urlPath\\",
operation: \\"is\\",
value: \\"/home\\",
},
]}
>
<div>Home</div>
<div>Div</div>
</Variant>
<Variant
name=\\"2\\"
query={[
{
property: \\"gendr\\",
operation: \\"is\\",
value: [\\"male\\", \\"female\\"],
},
]}
>
<Fragment>Male</Fragment>
</Variant>
<Variant default=\\"\\">
<div>Default</div>
<div>More tree</div>
</Variant>
</PersonalizationContainer>
);
}"
`;
exports[`Builder > Stamped 1`] = `
{
"data": {
Expand Down
92 changes: 91 additions & 1 deletion packages/core/src/__tests__/builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ describe('Builder', () => {
.foo {
background: green;
}
.bar {
font-weight: bold;
}
Expand All @@ -456,6 +456,96 @@ describe('Builder', () => {
const jsxToMitosis = parseJsx(jsx);
expect(jsxToMitosis.style).toMatchSnapshot();
});

test('Snapshot PersonalizedContainer', () => {
const code = dedent`
import { PersonalizationContainer, Variant } from "@components";
export default function MyComponent(props) {
return (
<PersonalizationContainer>
<Variant
name="variant1"
startDate="2024-01-01"
query={{
property: "urlPath",
operation: "is",
value: "/home",
}}
>
<div>Home</div>
<div>Div</div>
</Variant>
<PersonalizationOption
name="2"
query={[
{
property: "gendr",
operation: "is",
value: ["male", "female"],
},
]}
>
<>Male</>
</PersonalizationOption>
<Variant>
<div>Default</div>
</Variant>
<div>More tree</div>
</PersonalizationContainer>
);
}
`;

const component = parseJsx(code);
const builderJson = componentToBuilder()({ component });
expect(builderJson.data?.blocks?.[0]).toMatchSnapshot();

const backToMitosis = builderContentToMitosisComponent(builderJson);
const mitosis = componentToMitosis(mitosisOptions)({
component: backToMitosis,
});
expect(mitosis.trim()).toMatchSnapshot();
});

test('Regenerate PersonalizedContainer', () => {
const code = dedent`
import { PersonalizationContainer, Variant } from "@components";
export default function MyComponent(props) {
return (
<PersonalizationContainer>
<Variant
name="2"
startDate="2024-01-01"
endDate="2024-01-31"
query={[
{
property: "gendr",
operation: "is",
value: "male",
},
]}
>
<div>Male</div>
</Variant>
<Variant default="">
<div>Default</div>
</Variant>
</PersonalizationContainer>
);
}
`;

const component = parseJsx(code);
const builderJson = componentToBuilder()({ component });
const backToMitosis = builderContentToMitosisComponent(builderJson);
const mitosis = componentToMitosis(mitosisOptions)({
component: backToMitosis,
});
expect(mitosis.trim()).toEqual(code.trim());
});
});

const bindingJson = {
Expand Down
53 changes: 52 additions & 1 deletion packages/core/src/generators/builder/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,57 @@ const componentMappers: {

return block;
},
PersonalizationContainer(node, options) {
const block = blockToBuilder(node, options, { skipMapper: true });
// console.log('block', node);
const variants: any[] = [];
let defaultVariant: BuilderElement[] = [];
const validFakeNodeNames = [
'Variant',
'PersonalizationOption',
'PersonalizationVariant',
'Personalization',
];
block.children!.forEach((item) => {
console.log('item', item);
if (item.component && validFakeNodeNames.includes(item.component?.name)) {
let query: any;
if (item.component.options.query) {
const optionsQuery = item.component.options.query;
if (Array.isArray(optionsQuery)) {
query = optionsQuery.map((q) => ({
'@type': '@builder.io/core:Query',
...q,
}));
} else {
query = [
{
'@type': '@builder.io/core:Query',
...optionsQuery,
},
];
}
const newVariant = {
...item.component.options,
query,
blocks: item.children,
};
variants.push(newVariant);
} else if (item.children) {
defaultVariant.push(...item.children);
}
} else {
defaultVariant.push(item);
}
});
delete block.properties;
delete block.bindings;

block.component!.options.variants = variants;
block.children = defaultVariant;

return block;
},
For(_node, options) {
// rename `index` var to `state.$index`
const replaceIndex = (node: MitosisNode) => {
Expand Down Expand Up @@ -336,7 +387,7 @@ export const componentToBuilder =
${!hasProps(component) ? '' : `var props = state;`}
${!hasState ? '' : `Object.assign(state, ${getStateObjectStringFromComponent(component)});`}
${stringifySingleScopeOnMount(component)}
`),
tsCode: tryFormat(dedent`
Expand Down
Loading

0 comments on commit d15e0d6

Please sign in to comment.