accepts any valid expression, not just an identifier (#22778)
Fixing and issue with front component definition look at the unit test to see the actual fix
This commit is contained in:
+87
@@ -0,0 +1,87 @@
|
||||
import { unwrapDefineFrontComponentToDirectExport } from '@/cli/utilities/build/common/front-component-build/utils/unwrap-define-front-component-to-direct-export';
|
||||
|
||||
const INLINE_EXPRESSION_COMPONENT_SOURCE = `import { defineFrontComponent } from 'twenty-sdk/define';
|
||||
|
||||
import { SUMMARIZE_COMPANY_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers';
|
||||
import { createSummarizeRecordEffect } from 'src/front-components/utils/create-summarize-record-effect';
|
||||
import { SUMMARIZE_TARGETS } from 'src/front-components/utils/summarize-target';
|
||||
|
||||
const SummarizeRecordEffect = createSummarizeRecordEffect(SUMMARIZE_TARGETS.company)
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: SUMMARIZE_COMPANY_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER,
|
||||
name: 'Summarize Company',
|
||||
description: 'Asks AI to summarize the selected company',
|
||||
isHeadless: true,
|
||||
component: createSummarizeRecordEffect(SUMMARIZE_TARGETS.company),
|
||||
});
|
||||
`;
|
||||
|
||||
const IDENTIFIER_COMPONENT_SOURCE = `import { defineFrontComponent } from 'twenty-sdk/define';
|
||||
|
||||
import { SUMMARIZE_COMPANY_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers';
|
||||
import { createSummarizeRecordEffect } from 'src/front-components/utils/create-summarize-record-effect';
|
||||
import { SUMMARIZE_TARGETS } from 'src/front-components/utils/summarize-target';
|
||||
|
||||
const SummarizeRecordEffect = createSummarizeRecordEffect(SUMMARIZE_TARGETS.company)
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: SUMMARIZE_COMPANY_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER,
|
||||
name: 'Summarize Company',
|
||||
description: 'Asks AI to summarize the selected company',
|
||||
isHeadless: true,
|
||||
component: SummarizeRecordEffect,
|
||||
});
|
||||
`;
|
||||
|
||||
describe('unwrapDefineFrontComponentToDirectExport', () => {
|
||||
it('renders the component when component is an inline factory call', () => {
|
||||
const output = unwrapDefineFrontComponentToDirectExport(
|
||||
INLINE_EXPRESSION_COMPONENT_SOURCE,
|
||||
);
|
||||
|
||||
expect(output).toContain(
|
||||
'component: createSummarizeRecordEffect(SUMMARIZE_TARGETS.company),',
|
||||
);
|
||||
expect(output).toContain(
|
||||
'__frontComponentJsx(__frontComponentDefinition.component, {})',
|
||||
);
|
||||
expect(output).not.toContain('defineFrontComponent');
|
||||
});
|
||||
|
||||
it('renders the component when component is a bare identifier', () => {
|
||||
const output = unwrapDefineFrontComponentToDirectExport(
|
||||
IDENTIFIER_COMPONENT_SOURCE,
|
||||
);
|
||||
|
||||
expect(output).toContain('component: SummarizeRecordEffect,');
|
||||
expect(output).toContain(
|
||||
'__frontComponentJsx(__frontComponentDefinition.component, {})',
|
||||
);
|
||||
expect(output).not.toContain('defineFrontComponent');
|
||||
});
|
||||
|
||||
it('produces an equivalent renderer for the inline and identifier forms', () => {
|
||||
const inlineOutput = unwrapDefineFrontComponentToDirectExport(
|
||||
INLINE_EXPRESSION_COMPONENT_SOURCE,
|
||||
);
|
||||
const identifierOutput = unwrapDefineFrontComponentToDirectExport(
|
||||
IDENTIFIER_COMPONENT_SOURCE,
|
||||
);
|
||||
|
||||
const renderer =
|
||||
'\nexport default function __renderFrontComponent(__container) { __createRoot(__container).render(__frontComponentJsx(__frontComponentDefinition.component, {})); }\n';
|
||||
|
||||
expect(inlineOutput).toContain(renderer);
|
||||
expect(identifierOutput).toContain(renderer);
|
||||
});
|
||||
|
||||
it('leaves a source without a defineFrontComponent default export untouched', () => {
|
||||
const source = `import { useEffect } from 'react';
|
||||
|
||||
export const createSummarizeRecordEffect = () => () => null;
|
||||
`;
|
||||
|
||||
expect(unwrapDefineFrontComponentToDirectExport(source)).toBe(source);
|
||||
});
|
||||
});
|
||||
+26
-21
@@ -1,8 +1,13 @@
|
||||
const DEFINE_FRONT_COMPONENT_IMPORT_PATTERN =
|
||||
/import\s*\{\s*defineFrontComponent\s*\}\s*from\s*['"][^'"]+['"];?\n?/g;
|
||||
|
||||
const DEFINE_FRONT_COMPONENT_EXPORT_PATTERN =
|
||||
/export\s+default\s+defineFrontComponent\s*\(\s*\{[\s\S]*?component\s*:\s*(\w+)[\s\S]*?\}\s*\)\s*;?/s;
|
||||
const DEFINE_FRONT_COMPONENT_EXPORT_OPENING_PATTERN =
|
||||
/export\s+default\s+defineFrontComponent\s*\(/;
|
||||
|
||||
const IDENTIFIER_COMPONENT_VALUE_PATTERN =
|
||||
/component\s*:\s*([A-Za-z_$][\w$]*)\s*[,}]/;
|
||||
|
||||
const FRONT_COMPONENT_DEFINITION_NAME = '__frontComponentDefinition';
|
||||
|
||||
export const unwrapDefineFrontComponentToDirectExport = (
|
||||
sourceCode: string,
|
||||
@@ -12,32 +17,32 @@ export const unwrapDefineFrontComponentToDirectExport = (
|
||||
'',
|
||||
);
|
||||
|
||||
const defineFrontComponentMatch = transformedSource.match(
|
||||
DEFINE_FRONT_COMPONENT_EXPORT_PATTERN,
|
||||
if (!DEFINE_FRONT_COMPONENT_EXPORT_OPENING_PATTERN.test(transformedSource)) {
|
||||
return transformedSource;
|
||||
}
|
||||
|
||||
transformedSource = transformedSource.replace(
|
||||
DEFINE_FRONT_COMPONENT_EXPORT_OPENING_PATTERN,
|
||||
`const ${FRONT_COMPONENT_DEFINITION_NAME} = (`,
|
||||
);
|
||||
|
||||
if (defineFrontComponentMatch) {
|
||||
const wrappedComponentName = defineFrontComponentMatch[1];
|
||||
const identifierComponentMatch = transformedSource.match(
|
||||
IDENTIFIER_COMPONENT_VALUE_PATTERN,
|
||||
);
|
||||
|
||||
const exportedComponentDeclarationPattern = new RegExp(
|
||||
`export\\s+(const|function)\\s+${wrappedComponentName}\\b`,
|
||||
);
|
||||
if (identifierComponentMatch) {
|
||||
const wrappedComponentName = identifierComponentMatch[1];
|
||||
|
||||
transformedSource = transformedSource.replace(
|
||||
exportedComponentDeclarationPattern,
|
||||
new RegExp(`export\\s+(const|function)\\s+${wrappedComponentName}\\b`),
|
||||
`$1 ${wrappedComponentName}`,
|
||||
);
|
||||
|
||||
transformedSource =
|
||||
`import { createRoot as __createRoot } from 'react-dom/client';\n` +
|
||||
`import { jsx as __frontComponentJsx } from 'react/jsx-runtime';\n` +
|
||||
transformedSource;
|
||||
|
||||
transformedSource = transformedSource.replace(
|
||||
DEFINE_FRONT_COMPONENT_EXPORT_PATTERN,
|
||||
`export default function __renderFrontComponent(__container) { __createRoot(__container).render(__frontComponentJsx(${wrappedComponentName}, {})); }`,
|
||||
);
|
||||
}
|
||||
|
||||
return transformedSource;
|
||||
return (
|
||||
`import { createRoot as __createRoot } from 'react-dom/client';\n` +
|
||||
`import { jsx as __frontComponentJsx } from 'react/jsx-runtime';\n` +
|
||||
transformedSource +
|
||||
`\nexport default function __renderFrontComponent(__container) { __createRoot(__container).render(__frontComponentJsx(${FRONT_COMPONENT_DEFINITION_NAME}.component, {})); }\n`
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user