Serverless built updates (#17351)

follow up of https://github.com/twentyhq/twenty/pull/17317
This commit is contained in:
martmull
2026-01-22 15:04:29 +00:00
committed by GitHub
parent 7fcc43f96b
commit a68e05682b
24 changed files with 194 additions and 159 deletions
@@ -1060,9 +1060,9 @@ export type CreateServerlessFunctionInput = {
code?: InputMaybe<Scalars['JSON']>;
description?: InputMaybe<Scalars['String']>;
handlerName?: InputMaybe<Scalars['String']>;
handlerPath?: InputMaybe<Scalars['String']>;
isTool?: InputMaybe<Scalars['Boolean']>;
name: Scalars['String'];
sourceHandlerPath?: InputMaybe<Scalars['String']>;
timeoutSeconds?: InputMaybe<Scalars['Float']>;
toolInputSchema?: InputMaybe<Scalars['JSON']>;
};
@@ -4364,7 +4364,6 @@ export type ServerlessFunction = {
databaseEventTriggers?: Maybe<Array<DatabaseEventTrigger>>;
description?: Maybe<Scalars['String']>;
handlerName: Scalars['String'];
handlerPath: Scalars['String'];
id: Scalars['UUID'];
isTool: Scalars['Boolean'];
latestVersion?: Maybe<Scalars['String']>;
@@ -4372,6 +4371,7 @@ export type ServerlessFunction = {
publishedVersions: Array<Scalars['String']>;
routeTriggers?: Maybe<Array<RouteTrigger>>;
runtime: Scalars['String'];
sourceHandlerPath: Scalars['String'];
timeoutSeconds: Scalars['Float'];
toolInputSchema?: Maybe<Scalars['JSON']>;
universalIdentifier?: Maybe<Scalars['UUID']>;
@@ -4949,9 +4949,9 @@ export type UpdateServerlessFunctionInputUpdates = {
code: Scalars['JSON'];
description?: InputMaybe<Scalars['String']>;
handlerName?: InputMaybe<Scalars['String']>;
handlerPath?: InputMaybe<Scalars['String']>;
isTool?: InputMaybe<Scalars['Boolean']>;
name: Scalars['String'];
sourceHandlerPath?: InputMaybe<Scalars['String']>;
timeoutSeconds?: InputMaybe<Scalars['Float']>;
toolInputSchema?: InputMaybe<Scalars['JSON']>;
};
@@ -5762,7 +5762,7 @@ export type UpdateOneApplicationVariableMutationVariables = Exact<{
export type UpdateOneApplicationVariableMutation = { __typename?: 'Mutation', updateOneApplicationVariable: boolean };
export type ApplicationFieldsFragment = { __typename?: 'Application', id: string, name: string, description: string, version: string, universalIdentifier: string, canBeUninstalled: boolean, applicationVariables: Array<{ __typename?: 'ApplicationVariable', id: string, key: string, value: string, description: string, isSecret: boolean }>, agents: Array<{ __typename?: 'Agent', id: string, name: string, label: string, description?: string | null, icon?: string | null, prompt: string, modelId: string, responseFormat?: any | null, roleId?: string | null, isCustom: boolean, modelConfiguration?: any | null, evaluationInputs: Array<string>, applicationId?: string | null, createdAt: string, updatedAt: string }>, objects: Array<{ __typename?: 'Object', id: string, nameSingular: string, namePlural: string, labelSingular: string, labelPlural: string, description?: string | null, icon?: string | null, isCustom: boolean, isRemote: boolean, isActive: boolean, isSystem: boolean, isUIReadOnly: boolean, createdAt: string, updatedAt: string, labelIdentifierFieldMetadataId?: string | null, imageIdentifierFieldMetadataId?: string | null, applicationId: string, shortcut?: string | null, isLabelSyncedWithName: boolean, isSearchable: boolean, duplicateCriteria?: Array<Array<string>> | null, indexMetadataList: Array<{ __typename?: 'Index', id: string, createdAt: string, updatedAt: string, name: string, indexWhereClause?: string | null, indexType: IndexType, isUnique: boolean, isCustom?: boolean | null, indexFieldMetadataList: Array<{ __typename?: 'IndexField', id: string, fieldMetadataId: string, createdAt: string, updatedAt: string, order: number }> }>, fieldsList: Array<{ __typename?: 'Field', id: string, type: FieldMetadataType, name: string, label: string, description?: string | null, icon?: string | null, isCustom?: boolean | null, isActive?: boolean | null, isSystem?: boolean | null, isUIReadOnly?: boolean | null, isNullable?: boolean | null, isUnique?: boolean | null, createdAt: string, updatedAt: string, defaultValue?: any | null, options?: any | null, settings?: any | null, isLabelSyncedWithName?: boolean | null, morphId?: string | null, applicationId: string, relation?: { __typename?: 'Relation', type: RelationType, sourceObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, targetObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, sourceFieldMetadata: { __typename?: 'Field', id: string, name: string }, targetFieldMetadata: { __typename?: 'Field', id: string, name: string } } | null, morphRelations?: Array<{ __typename?: 'Relation', type: RelationType, sourceObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, targetObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, sourceFieldMetadata: { __typename?: 'Field', id: string, name: string }, targetFieldMetadata: { __typename?: 'Field', id: string, name: string } }> | null }> }>, serverlessFunctions: Array<{ __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, handlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null }> };
export type ApplicationFieldsFragment = { __typename?: 'Application', id: string, name: string, description: string, version: string, universalIdentifier: string, canBeUninstalled: boolean, applicationVariables: Array<{ __typename?: 'ApplicationVariable', id: string, key: string, value: string, description: string, isSecret: boolean }>, agents: Array<{ __typename?: 'Agent', id: string, name: string, label: string, description?: string | null, icon?: string | null, prompt: string, modelId: string, responseFormat?: any | null, roleId?: string | null, isCustom: boolean, modelConfiguration?: any | null, evaluationInputs: Array<string>, applicationId?: string | null, createdAt: string, updatedAt: string }>, objects: Array<{ __typename?: 'Object', id: string, nameSingular: string, namePlural: string, labelSingular: string, labelPlural: string, description?: string | null, icon?: string | null, isCustom: boolean, isRemote: boolean, isActive: boolean, isSystem: boolean, isUIReadOnly: boolean, createdAt: string, updatedAt: string, labelIdentifierFieldMetadataId?: string | null, imageIdentifierFieldMetadataId?: string | null, applicationId: string, shortcut?: string | null, isLabelSyncedWithName: boolean, isSearchable: boolean, duplicateCriteria?: Array<Array<string>> | null, indexMetadataList: Array<{ __typename?: 'Index', id: string, createdAt: string, updatedAt: string, name: string, indexWhereClause?: string | null, indexType: IndexType, isUnique: boolean, isCustom?: boolean | null, indexFieldMetadataList: Array<{ __typename?: 'IndexField', id: string, fieldMetadataId: string, createdAt: string, updatedAt: string, order: number }> }>, fieldsList: Array<{ __typename?: 'Field', id: string, type: FieldMetadataType, name: string, label: string, description?: string | null, icon?: string | null, isCustom?: boolean | null, isActive?: boolean | null, isSystem?: boolean | null, isUIReadOnly?: boolean | null, isNullable?: boolean | null, isUnique?: boolean | null, createdAt: string, updatedAt: string, defaultValue?: any | null, options?: any | null, settings?: any | null, isLabelSyncedWithName?: boolean | null, morphId?: string | null, applicationId: string, relation?: { __typename?: 'Relation', type: RelationType, sourceObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, targetObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, sourceFieldMetadata: { __typename?: 'Field', id: string, name: string }, targetFieldMetadata: { __typename?: 'Field', id: string, name: string } } | null, morphRelations?: Array<{ __typename?: 'Relation', type: RelationType, sourceObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, targetObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, sourceFieldMetadata: { __typename?: 'Field', id: string, name: string }, targetFieldMetadata: { __typename?: 'Field', id: string, name: string } }> | null }> }>, serverlessFunctions: Array<{ __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null }> };
export type FindManyApplicationsQueryVariables = Exact<{ [key: string]: never; }>;
@@ -5774,7 +5774,7 @@ export type FindOneApplicationQueryVariables = Exact<{
}>;
export type FindOneApplicationQuery = { __typename?: 'Query', findOneApplication: { __typename?: 'Application', id: string, name: string, description: string, version: string, universalIdentifier: string, canBeUninstalled: boolean, applicationVariables: Array<{ __typename?: 'ApplicationVariable', id: string, key: string, value: string, description: string, isSecret: boolean }>, agents: Array<{ __typename?: 'Agent', id: string, name: string, label: string, description?: string | null, icon?: string | null, prompt: string, modelId: string, responseFormat?: any | null, roleId?: string | null, isCustom: boolean, modelConfiguration?: any | null, evaluationInputs: Array<string>, applicationId?: string | null, createdAt: string, updatedAt: string }>, objects: Array<{ __typename?: 'Object', id: string, nameSingular: string, namePlural: string, labelSingular: string, labelPlural: string, description?: string | null, icon?: string | null, isCustom: boolean, isRemote: boolean, isActive: boolean, isSystem: boolean, isUIReadOnly: boolean, createdAt: string, updatedAt: string, labelIdentifierFieldMetadataId?: string | null, imageIdentifierFieldMetadataId?: string | null, applicationId: string, shortcut?: string | null, isLabelSyncedWithName: boolean, isSearchable: boolean, duplicateCriteria?: Array<Array<string>> | null, indexMetadataList: Array<{ __typename?: 'Index', id: string, createdAt: string, updatedAt: string, name: string, indexWhereClause?: string | null, indexType: IndexType, isUnique: boolean, isCustom?: boolean | null, indexFieldMetadataList: Array<{ __typename?: 'IndexField', id: string, fieldMetadataId: string, createdAt: string, updatedAt: string, order: number }> }>, fieldsList: Array<{ __typename?: 'Field', id: string, type: FieldMetadataType, name: string, label: string, description?: string | null, icon?: string | null, isCustom?: boolean | null, isActive?: boolean | null, isSystem?: boolean | null, isUIReadOnly?: boolean | null, isNullable?: boolean | null, isUnique?: boolean | null, createdAt: string, updatedAt: string, defaultValue?: any | null, options?: any | null, settings?: any | null, isLabelSyncedWithName?: boolean | null, morphId?: string | null, applicationId: string, relation?: { __typename?: 'Relation', type: RelationType, sourceObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, targetObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, sourceFieldMetadata: { __typename?: 'Field', id: string, name: string }, targetFieldMetadata: { __typename?: 'Field', id: string, name: string } } | null, morphRelations?: Array<{ __typename?: 'Relation', type: RelationType, sourceObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, targetObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, sourceFieldMetadata: { __typename?: 'Field', id: string, name: string }, targetFieldMetadata: { __typename?: 'Field', id: string, name: string } }> | null }> }>, serverlessFunctions: Array<{ __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, handlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null }> } };
export type FindOneApplicationQuery = { __typename?: 'Query', findOneApplication: { __typename?: 'Application', id: string, name: string, description: string, version: string, universalIdentifier: string, canBeUninstalled: boolean, applicationVariables: Array<{ __typename?: 'ApplicationVariable', id: string, key: string, value: string, description: string, isSecret: boolean }>, agents: Array<{ __typename?: 'Agent', id: string, name: string, label: string, description?: string | null, icon?: string | null, prompt: string, modelId: string, responseFormat?: any | null, roleId?: string | null, isCustom: boolean, modelConfiguration?: any | null, evaluationInputs: Array<string>, applicationId?: string | null, createdAt: string, updatedAt: string }>, objects: Array<{ __typename?: 'Object', id: string, nameSingular: string, namePlural: string, labelSingular: string, labelPlural: string, description?: string | null, icon?: string | null, isCustom: boolean, isRemote: boolean, isActive: boolean, isSystem: boolean, isUIReadOnly: boolean, createdAt: string, updatedAt: string, labelIdentifierFieldMetadataId?: string | null, imageIdentifierFieldMetadataId?: string | null, applicationId: string, shortcut?: string | null, isLabelSyncedWithName: boolean, isSearchable: boolean, duplicateCriteria?: Array<Array<string>> | null, indexMetadataList: Array<{ __typename?: 'Index', id: string, createdAt: string, updatedAt: string, name: string, indexWhereClause?: string | null, indexType: IndexType, isUnique: boolean, isCustom?: boolean | null, indexFieldMetadataList: Array<{ __typename?: 'IndexField', id: string, fieldMetadataId: string, createdAt: string, updatedAt: string, order: number }> }>, fieldsList: Array<{ __typename?: 'Field', id: string, type: FieldMetadataType, name: string, label: string, description?: string | null, icon?: string | null, isCustom?: boolean | null, isActive?: boolean | null, isSystem?: boolean | null, isUIReadOnly?: boolean | null, isNullable?: boolean | null, isUnique?: boolean | null, createdAt: string, updatedAt: string, defaultValue?: any | null, options?: any | null, settings?: any | null, isLabelSyncedWithName?: boolean | null, morphId?: string | null, applicationId: string, relation?: { __typename?: 'Relation', type: RelationType, sourceObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, targetObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, sourceFieldMetadata: { __typename?: 'Field', id: string, name: string }, targetFieldMetadata: { __typename?: 'Field', id: string, name: string } } | null, morphRelations?: Array<{ __typename?: 'Relation', type: RelationType, sourceObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, targetObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, sourceFieldMetadata: { __typename?: 'Field', id: string, name: string }, targetFieldMetadata: { __typename?: 'Field', id: string, name: string } }> | null }> }>, serverlessFunctions: Array<{ __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null }> } };
export type UploadFileMutationVariables = Exact<{
file: Scalars['Upload'];
@@ -6566,21 +6566,21 @@ export type GetSsoIdentityProvidersQueryVariables = Exact<{ [key: string]: never
export type GetSsoIdentityProvidersQuery = { __typename?: 'Query', getSSOIdentityProviders: Array<{ __typename?: 'FindAvailableSSOIDPOutput', type: IdentityProviderType, id: string, name: string, issuer: string, status: SsoIdentityProviderStatus }> };
export type ServerlessFunctionFieldsFragment = { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, handlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null };
export type ServerlessFunctionFieldsFragment = { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null };
export type CreateOneServerlessFunctionItemMutationVariables = Exact<{
input: CreateServerlessFunctionInput;
}>;
export type CreateOneServerlessFunctionItemMutation = { __typename?: 'Mutation', createOneServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, handlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null } };
export type CreateOneServerlessFunctionItemMutation = { __typename?: 'Mutation', createOneServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null } };
export type DeleteOneServerlessFunctionMutationVariables = Exact<{
input: ServerlessFunctionIdInput;
}>;
export type DeleteOneServerlessFunctionMutation = { __typename?: 'Mutation', deleteOneServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, handlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null } };
export type DeleteOneServerlessFunctionMutation = { __typename?: 'Mutation', deleteOneServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null } };
export type ExecuteOneServerlessFunctionMutationVariables = Exact<{
input: ExecuteServerlessFunctionInput;
@@ -6594,14 +6594,14 @@ export type PublishOneServerlessFunctionMutationVariables = Exact<{
}>;
export type PublishOneServerlessFunctionMutation = { __typename?: 'Mutation', publishServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, handlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null } };
export type PublishOneServerlessFunctionMutation = { __typename?: 'Mutation', publishServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null } };
export type UpdateOneServerlessFunctionMutationVariables = Exact<{
input: UpdateServerlessFunctionInput;
}>;
export type UpdateOneServerlessFunctionMutation = { __typename?: 'Mutation', updateOneServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, handlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null } };
export type UpdateOneServerlessFunctionMutation = { __typename?: 'Mutation', updateOneServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null } };
export type FindManyAvailablePackagesQueryVariables = Exact<{
input: ServerlessFunctionIdInput;
@@ -6613,14 +6613,14 @@ export type FindManyAvailablePackagesQuery = { __typename?: 'Query', getAvailabl
export type GetManyServerlessFunctionsQueryVariables = Exact<{ [key: string]: never; }>;
export type GetManyServerlessFunctionsQuery = { __typename?: 'Query', findManyServerlessFunctions: Array<{ __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, handlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null }> };
export type GetManyServerlessFunctionsQuery = { __typename?: 'Query', findManyServerlessFunctions: Array<{ __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null }> };
export type GetOneServerlessFunctionQueryVariables = Exact<{
input: ServerlessFunctionIdInput;
}>;
export type GetOneServerlessFunctionQuery = { __typename?: 'Query', findOneServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, handlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null } };
export type GetOneServerlessFunctionQuery = { __typename?: 'Query', findOneServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array<string>, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array<string>, createdAt: string, updatedAt: string }> | null } };
export type FindOneServerlessFunctionSourceCodeQueryVariables = Exact<{
input: GetServerlessFunctionSourceCodeInput;
@@ -7286,7 +7286,8 @@ export const ServerlessFunctionFieldsFragmentDoc = gql`
timeoutSeconds
latestVersion
publishedVersions
handlerPath
sourceHandlerPath
builtHandlerPath
handlerName
cronTriggers {
id
@@ -1036,9 +1036,9 @@ export type CreateServerlessFunctionInput = {
code?: InputMaybe<Scalars['JSON']>;
description?: InputMaybe<Scalars['String']>;
handlerName?: InputMaybe<Scalars['String']>;
handlerPath?: InputMaybe<Scalars['String']>;
isTool?: InputMaybe<Scalars['Boolean']>;
name: Scalars['String'];
sourceHandlerPath?: InputMaybe<Scalars['String']>;
timeoutSeconds?: InputMaybe<Scalars['Float']>;
toolInputSchema?: InputMaybe<Scalars['JSON']>;
};
@@ -4173,7 +4173,6 @@ export type ServerlessFunction = {
databaseEventTriggers?: Maybe<Array<DatabaseEventTrigger>>;
description?: Maybe<Scalars['String']>;
handlerName: Scalars['String'];
handlerPath: Scalars['String'];
id: Scalars['UUID'];
isTool: Scalars['Boolean'];
latestVersion?: Maybe<Scalars['String']>;
@@ -4181,6 +4180,7 @@ export type ServerlessFunction = {
publishedVersions: Array<Scalars['String']>;
routeTriggers?: Maybe<Array<RouteTrigger>>;
runtime: Scalars['String'];
sourceHandlerPath: Scalars['String'];
timeoutSeconds: Scalars['Float'];
toolInputSchema?: Maybe<Scalars['JSON']>;
universalIdentifier?: Maybe<Scalars['UUID']>;
@@ -4734,9 +4734,9 @@ export type UpdateServerlessFunctionInputUpdates = {
code: Scalars['JSON'];
description?: InputMaybe<Scalars['String']>;
handlerName?: InputMaybe<Scalars['String']>;
handlerPath?: InputMaybe<Scalars['String']>;
isTool?: InputMaybe<Scalars['Boolean']>;
name: Scalars['String'];
sourceHandlerPath?: InputMaybe<Scalars['String']>;
timeoutSeconds?: InputMaybe<Scalars['Float']>;
toolInputSchema?: InputMaybe<Scalars['JSON']>;
};
@@ -9,7 +9,8 @@ export const SERVERLESS_FUNCTION_FRAGMENT = gql`
timeoutSeconds
latestVersion
publishedVersions
handlerPath
sourceHandlerPath
builtHandlerPath
handlerName
cronTriggers {
id
@@ -79,7 +79,8 @@ export const useServerlessFunctionUpdateFormState = ({
const flattenedCode = flattenSources(code);
const sourceCode = flattenedCode.find(
(flatCode) => flatCode.path === serverlessFunction?.handlerPath,
(flatCode) =>
flatCode.path === serverlessFunction?.sourceHandlerPath,
);
if (isDefined(sourceCode)) {
@@ -110,7 +110,7 @@ export const SettingsServerlessFunctionDetail = () => {
// Parse and save schema if editing the handler file
let toolInputSchema: object | null | undefined;
if (filePath === serverlessFunction?.handlerPath) {
if (filePath === serverlessFunction?.sourceHandlerPath) {
toolInputSchema = await getToolInputSchemaFromSourceCode(value);
}
@@ -138,9 +138,9 @@ export const SettingsServerlessFunctionDetail = () => {
content: file.content,
}))
.sort((a, b) =>
a.path === serverlessFunction?.handlerPath
a.path === serverlessFunction?.sourceHandlerPath
? -1
: b.path === serverlessFunction?.handlerPath
: b.path === serverlessFunction?.sourceHandlerPath
? 1
: 0,
);
@@ -0,0 +1,19 @@
import { type MigrationInterface, type QueryRunner } from 'typeorm';
export class RenameHandlerPathToSourceHandlerPath1769091641000
implements MigrationInterface
{
name = 'RenameHandlerPathToSourceHandlerPath1769091641000';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "core"."serverlessFunction" RENAME COLUMN "handlerPath" TO "sourceHandlerPath"`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "core"."serverlessFunction" RENAME COLUMN "sourceHandlerPath" TO "handlerPath"`,
);
}
}
@@ -947,7 +947,7 @@ export class ApplicationSyncService {
name,
code,
timeoutSeconds: serverlessFunctionToSync.timeoutSeconds,
handlerPath: serverlessFunctionToSync.sourceHandlerPath,
sourceHandlerPath: serverlessFunctionToSync.sourceHandlerPath,
handlerName: serverlessFunctionToSync.handlerName,
toolInputSchema: serverlessFunctionToSync.toolInputSchema,
isTool: serverlessFunctionToSync.isTool,
@@ -991,7 +991,7 @@ export class ApplicationSyncService {
code,
universalIdentifier: serverlessFunctionToCreate.universalIdentifier,
timeoutSeconds: serverlessFunctionToCreate.timeoutSeconds,
handlerPath: serverlessFunctionToCreate.sourceHandlerPath,
sourceHandlerPath: serverlessFunctionToCreate.sourceHandlerPath,
handlerName: serverlessFunctionToCreate.handlerName,
applicationId,
serverlessFunctionLayerId,
@@ -1,86 +0,0 @@
import { join } from 'path';
import fs from 'fs/promises';
import { build } from 'esbuild';
import { FileFolder } from 'twenty-shared/types';
import { getServerlessFolderOrThrow } from 'src/engine/core-modules/serverless/utils/get-serverless-folder-or-throw.utils';
import { LambdaBuildDirectoryManager } from 'src/engine/core-modules/serverless/drivers/utils/lambda-build-directory-manager';
import { type FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type';
import { type FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service';
const buildServerlessFunctionInMemory = async ({
sourceTemporaryDir,
handlerPath,
builtHandlerPath,
}: {
sourceTemporaryDir: string;
handlerPath: string;
builtHandlerPath: string;
}): Promise<string> => {
const entryFilePath = join(sourceTemporaryDir, handlerPath);
const builtBundleFilePath = join(sourceTemporaryDir, builtHandlerPath);
await build({
entryPoints: [entryFilePath],
outfile: builtBundleFilePath,
platform: 'node',
format: 'esm',
target: 'es2017',
bundle: true,
sourcemap: true,
packages: 'external',
});
return builtBundleFilePath;
};
export const buildAndUploadServerlessFunction = async ({
flatServerlessFunction,
version,
fileStorageService,
}: {
flatServerlessFunction: FlatServerlessFunction;
version: string;
fileStorageService: FileStorageService;
}): Promise<void> => {
const sourceFolderPath = getServerlessFolderOrThrow({
flatServerlessFunction,
version,
fileFolder: FileFolder.ServerlessFunction,
});
const builtFolderPath = getServerlessFolderOrThrow({
flatServerlessFunction,
version,
fileFolder: FileFolder.BuiltFunction,
});
const lambdaBuildDirectoryManager = new LambdaBuildDirectoryManager();
try {
const { sourceTemporaryDir } = await lambdaBuildDirectoryManager.init();
await fileStorageService.download({
from: { folderPath: sourceFolderPath },
to: { folderPath: sourceTemporaryDir },
});
const builtBundleFilePath = await buildServerlessFunctionInMemory({
sourceTemporaryDir,
handlerPath: flatServerlessFunction.handlerPath,
builtHandlerPath: flatServerlessFunction.builtHandlerPath,
});
const builtFile = await fs.readFile(builtBundleFilePath, 'utf-8');
await fileStorageService.write({
file: builtFile,
name: flatServerlessFunction.builtHandlerPath,
mimeType: 'application/javascript',
folder: builtFolderPath,
});
} finally {
await lambdaBuildDirectoryManager.clean();
}
};
@@ -1,23 +0,0 @@
import type { FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type';
import type { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service';
import { getServerlessFolderOrThrow } from 'src/engine/core-modules/serverless/utils/get-serverless-folder-or-throw.utils';
export const isServerlessFunctionBuilt = async ({
flatServerlessFunction,
version,
fileStorageService,
}: {
flatServerlessFunction: FlatServerlessFunction;
version: string;
fileStorageService: FileStorageService;
}) => {
const folderPath = getServerlessFolderOrThrow({
flatServerlessFunction,
version,
});
return await fileStorageService.checkFileExists({
folderPath,
filename: flatServerlessFunction.builtHandlerPath,
});
};
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { FunctionBuildService } from 'src/engine/metadata-modules/function-build/function-build.service';
@Module({
providers: [FunctionBuildService],
exports: [FunctionBuildService],
})
export class FunctionBuildModule {}
@@ -0,0 +1,109 @@
import { Injectable } from '@nestjs/common';
import { join } from 'path';
import fs from 'fs/promises';
import { build } from 'esbuild';
import { FileFolder } from 'twenty-shared/types';
import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service';
import { LambdaBuildDirectoryManager } from 'src/engine/core-modules/serverless/drivers/utils/lambda-build-directory-manager';
import { getServerlessFolderOrThrow } from 'src/engine/core-modules/serverless/utils/get-serverless-folder-or-throw.utils';
import { type FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type';
@Injectable()
export class FunctionBuildService {
constructor(private readonly fileStorageService: FileStorageService) {}
async isBuilt({
flatServerlessFunction,
version,
}: {
flatServerlessFunction: FlatServerlessFunction;
version: string;
}): Promise<boolean> {
const folderPath = getServerlessFolderOrThrow({
flatServerlessFunction,
version,
});
return await this.fileStorageService.checkFileExists({
folderPath,
filename: flatServerlessFunction.builtHandlerPath,
});
}
async buildAndUpload({
flatServerlessFunction,
version,
}: {
flatServerlessFunction: FlatServerlessFunction;
version: string;
}): Promise<void> {
const sourceFolderPath = getServerlessFolderOrThrow({
flatServerlessFunction,
version,
fileFolder: FileFolder.ServerlessFunction,
});
const builtFolderPath = getServerlessFolderOrThrow({
flatServerlessFunction,
version,
fileFolder: FileFolder.BuiltFunction,
});
const lambdaBuildDirectoryManager = new LambdaBuildDirectoryManager();
try {
const { sourceTemporaryDir } = await lambdaBuildDirectoryManager.init();
await this.fileStorageService.download({
from: { folderPath: sourceFolderPath },
to: { folderPath: sourceTemporaryDir },
});
const builtBundleFilePath = await this.buildInMemory({
sourceTemporaryDir,
sourceHandlerPath: flatServerlessFunction.sourceHandlerPath,
builtHandlerPath: flatServerlessFunction.builtHandlerPath,
});
const builtFile = await fs.readFile(builtBundleFilePath, 'utf-8');
await this.fileStorageService.write({
file: builtFile,
name: flatServerlessFunction.builtHandlerPath,
mimeType: 'application/javascript',
folder: builtFolderPath,
});
} finally {
await lambdaBuildDirectoryManager.clean();
}
}
private async buildInMemory({
sourceTemporaryDir,
sourceHandlerPath,
builtHandlerPath,
}: {
sourceTemporaryDir: string;
sourceHandlerPath: string;
builtHandlerPath: string;
}): Promise<string> {
const entryFilePath = join(sourceTemporaryDir, sourceHandlerPath);
const builtBundleFilePath = join(sourceTemporaryDir, builtHandlerPath);
await build({
entryPoints: [entryFilePath],
outfile: builtBundleFilePath,
platform: 'node',
format: 'esm',
target: 'es2017',
bundle: true,
sourcemap: true,
packages: 'external',
});
return builtBundleFilePath;
}
}
@@ -6,7 +6,7 @@ export const FLAT_SERVERLESS_FUNCTION_EDITABLE_PROPERTIES = [
'timeoutSeconds',
'checksum',
'code',
'handlerPath',
'sourceHandlerPath',
'handlerName',
'toolInputSchema',
'isTool',
@@ -54,7 +54,7 @@ export class CreateServerlessFunctionInput {
@IsString()
@Field({ nullable: true })
@IsOptional()
handlerPath?: string;
sourceHandlerPath?: string;
@IsString()
@Field({ nullable: true })
@@ -63,7 +63,7 @@ export class ServerlessFunctionDTO {
@IsString()
@Field()
handlerPath: string;
sourceHandlerPath: string;
@IsString()
@Field()
@@ -50,7 +50,7 @@ class UpdateServerlessFunctionInputUpdates {
@IsString()
@Field({ nullable: true })
@IsOptional()
handlerPath?: string;
sourceHandlerPath?: string;
@Field(() => graphqlTypeJson, { nullable: true })
@IsObject()
@@ -26,7 +26,7 @@ export enum ServerlessFunctionRuntime {
NODE22 = 'nodejs22.x',
}
export const DEFAULT_HANDLER_PATH = 'src/index.ts';
export const DEFAULT_SOURCE_HANDLER_PATH = 'src/index.ts';
export const DEFAULT_BUILT_HANDLER_PATH = 'index.mjs';
export const DEFAULT_HANDLER_NAME = 'main';
@@ -43,8 +43,8 @@ export class ServerlessFunctionEntity
@Column({ nullable: false })
name: string;
@Column({ nullable: false, default: DEFAULT_HANDLER_PATH })
handlerPath: string;
@Column({ nullable: false, default: DEFAULT_SOURCE_HANDLER_PATH })
sourceHandlerPath: string;
@Column({ nullable: false, default: DEFAULT_BUILT_HANDLER_PATH })
builtHandlerPath: string;
@@ -26,6 +26,7 @@ import { WorkspaceFlatServerlessFunctionMapCacheService } from 'src/engine/metad
import { SubscriptionsModule } from 'src/engine/subscriptions/subscriptions.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
import { FunctionBuildModule } from 'src/engine/metadata-modules/function-build/function-build.module';
@Module({
imports: [
@@ -45,6 +46,7 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace
PermissionsModule,
WorkspaceManyOrAllFlatEntityMapsCacheModule,
WorkspaceMigrationModule,
FunctionBuildModule,
ServerlessFunctionLayerModule,
SubscriptionsModule,
WorkspaceCacheModule,
@@ -48,8 +48,7 @@ import {
WorkflowVersionStepExceptionCode,
} from 'src/modules/workflow/common/exceptions/workflow-version-step.exception';
import { cleanServerUrl } from 'src/utils/clean-server-url';
import { isServerlessFunctionBuilt } from 'src/engine/core-modules/serverless/drivers/utils/is-serverless-function-built';
import { buildAndUploadServerlessFunction } from 'src/engine/core-modules/serverless/drivers/utils/build-and-upload-serverless-function';
import { FunctionBuildService } from 'src/engine/metadata-modules/function-build/function-build.service';
const MIN_TOKEN_EXPIRATION_IN_SECONDS = 5;
@@ -58,6 +57,7 @@ export class ServerlessFunctionService {
constructor(
private readonly fileStorageService: FileStorageService,
private readonly serverlessService: ServerlessService,
private readonly functionBuildService: FunctionBuildService,
private readonly serverlessFunctionLayerService: ServerlessFunctionLayerService,
@InjectRepository(ServerlessFunctionEntity)
private readonly serverlessFunctionRepository: Repository<ServerlessFunctionEntity>,
@@ -210,16 +210,14 @@ export class ServerlessFunctionService {
// We keep that check to build functions
if (
!(await isServerlessFunctionBuilt({
!(await this.functionBuildService.isBuilt({
flatServerlessFunction,
version,
fileStorageService: this.fileStorageService,
}))
) {
await buildAndUploadServerlessFunction({
await this.functionBuildService.buildAndUpload({
flatServerlessFunction,
version,
fileStorageService: this.fileStorageService,
});
}
@@ -6,7 +6,7 @@ import { type CreateServerlessFunctionInput } from 'src/engine/metadata-modules/
import {
DEFAULT_BUILT_HANDLER_PATH,
DEFAULT_HANDLER_NAME,
DEFAULT_HANDLER_PATH,
DEFAULT_SOURCE_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';
@@ -35,8 +35,9 @@ export const fromCreateServerlessFunctionInputToFlatServerlessFunction = ({
id,
name: rawCreateServerlessFunctionInput.name,
description: rawCreateServerlessFunctionInput.description ?? null,
handlerPath:
rawCreateServerlessFunctionInput.handlerPath ?? DEFAULT_HANDLER_PATH,
sourceHandlerPath:
rawCreateServerlessFunctionInput.sourceHandlerPath ??
DEFAULT_SOURCE_HANDLER_PATH,
handlerName:
rawCreateServerlessFunctionInput.handlerName ?? DEFAULT_HANDLER_NAME,
builtHandlerPath:
@@ -43,7 +43,7 @@ export const fromFlatServerlessFunctionToServerlessFunctionDto = ({
runtime: flatServerlessFunction.runtime,
timeoutSeconds: flatServerlessFunction.timeoutSeconds,
latestVersion: flatServerlessFunction.latestVersion ?? undefined,
handlerPath: flatServerlessFunction.handlerPath,
sourceHandlerPath: flatServerlessFunction.sourceHandlerPath,
builtHandlerPath: flatServerlessFunction.builtHandlerPath,
handlerName: flatServerlessFunction.handlerName,
publishedVersions: flatServerlessFunction.publishedVersions,
@@ -13,14 +13,17 @@ import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless
import { CreateServerlessFunctionAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/serverless-function/types/workspace-migration-serverless-function-action.type';
import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import { FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type';
import { buildAndUploadServerlessFunction } from 'src/engine/core-modules/serverless/drivers/utils/build-and-upload-serverless-function';
import { FunctionBuildService } from 'src/engine/metadata-modules/function-build/function-build.service';
@Injectable()
export class CreateServerlessFunctionActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
'create',
'serverlessFunction',
) {
constructor(private readonly fileStorageService: FileStorageService) {
constructor(
private readonly fileStorageService: FileStorageService,
private readonly functionBuildService: FunctionBuildService,
) {
super();
}
@@ -66,10 +69,9 @@ export class CreateServerlessFunctionActionHandlerService extends WorkspaceMigra
});
}
}
await buildAndUploadServerlessFunction({
await this.functionBuildService.buildAndUpload({
flatServerlessFunction: serverlessFunction,
version: 'draft',
fileStorageService: this.fileStorageService,
});
}
@@ -14,7 +14,7 @@ import { FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-f
import { UpdateServerlessFunctionAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/serverless-function/types/workspace-migration-serverless-function-action.type';
import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type';
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
import { buildAndUploadServerlessFunction } from 'src/engine/core-modules/serverless/drivers/utils/build-and-upload-serverless-function';
import { FunctionBuildService } from 'src/engine/metadata-modules/function-build/function-build.service';
@Injectable()
export class UpdateServerlessFunctionActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
@@ -24,6 +24,7 @@ export class UpdateServerlessFunctionActionHandlerService extends WorkspaceMigra
constructor(
private readonly fileStorageService: FileStorageService,
private readonly serverlessService: ServerlessService,
private readonly functionBuildService: FunctionBuildService,
) {
super();
}
@@ -86,10 +87,9 @@ export class UpdateServerlessFunctionActionHandlerService extends WorkspaceMigra
await this.fileStorageService.writeFolder(code, fileFolder);
await buildAndUploadServerlessFunction({
await this.functionBuildService.buildAndUpload({
flatServerlessFunction,
version: 'draft',
fileStorageService: this.fileStorageService,
});
}
}
@@ -73,9 +73,10 @@ import { UpdateViewGroupActionHandlerService } from 'src/engine/workspace-manage
import { CreateViewActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view/services/create-view-action-handler.service';
import { DeleteViewActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view/services/delete-view-action-handler.service';
import { UpdateViewActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/view/services/update-view-action-handler.service';
import { FunctionBuildModule } from 'src/engine/metadata-modules/function-build/function-build.module';
@Module({
imports: [WorkspaceSchemaManagerModule],
imports: [WorkspaceSchemaManagerModule, FunctionBuildModule],
providers: [
CreateFieldActionHandlerService,
UpdateFieldActionHandlerService,
@@ -251,7 +251,7 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => {
deletedAt: null,
runtime: ServerlessFunctionRuntime.NODE22,
timeoutSeconds: 30,
handlerPath: 'src/index.ts',
sourceHandlerPath: 'src/index.ts',
builtHandlerPath: 'index.mjs',
handlerName: 'main',
checksum: null,
@@ -331,7 +331,7 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => {
deletedAt: null,
runtime: ServerlessFunctionRuntime.NODE22,
timeoutSeconds: 30,
handlerPath: 'src/index.ts',
sourceHandlerPath: 'src/index.ts',
builtHandlerPath: 'index.mjs',
handlerName: 'main',
checksum: null,