Files
twenty/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-create-serverless-function-input-to-flat-serverless-function.util.ts
T
martmull f92c8a98a4 2114 extensibility manage serverless execution from built code (#17317)
Summary

- Serverless functions are now built when created/updated instead of at
execution time
  - Added builtHandlerPath field to track pre-built function artifacts
- Renamed base-typescript-project to seed-project with pre-built ESM
output included
- Renamed file folder enums for consistency (Functions → BuiltFunction,
SourceCode → Source)
  - supports backwards compatibility with existing serverless functions

Tested with all combinations
- storage : local driver and S3 driver
- serverless : local driver and lambda driver
2026-01-22 12:56:44 +01:00

76 lines
3.1 KiB
TypeScript

import { isDefined } from 'twenty-shared/utils';
import { v4 } from 'uuid';
import { DEFAULT_TOOL_INPUT_SCHEMA } from 'src/engine/metadata-modules/serverless-function/constants/default-tool-input-schema.constant';
import { type CreateServerlessFunctionInput } from 'src/engine/metadata-modules/serverless-function/dtos/create-serverless-function.input';
import {
DEFAULT_BUILT_HANDLER_PATH,
DEFAULT_HANDLER_NAME,
DEFAULT_HANDLER_PATH,
ServerlessFunctionRuntime,
} from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
import { type FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type';
import { serverlessFunctionCreateHash } from 'src/engine/metadata-modules/serverless-function/utils/serverless-function-create-hash.utils';
export type FromCreateServerlessFunctionInputToFlatServerlessFunctionArgs = {
createServerlessFunctionInput: CreateServerlessFunctionInput & {
serverlessFunctionLayerId: string;
};
workspaceId: string;
workspaceCustomApplicationId: string;
};
export const fromCreateServerlessFunctionInputToFlatServerlessFunction = ({
createServerlessFunctionInput: rawCreateServerlessFunctionInput,
workspaceId,
workspaceCustomApplicationId,
}: FromCreateServerlessFunctionInputToFlatServerlessFunctionArgs): FlatServerlessFunction => {
const id = v4();
const currentDate = new Date();
return {
cronTriggerIds: [],
databaseEventTriggerIds: [],
routeTriggerIds: [],
id,
name: rawCreateServerlessFunctionInput.name,
description: rawCreateServerlessFunctionInput.description ?? null,
handlerPath:
rawCreateServerlessFunctionInput.handlerPath ?? DEFAULT_HANDLER_PATH,
handlerName:
rawCreateServerlessFunctionInput.handlerName ?? DEFAULT_HANDLER_NAME,
builtHandlerPath:
rawCreateServerlessFunctionInput.builtHandlerPath ??
DEFAULT_BUILT_HANDLER_PATH,
universalIdentifier:
rawCreateServerlessFunctionInput.universalIdentifier ?? v4(),
createdAt: currentDate.toISOString(),
updatedAt: currentDate.toISOString(),
deletedAt: null,
latestVersion: null,
publishedVersions: [],
applicationId: workspaceCustomApplicationId,
runtime: ServerlessFunctionRuntime.NODE22,
timeoutSeconds: rawCreateServerlessFunctionInput.timeoutSeconds ?? 300,
serverlessFunctionLayerId:
rawCreateServerlessFunctionInput.serverlessFunctionLayerId,
workspaceId,
code: rawCreateServerlessFunctionInput?.code,
checksum: rawCreateServerlessFunctionInput?.code
? serverlessFunctionCreateHash(
JSON.stringify(rawCreateServerlessFunctionInput.code),
)
: null,
// If no schema provided and no code provided, use default schema
// (because the default template will be used)
toolInputSchema: isDefined(
rawCreateServerlessFunctionInput?.toolInputSchema,
)
? rawCreateServerlessFunctionInput.toolInputSchema
: !isDefined(rawCreateServerlessFunctionInput?.code)
? DEFAULT_TOOL_INPUT_SCHEMA
: null,
isTool: rawCreateServerlessFunctionInput?.isTool ?? false,
};
};