diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 9d520f7d5a..4956e9dcbf 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -268,6 +268,7 @@ export type Application = { __typename?: 'Application'; agents: Array; applicationVariables: Array; + availablePackages: Scalars['JSON']; canBeUninstalled: Scalars['Boolean']; defaultLogicFunctionRole?: Maybe; defaultRoleId?: Maybe; @@ -276,8 +277,12 @@ export type Application = { logicFunctions: Array; name: Scalars['String']; objects: Array; + packageJsonChecksum?: Maybe; + packageJsonFileId?: Maybe; universalIdentifier: Scalars['String']; version: Scalars['String']; + yarnLockChecksum?: Maybe; + yarnLockFileId?: Maybe; }; export type ApplicationVariable = { @@ -5582,7 +5587,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, 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> | 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 }> }>, logicFunctions: Array<{ __typename?: 'LogicFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string }> }; +export type ApplicationFieldsFragment = { __typename?: 'Application', id: string, name: string, description: string, version: string, universalIdentifier: string, canBeUninstalled: boolean, availablePackages: any, 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, 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> | 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 }> }>, logicFunctions: Array<{ __typename?: 'LogicFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string }> }; export type FindManyApplicationsQueryVariables = Exact<{ [key: string]: never; }>; @@ -5594,7 +5599,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, 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> | 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 }> }>, logicFunctions: Array<{ __typename?: 'LogicFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string }> } }; +export type FindOneApplicationQuery = { __typename?: 'Query', findOneApplication: { __typename?: 'Application', id: string, name: string, description: string, version: string, universalIdentifier: string, canBeUninstalled: boolean, availablePackages: any, 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, 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> | 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 }> }>, logicFunctions: Array<{ __typename?: 'LogicFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string }> } }; export type UploadFileMutationVariables = Exact<{ file: Scalars['Upload']; @@ -7180,6 +7185,7 @@ export const ApplicationFieldsFragmentDoc = gql` version universalIdentifier canBeUninstalled + availablePackages applicationVariables { id key diff --git a/packages/twenty-front/src/generated/graphql.ts b/packages/twenty-front/src/generated/graphql.ts index e998c9f747..6e3cade8cc 100644 --- a/packages/twenty-front/src/generated/graphql.ts +++ b/packages/twenty-front/src/generated/graphql.ts @@ -268,6 +268,7 @@ export type Application = { __typename?: 'Application'; agents: Array; applicationVariables: Array; + availablePackages: Scalars['JSON']; canBeUninstalled: Scalars['Boolean']; defaultLogicFunctionRole?: Maybe; defaultRoleId?: Maybe; @@ -276,8 +277,12 @@ export type Application = { logicFunctions: Array; name: Scalars['String']; objects: Array; + packageJsonChecksum?: Maybe; + packageJsonFileId?: Maybe; universalIdentifier: Scalars['String']; version: Scalars['String']; + yarnLockChecksum?: Maybe; + yarnLockFileId?: Maybe; }; export type ApplicationVariable = { diff --git a/packages/twenty-front/src/modules/applications/graphql/fragments/applicationFragment.ts b/packages/twenty-front/src/modules/applications/graphql/fragments/applicationFragment.ts index ce796d6668..aab85c8e3f 100644 --- a/packages/twenty-front/src/modules/applications/graphql/fragments/applicationFragment.ts +++ b/packages/twenty-front/src/modules/applications/graphql/fragments/applicationFragment.ts @@ -1,7 +1,7 @@ -import { gql } from '@apollo/client'; import { AGENT_FRAGMENT } from '@/ai/graphql/fragments/agentFragment'; -import { LOGIC_FUNCTION_FRAGMENT } from '@/settings/logic-functions/graphql/fragments/logicFunctionFragment'; import { OBJECT_METADATA_FRAGMENT } from '@/object-metadata/graphql/fragment'; +import { LOGIC_FUNCTION_FRAGMENT } from '@/settings/logic-functions/graphql/fragments/logicFunctionFragment'; +import { gql } from '@apollo/client'; export const APPLICATION_FRAGMENT = gql` ${AGENT_FRAGMENT} @@ -14,6 +14,7 @@ export const APPLICATION_FRAGMENT = gql` version universalIdentifier canBeUninstalled + availablePackages applicationVariables { id key diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/constants/CustomWorkspaceApplicationMock.test.constant.ts b/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/constants/CustomWorkspaceApplicationMock.test.constant.ts index bbf997ed05..3f6bb09893 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/constants/CustomWorkspaceApplicationMock.test.constant.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/constants/CustomWorkspaceApplicationMock.test.constant.ts @@ -4,6 +4,7 @@ export const CUSTOM_WORKSPACE_APPLICATION_MOCK = { id: 'dc75f982-35a2-4c1b-a63d-bd1131215377', agents: [], applicationVariables: [], + availablePackages: {}, canBeUninstalled: false, description: 'workpace custom application', name: 'custom', diff --git a/packages/twenty-server/src/database/typeorm/core/migrations/common/1770050100000-addApplicationPackageFields.ts b/packages/twenty-server/src/database/typeorm/core/migrations/common/1770050100000-addApplicationPackageFields.ts new file mode 100644 index 0000000000..6cd10dd75a --- /dev/null +++ b/packages/twenty-server/src/database/typeorm/core/migrations/common/1770050100000-addApplicationPackageFields.ts @@ -0,0 +1,69 @@ +import { type MigrationInterface, type QueryRunner } from 'typeorm'; + +export class AddApplicationPackageFields1770050100000 + implements MigrationInterface +{ + name = 'AddApplicationPackageFields1770050100000'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."application" ADD "packageJsonChecksum" text`, + ); + await queryRunner.query( + `ALTER TABLE "core"."application" ADD "packageJsonFileId" uuid`, + ); + await queryRunner.query( + `ALTER TABLE "core"."application" ADD "yarnLockChecksum" text`, + ); + await queryRunner.query( + `ALTER TABLE "core"."application" ADD "yarnLockFileId" uuid`, + ); + await queryRunner.query( + `ALTER TABLE "core"."application" ADD "availablePackages" jsonb NOT NULL DEFAULT '{}'`, + ); + + await queryRunner.query( + `ALTER TABLE "core"."application" ADD CONSTRAINT "UQ_3818380258798f9ffa9963b6dc4" UNIQUE ("packageJsonFileId")`, + ); + await queryRunner.query( + `ALTER TABLE "core"."application" ADD CONSTRAINT "UQ_28f20711184b3c3318a8e44d117" UNIQUE ("yarnLockFileId")`, + ); + await queryRunner.query( + `ALTER TABLE "core"."application" ADD CONSTRAINT "FK_3818380258798f9ffa9963b6dc4" FOREIGN KEY ("packageJsonFileId") REFERENCES "core"."file"("id") ON DELETE RESTRICT ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "core"."application" ADD CONSTRAINT "FK_28f20711184b3c3318a8e44d117" FOREIGN KEY ("yarnLockFileId") REFERENCES "core"."file"("id") ON DELETE RESTRICT ON UPDATE NO ACTION`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."application" DROP CONSTRAINT "FK_28f20711184b3c3318a8e44d117"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."application" DROP CONSTRAINT "FK_3818380258798f9ffa9963b6dc4"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."application" DROP CONSTRAINT "UQ_28f20711184b3c3318a8e44d117"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."application" DROP CONSTRAINT "UQ_3818380258798f9ffa9963b6dc4"`, + ); + + await queryRunner.query( + `ALTER TABLE "core"."application" DROP COLUMN "availablePackages"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."application" DROP COLUMN "yarnLockFileId"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."application" DROP COLUMN "yarnLockChecksum"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."application" DROP COLUMN "packageJsonFileId"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."application" DROP COLUMN "packageJsonChecksum"`, + ); + } +} diff --git a/packages/twenty-server/src/engine/core-modules/application/application.entity.ts b/packages/twenty-server/src/engine/core-modules/application/application.entity.ts index 1d6a86a18e..d9e0bb940c 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application.entity.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application.entity.ts @@ -6,17 +6,20 @@ import { DeleteDateColumn, Entity, Index, + JoinColumn, OneToMany, + OneToOne, PrimaryGeneratedColumn, type Relation, UpdateDateColumn, } from 'typeorm'; +import { FileEntity } from 'src/engine/core-modules/file/entities/file.entity'; import { ApplicationVariableEntity } from 'src/engine/core-modules/applicationVariable/application-variable.entity'; import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity'; +import { LogicFunctionEntity } from 'src/engine/metadata-modules/logic-function/logic-function.entity'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { RoleDTO } from 'src/engine/metadata-modules/role/dtos/role.dto'; -import { LogicFunctionEntity } from 'src/engine/metadata-modules/logic-function/logic-function.entity'; import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity'; @Entity({ name: 'application', schema: 'core' }) @@ -53,6 +56,29 @@ export class ApplicationEntity extends WorkspaceRelatedEntity { @Column({ nullable: false, type: 'text' }) sourcePath: string; + @Column({ nullable: true, type: 'text' }) + packageJsonChecksum: string | null; + + @Column({ nullable: true, type: 'uuid' }) + packageJsonFileId: string | null; + + @OneToOne(() => FileEntity, { onDelete: 'RESTRICT' }) + @JoinColumn({ name: 'packageJsonFileId' }) + packageJsonFile: Relation | null; + + @Column({ nullable: true, type: 'text' }) + yarnLockChecksum: string | null; + + @Column({ nullable: true, type: 'uuid' }) + yarnLockFileId: string | null; + + @OneToOne(() => FileEntity, { onDelete: 'RESTRICT' }) + @JoinColumn({ name: 'yarnLockFileId' }) + yarnLockFile: Relation | null; + + @Column({ type: 'jsonb', nullable: false, default: {} }) + availablePackages: Record; + @Column({ nullable: true, type: 'uuid' }) logicFunctionLayerId: string | null; diff --git a/packages/twenty-server/src/engine/core-modules/application/constants/application-entity-relation-properties.constant.ts b/packages/twenty-server/src/engine/core-modules/application/constants/application-entity-relation-properties.constant.ts index 056afeae75..d45d83c787 100644 --- a/packages/twenty-server/src/engine/core-modules/application/constants/application-entity-relation-properties.constant.ts +++ b/packages/twenty-server/src/engine/core-modules/application/constants/application-entity-relation-properties.constant.ts @@ -6,4 +6,6 @@ export const APPLICATION_ENTITY_RELATION_PROPERTIES = [ 'logicFunctions', 'objects', 'applicationVariables', + 'packageJsonFile', + 'yarnLockFile', ] as const satisfies (keyof ApplicationEntity)[]; diff --git a/packages/twenty-server/src/engine/core-modules/application/dtos/application.dto.ts b/packages/twenty-server/src/engine/core-modules/application/dtos/application.dto.ts index c1c7b5c0be..dcfe95a8a2 100644 --- a/packages/twenty-server/src/engine/core-modules/application/dtos/application.dto.ts +++ b/packages/twenty-server/src/engine/core-modules/application/dtos/application.dto.ts @@ -7,12 +7,13 @@ import { IsString, IsUUID, } from 'class-validator'; +import GraphQLJSON from 'graphql-type-json'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { ApplicationVariableEntityDTO } from 'src/engine/core-modules/applicationVariable/dtos/application-variable.dto'; import { AgentDTO } from 'src/engine/metadata-modules/ai/ai-agent/dtos/agent.dto'; -import { ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto'; import { LogicFunctionDTO } from 'src/engine/metadata-modules/logic-function/dtos/logic-function.dto'; +import { ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto'; import { RoleDTO } from 'src/engine/metadata-modules/role/dtos/role.dto'; @ObjectType('Application') @@ -40,6 +41,29 @@ export class ApplicationDTO { @Field() universalIdentifier: string; + @IsOptional() + @IsString() + @Field({ nullable: true }) + packageJsonChecksum?: string; + + @IsOptional() + @IsUUID() + @Field(() => UUIDScalarType, { nullable: true }) + packageJsonFileId?: string; + + @IsOptional() + @IsString() + @Field({ nullable: true }) + yarnLockChecksum?: string; + + @IsOptional() + @IsUUID() + @Field(() => UUIDScalarType, { nullable: true }) + yarnLockFileId?: string; + + @Field(() => GraphQLJSON) + availablePackages: Record; + @Field(() => Boolean) @IsBoolean() canBeUninstalled: boolean; diff --git a/packages/twenty-server/src/engine/core-modules/application/services/application.service.ts b/packages/twenty-server/src/engine/core-modules/application/services/application.service.ts index 7e9838d514..2ad5fcb94c 100644 --- a/packages/twenty-server/src/engine/core-modules/application/services/application.service.ts +++ b/packages/twenty-server/src/engine/core-modules/application/services/application.service.ts @@ -119,6 +119,8 @@ export class ApplicationService { 'agents', 'objects', 'applicationVariables', + 'packageJsonFile', + 'yarnLockFile', ], }); } @@ -165,6 +167,8 @@ export class ApplicationService { 'agents', 'objects', 'applicationVariables', + 'packageJsonFile', + 'yarnLockFile', ], }); } diff --git a/packages/twenty-server/src/engine/core-modules/application/utils/from-flat-application-to-application-dto.util.ts b/packages/twenty-server/src/engine/core-modules/application/utils/from-flat-application-to-application-dto.util.ts index 664a93d6bc..1124d497d8 100644 --- a/packages/twenty-server/src/engine/core-modules/application/utils/from-flat-application-to-application-dto.util.ts +++ b/packages/twenty-server/src/engine/core-modules/application/utils/from-flat-application-to-application-dto.util.ts @@ -3,11 +3,14 @@ import { type FlatApplication } from 'src/engine/core-modules/application/types/ export const fromFlatApplicationToApplicationDto = ({ canBeUninstalled, - description, id, name, - + packageJsonChecksum, + packageJsonFileId, + yarnLockChecksum, + yarnLockFileId, + availablePackages, universalIdentifier, version, }: FlatApplication): ApplicationDTO => { @@ -17,6 +20,11 @@ export const fromFlatApplicationToApplicationDto = ({ id, name, objects: [], + packageJsonChecksum: packageJsonChecksum ?? undefined, + packageJsonFileId: packageJsonFileId ?? undefined, + yarnLockChecksum: yarnLockChecksum ?? undefined, + yarnLockFileId: yarnLockFileId ?? undefined, + availablePackages: availablePackages ?? {}, universalIdentifier, version: version ?? undefined, }; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__tests__/morph-relation-from-create-field-input-to-flat-field-metadatas-to-create.spec.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__tests__/morph-relation-from-create-field-input-to-flat-field-metadatas-to-create.spec.ts index 9c3b57ba26..d75e575c30 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__tests__/morph-relation-from-create-field-input-to-flat-field-metadatas-to-create.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__tests__/morph-relation-from-create-field-input-to-flat-field-metadatas-to-create.spec.ts @@ -28,6 +28,11 @@ const MOCK_FLAT_APPLICATION: FlatApplication = { version: null, sourceType: 'local', sourcePath: '', + packageJsonChecksum: null, + packageJsonFileId: null, + yarnLockChecksum: null, + yarnLockFileId: null, + availablePackages: {}, logicFunctionLayerId: null, defaultRoleId: null, defaultRole: null, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/__tests__/generate-morph-or-relation-flat-field-metadata-pair.spec.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/__tests__/generate-morph-or-relation-flat-field-metadata-pair.spec.ts index 68b09fd802..6fc6e17fe5 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/__tests__/generate-morph-or-relation-flat-field-metadata-pair.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/__tests__/generate-morph-or-relation-flat-field-metadata-pair.spec.ts @@ -23,6 +23,11 @@ const MOCK_FLAT_APPLICATION: FlatApplication = { version: null, sourceType: 'local', sourcePath: '', + packageJsonChecksum: null, + packageJsonFileId: null, + yarnLockChecksum: null, + yarnLockFileId: null, + availablePackages: {}, logicFunctionLayerId: null, defaultRoleId: null, defaultRole: null,