From 7f1e69740a49c6f50ce213093239140fff15aa35 Mon Sep 17 00:00:00 2001 From: martmull Date: Mon, 8 Dec 2025 10:42:46 +0100 Subject: [PATCH] 1895 extensibility v1 application tokens (#16365) First PR to implement application tokens - add new application role in twenty-server - move duplicated constants and types to twenty-shared - will add role configuration utils into twenty-sdk in another PR --- packages/create-twenty-app/package.json | 2 +- .../src/utils/app-template.ts | 2 +- .../src/generated-metadata/graphql.ts | 3 + .../twenty-front/src/generated/graphql.ts | 3 + .../utils/__tests__/flattenSources.test.ts | 3 +- .../utils/computeNewSources.ts | 2 +- .../utils/flattenSources.ts | 2 +- .../useServerlessFunctionUpdateFormState.ts | 2 +- packages/twenty-sdk/package.json | 2 +- packages/twenty-sdk/project.json | 1 + .../src/application/application-config.ts | 2 +- .../composite-fields.ts | 0 .../{field-metadata => fields}/field-type.ts | 0 .../field.decorator.ts | 2 +- .../on-delete-action.ts | 0 .../relation-type.ts | 0 .../relation.decorator.ts | 2 +- .../src/application/function-config.ts | 2 +- packages/twenty-sdk/src/application/index.ts | 16 +- .../object.decorator.ts | 2 +- .../standard-object-ids.ts | 0 ...tions-install-delete-reinstall.e2e-spec.ts | 8 +- .../cli/__tests__/e2e/constants/testConfig.ts | 2 +- .../src/cli/__tests__/e2e/health.e2e-spec.ts | 2 +- .../src/cli/__tests__/e2e/setupTest.ts | 4 +- packages/twenty-sdk/src/cli/cli.ts | 6 +- .../src/cli/commands/app-add.command.ts | 8 +- .../src/cli/commands/app-dev.command.ts | 2 +- .../src/cli/commands/app-generate.command.ts | 4 +- .../src/cli/commands/app-sync.command.ts | 10 +- .../src/cli/commands/app-uninstall.command.ts | 8 +- .../src/cli/commands/app.command.ts | 10 +- .../src/cli/commands/auth.command.ts | 4 +- .../src/cli/services/api.service.ts | 10 +- .../src/cli/services/config.service.ts | 6 +- .../src/cli/services/generate.service.ts | 4 +- .../src/cli/types/api-response.types.ts | 13 ++ .../twenty-sdk/src/cli/types/config.types.ts | 111 ----------- .../utils/__tests__/convert-to-label.spec.ts | 2 +- .../__tests__/get-function-base-file.spec.ts | 2 +- .../get-object-decorated-class.spec.ts | 2 +- .../cli/utils/__tests__/load-manifest.spec.ts | 39 ++-- .../twenty-sdk/src/cli/utils/format-path.ts | 2 +- .../src/cli/utils/load-env-variables.ts | 2 +- .../twenty-sdk/src/cli/utils/load-manifest.ts | 26 +-- packages/twenty-sdk/tsconfig.spec.json | 1 + ...1764923552610-addApplicationRoleColumns.ts | 25 +++ .../common-base-query-runner.service.ts | 2 +- ...-with-settings-permissions-requirements.ts | 2 +- .../metadata/rest-api-metadata.controller.ts | 2 +- .../admin-panel/admin-panel.resolver.ts | 2 +- .../core-modules/api-key/api-key.resolver.ts | 2 +- .../api-key/controllers/api-key.controller.ts | 2 +- .../application/application-sync.module.ts | 8 + .../application/application-sync.service.ts | 139 +++++++++++++- .../application/application.resolver.ts | 3 +- .../application/dtos/application.input.ts | 8 +- .../application/types/application.types.ts | 113 ------------ .../application-variable.resolver.ts | 3 +- .../application-variable.service.ts | 4 +- .../approved-access-domain.resolver.ts | 3 +- .../engine/core-modules/auth/auth.resolver.ts | 2 +- .../auth/services/auth.service.ts | 2 +- .../auth/strategies/jwt.auth.strategy.ts | 2 +- .../core-modules/billing/billing.resolver.ts | 2 +- .../engine/core-modules/core-engine.module.ts | 2 + .../emailing-domain.resolver.ts | 3 +- .../interfaces/storage-driver.interface.ts | 2 +- .../file-storage/drivers/local.driver.ts | 3 +- .../file-storage/drivers/s3.driver.ts | 3 +- .../file-storage/file-storage.service.ts | 3 +- .../file-storage/types/source.type.ts | 1 - .../utils/read-s3-folder-content.ts | 3 +- .../resolvers/file-upload.resolver.ts | 2 +- .../file/resolvers/file.resolver.ts | 2 +- .../imap-smtp-caldav-connection.resolver.ts | 2 +- .../services/impersonation.service.ts | 2 +- .../engine/core-modules/lab/lab.resolver.ts | 3 +- .../postgres-credentials.resolver.ts | 3 +- .../public-domain/public-domain.resolver.ts | 2 +- .../get-last-common-layer-dependencies.ts | 3 +- .../engine/core-modules/sso/sso.resolver.ts | 3 +- .../services/tool-provider.service.ts | 2 +- .../tool/services/tool-registry.service.ts | 60 ++++++ .../core-modules/tool/types/tool.type.ts | 2 +- .../user-workspace/user-workspace.entity.ts | 6 +- .../user-workspace/user-workspace.resolver.ts | 2 +- .../engine/core-modules/user/user.resolver.ts | 2 +- .../webhook/controllers/webhook.controller.ts | 3 +- .../core-modules/webhook/webhook.resolver.ts | 2 +- .../resolvers/workflow-builder.resolver.ts | 2 +- .../resolvers/workflow-trigger.resolver.ts | 3 +- .../workflow-version-edge.resolver.ts | 3 +- .../workflow-version-step.resolver.ts | 3 +- .../resolvers/workflow-version.resolver.ts | 3 +- .../workspace-invitation.resolver.ts | 3 +- .../workspace/services/workspace.service.ts | 2 +- .../workspace/workspace.resolver.ts | 2 +- .../settings-permission.guard.spec.ts | 2 +- .../guards/impersonate-permission.guard.ts | 2 +- .../guards/settings-permission.guard.ts | 2 +- .../resolvers/agent-turn.resolver.ts | 2 +- .../ai/ai-agent/agent.resolver.ts | 3 +- ...m-create-agent-input-to-flat-agent.util.ts | 1 + ...gent-input-to-flat-agent-to-update.util.ts | 1 + .../controllers/agent-chat.controller.ts | 2 +- .../ai-chat/resolvers/agent-chat.resolver.ts | 3 +- .../__tests__/tool-adapter.service.spec.ts | 172 ++++++++++++++++++ .../ai-tools/services/tool-adapter.service.ts | 54 ++++++ .../resolvers/cron-trigger.resolver.ts | 2 +- .../database-event-trigger.resolver.ts | 2 +- .../field-metadata/field-metadata.resolver.ts | 2 +- ...t-entities-by-universal-identifier.util.ts | 17 ++ ...-target-foreign-key-properties.constant.ts | 1 + ...-target-entity-to-flat-role-target.util.ts | 1 + ...-role-input-to-flat-role-to-create.util.ts | 2 + .../from-role-entity-to-flat-role.util.ts | 1 + .../object-metadata.resolver.ts | 3 +- .../controllers/page-layout-tab.controller.ts | 2 +- .../page-layout-widget.controller.ts | 2 +- .../controllers/page-layout.controller.ts | 2 +- .../resolvers/page-layout-tab.resolver.ts | 2 +- .../resolvers/page-layout-widget.resolver.ts | 3 +- .../resolvers/page-layout.resolver.ts | 2 +- .../dtos/permission-flag.dto.ts | 3 +- .../dtos/upsert-permission-flag-input.ts | 2 +- .../permission-flag/permission-flag.entity.ts | 2 +- .../permission-flag.service.ts | 2 +- .../__tests__/permissions.service.spec.ts | 3 +- .../permissions/permissions.service.ts | 2 +- .../types/user-workspace-permissions.ts | 3 +- .../remote-server/remote-server.resolver.ts | 3 +- .../remote-table/remote-table.resolver.ts | 3 +- .../role-target/role-target.entity.ts | 3 + ...nput-to-flat-role-target-to-create.util.ts | 1 + .../role/dtos/create-role-input.dto.ts | 5 + .../metadata-modules/role/dtos/role.dto.ts | 3 + .../role/dtos/update-role-input.dto.ts | 5 + .../metadata-modules/role/role.entity.ts | 3 + .../metadata-modules/role/role.resolver.ts | 2 +- .../metadata-modules/role/role.service.ts | 26 +++ ...rkspace-roles-permissions-cache.service.ts | 2 +- .../role/utils/fromFlatRoleToRoleDto.util.ts | 2 + ...ermissionsToUserWorkspacePermissionsDto.ts | 3 +- .../dtos/create-route-trigger.input.ts | 3 +- .../route-trigger/dtos/route-trigger.dto.ts | 2 +- .../dtos/update-route-trigger.input.ts | 3 +- .../resolvers/route-trigger.resolver.ts | 2 +- .../route-trigger/route-trigger.controller.ts | 2 +- .../route-trigger/route-trigger.entity.ts | 9 +- .../route-trigger/route-trigger.service.ts | 6 +- .../create-serverless-function-layer.input.ts | 3 +- .../serverless-function-layer.entity.ts | 2 +- .../serverless-function-layer.resolver.ts | 3 +- .../dtos/create-serverless-function.input.ts | 3 +- .../dtos/update-serverless-function.input.ts | 3 +- .../serverless-function.resolver.ts | 2 +- .../serverless-function.service.ts | 2 +- .../types/flat-serverless-function.type.ts | 3 +- .../services/view-access.service.ts | 2 +- ...tion-serverless-function-action-v2.type.ts | 3 +- ...verless-function-action-handler.service.ts | 2 +- .../services/workspace-sync-role.service.ts | 2 +- .../standard-roles/roles/admin-role.ts | 1 + .../roles/dashboard-manager-role.ts | 4 +- .../roles/data-manipulator-role.ts | 1 + .../roles/data-model-manager-role.ts | 4 +- .../roles/workflow-manager-role.ts | 4 +- .../standard-role-definition.interface.ts | 3 +- .../channel-sync/channel-sync.resolver.ts | 3 +- ...workspace-member-pre-query-hook.service.ts | 2 +- ...r-settings-permissions.integration-spec.ts | 2 +- .../roles.integration-spec.ts | 2 +- packages/twenty-shared/package.json | 9 + packages/twenty-shared/project.json | 2 + .../application/applicationManifestType.ts | 13 ++ .../src/application/applicationType.ts | 46 +++++ .../application/applicationVariablesType.ts | 8 + .../src/application/fieldManifestType.ts | 14 ++ .../twenty-shared/src/application/index.ts | 22 +++ .../src/application/objectManifestType.ts | 12 ++ .../src/application/packageJsonType.ts | 13 ++ .../serverlessFunctionManifestType.ts | 32 ++++ .../src/constants/PermissionFlagType.ts} | 0 packages/twenty-shared/src/constants/index.ts | 1 + .../twenty-shared/src/types/HttpMethod.ts | 7 + .../src/types/SourcesType.ts} | 0 packages/twenty-shared/src/types/index.ts | 2 + 188 files changed, 977 insertions(+), 457 deletions(-) rename packages/twenty-sdk/src/application/{field-metadata => fields}/composite-fields.ts (100%) rename packages/twenty-sdk/src/application/{field-metadata => fields}/field-type.ts (100%) rename packages/twenty-sdk/src/application/{field-metadata => fields}/field.decorator.ts (89%) rename packages/twenty-sdk/src/application/{field-metadata => fields}/on-delete-action.ts (100%) rename packages/twenty-sdk/src/application/{field-metadata => fields}/relation-type.ts (100%) rename packages/twenty-sdk/src/application/{field-metadata => fields}/relation.decorator.ts (93%) rename packages/twenty-sdk/src/application/{object-metadata => objects}/object.decorator.ts (76%) rename packages/twenty-sdk/src/application/{object-metadata => objects}/standard-object-ids.ts (100%) create mode 100644 packages/twenty-sdk/src/cli/types/api-response.types.ts delete mode 100644 packages/twenty-sdk/src/cli/types/config.types.ts create mode 100644 packages/twenty-server/src/database/typeorm/core/migrations/common/1764923552610-addApplicationRoleColumns.ts delete mode 100644 packages/twenty-server/src/engine/core-modules/application/types/application.types.ts delete mode 100644 packages/twenty-server/src/engine/core-modules/file-storage/types/source.type.ts create mode 100644 packages/twenty-server/src/engine/core-modules/tool/services/tool-registry.service.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/ai/ai-tools/services/__tests__/tool-adapter.service.spec.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/ai/ai-tools/services/tool-adapter.service.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-flat-entities-by-universal-identifier.util.ts create mode 100644 packages/twenty-shared/src/application/applicationManifestType.ts create mode 100644 packages/twenty-shared/src/application/applicationType.ts create mode 100644 packages/twenty-shared/src/application/applicationVariablesType.ts create mode 100644 packages/twenty-shared/src/application/fieldManifestType.ts create mode 100644 packages/twenty-shared/src/application/index.ts create mode 100644 packages/twenty-shared/src/application/objectManifestType.ts create mode 100644 packages/twenty-shared/src/application/packageJsonType.ts create mode 100644 packages/twenty-shared/src/application/serverlessFunctionManifestType.ts rename packages/{twenty-server/src/engine/metadata-modules/permissions/constants/permission-flag-type.constants.ts => twenty-shared/src/constants/PermissionFlagType.ts} (100%) create mode 100644 packages/twenty-shared/src/types/HttpMethod.ts rename packages/{twenty-front/src/modules/serverless-functions/types/sources.type.ts => twenty-shared/src/types/SourcesType.ts} (100%) diff --git a/packages/create-twenty-app/package.json b/packages/create-twenty-app/package.json index b520bbcb71..9667e533bd 100644 --- a/packages/create-twenty-app/package.json +++ b/packages/create-twenty-app/package.json @@ -1,6 +1,6 @@ { "name": "create-twenty-app", - "version": "0.1.3", + "version": "0.2.0", "description": "Command-line interface to create Twenty application", "main": "dist/cli.cjs", "bin": "dist/cli.cjs", diff --git a/packages/create-twenty-app/src/utils/app-template.ts b/packages/create-twenty-app/src/utils/app-template.ts index 1ce01a3190..ce0508bc6d 100644 --- a/packages/create-twenty-app/src/utils/app-template.ts +++ b/packages/create-twenty-app/src/utils/app-template.ts @@ -127,7 +127,7 @@ const createPackageJson = async ({ auth: 'twenty auth login', }, dependencies: { - 'twenty-sdk': '0.1.3', + 'twenty-sdk': '0.2.0', }, devDependencies: { '@types/node': '^24.7.2', diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index b218954623..4dd8f3c2e9 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -904,6 +904,7 @@ export type CreateRoleInput = { canAccessAllTools?: InputMaybe; canBeAssignedToAgents?: InputMaybe; canBeAssignedToApiKeys?: InputMaybe; + canBeAssignedToApplications?: InputMaybe; canBeAssignedToUsers?: InputMaybe; canDestroyAllObjectRecords?: InputMaybe; canReadAllObjectRecords?: InputMaybe; @@ -3794,6 +3795,7 @@ export type Role = { objectPermissions?: Maybe>; permissionFlags?: Maybe>; standardId?: Maybe; + universalIdentifier?: Maybe; workspaceMembers: Array; }; @@ -4358,6 +4360,7 @@ export type UpdateRolePayload = { canAccessAllTools?: InputMaybe; canBeAssignedToAgents?: InputMaybe; canBeAssignedToApiKeys?: InputMaybe; + canBeAssignedToApplications?: InputMaybe; canBeAssignedToUsers?: InputMaybe; canDestroyAllObjectRecords?: InputMaybe; canReadAllObjectRecords?: InputMaybe; diff --git a/packages/twenty-front/src/generated/graphql.ts b/packages/twenty-front/src/generated/graphql.ts index 2b01b6b0a6..f2b5b67edd 100644 --- a/packages/twenty-front/src/generated/graphql.ts +++ b/packages/twenty-front/src/generated/graphql.ts @@ -887,6 +887,7 @@ export type CreateRoleInput = { canAccessAllTools?: InputMaybe; canBeAssignedToAgents?: InputMaybe; canBeAssignedToApiKeys?: InputMaybe; + canBeAssignedToApplications?: InputMaybe; canBeAssignedToUsers?: InputMaybe; canDestroyAllObjectRecords?: InputMaybe; canReadAllObjectRecords?: InputMaybe; @@ -3631,6 +3632,7 @@ export type Role = { objectPermissions?: Maybe>; permissionFlags?: Maybe>; standardId?: Maybe; + universalIdentifier?: Maybe; workspaceMembers: Array; }; @@ -4187,6 +4189,7 @@ export type UpdateRolePayload = { canAccessAllTools?: InputMaybe; canBeAssignedToAgents?: InputMaybe; canBeAssignedToApiKeys?: InputMaybe; + canBeAssignedToApplications?: InputMaybe; canBeAssignedToUsers?: InputMaybe; canDestroyAllObjectRecords?: InputMaybe; canReadAllObjectRecords?: InputMaybe; diff --git a/packages/twenty-front/src/modules/serverless-functions/utils/__tests__/flattenSources.test.ts b/packages/twenty-front/src/modules/serverless-functions/utils/__tests__/flattenSources.test.ts index ac04f889dd..698a81125f 100644 --- a/packages/twenty-front/src/modules/serverless-functions/utils/__tests__/flattenSources.test.ts +++ b/packages/twenty-front/src/modules/serverless-functions/utils/__tests__/flattenSources.test.ts @@ -1,6 +1,7 @@ // IA Generated -import { type Sources } from '@/serverless-functions/types/sources.type'; + import { flattenSources } from '@/serverless-functions/utils/flattenSources'; +import { type Sources } from 'twenty-shared/types'; describe('flattenSources', () => { it('flattens nested sources with root files', () => { diff --git a/packages/twenty-front/src/modules/serverless-functions/utils/computeNewSources.ts b/packages/twenty-front/src/modules/serverless-functions/utils/computeNewSources.ts index ffbf77a3b9..b68c096b3d 100644 --- a/packages/twenty-front/src/modules/serverless-functions/utils/computeNewSources.ts +++ b/packages/twenty-front/src/modules/serverless-functions/utils/computeNewSources.ts @@ -1,4 +1,4 @@ -import { type Sources } from '@/serverless-functions/types/sources.type'; +import { type Sources } from 'twenty-shared/types'; export const computeNewSources = ({ previousCode, diff --git a/packages/twenty-front/src/modules/serverless-functions/utils/flattenSources.ts b/packages/twenty-front/src/modules/serverless-functions/utils/flattenSources.ts index 8aa41feaaa..7eb7816711 100644 --- a/packages/twenty-front/src/modules/serverless-functions/utils/flattenSources.ts +++ b/packages/twenty-front/src/modules/serverless-functions/utils/flattenSources.ts @@ -1,5 +1,5 @@ // IA Generated -import { type Sources } from '@/serverless-functions/types/sources.type'; +import { type Sources } from 'twenty-shared/types'; type FlatSource = { path: string; content: string }; diff --git a/packages/twenty-front/src/modules/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState.ts b/packages/twenty-front/src/modules/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState.ts index 06ed4fe696..358c0f4404 100644 --- a/packages/twenty-front/src/modules/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState.ts +++ b/packages/twenty-front/src/modules/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState.ts @@ -6,7 +6,7 @@ import { type Dispatch, type SetStateAction, useState } from 'react'; import { useRecoilState } from 'recoil'; import { type FindOneServerlessFunctionSourceCodeQuery } from '~/generated-metadata/graphql'; import { type ServerlessFunction } from '~/generated/graphql'; -import { type Sources } from '@/serverless-functions/types/sources.type'; +import { type Sources } from 'twenty-shared/types'; import { flattenSources } from '@/serverless-functions/utils/flattenSources'; import { isDefined } from 'twenty-shared/utils'; diff --git a/packages/twenty-sdk/package.json b/packages/twenty-sdk/package.json index e1cf05e04c..5109d94cb7 100644 --- a/packages/twenty-sdk/package.json +++ b/packages/twenty-sdk/package.json @@ -1,6 +1,6 @@ { "name": "twenty-sdk", - "version": "0.1.3", + "version": "0.2.0", "main": "dist/index.cjs", "module": "dist/index.mjs", "types": "dist/index.d.ts", diff --git a/packages/twenty-sdk/project.json b/packages/twenty-sdk/project.json index ca53226296..1a36ebc442 100644 --- a/packages/twenty-sdk/project.json +++ b/packages/twenty-sdk/project.json @@ -42,6 +42,7 @@ "command": "tsx {projectRoot}/scripts/generateBarrels.ts" } }, + "typecheck": {}, "lint": { "options": { "lintFilePatterns": [ diff --git a/packages/twenty-sdk/src/application/application-config.ts b/packages/twenty-sdk/src/application/application-config.ts index 56616c4191..2671a8f60c 100644 --- a/packages/twenty-sdk/src/application/application-config.ts +++ b/packages/twenty-sdk/src/application/application-config.ts @@ -1,4 +1,4 @@ -import { type SyncableEntityOptions } from './syncable-entity-options.type'; +import { type SyncableEntityOptions } from '@/application/syncable-entity-options.type'; type ApplicationVariable = SyncableEntityOptions & { value?: string; diff --git a/packages/twenty-sdk/src/application/field-metadata/composite-fields.ts b/packages/twenty-sdk/src/application/fields/composite-fields.ts similarity index 100% rename from packages/twenty-sdk/src/application/field-metadata/composite-fields.ts rename to packages/twenty-sdk/src/application/fields/composite-fields.ts diff --git a/packages/twenty-sdk/src/application/field-metadata/field-type.ts b/packages/twenty-sdk/src/application/fields/field-type.ts similarity index 100% rename from packages/twenty-sdk/src/application/field-metadata/field-type.ts rename to packages/twenty-sdk/src/application/fields/field-type.ts diff --git a/packages/twenty-sdk/src/application/field-metadata/field.decorator.ts b/packages/twenty-sdk/src/application/fields/field.decorator.ts similarity index 89% rename from packages/twenty-sdk/src/application/field-metadata/field.decorator.ts rename to packages/twenty-sdk/src/application/fields/field.decorator.ts index afbebe6307..324f2ef06e 100644 --- a/packages/twenty-sdk/src/application/field-metadata/field.decorator.ts +++ b/packages/twenty-sdk/src/application/fields/field.decorator.ts @@ -1,4 +1,4 @@ -import { type SyncableEntityOptions } from '../syncable-entity-options.type'; +import { type SyncableEntityOptions } from '@/application/syncable-entity-options.type'; import { type FieldMetadataType, diff --git a/packages/twenty-sdk/src/application/field-metadata/on-delete-action.ts b/packages/twenty-sdk/src/application/fields/on-delete-action.ts similarity index 100% rename from packages/twenty-sdk/src/application/field-metadata/on-delete-action.ts rename to packages/twenty-sdk/src/application/fields/on-delete-action.ts diff --git a/packages/twenty-sdk/src/application/field-metadata/relation-type.ts b/packages/twenty-sdk/src/application/fields/relation-type.ts similarity index 100% rename from packages/twenty-sdk/src/application/field-metadata/relation-type.ts rename to packages/twenty-sdk/src/application/fields/relation-type.ts diff --git a/packages/twenty-sdk/src/application/field-metadata/relation.decorator.ts b/packages/twenty-sdk/src/application/fields/relation.decorator.ts similarity index 93% rename from packages/twenty-sdk/src/application/field-metadata/relation.decorator.ts rename to packages/twenty-sdk/src/application/fields/relation.decorator.ts index 862a1e26f3..37fef1d9ad 100644 --- a/packages/twenty-sdk/src/application/field-metadata/relation.decorator.ts +++ b/packages/twenty-sdk/src/application/fields/relation.decorator.ts @@ -1,4 +1,4 @@ -import { type SyncableEntityOptions } from '../syncable-entity-options.type'; +import { type SyncableEntityOptions } from '@/application/syncable-entity-options.type'; import { type RelationOnDeleteAction, diff --git a/packages/twenty-sdk/src/application/function-config.ts b/packages/twenty-sdk/src/application/function-config.ts index 9a85e1a148..4a1f183ff2 100644 --- a/packages/twenty-sdk/src/application/function-config.ts +++ b/packages/twenty-sdk/src/application/function-config.ts @@ -1,4 +1,4 @@ -import { type SyncableEntityOptions } from './syncable-entity-options.type'; +import { type SyncableEntityOptions } from '@/application/syncable-entity-options.type'; type RouteTrigger = { type: 'route'; diff --git a/packages/twenty-sdk/src/application/index.ts b/packages/twenty-sdk/src/application/index.ts index d7a1defd8f..c1e7dd4912 100644 --- a/packages/twenty-sdk/src/application/index.ts +++ b/packages/twenty-sdk/src/application/index.ts @@ -17,13 +17,13 @@ export type { LinksField, PhonesField, RichTextField, -} from './field-metadata/composite-fields'; -export { FieldType } from './field-metadata/field-type'; -export { Field } from './field-metadata/field.decorator'; -export { OnDeleteAction } from './field-metadata/on-delete-action'; -export { RelationType } from './field-metadata/relation-type'; -export { Relation } from './field-metadata/relation.decorator'; +} from './fields/composite-fields'; +export { FieldType } from './fields/field-type'; +export { Field } from './fields/field.decorator'; +export { OnDeleteAction } from './fields/on-delete-action'; +export { RelationType } from './fields/relation-type'; +export { Relation } from './fields/relation.decorator'; export type { FunctionConfig } from './function-config'; -export { Object } from './object-metadata/object.decorator'; -export { STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS } from './object-metadata/standard-object-ids'; +export { Object } from './objects/object.decorator'; +export { STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS } from './objects/standard-object-ids'; export type { SyncableEntityOptions } from './syncable-entity-options.type'; diff --git a/packages/twenty-sdk/src/application/object-metadata/object.decorator.ts b/packages/twenty-sdk/src/application/objects/object.decorator.ts similarity index 76% rename from packages/twenty-sdk/src/application/object-metadata/object.decorator.ts rename to packages/twenty-sdk/src/application/objects/object.decorator.ts index c3fb877c98..1b6d2d1ef2 100644 --- a/packages/twenty-sdk/src/application/object-metadata/object.decorator.ts +++ b/packages/twenty-sdk/src/application/objects/object.decorator.ts @@ -1,4 +1,4 @@ -import { type SyncableEntityOptions } from '../syncable-entity-options.type'; +import { type SyncableEntityOptions } from '@/application/syncable-entity-options.type'; type ObjectMetadataOptions = SyncableEntityOptions & { nameSingular: string; diff --git a/packages/twenty-sdk/src/application/object-metadata/standard-object-ids.ts b/packages/twenty-sdk/src/application/objects/standard-object-ids.ts similarity index 100% rename from packages/twenty-sdk/src/application/object-metadata/standard-object-ids.ts rename to packages/twenty-sdk/src/application/objects/standard-object-ids.ts diff --git a/packages/twenty-sdk/src/cli/__tests__/e2e/applications-install-delete-reinstall.e2e-spec.ts b/packages/twenty-sdk/src/cli/__tests__/e2e/applications-install-delete-reinstall.e2e-spec.ts index cb54c205d3..5e5d0e01b3 100644 --- a/packages/twenty-sdk/src/cli/__tests__/e2e/applications-install-delete-reinstall.e2e-spec.ts +++ b/packages/twenty-sdk/src/cli/__tests__/e2e/applications-install-delete-reinstall.e2e-spec.ts @@ -1,8 +1,8 @@ import { existsSync } from 'fs'; -import { AppSyncCommand } from '../../commands/app-sync.command'; -import { AppUninstallCommand } from '../../commands/app-uninstall.command'; -import { COVERED_APPLICATION_FOLDERS } from './constants/covered-applications-folder.constant'; -import { getTestedApplicationPath } from './utils/get-tested-application-path.util'; +import { AppSyncCommand } from '@/cli/commands/app-sync.command'; +import { AppUninstallCommand } from '@/cli/commands/app-uninstall.command'; +import { COVERED_APPLICATION_FOLDERS } from '@/cli/__tests__/e2e/constants/covered-applications-folder.constant'; +import { getTestedApplicationPath } from '@/cli/__tests__/e2e/utils/get-tested-application-path.util'; describe.each(COVERED_APPLICATION_FOLDERS)( 'Application: "%s" install delete and reinstall test suite', diff --git a/packages/twenty-sdk/src/cli/__tests__/e2e/constants/testConfig.ts b/packages/twenty-sdk/src/cli/__tests__/e2e/constants/testConfig.ts index fbeadb02e3..b5f9b58dc0 100644 --- a/packages/twenty-sdk/src/cli/__tests__/e2e/constants/testConfig.ts +++ b/packages/twenty-sdk/src/cli/__tests__/e2e/constants/testConfig.ts @@ -1,4 +1,4 @@ -import { type TwentyConfig } from '../../../types/config.types'; +import { type TwentyConfig } from '@/cli/services/config.service'; export const testConfig: TwentyConfig = { apiUrl: 'http://localhost:3000', diff --git a/packages/twenty-sdk/src/cli/__tests__/e2e/health.e2e-spec.ts b/packages/twenty-sdk/src/cli/__tests__/e2e/health.e2e-spec.ts index 0e7ec1eb41..12aed653fe 100644 --- a/packages/twenty-sdk/src/cli/__tests__/e2e/health.e2e-spec.ts +++ b/packages/twenty-sdk/src/cli/__tests__/e2e/health.e2e-spec.ts @@ -1,5 +1,5 @@ import axios from 'axios'; -import { SERVER_URL } from './constants/server-url.constant'; +import { SERVER_URL } from '@/cli/__tests__/e2e/constants/server-url.constant'; describe('Twenty Server Health Check (E2E)', () => { const HEALTH_ENDPOINT = `${SERVER_URL}/healthz`; diff --git a/packages/twenty-sdk/src/cli/__tests__/e2e/setupTest.ts b/packages/twenty-sdk/src/cli/__tests__/e2e/setupTest.ts index 54ec3ecb72..53b04a18a5 100644 --- a/packages/twenty-sdk/src/cli/__tests__/e2e/setupTest.ts +++ b/packages/twenty-sdk/src/cli/__tests__/e2e/setupTest.ts @@ -1,5 +1,5 @@ -import { ConfigService } from '../../services/config.service'; -import { testConfig } from './constants/testConfig'; +import { ConfigService } from '@/cli/services/config.service'; +import { testConfig } from '@/cli/__tests__/e2e/constants/testConfig'; beforeAll(() => { jest diff --git a/packages/twenty-sdk/src/cli/cli.ts b/packages/twenty-sdk/src/cli/cli.ts index a13817bd20..0670fef298 100644 --- a/packages/twenty-sdk/src/cli/cli.ts +++ b/packages/twenty-sdk/src/cli/cli.ts @@ -1,9 +1,9 @@ #!/usr/bin/env node import chalk from 'chalk'; import { Command, CommanderError } from 'commander'; -import { AppCommand } from './commands/app.command'; -import { AuthCommand } from './commands/auth.command'; -import { ConfigService } from './services/config.service'; +import { AppCommand } from '@/cli/commands/app.command'; +import { AuthCommand } from '@/cli/commands/auth.command'; +import { ConfigService } from '@/cli/services/config.service'; import packageJson from '../../package.json'; const program = new Command(); diff --git a/packages/twenty-sdk/src/cli/commands/app-add.command.ts b/packages/twenty-sdk/src/cli/commands/app-add.command.ts index 65ae73cc6b..67c4628683 100644 --- a/packages/twenty-sdk/src/cli/commands/app-add.command.ts +++ b/packages/twenty-sdk/src/cli/commands/app-add.command.ts @@ -3,10 +3,10 @@ import * as fs from 'fs-extra'; import inquirer from 'inquirer'; import { join } from 'path'; import camelcase from 'lodash.camelcase'; -import { CURRENT_EXECUTION_DIRECTORY } from '../constants/current-execution-directory'; -import { getObjectDecoratedClass } from '../utils/get-object-decorated-class'; -import { getFunctionBaseFile } from '../utils/get-function-base-file'; -import { convertToLabel } from '../utils/convert-to-label'; +import { CURRENT_EXECUTION_DIRECTORY } from '@/cli/constants/current-execution-directory'; +import { getObjectDecoratedClass } from '@/cli/utils/get-object-decorated-class'; +import { getFunctionBaseFile } from '@/cli/utils/get-function-base-file'; +import { convertToLabel } from '@/cli/utils/convert-to-label'; export enum SyncableEntity { AGENT = 'agent', diff --git a/packages/twenty-sdk/src/cli/commands/app-dev.command.ts b/packages/twenty-sdk/src/cli/commands/app-dev.command.ts index d2000bbfab..9c6831e150 100644 --- a/packages/twenty-sdk/src/cli/commands/app-dev.command.ts +++ b/packages/twenty-sdk/src/cli/commands/app-dev.command.ts @@ -1,6 +1,6 @@ import chalk from 'chalk'; import * as chokidar from 'chokidar'; -import { CURRENT_EXECUTION_DIRECTORY } from '../constants/current-execution-directory'; +import { CURRENT_EXECUTION_DIRECTORY } from '@/cli/constants/current-execution-directory'; import { ApiService } from '@/cli/services/api.service'; import { loadManifest } from '@/cli/utils/load-manifest'; diff --git a/packages/twenty-sdk/src/cli/commands/app-generate.command.ts b/packages/twenty-sdk/src/cli/commands/app-generate.command.ts index 62832ec0df..dee937a844 100644 --- a/packages/twenty-sdk/src/cli/commands/app-generate.command.ts +++ b/packages/twenty-sdk/src/cli/commands/app-generate.command.ts @@ -1,6 +1,6 @@ import chalk from 'chalk'; -import { GenerateService } from '../services/generate.service'; -import { CURRENT_EXECUTION_DIRECTORY } from '../constants/current-execution-directory'; +import { GenerateService } from '@/cli/services/generate.service'; +import { CURRENT_EXECUTION_DIRECTORY } from '@/cli/constants/current-execution-directory'; export class AppGenerateCommand { private generateService = new GenerateService(); diff --git a/packages/twenty-sdk/src/cli/commands/app-sync.command.ts b/packages/twenty-sdk/src/cli/commands/app-sync.command.ts index 97ebf7e88d..27d2ce785c 100644 --- a/packages/twenty-sdk/src/cli/commands/app-sync.command.ts +++ b/packages/twenty-sdk/src/cli/commands/app-sync.command.ts @@ -1,9 +1,9 @@ import chalk from 'chalk'; -import { CURRENT_EXECUTION_DIRECTORY } from '../constants/current-execution-directory'; -import { ApiService } from '../services/api.service'; -import { GenerateService } from '../services/generate.service'; -import { type ApiResponse } from '../types/config.types'; -import { loadManifest } from '../utils/load-manifest'; +import { CURRENT_EXECUTION_DIRECTORY } from '@/cli/constants/current-execution-directory'; +import { ApiService } from '@/cli/services/api.service'; +import { GenerateService } from '@/cli/services/generate.service'; +import { type ApiResponse } from '@/cli/types/api-response.types'; +import { loadManifest } from '@/cli/utils/load-manifest'; export class AppSyncCommand { private apiService = new ApiService(); diff --git a/packages/twenty-sdk/src/cli/commands/app-uninstall.command.ts b/packages/twenty-sdk/src/cli/commands/app-uninstall.command.ts index ccc35ee043..4a1f66da06 100644 --- a/packages/twenty-sdk/src/cli/commands/app-uninstall.command.ts +++ b/packages/twenty-sdk/src/cli/commands/app-uninstall.command.ts @@ -1,9 +1,9 @@ import chalk from 'chalk'; import inquirer from 'inquirer'; -import { CURRENT_EXECUTION_DIRECTORY } from '../constants/current-execution-directory'; -import { ApiService } from '../services/api.service'; -import { type ApiResponse } from '../types/config.types'; -import { loadManifest } from '../utils/load-manifest'; +import { CURRENT_EXECUTION_DIRECTORY } from '@/cli/constants/current-execution-directory'; +import { ApiService } from '@/cli/services/api.service'; +import { type ApiResponse } from '@/cli/types/api-response.types'; +import { loadManifest } from '@/cli/utils/load-manifest'; export class AppUninstallCommand { private apiService = new ApiService(); diff --git a/packages/twenty-sdk/src/cli/commands/app.command.ts b/packages/twenty-sdk/src/cli/commands/app.command.ts index c7f2e20c49..9de39db0ce 100644 --- a/packages/twenty-sdk/src/cli/commands/app.command.ts +++ b/packages/twenty-sdk/src/cli/commands/app.command.ts @@ -5,11 +5,11 @@ import { isSyncableEntity, SyncableEntity, } from './app-add.command'; -import { AppUninstallCommand } from './app-uninstall.command'; -import { AppDevCommand } from './app-dev.command'; -import { AppSyncCommand } from './app-sync.command'; -import { formatPath } from '../utils/format-path'; -import { AppGenerateCommand } from './app-generate.command'; +import { AppUninstallCommand } from '@/cli/commands/app-uninstall.command'; +import { AppDevCommand } from '@/cli/commands/app-dev.command'; +import { AppSyncCommand } from '@/cli/commands/app-sync.command'; +import { formatPath } from '@/cli/utils/format-path'; +import { AppGenerateCommand } from '@/cli/commands/app-generate.command'; import { AppLogsCommand } from '@/cli/commands/app-logs.command'; export class AppCommand { diff --git a/packages/twenty-sdk/src/cli/commands/auth.command.ts b/packages/twenty-sdk/src/cli/commands/auth.command.ts index 84be8ecca8..d0fc1edb22 100644 --- a/packages/twenty-sdk/src/cli/commands/auth.command.ts +++ b/packages/twenty-sdk/src/cli/commands/auth.command.ts @@ -1,8 +1,8 @@ import chalk from 'chalk'; import { Command } from 'commander'; import inquirer from 'inquirer'; -import { ApiService } from '../services/api.service'; -import { ConfigService } from '../services/config.service'; +import { ApiService } from '@/cli/services/api.service'; +import { ConfigService } from '@/cli/services/config.service'; export class AuthCommand { private configService = new ConfigService(); diff --git a/packages/twenty-sdk/src/cli/services/api.service.ts b/packages/twenty-sdk/src/cli/services/api.service.ts index 3adde433f1..301c3eee31 100644 --- a/packages/twenty-sdk/src/cli/services/api.service.ts +++ b/packages/twenty-sdk/src/cli/services/api.service.ts @@ -6,12 +6,12 @@ import { printSchema, } from 'graphql/index'; import { createClient } from 'graphql-sse'; +import { type ApiResponse } from '@/cli/types/api-response.types'; +import { ConfigService } from '@/cli/services/config.service'; import { - type ApiResponse, - type AppManifest, type PackageJson, -} from '../types/config.types'; -import { ConfigService } from './config.service'; + type ApplicationManifest, +} from 'twenty-shared/application'; export class ApiService { private client: AxiosInstance; @@ -94,7 +94,7 @@ export class ApiService { }: { packageJson: PackageJson; yarnLock: string; - manifest: AppManifest; + manifest: ApplicationManifest; }): Promise { try { const mutation = ` diff --git a/packages/twenty-sdk/src/cli/services/config.service.ts b/packages/twenty-sdk/src/cli/services/config.service.ts index 9d95b02950..f3f0bb982a 100644 --- a/packages/twenty-sdk/src/cli/services/config.service.ts +++ b/packages/twenty-sdk/src/cli/services/config.service.ts @@ -1,7 +1,11 @@ import * as fs from 'fs-extra'; import * as os from 'os'; import * as path from 'path'; -import { type TwentyConfig } from '../types/config.types'; + +export type TwentyConfig = { + apiUrl: string; + apiKey?: string; +}; type PersistedConfig = TwentyConfig & { profiles?: Record; diff --git a/packages/twenty-sdk/src/cli/services/generate.service.ts b/packages/twenty-sdk/src/cli/services/generate.service.ts index 0e9468a011..2fcc6b90f9 100644 --- a/packages/twenty-sdk/src/cli/services/generate.service.ts +++ b/packages/twenty-sdk/src/cli/services/generate.service.ts @@ -1,8 +1,8 @@ import { generate } from '@genql/cli'; import chalk from 'chalk'; import { join, resolve } from 'path'; -import { ApiService } from './api.service'; -import { ConfigService } from './config.service'; +import { ApiService } from '@/cli/services/api.service'; +import { ConfigService } from '@/cli/services/config.service'; export const GENERATED_FOLDER_NAME = 'generated'; diff --git a/packages/twenty-sdk/src/cli/types/api-response.types.ts b/packages/twenty-sdk/src/cli/types/api-response.types.ts new file mode 100644 index 0000000000..ed65e535f1 --- /dev/null +++ b/packages/twenty-sdk/src/cli/types/api-response.types.ts @@ -0,0 +1,13 @@ +type SuccessfulApiResponse = { + success: true; + data: T; + message?: string; +}; +type FailingApiResponse = { + success: false; + error?: unknown; + message?: string; +}; +export type ApiResponse = + | SuccessfulApiResponse + | FailingApiResponse; diff --git a/packages/twenty-sdk/src/cli/types/config.types.ts b/packages/twenty-sdk/src/cli/types/config.types.ts deleted file mode 100644 index 206a3ec4d0..0000000000 --- a/packages/twenty-sdk/src/cli/types/config.types.ts +++ /dev/null @@ -1,111 +0,0 @@ -export interface TwentyConfig { - apiUrl: string; - apiKey?: string; -} - -export type PackageJson = { - name: string; - license: string; - engines: { - node: string; - npm: string; - yarn: string; - }; - packageManager: string; - version: string; - dependencies?: object; - devDependencies?: object; -}; - -type ApplicationVariable = { - universalIdentifier: string; - value?: string; - description?: string; - isSecret?: boolean; -}; - -export type Application = { - universalIdentifier: string; - displayName?: string; - description?: string; - icon?: string; - applicationVariables?: Record; -}; - -export type AppManifest = { - application: Application; - objects: ObjectManifest[]; - serverlessFunctions: ServerlessFunctionManifest[]; - sources: Sources; -}; - -export type ServerlessFunctionManifest = { - universalIdentifier: string; - name?: string; - description?: string; - timeoutSeconds?: number; - triggers: ServerlessFunctionTriggerManifest[]; - handlerPath: string; - handlerName: string; -}; - -export type DatabaseEventTrigger = { - type: 'databaseEvent'; - eventName: string; -}; - -export type CronTrigger = { - type: 'cron'; - pattern: string; -}; - -export type RouteTrigger = { - type: 'route'; - path: string; - httpMethod: string; - isAuthRequired: boolean; -}; - -export type ServerlessFunctionTriggerManifest = { - universalIdentifier: string; -} & (CronTrigger | DatabaseEventTrigger | RouteTrigger); - -export type Sources = { [key: string]: string | Sources }; - -export type FieldMetadata = { - universalIdentifier: string; - type: string; - label: string; - description?: string; - icon?: string; - defaultValue?: any; - options?: any; - settings?: any; - isNullable?: boolean; - isFieldUiReadOnly?: boolean; -}; - -export type ObjectManifest = { - universalIdentifier: string; - nameSingular: string; - namePlural: string; - labelSingular: string; - labelPlural: string; - description?: string; - icon?: string; - fields: FieldMetadata[]; -}; - -export type SuccessfulApiResponse = { - success: true; - data: T; - message?: string; -}; -export type FailingApiResponse = { - success: false; - error?: unknown; - message?: string; -}; -export type ApiResponse = - | SuccessfulApiResponse - | FailingApiResponse; diff --git a/packages/twenty-sdk/src/cli/utils/__tests__/convert-to-label.spec.ts b/packages/twenty-sdk/src/cli/utils/__tests__/convert-to-label.spec.ts index d565478c2a..a49d241975 100644 --- a/packages/twenty-sdk/src/cli/utils/__tests__/convert-to-label.spec.ts +++ b/packages/twenty-sdk/src/cli/utils/__tests__/convert-to-label.spec.ts @@ -1,4 +1,4 @@ -import { convertToLabel } from '../convert-to-label'; +import { convertToLabel } from '@/cli/utils/convert-to-label'; describe('convertToLabel', () => { it('should convert to label', () => { diff --git a/packages/twenty-sdk/src/cli/utils/__tests__/get-function-base-file.spec.ts b/packages/twenty-sdk/src/cli/utils/__tests__/get-function-base-file.spec.ts index 67bca21d2f..891d0e49b9 100644 --- a/packages/twenty-sdk/src/cli/utils/__tests__/get-function-base-file.spec.ts +++ b/packages/twenty-sdk/src/cli/utils/__tests__/get-function-base-file.spec.ts @@ -1,4 +1,4 @@ -import { getFunctionBaseFile } from '../get-function-base-file'; +import { getFunctionBaseFile } from '@/cli/utils/get-function-base-file'; describe('getFunctionBaseFile', () => { it('should render proper file', () => { diff --git a/packages/twenty-sdk/src/cli/utils/__tests__/get-object-decorated-class.spec.ts b/packages/twenty-sdk/src/cli/utils/__tests__/get-object-decorated-class.spec.ts index cb115b692c..5461fd9c01 100644 --- a/packages/twenty-sdk/src/cli/utils/__tests__/get-object-decorated-class.spec.ts +++ b/packages/twenty-sdk/src/cli/utils/__tests__/get-object-decorated-class.spec.ts @@ -1,4 +1,4 @@ -import { getObjectDecoratedClass } from '../get-object-decorated-class'; +import { getObjectDecoratedClass } from '@/cli/utils/get-object-decorated-class'; describe('getObjectDecoratedClass', () => { it('should return proper object file', () => { diff --git a/packages/twenty-sdk/src/cli/utils/__tests__/load-manifest.spec.ts b/packages/twenty-sdk/src/cli/utils/__tests__/load-manifest.spec.ts index f55998813f..ddf49a6065 100644 --- a/packages/twenty-sdk/src/cli/utils/__tests__/load-manifest.spec.ts +++ b/packages/twenty-sdk/src/cli/utils/__tests__/load-manifest.spec.ts @@ -1,7 +1,7 @@ import { ensureDirSync, writeFileSync, removeSync } from 'fs-extra'; import { tmpdir } from 'node:os'; import { join, resolve } from 'node:path'; -import { loadManifest } from '../load-manifest'; +import { loadManifest } from '@/cli/utils/load-manifest'; import { v4 } from 'uuid'; const write = (root: string, file: string, content: string) => { @@ -74,13 +74,13 @@ declare module 'twenty-sdk' { icon?: string; }; - export const ObjectMetadata = (_: ObjectMetadataOptions): ClassDecorator => { + export const Object = (_: ObjectMetadataOptions): ClassDecorator => { return () => {}; }; export class BaseObjectMetadata {} - export enum FieldMetadataType { + export enum FieldType { TEXT = 'TEXT', FULL_NAME = 'FULL_NAME', ADDRESS = 'ADDRESS', @@ -88,7 +88,7 @@ declare module 'twenty-sdk' { DATE_TIME = 'DATE_TIME', } - export const FieldMetadata: (_: any) => PropertyDecorator; + export const Field: (_: any) => PropertyDecorator; } `; @@ -125,10 +125,9 @@ export const config: FunctionConfig = { };`; const objectMock = `import { - ObjectMetadata, - BaseObjectMetadata, - FieldMetadata, - FieldMetadataType + Object, + Field, + FieldType } from 'twenty-sdk'; enum PostCardStatus { @@ -138,7 +137,7 @@ enum PostCardStatus { RETURNED = 'RETURNED', } -@ObjectMetadata({ +@Object({ universalIdentifier: '54b589ca-eeed-4950-a176-358418b85c05', nameSingular: 'postCard', namePlural: 'postCards', @@ -147,32 +146,32 @@ enum PostCardStatus { description: ' A post card object', icon: 'IconMail', }) -export class PostCard extends BaseObjectMetadata { - @FieldMetadata({ +export class PostCard { + @Field({ universalIdentifier: '58a0a314-d7ea-4865-9850-7fb84e72f30b', - type: FieldMetadataType.TEXT, + type: FieldType.TEXT, label: 'Content', description: "Postcard's content", }) content: string; - @FieldMetadata({ + @Field({ universalIdentifier: 'c6aa31f3-da76-4ac6-889f-475e226009ac', - type: FieldMetadataType.FULL_NAME, + type: FieldType.FULL_NAME, label: 'Recipient name', }) recipientName: string; - @FieldMetadata({ + @Field({ universalIdentifier: '95045777-a0ad-49ec-98f9-22f9fc0c8266', - type: FieldMetadataType.ADDRESS, + type: FieldType.ADDRESS, label: 'Recipient address', }) recipientAddress: string; - @FieldMetadata({ + @Field({ universalIdentifier: '87b675b8-dd8c-4448-b4ca-20e5a2234a1e', - type: FieldMetadataType.SELECT, + type: FieldType.SELECT, label: 'Status', defaultValue: \`'\${PostCardStatus.DRAFT}'\`, options: [ @@ -204,9 +203,9 @@ export class PostCard extends BaseObjectMetadata { }) status: 'draft' | 'sent' | 'delivered' | 'returned'; - @FieldMetadata({ + @Field({ universalIdentifier: 'e06abe72-5b44-4e7f-93be-afc185a3c433', - type: FieldMetadataType.DATE_TIME, + type: FieldType.DATE_TIME, label: 'Delivered at', isNullable: true, defaultValue: null, diff --git a/packages/twenty-sdk/src/cli/utils/format-path.ts b/packages/twenty-sdk/src/cli/utils/format-path.ts index 751a902af1..47147a5908 100644 --- a/packages/twenty-sdk/src/cli/utils/format-path.ts +++ b/packages/twenty-sdk/src/cli/utils/format-path.ts @@ -1,5 +1,5 @@ import { join } from 'path'; -import { CURRENT_EXECUTION_DIRECTORY } from '../constants/current-execution-directory'; +import { CURRENT_EXECUTION_DIRECTORY } from '@/cli/constants/current-execution-directory'; export const formatPath = (appPath?: string) => { return appPath && !appPath?.startsWith('/') diff --git a/packages/twenty-sdk/src/cli/utils/load-env-variables.ts b/packages/twenty-sdk/src/cli/utils/load-env-variables.ts index 2a288dc07b..82f4e1e23b 100644 --- a/packages/twenty-sdk/src/cli/utils/load-env-variables.ts +++ b/packages/twenty-sdk/src/cli/utils/load-env-variables.ts @@ -1,6 +1,6 @@ import * as fs from 'fs-extra'; import dotenv from 'dotenv'; -import { findPathFile } from './find-path-file'; +import { findPathFile } from '@/cli/utils/find-path-file'; export const loadEnvVariables = async (appPath: string) => { let envFile = ''; diff --git a/packages/twenty-sdk/src/cli/utils/load-manifest.ts b/packages/twenty-sdk/src/cli/utils/load-manifest.ts index 7391917cc8..77780cff05 100644 --- a/packages/twenty-sdk/src/cli/utils/load-manifest.ts +++ b/packages/twenty-sdk/src/cli/utils/load-manifest.ts @@ -32,20 +32,20 @@ import { isTemplateExpression, isVariableStatement, } from 'typescript'; -import { GENERATED_FOLDER_NAME } from '../services/generate.service'; +import { GENERATED_FOLDER_NAME } from '@/cli/services/generate.service'; +import { type Sources } from 'twenty-shared/types'; import { - type AppManifest, type Application, - type FieldMetadata, - type ObjectManifest, type PackageJson, + type ApplicationManifest, type ServerlessFunctionManifest, - type Sources, -} from '../types/config.types'; -import { findPathFile } from '../utils/find-path-file'; -import { getTsProgramAndDiagnostics } from '../utils/get-ts-program-and-diagnostics'; -import { parseJsoncFile, parseTextFile } from '../utils/jsonc-parser'; -import { formatAndWarnTsDiagnostics } from './format-and-warn-ts-diagnostics'; + type ObjectManifest, + type FieldManifest, +} from 'twenty-shared/application'; +import { findPathFile } from '@/cli/utils/find-path-file'; +import { getTsProgramAndDiagnostics } from '@/cli/utils/get-ts-program-and-diagnostics'; +import { parseJsoncFile, parseTextFile } from '@/cli/utils/jsonc-parser'; +import { formatAndWarnTsDiagnostics } from '@/cli/utils/format-and-warn-ts-diagnostics'; type JSONValue = | string @@ -161,7 +161,7 @@ const collectObjects = (program: Program) => { const fieldDec = getDecorators(member)?.find( (d) => - isDecoratorNamed(d, 'FieldMetadata') || + isDecoratorNamed(d, 'FieldManifest') || isDecoratorNamed(d, 'Field'), ); @@ -185,7 +185,7 @@ const collectObjects = (program: Program) => { } fields.push({ - ...(fieldCfg as FieldMetadata), + ...(fieldCfg as FieldManifest), ...(name ? { name } : {}), }); } @@ -490,7 +490,7 @@ export const loadManifest = async ( ): Promise<{ packageJson: PackageJson; yarnLock: string; - manifest: AppManifest; + manifest: ApplicationManifest; shouldGenerate: boolean; }> => { const packageJson = await parseJsoncFile( diff --git a/packages/twenty-sdk/tsconfig.spec.json b/packages/twenty-sdk/tsconfig.spec.json index 16fd60f00c..fc1d192362 100644 --- a/packages/twenty-sdk/tsconfig.spec.json +++ b/packages/twenty-sdk/tsconfig.spec.json @@ -5,6 +5,7 @@ }, "include": [ "**/__mocks__/**/*", + "**/__tests__/**/*", "vite.config.ts", "scripts/generateBarrels.ts", "jest.config.mjs", diff --git a/packages/twenty-server/src/database/typeorm/core/migrations/common/1764923552610-addApplicationRoleColumns.ts b/packages/twenty-server/src/database/typeorm/core/migrations/common/1764923552610-addApplicationRoleColumns.ts new file mode 100644 index 0000000000..4068b44221 --- /dev/null +++ b/packages/twenty-server/src/database/typeorm/core/migrations/common/1764923552610-addApplicationRoleColumns.ts @@ -0,0 +1,25 @@ +import { type MigrationInterface, type QueryRunner } from 'typeorm'; + +export class AddApplicationRoleColumns1764923552610 + implements MigrationInterface +{ + name = 'AddApplicationRoleColumns1764923552610'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."roleTarget" ADD "targetApplicationId" uuid`, + ); + await queryRunner.query( + `ALTER TABLE "core"."role" ADD "canBeAssignedToApplications" boolean NOT NULL DEFAULT true`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."role" DROP COLUMN "canBeAssignedToApplications"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."roleTarget" DROP COLUMN "targetApplicationId"`, + ); + } +} diff --git a/packages/twenty-server/src/engine/api/common/common-query-runners/common-base-query-runner.service.ts b/packages/twenty-server/src/engine/api/common/common-query-runners/common-base-query-runner.service.ts index 77fad00f49..cbf413fd51 100644 --- a/packages/twenty-server/src/engine/api/common/common-query-runners/common-base-query-runner.service.ts +++ b/packages/twenty-server/src/engine/api/common/common-query-runners/common-base-query-runner.service.ts @@ -3,6 +3,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { msg } from '@lingui/core/macro'; import { isDefined } from 'twenty-shared/utils'; import { Omit } from 'zod/v4/core/util.cjs'; +import { type PermissionFlagType } from 'twenty-shared/constants'; import { WorkspaceAuthContext } from 'src/engine/api/common/interfaces/workspace-auth-context.interface'; import { QueryResultFieldValue } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/interfaces/query-result-field-value'; @@ -40,7 +41,6 @@ import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twent import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; -import { type PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsException, PermissionsExceptionCode, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/constants/objects-with-settings-permissions-requirements.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/constants/objects-with-settings-permissions-requirements.ts index b709deaeb5..09e1379d1c 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/constants/objects-with-settings-permissions-requirements.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/constants/objects-with-settings-permissions-requirements.ts @@ -1,4 +1,4 @@ -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; +import { PermissionFlagType } from 'twenty-shared/constants'; export const OBJECTS_WITH_SETTINGS_PERMISSIONS_REQUIREMENTS = { apiKey: PermissionFlagType.API_KEYS_AND_WEBHOOKS, diff --git a/packages/twenty-server/src/engine/api/rest/metadata/rest-api-metadata.controller.ts b/packages/twenty-server/src/engine/api/rest/metadata/rest-api-metadata.controller.ts index 89afb56c41..fc57b2f530 100644 --- a/packages/twenty-server/src/engine/api/rest/metadata/rest-api-metadata.controller.ts +++ b/packages/twenty-server/src/engine/api/rest/metadata/rest-api-metadata.controller.ts @@ -11,13 +11,13 @@ import { } from '@nestjs/common'; import { Request, Response } from 'express'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { RestApiMetadataService } from 'src/engine/api/rest/metadata/rest-api-metadata.service'; import { cleanGraphQLResponse } from 'src/engine/api/rest/utils/clean-graphql-response.utils'; import { JwtAuthGuard } from 'src/engine/guards/jwt-auth.guard'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @Controller('rest/metadata/*path') @UseGuards( diff --git a/packages/twenty-server/src/engine/core-modules/admin-panel/admin-panel.resolver.ts b/packages/twenty-server/src/engine/core-modules/admin-panel/admin-panel.resolver.ts index 50cfb654d5..c16aad086e 100644 --- a/packages/twenty-server/src/engine/core-modules/admin-panel/admin-panel.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/admin-panel/admin-panel.resolver.ts @@ -2,6 +2,7 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Int, Mutation, Query, Resolver } from '@nestjs/graphql'; import GraphQLJSON from 'graphql-type-json'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { AdminPanelHealthService } from 'src/engine/core-modules/admin-panel/admin-panel-health.service'; import { AdminPanelQueueService } from 'src/engine/core-modules/admin-panel/admin-panel-queue.service'; @@ -34,7 +35,6 @@ import { ServerLevelImpersonateGuard } from 'src/engine/guards/server-level-impe import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { UserAuthGuard } from 'src/engine/guards/user-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { AdminPanelHealthServiceDataDTO } from './dtos/admin-panel-health-service-data.dto'; import { QueueMetricsDataDTO } from './dtos/queue-metrics-data.dto'; diff --git a/packages/twenty-server/src/engine/core-modules/api-key/api-key.resolver.ts b/packages/twenty-server/src/engine/core-modules/api-key/api-key.resolver.ts index 58ceb6e495..5b0df4e8bc 100644 --- a/packages/twenty-server/src/engine/core-modules/api-key/api-key.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/api-key/api-key.resolver.ts @@ -9,6 +9,7 @@ import { } from '@nestjs/graphql'; import { type QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity'; @@ -25,7 +26,6 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { RoleDTO } from 'src/engine/metadata-modules/role/dtos/role.dto'; import { ApiKeyRoleService } from './services/api-key-role.service'; diff --git a/packages/twenty-server/src/engine/core-modules/api-key/controllers/api-key.controller.ts b/packages/twenty-server/src/engine/core-modules/api-key/controllers/api-key.controller.ts index ef68d128bb..af2c61d3be 100644 --- a/packages/twenty-server/src/engine/core-modules/api-key/controllers/api-key.controller.ts +++ b/packages/twenty-server/src/engine/core-modules/api-key/controllers/api-key.controller.ts @@ -11,6 +11,7 @@ import { } from '@nestjs/common'; import { type QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { RestApiExceptionFilter } from 'src/engine/api/rest/rest-api-exception.filter'; import { type ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity'; @@ -22,7 +23,6 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat import { JwtAuthGuard } from 'src/engine/guards/jwt-auth.guard'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; /** * rest/apiKeys is deprecated, use rest/metadata/apiKeys instead diff --git a/packages/twenty-server/src/engine/core-modules/application/application-sync.module.ts b/packages/twenty-server/src/engine/core-modules/application/application-sync.module.ts index 04237f030a..6c76fc50ee 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-sync.module.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-sync.module.ts @@ -16,6 +16,10 @@ import { ServerlessFunctionLayerModule } from 'src/engine/metadata-modules/serve import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module'; import { WorkspaceMigrationBuilderGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration-v2/interceptors/workspace-migration-builder-graphql-api-exception.interceptor'; import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-v2.module'; +import { RoleTargetModule } from 'src/engine/metadata-modules/role-target/role-target.module'; +import { ObjectPermissionModule } from 'src/engine/metadata-modules/object-permission/object-permission.module'; +import { PermissionFlagModule } from 'src/engine/metadata-modules/permission-flag/permission-flag.module'; +import { RoleModule } from 'src/engine/metadata-modules/role/role.module'; @Module({ imports: [ @@ -32,6 +36,10 @@ import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspa RouteTriggerModule, WorkspaceMigrationV2Module, PermissionsModule, + RoleModule, + RoleTargetModule, + ObjectPermissionModule, + PermissionFlagModule, ], providers: [ ApplicationResolver, diff --git a/packages/twenty-server/src/engine/core-modules/application/application-sync.service.ts b/packages/twenty-server/src/engine/core-modules/application/application-sync.service.ts index bae22fdc2f..141b130807 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-sync.service.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-sync.service.ts @@ -3,6 +3,14 @@ import { Injectable, Logger } from '@nestjs/common'; import { parse } from 'path'; import { isDefined } from 'twenty-shared/utils'; +import { Sources } from 'twenty-shared/types'; +import { + ApplicationManifest, + FieldManifest, + ObjectManifest, + ServerlessFunctionManifest, + ServerlessFunctionTriggerManifest, +} from 'twenty-shared/application'; import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity'; import { @@ -11,14 +19,7 @@ import { } from 'src/engine/core-modules/application/application.exception'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; import { ApplicationInput } from 'src/engine/core-modules/application/dtos/application.input'; -import { - FieldManifest, - ObjectManifest, - ServerlessFunctionManifest, - ServerlessFunctionTriggerManifest, -} from 'src/engine/core-modules/application/types/application.types'; import { ApplicationVariableEntityService } from 'src/engine/core-modules/applicationVariable/application-variable.service'; -import { Sources } from 'src/engine/core-modules/file-storage/types/source.type'; import { CronTriggerV2Service } from 'src/engine/metadata-modules/cron-trigger/services/cron-trigger-v2.service'; import { FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type'; import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; @@ -37,6 +38,11 @@ import { ServerlessFunctionV2Service } from 'src/engine/metadata-modules/serverl import { FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type'; import { computeMetadataNameFromLabelOrThrow } from 'src/engine/metadata-modules/utils/compute-metadata-name-from-label-or-throw.util'; import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service'; +import { RoleService } from 'src/engine/metadata-modules/role/role.service'; +import { RoleTargetService } from 'src/engine/metadata-modules/role-target/services/role-target.service'; +import { ObjectPermissionService } from 'src/engine/metadata-modules/object-permission/object-permission.service'; +import { FieldPermissionService } from 'src/engine/metadata-modules/object-permission/field-permission/field-permission.service'; +import { PermissionFlagService } from 'src/engine/metadata-modules/permission-flag/permission-flag.service'; @Injectable() export class ApplicationSyncService { @@ -55,6 +61,11 @@ export class ApplicationSyncService { private readonly cronTriggerV2Service: CronTriggerV2Service, private readonly routeTriggerV2Service: RouteTriggerV2Service, private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService, + private readonly roleService: RoleService, + private readonly roleTargetService: RoleTargetService, + private readonly objectPermissionService: ObjectPermissionService, + private readonly fieldPermissionService: FieldPermissionService, + private readonly permissionService: PermissionFlagService, ) {} public async synchronizeFromManifest({ @@ -124,6 +135,12 @@ export class ApplicationSyncService { let serverlessFunctionLayerId = application.serverlessFunctionLayerId; + await this.syncApplicationRole({ + applicationId: application.id, + manifest, + workspaceId, + }); + if (manifest.serverlessFunctions.length > 0) { if (!isDefined(serverlessFunctionLayerId)) { serverlessFunctionLayerId = ( @@ -161,6 +178,114 @@ export class ApplicationSyncService { }); } + private async syncApplicationRole({ + manifest, + applicationId, + workspaceId, + }: { + manifest: ApplicationManifest; + applicationId: string; + workspaceId: string; + }) { + const applicationRole = manifest.application.applicationRole; + + if ( + isDefined(applicationRole) && + isDefined(applicationRole.universalIdentifier) + ) { + let role = await this.roleService.getRoleByUniversalIdentifier({ + universalIdentifier: applicationRole.universalIdentifier, + workspaceId, + }); + + if (role) { + await this.roleService.updateRole({ + input: { + id: role.id, + update: { + ...applicationRole, + canAccessAllTools: false, + canUpdateAllSettings: false, + canBeAssignedToAgents: false, + canBeAssignedToUsers: false, + canBeAssignedToApiKeys: false, + canBeAssignedToApplications: true, + }, + }, + workspaceId, + }); + } else { + role = await this.roleService.createRole({ + input: { + canReadAllObjectRecords: true, + canUpdateAllObjectRecords: false, + canSoftDeleteAllObjectRecords: false, + canDestroyAllObjectRecords: false, + ...applicationRole, + canAccessAllTools: false, + canUpdateAllSettings: false, + canBeAssignedToAgents: false, + canBeAssignedToUsers: false, + canBeAssignedToApiKeys: false, + canBeAssignedToApplications: true, + }, + workspaceId, + applicationId: applicationId, + }); + + await this.roleTargetService.create({ + createRoleTargetInput: { + roleId: role.id, + applicationId: applicationId, + universalIdentifier: role.universalIdentifier, + targetMetadataForeignKey: 'targetApplicationId', + targetId: applicationId, + }, + workspaceId, + }); + } + + if ( + isDefined(applicationRole.objectPermissions) && + applicationRole.objectPermissions.length > 0 + ) { + await this.objectPermissionService.upsertObjectPermissions({ + workspaceId, + input: { + roleId: role.id, + objectPermissions: applicationRole.objectPermissions, + }, + }); + } + + if ( + isDefined(applicationRole.fieldPermissions) && + applicationRole.fieldPermissions.length > 0 + ) { + await this.fieldPermissionService.upsertFieldPermissions({ + workspaceId, + input: { + roleId: role.id, + fieldPermissions: applicationRole.fieldPermissions, + }, + }); + } + + if ( + isDefined(applicationRole.permissionFlags) && + applicationRole.permissionFlags.length > 0 + ) { + await this.permissionService.upsertPermissionFlags({ + workspaceId, + input: { + roleId: role.id, + permissionFlagKeys: applicationRole.permissionFlags, + }, + }); + } + } + } + private async syncFields({ objectId, fieldsToSync, diff --git a/packages/twenty-server/src/engine/core-modules/application/application.resolver.ts b/packages/twenty-server/src/engine/core-modules/application/application.resolver.ts index f4e22e8a03..ae6b2659fa 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application.resolver.ts @@ -1,6 +1,8 @@ import { UseFilters, UseGuards, UseInterceptors } from '@nestjs/common'; import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { ApplicationExceptionFilter } from 'src/engine/core-modules/application/application-exception-filter'; import { ApplicationSyncService } from 'src/engine/core-modules/application/application-sync.service'; @@ -14,7 +16,6 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat import { RequireFeatureFlag } from 'src/engine/guards/feature-flag.guard'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { WorkspaceMigrationBuilderGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration-v2/interceptors/workspace-migration-builder-graphql-api-exception.interceptor'; @UseGuards( diff --git a/packages/twenty-server/src/engine/core-modules/application/dtos/application.input.ts b/packages/twenty-server/src/engine/core-modules/application/dtos/application.input.ts index 0a5395c878..8fb5ca11f8 100644 --- a/packages/twenty-server/src/engine/core-modules/application/dtos/application.input.ts +++ b/packages/twenty-server/src/engine/core-modules/application/dtos/application.input.ts @@ -1,16 +1,12 @@ import { ArgsType, Field } from '@nestjs/graphql'; import GraphQLJSON from 'graphql-type-json'; - -import { - AppManifest, - PackageJson, -} from 'src/engine/core-modules/application/types/application.types'; +import { ApplicationManifest, PackageJson } from 'twenty-shared/application'; @ArgsType() export class ApplicationInput { @Field(() => GraphQLJSON, { nullable: false }) - manifest: AppManifest; + manifest: ApplicationManifest; @Field(() => GraphQLJSON, { nullable: false }) packageJson: PackageJson; diff --git a/packages/twenty-server/src/engine/core-modules/application/types/application.types.ts b/packages/twenty-server/src/engine/core-modules/application/types/application.types.ts deleted file mode 100644 index 114f378151..0000000000 --- a/packages/twenty-server/src/engine/core-modules/application/types/application.types.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { type FieldMetadataType } from 'twenty-shared/types'; - -import { type HTTPMethod } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; - -export type PackageJson = { - name: string; - license: string; - engines: { - node: string; - npm: string; - yarn: string; - }; - packageManager: string; - version: string; - dependencies?: object; - devDependencies?: object; -}; - -type ApplicationVariable = { - universalIdentifier: string; - value?: string; - description?: string; - isSecret?: boolean; -}; - -type Sources = { [key: string]: string | Sources }; - -type Application = { - universalIdentifier: string; - displayName?: string; - description?: string; - icon?: string; - applicationVariables?: Record; -}; -export type AppManifest = { - application: Application; - objects: ObjectManifest[]; - serverlessFunctions: ServerlessFunctionManifest[]; - sources: Sources; -}; - -export type ServerlessFunctionManifest = { - universalIdentifier: string; - name?: string; - description?: string; - timeoutSeconds?: number; - handlerPath: string; - handlerName: string; - triggers: ServerlessFunctionTriggerManifest[]; -}; - -export type ServerlessFunctionTriggerManifest = ( - | { - type: 'cron'; - pattern: string; - } - | { - type: 'databaseEvent'; - eventName: string; - } - | { - type: 'route'; - path: string; - httpMethod: HTTPMethod; - isAuthRequired: boolean; - } -) & { - universalIdentifier: string; -}; - -export type FieldManifest = { - universalIdentifier: string; - type: FieldMetadataType; - label: string; - description?: string; - icon?: string; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - defaultValue?: any; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - options?: any; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - settings?: any; - isNullable?: boolean; - isFieldUiReadOnly?: boolean; -}; - -export type ObjectManifest = { - universalIdentifier: string; - nameSingular: string; - namePlural: string; - labelSingular: string; - labelPlural: string; - description?: string; - icon?: string; - fields?: FieldManifest[]; -}; - -interface AgentResponseFormat { - type: 'json' | 'text'; - schema?: Record; -} - -export type AgentManifest = { - $schema?: string; - standardId: string; - name: string; - label: string; - description?: string; - icon?: string; - prompt: string; - modelId: string; - responseFormat?: AgentResponseFormat; -}; diff --git a/packages/twenty-server/src/engine/core-modules/applicationVariable/application-variable.resolver.ts b/packages/twenty-server/src/engine/core-modules/applicationVariable/application-variable.resolver.ts index 74a0f4d873..211a27cb2e 100644 --- a/packages/twenty-server/src/engine/core-modules/applicationVariable/application-variable.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/applicationVariable/application-variable.resolver.ts @@ -1,12 +1,13 @@ import { UseFilters, UseGuards } from '@nestjs/common'; import { Args, Mutation, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { ApplicationVariableEntityExceptionFilter } from 'src/engine/core-modules/applicationVariable/application-variable-exception-filter'; import { ApplicationVariableEntityService } from 'src/engine/core-modules/applicationVariable/application-variable.service'; import { UpdateApplicationVariableEntityInput } from 'src/engine/core-modules/applicationVariable/dtos/update-application-variable.input'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @UseGuards( WorkspaceAuthGuard, diff --git a/packages/twenty-server/src/engine/core-modules/applicationVariable/application-variable.service.ts b/packages/twenty-server/src/engine/core-modules/applicationVariable/application-variable.service.ts index d5070a4118..f16096a585 100644 --- a/packages/twenty-server/src/engine/core-modules/applicationVariable/application-variable.service.ts +++ b/packages/twenty-server/src/engine/core-modules/applicationVariable/application-variable.service.ts @@ -2,9 +2,9 @@ import { InjectRepository } from '@nestjs/typeorm'; import { isDefined } from 'twenty-shared/utils'; import { In, Not, Repository } from 'typeorm'; +import { ApplicationVariables } from 'twenty-shared/application'; import { ApplicationVariableEntity } from 'src/engine/core-modules/applicationVariable/application-variable.entity'; -import { AppManifest } from 'src/engine/core-modules/application/types/application.types'; export class ApplicationVariableEntityService { constructor( @@ -31,7 +31,7 @@ export class ApplicationVariableEntityService { applicationVariables, applicationId, }: { - applicationVariables?: AppManifest['application']['applicationVariables']; + applicationVariables?: ApplicationVariables; applicationId: string; }) { if (!isDefined(applicationVariables)) { diff --git a/packages/twenty-server/src/engine/core-modules/approved-access-domain/approved-access-domain.resolver.ts b/packages/twenty-server/src/engine/core-modules/approved-access-domain/approved-access-domain.resolver.ts index d3acbfd3c0..ce6fcee3c7 100644 --- a/packages/twenty-server/src/engine/core-modules/approved-access-domain/approved-access-domain.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/approved-access-domain/approved-access-domain.resolver.ts @@ -1,6 +1,8 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { ApprovedAccessDomainExceptionFilter } from 'src/engine/core-modules/approved-access-domain/approved-access-domain-exception-filter'; import { ApprovedAccessDomainDTO } from 'src/engine/core-modules/approved-access-domain/dtos/approved-access-domain.dto'; import { CreateApprovedAccessDomainInput } from 'src/engine/core-modules/approved-access-domain/dtos/create-approved-access.domain.input'; @@ -15,7 +17,6 @@ import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity'; diff --git a/packages/twenty-server/src/engine/core-modules/auth/auth.resolver.ts b/packages/twenty-server/src/engine/core-modules/auth/auth.resolver.ts index 07cc4eb936..f1a36742ea 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/auth.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/auth.resolver.ts @@ -7,6 +7,7 @@ import { SOURCE_LOCALE } from 'twenty-shared/translations'; import { TwoFactorAuthenticationStrategy } from 'twenty-shared/types'; import { assertIsDefinedOrThrow, isDefined } from 'twenty-shared/utils'; import { Repository } from 'typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { ApiKeyTokenInput } from 'src/engine/core-modules/auth/dto/api-key-token.input'; import { AppTokenInput } from 'src/engine/core-modules/auth/dto/app-token.input'; @@ -74,7 +75,6 @@ import { PublicEndpointGuard } from 'src/engine/guards/public-endpoint.guard'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { UserAuthGuard } from 'src/engine/guards/user-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; diff --git a/packages/twenty-server/src/engine/core-modules/auth/services/auth.service.ts b/packages/twenty-server/src/engine/core-modules/auth/services/auth.service.ts index 0723bd66b6..52543d7cbc 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/services/auth.service.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/services/auth.service.ts @@ -11,6 +11,7 @@ import { PasswordUpdateNotifyEmail } from 'twenty-emails'; import { AppPath } from 'twenty-shared/types'; import { assertIsDefinedOrThrow, isDefined } from 'twenty-shared/utils'; import { Repository } from 'typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { NodeEnvironment } from 'src/engine/core-modules/twenty-config/interfaces/node-environment.interface'; @@ -64,7 +65,6 @@ import { WorkspaceInvitationService } from 'src/engine/core-modules/workspace-in import { AuthProviderEnum } from 'src/engine/core-modules/workspace/types/workspace.type'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service'; @Injectable() diff --git a/packages/twenty-server/src/engine/core-modules/auth/strategies/jwt.auth.strategy.ts b/packages/twenty-server/src/engine/core-modules/auth/strategies/jwt.auth.strategy.ts index 6223a8e264..7718e6b093 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/strategies/jwt.auth.strategy.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/strategies/jwt.auth.strategy.ts @@ -6,6 +6,7 @@ import { msg } from '@lingui/core/macro'; import { Strategy } from 'passport-jwt'; import { assertIsDefinedOrThrow, isDefined } from 'twenty-shared/utils'; import { Repository } from 'typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity'; import { @@ -25,7 +26,6 @@ import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user import { UserEntity } from 'src/engine/core-modules/user/user.entity'; import { userValidator } from 'src/engine/core-modules/user/user.validate'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service'; @Injectable() export class JwtAuthStrategy extends PassportStrategy(Strategy, 'jwt') { diff --git a/packages/twenty-server/src/engine/core-modules/billing/billing.resolver.ts b/packages/twenty-server/src/engine/core-modules/billing/billing.resolver.ts index efe81ce75b..6b23e3c16a 100644 --- a/packages/twenty-server/src/engine/core-modules/billing/billing.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/billing.resolver.ts @@ -4,6 +4,7 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; import { WorkspaceActivationStatus } from 'twenty-shared/workspace'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { BillingCheckoutSessionInput } from 'src/engine/core-modules/billing/dtos/inputs/billing-checkout-session.input'; import { BillingSessionInput } from 'src/engine/core-modules/billing/dtos/inputs/billing-session.input'; @@ -32,7 +33,6 @@ import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { UserAuthGuard } from 'src/engine/guards/user-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsException, PermissionsExceptionCode, diff --git a/packages/twenty-server/src/engine/core-modules/core-engine.module.ts b/packages/twenty-server/src/engine/core-modules/core-engine.module.ts index 73b2924f34..537598c639 100644 --- a/packages/twenty-server/src/engine/core-modules/core-engine.module.ts +++ b/packages/twenty-server/src/engine/core-modules/core-engine.module.ts @@ -61,6 +61,7 @@ import { SubscriptionsModule } from 'src/engine/subscriptions/subscriptions.modu import { TrashCleanupModule } from 'src/engine/trash-cleanup/trash-cleanup.module'; import { WorkspaceEventEmitterModule } from 'src/engine/workspace-event-emitter/workspace-event-emitter.module'; import { ChannelSyncModule } from 'src/modules/connected-account/channel-sync/channel-sync.module'; +import { FlatPageLayoutTabModule } from 'src/engine/metadata-modules/flat-page-layout-tab/flat-page-layout-tab.module'; import { AuditModule } from './audit/audit.module'; import { ClientConfigModule } from './client-config/client-config.module'; @@ -138,6 +139,7 @@ import { FileModule } from './file/file.module'; ApiKeyModule, WebhookModule, PageLayoutModule, + FlatPageLayoutTabModule, ImpersonationModule, TrashCleanupModule, ], diff --git a/packages/twenty-server/src/engine/core-modules/emailing-domain/emailing-domain.resolver.ts b/packages/twenty-server/src/engine/core-modules/emailing-domain/emailing-domain.resolver.ts index 443e417cab..4f496e87e0 100644 --- a/packages/twenty-server/src/engine/core-modules/emailing-domain/emailing-domain.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/emailing-domain/emailing-domain.resolver.ts @@ -1,6 +1,8 @@ import { UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { EmailingDomainDriver } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain'; import { EmailingDomainDto } from 'src/engine/core-modules/emailing-domain/dtos/emailing-domain.dto'; import { EmailingDomainService } from 'src/engine/core-modules/emailing-domain/services/emailing-domain.service'; @@ -9,7 +11,6 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @UseGuards( WorkspaceAuthGuard, diff --git a/packages/twenty-server/src/engine/core-modules/file-storage/drivers/interfaces/storage-driver.interface.ts b/packages/twenty-server/src/engine/core-modules/file-storage/drivers/interfaces/storage-driver.interface.ts index 70e7561f87..2d5ca3a3e8 100644 --- a/packages/twenty-server/src/engine/core-modules/file-storage/drivers/interfaces/storage-driver.interface.ts +++ b/packages/twenty-server/src/engine/core-modules/file-storage/drivers/interfaces/storage-driver.interface.ts @@ -1,6 +1,6 @@ import { type Readable } from 'stream'; -import { type Sources } from 'src/engine/core-modules/file-storage/types/source.type'; +import { type Sources } from 'twenty-shared/types'; export interface StorageDriver { delete(params: { folderPath: string; filename?: string }): Promise; diff --git a/packages/twenty-server/src/engine/core-modules/file-storage/drivers/local.driver.ts b/packages/twenty-server/src/engine/core-modules/file-storage/drivers/local.driver.ts index c908212ece..81e257bfbe 100644 --- a/packages/twenty-server/src/engine/core-modules/file-storage/drivers/local.driver.ts +++ b/packages/twenty-server/src/engine/core-modules/file-storage/drivers/local.driver.ts @@ -4,6 +4,7 @@ import path, { dirname, join } from 'path'; import { type Readable } from 'stream'; import { isObject } from '@sniptt/guards'; +import { type Sources } from 'twenty-shared/types'; import { type StorageDriver } from 'src/engine/core-modules/file-storage/drivers/interfaces/storage-driver.interface'; import { @@ -11,8 +12,6 @@ import { FileStorageExceptionCode, } from 'src/engine/core-modules/file-storage/interfaces/file-storage-exception'; -import { type Sources } from 'src/engine/core-modules/file-storage/types/source.type'; - export interface LocalDriverOptions { storagePath: string; } diff --git a/packages/twenty-server/src/engine/core-modules/file-storage/drivers/s3.driver.ts b/packages/twenty-server/src/engine/core-modules/file-storage/drivers/s3.driver.ts index d47097b05d..149aabaf52 100644 --- a/packages/twenty-server/src/engine/core-modules/file-storage/drivers/s3.driver.ts +++ b/packages/twenty-server/src/engine/core-modules/file-storage/drivers/s3.driver.ts @@ -29,7 +29,8 @@ import { FileStorageExceptionCode, } from 'src/engine/core-modules/file-storage/interfaces/file-storage-exception'; -import type { Sources } from 'src/engine/core-modules/file-storage/types/source.type'; +import type { Sources } from 'twenty-shared/types'; + import { readFileContent } from 'src/engine/core-modules/file-storage/utils/read-file-content'; import { readS3FolderContent } from 'src/engine/core-modules/file-storage/utils/read-s3-folder-content'; diff --git a/packages/twenty-server/src/engine/core-modules/file-storage/file-storage.service.ts b/packages/twenty-server/src/engine/core-modules/file-storage/file-storage.service.ts index bd6135cd96..cf555ab845 100644 --- a/packages/twenty-server/src/engine/core-modules/file-storage/file-storage.service.ts +++ b/packages/twenty-server/src/engine/core-modules/file-storage/file-storage.service.ts @@ -2,10 +2,11 @@ import { Injectable } from '@nestjs/common'; import { type Readable } from 'stream'; +import { Sources } from 'twenty-shared/types'; + import { type StorageDriver } from 'src/engine/core-modules/file-storage/drivers/interfaces/storage-driver.interface'; import { FileStorageDriverFactory } from 'src/engine/core-modules/file-storage/file-storage-driver.factory'; -import { Sources } from 'src/engine/core-modules/file-storage/types/source.type'; @Injectable() export class FileStorageService implements StorageDriver { diff --git a/packages/twenty-server/src/engine/core-modules/file-storage/types/source.type.ts b/packages/twenty-server/src/engine/core-modules/file-storage/types/source.type.ts deleted file mode 100644 index 55873723ff..0000000000 --- a/packages/twenty-server/src/engine/core-modules/file-storage/types/source.type.ts +++ /dev/null @@ -1 +0,0 @@ -export type Sources = { [key: string]: string | Sources }; diff --git a/packages/twenty-server/src/engine/core-modules/file-storage/utils/read-s3-folder-content.ts b/packages/twenty-server/src/engine/core-modules/file-storage/utils/read-s3-folder-content.ts index 4829bdd3ea..1884fe1e7e 100644 --- a/packages/twenty-server/src/engine/core-modules/file-storage/utils/read-s3-folder-content.ts +++ b/packages/twenty-server/src/engine/core-modules/file-storage/utils/read-s3-folder-content.ts @@ -1,7 +1,6 @@ import { isDefined } from 'twenty-shared/utils'; import { isObject } from '@sniptt/guards'; - -import { type Sources } from 'src/engine/core-modules/file-storage/types/source.type'; +import { type Sources } from 'twenty-shared/types'; export const readS3FolderContent = ( files: { path: string; fileContent: string }[], diff --git a/packages/twenty-server/src/engine/core-modules/file/file-upload/resolvers/file-upload.resolver.ts b/packages/twenty-server/src/engine/core-modules/file/file-upload/resolvers/file-upload.resolver.ts index 00014552d5..659a3800ea 100644 --- a/packages/twenty-server/src/engine/core-modules/file/file-upload/resolvers/file-upload.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/file/file-upload/resolvers/file-upload.resolver.ts @@ -2,6 +2,7 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Resolver } from '@nestjs/graphql'; import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface'; @@ -15,7 +16,6 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { streamToBuffer } from 'src/utils/stream-to-buffer'; @UseGuards(WorkspaceAuthGuard) diff --git a/packages/twenty-server/src/engine/core-modules/file/resolvers/file.resolver.ts b/packages/twenty-server/src/engine/core-modules/file/resolvers/file.resolver.ts index 26591d7016..132f42c2e7 100644 --- a/packages/twenty-server/src/engine/core-modules/file/resolvers/file.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/file/resolvers/file.resolver.ts @@ -2,6 +2,7 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Resolver } from '@nestjs/graphql'; import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs'; +import { PermissionFlagType } from 'twenty-shared/constants'; import type { FileUpload } from 'graphql-upload/processRequest.mjs'; @@ -14,7 +15,6 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { streamToBuffer } from 'src/utils/stream-to-buffer'; @UseGuards(WorkspaceAuthGuard) diff --git a/packages/twenty-server/src/engine/core-modules/imap-smtp-caldav-connection/imap-smtp-caldav-connection.resolver.ts b/packages/twenty-server/src/engine/core-modules/imap-smtp-caldav-connection/imap-smtp-caldav-connection.resolver.ts index 64dd6ad979..25119dac6b 100644 --- a/packages/twenty-server/src/engine/core-modules/imap-smtp-caldav-connection/imap-smtp-caldav-connection.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/imap-smtp-caldav-connection/imap-smtp-caldav-connection.resolver.ts @@ -9,6 +9,7 @@ import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; import { ConnectedAccountProvider } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { AuthGraphqlApiExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-graphql-api-exception.filter'; @@ -25,7 +26,6 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; import { ImapSmtpCalDavAPIService } from 'src/modules/connected-account/services/imap-smtp-caldav-apis.service'; diff --git a/packages/twenty-server/src/engine/core-modules/impersonation/services/impersonation.service.ts b/packages/twenty-server/src/engine/core-modules/impersonation/services/impersonation.service.ts index e9ae50afc8..c843f4f698 100644 --- a/packages/twenty-server/src/engine/core-modules/impersonation/services/impersonation.service.ts +++ b/packages/twenty-server/src/engine/core-modules/impersonation/services/impersonation.service.ts @@ -3,6 +3,7 @@ import { InjectRepository } from '@nestjs/typeorm'; import { isDefined } from 'twenty-shared/utils'; import { Repository } from 'typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { NodeEnvironment } from 'src/engine/core-modules/twenty-config/interfaces/node-environment.interface'; @@ -18,7 +19,6 @@ import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twent import { twoFactorAuthenticationMethodsValidator } from 'src/engine/core-modules/two-factor-authentication/two-factor-authentication.validation'; import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; import { AuthProviderEnum } from 'src/engine/core-modules/workspace/types/workspace.type'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service'; @Injectable() diff --git a/packages/twenty-server/src/engine/core-modules/lab/lab.resolver.ts b/packages/twenty-server/src/engine/core-modules/lab/lab.resolver.ts index 66dfaa05ac..dd1947b0c5 100644 --- a/packages/twenty-server/src/engine/core-modules/lab/lab.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/lab/lab.resolver.ts @@ -1,6 +1,8 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { AuthGraphqlApiExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-graphql-api-exception.filter'; import { FeatureFlagDTO } from 'src/engine/core-modules/feature-flag/dtos/feature-flag-dto'; import { FeatureFlagException } from 'src/engine/core-modules/feature-flag/feature-flag.exception'; @@ -13,7 +15,6 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; @Resolver() diff --git a/packages/twenty-server/src/engine/core-modules/postgres-credentials/postgres-credentials.resolver.ts b/packages/twenty-server/src/engine/core-modules/postgres-credentials/postgres-credentials.resolver.ts index 68ef66397a..1dcf3a2046 100644 --- a/packages/twenty-server/src/engine/core-modules/postgres-credentials/postgres-credentials.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/postgres-credentials/postgres-credentials.resolver.ts @@ -1,13 +1,14 @@ import { UseGuards } from '@nestjs/common'; import { Mutation, Query, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { PostgresCredentialsDTO } from 'src/engine/core-modules/postgres-credentials/dtos/postgres-credentials.dto'; import { PostgresCredentialsService } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.service'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @UseGuards( WorkspaceAuthGuard, diff --git a/packages/twenty-server/src/engine/core-modules/public-domain/public-domain.resolver.ts b/packages/twenty-server/src/engine/core-modules/public-domain/public-domain.resolver.ts index 9e84f90427..e34a9383aa 100644 --- a/packages/twenty-server/src/engine/core-modules/public-domain/public-domain.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/public-domain/public-domain.resolver.ts @@ -4,6 +4,7 @@ import { InjectRepository } from '@nestjs/typeorm'; import { assertIsDefinedOrThrow } from 'twenty-shared/utils'; import { Repository } from 'typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { DomainValidRecords } from 'src/engine/core-modules/dns-manager/dtos/domain-valid-records'; import { DnsManagerService } from 'src/engine/core-modules/dns-manager/services/dns-manager.service'; @@ -22,7 +23,6 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @UseGuards( WorkspaceAuthGuard, diff --git a/packages/twenty-server/src/engine/core-modules/serverless/drivers/utils/get-last-common-layer-dependencies.ts b/packages/twenty-server/src/engine/core-modules/serverless/drivers/utils/get-last-common-layer-dependencies.ts index 963a803d56..f538c3fd5a 100644 --- a/packages/twenty-server/src/engine/core-modules/serverless/drivers/utils/get-last-common-layer-dependencies.ts +++ b/packages/twenty-server/src/engine/core-modules/serverless/drivers/utils/get-last-common-layer-dependencies.ts @@ -1,9 +1,10 @@ import fs from 'fs/promises'; import { join } from 'path'; +import { type PackageJson } from 'twenty-shared/application'; + import { getLayerDependenciesDirName } from 'src/engine/core-modules/serverless/drivers/utils/get-layer-dependencies-dir-name'; import { LAST_LAYER_VERSION } from 'src/engine/core-modules/serverless/drivers/layers/last-layer-version'; -import { type PackageJson } from 'src/engine/core-modules/application/types/application.types'; export type LayerDependencies = { packageJson: PackageJson; diff --git a/packages/twenty-server/src/engine/core-modules/sso/sso.resolver.ts b/packages/twenty-server/src/engine/core-modules/sso/sso.resolver.ts index b4f9af355f..d143b8faff 100644 --- a/packages/twenty-server/src/engine/core-modules/sso/sso.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/sso/sso.resolver.ts @@ -3,6 +3,8 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { EnterpriseFeaturesEnabledGuard } from 'src/engine/core-modules/auth/guards/enterprise-features-enabled.guard'; import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; @@ -22,7 +24,6 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; @Resolver() diff --git a/packages/twenty-server/src/engine/core-modules/tool-provider/services/tool-provider.service.ts b/packages/twenty-server/src/engine/core-modules/tool-provider/services/tool-provider.service.ts index f378ed4e80..773d0c83cd 100644 --- a/packages/twenty-server/src/engine/core-modules/tool-provider/services/tool-provider.service.ts +++ b/packages/twenty-server/src/engine/core-modules/tool-provider/services/tool-provider.service.ts @@ -1,6 +1,7 @@ import { Inject, Injectable, Logger, Optional } from '@nestjs/common'; import { type ToolSet } from 'ai'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { CreateRecordService } from 'src/engine/core-modules/record-crud/services/create-record.service'; import { DeleteRecordService } from 'src/engine/core-modules/record-crud/services/delete-record.service'; @@ -21,7 +22,6 @@ import { AgentModelConfigService } from 'src/engine/metadata-modules/ai/ai-model import { AiModelRegistryService } from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-registry.service'; import { FieldMetadataToolsFactory } from 'src/engine/metadata-modules/field-metadata/tools/field-metadata-tools.factory'; import { ObjectMetadataToolsFactory } from 'src/engine/metadata-modules/object-metadata/tools/object-metadata-tools.factory'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service'; // Type-only import to avoid circular dependency at file level import type { WorkflowToolWorkspaceService } from 'src/modules/workflow/workflow-tools/services/workflow-tool.workspace-service'; diff --git a/packages/twenty-server/src/engine/core-modules/tool/services/tool-registry.service.ts b/packages/twenty-server/src/engine/core-modules/tool/services/tool-registry.service.ts new file mode 100644 index 0000000000..77396a566b --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/tool/services/tool-registry.service.ts @@ -0,0 +1,60 @@ +import { Injectable } from '@nestjs/common'; + +import { PermissionFlagType } from 'twenty-shared/constants'; + +import { ToolType } from 'src/engine/core-modules/tool/enums/tool-type.enum'; +import { HttpTool } from 'src/engine/core-modules/tool/tools/http-tool/http-tool'; +import { SendEmailTool } from 'src/engine/core-modules/tool/tools/send-email-tool/send-email-tool'; +import { type SendEmailInput } from 'src/engine/core-modules/tool/tools/send-email-tool/types/send-email-input.type'; +import { type Tool } from 'src/engine/core-modules/tool/types/tool.type'; +import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; + +@Injectable() +export class ToolRegistryService { + private readonly toolFactories: Map Tool>; + + constructor( + private readonly sendEmailTool: SendEmailTool, + private readonly twentyConfigService: TwentyConfigService, + ) { + this.toolFactories = new Map Tool>([ + [ + ToolType.HTTP_REQUEST, + () => { + const httpTool = new HttpTool(twentyConfigService); + + return { + description: httpTool.description, + inputSchema: httpTool.inputSchema, + execute: (params) => httpTool.execute(params), + flag: PermissionFlagType.HTTP_REQUEST_TOOL, + }; + }, + ], + [ + ToolType.SEND_EMAIL, + () => ({ + description: this.sendEmailTool.description, + inputSchema: this.sendEmailTool.inputSchema, + execute: (params) => + this.sendEmailTool.execute(params as SendEmailInput), + flag: PermissionFlagType.SEND_EMAIL_TOOL, + }), + ], + ]); + } + + getTool(toolType: ToolType): Tool { + const factory = this.toolFactories.get(toolType); + + if (!factory) { + throw new Error(`Unknown tool type: ${toolType}`); + } + + return factory(); + } + + getAllToolTypes(): ToolType[] { + return Array.from(this.toolFactories.keys()); + } +} diff --git a/packages/twenty-server/src/engine/core-modules/tool/types/tool.type.ts b/packages/twenty-server/src/engine/core-modules/tool/types/tool.type.ts index 9880c284ed..583892023d 100644 --- a/packages/twenty-server/src/engine/core-modules/tool/types/tool.type.ts +++ b/packages/twenty-server/src/engine/core-modules/tool/types/tool.type.ts @@ -1,8 +1,8 @@ import { type FlexibleSchema } from '@ai-sdk/provider-utils'; +import { type PermissionFlagType } from 'twenty-shared/constants'; import { type ToolInput } from 'src/engine/core-modules/tool/types/tool-input.type'; import { type ToolOutput } from 'src/engine/core-modules/tool/types/tool-output.type'; -import { type PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; export type Tool = { description: string; diff --git a/packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.entity.ts b/packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.entity.ts index 5847d64474..1d15a47b59 100644 --- a/packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.entity.ts +++ b/packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.entity.ts @@ -1,7 +1,10 @@ import { Field, ObjectType, registerEnumType } from '@nestjs/graphql'; import { IDField } from '@ptc-org/nestjs-query-graphql'; -import { PermissionsOnAllObjectRecords } from 'twenty-shared/constants'; +import { + PermissionsOnAllObjectRecords, + PermissionFlagType, +} from 'twenty-shared/constants'; import { type APP_LOCALES, SOURCE_LOCALE } from 'twenty-shared/translations'; import { Column, @@ -23,7 +26,6 @@ import { TwoFactorAuthenticationMethodEntity } from 'src/engine/core-modules/two import { UserEntity } from 'src/engine/core-modules/user/user.entity'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { ObjectPermissionDTO } from 'src/engine/metadata-modules/object-permission/dtos/object-permission.dto'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; registerEnumType(PermissionFlagType, { name: 'PermissionFlagType', diff --git a/packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.resolver.ts b/packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.resolver.ts index 7712478feb..af7ed4c9da 100644 --- a/packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/user-workspace/user-workspace.resolver.ts @@ -2,6 +2,7 @@ import { UseGuards } from '@nestjs/common'; import { Args, Mutation, Resolver } from '@nestjs/graphql'; import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface'; @@ -13,7 +14,6 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { streamToBuffer } from 'src/utils/stream-to-buffer'; @Resolver() diff --git a/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts b/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts index c89d86ceb5..8ce40bed5d 100644 --- a/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts @@ -17,6 +17,7 @@ import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs'; import { isDefined } from 'twenty-shared/utils'; import { WorkspaceActivationStatus } from 'twenty-shared/workspace'; import { In, Repository } from 'typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface'; import { SupportDriver } from 'src/engine/core-modules/twenty-config/interfaces/support.interface'; @@ -62,7 +63,6 @@ import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { UserAuthGuard } from 'src/engine/guards/user-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsException, PermissionsExceptionCode, diff --git a/packages/twenty-server/src/engine/core-modules/webhook/controllers/webhook.controller.ts b/packages/twenty-server/src/engine/core-modules/webhook/controllers/webhook.controller.ts index 5c33273209..f2dbedb60a 100644 --- a/packages/twenty-server/src/engine/core-modules/webhook/controllers/webhook.controller.ts +++ b/packages/twenty-server/src/engine/core-modules/webhook/controllers/webhook.controller.ts @@ -10,6 +10,8 @@ import { UseGuards, } from '@nestjs/common'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { RestApiExceptionFilter } from 'src/engine/api/rest/rest-api-exception.filter'; import { CreateWebhookInput } from 'src/engine/core-modules/webhook/dtos/create-webhook.dto'; import { UpdateWebhookInput } from 'src/engine/core-modules/webhook/dtos/update-webhook.dto'; @@ -20,7 +22,6 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat import { JwtAuthGuard } from 'src/engine/guards/jwt-auth.guard'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; /** * rest/webhooks is deprecated, use rest/metadata/webhooks instead diff --git a/packages/twenty-server/src/engine/core-modules/webhook/webhook.resolver.ts b/packages/twenty-server/src/engine/core-modules/webhook/webhook.resolver.ts index 7220fead3f..577b74c281 100644 --- a/packages/twenty-server/src/engine/core-modules/webhook/webhook.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/webhook/webhook.resolver.ts @@ -2,6 +2,7 @@ import { UseGuards } from '@nestjs/common'; import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; import { type QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { CreateWebhookInput } from 'src/engine/core-modules/webhook/dtos/create-webhook.dto'; import { DeleteWebhookInput } from 'src/engine/core-modules/webhook/dtos/delete-webhook.dto'; @@ -12,7 +13,6 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { WebhookEntity } from './webhook.entity'; import { WebhookService } from './webhook.service'; diff --git a/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-builder.resolver.ts b/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-builder.resolver.ts index 716618fe1e..44bf55e9d3 100644 --- a/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-builder.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-builder.resolver.ts @@ -2,6 +2,7 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Resolver } from '@nestjs/graphql'; import graphqlTypeJson from 'graphql-type-json'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; @@ -12,7 +13,6 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { UserAuthGuard } from 'src/engine/guards/user-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; import { type OutputSchema } from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type'; import { WorkflowSchemaWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.workspace-service'; diff --git a/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-trigger.resolver.ts b/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-trigger.resolver.ts index bde9b1bded..23a628accc 100644 --- a/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-trigger.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-trigger.resolver.ts @@ -1,6 +1,8 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { buildCreatedByFromFullNameMetadata } from 'src/engine/core-modules/actor/utils/build-created-by-from-full-name-metadata.util'; import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; @@ -16,7 +18,6 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { UserAuthGuard } from 'src/engine/guards/user-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; import { WorkflowTriggerWorkspaceService } from 'src/modules/workflow/workflow-trigger/workspace-services/workflow-trigger.workspace-service'; diff --git a/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version-edge.resolver.ts b/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version-edge.resolver.ts index 5fbf256817..2711f106e4 100644 --- a/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version-edge.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version-edge.resolver.ts @@ -1,6 +1,8 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; import { CreateWorkflowVersionEdgeInput } from 'src/engine/core-modules/workflow/dtos/create-workflow-version-edge-input.dto'; @@ -11,7 +13,6 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { UserAuthGuard } from 'src/engine/guards/user-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; import { WorkflowVersionEdgeWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-edge/workflow-version-edge.workspace-service'; diff --git a/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version-step.resolver.ts b/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version-step.resolver.ts index 46829b6367..f0c45bc6b8 100644 --- a/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version-step.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version-step.resolver.ts @@ -1,6 +1,8 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service'; import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; @@ -22,7 +24,6 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { UserAuthGuard } from 'src/engine/guards/user-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; import { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step.workspace-service'; import { WorkflowActionType } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type'; diff --git a/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version.resolver.ts b/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version.resolver.ts index 3dbc5d65fa..ecb5ce99b2 100644 --- a/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/workflow/resolvers/workflow-version.resolver.ts @@ -1,6 +1,8 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; import { CreateDraftFromWorkflowVersionInput } from 'src/engine/core-modules/workflow/dtos/create-draft-from-workflow-version-input.dto'; @@ -12,7 +14,6 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { UserAuthGuard } from 'src/engine/guards/user-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; import { WorkflowVersionWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-version.workspace-service'; diff --git a/packages/twenty-server/src/engine/core-modules/workspace-invitation/workspace-invitation.resolver.ts b/packages/twenty-server/src/engine/core-modules/workspace-invitation/workspace-invitation.resolver.ts index 81fdce7903..acc94d7e87 100644 --- a/packages/twenty-server/src/engine/core-modules/workspace-invitation/workspace-invitation.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/workspace-invitation/workspace-invitation.resolver.ts @@ -1,6 +1,8 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; import { UserEntity } from 'src/engine/core-modules/user/user.entity'; @@ -13,7 +15,6 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { UserAuthGuard } from 'src/engine/guards/user-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity'; diff --git a/packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.ts b/packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.ts index 10af8c5b92..c185ec1d8a 100644 --- a/packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.ts +++ b/packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.ts @@ -8,6 +8,7 @@ import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm'; import { assertIsDefinedOrThrow, isDefined } from 'twenty-shared/utils'; import { WorkspaceActivationStatus } from 'twenty-shared/workspace'; import { Repository } from 'typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { BillingSubscriptionService } from 'src/engine/core-modules/billing/services/billing-subscription.service'; import { BillingService } from 'src/engine/core-modules/billing/services/billing.service'; @@ -35,7 +36,6 @@ import { WorkspaceNotFoundDefaultError, } from 'src/engine/core-modules/workspace/workspace.exception'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsException, PermissionsExceptionCode, diff --git a/packages/twenty-server/src/engine/core-modules/workspace/workspace.resolver.ts b/packages/twenty-server/src/engine/core-modules/workspace/workspace.resolver.ts index 2de23ceecc..63981af991 100644 --- a/packages/twenty-server/src/engine/core-modules/workspace/workspace.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/workspace/workspace.resolver.ts @@ -18,6 +18,7 @@ import assert from 'assert'; import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs'; import { assertIsDefinedOrThrow, isDefined } from 'twenty-shared/utils'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface'; @@ -70,7 +71,6 @@ import { PublicEndpointGuard } from 'src/engine/guards/public-endpoint.guard'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { UserAuthGuard } from 'src/engine/guards/user-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; import { RoleDTO } from 'src/engine/metadata-modules/role/dtos/role.dto'; import { RoleService } from 'src/engine/metadata-modules/role/role.service'; diff --git a/packages/twenty-server/src/engine/guards/__tests__/settings-permission.guard.spec.ts b/packages/twenty-server/src/engine/guards/__tests__/settings-permission.guard.spec.ts index 59b2358f53..7fa72558c3 100644 --- a/packages/twenty-server/src/engine/guards/__tests__/settings-permission.guard.spec.ts +++ b/packages/twenty-server/src/engine/guards/__tests__/settings-permission.guard.spec.ts @@ -2,9 +2,9 @@ import { type ExecutionContext } from '@nestjs/common'; import { GqlExecutionContext } from '@nestjs/graphql'; import { WorkspaceActivationStatus } from 'twenty-shared/workspace'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsException } from 'src/engine/metadata-modules/permissions/permissions.exception'; import { type PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service'; diff --git a/packages/twenty-server/src/engine/guards/impersonate-permission.guard.ts b/packages/twenty-server/src/engine/guards/impersonate-permission.guard.ts index 354a5eada3..9994043776 100644 --- a/packages/twenty-server/src/engine/guards/impersonate-permission.guard.ts +++ b/packages/twenty-server/src/engine/guards/impersonate-permission.guard.ts @@ -7,8 +7,8 @@ import { GqlExecutionContext } from '@nestjs/graphql'; import { msg } from '@lingui/core/macro'; import { isDefined } from 'class-validator'; +import { PermissionFlagType } from 'twenty-shared/constants'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsException, PermissionsExceptionCode, diff --git a/packages/twenty-server/src/engine/guards/settings-permission.guard.ts b/packages/twenty-server/src/engine/guards/settings-permission.guard.ts index 9847ce4db8..17642353f2 100644 --- a/packages/twenty-server/src/engine/guards/settings-permission.guard.ts +++ b/packages/twenty-server/src/engine/guards/settings-permission.guard.ts @@ -9,8 +9,8 @@ import { GqlExecutionContext } from '@nestjs/graphql'; import { msg } from '@lingui/core/macro'; import { WorkspaceActivationStatus } from 'twenty-shared/workspace'; +import { type PermissionFlagType } from 'twenty-shared/constants'; -import { type PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsException, PermissionsExceptionCode, diff --git a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent-monitor/resolvers/agent-turn.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent-monitor/resolvers/agent-turn.resolver.ts index ba37314001..9146e4d23d 100644 --- a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent-monitor/resolvers/agent-turn.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent-monitor/resolvers/agent-turn.resolver.ts @@ -4,6 +4,7 @@ import { InjectRepository } from '@nestjs/typeorm'; import { msg } from '@lingui/core/macro'; import { Repository } from 'typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { NotFoundError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; @@ -21,7 +22,6 @@ import { AgentTurnEvaluationDTO } from 'src/engine/metadata-modules/ai/ai-agent- import { RunEvaluationInputJob } from 'src/engine/metadata-modules/ai/ai-agent-monitor/jobs/run-evaluation-input.job'; import { AgentTurnGraderService } from 'src/engine/metadata-modules/ai/ai-agent-monitor/services/agent-turn-grader.service'; import { AgentChatThreadEntity } from 'src/engine/metadata-modules/ai/ai-chat/entities/agent-chat-thread.entity'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @UseGuards(WorkspaceAuthGuard, SettingsPermissionGuard(PermissionFlagType.AI)) @Resolver() diff --git a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/agent.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/agent.resolver.ts index 15a8f85169..e73930dcb5 100644 --- a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/agent.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/agent.resolver.ts @@ -1,6 +1,8 @@ import { UseGuards, UseInterceptors } from '@nestjs/common'; import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; @@ -10,7 +12,6 @@ import { } from 'src/engine/guards/feature-flag.guard'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { fromFlatAgentWithRoleIdToAgentDto } from 'src/engine/metadata-modules/flat-agent/utils/from-agent-entity-to-agent-dto.util'; import { WorkspaceMigrationBuilderGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration-v2/interceptors/workspace-migration-builder-graphql-api-exception.interceptor'; diff --git a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/utils/from-create-agent-input-to-flat-agent.util.ts b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/utils/from-create-agent-input-to-flat-agent.util.ts index c79390693e..5a38cbd6c8 100644 --- a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/utils/from-create-agent-input-to-flat-agent.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/utils/from-create-agent-input-to-flat-agent.util.ts @@ -73,6 +73,7 @@ export const fromCreateAgentInputToFlatAgent = ({ userWorkspaceId: null, agentId, apiKeyId: null, + targetApplicationId: null, createdAt, updatedAt: createdAt, universalIdentifier: v4(), diff --git a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/utils/from-update-agent-input-to-flat-agent-to-update.util.ts b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/utils/from-update-agent-input-to-flat-agent-to-update.util.ts index e6f071a123..505eb17b84 100644 --- a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/utils/from-update-agent-input-to-flat-agent-to-update.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent/utils/from-update-agent-input-to-flat-agent-to-update.util.ts @@ -67,6 +67,7 @@ const computeAgentFlatRoleTargetToUpdate = ({ userWorkspaceId: null, agentId: flatAgent.id, apiKeyId: null, + targetApplicationId: null, createdAt: updatedAt, updatedAt, universalIdentifier: v4(), diff --git a/packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/controllers/agent-chat.controller.ts b/packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/controllers/agent-chat.controller.ts index 7dd807c472..fa258f8a7f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/controllers/agent-chat.controller.ts +++ b/packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/controllers/agent-chat.controller.ts @@ -9,6 +9,7 @@ import { import { Response } from 'express'; import { type ExtendedUIMessage } from 'twenty-shared/ai'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { RestApiExceptionFilter } from 'src/engine/api/rest/rest-api-exception.filter'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; @@ -19,7 +20,6 @@ import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.g import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; import { type RecordIdsByObjectMetadataNameSingularType } from 'src/engine/metadata-modules/ai/ai-agent/types/recordIdsByObjectMetadataNameSingular.type'; import { AgentChatStreamingService } from 'src/engine/metadata-modules/ai/ai-chat/services/agent-chat-streaming.service'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @Controller('rest/agent-chat') @UseGuards(JwtAuthGuard, WorkspaceAuthGuard) diff --git a/packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/resolvers/agent-chat.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/resolvers/agent-chat.resolver.ts index 57150b5d2d..cf657bb95f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/resolvers/agent-chat.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/resolvers/agent-chat.resolver.ts @@ -1,6 +1,8 @@ import { UseGuards } from '@nestjs/common'; import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { AuthUserWorkspaceId } from 'src/engine/decorators/auth/auth-user-workspace-id.decorator'; @@ -13,7 +15,6 @@ import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; import { AgentMessageDTO } from 'src/engine/metadata-modules/ai/ai-agent-execution/dtos/agent-message.dto'; import { AgentChatThreadDTO } from 'src/engine/metadata-modules/ai/ai-chat/dtos/agent-chat-thread.dto'; import { AgentChatService } from 'src/engine/metadata-modules/ai/ai-chat/services/agent-chat.service'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @UseGuards( WorkspaceAuthGuard, diff --git a/packages/twenty-server/src/engine/metadata-modules/ai/ai-tools/services/__tests__/tool-adapter.service.spec.ts b/packages/twenty-server/src/engine/metadata-modules/ai/ai-tools/services/__tests__/tool-adapter.service.spec.ts new file mode 100644 index 0000000000..30d2771608 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/ai/ai-tools/services/__tests__/tool-adapter.service.spec.ts @@ -0,0 +1,172 @@ +import { Test } from '@nestjs/testing'; + +import { jsonSchema } from 'ai'; +import { PermissionFlagType } from 'twenty-shared/constants'; + +import { ToolType } from 'src/engine/core-modules/tool/enums/tool-type.enum'; +import { ToolRegistryService } from 'src/engine/core-modules/tool/services/tool-registry.service'; +import { type ToolInput } from 'src/engine/core-modules/tool/types/tool-input.type'; +import { type Tool } from 'src/engine/core-modules/tool/types/tool.type'; +import { ToolAdapterService } from 'src/engine/metadata-modules/ai/ai-tools/services/tool-adapter.service'; +import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service'; +import { type RolePermissionConfig } from 'src/engine/twenty-orm/types/role-permission-config'; + +const createMockToolRegistry = () => ({ + getAllToolTypes: jest.fn(), + getTool: jest.fn(), +}); + +const createMockPermissions = () => ({ + hasToolPermission: jest.fn< + Promise, + [RolePermissionConfig, string, PermissionFlagType] + >(), +}); + +describe('ToolAdapterService', () => { + let mockRegistry: ReturnType; + let mockPermissions: ReturnType; + let service: ToolAdapterService; + + // Shared tools + const unflaggedToolExecute = jest.fn(async (input: ToolInput) => ({ + success: true, + message: 'Tool executed successfully', + result: { echoed: input }, + })); + const unflaggedTool: Tool = { + description: 'HTTP Request tool', + inputSchema: jsonSchema({ type: 'object', properties: {} }), + execute: unflaggedToolExecute, + }; + + const flaggedToolExecute = jest.fn(async (input: ToolInput) => ({ + success: true, + message: 'Tool executed successfully', + result: { sent: input }, + })); + const flaggedTool: Tool = { + description: 'Send Email tool', + inputSchema: jsonSchema({ type: 'object', properties: {} }), + execute: flaggedToolExecute, + flag: PermissionFlagType.SEND_EMAIL_TOOL, + }; + + beforeEach(async () => { + jest.clearAllMocks(); + mockRegistry = createMockToolRegistry(); + mockPermissions = createMockPermissions(); + + // Setup mock tool responses + mockRegistry.getAllToolTypes.mockReturnValue([ + ToolType.HTTP_REQUEST, + ToolType.SEND_EMAIL, + ]); + mockRegistry.getTool.mockImplementation((type: ToolType) => { + if (type === ToolType.HTTP_REQUEST) return unflaggedTool; + if (type === ToolType.SEND_EMAIL) return flaggedTool; + throw new Error('Tool not found in mock'); + }); + + const moduleRef = await Test.createTestingModule({ + providers: [ + ToolAdapterService, + { + provide: ToolRegistryService, + useValue: mockRegistry, + }, + { + provide: PermissionsService, + useValue: mockPermissions, + }, + ], + }).compile(); + + service = moduleRef.get(ToolAdapterService); + }); + + it('should include unflagged tools regardless of role/workspace', async () => { + const toolsNoContext = await service.getTools(); + + expect(Object.keys(toolsNoContext)).toContain('http_request'); + + const toolsWithPartialContext = await service.getTools({ + unionOf: ['role-1'], + }); + + expect(Object.keys(toolsWithPartialContext)).toContain('http_request'); + }); + + it('should not include flagged tools when role/workspace are missing', async () => { + const toolsNoContext = await service.getTools(); + + expect(Object.keys(toolsNoContext)).not.toContain('send_email'); + + const toolsRoleOnly = await service.getTools({ + unionOf: ['role-1'], + }); + + expect(Object.keys(toolsRoleOnly)).not.toContain('send_email'); + + const toolsWorkspaceOnly = await service.getTools(undefined, 'ws-1'); + + expect(Object.keys(toolsWorkspaceOnly)).not.toContain('send_email'); + }); + + it('should include flagged tools when permission is granted', async () => { + mockPermissions.hasToolPermission.mockResolvedValueOnce(true); + + const tools = await service.getTools({ unionOf: ['role-1'] }, 'ws-1'); + + expect(mockPermissions.hasToolPermission).toHaveBeenCalledWith( + { unionOf: ['role-1'] }, + 'ws-1', + PermissionFlagType.SEND_EMAIL_TOOL, + ); + + expect(Object.keys(tools)).toContain('send_email'); + }); + + it('should exclude flagged tools when permission is denied', async () => { + mockPermissions.hasToolPermission.mockResolvedValueOnce(false); + + const tools = await service.getTools({ unionOf: ['role-1'] }, 'ws-1'); + + expect(Object.keys(tools)).not.toContain('send_email'); + }); + + it('should lowercase tool type keys in the returned ToolSet', async () => { + const tools = await service.getTools(); + + const keys = Object.keys(tools); + + expect(keys).toContain('http_request'); + expect(keys).not.toContain(ToolType.HTTP_REQUEST); // ensure enum raw value not used as-is + }); + + it('should forward execute input correctly and return underlying result', async () => { + const tools = await service.getTools(); + + const input = { url: 'https://example.com', method: 'GET' } as ToolInput; + const result = await tools['http_request'].execute?.( + { input }, + { + toolCallId: 'test-tool-call-id', + messages: [ + { + role: 'user', + content: 'content', + }, + ], + }, + ); + + // Ensure wrapper forwards only parameters.input + expect(unflaggedToolExecute).toHaveBeenCalledWith(input); + expect(result).toEqual({ + success: true, + message: 'Tool executed successfully', + result: { echoed: input }, + }); + }); +}); diff --git a/packages/twenty-server/src/engine/metadata-modules/ai/ai-tools/services/tool-adapter.service.ts b/packages/twenty-server/src/engine/metadata-modules/ai/ai-tools/services/tool-adapter.service.ts new file mode 100644 index 0000000000..dd20f30ff2 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/ai/ai-tools/services/tool-adapter.service.ts @@ -0,0 +1,54 @@ +import { Injectable } from '@nestjs/common'; + +import { type ToolSet } from 'ai'; +import { type PermissionFlagType } from 'twenty-shared/constants'; + +import { ToolRegistryService } from 'src/engine/core-modules/tool/services/tool-registry.service'; +import { type ToolInput } from 'src/engine/core-modules/tool/types/tool-input.type'; +import { type Tool } from 'src/engine/core-modules/tool/types/tool.type'; +import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service'; +import { type RolePermissionConfig } from 'src/engine/twenty-orm/types/role-permission-config'; + +@Injectable() +export class ToolAdapterService { + constructor( + private readonly toolRegistry: ToolRegistryService, + private readonly permissionsService: PermissionsService, + ) {} + + async getTools( + rolePermissionConfig?: RolePermissionConfig, + workspaceId?: string, + ): Promise { + const tools: ToolSet = {}; + + for (const toolType of this.toolRegistry.getAllToolTypes()) { + const tool = this.toolRegistry.getTool(toolType); + + if (!tool.flag) { + tools[toolType.toLowerCase()] = this.createToolSet(tool); + } else if (rolePermissionConfig && workspaceId) { + const hasPermission = await this.permissionsService.hasToolPermission( + rolePermissionConfig, + workspaceId, + tool.flag as PermissionFlagType, + ); + + if (hasPermission) { + tools[toolType.toLowerCase()] = this.createToolSet(tool); + } + } + } + + return tools; + } + + private createToolSet(tool: Tool) { + return { + description: tool.description, + inputSchema: tool.inputSchema, + execute: async (parameters: { input: ToolInput }) => + tool.execute(parameters.input), + }; + } +} diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/resolvers/cron-trigger.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/resolvers/cron-trigger.resolver.ts index ea33b5e724..93b47b62c6 100644 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/resolvers/cron-trigger.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/resolvers/cron-trigger.resolver.ts @@ -3,6 +3,7 @@ import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; @@ -17,7 +18,6 @@ import { UpdateCronTriggerInput } from 'src/engine/metadata-modules/cron-trigger import { CronTriggerEntity } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; import { CronTriggerV2Service } from 'src/engine/metadata-modules/cron-trigger/services/cron-trigger-v2.service'; import { cronTriggerGraphQLApiExceptionHandler } from 'src/engine/metadata-modules/cron-trigger/utils/cron-trigger-graphql-api-exception-handler.util'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @UseGuards( WorkspaceAuthGuard, diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/resolvers/database-event-trigger.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/resolvers/database-event-trigger.resolver.ts index 45dc0c9b2e..5e0f77096f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/resolvers/database-event-trigger.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/resolvers/database-event-trigger.resolver.ts @@ -3,6 +3,7 @@ import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; @@ -17,7 +18,6 @@ import { UpdateDatabaseEventTriggerInput } from 'src/engine/metadata-modules/dat import { DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; import { DatabaseEventTriggerV2Service } from 'src/engine/metadata-modules/database-event-trigger/services/database-event-trigger-v2.service'; import { databaseEventTriggerGraphQLApiExceptionHandler } from 'src/engine/metadata-modules/database-event-trigger/utils/database-event-trigger-graphql-api-exception-handler.utils'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @UseGuards( WorkspaceAuthGuard, diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.resolver.ts index d227477ea4..2a94e09515 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.resolver.ts @@ -9,6 +9,7 @@ import { } from '@nestjs/graphql'; import { isDefined } from 'twenty-shared/utils'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; @@ -28,7 +29,6 @@ import { UpdateOneFieldMetadataInput } from 'src/engine/metadata-modules/field-m import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/services/field-metadata.service'; import { fieldMetadataGraphqlApiExceptionHandler } from 'src/engine/metadata-modules/field-metadata/utils/field-metadata-graphql-api-exception-handler.util'; import { fromFlatFieldMetadataToFieldMetadataDto } from 'src/engine/metadata-modules/flat-field-metadata/utils/from-flat-field-metadata-to-field-metadata-dto.util'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; @UseGuards(WorkspaceAuthGuard) diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-flat-entities-by-universal-identifier.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-flat-entities-by-universal-identifier.util.ts new file mode 100644 index 0000000000..20c009bff8 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/get-flat-entities-by-universal-identifier.util.ts @@ -0,0 +1,17 @@ +import { isDefined } from 'twenty-shared/utils'; + +import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; +import { type FlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type'; + +export const getFlatEntityByUniversalIdentifier = ( + maps: FlatEntityMaps, + universalIdentifier: string, +): T | undefined => { + const flatEntityId = maps.idByUniversalIdentifier[universalIdentifier]; + + if (!isDefined(flatEntityId)) { + return; + } + + return maps.byId[flatEntityId]; +}; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-role-target/constants/role-target-foreign-key-properties.constant.ts b/packages/twenty-server/src/engine/metadata-modules/flat-role-target/constants/role-target-foreign-key-properties.constant.ts index 744a18d890..3477fa4865 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-role-target/constants/role-target-foreign-key-properties.constant.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-role-target/constants/role-target-foreign-key-properties.constant.ts @@ -4,4 +4,5 @@ export const ROLE_TARGET_FOREIGN_KEY_PROPERTIES = [ 'userWorkspaceId', 'apiKeyId', 'agentId', + 'targetApplicationId', ] as const satisfies (keyof FlatRoleTarget)[]; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-role-target/utils/from-role-target-entity-to-flat-role-target.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-role-target/utils/from-role-target-entity-to-flat-role-target.util.ts index 92e2dc5b2f..6c45e87e05 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-role-target/utils/from-role-target-entity-to-flat-role-target.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-role-target/utils/from-role-target-entity-to-flat-role-target.util.ts @@ -11,6 +11,7 @@ export const fromRoleTargetsEntityToFlatRoleTarget = ( userWorkspaceId: roleTarget.userWorkspaceId, agentId: roleTarget.agentId, apiKeyId: roleTarget.apiKeyId, + targetApplicationId: roleTarget.targetApplicationId, applicationId: roleTarget.applicationId, universalIdentifier: roleTarget.universalIdentifier ?? roleTarget.id, createdAt: roleTarget.createdAt, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-role/utils/from-create-role-input-to-flat-role-to-create.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-role/utils/from-create-role-input-to-flat-role-to-create.util.ts index 33415bee33..40a83f9c90 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-role/utils/from-create-role-input-to-flat-role-to-create.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-role/utils/from-create-role-input-to-flat-role-to-create.util.ts @@ -44,6 +44,8 @@ export const fromCreateRoleInputToFlatRoleToCreate = ({ canBeAssignedToUsers: createRoleInput.canBeAssignedToUsers ?? true, canBeAssignedToAgents: createRoleInput.canBeAssignedToAgents ?? true, canBeAssignedToApiKeys: createRoleInput.canBeAssignedToApiKeys ?? true, + canBeAssignedToApplications: + createRoleInput.canBeAssignedToApplications ?? true, isEditable: true, workspaceId, createdAt: now, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-role/utils/from-role-entity-to-flat-role.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-role/utils/from-role-entity-to-flat-role.util.ts index edb516075d..a50397926f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-role/utils/from-role-entity-to-flat-role.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-role/utils/from-role-entity-to-flat-role.util.ts @@ -18,6 +18,7 @@ export const fromRoleEntityToFlatRole = (role: RoleEntity): FlatRole => { canBeAssignedToUsers: role.canBeAssignedToUsers, canBeAssignedToAgents: role.canBeAssignedToAgents, canBeAssignedToApiKeys: role.canBeAssignedToApiKeys, + canBeAssignedToApplications: role.canBeAssignedToApplications, workspaceId: role.workspaceId, createdAt: role.createdAt, updatedAt: role.updatedAt, diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.resolver.ts index 10fb1ee149..89d1760623 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.resolver.ts @@ -8,6 +8,8 @@ import { Resolver, } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; import { I18nService } from 'src/engine/core-modules/i18n/i18n.service'; @@ -27,7 +29,6 @@ import { UpdateOneObjectInput } from 'src/engine/metadata-modules/object-metadat import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; import { objectMetadataGraphqlApiExceptionHandler } from 'src/engine/metadata-modules/object-metadata/utils/object-metadata-graphql-api-exception-handler.util'; import { resolveObjectMetadataStandardOverride } from 'src/engine/metadata-modules/object-metadata/utils/resolve-object-metadata-standard-override.util'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; @UseGuards(WorkspaceAuthGuard) diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout/controllers/page-layout-tab.controller.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout/controllers/page-layout-tab.controller.ts index 580607c910..f9b16cb877 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout/controllers/page-layout-tab.controller.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout/controllers/page-layout-tab.controller.ts @@ -12,6 +12,7 @@ import { } from '@nestjs/common'; import { isDefined } from 'twenty-shared/utils'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { CreatePageLayoutTabInput } from 'src/engine/metadata-modules/page-layout/dtos/inputs/create-page-layout-tab.input'; import { UpdatePageLayoutTabInput } from 'src/engine/metadata-modules/page-layout/dtos/inputs/update-page-layout-tab.input'; @@ -29,7 +30,6 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @Controller('rest/metadata/pageLayoutTabs') @UseGuards(WorkspaceAuthGuard) diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout/controllers/page-layout-widget.controller.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout/controllers/page-layout-widget.controller.ts index 498c545eea..489f026980 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout/controllers/page-layout-widget.controller.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout/controllers/page-layout-widget.controller.ts @@ -12,6 +12,7 @@ import { } from '@nestjs/common'; import { isDefined } from 'class-validator'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; @@ -29,7 +30,6 @@ import { } from 'src/engine/metadata-modules/page-layout/exceptions/page-layout-widget.exception'; import { PageLayoutWidgetRestApiExceptionFilter } from 'src/engine/metadata-modules/page-layout/filters/page-layout-widget-rest-api-exception.filter'; import { PageLayoutWidgetService } from 'src/engine/metadata-modules/page-layout/services/page-layout-widget.service'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @Controller('rest/metadata/pageLayoutWidgets') @UseGuards(WorkspaceAuthGuard) diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout/controllers/page-layout.controller.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout/controllers/page-layout.controller.ts index 4f87000588..20dca13f91 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout/controllers/page-layout.controller.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout/controllers/page-layout.controller.ts @@ -12,6 +12,7 @@ import { } from '@nestjs/common'; import { isDefined } from 'twenty-shared/utils'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { CreatePageLayoutInput } from 'src/engine/metadata-modules/page-layout/dtos/inputs/create-page-layout.input'; import { UpdatePageLayoutInput } from 'src/engine/metadata-modules/page-layout/dtos/inputs/update-page-layout.input'; @@ -24,7 +25,6 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @Controller('rest/metadata/pageLayouts') @UseGuards(WorkspaceAuthGuard) diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout/resolvers/page-layout-tab.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout/resolvers/page-layout-tab.resolver.ts index ab5261c179..eeebb15025 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout/resolvers/page-layout-tab.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout/resolvers/page-layout-tab.resolver.ts @@ -2,6 +2,7 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; import { isDefined } from 'twenty-shared/utils'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; import { CreatePageLayoutTabInput } from 'src/engine/metadata-modules/page-layout/dtos/inputs/create-page-layout-tab.input'; @@ -14,7 +15,6 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @Resolver(() => PageLayoutTabDTO) @UseFilters(PageLayoutGraphqlApiExceptionFilter) diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout/resolvers/page-layout-widget.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout/resolvers/page-layout-widget.resolver.ts index 229a9cf652..fda6826e02 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout/resolvers/page-layout-widget.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout/resolvers/page-layout-widget.resolver.ts @@ -8,6 +8,8 @@ import { Resolver, } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; import { type WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; @@ -21,7 +23,6 @@ import { WidgetConfiguration } from 'src/engine/metadata-modules/page-layout/dto import { PageLayoutWidgetService } from 'src/engine/metadata-modules/page-layout/services/page-layout-widget.service'; import { injectWidgetConfigurationDiscriminator } from 'src/engine/metadata-modules/page-layout/utils/inject-widget-configuration-discriminator.util'; import { PageLayoutGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/page-layout/utils/page-layout-graphql-api-exception.filter'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @Resolver(() => PageLayoutWidgetDTO) @UseFilters(PageLayoutGraphqlApiExceptionFilter) diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout/resolvers/page-layout.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout/resolvers/page-layout.resolver.ts index 7e46df6847..cc7f659ec6 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout/resolvers/page-layout.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout/resolvers/page-layout.resolver.ts @@ -2,6 +2,7 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; import { isDefined } from 'twenty-shared/utils'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; import { CreatePageLayoutInput } from 'src/engine/metadata-modules/page-layout/dtos/inputs/create-page-layout.input'; @@ -16,7 +17,6 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @Resolver(() => PageLayoutDTO) @UseFilters(PageLayoutGraphqlApiExceptionFilter) diff --git a/packages/twenty-server/src/engine/metadata-modules/permission-flag/dtos/permission-flag.dto.ts b/packages/twenty-server/src/engine/metadata-modules/permission-flag/dtos/permission-flag.dto.ts index 19f9dc95a9..2e5c16d5a2 100644 --- a/packages/twenty-server/src/engine/metadata-modules/permission-flag/dtos/permission-flag.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/permission-flag/dtos/permission-flag.dto.ts @@ -1,7 +1,8 @@ import { Field, ObjectType } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @ObjectType('PermissionFlag') export class PermissionFlagDTO { diff --git a/packages/twenty-server/src/engine/metadata-modules/permission-flag/dtos/upsert-permission-flag-input.ts b/packages/twenty-server/src/engine/metadata-modules/permission-flag/dtos/upsert-permission-flag-input.ts index 27eb584645..063944d3e2 100644 --- a/packages/twenty-server/src/engine/metadata-modules/permission-flag/dtos/upsert-permission-flag-input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/permission-flag/dtos/upsert-permission-flag-input.ts @@ -1,9 +1,9 @@ import { Field, InputType } from '@nestjs/graphql'; import { IsArray, IsEnum, IsNotEmpty, IsUUID } from 'class-validator'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; @InputType() export class UpsertPermissionFlagsInput { diff --git a/packages/twenty-server/src/engine/metadata-modules/permission-flag/permission-flag.entity.ts b/packages/twenty-server/src/engine/metadata-modules/permission-flag/permission-flag.entity.ts index 8619798b7a..3f736af788 100644 --- a/packages/twenty-server/src/engine/metadata-modules/permission-flag/permission-flag.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/permission-flag/permission-flag.entity.ts @@ -9,8 +9,8 @@ import { Unique, UpdateDateColumn, } from 'typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity'; @Entity('permissionFlag') diff --git a/packages/twenty-server/src/engine/metadata-modules/permission-flag/permission-flag.service.ts b/packages/twenty-server/src/engine/metadata-modules/permission-flag/permission-flag.service.ts index a01e433a1f..c346daadca 100644 --- a/packages/twenty-server/src/engine/metadata-modules/permission-flag/permission-flag.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/permission-flag/permission-flag.service.ts @@ -3,10 +3,10 @@ import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; import { msg } from '@lingui/core/macro'; import { isDefined } from 'twenty-shared/utils'; import { DataSource, In, Repository } from 'typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { type UpsertPermissionFlagsInput } from 'src/engine/metadata-modules/permission-flag/dtos/upsert-permission-flag-input'; import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsException, PermissionsExceptionCode, diff --git a/packages/twenty-server/src/engine/metadata-modules/permissions/__tests__/permissions.service.spec.ts b/packages/twenty-server/src/engine/metadata-modules/permissions/__tests__/permissions.service.spec.ts index d154304db3..ff5d547776 100644 --- a/packages/twenty-server/src/engine/metadata-modules/permissions/__tests__/permissions.service.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/permissions/__tests__/permissions.service.spec.ts @@ -1,8 +1,9 @@ import { Test, type TestingModule } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/services/api-key-role.service'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service'; import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity'; import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service'; diff --git a/packages/twenty-server/src/engine/metadata-modules/permissions/permissions.service.ts b/packages/twenty-server/src/engine/metadata-modules/permissions/permissions.service.ts index d235bd2e1a..b49147e9a5 100644 --- a/packages/twenty-server/src/engine/metadata-modules/permissions/permissions.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/permissions/permissions.service.ts @@ -4,9 +4,9 @@ import { InjectRepository } from '@nestjs/typeorm'; import { msg } from '@lingui/core/macro'; import { isDefined } from 'twenty-shared/utils'; import { In, Repository } from 'typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/services/api-key-role.service'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { TOOL_PERMISSION_FLAGS } from 'src/engine/metadata-modules/permissions/constants/tool-permission-flags'; import { PermissionsException, diff --git a/packages/twenty-server/src/engine/metadata-modules/permissions/types/user-workspace-permissions.ts b/packages/twenty-server/src/engine/metadata-modules/permissions/types/user-workspace-permissions.ts index afc6189041..f36fd716d7 100644 --- a/packages/twenty-server/src/engine/metadata-modules/permissions/types/user-workspace-permissions.ts +++ b/packages/twenty-server/src/engine/metadata-modules/permissions/types/user-workspace-permissions.ts @@ -1,6 +1,5 @@ import { type ObjectsPermissions } from 'twenty-shared/types'; - -import { type PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; +import { type PermissionFlagType } from 'twenty-shared/constants'; export type UserWorkspacePermissions = { permissionFlags: Record; diff --git a/packages/twenty-server/src/engine/metadata-modules/remote-server/remote-server.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/remote-server/remote-server.resolver.ts index 8fc84a2bc1..d5592405b8 100644 --- a/packages/twenty-server/src/engine/metadata-modules/remote-server/remote-server.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/remote-server/remote-server.resolver.ts @@ -1,13 +1,14 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { CreateRemoteServerInput } from 'src/engine/metadata-modules/remote-server/dtos/create-remote-server.input'; import { RemoteServerIdInput } from 'src/engine/metadata-modules/remote-server/dtos/remote-server-id.input'; import { RemoteServerTypeInput } from 'src/engine/metadata-modules/remote-server/dtos/remote-server-type.input'; diff --git a/packages/twenty-server/src/engine/metadata-modules/remote-server/remote-table/remote-table.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/remote-server/remote-table/remote-table.resolver.ts index 1c468c1e06..1b228085d4 100644 --- a/packages/twenty-server/src/engine/metadata-modules/remote-server/remote-table/remote-table.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/remote-server/remote-table/remote-table.resolver.ts @@ -1,13 +1,14 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { FindManyRemoteTablesInput } from 'src/engine/metadata-modules/remote-server/remote-table/dtos/find-many-remote-tables-input'; import { RemoteTableInput } from 'src/engine/metadata-modules/remote-server/remote-table/dtos/remote-table-input'; import { RemoteTableDTO } from 'src/engine/metadata-modules/remote-server/remote-table/dtos/remote-table.dto'; diff --git a/packages/twenty-server/src/engine/metadata-modules/role-target/role-target.entity.ts b/packages/twenty-server/src/engine/metadata-modules/role-target/role-target.entity.ts index abd2978399..a2b23995bb 100644 --- a/packages/twenty-server/src/engine/metadata-modules/role-target/role-target.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/role-target/role-target.entity.ts @@ -56,6 +56,9 @@ export class RoleTargetEntity extends SyncableEntity { @Column({ nullable: true, type: 'uuid' }) apiKeyId: string | null; + @Column({ nullable: true, type: 'uuid' }) + targetApplicationId: string | null; + @ManyToOne(() => ApiKeyEntity, { onDelete: 'CASCADE' }) @JoinColumn({ name: 'apiKeyId' }) apiKey: Relation; diff --git a/packages/twenty-server/src/engine/metadata-modules/role-target/utils/from-create-role-target-input-to-flat-role-target-to-create.util.ts b/packages/twenty-server/src/engine/metadata-modules/role-target/utils/from-create-role-target-input-to-flat-role-target-to-create.util.ts index 41cf386404..1254e0890e 100644 --- a/packages/twenty-server/src/engine/metadata-modules/role-target/utils/from-create-role-target-input-to-flat-role-target-to-create.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/role-target/utils/from-create-role-target-input-to-flat-role-target-to-create.util.ts @@ -27,6 +27,7 @@ export const fromCreateRoleTargetInputToFlatRoleTargetToCreate = ({ userWorkspaceId: null, agentId: null, apiKeyId: null, + targetApplicationId: null, createdAt: now, updatedAt: now, universalIdentifier: universalIdentifier ?? v4(), diff --git a/packages/twenty-server/src/engine/metadata-modules/role/dtos/create-role-input.dto.ts b/packages/twenty-server/src/engine/metadata-modules/role/dtos/create-role-input.dto.ts index 7d268dc4e7..5b2621e3fa 100644 --- a/packages/twenty-server/src/engine/metadata-modules/role/dtos/create-role-input.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/role/dtos/create-role-input.dto.ts @@ -67,4 +67,9 @@ export class CreateRoleInput { @IsOptional() @Field({ nullable: true }) canBeAssignedToApiKeys?: boolean; + + @IsBoolean() + @IsOptional() + @Field({ nullable: true }) + canBeAssignedToApplications?: boolean; } diff --git a/packages/twenty-server/src/engine/metadata-modules/role/dtos/role.dto.ts b/packages/twenty-server/src/engine/metadata-modules/role/dtos/role.dto.ts index d78eea21b8..6fb586687f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/role/dtos/role.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/role/dtos/role.dto.ts @@ -33,6 +33,9 @@ export class RoleDTO { @Field(() => UUIDScalarType, { nullable: true }) standardId?: string; + @Field(() => UUIDScalarType, { nullable: true }) + universalIdentifier?: string; + @Field({ nullable: false }) label: string; diff --git a/packages/twenty-server/src/engine/metadata-modules/role/dtos/update-role-input.dto.ts b/packages/twenty-server/src/engine/metadata-modules/role/dtos/update-role-input.dto.ts index fec0d2a35d..9774cd0977 100644 --- a/packages/twenty-server/src/engine/metadata-modules/role/dtos/update-role-input.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/role/dtos/update-role-input.dto.ts @@ -71,6 +71,11 @@ export class UpdateRolePayload { @IsOptional() @Field({ nullable: true }) canBeAssignedToApiKeys?: boolean; + + @IsBoolean() + @IsOptional() + @Field({ nullable: true }) + canBeAssignedToApplications?: boolean; } @InputType() diff --git a/packages/twenty-server/src/engine/metadata-modules/role/role.entity.ts b/packages/twenty-server/src/engine/metadata-modules/role/role.entity.ts index 6d7302d158..a2dc1f4cb8 100644 --- a/packages/twenty-server/src/engine/metadata-modules/role/role.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/role/role.entity.ts @@ -73,6 +73,9 @@ export class RoleEntity extends SyncableEntity implements Required { @Column({ nullable: false, default: true }) canBeAssignedToApiKeys: boolean; + @Column({ nullable: false, default: true }) + canBeAssignedToApplications: boolean; + @OneToMany( () => RoleTargetEntity, (roleTargets: RoleTargetEntity) => roleTargets.role, diff --git a/packages/twenty-server/src/engine/metadata-modules/role/role.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/role/role.resolver.ts index c58aea184b..4ce15c46ed 100644 --- a/packages/twenty-server/src/engine/metadata-modules/role/role.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/role/role.resolver.ts @@ -14,6 +14,7 @@ import { } from '@nestjs/graphql'; import { msg } from '@lingui/core/macro'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { ApiKeyRoleService } from 'src/engine/core-modules/api-key/services/api-key-role.service'; @@ -42,7 +43,6 @@ import { ObjectPermissionService } from 'src/engine/metadata-modules/object-perm import { PermissionFlagDTO } from 'src/engine/metadata-modules/permission-flag/dtos/permission-flag.dto'; import { UpsertPermissionFlagsInput } from 'src/engine/metadata-modules/permission-flag/dtos/upsert-permission-flag-input'; import { PermissionFlagService } from 'src/engine/metadata-modules/permission-flag/permission-flag.service'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsException, PermissionsExceptionCode, diff --git a/packages/twenty-server/src/engine/metadata-modules/role/role.service.ts b/packages/twenty-server/src/engine/metadata-modules/role/role.service.ts index 424d6a3a5d..46ca384129 100644 --- a/packages/twenty-server/src/engine/metadata-modules/role/role.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/role/role.service.ts @@ -25,6 +25,7 @@ import { fromFlatRoleToRoleDto } from 'src/engine/metadata-modules/role/utils/fr import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service'; import { WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2'; import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service'; +import { getFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/get-flat-entities-by-universal-identifier.util'; @Injectable() export class RoleService { @@ -70,6 +71,31 @@ export class RoleService { }); } + public async getRoleByUniversalIdentifier({ + universalIdentifier, + workspaceId, + }: { + universalIdentifier: string; + workspaceId: string; + }): Promise { + const { flatRoleMaps } = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatMapsKeys: ['flatRoleMaps'], + }, + ); + + const flatRoleEntity = getFlatEntityByUniversalIdentifier( + flatRoleMaps, + universalIdentifier, + ); + + return isDefined(flatRoleEntity) + ? fromFlatRoleToRoleDto(flatRoleEntity) + : null; + } + public async createRole({ input, workspaceId, diff --git a/packages/twenty-server/src/engine/metadata-modules/role/services/workspace-roles-permissions-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/role/services/workspace-roles-permissions-cache.service.ts index f12f49aace..bd8f3b624f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/role/services/workspace-roles-permissions-cache.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/role/services/workspace-roles-permissions-cache.service.ts @@ -9,11 +9,11 @@ import { } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { Repository } from 'typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity'; import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator'; diff --git a/packages/twenty-server/src/engine/metadata-modules/role/utils/fromFlatRoleToRoleDto.util.ts b/packages/twenty-server/src/engine/metadata-modules/role/utils/fromFlatRoleToRoleDto.util.ts index 48cc6aa653..a706f83126 100644 --- a/packages/twenty-server/src/engine/metadata-modules/role/utils/fromFlatRoleToRoleDto.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/role/utils/fromFlatRoleToRoleDto.util.ts @@ -17,6 +17,7 @@ export const fromFlatRoleToRoleDto = ({ description, icon, standardId, + universalIdentifier, }: FlatRole): RoleDTO => { return { canAccessAllTools, @@ -34,5 +35,6 @@ export const fromFlatRoleToRoleDto = ({ description: description ?? undefined, icon: icon ?? undefined, standardId: standardId ?? undefined, + universalIdentifier: universalIdentifier ?? undefined, }; }; diff --git a/packages/twenty-server/src/engine/metadata-modules/role/utils/fromUserWorkspacePermissionsToUserWorkspacePermissionsDto.ts b/packages/twenty-server/src/engine/metadata-modules/role/utils/fromUserWorkspacePermissionsToUserWorkspacePermissionsDto.ts index e0b477367b..44b8772a87 100644 --- a/packages/twenty-server/src/engine/metadata-modules/role/utils/fromUserWorkspacePermissionsToUserWorkspacePermissionsDto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/role/utils/fromUserWorkspacePermissionsToUserWorkspacePermissionsDto.ts @@ -1,4 +1,5 @@ -import { type PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; +import { type PermissionFlagType } from 'twenty-shared/constants'; + import { type UserWorkspacePermissions } from 'src/engine/metadata-modules/permissions/types/user-workspace-permissions'; import { type UserWorkspacePermissionsDto } from 'src/engine/metadata-modules/role/dtos/user-workspace-permissions.dto'; diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input.ts index 81b2351fe4..a2eeff570d 100644 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input.ts @@ -7,8 +7,7 @@ import { IsString, IsUUID, } from 'class-validator'; - -import { HTTPMethod } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; +import { HTTPMethod } from 'twenty-shared/types'; @InputType() export class CreateRouteTriggerInput { diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/route-trigger.dto.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/route-trigger.dto.ts index e902c5c3e8..dff886ba6b 100644 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/route-trigger.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/route-trigger.dto.ts @@ -1,6 +1,6 @@ import { Field, ID, ObjectType, registerEnumType } from '@nestjs/graphql'; -import { HTTPMethod } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; +import { HTTPMethod } from 'twenty-shared/types'; registerEnumType(HTTPMethod, { name: 'HTTPMethod' }); diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/update-route-trigger.input.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/update-route-trigger.input.ts index 89f846d66c..9a746ca97a 100644 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/update-route-trigger.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/update-route-trigger.input.ts @@ -9,8 +9,7 @@ import { IsUUID, ValidateNested, } from 'class-validator'; - -import { HTTPMethod } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; +import { HTTPMethod } from 'twenty-shared/types'; @InputType() class UpdateRouteTriggerInputUpdates { diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/resolvers/route-trigger.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/resolvers/route-trigger.resolver.ts index 69dcfafee3..2ea1cf41c6 100644 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/resolvers/route-trigger.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/resolvers/route-trigger.resolver.ts @@ -3,6 +3,7 @@ import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; @@ -10,7 +11,6 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; import { CreateRouteTriggerInput } from 'src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input'; import { RouteTriggerIdInput } from 'src/engine/metadata-modules/route-trigger/dtos/route-trigger-id.input'; diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.controller.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.controller.ts index 54de9a41aa..4d9de29219 100644 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.controller.ts +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.controller.ts @@ -11,11 +11,11 @@ import { } from '@nestjs/common'; import { Request } from 'express'; +import { HTTPMethod } from 'twenty-shared/types'; import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard'; import { PublicEndpointGuard } from 'src/engine/guards/public-endpoint.guard'; import { RouteTriggerRestApiExceptionFilter } from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger-rest-api-exception-filter'; -import { HTTPMethod } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; import { RouteTriggerService } from 'src/engine/metadata-modules/route-trigger/route-trigger.service'; @Controller('s') diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.entity.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.entity.ts index df0b7fc273..6e83207c66 100644 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.entity.ts @@ -9,20 +9,13 @@ import { Unique, UpdateDateColumn, } from 'typeorm'; +import { HTTPMethod } from 'twenty-shared/types'; import { SyncableEntity } from 'src/engine/workspace-manager/workspace-sync/interfaces/syncable-entity.interface'; import { RouteTriggerEntityRelationProperties } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; -export enum HTTPMethod { - GET = 'GET', - POST = 'POST', - PUT = 'PUT', - PATCH = 'PATCH', - DELETE = 'DELETE', -} - export const ROUTE_TRIGGER_ENTITY_RELATION_PROPERTIES = [ 'serverlessFunction', ] as const satisfies readonly RouteTriggerEntityRelationProperties[]; diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.service.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.service.ts index ffc8674460..de434841c3 100644 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.service.ts @@ -5,6 +5,7 @@ import { Request } from 'express'; import { match } from 'path-to-regexp'; import { assertIsDefinedOrThrow, isDefined } from 'twenty-shared/utils'; import { Repository } from 'typeorm'; +import { HTTPMethod } from 'twenty-shared/types'; import { AccessTokenService } from 'src/engine/core-modules/auth/token/services/access-token.service'; import { WorkspaceDomainsService } from 'src/engine/core-modules/domain/workspace-domains/services/workspace-domains.service'; @@ -12,10 +13,7 @@ import { RouteTriggerException, RouteTriggerExceptionCode, } from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception'; -import { - HTTPMethod, - RouteTriggerEntity, -} from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; +import { RouteTriggerEntity } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service'; @Injectable() diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function-layer/dtos/create-serverless-function-layer.input.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function-layer/dtos/create-serverless-function-layer.input.ts index 690b6aac7c..86799f14ca 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function-layer/dtos/create-serverless-function-layer.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function-layer/dtos/create-serverless-function-layer.input.ts @@ -2,8 +2,7 @@ import { ArgsType, Field } from '@nestjs/graphql'; import { IsString } from 'class-validator'; import GraphQLJSON from 'graphql-type-json'; - -import { PackageJson } from 'src/engine/core-modules/application/types/application.types'; +import { PackageJson } from 'twenty-shared/application'; @ArgsType() export class CreateServerlessFunctionLayerInput { diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function-layer/serverless-function-layer.entity.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function-layer/serverless-function-layer.entity.ts index 9ffa591de1..d4f0418d2f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function-layer/serverless-function-layer.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function-layer/serverless-function-layer.entity.ts @@ -7,8 +7,8 @@ import { Relation, UpdateDateColumn, } from 'typeorm'; +import { PackageJson } from 'twenty-shared/application'; -import { PackageJson } from 'src/engine/core-modules/application/types/application.types'; import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; @Entity('serverlessFunctionLayer') diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function-layer/serverless-function-layer.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function-layer/serverless-function-layer.resolver.ts index d2fa26629e..29535551ee 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function-layer/serverless-function-layer.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function-layer/serverless-function-layer.resolver.ts @@ -1,11 +1,12 @@ import { UseGuards } from '@nestjs/common'; import { Args, Mutation, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { CreateServerlessFunctionLayerInput } from 'src/engine/metadata-modules/serverless-function-layer/dtos/create-serverless-function-layer.input'; import { ServerlessFunctionLayerDTO } from 'src/engine/metadata-modules/serverless-function-layer/dtos/serverless-function-layer.dto'; import { ServerlessFunctionLayerService } from 'src/engine/metadata-modules/serverless-function-layer/serverless-function-layer.service'; diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/create-serverless-function.input.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/create-serverless-function.input.ts index b02266c714..f6b4795e96 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/create-serverless-function.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/create-serverless-function.input.ts @@ -10,8 +10,7 @@ import { Min, } from 'class-validator'; import graphqlTypeJson from 'graphql-type-json'; - -import { Sources } from 'src/engine/core-modules/file-storage/types/source.type'; +import { Sources } from 'twenty-shared/types'; @InputType() export class CreateServerlessFunctionInput { diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/update-serverless-function.input.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/update-serverless-function.input.ts index a1fae851d7..70ff36a284 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/update-serverless-function.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/update-serverless-function.input.ts @@ -14,8 +14,9 @@ import { } from 'class-validator'; import graphqlTypeJson from 'graphql-type-json'; +import type { Sources } from 'twenty-shared/types'; + import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; -import type { Sources } from 'src/engine/core-modules/file-storage/types/source.type'; @InputType() class UpdateServerlessFunctionInputUpdates { diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.resolver.ts index c6b89f719a..96b3897432 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.resolver.ts @@ -6,6 +6,7 @@ import graphqlTypeJson from 'graphql-type-json'; import { Repository } from 'typeorm'; import { RedisPubSub } from 'graphql-redis-subscriptions'; import { isDefined } from 'twenty-shared/utils'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; @@ -14,7 +15,6 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat import { FeatureFlagGuard } from 'src/engine/guards/feature-flag.guard'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { CreateServerlessFunctionInput } from 'src/engine/metadata-modules/serverless-function/dtos/create-serverless-function.input'; import { ExecuteServerlessFunctionInput } from 'src/engine/metadata-modules/serverless-function/dtos/execute-serverless-function.input'; import { GetServerlessFunctionSourceCodeInput } from 'src/engine/metadata-modules/serverless-function/dtos/get-serverless-function-source-code.input'; diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.service.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.service.ts index 59796474a7..ea942a8d3b 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.service.ts @@ -7,6 +7,7 @@ import deepEqual from 'deep-equal'; import { isDefined } from 'twenty-shared/utils'; import { IsNull, Not, Repository } from 'typeorm'; import { RedisPubSub } from 'graphql-redis-subscriptions'; +import { Sources } from 'twenty-shared/types'; import { FileStorageExceptionCode } from 'src/engine/core-modules/file-storage/interfaces/file-storage-exception'; import { type ServerlessExecuteResult } from 'src/engine/core-modules/serverless/drivers/interfaces/serverless-driver.interface'; @@ -14,7 +15,6 @@ import { type ServerlessExecuteResult } from 'src/engine/core-modules/serverless import { AuditService } from 'src/engine/core-modules/audit/services/audit.service'; import { SERVERLESS_FUNCTION_EXECUTED_EVENT } from 'src/engine/core-modules/audit/utils/events/workspace-event/serverless-function/serverless-function-executed'; import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service'; -import { Sources } from 'src/engine/core-modules/file-storage/types/source.type'; import { getBaseTypescriptProjectFiles } from 'src/engine/core-modules/serverless/drivers/utils/get-base-typescript-project-files'; import { ServerlessService } from 'src/engine/core-modules/serverless/serverless.service'; import { getServerlessFolder } from 'src/engine/core-modules/serverless/utils/serverless-get-folder.utils'; diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type.ts index 9ff36d4d4c..2b49aa83c2 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type.ts @@ -1,4 +1,5 @@ -import { type Sources } from 'src/engine/core-modules/file-storage/types/source.type'; +import { type Sources } from 'twenty-shared/types'; + import { type WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { type CronTriggerEntity } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; import { type DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; diff --git a/packages/twenty-server/src/engine/metadata-modules/view-permissions/services/view-access.service.ts b/packages/twenty-server/src/engine/metadata-modules/view-permissions/services/view-access.service.ts index 2a6b35fb57..16a98b721c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/view-permissions/services/view-access.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/view-permissions/services/view-access.service.ts @@ -1,8 +1,8 @@ import { Injectable } from '@nestjs/common'; import { isDefined } from 'twenty-shared/utils'; +import { PermissionFlagType } from 'twenty-shared/constants'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service'; import { type ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity'; import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/serverless-function/types/workspace-migration-serverless-function-action-v2.type.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/serverless-function/types/workspace-migration-serverless-function-action-v2.type.ts index fa96480321..c8b3e63b43 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/serverless-function/types/workspace-migration-serverless-function-action-v2.type.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/serverless-function/types/workspace-migration-serverless-function-action-v2.type.ts @@ -1,6 +1,7 @@ +import { type Sources } from 'twenty-shared/types'; + import { type FlatEntityPropertiesUpdates } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type'; import { type FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type'; -import { type Sources } from 'src/engine/core-modules/file-storage/types/source.type'; export type CreateServerlessFunctionAction = { type: 'create_serverless_function'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/serverless-function/services/update-serverless-function-action-handler.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/serverless-function/services/update-serverless-function-action-handler.service.ts index a1125b2a63..378b7b46bc 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/serverless-function/services/update-serverless-function-action-handler.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/serverless-function/services/update-serverless-function-action-handler.service.ts @@ -1,11 +1,11 @@ import { Injectable } from '@nestjs/common'; import { isDefined } from 'twenty-shared/utils'; +import { type Sources } from 'twenty-shared/types'; import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/interfaces/workspace-migration-runner-action-handler-service.interface'; import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service'; -import { type Sources } from 'src/engine/core-modules/file-storage/types/source.type'; import { ServerlessService } from 'src/engine/core-modules/serverless/serverless.service'; import { getServerlessFolder } from 'src/engine/core-modules/serverless/utils/serverless-get-folder.utils'; import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-role.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-role.service.ts index 93233526bf..7563761ce2 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-role.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-role.service.ts @@ -2,13 +2,13 @@ import { Injectable, Logger } from '@nestjs/common'; import { removePropertiesFromRecord } from 'twenty-shared/utils'; import { IsNull, Not, type EntityManager, type Repository } from 'typeorm'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { ComparatorAction } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/comparator.interface'; import { type WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/workspace-sync-context.interface'; import { fromRoleEntityToFlatRole } from 'src/engine/metadata-modules/flat-role/utils/from-role-entity-to-flat-role.util'; import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity'; import { WorkspaceRoleComparator } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-role.comparator'; import { StandardRoleFactory } from 'src/engine/workspace-manager/workspace-sync-metadata/factories/standard-role.factory'; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/admin-role.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/admin-role.ts index 42f8b1b959..a7d265a643 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/admin-role.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/admin-role.ts @@ -15,5 +15,6 @@ export const ADMIN_ROLE: StandardRoleDefinition = { canBeAssignedToUsers: true, canBeAssignedToAgents: false, canBeAssignedToApiKeys: true, + canBeAssignedToApplications: false, applicationId: null, // TODO: Replace with Twenty application ID }; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/dashboard-manager-role.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/dashboard-manager-role.ts index 7e8e4c049e..0be8202a18 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/dashboard-manager-role.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/dashboard-manager-role.ts @@ -1,4 +1,5 @@ -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { type StandardRoleDefinition } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-roles/types/standard-role-definition.interface'; export const DASHBOARD_MANAGER_ROLE: StandardRoleDefinition = { @@ -16,6 +17,7 @@ export const DASHBOARD_MANAGER_ROLE: StandardRoleDefinition = { canBeAssignedToUsers: false, canBeAssignedToAgents: true, canBeAssignedToApiKeys: false, + canBeAssignedToApplications: true, permissionFlags: [PermissionFlagType.LAYOUTS], applicationId: null, // TODO: Replace with Twenty application ID }; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/data-manipulator-role.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/data-manipulator-role.ts index 2c5f043c5b..443e36953e 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/data-manipulator-role.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/data-manipulator-role.ts @@ -15,5 +15,6 @@ export const DATA_MANIPULATOR_ROLE: StandardRoleDefinition = { canBeAssignedToUsers: false, canBeAssignedToAgents: true, canBeAssignedToApiKeys: false, + canBeAssignedToApplications: true, applicationId: null, // TODO: Replace with Twenty application ID }; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/data-model-manager-role.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/data-model-manager-role.ts index f38e4c2fc4..278c13c709 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/data-model-manager-role.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/data-model-manager-role.ts @@ -1,4 +1,5 @@ -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { type StandardRoleDefinition } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-roles/types/standard-role-definition.interface'; export const DATA_MODEL_MANAGER_ROLE: StandardRoleDefinition = { @@ -16,6 +17,7 @@ export const DATA_MODEL_MANAGER_ROLE: StandardRoleDefinition = { canBeAssignedToUsers: false, canBeAssignedToAgents: true, canBeAssignedToApiKeys: false, + canBeAssignedToApplications: true, permissionFlags: [PermissionFlagType.DATA_MODEL], applicationId: null, }; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/workflow-manager-role.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/workflow-manager-role.ts index 2fbaf28f7c..683b6455f2 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/workflow-manager-role.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/workflow-manager-role.ts @@ -1,4 +1,5 @@ -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { type StandardRoleDefinition } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-roles/types/standard-role-definition.interface'; export const WORKFLOW_MANAGER_ROLE: StandardRoleDefinition = { @@ -16,6 +17,7 @@ export const WORKFLOW_MANAGER_ROLE: StandardRoleDefinition = { canBeAssignedToUsers: false, canBeAssignedToAgents: true, canBeAssignedToApiKeys: false, + canBeAssignedToApplications: true, permissionFlags: [PermissionFlagType.WORKFLOWS], applicationId: null, // TODO: Replace with Twenty application ID }; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/types/standard-role-definition.interface.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/types/standard-role-definition.interface.ts index 3465c805f1..0d6a92d16d 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/types/standard-role-definition.interface.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-roles/types/standard-role-definition.interface.ts @@ -1,5 +1,6 @@ +import { type PermissionFlagType } from 'twenty-shared/constants'; + import { type FlatRole } from 'src/engine/metadata-modules/flat-role/types/flat-role.type'; -import { type PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; export type StandardRoleDefinition = Omit< FlatRole, diff --git a/packages/twenty-server/src/modules/connected-account/channel-sync/channel-sync.resolver.ts b/packages/twenty-server/src/modules/connected-account/channel-sync/channel-sync.resolver.ts index 1f9bdad6e1..a2711f4714 100644 --- a/packages/twenty-server/src/modules/connected-account/channel-sync/channel-sync.resolver.ts +++ b/packages/twenty-server/src/modules/connected-account/channel-sync/channel-sync.resolver.ts @@ -1,6 +1,8 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation, Resolver } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; + import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { AuthGraphqlApiExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-graphql-api-exception.filter'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; @@ -8,7 +10,6 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { ChannelSyncSuccessDTO } from 'src/modules/connected-account/channel-sync/dtos/channel-sync-success.dto'; import { ChannelSyncService } from 'src/modules/connected-account/channel-sync/services/channel-sync.service'; diff --git a/packages/twenty-server/src/modules/workspace-member/query-hooks/workspace-member-pre-query-hook.service.ts b/packages/twenty-server/src/modules/workspace-member/query-hooks/workspace-member-pre-query-hook.service.ts index 57d918c759..a88fd4453f 100644 --- a/packages/twenty-server/src/modules/workspace-member/query-hooks/workspace-member-pre-query-hook.service.ts +++ b/packages/twenty-server/src/modules/workspace-member/query-hooks/workspace-member-pre-query-hook.service.ts @@ -1,9 +1,9 @@ import { Injectable } from '@nestjs/common'; import { isDefined } from 'twenty-shared/utils'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { type ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsException, PermissionsExceptionCode, diff --git a/packages/twenty-server/test/integration/graphql/suites/settings-permissions/granular-settings-permissions.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/settings-permissions/granular-settings-permissions.integration-spec.ts index 3b29e38288..396f17f2a2 100644 --- a/packages/twenty-server/test/integration/graphql/suites/settings-permissions/granular-settings-permissions.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/settings-permissions/granular-settings-permissions.integration-spec.ts @@ -8,9 +8,9 @@ import { findOneRoleByLabel } from 'test/integration/metadata/suites/role/utils/ import { findRoles } from 'test/integration/metadata/suites/role/utils/find-roles.util'; import { updateWorkspaceMemberRole } from 'test/integration/metadata/suites/role/utils/update-workspace-member-role.util'; import { jestExpectToBeDefined } from 'test/utils/jest-expect-to-be-defined.util.test'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception'; import { WORKSPACE_MEMBER_DATA_SEED_IDS } from 'src/engine/workspace-manager/dev-seeder/data/constants/workspace-member-data-seeds.constant'; diff --git a/packages/twenty-server/test/integration/graphql/suites/settings-permissions/roles.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/settings-permissions/roles.integration-spec.ts index a8bc5e7aeb..d33c270117 100644 --- a/packages/twenty-server/test/integration/graphql/suites/settings-permissions/roles.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/settings-permissions/roles.integration-spec.ts @@ -3,10 +3,10 @@ import { deleteOneRoleOperationFactory } from 'test/integration/graphql/utils/de import { createOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/create-one-object-metadata.util'; import { deleteOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/delete-one-object-metadata.util'; import { updateOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/update-one-object-metadata.util'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { fieldTextMock } from 'src/engine/api/__mocks__/object-metadata-item.mock'; import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; -import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants'; import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception'; import { WORKSPACE_MEMBER_DATA_SEED_IDS } from 'src/engine/workspace-manager/dev-seeder/data/constants/workspace-member-data-seeds.constant'; diff --git a/packages/twenty-shared/package.json b/packages/twenty-shared/package.json index 1a8685c28c..2499c37d2c 100644 --- a/packages/twenty-shared/package.json +++ b/packages/twenty-shared/package.json @@ -47,6 +47,11 @@ "import": "./dist/ai.mjs", "require": "./dist/ai.cjs" }, + "./application": { + "types": "./dist/application/index.d.ts", + "import": "./dist/application.mjs", + "require": "./dist/application.cjs" + }, "./constants": { "types": "./dist/constants/index.d.ts", "import": "./dist/constants.mjs", @@ -91,6 +96,7 @@ "files": [ "dist", "ai", + "application", "constants", "metadata", "testing", @@ -105,6 +111,9 @@ "ai": [ "dist/ai/index.d.ts" ], + "application": [ + "dist/application/index.d.ts" + ], "constants": [ "dist/constants/index.d.ts" ], diff --git a/packages/twenty-shared/project.json b/packages/twenty-shared/project.json index f8fd5a97ed..31f49918b8 100644 --- a/packages/twenty-shared/project.json +++ b/packages/twenty-shared/project.json @@ -16,6 +16,8 @@ "{projectRoot}/dist", "{projectRoot}/ai/package.json", "{projectRoot}/ai/dist", + "{projectRoot}/application/package.json", + "{projectRoot}/application/dist", "{projectRoot}/constants/package.json", "{projectRoot}/constants/dist", "{projectRoot}/metadata/package.json", diff --git a/packages/twenty-shared/src/application/applicationManifestType.ts b/packages/twenty-shared/src/application/applicationManifestType.ts new file mode 100644 index 0000000000..08bc280761 --- /dev/null +++ b/packages/twenty-shared/src/application/applicationManifestType.ts @@ -0,0 +1,13 @@ +import { + type ObjectManifest, + type ServerlessFunctionManifest, + type Application, +} from '@/application'; +import { type Sources } from '@/types'; + +export type ApplicationManifest = { + application: Application; + objects: ObjectManifest[]; + serverlessFunctions: ServerlessFunctionManifest[]; + sources: Sources; +}; diff --git a/packages/twenty-shared/src/application/applicationType.ts b/packages/twenty-shared/src/application/applicationType.ts new file mode 100644 index 0000000000..71374cb7b9 --- /dev/null +++ b/packages/twenty-shared/src/application/applicationType.ts @@ -0,0 +1,46 @@ +import { type ApplicationVariables } from '@/application'; +import { type PermissionFlagType } from '@/constants'; + +type ObjectPermission = { + objectMetadataId: string; + canReadObjectRecords?: boolean; + canUpdateObjectRecords?: boolean; + canSoftDeleteObjectRecords?: boolean; + canDestroyObjectRecords?: boolean; +}; + +type FieldPermission = { + objectMetadataId: string; + fieldMetadataId: string; + canReadFieldValue?: boolean; + canUpdateFieldValue?: boolean; +}; + +type Role = { + label: string; + description?: string; + icon?: string; + canUpdateAllSettings?: boolean; + canAccessAllTools?: boolean; + canReadAllObjectRecords?: boolean; + canUpdateAllObjectRecords?: boolean; + canSoftDeleteAllObjectRecords?: boolean; + canDestroyAllObjectRecords?: boolean; + canBeAssignedToUsers?: boolean; + canBeAssignedToAgents?: boolean; + canBeAssignedToApiKeys?: boolean; + canBeAssignedToApplications?: boolean; + universalIdentifier: string; + objectPermissions?: ObjectPermission[]; + fieldPermissions?: FieldPermission[]; + permissionFlags?: PermissionFlagType[]; +}; + +export type Application = { + universalIdentifier: string; + displayName?: string; + description?: string; + icon?: string; + applicationVariables?: ApplicationVariables; + applicationRole?: Role; +}; diff --git a/packages/twenty-shared/src/application/applicationVariablesType.ts b/packages/twenty-shared/src/application/applicationVariablesType.ts new file mode 100644 index 0000000000..008747cf66 --- /dev/null +++ b/packages/twenty-shared/src/application/applicationVariablesType.ts @@ -0,0 +1,8 @@ +type ApplicationVariable = { + universalIdentifier: string; + value?: string; + description?: string; + isSecret?: boolean; +}; + +export type ApplicationVariables = Record; diff --git a/packages/twenty-shared/src/application/fieldManifestType.ts b/packages/twenty-shared/src/application/fieldManifestType.ts new file mode 100644 index 0000000000..85903d1bb2 --- /dev/null +++ b/packages/twenty-shared/src/application/fieldManifestType.ts @@ -0,0 +1,14 @@ +import { type FieldMetadataType } from '@/types'; + +export type FieldManifest = { + universalIdentifier: string; + type: FieldMetadataType; + label: string; + description?: string; + icon?: string; + defaultValue?: any; + options?: any; + settings?: any; + isNullable?: boolean; + isFieldUiReadOnly?: boolean; +}; diff --git a/packages/twenty-shared/src/application/index.ts b/packages/twenty-shared/src/application/index.ts new file mode 100644 index 0000000000..3c95665faf --- /dev/null +++ b/packages/twenty-shared/src/application/index.ts @@ -0,0 +1,22 @@ +/* + * _____ _ + *|_ _|_ _____ _ __ | |_ _ _ + * | | \ \ /\ / / _ \ '_ \| __| | | | Auto-generated file + * | | \ V V / __/ | | | |_| |_| | Any edits to this will be overridden + * |_| \_/\_/ \___|_| |_|\__|\__, | + * |___/ + */ + +export type { ApplicationManifest } from './applicationManifestType'; +export type { Application } from './applicationType'; +export type { ApplicationVariables } from './applicationVariablesType'; +export type { FieldManifest } from './fieldManifestType'; +export type { ObjectManifest } from './objectManifestType'; +export type { PackageJson } from './packageJsonType'; +export type { + ServerlessFunctionManifest, + DatabaseEventTrigger, + CronTrigger, + RouteTrigger, + ServerlessFunctionTriggerManifest, +} from './serverlessFunctionManifestType'; diff --git a/packages/twenty-shared/src/application/objectManifestType.ts b/packages/twenty-shared/src/application/objectManifestType.ts new file mode 100644 index 0000000000..78ff7cca07 --- /dev/null +++ b/packages/twenty-shared/src/application/objectManifestType.ts @@ -0,0 +1,12 @@ +import { type FieldManifest } from '@/application'; + +export type ObjectManifest = { + universalIdentifier: string; + nameSingular: string; + namePlural: string; + labelSingular: string; + labelPlural: string; + description?: string; + icon?: string; + fields?: FieldManifest[]; +}; diff --git a/packages/twenty-shared/src/application/packageJsonType.ts b/packages/twenty-shared/src/application/packageJsonType.ts new file mode 100644 index 0000000000..a646a472d1 --- /dev/null +++ b/packages/twenty-shared/src/application/packageJsonType.ts @@ -0,0 +1,13 @@ +export type PackageJson = { + name: string; + license: string; + engines: { + node: string; + npm: string; + yarn: string; + }; + packageManager: string; + version: string; + dependencies?: object; + devDependencies?: object; +}; diff --git a/packages/twenty-shared/src/application/serverlessFunctionManifestType.ts b/packages/twenty-shared/src/application/serverlessFunctionManifestType.ts new file mode 100644 index 0000000000..b21c01f517 --- /dev/null +++ b/packages/twenty-shared/src/application/serverlessFunctionManifestType.ts @@ -0,0 +1,32 @@ +import { type HTTPMethod } from '@/types'; + +export type ServerlessFunctionManifest = { + universalIdentifier: string; + name?: string; + description?: string; + timeoutSeconds?: number; + triggers: ServerlessFunctionTriggerManifest[]; + handlerPath: string; + handlerName: string; +}; + +export type DatabaseEventTrigger = { + type: 'databaseEvent'; + eventName: string; +}; + +export type CronTrigger = { + type: 'cron'; + pattern: string; +}; + +export type RouteTrigger = { + type: 'route'; + path: string; + httpMethod: HTTPMethod; + isAuthRequired: boolean; +}; + +export type ServerlessFunctionTriggerManifest = { + universalIdentifier: string; +} & (CronTrigger | DatabaseEventTrigger | RouteTrigger); diff --git a/packages/twenty-server/src/engine/metadata-modules/permissions/constants/permission-flag-type.constants.ts b/packages/twenty-shared/src/constants/PermissionFlagType.ts similarity index 100% rename from packages/twenty-server/src/engine/metadata-modules/permissions/constants/permission-flag-type.constants.ts rename to packages/twenty-shared/src/constants/PermissionFlagType.ts diff --git a/packages/twenty-shared/src/constants/index.ts b/packages/twenty-shared/src/constants/index.ts index c2f9052d55..fb4cac181b 100644 --- a/packages/twenty-shared/src/constants/index.ts +++ b/packages/twenty-shared/src/constants/index.ts @@ -21,6 +21,7 @@ export { LABEL_IDENTIFIER_FIELD_METADATA_TYPES } from './LabelIdentifierFieldMet export { MULTI_ITEM_FIELD_DEFAULT_MAX_VALUES } from './MultiItemFieldDefaultMaxValues'; export { MULTI_ITEM_FIELD_MIN_MAX_VALUES } from './MultiItemFieldMinMaxValues'; export { MUTATION_MAX_MERGE_RECORDS } from './MutationMaxMergeRecords'; +export { PermissionFlagType } from './PermissionFlagType'; export { PermissionsOnAllObjectRecords } from './PermissionsOnAllObjectRecords'; export { QUERY_DEFAULT_LIMIT_RECORDS } from './QueryDefaultLimitRecords'; export { QUERY_MAX_RECORDS } from './QueryMaxRecords'; diff --git a/packages/twenty-shared/src/types/HttpMethod.ts b/packages/twenty-shared/src/types/HttpMethod.ts new file mode 100644 index 0000000000..1a2af26f35 --- /dev/null +++ b/packages/twenty-shared/src/types/HttpMethod.ts @@ -0,0 +1,7 @@ +export enum HTTPMethod { + GET = 'GET', + POST = 'POST', + PUT = 'PUT', + PATCH = 'PATCH', + DELETE = 'DELETE', +} diff --git a/packages/twenty-front/src/modules/serverless-functions/types/sources.type.ts b/packages/twenty-shared/src/types/SourcesType.ts similarity index 100% rename from packages/twenty-front/src/modules/serverless-functions/types/sources.type.ts rename to packages/twenty-shared/src/types/SourcesType.ts diff --git a/packages/twenty-shared/src/types/index.ts b/packages/twenty-shared/src/types/index.ts index e32ba4eb00..f1cbfddb6d 100644 --- a/packages/twenty-shared/src/types/index.ts +++ b/packages/twenty-shared/src/types/index.ts @@ -111,6 +111,7 @@ export type { export { FILTERABLE_FIELD_TYPES } from './FilterableFieldType'; export { FirstDayOfTheWeek } from './FirstDayOfTheWeek'; export type { FromTo } from './FromToType'; +export { HTTPMethod } from './HttpMethod'; export type { IsEmptyRecord } from './IsEmptyRecord.type'; export type { IsExactly } from './IsExactly'; export type { ModifiedProperties } from './ModifiedProperties'; @@ -176,6 +177,7 @@ export type { RelationUpdatePayload } from './RelationUpdatePayload'; export type { RestrictedFieldPermissions } from './RestrictedFieldPermissions'; export type { RestrictedFieldsPermissions } from './RestrictedFieldsPermissions'; export { SettingsPath } from './SettingsPath'; +export type { Sources } from './SourcesType'; export type { StepFilterGroup, StepFilter,