Add error marker when invalid main function (#9489)
## Before  ## After 
This commit is contained in:
@ -8,6 +8,7 @@ import { WorkflowCodeAction } from '@/workflow/types/Workflow';
|
||||
import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
|
||||
import { setNestedValue } from '@/workflow/workflow-steps/workflow-actions/utils/setNestedValue';
|
||||
|
||||
import { Monaco } from '@monaco-editor/react';
|
||||
import { CmdEnterActionButton } from '@/action-menu/components/CmdEnterActionButton';
|
||||
import { ServerlessFunctionExecutionResult } from '@/serverless-functions/components/ServerlessFunctionExecutionResult';
|
||||
import { INDEX_FILE_PATH } from '@/serverless-functions/constants/IndexFilePath';
|
||||
@ -26,13 +27,13 @@ import { WORKFLOW_SERVERLESS_FUNCTION_TAB_LIST_COMPONENT_ID } from '@/workflow/w
|
||||
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { Monaco } from '@monaco-editor/react';
|
||||
import { editor } from 'monaco-editor';
|
||||
import { AutoTypings } from 'monaco-editor-auto-typings';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { CodeEditor, IconCode, IconPlayerPlay, isDefined } from 'twenty-ui';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
import { getWrongExportedFunctionMarkers } from '@/workflow/workflow-steps/workflow-actions/utils/getWrongExportedFunctionMarkers';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
@ -299,6 +300,7 @@ export const WorkflowEditActionFormServerlessFunction = ({
|
||||
language={'typescript'}
|
||||
onChange={handleCodeChange}
|
||||
onMount={handleEditorDidMount}
|
||||
setMarkers={getWrongExportedFunctionMarkers}
|
||||
options={{
|
||||
readOnly: actionOptions.readonly,
|
||||
domReadOnly: actionOptions.readonly,
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
import { getWrongExportedFunctionMarkers } from '@/workflow/workflow-steps/workflow-actions/utils/getWrongExportedFunctionMarkers';
|
||||
|
||||
describe('getWrongExportedFunctionMarkers', () => {
|
||||
it('should return marker when no exported function', () => {
|
||||
const value = 'const main = async () => {}';
|
||||
const result = getWrongExportedFunctionMarkers(value);
|
||||
expect(result.length).toEqual(1);
|
||||
expect(result[0].message).toEqual(
|
||||
'An exported "main" arrow function is required.',
|
||||
);
|
||||
});
|
||||
|
||||
it('should return marker when no wrong exported function', () => {
|
||||
const value = 'export const wrongMain = async () => {}';
|
||||
const result = getWrongExportedFunctionMarkers(value);
|
||||
expect(result.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('should return no marker when valid exported function', () => {
|
||||
const value = 'export const main = async () => {}';
|
||||
const result = getWrongExportedFunctionMarkers(value);
|
||||
expect(result.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('should return handle multiple spaces', () => {
|
||||
const value = 'export const main = async () => {}';
|
||||
const result = getWrongExportedFunctionMarkers(value);
|
||||
expect(result.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,60 @@
|
||||
import { isDefined } from 'twenty-ui';
|
||||
|
||||
const getSubstringCoordinate = (
|
||||
text: string,
|
||||
substring: string,
|
||||
): { line: number; column: number } | null => {
|
||||
const lines = text.split('\n');
|
||||
|
||||
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
||||
const columnIndex = lines[lineIndex].indexOf(substring);
|
||||
if (columnIndex !== -1) {
|
||||
return {
|
||||
line: lineIndex + 1, // 1-based line number
|
||||
column: columnIndex + 1, // 1-based column number
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export const getWrongExportedFunctionMarkers = (value: string) => {
|
||||
const validRegex = /export\s+const\s+main\s*=/g;
|
||||
const invalidRegex = /export\s+const\s+\S*/g;
|
||||
const exportRegex = /export\s+const/g;
|
||||
const validMatch = value.match(validRegex);
|
||||
const invalidMatch = value.match(invalidRegex);
|
||||
const exportMatch = value.match(exportRegex);
|
||||
const markers = [];
|
||||
|
||||
if (!validMatch && !!invalidMatch) {
|
||||
const coordinates = getSubstringCoordinate(value, invalidMatch[0]);
|
||||
if (isDefined(coordinates)) {
|
||||
const endColumn = invalidMatch[0].length + coordinates.column;
|
||||
markers.push({
|
||||
severity: 8, //MarkerSeverity.Error,
|
||||
message: 'Exported arrow function should be named "main"',
|
||||
code: 'export const main',
|
||||
startLineNumber: coordinates.line,
|
||||
startColumn: coordinates.column,
|
||||
endLineNumber: 1,
|
||||
endColumn,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!exportMatch) {
|
||||
markers.push({
|
||||
severity: 8, //MarkerSeverity.Error,
|
||||
message: 'An exported "main" arrow function is required.',
|
||||
code: 'export const main',
|
||||
startLineNumber: 1,
|
||||
startColumn: 1,
|
||||
endLineNumber: 1,
|
||||
endColumn: 1,
|
||||
});
|
||||
}
|
||||
|
||||
return markers;
|
||||
};
|
||||
Reference in New Issue
Block a user