Skip to content

Commit 873a4c1

Browse files
authored
Fix serverless save when name empty (#6720)
- fix serverless function error on save when name empty - remove useless unique constraint on serverless function names
1 parent 5d8162d commit 873a4c1

File tree

8 files changed

+38
-24
lines changed

8 files changed

+38
-24
lines changed

packages/twenty-front/src/modules/settings/serverless-functions/hooks/__tests__/useServerlessFunctionUpdateFormState.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ describe('useServerlessFunctionUpdateFormState', () => {
4242
},
4343
);
4444

45-
const [formValues] = result.current;
45+
const { formValues } = result.current;
4646

4747
expect(formValues).toEqual({ name: '', description: '', code: '' });
4848
});

packages/twenty-front/src/modules/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ type SetServerlessFunctionFormValues = Dispatch<
1818

1919
export const useServerlessFunctionUpdateFormState = (
2020
serverlessFunctionId: string,
21-
): [ServerlessFunctionFormValues, SetServerlessFunctionFormValues] => {
21+
): {
22+
formValues: ServerlessFunctionFormValues;
23+
setFormValues: SetServerlessFunctionFormValues;
24+
loading: boolean;
25+
} => {
2226
const [formValues, setFormValues] = useState<ServerlessFunctionFormValues>({
2327
name: '',
2428
description: '',
@@ -28,7 +32,7 @@ export const useServerlessFunctionUpdateFormState = (
2832
const { serverlessFunction } =
2933
useGetOneServerlessFunction(serverlessFunctionId);
3034

31-
useGetOneServerlessFunctionSourceCode({
35+
const { loading } = useGetOneServerlessFunctionSourceCode({
3236
id: serverlessFunctionId,
3337
version: 'draft',
3438
onCompleted: (data: FindOneServerlessFunctionSourceCodeQuery) => {
@@ -44,5 +48,5 @@ export const useServerlessFunctionUpdateFormState = (
4448
},
4549
});
4650

47-
return [formValues, setFormValues];
51+
return { formValues, setFormValues, loading };
4852
};

packages/twenty-front/src/pages/settings/serverless-functions/SettingsServerlessFunctionDetail.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { isDefined } from '~/utils/isDefined';
2323
import { useDebouncedCallback } from 'use-debounce';
2424
import { useGetOneServerlessFunctionSourceCode } from '@/settings/serverless-functions/hooks/useGetOneServerlessFunctionSourceCode';
2525
import { useState } from 'react';
26+
import isEmpty from 'lodash.isempty';
2627

2728
const TAB_LIST_COMPONENT_ID = 'serverless-function-detail';
2829

@@ -37,7 +38,7 @@ export const SettingsServerlessFunctionDetail = () => {
3738
const { executeOneServerlessFunction } = useExecuteOneServerlessFunction();
3839
const { updateOneServerlessFunction } = useUpdateOneServerlessFunction();
3940
const { publishOneServerlessFunction } = usePublishOneServerlessFunction();
40-
const [formValues, setFormValues] =
41+
const { formValues, setFormValues, loading } =
4142
useServerlessFunctionUpdateFormState(serverlessFunctionId);
4243
const { code: latestVersionCode } = useGetOneServerlessFunctionSourceCode({
4344
id: serverlessFunctionId,
@@ -52,6 +53,9 @@ export const SettingsServerlessFunctionDetail = () => {
5253

5354
const save = async () => {
5455
try {
56+
if (isEmpty(formValues.name)) {
57+
return;
58+
}
5559
await updateOneServerlessFunction({
5660
id: serverlessFunctionId,
5761
name: formValues.name,
@@ -201,7 +205,7 @@ export const SettingsServerlessFunctionDetail = () => {
201205
};
202206

203207
return (
204-
formValues.name && (
208+
!loading && (
205209
<SubMenuTopBarContainer
206210
Icon={IconFunction}
207211
title={
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { MigrationInterface, QueryRunner } from 'typeorm';
2+
3+
export class RemoveServerlessFunctionUniqueConstraint1724423248330
4+
implements MigrationInterface
5+
{
6+
name = 'RemoveServerlessFunctionUniqueConstraint1724423248330';
7+
8+
public async up(queryRunner: QueryRunner): Promise<void> {
9+
await queryRunner.query(
10+
`ALTER TABLE "metadata"."serverlessFunction" DROP CONSTRAINT "IndexOnNameAndWorkspaceIdUnique"`,
11+
);
12+
}
13+
14+
public async down(queryRunner: QueryRunner): Promise<void> {
15+
await queryRunner.query(
16+
`ALTER TABLE "metadata"."serverlessFunction" ADD CONSTRAINT "IndexOnNameAndWorkspaceIdUnique" UNIQUE ("name", "workspaceId")`,
17+
);
18+
}
19+
}

packages/twenty-server/src/engine/integrations/serverless/drivers/local.driver.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable no-console */
12
import { join } from 'path';
23
import { tmpdir } from 'os';
34
import { promises as fs } from 'fs';
@@ -137,7 +138,7 @@ export class LocalDriver
137138
});
138139
}
139140
child.kill();
140-
fs.unlink(tmpFilePath);
141+
fs.unlink(tmpFilePath).catch(console.error);
141142
});
142143

143144
child.stderr?.on('data', (data) => {
@@ -169,19 +170,19 @@ export class LocalDriver
169170
},
170171
});
171172
child.kill();
172-
fs.unlink(tmpFilePath);
173+
fs.unlink(tmpFilePath).catch(console.error);
173174
});
174175

175176
child.on('error', (error) => {
176177
reject(error);
177178
child.kill();
178-
fs.unlink(tmpFilePath);
179+
fs.unlink(tmpFilePath).catch(console.error);
179180
});
180181

181182
child.on('exit', (code) => {
182183
if (code && code !== 0) {
183184
reject(new Error(`Child process exited with code ${code}`));
184-
fs.unlink(tmpFilePath);
185+
fs.unlink(tmpFilePath).catch(console.error);
185186
}
186187
});
187188

packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/update-serverless-function.input.ts

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ export class UpdateServerlessFunctionInput {
2323
description?: string;
2424

2525
@IsString()
26-
@IsNotEmpty()
2726
@Field()
2827
code: string;
2928
}

packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.entity.ts

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ export enum ServerlessFunctionRuntime {
1717
}
1818

1919
@Entity('serverlessFunction')
20-
@Unique('IndexOnNameAndWorkspaceIdUnique', ['name', 'workspaceId'])
2120
export class ServerlessFunctionEntity {
2221
@PrimaryGeneratedColumn('uuid')
2322
id: string;

packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.service.ts

-12
Original file line numberDiff line numberDiff line change
@@ -240,18 +240,6 @@ export class ServerlessFunctionService extends TypeOrmQueryService<ServerlessFun
240240
code: FileUpload | string,
241241
workspaceId: string,
242242
) {
243-
const existingServerlessFunction =
244-
await this.serverlessFunctionRepository.findOne({
245-
where: { name: serverlessFunctionInput.name, workspaceId },
246-
});
247-
248-
if (existingServerlessFunction) {
249-
throw new ServerlessFunctionException(
250-
`Function already exists`,
251-
ServerlessFunctionExceptionCode.SERVERLESS_FUNCTION_ALREADY_EXIST,
252-
);
253-
}
254-
255243
let typescriptCode: string;
256244

257245
if (typeof code === 'string') {

0 commit comments

Comments
 (0)