diff --git a/.changeset/empty-ligers-look.md b/.changeset/empty-ligers-look.md new file mode 100644 index 00000000000..0b19ee1e460 --- /dev/null +++ b/.changeset/empty-ligers-look.md @@ -0,0 +1,14 @@ +--- +"@builder.io/sdk": patch +"@builder.io/react": patch +"@builder.io/sdk-angular": patch +"@builder.io/sdk-react-nextjs": patch +"@builder.io/sdk-qwik": patch +"@builder.io/sdk-react": patch +"@builder.io/sdk-react-native": patch +"@builder.io/sdk-solid": patch +"@builder.io/sdk-svelte": patch +"@builder.io/sdk-vue": patch +--- + +fix serializing single arg arrow functions that some compilers emit diff --git a/packages/core/src/builder.class.test.ts b/packages/core/src/builder.class.test.ts index f6924b58b92..80fe35d7f60 100644 --- a/packages/core/src/builder.class.test.ts +++ b/packages/core/src/builder.class.test.ts @@ -46,6 +46,8 @@ describe('serializeIncludingFunctions', () => { }); test('serializes arrow functions in inputs', () => { + // Using eval and template literal to prevent TypeScript from adding parens + const fn = eval(`(${`e => !0 === e.get("isABTest")`})`); const input = { name: 'ArrowComponent', inputs: [ @@ -53,6 +55,7 @@ describe('serializeIncludingFunctions', () => { name: 'number', type: 'number', onChange: (value: number) => value * 2, + showIf: fn, }, ], }; @@ -61,6 +64,9 @@ describe('serializeIncludingFunctions', () => { expect(typeof result.inputs[0].onChange).toBe('string'); expect(result.inputs[0].onChange).toContain('value * 2'); + expect(result.inputs[0].showIf).toBe( + `return (e => !0 === e.get(\"isABTest\")).apply(this, arguments)` + ); }); test('does not modify non-function properties', () => { diff --git a/packages/core/src/builder.class.ts b/packages/core/src/builder.class.ts index 155a7f19887..a0de81d3342 100644 --- a/packages/core/src/builder.class.ts +++ b/packages/core/src/builder.class.ts @@ -1101,7 +1101,10 @@ export class Builder { // 1. `function name(args) => {code}` // 2. `name(args) => {code}` // 3. `(args) => {}` - const appendFunction = !fnStr.startsWith('function') && !fnStr.startsWith('('); + // 4. `args => {}` + const isArrowWithoutParens = /^[a-zA-Z0-9_]+\s*=>/i.test(fnStr); + const appendFunction = + !fnStr.startsWith('function') && !fnStr.startsWith('(') && !isArrowWithoutParens; return `return (${appendFunction ? 'function ' : ''}${fnStr}).apply(this, arguments)`; }; diff --git a/packages/sdks/src/functions/__snapshots__/register-component.test.ts.snap b/packages/sdks/src/functions/__snapshots__/register-component.test.ts.snap index df278ead89d..914ad6aee90 100644 --- a/packages/sdks/src/functions/__snapshots__/register-component.test.ts.snap +++ b/packages/sdks/src/functions/__snapshots__/register-component.test.ts.snap @@ -42,6 +42,7 @@ exports[`Component Registration and Serialization > serializeFn handles differen "func3": "return (function func3(x) { return x - 1; }).apply(this, arguments)", + "func4": "return (e => !0 === e.get(\\"isABTest\\")).apply(this, arguments)", }, "inputs": [ { diff --git a/packages/sdks/src/functions/register-component.test.ts b/packages/sdks/src/functions/register-component.test.ts index 9b6c61b72a0..d594d94c34c 100644 --- a/packages/sdks/src/functions/register-component.test.ts +++ b/packages/sdks/src/functions/register-component.test.ts @@ -60,6 +60,8 @@ describe('Component Registration and Serialization', () => { }); test('serializeFn handles different function syntaxes', () => { + // Using eval and template literal to prevent TypeScript from adding parens + const fn = eval(`(${`e => !0 === e.get("isABTest")`})`); const mockComponentInfo: ComponentInfo = { name: 'SyntaxTestComponent', inputs: [{ name: 'testInput', type: 'string' }], @@ -71,6 +73,7 @@ describe('Component Registration and Serialization', () => { func3(x: number) { return x - 1; }, + func4: fn, }, // Add other required fields as necessary }; diff --git a/packages/sdks/src/functions/register-component.ts b/packages/sdks/src/functions/register-component.ts index 7be68ad9d56..4547b0e9324 100644 --- a/packages/sdks/src/functions/register-component.ts +++ b/packages/sdks/src/functions/register-component.ts @@ -13,8 +13,12 @@ const serializeFn = (fnValue: Function) => { // 1. `function name(args) => {code}` // 2. `name(args) => {code}` // 3. `(args) => {}` + // 4. `args => {}` + const isArrowWithoutParens = /^[a-zA-Z0-9_]+\s*=>/i.test(fnStr); const appendFunction = - !fnStr.startsWith('function') && !fnStr.startsWith('('); + !fnStr.startsWith('function') && + !fnStr.startsWith('(') && + !isArrowWithoutParens; return `return (${appendFunction ? 'function ' : ''}${fnStr}).apply(this, arguments)`; };