Closes #6181 ## Testing - download Altair graphql dev tool https://altairgraphql.dev/#download - create a file locally `test.ts` containing: ``` export const handler = async (event: object, context: object) => { return { test: 'toto', data: event['data'] }; } ``` - play those requests in Altair: mutation UpsertFunction($file: Upload!) { upsertFunction(name: "toto", file: $file) } mutation ExecFunction { executeFunction(name:"toto", payload: {data: "titi"}) } - it will run the local driver, add those env variable to test with lambda driver ``` CUSTOM_CODE_ENGINE_DRIVER_TYPE=lambda LAMBDA_REGION=eu-west-2 LAMBDA_ROLE=<ASK_ME> ```
113 lines
3.5 KiB
TypeScript
113 lines
3.5 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
|
|
import { join } from 'path';
|
|
|
|
import { FileUpload } from 'graphql-upload';
|
|
import { Repository } from 'typeorm';
|
|
|
|
import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface';
|
|
|
|
import { ServerlessService } from 'src/engine/integrations/serverless/serverless.service';
|
|
import {
|
|
ServerlessFunctionEntity,
|
|
ServerlessFunctionSyncStatus,
|
|
} from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
|
|
import {
|
|
ServerlessFunctionException,
|
|
ServerlessFunctionExceptionCode,
|
|
} from 'src/engine/metadata-modules/serverless-function/serverless-function.exception';
|
|
import { readFileContent } from 'src/engine/integrations/file-storage/utils/read-file-content';
|
|
import { FileStorageService } from 'src/engine/integrations/file-storage/file-storage.service';
|
|
import { SOURCE_FILE_NAME } from 'src/engine/integrations/serverless/drivers/constants/source-file-name';
|
|
import { serverlessFunctionCreateHash } from 'src/engine/metadata-modules/serverless-function/utils/serverless-function-create-hash.utils';
|
|
|
|
@Injectable()
|
|
export class ServerlessFunctionService {
|
|
constructor(
|
|
private readonly fileStorageService: FileStorageService,
|
|
private readonly serverlessService: ServerlessService,
|
|
@InjectRepository(ServerlessFunctionEntity, 'metadata')
|
|
private readonly serverlessFunctionRepository: Repository<ServerlessFunctionEntity>,
|
|
) {}
|
|
|
|
async executeOne(
|
|
name: string,
|
|
workspaceId: string,
|
|
payload: object | undefined = undefined,
|
|
) {
|
|
const functionToExecute = await this.serverlessFunctionRepository.findOne({
|
|
where: {
|
|
name,
|
|
workspaceId,
|
|
},
|
|
});
|
|
|
|
if (!functionToExecute) {
|
|
throw new ServerlessFunctionException(
|
|
`Function does not exist`,
|
|
ServerlessFunctionExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND,
|
|
);
|
|
}
|
|
|
|
if (
|
|
functionToExecute.syncStatus === ServerlessFunctionSyncStatus.NOT_READY
|
|
) {
|
|
throw new ServerlessFunctionException(
|
|
`Function is not ready to be executed`,
|
|
ServerlessFunctionExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND,
|
|
);
|
|
}
|
|
|
|
return this.serverlessService.execute(functionToExecute, payload);
|
|
}
|
|
|
|
async createOne(
|
|
name: string,
|
|
workspaceId: string,
|
|
{ createReadStream, mimetype }: FileUpload,
|
|
) {
|
|
const existingServerlessFunction =
|
|
await this.serverlessFunctionRepository.findOne({
|
|
where: { name, workspaceId },
|
|
});
|
|
|
|
if (existingServerlessFunction) {
|
|
throw new ServerlessFunctionException(
|
|
`Function already exists`,
|
|
ServerlessFunctionExceptionCode.SERVERLESS_FUNCTION_ALREADY_EXIST,
|
|
);
|
|
}
|
|
|
|
const typescriptCode = await readFileContent(createReadStream());
|
|
|
|
const serverlessFunction = await this.serverlessFunctionRepository.save({
|
|
name,
|
|
workspaceId,
|
|
sourceCodeHash: serverlessFunctionCreateHash(typescriptCode),
|
|
});
|
|
|
|
const fileFolder = join(
|
|
FileFolder.ServerlessFunction,
|
|
workspaceId,
|
|
serverlessFunction.id,
|
|
);
|
|
|
|
await this.fileStorageService.write({
|
|
file: typescriptCode,
|
|
name: SOURCE_FILE_NAME,
|
|
mimeType: mimetype,
|
|
folder: fileFolder,
|
|
});
|
|
|
|
await this.serverlessService.build(serverlessFunction);
|
|
await this.serverlessFunctionRepository.update(serverlessFunction.id, {
|
|
syncStatus: ServerlessFunctionSyncStatus.READY,
|
|
});
|
|
|
|
return await this.serverlessFunctionRepository.findOneByOrFail({
|
|
id: serverlessFunction.id,
|
|
});
|
|
}
|
|
}
|