Skip to content

Commit

Permalink
fix(sdks): serialize single arg functions with no parens correctly (#…
Browse files Browse the repository at this point in the history
…3729)

a single argument arrow function without parens would cause this invalid
js syntax
```js
return (function e=>!0===e.get(\"isABTest\")).apply(this, arguments)
```
  • Loading branch information
teleaziz authored Nov 12, 2024
1 parent b72f445 commit 9b11521
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 2 deletions.
14 changes: 14 additions & 0 deletions .changeset/empty-ligers-look.md
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions packages/core/src/builder.class.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,16 @@ 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: [
{
name: 'number',
type: 'number',
onChange: (value: number) => value * 2,
showIf: fn,
},
],
};
Expand All @@ -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', () => {
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/builder.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)`;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
{
Expand Down
3 changes: 3 additions & 0 deletions packages/sdks/src/functions/register-component.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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' }],
Expand All @@ -71,6 +73,7 @@ describe('Component Registration and Serialization', () => {
func3(x: number) {
return x - 1;
},
func4: fn,
},
// Add other required fields as necessary
};
Expand Down
6 changes: 5 additions & 1 deletion packages/sdks/src/functions/register-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)`;
};
Expand Down

0 comments on commit 9b11521

Please sign in to comment.