From 6bf9593906290e92da36f6bcffa1a2b0ed1e2cd5 Mon Sep 17 00:00:00 2001 From: "amplication[bot]" Date: Mon, 26 May 2025 23:29:52 +0000 Subject: [PATCH 1/2] Amplication build # cmb5py5zg0tiq6zgm8lm2lyt9 Congratulations on your first commit! We encourage you to continue exploring how Amplication can enhance your development process, including easy management of entities, API generation, and the simplification of backend services management through extensive plugin system. Remember, [Amplication](https://amplication.com/) is the fastest way in the world to build production-ready backend services : ) Happy coding! Build URL: [https://app.amplication.com/cmb5ob2l90t4f6zgmiv25nof5/cmb5ocxdq0ra2j0tz5cxs6f3r/cmb5pom8f0tfzjwsit3tf1azx/builds/cmb5py5zg0tiq6zgm8lm2lyt9](https://app.amplication.com/cmb5ob2l90t4f6zgmiv25nof5/cmb5ocxdq0ra2j0tz5cxs6f3r/cmb5pom8f0tfzjwsit3tf1azx/builds/cmb5py5zg0tiq6zgm8lm2lyt9) --- .../.dockerignore | 7 + apps/deployment-orchestrator-admin/.env | 2 + apps/deployment-orchestrator-admin/.gitignore | 23 ++ apps/deployment-orchestrator-admin/Dockerfile | 51 +++ apps/deployment-orchestrator-admin/README.md | 47 +++ .../configuration/nginx.conf | 11 + apps/deployment-orchestrator-admin/index.html | 17 + .../package.json | 41 +++ .../public/favicon.ico | Bin 0 -> 6548 bytes .../public/logo192.png | Bin 0 -> 9721 bytes .../public/logo512.png | Bin 0 -> 17361 bytes .../public/manifest.json | 25 ++ .../public/robots.txt | 3 + .../src/App.scss | 59 ++++ .../deployment-orchestrator-admin/src/App.tsx | 81 +++++ .../src/Components/Pagination.tsx | 10 + .../src/Login.tsx | 82 +++++ .../src/LoginForm.tsx | 48 +++ .../api/cloudConnection/CloudConnection.ts | 11 + .../CloudConnectionCountArgs.ts | 5 + .../CloudConnectionCreateInput.ts | 8 + .../CloudConnectionFindManyArgs.ts | 9 + .../CloudConnectionFindUniqueArgs.ts | 5 + .../CloudConnectionListRelationFilter.ts | 7 + .../CloudConnectionOrderByInput.ts | 11 + .../CloudConnectionUpdateInput.ts | 8 + .../CloudConnectionWhereInput.ts | 11 + .../CloudConnectionWhereUniqueInput.ts | 3 + .../CreateCloudConnectionArgs.ts | 5 + .../DeleteCloudConnectionArgs.ts | 5 + .../UpdateCloudConnectionArgs.ts | 7 + .../api/deployment/CreateDeploymentArgs.ts | 5 + .../api/deployment/DeleteDeploymentArgs.ts | 5 + .../src/api/deployment/Deployment.ts | 17 + .../src/api/deployment/DeploymentCountArgs.ts | 5 + .../api/deployment/DeploymentCreateInput.ts | 14 + .../api/deployment/DeploymentFindManyArgs.ts | 9 + .../deployment/DeploymentFindUniqueArgs.ts | 5 + .../DeploymentListRelationFilter.ts | 7 + .../api/deployment/DeploymentOrderByInput.ts | 14 + .../api/deployment/DeploymentUpdateInput.ts | 14 + .../api/deployment/DeploymentWhereInput.ts | 18 + .../deployment/DeploymentWhereUniqueInput.ts | 3 + .../api/deployment/EnumDeploymentStatus.ts | 3 + ...CreateNestedManyWithoutDeploymentsInput.ts | 5 + ...andlerUpdateManyWithoutDeploymentsInput.ts | 7 + .../api/deployment/UpdateDeploymentArgs.ts | 7 + .../CreateLlmIntegrationArgs.ts | 5 + .../DeleteLlmIntegrationArgs.ts | 5 + .../src/api/llmIntegration/LlmIntegration.ts | 12 + .../llmIntegration/LlmIntegrationCountArgs.ts | 5 + .../LlmIntegrationCreateInput.ts | 9 + .../LlmIntegrationFindManyArgs.ts | 9 + .../LlmIntegrationFindUniqueArgs.ts | 5 + .../LlmIntegrationListRelationFilter.ts | 7 + .../LlmIntegrationOrderByInput.ts | 12 + .../LlmIntegrationUpdateInput.ts | 9 + .../LlmIntegrationWhereInput.ts | 12 + .../LlmIntegrationWhereUniqueInput.ts | 3 + .../UpdateLlmIntegrationArgs.ts | 7 + .../promptHandler/CreatePromptHandlerArgs.ts | 5 + .../promptHandler/DeletePromptHandlerArgs.ts | 5 + ...ateNestedManyWithoutPromptHandlersInput.ts | 5 + ...ionUpdateManyWithoutPromptHandlersInput.ts | 7 + .../src/api/promptHandler/PromptHandler.ts | 15 + .../promptHandler/PromptHandlerCountArgs.ts | 5 + .../promptHandler/PromptHandlerCreateInput.ts | 12 + .../PromptHandlerFindManyArgs.ts | 9 + .../PromptHandlerFindUniqueArgs.ts | 5 + .../PromptHandlerListRelationFilter.ts | 7 + .../PromptHandlerOrderByInput.ts | 12 + .../promptHandler/PromptHandlerUpdateInput.ts | 12 + .../promptHandler/PromptHandlerWhereInput.ts | 15 + .../PromptHandlerWhereUniqueInput.ts | 3 + .../promptHandler/UpdatePromptHandlerArgs.ts | 7 + ...reateNestedManyWithoutUserProfilesInput.ts | 5 + ...ctionUpdateManyWithoutUserProfilesInput.ts | 7 + .../api/userProfile/CreateUserProfileArgs.ts | 5 + .../api/userProfile/DeleteUserProfileArgs.ts | 5 + ...reateNestedManyWithoutUserProfilesInput.ts | 5 + ...ymentUpdateManyWithoutUserProfilesInput.ts | 7 + .../api/userProfile/UpdateUserProfileArgs.ts | 7 + .../src/api/userProfile/UserProfile.ts | 14 + .../api/userProfile/UserProfileCountArgs.ts | 5 + .../api/userProfile/UserProfileCreateInput.ts | 11 + .../userProfile/UserProfileFindManyArgs.ts | 9 + .../userProfile/UserProfileFindUniqueArgs.ts | 5 + .../UserProfileListRelationFilter.ts | 7 + .../userProfile/UserProfileOrderByInput.ts | 11 + .../api/userProfile/UserProfileUpdateInput.ts | 11 + .../api/userProfile/UserProfileWhereInput.ts | 14 + .../UserProfileWhereUniqueInput.ts | 3 + .../src/auth-provider/ra-auth-http.ts | 78 +++++ .../src/auth-provider/ra-auth-jwt.ts | 72 ++++ .../deployment-orchestrator-admin/src/auth.ts | 34 ++ .../cloudConnection/CloudConnectionCreate.tsx | 31 ++ .../cloudConnection/CloudConnectionEdit.tsx | 29 ++ .../cloudConnection/CloudConnectionList.tsx | 38 ++ .../cloudConnection/CloudConnectionShow.tsx | 32 ++ .../cloudConnection/CloudConnectionTitle.ts | 7 + .../src/constants.ts | 2 + .../src/data-provider/graphqlDataProvider.ts | 28 ++ .../src/deployment/DeploymentCreate.tsx | 52 +++ .../src/deployment/DeploymentEdit.tsx | 52 +++ .../src/deployment/DeploymentList.tsx | 41 +++ .../src/deployment/DeploymentShow.tsx | 62 ++++ .../src/deployment/DeploymentTitle.ts | 7 + .../src/index.css | 26 ++ .../src/index.tsx | 10 + .../llmIntegration/LlmIntegrationCreate.tsx | 32 ++ .../src/llmIntegration/LlmIntegrationEdit.tsx | 30 ++ .../src/llmIntegration/LlmIntegrationList.tsx | 39 +++ .../src/llmIntegration/LlmIntegrationShow.tsx | 33 ++ .../src/llmIntegration/LlmIntegrationTitle.ts | 7 + .../src/login.scss | 119 +++++++ .../src/pages/Dashboard.tsx | 12 + .../src/promptHandler/PromptHandlerCreate.tsx | 45 +++ .../src/promptHandler/PromptHandlerEdit.tsx | 45 +++ .../src/promptHandler/PromptHandlerList.tsx | 39 +++ .../src/promptHandler/PromptHandlerShow.tsx | 60 ++++ .../src/promptHandler/PromptHandlerTitle.ts | 7 + .../src/reportWebVitals.ts | 17 + .../src/setupTests.ts | 5 + .../src/theme/theme.ts | 33 ++ .../src/types.ts | 13 + .../src/user/EnumRoles.ts | 3 + .../src/user/RolesOptions.ts | 11 + .../src/user/roles.ts | 6 + .../src/userProfile/UserProfileCreate.tsx | 43 +++ .../src/userProfile/UserProfileEdit.tsx | 43 +++ .../src/userProfile/UserProfileList.tsx | 24 ++ .../src/userProfile/UserProfileShow.tsx | 75 ++++ .../src/userProfile/UserProfileTitle.ts | 7 + .../src/util/BooleanFilter.ts | 4 + .../src/util/BooleanNullableFilter.ts | 4 + .../src/util/DateTimeFilter.ts | 10 + .../src/util/DateTimeNullableFilter.ts | 10 + .../src/util/FloatFilter.ts | 10 + .../src/util/FloatNullableFilter.ts | 10 + .../src/util/IntFilter.ts | 10 + .../src/util/IntNullableFilter.ts | 10 + .../src/util/JsonFilter.ts | 5 + .../src/util/JsonNullableFilter.ts | 5 + .../src/util/MetaQueryPayload.ts | 3 + .../src/util/QueryMode.ts | 4 + .../src/util/SortOrder.ts | 4 + .../src/util/StringFilter.ts | 16 + .../src/util/StringNullableFilter.ts | 15 + .../src/vite-env.d.ts | 1 + .../tsconfig.json | 21 ++ .../vite.config.ts | 14 + .../.dockerignore | 8 + apps/deployment-orchestrator-server/.env | 8 + .../deployment-orchestrator-server/.gitignore | 5 + .../.prettierignore | 5 + .../deployment-orchestrator-server/Dockerfile | 68 ++++ apps/deployment-orchestrator-server/README.md | 64 ++++ .../docker-compose.dev.yml | 13 + .../docker-compose.yml | 47 +++ .../nest-cli.json | 10 + .../package.json | 76 ++++ .../prisma/schema.prisma | 75 ++++ .../scripts/customSeed.ts | 7 + .../scripts/seed.ts | 25 ++ .../src/app.module.ts | 49 +++ .../cloudConnection/base/CloudConnection.ts | 96 ++++++ .../base/CloudConnectionCountArgs.ts | 28 ++ .../base/CloudConnectionCreateInput.ts | 74 ++++ .../base/CloudConnectionFindManyArgs.ts | 62 ++++ .../base/CloudConnectionFindUniqueArgs.ts | 30 ++ .../base/CloudConnectionListRelationFilter.ts | 56 +++ .../base/CloudConnectionOrderByInput.ts | 100 ++++++ .../base/CloudConnectionUpdateInput.ts | 74 ++++ .../base/CloudConnectionWhereInput.ts | 79 +++++ .../base/CloudConnectionWhereUniqueInput.ts | 27 ++ .../base/CreateCloudConnectionArgs.ts | 30 ++ .../base/DeleteCloudConnectionArgs.ts | 30 ++ .../base/UpdateCloudConnectionArgs.ts | 40 +++ .../cloudConnection.controller.base.spec.ts | 202 +++++++++++ .../base/cloudConnection.controller.base.ts | 194 +++++++++++ .../base/cloudConnection.module.base.ts | 18 + .../base/cloudConnection.resolver.base.ts | 131 +++++++ .../base/cloudConnection.service.base.ts | 62 ++++ .../cloudConnection.controller.ts | 12 + .../cloudConnection/cloudConnection.module.ts | 13 + .../cloudConnection.resolver.ts | 11 + .../cloudConnection.service.ts | 10 + .../src/connectMicroservices.ts | 6 + .../decorators/api-nested-query.decorator.ts | 80 +++++ .../src/decorators/public.decorator.ts | 10 + .../deployment/base/CreateDeploymentArgs.ts | 30 ++ .../deployment/base/DeleteDeploymentArgs.ts | 30 ++ .../src/deployment/base/Deployment.ts | 143 ++++++++ .../deployment/base/DeploymentCountArgs.ts | 28 ++ .../deployment/base/DeploymentCreateInput.ts | 125 +++++++ .../deployment/base/DeploymentFindManyArgs.ts | 62 ++++ .../base/DeploymentFindUniqueArgs.ts | 30 ++ .../base/DeploymentListRelationFilter.ts | 56 +++ .../deployment/base/DeploymentOrderByInput.ts | 133 +++++++ .../deployment/base/DeploymentUpdateInput.ts | 125 +++++++ .../deployment/base/DeploymentWhereInput.ts | 128 +++++++ .../base/DeploymentWhereUniqueInput.ts | 27 ++ .../deployment/base/EnumDeploymentStatus.ts | 20 ++ ...CreateNestedManyWithoutDeploymentsInput.ts | 28 ++ ...andlerUpdateManyWithoutDeploymentsInput.ts | 46 +++ .../deployment/base/UpdateDeploymentArgs.ts | 40 +++ .../base/deployment.controller.base.spec.ts | 210 +++++++++++ .../base/deployment.controller.base.ts | 295 ++++++++++++++++ .../deployment/base/deployment.module.base.ts | 18 + .../base/deployment.resolver.base.ts | 147 ++++++++ .../base/deployment.service.base.ts | 74 ++++ .../src/deployment/deployment.controller.ts | 12 + .../src/deployment/deployment.module.ts | 13 + .../src/deployment/deployment.resolver.ts | 11 + .../src/deployment/deployment.service.ts | 10 + .../src/errors.ts | 16 + .../src/filters/HttpExceptions.filter.ts | 89 +++++ .../src/health/base/health.controller.base.ts | 19 + .../src/health/base/health.service.base.ts | 15 + .../src/health/health.controller.ts | 10 + .../src/health/health.module.ts | 10 + .../src/health/health.service.ts | 10 + .../base/CreateLlmIntegrationArgs.ts | 30 ++ .../base/DeleteLlmIntegrationArgs.ts | 30 ++ .../src/llmIntegration/base/LlmIntegration.ts | 108 ++++++ .../base/LlmIntegrationCountArgs.ts | 28 ++ .../base/LlmIntegrationCreateInput.ts | 86 +++++ .../base/LlmIntegrationFindManyArgs.ts | 62 ++++ .../base/LlmIntegrationFindUniqueArgs.ts | 30 ++ .../base/LlmIntegrationListRelationFilter.ts | 56 +++ .../base/LlmIntegrationOrderByInput.ts | 111 ++++++ .../base/LlmIntegrationUpdateInput.ts | 86 +++++ .../base/LlmIntegrationWhereInput.ts | 90 +++++ .../base/LlmIntegrationWhereUniqueInput.ts | 27 ++ .../base/UpdateLlmIntegrationArgs.ts | 40 +++ .../llmIntegration.controller.base.spec.ts | 206 +++++++++++ .../base/llmIntegration.controller.base.ts | 204 +++++++++++ .../base/llmIntegration.module.base.ts | 18 + .../base/llmIntegration.resolver.base.ts | 131 +++++++ .../base/llmIntegration.service.base.ts | 64 ++++ .../llmIntegration.controller.ts | 12 + .../llmIntegration/llmIntegration.module.ts | 13 + .../llmIntegration/llmIntegration.resolver.ts | 11 + .../llmIntegration/llmIntegration.service.ts | 10 + .../src/main.ts | 53 +++ .../src/prisma.util.spec.ts | 23 ++ .../src/prisma.util.ts | 29 ++ .../src/prisma/prisma.module.ts | 9 + .../src/prisma/prisma.service.ts | 9 + .../base/CreatePromptHandlerArgs.ts | 30 ++ .../base/DeletePromptHandlerArgs.ts | 30 ++ ...ateNestedManyWithoutPromptHandlersInput.ts | 28 ++ ...ionUpdateManyWithoutPromptHandlersInput.ts | 46 +++ .../src/promptHandler/base/PromptHandler.ts | 117 +++++++ .../base/PromptHandlerCountArgs.ts | 28 ++ .../base/PromptHandlerCreateInput.ts | 98 ++++++ .../base/PromptHandlerFindManyArgs.ts | 62 ++++ .../base/PromptHandlerFindUniqueArgs.ts | 30 ++ .../base/PromptHandlerListRelationFilter.ts | 56 +++ .../base/PromptHandlerOrderByInput.ts | 111 ++++++ .../base/PromptHandlerUpdateInput.ts | 98 ++++++ .../base/PromptHandlerWhereInput.ts | 104 ++++++ .../base/PromptHandlerWhereUniqueInput.ts | 27 ++ .../base/UpdatePromptHandlerArgs.ts | 40 +++ .../promptHandler.controller.base.spec.ts | 198 +++++++++++ .../base/promptHandler.controller.base.ts | 292 ++++++++++++++++ .../base/promptHandler.module.base.ts | 18 + .../base/promptHandler.resolver.base.ts | 147 ++++++++ .../base/promptHandler.service.base.ts | 74 ++++ .../promptHandler/promptHandler.controller.ts | 12 + .../src/promptHandler/promptHandler.module.ts | 13 + .../promptHandler/promptHandler.resolver.ts | 11 + .../promptHandler/promptHandler.service.ts | 10 + .../base/secretsManager.service.base.spec.ts | 41 +++ .../base/secretsManager.service.base.ts | 17 + .../secrets/secretsManager.module.ts | 8 + .../secrets/secretsManager.service.ts | 10 + .../providers/secrets/secretsNameKey.enum.ts | 1 + .../src/serveStaticOptions.service.ts | 39 +++ .../src/swagger.ts | 20 ++ .../src/swagger/favicon.png | Bin 0 -> 2498 bytes .../src/swagger/logo-amplication-white.svg | 15 + .../src/swagger/swagger.css | 321 +++++++++++++++++ .../src/tests/health/health.service.spec.ts | 36 ++ .../src/types.ts | 3 + ...reateNestedManyWithoutUserProfilesInput.ts | 28 ++ ...ctionUpdateManyWithoutUserProfilesInput.ts | 46 +++ .../userProfile/base/CreateUserProfileArgs.ts | 30 ++ .../userProfile/base/DeleteUserProfileArgs.ts | 30 ++ ...reateNestedManyWithoutUserProfilesInput.ts | 28 ++ ...ymentUpdateManyWithoutUserProfilesInput.ts | 46 +++ .../userProfile/base/UpdateUserProfileArgs.ts | 40 +++ .../src/userProfile/base/UserProfile.ts | 117 +++++++ .../userProfile/base/UserProfileCountArgs.ts | 28 ++ .../base/UserProfileCreateInput.ts | 98 ++++++ .../base/UserProfileFindManyArgs.ts | 62 ++++ .../base/UserProfileFindUniqueArgs.ts | 30 ++ .../base/UserProfileListRelationFilter.ts | 56 +++ .../base/UserProfileOrderByInput.ts | 100 ++++++ .../base/UserProfileUpdateInput.ts | 98 ++++++ .../userProfile/base/UserProfileWhereInput.ts | 103 ++++++ .../base/UserProfileWhereUniqueInput.ts | 27 ++ .../base/userProfile.controller.base.spec.ts | 206 +++++++++++ .../base/userProfile.controller.base.ts | 326 ++++++++++++++++++ .../base/userProfile.module.base.ts | 18 + .../base/userProfile.resolver.base.ts | 131 +++++++ .../base/userProfile.service.base.ts | 77 +++++ .../src/userProfile/userProfile.controller.ts | 12 + .../src/userProfile/userProfile.module.ts | 13 + .../src/userProfile/userProfile.resolver.ts | 11 + .../src/userProfile/userProfile.service.ts | 10 + .../src/util/BooleanFilter.ts | 32 ++ .../src/util/BooleanNullableFilter.ts | 31 ++ .../src/util/DateTimeFilter.ts | 97 ++++++ .../src/util/DateTimeNullableFilter.ts | 97 ++++++ .../src/util/FloatFilter.ts | 98 ++++++ .../src/util/FloatNullableFilter.ts | 98 ++++++ .../src/util/IntFilter.ts | 98 ++++++ .../src/util/IntNullableFilter.ts | 98 ++++++ .../src/util/JsonFilter.ts | 31 ++ .../src/util/JsonNullableFilter.ts | 31 ++ .../src/util/MetaQueryPayload.ts | 13 + .../src/util/QueryMode.ts | 10 + .../src/util/SortOrder.ts | 10 + .../src/util/StringFilter.ts | 141 ++++++++ .../src/util/StringNullableFilter.ts | 141 ++++++++ .../src/validators/index.ts | 1 + .../is-json-value-validator.spec.ts | 44 +++ .../src/validators/is-json-value-validator.ts | 29 ++ .../tsconfig.build.json | 4 + .../tsconfig.json | 21 ++ 331 files changed, 13208 insertions(+) create mode 100644 apps/deployment-orchestrator-admin/.dockerignore create mode 100644 apps/deployment-orchestrator-admin/.env create mode 100644 apps/deployment-orchestrator-admin/.gitignore create mode 100644 apps/deployment-orchestrator-admin/Dockerfile create mode 100644 apps/deployment-orchestrator-admin/README.md create mode 100644 apps/deployment-orchestrator-admin/configuration/nginx.conf create mode 100644 apps/deployment-orchestrator-admin/index.html create mode 100644 apps/deployment-orchestrator-admin/package.json create mode 100644 apps/deployment-orchestrator-admin/public/favicon.ico create mode 100644 apps/deployment-orchestrator-admin/public/logo192.png create mode 100644 apps/deployment-orchestrator-admin/public/logo512.png create mode 100644 apps/deployment-orchestrator-admin/public/manifest.json create mode 100644 apps/deployment-orchestrator-admin/public/robots.txt create mode 100644 apps/deployment-orchestrator-admin/src/App.scss create mode 100644 apps/deployment-orchestrator-admin/src/App.tsx create mode 100644 apps/deployment-orchestrator-admin/src/Components/Pagination.tsx create mode 100644 apps/deployment-orchestrator-admin/src/Login.tsx create mode 100644 apps/deployment-orchestrator-admin/src/LoginForm.tsx create mode 100644 apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnection.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionCountArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionCreateInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionFindManyArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionFindUniqueArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionListRelationFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionOrderByInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionUpdateInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionWhereInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionWhereUniqueInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/cloudConnection/CreateCloudConnectionArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/cloudConnection/DeleteCloudConnectionArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/cloudConnection/UpdateCloudConnectionArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/deployment/CreateDeploymentArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/deployment/DeleteDeploymentArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/deployment/Deployment.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/deployment/DeploymentCountArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/deployment/DeploymentCreateInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/deployment/DeploymentFindManyArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/deployment/DeploymentFindUniqueArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/deployment/DeploymentListRelationFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/deployment/DeploymentOrderByInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/deployment/DeploymentUpdateInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/deployment/DeploymentWhereInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/deployment/DeploymentWhereUniqueInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/deployment/EnumDeploymentStatus.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/deployment/PromptHandlerCreateNestedManyWithoutDeploymentsInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/deployment/PromptHandlerUpdateManyWithoutDeploymentsInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/deployment/UpdateDeploymentArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/llmIntegration/CreateLlmIntegrationArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/llmIntegration/DeleteLlmIntegrationArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegration.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationCountArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationCreateInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationFindManyArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationFindUniqueArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationListRelationFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationOrderByInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationUpdateInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationWhereInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationWhereUniqueInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/llmIntegration/UpdateLlmIntegrationArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/promptHandler/CreatePromptHandlerArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/promptHandler/DeletePromptHandlerArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/promptHandler/LlmIntegrationCreateNestedManyWithoutPromptHandlersInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/promptHandler/LlmIntegrationUpdateManyWithoutPromptHandlersInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandler.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerCountArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerCreateInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerFindManyArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerFindUniqueArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerListRelationFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerOrderByInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerUpdateInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerWhereInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerWhereUniqueInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/promptHandler/UpdatePromptHandlerArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/CloudConnectionCreateNestedManyWithoutUserProfilesInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/CloudConnectionUpdateManyWithoutUserProfilesInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/CreateUserProfileArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/DeleteUserProfileArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/DeploymentCreateNestedManyWithoutUserProfilesInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/DeploymentUpdateManyWithoutUserProfilesInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/UpdateUserProfileArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/UserProfile.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileCountArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileCreateInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileFindManyArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileFindUniqueArgs.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileListRelationFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileOrderByInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileUpdateInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileWhereInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileWhereUniqueInput.ts create mode 100644 apps/deployment-orchestrator-admin/src/auth-provider/ra-auth-http.ts create mode 100644 apps/deployment-orchestrator-admin/src/auth-provider/ra-auth-jwt.ts create mode 100644 apps/deployment-orchestrator-admin/src/auth.ts create mode 100644 apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionCreate.tsx create mode 100644 apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionEdit.tsx create mode 100644 apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionList.tsx create mode 100644 apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionShow.tsx create mode 100644 apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionTitle.ts create mode 100644 apps/deployment-orchestrator-admin/src/constants.ts create mode 100644 apps/deployment-orchestrator-admin/src/data-provider/graphqlDataProvider.ts create mode 100644 apps/deployment-orchestrator-admin/src/deployment/DeploymentCreate.tsx create mode 100644 apps/deployment-orchestrator-admin/src/deployment/DeploymentEdit.tsx create mode 100644 apps/deployment-orchestrator-admin/src/deployment/DeploymentList.tsx create mode 100644 apps/deployment-orchestrator-admin/src/deployment/DeploymentShow.tsx create mode 100644 apps/deployment-orchestrator-admin/src/deployment/DeploymentTitle.ts create mode 100644 apps/deployment-orchestrator-admin/src/index.css create mode 100644 apps/deployment-orchestrator-admin/src/index.tsx create mode 100644 apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationCreate.tsx create mode 100644 apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationEdit.tsx create mode 100644 apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationList.tsx create mode 100644 apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationShow.tsx create mode 100644 apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationTitle.ts create mode 100644 apps/deployment-orchestrator-admin/src/login.scss create mode 100644 apps/deployment-orchestrator-admin/src/pages/Dashboard.tsx create mode 100644 apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerCreate.tsx create mode 100644 apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerEdit.tsx create mode 100644 apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerList.tsx create mode 100644 apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerShow.tsx create mode 100644 apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerTitle.ts create mode 100644 apps/deployment-orchestrator-admin/src/reportWebVitals.ts create mode 100644 apps/deployment-orchestrator-admin/src/setupTests.ts create mode 100644 apps/deployment-orchestrator-admin/src/theme/theme.ts create mode 100644 apps/deployment-orchestrator-admin/src/types.ts create mode 100644 apps/deployment-orchestrator-admin/src/user/EnumRoles.ts create mode 100644 apps/deployment-orchestrator-admin/src/user/RolesOptions.ts create mode 100644 apps/deployment-orchestrator-admin/src/user/roles.ts create mode 100644 apps/deployment-orchestrator-admin/src/userProfile/UserProfileCreate.tsx create mode 100644 apps/deployment-orchestrator-admin/src/userProfile/UserProfileEdit.tsx create mode 100644 apps/deployment-orchestrator-admin/src/userProfile/UserProfileList.tsx create mode 100644 apps/deployment-orchestrator-admin/src/userProfile/UserProfileShow.tsx create mode 100644 apps/deployment-orchestrator-admin/src/userProfile/UserProfileTitle.ts create mode 100644 apps/deployment-orchestrator-admin/src/util/BooleanFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/util/BooleanNullableFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/util/DateTimeFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/util/DateTimeNullableFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/util/FloatFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/util/FloatNullableFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/util/IntFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/util/IntNullableFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/util/JsonFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/util/JsonNullableFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/util/MetaQueryPayload.ts create mode 100644 apps/deployment-orchestrator-admin/src/util/QueryMode.ts create mode 100644 apps/deployment-orchestrator-admin/src/util/SortOrder.ts create mode 100644 apps/deployment-orchestrator-admin/src/util/StringFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/util/StringNullableFilter.ts create mode 100644 apps/deployment-orchestrator-admin/src/vite-env.d.ts create mode 100644 apps/deployment-orchestrator-admin/tsconfig.json create mode 100644 apps/deployment-orchestrator-admin/vite.config.ts create mode 100644 apps/deployment-orchestrator-server/.dockerignore create mode 100644 apps/deployment-orchestrator-server/.env create mode 100644 apps/deployment-orchestrator-server/.gitignore create mode 100644 apps/deployment-orchestrator-server/.prettierignore create mode 100644 apps/deployment-orchestrator-server/Dockerfile create mode 100644 apps/deployment-orchestrator-server/README.md create mode 100644 apps/deployment-orchestrator-server/docker-compose.dev.yml create mode 100644 apps/deployment-orchestrator-server/docker-compose.yml create mode 100644 apps/deployment-orchestrator-server/nest-cli.json create mode 100644 apps/deployment-orchestrator-server/package.json create mode 100644 apps/deployment-orchestrator-server/prisma/schema.prisma create mode 100644 apps/deployment-orchestrator-server/scripts/customSeed.ts create mode 100644 apps/deployment-orchestrator-server/scripts/seed.ts create mode 100644 apps/deployment-orchestrator-server/src/app.module.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnection.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionCountArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionCreateInput.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionFindManyArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionFindUniqueArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionListRelationFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionOrderByInput.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionUpdateInput.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionWhereInput.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionWhereUniqueInput.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/CreateCloudConnectionArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/DeleteCloudConnectionArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/UpdateCloudConnectionArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.controller.base.spec.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.controller.base.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.module.base.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.resolver.base.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.service.base.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/cloudConnection.controller.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/cloudConnection.module.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/cloudConnection.resolver.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/cloudConnection.service.ts create mode 100644 apps/deployment-orchestrator-server/src/connectMicroservices.ts create mode 100644 apps/deployment-orchestrator-server/src/decorators/api-nested-query.decorator.ts create mode 100644 apps/deployment-orchestrator-server/src/decorators/public.decorator.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/CreateDeploymentArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/DeleteDeploymentArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/Deployment.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/DeploymentCountArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/DeploymentCreateInput.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/DeploymentFindManyArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/DeploymentFindUniqueArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/DeploymentListRelationFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/DeploymentOrderByInput.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/DeploymentUpdateInput.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/DeploymentWhereInput.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/DeploymentWhereUniqueInput.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/EnumDeploymentStatus.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/PromptHandlerCreateNestedManyWithoutDeploymentsInput.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/PromptHandlerUpdateManyWithoutDeploymentsInput.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/UpdateDeploymentArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/deployment.controller.base.spec.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/deployment.controller.base.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/deployment.module.base.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/deployment.resolver.base.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/base/deployment.service.base.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/deployment.controller.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/deployment.module.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/deployment.resolver.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/deployment.service.ts create mode 100644 apps/deployment-orchestrator-server/src/errors.ts create mode 100644 apps/deployment-orchestrator-server/src/filters/HttpExceptions.filter.ts create mode 100644 apps/deployment-orchestrator-server/src/health/base/health.controller.base.ts create mode 100644 apps/deployment-orchestrator-server/src/health/base/health.service.base.ts create mode 100644 apps/deployment-orchestrator-server/src/health/health.controller.ts create mode 100644 apps/deployment-orchestrator-server/src/health/health.module.ts create mode 100644 apps/deployment-orchestrator-server/src/health/health.service.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/CreateLlmIntegrationArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/DeleteLlmIntegrationArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegration.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationCountArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationCreateInput.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationFindManyArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationFindUniqueArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationListRelationFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationOrderByInput.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationUpdateInput.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationWhereInput.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationWhereUniqueInput.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/UpdateLlmIntegrationArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.controller.base.spec.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.controller.base.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.module.base.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.resolver.base.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.service.base.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/llmIntegration.controller.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/llmIntegration.module.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/llmIntegration.resolver.ts create mode 100644 apps/deployment-orchestrator-server/src/llmIntegration/llmIntegration.service.ts create mode 100644 apps/deployment-orchestrator-server/src/main.ts create mode 100644 apps/deployment-orchestrator-server/src/prisma.util.spec.ts create mode 100644 apps/deployment-orchestrator-server/src/prisma.util.ts create mode 100644 apps/deployment-orchestrator-server/src/prisma/prisma.module.ts create mode 100644 apps/deployment-orchestrator-server/src/prisma/prisma.service.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/CreatePromptHandlerArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/DeletePromptHandlerArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/LlmIntegrationCreateNestedManyWithoutPromptHandlersInput.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/LlmIntegrationUpdateManyWithoutPromptHandlersInput.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandler.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerCountArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerCreateInput.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerFindManyArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerFindUniqueArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerListRelationFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerOrderByInput.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerUpdateInput.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerWhereInput.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerWhereUniqueInput.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/UpdatePromptHandlerArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.controller.base.spec.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.controller.base.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.module.base.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.resolver.base.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.service.base.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/promptHandler.controller.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/promptHandler.module.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/promptHandler.resolver.ts create mode 100644 apps/deployment-orchestrator-server/src/promptHandler/promptHandler.service.ts create mode 100644 apps/deployment-orchestrator-server/src/providers/secrets/base/secretsManager.service.base.spec.ts create mode 100644 apps/deployment-orchestrator-server/src/providers/secrets/base/secretsManager.service.base.ts create mode 100644 apps/deployment-orchestrator-server/src/providers/secrets/secretsManager.module.ts create mode 100644 apps/deployment-orchestrator-server/src/providers/secrets/secretsManager.service.ts create mode 100644 apps/deployment-orchestrator-server/src/providers/secrets/secretsNameKey.enum.ts create mode 100644 apps/deployment-orchestrator-server/src/serveStaticOptions.service.ts create mode 100644 apps/deployment-orchestrator-server/src/swagger.ts create mode 100644 apps/deployment-orchestrator-server/src/swagger/favicon.png create mode 100644 apps/deployment-orchestrator-server/src/swagger/logo-amplication-white.svg create mode 100644 apps/deployment-orchestrator-server/src/swagger/swagger.css create mode 100644 apps/deployment-orchestrator-server/src/tests/health/health.service.spec.ts create mode 100644 apps/deployment-orchestrator-server/src/types.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/CloudConnectionCreateNestedManyWithoutUserProfilesInput.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/CloudConnectionUpdateManyWithoutUserProfilesInput.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/CreateUserProfileArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/DeleteUserProfileArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/DeploymentCreateNestedManyWithoutUserProfilesInput.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/DeploymentUpdateManyWithoutUserProfilesInput.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/UpdateUserProfileArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/UserProfile.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/UserProfileCountArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/UserProfileCreateInput.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/UserProfileFindManyArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/UserProfileFindUniqueArgs.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/UserProfileListRelationFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/UserProfileOrderByInput.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/UserProfileUpdateInput.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/UserProfileWhereInput.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/UserProfileWhereUniqueInput.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/userProfile.controller.base.spec.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/userProfile.controller.base.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/userProfile.module.base.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/userProfile.resolver.base.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/base/userProfile.service.base.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/userProfile.controller.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/userProfile.module.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/userProfile.resolver.ts create mode 100644 apps/deployment-orchestrator-server/src/userProfile/userProfile.service.ts create mode 100644 apps/deployment-orchestrator-server/src/util/BooleanFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/util/BooleanNullableFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/util/DateTimeFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/util/DateTimeNullableFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/util/FloatFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/util/FloatNullableFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/util/IntFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/util/IntNullableFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/util/JsonFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/util/JsonNullableFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/util/MetaQueryPayload.ts create mode 100644 apps/deployment-orchestrator-server/src/util/QueryMode.ts create mode 100644 apps/deployment-orchestrator-server/src/util/SortOrder.ts create mode 100644 apps/deployment-orchestrator-server/src/util/StringFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/util/StringNullableFilter.ts create mode 100644 apps/deployment-orchestrator-server/src/validators/index.ts create mode 100644 apps/deployment-orchestrator-server/src/validators/is-json-value-validator.spec.ts create mode 100644 apps/deployment-orchestrator-server/src/validators/is-json-value-validator.ts create mode 100644 apps/deployment-orchestrator-server/tsconfig.build.json create mode 100644 apps/deployment-orchestrator-server/tsconfig.json diff --git a/apps/deployment-orchestrator-admin/.dockerignore b/apps/deployment-orchestrator-admin/.dockerignore new file mode 100644 index 000000000..1194b4f95 --- /dev/null +++ b/apps/deployment-orchestrator-admin/.dockerignore @@ -0,0 +1,7 @@ +.dockerignore +docker-compose.yml +Dockerfile +build/ +node_modules +.env +.gitignore diff --git a/apps/deployment-orchestrator-admin/.env b/apps/deployment-orchestrator-admin/.env new file mode 100644 index 000000000..e96bc900f --- /dev/null +++ b/apps/deployment-orchestrator-admin/.env @@ -0,0 +1,2 @@ +PORT=3001 +VITE_REACT_APP_SERVER_URL=http://localhost:3000 \ No newline at end of file diff --git a/apps/deployment-orchestrator-admin/.gitignore b/apps/deployment-orchestrator-admin/.gitignore new file mode 100644 index 000000000..590b2e050 --- /dev/null +++ b/apps/deployment-orchestrator-admin/.gitignore @@ -0,0 +1,23 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/apps/deployment-orchestrator-admin/Dockerfile b/apps/deployment-orchestrator-admin/Dockerfile new file mode 100644 index 000000000..0911e21fa --- /dev/null +++ b/apps/deployment-orchestrator-admin/Dockerfile @@ -0,0 +1,51 @@ +# multi-stage: base (build) +FROM node:18.13.0-slim AS base + +# instantiate environment variable +ARG REACT_APP_SERVER_URL=http://localhost:3000 + +# set the environment variable that points to the server +ENV REACT_APP_SERVER_URL=$REACT_APP_SERVER_URL + +# create directory where the application will be built +WORKDIR /app + +# copy over the dependency manifests, both the package.json +# and the package-lock.json are copied over +COPY package*.json ./ + +# installs packages and their dependencies +RUN npm install + +# copy over the code base +COPY . . + +# create the bundle of the application +RUN npm run build + +# multi-stage: production (runtime) +FROM nginx:1.22-alpine AS production + +# copy over the bundled code from the build stage +COPY --from=base /app/build /usr/share/nginx/html +COPY --from=base /app/configuration/nginx.conf /etc/nginx/conf.d/default.conf + +# create a new process indication file +RUN touch /var/run/nginx.pid + +# change ownership of nginx related directories and files +RUN chown -R nginx:nginx /var/run/nginx.pid \ + /usr/share/nginx/html \ + /var/cache/nginx \ + /var/log/nginx \ + /etc/nginx/conf.d + +# set user to the created non-privileged user +USER nginx + +# expose a specific port on the docker container +ENV PORT=3001 +EXPOSE ${PORT} + +# start the server using the previously build application +ENTRYPOINT [ "nginx", "-g", "daemon off;" ] diff --git a/apps/deployment-orchestrator-admin/README.md b/apps/deployment-orchestrator-admin/README.md new file mode 100644 index 000000000..cc7c38732 --- /dev/null +++ b/apps/deployment-orchestrator-admin/README.md @@ -0,0 +1,47 @@ +

+ + amplication-logo + +

+ +# Introduction + +This service was generated with Amplication. It serves as the client-side for the generated server component. The client-side consist of a React application with ready-made forms for creating and editing the different data models of the application. It is pre-conffigured to work with the server and comes with the boilerplate and foundation for the client - i.e., routing, navigation, authentication, permissions, menu, breadcrumbs, error handling and much more. Additional information about the admin component and the architecture around it, can be found on the [documentation](https://docs.amplication.com/guides/getting-started) site. This side of the generated project was bootstrapped with [create-react-app](https://github.com/facebook/create-react-app) and built with [react-admin](https://marmelab.com/react-admin/). + + +

+ +

+ +# Getting started + +## Step 1: Configuration + +Configuration for the client component can be provided through the use of environment variables. These can be passed to the application via the use of the `.env` file in the base directory of the generated service. Below a table can be found which show the different variables that can be passed. These values are provided default values after generation, change them to the desired values. + +| Variable | Description | Value | +| -------------------- | ------------------------------------------------ | ------------------------------ | +| PORT | the port on which to run the client | 3001 | +| REACT_APP_SERVER_URL | the url on which the server component is running | http://localhost:[server-port] | + +> **Note** +> Amplication generates default values and stores them under the .env file. It is advised to use some form of secrets manager/vault solution when using in production. + + +## Step 2: Scripts + +After configuration of the client the next step would be to run the application. Before running the client side of the component, make sure that the different pre-requisites are met - i.e., npm, docker. Make sure that the server-side of the application is running. + +```sh +# installation of the dependencies +$ npm install + +# starts the application in development mode - available by default under http://localhost:3001 with a pre-configured user with the username "admin" and password "admin" +$ npm run start + +# builds the application in production mode - available under 'build' +$ npm run build + +# removes the single build dependency from the project +$ npm run eject +``` diff --git a/apps/deployment-orchestrator-admin/configuration/nginx.conf b/apps/deployment-orchestrator-admin/configuration/nginx.conf new file mode 100644 index 000000000..c907b5ce1 --- /dev/null +++ b/apps/deployment-orchestrator-admin/configuration/nginx.conf @@ -0,0 +1,11 @@ +server_tokens off; + +server { + listen 3001; + server_name localhost; + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri /index.html; + } +} \ No newline at end of file diff --git a/apps/deployment-orchestrator-admin/index.html b/apps/deployment-orchestrator-admin/index.html new file mode 100644 index 000000000..354123d81 --- /dev/null +++ b/apps/deployment-orchestrator-admin/index.html @@ -0,0 +1,17 @@ + + + + + + + + + + Deployment Orchestrator + + + +
+ + + diff --git a/apps/deployment-orchestrator-admin/package.json b/apps/deployment-orchestrator-admin/package.json new file mode 100644 index 000000000..747e11b49 --- /dev/null +++ b/apps/deployment-orchestrator-admin/package.json @@ -0,0 +1,41 @@ +{ + "name": "@deployment-orchestrator/admin", + "private": true, + "dependencies": { + "@apollo/client": "3.6.9", + "graphql": "15.6.1", + "lodash": "4.17.21", + "pluralize": "8.0.0", + "ra-data-graphql-amplication": "1.0.2", + "react": "^18.3.0", + "react-admin": "^5.1.0", + "react-dom": "^18.3.0", + "sass": "^1.39.0" + }, + "scripts": { + "start": "vite", + "build": "vite build", + "serve": "vite preview", + "type-check": "tsc --noEmit", + "lint": "eslint --fix --ext .js,.jsx,.ts,.tsx ./src", + "format": "prettier --write ./src", + "package:container": "docker build ." + }, + "devDependencies": { + "@types/lodash": "4.14.178", + "@types/node": "^20.10.7", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@typescript-eslint/eslint-plugin": "^5.60.1", + "@typescript-eslint/parser": "^5.60.1", + "@vitejs/plugin-react": "^4.0.1", + "eslint": "^8.43.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-react": "^7.32.2", + "eslint-plugin-react-hooks": "^4.6.0", + "prettier": "^2.8.8", + "type-fest": "0.13.1", + "typescript": "^5.1.6", + "vite": "^4.3.9" + } +} \ No newline at end of file diff --git a/apps/deployment-orchestrator-admin/public/favicon.ico b/apps/deployment-orchestrator-admin/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..fcbdcf2d26233c47420d1e8d0f47f0aede4c1130 GIT binary patch literal 6548 zcma)A`EOj+6@K2G#EugH`3D$$Xw$;Z~QgJFxm{m$jTB+N}OR7#~Ma%uGBrK*CZH*-*0`9Xc%kB z2EQHXYfn9V>M%Y}?d)hBg2cE+dNRH-9A#<45bV`663V~puX14A_aIt}>%1imO&!oc zWx@84X!Y~!HRE%&lMCHaS5eVB>RH;X8lLJDbHmbBk-N&ji`tl2MnnYmq9*?i^xCP# zJCn3@>eo7#)9bIBjnvJaZ%d$I5EBnWtjR9RmL1AI5bg-AY zbOD@){=hjTYz_4dtC_1=&>~0F*%}zR5~CALgaRpO1%3YFAyMqQa;c4sEJJCRN~s8N zUmRE_%09{}$|B_&c>u+R(v-(OODLcYm7%Yn`sd4gv4;}Bd{r8RUr3+7*Q$4|AG7o- zXg&GrQp*Zu5QVdVZoGDSkrQ)uH4#tj$q#-GjYpYNz8Z{$1YK6)ZB2#dECk~@9v3q> z9lD<3fA6Is^&F3Lef5+p>Gq3BP~kkIGt|d!!LwkXyHf&*Wn`HtaqD-|2br|+|C2(p zq;hCN14%boH8iPOagFBz8N}T^Tz%#&w+zx4K#;h*hKg$&kQN%E`2_`LxQ$B3X70Ih zZMU$jT*pD!HAF52d1hwL1ei-2w&k4z8jHRSST*uyp@MWyo1@sfa#iC)Geo^LAswqm zXOOm4Bhy;f)^TZV6M@XvsgU!f{!q=teE*%64(;mn1vJl)f~u(l%sr|JIbmjeet~UD zhNwOhR!wuw<|uK6dS;|mfunYMxxi-Es4gfh@}9q}EoCj8x>?0^_518x8K>?jI?-^Y(w{!$$$;dG(AVUtY1g>FtaPt&I zB=yEq5bEj7G0uF%V8#}sEOA^A0SJ^HyOjV@7TJ^fF$gZdS#x+LI1#?_QuQvK{;wxq zon5Ghvh&VE;Gok)5{?RLMp^XMyCAsiEfgP$_voPph?>g9{cbL4f8`!<&}Tmb^RRn? z7-9pE%o3r@#M7c^44w7G#o5HttPz457r(&};Xqxsw8PCa(IIZr53apZaL}fRl$6<# zt*wt=H;z{n5Q56-zp}|hU6!H{1y9GKiPQ5nRs{;TyD-Ncef4OBlY>&yPl9jUeAvl@ ziP?Me34UT;;gItv8b_w}2OwWA;xX4mKKfq>F&H5Bq3NzCLDT>QRKKaOM&)bs#Q?-9 zs;rq7i-r~Q1*xMrp~BrY=(~7brv~Qfh#~n98L4BdL4l}4nmzLuwOI{{TG|UB^(|N9 z69tI!_TGalE^=2Yu0_FA*H>6x;a%AQw(CghU1kVqN<>&hMgJKf`QQPYVy+3zIs`xs zAgLn&wiK~}X6h$JF5L_sE_hm~&BPr>1PJ)3z@&|Mgy?iY)r!8cirx`*tOC8eDB14SA#M}i`zC%r}BJL>eY>lLgE;QkYA^S$ z@h5iX{0ToF19f5$-Us2kClfryGQaoyrPRGoe~-Eoh0X~_Hgcu8u2!UQ-*PGx4JK$g zD?A&nXAdRuy%)eIxuQ-FopZsH2rk40a>>MIkmuf;&q8bj^`Ln$LZeJH4Nqe-NsLD? zi`-?XC2fOcQv)$r?h^XdA{sWNy&MVE zWS~u4OZw_@$f%Fc>rukEmIfxI+F2V>hhA>)x7tdeU9oC(=y=IBUW{4vLPFYn8uH}( z-=ltX@|&n^jRnOpVjI36m!k;%!!$fdO$<;+XpZQi4a@wBOn3p6)HiBqhNVe`zM=50 zQ-k&@u-ny%ioSTunsC%DpX+qyvsQZm_02m3FDG+h2bY4^wTY$*PKrW6JT)jL<6==H z1}1AK{QOejH{Wq4=;{1wuX*4cP#o`Cz$YGlcoO4xC+-U!w8YztpS8vHjkx>t3qbj_ z>;&&!yorIRc=gwXS2QMYN7aW{&CCc%KV2u27lgY9uWlWpnW2NHxVpP`YDrg)OF$tQ zKY|rG7=0kUCe;796wGI~rnMeIS)d)yX1y)y&#kMbC$6*MzBWItpIft+IQ1-amH0;h z{s(}Y+EG)l$D!N6vt9kH$Bdidpg|Xir@JovPRE{Mq6^5gu%W(Dfqx%pldcVyqaJ~t z7w%>Jvmhwnn?HwiaP_34x(?5A{L`YuDGD&idB4tmS7a%dfqC`vMZ6QR=u;}BbOD!FWk5d{(e2R5R zzW;JeOP&$WPLKTryoJ|D0;>=+J44fudiwp;EpqelDy=G%{A}JNLJs%XacG3x2kZl_ zBW2eetJ0DO(Vap&%JJ)B1m{66?n?Evi15Bh;d&kPUo1pD=O4cktHGcK6`-6K^@~?H zl}>lAcv>}SEPngBrA4S2%NN7|{^2jcmX^TY`KcJW5vPVX)Ju__gt1%CLyLYi#V~K6 zcav+uK<97#Db)*^k3tF3A!49%QqVCG7FP(Adc6;F9YsHfX1)NV^`l=0IsJmvj!$JL z)LnEQ*c^|fQJNWS$Zx^Hz)dAe}+sjz?ghN&hg=Ia>08X#ta?y)1syYBUf ztp=hs1Xj)1szxc~TE?hFk3CbJvAwz2fQF^0vxADEHkhLx`{toXQ1>&~J7=5Y8t-GE zCu_y@5p56m~86_*Rt(A@yahWpWaQJi5VMJ5fHLhs)i@#hBfBrBu zdi-y%f(bcRm&&cmw-si?BuaAD$vLr~U?PADKlx*lXf{Ui)ps8|0TJKP6o%*?snGE% z`lS)KyV`uih1r+^s250`;8-G1CMjDPY==zCxP7Cc3)UY&?XN_TFH8T=+Qzk-=> zQNO=%Tj!n?;}pbE6iQc`*qmHXoHr*UCNGhIm69%Ya63wF7gx!pzxiYlN1NtYUKI8# d$}i+n)((Y_4MNTsC&AAV=X77V%?~`&{|DHLP-*}G literal 0 HcmV?d00001 diff --git a/apps/deployment-orchestrator-admin/public/logo192.png b/apps/deployment-orchestrator-admin/public/logo192.png new file mode 100644 index 0000000000000000000000000000000000000000..1918ff2edeedb1a1cfb429c71deb46b3cb71427e GIT binary patch literal 9721 zcmc&)`EOj;bskbAhx;N9N92%0QWCcriu*p?H*qKq$>ApM`ywvlPKu<&AtS@JQAdsA z*!3dEjuXRjyeo+lwT%n|w&h5cEm?IWtG1+|DT20gPyjd(Ni1Ab*p;PNxg1x7V~nfBXJ>!oItp$35Za$$-<*UJGjsBf#+g zs~Y+!I|E<6en?1j?l!ol@5mF?>?*bB7;$qY^Rj6RwkU0eny0x|^=ln<8k^%5VZ|7=5g3IK z?pi|@tY-0&p;(zfiKw9UP%#)`o{xv-q7@Dh5N_cMx1ad({JsJi5l*;$N{kFq^-wbq ztGM8H$lBGP@O6IvFvK&oireFeO4K&&ZoUhoLjvO?RLa9VGvVj8**${f@n+zyw_)*n z-s6R($3|9R_2tP!lPFlTs=%bB(uKM=Q*cJY~idg^(ZpRe-| zu5RN-bAneH-bMRpzS@)}1%4c4Hv|ZQ@SK2yN76(1ChJgeK!x_&!(aZ0rM7S!#9V&y zqD)}10mkkY@J5eHK(*~RKN$97>D8D)7k&-eg!DmTcYzuqEj(wgcfNjv!D=qz5Tpwt z;7)T^e6J1(DQ=2TK)H9&xZYR(kYH-Gk4nz}Z$K^XPn+ZLv9NFBJLxmy=*y7`yc zOXV2l5q9}kv$z2^rHPg8Zt=#={6ckm=~V(FB4a;)OJ1mfvUb>7#S=E&dJKkIp-#p+ zq0(pD_p=Y!dBrTjUdYvlN-R)-L48F$z5ukToH3Bx?hMN&$qW)?L0Nj)ECBBT=eGLd zP|29hi$@W#*JjfARW1YcKw7tQ#R-C9+A|<}NU;ak0(uKNz)QvVT`PuujD;l3vuS`u z2y2Yjvf~Iyjl%*$ec1Lu05b@5{o(vCgH4yta_a(P`={S$hB_B!v@sY#_XPw4F83?& z;$?0UR2=&S;9dc}Cn!PeD)vq##HNnGmgP>P)nYk3JHR`P`Qol+T$c177>g?VKkp=QRi0|Hlan_%$uiu_G0lz?qnd-usVC!n(-^R0df%kpS# zW|2);dgp0(!`ys+hM5?fb2?XBVDKcYpKvbja`2+s;7Nn^Oda5ELr(31>{%&}cR@SN zMy~KbVxo)L2QHom?W!td3a_67Z9$k^pv)&xH7Xo_zaKIO5v)NqMz*XmJVk3GF&@F% zqX!IUI0igNL3-Y{KyQXm^3c_j;%ti&W;GYycuOUC&09uQ*^0x`u@s999)Ro?Zy=*6 zq=PX4qK|+5_;EfPjdY&^u4)IF6QVWbBY(*Bqa0b?#85U z?xY2E>?|+k6O%)19TAB5%nr#o&0DsWUU3R}gCy-~t`Pi=RFTeH;>P z1_5E|dVX_}<;s*My0@*ajb4lb_Z<|zM+#`B%c$0oNxYJd@IAJ!UNtGpA7GsM(*fW~ zO_0utv|%V8MuDdj1gQ#VW&y(*>%4k^?{ciV5op? zFV?rw2gFSREX&GeZ?hwcQ`Q(tz-F|nGE}!#8iOcU<371LTQrZBN~)e?3vpTQGUD#Z zXQ7zsC6_CpW2~JS2CCIs>y2>wvwgw24F&s?gLp)DqTx7M1mOwXIDd*+nXGw8?=Cyo| zE+oPjvVHcr`WoxAD8OBOmGF7xE({)S5ApVZ#U&#kz}A5R@DwB~+z{IiU3U-!Skkh= zUIvvW+nnkWUcW^KCWXEI0GL4@sckG1%tlCp{3*2W{DPNxSe~im|a1$|DnHOGXpaCZzfD&%s6r5Vy!(OslS8+1uGV z%;VtI^DT)tAEMQl0Db`K4<#673W52Y>Q6WuNW1&vzk=dTu?{icmo}zjvsL{lferAN zK<;wjXbSkZFMt3}G}(A_0MoOqXa>WdWh1!rB7Y1pe!xu4g;!a}F_6{9=^-d*kE1k3 zx4hg3oBi&)=H3YlylFI|a>f&e&k;~DWaO)NIT6^2!-@9DUT#30pVw&V8mLW8idujp zD1}mCWRzJO5rLWV47?k{Qa$S5W~mtu(#wMgQDeP@VyNwLZ@_M@mzN4kIzjWBmmXH{ z!P!jP`Gc6+2nO=^^2orI=R~t-#(I|u-0yH?xhvC`d*zY557zoI=RjT#D8;8A%uMjm zmFg-Fo`4frb>a|z{psFp8-M~F?I0I~edjknlo(nHLtQYiVsE|95*)Oas#6_h^Oz?-F~awl2x(9^4%wc;L)CL zyEy!D$YNqeEDdy;;!~KaaJGKP!G_S|Y++yBbO5)awgW3@{qyIc`cyhfcw;aW` z>iUDd?(ZdDd-VXG09-9!%ma&B5TNO0u^(TmzhAS^Zk1#oXA%%S?)uBx*n+l~p$oNC-*_O`{qJ1YYcK9SV1 zxkt4p^DS6reU*A}2GF8POgu~K6b#*PkhneLqPcz)cXC*K;qGO7VIz;Su8lUrI@Z5s zhRTz{a67}SX7~lwfBhG5b0FOrhIJw;)l@pgZrN7Y~}p3Z#nHaIx!+Sx1~ScP~V zrm8RQl+jkD3JVA{&80!91Vo$coAV2@j^QXb-5PHT-XGfr-4(70i!*9M0wukPNi3_IS_Ya>cOJ&LhLH?S_ z%Z}FpZx7C2=h5gy_9PTLSzFwJ^~$4VP|Pg9J9bz_BR_5uE)T;r`4=W1f(oom_1hE8 zID4%zM+YGshHwFgm$7-xeY5zKMHxFV%p7qxKMCxIj8_KfR8r`wBHmC%CG*dZFt`W!JZGyq=xQkhyfV0IiYXh3WuC%fU`eleIRnr)rRtUAa zTCKUP!?EKxzY7IaLP9+@7ogZ;f~A-b&-;vO?!_lz?k}DJN6Vn9<9I8ty}*H{c{Uc1 zC<@GVfrt#zbIs6!K4mT9g1eVN`#s1#;J6?HI4|TYRoG$}B+c@J6=r?=8 zo;LAlLii^EAoI6Ri(wVD(^Tq55=H`;wuABrta8Hlxm}+@UVGoZaTc5%qt3CK8Ok;R z7-t?Em}4dmnZ+@P;-`4Ks447jpsYq|s3r)%bNd{Znr5(p65e`1z*jGdF_gdw?*?|@Lczze9S}KV&0YA4i$pSf2~b2i}i1>Jf;oh+KjMS!Mqew zAxkC@!{dSgy90S$PBU*jCOgA-MP-^(HCTE40dbjNLALXf^wbUPCR7w{maBPc#(_bfkI+79aR0clvs6w}3y0X8c^{!=U$ zfRzKp@)9`=>9uytNN$_c7ZzK!AHu3))B)=X_t9Lq&K5I6^nswti@)FrnTOhB5Kji| z{OwlF+@WyRKhV>~;&4I?wIHwQu?Z-JH$=!Jq^e8_lmgU$?o2Uz0~Zhdd(Z@;)xRcrDPT*1LI zh>rJu`L&akQ|@ZO2=`sS%7U!i3IH!dfR!Om_aA0C@tdk7iW$t3B9Mlo{;Qm%lYy9$ z=|pZ}|Kzu?{2esw@DP{M5L#8gZ|y{QSe1+{LGggAkl{6U0aqVnHU)K>)pUYIs?N>% z8!@1--dU*$TWB;Mfo*HuV&=JKT(t{)FN#u`fsfv}@iVAuNDG8Dw`l17-grkC~z#_~6BKBv}8t?Oci za|3|K*2ZqAfE97Opm>Lua7#H`6Sz2l|jlpaZ_W>SYPy~z-i?}SkYP7fT zi)Y8%tPF5*F30T2)BL~(JUH;>bG&}{igPdb1ymd1|NiAuVE@xawq$tLna$Ec0xM}72@ zm-<@GJaqXn5Wt!TRN1R-)CZ{pM&S`>11UM>E~qAhxNRRiDF(x4X=cH&bY~zcudENA TglphG9_i|9n`&TI@kIX#FLjTn literal 0 HcmV?d00001 diff --git a/apps/deployment-orchestrator-admin/public/logo512.png b/apps/deployment-orchestrator-admin/public/logo512.png new file mode 100644 index 0000000000000000000000000000000000000000..7e7dc74f2a9aa690a5420ac9d4bcf4fbad6c67b6 GIT binary patch literal 17361 zcma)k2a{dZmG14no#X8sZ|9uUIk!68+d1c))9s+nIf`Tqc41>vt_p)$T6A zE;^mgy|%{OrqkI%wbeQ4A>MvA<{xkU4$4+bLq{d#D2BkDV(9CPBVru;y16?aS1a!{ zj{m=(yYqqJ|L^_od`^wN_7GpY@=hamEs&kzo%pr3rgohS!JV%^5AF|Y03~;BgS$@_ zW!k(P2Ed20t^@Xi$HU>i~r7NelS7H^4N^L*ums^K{hhh}8zRdG(?fduTQ&=H~yt z|4}h;f4d1rme<%*4seBj>1@Rg#8N-l!5A+G^cS1$M5}hR6$Sh_C>_;eOe}6H7<7T2 zmo5g&UcEDKB}kovq<`OiQ5kjlHp(%1vP5M~xq1MCp=!PKAUP;~uBmBuq>rcD?~NV# zT@v zdKt&gdpGSH66`UW-8c>&!$~Jr_*gTyc+``z2U6(d+u^>ubM;IbEOy+=8{`P8pzmU` ze86i!Lrs5t6+&PX!Q)+f6U+$|BDQI!ZyL}0*B8GDev0*ZN6j6)|9wWt=mr*>?Y9W= zC3x0~;e#{o)R@!x$pB-8dNyxI$#{6 zLe02qP|>d2liSAHEsk2cgUEpWNc?PD!@4cHbA@z&!Qo#CPnm9N$Q&F(s8@6FEu*m zK-8P{JfIUJ#J4asiJ)m-VlFs=c@PJ(fZRbE^w1cWb7u{+5M!V_8c84wT*I>uPysHy z>dW1ZIvddGjp{tggqW0cv?UJpyDh04Ke`3?S}d9|qPj!EMh!4OZFJ z1r9LJ1O~O~&=$MuDl0^#mALqVwnvsnALaY!cVrMVF4b{QuYv=GBEb7XSV1$hiOm0LG28H_JDq$H75bF7Spf}PeaaI8IL?da zg}HuzSo&qchHtv@!^7V4U^BEFm+GpEPi!=(kH?@aic0N+QpK(%uzmLxQFvMnj)ob! zD$S5oBR0Bsw{b2BqPv+v>kAB|Bco5XfwM!9D*18&52HbUf|(CQ?+1%w1K}2{Jj*IB z6ni-Y8#&`XUNZ)sF|-{Iq2^h@S)E+Pk`PSUn3?Q#paFV^-5{Zu59Q_>SqcUau)zxR zQsJkofv%an&!5VJl78zhwjDK_WP~1m0M=~Z+YslQ%k0%q#tB1Hc~ys@Pcx4E>0aoz z>j#xnTe+7WfSwh;56-s=8b%Gh(9ZwXXZedW4=mFqo1lJ`FFj19L6Ax*Xv{N!L00|N zvsz3VXBAl3PXr?ngSs9W40%B6L0(Lec`*t<<-~U8-h1v5h%6Ixi`|cYoa$r00RGSY zcY}9_fYIT=HYib48;JZC(V5~G&gj4+*W$(@=C^qN;xNv`1}v?Uo86hZd7u$(F*#iY*3MgnYr z+>*Lxc>`bjUS|k~+ZYPgekz`k1-ME**PaQT@#6~mh5b{5k*>Dv%DB$<;*Yc$>(B4J z8nb^Qn|(vTg5zmb;_xO8ZQKN4r43eqaieHZL=YI;pJkZQ`C2gL`8i#x=H-WE4Ic(n zLTvIifMG=><8#gW^FNd=S22S7BxGqi6f@WHatsqt&DUkAclAT(Q32&D8SIFlV+4GN z=_42{TpaLRZt$GNkgry$!b?m|sLJEv8A8Ev=U-*l3jr;F!sx`wb1yJm1QEd@;m42l z7Q$LSx=25dfVw_^9Nf!=oAOb;FPJqQ?9!o?^mT&+hd%Y2N)5p9e;#@6+fFP)pl31C z0?}uqJJDDVC9N`-IlB$YiO2?@iDeg@i3L+74-E(~jETZqH;DTA>yQbegKzU(lg-Dm zptjt|(isY-t_PKa0B;d>-8NhO!BHvd&MKiW7t$H-0x>>OiTX6& zO}`K33wq}jFe8W?Tih5XKnZ9imVEvQs9~?O&zCRYl{C;VgX>`VV&WMCOkmj&GhzW> z=?6O%^~HU^h3t(GdtFC>uKD9%VBirWmKiP+B(+1Tj#DhA(H(8};)_t}5%taAl$qgu zZ3RENtA2yv(_9BI^?+2iE+)^Hz^L|#%_t%lLb(}Q4~PyG@WOMV=Be5%!BF{*$t++; zRM$QCQ}uJ?aY6panKPK@O#x;H5J~TvZ~g|n8N|iszXdjBsQQezzVswmnhTFBNH&Q4 z+uc7F<=Q!5)BG-16u^~=~y|?P3&;RxV=4mi1Kq7^ z^!h^>Xb9pJ1lRA=R8bfgN01F@F%Qi8yYwLL=Dl<`=*EF;k%R_xIB`Ms6&) zqhwk%Gqs>5o?tQR*pawKl3**Cknh8q&I!|)KE#n^{0n0*aiWNTCk{tBKY1* z&j)XHLsqvq(^+9MGbO^@DiYjivRz<1VzOQRXD}V;!`BjnGS#){4ZxRq)UPsA`EX07 z7+qS*WXPi7`xjjfj=ZM)0AqrWEE0Yg>)V^cM|s4X_c9;{G2B;uC|lhpGBE`VeJOK3l|)sXxHdi()x6gO=%U-?*5ykYyL{Zanl4j|oHX0kfDOa(%$`}cy! zx{Dy?Ac4Q?QcMw`{^oajW^X<3R1V!qOs%%exgfRyfznLvMNG}E zbI)iqg+5SMc?R`5XqBLhe|z<(afZWX7B65_SuUebf2j-1ZV=rKf*B(SVjbFo>KuG? zAe;=mFJKyqv4=?VV<9>&mV#%11Pq{teI_j%1HceR1gl$laHOH^+{4i63gr%H`t`Se zeTr^mMF8)=0QS*c`r$iHU&YTI;|WxQ#vR+h+Y(vTK!D1FNp(I?+u(CQT2kvV@5mYh zcyXt(PHsnw+iVXrtn?5JSWX65Satx0X}(`<=@3C6 z_f{FZpAtEcCenTzGE(&XuBzSMBGFwd)dI#eviq{yg0JU=@-1wTwJZ=oIeseA#1ah! zRSeF_6u93+=VF>u22&<9l*!G!6}Ms%qw zz2lKT=M?D&MGz;#+qYsLnt!8x7q7I#v|6T<)ZL+3KtNP27^j&BfTweN`ShN;?A2$N z%UF@^#R2S?8f+OH4Xe;B`C#-qkR<}#1JrTu=`4oTPCetu5_(_z-qF`b#ZVR(DL>lV*Qp%!sPjw2Txh8S4cA`+yL1;< zF{8c1z>-z}gDSZ6^Jpk#^vL|j-#hW=$4&>!L^T9`N;lAP-aJ;We{n$)B78+Q5%Z%2rj+<1g!+PeF%aS}1 zbo6?NgD!zip3MR41M#3hIIDER%9udDT(i3hwz$DIG-mys$vF=j=)ht1AD%So`uLHz zqwB)>ri$|~&zg&%w32z-gW0-Sz*UabLghr|jwlUG^G@}H0@SSFWtjjEWxJ&>d&lVv z9zn38bGq_PQC(v7)}H{>>jL7v8!_QL&8XeBEk+|CQwhI{i(5gP=A$o4q!AXwmAmgK z5|{uw0$9+AjAU?5q}#Et=Fq*fyrPaVR81Ay#h-%#`?lfM;EqH0{P(wBfoNhDAC#HY zJ-Y03*BVYKe?&QU`5t{#D%*px5ZDB%GeBc7rcM@lL#*!P1p9dJLkj_^KB79PJDb9_ z2k0wu82UDQf)PyC{)!jT59n)A4+z!DE0E$7g2OZ2PUJ5w; zcYst1hWBS-Ah6|v*hJQ(pasHW{d1L`)$M+oM z=FtS3nUE@-D^Ie#_bSGlBGiu>ZmgBg#U$5m-hH{irMPs_u7+peYqMRV%NqTipaEl` zzyJJKHia_mhDc&z0BQ5gA5YLBMH;?n&g2;dvD0Lv^CLP^P$LZ)%RsJiSTu{VG2arb(qXTSKj`K!eMIXN& z`ydu5g9`)&ue5}y1m;_2FTS=TGk^Kk^HH9~*%MJkUwrShyV&yHdxZhk;1$EyMHck7 z_Wk+p)0+8qh1aJ8*~X?UHId#lVH1fSEzd@#KuWNo5QVwciQG0IxTI0a>XN z;3=RDF9Q?1p5JdaBfy2O5S-Gqj$BdcQ=1VoKbL$4B3|s^`pFpZYM&nPQf}J}@?*~} z;~Nv!yrSDYY&?RY1G?N&V;~R8DNx=guU5$j+?$SKe1S2?bRKLE#N|9Vi!-LVFrb>j z3)lVk3ujel9pDMLGISCwx1XT^^de}}PLGe(KSc{0W70Y=Ke+$MO#nxtGN zX~#&}hfhGRg5p4vTw(TW1TSawcn(HRkes2aUxxImfZsepjtyi@I#{n}YjrDNq)PvI zRx|ZMvmIj7WN98S&fBqI9yR2HAa>_zkYMuCo1#=`CKbIR6N|_^*g5B`dN76|+A5FD zl8^uuB|fV@Uky-sQl=8%IG5GV&FIiI5ZxhgtA}Js=P}(`BxRLg%=hVpmfqqhC}DG8 z038)A>Q0=Ws|Bih(GoihlVoCjUlxGRM1T#-aDvZX`_8dP#az-QGF*f;WVY&>yRg0g z3NHbC{Ov2sxgHoXYrSN`lIdh{;qJgP$W_!K?oHhPUGR~FqoG6`CigT;-RjX_i(1Tq zrD&lyU-01p*qt9f1{434=FK%dO}zx7Zka%bdCh zGk!fWtOcSQ1k4mnfvbKrvdIC^1RC%KV}?>RPq`oa0tQ=|7Mp@G5NfSAKPD2f*1+DlgHcy0rqru z|FDa^k*UG0_XFpnM0gtm@i%)&|hA_1+KNOGh~+ z@P$ZKmEmB|-mnOwr^afXn6QF$h>3QFd7Y`tgqQ(^8sgk0x4WSUvKh@}kPcJ_@(a%e z2ly(LvOK+wX=XU>%30;;cm4&YE~h~=gn$WSmwe+PO9zX2Jcw~;^8u0vx4>1h{r$Cj z#0vhG=YGmW0JyWjWDn`ZYi043F~>*6i066x8(f^jR|1}(IDSkt98@q2{3!S*w2O7D zWL}$g7A**(nx{YiOh+a+0*2@_z)uAIumfTPSn-%TcI{$8(r9X6fUL5ls90dwT`D&4 zswBpVFII7c7N_xaRPcb2(XGv6lgPlC(?&Btjrd)8S1jr)Ip@->qKt22Lg3ETj>@m#=> zf7~!^0cqG5ZELxO-;F`dPA>zIy5cp>R>JUP`X2ptUCmyvYFiA|CE5fOAMg5Q<=Z?T z2EzKcQDjAVNt1p5@v}^FAG%ObwprW9h61QKF)>vvKluT@7E}qgl;Ny$Fl{~sV?ed4 z=~dNjY$~}zor}TIFkco$f3vMro3~iW`g+fpYcJbFWGp@ceb<=r|vCnj6fcv$xne|z}}h(A3In&23l%$6nOS@bvg4oH69G; zQ%&0&dZd@X7&k?f7Z!`cI3V&+5_;g^pWCPVP!-7!$*zdXWMe+jz_F!0r3D)KVV z@R#zQfaA2tJifGK&%Bn#n+r}d&H|PbFg(Utl?~zanCk>sDd@8wY=hT>4y}uzs0%=2 zzY*Me5t3(K;482HOsshf$r`(q26wtq@L!Mr&hfbVBT}2`kyvfoiJc4xVV$UK)Fz?) z^~ux9*ZaG5%K0!))_?d<5bQDsyaeF7&<)Pl0OOY*?Gz3Cux{p$k3%Ml<>ITfiQezV zPzz#92iFVe2LU(h0M-5eWijkStbo`mB0x;M5fHF`oW2+x@9gQ^{EzSb{G{~{pk<}A ziH=t*^6C3;5Cfof>u+}qr>hq1(!=Kfwb&l&s;ZL>=z5SfmuFNu)$g+B9{rfXm4zT6 z;R5*`Suk1#i;3|DHkmg7y{93<`cGT5p?MrCJB@~-d8liArp%2F0ydjP8Ui7MQU}(1 znL=zAU&X#=>KcaXPk%FPpZ+=p+z$k#IktDZ@Egr5hVBd|_MLxz)!itQbcoL;-`)%Q z+iOoVbj6@09z&J&2K#NBt+hcgyg-Qv@bYa2%=FQ{V%gIsvU5W}dno3(6flv?o@zdE z@%!2$O}V29z?upwa%cXvgM8M&K79a81r{2x5o}1}IoUKW{jd+5{oM57W8k`KFcnoZ z)NvjY7|@9XXKRn82d+LC=L=Dt3ue1i?o&tiIi}HRd{j`!mlcYB<&h=_6>uh)`gy60 z>9H*-3eXW< z-2C0|unvJC5bwaP_co`-FW+Zdwn~@M03?CffC5XvS`Pm6yWe$zq9#v56?8x_TCC(C z1`FuorYdhfe{-U3(+y*WMT05{dNQ14TOHx28;MOE>#XC4dK1LNisg<43|g(|)$oP+SKw%?tW=PlD5zod(n1I^^{yb?M1GxP2cO zlQ11rxot8+9Q_+FZ|H)fzbcB+1So~w&#gp_AOOZx9e(t)pI~6*J^;^8=S}(>RiCo{ zB9Qw5Je~?TG*#@%H?gqzgB-)bTz8AujXrv2Xr}d}({@ZQ!OeTJyP!G9NFNblgvK!S zG$<29q9dIbx{@iTFkN$jE@9Ag;lV-})UiBtNiqwrB4zz^7z_i=``}D;euWq)Kow8e zomPw%x!7j!+H;xKzr5tZ;CA|?W<>K0{i9%1+yZsJBV|6&npm^I`7>b589}`2Gi$*Z z=ZBY_tiN$DG$RW`&oBsB_!DKK)04KKk6#BnWfUVf0}|rF%95`=yATn#!XKb`EWi(x zd}V&&{7!zwk#kFRLCR)T10r*isY1F zBLi|vbnCAtB1U9j*z{zOfiR!9Ut^f_9Ld9d^Y~6PC}M0M9LNVHF$`_ze_LA3=|$EK z5P9zPl8v-6UPjO}0e2*?$>2H*E8v$4<{D7v&Y%J2RImbi3~=^jB?H!fTc-}m zq|Te>QRlo@=z>UQ3*#6FV%O5JcvLyCr~nzEUi^-%xN#4I0dQ|W5c|nWZY)0(8r+P& zqTlvUJYm=qW9)8~wvw+FOnU?sLre4x(@dh6=6PT?osFtkenKZqyzd++0^~UpykOg_ z+=($j2MX-c_k0*yCKkYK_jKsxKETmVOh~^Ov9U7>3>jI4AO0v}f(|O88|}!JWHOr$ z74#Sx=^19s|33EYqlGO{dJT3m>5&v$PX_@EF~F*ys$tld+uB(0BQ9V-V>*~BA3wG- zYvml+@UZ$iyGWI=d_9ZaxnQCJLJ+5EV~lZ95Dn*_F$J>mEYkw=(rGD2 zBO=rjaxxpNC7qu}AX|B~e*5af|M9PH?9knepPfpm^g0aa8lczVgL`>^FMjg?BcCVM z74=uaX6&CFg&!9oX$v?TE2DB{Y^fJ#aftFtygl#ME3XGK6Pnu9m?`PG%3KdXz)b zQ?m@+SHTypveit2-g*2>3+i{5YWP2Jpof4telKqOA37*?!DjGFg#l}&6U6)cMX E3vX#zv;Y7A literal 0 HcmV?d00001 diff --git a/apps/deployment-orchestrator-admin/public/manifest.json b/apps/deployment-orchestrator-admin/public/manifest.json new file mode 100644 index 000000000..16069e5bc --- /dev/null +++ b/apps/deployment-orchestrator-admin/public/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "Deployment Orchestrator", + "name": "Deployment Orchestrator", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} \ No newline at end of file diff --git a/apps/deployment-orchestrator-admin/public/robots.txt b/apps/deployment-orchestrator-admin/public/robots.txt new file mode 100644 index 000000000..e9e57dc4d --- /dev/null +++ b/apps/deployment-orchestrator-admin/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/apps/deployment-orchestrator-admin/src/App.scss b/apps/deployment-orchestrator-admin/src/App.scss new file mode 100644 index 000000000..4c1cbb06c --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/App.scss @@ -0,0 +1,59 @@ +// .App { +// .MuiAppBar-colorSecondary { +// background-color: black; + +// .RaAppBar-menuButton-13 { +// background-color: yellow; +// } +// } + +// .MuiDrawer-paper { +// background-color: red; + +// .MuiListItemIcon-root { +// color: white; +// } +// } + +// .MuiButton-textPrimary { +// background-color: purple; +// margin: 0 0.5rem; +// color: white; +// padding: 0.5rem 1rem; + +// &:hover { +// background-color: blue; +// } +// } + +// .MuiTableRow-head { +// .MuiTableCell-head { +// background-color: black; +// color: white; +// } + +// .MuiTableSortLabel-root { +// &:hover { +// color: red; + +// .MuiTableSortLabel-icon { +// color: red !important; +// } +// } +// .MuiTableSortLabel-icon { +// color: white !important; +// } +// } +// .MuiTableSortLabel-active { +// color: green; + +// .MuiTableSortLabel-icon { +// color: green !important; +// } +// } +// } + +// .MuiFormLabel-root { +// color: magenta; +// } +// } diff --git a/apps/deployment-orchestrator-admin/src/App.tsx b/apps/deployment-orchestrator-admin/src/App.tsx new file mode 100644 index 000000000..7f8f0784d --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/App.tsx @@ -0,0 +1,81 @@ +import React, { useEffect, useState } from "react"; +import { Admin, DataProvider, Resource } from "react-admin"; +import dataProvider from "./data-provider/graphqlDataProvider"; +import { theme } from "./theme/theme"; +import Login from "./Login"; +import "./App.scss"; +import Dashboard from "./pages/Dashboard"; +import { DeploymentList } from "./deployment/DeploymentList"; +import { DeploymentCreate } from "./deployment/DeploymentCreate"; +import { DeploymentEdit } from "./deployment/DeploymentEdit"; +import { DeploymentShow } from "./deployment/DeploymentShow"; +import { PromptHandlerList } from "./promptHandler/PromptHandlerList"; +import { PromptHandlerCreate } from "./promptHandler/PromptHandlerCreate"; +import { PromptHandlerEdit } from "./promptHandler/PromptHandlerEdit"; +import { PromptHandlerShow } from "./promptHandler/PromptHandlerShow"; +import { CloudConnectionList } from "./cloudConnection/CloudConnectionList"; +import { CloudConnectionCreate } from "./cloudConnection/CloudConnectionCreate"; +import { CloudConnectionEdit } from "./cloudConnection/CloudConnectionEdit"; +import { CloudConnectionShow } from "./cloudConnection/CloudConnectionShow"; +import { UserProfileList } from "./userProfile/UserProfileList"; +import { UserProfileCreate } from "./userProfile/UserProfileCreate"; +import { UserProfileEdit } from "./userProfile/UserProfileEdit"; +import { UserProfileShow } from "./userProfile/UserProfileShow"; +import { LlmIntegrationList } from "./llmIntegration/LlmIntegrationList"; +import { LlmIntegrationCreate } from "./llmIntegration/LlmIntegrationCreate"; +import { LlmIntegrationEdit } from "./llmIntegration/LlmIntegrationEdit"; +import { LlmIntegrationShow } from "./llmIntegration/LlmIntegrationShow"; +import { jwtAuthProvider } from "./auth-provider/ra-auth-jwt"; + +const App = (): React.ReactElement => { + return ( +
+ + + + + + + +
+ ); +}; + +export default App; diff --git a/apps/deployment-orchestrator-admin/src/Components/Pagination.tsx b/apps/deployment-orchestrator-admin/src/Components/Pagination.tsx new file mode 100644 index 000000000..2de2ebf33 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/Components/Pagination.tsx @@ -0,0 +1,10 @@ +import React from "react"; +import { Pagination as RAPagination, PaginationProps } from "react-admin"; + +const PAGINATION_OPTIONS = [10, 25, 50, 100, 200]; + +const Pagination = (props: PaginationProps) => ( + +); + +export default Pagination; diff --git a/apps/deployment-orchestrator-admin/src/Login.tsx b/apps/deployment-orchestrator-admin/src/Login.tsx new file mode 100644 index 000000000..dbd6a85b8 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/Login.tsx @@ -0,0 +1,82 @@ +import * as React from "react"; +import { useState } from "react"; +import { useLogin, useNotify, Notification, defaultTheme } from "react-admin"; +import { Button, createTheme, ThemeProvider } from "@mui/material"; +import "./login.scss"; +import LoginForm from "./LoginForm"; + +const CLASS_NAME = "login-page"; + +const Login = ({ theme }: any) => { + const BASE_URI = process.env.REACT_APP_SERVER_URL; + + return ( + +
+
+
+ GraphQL API +

Connect via GraphQL

+
+ Connect to the server using GraphQL API with a complete and + understandable description of the data in your API +
+ +
+
+ React-Admin +

Admin UI

+
+ Sign in to a React-Admin client with ready-made forms for creating + and editing all the data models of your application +
+ +
+
+ REST API +

Connect via REST API

+
+ Connect to the server using REST API with a built-in Swagger + documentation +
+ +
+ + +
+
+ Read + + Amplication docs + + to learn more +
+
+
+ ); +}; + +export default Login; diff --git a/apps/deployment-orchestrator-admin/src/LoginForm.tsx b/apps/deployment-orchestrator-admin/src/LoginForm.tsx new file mode 100644 index 000000000..92d48da17 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/LoginForm.tsx @@ -0,0 +1,48 @@ +import { useState } from "react"; +import { useLogin, useNotify } from "react-admin"; +import { Button } from "@mui/material"; +import "./login.scss"; + +const LoginForm = ({ theme }: any) => { + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); + const login = useLogin(); + const notify = useNotify(); + const BASE_URI = process.env.REACT_APP_SERVER_URL; + const submit = (e: any) => { + e.preventDefault(); + login({ username, password }).catch(() => + notify("Invalid username or password") + ); + }; + + return ( +
+ + + +
+ ); +}; + +export default LoginForm; diff --git a/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnection.ts b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnection.ts new file mode 100644 index 000000000..18cc65c77 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnection.ts @@ -0,0 +1,11 @@ +import { UserProfile } from "../userProfile/UserProfile"; + +export type CloudConnection = { + accessKey: string | null; + createdAt: Date; + id: string; + provider: string | null; + region: string | null; + updatedAt: Date; + userProfile?: UserProfile | null; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionCountArgs.ts b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionCountArgs.ts new file mode 100644 index 000000000..0c9cb4c26 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionCountArgs.ts @@ -0,0 +1,5 @@ +import { CloudConnectionWhereInput } from "./CloudConnectionWhereInput"; + +export type CloudConnectionCountArgs = { + where?: CloudConnectionWhereInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionCreateInput.ts b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionCreateInput.ts new file mode 100644 index 000000000..f7b4826c8 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionCreateInput.ts @@ -0,0 +1,8 @@ +import { UserProfileWhereUniqueInput } from "../userProfile/UserProfileWhereUniqueInput"; + +export type CloudConnectionCreateInput = { + accessKey?: string | null; + provider?: string | null; + region?: string | null; + userProfile?: UserProfileWhereUniqueInput | null; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionFindManyArgs.ts b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionFindManyArgs.ts new file mode 100644 index 000000000..95a859fc7 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionFindManyArgs.ts @@ -0,0 +1,9 @@ +import { CloudConnectionWhereInput } from "./CloudConnectionWhereInput"; +import { CloudConnectionOrderByInput } from "./CloudConnectionOrderByInput"; + +export type CloudConnectionFindManyArgs = { + where?: CloudConnectionWhereInput; + orderBy?: Array; + skip?: number; + take?: number; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionFindUniqueArgs.ts b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionFindUniqueArgs.ts new file mode 100644 index 000000000..0c359102c --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionFindUniqueArgs.ts @@ -0,0 +1,5 @@ +import { CloudConnectionWhereUniqueInput } from "./CloudConnectionWhereUniqueInput"; + +export type CloudConnectionFindUniqueArgs = { + where: CloudConnectionWhereUniqueInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionListRelationFilter.ts b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionListRelationFilter.ts new file mode 100644 index 000000000..dcfd0f007 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionListRelationFilter.ts @@ -0,0 +1,7 @@ +import { CloudConnectionWhereInput } from "./CloudConnectionWhereInput"; + +export type CloudConnectionListRelationFilter = { + every?: CloudConnectionWhereInput; + some?: CloudConnectionWhereInput; + none?: CloudConnectionWhereInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionOrderByInput.ts b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionOrderByInput.ts new file mode 100644 index 000000000..b3054a35c --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionOrderByInput.ts @@ -0,0 +1,11 @@ +import { SortOrder } from "../../util/SortOrder"; + +export type CloudConnectionOrderByInput = { + accessKey?: SortOrder; + createdAt?: SortOrder; + id?: SortOrder; + provider?: SortOrder; + region?: SortOrder; + updatedAt?: SortOrder; + userProfileId?: SortOrder; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionUpdateInput.ts b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionUpdateInput.ts new file mode 100644 index 000000000..6634418e6 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionUpdateInput.ts @@ -0,0 +1,8 @@ +import { UserProfileWhereUniqueInput } from "../userProfile/UserProfileWhereUniqueInput"; + +export type CloudConnectionUpdateInput = { + accessKey?: string | null; + provider?: string | null; + region?: string | null; + userProfile?: UserProfileWhereUniqueInput | null; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionWhereInput.ts b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionWhereInput.ts new file mode 100644 index 000000000..d082b8041 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionWhereInput.ts @@ -0,0 +1,11 @@ +import { StringNullableFilter } from "../../util/StringNullableFilter"; +import { StringFilter } from "../../util/StringFilter"; +import { UserProfileWhereUniqueInput } from "../userProfile/UserProfileWhereUniqueInput"; + +export type CloudConnectionWhereInput = { + accessKey?: StringNullableFilter; + id?: StringFilter; + provider?: StringNullableFilter; + region?: StringNullableFilter; + userProfile?: UserProfileWhereUniqueInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionWhereUniqueInput.ts b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionWhereUniqueInput.ts new file mode 100644 index 000000000..406b74b2d --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CloudConnectionWhereUniqueInput.ts @@ -0,0 +1,3 @@ +export type CloudConnectionWhereUniqueInput = { + id: string; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/cloudConnection/CreateCloudConnectionArgs.ts b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CreateCloudConnectionArgs.ts new file mode 100644 index 000000000..0e4bbca2c --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/cloudConnection/CreateCloudConnectionArgs.ts @@ -0,0 +1,5 @@ +import { CloudConnectionCreateInput } from "./CloudConnectionCreateInput"; + +export type CreateCloudConnectionArgs = { + data: CloudConnectionCreateInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/cloudConnection/DeleteCloudConnectionArgs.ts b/apps/deployment-orchestrator-admin/src/api/cloudConnection/DeleteCloudConnectionArgs.ts new file mode 100644 index 000000000..4530eb18c --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/cloudConnection/DeleteCloudConnectionArgs.ts @@ -0,0 +1,5 @@ +import { CloudConnectionWhereUniqueInput } from "./CloudConnectionWhereUniqueInput"; + +export type DeleteCloudConnectionArgs = { + where: CloudConnectionWhereUniqueInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/cloudConnection/UpdateCloudConnectionArgs.ts b/apps/deployment-orchestrator-admin/src/api/cloudConnection/UpdateCloudConnectionArgs.ts new file mode 100644 index 000000000..d64181688 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/cloudConnection/UpdateCloudConnectionArgs.ts @@ -0,0 +1,7 @@ +import { CloudConnectionWhereUniqueInput } from "./CloudConnectionWhereUniqueInput"; +import { CloudConnectionUpdateInput } from "./CloudConnectionUpdateInput"; + +export type UpdateCloudConnectionArgs = { + where: CloudConnectionWhereUniqueInput; + data: CloudConnectionUpdateInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/deployment/CreateDeploymentArgs.ts b/apps/deployment-orchestrator-admin/src/api/deployment/CreateDeploymentArgs.ts new file mode 100644 index 000000000..569503eae --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/deployment/CreateDeploymentArgs.ts @@ -0,0 +1,5 @@ +import { DeploymentCreateInput } from "./DeploymentCreateInput"; + +export type CreateDeploymentArgs = { + data: DeploymentCreateInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/deployment/DeleteDeploymentArgs.ts b/apps/deployment-orchestrator-admin/src/api/deployment/DeleteDeploymentArgs.ts new file mode 100644 index 000000000..ad64b53d5 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/deployment/DeleteDeploymentArgs.ts @@ -0,0 +1,5 @@ +import { DeploymentWhereUniqueInput } from "./DeploymentWhereUniqueInput"; + +export type DeleteDeploymentArgs = { + where: DeploymentWhereUniqueInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/deployment/Deployment.ts b/apps/deployment-orchestrator-admin/src/api/deployment/Deployment.ts new file mode 100644 index 000000000..13ad01335 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/deployment/Deployment.ts @@ -0,0 +1,17 @@ +import { PromptHandler } from "../promptHandler/PromptHandler"; +import { JsonValue } from "type-fest"; +import { UserProfile } from "../userProfile/UserProfile"; + +export type Deployment = { + autoTerminateAt: Date | null; + createdAt: Date; + environment: string | null; + id: string; + promptHandlers?: Array; + region: string | null; + requestPrompt: string | null; + resolvedConfig: JsonValue; + status?: "Option1" | null; + updatedAt: Date; + userProfile?: UserProfile | null; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentCountArgs.ts b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentCountArgs.ts new file mode 100644 index 000000000..6f0eddfa0 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentCountArgs.ts @@ -0,0 +1,5 @@ +import { DeploymentWhereInput } from "./DeploymentWhereInput"; + +export type DeploymentCountArgs = { + where?: DeploymentWhereInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentCreateInput.ts b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentCreateInput.ts new file mode 100644 index 000000000..348343286 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentCreateInput.ts @@ -0,0 +1,14 @@ +import { PromptHandlerCreateNestedManyWithoutDeploymentsInput } from "./PromptHandlerCreateNestedManyWithoutDeploymentsInput"; +import { InputJsonValue } from "../../types"; +import { UserProfileWhereUniqueInput } from "../userProfile/UserProfileWhereUniqueInput"; + +export type DeploymentCreateInput = { + autoTerminateAt?: Date | null; + environment?: string | null; + promptHandlers?: PromptHandlerCreateNestedManyWithoutDeploymentsInput; + region?: string | null; + requestPrompt?: string | null; + resolvedConfig?: InputJsonValue; + status?: "Option1" | null; + userProfile?: UserProfileWhereUniqueInput | null; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentFindManyArgs.ts b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentFindManyArgs.ts new file mode 100644 index 000000000..575e939c2 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentFindManyArgs.ts @@ -0,0 +1,9 @@ +import { DeploymentWhereInput } from "./DeploymentWhereInput"; +import { DeploymentOrderByInput } from "./DeploymentOrderByInput"; + +export type DeploymentFindManyArgs = { + where?: DeploymentWhereInput; + orderBy?: Array; + skip?: number; + take?: number; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentFindUniqueArgs.ts b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentFindUniqueArgs.ts new file mode 100644 index 000000000..116923105 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentFindUniqueArgs.ts @@ -0,0 +1,5 @@ +import { DeploymentWhereUniqueInput } from "./DeploymentWhereUniqueInput"; + +export type DeploymentFindUniqueArgs = { + where: DeploymentWhereUniqueInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentListRelationFilter.ts b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentListRelationFilter.ts new file mode 100644 index 000000000..af15ee6e0 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentListRelationFilter.ts @@ -0,0 +1,7 @@ +import { DeploymentWhereInput } from "./DeploymentWhereInput"; + +export type DeploymentListRelationFilter = { + every?: DeploymentWhereInput; + some?: DeploymentWhereInput; + none?: DeploymentWhereInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentOrderByInput.ts b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentOrderByInput.ts new file mode 100644 index 000000000..44d1eacbc --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentOrderByInput.ts @@ -0,0 +1,14 @@ +import { SortOrder } from "../../util/SortOrder"; + +export type DeploymentOrderByInput = { + autoTerminateAt?: SortOrder; + createdAt?: SortOrder; + environment?: SortOrder; + id?: SortOrder; + region?: SortOrder; + requestPrompt?: SortOrder; + resolvedConfig?: SortOrder; + status?: SortOrder; + updatedAt?: SortOrder; + userProfileId?: SortOrder; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentUpdateInput.ts b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentUpdateInput.ts new file mode 100644 index 000000000..72e670918 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentUpdateInput.ts @@ -0,0 +1,14 @@ +import { PromptHandlerUpdateManyWithoutDeploymentsInput } from "./PromptHandlerUpdateManyWithoutDeploymentsInput"; +import { InputJsonValue } from "../../types"; +import { UserProfileWhereUniqueInput } from "../userProfile/UserProfileWhereUniqueInput"; + +export type DeploymentUpdateInput = { + autoTerminateAt?: Date | null; + environment?: string | null; + promptHandlers?: PromptHandlerUpdateManyWithoutDeploymentsInput; + region?: string | null; + requestPrompt?: string | null; + resolvedConfig?: InputJsonValue; + status?: "Option1" | null; + userProfile?: UserProfileWhereUniqueInput | null; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentWhereInput.ts b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentWhereInput.ts new file mode 100644 index 000000000..621df01c1 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentWhereInput.ts @@ -0,0 +1,18 @@ +import { DateTimeNullableFilter } from "../../util/DateTimeNullableFilter"; +import { StringNullableFilter } from "../../util/StringNullableFilter"; +import { StringFilter } from "../../util/StringFilter"; +import { PromptHandlerListRelationFilter } from "../promptHandler/PromptHandlerListRelationFilter"; +import { JsonFilter } from "../../util/JsonFilter"; +import { UserProfileWhereUniqueInput } from "../userProfile/UserProfileWhereUniqueInput"; + +export type DeploymentWhereInput = { + autoTerminateAt?: DateTimeNullableFilter; + environment?: StringNullableFilter; + id?: StringFilter; + promptHandlers?: PromptHandlerListRelationFilter; + region?: StringNullableFilter; + requestPrompt?: StringNullableFilter; + resolvedConfig?: JsonFilter; + status?: "Option1"; + userProfile?: UserProfileWhereUniqueInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentWhereUniqueInput.ts b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentWhereUniqueInput.ts new file mode 100644 index 000000000..b34742063 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/deployment/DeploymentWhereUniqueInput.ts @@ -0,0 +1,3 @@ +export type DeploymentWhereUniqueInput = { + id: string; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/deployment/EnumDeploymentStatus.ts b/apps/deployment-orchestrator-admin/src/api/deployment/EnumDeploymentStatus.ts new file mode 100644 index 000000000..20afbb838 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/deployment/EnumDeploymentStatus.ts @@ -0,0 +1,3 @@ +export enum EnumDeploymentStatus { + Option_1 = "Option1", +} diff --git a/apps/deployment-orchestrator-admin/src/api/deployment/PromptHandlerCreateNestedManyWithoutDeploymentsInput.ts b/apps/deployment-orchestrator-admin/src/api/deployment/PromptHandlerCreateNestedManyWithoutDeploymentsInput.ts new file mode 100644 index 000000000..f4a0b8c73 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/deployment/PromptHandlerCreateNestedManyWithoutDeploymentsInput.ts @@ -0,0 +1,5 @@ +import { PromptHandlerWhereUniqueInput } from "../promptHandler/PromptHandlerWhereUniqueInput"; + +export type PromptHandlerCreateNestedManyWithoutDeploymentsInput = { + connect?: Array; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/deployment/PromptHandlerUpdateManyWithoutDeploymentsInput.ts b/apps/deployment-orchestrator-admin/src/api/deployment/PromptHandlerUpdateManyWithoutDeploymentsInput.ts new file mode 100644 index 000000000..d751c0ee1 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/deployment/PromptHandlerUpdateManyWithoutDeploymentsInput.ts @@ -0,0 +1,7 @@ +import { PromptHandlerWhereUniqueInput } from "../promptHandler/PromptHandlerWhereUniqueInput"; + +export type PromptHandlerUpdateManyWithoutDeploymentsInput = { + connect?: Array; + disconnect?: Array; + set?: Array; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/deployment/UpdateDeploymentArgs.ts b/apps/deployment-orchestrator-admin/src/api/deployment/UpdateDeploymentArgs.ts new file mode 100644 index 000000000..3c0ec4b84 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/deployment/UpdateDeploymentArgs.ts @@ -0,0 +1,7 @@ +import { DeploymentWhereUniqueInput } from "./DeploymentWhereUniqueInput"; +import { DeploymentUpdateInput } from "./DeploymentUpdateInput"; + +export type UpdateDeploymentArgs = { + where: DeploymentWhereUniqueInput; + data: DeploymentUpdateInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/llmIntegration/CreateLlmIntegrationArgs.ts b/apps/deployment-orchestrator-admin/src/api/llmIntegration/CreateLlmIntegrationArgs.ts new file mode 100644 index 000000000..de2f63b28 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/llmIntegration/CreateLlmIntegrationArgs.ts @@ -0,0 +1,5 @@ +import { LlmIntegrationCreateInput } from "./LlmIntegrationCreateInput"; + +export type CreateLlmIntegrationArgs = { + data: LlmIntegrationCreateInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/llmIntegration/DeleteLlmIntegrationArgs.ts b/apps/deployment-orchestrator-admin/src/api/llmIntegration/DeleteLlmIntegrationArgs.ts new file mode 100644 index 000000000..f2827908d --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/llmIntegration/DeleteLlmIntegrationArgs.ts @@ -0,0 +1,5 @@ +import { LlmIntegrationWhereUniqueInput } from "./LlmIntegrationWhereUniqueInput"; + +export type DeleteLlmIntegrationArgs = { + where: LlmIntegrationWhereUniqueInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegration.ts b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegration.ts new file mode 100644 index 000000000..f426a5388 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegration.ts @@ -0,0 +1,12 @@ +import { PromptHandler } from "../promptHandler/PromptHandler"; + +export type LlmIntegration = { + apiEndpoint: string | null; + apiKeyName: string | null; + createdAt: Date; + id: string; + modelUsed: string | null; + promptHandler?: PromptHandler | null; + provider: string | null; + updatedAt: Date; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationCountArgs.ts b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationCountArgs.ts new file mode 100644 index 000000000..445c5ca36 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationCountArgs.ts @@ -0,0 +1,5 @@ +import { LlmIntegrationWhereInput } from "./LlmIntegrationWhereInput"; + +export type LlmIntegrationCountArgs = { + where?: LlmIntegrationWhereInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationCreateInput.ts b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationCreateInput.ts new file mode 100644 index 000000000..e696c5a12 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationCreateInput.ts @@ -0,0 +1,9 @@ +import { PromptHandlerWhereUniqueInput } from "../promptHandler/PromptHandlerWhereUniqueInput"; + +export type LlmIntegrationCreateInput = { + apiEndpoint?: string | null; + apiKeyName?: string | null; + modelUsed?: string | null; + promptHandler?: PromptHandlerWhereUniqueInput | null; + provider?: string | null; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationFindManyArgs.ts b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationFindManyArgs.ts new file mode 100644 index 000000000..ce7a58d9e --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationFindManyArgs.ts @@ -0,0 +1,9 @@ +import { LlmIntegrationWhereInput } from "./LlmIntegrationWhereInput"; +import { LlmIntegrationOrderByInput } from "./LlmIntegrationOrderByInput"; + +export type LlmIntegrationFindManyArgs = { + where?: LlmIntegrationWhereInput; + orderBy?: Array; + skip?: number; + take?: number; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationFindUniqueArgs.ts b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationFindUniqueArgs.ts new file mode 100644 index 000000000..7171cad47 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationFindUniqueArgs.ts @@ -0,0 +1,5 @@ +import { LlmIntegrationWhereUniqueInput } from "./LlmIntegrationWhereUniqueInput"; + +export type LlmIntegrationFindUniqueArgs = { + where: LlmIntegrationWhereUniqueInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationListRelationFilter.ts b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationListRelationFilter.ts new file mode 100644 index 000000000..b0bbe5a0d --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationListRelationFilter.ts @@ -0,0 +1,7 @@ +import { LlmIntegrationWhereInput } from "./LlmIntegrationWhereInput"; + +export type LlmIntegrationListRelationFilter = { + every?: LlmIntegrationWhereInput; + some?: LlmIntegrationWhereInput; + none?: LlmIntegrationWhereInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationOrderByInput.ts b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationOrderByInput.ts new file mode 100644 index 000000000..cdd910b31 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationOrderByInput.ts @@ -0,0 +1,12 @@ +import { SortOrder } from "../../util/SortOrder"; + +export type LlmIntegrationOrderByInput = { + apiEndpoint?: SortOrder; + apiKeyName?: SortOrder; + createdAt?: SortOrder; + id?: SortOrder; + modelUsed?: SortOrder; + promptHandlerId?: SortOrder; + provider?: SortOrder; + updatedAt?: SortOrder; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationUpdateInput.ts b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationUpdateInput.ts new file mode 100644 index 000000000..11453662e --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationUpdateInput.ts @@ -0,0 +1,9 @@ +import { PromptHandlerWhereUniqueInput } from "../promptHandler/PromptHandlerWhereUniqueInput"; + +export type LlmIntegrationUpdateInput = { + apiEndpoint?: string | null; + apiKeyName?: string | null; + modelUsed?: string | null; + promptHandler?: PromptHandlerWhereUniqueInput | null; + provider?: string | null; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationWhereInput.ts b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationWhereInput.ts new file mode 100644 index 000000000..a9d3f96be --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationWhereInput.ts @@ -0,0 +1,12 @@ +import { StringNullableFilter } from "../../util/StringNullableFilter"; +import { StringFilter } from "../../util/StringFilter"; +import { PromptHandlerWhereUniqueInput } from "../promptHandler/PromptHandlerWhereUniqueInput"; + +export type LlmIntegrationWhereInput = { + apiEndpoint?: StringNullableFilter; + apiKeyName?: StringNullableFilter; + id?: StringFilter; + modelUsed?: StringNullableFilter; + promptHandler?: PromptHandlerWhereUniqueInput; + provider?: StringNullableFilter; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationWhereUniqueInput.ts b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationWhereUniqueInput.ts new file mode 100644 index 000000000..669c8f911 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/llmIntegration/LlmIntegrationWhereUniqueInput.ts @@ -0,0 +1,3 @@ +export type LlmIntegrationWhereUniqueInput = { + id: string; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/llmIntegration/UpdateLlmIntegrationArgs.ts b/apps/deployment-orchestrator-admin/src/api/llmIntegration/UpdateLlmIntegrationArgs.ts new file mode 100644 index 000000000..e0a6411e5 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/llmIntegration/UpdateLlmIntegrationArgs.ts @@ -0,0 +1,7 @@ +import { LlmIntegrationWhereUniqueInput } from "./LlmIntegrationWhereUniqueInput"; +import { LlmIntegrationUpdateInput } from "./LlmIntegrationUpdateInput"; + +export type UpdateLlmIntegrationArgs = { + where: LlmIntegrationWhereUniqueInput; + data: LlmIntegrationUpdateInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/promptHandler/CreatePromptHandlerArgs.ts b/apps/deployment-orchestrator-admin/src/api/promptHandler/CreatePromptHandlerArgs.ts new file mode 100644 index 000000000..08cb1f100 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/promptHandler/CreatePromptHandlerArgs.ts @@ -0,0 +1,5 @@ +import { PromptHandlerCreateInput } from "./PromptHandlerCreateInput"; + +export type CreatePromptHandlerArgs = { + data: PromptHandlerCreateInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/promptHandler/DeletePromptHandlerArgs.ts b/apps/deployment-orchestrator-admin/src/api/promptHandler/DeletePromptHandlerArgs.ts new file mode 100644 index 000000000..beba611a8 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/promptHandler/DeletePromptHandlerArgs.ts @@ -0,0 +1,5 @@ +import { PromptHandlerWhereUniqueInput } from "./PromptHandlerWhereUniqueInput"; + +export type DeletePromptHandlerArgs = { + where: PromptHandlerWhereUniqueInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/promptHandler/LlmIntegrationCreateNestedManyWithoutPromptHandlersInput.ts b/apps/deployment-orchestrator-admin/src/api/promptHandler/LlmIntegrationCreateNestedManyWithoutPromptHandlersInput.ts new file mode 100644 index 000000000..5d7f8d93b --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/promptHandler/LlmIntegrationCreateNestedManyWithoutPromptHandlersInput.ts @@ -0,0 +1,5 @@ +import { LlmIntegrationWhereUniqueInput } from "../llmIntegration/LlmIntegrationWhereUniqueInput"; + +export type LlmIntegrationCreateNestedManyWithoutPromptHandlersInput = { + connect?: Array; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/promptHandler/LlmIntegrationUpdateManyWithoutPromptHandlersInput.ts b/apps/deployment-orchestrator-admin/src/api/promptHandler/LlmIntegrationUpdateManyWithoutPromptHandlersInput.ts new file mode 100644 index 000000000..5fa9e32c8 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/promptHandler/LlmIntegrationUpdateManyWithoutPromptHandlersInput.ts @@ -0,0 +1,7 @@ +import { LlmIntegrationWhereUniqueInput } from "../llmIntegration/LlmIntegrationWhereUniqueInput"; + +export type LlmIntegrationUpdateManyWithoutPromptHandlersInput = { + connect?: Array; + disconnect?: Array; + set?: Array; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandler.ts b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandler.ts new file mode 100644 index 000000000..01a151d8f --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandler.ts @@ -0,0 +1,15 @@ +import { Deployment } from "../deployment/Deployment"; +import { LlmIntegration } from "../llmIntegration/LlmIntegration"; +import { JsonValue } from "type-fest"; + +export type PromptHandler = { + createdAt: Date; + deployment?: Deployment | null; + detectedOs: string | null; + id: string; + inputPrompt: string | null; + llmIntegrations?: Array; + parsedInstructions: JsonValue; + resourcesRequested: JsonValue; + updatedAt: Date; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerCountArgs.ts b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerCountArgs.ts new file mode 100644 index 000000000..2ba4be704 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerCountArgs.ts @@ -0,0 +1,5 @@ +import { PromptHandlerWhereInput } from "./PromptHandlerWhereInput"; + +export type PromptHandlerCountArgs = { + where?: PromptHandlerWhereInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerCreateInput.ts b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerCreateInput.ts new file mode 100644 index 000000000..616b5abae --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerCreateInput.ts @@ -0,0 +1,12 @@ +import { DeploymentWhereUniqueInput } from "../deployment/DeploymentWhereUniqueInput"; +import { LlmIntegrationCreateNestedManyWithoutPromptHandlersInput } from "./LlmIntegrationCreateNestedManyWithoutPromptHandlersInput"; +import { InputJsonValue } from "../../types"; + +export type PromptHandlerCreateInput = { + deployment?: DeploymentWhereUniqueInput | null; + detectedOs?: string | null; + inputPrompt?: string | null; + llmIntegrations?: LlmIntegrationCreateNestedManyWithoutPromptHandlersInput; + parsedInstructions?: InputJsonValue; + resourcesRequested?: InputJsonValue; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerFindManyArgs.ts b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerFindManyArgs.ts new file mode 100644 index 000000000..08ad51d01 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerFindManyArgs.ts @@ -0,0 +1,9 @@ +import { PromptHandlerWhereInput } from "./PromptHandlerWhereInput"; +import { PromptHandlerOrderByInput } from "./PromptHandlerOrderByInput"; + +export type PromptHandlerFindManyArgs = { + where?: PromptHandlerWhereInput; + orderBy?: Array; + skip?: number; + take?: number; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerFindUniqueArgs.ts b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerFindUniqueArgs.ts new file mode 100644 index 000000000..d6008db93 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerFindUniqueArgs.ts @@ -0,0 +1,5 @@ +import { PromptHandlerWhereUniqueInput } from "./PromptHandlerWhereUniqueInput"; + +export type PromptHandlerFindUniqueArgs = { + where: PromptHandlerWhereUniqueInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerListRelationFilter.ts b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerListRelationFilter.ts new file mode 100644 index 000000000..5d3f746a9 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerListRelationFilter.ts @@ -0,0 +1,7 @@ +import { PromptHandlerWhereInput } from "./PromptHandlerWhereInput"; + +export type PromptHandlerListRelationFilter = { + every?: PromptHandlerWhereInput; + some?: PromptHandlerWhereInput; + none?: PromptHandlerWhereInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerOrderByInput.ts b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerOrderByInput.ts new file mode 100644 index 000000000..bbddb582f --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerOrderByInput.ts @@ -0,0 +1,12 @@ +import { SortOrder } from "../../util/SortOrder"; + +export type PromptHandlerOrderByInput = { + createdAt?: SortOrder; + deploymentId?: SortOrder; + detectedOs?: SortOrder; + id?: SortOrder; + inputPrompt?: SortOrder; + parsedInstructions?: SortOrder; + resourcesRequested?: SortOrder; + updatedAt?: SortOrder; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerUpdateInput.ts b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerUpdateInput.ts new file mode 100644 index 000000000..2cb714996 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerUpdateInput.ts @@ -0,0 +1,12 @@ +import { DeploymentWhereUniqueInput } from "../deployment/DeploymentWhereUniqueInput"; +import { LlmIntegrationUpdateManyWithoutPromptHandlersInput } from "./LlmIntegrationUpdateManyWithoutPromptHandlersInput"; +import { InputJsonValue } from "../../types"; + +export type PromptHandlerUpdateInput = { + deployment?: DeploymentWhereUniqueInput | null; + detectedOs?: string | null; + inputPrompt?: string | null; + llmIntegrations?: LlmIntegrationUpdateManyWithoutPromptHandlersInput; + parsedInstructions?: InputJsonValue; + resourcesRequested?: InputJsonValue; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerWhereInput.ts b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerWhereInput.ts new file mode 100644 index 000000000..09794cde2 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerWhereInput.ts @@ -0,0 +1,15 @@ +import { DeploymentWhereUniqueInput } from "../deployment/DeploymentWhereUniqueInput"; +import { StringNullableFilter } from "../../util/StringNullableFilter"; +import { StringFilter } from "../../util/StringFilter"; +import { LlmIntegrationListRelationFilter } from "../llmIntegration/LlmIntegrationListRelationFilter"; +import { JsonFilter } from "../../util/JsonFilter"; + +export type PromptHandlerWhereInput = { + deployment?: DeploymentWhereUniqueInput; + detectedOs?: StringNullableFilter; + id?: StringFilter; + inputPrompt?: StringNullableFilter; + llmIntegrations?: LlmIntegrationListRelationFilter; + parsedInstructions?: JsonFilter; + resourcesRequested?: JsonFilter; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerWhereUniqueInput.ts b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerWhereUniqueInput.ts new file mode 100644 index 000000000..1d42687e3 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/promptHandler/PromptHandlerWhereUniqueInput.ts @@ -0,0 +1,3 @@ +export type PromptHandlerWhereUniqueInput = { + id: string; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/promptHandler/UpdatePromptHandlerArgs.ts b/apps/deployment-orchestrator-admin/src/api/promptHandler/UpdatePromptHandlerArgs.ts new file mode 100644 index 000000000..cb0809ea8 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/promptHandler/UpdatePromptHandlerArgs.ts @@ -0,0 +1,7 @@ +import { PromptHandlerWhereUniqueInput } from "./PromptHandlerWhereUniqueInput"; +import { PromptHandlerUpdateInput } from "./PromptHandlerUpdateInput"; + +export type UpdatePromptHandlerArgs = { + where: PromptHandlerWhereUniqueInput; + data: PromptHandlerUpdateInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/CloudConnectionCreateNestedManyWithoutUserProfilesInput.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/CloudConnectionCreateNestedManyWithoutUserProfilesInput.ts new file mode 100644 index 000000000..6bff9cabc --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/CloudConnectionCreateNestedManyWithoutUserProfilesInput.ts @@ -0,0 +1,5 @@ +import { CloudConnectionWhereUniqueInput } from "../cloudConnection/CloudConnectionWhereUniqueInput"; + +export type CloudConnectionCreateNestedManyWithoutUserProfilesInput = { + connect?: Array; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/CloudConnectionUpdateManyWithoutUserProfilesInput.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/CloudConnectionUpdateManyWithoutUserProfilesInput.ts new file mode 100644 index 000000000..74136418a --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/CloudConnectionUpdateManyWithoutUserProfilesInput.ts @@ -0,0 +1,7 @@ +import { CloudConnectionWhereUniqueInput } from "../cloudConnection/CloudConnectionWhereUniqueInput"; + +export type CloudConnectionUpdateManyWithoutUserProfilesInput = { + connect?: Array; + disconnect?: Array; + set?: Array; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/CreateUserProfileArgs.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/CreateUserProfileArgs.ts new file mode 100644 index 000000000..7190c661f --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/CreateUserProfileArgs.ts @@ -0,0 +1,5 @@ +import { UserProfileCreateInput } from "./UserProfileCreateInput"; + +export type CreateUserProfileArgs = { + data: UserProfileCreateInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/DeleteUserProfileArgs.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/DeleteUserProfileArgs.ts new file mode 100644 index 000000000..929590f95 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/DeleteUserProfileArgs.ts @@ -0,0 +1,5 @@ +import { UserProfileWhereUniqueInput } from "./UserProfileWhereUniqueInput"; + +export type DeleteUserProfileArgs = { + where: UserProfileWhereUniqueInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/DeploymentCreateNestedManyWithoutUserProfilesInput.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/DeploymentCreateNestedManyWithoutUserProfilesInput.ts new file mode 100644 index 000000000..ccdb5dbff --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/DeploymentCreateNestedManyWithoutUserProfilesInput.ts @@ -0,0 +1,5 @@ +import { DeploymentWhereUniqueInput } from "../deployment/DeploymentWhereUniqueInput"; + +export type DeploymentCreateNestedManyWithoutUserProfilesInput = { + connect?: Array; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/DeploymentUpdateManyWithoutUserProfilesInput.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/DeploymentUpdateManyWithoutUserProfilesInput.ts new file mode 100644 index 000000000..8cb4dfc4f --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/DeploymentUpdateManyWithoutUserProfilesInput.ts @@ -0,0 +1,7 @@ +import { DeploymentWhereUniqueInput } from "../deployment/DeploymentWhereUniqueInput"; + +export type DeploymentUpdateManyWithoutUserProfilesInput = { + connect?: Array; + disconnect?: Array; + set?: Array; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/UpdateUserProfileArgs.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/UpdateUserProfileArgs.ts new file mode 100644 index 000000000..fa912ca11 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/UpdateUserProfileArgs.ts @@ -0,0 +1,7 @@ +import { UserProfileWhereUniqueInput } from "./UserProfileWhereUniqueInput"; +import { UserProfileUpdateInput } from "./UserProfileUpdateInput"; + +export type UpdateUserProfileArgs = { + where: UserProfileWhereUniqueInput; + data: UserProfileUpdateInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfile.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfile.ts new file mode 100644 index 000000000..e3d31e668 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfile.ts @@ -0,0 +1,14 @@ +import { CloudConnection } from "../cloudConnection/CloudConnection"; +import { Deployment } from "../deployment/Deployment"; + +export type UserProfile = { + cloudConnections?: Array; + createdAt: Date; + deployments?: Array; + email: string | null; + id: string; + name: string | null; + role: string | null; + sshKey: string | null; + updatedAt: Date; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileCountArgs.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileCountArgs.ts new file mode 100644 index 000000000..d7061317c --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileCountArgs.ts @@ -0,0 +1,5 @@ +import { UserProfileWhereInput } from "./UserProfileWhereInput"; + +export type UserProfileCountArgs = { + where?: UserProfileWhereInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileCreateInput.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileCreateInput.ts new file mode 100644 index 000000000..587737823 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileCreateInput.ts @@ -0,0 +1,11 @@ +import { CloudConnectionCreateNestedManyWithoutUserProfilesInput } from "./CloudConnectionCreateNestedManyWithoutUserProfilesInput"; +import { DeploymentCreateNestedManyWithoutUserProfilesInput } from "./DeploymentCreateNestedManyWithoutUserProfilesInput"; + +export type UserProfileCreateInput = { + cloudConnections?: CloudConnectionCreateNestedManyWithoutUserProfilesInput; + deployments?: DeploymentCreateNestedManyWithoutUserProfilesInput; + email?: string | null; + name?: string | null; + role?: string | null; + sshKey?: string | null; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileFindManyArgs.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileFindManyArgs.ts new file mode 100644 index 000000000..a2dd02b60 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileFindManyArgs.ts @@ -0,0 +1,9 @@ +import { UserProfileWhereInput } from "./UserProfileWhereInput"; +import { UserProfileOrderByInput } from "./UserProfileOrderByInput"; + +export type UserProfileFindManyArgs = { + where?: UserProfileWhereInput; + orderBy?: Array; + skip?: number; + take?: number; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileFindUniqueArgs.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileFindUniqueArgs.ts new file mode 100644 index 000000000..9f0f362fe --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileFindUniqueArgs.ts @@ -0,0 +1,5 @@ +import { UserProfileWhereUniqueInput } from "./UserProfileWhereUniqueInput"; + +export type UserProfileFindUniqueArgs = { + where: UserProfileWhereUniqueInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileListRelationFilter.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileListRelationFilter.ts new file mode 100644 index 000000000..1c0bc6bf8 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileListRelationFilter.ts @@ -0,0 +1,7 @@ +import { UserProfileWhereInput } from "./UserProfileWhereInput"; + +export type UserProfileListRelationFilter = { + every?: UserProfileWhereInput; + some?: UserProfileWhereInput; + none?: UserProfileWhereInput; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileOrderByInput.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileOrderByInput.ts new file mode 100644 index 000000000..f232ba34f --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileOrderByInput.ts @@ -0,0 +1,11 @@ +import { SortOrder } from "../../util/SortOrder"; + +export type UserProfileOrderByInput = { + createdAt?: SortOrder; + email?: SortOrder; + id?: SortOrder; + name?: SortOrder; + role?: SortOrder; + sshKey?: SortOrder; + updatedAt?: SortOrder; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileUpdateInput.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileUpdateInput.ts new file mode 100644 index 000000000..3eb8a0713 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileUpdateInput.ts @@ -0,0 +1,11 @@ +import { CloudConnectionUpdateManyWithoutUserProfilesInput } from "./CloudConnectionUpdateManyWithoutUserProfilesInput"; +import { DeploymentUpdateManyWithoutUserProfilesInput } from "./DeploymentUpdateManyWithoutUserProfilesInput"; + +export type UserProfileUpdateInput = { + cloudConnections?: CloudConnectionUpdateManyWithoutUserProfilesInput; + deployments?: DeploymentUpdateManyWithoutUserProfilesInput; + email?: string | null; + name?: string | null; + role?: string | null; + sshKey?: string | null; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileWhereInput.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileWhereInput.ts new file mode 100644 index 000000000..e51ffd59a --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileWhereInput.ts @@ -0,0 +1,14 @@ +import { CloudConnectionListRelationFilter } from "../cloudConnection/CloudConnectionListRelationFilter"; +import { DeploymentListRelationFilter } from "../deployment/DeploymentListRelationFilter"; +import { StringNullableFilter } from "../../util/StringNullableFilter"; +import { StringFilter } from "../../util/StringFilter"; + +export type UserProfileWhereInput = { + cloudConnections?: CloudConnectionListRelationFilter; + deployments?: DeploymentListRelationFilter; + email?: StringNullableFilter; + id?: StringFilter; + name?: StringNullableFilter; + role?: StringNullableFilter; + sshKey?: StringNullableFilter; +}; diff --git a/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileWhereUniqueInput.ts b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileWhereUniqueInput.ts new file mode 100644 index 000000000..35ce30358 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/api/userProfile/UserProfileWhereUniqueInput.ts @@ -0,0 +1,3 @@ +export type UserProfileWhereUniqueInput = { + id: string; +}; diff --git a/apps/deployment-orchestrator-admin/src/auth-provider/ra-auth-http.ts b/apps/deployment-orchestrator-admin/src/auth-provider/ra-auth-http.ts new file mode 100644 index 000000000..c6eeba8c0 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/auth-provider/ra-auth-http.ts @@ -0,0 +1,78 @@ +import { gql } from "@apollo/client/core"; +import { AuthProvider } from "react-admin"; +import { + CREDENTIALS_LOCAL_STORAGE_ITEM, + USER_DATA_LOCAL_STORAGE_ITEM, +} from "../constants"; +import { Credentials, LoginMutateResult } from "../types"; +import { apolloClient } from "../data-provider/graphqlDataProvider"; + +const LOGIN = gql` + mutation login($username: String!, $password: String!) { + login(credentials: { username: $username, password: $password }) { + username + roles + } + } +`; + +export const httpAuthProvider: AuthProvider = { + login: async (credentials: Credentials) => { + const userData = await apolloClient.mutate({ + mutation: LOGIN, + variables: { + ...credentials, + }, + }); + + if (userData && userData.data?.login.username) { + localStorage.setItem( + CREDENTIALS_LOCAL_STORAGE_ITEM, + createBasicAuthorizationHeader( + credentials.username, + credentials.password + ) + ); + localStorage.setItem( + USER_DATA_LOCAL_STORAGE_ITEM, + JSON.stringify(userData.data) + ); + return Promise.resolve(); + } + return Promise.reject(); + }, + logout: () => { + localStorage.removeItem(CREDENTIALS_LOCAL_STORAGE_ITEM); + return Promise.resolve(); + }, + checkError: ({ status }: any) => { + if (status === 401 || status === 403) { + localStorage.removeItem(CREDENTIALS_LOCAL_STORAGE_ITEM); + return Promise.reject(); + } + return Promise.resolve(); + }, + checkAuth: () => { + return localStorage.getItem(CREDENTIALS_LOCAL_STORAGE_ITEM) + ? Promise.resolve() + : Promise.reject(); + }, + getPermissions: () => Promise.reject("Unknown method"), + getIdentity: () => { + const str = localStorage.getItem(USER_DATA_LOCAL_STORAGE_ITEM); + const userData: LoginMutateResult = JSON.parse(str || ""); + + return Promise.resolve({ + id: userData.login.username, + fullName: userData.login.username, + avatar: undefined, + }); + }, +}; + +function createBasicAuthorizationHeader( + username: string, + password: string +): string { + return `Basic ${btoa(`${username}:${password}`)}`; +} diff --git a/apps/deployment-orchestrator-admin/src/auth-provider/ra-auth-jwt.ts b/apps/deployment-orchestrator-admin/src/auth-provider/ra-auth-jwt.ts new file mode 100644 index 000000000..c8bcafc03 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/auth-provider/ra-auth-jwt.ts @@ -0,0 +1,72 @@ +import { gql } from "@apollo/client/core"; +import { AuthProvider } from "react-admin"; +import { + CREDENTIALS_LOCAL_STORAGE_ITEM, + USER_DATA_LOCAL_STORAGE_ITEM, +} from "../constants"; +import { Credentials, LoginMutateResult } from "../types"; +import { apolloClient } from "../data-provider/graphqlDataProvider"; + +const LOGIN = gql` + mutation login($username: String!, $password: String!) { + login(credentials: { username: $username, password: $password }) { + username + accessToken + } + } +`; + +export const jwtAuthProvider: AuthProvider = { + login: async (credentials: Credentials) => { + const userData = await apolloClient.mutate({ + mutation: LOGIN, + variables: { + ...credentials, + }, + }); + + if (userData && userData.data?.login.username) { + localStorage.setItem( + CREDENTIALS_LOCAL_STORAGE_ITEM, + createBearerAuthorizationHeader(userData.data.login?.accessToken) + ); + localStorage.setItem( + USER_DATA_LOCAL_STORAGE_ITEM, + JSON.stringify(userData.data) + ); + return Promise.resolve(); + } + return Promise.reject(); + }, + logout: () => { + localStorage.removeItem(CREDENTIALS_LOCAL_STORAGE_ITEM); + return Promise.resolve(); + }, + checkError: ({ status }: any) => { + if (status === 401 || status === 403) { + localStorage.removeItem(CREDENTIALS_LOCAL_STORAGE_ITEM); + return Promise.reject(); + } + return Promise.resolve(); + }, + checkAuth: () => { + return localStorage.getItem(CREDENTIALS_LOCAL_STORAGE_ITEM) + ? Promise.resolve() + : Promise.reject(); + }, + getPermissions: () => Promise.reject("Unknown method"), + getIdentity: () => { + const str = localStorage.getItem(USER_DATA_LOCAL_STORAGE_ITEM); + const userData: LoginMutateResult = JSON.parse(str || ""); + + return Promise.resolve({ + id: userData.login.username, + fullName: userData.login.username, + avatar: undefined, + }); + }, +}; + +export function createBearerAuthorizationHeader(accessToken: string) { + return `Bearer ${accessToken}`; +} diff --git a/apps/deployment-orchestrator-admin/src/auth.ts b/apps/deployment-orchestrator-admin/src/auth.ts new file mode 100644 index 000000000..498b026bd --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/auth.ts @@ -0,0 +1,34 @@ +import { EventEmitter } from "events"; +import { CREDENTIALS_LOCAL_STORAGE_ITEM } from "./constants"; +import { Credentials } from "./types"; + +const eventEmitter = new EventEmitter(); + +export function isAuthenticated(): boolean { + return Boolean(getCredentials()); +} + +export function listen(listener: (authenticated: boolean) => void): void { + eventEmitter.on("change", () => { + listener(isAuthenticated()); + }); +} + +export function setCredentials(credentials: Credentials) { + localStorage.setItem( + CREDENTIALS_LOCAL_STORAGE_ITEM, + JSON.stringify(credentials) + ); +} + +export function getCredentials(): Credentials | null { + const raw = localStorage.getItem(CREDENTIALS_LOCAL_STORAGE_ITEM); + if (raw === null) { + return null; + } + return JSON.parse(raw); +} + +export function removeCredentials(): void { + localStorage.removeItem(CREDENTIALS_LOCAL_STORAGE_ITEM); +} diff --git a/apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionCreate.tsx b/apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionCreate.tsx new file mode 100644 index 000000000..48f5dd2e8 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionCreate.tsx @@ -0,0 +1,31 @@ +import * as React from "react"; +import { + Create, + SimpleForm, + CreateProps, + TextInput, + ReferenceInput, + SelectInput, +} from "react-admin"; +import { UserProfileTitle } from "../userProfile/UserProfileTitle"; + +export const CloudConnectionCreate = ( + props: CreateProps +): React.ReactElement => { + return ( + + + + + + + + + + + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionEdit.tsx b/apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionEdit.tsx new file mode 100644 index 000000000..875a2973b --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionEdit.tsx @@ -0,0 +1,29 @@ +import * as React from "react"; +import { + Edit, + SimpleForm, + EditProps, + TextInput, + ReferenceInput, + SelectInput, +} from "react-admin"; +import { UserProfileTitle } from "../userProfile/UserProfileTitle"; + +export const CloudConnectionEdit = (props: EditProps): React.ReactElement => { + return ( + + + + + + + + + + + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionList.tsx b/apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionList.tsx new file mode 100644 index 000000000..b2b16385c --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionList.tsx @@ -0,0 +1,38 @@ +import * as React from "react"; +import { + List, + Datagrid, + ListProps, + TextField, + DateField, + ReferenceField, +} from "react-admin"; +import Pagination from "../Components/Pagination"; +import { USERPROFILE_TITLE_FIELD } from "../userProfile/UserProfileTitle"; + +export const CloudConnectionList = (props: ListProps): React.ReactElement => { + return ( + } + > + + + + + + + + + + {" "} + + + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionShow.tsx b/apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionShow.tsx new file mode 100644 index 000000000..04fd873d3 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionShow.tsx @@ -0,0 +1,32 @@ +import * as React from "react"; +import { + Show, + SimpleShowLayout, + ShowProps, + TextField, + DateField, + ReferenceField, +} from "react-admin"; +import { USERPROFILE_TITLE_FIELD } from "../userProfile/UserProfileTitle"; + +export const CloudConnectionShow = (props: ShowProps): React.ReactElement => { + return ( + + + + + + + + + + + + + + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionTitle.ts b/apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionTitle.ts new file mode 100644 index 000000000..fecf7c904 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/cloudConnection/CloudConnectionTitle.ts @@ -0,0 +1,7 @@ +import { CloudConnection as TCloudConnection } from "../api/cloudConnection/CloudConnection"; + +export const CLOUDCONNECTION_TITLE_FIELD = "accessKey"; + +export const CloudConnectionTitle = (record: TCloudConnection): string => { + return record.accessKey?.toString() || String(record.id); +}; diff --git a/apps/deployment-orchestrator-admin/src/constants.ts b/apps/deployment-orchestrator-admin/src/constants.ts new file mode 100644 index 000000000..4b3ca4bb6 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/constants.ts @@ -0,0 +1,2 @@ +export const CREDENTIALS_LOCAL_STORAGE_ITEM = "credentials"; +export const USER_DATA_LOCAL_STORAGE_ITEM = "userData"; diff --git a/apps/deployment-orchestrator-admin/src/data-provider/graphqlDataProvider.ts b/apps/deployment-orchestrator-admin/src/data-provider/graphqlDataProvider.ts new file mode 100644 index 000000000..2deee266c --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/data-provider/graphqlDataProvider.ts @@ -0,0 +1,28 @@ +import buildGraphQLProvider from "ra-data-graphql-amplication"; +import { ApolloClient, InMemoryCache, createHttpLink } from "@apollo/client"; +import { setContext } from "@apollo/client/link/context"; +import { CREDENTIALS_LOCAL_STORAGE_ITEM } from "../constants"; + +const httpLink = createHttpLink({ + uri: `${import.meta.env.VITE_REACT_APP_SERVER_URL}/graphql`, +}); + +// eslint-disable-next-line @typescript-eslint/naming-convention +const authLink = setContext((_, { headers }) => { + const token = localStorage.getItem(CREDENTIALS_LOCAL_STORAGE_ITEM); + return { + headers: { + ...headers, + authorization: token ? token : "", + }, + }; +}); + +export const apolloClient = new ApolloClient({ + cache: new InMemoryCache(), + link: authLink.concat(httpLink), +}); + +export default buildGraphQLProvider({ + client: apolloClient, +}); diff --git a/apps/deployment-orchestrator-admin/src/deployment/DeploymentCreate.tsx b/apps/deployment-orchestrator-admin/src/deployment/DeploymentCreate.tsx new file mode 100644 index 000000000..89273c3d4 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/deployment/DeploymentCreate.tsx @@ -0,0 +1,52 @@ +import * as React from "react"; + +import { + Create, + SimpleForm, + CreateProps, + DateTimeInput, + TextInput, + ReferenceArrayInput, + SelectArrayInput, + SelectInput, + ReferenceInput, +} from "react-admin"; + +import { PromptHandlerTitle } from "../promptHandler/PromptHandlerTitle"; +import { UserProfileTitle } from "../userProfile/UserProfileTitle"; + +export const DeploymentCreate = (props: CreateProps): React.ReactElement => { + return ( + + + + + + value && value.map((v: any) => ({ id: v }))} + format={(value: any) => value && value.map((v: any) => v.id)} + /> + + + +
+ + + + + + + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/deployment/DeploymentEdit.tsx b/apps/deployment-orchestrator-admin/src/deployment/DeploymentEdit.tsx new file mode 100644 index 000000000..9bb2f6c5a --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/deployment/DeploymentEdit.tsx @@ -0,0 +1,52 @@ +import * as React from "react"; + +import { + Edit, + SimpleForm, + EditProps, + DateTimeInput, + TextInput, + ReferenceArrayInput, + SelectArrayInput, + SelectInput, + ReferenceInput, +} from "react-admin"; + +import { PromptHandlerTitle } from "../promptHandler/PromptHandlerTitle"; +import { UserProfileTitle } from "../userProfile/UserProfileTitle"; + +export const DeploymentEdit = (props: EditProps): React.ReactElement => { + return ( + + + + + + value && value.map((v: any) => ({ id: v }))} + format={(value: any) => value && value.map((v: any) => v.id)} + /> + + + +
+ + + + + + + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/deployment/DeploymentList.tsx b/apps/deployment-orchestrator-admin/src/deployment/DeploymentList.tsx new file mode 100644 index 000000000..f1a40dc55 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/deployment/DeploymentList.tsx @@ -0,0 +1,41 @@ +import * as React from "react"; +import { + List, + Datagrid, + ListProps, + TextField, + DateField, + ReferenceField, +} from "react-admin"; +import Pagination from "../Components/Pagination"; +import { USERPROFILE_TITLE_FIELD } from "../userProfile/UserProfileTitle"; + +export const DeploymentList = (props: ListProps): React.ReactElement => { + return ( + } + > + + + + + + + + + + + + + {" "} + + + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/deployment/DeploymentShow.tsx b/apps/deployment-orchestrator-admin/src/deployment/DeploymentShow.tsx new file mode 100644 index 000000000..ad14041e5 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/deployment/DeploymentShow.tsx @@ -0,0 +1,62 @@ +import * as React from "react"; + +import { + Show, + SimpleShowLayout, + ShowProps, + TextField, + DateField, + ReferenceField, + ReferenceManyField, + Datagrid, +} from "react-admin"; + +import { DEPLOYMENT_TITLE_FIELD } from "./DeploymentTitle"; +import { USERPROFILE_TITLE_FIELD } from "../userProfile/UserProfileTitle"; + +export const DeploymentShow = (props: ShowProps): React.ReactElement => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/deployment/DeploymentTitle.ts b/apps/deployment-orchestrator-admin/src/deployment/DeploymentTitle.ts new file mode 100644 index 000000000..86baecefb --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/deployment/DeploymentTitle.ts @@ -0,0 +1,7 @@ +import { Deployment as TDeployment } from "../api/deployment/Deployment"; + +export const DEPLOYMENT_TITLE_FIELD = "environment"; + +export const DeploymentTitle = (record: TDeployment): string => { + return record.environment?.toString() || String(record.id); +}; diff --git a/apps/deployment-orchestrator-admin/src/index.css b/apps/deployment-orchestrator-admin/src/index.css new file mode 100644 index 000000000..868684807 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/index.css @@ -0,0 +1,26 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", + "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +#root { + height: 100vh; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", + monospace; +} + +.amp-breadcrumbs { + padding: var(--default-spacing); +} + +.entity-id { + color: var(--primary); + text-decoration: underline; +} diff --git a/apps/deployment-orchestrator-admin/src/index.tsx b/apps/deployment-orchestrator-admin/src/index.tsx new file mode 100644 index 000000000..7467839cc --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/index.tsx @@ -0,0 +1,10 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import "./index.css"; +import App from "./App"; + +ReactDOM.createRoot(document.getElementById("root")!).render( + + + +); diff --git a/apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationCreate.tsx b/apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationCreate.tsx new file mode 100644 index 000000000..ab8e27408 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationCreate.tsx @@ -0,0 +1,32 @@ +import * as React from "react"; +import { + Create, + SimpleForm, + CreateProps, + TextInput, + ReferenceInput, + SelectInput, +} from "react-admin"; +import { PromptHandlerTitle } from "../promptHandler/PromptHandlerTitle"; + +export const LlmIntegrationCreate = ( + props: CreateProps +): React.ReactElement => { + return ( + + + + + + + + + + + + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationEdit.tsx b/apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationEdit.tsx new file mode 100644 index 000000000..969629fcf --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationEdit.tsx @@ -0,0 +1,30 @@ +import * as React from "react"; +import { + Edit, + SimpleForm, + EditProps, + TextInput, + ReferenceInput, + SelectInput, +} from "react-admin"; +import { PromptHandlerTitle } from "../promptHandler/PromptHandlerTitle"; + +export const LlmIntegrationEdit = (props: EditProps): React.ReactElement => { + return ( + + + + + + + + + + + + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationList.tsx b/apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationList.tsx new file mode 100644 index 000000000..eca7597ea --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationList.tsx @@ -0,0 +1,39 @@ +import * as React from "react"; +import { + List, + Datagrid, + ListProps, + TextField, + DateField, + ReferenceField, +} from "react-admin"; +import Pagination from "../Components/Pagination"; +import { PROMPTHANDLER_TITLE_FIELD } from "../promptHandler/PromptHandlerTitle"; + +export const LlmIntegrationList = (props: ListProps): React.ReactElement => { + return ( + } + > + + + + + + + + + + + {" "} + + + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationShow.tsx b/apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationShow.tsx new file mode 100644 index 000000000..9784a8a4a --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationShow.tsx @@ -0,0 +1,33 @@ +import * as React from "react"; +import { + Show, + SimpleShowLayout, + ShowProps, + TextField, + DateField, + ReferenceField, +} from "react-admin"; +import { PROMPTHANDLER_TITLE_FIELD } from "../promptHandler/PromptHandlerTitle"; + +export const LlmIntegrationShow = (props: ShowProps): React.ReactElement => { + return ( + + + + + + + + + + + + + + + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationTitle.ts b/apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationTitle.ts new file mode 100644 index 000000000..478c17582 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/llmIntegration/LlmIntegrationTitle.ts @@ -0,0 +1,7 @@ +import { LlmIntegration as TLlmIntegration } from "../api/llmIntegration/LlmIntegration"; + +export const LLMINTEGRATION_TITLE_FIELD = "apiKeyName"; + +export const LlmIntegrationTitle = (record: TLlmIntegration): string => { + return record.apiKeyName?.toString() || String(record.id); +}; diff --git a/apps/deployment-orchestrator-admin/src/login.scss b/apps/deployment-orchestrator-admin/src/login.scss new file mode 100644 index 000000000..667d8d2ba --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/login.scss @@ -0,0 +1,119 @@ +:root { + --surface: #15192c; /*dark: black100 */ + --white: #15192c; /*dark: black100 */ + + --black100: #ffffff; /*dark: white */ + --black90: #b7bac7; /*dark: black10 */ + --black80: #a3a8b8; /*dark: black20 */ + --black60: #80869d; /*dark: black30 */ + --black40: #686f8c; /*dark: black40 */ + --black30: #515873; /*dark: black50 */ + --black20: #444b66; /*dark: black60 */ + --black10: #373d57; /*dark: black70 */ + --black5: #2c3249; /*dark: black80 */ + --black2: #22273c; /*dark: black90 */ + + --primary: #7950ed; +} + +.login-page { + height: 100vh; + width: 100%; + background-color: var(--surface); + color: var(--black100); + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + + &__wrapper { + display: flex; + align-items: stretch; + justify-content: center; + flex-direction: row; + } + + &__box { + text-align: center; + width: 340px; + background-color: var(--black2); + border-radius: var(--small-border-radius); + margin: 1rem; + padding: 1rem; + border: 1px solid var(--black10); + display: flex; + flex-direction: column; + align-items: center; + justify-content: stretch; + + h2 { + font-size: 18px; + } + img { + width: 48px; + } + + &__message { + color: var(--black80); + font-size: 14px; + line-height: 22px; + } + + button, + .MuiButton-contained { + box-sizing: border-box; + background-color: var(--primary); + width: 300px; + margin-top: 0.5rem; + margin-bottom: 1rem; + margin-top: auto; + &:hover, + &:active, + &:focus { + background-color: var(--primary); + } + } + } + + form { + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + margin-top: 2rem; + + label { + span { + display: block; + text-align: left; + font-size: 12px; + color: var(--black60); + } + } + + input { + box-sizing: border-box; + background-color: var(--white); + border: 1px solid var(--black10); + padding: 0.5rem; + margin-bottom: 1rem; + outline: none; + border-radius: var(--small-border-radius); + width: 300px; + color: var(--black100); + &:hover, + &:active, + &:focus { + border: 1px solid var(--black100); + } + } + } + + &__read-more { + color: var(--black80); + a { + color: var(--black100); + text-decoration: none; + } + } +} diff --git a/apps/deployment-orchestrator-admin/src/pages/Dashboard.tsx b/apps/deployment-orchestrator-admin/src/pages/Dashboard.tsx new file mode 100644 index 000000000..29776bc29 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/pages/Dashboard.tsx @@ -0,0 +1,12 @@ +import * as React from "react"; +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import { Title } from "react-admin"; +const Dashboard = () => ( + + + <CardContent>Welcome</CardContent> + </Card> +); + +export default Dashboard; diff --git a/apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerCreate.tsx b/apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerCreate.tsx new file mode 100644 index 000000000..1e7fe2644 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerCreate.tsx @@ -0,0 +1,45 @@ +import * as React from "react"; + +import { + Create, + SimpleForm, + CreateProps, + ReferenceInput, + SelectInput, + TextInput, + ReferenceArrayInput, + SelectArrayInput, +} from "react-admin"; + +import { DeploymentTitle } from "../deployment/DeploymentTitle"; +import { LlmIntegrationTitle } from "../llmIntegration/LlmIntegrationTitle"; + +export const PromptHandlerCreate = (props: CreateProps): React.ReactElement => { + return ( + <Create {...props}> + <SimpleForm> + <ReferenceInput + source="deployment.id" + reference="Deployment" + label="Deployment" + > + <SelectInput optionText={DeploymentTitle} /> + </ReferenceInput> + <TextInput label="detectedOs" source="detectedOs" /> + <TextInput label="inputPrompt" multiline source="inputPrompt" /> + <ReferenceArrayInput + source="llmIntegrations" + reference="LlmIntegration" + > + <SelectArrayInput + optionText={LlmIntegrationTitle} + parse={(value: any) => value && value.map((v: any) => ({ id: v }))} + format={(value: any) => value && value.map((v: any) => v.id)} + /> + </ReferenceArrayInput> + <div /> + <div /> + </SimpleForm> + </Create> + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerEdit.tsx b/apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerEdit.tsx new file mode 100644 index 000000000..8029f39c3 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerEdit.tsx @@ -0,0 +1,45 @@ +import * as React from "react"; + +import { + Edit, + SimpleForm, + EditProps, + ReferenceInput, + SelectInput, + TextInput, + ReferenceArrayInput, + SelectArrayInput, +} from "react-admin"; + +import { DeploymentTitle } from "../deployment/DeploymentTitle"; +import { LlmIntegrationTitle } from "../llmIntegration/LlmIntegrationTitle"; + +export const PromptHandlerEdit = (props: EditProps): React.ReactElement => { + return ( + <Edit {...props}> + <SimpleForm> + <ReferenceInput + source="deployment.id" + reference="Deployment" + label="Deployment" + > + <SelectInput optionText={DeploymentTitle} /> + </ReferenceInput> + <TextInput label="detectedOs" source="detectedOs" /> + <TextInput label="inputPrompt" multiline source="inputPrompt" /> + <ReferenceArrayInput + source="llmIntegrations" + reference="LlmIntegration" + > + <SelectArrayInput + optionText={LlmIntegrationTitle} + parse={(value: any) => value && value.map((v: any) => ({ id: v }))} + format={(value: any) => value && value.map((v: any) => v.id)} + /> + </ReferenceArrayInput> + <div /> + <div /> + </SimpleForm> + </Edit> + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerList.tsx b/apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerList.tsx new file mode 100644 index 000000000..36b5a0dfc --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerList.tsx @@ -0,0 +1,39 @@ +import * as React from "react"; +import { + List, + Datagrid, + ListProps, + DateField, + ReferenceField, + TextField, +} from "react-admin"; +import Pagination from "../Components/Pagination"; +import { DEPLOYMENT_TITLE_FIELD } from "../deployment/DeploymentTitle"; + +export const PromptHandlerList = (props: ListProps): React.ReactElement => { + return ( + <List + {...props} + title={"PromptHandlers"} + perPage={50} + pagination={<Pagination />} + > + <Datagrid rowClick="show" bulkActionButtons={false}> + <DateField source="createdAt" label="Created At" /> + <ReferenceField + label="Deployment" + source="deployment.id" + reference="Deployment" + > + <TextField source={DEPLOYMENT_TITLE_FIELD} /> + </ReferenceField> + <TextField label="detectedOs" source="detectedOs" /> + <TextField label="ID" source="id" /> + <TextField label="inputPrompt" source="inputPrompt" /> + <TextField label="parsedInstructions" source="parsedInstructions" /> + <TextField label="resourcesRequested" source="resourcesRequested" /> + <DateField source="updatedAt" label="Updated At" />{" "} + </Datagrid> + </List> + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerShow.tsx b/apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerShow.tsx new file mode 100644 index 000000000..36b6bdf3d --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerShow.tsx @@ -0,0 +1,60 @@ +import * as React from "react"; + +import { + Show, + SimpleShowLayout, + ShowProps, + DateField, + ReferenceField, + TextField, + ReferenceManyField, + Datagrid, +} from "react-admin"; + +import { PROMPTHANDLER_TITLE_FIELD } from "./PromptHandlerTitle"; +import { DEPLOYMENT_TITLE_FIELD } from "../deployment/DeploymentTitle"; + +export const PromptHandlerShow = (props: ShowProps): React.ReactElement => { + return ( + <Show {...props}> + <SimpleShowLayout> + <DateField source="createdAt" label="Created At" /> + <ReferenceField + label="Deployment" + source="deployment.id" + reference="Deployment" + > + <TextField source={DEPLOYMENT_TITLE_FIELD} /> + </ReferenceField> + <TextField label="detectedOs" source="detectedOs" /> + <TextField label="ID" source="id" /> + <TextField label="inputPrompt" source="inputPrompt" /> + <TextField label="parsedInstructions" source="parsedInstructions" /> + <TextField label="resourcesRequested" source="resourcesRequested" /> + <DateField source="updatedAt" label="Updated At" /> + <ReferenceManyField + reference="LlmIntegration" + target="promptHandlerId" + label="LLMIntegrations" + > + <Datagrid rowClick="show" bulkActionButtons={false}> + <TextField label="apiEndpoint" source="apiEndpoint" /> + <TextField label="apiKeyName" source="apiKeyName" /> + <DateField source="createdAt" label="Created At" /> + <TextField label="ID" source="id" /> + <TextField label="modelUsed" source="modelUsed" /> + <ReferenceField + label="PromptHandler" + source="prompthandler.id" + reference="PromptHandler" + > + <TextField source={PROMPTHANDLER_TITLE_FIELD} /> + </ReferenceField> + <TextField label="provider" source="provider" /> + <DateField source="updatedAt" label="Updated At" /> + </Datagrid> + </ReferenceManyField> + </SimpleShowLayout> + </Show> + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerTitle.ts b/apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerTitle.ts new file mode 100644 index 000000000..39b0e1b36 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/promptHandler/PromptHandlerTitle.ts @@ -0,0 +1,7 @@ +import { PromptHandler as TPromptHandler } from "../api/promptHandler/PromptHandler"; + +export const PROMPTHANDLER_TITLE_FIELD = "detectedOs"; + +export const PromptHandlerTitle = (record: TPromptHandler): string => { + return record.detectedOs?.toString() || String(record.id); +}; diff --git a/apps/deployment-orchestrator-admin/src/reportWebVitals.ts b/apps/deployment-orchestrator-admin/src/reportWebVitals.ts new file mode 100644 index 000000000..821a6cdee --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/reportWebVitals.ts @@ -0,0 +1,17 @@ +import { ReportHandler } from "web-vitals"; + +const reportWebVitals = (onPerfEntry?: ReportHandler): void => { + if (onPerfEntry && onPerfEntry instanceof Function) { + void import("web-vitals").then( + ({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + getCLS(onPerfEntry); + getFID(onPerfEntry); + getFCP(onPerfEntry); + getLCP(onPerfEntry); + getTTFB(onPerfEntry); + } + ); + } +}; + +export default reportWebVitals; diff --git a/apps/deployment-orchestrator-admin/src/setupTests.ts b/apps/deployment-orchestrator-admin/src/setupTests.ts new file mode 100644 index 000000000..1dd407a63 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/setupTests.ts @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import "@testing-library/jest-dom"; diff --git a/apps/deployment-orchestrator-admin/src/theme/theme.ts b/apps/deployment-orchestrator-admin/src/theme/theme.ts new file mode 100644 index 000000000..bcfca0e62 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/theme/theme.ts @@ -0,0 +1,33 @@ +import { defaultTheme } from "react-admin"; +import { createTheme, ThemeOptions } from "@mui/material/styles"; +import { merge } from "lodash"; +import createPalette from "@mui/material/styles/createPalette"; + +const palette = createPalette( + merge({}, defaultTheme.palette, { + primary: { + main: "#20a4f3", + }, + secondary: { + main: "#7950ed", + }, + error: { + main: "#e93c51", + }, + warning: { + main: "#f6aa50", + }, + info: { + main: "#144bc1", + }, + success: { + main: "#31c587", + }, + }) +); + +const themeOptions: ThemeOptions = { + palette, +}; + +export const theme = createTheme(merge({}, defaultTheme, themeOptions)); diff --git a/apps/deployment-orchestrator-admin/src/types.ts b/apps/deployment-orchestrator-admin/src/types.ts new file mode 100644 index 000000000..45a457df6 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/types.ts @@ -0,0 +1,13 @@ +import { JsonValue } from "type-fest"; + +export type Credentials = { + username: string; + password: string; +}; +export type LoginMutateResult = { + login: { + username: string; + accessToken: string; + }; +}; +export type InputJsonValue = Omit<JsonValue, "null">; diff --git a/apps/deployment-orchestrator-admin/src/user/EnumRoles.ts b/apps/deployment-orchestrator-admin/src/user/EnumRoles.ts new file mode 100644 index 000000000..3df7048d3 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/user/EnumRoles.ts @@ -0,0 +1,3 @@ +export enum EnumRoles { + User = "user", +} diff --git a/apps/deployment-orchestrator-admin/src/user/RolesOptions.ts b/apps/deployment-orchestrator-admin/src/user/RolesOptions.ts new file mode 100644 index 000000000..5e30fe9ab --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/user/RolesOptions.ts @@ -0,0 +1,11 @@ +import { ROLES } from "./roles"; + +declare interface Role { + name: string; + displayName: string; +} + +export const ROLES_OPTIONS = ROLES.map((role: Role) => ({ + value: role.name, + label: role.displayName, +})); diff --git a/apps/deployment-orchestrator-admin/src/user/roles.ts b/apps/deployment-orchestrator-admin/src/user/roles.ts new file mode 100644 index 000000000..732870a14 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/user/roles.ts @@ -0,0 +1,6 @@ +export const ROLES = [ + { + name: "user", + displayName: "User", + }, +]; diff --git a/apps/deployment-orchestrator-admin/src/userProfile/UserProfileCreate.tsx b/apps/deployment-orchestrator-admin/src/userProfile/UserProfileCreate.tsx new file mode 100644 index 000000000..bb330f49a --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/userProfile/UserProfileCreate.tsx @@ -0,0 +1,43 @@ +import * as React from "react"; + +import { + Create, + SimpleForm, + CreateProps, + ReferenceArrayInput, + SelectArrayInput, + TextInput, +} from "react-admin"; + +import { CloudConnectionTitle } from "../cloudConnection/CloudConnectionTitle"; +import { DeploymentTitle } from "../deployment/DeploymentTitle"; + +export const UserProfileCreate = (props: CreateProps): React.ReactElement => { + return ( + <Create {...props}> + <SimpleForm> + <ReferenceArrayInput + source="cloudConnections" + reference="CloudConnection" + > + <SelectArrayInput + optionText={CloudConnectionTitle} + parse={(value: any) => value && value.map((v: any) => ({ id: v }))} + format={(value: any) => value && value.map((v: any) => v.id)} + /> + </ReferenceArrayInput> + <ReferenceArrayInput source="deployments" reference="Deployment"> + <SelectArrayInput + optionText={DeploymentTitle} + parse={(value: any) => value && value.map((v: any) => ({ id: v }))} + format={(value: any) => value && value.map((v: any) => v.id)} + /> + </ReferenceArrayInput> + <TextInput label="email" source="email" type="email" /> + <TextInput label="name" source="name" /> + <TextInput label="role" source="role" /> + <TextInput label="sshKey" multiline source="sshKey" /> + </SimpleForm> + </Create> + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/userProfile/UserProfileEdit.tsx b/apps/deployment-orchestrator-admin/src/userProfile/UserProfileEdit.tsx new file mode 100644 index 000000000..1a898adbd --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/userProfile/UserProfileEdit.tsx @@ -0,0 +1,43 @@ +import * as React from "react"; + +import { + Edit, + SimpleForm, + EditProps, + ReferenceArrayInput, + SelectArrayInput, + TextInput, +} from "react-admin"; + +import { CloudConnectionTitle } from "../cloudConnection/CloudConnectionTitle"; +import { DeploymentTitle } from "../deployment/DeploymentTitle"; + +export const UserProfileEdit = (props: EditProps): React.ReactElement => { + return ( + <Edit {...props}> + <SimpleForm> + <ReferenceArrayInput + source="cloudConnections" + reference="CloudConnection" + > + <SelectArrayInput + optionText={CloudConnectionTitle} + parse={(value: any) => value && value.map((v: any) => ({ id: v }))} + format={(value: any) => value && value.map((v: any) => v.id)} + /> + </ReferenceArrayInput> + <ReferenceArrayInput source="deployments" reference="Deployment"> + <SelectArrayInput + optionText={DeploymentTitle} + parse={(value: any) => value && value.map((v: any) => ({ id: v }))} + format={(value: any) => value && value.map((v: any) => v.id)} + /> + </ReferenceArrayInput> + <TextInput label="email" source="email" type="email" /> + <TextInput label="name" source="name" /> + <TextInput label="role" source="role" /> + <TextInput label="sshKey" multiline source="sshKey" /> + </SimpleForm> + </Edit> + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/userProfile/UserProfileList.tsx b/apps/deployment-orchestrator-admin/src/userProfile/UserProfileList.tsx new file mode 100644 index 000000000..dbc723b23 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/userProfile/UserProfileList.tsx @@ -0,0 +1,24 @@ +import * as React from "react"; +import { List, Datagrid, ListProps, DateField, TextField } from "react-admin"; +import Pagination from "../Components/Pagination"; + +export const UserProfileList = (props: ListProps): React.ReactElement => { + return ( + <List + {...props} + title={"UserProfiles"} + perPage={50} + pagination={<Pagination />} + > + <Datagrid rowClick="show" bulkActionButtons={false}> + <DateField source="createdAt" label="Created At" /> + <TextField label="email" source="email" /> + <TextField label="ID" source="id" /> + <TextField label="name" source="name" /> + <TextField label="role" source="role" /> + <TextField label="sshKey" source="sshKey" /> + <DateField source="updatedAt" label="Updated At" />{" "} + </Datagrid> + </List> + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/userProfile/UserProfileShow.tsx b/apps/deployment-orchestrator-admin/src/userProfile/UserProfileShow.tsx new file mode 100644 index 000000000..ee1b6a68c --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/userProfile/UserProfileShow.tsx @@ -0,0 +1,75 @@ +import * as React from "react"; + +import { + Show, + SimpleShowLayout, + ShowProps, + DateField, + TextField, + ReferenceManyField, + Datagrid, + ReferenceField, +} from "react-admin"; + +import { USERPROFILE_TITLE_FIELD } from "./UserProfileTitle"; + +export const UserProfileShow = (props: ShowProps): React.ReactElement => { + return ( + <Show {...props}> + <SimpleShowLayout> + <DateField source="createdAt" label="Created At" /> + <TextField label="email" source="email" /> + <TextField label="ID" source="id" /> + <TextField label="name" source="name" /> + <TextField label="role" source="role" /> + <TextField label="sshKey" source="sshKey" /> + <DateField source="updatedAt" label="Updated At" /> + <ReferenceManyField + reference="CloudConnection" + target="userProfileId" + label="CloudConnections" + > + <Datagrid rowClick="show" bulkActionButtons={false}> + <TextField label="accessKey" source="accessKey" /> + <DateField source="createdAt" label="Created At" /> + <TextField label="ID" source="id" /> + <TextField label="provider" source="provider" /> + <TextField label="region" source="region" /> + <DateField source="updatedAt" label="Updated At" /> + <ReferenceField + label="UserProfile" + source="userprofile.id" + reference="UserProfile" + > + <TextField source={USERPROFILE_TITLE_FIELD} /> + </ReferenceField> + </Datagrid> + </ReferenceManyField> + <ReferenceManyField + reference="Deployment" + target="userProfileId" + label="Deployments" + > + <Datagrid rowClick="show" bulkActionButtons={false}> + <TextField label="autoTerminateAt" source="autoTerminateAt" /> + <DateField source="createdAt" label="Created At" /> + <TextField label="environment" source="environment" /> + <TextField label="ID" source="id" /> + <TextField label="region" source="region" /> + <TextField label="requestPrompt" source="requestPrompt" /> + <TextField label="resolvedConfig" source="resolvedConfig" /> + <TextField label="status" source="status" /> + <DateField source="updatedAt" label="Updated At" /> + <ReferenceField + label="UserProfile" + source="userprofile.id" + reference="UserProfile" + > + <TextField source={USERPROFILE_TITLE_FIELD} /> + </ReferenceField> + </Datagrid> + </ReferenceManyField> + </SimpleShowLayout> + </Show> + ); +}; diff --git a/apps/deployment-orchestrator-admin/src/userProfile/UserProfileTitle.ts b/apps/deployment-orchestrator-admin/src/userProfile/UserProfileTitle.ts new file mode 100644 index 000000000..1007e37a6 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/userProfile/UserProfileTitle.ts @@ -0,0 +1,7 @@ +import { UserProfile as TUserProfile } from "../api/userProfile/UserProfile"; + +export const USERPROFILE_TITLE_FIELD = "name"; + +export const UserProfileTitle = (record: TUserProfile): string => { + return record.name?.toString() || String(record.id); +}; diff --git a/apps/deployment-orchestrator-admin/src/util/BooleanFilter.ts b/apps/deployment-orchestrator-admin/src/util/BooleanFilter.ts new file mode 100644 index 000000000..a142d58c9 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/util/BooleanFilter.ts @@ -0,0 +1,4 @@ +export class BooleanFilter { + equals?: boolean; + not?: boolean; +} diff --git a/apps/deployment-orchestrator-admin/src/util/BooleanNullableFilter.ts b/apps/deployment-orchestrator-admin/src/util/BooleanNullableFilter.ts new file mode 100644 index 000000000..b94aefce8 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/util/BooleanNullableFilter.ts @@ -0,0 +1,4 @@ +export class BooleanNullableFilter { + equals?: boolean | null; + not?: boolean | null; +} diff --git a/apps/deployment-orchestrator-admin/src/util/DateTimeFilter.ts b/apps/deployment-orchestrator-admin/src/util/DateTimeFilter.ts new file mode 100644 index 000000000..cd8d21396 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/util/DateTimeFilter.ts @@ -0,0 +1,10 @@ +export class DateTimeFilter { + equals?: Date; + not?: Date; + in?: Date[]; + notIn?: Date[]; + lt?: Date; + lte?: Date; + gt?: Date; + gte?: Date; +} diff --git a/apps/deployment-orchestrator-admin/src/util/DateTimeNullableFilter.ts b/apps/deployment-orchestrator-admin/src/util/DateTimeNullableFilter.ts new file mode 100644 index 000000000..2f9c7b3b7 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/util/DateTimeNullableFilter.ts @@ -0,0 +1,10 @@ +export class DateTimeNullableFilter { + equals?: Date | null; + in?: Date[] | null; + notIn?: Date[] | null; + lt?: Date; + lte?: Date; + gt?: Date; + gte?: Date; + not?: Date; +} diff --git a/apps/deployment-orchestrator-admin/src/util/FloatFilter.ts b/apps/deployment-orchestrator-admin/src/util/FloatFilter.ts new file mode 100644 index 000000000..62aeb1453 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/util/FloatFilter.ts @@ -0,0 +1,10 @@ +export class FloatFilter { + equals?: number; + in?: number[]; + notIn?: number[]; + lt?: number; + lte?: number; + gt?: number; + gte?: number; + not?: number; +} diff --git a/apps/deployment-orchestrator-admin/src/util/FloatNullableFilter.ts b/apps/deployment-orchestrator-admin/src/util/FloatNullableFilter.ts new file mode 100644 index 000000000..d7bb16356 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/util/FloatNullableFilter.ts @@ -0,0 +1,10 @@ +export class FloatNullableFilter { + equals?: number | null; + in?: number[] | null; + notIn?: number[] | null; + lt?: number; + lte?: number; + gt?: number; + gte?: number; + not?: number; +} diff --git a/apps/deployment-orchestrator-admin/src/util/IntFilter.ts b/apps/deployment-orchestrator-admin/src/util/IntFilter.ts new file mode 100644 index 000000000..3dc02212f --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/util/IntFilter.ts @@ -0,0 +1,10 @@ +export class IntFilter { + equals?: number; + in?: number[]; + notIn?: number[]; + lt?: number; + lte?: number; + gt?: number; + gte?: number; + not?: number; +} diff --git a/apps/deployment-orchestrator-admin/src/util/IntNullableFilter.ts b/apps/deployment-orchestrator-admin/src/util/IntNullableFilter.ts new file mode 100644 index 000000000..2107cae8f --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/util/IntNullableFilter.ts @@ -0,0 +1,10 @@ +export class IntNullableFilter { + equals?: number | null; + in?: number[] | null; + notIn?: number[] | null; + lt?: number; + lte?: number; + gt?: number; + gte?: number; + not?: number; +} diff --git a/apps/deployment-orchestrator-admin/src/util/JsonFilter.ts b/apps/deployment-orchestrator-admin/src/util/JsonFilter.ts new file mode 100644 index 000000000..cc447632f --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/util/JsonFilter.ts @@ -0,0 +1,5 @@ +import { InputJsonValue } from "../types"; +export class JsonFilter { + equals?: InputJsonValue; + not?: InputJsonValue; +} diff --git a/apps/deployment-orchestrator-admin/src/util/JsonNullableFilter.ts b/apps/deployment-orchestrator-admin/src/util/JsonNullableFilter.ts new file mode 100644 index 000000000..e6d150669 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/util/JsonNullableFilter.ts @@ -0,0 +1,5 @@ +import { JsonValue } from "type-fest"; +export class JsonNullableFilter { + equals?: JsonValue | null; + not?: JsonValue | null; +} diff --git a/apps/deployment-orchestrator-admin/src/util/MetaQueryPayload.ts b/apps/deployment-orchestrator-admin/src/util/MetaQueryPayload.ts new file mode 100644 index 000000000..bc3175b18 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/util/MetaQueryPayload.ts @@ -0,0 +1,3 @@ +export class MetaQueryPayload { + count!: number; +} diff --git a/apps/deployment-orchestrator-admin/src/util/QueryMode.ts b/apps/deployment-orchestrator-admin/src/util/QueryMode.ts new file mode 100644 index 000000000..8a2164e03 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/util/QueryMode.ts @@ -0,0 +1,4 @@ +export enum QueryMode { + Default = "default", + Insensitive = "insensitive", +} diff --git a/apps/deployment-orchestrator-admin/src/util/SortOrder.ts b/apps/deployment-orchestrator-admin/src/util/SortOrder.ts new file mode 100644 index 000000000..a5bcdb671 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/util/SortOrder.ts @@ -0,0 +1,4 @@ +export enum SortOrder { + Asc = "asc", + Desc = "desc", +} diff --git a/apps/deployment-orchestrator-admin/src/util/StringFilter.ts b/apps/deployment-orchestrator-admin/src/util/StringFilter.ts new file mode 100644 index 000000000..c2e26c5da --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/util/StringFilter.ts @@ -0,0 +1,16 @@ +import { QueryMode } from "./QueryMode"; + +export class StringFilter { + equals?: string; + in?: string[]; + notIn?: string[]; + lt?: string; + lte?: string; + gt?: string; + gte?: string; + contains?: string; + startsWith?: string; + endsWith?: string; + mode?: QueryMode; + not?: string; +} diff --git a/apps/deployment-orchestrator-admin/src/util/StringNullableFilter.ts b/apps/deployment-orchestrator-admin/src/util/StringNullableFilter.ts new file mode 100644 index 000000000..e1e37ec32 --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/util/StringNullableFilter.ts @@ -0,0 +1,15 @@ +import { QueryMode } from "./QueryMode"; +export class StringNullableFilter { + equals?: string | null; + in?: string[] | null; + notIn?: string[] | null; + lt?: string; + lte?: string; + gt?: string; + gte?: string; + contains?: string; + startsWith?: string; + endsWith?: string; + mode?: QueryMode; + not?: string; +} diff --git a/apps/deployment-orchestrator-admin/src/vite-env.d.ts b/apps/deployment-orchestrator-admin/src/vite-env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/apps/deployment-orchestrator-admin/src/vite-env.d.ts @@ -0,0 +1 @@ +/// <reference types="vite/client" /> diff --git a/apps/deployment-orchestrator-admin/tsconfig.json b/apps/deployment-orchestrator-admin/tsconfig.json new file mode 100644 index 000000000..31cc78008 --- /dev/null +++ b/apps/deployment-orchestrator-admin/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "strict": true + }, + "include": ["src"], + "exclude": ["./node_modules"] +} diff --git a/apps/deployment-orchestrator-admin/vite.config.ts b/apps/deployment-orchestrator-admin/vite.config.ts new file mode 100644 index 000000000..cf64d08cc --- /dev/null +++ b/apps/deployment-orchestrator-admin/vite.config.ts @@ -0,0 +1,14 @@ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], + define: { + "process.env": process.env, + }, + server: { + host: true, + }, + base: "./", +}); diff --git a/apps/deployment-orchestrator-server/.dockerignore b/apps/deployment-orchestrator-server/.dockerignore new file mode 100644 index 000000000..cb5c30bbc --- /dev/null +++ b/apps/deployment-orchestrator-server/.dockerignore @@ -0,0 +1,8 @@ +.dockerignore +docker-compose.yml +Dockerfile +dist/ +node_modules +.env +.gitignore +.prettierignore \ No newline at end of file diff --git a/apps/deployment-orchestrator-server/.env b/apps/deployment-orchestrator-server/.env new file mode 100644 index 000000000..dc319af41 --- /dev/null +++ b/apps/deployment-orchestrator-server/.env @@ -0,0 +1,8 @@ +BCRYPT_SALT=10 +COMPOSE_PROJECT_NAME=amp_cmb5pom8f0tfzjwsit3tf1azx +DB_NAME=my-db +DB_PASSWORD=admin +DB_PORT=5432 +DB_URL=postgres://admin:admin@localhost:5432/my-db +DB_USER=admin +PORT=3000 \ No newline at end of file diff --git a/apps/deployment-orchestrator-server/.gitignore b/apps/deployment-orchestrator-server/.gitignore new file mode 100644 index 000000000..08c9980f4 --- /dev/null +++ b/apps/deployment-orchestrator-server/.gitignore @@ -0,0 +1,5 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +/node_modules +/dist +.DS_Store diff --git a/apps/deployment-orchestrator-server/.prettierignore b/apps/deployment-orchestrator-server/.prettierignore new file mode 100644 index 000000000..e48f35599 --- /dev/null +++ b/apps/deployment-orchestrator-server/.prettierignore @@ -0,0 +1,5 @@ +node_modules/ +dist/ +prisma/migrations/ +package-lock.json +coverage/ \ No newline at end of file diff --git a/apps/deployment-orchestrator-server/Dockerfile b/apps/deployment-orchestrator-server/Dockerfile new file mode 100644 index 000000000..80dd8d375 --- /dev/null +++ b/apps/deployment-orchestrator-server/Dockerfile @@ -0,0 +1,68 @@ +# multi-stage: base (build) +FROM node:18.13.0 AS base + +# create directory where the application will be built +WORKDIR /app + +# copy over the dependency manifests, both the package.json +# and the package-lock.json are copied over +COPY package*.json ./ + +# installs packages and their dependencies +RUN npm install + +# copy over the prisma schema +COPY prisma/schema.prisma ./prisma/ + +# generate the prisma client based on the schema +RUN npm run prisma:generate + +# copy over the code base +COPY . . + +# create the bundle of the application +RUN npm run build + +# multi-stage: production (runtime) +FROM node:18.13.0-slim AS production + +# create arguments of builds time variables +ARG user=amplication +ARG group=${user} +ARG uid=1001 +ARG gid=$uid + +# [temporary] work around to be able to run prisma +RUN apt-get update -y && apt-get install -y openssl + +# create directory where the application will be executed from +WORKDIR /app + +# add the user and group +RUN groupadd --gid ${gid} ${user} +RUN useradd --uid ${uid} --gid ${gid} -m ${user} + +# copy over the bundled code from the build stage +COPY --from=base /app/node_modules/ ./node_modules +COPY --from=base /app/package.json ./package.json +COPY --from=base /app/dist ./dist +COPY --from=base /app/prisma ./prisma +COPY --from=base /app/scripts ./scripts +COPY --from=base /app/src ./src +COPY --from=base /app/tsconfig* ./ + +# change ownership of the workspace directory +RUN chown -R ${uid}:${gid} /app/ + +# get rid of the development dependencies +RUN npm install --production + +# set user to the created non-privileged user +USER ${user} + +# expose a specific port on the docker container +ENV PORT=3000 +EXPOSE ${PORT} + +# start the server using the previously build application +CMD [ "node", "./dist/main.js" ] diff --git a/apps/deployment-orchestrator-server/README.md b/apps/deployment-orchestrator-server/README.md new file mode 100644 index 000000000..bca0445d8 --- /dev/null +++ b/apps/deployment-orchestrator-server/README.md @@ -0,0 +1,64 @@ +<p align="right"> + <a href="https://amplication.com" target="_blank"> + <img alt="amplication-logo" height="70" alt="Amplication Logo" src="https://amplication.com/images/logo.svg"/> + </a> +</p> + +# Introduction + +This service was generated with Amplication. The server-side of the generated project. This component provides the different backend services - i.e., REST API, GraphQL API, authentication, authorization, logging, data validation and the connection to the database. Additional information about the server component and the architecture around it, can be found on the [documentation](https://docs.amplication.com/guides/getting-started) site. + +# Getting started + +## Step 1: Configuration + +Configuration for the server component can be provided through the use of environment variables. These can be passed to the application via the use of the `.env` file in the base directory of the generated service. Below a table can be found which show the different variables that can be passed - these are the variables which exist by default, through the use of plugins additional integrations could require additional values. These values are provided default values after generation, change them to the desired values. + +| Variable | Description | Value | +| -------------------- | -------------------------------------------- | ------------------------------------------------------------------- | +| BCRYPT_SALT | the string used for hashing | [random-string] | +| COMPOSE_PROJECT_NAME | the identifier of the service plus prefix | amp_[service-identifier] | +| PORT | the port on which to run the server | 3000 | +| DB_URL | the connection url for the database | [db-provider]://[username]:[password]@localhost:[db-port]/[db-name] | +| DB_PORT | the port used by the database instance | [db-provider-port] | +| DB_USER | the username used to connect to the database | [username] | +| DB_PASSWORD | the password used to connect to the database | [password] | +| DB_NAME | the name of the database | [service-name] / [project-name] | +| JWT_SECRET_KEY | the secret used to sign the json-web token | [secret] | +| JWT_EXPIRATION | the expiration time for the json-web token | 2d | + +> **Note** +> Amplication generates default values and stores them under the .env file. It is advised to use some form of secrets manager/vault solution when using in production. + +## Step 2.1: Scripts - pre-requisites + +After configuration of the server the next step would be to run the application. Before running the server side of the component, make sure that the different pre-requisites are met - i.e., node.js [^16.x], npm, docker. After the setup of the pre-requisites the server component can be started. + +```sh +# installation of the dependencies +$ npm install + +# generate the prisma client +$ npm run prisma:generate +``` + +## Step 2.2: Scripts - local development + +```sh +# start the database where the server component will connect to +$ npm run docker:dev + +# initialize the database +$ npm run db:init + +# start the server component +$ npm run start +``` +By default, your app comes with one user with the username "admin" and password "admin". + +## Step 2.2: Scripts - container based development + +```shell +# start the server component as a docker container +$ npm run compose:up +``` diff --git a/apps/deployment-orchestrator-server/docker-compose.dev.yml b/apps/deployment-orchestrator-server/docker-compose.dev.yml new file mode 100644 index 000000000..8d7c3589b --- /dev/null +++ b/apps/deployment-orchestrator-server/docker-compose.dev.yml @@ -0,0 +1,13 @@ +version: "3" +services: + db: + image: postgres:12 + ports: + - ${DB_PORT}:5432 + environment: + POSTGRES_USER: ${DB_USER} + POSTGRES_PASSWORD: ${DB_PASSWORD} + volumes: + - postgres:/var/lib/postgresql/data +volumes: + postgres: ~ diff --git a/apps/deployment-orchestrator-server/docker-compose.yml b/apps/deployment-orchestrator-server/docker-compose.yml new file mode 100644 index 000000000..ef3a7a5f9 --- /dev/null +++ b/apps/deployment-orchestrator-server/docker-compose.yml @@ -0,0 +1,47 @@ +version: "3" +services: + server: + build: + context: . + args: + NPM_LOG_LEVEL: notice + ports: + - ${PORT}:3000 + environment: + BCRYPT_SALT: ${BCRYPT_SALT} + DB_URL: postgres://${DB_USER}:${DB_PASSWORD}@db:5432/${DB_NAME} + depends_on: + - migrate + restart: on-failure + migrate: + build: + context: . + args: + NPM_LOG_LEVEL: notice + command: npm run db:init + working_dir: /app/server + environment: + BCRYPT_SALT: ${BCRYPT_SALT} + DB_URL: postgres://${DB_USER}:${DB_PASSWORD}@db:5432/${DB_NAME} + depends_on: + db: + condition: service_healthy + db: + image: postgres:12 + ports: + - ${DB_PORT}:5432 + environment: + POSTGRES_USER: ${DB_USER} + POSTGRES_PASSWORD: ${DB_PASSWORD} + POSTGRES_DB: ${DB_NAME} + volumes: + - postgres:/var/lib/postgresql/data + healthcheck: + test: + - CMD-SHELL + - pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER} + timeout: 45s + interval: 10s + retries: 10 +volumes: + postgres: ~ diff --git a/apps/deployment-orchestrator-server/nest-cli.json b/apps/deployment-orchestrator-server/nest-cli.json new file mode 100644 index 000000000..b7b60ae9f --- /dev/null +++ b/apps/deployment-orchestrator-server/nest-cli.json @@ -0,0 +1,10 @@ +{ + "sourceRoot": "src", + "compilerOptions": { + "assets": [ + { + "include": "swagger/**/*" + } + ] + } +} diff --git a/apps/deployment-orchestrator-server/package.json b/apps/deployment-orchestrator-server/package.json new file mode 100644 index 000000000..61be11d9c --- /dev/null +++ b/apps/deployment-orchestrator-server/package.json @@ -0,0 +1,76 @@ +{ + "name": "@deployment-orchestrator/server", + "private": true, + "scripts": { + "start": "nest start", + "start:watch": "nest start --watch", + "start:debug": "nest start --debug --watch", + "build": "nest build", + "test": "jest", + "seed": "ts-node scripts/seed.ts", + "db:migrate-save": "prisma migrate dev", + "db:migrate-up": "prisma migrate deploy", + "db:clean": "prisma migrate reset", + "db:init": "run-s \"db:migrate-save -- --name 'initial version'\" db:migrate-up seed", + "prisma:generate": "prisma generate", + "docker:dev": "docker-compose -f docker-compose.dev.yml up -d", + "package:container": "docker build .", + "compose:up": "docker-compose up -d", + "compose:down": "docker-compose down --volumes" + }, + "dependencies": { + "@apollo/server": "^4.9.4", + "@nestjs/apollo": "12.0.9", + "@nestjs/common": "10.2.7", + "@nestjs/config": "3.1.1", + "@nestjs/core": "10.2.7", + "@nestjs/graphql": "12.0.9", + "@nestjs/jwt": "^10.1.1", + "@nestjs/passport": "^10.0.2", + "@nestjs/platform-express": "10.2.7", + "@nestjs/serve-static": "4.0.0", + "@nestjs/swagger": "7.1.13", + "@prisma/client": "^5.4.2", + "@types/bcrypt": "5.0.0", + "bcrypt": "5.1.1", + "class-transformer": "0.5.1", + "class-validator": "0.14.0", + "dotenv": "16.3.1", + "graphql": "^16.8.1", + "graphql-type-json": "0.3.2", + "npm-run-all": "4.1.5", + "passport": "0.6.0", + "passport-http": "0.3.0", + "passport-jwt": "4.0.1", + "reflect-metadata": "0.1.13", + "ts-node": "10.9.2", + "type-fest": "2.19.0", + "validator": "13.11.0" + }, + "devDependencies": { + "@nestjs/cli": "^10.1.18", + "@nestjs/testing": "^10.2.7", + "@types/express": "^4.17.19", + "@types/graphql-type-json": "0.3.3", + "@types/jest": "^29.5.5", + "@types/normalize-path": "3.0.0", + "@types/passport-http": "0.3.9", + "@types/passport-jwt": "3.0.10", + "@types/supertest": "^2.0.14", + "@types/validator": "^13.11.2", + "jest": "^29.7.0", + "jest-mock-extended": "^3.0.5", + "prisma": "^5.4.2", + "supertest": "^6.3.3", + "ts-jest": "^29.1.1", + "typescript": "^5.4.3" + }, + "jest": { + "preset": "ts-jest", + "testEnvironment": "node", + "moduleNameMapper": { + "@app/custom-validators": "<rootDir>/src/validators" + }, + "modulePathIgnorePatterns": ["<rootDir>/dist/"] + } +} diff --git a/apps/deployment-orchestrator-server/prisma/schema.prisma b/apps/deployment-orchestrator-server/prisma/schema.prisma new file mode 100644 index 000000000..0dcefc63a --- /dev/null +++ b/apps/deployment-orchestrator-server/prisma/schema.prisma @@ -0,0 +1,75 @@ +datasource db { + provider = "postgresql" + url = env("DB_URL") +} + +generator client { + provider = "prisma-client-js" +} + +model Deployment { + autoTerminateAt DateTime? + createdAt DateTime @default(now()) + environment String? + id String @id @default(cuid()) + promptHandlers PromptHandler[] + region String? + requestPrompt String? + resolvedConfig Json? + status EnumDeploymentStatus? + updatedAt DateTime @updatedAt + userProfile UserProfile? @relation(fields: [userProfileId], references: [id]) + userProfileId String? +} + +model PromptHandler { + createdAt DateTime @default(now()) + deployment Deployment? @relation(fields: [deploymentId], references: [id]) + deploymentId String? + detectedOs String? + id String @id @default(cuid()) + inputPrompt String? + llmIntegrations LlmIntegration[] + parsedInstructions Json? + resourcesRequested Json? + updatedAt DateTime @updatedAt +} + +model CloudConnection { + accessKey String? + createdAt DateTime @default(now()) + id String @id @default(cuid()) + provider String? + region String? + updatedAt DateTime @updatedAt + userProfile UserProfile? @relation(fields: [userProfileId], references: [id]) + userProfileId String? +} + +model UserProfile { + cloudConnections CloudConnection[] + createdAt DateTime @default(now()) + deployments Deployment[] + email String? + id String @id @default(cuid()) + name String? + role String? + sshKey String? + updatedAt DateTime @updatedAt +} + +model LlmIntegration { + apiEndpoint String? + apiKeyName String? + createdAt DateTime @default(now()) + id String @id @default(cuid()) + modelUsed String? + promptHandler PromptHandler? @relation(fields: [promptHandlerId], references: [id]) + promptHandlerId String? + provider String? + updatedAt DateTime @updatedAt +} + +enum EnumDeploymentStatus { + Option1 +} diff --git a/apps/deployment-orchestrator-server/scripts/customSeed.ts b/apps/deployment-orchestrator-server/scripts/customSeed.ts new file mode 100644 index 000000000..26ccaf4c2 --- /dev/null +++ b/apps/deployment-orchestrator-server/scripts/customSeed.ts @@ -0,0 +1,7 @@ +import { PrismaClient } from "@prisma/client"; + +export async function customSeed() { + const client = new PrismaClient(); + + client.$disconnect(); +} diff --git a/apps/deployment-orchestrator-server/scripts/seed.ts b/apps/deployment-orchestrator-server/scripts/seed.ts new file mode 100644 index 000000000..04cee655d --- /dev/null +++ b/apps/deployment-orchestrator-server/scripts/seed.ts @@ -0,0 +1,25 @@ +import * as dotenv from "dotenv"; +import { PrismaClient } from "@prisma/client"; +import { customSeed } from "./customSeed"; + +if (require.main === module) { + dotenv.config(); + + const { BCRYPT_SALT } = process.env; + + if (!BCRYPT_SALT) { + throw new Error("BCRYPT_SALT environment variable must be defined"); + } +} + +async function seed() { + console.info("Seeding database..."); + + const client = new PrismaClient(); + void client.$disconnect(); + + console.info("Seeding database with custom seed..."); + customSeed(); + + console.info("Seeded database successfully"); +} diff --git a/apps/deployment-orchestrator-server/src/app.module.ts b/apps/deployment-orchestrator-server/src/app.module.ts new file mode 100644 index 000000000..2cff9f53c --- /dev/null +++ b/apps/deployment-orchestrator-server/src/app.module.ts @@ -0,0 +1,49 @@ +import { Module } from "@nestjs/common"; +import { DeploymentModule } from "./deployment/deployment.module"; +import { PromptHandlerModule } from "./promptHandler/promptHandler.module"; +import { CloudConnectionModule } from "./cloudConnection/cloudConnection.module"; +import { UserProfileModule } from "./userProfile/userProfile.module"; +import { LlmIntegrationModule } from "./llmIntegration/llmIntegration.module"; +import { HealthModule } from "./health/health.module"; +import { PrismaModule } from "./prisma/prisma.module"; +import { SecretsManagerModule } from "./providers/secrets/secretsManager.module"; +import { ServeStaticModule } from "@nestjs/serve-static"; +import { ServeStaticOptionsService } from "./serveStaticOptions.service"; +import { ConfigModule, ConfigService } from "@nestjs/config"; +import { GraphQLModule } from "@nestjs/graphql"; +import { ApolloDriver, ApolloDriverConfig } from "@nestjs/apollo"; + +@Module({ + controllers: [], + imports: [ + DeploymentModule, + PromptHandlerModule, + CloudConnectionModule, + UserProfileModule, + LlmIntegrationModule, + HealthModule, + PrismaModule, + SecretsManagerModule, + ConfigModule.forRoot({ isGlobal: true }), + ServeStaticModule.forRootAsync({ + useClass: ServeStaticOptionsService, + }), + GraphQLModule.forRootAsync<ApolloDriverConfig>({ + driver: ApolloDriver, + useFactory: (configService: ConfigService) => { + const playground = configService.get("GRAPHQL_PLAYGROUND"); + const introspection = configService.get("GRAPHQL_INTROSPECTION"); + return { + autoSchemaFile: "schema.graphql", + sortSchema: true, + playground, + introspection: playground || introspection, + }; + }, + inject: [ConfigService], + imports: [ConfigModule], + }), + ], + providers: [], +}) +export class AppModule {} diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnection.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnection.ts new file mode 100644 index 000000000..a154d8b8f --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnection.ts @@ -0,0 +1,96 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ObjectType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { + IsString, + MaxLength, + IsOptional, + IsDate, + ValidateNested, +} from "class-validator"; +import { Type } from "class-transformer"; +import { UserProfile } from "../../userProfile/base/UserProfile"; + +@ObjectType() +class CloudConnection { + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + accessKey!: string | null; + + @ApiProperty({ + required: true, + }) + @IsDate() + @Type(() => Date) + @Field(() => Date) + createdAt!: Date; + + @ApiProperty({ + required: true, + type: String, + }) + @IsString() + @Field(() => String) + id!: string; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + provider!: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + region!: string | null; + + @ApiProperty({ + required: true, + }) + @IsDate() + @Type(() => Date) + @Field(() => Date) + updatedAt!: Date; + + @ApiProperty({ + required: false, + type: () => UserProfile, + }) + @ValidateNested() + @Type(() => UserProfile) + @IsOptional() + userProfile?: UserProfile | null; +} + +export { CloudConnection as CloudConnection }; diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionCountArgs.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionCountArgs.ts new file mode 100644 index 000000000..f217da206 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionCountArgs.ts @@ -0,0 +1,28 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { CloudConnectionWhereInput } from "./CloudConnectionWhereInput"; +import { Type } from "class-transformer"; + +@ArgsType() +class CloudConnectionCountArgs { + @ApiProperty({ + required: false, + type: () => CloudConnectionWhereInput, + }) + @Field(() => CloudConnectionWhereInput, { nullable: true }) + @Type(() => CloudConnectionWhereInput) + where?: CloudConnectionWhereInput; +} + +export { CloudConnectionCountArgs as CloudConnectionCountArgs }; diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionCreateInput.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionCreateInput.ts new file mode 100644 index 000000000..5613d6a80 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionCreateInput.ts @@ -0,0 +1,74 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { + IsString, + MaxLength, + IsOptional, + ValidateNested, +} from "class-validator"; +import { UserProfileWhereUniqueInput } from "../../userProfile/base/UserProfileWhereUniqueInput"; +import { Type } from "class-transformer"; + +@InputType() +class CloudConnectionCreateInput { + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + accessKey?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + provider?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + region?: string | null; + + @ApiProperty({ + required: false, + type: () => UserProfileWhereUniqueInput, + }) + @ValidateNested() + @Type(() => UserProfileWhereUniqueInput) + @IsOptional() + @Field(() => UserProfileWhereUniqueInput, { + nullable: true, + }) + userProfile?: UserProfileWhereUniqueInput | null; +} + +export { CloudConnectionCreateInput as CloudConnectionCreateInput }; diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionFindManyArgs.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionFindManyArgs.ts new file mode 100644 index 000000000..fbdf893b6 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionFindManyArgs.ts @@ -0,0 +1,62 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { CloudConnectionWhereInput } from "./CloudConnectionWhereInput"; +import { IsOptional, ValidateNested, IsInt } from "class-validator"; +import { Type } from "class-transformer"; +import { CloudConnectionOrderByInput } from "./CloudConnectionOrderByInput"; + +@ArgsType() +class CloudConnectionFindManyArgs { + @ApiProperty({ + required: false, + type: () => CloudConnectionWhereInput, + }) + @IsOptional() + @ValidateNested() + @Field(() => CloudConnectionWhereInput, { nullable: true }) + @Type(() => CloudConnectionWhereInput) + where?: CloudConnectionWhereInput; + + @ApiProperty({ + required: false, + type: [CloudConnectionOrderByInput], + }) + @IsOptional() + @ValidateNested({ each: true }) + @Field(() => [CloudConnectionOrderByInput], { nullable: true }) + @Type(() => CloudConnectionOrderByInput) + orderBy?: Array<CloudConnectionOrderByInput>; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @IsInt() + @Field(() => Number, { nullable: true }) + @Type(() => Number) + skip?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @IsInt() + @Field(() => Number, { nullable: true }) + @Type(() => Number) + take?: number; +} + +export { CloudConnectionFindManyArgs as CloudConnectionFindManyArgs }; diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionFindUniqueArgs.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionFindUniqueArgs.ts new file mode 100644 index 000000000..db6893b71 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionFindUniqueArgs.ts @@ -0,0 +1,30 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { CloudConnectionWhereUniqueInput } from "./CloudConnectionWhereUniqueInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; + +@ArgsType() +class CloudConnectionFindUniqueArgs { + @ApiProperty({ + required: true, + type: () => CloudConnectionWhereUniqueInput, + }) + @ValidateNested() + @Type(() => CloudConnectionWhereUniqueInput) + @Field(() => CloudConnectionWhereUniqueInput, { nullable: false }) + where!: CloudConnectionWhereUniqueInput; +} + +export { CloudConnectionFindUniqueArgs as CloudConnectionFindUniqueArgs }; diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionListRelationFilter.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionListRelationFilter.ts new file mode 100644 index 000000000..aaff3b541 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionListRelationFilter.ts @@ -0,0 +1,56 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { CloudConnectionWhereInput } from "./CloudConnectionWhereInput"; +import { ValidateNested, IsOptional } from "class-validator"; +import { Type } from "class-transformer"; + +@InputType() +class CloudConnectionListRelationFilter { + @ApiProperty({ + required: false, + type: () => CloudConnectionWhereInput, + }) + @ValidateNested() + @Type(() => CloudConnectionWhereInput) + @IsOptional() + @Field(() => CloudConnectionWhereInput, { + nullable: true, + }) + every?: CloudConnectionWhereInput; + + @ApiProperty({ + required: false, + type: () => CloudConnectionWhereInput, + }) + @ValidateNested() + @Type(() => CloudConnectionWhereInput) + @IsOptional() + @Field(() => CloudConnectionWhereInput, { + nullable: true, + }) + some?: CloudConnectionWhereInput; + + @ApiProperty({ + required: false, + type: () => CloudConnectionWhereInput, + }) + @ValidateNested() + @Type(() => CloudConnectionWhereInput) + @IsOptional() + @Field(() => CloudConnectionWhereInput, { + nullable: true, + }) + none?: CloudConnectionWhereInput; +} +export { CloudConnectionListRelationFilter as CloudConnectionListRelationFilter }; diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionOrderByInput.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionOrderByInput.ts new file mode 100644 index 000000000..08126a577 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionOrderByInput.ts @@ -0,0 +1,100 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional, IsEnum } from "class-validator"; +import { SortOrder } from "../../util/SortOrder"; + +@InputType({ + isAbstract: true, + description: undefined, +}) +class CloudConnectionOrderByInput { + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + accessKey?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + createdAt?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + id?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + provider?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + region?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + updatedAt?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + userProfileId?: SortOrder; +} + +export { CloudConnectionOrderByInput as CloudConnectionOrderByInput }; diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionUpdateInput.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionUpdateInput.ts new file mode 100644 index 000000000..35878e8c2 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionUpdateInput.ts @@ -0,0 +1,74 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { + IsString, + MaxLength, + IsOptional, + ValidateNested, +} from "class-validator"; +import { UserProfileWhereUniqueInput } from "../../userProfile/base/UserProfileWhereUniqueInput"; +import { Type } from "class-transformer"; + +@InputType() +class CloudConnectionUpdateInput { + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + accessKey?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + provider?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + region?: string | null; + + @ApiProperty({ + required: false, + type: () => UserProfileWhereUniqueInput, + }) + @ValidateNested() + @Type(() => UserProfileWhereUniqueInput) + @IsOptional() + @Field(() => UserProfileWhereUniqueInput, { + nullable: true, + }) + userProfile?: UserProfileWhereUniqueInput | null; +} + +export { CloudConnectionUpdateInput as CloudConnectionUpdateInput }; diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionWhereInput.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionWhereInput.ts new file mode 100644 index 000000000..19d6fee8d --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionWhereInput.ts @@ -0,0 +1,79 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { StringNullableFilter } from "../../util/StringNullableFilter"; +import { Type } from "class-transformer"; +import { IsOptional, ValidateNested } from "class-validator"; +import { StringFilter } from "../../util/StringFilter"; +import { UserProfileWhereUniqueInput } from "../../userProfile/base/UserProfileWhereUniqueInput"; + +@InputType() +class CloudConnectionWhereInput { + @ApiProperty({ + required: false, + type: StringNullableFilter, + }) + @Type(() => StringNullableFilter) + @IsOptional() + @Field(() => StringNullableFilter, { + nullable: true, + }) + accessKey?: StringNullableFilter; + + @ApiProperty({ + required: false, + type: StringFilter, + }) + @Type(() => StringFilter) + @IsOptional() + @Field(() => StringFilter, { + nullable: true, + }) + id?: StringFilter; + + @ApiProperty({ + required: false, + type: StringNullableFilter, + }) + @Type(() => StringNullableFilter) + @IsOptional() + @Field(() => StringNullableFilter, { + nullable: true, + }) + provider?: StringNullableFilter; + + @ApiProperty({ + required: false, + type: StringNullableFilter, + }) + @Type(() => StringNullableFilter) + @IsOptional() + @Field(() => StringNullableFilter, { + nullable: true, + }) + region?: StringNullableFilter; + + @ApiProperty({ + required: false, + type: () => UserProfileWhereUniqueInput, + }) + @ValidateNested() + @Type(() => UserProfileWhereUniqueInput) + @IsOptional() + @Field(() => UserProfileWhereUniqueInput, { + nullable: true, + }) + userProfile?: UserProfileWhereUniqueInput; +} + +export { CloudConnectionWhereInput as CloudConnectionWhereInput }; diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionWhereUniqueInput.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionWhereUniqueInput.ts new file mode 100644 index 000000000..e7bb90fc9 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/CloudConnectionWhereUniqueInput.ts @@ -0,0 +1,27 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsString } from "class-validator"; + +@InputType() +class CloudConnectionWhereUniqueInput { + @ApiProperty({ + required: true, + type: String, + }) + @IsString() + @Field(() => String) + id!: string; +} + +export { CloudConnectionWhereUniqueInput as CloudConnectionWhereUniqueInput }; diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/CreateCloudConnectionArgs.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/CreateCloudConnectionArgs.ts new file mode 100644 index 000000000..9e1008829 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/CreateCloudConnectionArgs.ts @@ -0,0 +1,30 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { CloudConnectionCreateInput } from "./CloudConnectionCreateInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; + +@ArgsType() +class CreateCloudConnectionArgs { + @ApiProperty({ + required: true, + type: () => CloudConnectionCreateInput, + }) + @ValidateNested() + @Type(() => CloudConnectionCreateInput) + @Field(() => CloudConnectionCreateInput, { nullable: false }) + data!: CloudConnectionCreateInput; +} + +export { CreateCloudConnectionArgs as CreateCloudConnectionArgs }; diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/DeleteCloudConnectionArgs.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/DeleteCloudConnectionArgs.ts new file mode 100644 index 000000000..3e171d5a7 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/DeleteCloudConnectionArgs.ts @@ -0,0 +1,30 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { CloudConnectionWhereUniqueInput } from "./CloudConnectionWhereUniqueInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; + +@ArgsType() +class DeleteCloudConnectionArgs { + @ApiProperty({ + required: true, + type: () => CloudConnectionWhereUniqueInput, + }) + @ValidateNested() + @Type(() => CloudConnectionWhereUniqueInput) + @Field(() => CloudConnectionWhereUniqueInput, { nullable: false }) + where!: CloudConnectionWhereUniqueInput; +} + +export { DeleteCloudConnectionArgs as DeleteCloudConnectionArgs }; diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/UpdateCloudConnectionArgs.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/UpdateCloudConnectionArgs.ts new file mode 100644 index 000000000..4e031ee15 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/UpdateCloudConnectionArgs.ts @@ -0,0 +1,40 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { CloudConnectionWhereUniqueInput } from "./CloudConnectionWhereUniqueInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; +import { CloudConnectionUpdateInput } from "./CloudConnectionUpdateInput"; + +@ArgsType() +class UpdateCloudConnectionArgs { + @ApiProperty({ + required: true, + type: () => CloudConnectionWhereUniqueInput, + }) + @ValidateNested() + @Type(() => CloudConnectionWhereUniqueInput) + @Field(() => CloudConnectionWhereUniqueInput, { nullable: false }) + where!: CloudConnectionWhereUniqueInput; + + @ApiProperty({ + required: true, + type: () => CloudConnectionUpdateInput, + }) + @ValidateNested() + @Type(() => CloudConnectionUpdateInput) + @Field(() => CloudConnectionUpdateInput, { nullable: false }) + data!: CloudConnectionUpdateInput; +} + +export { UpdateCloudConnectionArgs as UpdateCloudConnectionArgs }; diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.controller.base.spec.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.controller.base.spec.ts new file mode 100644 index 000000000..5a77c88a2 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.controller.base.spec.ts @@ -0,0 +1,202 @@ +import { Test } from "@nestjs/testing"; +import { + INestApplication, + HttpStatus, + ExecutionContext, + CallHandler, +} from "@nestjs/common"; +import request from "supertest"; +import { ACGuard } from "nest-access-control"; +import { DefaultAuthGuard } from "../../auth/defaultAuth.guard"; +import { ACLModule } from "../../auth/acl.module"; +import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor"; +import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor"; +import { map } from "rxjs"; +import { CloudConnectionController } from "../cloudConnection.controller"; +import { CloudConnectionService } from "../cloudConnection.service"; + +const nonExistingId = "nonExistingId"; +const existingId = "existingId"; +const CREATE_INPUT = { + accessKey: "exampleAccessKey", + createdAt: new Date(), + id: "exampleId", + provider: "exampleProvider", + region: "exampleRegion", + updatedAt: new Date(), +}; +const CREATE_RESULT = { + accessKey: "exampleAccessKey", + createdAt: new Date(), + id: "exampleId", + provider: "exampleProvider", + region: "exampleRegion", + updatedAt: new Date(), +}; +const FIND_MANY_RESULT = [ + { + accessKey: "exampleAccessKey", + createdAt: new Date(), + id: "exampleId", + provider: "exampleProvider", + region: "exampleRegion", + updatedAt: new Date(), + }, +]; +const FIND_ONE_RESULT = { + accessKey: "exampleAccessKey", + createdAt: new Date(), + id: "exampleId", + provider: "exampleProvider", + region: "exampleRegion", + updatedAt: new Date(), +}; + +const service = { + createCloudConnection() { + return CREATE_RESULT; + }, + cloudConnections: () => FIND_MANY_RESULT, + cloudConnection: ({ where }: { where: { id: string } }) => { + switch (where.id) { + case existingId: + return FIND_ONE_RESULT; + case nonExistingId: + return null; + } + }, +}; + +const basicAuthGuard = { + canActivate: (context: ExecutionContext) => { + const argumentHost = context.switchToHttp(); + const request = argumentHost.getRequest(); + request.user = { + roles: ["user"], + }; + return true; + }, +}; + +const acGuard = { + canActivate: () => { + return true; + }, +}; + +const aclFilterResponseInterceptor = { + intercept: (context: ExecutionContext, next: CallHandler) => { + return next.handle().pipe( + map((data) => { + return data; + }) + ); + }, +}; +const aclValidateRequestInterceptor = { + intercept: (context: ExecutionContext, next: CallHandler) => { + return next.handle(); + }, +}; + +describe("CloudConnection", () => { + let app: INestApplication; + + beforeAll(async () => { + const moduleRef = await Test.createTestingModule({ + providers: [ + { + provide: CloudConnectionService, + useValue: service, + }, + ], + controllers: [CloudConnectionController], + imports: [ACLModule], + }) + .overrideGuard(DefaultAuthGuard) + .useValue(basicAuthGuard) + .overrideGuard(ACGuard) + .useValue(acGuard) + .overrideInterceptor(AclFilterResponseInterceptor) + .useValue(aclFilterResponseInterceptor) + .overrideInterceptor(AclValidateRequestInterceptor) + .useValue(aclValidateRequestInterceptor) + .compile(); + + app = moduleRef.createNestApplication(); + await app.init(); + }); + + test("POST /cloudConnections", async () => { + await request(app.getHttpServer()) + .post("/cloudConnections") + .send(CREATE_INPUT) + .expect(HttpStatus.CREATED) + .expect({ + ...CREATE_RESULT, + createdAt: CREATE_RESULT.createdAt.toISOString(), + updatedAt: CREATE_RESULT.updatedAt.toISOString(), + }); + }); + + test("GET /cloudConnections", async () => { + await request(app.getHttpServer()) + .get("/cloudConnections") + .expect(HttpStatus.OK) + .expect([ + { + ...FIND_MANY_RESULT[0], + createdAt: FIND_MANY_RESULT[0].createdAt.toISOString(), + updatedAt: FIND_MANY_RESULT[0].updatedAt.toISOString(), + }, + ]); + }); + + test("GET /cloudConnections/:id non existing", async () => { + await request(app.getHttpServer()) + .get(`${"/cloudConnections"}/${nonExistingId}`) + .expect(HttpStatus.NOT_FOUND) + .expect({ + statusCode: HttpStatus.NOT_FOUND, + message: `No resource was found for {"${"id"}":"${nonExistingId}"}`, + error: "Not Found", + }); + }); + + test("GET /cloudConnections/:id existing", async () => { + await request(app.getHttpServer()) + .get(`${"/cloudConnections"}/${existingId}`) + .expect(HttpStatus.OK) + .expect({ + ...FIND_ONE_RESULT, + createdAt: FIND_ONE_RESULT.createdAt.toISOString(), + updatedAt: FIND_ONE_RESULT.updatedAt.toISOString(), + }); + }); + + test("POST /cloudConnections existing resource", async () => { + const agent = request(app.getHttpServer()); + await agent + .post("/cloudConnections") + .send(CREATE_INPUT) + .expect(HttpStatus.CREATED) + .expect({ + ...CREATE_RESULT, + createdAt: CREATE_RESULT.createdAt.toISOString(), + updatedAt: CREATE_RESULT.updatedAt.toISOString(), + }) + .then(function () { + agent + .post("/cloudConnections") + .send(CREATE_INPUT) + .expect(HttpStatus.CONFLICT) + .expect({ + statusCode: HttpStatus.CONFLICT, + }); + }); + }); + + afterAll(async () => { + await app.close(); + }); +}); diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.controller.base.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.controller.base.ts new file mode 100644 index 000000000..89bd23552 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.controller.base.ts @@ -0,0 +1,194 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import * as common from "@nestjs/common"; +import * as swagger from "@nestjs/swagger"; +import { isRecordNotFoundError } from "../../prisma.util"; +import * as errors from "../../errors"; +import { Request } from "express"; +import { plainToClass } from "class-transformer"; +import { ApiNestedQuery } from "../../decorators/api-nested-query.decorator"; +import { CloudConnectionService } from "../cloudConnection.service"; +import { CloudConnectionCreateInput } from "./CloudConnectionCreateInput"; +import { CloudConnection } from "./CloudConnection"; +import { CloudConnectionFindManyArgs } from "./CloudConnectionFindManyArgs"; +import { CloudConnectionWhereUniqueInput } from "./CloudConnectionWhereUniqueInput"; +import { CloudConnectionUpdateInput } from "./CloudConnectionUpdateInput"; + +export class CloudConnectionControllerBase { + constructor(protected readonly service: CloudConnectionService) {} + @common.Post() + @swagger.ApiCreatedResponse({ type: CloudConnection }) + async createCloudConnection( + @common.Body() data: CloudConnectionCreateInput + ): Promise<CloudConnection> { + return await this.service.createCloudConnection({ + data: { + ...data, + + userProfile: data.userProfile + ? { + connect: data.userProfile, + } + : undefined, + }, + select: { + accessKey: true, + createdAt: true, + id: true, + provider: true, + region: true, + updatedAt: true, + + userProfile: { + select: { + id: true, + }, + }, + }, + }); + } + + @common.Get() + @swagger.ApiOkResponse({ type: [CloudConnection] }) + @ApiNestedQuery(CloudConnectionFindManyArgs) + async cloudConnections( + @common.Req() request: Request + ): Promise<CloudConnection[]> { + const args = plainToClass(CloudConnectionFindManyArgs, request.query); + return this.service.cloudConnections({ + ...args, + select: { + accessKey: true, + createdAt: true, + id: true, + provider: true, + region: true, + updatedAt: true, + + userProfile: { + select: { + id: true, + }, + }, + }, + }); + } + + @common.Get("/:id") + @swagger.ApiOkResponse({ type: CloudConnection }) + @swagger.ApiNotFoundResponse({ type: errors.NotFoundException }) + async cloudConnection( + @common.Param() params: CloudConnectionWhereUniqueInput + ): Promise<CloudConnection | null> { + const result = await this.service.cloudConnection({ + where: params, + select: { + accessKey: true, + createdAt: true, + id: true, + provider: true, + region: true, + updatedAt: true, + + userProfile: { + select: { + id: true, + }, + }, + }, + }); + if (result === null) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + return result; + } + + @common.Patch("/:id") + @swagger.ApiOkResponse({ type: CloudConnection }) + @swagger.ApiNotFoundResponse({ type: errors.NotFoundException }) + async updateCloudConnection( + @common.Param() params: CloudConnectionWhereUniqueInput, + @common.Body() data: CloudConnectionUpdateInput + ): Promise<CloudConnection | null> { + try { + return await this.service.updateCloudConnection({ + where: params, + data: { + ...data, + + userProfile: data.userProfile + ? { + connect: data.userProfile, + } + : undefined, + }, + select: { + accessKey: true, + createdAt: true, + id: true, + provider: true, + region: true, + updatedAt: true, + + userProfile: { + select: { + id: true, + }, + }, + }, + }); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + throw error; + } + } + + @common.Delete("/:id") + @swagger.ApiOkResponse({ type: CloudConnection }) + @swagger.ApiNotFoundResponse({ type: errors.NotFoundException }) + async deleteCloudConnection( + @common.Param() params: CloudConnectionWhereUniqueInput + ): Promise<CloudConnection | null> { + try { + return await this.service.deleteCloudConnection({ + where: params, + select: { + accessKey: true, + createdAt: true, + id: true, + provider: true, + region: true, + updatedAt: true, + + userProfile: { + select: { + id: true, + }, + }, + }, + }); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + throw error; + } + } +} diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.module.base.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.module.base.ts new file mode 100644 index 000000000..8496c8827 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.module.base.ts @@ -0,0 +1,18 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { Module } from "@nestjs/common"; + +@Module({ + imports: [], + exports: [], +}) +export class CloudConnectionModuleBase {} diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.resolver.base.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.resolver.base.ts new file mode 100644 index 000000000..7b833a04e --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.resolver.base.ts @@ -0,0 +1,131 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import * as graphql from "@nestjs/graphql"; +import { GraphQLError } from "graphql"; +import { isRecordNotFoundError } from "../../prisma.util"; +import { MetaQueryPayload } from "../../util/MetaQueryPayload"; +import { CloudConnection } from "./CloudConnection"; +import { CloudConnectionCountArgs } from "./CloudConnectionCountArgs"; +import { CloudConnectionFindManyArgs } from "./CloudConnectionFindManyArgs"; +import { CloudConnectionFindUniqueArgs } from "./CloudConnectionFindUniqueArgs"; +import { CreateCloudConnectionArgs } from "./CreateCloudConnectionArgs"; +import { UpdateCloudConnectionArgs } from "./UpdateCloudConnectionArgs"; +import { DeleteCloudConnectionArgs } from "./DeleteCloudConnectionArgs"; +import { UserProfile } from "../../userProfile/base/UserProfile"; +import { CloudConnectionService } from "../cloudConnection.service"; +@graphql.Resolver(() => CloudConnection) +export class CloudConnectionResolverBase { + constructor(protected readonly service: CloudConnectionService) {} + + async _cloudConnectionsMeta( + @graphql.Args() args: CloudConnectionCountArgs + ): Promise<MetaQueryPayload> { + const result = await this.service.count(args); + return { + count: result, + }; + } + + @graphql.Query(() => [CloudConnection]) + async cloudConnections( + @graphql.Args() args: CloudConnectionFindManyArgs + ): Promise<CloudConnection[]> { + return this.service.cloudConnections(args); + } + + @graphql.Query(() => CloudConnection, { nullable: true }) + async cloudConnection( + @graphql.Args() args: CloudConnectionFindUniqueArgs + ): Promise<CloudConnection | null> { + const result = await this.service.cloudConnection(args); + if (result === null) { + return null; + } + return result; + } + + @graphql.Mutation(() => CloudConnection) + async createCloudConnection( + @graphql.Args() args: CreateCloudConnectionArgs + ): Promise<CloudConnection> { + return await this.service.createCloudConnection({ + ...args, + data: { + ...args.data, + + userProfile: args.data.userProfile + ? { + connect: args.data.userProfile, + } + : undefined, + }, + }); + } + + @graphql.Mutation(() => CloudConnection) + async updateCloudConnection( + @graphql.Args() args: UpdateCloudConnectionArgs + ): Promise<CloudConnection | null> { + try { + return await this.service.updateCloudConnection({ + ...args, + data: { + ...args.data, + + userProfile: args.data.userProfile + ? { + connect: args.data.userProfile, + } + : undefined, + }, + }); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new GraphQLError( + `No resource was found for ${JSON.stringify(args.where)}` + ); + } + throw error; + } + } + + @graphql.Mutation(() => CloudConnection) + async deleteCloudConnection( + @graphql.Args() args: DeleteCloudConnectionArgs + ): Promise<CloudConnection | null> { + try { + return await this.service.deleteCloudConnection(args); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new GraphQLError( + `No resource was found for ${JSON.stringify(args.where)}` + ); + } + throw error; + } + } + + @graphql.ResolveField(() => UserProfile, { + nullable: true, + name: "userProfile", + }) + async getUserProfile( + @graphql.Parent() parent: CloudConnection + ): Promise<UserProfile | null> { + const result = await this.service.getUserProfile(parent.id); + + if (!result) { + return null; + } + return result; + } +} diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.service.base.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.service.base.ts new file mode 100644 index 000000000..d071e70bf --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.service.base.ts @@ -0,0 +1,62 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { PrismaService } from "../../prisma/prisma.service"; + +import { + Prisma, + CloudConnection as PrismaCloudConnection, + UserProfile as PrismaUserProfile, +} from "@prisma/client"; + +export class CloudConnectionServiceBase { + constructor(protected readonly prisma: PrismaService) {} + + async count( + args: Omit<Prisma.CloudConnectionCountArgs, "select"> + ): Promise<number> { + return this.prisma.cloudConnection.count(args); + } + + async cloudConnections( + args: Prisma.CloudConnectionFindManyArgs + ): Promise<PrismaCloudConnection[]> { + return this.prisma.cloudConnection.findMany(args); + } + async cloudConnection( + args: Prisma.CloudConnectionFindUniqueArgs + ): Promise<PrismaCloudConnection | null> { + return this.prisma.cloudConnection.findUnique(args); + } + async createCloudConnection( + args: Prisma.CloudConnectionCreateArgs + ): Promise<PrismaCloudConnection> { + return this.prisma.cloudConnection.create(args); + } + async updateCloudConnection( + args: Prisma.CloudConnectionUpdateArgs + ): Promise<PrismaCloudConnection> { + return this.prisma.cloudConnection.update(args); + } + async deleteCloudConnection( + args: Prisma.CloudConnectionDeleteArgs + ): Promise<PrismaCloudConnection> { + return this.prisma.cloudConnection.delete(args); + } + + async getUserProfile(parentId: string): Promise<PrismaUserProfile | null> { + return this.prisma.cloudConnection + .findUnique({ + where: { id: parentId }, + }) + .userProfile(); + } +} diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/cloudConnection.controller.ts b/apps/deployment-orchestrator-server/src/cloudConnection/cloudConnection.controller.ts new file mode 100644 index 000000000..21c06a18a --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/cloudConnection.controller.ts @@ -0,0 +1,12 @@ +import * as common from "@nestjs/common"; +import * as swagger from "@nestjs/swagger"; +import { CloudConnectionService } from "./cloudConnection.service"; +import { CloudConnectionControllerBase } from "./base/cloudConnection.controller.base"; + +@swagger.ApiTags("cloudConnections") +@common.Controller("cloudConnections") +export class CloudConnectionController extends CloudConnectionControllerBase { + constructor(protected readonly service: CloudConnectionService) { + super(service); + } +} diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/cloudConnection.module.ts b/apps/deployment-orchestrator-server/src/cloudConnection/cloudConnection.module.ts new file mode 100644 index 000000000..fd18ce31f --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/cloudConnection.module.ts @@ -0,0 +1,13 @@ +import { Module } from "@nestjs/common"; +import { CloudConnectionModuleBase } from "./base/cloudConnection.module.base"; +import { CloudConnectionService } from "./cloudConnection.service"; +import { CloudConnectionController } from "./cloudConnection.controller"; +import { CloudConnectionResolver } from "./cloudConnection.resolver"; + +@Module({ + imports: [CloudConnectionModuleBase], + controllers: [CloudConnectionController], + providers: [CloudConnectionService, CloudConnectionResolver], + exports: [CloudConnectionService], +}) +export class CloudConnectionModule {} diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/cloudConnection.resolver.ts b/apps/deployment-orchestrator-server/src/cloudConnection/cloudConnection.resolver.ts new file mode 100644 index 000000000..16704e147 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/cloudConnection.resolver.ts @@ -0,0 +1,11 @@ +import * as graphql from "@nestjs/graphql"; +import { CloudConnectionResolverBase } from "./base/cloudConnection.resolver.base"; +import { CloudConnection } from "./base/CloudConnection"; +import { CloudConnectionService } from "./cloudConnection.service"; + +@graphql.Resolver(() => CloudConnection) +export class CloudConnectionResolver extends CloudConnectionResolverBase { + constructor(protected readonly service: CloudConnectionService) { + super(service); + } +} diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/cloudConnection.service.ts b/apps/deployment-orchestrator-server/src/cloudConnection/cloudConnection.service.ts new file mode 100644 index 000000000..872b755c8 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/cloudConnection.service.ts @@ -0,0 +1,10 @@ +import { Injectable } from "@nestjs/common"; +import { PrismaService } from "../prisma/prisma.service"; +import { CloudConnectionServiceBase } from "./base/cloudConnection.service.base"; + +@Injectable() +export class CloudConnectionService extends CloudConnectionServiceBase { + constructor(protected readonly prisma: PrismaService) { + super(prisma); + } +} diff --git a/apps/deployment-orchestrator-server/src/connectMicroservices.ts b/apps/deployment-orchestrator-server/src/connectMicroservices.ts new file mode 100644 index 000000000..068fa5f0d --- /dev/null +++ b/apps/deployment-orchestrator-server/src/connectMicroservices.ts @@ -0,0 +1,6 @@ +import { INestApplication } from "@nestjs/common"; +import { ConfigService } from "@nestjs/config"; + +export async function connectMicroservices(app: INestApplication) { + const configService = app.get(ConfigService); +} diff --git a/apps/deployment-orchestrator-server/src/decorators/api-nested-query.decorator.ts b/apps/deployment-orchestrator-server/src/decorators/api-nested-query.decorator.ts new file mode 100644 index 000000000..9fd5ba30f --- /dev/null +++ b/apps/deployment-orchestrator-server/src/decorators/api-nested-query.decorator.ts @@ -0,0 +1,80 @@ +import { applyDecorators } from "@nestjs/common"; +import { + ApiExtraModels, + ApiQuery, + ApiQueryOptions, + getSchemaPath, +} from "@nestjs/swagger"; +import "reflect-metadata"; + +const generateApiQueryObject = ( + prop: any, + propType: any, + required: boolean, + isArray: boolean +): ApiQueryOptions => { + if (propType === Number) { + return { + required, + name: prop, + style: "deepObject", + explode: true, + type: "number", + isArray, + }; + } else if (propType === String) { + return { + required, + name: prop, + style: "deepObject", + explode: true, + type: "string", + isArray, + }; + } else { + return { + required, + name: prop, + style: "deepObject", + explode: true, + type: "object", + isArray, + schema: { + $ref: getSchemaPath(propType), + }, + }; + } +}; + +// eslint-disable-next-line @typescript-eslint/ban-types,@typescript-eslint/explicit-module-boundary-types,@typescript-eslint/naming-convention +export function ApiNestedQuery(query: Function) { + const constructor = query.prototype; + const properties = Reflect.getMetadata( + "swagger/apiModelPropertiesArray", + constructor + ).map((prop: any) => prop.slice(1)); + + const decorators = properties + .map((property: any) => { + const { required, isArray } = Reflect.getMetadata( + "swagger/apiModelProperties", + constructor, + property + ); + const propertyType = Reflect.getMetadata( + "design:type", + constructor, + property + ); + const typedQuery = generateApiQueryObject( + property, + propertyType, + required, + isArray + ); + return [ApiExtraModels(propertyType), ApiQuery(typedQuery)]; + }) + .flat(); + + return applyDecorators(...decorators); +} diff --git a/apps/deployment-orchestrator-server/src/decorators/public.decorator.ts b/apps/deployment-orchestrator-server/src/decorators/public.decorator.ts new file mode 100644 index 000000000..9eab4e06f --- /dev/null +++ b/apps/deployment-orchestrator-server/src/decorators/public.decorator.ts @@ -0,0 +1,10 @@ +import { applyDecorators, SetMetadata } from "@nestjs/common"; + +export const IS_PUBLIC_KEY = "isPublic"; + +const PublicAuthMiddleware = SetMetadata(IS_PUBLIC_KEY, true); +const PublicAuthSwagger = SetMetadata("swagger/apiSecurity", ["isPublic"]); + +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +export const Public = () => + applyDecorators(PublicAuthMiddleware, PublicAuthSwagger); diff --git a/apps/deployment-orchestrator-server/src/deployment/base/CreateDeploymentArgs.ts b/apps/deployment-orchestrator-server/src/deployment/base/CreateDeploymentArgs.ts new file mode 100644 index 000000000..e201d4e18 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/CreateDeploymentArgs.ts @@ -0,0 +1,30 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { DeploymentCreateInput } from "./DeploymentCreateInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; + +@ArgsType() +class CreateDeploymentArgs { + @ApiProperty({ + required: true, + type: () => DeploymentCreateInput, + }) + @ValidateNested() + @Type(() => DeploymentCreateInput) + @Field(() => DeploymentCreateInput, { nullable: false }) + data!: DeploymentCreateInput; +} + +export { CreateDeploymentArgs as CreateDeploymentArgs }; diff --git a/apps/deployment-orchestrator-server/src/deployment/base/DeleteDeploymentArgs.ts b/apps/deployment-orchestrator-server/src/deployment/base/DeleteDeploymentArgs.ts new file mode 100644 index 000000000..5a517ca3f --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/DeleteDeploymentArgs.ts @@ -0,0 +1,30 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { DeploymentWhereUniqueInput } from "./DeploymentWhereUniqueInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; + +@ArgsType() +class DeleteDeploymentArgs { + @ApiProperty({ + required: true, + type: () => DeploymentWhereUniqueInput, + }) + @ValidateNested() + @Type(() => DeploymentWhereUniqueInput) + @Field(() => DeploymentWhereUniqueInput, { nullable: false }) + where!: DeploymentWhereUniqueInput; +} + +export { DeleteDeploymentArgs as DeleteDeploymentArgs }; diff --git a/apps/deployment-orchestrator-server/src/deployment/base/Deployment.ts b/apps/deployment-orchestrator-server/src/deployment/base/Deployment.ts new file mode 100644 index 000000000..826a0e185 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/Deployment.ts @@ -0,0 +1,143 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ObjectType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { + IsDate, + IsOptional, + IsString, + MaxLength, + ValidateNested, + IsEnum, +} from "class-validator"; +import { Type } from "class-transformer"; +import { PromptHandler } from "../../promptHandler/base/PromptHandler"; +import { IsJSONValue } from "../../validators"; +import { GraphQLJSON } from "graphql-type-json"; +import { JsonValue } from "type-fest"; +import { EnumDeploymentStatus } from "./EnumDeploymentStatus"; +import { UserProfile } from "../../userProfile/base/UserProfile"; + +@ObjectType() +class Deployment { + @ApiProperty({ + required: false, + }) + @IsDate() + @Type(() => Date) + @IsOptional() + @Field(() => Date, { + nullable: true, + }) + autoTerminateAt!: Date | null; + + @ApiProperty({ + required: true, + }) + @IsDate() + @Type(() => Date) + @Field(() => Date) + createdAt!: Date; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + environment!: string | null; + + @ApiProperty({ + required: true, + type: String, + }) + @IsString() + @Field(() => String) + id!: string; + + @ApiProperty({ + required: false, + type: () => [PromptHandler], + }) + @ValidateNested() + @Type(() => PromptHandler) + @IsOptional() + promptHandlers?: Array<PromptHandler>; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + region!: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + requestPrompt!: string | null; + + @ApiProperty({ + required: false, + }) + @IsJSONValue() + @IsOptional() + @Field(() => GraphQLJSON, { + nullable: true, + }) + resolvedConfig!: JsonValue; + + @ApiProperty({ + required: false, + enum: EnumDeploymentStatus, + }) + @IsEnum(EnumDeploymentStatus) + @IsOptional() + @Field(() => EnumDeploymentStatus, { + nullable: true, + }) + status?: "Option1" | null; + + @ApiProperty({ + required: true, + }) + @IsDate() + @Type(() => Date) + @Field(() => Date) + updatedAt!: Date; + + @ApiProperty({ + required: false, + type: () => UserProfile, + }) + @ValidateNested() + @Type(() => UserProfile) + @IsOptional() + userProfile?: UserProfile | null; +} + +export { Deployment as Deployment }; diff --git a/apps/deployment-orchestrator-server/src/deployment/base/DeploymentCountArgs.ts b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentCountArgs.ts new file mode 100644 index 000000000..9be5b79a0 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentCountArgs.ts @@ -0,0 +1,28 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { DeploymentWhereInput } from "./DeploymentWhereInput"; +import { Type } from "class-transformer"; + +@ArgsType() +class DeploymentCountArgs { + @ApiProperty({ + required: false, + type: () => DeploymentWhereInput, + }) + @Field(() => DeploymentWhereInput, { nullable: true }) + @Type(() => DeploymentWhereInput) + where?: DeploymentWhereInput; +} + +export { DeploymentCountArgs as DeploymentCountArgs }; diff --git a/apps/deployment-orchestrator-server/src/deployment/base/DeploymentCreateInput.ts b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentCreateInput.ts new file mode 100644 index 000000000..a4b5de210 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentCreateInput.ts @@ -0,0 +1,125 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { + IsDate, + IsOptional, + IsString, + MaxLength, + ValidateNested, + IsEnum, +} from "class-validator"; +import { Type } from "class-transformer"; +import { PromptHandlerCreateNestedManyWithoutDeploymentsInput } from "./PromptHandlerCreateNestedManyWithoutDeploymentsInput"; +import { IsJSONValue } from "../../validators"; +import { GraphQLJSON } from "graphql-type-json"; +import { InputJsonValue } from "../../types"; +import { EnumDeploymentStatus } from "./EnumDeploymentStatus"; +import { UserProfileWhereUniqueInput } from "../../userProfile/base/UserProfileWhereUniqueInput"; + +@InputType() +class DeploymentCreateInput { + @ApiProperty({ + required: false, + }) + @IsDate() + @Type(() => Date) + @IsOptional() + @Field(() => Date, { + nullable: true, + }) + autoTerminateAt?: Date | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + environment?: string | null; + + @ApiProperty({ + required: false, + type: () => PromptHandlerCreateNestedManyWithoutDeploymentsInput, + }) + @ValidateNested() + @Type(() => PromptHandlerCreateNestedManyWithoutDeploymentsInput) + @IsOptional() + @Field(() => PromptHandlerCreateNestedManyWithoutDeploymentsInput, { + nullable: true, + }) + promptHandlers?: PromptHandlerCreateNestedManyWithoutDeploymentsInput; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + region?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + requestPrompt?: string | null; + + @ApiProperty({ + required: false, + }) + @IsJSONValue() + @IsOptional() + @Field(() => GraphQLJSON, { + nullable: true, + }) + resolvedConfig?: InputJsonValue; + + @ApiProperty({ + required: false, + enum: EnumDeploymentStatus, + }) + @IsEnum(EnumDeploymentStatus) + @IsOptional() + @Field(() => EnumDeploymentStatus, { + nullable: true, + }) + status?: "Option1" | null; + + @ApiProperty({ + required: false, + type: () => UserProfileWhereUniqueInput, + }) + @ValidateNested() + @Type(() => UserProfileWhereUniqueInput) + @IsOptional() + @Field(() => UserProfileWhereUniqueInput, { + nullable: true, + }) + userProfile?: UserProfileWhereUniqueInput | null; +} + +export { DeploymentCreateInput as DeploymentCreateInput }; diff --git a/apps/deployment-orchestrator-server/src/deployment/base/DeploymentFindManyArgs.ts b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentFindManyArgs.ts new file mode 100644 index 000000000..3b8d77b9d --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentFindManyArgs.ts @@ -0,0 +1,62 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { DeploymentWhereInput } from "./DeploymentWhereInput"; +import { IsOptional, ValidateNested, IsInt } from "class-validator"; +import { Type } from "class-transformer"; +import { DeploymentOrderByInput } from "./DeploymentOrderByInput"; + +@ArgsType() +class DeploymentFindManyArgs { + @ApiProperty({ + required: false, + type: () => DeploymentWhereInput, + }) + @IsOptional() + @ValidateNested() + @Field(() => DeploymentWhereInput, { nullable: true }) + @Type(() => DeploymentWhereInput) + where?: DeploymentWhereInput; + + @ApiProperty({ + required: false, + type: [DeploymentOrderByInput], + }) + @IsOptional() + @ValidateNested({ each: true }) + @Field(() => [DeploymentOrderByInput], { nullable: true }) + @Type(() => DeploymentOrderByInput) + orderBy?: Array<DeploymentOrderByInput>; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @IsInt() + @Field(() => Number, { nullable: true }) + @Type(() => Number) + skip?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @IsInt() + @Field(() => Number, { nullable: true }) + @Type(() => Number) + take?: number; +} + +export { DeploymentFindManyArgs as DeploymentFindManyArgs }; diff --git a/apps/deployment-orchestrator-server/src/deployment/base/DeploymentFindUniqueArgs.ts b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentFindUniqueArgs.ts new file mode 100644 index 000000000..69e5ebcb5 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentFindUniqueArgs.ts @@ -0,0 +1,30 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { DeploymentWhereUniqueInput } from "./DeploymentWhereUniqueInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; + +@ArgsType() +class DeploymentFindUniqueArgs { + @ApiProperty({ + required: true, + type: () => DeploymentWhereUniqueInput, + }) + @ValidateNested() + @Type(() => DeploymentWhereUniqueInput) + @Field(() => DeploymentWhereUniqueInput, { nullable: false }) + where!: DeploymentWhereUniqueInput; +} + +export { DeploymentFindUniqueArgs as DeploymentFindUniqueArgs }; diff --git a/apps/deployment-orchestrator-server/src/deployment/base/DeploymentListRelationFilter.ts b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentListRelationFilter.ts new file mode 100644 index 000000000..36644ea8d --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentListRelationFilter.ts @@ -0,0 +1,56 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { DeploymentWhereInput } from "./DeploymentWhereInput"; +import { ValidateNested, IsOptional } from "class-validator"; +import { Type } from "class-transformer"; + +@InputType() +class DeploymentListRelationFilter { + @ApiProperty({ + required: false, + type: () => DeploymentWhereInput, + }) + @ValidateNested() + @Type(() => DeploymentWhereInput) + @IsOptional() + @Field(() => DeploymentWhereInput, { + nullable: true, + }) + every?: DeploymentWhereInput; + + @ApiProperty({ + required: false, + type: () => DeploymentWhereInput, + }) + @ValidateNested() + @Type(() => DeploymentWhereInput) + @IsOptional() + @Field(() => DeploymentWhereInput, { + nullable: true, + }) + some?: DeploymentWhereInput; + + @ApiProperty({ + required: false, + type: () => DeploymentWhereInput, + }) + @ValidateNested() + @Type(() => DeploymentWhereInput) + @IsOptional() + @Field(() => DeploymentWhereInput, { + nullable: true, + }) + none?: DeploymentWhereInput; +} +export { DeploymentListRelationFilter as DeploymentListRelationFilter }; diff --git a/apps/deployment-orchestrator-server/src/deployment/base/DeploymentOrderByInput.ts b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentOrderByInput.ts new file mode 100644 index 000000000..b05bd5f50 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentOrderByInput.ts @@ -0,0 +1,133 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional, IsEnum } from "class-validator"; +import { SortOrder } from "../../util/SortOrder"; + +@InputType({ + isAbstract: true, + description: undefined, +}) +class DeploymentOrderByInput { + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + autoTerminateAt?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + createdAt?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + environment?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + id?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + region?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + requestPrompt?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + resolvedConfig?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + status?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + updatedAt?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + userProfileId?: SortOrder; +} + +export { DeploymentOrderByInput as DeploymentOrderByInput }; diff --git a/apps/deployment-orchestrator-server/src/deployment/base/DeploymentUpdateInput.ts b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentUpdateInput.ts new file mode 100644 index 000000000..13ea311f6 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentUpdateInput.ts @@ -0,0 +1,125 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { + IsDate, + IsOptional, + IsString, + MaxLength, + ValidateNested, + IsEnum, +} from "class-validator"; +import { Type } from "class-transformer"; +import { PromptHandlerUpdateManyWithoutDeploymentsInput } from "./PromptHandlerUpdateManyWithoutDeploymentsInput"; +import { IsJSONValue } from "../../validators"; +import { GraphQLJSON } from "graphql-type-json"; +import { InputJsonValue } from "../../types"; +import { EnumDeploymentStatus } from "./EnumDeploymentStatus"; +import { UserProfileWhereUniqueInput } from "../../userProfile/base/UserProfileWhereUniqueInput"; + +@InputType() +class DeploymentUpdateInput { + @ApiProperty({ + required: false, + }) + @IsDate() + @Type(() => Date) + @IsOptional() + @Field(() => Date, { + nullable: true, + }) + autoTerminateAt?: Date | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + environment?: string | null; + + @ApiProperty({ + required: false, + type: () => PromptHandlerUpdateManyWithoutDeploymentsInput, + }) + @ValidateNested() + @Type(() => PromptHandlerUpdateManyWithoutDeploymentsInput) + @IsOptional() + @Field(() => PromptHandlerUpdateManyWithoutDeploymentsInput, { + nullable: true, + }) + promptHandlers?: PromptHandlerUpdateManyWithoutDeploymentsInput; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + region?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + requestPrompt?: string | null; + + @ApiProperty({ + required: false, + }) + @IsJSONValue() + @IsOptional() + @Field(() => GraphQLJSON, { + nullable: true, + }) + resolvedConfig?: InputJsonValue; + + @ApiProperty({ + required: false, + enum: EnumDeploymentStatus, + }) + @IsEnum(EnumDeploymentStatus) + @IsOptional() + @Field(() => EnumDeploymentStatus, { + nullable: true, + }) + status?: "Option1" | null; + + @ApiProperty({ + required: false, + type: () => UserProfileWhereUniqueInput, + }) + @ValidateNested() + @Type(() => UserProfileWhereUniqueInput) + @IsOptional() + @Field(() => UserProfileWhereUniqueInput, { + nullable: true, + }) + userProfile?: UserProfileWhereUniqueInput | null; +} + +export { DeploymentUpdateInput as DeploymentUpdateInput }; diff --git a/apps/deployment-orchestrator-server/src/deployment/base/DeploymentWhereInput.ts b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentWhereInput.ts new file mode 100644 index 000000000..8ded4c914 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentWhereInput.ts @@ -0,0 +1,128 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { DateTimeNullableFilter } from "../../util/DateTimeNullableFilter"; +import { Type } from "class-transformer"; +import { IsOptional, ValidateNested, IsEnum } from "class-validator"; +import { StringNullableFilter } from "../../util/StringNullableFilter"; +import { StringFilter } from "../../util/StringFilter"; +import { PromptHandlerListRelationFilter } from "../../promptHandler/base/PromptHandlerListRelationFilter"; +import { JsonFilter } from "../../util/JsonFilter"; +import { EnumDeploymentStatus } from "./EnumDeploymentStatus"; +import { UserProfileWhereUniqueInput } from "../../userProfile/base/UserProfileWhereUniqueInput"; + +@InputType() +class DeploymentWhereInput { + @ApiProperty({ + required: false, + type: DateTimeNullableFilter, + }) + @Type(() => DateTimeNullableFilter) + @IsOptional() + @Field(() => DateTimeNullableFilter, { + nullable: true, + }) + autoTerminateAt?: DateTimeNullableFilter; + + @ApiProperty({ + required: false, + type: StringNullableFilter, + }) + @Type(() => StringNullableFilter) + @IsOptional() + @Field(() => StringNullableFilter, { + nullable: true, + }) + environment?: StringNullableFilter; + + @ApiProperty({ + required: false, + type: StringFilter, + }) + @Type(() => StringFilter) + @IsOptional() + @Field(() => StringFilter, { + nullable: true, + }) + id?: StringFilter; + + @ApiProperty({ + required: false, + type: () => PromptHandlerListRelationFilter, + }) + @ValidateNested() + @Type(() => PromptHandlerListRelationFilter) + @IsOptional() + @Field(() => PromptHandlerListRelationFilter, { + nullable: true, + }) + promptHandlers?: PromptHandlerListRelationFilter; + + @ApiProperty({ + required: false, + type: StringNullableFilter, + }) + @Type(() => StringNullableFilter) + @IsOptional() + @Field(() => StringNullableFilter, { + nullable: true, + }) + region?: StringNullableFilter; + + @ApiProperty({ + required: false, + type: StringNullableFilter, + }) + @Type(() => StringNullableFilter) + @IsOptional() + @Field(() => StringNullableFilter, { + nullable: true, + }) + requestPrompt?: StringNullableFilter; + + @ApiProperty({ + required: false, + type: JsonFilter, + }) + @Type(() => JsonFilter) + @IsOptional() + @Field(() => JsonFilter, { + nullable: true, + }) + resolvedConfig?: JsonFilter; + + @ApiProperty({ + required: false, + enum: EnumDeploymentStatus, + }) + @IsEnum(EnumDeploymentStatus) + @IsOptional() + @Field(() => EnumDeploymentStatus, { + nullable: true, + }) + status?: "Option1"; + + @ApiProperty({ + required: false, + type: () => UserProfileWhereUniqueInput, + }) + @ValidateNested() + @Type(() => UserProfileWhereUniqueInput) + @IsOptional() + @Field(() => UserProfileWhereUniqueInput, { + nullable: true, + }) + userProfile?: UserProfileWhereUniqueInput; +} + +export { DeploymentWhereInput as DeploymentWhereInput }; diff --git a/apps/deployment-orchestrator-server/src/deployment/base/DeploymentWhereUniqueInput.ts b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentWhereUniqueInput.ts new file mode 100644 index 000000000..f8c2f9ab1 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/DeploymentWhereUniqueInput.ts @@ -0,0 +1,27 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsString } from "class-validator"; + +@InputType() +class DeploymentWhereUniqueInput { + @ApiProperty({ + required: true, + type: String, + }) + @IsString() + @Field(() => String) + id!: string; +} + +export { DeploymentWhereUniqueInput as DeploymentWhereUniqueInput }; diff --git a/apps/deployment-orchestrator-server/src/deployment/base/EnumDeploymentStatus.ts b/apps/deployment-orchestrator-server/src/deployment/base/EnumDeploymentStatus.ts new file mode 100644 index 000000000..a82f5b338 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/EnumDeploymentStatus.ts @@ -0,0 +1,20 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { registerEnumType } from "@nestjs/graphql"; + +export enum EnumDeploymentStatus { + Option_1 = "Option1", +} + +registerEnumType(EnumDeploymentStatus, { + name: "EnumDeploymentStatus", +}); diff --git a/apps/deployment-orchestrator-server/src/deployment/base/PromptHandlerCreateNestedManyWithoutDeploymentsInput.ts b/apps/deployment-orchestrator-server/src/deployment/base/PromptHandlerCreateNestedManyWithoutDeploymentsInput.ts new file mode 100644 index 000000000..55ab0e19f --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/PromptHandlerCreateNestedManyWithoutDeploymentsInput.ts @@ -0,0 +1,28 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { PromptHandlerWhereUniqueInput } from "../../promptHandler/base/PromptHandlerWhereUniqueInput"; +import { ApiProperty } from "@nestjs/swagger"; + +@InputType() +class PromptHandlerCreateNestedManyWithoutDeploymentsInput { + @Field(() => [PromptHandlerWhereUniqueInput], { + nullable: true, + }) + @ApiProperty({ + required: false, + type: () => [PromptHandlerWhereUniqueInput], + }) + connect?: Array<PromptHandlerWhereUniqueInput>; +} + +export { PromptHandlerCreateNestedManyWithoutDeploymentsInput as PromptHandlerCreateNestedManyWithoutDeploymentsInput }; diff --git a/apps/deployment-orchestrator-server/src/deployment/base/PromptHandlerUpdateManyWithoutDeploymentsInput.ts b/apps/deployment-orchestrator-server/src/deployment/base/PromptHandlerUpdateManyWithoutDeploymentsInput.ts new file mode 100644 index 000000000..8253ac96f --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/PromptHandlerUpdateManyWithoutDeploymentsInput.ts @@ -0,0 +1,46 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { PromptHandlerWhereUniqueInput } from "../../promptHandler/base/PromptHandlerWhereUniqueInput"; +import { ApiProperty } from "@nestjs/swagger"; + +@InputType() +class PromptHandlerUpdateManyWithoutDeploymentsInput { + @Field(() => [PromptHandlerWhereUniqueInput], { + nullable: true, + }) + @ApiProperty({ + required: false, + type: () => [PromptHandlerWhereUniqueInput], + }) + connect?: Array<PromptHandlerWhereUniqueInput>; + + @Field(() => [PromptHandlerWhereUniqueInput], { + nullable: true, + }) + @ApiProperty({ + required: false, + type: () => [PromptHandlerWhereUniqueInput], + }) + disconnect?: Array<PromptHandlerWhereUniqueInput>; + + @Field(() => [PromptHandlerWhereUniqueInput], { + nullable: true, + }) + @ApiProperty({ + required: false, + type: () => [PromptHandlerWhereUniqueInput], + }) + set?: Array<PromptHandlerWhereUniqueInput>; +} + +export { PromptHandlerUpdateManyWithoutDeploymentsInput as PromptHandlerUpdateManyWithoutDeploymentsInput }; diff --git a/apps/deployment-orchestrator-server/src/deployment/base/UpdateDeploymentArgs.ts b/apps/deployment-orchestrator-server/src/deployment/base/UpdateDeploymentArgs.ts new file mode 100644 index 000000000..8661ae19c --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/UpdateDeploymentArgs.ts @@ -0,0 +1,40 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { DeploymentWhereUniqueInput } from "./DeploymentWhereUniqueInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; +import { DeploymentUpdateInput } from "./DeploymentUpdateInput"; + +@ArgsType() +class UpdateDeploymentArgs { + @ApiProperty({ + required: true, + type: () => DeploymentWhereUniqueInput, + }) + @ValidateNested() + @Type(() => DeploymentWhereUniqueInput) + @Field(() => DeploymentWhereUniqueInput, { nullable: false }) + where!: DeploymentWhereUniqueInput; + + @ApiProperty({ + required: true, + type: () => DeploymentUpdateInput, + }) + @ValidateNested() + @Type(() => DeploymentUpdateInput) + @Field(() => DeploymentUpdateInput, { nullable: false }) + data!: DeploymentUpdateInput; +} + +export { UpdateDeploymentArgs as UpdateDeploymentArgs }; diff --git a/apps/deployment-orchestrator-server/src/deployment/base/deployment.controller.base.spec.ts b/apps/deployment-orchestrator-server/src/deployment/base/deployment.controller.base.spec.ts new file mode 100644 index 000000000..ec78ee491 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/deployment.controller.base.spec.ts @@ -0,0 +1,210 @@ +import { Test } from "@nestjs/testing"; +import { + INestApplication, + HttpStatus, + ExecutionContext, + CallHandler, +} from "@nestjs/common"; +import request from "supertest"; +import { ACGuard } from "nest-access-control"; +import { DefaultAuthGuard } from "../../auth/defaultAuth.guard"; +import { ACLModule } from "../../auth/acl.module"; +import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor"; +import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor"; +import { map } from "rxjs"; +import { DeploymentController } from "../deployment.controller"; +import { DeploymentService } from "../deployment.service"; + +const nonExistingId = "nonExistingId"; +const existingId = "existingId"; +const CREATE_INPUT = { + autoTerminateAt: new Date(), + createdAt: new Date(), + environment: "exampleEnvironment", + id: "exampleId", + region: "exampleRegion", + requestPrompt: "exampleRequestPrompt", + updatedAt: new Date(), +}; +const CREATE_RESULT = { + autoTerminateAt: new Date(), + createdAt: new Date(), + environment: "exampleEnvironment", + id: "exampleId", + region: "exampleRegion", + requestPrompt: "exampleRequestPrompt", + updatedAt: new Date(), +}; +const FIND_MANY_RESULT = [ + { + autoTerminateAt: new Date(), + createdAt: new Date(), + environment: "exampleEnvironment", + id: "exampleId", + region: "exampleRegion", + requestPrompt: "exampleRequestPrompt", + updatedAt: new Date(), + }, +]; +const FIND_ONE_RESULT = { + autoTerminateAt: new Date(), + createdAt: new Date(), + environment: "exampleEnvironment", + id: "exampleId", + region: "exampleRegion", + requestPrompt: "exampleRequestPrompt", + updatedAt: new Date(), +}; + +const service = { + createDeployment() { + return CREATE_RESULT; + }, + deployments: () => FIND_MANY_RESULT, + deployment: ({ where }: { where: { id: string } }) => { + switch (where.id) { + case existingId: + return FIND_ONE_RESULT; + case nonExistingId: + return null; + } + }, +}; + +const basicAuthGuard = { + canActivate: (context: ExecutionContext) => { + const argumentHost = context.switchToHttp(); + const request = argumentHost.getRequest(); + request.user = { + roles: ["user"], + }; + return true; + }, +}; + +const acGuard = { + canActivate: () => { + return true; + }, +}; + +const aclFilterResponseInterceptor = { + intercept: (context: ExecutionContext, next: CallHandler) => { + return next.handle().pipe( + map((data) => { + return data; + }) + ); + }, +}; +const aclValidateRequestInterceptor = { + intercept: (context: ExecutionContext, next: CallHandler) => { + return next.handle(); + }, +}; + +describe("Deployment", () => { + let app: INestApplication; + + beforeAll(async () => { + const moduleRef = await Test.createTestingModule({ + providers: [ + { + provide: DeploymentService, + useValue: service, + }, + ], + controllers: [DeploymentController], + imports: [ACLModule], + }) + .overrideGuard(DefaultAuthGuard) + .useValue(basicAuthGuard) + .overrideGuard(ACGuard) + .useValue(acGuard) + .overrideInterceptor(AclFilterResponseInterceptor) + .useValue(aclFilterResponseInterceptor) + .overrideInterceptor(AclValidateRequestInterceptor) + .useValue(aclValidateRequestInterceptor) + .compile(); + + app = moduleRef.createNestApplication(); + await app.init(); + }); + + test("POST /deployments", async () => { + await request(app.getHttpServer()) + .post("/deployments") + .send(CREATE_INPUT) + .expect(HttpStatus.CREATED) + .expect({ + ...CREATE_RESULT, + autoTerminateAt: CREATE_RESULT.autoTerminateAt.toISOString(), + createdAt: CREATE_RESULT.createdAt.toISOString(), + updatedAt: CREATE_RESULT.updatedAt.toISOString(), + }); + }); + + test("GET /deployments", async () => { + await request(app.getHttpServer()) + .get("/deployments") + .expect(HttpStatus.OK) + .expect([ + { + ...FIND_MANY_RESULT[0], + autoTerminateAt: FIND_MANY_RESULT[0].autoTerminateAt.toISOString(), + createdAt: FIND_MANY_RESULT[0].createdAt.toISOString(), + updatedAt: FIND_MANY_RESULT[0].updatedAt.toISOString(), + }, + ]); + }); + + test("GET /deployments/:id non existing", async () => { + await request(app.getHttpServer()) + .get(`${"/deployments"}/${nonExistingId}`) + .expect(HttpStatus.NOT_FOUND) + .expect({ + statusCode: HttpStatus.NOT_FOUND, + message: `No resource was found for {"${"id"}":"${nonExistingId}"}`, + error: "Not Found", + }); + }); + + test("GET /deployments/:id existing", async () => { + await request(app.getHttpServer()) + .get(`${"/deployments"}/${existingId}`) + .expect(HttpStatus.OK) + .expect({ + ...FIND_ONE_RESULT, + autoTerminateAt: FIND_ONE_RESULT.autoTerminateAt.toISOString(), + createdAt: FIND_ONE_RESULT.createdAt.toISOString(), + updatedAt: FIND_ONE_RESULT.updatedAt.toISOString(), + }); + }); + + test("POST /deployments existing resource", async () => { + const agent = request(app.getHttpServer()); + await agent + .post("/deployments") + .send(CREATE_INPUT) + .expect(HttpStatus.CREATED) + .expect({ + ...CREATE_RESULT, + autoTerminateAt: CREATE_RESULT.autoTerminateAt.toISOString(), + createdAt: CREATE_RESULT.createdAt.toISOString(), + updatedAt: CREATE_RESULT.updatedAt.toISOString(), + }) + .then(function () { + agent + .post("/deployments") + .send(CREATE_INPUT) + .expect(HttpStatus.CONFLICT) + .expect({ + statusCode: HttpStatus.CONFLICT, + }); + }); + }); + + afterAll(async () => { + await app.close(); + }); +}); diff --git a/apps/deployment-orchestrator-server/src/deployment/base/deployment.controller.base.ts b/apps/deployment-orchestrator-server/src/deployment/base/deployment.controller.base.ts new file mode 100644 index 000000000..4358fd167 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/deployment.controller.base.ts @@ -0,0 +1,295 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import * as common from "@nestjs/common"; +import * as swagger from "@nestjs/swagger"; +import { isRecordNotFoundError } from "../../prisma.util"; +import * as errors from "../../errors"; +import { Request } from "express"; +import { plainToClass } from "class-transformer"; +import { ApiNestedQuery } from "../../decorators/api-nested-query.decorator"; +import { DeploymentService } from "../deployment.service"; +import { DeploymentCreateInput } from "./DeploymentCreateInput"; +import { Deployment } from "./Deployment"; +import { DeploymentFindManyArgs } from "./DeploymentFindManyArgs"; +import { DeploymentWhereUniqueInput } from "./DeploymentWhereUniqueInput"; +import { DeploymentUpdateInput } from "./DeploymentUpdateInput"; +import { PromptHandlerFindManyArgs } from "../../promptHandler/base/PromptHandlerFindManyArgs"; +import { PromptHandler } from "../../promptHandler/base/PromptHandler"; +import { PromptHandlerWhereUniqueInput } from "../../promptHandler/base/PromptHandlerWhereUniqueInput"; + +export class DeploymentControllerBase { + constructor(protected readonly service: DeploymentService) {} + @common.Post() + @swagger.ApiCreatedResponse({ type: Deployment }) + async createDeployment( + @common.Body() data: DeploymentCreateInput + ): Promise<Deployment> { + return await this.service.createDeployment({ + data: { + ...data, + + userProfile: data.userProfile + ? { + connect: data.userProfile, + } + : undefined, + }, + select: { + autoTerminateAt: true, + createdAt: true, + environment: true, + id: true, + region: true, + requestPrompt: true, + resolvedConfig: true, + status: true, + updatedAt: true, + + userProfile: { + select: { + id: true, + }, + }, + }, + }); + } + + @common.Get() + @swagger.ApiOkResponse({ type: [Deployment] }) + @ApiNestedQuery(DeploymentFindManyArgs) + async deployments(@common.Req() request: Request): Promise<Deployment[]> { + const args = plainToClass(DeploymentFindManyArgs, request.query); + return this.service.deployments({ + ...args, + select: { + autoTerminateAt: true, + createdAt: true, + environment: true, + id: true, + region: true, + requestPrompt: true, + resolvedConfig: true, + status: true, + updatedAt: true, + + userProfile: { + select: { + id: true, + }, + }, + }, + }); + } + + @common.Get("/:id") + @swagger.ApiOkResponse({ type: Deployment }) + @swagger.ApiNotFoundResponse({ type: errors.NotFoundException }) + async deployment( + @common.Param() params: DeploymentWhereUniqueInput + ): Promise<Deployment | null> { + const result = await this.service.deployment({ + where: params, + select: { + autoTerminateAt: true, + createdAt: true, + environment: true, + id: true, + region: true, + requestPrompt: true, + resolvedConfig: true, + status: true, + updatedAt: true, + + userProfile: { + select: { + id: true, + }, + }, + }, + }); + if (result === null) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + return result; + } + + @common.Patch("/:id") + @swagger.ApiOkResponse({ type: Deployment }) + @swagger.ApiNotFoundResponse({ type: errors.NotFoundException }) + async updateDeployment( + @common.Param() params: DeploymentWhereUniqueInput, + @common.Body() data: DeploymentUpdateInput + ): Promise<Deployment | null> { + try { + return await this.service.updateDeployment({ + where: params, + data: { + ...data, + + userProfile: data.userProfile + ? { + connect: data.userProfile, + } + : undefined, + }, + select: { + autoTerminateAt: true, + createdAt: true, + environment: true, + id: true, + region: true, + requestPrompt: true, + resolvedConfig: true, + status: true, + updatedAt: true, + + userProfile: { + select: { + id: true, + }, + }, + }, + }); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + throw error; + } + } + + @common.Delete("/:id") + @swagger.ApiOkResponse({ type: Deployment }) + @swagger.ApiNotFoundResponse({ type: errors.NotFoundException }) + async deleteDeployment( + @common.Param() params: DeploymentWhereUniqueInput + ): Promise<Deployment | null> { + try { + return await this.service.deleteDeployment({ + where: params, + select: { + autoTerminateAt: true, + createdAt: true, + environment: true, + id: true, + region: true, + requestPrompt: true, + resolvedConfig: true, + status: true, + updatedAt: true, + + userProfile: { + select: { + id: true, + }, + }, + }, + }); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + throw error; + } + } + + @common.Get("/:id/promptHandlers") + @ApiNestedQuery(PromptHandlerFindManyArgs) + async findPromptHandlers( + @common.Req() request: Request, + @common.Param() params: DeploymentWhereUniqueInput + ): Promise<PromptHandler[]> { + const query = plainToClass(PromptHandlerFindManyArgs, request.query); + const results = await this.service.findPromptHandlers(params.id, { + ...query, + select: { + createdAt: true, + + deployment: { + select: { + id: true, + }, + }, + + detectedOs: true, + id: true, + inputPrompt: true, + parsedInstructions: true, + resourcesRequested: true, + updatedAt: true, + }, + }); + if (results === null) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + return results; + } + + @common.Post("/:id/promptHandlers") + async connectPromptHandlers( + @common.Param() params: DeploymentWhereUniqueInput, + @common.Body() body: PromptHandlerWhereUniqueInput[] + ): Promise<void> { + const data = { + promptHandlers: { + connect: body, + }, + }; + await this.service.updateDeployment({ + where: params, + data, + select: { id: true }, + }); + } + + @common.Patch("/:id/promptHandlers") + async updatePromptHandlers( + @common.Param() params: DeploymentWhereUniqueInput, + @common.Body() body: PromptHandlerWhereUniqueInput[] + ): Promise<void> { + const data = { + promptHandlers: { + set: body, + }, + }; + await this.service.updateDeployment({ + where: params, + data, + select: { id: true }, + }); + } + + @common.Delete("/:id/promptHandlers") + async disconnectPromptHandlers( + @common.Param() params: DeploymentWhereUniqueInput, + @common.Body() body: PromptHandlerWhereUniqueInput[] + ): Promise<void> { + const data = { + promptHandlers: { + disconnect: body, + }, + }; + await this.service.updateDeployment({ + where: params, + data, + select: { id: true }, + }); + } +} diff --git a/apps/deployment-orchestrator-server/src/deployment/base/deployment.module.base.ts b/apps/deployment-orchestrator-server/src/deployment/base/deployment.module.base.ts new file mode 100644 index 000000000..955318c0f --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/deployment.module.base.ts @@ -0,0 +1,18 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { Module } from "@nestjs/common"; + +@Module({ + imports: [], + exports: [], +}) +export class DeploymentModuleBase {} diff --git a/apps/deployment-orchestrator-server/src/deployment/base/deployment.resolver.base.ts b/apps/deployment-orchestrator-server/src/deployment/base/deployment.resolver.base.ts new file mode 100644 index 000000000..2b63878a2 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/deployment.resolver.base.ts @@ -0,0 +1,147 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import * as graphql from "@nestjs/graphql"; +import { GraphQLError } from "graphql"; +import { isRecordNotFoundError } from "../../prisma.util"; +import { MetaQueryPayload } from "../../util/MetaQueryPayload"; +import { Deployment } from "./Deployment"; +import { DeploymentCountArgs } from "./DeploymentCountArgs"; +import { DeploymentFindManyArgs } from "./DeploymentFindManyArgs"; +import { DeploymentFindUniqueArgs } from "./DeploymentFindUniqueArgs"; +import { CreateDeploymentArgs } from "./CreateDeploymentArgs"; +import { UpdateDeploymentArgs } from "./UpdateDeploymentArgs"; +import { DeleteDeploymentArgs } from "./DeleteDeploymentArgs"; +import { PromptHandlerFindManyArgs } from "../../promptHandler/base/PromptHandlerFindManyArgs"; +import { PromptHandler } from "../../promptHandler/base/PromptHandler"; +import { UserProfile } from "../../userProfile/base/UserProfile"; +import { DeploymentService } from "../deployment.service"; +@graphql.Resolver(() => Deployment) +export class DeploymentResolverBase { + constructor(protected readonly service: DeploymentService) {} + + async _deploymentsMeta( + @graphql.Args() args: DeploymentCountArgs + ): Promise<MetaQueryPayload> { + const result = await this.service.count(args); + return { + count: result, + }; + } + + @graphql.Query(() => [Deployment]) + async deployments( + @graphql.Args() args: DeploymentFindManyArgs + ): Promise<Deployment[]> { + return this.service.deployments(args); + } + + @graphql.Query(() => Deployment, { nullable: true }) + async deployment( + @graphql.Args() args: DeploymentFindUniqueArgs + ): Promise<Deployment | null> { + const result = await this.service.deployment(args); + if (result === null) { + return null; + } + return result; + } + + @graphql.Mutation(() => Deployment) + async createDeployment( + @graphql.Args() args: CreateDeploymentArgs + ): Promise<Deployment> { + return await this.service.createDeployment({ + ...args, + data: { + ...args.data, + + userProfile: args.data.userProfile + ? { + connect: args.data.userProfile, + } + : undefined, + }, + }); + } + + @graphql.Mutation(() => Deployment) + async updateDeployment( + @graphql.Args() args: UpdateDeploymentArgs + ): Promise<Deployment | null> { + try { + return await this.service.updateDeployment({ + ...args, + data: { + ...args.data, + + userProfile: args.data.userProfile + ? { + connect: args.data.userProfile, + } + : undefined, + }, + }); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new GraphQLError( + `No resource was found for ${JSON.stringify(args.where)}` + ); + } + throw error; + } + } + + @graphql.Mutation(() => Deployment) + async deleteDeployment( + @graphql.Args() args: DeleteDeploymentArgs + ): Promise<Deployment | null> { + try { + return await this.service.deleteDeployment(args); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new GraphQLError( + `No resource was found for ${JSON.stringify(args.where)}` + ); + } + throw error; + } + } + + @graphql.ResolveField(() => [PromptHandler], { name: "promptHandlers" }) + async findPromptHandlers( + @graphql.Parent() parent: Deployment, + @graphql.Args() args: PromptHandlerFindManyArgs + ): Promise<PromptHandler[]> { + const results = await this.service.findPromptHandlers(parent.id, args); + + if (!results) { + return []; + } + + return results; + } + + @graphql.ResolveField(() => UserProfile, { + nullable: true, + name: "userProfile", + }) + async getUserProfile( + @graphql.Parent() parent: Deployment + ): Promise<UserProfile | null> { + const result = await this.service.getUserProfile(parent.id); + + if (!result) { + return null; + } + return result; + } +} diff --git a/apps/deployment-orchestrator-server/src/deployment/base/deployment.service.base.ts b/apps/deployment-orchestrator-server/src/deployment/base/deployment.service.base.ts new file mode 100644 index 000000000..bf04778d4 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/base/deployment.service.base.ts @@ -0,0 +1,74 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { PrismaService } from "../../prisma/prisma.service"; + +import { + Prisma, + Deployment as PrismaDeployment, + PromptHandler as PrismaPromptHandler, + UserProfile as PrismaUserProfile, +} from "@prisma/client"; + +export class DeploymentServiceBase { + constructor(protected readonly prisma: PrismaService) {} + + async count( + args: Omit<Prisma.DeploymentCountArgs, "select"> + ): Promise<number> { + return this.prisma.deployment.count(args); + } + + async deployments( + args: Prisma.DeploymentFindManyArgs + ): Promise<PrismaDeployment[]> { + return this.prisma.deployment.findMany(args); + } + async deployment( + args: Prisma.DeploymentFindUniqueArgs + ): Promise<PrismaDeployment | null> { + return this.prisma.deployment.findUnique(args); + } + async createDeployment( + args: Prisma.DeploymentCreateArgs + ): Promise<PrismaDeployment> { + return this.prisma.deployment.create(args); + } + async updateDeployment( + args: Prisma.DeploymentUpdateArgs + ): Promise<PrismaDeployment> { + return this.prisma.deployment.update(args); + } + async deleteDeployment( + args: Prisma.DeploymentDeleteArgs + ): Promise<PrismaDeployment> { + return this.prisma.deployment.delete(args); + } + + async findPromptHandlers( + parentId: string, + args: Prisma.PromptHandlerFindManyArgs + ): Promise<PrismaPromptHandler[]> { + return this.prisma.deployment + .findUniqueOrThrow({ + where: { id: parentId }, + }) + .promptHandlers(args); + } + + async getUserProfile(parentId: string): Promise<PrismaUserProfile | null> { + return this.prisma.deployment + .findUnique({ + where: { id: parentId }, + }) + .userProfile(); + } +} diff --git a/apps/deployment-orchestrator-server/src/deployment/deployment.controller.ts b/apps/deployment-orchestrator-server/src/deployment/deployment.controller.ts new file mode 100644 index 000000000..c68efb4c5 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/deployment.controller.ts @@ -0,0 +1,12 @@ +import * as common from "@nestjs/common"; +import * as swagger from "@nestjs/swagger"; +import { DeploymentService } from "./deployment.service"; +import { DeploymentControllerBase } from "./base/deployment.controller.base"; + +@swagger.ApiTags("deployments") +@common.Controller("deployments") +export class DeploymentController extends DeploymentControllerBase { + constructor(protected readonly service: DeploymentService) { + super(service); + } +} diff --git a/apps/deployment-orchestrator-server/src/deployment/deployment.module.ts b/apps/deployment-orchestrator-server/src/deployment/deployment.module.ts new file mode 100644 index 000000000..9bcccb249 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/deployment.module.ts @@ -0,0 +1,13 @@ +import { Module } from "@nestjs/common"; +import { DeploymentModuleBase } from "./base/deployment.module.base"; +import { DeploymentService } from "./deployment.service"; +import { DeploymentController } from "./deployment.controller"; +import { DeploymentResolver } from "./deployment.resolver"; + +@Module({ + imports: [DeploymentModuleBase], + controllers: [DeploymentController], + providers: [DeploymentService, DeploymentResolver], + exports: [DeploymentService], +}) +export class DeploymentModule {} diff --git a/apps/deployment-orchestrator-server/src/deployment/deployment.resolver.ts b/apps/deployment-orchestrator-server/src/deployment/deployment.resolver.ts new file mode 100644 index 000000000..3f026c03d --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/deployment.resolver.ts @@ -0,0 +1,11 @@ +import * as graphql from "@nestjs/graphql"; +import { DeploymentResolverBase } from "./base/deployment.resolver.base"; +import { Deployment } from "./base/Deployment"; +import { DeploymentService } from "./deployment.service"; + +@graphql.Resolver(() => Deployment) +export class DeploymentResolver extends DeploymentResolverBase { + constructor(protected readonly service: DeploymentService) { + super(service); + } +} diff --git a/apps/deployment-orchestrator-server/src/deployment/deployment.service.ts b/apps/deployment-orchestrator-server/src/deployment/deployment.service.ts new file mode 100644 index 000000000..57aac5466 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/deployment.service.ts @@ -0,0 +1,10 @@ +import { Injectable } from "@nestjs/common"; +import { PrismaService } from "../prisma/prisma.service"; +import { DeploymentServiceBase } from "./base/deployment.service.base"; + +@Injectable() +export class DeploymentService extends DeploymentServiceBase { + constructor(protected readonly prisma: PrismaService) { + super(prisma); + } +} diff --git a/apps/deployment-orchestrator-server/src/errors.ts b/apps/deployment-orchestrator-server/src/errors.ts new file mode 100644 index 000000000..bd1aa6dad --- /dev/null +++ b/apps/deployment-orchestrator-server/src/errors.ts @@ -0,0 +1,16 @@ +import * as common from "@nestjs/common"; +import { ApiProperty } from "@nestjs/swagger"; + +export class ForbiddenException extends common.ForbiddenException { + @ApiProperty() + statusCode!: number; + @ApiProperty() + message!: string; +} + +export class NotFoundException extends common.NotFoundException { + @ApiProperty() + statusCode!: number; + @ApiProperty() + message!: string; +} diff --git a/apps/deployment-orchestrator-server/src/filters/HttpExceptions.filter.ts b/apps/deployment-orchestrator-server/src/filters/HttpExceptions.filter.ts new file mode 100644 index 000000000..f5eda8e39 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/filters/HttpExceptions.filter.ts @@ -0,0 +1,89 @@ +import { + ArgumentsHost, + Catch, + HttpException, + HttpServer, + HttpStatus, +} from "@nestjs/common"; +import { BaseExceptionFilter } from "@nestjs/core"; +import { Prisma } from "@prisma/client"; +import { Response } from "express"; + +export type ErrorCodesStatusMapping = { + [key: string]: number; +}; + +/** + * {@link PrismaClientExceptionFilter} handling {@link Prisma.PrismaClientKnownRequestError} exceptions. + */ +@Catch(Prisma?.PrismaClientKnownRequestError) +export class HttpExceptionFilter extends BaseExceptionFilter { + /** + * default error codes mapping + * + * Error codes definition for Prisma Client (Query Engine) + * @see https://www.prisma.io/docs/reference/api-reference/error-reference#prisma-client-query-engine + */ + private errorCodesStatusMapping: ErrorCodesStatusMapping = { + P2000: HttpStatus.BAD_REQUEST, + P2002: HttpStatus.CONFLICT, + P2025: HttpStatus.NOT_FOUND, + }; + + /** + * @param applicationRef + */ + // eslint-disable-next-line @typescript-eslint/no-useless-constructor + constructor(applicationRef?: HttpServer) { + super(applicationRef); + } + + /** + * @param exception + * @param host + * @returns + */ + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + catch(exception: Prisma.PrismaClientKnownRequestError, host: ArgumentsHost) { + const statusCode = this.errorCodesStatusMapping[exception.code]; + let message; + if (host.getType() === "http") { + // for http requests (REST) + // Todo : Add all other exception types and also add mapping + const ctx = host.switchToHttp(); + const response = ctx.getResponse<Response>(); + if (exception.code === "P2002") { + // Handling Unique Key Constraint Violation Error + const fields = (exception.meta as { target: string[] }).target; + message = `Another record with the requested (${fields.join( + ", " + )}) already exists`; + } else { + message = + `[${exception.code}]: ` + + this.exceptionShortMessage(exception.message); + } + if (!Object.keys(this.errorCodesStatusMapping).includes(exception.code)) { + return super.catch(exception, host); + } + const errorResponse = { + message: message, + statusCode: statusCode, + }; + response.status(statusCode).send(errorResponse); + } + return new HttpException({ statusCode, message }, statusCode); + } + + /** + * @param exception + * @returns short message for the exception + */ + exceptionShortMessage(message: string): string { + const shortMessage = message.substring(message.indexOf("→")); + return shortMessage + .substring(shortMessage.indexOf("\n")) + .replace(/\n/g, "") + .trim(); + } +} diff --git a/apps/deployment-orchestrator-server/src/health/base/health.controller.base.ts b/apps/deployment-orchestrator-server/src/health/base/health.controller.base.ts new file mode 100644 index 000000000..afd9e0ddd --- /dev/null +++ b/apps/deployment-orchestrator-server/src/health/base/health.controller.base.ts @@ -0,0 +1,19 @@ +import { Get, HttpStatus, Res } from "@nestjs/common"; +import { Response } from "express"; +import { HealthService } from "../health.service"; + +export class HealthControllerBase { + constructor(protected readonly healthService: HealthService) {} + @Get("live") + healthLive(@Res() response: Response): Response<void> { + return response.status(HttpStatus.NO_CONTENT).send(); + } + @Get("ready") + async healthReady(@Res() response: Response): Promise<Response<void>> { + const dbConnection = await this.healthService.isDbReady(); + if (!dbConnection) { + return response.status(HttpStatus.NOT_FOUND).send(); + } + return response.status(HttpStatus.NO_CONTENT).send(); + } +} diff --git a/apps/deployment-orchestrator-server/src/health/base/health.service.base.ts b/apps/deployment-orchestrator-server/src/health/base/health.service.base.ts new file mode 100644 index 000000000..49a93a510 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/health/base/health.service.base.ts @@ -0,0 +1,15 @@ +import { Injectable } from "@nestjs/common"; +import { PrismaService } from "../../prisma/prisma.service"; + +@Injectable() +export class HealthServiceBase { + constructor(protected readonly prisma: PrismaService) {} + async isDbReady(): Promise<boolean> { + try { + await this.prisma.$queryRaw`SELECT 1`; + return true; + } catch (error) { + return false; + } + } +} diff --git a/apps/deployment-orchestrator-server/src/health/health.controller.ts b/apps/deployment-orchestrator-server/src/health/health.controller.ts new file mode 100644 index 000000000..ff484e783 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/health/health.controller.ts @@ -0,0 +1,10 @@ +import { Controller } from "@nestjs/common"; +import { HealthControllerBase } from "./base/health.controller.base"; +import { HealthService } from "./health.service"; + +@Controller("_health") +export class HealthController extends HealthControllerBase { + constructor(protected readonly healthService: HealthService) { + super(healthService); + } +} diff --git a/apps/deployment-orchestrator-server/src/health/health.module.ts b/apps/deployment-orchestrator-server/src/health/health.module.ts new file mode 100644 index 000000000..39eff7f11 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/health/health.module.ts @@ -0,0 +1,10 @@ +import { Module } from "@nestjs/common"; +import { HealthController } from "./health.controller"; +import { HealthService } from "./health.service"; + +@Module({ + controllers: [HealthController], + providers: [HealthService], + exports: [HealthService], +}) +export class HealthModule {} diff --git a/apps/deployment-orchestrator-server/src/health/health.service.ts b/apps/deployment-orchestrator-server/src/health/health.service.ts new file mode 100644 index 000000000..44d934322 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/health/health.service.ts @@ -0,0 +1,10 @@ +import { Injectable } from "@nestjs/common"; +import { PrismaService } from "../prisma/prisma.service"; +import { HealthServiceBase } from "./base/health.service.base"; + +@Injectable() +export class HealthService extends HealthServiceBase { + constructor(protected readonly prisma: PrismaService) { + super(prisma); + } +} diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/CreateLlmIntegrationArgs.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/CreateLlmIntegrationArgs.ts new file mode 100644 index 000000000..1a859d25c --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/CreateLlmIntegrationArgs.ts @@ -0,0 +1,30 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { LlmIntegrationCreateInput } from "./LlmIntegrationCreateInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; + +@ArgsType() +class CreateLlmIntegrationArgs { + @ApiProperty({ + required: true, + type: () => LlmIntegrationCreateInput, + }) + @ValidateNested() + @Type(() => LlmIntegrationCreateInput) + @Field(() => LlmIntegrationCreateInput, { nullable: false }) + data!: LlmIntegrationCreateInput; +} + +export { CreateLlmIntegrationArgs as CreateLlmIntegrationArgs }; diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/DeleteLlmIntegrationArgs.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/DeleteLlmIntegrationArgs.ts new file mode 100644 index 000000000..63d80d605 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/DeleteLlmIntegrationArgs.ts @@ -0,0 +1,30 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { LlmIntegrationWhereUniqueInput } from "./LlmIntegrationWhereUniqueInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; + +@ArgsType() +class DeleteLlmIntegrationArgs { + @ApiProperty({ + required: true, + type: () => LlmIntegrationWhereUniqueInput, + }) + @ValidateNested() + @Type(() => LlmIntegrationWhereUniqueInput) + @Field(() => LlmIntegrationWhereUniqueInput, { nullable: false }) + where!: LlmIntegrationWhereUniqueInput; +} + +export { DeleteLlmIntegrationArgs as DeleteLlmIntegrationArgs }; diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegration.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegration.ts new file mode 100644 index 000000000..59ff5c221 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegration.ts @@ -0,0 +1,108 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ObjectType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { + IsString, + MaxLength, + IsOptional, + IsDate, + ValidateNested, +} from "class-validator"; +import { Type } from "class-transformer"; +import { PromptHandler } from "../../promptHandler/base/PromptHandler"; + +@ObjectType() +class LlmIntegration { + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + apiEndpoint!: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + apiKeyName!: string | null; + + @ApiProperty({ + required: true, + }) + @IsDate() + @Type(() => Date) + @Field(() => Date) + createdAt!: Date; + + @ApiProperty({ + required: true, + type: String, + }) + @IsString() + @Field(() => String) + id!: string; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + modelUsed!: string | null; + + @ApiProperty({ + required: false, + type: () => PromptHandler, + }) + @ValidateNested() + @Type(() => PromptHandler) + @IsOptional() + promptHandler?: PromptHandler | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + provider!: string | null; + + @ApiProperty({ + required: true, + }) + @IsDate() + @Type(() => Date) + @Field(() => Date) + updatedAt!: Date; +} + +export { LlmIntegration as LlmIntegration }; diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationCountArgs.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationCountArgs.ts new file mode 100644 index 000000000..ffe7790de --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationCountArgs.ts @@ -0,0 +1,28 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { LlmIntegrationWhereInput } from "./LlmIntegrationWhereInput"; +import { Type } from "class-transformer"; + +@ArgsType() +class LlmIntegrationCountArgs { + @ApiProperty({ + required: false, + type: () => LlmIntegrationWhereInput, + }) + @Field(() => LlmIntegrationWhereInput, { nullable: true }) + @Type(() => LlmIntegrationWhereInput) + where?: LlmIntegrationWhereInput; +} + +export { LlmIntegrationCountArgs as LlmIntegrationCountArgs }; diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationCreateInput.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationCreateInput.ts new file mode 100644 index 000000000..8626383f3 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationCreateInput.ts @@ -0,0 +1,86 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { + IsString, + MaxLength, + IsOptional, + ValidateNested, +} from "class-validator"; +import { PromptHandlerWhereUniqueInput } from "../../promptHandler/base/PromptHandlerWhereUniqueInput"; +import { Type } from "class-transformer"; + +@InputType() +class LlmIntegrationCreateInput { + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + apiEndpoint?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + apiKeyName?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + modelUsed?: string | null; + + @ApiProperty({ + required: false, + type: () => PromptHandlerWhereUniqueInput, + }) + @ValidateNested() + @Type(() => PromptHandlerWhereUniqueInput) + @IsOptional() + @Field(() => PromptHandlerWhereUniqueInput, { + nullable: true, + }) + promptHandler?: PromptHandlerWhereUniqueInput | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + provider?: string | null; +} + +export { LlmIntegrationCreateInput as LlmIntegrationCreateInput }; diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationFindManyArgs.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationFindManyArgs.ts new file mode 100644 index 000000000..9222a7d61 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationFindManyArgs.ts @@ -0,0 +1,62 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { LlmIntegrationWhereInput } from "./LlmIntegrationWhereInput"; +import { IsOptional, ValidateNested, IsInt } from "class-validator"; +import { Type } from "class-transformer"; +import { LlmIntegrationOrderByInput } from "./LlmIntegrationOrderByInput"; + +@ArgsType() +class LlmIntegrationFindManyArgs { + @ApiProperty({ + required: false, + type: () => LlmIntegrationWhereInput, + }) + @IsOptional() + @ValidateNested() + @Field(() => LlmIntegrationWhereInput, { nullable: true }) + @Type(() => LlmIntegrationWhereInput) + where?: LlmIntegrationWhereInput; + + @ApiProperty({ + required: false, + type: [LlmIntegrationOrderByInput], + }) + @IsOptional() + @ValidateNested({ each: true }) + @Field(() => [LlmIntegrationOrderByInput], { nullable: true }) + @Type(() => LlmIntegrationOrderByInput) + orderBy?: Array<LlmIntegrationOrderByInput>; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @IsInt() + @Field(() => Number, { nullable: true }) + @Type(() => Number) + skip?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @IsInt() + @Field(() => Number, { nullable: true }) + @Type(() => Number) + take?: number; +} + +export { LlmIntegrationFindManyArgs as LlmIntegrationFindManyArgs }; diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationFindUniqueArgs.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationFindUniqueArgs.ts new file mode 100644 index 000000000..76efc4a03 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationFindUniqueArgs.ts @@ -0,0 +1,30 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { LlmIntegrationWhereUniqueInput } from "./LlmIntegrationWhereUniqueInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; + +@ArgsType() +class LlmIntegrationFindUniqueArgs { + @ApiProperty({ + required: true, + type: () => LlmIntegrationWhereUniqueInput, + }) + @ValidateNested() + @Type(() => LlmIntegrationWhereUniqueInput) + @Field(() => LlmIntegrationWhereUniqueInput, { nullable: false }) + where!: LlmIntegrationWhereUniqueInput; +} + +export { LlmIntegrationFindUniqueArgs as LlmIntegrationFindUniqueArgs }; diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationListRelationFilter.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationListRelationFilter.ts new file mode 100644 index 000000000..6ff3be3f9 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationListRelationFilter.ts @@ -0,0 +1,56 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { LlmIntegrationWhereInput } from "./LlmIntegrationWhereInput"; +import { ValidateNested, IsOptional } from "class-validator"; +import { Type } from "class-transformer"; + +@InputType() +class LlmIntegrationListRelationFilter { + @ApiProperty({ + required: false, + type: () => LlmIntegrationWhereInput, + }) + @ValidateNested() + @Type(() => LlmIntegrationWhereInput) + @IsOptional() + @Field(() => LlmIntegrationWhereInput, { + nullable: true, + }) + every?: LlmIntegrationWhereInput; + + @ApiProperty({ + required: false, + type: () => LlmIntegrationWhereInput, + }) + @ValidateNested() + @Type(() => LlmIntegrationWhereInput) + @IsOptional() + @Field(() => LlmIntegrationWhereInput, { + nullable: true, + }) + some?: LlmIntegrationWhereInput; + + @ApiProperty({ + required: false, + type: () => LlmIntegrationWhereInput, + }) + @ValidateNested() + @Type(() => LlmIntegrationWhereInput) + @IsOptional() + @Field(() => LlmIntegrationWhereInput, { + nullable: true, + }) + none?: LlmIntegrationWhereInput; +} +export { LlmIntegrationListRelationFilter as LlmIntegrationListRelationFilter }; diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationOrderByInput.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationOrderByInput.ts new file mode 100644 index 000000000..8e1a4a288 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationOrderByInput.ts @@ -0,0 +1,111 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional, IsEnum } from "class-validator"; +import { SortOrder } from "../../util/SortOrder"; + +@InputType({ + isAbstract: true, + description: undefined, +}) +class LlmIntegrationOrderByInput { + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + apiEndpoint?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + apiKeyName?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + createdAt?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + id?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + modelUsed?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + promptHandlerId?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + provider?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + updatedAt?: SortOrder; +} + +export { LlmIntegrationOrderByInput as LlmIntegrationOrderByInput }; diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationUpdateInput.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationUpdateInput.ts new file mode 100644 index 000000000..d8e3aa423 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationUpdateInput.ts @@ -0,0 +1,86 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { + IsString, + MaxLength, + IsOptional, + ValidateNested, +} from "class-validator"; +import { PromptHandlerWhereUniqueInput } from "../../promptHandler/base/PromptHandlerWhereUniqueInput"; +import { Type } from "class-transformer"; + +@InputType() +class LlmIntegrationUpdateInput { + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + apiEndpoint?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + apiKeyName?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + modelUsed?: string | null; + + @ApiProperty({ + required: false, + type: () => PromptHandlerWhereUniqueInput, + }) + @ValidateNested() + @Type(() => PromptHandlerWhereUniqueInput) + @IsOptional() + @Field(() => PromptHandlerWhereUniqueInput, { + nullable: true, + }) + promptHandler?: PromptHandlerWhereUniqueInput | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + provider?: string | null; +} + +export { LlmIntegrationUpdateInput as LlmIntegrationUpdateInput }; diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationWhereInput.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationWhereInput.ts new file mode 100644 index 000000000..9d9fbb1df --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationWhereInput.ts @@ -0,0 +1,90 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { StringNullableFilter } from "../../util/StringNullableFilter"; +import { Type } from "class-transformer"; +import { IsOptional, ValidateNested } from "class-validator"; +import { StringFilter } from "../../util/StringFilter"; +import { PromptHandlerWhereUniqueInput } from "../../promptHandler/base/PromptHandlerWhereUniqueInput"; + +@InputType() +class LlmIntegrationWhereInput { + @ApiProperty({ + required: false, + type: StringNullableFilter, + }) + @Type(() => StringNullableFilter) + @IsOptional() + @Field(() => StringNullableFilter, { + nullable: true, + }) + apiEndpoint?: StringNullableFilter; + + @ApiProperty({ + required: false, + type: StringNullableFilter, + }) + @Type(() => StringNullableFilter) + @IsOptional() + @Field(() => StringNullableFilter, { + nullable: true, + }) + apiKeyName?: StringNullableFilter; + + @ApiProperty({ + required: false, + type: StringFilter, + }) + @Type(() => StringFilter) + @IsOptional() + @Field(() => StringFilter, { + nullable: true, + }) + id?: StringFilter; + + @ApiProperty({ + required: false, + type: StringNullableFilter, + }) + @Type(() => StringNullableFilter) + @IsOptional() + @Field(() => StringNullableFilter, { + nullable: true, + }) + modelUsed?: StringNullableFilter; + + @ApiProperty({ + required: false, + type: () => PromptHandlerWhereUniqueInput, + }) + @ValidateNested() + @Type(() => PromptHandlerWhereUniqueInput) + @IsOptional() + @Field(() => PromptHandlerWhereUniqueInput, { + nullable: true, + }) + promptHandler?: PromptHandlerWhereUniqueInput; + + @ApiProperty({ + required: false, + type: StringNullableFilter, + }) + @Type(() => StringNullableFilter) + @IsOptional() + @Field(() => StringNullableFilter, { + nullable: true, + }) + provider?: StringNullableFilter; +} + +export { LlmIntegrationWhereInput as LlmIntegrationWhereInput }; diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationWhereUniqueInput.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationWhereUniqueInput.ts new file mode 100644 index 000000000..cc21c6dd8 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/LlmIntegrationWhereUniqueInput.ts @@ -0,0 +1,27 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsString } from "class-validator"; + +@InputType() +class LlmIntegrationWhereUniqueInput { + @ApiProperty({ + required: true, + type: String, + }) + @IsString() + @Field(() => String) + id!: string; +} + +export { LlmIntegrationWhereUniqueInput as LlmIntegrationWhereUniqueInput }; diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/UpdateLlmIntegrationArgs.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/UpdateLlmIntegrationArgs.ts new file mode 100644 index 000000000..379cbfd2f --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/UpdateLlmIntegrationArgs.ts @@ -0,0 +1,40 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { LlmIntegrationWhereUniqueInput } from "./LlmIntegrationWhereUniqueInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; +import { LlmIntegrationUpdateInput } from "./LlmIntegrationUpdateInput"; + +@ArgsType() +class UpdateLlmIntegrationArgs { + @ApiProperty({ + required: true, + type: () => LlmIntegrationWhereUniqueInput, + }) + @ValidateNested() + @Type(() => LlmIntegrationWhereUniqueInput) + @Field(() => LlmIntegrationWhereUniqueInput, { nullable: false }) + where!: LlmIntegrationWhereUniqueInput; + + @ApiProperty({ + required: true, + type: () => LlmIntegrationUpdateInput, + }) + @ValidateNested() + @Type(() => LlmIntegrationUpdateInput) + @Field(() => LlmIntegrationUpdateInput, { nullable: false }) + data!: LlmIntegrationUpdateInput; +} + +export { UpdateLlmIntegrationArgs as UpdateLlmIntegrationArgs }; diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.controller.base.spec.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.controller.base.spec.ts new file mode 100644 index 000000000..72ece3012 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.controller.base.spec.ts @@ -0,0 +1,206 @@ +import { Test } from "@nestjs/testing"; +import { + INestApplication, + HttpStatus, + ExecutionContext, + CallHandler, +} from "@nestjs/common"; +import request from "supertest"; +import { ACGuard } from "nest-access-control"; +import { DefaultAuthGuard } from "../../auth/defaultAuth.guard"; +import { ACLModule } from "../../auth/acl.module"; +import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor"; +import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor"; +import { map } from "rxjs"; +import { LlmIntegrationController } from "../llmIntegration.controller"; +import { LlmIntegrationService } from "../llmIntegration.service"; + +const nonExistingId = "nonExistingId"; +const existingId = "existingId"; +const CREATE_INPUT = { + apiEndpoint: "exampleApiEndpoint", + apiKeyName: "exampleApiKeyName", + createdAt: new Date(), + id: "exampleId", + modelUsed: "exampleModelUsed", + provider: "exampleProvider", + updatedAt: new Date(), +}; +const CREATE_RESULT = { + apiEndpoint: "exampleApiEndpoint", + apiKeyName: "exampleApiKeyName", + createdAt: new Date(), + id: "exampleId", + modelUsed: "exampleModelUsed", + provider: "exampleProvider", + updatedAt: new Date(), +}; +const FIND_MANY_RESULT = [ + { + apiEndpoint: "exampleApiEndpoint", + apiKeyName: "exampleApiKeyName", + createdAt: new Date(), + id: "exampleId", + modelUsed: "exampleModelUsed", + provider: "exampleProvider", + updatedAt: new Date(), + }, +]; +const FIND_ONE_RESULT = { + apiEndpoint: "exampleApiEndpoint", + apiKeyName: "exampleApiKeyName", + createdAt: new Date(), + id: "exampleId", + modelUsed: "exampleModelUsed", + provider: "exampleProvider", + updatedAt: new Date(), +}; + +const service = { + createLlmIntegration() { + return CREATE_RESULT; + }, + llmIntegrations: () => FIND_MANY_RESULT, + llmIntegration: ({ where }: { where: { id: string } }) => { + switch (where.id) { + case existingId: + return FIND_ONE_RESULT; + case nonExistingId: + return null; + } + }, +}; + +const basicAuthGuard = { + canActivate: (context: ExecutionContext) => { + const argumentHost = context.switchToHttp(); + const request = argumentHost.getRequest(); + request.user = { + roles: ["user"], + }; + return true; + }, +}; + +const acGuard = { + canActivate: () => { + return true; + }, +}; + +const aclFilterResponseInterceptor = { + intercept: (context: ExecutionContext, next: CallHandler) => { + return next.handle().pipe( + map((data) => { + return data; + }) + ); + }, +}; +const aclValidateRequestInterceptor = { + intercept: (context: ExecutionContext, next: CallHandler) => { + return next.handle(); + }, +}; + +describe("LlmIntegration", () => { + let app: INestApplication; + + beforeAll(async () => { + const moduleRef = await Test.createTestingModule({ + providers: [ + { + provide: LlmIntegrationService, + useValue: service, + }, + ], + controllers: [LlmIntegrationController], + imports: [ACLModule], + }) + .overrideGuard(DefaultAuthGuard) + .useValue(basicAuthGuard) + .overrideGuard(ACGuard) + .useValue(acGuard) + .overrideInterceptor(AclFilterResponseInterceptor) + .useValue(aclFilterResponseInterceptor) + .overrideInterceptor(AclValidateRequestInterceptor) + .useValue(aclValidateRequestInterceptor) + .compile(); + + app = moduleRef.createNestApplication(); + await app.init(); + }); + + test("POST /llmIntegrations", async () => { + await request(app.getHttpServer()) + .post("/llmIntegrations") + .send(CREATE_INPUT) + .expect(HttpStatus.CREATED) + .expect({ + ...CREATE_RESULT, + createdAt: CREATE_RESULT.createdAt.toISOString(), + updatedAt: CREATE_RESULT.updatedAt.toISOString(), + }); + }); + + test("GET /llmIntegrations", async () => { + await request(app.getHttpServer()) + .get("/llmIntegrations") + .expect(HttpStatus.OK) + .expect([ + { + ...FIND_MANY_RESULT[0], + createdAt: FIND_MANY_RESULT[0].createdAt.toISOString(), + updatedAt: FIND_MANY_RESULT[0].updatedAt.toISOString(), + }, + ]); + }); + + test("GET /llmIntegrations/:id non existing", async () => { + await request(app.getHttpServer()) + .get(`${"/llmIntegrations"}/${nonExistingId}`) + .expect(HttpStatus.NOT_FOUND) + .expect({ + statusCode: HttpStatus.NOT_FOUND, + message: `No resource was found for {"${"id"}":"${nonExistingId}"}`, + error: "Not Found", + }); + }); + + test("GET /llmIntegrations/:id existing", async () => { + await request(app.getHttpServer()) + .get(`${"/llmIntegrations"}/${existingId}`) + .expect(HttpStatus.OK) + .expect({ + ...FIND_ONE_RESULT, + createdAt: FIND_ONE_RESULT.createdAt.toISOString(), + updatedAt: FIND_ONE_RESULT.updatedAt.toISOString(), + }); + }); + + test("POST /llmIntegrations existing resource", async () => { + const agent = request(app.getHttpServer()); + await agent + .post("/llmIntegrations") + .send(CREATE_INPUT) + .expect(HttpStatus.CREATED) + .expect({ + ...CREATE_RESULT, + createdAt: CREATE_RESULT.createdAt.toISOString(), + updatedAt: CREATE_RESULT.updatedAt.toISOString(), + }) + .then(function () { + agent + .post("/llmIntegrations") + .send(CREATE_INPUT) + .expect(HttpStatus.CONFLICT) + .expect({ + statusCode: HttpStatus.CONFLICT, + }); + }); + }); + + afterAll(async () => { + await app.close(); + }); +}); diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.controller.base.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.controller.base.ts new file mode 100644 index 000000000..9371c58c0 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.controller.base.ts @@ -0,0 +1,204 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import * as common from "@nestjs/common"; +import * as swagger from "@nestjs/swagger"; +import { isRecordNotFoundError } from "../../prisma.util"; +import * as errors from "../../errors"; +import { Request } from "express"; +import { plainToClass } from "class-transformer"; +import { ApiNestedQuery } from "../../decorators/api-nested-query.decorator"; +import { LlmIntegrationService } from "../llmIntegration.service"; +import { LlmIntegrationCreateInput } from "./LlmIntegrationCreateInput"; +import { LlmIntegration } from "./LlmIntegration"; +import { LlmIntegrationFindManyArgs } from "./LlmIntegrationFindManyArgs"; +import { LlmIntegrationWhereUniqueInput } from "./LlmIntegrationWhereUniqueInput"; +import { LlmIntegrationUpdateInput } from "./LlmIntegrationUpdateInput"; + +export class LlmIntegrationControllerBase { + constructor(protected readonly service: LlmIntegrationService) {} + @common.Post() + @swagger.ApiCreatedResponse({ type: LlmIntegration }) + async createLlmIntegration( + @common.Body() data: LlmIntegrationCreateInput + ): Promise<LlmIntegration> { + return await this.service.createLlmIntegration({ + data: { + ...data, + + promptHandler: data.promptHandler + ? { + connect: data.promptHandler, + } + : undefined, + }, + select: { + apiEndpoint: true, + apiKeyName: true, + createdAt: true, + id: true, + modelUsed: true, + + promptHandler: { + select: { + id: true, + }, + }, + + provider: true, + updatedAt: true, + }, + }); + } + + @common.Get() + @swagger.ApiOkResponse({ type: [LlmIntegration] }) + @ApiNestedQuery(LlmIntegrationFindManyArgs) + async llmIntegrations( + @common.Req() request: Request + ): Promise<LlmIntegration[]> { + const args = plainToClass(LlmIntegrationFindManyArgs, request.query); + return this.service.llmIntegrations({ + ...args, + select: { + apiEndpoint: true, + apiKeyName: true, + createdAt: true, + id: true, + modelUsed: true, + + promptHandler: { + select: { + id: true, + }, + }, + + provider: true, + updatedAt: true, + }, + }); + } + + @common.Get("/:id") + @swagger.ApiOkResponse({ type: LlmIntegration }) + @swagger.ApiNotFoundResponse({ type: errors.NotFoundException }) + async llmIntegration( + @common.Param() params: LlmIntegrationWhereUniqueInput + ): Promise<LlmIntegration | null> { + const result = await this.service.llmIntegration({ + where: params, + select: { + apiEndpoint: true, + apiKeyName: true, + createdAt: true, + id: true, + modelUsed: true, + + promptHandler: { + select: { + id: true, + }, + }, + + provider: true, + updatedAt: true, + }, + }); + if (result === null) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + return result; + } + + @common.Patch("/:id") + @swagger.ApiOkResponse({ type: LlmIntegration }) + @swagger.ApiNotFoundResponse({ type: errors.NotFoundException }) + async updateLlmIntegration( + @common.Param() params: LlmIntegrationWhereUniqueInput, + @common.Body() data: LlmIntegrationUpdateInput + ): Promise<LlmIntegration | null> { + try { + return await this.service.updateLlmIntegration({ + where: params, + data: { + ...data, + + promptHandler: data.promptHandler + ? { + connect: data.promptHandler, + } + : undefined, + }, + select: { + apiEndpoint: true, + apiKeyName: true, + createdAt: true, + id: true, + modelUsed: true, + + promptHandler: { + select: { + id: true, + }, + }, + + provider: true, + updatedAt: true, + }, + }); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + throw error; + } + } + + @common.Delete("/:id") + @swagger.ApiOkResponse({ type: LlmIntegration }) + @swagger.ApiNotFoundResponse({ type: errors.NotFoundException }) + async deleteLlmIntegration( + @common.Param() params: LlmIntegrationWhereUniqueInput + ): Promise<LlmIntegration | null> { + try { + return await this.service.deleteLlmIntegration({ + where: params, + select: { + apiEndpoint: true, + apiKeyName: true, + createdAt: true, + id: true, + modelUsed: true, + + promptHandler: { + select: { + id: true, + }, + }, + + provider: true, + updatedAt: true, + }, + }); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + throw error; + } + } +} diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.module.base.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.module.base.ts new file mode 100644 index 000000000..aed1d6af4 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.module.base.ts @@ -0,0 +1,18 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { Module } from "@nestjs/common"; + +@Module({ + imports: [], + exports: [], +}) +export class LlmIntegrationModuleBase {} diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.resolver.base.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.resolver.base.ts new file mode 100644 index 000000000..e6a0856d3 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.resolver.base.ts @@ -0,0 +1,131 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import * as graphql from "@nestjs/graphql"; +import { GraphQLError } from "graphql"; +import { isRecordNotFoundError } from "../../prisma.util"; +import { MetaQueryPayload } from "../../util/MetaQueryPayload"; +import { LlmIntegration } from "./LlmIntegration"; +import { LlmIntegrationCountArgs } from "./LlmIntegrationCountArgs"; +import { LlmIntegrationFindManyArgs } from "./LlmIntegrationFindManyArgs"; +import { LlmIntegrationFindUniqueArgs } from "./LlmIntegrationFindUniqueArgs"; +import { CreateLlmIntegrationArgs } from "./CreateLlmIntegrationArgs"; +import { UpdateLlmIntegrationArgs } from "./UpdateLlmIntegrationArgs"; +import { DeleteLlmIntegrationArgs } from "./DeleteLlmIntegrationArgs"; +import { PromptHandler } from "../../promptHandler/base/PromptHandler"; +import { LlmIntegrationService } from "../llmIntegration.service"; +@graphql.Resolver(() => LlmIntegration) +export class LlmIntegrationResolverBase { + constructor(protected readonly service: LlmIntegrationService) {} + + async _llmIntegrationsMeta( + @graphql.Args() args: LlmIntegrationCountArgs + ): Promise<MetaQueryPayload> { + const result = await this.service.count(args); + return { + count: result, + }; + } + + @graphql.Query(() => [LlmIntegration]) + async llmIntegrations( + @graphql.Args() args: LlmIntegrationFindManyArgs + ): Promise<LlmIntegration[]> { + return this.service.llmIntegrations(args); + } + + @graphql.Query(() => LlmIntegration, { nullable: true }) + async llmIntegration( + @graphql.Args() args: LlmIntegrationFindUniqueArgs + ): Promise<LlmIntegration | null> { + const result = await this.service.llmIntegration(args); + if (result === null) { + return null; + } + return result; + } + + @graphql.Mutation(() => LlmIntegration) + async createLlmIntegration( + @graphql.Args() args: CreateLlmIntegrationArgs + ): Promise<LlmIntegration> { + return await this.service.createLlmIntegration({ + ...args, + data: { + ...args.data, + + promptHandler: args.data.promptHandler + ? { + connect: args.data.promptHandler, + } + : undefined, + }, + }); + } + + @graphql.Mutation(() => LlmIntegration) + async updateLlmIntegration( + @graphql.Args() args: UpdateLlmIntegrationArgs + ): Promise<LlmIntegration | null> { + try { + return await this.service.updateLlmIntegration({ + ...args, + data: { + ...args.data, + + promptHandler: args.data.promptHandler + ? { + connect: args.data.promptHandler, + } + : undefined, + }, + }); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new GraphQLError( + `No resource was found for ${JSON.stringify(args.where)}` + ); + } + throw error; + } + } + + @graphql.Mutation(() => LlmIntegration) + async deleteLlmIntegration( + @graphql.Args() args: DeleteLlmIntegrationArgs + ): Promise<LlmIntegration | null> { + try { + return await this.service.deleteLlmIntegration(args); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new GraphQLError( + `No resource was found for ${JSON.stringify(args.where)}` + ); + } + throw error; + } + } + + @graphql.ResolveField(() => PromptHandler, { + nullable: true, + name: "promptHandler", + }) + async getPromptHandler( + @graphql.Parent() parent: LlmIntegration + ): Promise<PromptHandler | null> { + const result = await this.service.getPromptHandler(parent.id); + + if (!result) { + return null; + } + return result; + } +} diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.service.base.ts b/apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.service.base.ts new file mode 100644 index 000000000..45d1b9492 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/base/llmIntegration.service.base.ts @@ -0,0 +1,64 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { PrismaService } from "../../prisma/prisma.service"; + +import { + Prisma, + LlmIntegration as PrismaLlmIntegration, + PromptHandler as PrismaPromptHandler, +} from "@prisma/client"; + +export class LlmIntegrationServiceBase { + constructor(protected readonly prisma: PrismaService) {} + + async count( + args: Omit<Prisma.LlmIntegrationCountArgs, "select"> + ): Promise<number> { + return this.prisma.llmIntegration.count(args); + } + + async llmIntegrations( + args: Prisma.LlmIntegrationFindManyArgs + ): Promise<PrismaLlmIntegration[]> { + return this.prisma.llmIntegration.findMany(args); + } + async llmIntegration( + args: Prisma.LlmIntegrationFindUniqueArgs + ): Promise<PrismaLlmIntegration | null> { + return this.prisma.llmIntegration.findUnique(args); + } + async createLlmIntegration( + args: Prisma.LlmIntegrationCreateArgs + ): Promise<PrismaLlmIntegration> { + return this.prisma.llmIntegration.create(args); + } + async updateLlmIntegration( + args: Prisma.LlmIntegrationUpdateArgs + ): Promise<PrismaLlmIntegration> { + return this.prisma.llmIntegration.update(args); + } + async deleteLlmIntegration( + args: Prisma.LlmIntegrationDeleteArgs + ): Promise<PrismaLlmIntegration> { + return this.prisma.llmIntegration.delete(args); + } + + async getPromptHandler( + parentId: string + ): Promise<PrismaPromptHandler | null> { + return this.prisma.llmIntegration + .findUnique({ + where: { id: parentId }, + }) + .promptHandler(); + } +} diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/llmIntegration.controller.ts b/apps/deployment-orchestrator-server/src/llmIntegration/llmIntegration.controller.ts new file mode 100644 index 000000000..41052e227 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/llmIntegration.controller.ts @@ -0,0 +1,12 @@ +import * as common from "@nestjs/common"; +import * as swagger from "@nestjs/swagger"; +import { LlmIntegrationService } from "./llmIntegration.service"; +import { LlmIntegrationControllerBase } from "./base/llmIntegration.controller.base"; + +@swagger.ApiTags("llmIntegrations") +@common.Controller("llmIntegrations") +export class LlmIntegrationController extends LlmIntegrationControllerBase { + constructor(protected readonly service: LlmIntegrationService) { + super(service); + } +} diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/llmIntegration.module.ts b/apps/deployment-orchestrator-server/src/llmIntegration/llmIntegration.module.ts new file mode 100644 index 000000000..fcafe39f5 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/llmIntegration.module.ts @@ -0,0 +1,13 @@ +import { Module } from "@nestjs/common"; +import { LlmIntegrationModuleBase } from "./base/llmIntegration.module.base"; +import { LlmIntegrationService } from "./llmIntegration.service"; +import { LlmIntegrationController } from "./llmIntegration.controller"; +import { LlmIntegrationResolver } from "./llmIntegration.resolver"; + +@Module({ + imports: [LlmIntegrationModuleBase], + controllers: [LlmIntegrationController], + providers: [LlmIntegrationService, LlmIntegrationResolver], + exports: [LlmIntegrationService], +}) +export class LlmIntegrationModule {} diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/llmIntegration.resolver.ts b/apps/deployment-orchestrator-server/src/llmIntegration/llmIntegration.resolver.ts new file mode 100644 index 000000000..cda062500 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/llmIntegration.resolver.ts @@ -0,0 +1,11 @@ +import * as graphql from "@nestjs/graphql"; +import { LlmIntegrationResolverBase } from "./base/llmIntegration.resolver.base"; +import { LlmIntegration } from "./base/LlmIntegration"; +import { LlmIntegrationService } from "./llmIntegration.service"; + +@graphql.Resolver(() => LlmIntegration) +export class LlmIntegrationResolver extends LlmIntegrationResolverBase { + constructor(protected readonly service: LlmIntegrationService) { + super(service); + } +} diff --git a/apps/deployment-orchestrator-server/src/llmIntegration/llmIntegration.service.ts b/apps/deployment-orchestrator-server/src/llmIntegration/llmIntegration.service.ts new file mode 100644 index 000000000..6f17554d3 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/llmIntegration/llmIntegration.service.ts @@ -0,0 +1,10 @@ +import { Injectable } from "@nestjs/common"; +import { PrismaService } from "../prisma/prisma.service"; +import { LlmIntegrationServiceBase } from "./base/llmIntegration.service.base"; + +@Injectable() +export class LlmIntegrationService extends LlmIntegrationServiceBase { + constructor(protected readonly prisma: PrismaService) { + super(prisma); + } +} diff --git a/apps/deployment-orchestrator-server/src/main.ts b/apps/deployment-orchestrator-server/src/main.ts new file mode 100644 index 000000000..474eeadf7 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/main.ts @@ -0,0 +1,53 @@ +import { ValidationPipe } from "@nestjs/common"; +import { HttpAdapterHost, NestFactory } from "@nestjs/core"; +import { OpenAPIObject, SwaggerModule } from "@nestjs/swagger"; +import { HttpExceptionFilter } from "./filters/HttpExceptions.filter"; +import { AppModule } from "./app.module"; +import { connectMicroservices } from "./connectMicroservices"; +import { + swaggerPath, + swaggerDocumentOptions, + swaggerSetupOptions, +} from "./swagger"; + +const { PORT = 3000 } = process.env; + +async function main() { + const app = await NestFactory.create(AppModule, { cors: true }); + + app.setGlobalPrefix("api"); + app.useGlobalPipes( + new ValidationPipe({ + transform: true, + forbidUnknownValues: false, + }) + ); + + const document = SwaggerModule.createDocument(app, swaggerDocumentOptions); + + /** check if there is Public decorator for each path (action) and its method (findMany / findOne) on each controller */ + Object.values((document as OpenAPIObject).paths).forEach((path: any) => { + Object.values(path).forEach((method: any) => { + if ( + Array.isArray(method.security) && + method.security.includes("isPublic") + ) { + method.security = []; + } + }); + }); + + await connectMicroservices(app); + await app.startAllMicroservices(); + + SwaggerModule.setup(swaggerPath, app, document, swaggerSetupOptions); + + const { httpAdapter } = app.get(HttpAdapterHost); + app.useGlobalFilters(new HttpExceptionFilter(httpAdapter)); + + void app.listen(PORT); + + return app; +} + +module.exports = main(); diff --git a/apps/deployment-orchestrator-server/src/prisma.util.spec.ts b/apps/deployment-orchestrator-server/src/prisma.util.spec.ts new file mode 100644 index 000000000..0aa308ed0 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/prisma.util.spec.ts @@ -0,0 +1,23 @@ +import { + isRecordNotFoundError, + PRISMA_QUERY_INTERPRETATION_ERROR, +} from "./prisma.util"; + +describe("isRecordNotFoundError", () => { + test("returns true for record not found error", () => { + expect( + isRecordNotFoundError( + Object.assign( + new Error(`Error occurred during query execution: + InterpretationError("Error for binding '0': RecordNotFound("Record to update not found.")")`), + { + code: PRISMA_QUERY_INTERPRETATION_ERROR, + } + ) + ) + ).toBe(true); + }); + test("returns false for any other error", () => { + expect(isRecordNotFoundError(new Error())).toBe(false); + }); +}); diff --git a/apps/deployment-orchestrator-server/src/prisma.util.ts b/apps/deployment-orchestrator-server/src/prisma.util.ts new file mode 100644 index 000000000..029b98a90 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/prisma.util.ts @@ -0,0 +1,29 @@ +export const PRISMA_QUERY_INTERPRETATION_ERROR = "P2016"; +export const PRISMA_RECORD_NOT_FOUND = "RecordNotFound"; + +export function isRecordNotFoundError(error: any): boolean { + return ( + error instanceof Error && + "code" in error && + error.code === PRISMA_QUERY_INTERPRETATION_ERROR && + error.message.includes(PRISMA_RECORD_NOT_FOUND) + ); +} + +export async function transformStringFieldUpdateInput< + T extends undefined | string | { set?: string } +>(input: T, transform: (input: string) => Promise<string>): Promise<T> { + if (typeof input === "object" && typeof input?.set === "string") { + return { set: await transform(input.set) } as T; + } + if (typeof input === "object") { + if (typeof input.set === "string") { + return { set: await transform(input.set) } as T; + } + return input; + } + if (typeof input === "string") { + return (await transform(input)) as T; + } + return input; +} diff --git a/apps/deployment-orchestrator-server/src/prisma/prisma.module.ts b/apps/deployment-orchestrator-server/src/prisma/prisma.module.ts new file mode 100644 index 000000000..1edbf95e6 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/prisma/prisma.module.ts @@ -0,0 +1,9 @@ +import { Global, Module } from "@nestjs/common"; +import { PrismaService } from "./prisma.service"; + +@Global() +@Module({ + providers: [PrismaService], + exports: [PrismaService], +}) +export class PrismaModule {} diff --git a/apps/deployment-orchestrator-server/src/prisma/prisma.service.ts b/apps/deployment-orchestrator-server/src/prisma/prisma.service.ts new file mode 100644 index 000000000..79ea4fa74 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/prisma/prisma.service.ts @@ -0,0 +1,9 @@ +import { Injectable, OnModuleInit, INestApplication } from "@nestjs/common"; +import { PrismaClient } from "@prisma/client"; + +@Injectable() +export class PrismaService extends PrismaClient implements OnModuleInit { + async onModuleInit() { + await this.$connect(); + } +} diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/CreatePromptHandlerArgs.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/CreatePromptHandlerArgs.ts new file mode 100644 index 000000000..c00a02800 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/CreatePromptHandlerArgs.ts @@ -0,0 +1,30 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { PromptHandlerCreateInput } from "./PromptHandlerCreateInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; + +@ArgsType() +class CreatePromptHandlerArgs { + @ApiProperty({ + required: true, + type: () => PromptHandlerCreateInput, + }) + @ValidateNested() + @Type(() => PromptHandlerCreateInput) + @Field(() => PromptHandlerCreateInput, { nullable: false }) + data!: PromptHandlerCreateInput; +} + +export { CreatePromptHandlerArgs as CreatePromptHandlerArgs }; diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/DeletePromptHandlerArgs.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/DeletePromptHandlerArgs.ts new file mode 100644 index 000000000..8426ea677 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/DeletePromptHandlerArgs.ts @@ -0,0 +1,30 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { PromptHandlerWhereUniqueInput } from "./PromptHandlerWhereUniqueInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; + +@ArgsType() +class DeletePromptHandlerArgs { + @ApiProperty({ + required: true, + type: () => PromptHandlerWhereUniqueInput, + }) + @ValidateNested() + @Type(() => PromptHandlerWhereUniqueInput) + @Field(() => PromptHandlerWhereUniqueInput, { nullable: false }) + where!: PromptHandlerWhereUniqueInput; +} + +export { DeletePromptHandlerArgs as DeletePromptHandlerArgs }; diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/LlmIntegrationCreateNestedManyWithoutPromptHandlersInput.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/LlmIntegrationCreateNestedManyWithoutPromptHandlersInput.ts new file mode 100644 index 000000000..252a8905b --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/LlmIntegrationCreateNestedManyWithoutPromptHandlersInput.ts @@ -0,0 +1,28 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { LlmIntegrationWhereUniqueInput } from "../../llmIntegration/base/LlmIntegrationWhereUniqueInput"; +import { ApiProperty } from "@nestjs/swagger"; + +@InputType() +class LlmIntegrationCreateNestedManyWithoutPromptHandlersInput { + @Field(() => [LlmIntegrationWhereUniqueInput], { + nullable: true, + }) + @ApiProperty({ + required: false, + type: () => [LlmIntegrationWhereUniqueInput], + }) + connect?: Array<LlmIntegrationWhereUniqueInput>; +} + +export { LlmIntegrationCreateNestedManyWithoutPromptHandlersInput as LlmIntegrationCreateNestedManyWithoutPromptHandlersInput }; diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/LlmIntegrationUpdateManyWithoutPromptHandlersInput.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/LlmIntegrationUpdateManyWithoutPromptHandlersInput.ts new file mode 100644 index 000000000..0c92163e7 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/LlmIntegrationUpdateManyWithoutPromptHandlersInput.ts @@ -0,0 +1,46 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { LlmIntegrationWhereUniqueInput } from "../../llmIntegration/base/LlmIntegrationWhereUniqueInput"; +import { ApiProperty } from "@nestjs/swagger"; + +@InputType() +class LlmIntegrationUpdateManyWithoutPromptHandlersInput { + @Field(() => [LlmIntegrationWhereUniqueInput], { + nullable: true, + }) + @ApiProperty({ + required: false, + type: () => [LlmIntegrationWhereUniqueInput], + }) + connect?: Array<LlmIntegrationWhereUniqueInput>; + + @Field(() => [LlmIntegrationWhereUniqueInput], { + nullable: true, + }) + @ApiProperty({ + required: false, + type: () => [LlmIntegrationWhereUniqueInput], + }) + disconnect?: Array<LlmIntegrationWhereUniqueInput>; + + @Field(() => [LlmIntegrationWhereUniqueInput], { + nullable: true, + }) + @ApiProperty({ + required: false, + type: () => [LlmIntegrationWhereUniqueInput], + }) + set?: Array<LlmIntegrationWhereUniqueInput>; +} + +export { LlmIntegrationUpdateManyWithoutPromptHandlersInput as LlmIntegrationUpdateManyWithoutPromptHandlersInput }; diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandler.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandler.ts new file mode 100644 index 000000000..cd0e0f130 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandler.ts @@ -0,0 +1,117 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ObjectType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { + IsDate, + ValidateNested, + IsOptional, + IsString, + MaxLength, +} from "class-validator"; +import { Type } from "class-transformer"; +import { Deployment } from "../../deployment/base/Deployment"; +import { LlmIntegration } from "../../llmIntegration/base/LlmIntegration"; +import { IsJSONValue } from "../../validators"; +import { GraphQLJSON } from "graphql-type-json"; +import { JsonValue } from "type-fest"; + +@ObjectType() +class PromptHandler { + @ApiProperty({ + required: true, + }) + @IsDate() + @Type(() => Date) + @Field(() => Date) + createdAt!: Date; + + @ApiProperty({ + required: false, + type: () => Deployment, + }) + @ValidateNested() + @Type(() => Deployment) + @IsOptional() + deployment?: Deployment | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + detectedOs!: string | null; + + @ApiProperty({ + required: true, + type: String, + }) + @IsString() + @Field(() => String) + id!: string; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + inputPrompt!: string | null; + + @ApiProperty({ + required: false, + type: () => [LlmIntegration], + }) + @ValidateNested() + @Type(() => LlmIntegration) + @IsOptional() + llmIntegrations?: Array<LlmIntegration>; + + @ApiProperty({ + required: false, + }) + @IsJSONValue() + @IsOptional() + @Field(() => GraphQLJSON, { + nullable: true, + }) + parsedInstructions!: JsonValue; + + @ApiProperty({ + required: false, + }) + @IsJSONValue() + @IsOptional() + @Field(() => GraphQLJSON, { + nullable: true, + }) + resourcesRequested!: JsonValue; + + @ApiProperty({ + required: true, + }) + @IsDate() + @Type(() => Date) + @Field(() => Date) + updatedAt!: Date; +} + +export { PromptHandler as PromptHandler }; diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerCountArgs.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerCountArgs.ts new file mode 100644 index 000000000..c7a9e5aff --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerCountArgs.ts @@ -0,0 +1,28 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { PromptHandlerWhereInput } from "./PromptHandlerWhereInput"; +import { Type } from "class-transformer"; + +@ArgsType() +class PromptHandlerCountArgs { + @ApiProperty({ + required: false, + type: () => PromptHandlerWhereInput, + }) + @Field(() => PromptHandlerWhereInput, { nullable: true }) + @Type(() => PromptHandlerWhereInput) + where?: PromptHandlerWhereInput; +} + +export { PromptHandlerCountArgs as PromptHandlerCountArgs }; diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerCreateInput.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerCreateInput.ts new file mode 100644 index 000000000..afd36c4d7 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerCreateInput.ts @@ -0,0 +1,98 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { DeploymentWhereUniqueInput } from "../../deployment/base/DeploymentWhereUniqueInput"; +import { + ValidateNested, + IsOptional, + IsString, + MaxLength, +} from "class-validator"; +import { Type } from "class-transformer"; +import { LlmIntegrationCreateNestedManyWithoutPromptHandlersInput } from "./LlmIntegrationCreateNestedManyWithoutPromptHandlersInput"; +import { IsJSONValue } from "../../validators"; +import { GraphQLJSON } from "graphql-type-json"; +import { InputJsonValue } from "../../types"; + +@InputType() +class PromptHandlerCreateInput { + @ApiProperty({ + required: false, + type: () => DeploymentWhereUniqueInput, + }) + @ValidateNested() + @Type(() => DeploymentWhereUniqueInput) + @IsOptional() + @Field(() => DeploymentWhereUniqueInput, { + nullable: true, + }) + deployment?: DeploymentWhereUniqueInput | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + detectedOs?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + inputPrompt?: string | null; + + @ApiProperty({ + required: false, + type: () => LlmIntegrationCreateNestedManyWithoutPromptHandlersInput, + }) + @ValidateNested() + @Type(() => LlmIntegrationCreateNestedManyWithoutPromptHandlersInput) + @IsOptional() + @Field(() => LlmIntegrationCreateNestedManyWithoutPromptHandlersInput, { + nullable: true, + }) + llmIntegrations?: LlmIntegrationCreateNestedManyWithoutPromptHandlersInput; + + @ApiProperty({ + required: false, + }) + @IsJSONValue() + @IsOptional() + @Field(() => GraphQLJSON, { + nullable: true, + }) + parsedInstructions?: InputJsonValue; + + @ApiProperty({ + required: false, + }) + @IsJSONValue() + @IsOptional() + @Field(() => GraphQLJSON, { + nullable: true, + }) + resourcesRequested?: InputJsonValue; +} + +export { PromptHandlerCreateInput as PromptHandlerCreateInput }; diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerFindManyArgs.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerFindManyArgs.ts new file mode 100644 index 000000000..375f49c26 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerFindManyArgs.ts @@ -0,0 +1,62 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { PromptHandlerWhereInput } from "./PromptHandlerWhereInput"; +import { IsOptional, ValidateNested, IsInt } from "class-validator"; +import { Type } from "class-transformer"; +import { PromptHandlerOrderByInput } from "./PromptHandlerOrderByInput"; + +@ArgsType() +class PromptHandlerFindManyArgs { + @ApiProperty({ + required: false, + type: () => PromptHandlerWhereInput, + }) + @IsOptional() + @ValidateNested() + @Field(() => PromptHandlerWhereInput, { nullable: true }) + @Type(() => PromptHandlerWhereInput) + where?: PromptHandlerWhereInput; + + @ApiProperty({ + required: false, + type: [PromptHandlerOrderByInput], + }) + @IsOptional() + @ValidateNested({ each: true }) + @Field(() => [PromptHandlerOrderByInput], { nullable: true }) + @Type(() => PromptHandlerOrderByInput) + orderBy?: Array<PromptHandlerOrderByInput>; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @IsInt() + @Field(() => Number, { nullable: true }) + @Type(() => Number) + skip?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @IsInt() + @Field(() => Number, { nullable: true }) + @Type(() => Number) + take?: number; +} + +export { PromptHandlerFindManyArgs as PromptHandlerFindManyArgs }; diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerFindUniqueArgs.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerFindUniqueArgs.ts new file mode 100644 index 000000000..89edc3285 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerFindUniqueArgs.ts @@ -0,0 +1,30 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { PromptHandlerWhereUniqueInput } from "./PromptHandlerWhereUniqueInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; + +@ArgsType() +class PromptHandlerFindUniqueArgs { + @ApiProperty({ + required: true, + type: () => PromptHandlerWhereUniqueInput, + }) + @ValidateNested() + @Type(() => PromptHandlerWhereUniqueInput) + @Field(() => PromptHandlerWhereUniqueInput, { nullable: false }) + where!: PromptHandlerWhereUniqueInput; +} + +export { PromptHandlerFindUniqueArgs as PromptHandlerFindUniqueArgs }; diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerListRelationFilter.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerListRelationFilter.ts new file mode 100644 index 000000000..5cba5a864 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerListRelationFilter.ts @@ -0,0 +1,56 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { PromptHandlerWhereInput } from "./PromptHandlerWhereInput"; +import { ValidateNested, IsOptional } from "class-validator"; +import { Type } from "class-transformer"; + +@InputType() +class PromptHandlerListRelationFilter { + @ApiProperty({ + required: false, + type: () => PromptHandlerWhereInput, + }) + @ValidateNested() + @Type(() => PromptHandlerWhereInput) + @IsOptional() + @Field(() => PromptHandlerWhereInput, { + nullable: true, + }) + every?: PromptHandlerWhereInput; + + @ApiProperty({ + required: false, + type: () => PromptHandlerWhereInput, + }) + @ValidateNested() + @Type(() => PromptHandlerWhereInput) + @IsOptional() + @Field(() => PromptHandlerWhereInput, { + nullable: true, + }) + some?: PromptHandlerWhereInput; + + @ApiProperty({ + required: false, + type: () => PromptHandlerWhereInput, + }) + @ValidateNested() + @Type(() => PromptHandlerWhereInput) + @IsOptional() + @Field(() => PromptHandlerWhereInput, { + nullable: true, + }) + none?: PromptHandlerWhereInput; +} +export { PromptHandlerListRelationFilter as PromptHandlerListRelationFilter }; diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerOrderByInput.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerOrderByInput.ts new file mode 100644 index 000000000..a5ff52fe2 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerOrderByInput.ts @@ -0,0 +1,111 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional, IsEnum } from "class-validator"; +import { SortOrder } from "../../util/SortOrder"; + +@InputType({ + isAbstract: true, + description: undefined, +}) +class PromptHandlerOrderByInput { + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + createdAt?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + deploymentId?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + detectedOs?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + id?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + inputPrompt?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + parsedInstructions?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + resourcesRequested?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + updatedAt?: SortOrder; +} + +export { PromptHandlerOrderByInput as PromptHandlerOrderByInput }; diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerUpdateInput.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerUpdateInput.ts new file mode 100644 index 000000000..441920a68 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerUpdateInput.ts @@ -0,0 +1,98 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { DeploymentWhereUniqueInput } from "../../deployment/base/DeploymentWhereUniqueInput"; +import { + ValidateNested, + IsOptional, + IsString, + MaxLength, +} from "class-validator"; +import { Type } from "class-transformer"; +import { LlmIntegrationUpdateManyWithoutPromptHandlersInput } from "./LlmIntegrationUpdateManyWithoutPromptHandlersInput"; +import { IsJSONValue } from "../../validators"; +import { GraphQLJSON } from "graphql-type-json"; +import { InputJsonValue } from "../../types"; + +@InputType() +class PromptHandlerUpdateInput { + @ApiProperty({ + required: false, + type: () => DeploymentWhereUniqueInput, + }) + @ValidateNested() + @Type(() => DeploymentWhereUniqueInput) + @IsOptional() + @Field(() => DeploymentWhereUniqueInput, { + nullable: true, + }) + deployment?: DeploymentWhereUniqueInput | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + detectedOs?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + inputPrompt?: string | null; + + @ApiProperty({ + required: false, + type: () => LlmIntegrationUpdateManyWithoutPromptHandlersInput, + }) + @ValidateNested() + @Type(() => LlmIntegrationUpdateManyWithoutPromptHandlersInput) + @IsOptional() + @Field(() => LlmIntegrationUpdateManyWithoutPromptHandlersInput, { + nullable: true, + }) + llmIntegrations?: LlmIntegrationUpdateManyWithoutPromptHandlersInput; + + @ApiProperty({ + required: false, + }) + @IsJSONValue() + @IsOptional() + @Field(() => GraphQLJSON, { + nullable: true, + }) + parsedInstructions?: InputJsonValue; + + @ApiProperty({ + required: false, + }) + @IsJSONValue() + @IsOptional() + @Field(() => GraphQLJSON, { + nullable: true, + }) + resourcesRequested?: InputJsonValue; +} + +export { PromptHandlerUpdateInput as PromptHandlerUpdateInput }; diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerWhereInput.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerWhereInput.ts new file mode 100644 index 000000000..4097358e4 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerWhereInput.ts @@ -0,0 +1,104 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { DeploymentWhereUniqueInput } from "../../deployment/base/DeploymentWhereUniqueInput"; +import { ValidateNested, IsOptional } from "class-validator"; +import { Type } from "class-transformer"; +import { StringNullableFilter } from "../../util/StringNullableFilter"; +import { StringFilter } from "../../util/StringFilter"; +import { LlmIntegrationListRelationFilter } from "../../llmIntegration/base/LlmIntegrationListRelationFilter"; +import { JsonFilter } from "../../util/JsonFilter"; + +@InputType() +class PromptHandlerWhereInput { + @ApiProperty({ + required: false, + type: () => DeploymentWhereUniqueInput, + }) + @ValidateNested() + @Type(() => DeploymentWhereUniqueInput) + @IsOptional() + @Field(() => DeploymentWhereUniqueInput, { + nullable: true, + }) + deployment?: DeploymentWhereUniqueInput; + + @ApiProperty({ + required: false, + type: StringNullableFilter, + }) + @Type(() => StringNullableFilter) + @IsOptional() + @Field(() => StringNullableFilter, { + nullable: true, + }) + detectedOs?: StringNullableFilter; + + @ApiProperty({ + required: false, + type: StringFilter, + }) + @Type(() => StringFilter) + @IsOptional() + @Field(() => StringFilter, { + nullable: true, + }) + id?: StringFilter; + + @ApiProperty({ + required: false, + type: StringNullableFilter, + }) + @Type(() => StringNullableFilter) + @IsOptional() + @Field(() => StringNullableFilter, { + nullable: true, + }) + inputPrompt?: StringNullableFilter; + + @ApiProperty({ + required: false, + type: () => LlmIntegrationListRelationFilter, + }) + @ValidateNested() + @Type(() => LlmIntegrationListRelationFilter) + @IsOptional() + @Field(() => LlmIntegrationListRelationFilter, { + nullable: true, + }) + llmIntegrations?: LlmIntegrationListRelationFilter; + + @ApiProperty({ + required: false, + type: JsonFilter, + }) + @Type(() => JsonFilter) + @IsOptional() + @Field(() => JsonFilter, { + nullable: true, + }) + parsedInstructions?: JsonFilter; + + @ApiProperty({ + required: false, + type: JsonFilter, + }) + @Type(() => JsonFilter) + @IsOptional() + @Field(() => JsonFilter, { + nullable: true, + }) + resourcesRequested?: JsonFilter; +} + +export { PromptHandlerWhereInput as PromptHandlerWhereInput }; diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerWhereUniqueInput.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerWhereUniqueInput.ts new file mode 100644 index 000000000..28c09e89f --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/PromptHandlerWhereUniqueInput.ts @@ -0,0 +1,27 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsString } from "class-validator"; + +@InputType() +class PromptHandlerWhereUniqueInput { + @ApiProperty({ + required: true, + type: String, + }) + @IsString() + @Field(() => String) + id!: string; +} + +export { PromptHandlerWhereUniqueInput as PromptHandlerWhereUniqueInput }; diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/UpdatePromptHandlerArgs.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/UpdatePromptHandlerArgs.ts new file mode 100644 index 000000000..6b356ead4 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/UpdatePromptHandlerArgs.ts @@ -0,0 +1,40 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { PromptHandlerWhereUniqueInput } from "./PromptHandlerWhereUniqueInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; +import { PromptHandlerUpdateInput } from "./PromptHandlerUpdateInput"; + +@ArgsType() +class UpdatePromptHandlerArgs { + @ApiProperty({ + required: true, + type: () => PromptHandlerWhereUniqueInput, + }) + @ValidateNested() + @Type(() => PromptHandlerWhereUniqueInput) + @Field(() => PromptHandlerWhereUniqueInput, { nullable: false }) + where!: PromptHandlerWhereUniqueInput; + + @ApiProperty({ + required: true, + type: () => PromptHandlerUpdateInput, + }) + @ValidateNested() + @Type(() => PromptHandlerUpdateInput) + @Field(() => PromptHandlerUpdateInput, { nullable: false }) + data!: PromptHandlerUpdateInput; +} + +export { UpdatePromptHandlerArgs as UpdatePromptHandlerArgs }; diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.controller.base.spec.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.controller.base.spec.ts new file mode 100644 index 000000000..a8b73eac8 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.controller.base.spec.ts @@ -0,0 +1,198 @@ +import { Test } from "@nestjs/testing"; +import { + INestApplication, + HttpStatus, + ExecutionContext, + CallHandler, +} from "@nestjs/common"; +import request from "supertest"; +import { ACGuard } from "nest-access-control"; +import { DefaultAuthGuard } from "../../auth/defaultAuth.guard"; +import { ACLModule } from "../../auth/acl.module"; +import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor"; +import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor"; +import { map } from "rxjs"; +import { PromptHandlerController } from "../promptHandler.controller"; +import { PromptHandlerService } from "../promptHandler.service"; + +const nonExistingId = "nonExistingId"; +const existingId = "existingId"; +const CREATE_INPUT = { + createdAt: new Date(), + detectedOs: "exampleDetectedOs", + id: "exampleId", + inputPrompt: "exampleInputPrompt", + updatedAt: new Date(), +}; +const CREATE_RESULT = { + createdAt: new Date(), + detectedOs: "exampleDetectedOs", + id: "exampleId", + inputPrompt: "exampleInputPrompt", + updatedAt: new Date(), +}; +const FIND_MANY_RESULT = [ + { + createdAt: new Date(), + detectedOs: "exampleDetectedOs", + id: "exampleId", + inputPrompt: "exampleInputPrompt", + updatedAt: new Date(), + }, +]; +const FIND_ONE_RESULT = { + createdAt: new Date(), + detectedOs: "exampleDetectedOs", + id: "exampleId", + inputPrompt: "exampleInputPrompt", + updatedAt: new Date(), +}; + +const service = { + createPromptHandler() { + return CREATE_RESULT; + }, + promptHandlers: () => FIND_MANY_RESULT, + promptHandler: ({ where }: { where: { id: string } }) => { + switch (where.id) { + case existingId: + return FIND_ONE_RESULT; + case nonExistingId: + return null; + } + }, +}; + +const basicAuthGuard = { + canActivate: (context: ExecutionContext) => { + const argumentHost = context.switchToHttp(); + const request = argumentHost.getRequest(); + request.user = { + roles: ["user"], + }; + return true; + }, +}; + +const acGuard = { + canActivate: () => { + return true; + }, +}; + +const aclFilterResponseInterceptor = { + intercept: (context: ExecutionContext, next: CallHandler) => { + return next.handle().pipe( + map((data) => { + return data; + }) + ); + }, +}; +const aclValidateRequestInterceptor = { + intercept: (context: ExecutionContext, next: CallHandler) => { + return next.handle(); + }, +}; + +describe("PromptHandler", () => { + let app: INestApplication; + + beforeAll(async () => { + const moduleRef = await Test.createTestingModule({ + providers: [ + { + provide: PromptHandlerService, + useValue: service, + }, + ], + controllers: [PromptHandlerController], + imports: [ACLModule], + }) + .overrideGuard(DefaultAuthGuard) + .useValue(basicAuthGuard) + .overrideGuard(ACGuard) + .useValue(acGuard) + .overrideInterceptor(AclFilterResponseInterceptor) + .useValue(aclFilterResponseInterceptor) + .overrideInterceptor(AclValidateRequestInterceptor) + .useValue(aclValidateRequestInterceptor) + .compile(); + + app = moduleRef.createNestApplication(); + await app.init(); + }); + + test("POST /promptHandlers", async () => { + await request(app.getHttpServer()) + .post("/promptHandlers") + .send(CREATE_INPUT) + .expect(HttpStatus.CREATED) + .expect({ + ...CREATE_RESULT, + createdAt: CREATE_RESULT.createdAt.toISOString(), + updatedAt: CREATE_RESULT.updatedAt.toISOString(), + }); + }); + + test("GET /promptHandlers", async () => { + await request(app.getHttpServer()) + .get("/promptHandlers") + .expect(HttpStatus.OK) + .expect([ + { + ...FIND_MANY_RESULT[0], + createdAt: FIND_MANY_RESULT[0].createdAt.toISOString(), + updatedAt: FIND_MANY_RESULT[0].updatedAt.toISOString(), + }, + ]); + }); + + test("GET /promptHandlers/:id non existing", async () => { + await request(app.getHttpServer()) + .get(`${"/promptHandlers"}/${nonExistingId}`) + .expect(HttpStatus.NOT_FOUND) + .expect({ + statusCode: HttpStatus.NOT_FOUND, + message: `No resource was found for {"${"id"}":"${nonExistingId}"}`, + error: "Not Found", + }); + }); + + test("GET /promptHandlers/:id existing", async () => { + await request(app.getHttpServer()) + .get(`${"/promptHandlers"}/${existingId}`) + .expect(HttpStatus.OK) + .expect({ + ...FIND_ONE_RESULT, + createdAt: FIND_ONE_RESULT.createdAt.toISOString(), + updatedAt: FIND_ONE_RESULT.updatedAt.toISOString(), + }); + }); + + test("POST /promptHandlers existing resource", async () => { + const agent = request(app.getHttpServer()); + await agent + .post("/promptHandlers") + .send(CREATE_INPUT) + .expect(HttpStatus.CREATED) + .expect({ + ...CREATE_RESULT, + createdAt: CREATE_RESULT.createdAt.toISOString(), + updatedAt: CREATE_RESULT.updatedAt.toISOString(), + }) + .then(function () { + agent + .post("/promptHandlers") + .send(CREATE_INPUT) + .expect(HttpStatus.CONFLICT) + .expect({ + statusCode: HttpStatus.CONFLICT, + }); + }); + }); + + afterAll(async () => { + await app.close(); + }); +}); diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.controller.base.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.controller.base.ts new file mode 100644 index 000000000..ba3afc549 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.controller.base.ts @@ -0,0 +1,292 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import * as common from "@nestjs/common"; +import * as swagger from "@nestjs/swagger"; +import { isRecordNotFoundError } from "../../prisma.util"; +import * as errors from "../../errors"; +import { Request } from "express"; +import { plainToClass } from "class-transformer"; +import { ApiNestedQuery } from "../../decorators/api-nested-query.decorator"; +import { PromptHandlerService } from "../promptHandler.service"; +import { PromptHandlerCreateInput } from "./PromptHandlerCreateInput"; +import { PromptHandler } from "./PromptHandler"; +import { PromptHandlerFindManyArgs } from "./PromptHandlerFindManyArgs"; +import { PromptHandlerWhereUniqueInput } from "./PromptHandlerWhereUniqueInput"; +import { PromptHandlerUpdateInput } from "./PromptHandlerUpdateInput"; +import { LlmIntegrationFindManyArgs } from "../../llmIntegration/base/LlmIntegrationFindManyArgs"; +import { LlmIntegration } from "../../llmIntegration/base/LlmIntegration"; +import { LlmIntegrationWhereUniqueInput } from "../../llmIntegration/base/LlmIntegrationWhereUniqueInput"; + +export class PromptHandlerControllerBase { + constructor(protected readonly service: PromptHandlerService) {} + @common.Post() + @swagger.ApiCreatedResponse({ type: PromptHandler }) + async createPromptHandler( + @common.Body() data: PromptHandlerCreateInput + ): Promise<PromptHandler> { + return await this.service.createPromptHandler({ + data: { + ...data, + + deployment: data.deployment + ? { + connect: data.deployment, + } + : undefined, + }, + select: { + createdAt: true, + + deployment: { + select: { + id: true, + }, + }, + + detectedOs: true, + id: true, + inputPrompt: true, + parsedInstructions: true, + resourcesRequested: true, + updatedAt: true, + }, + }); + } + + @common.Get() + @swagger.ApiOkResponse({ type: [PromptHandler] }) + @ApiNestedQuery(PromptHandlerFindManyArgs) + async promptHandlers( + @common.Req() request: Request + ): Promise<PromptHandler[]> { + const args = plainToClass(PromptHandlerFindManyArgs, request.query); + return this.service.promptHandlers({ + ...args, + select: { + createdAt: true, + + deployment: { + select: { + id: true, + }, + }, + + detectedOs: true, + id: true, + inputPrompt: true, + parsedInstructions: true, + resourcesRequested: true, + updatedAt: true, + }, + }); + } + + @common.Get("/:id") + @swagger.ApiOkResponse({ type: PromptHandler }) + @swagger.ApiNotFoundResponse({ type: errors.NotFoundException }) + async promptHandler( + @common.Param() params: PromptHandlerWhereUniqueInput + ): Promise<PromptHandler | null> { + const result = await this.service.promptHandler({ + where: params, + select: { + createdAt: true, + + deployment: { + select: { + id: true, + }, + }, + + detectedOs: true, + id: true, + inputPrompt: true, + parsedInstructions: true, + resourcesRequested: true, + updatedAt: true, + }, + }); + if (result === null) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + return result; + } + + @common.Patch("/:id") + @swagger.ApiOkResponse({ type: PromptHandler }) + @swagger.ApiNotFoundResponse({ type: errors.NotFoundException }) + async updatePromptHandler( + @common.Param() params: PromptHandlerWhereUniqueInput, + @common.Body() data: PromptHandlerUpdateInput + ): Promise<PromptHandler | null> { + try { + return await this.service.updatePromptHandler({ + where: params, + data: { + ...data, + + deployment: data.deployment + ? { + connect: data.deployment, + } + : undefined, + }, + select: { + createdAt: true, + + deployment: { + select: { + id: true, + }, + }, + + detectedOs: true, + id: true, + inputPrompt: true, + parsedInstructions: true, + resourcesRequested: true, + updatedAt: true, + }, + }); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + throw error; + } + } + + @common.Delete("/:id") + @swagger.ApiOkResponse({ type: PromptHandler }) + @swagger.ApiNotFoundResponse({ type: errors.NotFoundException }) + async deletePromptHandler( + @common.Param() params: PromptHandlerWhereUniqueInput + ): Promise<PromptHandler | null> { + try { + return await this.service.deletePromptHandler({ + where: params, + select: { + createdAt: true, + + deployment: { + select: { + id: true, + }, + }, + + detectedOs: true, + id: true, + inputPrompt: true, + parsedInstructions: true, + resourcesRequested: true, + updatedAt: true, + }, + }); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + throw error; + } + } + + @common.Get("/:id/llmIntegrations") + @ApiNestedQuery(LlmIntegrationFindManyArgs) + async findLlmIntegrations( + @common.Req() request: Request, + @common.Param() params: PromptHandlerWhereUniqueInput + ): Promise<LlmIntegration[]> { + const query = plainToClass(LlmIntegrationFindManyArgs, request.query); + const results = await this.service.findLlmIntegrations(params.id, { + ...query, + select: { + apiEndpoint: true, + apiKeyName: true, + createdAt: true, + id: true, + modelUsed: true, + + promptHandler: { + select: { + id: true, + }, + }, + + provider: true, + updatedAt: true, + }, + }); + if (results === null) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + return results; + } + + @common.Post("/:id/llmIntegrations") + async connectLlmIntegrations( + @common.Param() params: PromptHandlerWhereUniqueInput, + @common.Body() body: LlmIntegrationWhereUniqueInput[] + ): Promise<void> { + const data = { + llmIntegrations: { + connect: body, + }, + }; + await this.service.updatePromptHandler({ + where: params, + data, + select: { id: true }, + }); + } + + @common.Patch("/:id/llmIntegrations") + async updateLlmIntegrations( + @common.Param() params: PromptHandlerWhereUniqueInput, + @common.Body() body: LlmIntegrationWhereUniqueInput[] + ): Promise<void> { + const data = { + llmIntegrations: { + set: body, + }, + }; + await this.service.updatePromptHandler({ + where: params, + data, + select: { id: true }, + }); + } + + @common.Delete("/:id/llmIntegrations") + async disconnectLlmIntegrations( + @common.Param() params: PromptHandlerWhereUniqueInput, + @common.Body() body: LlmIntegrationWhereUniqueInput[] + ): Promise<void> { + const data = { + llmIntegrations: { + disconnect: body, + }, + }; + await this.service.updatePromptHandler({ + where: params, + data, + select: { id: true }, + }); + } +} diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.module.base.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.module.base.ts new file mode 100644 index 000000000..c2a6fd238 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.module.base.ts @@ -0,0 +1,18 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { Module } from "@nestjs/common"; + +@Module({ + imports: [], + exports: [], +}) +export class PromptHandlerModuleBase {} diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.resolver.base.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.resolver.base.ts new file mode 100644 index 000000000..e36c82019 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.resolver.base.ts @@ -0,0 +1,147 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import * as graphql from "@nestjs/graphql"; +import { GraphQLError } from "graphql"; +import { isRecordNotFoundError } from "../../prisma.util"; +import { MetaQueryPayload } from "../../util/MetaQueryPayload"; +import { PromptHandler } from "./PromptHandler"; +import { PromptHandlerCountArgs } from "./PromptHandlerCountArgs"; +import { PromptHandlerFindManyArgs } from "./PromptHandlerFindManyArgs"; +import { PromptHandlerFindUniqueArgs } from "./PromptHandlerFindUniqueArgs"; +import { CreatePromptHandlerArgs } from "./CreatePromptHandlerArgs"; +import { UpdatePromptHandlerArgs } from "./UpdatePromptHandlerArgs"; +import { DeletePromptHandlerArgs } from "./DeletePromptHandlerArgs"; +import { LlmIntegrationFindManyArgs } from "../../llmIntegration/base/LlmIntegrationFindManyArgs"; +import { LlmIntegration } from "../../llmIntegration/base/LlmIntegration"; +import { Deployment } from "../../deployment/base/Deployment"; +import { PromptHandlerService } from "../promptHandler.service"; +@graphql.Resolver(() => PromptHandler) +export class PromptHandlerResolverBase { + constructor(protected readonly service: PromptHandlerService) {} + + async _promptHandlersMeta( + @graphql.Args() args: PromptHandlerCountArgs + ): Promise<MetaQueryPayload> { + const result = await this.service.count(args); + return { + count: result, + }; + } + + @graphql.Query(() => [PromptHandler]) + async promptHandlers( + @graphql.Args() args: PromptHandlerFindManyArgs + ): Promise<PromptHandler[]> { + return this.service.promptHandlers(args); + } + + @graphql.Query(() => PromptHandler, { nullable: true }) + async promptHandler( + @graphql.Args() args: PromptHandlerFindUniqueArgs + ): Promise<PromptHandler | null> { + const result = await this.service.promptHandler(args); + if (result === null) { + return null; + } + return result; + } + + @graphql.Mutation(() => PromptHandler) + async createPromptHandler( + @graphql.Args() args: CreatePromptHandlerArgs + ): Promise<PromptHandler> { + return await this.service.createPromptHandler({ + ...args, + data: { + ...args.data, + + deployment: args.data.deployment + ? { + connect: args.data.deployment, + } + : undefined, + }, + }); + } + + @graphql.Mutation(() => PromptHandler) + async updatePromptHandler( + @graphql.Args() args: UpdatePromptHandlerArgs + ): Promise<PromptHandler | null> { + try { + return await this.service.updatePromptHandler({ + ...args, + data: { + ...args.data, + + deployment: args.data.deployment + ? { + connect: args.data.deployment, + } + : undefined, + }, + }); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new GraphQLError( + `No resource was found for ${JSON.stringify(args.where)}` + ); + } + throw error; + } + } + + @graphql.Mutation(() => PromptHandler) + async deletePromptHandler( + @graphql.Args() args: DeletePromptHandlerArgs + ): Promise<PromptHandler | null> { + try { + return await this.service.deletePromptHandler(args); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new GraphQLError( + `No resource was found for ${JSON.stringify(args.where)}` + ); + } + throw error; + } + } + + @graphql.ResolveField(() => [LlmIntegration], { name: "llmIntegrations" }) + async findLlmIntegrations( + @graphql.Parent() parent: PromptHandler, + @graphql.Args() args: LlmIntegrationFindManyArgs + ): Promise<LlmIntegration[]> { + const results = await this.service.findLlmIntegrations(parent.id, args); + + if (!results) { + return []; + } + + return results; + } + + @graphql.ResolveField(() => Deployment, { + nullable: true, + name: "deployment", + }) + async getDeployment( + @graphql.Parent() parent: PromptHandler + ): Promise<Deployment | null> { + const result = await this.service.getDeployment(parent.id); + + if (!result) { + return null; + } + return result; + } +} diff --git a/apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.service.base.ts b/apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.service.base.ts new file mode 100644 index 000000000..24802e06b --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/base/promptHandler.service.base.ts @@ -0,0 +1,74 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { PrismaService } from "../../prisma/prisma.service"; + +import { + Prisma, + PromptHandler as PrismaPromptHandler, + LlmIntegration as PrismaLlmIntegration, + Deployment as PrismaDeployment, +} from "@prisma/client"; + +export class PromptHandlerServiceBase { + constructor(protected readonly prisma: PrismaService) {} + + async count( + args: Omit<Prisma.PromptHandlerCountArgs, "select"> + ): Promise<number> { + return this.prisma.promptHandler.count(args); + } + + async promptHandlers( + args: Prisma.PromptHandlerFindManyArgs + ): Promise<PrismaPromptHandler[]> { + return this.prisma.promptHandler.findMany(args); + } + async promptHandler( + args: Prisma.PromptHandlerFindUniqueArgs + ): Promise<PrismaPromptHandler | null> { + return this.prisma.promptHandler.findUnique(args); + } + async createPromptHandler( + args: Prisma.PromptHandlerCreateArgs + ): Promise<PrismaPromptHandler> { + return this.prisma.promptHandler.create(args); + } + async updatePromptHandler( + args: Prisma.PromptHandlerUpdateArgs + ): Promise<PrismaPromptHandler> { + return this.prisma.promptHandler.update(args); + } + async deletePromptHandler( + args: Prisma.PromptHandlerDeleteArgs + ): Promise<PrismaPromptHandler> { + return this.prisma.promptHandler.delete(args); + } + + async findLlmIntegrations( + parentId: string, + args: Prisma.LlmIntegrationFindManyArgs + ): Promise<PrismaLlmIntegration[]> { + return this.prisma.promptHandler + .findUniqueOrThrow({ + where: { id: parentId }, + }) + .llmIntegrations(args); + } + + async getDeployment(parentId: string): Promise<PrismaDeployment | null> { + return this.prisma.promptHandler + .findUnique({ + where: { id: parentId }, + }) + .deployment(); + } +} diff --git a/apps/deployment-orchestrator-server/src/promptHandler/promptHandler.controller.ts b/apps/deployment-orchestrator-server/src/promptHandler/promptHandler.controller.ts new file mode 100644 index 000000000..a3c185e8d --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/promptHandler.controller.ts @@ -0,0 +1,12 @@ +import * as common from "@nestjs/common"; +import * as swagger from "@nestjs/swagger"; +import { PromptHandlerService } from "./promptHandler.service"; +import { PromptHandlerControllerBase } from "./base/promptHandler.controller.base"; + +@swagger.ApiTags("promptHandlers") +@common.Controller("promptHandlers") +export class PromptHandlerController extends PromptHandlerControllerBase { + constructor(protected readonly service: PromptHandlerService) { + super(service); + } +} diff --git a/apps/deployment-orchestrator-server/src/promptHandler/promptHandler.module.ts b/apps/deployment-orchestrator-server/src/promptHandler/promptHandler.module.ts new file mode 100644 index 000000000..709abd2bc --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/promptHandler.module.ts @@ -0,0 +1,13 @@ +import { Module } from "@nestjs/common"; +import { PromptHandlerModuleBase } from "./base/promptHandler.module.base"; +import { PromptHandlerService } from "./promptHandler.service"; +import { PromptHandlerController } from "./promptHandler.controller"; +import { PromptHandlerResolver } from "./promptHandler.resolver"; + +@Module({ + imports: [PromptHandlerModuleBase], + controllers: [PromptHandlerController], + providers: [PromptHandlerService, PromptHandlerResolver], + exports: [PromptHandlerService], +}) +export class PromptHandlerModule {} diff --git a/apps/deployment-orchestrator-server/src/promptHandler/promptHandler.resolver.ts b/apps/deployment-orchestrator-server/src/promptHandler/promptHandler.resolver.ts new file mode 100644 index 000000000..4b848451b --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/promptHandler.resolver.ts @@ -0,0 +1,11 @@ +import * as graphql from "@nestjs/graphql"; +import { PromptHandlerResolverBase } from "./base/promptHandler.resolver.base"; +import { PromptHandler } from "./base/PromptHandler"; +import { PromptHandlerService } from "./promptHandler.service"; + +@graphql.Resolver(() => PromptHandler) +export class PromptHandlerResolver extends PromptHandlerResolverBase { + constructor(protected readonly service: PromptHandlerService) { + super(service); + } +} diff --git a/apps/deployment-orchestrator-server/src/promptHandler/promptHandler.service.ts b/apps/deployment-orchestrator-server/src/promptHandler/promptHandler.service.ts new file mode 100644 index 000000000..ef84c20c5 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/promptHandler/promptHandler.service.ts @@ -0,0 +1,10 @@ +import { Injectable } from "@nestjs/common"; +import { PrismaService } from "../prisma/prisma.service"; +import { PromptHandlerServiceBase } from "./base/promptHandler.service.base"; + +@Injectable() +export class PromptHandlerService extends PromptHandlerServiceBase { + constructor(protected readonly prisma: PrismaService) { + super(prisma); + } +} diff --git a/apps/deployment-orchestrator-server/src/providers/secrets/base/secretsManager.service.base.spec.ts b/apps/deployment-orchestrator-server/src/providers/secrets/base/secretsManager.service.base.spec.ts new file mode 100644 index 000000000..f16117225 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/providers/secrets/base/secretsManager.service.base.spec.ts @@ -0,0 +1,41 @@ +import { ConfigService } from "@nestjs/config"; +import { mock } from "jest-mock-extended"; +import { SecretsManagerServiceBase } from "./secretsManager.service.base"; +import { EnumSecretsNameKey } from "../secretsNameKey.enum"; + +describe("Testing the secrets manager base class", () => { + const SECRET_KEY = "SECRET_KEY"; + const SECRET_VALUE = "SECRET_VALUE"; + const configService = mock<ConfigService>(); + const secretsManagerServiceBase = new SecretsManagerServiceBase( + configService + ); + beforeEach(() => { + configService.get.mockClear(); + }); + it("should return value from env", async () => { + //ARRANGE + configService.get.mockReturnValue(SECRET_VALUE); + //ACT + const result = await secretsManagerServiceBase.getSecret( + SECRET_KEY as unknown as EnumSecretsNameKey + ); + //ASSERT + expect(result).toBe(SECRET_VALUE); + }); + it("should return null for unknown keys", async () => { + //ARRANGE + configService.get.mockReturnValue(undefined); + //ACT + const result = await secretsManagerServiceBase.getSecret( + SECRET_KEY as unknown as EnumSecretsNameKey + ); + //ASSERT + expect(result).toBeNull(); + }); + it("should throw an exception if getting null key", () => { + return expect( + secretsManagerServiceBase.getSecret(null as unknown as EnumSecretsNameKey) + ).rejects.toThrow(); + }); +}); diff --git a/apps/deployment-orchestrator-server/src/providers/secrets/base/secretsManager.service.base.ts b/apps/deployment-orchestrator-server/src/providers/secrets/base/secretsManager.service.base.ts new file mode 100644 index 000000000..340818c23 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/providers/secrets/base/secretsManager.service.base.ts @@ -0,0 +1,17 @@ +import { ConfigService } from "@nestjs/config"; +import { EnumSecretsNameKey } from "../secretsNameKey.enum"; + +export interface ISecretsManager { + getSecret: (key: EnumSecretsNameKey) => Promise<any | null>; +} + +export class SecretsManagerServiceBase implements ISecretsManager { + constructor(protected readonly configService: ConfigService) {} + async getSecret<T>(key: EnumSecretsNameKey): Promise<T | null> { + const value = this.configService.get(key.toString()); + if (value) { + return value; + } + return null; + } +} diff --git a/apps/deployment-orchestrator-server/src/providers/secrets/secretsManager.module.ts b/apps/deployment-orchestrator-server/src/providers/secrets/secretsManager.module.ts new file mode 100644 index 000000000..3a621e40b --- /dev/null +++ b/apps/deployment-orchestrator-server/src/providers/secrets/secretsManager.module.ts @@ -0,0 +1,8 @@ +import { Module } from "@nestjs/common"; +import { SecretsManagerService } from "./secretsManager.service"; + +@Module({ + providers: [SecretsManagerService], + exports: [SecretsManagerService], +}) +export class SecretsManagerModule {} diff --git a/apps/deployment-orchestrator-server/src/providers/secrets/secretsManager.service.ts b/apps/deployment-orchestrator-server/src/providers/secrets/secretsManager.service.ts new file mode 100644 index 000000000..89907c3bb --- /dev/null +++ b/apps/deployment-orchestrator-server/src/providers/secrets/secretsManager.service.ts @@ -0,0 +1,10 @@ +import { Injectable } from "@nestjs/common"; +import { ConfigService } from "@nestjs/config"; +import { SecretsManagerServiceBase } from "./base/secretsManager.service.base"; + +@Injectable() +export class SecretsManagerService extends SecretsManagerServiceBase { + constructor(protected readonly configService: ConfigService) { + super(configService); + } +} diff --git a/apps/deployment-orchestrator-server/src/providers/secrets/secretsNameKey.enum.ts b/apps/deployment-orchestrator-server/src/providers/secrets/secretsNameKey.enum.ts new file mode 100644 index 000000000..e225d65df --- /dev/null +++ b/apps/deployment-orchestrator-server/src/providers/secrets/secretsNameKey.enum.ts @@ -0,0 +1 @@ +export enum EnumSecretsNameKey {} \ No newline at end of file diff --git a/apps/deployment-orchestrator-server/src/serveStaticOptions.service.ts b/apps/deployment-orchestrator-server/src/serveStaticOptions.service.ts new file mode 100644 index 000000000..390248b43 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/serveStaticOptions.service.ts @@ -0,0 +1,39 @@ +import * as path from "path"; +import { Injectable, Logger } from "@nestjs/common"; +import { ConfigService } from "@nestjs/config"; +import { + ServeStaticModuleOptions, + ServeStaticModuleOptionsFactory, +} from "@nestjs/serve-static"; + +const SERVE_STATIC_ROOT_PATH_VAR = "SERVE_STATIC_ROOT_PATH"; +const DEFAULT_STATIC_MODULE_OPTIONS_LIST: ServeStaticModuleOptions[] = [ + { + serveRoot: "/swagger", + rootPath: path.join(__dirname, "swagger"), + }, +]; + +@Injectable() +export class ServeStaticOptionsService + implements ServeStaticModuleOptionsFactory +{ + private readonly logger = new Logger(ServeStaticOptionsService.name); + + constructor(private readonly configService: ConfigService) {} + + createLoggerOptions(): ServeStaticModuleOptions[] { + const serveStaticRootPath = this.configService.get( + SERVE_STATIC_ROOT_PATH_VAR + ); + if (serveStaticRootPath) { + const resolvedPath = path.resolve(serveStaticRootPath); + this.logger.log(`Serving static files from ${resolvedPath}`); + return [ + ...DEFAULT_STATIC_MODULE_OPTIONS_LIST, + { rootPath: resolvedPath, exclude: ["/api*", "/graphql"] }, + ]; + } + return DEFAULT_STATIC_MODULE_OPTIONS_LIST; + } +} diff --git a/apps/deployment-orchestrator-server/src/swagger.ts b/apps/deployment-orchestrator-server/src/swagger.ts new file mode 100644 index 000000000..d3fad7bc1 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/swagger.ts @@ -0,0 +1,20 @@ +import { DocumentBuilder, SwaggerCustomOptions } from "@nestjs/swagger"; + +export const swaggerPath = "api"; + +export const swaggerDocumentOptions = new DocumentBuilder() + .setTitle("Deployment Orchestrator") + .setDescription( + 'Handles prompt parsing and deployment coordination.\n\n## Congratulations! Your service resource is ready.\n \nPlease note that all endpoints are secured with JWT Bearer authentication.\nBy default, your service resource comes with one user with the username "admin" and password "admin".\nLearn more in [our docs](https://docs.amplication.com)' + ) + .addBearerAuth() + .build(); + +export const swaggerSetupOptions: SwaggerCustomOptions = { + swaggerOptions: { + persistAuthorization: true, + }, + customCssUrl: "../swagger/swagger.css", + customfavIcon: "../swagger/favicon.png", + customSiteTitle: "Deployment Orchestrator", +}; diff --git a/apps/deployment-orchestrator-server/src/swagger/favicon.png b/apps/deployment-orchestrator-server/src/swagger/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..a79882d55bdcd1d04939ed7a42257c20ac32f17c GIT binary patch literal 2498 zcmZ`*>rdNd6#kVvl#bgdw{@jJ2c2M{$hfWC29(Qyav88OF5?my1-7meXrU!j6F<&G z-ABd5FD8azVwPxROPCY=pqU9IVsw7-<C6UgK9A>3sY^_r^PK0L_t)QhIp_Dnt0#Nz zUY8*$H%ZepLuW_p0DL|zAr9;d1YSMa)3n&PI$N8EMqLPi?xpdO9FbuTLR}6=B34ZB zy#t_5cb?U4GfMi3xYNne*$y3abW!UWxa^9V{q33d1Q|_*bMr~9z|sXrD};qn7-fYX zJ9r$<JpV?duM@t+3o3Tig-1P5eN4{vNX{J|65&lTytof(;d_g?Zy-06DWbGYd^4O~ zr0{<>ZL*gj`_q@8O&Pu=ZcALiC%(#YrvYl=><YNs>*7ZL+_u<We*AS7<g+h8fYllj zG2+o6g0PNU$ux<(2xm@HJAzKOOvu3hv0<qBri>Z1LLR8y1ma@<cqI7&Rv<YZbeBiO zN$cGU;1!2j4K$Fe=bHE&Fw$02QadFYTmfUnxG+5f#uq^8S=?WU+wO9L1T24P+1=Sv z38#N!9ayWU+d3XNkR}f7H;8Q6yedMkWk8&R8Gn9<Yg&ToCplfuDb{M9bB@7)+Dg6` z$Weuhnwdcq)Q^ByxGoR(U%{>|zuo%${e}1{$Q(P*)dWk2g>f3H@$e(CwZ3uE+aLqK z?07P=SW=y8g0XIce%v;Tj76T%H!`q$&8i7QLkLwB>*hDih!$ad2k`gKV+Pkitia~M zciiE|BnaTf0h>7ReDWpmD!&3CPh79gG4=X4tM|)TnEm_>i}Abag~Lx}tm`7YKN~bC z2{6lGV;gQrDqkGf&e8+xJ?wsU@KBR)f`SwY&8}tmC>XE`v$1gL<sfcTz}M7;qeM}e za7D24;d(F+I0iOu(|Dp?`ybv}hX*oqx28qe*15F7AKz{7xu$wY24eZK0&}oR*jBH^ zbsGT)c6Pwp*pjx&6V5wxOI<%|(cMTIw+=pm6TG~CZ`=`%%EAib)YIJwxY)=XG_O<L z+O$C(7kh&T#%>l&@O}9~kZ&FoBJm70?rd0NJ!Xul;7G7}#yNDdgkg_Qo+ur=9{H$f ze=%oW^lx>uo#SAYe4KT#cr^dPgEz_>PRfAnQcB_5%T5S^nd|4zfPjJ11J(BA>a!xj zd>>m~WlmZJx$`IcjVorK2~<D3-F4Bq$Q<r~I0+9@5TD%$aq<gug2kCwcOJR;U%#5u z`kcH0`d2{Fe9pND1|0D`7;BqEW<F%(_mt59;@eCxz!ww`X6vcz0*a?~p)rk(_!@Xi z0=Fa6?3!^&6tQeAk%Lu{0ngZ;VeC8C&LS;G4naq&s{_)J!rSoX@%Hz7{Sa{#phy%P z-DCaL4}wi=2u5KAjxO$6bvYEEU%8~ScX`xo4Si1Jh6hi+S)M(>>kx1SKnXpd5bWTC z`X(#<zgIdxVnLw}-UvJT_IOu)Vu&g$If(%VT;<L)+-aHW@<8<LJrKLw1QT#pF5Fw& zcl24zBvchE#ZpwmM%Ai9>^Yv^;X_dI6bMM&fAqrxc-3ApTslzP0rD-r_&kecO5$Gw z)fhF90)A5MFm65xcD&1q@Gry-n6-b6S5E#+4flMxno9we)N5k?ddS}oaJLCE1m<PM t<*K%ZYUNV^ClYWAo*T1?*DFfZWvA{M8D=Njui(Ejt+TDS6+sJk`VZG>JHG$` literal 0 HcmV?d00001 diff --git a/apps/deployment-orchestrator-server/src/swagger/logo-amplication-white.svg b/apps/deployment-orchestrator-server/src/swagger/logo-amplication-white.svg new file mode 100644 index 000000000..0054cd4df --- /dev/null +++ b/apps/deployment-orchestrator-server/src/swagger/logo-amplication-white.svg @@ -0,0 +1,15 @@ +<svg width="206" height="45" viewBox="0 0 206 45" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M0 22.472C0 34.0994 8.90877 43.6025 20.3874 44.9441V0C8.90877 1.34161 0 10.9006 0 22.472Z" fill="white"/> +<path d="M46.2574 22.472C46.2574 10.8447 37.2344 1.22981 25.6987 0V45H46.2574V23.1429C46.2574 22.9193 46.2574 22.6957 46.2574 22.472Z" fill="white"/> +<path d="M70.8698 26.2732V38.8508H67.6718V37.1738C66.8152 38.5154 64.9877 39.1303 63.3887 39.1303C60.0194 39.1303 57.0498 36.5589 57.0498 32.534C57.0498 28.5092 59.9623 25.9937 63.3887 25.9937C64.9877 25.9937 66.8152 26.6086 67.6718 27.9502V26.2732H70.8698ZM67.6147 32.534C67.6147 30.298 65.7301 28.9005 63.9027 28.9005C61.9039 28.9005 60.3049 30.4098 60.3049 32.534C60.3049 34.6583 61.9039 36.2235 63.9027 36.2235C65.8444 36.2235 67.6147 34.7701 67.6147 32.534Z" fill="white"/> +<path d="M95.14 31.8074V38.8509H91.942V32.031C91.942 30.0186 90.857 29.0124 89.3722 29.0124C87.5447 29.0124 86.3455 30.354 86.5168 32.6459V32.5341V38.8509H83.3188V32.031C83.3188 30.0186 82.2337 29.0124 80.8632 29.0124C79.3784 29.0124 77.8936 29.795 77.8936 32.1987V38.8509H74.6956V26.2733H77.8936V28.4534C78.3504 26.8882 80.1208 26.0497 81.7198 26.0497C83.6043 26.0497 85.1462 26.8882 85.8886 28.5093C86.9166 26.4969 88.9153 26.0497 90.2288 26.0497C93.4268 25.9938 95.14 28.118 95.14 31.8074Z" fill="white"/> +<path d="M112.614 32.534C112.614 36.5589 109.702 39.0744 106.276 39.0744C104.677 39.0744 102.849 38.4595 101.992 37.1179V44.944H98.7944V26.2732H101.992V27.9502C102.849 26.6086 104.734 25.9937 106.276 25.9937C109.645 25.9937 112.614 28.5651 112.614 32.534ZM109.416 32.5899C109.416 30.4657 107.76 28.9005 105.762 28.9005C103.82 28.9005 102.05 30.3539 102.05 32.5899C102.05 34.8259 103.934 36.2235 105.762 36.2235C107.76 36.2235 109.416 34.7141 109.416 32.5899Z" fill="white"/> +<path d="M115.642 19.5092H118.84V38.8508H115.642V19.5092Z" fill="white"/> +<path d="M122.152 21.8006C122.152 20.6826 123.123 19.9 124.265 19.9C125.407 19.9 126.321 20.6826 126.321 21.8006C126.321 22.8628 125.407 23.7013 124.265 23.7013C123.123 23.7572 122.152 22.9187 122.152 21.8006ZM122.609 26.2727H125.807V38.8503H122.609V26.2727Z" fill="white"/> +<path d="M128.834 32.534C128.834 28.5651 132.09 25.9937 135.859 25.9937C138.086 25.9937 139.913 26.944 141.113 28.3974L138.828 30.1303C138.143 29.3477 137.058 28.8446 135.916 28.8446C133.689 28.8446 132.09 30.3539 132.09 32.4781C132.09 34.6024 133.689 36.1117 135.916 36.1117C137.058 36.1117 138.143 35.6086 138.828 34.826L141.113 36.5589C139.913 38.0123 138.086 38.9626 135.859 38.9626C132.09 39.1303 128.834 36.5589 128.834 32.534Z" fill="white"/> +<path d="M156.589 26.2732V38.8508H153.391V37.1738C152.534 38.5154 150.707 39.1303 149.107 39.1303C145.738 39.1303 142.769 36.5589 142.769 32.534C142.769 28.5092 145.681 25.9937 149.107 25.9937C150.707 25.9937 152.534 26.6086 153.391 27.9502V26.2732H156.589ZM153.333 32.534C153.333 30.298 151.449 28.9005 149.621 28.9005C147.623 28.9005 146.024 30.4098 146.024 32.534C146.024 34.6583 147.623 36.2235 149.621 36.2235C151.563 36.2235 153.333 34.7701 153.333 32.534Z" fill="white"/> +<path d="M167.496 28.7891H164.755V38.9071H161.556V28.7891H159.215V26.2735H161.556V21.6338H164.755V26.2735H167.496V28.7891Z" fill="white"/> +<path d="M169.438 21.8006C169.438 20.6826 170.409 19.9 171.551 19.9C172.693 19.9 173.607 20.6826 173.607 21.8006C173.607 22.8628 172.693 23.7013 171.551 23.7013C170.409 23.7572 169.438 22.9187 169.438 21.8006ZM169.952 26.2727H173.15V38.8503H169.952V26.2727Z" fill="white"/> +<path d="M176.12 32.534C176.12 28.5651 179.318 25.9937 182.973 25.9937C186.627 25.9937 189.825 28.5092 189.825 32.534C189.825 36.503 186.627 39.1303 182.973 39.1303C179.318 39.1303 176.12 36.503 176.12 32.534ZM186.627 32.534C186.627 30.3539 184.971 28.9005 182.973 28.9005C180.974 28.9005 179.375 30.3539 179.375 32.534C179.375 34.7701 180.974 36.2235 182.973 36.2235C184.971 36.2235 186.627 34.7701 186.627 32.534Z" fill="white"/> +<path d="M205.187 31.8073V38.8508H201.989V32.0868C201.989 30.0744 200.733 29.0682 199.305 29.0682C197.82 29.0682 196.05 29.8508 196.05 32.2545V38.8508H192.852V26.2732H196.05V28.2856C196.735 26.7204 198.734 25.9937 200.047 25.9937C203.36 25.9937 205.187 28.1179 205.187 31.8073Z" fill="white"/> +</svg> diff --git a/apps/deployment-orchestrator-server/src/swagger/swagger.css b/apps/deployment-orchestrator-server/src/swagger/swagger.css new file mode 100644 index 000000000..b7c403725 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/swagger/swagger.css @@ -0,0 +1,321 @@ +html, +body { + background-color: #f4f4f7; +} + +body { + margin: auto; + line-height: 1.6; + font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", + "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", + "Helvetica Neue", sans-serif; + color: #121242; +} + +.swagger-ui { + font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", + "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", + "Helvetica Neue", sans-serif; +} + +.swagger-ui button, +.swagger-ui input, +.swagger-ui optgroup, +.swagger-ui select, +.swagger-ui textarea, +.swagger-ui .parameter__name, +.swagger-ui .parameters-col_name > *, +.swagger-ui label { + font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", + "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", + "Helvetica Neue", sans-serif; + font-weight: normal; + font-size: 12px; + outline: none; +} + +.swagger-ui textarea { + border: 1px solid #d0d0d9; + min-height: 100px; +} + +.swagger-ui input[type="email"], +.swagger-ui input[type="file"], +.swagger-ui input[type="password"], +.swagger-ui input[type="search"], +.swagger-ui input[type="text"], +.swagger-ui textarea { + border-radius: 3px; +} + +.swagger-ui input[disabled], +.swagger-ui select[disabled], +.swagger-ui textarea[disabled] { + background: #f4f4f7; + color: #b8b8c6; +} + +.swagger-ui .btn { + font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", + "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", + "Helvetica Neue", sans-serif; + font-weight: 500; + box-shadow: none; + border: 1px solid #d0d0d9; + height: 28px; + border-radius: 14px; + background-color: #fff; + color: #7950ed; +} + +.swagger-ui .btn:hover { + box-shadow: none; +} + +/* topbar */ + +.swagger-ui .topbar { + background-color: #7950ed; + height: 80px; + padding: 0; + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; +} + +.swagger-ui .topbar-wrapper a { + display: block; + width: 206px; + height: 35px; + background-image: url("logo-amplication-white.svg"); + background-repeat: no-repeat; + background-size: contain; +} + +.swagger-ui .topbar-wrapper svg, +.swagger-ui .topbar-wrapper img { + display: none; +} + +/* title */ +.swagger-ui .info { + margin: 0; +} + +.swagger-ui .info .title { + font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", + "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", + "Helvetica Neue", sans-serif; + font-size: 32px; + font-weight: 600; +} + +.swagger-ui .information-container { + padding-top: 50px; + padding-bottom: 20px; + position: relative; +} + +.swagger-ui .info .title small.version-stamp { + display: none; +} + +.swagger-ui .info .title small { + background-color: #a787ff; +} + +.swagger-ui .info .description p { + max-width: 1000px; + margin: 0; +} + +.swagger-ui .info .description p, +.swagger-ui .info .description a { + font-size: 1rem; +} + +.swagger-ui .information-container section { + position: relative; +} + +.swagger-ui .scheme-container { + box-shadow: none; + background-color: transparent; + position: relative; + margin: 0; + margin-top: 20px; + margin-bottom: 20px; + padding: 0; +} + +.swagger-ui .scheme-container .auth-wrapper { + justify-content: flex-start; +} + +.swagger-ui .btn.authorize { + box-shadow: none; + border: 1px solid #d0d0d9; + height: 40px; + border-radius: 20px; + background-color: #fff; + color: #7950ed; +} + +.swagger-ui .btn.authorize svg { + fill: #7950ed; +} + +/* content */ + +.swagger-ui .opblock-tag { + font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", + "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", + "Helvetica Neue", sans-serif; + font-size: 28px; + font-weight: 600; +} + +.swagger-ui .opblock.is-open .opblock-summary { + border-color: #e7e7ec !important; + border-bottom: none; +} + +.swagger-ui .opblock .opblock-section-header { + background-color: #fff; + border: none; + border-top: 1px solid #e7e7ec; + border-bottom: 1px solid #e7e7ec; + box-shadow: none; +} + +.swagger-ui .opblock .tab-header .tab-item.active h4 span:after { + display: none; +} + +.swagger-ui .opblock.opblock-post { + border: 1px solid #e7e7ec; + background: #f9f9fa; + box-shadow: none; + color: #fff; +} + +.swagger-ui .opblock.opblock-post:hover, +.swagger-ui .opblock.opblock-post.is-open { + border-color: #31c587; +} + +.swagger-ui .opblock.opblock-post .opblock-summary-method { + background-color: #31c587; +} + +.swagger-ui .opblock.opblock-get { + border: 1px solid #e7e7ec; + background: #f9f9fa; + box-shadow: none; +} +.swagger-ui .opblock.opblock-get:hover, +.swagger-ui .opblock.opblock-get.is-open { + border-color: #20a4f3; +} +.swagger-ui .opblock.opblock-get .opblock-summary-method { + background-color: #20a4f3; +} + +.swagger-ui .opblock.opblock-delete { + border: 1px solid #e7e7ec; + background: #f9f9fa; + box-shadow: none; +} +.swagger-ui .opblock.opblock-delete:hover, +.swagger-ui .opblock.opblock-delete.is-open { + border-color: #e93c51; +} +.swagger-ui .opblock.opblock-delete .opblock-summary-method { + background-color: #e93c51; +} + +.swagger-ui .opblock.opblock-patch { + border: 1px solid #e7e7ec; + background: #f9f9fa; + box-shadow: none; +} +.swagger-ui .opblock.opblock-patch:hover, +.swagger-ui .opblock.opblock-patch.is-open { + border-color: #41cadd; +} +.swagger-ui .opblock.opblock-patch .opblock-summary-method { + background-color: #41cadd; +} + +.swagger-ui .opblock-body pre { + background-color: #121242 !important; +} + +.swagger-ui select, +.swagger-ui .response-control-media-type--accept-controller select { + border: 1px solid #d0d0d9; + box-shadow: none; + outline: none; +} + +/* models */ + +.swagger-ui section.models { + background-color: #fff; + border: 1px solid #e7e7ec; +} + +.swagger-ui section.models.is-open h4 { + border-bottom: 1px solid #e7e7ec; +} + +.swagger-ui section.models .model-container, +.swagger-ui section.models .model-container:hover { + background-color: #f4f4f7; + color: #121242; +} + +.swagger-ui .model-title { + font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", + "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", + "Helvetica Neue", sans-serif; + font-weight: normal; + font-size: 15px; + color: #121242; +} + +/* modal */ + +.swagger-ui .dialog-ux .modal-ux-header h3, +.swagger-ui .dialog-ux .modal-ux-content h4, +.swagger-ui .dialog-ux .modal-ux-content h4 code { + font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", + "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", + "Helvetica Neue", sans-serif; + font-weight: normal; + font-size: 15px; + color: #121242; +} + +.swagger-ui .dialog-ux .modal-ux-content .btn.authorize { + height: 28px; + border-radius: 14px; +} + +.swagger-ui .auth-btn-wrapper { + display: flex; + flex-direction: row-reverse; + align-items: center; + justify-content: flex-start; +} + +.swagger-ui .auth-btn-wrapper .btn-done { + border: none; + color: #121242; + margin-right: 0; +} + +.swagger-ui .authorization__btn { + fill: #414168; +} diff --git a/apps/deployment-orchestrator-server/src/tests/health/health.service.spec.ts b/apps/deployment-orchestrator-server/src/tests/health/health.service.spec.ts new file mode 100644 index 000000000..4b191f1fd --- /dev/null +++ b/apps/deployment-orchestrator-server/src/tests/health/health.service.spec.ts @@ -0,0 +1,36 @@ +import { mock } from "jest-mock-extended"; +import { PrismaService } from "../../prisma/prisma.service"; +import { HealthServiceBase } from "../../health/base/health.service.base"; + +describe("Testing the HealthServiceBase", () => { + //ARRANGE + let prismaService: PrismaService; + let healthServiceBase: HealthServiceBase; + + describe("Testing the isDbReady function in HealthServiceBase class", () => { + beforeEach(() => { + prismaService = mock<PrismaService>(); + healthServiceBase = new HealthServiceBase(prismaService); + }); + it("should return true if allow connection to db", async () => { + //ARRANGE + (prismaService.$queryRaw as jest.Mock).mockReturnValue( + Promise.resolve(true) + ); + //ACT + const response = await healthServiceBase.isDbReady(); + //ASSERT + expect(response).toBe(true); + }); + it("should return false if db is not available", async () => { + //ARRANGE + (prismaService.$queryRaw as jest.Mock).mockReturnValue( + Promise.reject(false) + ); + //ACT + const response = await healthServiceBase.isDbReady(); + //ASSERT + expect(response).toBe(false); + }); + }); +}); diff --git a/apps/deployment-orchestrator-server/src/types.ts b/apps/deployment-orchestrator-server/src/types.ts new file mode 100644 index 000000000..f762a5dfa --- /dev/null +++ b/apps/deployment-orchestrator-server/src/types.ts @@ -0,0 +1,3 @@ +import type { JsonValue } from "type-fest"; + +export type InputJsonValue = Omit<JsonValue, "null">; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/CloudConnectionCreateNestedManyWithoutUserProfilesInput.ts b/apps/deployment-orchestrator-server/src/userProfile/base/CloudConnectionCreateNestedManyWithoutUserProfilesInput.ts new file mode 100644 index 000000000..c9f926978 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/CloudConnectionCreateNestedManyWithoutUserProfilesInput.ts @@ -0,0 +1,28 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { CloudConnectionWhereUniqueInput } from "../../cloudConnection/base/CloudConnectionWhereUniqueInput"; +import { ApiProperty } from "@nestjs/swagger"; + +@InputType() +class CloudConnectionCreateNestedManyWithoutUserProfilesInput { + @Field(() => [CloudConnectionWhereUniqueInput], { + nullable: true, + }) + @ApiProperty({ + required: false, + type: () => [CloudConnectionWhereUniqueInput], + }) + connect?: Array<CloudConnectionWhereUniqueInput>; +} + +export { CloudConnectionCreateNestedManyWithoutUserProfilesInput as CloudConnectionCreateNestedManyWithoutUserProfilesInput }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/CloudConnectionUpdateManyWithoutUserProfilesInput.ts b/apps/deployment-orchestrator-server/src/userProfile/base/CloudConnectionUpdateManyWithoutUserProfilesInput.ts new file mode 100644 index 000000000..ce9eb7654 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/CloudConnectionUpdateManyWithoutUserProfilesInput.ts @@ -0,0 +1,46 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { CloudConnectionWhereUniqueInput } from "../../cloudConnection/base/CloudConnectionWhereUniqueInput"; +import { ApiProperty } from "@nestjs/swagger"; + +@InputType() +class CloudConnectionUpdateManyWithoutUserProfilesInput { + @Field(() => [CloudConnectionWhereUniqueInput], { + nullable: true, + }) + @ApiProperty({ + required: false, + type: () => [CloudConnectionWhereUniqueInput], + }) + connect?: Array<CloudConnectionWhereUniqueInput>; + + @Field(() => [CloudConnectionWhereUniqueInput], { + nullable: true, + }) + @ApiProperty({ + required: false, + type: () => [CloudConnectionWhereUniqueInput], + }) + disconnect?: Array<CloudConnectionWhereUniqueInput>; + + @Field(() => [CloudConnectionWhereUniqueInput], { + nullable: true, + }) + @ApiProperty({ + required: false, + type: () => [CloudConnectionWhereUniqueInput], + }) + set?: Array<CloudConnectionWhereUniqueInput>; +} + +export { CloudConnectionUpdateManyWithoutUserProfilesInput as CloudConnectionUpdateManyWithoutUserProfilesInput }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/CreateUserProfileArgs.ts b/apps/deployment-orchestrator-server/src/userProfile/base/CreateUserProfileArgs.ts new file mode 100644 index 000000000..2b48c37bd --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/CreateUserProfileArgs.ts @@ -0,0 +1,30 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { UserProfileCreateInput } from "./UserProfileCreateInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; + +@ArgsType() +class CreateUserProfileArgs { + @ApiProperty({ + required: true, + type: () => UserProfileCreateInput, + }) + @ValidateNested() + @Type(() => UserProfileCreateInput) + @Field(() => UserProfileCreateInput, { nullable: false }) + data!: UserProfileCreateInput; +} + +export { CreateUserProfileArgs as CreateUserProfileArgs }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/DeleteUserProfileArgs.ts b/apps/deployment-orchestrator-server/src/userProfile/base/DeleteUserProfileArgs.ts new file mode 100644 index 000000000..29b92e4ee --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/DeleteUserProfileArgs.ts @@ -0,0 +1,30 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { UserProfileWhereUniqueInput } from "./UserProfileWhereUniqueInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; + +@ArgsType() +class DeleteUserProfileArgs { + @ApiProperty({ + required: true, + type: () => UserProfileWhereUniqueInput, + }) + @ValidateNested() + @Type(() => UserProfileWhereUniqueInput) + @Field(() => UserProfileWhereUniqueInput, { nullable: false }) + where!: UserProfileWhereUniqueInput; +} + +export { DeleteUserProfileArgs as DeleteUserProfileArgs }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/DeploymentCreateNestedManyWithoutUserProfilesInput.ts b/apps/deployment-orchestrator-server/src/userProfile/base/DeploymentCreateNestedManyWithoutUserProfilesInput.ts new file mode 100644 index 000000000..279acfbb5 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/DeploymentCreateNestedManyWithoutUserProfilesInput.ts @@ -0,0 +1,28 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { DeploymentWhereUniqueInput } from "../../deployment/base/DeploymentWhereUniqueInput"; +import { ApiProperty } from "@nestjs/swagger"; + +@InputType() +class DeploymentCreateNestedManyWithoutUserProfilesInput { + @Field(() => [DeploymentWhereUniqueInput], { + nullable: true, + }) + @ApiProperty({ + required: false, + type: () => [DeploymentWhereUniqueInput], + }) + connect?: Array<DeploymentWhereUniqueInput>; +} + +export { DeploymentCreateNestedManyWithoutUserProfilesInput as DeploymentCreateNestedManyWithoutUserProfilesInput }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/DeploymentUpdateManyWithoutUserProfilesInput.ts b/apps/deployment-orchestrator-server/src/userProfile/base/DeploymentUpdateManyWithoutUserProfilesInput.ts new file mode 100644 index 000000000..65749eddc --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/DeploymentUpdateManyWithoutUserProfilesInput.ts @@ -0,0 +1,46 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { DeploymentWhereUniqueInput } from "../../deployment/base/DeploymentWhereUniqueInput"; +import { ApiProperty } from "@nestjs/swagger"; + +@InputType() +class DeploymentUpdateManyWithoutUserProfilesInput { + @Field(() => [DeploymentWhereUniqueInput], { + nullable: true, + }) + @ApiProperty({ + required: false, + type: () => [DeploymentWhereUniqueInput], + }) + connect?: Array<DeploymentWhereUniqueInput>; + + @Field(() => [DeploymentWhereUniqueInput], { + nullable: true, + }) + @ApiProperty({ + required: false, + type: () => [DeploymentWhereUniqueInput], + }) + disconnect?: Array<DeploymentWhereUniqueInput>; + + @Field(() => [DeploymentWhereUniqueInput], { + nullable: true, + }) + @ApiProperty({ + required: false, + type: () => [DeploymentWhereUniqueInput], + }) + set?: Array<DeploymentWhereUniqueInput>; +} + +export { DeploymentUpdateManyWithoutUserProfilesInput as DeploymentUpdateManyWithoutUserProfilesInput }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/UpdateUserProfileArgs.ts b/apps/deployment-orchestrator-server/src/userProfile/base/UpdateUserProfileArgs.ts new file mode 100644 index 000000000..c98dee625 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/UpdateUserProfileArgs.ts @@ -0,0 +1,40 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { UserProfileWhereUniqueInput } from "./UserProfileWhereUniqueInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; +import { UserProfileUpdateInput } from "./UserProfileUpdateInput"; + +@ArgsType() +class UpdateUserProfileArgs { + @ApiProperty({ + required: true, + type: () => UserProfileWhereUniqueInput, + }) + @ValidateNested() + @Type(() => UserProfileWhereUniqueInput) + @Field(() => UserProfileWhereUniqueInput, { nullable: false }) + where!: UserProfileWhereUniqueInput; + + @ApiProperty({ + required: true, + type: () => UserProfileUpdateInput, + }) + @ValidateNested() + @Type(() => UserProfileUpdateInput) + @Field(() => UserProfileUpdateInput, { nullable: false }) + data!: UserProfileUpdateInput; +} + +export { UpdateUserProfileArgs as UpdateUserProfileArgs }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/UserProfile.ts b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfile.ts new file mode 100644 index 000000000..6db305e00 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfile.ts @@ -0,0 +1,117 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ObjectType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { CloudConnection } from "../../cloudConnection/base/CloudConnection"; +import { + ValidateNested, + IsOptional, + IsDate, + IsString, + MaxLength, +} from "class-validator"; +import { Type } from "class-transformer"; +import { Deployment } from "../../deployment/base/Deployment"; + +@ObjectType() +class UserProfile { + @ApiProperty({ + required: false, + type: () => [CloudConnection], + }) + @ValidateNested() + @Type(() => CloudConnection) + @IsOptional() + cloudConnections?: Array<CloudConnection>; + + @ApiProperty({ + required: true, + }) + @IsDate() + @Type(() => Date) + @Field(() => Date) + createdAt!: Date; + + @ApiProperty({ + required: false, + type: () => [Deployment], + }) + @ValidateNested() + @Type(() => Deployment) + @IsOptional() + deployments?: Array<Deployment>; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @IsOptional() + @Field(() => String, { + nullable: true, + }) + email!: string | null; + + @ApiProperty({ + required: true, + type: String, + }) + @IsString() + @Field(() => String) + id!: string; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + name!: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + role!: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + sshKey!: string | null; + + @ApiProperty({ + required: true, + }) + @IsDate() + @Type(() => Date) + @Field(() => Date) + updatedAt!: Date; +} + +export { UserProfile as UserProfile }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileCountArgs.ts b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileCountArgs.ts new file mode 100644 index 000000000..d0fb8a69a --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileCountArgs.ts @@ -0,0 +1,28 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { UserProfileWhereInput } from "./UserProfileWhereInput"; +import { Type } from "class-transformer"; + +@ArgsType() +class UserProfileCountArgs { + @ApiProperty({ + required: false, + type: () => UserProfileWhereInput, + }) + @Field(() => UserProfileWhereInput, { nullable: true }) + @Type(() => UserProfileWhereInput) + where?: UserProfileWhereInput; +} + +export { UserProfileCountArgs as UserProfileCountArgs }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileCreateInput.ts b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileCreateInput.ts new file mode 100644 index 000000000..583970f5a --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileCreateInput.ts @@ -0,0 +1,98 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { CloudConnectionCreateNestedManyWithoutUserProfilesInput } from "./CloudConnectionCreateNestedManyWithoutUserProfilesInput"; +import { + ValidateNested, + IsOptional, + IsString, + MaxLength, +} from "class-validator"; +import { Type } from "class-transformer"; +import { DeploymentCreateNestedManyWithoutUserProfilesInput } from "./DeploymentCreateNestedManyWithoutUserProfilesInput"; + +@InputType() +class UserProfileCreateInput { + @ApiProperty({ + required: false, + type: () => CloudConnectionCreateNestedManyWithoutUserProfilesInput, + }) + @ValidateNested() + @Type(() => CloudConnectionCreateNestedManyWithoutUserProfilesInput) + @IsOptional() + @Field(() => CloudConnectionCreateNestedManyWithoutUserProfilesInput, { + nullable: true, + }) + cloudConnections?: CloudConnectionCreateNestedManyWithoutUserProfilesInput; + + @ApiProperty({ + required: false, + type: () => DeploymentCreateNestedManyWithoutUserProfilesInput, + }) + @ValidateNested() + @Type(() => DeploymentCreateNestedManyWithoutUserProfilesInput) + @IsOptional() + @Field(() => DeploymentCreateNestedManyWithoutUserProfilesInput, { + nullable: true, + }) + deployments?: DeploymentCreateNestedManyWithoutUserProfilesInput; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @IsOptional() + @Field(() => String, { + nullable: true, + }) + email?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + name?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + role?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + sshKey?: string | null; +} + +export { UserProfileCreateInput as UserProfileCreateInput }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileFindManyArgs.ts b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileFindManyArgs.ts new file mode 100644 index 000000000..379a05097 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileFindManyArgs.ts @@ -0,0 +1,62 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { UserProfileWhereInput } from "./UserProfileWhereInput"; +import { IsOptional, ValidateNested, IsInt } from "class-validator"; +import { Type } from "class-transformer"; +import { UserProfileOrderByInput } from "./UserProfileOrderByInput"; + +@ArgsType() +class UserProfileFindManyArgs { + @ApiProperty({ + required: false, + type: () => UserProfileWhereInput, + }) + @IsOptional() + @ValidateNested() + @Field(() => UserProfileWhereInput, { nullable: true }) + @Type(() => UserProfileWhereInput) + where?: UserProfileWhereInput; + + @ApiProperty({ + required: false, + type: [UserProfileOrderByInput], + }) + @IsOptional() + @ValidateNested({ each: true }) + @Field(() => [UserProfileOrderByInput], { nullable: true }) + @Type(() => UserProfileOrderByInput) + orderBy?: Array<UserProfileOrderByInput>; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @IsInt() + @Field(() => Number, { nullable: true }) + @Type(() => Number) + skip?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @IsInt() + @Field(() => Number, { nullable: true }) + @Type(() => Number) + take?: number; +} + +export { UserProfileFindManyArgs as UserProfileFindManyArgs }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileFindUniqueArgs.ts b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileFindUniqueArgs.ts new file mode 100644 index 000000000..3bec86844 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileFindUniqueArgs.ts @@ -0,0 +1,30 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { UserProfileWhereUniqueInput } from "./UserProfileWhereUniqueInput"; +import { ValidateNested } from "class-validator"; +import { Type } from "class-transformer"; + +@ArgsType() +class UserProfileFindUniqueArgs { + @ApiProperty({ + required: true, + type: () => UserProfileWhereUniqueInput, + }) + @ValidateNested() + @Type(() => UserProfileWhereUniqueInput) + @Field(() => UserProfileWhereUniqueInput, { nullable: false }) + where!: UserProfileWhereUniqueInput; +} + +export { UserProfileFindUniqueArgs as UserProfileFindUniqueArgs }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileListRelationFilter.ts b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileListRelationFilter.ts new file mode 100644 index 000000000..eb24ff867 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileListRelationFilter.ts @@ -0,0 +1,56 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { UserProfileWhereInput } from "./UserProfileWhereInput"; +import { ValidateNested, IsOptional } from "class-validator"; +import { Type } from "class-transformer"; + +@InputType() +class UserProfileListRelationFilter { + @ApiProperty({ + required: false, + type: () => UserProfileWhereInput, + }) + @ValidateNested() + @Type(() => UserProfileWhereInput) + @IsOptional() + @Field(() => UserProfileWhereInput, { + nullable: true, + }) + every?: UserProfileWhereInput; + + @ApiProperty({ + required: false, + type: () => UserProfileWhereInput, + }) + @ValidateNested() + @Type(() => UserProfileWhereInput) + @IsOptional() + @Field(() => UserProfileWhereInput, { + nullable: true, + }) + some?: UserProfileWhereInput; + + @ApiProperty({ + required: false, + type: () => UserProfileWhereInput, + }) + @ValidateNested() + @Type(() => UserProfileWhereInput) + @IsOptional() + @Field(() => UserProfileWhereInput, { + nullable: true, + }) + none?: UserProfileWhereInput; +} +export { UserProfileListRelationFilter as UserProfileListRelationFilter }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileOrderByInput.ts b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileOrderByInput.ts new file mode 100644 index 000000000..3a3a5fbb2 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileOrderByInput.ts @@ -0,0 +1,100 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional, IsEnum } from "class-validator"; +import { SortOrder } from "../../util/SortOrder"; + +@InputType({ + isAbstract: true, + description: undefined, +}) +class UserProfileOrderByInput { + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + createdAt?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + email?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + id?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + name?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + role?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + sshKey?: SortOrder; + + @ApiProperty({ + required: false, + enum: ["asc", "desc"], + }) + @IsOptional() + @IsEnum(SortOrder) + @Field(() => SortOrder, { + nullable: true, + }) + updatedAt?: SortOrder; +} + +export { UserProfileOrderByInput as UserProfileOrderByInput }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileUpdateInput.ts b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileUpdateInput.ts new file mode 100644 index 000000000..5b776366d --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileUpdateInput.ts @@ -0,0 +1,98 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { CloudConnectionUpdateManyWithoutUserProfilesInput } from "./CloudConnectionUpdateManyWithoutUserProfilesInput"; +import { + ValidateNested, + IsOptional, + IsString, + MaxLength, +} from "class-validator"; +import { Type } from "class-transformer"; +import { DeploymentUpdateManyWithoutUserProfilesInput } from "./DeploymentUpdateManyWithoutUserProfilesInput"; + +@InputType() +class UserProfileUpdateInput { + @ApiProperty({ + required: false, + type: () => CloudConnectionUpdateManyWithoutUserProfilesInput, + }) + @ValidateNested() + @Type(() => CloudConnectionUpdateManyWithoutUserProfilesInput) + @IsOptional() + @Field(() => CloudConnectionUpdateManyWithoutUserProfilesInput, { + nullable: true, + }) + cloudConnections?: CloudConnectionUpdateManyWithoutUserProfilesInput; + + @ApiProperty({ + required: false, + type: () => DeploymentUpdateManyWithoutUserProfilesInput, + }) + @ValidateNested() + @Type(() => DeploymentUpdateManyWithoutUserProfilesInput) + @IsOptional() + @Field(() => DeploymentUpdateManyWithoutUserProfilesInput, { + nullable: true, + }) + deployments?: DeploymentUpdateManyWithoutUserProfilesInput; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @IsOptional() + @Field(() => String, { + nullable: true, + }) + email?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + name?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + role?: string | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsString() + @MaxLength(1000) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + sshKey?: string | null; +} + +export { UserProfileUpdateInput as UserProfileUpdateInput }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileWhereInput.ts b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileWhereInput.ts new file mode 100644 index 000000000..65a67aaee --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileWhereInput.ts @@ -0,0 +1,103 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { CloudConnectionListRelationFilter } from "../../cloudConnection/base/CloudConnectionListRelationFilter"; +import { ValidateNested, IsOptional } from "class-validator"; +import { Type } from "class-transformer"; +import { DeploymentListRelationFilter } from "../../deployment/base/DeploymentListRelationFilter"; +import { StringNullableFilter } from "../../util/StringNullableFilter"; +import { StringFilter } from "../../util/StringFilter"; + +@InputType() +class UserProfileWhereInput { + @ApiProperty({ + required: false, + type: () => CloudConnectionListRelationFilter, + }) + @ValidateNested() + @Type(() => CloudConnectionListRelationFilter) + @IsOptional() + @Field(() => CloudConnectionListRelationFilter, { + nullable: true, + }) + cloudConnections?: CloudConnectionListRelationFilter; + + @ApiProperty({ + required: false, + type: () => DeploymentListRelationFilter, + }) + @ValidateNested() + @Type(() => DeploymentListRelationFilter) + @IsOptional() + @Field(() => DeploymentListRelationFilter, { + nullable: true, + }) + deployments?: DeploymentListRelationFilter; + + @ApiProperty({ + required: false, + type: StringNullableFilter, + }) + @Type(() => StringNullableFilter) + @IsOptional() + @Field(() => StringNullableFilter, { + nullable: true, + }) + email?: StringNullableFilter; + + @ApiProperty({ + required: false, + type: StringFilter, + }) + @Type(() => StringFilter) + @IsOptional() + @Field(() => StringFilter, { + nullable: true, + }) + id?: StringFilter; + + @ApiProperty({ + required: false, + type: StringNullableFilter, + }) + @Type(() => StringNullableFilter) + @IsOptional() + @Field(() => StringNullableFilter, { + nullable: true, + }) + name?: StringNullableFilter; + + @ApiProperty({ + required: false, + type: StringNullableFilter, + }) + @Type(() => StringNullableFilter) + @IsOptional() + @Field(() => StringNullableFilter, { + nullable: true, + }) + role?: StringNullableFilter; + + @ApiProperty({ + required: false, + type: StringNullableFilter, + }) + @Type(() => StringNullableFilter) + @IsOptional() + @Field(() => StringNullableFilter, { + nullable: true, + }) + sshKey?: StringNullableFilter; +} + +export { UserProfileWhereInput as UserProfileWhereInput }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileWhereUniqueInput.ts b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileWhereUniqueInput.ts new file mode 100644 index 000000000..8129bbe8f --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/UserProfileWhereUniqueInput.ts @@ -0,0 +1,27 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { InputType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsString } from "class-validator"; + +@InputType() +class UserProfileWhereUniqueInput { + @ApiProperty({ + required: true, + type: String, + }) + @IsString() + @Field(() => String) + id!: string; +} + +export { UserProfileWhereUniqueInput as UserProfileWhereUniqueInput }; diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/userProfile.controller.base.spec.ts b/apps/deployment-orchestrator-server/src/userProfile/base/userProfile.controller.base.spec.ts new file mode 100644 index 000000000..742642e15 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/userProfile.controller.base.spec.ts @@ -0,0 +1,206 @@ +import { Test } from "@nestjs/testing"; +import { + INestApplication, + HttpStatus, + ExecutionContext, + CallHandler, +} from "@nestjs/common"; +import request from "supertest"; +import { ACGuard } from "nest-access-control"; +import { DefaultAuthGuard } from "../../auth/defaultAuth.guard"; +import { ACLModule } from "../../auth/acl.module"; +import { AclFilterResponseInterceptor } from "../../interceptors/aclFilterResponse.interceptor"; +import { AclValidateRequestInterceptor } from "../../interceptors/aclValidateRequest.interceptor"; +import { map } from "rxjs"; +import { UserProfileController } from "../userProfile.controller"; +import { UserProfileService } from "../userProfile.service"; + +const nonExistingId = "nonExistingId"; +const existingId = "existingId"; +const CREATE_INPUT = { + createdAt: new Date(), + email: "exampleEmail", + id: "exampleId", + name: "exampleName", + role: "exampleRole", + sshKey: "exampleSshKey", + updatedAt: new Date(), +}; +const CREATE_RESULT = { + createdAt: new Date(), + email: "exampleEmail", + id: "exampleId", + name: "exampleName", + role: "exampleRole", + sshKey: "exampleSshKey", + updatedAt: new Date(), +}; +const FIND_MANY_RESULT = [ + { + createdAt: new Date(), + email: "exampleEmail", + id: "exampleId", + name: "exampleName", + role: "exampleRole", + sshKey: "exampleSshKey", + updatedAt: new Date(), + }, +]; +const FIND_ONE_RESULT = { + createdAt: new Date(), + email: "exampleEmail", + id: "exampleId", + name: "exampleName", + role: "exampleRole", + sshKey: "exampleSshKey", + updatedAt: new Date(), +}; + +const service = { + createUserProfile() { + return CREATE_RESULT; + }, + userProfiles: () => FIND_MANY_RESULT, + userProfile: ({ where }: { where: { id: string } }) => { + switch (where.id) { + case existingId: + return FIND_ONE_RESULT; + case nonExistingId: + return null; + } + }, +}; + +const basicAuthGuard = { + canActivate: (context: ExecutionContext) => { + const argumentHost = context.switchToHttp(); + const request = argumentHost.getRequest(); + request.user = { + roles: ["user"], + }; + return true; + }, +}; + +const acGuard = { + canActivate: () => { + return true; + }, +}; + +const aclFilterResponseInterceptor = { + intercept: (context: ExecutionContext, next: CallHandler) => { + return next.handle().pipe( + map((data) => { + return data; + }) + ); + }, +}; +const aclValidateRequestInterceptor = { + intercept: (context: ExecutionContext, next: CallHandler) => { + return next.handle(); + }, +}; + +describe("UserProfile", () => { + let app: INestApplication; + + beforeAll(async () => { + const moduleRef = await Test.createTestingModule({ + providers: [ + { + provide: UserProfileService, + useValue: service, + }, + ], + controllers: [UserProfileController], + imports: [ACLModule], + }) + .overrideGuard(DefaultAuthGuard) + .useValue(basicAuthGuard) + .overrideGuard(ACGuard) + .useValue(acGuard) + .overrideInterceptor(AclFilterResponseInterceptor) + .useValue(aclFilterResponseInterceptor) + .overrideInterceptor(AclValidateRequestInterceptor) + .useValue(aclValidateRequestInterceptor) + .compile(); + + app = moduleRef.createNestApplication(); + await app.init(); + }); + + test("POST /userProfiles", async () => { + await request(app.getHttpServer()) + .post("/userProfiles") + .send(CREATE_INPUT) + .expect(HttpStatus.CREATED) + .expect({ + ...CREATE_RESULT, + createdAt: CREATE_RESULT.createdAt.toISOString(), + updatedAt: CREATE_RESULT.updatedAt.toISOString(), + }); + }); + + test("GET /userProfiles", async () => { + await request(app.getHttpServer()) + .get("/userProfiles") + .expect(HttpStatus.OK) + .expect([ + { + ...FIND_MANY_RESULT[0], + createdAt: FIND_MANY_RESULT[0].createdAt.toISOString(), + updatedAt: FIND_MANY_RESULT[0].updatedAt.toISOString(), + }, + ]); + }); + + test("GET /userProfiles/:id non existing", async () => { + await request(app.getHttpServer()) + .get(`${"/userProfiles"}/${nonExistingId}`) + .expect(HttpStatus.NOT_FOUND) + .expect({ + statusCode: HttpStatus.NOT_FOUND, + message: `No resource was found for {"${"id"}":"${nonExistingId}"}`, + error: "Not Found", + }); + }); + + test("GET /userProfiles/:id existing", async () => { + await request(app.getHttpServer()) + .get(`${"/userProfiles"}/${existingId}`) + .expect(HttpStatus.OK) + .expect({ + ...FIND_ONE_RESULT, + createdAt: FIND_ONE_RESULT.createdAt.toISOString(), + updatedAt: FIND_ONE_RESULT.updatedAt.toISOString(), + }); + }); + + test("POST /userProfiles existing resource", async () => { + const agent = request(app.getHttpServer()); + await agent + .post("/userProfiles") + .send(CREATE_INPUT) + .expect(HttpStatus.CREATED) + .expect({ + ...CREATE_RESULT, + createdAt: CREATE_RESULT.createdAt.toISOString(), + updatedAt: CREATE_RESULT.updatedAt.toISOString(), + }) + .then(function () { + agent + .post("/userProfiles") + .send(CREATE_INPUT) + .expect(HttpStatus.CONFLICT) + .expect({ + statusCode: HttpStatus.CONFLICT, + }); + }); + }); + + afterAll(async () => { + await app.close(); + }); +}); diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/userProfile.controller.base.ts b/apps/deployment-orchestrator-server/src/userProfile/base/userProfile.controller.base.ts new file mode 100644 index 000000000..e1110afbe --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/userProfile.controller.base.ts @@ -0,0 +1,326 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import * as common from "@nestjs/common"; +import * as swagger from "@nestjs/swagger"; +import { isRecordNotFoundError } from "../../prisma.util"; +import * as errors from "../../errors"; +import { Request } from "express"; +import { plainToClass } from "class-transformer"; +import { ApiNestedQuery } from "../../decorators/api-nested-query.decorator"; +import { UserProfileService } from "../userProfile.service"; +import { UserProfileCreateInput } from "./UserProfileCreateInput"; +import { UserProfile } from "./UserProfile"; +import { UserProfileFindManyArgs } from "./UserProfileFindManyArgs"; +import { UserProfileWhereUniqueInput } from "./UserProfileWhereUniqueInput"; +import { UserProfileUpdateInput } from "./UserProfileUpdateInput"; +import { CloudConnectionFindManyArgs } from "../../cloudConnection/base/CloudConnectionFindManyArgs"; +import { CloudConnection } from "../../cloudConnection/base/CloudConnection"; +import { CloudConnectionWhereUniqueInput } from "../../cloudConnection/base/CloudConnectionWhereUniqueInput"; +import { DeploymentFindManyArgs } from "../../deployment/base/DeploymentFindManyArgs"; +import { Deployment } from "../../deployment/base/Deployment"; +import { DeploymentWhereUniqueInput } from "../../deployment/base/DeploymentWhereUniqueInput"; + +export class UserProfileControllerBase { + constructor(protected readonly service: UserProfileService) {} + @common.Post() + @swagger.ApiCreatedResponse({ type: UserProfile }) + async createUserProfile( + @common.Body() data: UserProfileCreateInput + ): Promise<UserProfile> { + return await this.service.createUserProfile({ + data: data, + select: { + createdAt: true, + email: true, + id: true, + name: true, + role: true, + sshKey: true, + updatedAt: true, + }, + }); + } + + @common.Get() + @swagger.ApiOkResponse({ type: [UserProfile] }) + @ApiNestedQuery(UserProfileFindManyArgs) + async userProfiles(@common.Req() request: Request): Promise<UserProfile[]> { + const args = plainToClass(UserProfileFindManyArgs, request.query); + return this.service.userProfiles({ + ...args, + select: { + createdAt: true, + email: true, + id: true, + name: true, + role: true, + sshKey: true, + updatedAt: true, + }, + }); + } + + @common.Get("/:id") + @swagger.ApiOkResponse({ type: UserProfile }) + @swagger.ApiNotFoundResponse({ type: errors.NotFoundException }) + async userProfile( + @common.Param() params: UserProfileWhereUniqueInput + ): Promise<UserProfile | null> { + const result = await this.service.userProfile({ + where: params, + select: { + createdAt: true, + email: true, + id: true, + name: true, + role: true, + sshKey: true, + updatedAt: true, + }, + }); + if (result === null) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + return result; + } + + @common.Patch("/:id") + @swagger.ApiOkResponse({ type: UserProfile }) + @swagger.ApiNotFoundResponse({ type: errors.NotFoundException }) + async updateUserProfile( + @common.Param() params: UserProfileWhereUniqueInput, + @common.Body() data: UserProfileUpdateInput + ): Promise<UserProfile | null> { + try { + return await this.service.updateUserProfile({ + where: params, + data: data, + select: { + createdAt: true, + email: true, + id: true, + name: true, + role: true, + sshKey: true, + updatedAt: true, + }, + }); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + throw error; + } + } + + @common.Delete("/:id") + @swagger.ApiOkResponse({ type: UserProfile }) + @swagger.ApiNotFoundResponse({ type: errors.NotFoundException }) + async deleteUserProfile( + @common.Param() params: UserProfileWhereUniqueInput + ): Promise<UserProfile | null> { + try { + return await this.service.deleteUserProfile({ + where: params, + select: { + createdAt: true, + email: true, + id: true, + name: true, + role: true, + sshKey: true, + updatedAt: true, + }, + }); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + throw error; + } + } + + @common.Get("/:id/cloudConnections") + @ApiNestedQuery(CloudConnectionFindManyArgs) + async findCloudConnections( + @common.Req() request: Request, + @common.Param() params: UserProfileWhereUniqueInput + ): Promise<CloudConnection[]> { + const query = plainToClass(CloudConnectionFindManyArgs, request.query); + const results = await this.service.findCloudConnections(params.id, { + ...query, + select: { + accessKey: true, + createdAt: true, + id: true, + provider: true, + region: true, + updatedAt: true, + + userProfile: { + select: { + id: true, + }, + }, + }, + }); + if (results === null) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + return results; + } + + @common.Post("/:id/cloudConnections") + async connectCloudConnections( + @common.Param() params: UserProfileWhereUniqueInput, + @common.Body() body: CloudConnectionWhereUniqueInput[] + ): Promise<void> { + const data = { + cloudConnections: { + connect: body, + }, + }; + await this.service.updateUserProfile({ + where: params, + data, + select: { id: true }, + }); + } + + @common.Patch("/:id/cloudConnections") + async updateCloudConnections( + @common.Param() params: UserProfileWhereUniqueInput, + @common.Body() body: CloudConnectionWhereUniqueInput[] + ): Promise<void> { + const data = { + cloudConnections: { + set: body, + }, + }; + await this.service.updateUserProfile({ + where: params, + data, + select: { id: true }, + }); + } + + @common.Delete("/:id/cloudConnections") + async disconnectCloudConnections( + @common.Param() params: UserProfileWhereUniqueInput, + @common.Body() body: CloudConnectionWhereUniqueInput[] + ): Promise<void> { + const data = { + cloudConnections: { + disconnect: body, + }, + }; + await this.service.updateUserProfile({ + where: params, + data, + select: { id: true }, + }); + } + + @common.Get("/:id/deployments") + @ApiNestedQuery(DeploymentFindManyArgs) + async findDeployments( + @common.Req() request: Request, + @common.Param() params: UserProfileWhereUniqueInput + ): Promise<Deployment[]> { + const query = plainToClass(DeploymentFindManyArgs, request.query); + const results = await this.service.findDeployments(params.id, { + ...query, + select: { + autoTerminateAt: true, + createdAt: true, + environment: true, + id: true, + region: true, + requestPrompt: true, + resolvedConfig: true, + status: true, + updatedAt: true, + + userProfile: { + select: { + id: true, + }, + }, + }, + }); + if (results === null) { + throw new errors.NotFoundException( + `No resource was found for ${JSON.stringify(params)}` + ); + } + return results; + } + + @common.Post("/:id/deployments") + async connectDeployments( + @common.Param() params: UserProfileWhereUniqueInput, + @common.Body() body: DeploymentWhereUniqueInput[] + ): Promise<void> { + const data = { + deployments: { + connect: body, + }, + }; + await this.service.updateUserProfile({ + where: params, + data, + select: { id: true }, + }); + } + + @common.Patch("/:id/deployments") + async updateDeployments( + @common.Param() params: UserProfileWhereUniqueInput, + @common.Body() body: DeploymentWhereUniqueInput[] + ): Promise<void> { + const data = { + deployments: { + set: body, + }, + }; + await this.service.updateUserProfile({ + where: params, + data, + select: { id: true }, + }); + } + + @common.Delete("/:id/deployments") + async disconnectDeployments( + @common.Param() params: UserProfileWhereUniqueInput, + @common.Body() body: DeploymentWhereUniqueInput[] + ): Promise<void> { + const data = { + deployments: { + disconnect: body, + }, + }; + await this.service.updateUserProfile({ + where: params, + data, + select: { id: true }, + }); + } +} diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/userProfile.module.base.ts b/apps/deployment-orchestrator-server/src/userProfile/base/userProfile.module.base.ts new file mode 100644 index 000000000..172ed5525 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/userProfile.module.base.ts @@ -0,0 +1,18 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { Module } from "@nestjs/common"; + +@Module({ + imports: [], + exports: [], +}) +export class UserProfileModuleBase {} diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/userProfile.resolver.base.ts b/apps/deployment-orchestrator-server/src/userProfile/base/userProfile.resolver.base.ts new file mode 100644 index 000000000..cb9ab294e --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/userProfile.resolver.base.ts @@ -0,0 +1,131 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import * as graphql from "@nestjs/graphql"; +import { GraphQLError } from "graphql"; +import { isRecordNotFoundError } from "../../prisma.util"; +import { MetaQueryPayload } from "../../util/MetaQueryPayload"; +import { UserProfile } from "./UserProfile"; +import { UserProfileCountArgs } from "./UserProfileCountArgs"; +import { UserProfileFindManyArgs } from "./UserProfileFindManyArgs"; +import { UserProfileFindUniqueArgs } from "./UserProfileFindUniqueArgs"; +import { CreateUserProfileArgs } from "./CreateUserProfileArgs"; +import { UpdateUserProfileArgs } from "./UpdateUserProfileArgs"; +import { DeleteUserProfileArgs } from "./DeleteUserProfileArgs"; +import { CloudConnectionFindManyArgs } from "../../cloudConnection/base/CloudConnectionFindManyArgs"; +import { CloudConnection } from "../../cloudConnection/base/CloudConnection"; +import { DeploymentFindManyArgs } from "../../deployment/base/DeploymentFindManyArgs"; +import { Deployment } from "../../deployment/base/Deployment"; +import { UserProfileService } from "../userProfile.service"; +@graphql.Resolver(() => UserProfile) +export class UserProfileResolverBase { + constructor(protected readonly service: UserProfileService) {} + + async _userProfilesMeta( + @graphql.Args() args: UserProfileCountArgs + ): Promise<MetaQueryPayload> { + const result = await this.service.count(args); + return { + count: result, + }; + } + + @graphql.Query(() => [UserProfile]) + async userProfiles( + @graphql.Args() args: UserProfileFindManyArgs + ): Promise<UserProfile[]> { + return this.service.userProfiles(args); + } + + @graphql.Query(() => UserProfile, { nullable: true }) + async userProfile( + @graphql.Args() args: UserProfileFindUniqueArgs + ): Promise<UserProfile | null> { + const result = await this.service.userProfile(args); + if (result === null) { + return null; + } + return result; + } + + @graphql.Mutation(() => UserProfile) + async createUserProfile( + @graphql.Args() args: CreateUserProfileArgs + ): Promise<UserProfile> { + return await this.service.createUserProfile({ + ...args, + data: args.data, + }); + } + + @graphql.Mutation(() => UserProfile) + async updateUserProfile( + @graphql.Args() args: UpdateUserProfileArgs + ): Promise<UserProfile | null> { + try { + return await this.service.updateUserProfile({ + ...args, + data: args.data, + }); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new GraphQLError( + `No resource was found for ${JSON.stringify(args.where)}` + ); + } + throw error; + } + } + + @graphql.Mutation(() => UserProfile) + async deleteUserProfile( + @graphql.Args() args: DeleteUserProfileArgs + ): Promise<UserProfile | null> { + try { + return await this.service.deleteUserProfile(args); + } catch (error) { + if (isRecordNotFoundError(error)) { + throw new GraphQLError( + `No resource was found for ${JSON.stringify(args.where)}` + ); + } + throw error; + } + } + + @graphql.ResolveField(() => [CloudConnection], { name: "cloudConnections" }) + async findCloudConnections( + @graphql.Parent() parent: UserProfile, + @graphql.Args() args: CloudConnectionFindManyArgs + ): Promise<CloudConnection[]> { + const results = await this.service.findCloudConnections(parent.id, args); + + if (!results) { + return []; + } + + return results; + } + + @graphql.ResolveField(() => [Deployment], { name: "deployments" }) + async findDeployments( + @graphql.Parent() parent: UserProfile, + @graphql.Args() args: DeploymentFindManyArgs + ): Promise<Deployment[]> { + const results = await this.service.findDeployments(parent.id, args); + + if (!results) { + return []; + } + + return results; + } +} diff --git a/apps/deployment-orchestrator-server/src/userProfile/base/userProfile.service.base.ts b/apps/deployment-orchestrator-server/src/userProfile/base/userProfile.service.base.ts new file mode 100644 index 000000000..b9d29e197 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/base/userProfile.service.base.ts @@ -0,0 +1,77 @@ +/* +------------------------------------------------------------------------------ +This code was generated by Amplication. + +Changes to this file will be lost if the code is regenerated. + +There are other ways to to customize your code, see this doc to learn more +https://docs.amplication.com/how-to/custom-code + +------------------------------------------------------------------------------ + */ +import { PrismaService } from "../../prisma/prisma.service"; + +import { + Prisma, + UserProfile as PrismaUserProfile, + CloudConnection as PrismaCloudConnection, + Deployment as PrismaDeployment, +} from "@prisma/client"; + +export class UserProfileServiceBase { + constructor(protected readonly prisma: PrismaService) {} + + async count( + args: Omit<Prisma.UserProfileCountArgs, "select"> + ): Promise<number> { + return this.prisma.userProfile.count(args); + } + + async userProfiles( + args: Prisma.UserProfileFindManyArgs + ): Promise<PrismaUserProfile[]> { + return this.prisma.userProfile.findMany(args); + } + async userProfile( + args: Prisma.UserProfileFindUniqueArgs + ): Promise<PrismaUserProfile | null> { + return this.prisma.userProfile.findUnique(args); + } + async createUserProfile( + args: Prisma.UserProfileCreateArgs + ): Promise<PrismaUserProfile> { + return this.prisma.userProfile.create(args); + } + async updateUserProfile( + args: Prisma.UserProfileUpdateArgs + ): Promise<PrismaUserProfile> { + return this.prisma.userProfile.update(args); + } + async deleteUserProfile( + args: Prisma.UserProfileDeleteArgs + ): Promise<PrismaUserProfile> { + return this.prisma.userProfile.delete(args); + } + + async findCloudConnections( + parentId: string, + args: Prisma.CloudConnectionFindManyArgs + ): Promise<PrismaCloudConnection[]> { + return this.prisma.userProfile + .findUniqueOrThrow({ + where: { id: parentId }, + }) + .cloudConnections(args); + } + + async findDeployments( + parentId: string, + args: Prisma.DeploymentFindManyArgs + ): Promise<PrismaDeployment[]> { + return this.prisma.userProfile + .findUniqueOrThrow({ + where: { id: parentId }, + }) + .deployments(args); + } +} diff --git a/apps/deployment-orchestrator-server/src/userProfile/userProfile.controller.ts b/apps/deployment-orchestrator-server/src/userProfile/userProfile.controller.ts new file mode 100644 index 000000000..07c564b0f --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/userProfile.controller.ts @@ -0,0 +1,12 @@ +import * as common from "@nestjs/common"; +import * as swagger from "@nestjs/swagger"; +import { UserProfileService } from "./userProfile.service"; +import { UserProfileControllerBase } from "./base/userProfile.controller.base"; + +@swagger.ApiTags("userProfiles") +@common.Controller("userProfiles") +export class UserProfileController extends UserProfileControllerBase { + constructor(protected readonly service: UserProfileService) { + super(service); + } +} diff --git a/apps/deployment-orchestrator-server/src/userProfile/userProfile.module.ts b/apps/deployment-orchestrator-server/src/userProfile/userProfile.module.ts new file mode 100644 index 000000000..8b82d6afd --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/userProfile.module.ts @@ -0,0 +1,13 @@ +import { Module } from "@nestjs/common"; +import { UserProfileModuleBase } from "./base/userProfile.module.base"; +import { UserProfileService } from "./userProfile.service"; +import { UserProfileController } from "./userProfile.controller"; +import { UserProfileResolver } from "./userProfile.resolver"; + +@Module({ + imports: [UserProfileModuleBase], + controllers: [UserProfileController], + providers: [UserProfileService, UserProfileResolver], + exports: [UserProfileService], +}) +export class UserProfileModule {} diff --git a/apps/deployment-orchestrator-server/src/userProfile/userProfile.resolver.ts b/apps/deployment-orchestrator-server/src/userProfile/userProfile.resolver.ts new file mode 100644 index 000000000..3e03b5e43 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/userProfile.resolver.ts @@ -0,0 +1,11 @@ +import * as graphql from "@nestjs/graphql"; +import { UserProfileResolverBase } from "./base/userProfile.resolver.base"; +import { UserProfile } from "./base/UserProfile"; +import { UserProfileService } from "./userProfile.service"; + +@graphql.Resolver(() => UserProfile) +export class UserProfileResolver extends UserProfileResolverBase { + constructor(protected readonly service: UserProfileService) { + super(service); + } +} diff --git a/apps/deployment-orchestrator-server/src/userProfile/userProfile.service.ts b/apps/deployment-orchestrator-server/src/userProfile/userProfile.service.ts new file mode 100644 index 000000000..b2378e0a8 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/userProfile/userProfile.service.ts @@ -0,0 +1,10 @@ +import { Injectable } from "@nestjs/common"; +import { PrismaService } from "../prisma/prisma.service"; +import { UserProfileServiceBase } from "./base/userProfile.service.base"; + +@Injectable() +export class UserProfileService extends UserProfileServiceBase { + constructor(protected readonly prisma: PrismaService) { + super(prisma); + } +} diff --git a/apps/deployment-orchestrator-server/src/util/BooleanFilter.ts b/apps/deployment-orchestrator-server/src/util/BooleanFilter.ts new file mode 100644 index 000000000..75f4e3445 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/util/BooleanFilter.ts @@ -0,0 +1,32 @@ +import { Field, InputType } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional } from "class-validator"; +import { Type } from "class-transformer"; + +@InputType({ + isAbstract: true, + description: undefined, +}) +export class BooleanFilter { + @ApiProperty({ + required: false, + type: Boolean, + }) + @IsOptional() + @Field(() => Boolean, { + nullable: true, + }) + @Type(() => Boolean) + equals?: boolean; + + @ApiProperty({ + required: false, + type: Boolean, + }) + @IsOptional() + @Field(() => Boolean, { + nullable: true, + }) + @Type(() => Boolean) + not?: boolean; +} diff --git a/apps/deployment-orchestrator-server/src/util/BooleanNullableFilter.ts b/apps/deployment-orchestrator-server/src/util/BooleanNullableFilter.ts new file mode 100644 index 000000000..9f48ac17f --- /dev/null +++ b/apps/deployment-orchestrator-server/src/util/BooleanNullableFilter.ts @@ -0,0 +1,31 @@ +import { Field, InputType } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional } from "class-validator"; +import { Type } from "class-transformer"; +@InputType({ + isAbstract: true, + description: undefined, +}) +export class BooleanNullableFilter { + @ApiProperty({ + required: false, + type: Boolean, + }) + @IsOptional() + @Field(() => Boolean, { + nullable: true, + }) + @Type(() => Boolean) + equals?: boolean | null; + + @ApiProperty({ + required: false, + type: Boolean, + }) + @IsOptional() + @Field(() => Boolean, { + nullable: true, + }) + @Type(() => Boolean) + not?: boolean | null; +} diff --git a/apps/deployment-orchestrator-server/src/util/DateTimeFilter.ts b/apps/deployment-orchestrator-server/src/util/DateTimeFilter.ts new file mode 100644 index 000000000..d2b6dfba8 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/util/DateTimeFilter.ts @@ -0,0 +1,97 @@ +import { Field, InputType } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional } from "class-validator"; +import { Type } from "class-transformer"; +@InputType({ + isAbstract: true, + description: undefined, +}) +export class DateTimeFilter { + @ApiProperty({ + required: false, + type: Date, + }) + @IsOptional() + @Field(() => Date, { + nullable: true, + }) + @Type(() => Date) + equals?: Date; + + @ApiProperty({ + required: false, + type: Date, + }) + @IsOptional() + @Field(() => Date, { + nullable: true, + }) + @Type(() => Date) + not?: Date; + + @ApiProperty({ + required: false, + type: [Date], + }) + @IsOptional() + @Field(() => [Date], { + nullable: true, + }) + @Type(() => Date) + in?: Date[]; + + @ApiProperty({ + required: false, + type: [Date], + }) + @IsOptional() + @Field(() => [Date], { + nullable: true, + }) + @Type(() => Date) + notIn?: Date[]; + + @ApiProperty({ + required: false, + type: Date, + }) + @IsOptional() + @Field(() => Date, { + nullable: true, + }) + @Type(() => Date) + lt?: Date; + + @ApiProperty({ + required: false, + type: Date, + }) + @IsOptional() + @Field(() => Date, { + nullable: true, + }) + @Type(() => Date) + lte?: Date; + + @ApiProperty({ + required: false, + type: Date, + }) + @IsOptional() + @Field(() => Date, { + nullable: true, + }) + @Type(() => Date) + gt?: Date; + + @ApiProperty({ + required: false, + type: Date, + }) + @IsOptional() + @Field(() => Date, { + nullable: true, + }) + @Type(() => Date) + gte?: Date; +} diff --git a/apps/deployment-orchestrator-server/src/util/DateTimeNullableFilter.ts b/apps/deployment-orchestrator-server/src/util/DateTimeNullableFilter.ts new file mode 100644 index 000000000..ccc00a549 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/util/DateTimeNullableFilter.ts @@ -0,0 +1,97 @@ +import { Field, InputType } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional } from "class-validator"; +import { Type } from "class-transformer"; +@InputType({ + isAbstract: true, + description: undefined, +}) +export class DateTimeNullableFilter { + @ApiProperty({ + required: false, + type: Date, + }) + @IsOptional() + @Field(() => Date, { + nullable: true, + }) + @Type(() => Date) + equals?: Date | null; + + @ApiProperty({ + required: false, + type: [Date], + }) + @IsOptional() + @Field(() => [Date], { + nullable: true, + }) + @Type(() => Date) + in?: Date[] | null; + + @ApiProperty({ + required: false, + type: [Date], + }) + @IsOptional() + @Field(() => [Date], { + nullable: true, + }) + @Type(() => Date) + notIn?: Date[] | null; + + @ApiProperty({ + required: false, + type: Date, + }) + @IsOptional() + @Field(() => Date, { + nullable: true, + }) + @Type(() => Date) + lt?: Date; + + @ApiProperty({ + required: false, + type: Date, + }) + @IsOptional() + @Field(() => Date, { + nullable: true, + }) + @Type(() => Date) + lte?: Date; + + @ApiProperty({ + required: false, + type: Date, + }) + @IsOptional() + @Field(() => Date, { + nullable: true, + }) + @Type(() => Date) + gt?: Date; + + @ApiProperty({ + required: false, + type: Date, + }) + @IsOptional() + @Field(() => Date, { + nullable: true, + }) + @Type(() => Date) + gte?: Date; + + @ApiProperty({ + required: false, + type: Date, + }) + @IsOptional() + @Field(() => Date, { + nullable: true, + }) + @Type(() => Date) + not?: Date; +} diff --git a/apps/deployment-orchestrator-server/src/util/FloatFilter.ts b/apps/deployment-orchestrator-server/src/util/FloatFilter.ts new file mode 100644 index 000000000..a3266d211 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/util/FloatFilter.ts @@ -0,0 +1,98 @@ +import { Field, InputType, Float } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional } from "class-validator"; +import { Type } from "class-transformer"; + +@InputType({ + isAbstract: true, + description: undefined, +}) +export class FloatFilter { + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Float, { + nullable: true, + }) + @Type(() => Number) + equals?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => [Float], { + nullable: true, + }) + @Type(() => Number) + in?: number[]; + + @ApiProperty({ + required: false, + type: [Number], + }) + @IsOptional() + @Field(() => [Float], { + nullable: true, + }) + @Type(() => Number) + notIn?: number[]; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Float, { + nullable: true, + }) + @Type(() => Number) + lt?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Float, { + nullable: true, + }) + @Type(() => Number) + lte?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Float, { + nullable: true, + }) + @Type(() => Number) + gt?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Float, { + nullable: true, + }) + @Type(() => Number) + gte?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Float, { + nullable: true, + }) + @Type(() => Number) + not?: number; +} diff --git a/apps/deployment-orchestrator-server/src/util/FloatNullableFilter.ts b/apps/deployment-orchestrator-server/src/util/FloatNullableFilter.ts new file mode 100644 index 000000000..feb0fc528 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/util/FloatNullableFilter.ts @@ -0,0 +1,98 @@ +import { Field, InputType, Float } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional } from "class-validator"; +import { Type } from "class-transformer"; + +@InputType({ + isAbstract: true, + description: undefined, +}) +export class FloatNullableFilter { + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Float, { + nullable: true, + }) + @Type(() => Number) + equals?: number | null; + + @ApiProperty({ + required: false, + type: [Number], + }) + @IsOptional() + @Field(() => [Float], { + nullable: true, + }) + @Type(() => Number) + in?: number[] | null; + + @ApiProperty({ + required: false, + type: [Number], + }) + @IsOptional() + @Field(() => [Float], { + nullable: true, + }) + @Type(() => Number) + notIn?: number[] | null; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Float, { + nullable: true, + }) + @Type(() => Number) + lt?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Float, { + nullable: true, + }) + @Type(() => Number) + lte?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Float, { + nullable: true, + }) + @Type(() => Number) + gt?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Float, { + nullable: true, + }) + @Type(() => Number) + gte?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Float, { + nullable: true, + }) + @Type(() => Number) + not?: number; +} diff --git a/apps/deployment-orchestrator-server/src/util/IntFilter.ts b/apps/deployment-orchestrator-server/src/util/IntFilter.ts new file mode 100644 index 000000000..f6880e778 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/util/IntFilter.ts @@ -0,0 +1,98 @@ +import { Field, InputType, Int } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional } from "class-validator"; +import { Type } from "class-transformer"; + +@InputType({ + isAbstract: true, + description: undefined, +}) +export class IntFilter { + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Int, { + nullable: true, + }) + @Type(() => Number) + equals?: number; + + @ApiProperty({ + required: false, + type: [Number], + }) + @IsOptional() + @Field(() => [Int], { + nullable: true, + }) + @Type(() => Number) + in?: number[]; + + @ApiProperty({ + required: false, + type: [Number], + }) + @IsOptional() + @Field(() => [Int], { + nullable: true, + }) + @Type(() => Number) + notIn?: number[]; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Int, { + nullable: true, + }) + @Type(() => Number) + lt?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Int, { + nullable: true, + }) + @Type(() => Number) + lte?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Int, { + nullable: true, + }) + @Type(() => Number) + gt?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Int, { + nullable: true, + }) + @Type(() => Number) + gte?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Int, { + nullable: true, + }) + @Type(() => Number) + not?: number; +} diff --git a/apps/deployment-orchestrator-server/src/util/IntNullableFilter.ts b/apps/deployment-orchestrator-server/src/util/IntNullableFilter.ts new file mode 100644 index 000000000..e3b71a33e --- /dev/null +++ b/apps/deployment-orchestrator-server/src/util/IntNullableFilter.ts @@ -0,0 +1,98 @@ +import { Field, InputType, Int } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional } from "class-validator"; +import { Type } from "class-transformer"; + +@InputType({ + isAbstract: true, + description: undefined, +}) +export class IntNullableFilter { + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Int, { + nullable: true, + }) + @Type(() => Number) + equals?: number | null; + + @ApiProperty({ + required: false, + type: [Number], + }) + @IsOptional() + @Field(() => [Int], { + nullable: true, + }) + @Type(() => Number) + in?: number[] | null; + + @ApiProperty({ + required: false, + type: [Number], + }) + @IsOptional() + @Field(() => [Int], { + nullable: true, + }) + @Type(() => Number) + notIn?: number[] | null; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Int, { + nullable: true, + }) + @Type(() => Number) + lt?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Int, { + nullable: true, + }) + @Type(() => Number) + lte?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Int, { + nullable: true, + }) + @Type(() => Number) + gt?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Int, { + nullable: true, + }) + @Type(() => Number) + gte?: number; + + @ApiProperty({ + required: false, + type: Number, + }) + @IsOptional() + @Field(() => Int, { + nullable: true, + }) + @Type(() => Number) + not?: number; +} diff --git a/apps/deployment-orchestrator-server/src/util/JsonFilter.ts b/apps/deployment-orchestrator-server/src/util/JsonFilter.ts new file mode 100644 index 000000000..7040b74f3 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/util/JsonFilter.ts @@ -0,0 +1,31 @@ +import { Field, InputType } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional } from "class-validator"; +import { GraphQLJSONObject } from "graphql-type-json"; +import { InputJsonValue } from "../types"; + +@InputType({ + isAbstract: true, + description: undefined, +}) +export class JsonFilter { + @ApiProperty({ + required: false, + type: GraphQLJSONObject, + }) + @IsOptional() + @Field(() => GraphQLJSONObject, { + nullable: true, + }) + equals?: InputJsonValue; + + @ApiProperty({ + required: false, + type: GraphQLJSONObject, + }) + @IsOptional() + @Field(() => GraphQLJSONObject, { + nullable: true, + }) + not?: InputJsonValue; +} diff --git a/apps/deployment-orchestrator-server/src/util/JsonNullableFilter.ts b/apps/deployment-orchestrator-server/src/util/JsonNullableFilter.ts new file mode 100644 index 000000000..3381d5242 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/util/JsonNullableFilter.ts @@ -0,0 +1,31 @@ +import type { JsonValue } from "type-fest"; +import { Field, InputType } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional } from "class-validator"; +import { GraphQLJSONObject } from "graphql-type-json"; + +@InputType({ + isAbstract: true, + description: undefined, +}) +export class JsonNullableFilter { + @ApiProperty({ + required: false, + type: GraphQLJSONObject, + }) + @IsOptional() + @Field(() => GraphQLJSONObject, { + nullable: true, + }) + equals?: JsonValue; + + @ApiProperty({ + required: false, + type: GraphQLJSONObject, + }) + @IsOptional() + @Field(() => GraphQLJSONObject, { + nullable: true, + }) + not?: JsonValue; +} diff --git a/apps/deployment-orchestrator-server/src/util/MetaQueryPayload.ts b/apps/deployment-orchestrator-server/src/util/MetaQueryPayload.ts new file mode 100644 index 000000000..fc30531c0 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/util/MetaQueryPayload.ts @@ -0,0 +1,13 @@ +import { ObjectType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; + +@ObjectType() +class MetaQueryPayload { + @ApiProperty({ + required: true, + type: [Number], + }) + @Field(() => Number) + count!: number; +} +export { MetaQueryPayload }; diff --git a/apps/deployment-orchestrator-server/src/util/QueryMode.ts b/apps/deployment-orchestrator-server/src/util/QueryMode.ts new file mode 100644 index 000000000..f9b1653e9 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/util/QueryMode.ts @@ -0,0 +1,10 @@ +import { registerEnumType } from "@nestjs/graphql"; + +export enum QueryMode { + Default = "default", + Insensitive = "insensitive", +} +registerEnumType(QueryMode, { + name: "QueryMode", + description: undefined, +}); diff --git a/apps/deployment-orchestrator-server/src/util/SortOrder.ts b/apps/deployment-orchestrator-server/src/util/SortOrder.ts new file mode 100644 index 000000000..d4108e69b --- /dev/null +++ b/apps/deployment-orchestrator-server/src/util/SortOrder.ts @@ -0,0 +1,10 @@ +import { registerEnumType } from "@nestjs/graphql"; + +export enum SortOrder { + Asc = "asc", + Desc = "desc", +} +registerEnumType(SortOrder, { + name: "SortOrder", + description: undefined, +}); diff --git a/apps/deployment-orchestrator-server/src/util/StringFilter.ts b/apps/deployment-orchestrator-server/src/util/StringFilter.ts new file mode 100644 index 000000000..80b573d02 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/util/StringFilter.ts @@ -0,0 +1,141 @@ +import { Field, InputType } from "@nestjs/graphql"; +import { QueryMode } from "./QueryMode"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional } from "class-validator"; +import { Type } from "class-transformer"; + +@InputType({ + isAbstract: true, +}) +export class StringFilter { + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + equals?: string; + + @ApiProperty({ + required: false, + type: [String], + }) + @IsOptional() + @Field(() => [String], { + nullable: true, + }) + @Type(() => String) + in?: string[]; + + @ApiProperty({ + required: false, + type: [String], + }) + @IsOptional() + @Field(() => [String], { + nullable: true, + }) + @Type(() => String) + notIn?: string[]; + + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + lt?: string; + + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + lte?: string; + + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + gt?: string; + + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + gte?: string; + + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + contains?: string; + + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + startsWith?: string; + + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + endsWith?: string; + + @ApiProperty({ + required: false, + enum: ["Default", "Insensitive"], + }) + @IsOptional() + @Field(() => QueryMode, { + nullable: true, + }) + mode?: QueryMode; + + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + not?: string; +} diff --git a/apps/deployment-orchestrator-server/src/util/StringNullableFilter.ts b/apps/deployment-orchestrator-server/src/util/StringNullableFilter.ts new file mode 100644 index 000000000..01b399cb3 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/util/StringNullableFilter.ts @@ -0,0 +1,141 @@ +import { Field, InputType } from "@nestjs/graphql"; +import { QueryMode } from "./QueryMode"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsOptional } from "class-validator"; +import { Type } from "class-transformer"; + +@InputType({ + isAbstract: true, +}) +export class StringNullableFilter { + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + equals?: string | null; + + @ApiProperty({ + required: false, + type: [String], + }) + @IsOptional() + @Field(() => [String], { + nullable: true, + }) + @Type(() => String) + in?: string[] | null; + + @ApiProperty({ + required: false, + type: [String], + }) + @IsOptional() + @Field(() => [String], { + nullable: true, + }) + @Type(() => String) + notIn?: string[] | null; + + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + lt?: string; + + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + lte?: string; + + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + gt?: string; + + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + gte?: string; + + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + contains?: string; + + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + startsWith?: string; + + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + endsWith?: string; + + @ApiProperty({ + required: false, + enum: ["Default", "Insensitive"], + }) + @IsOptional() + @Field(() => QueryMode, { + nullable: true, + }) + mode?: QueryMode; + + @ApiProperty({ + required: false, + type: String, + }) + @IsOptional() + @Field(() => String, { + nullable: true, + }) + @Type(() => String) + not?: string; +} diff --git a/apps/deployment-orchestrator-server/src/validators/index.ts b/apps/deployment-orchestrator-server/src/validators/index.ts new file mode 100644 index 000000000..7f62d844d --- /dev/null +++ b/apps/deployment-orchestrator-server/src/validators/index.ts @@ -0,0 +1 @@ +export * from "./is-json-value-validator"; diff --git a/apps/deployment-orchestrator-server/src/validators/is-json-value-validator.spec.ts b/apps/deployment-orchestrator-server/src/validators/is-json-value-validator.spec.ts new file mode 100644 index 000000000..5a7782420 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/validators/is-json-value-validator.spec.ts @@ -0,0 +1,44 @@ +import { validate, ValidationError } from "class-validator"; +import { IsJSONValue } from "./is-json-value-validator"; + +class TestClass { + @IsJSONValue() + jsonProperty: unknown; +} + +describe("IsJSONValue", () => { + it("should validate a valid JSON string", async () => { + const testObj = new TestClass(); + testObj.jsonProperty = '{"name": "John", "age": 30}'; + const errors: ValidationError[] = await validate(testObj); + expect(errors.length).toBe(0); + }); + + it("should not validate an invalid JSON string", async () => { + const testObj = new TestClass(); + testObj.jsonProperty = '{name: "John", age: 30}'; + const errors: ValidationError[] = await validate(testObj); + expect(errors.length).toBe(1); + }); + + it("should not validate an invalid JSON string", async () => { + const testObj = new TestClass(); + testObj.jsonProperty = "John"; + const errors: ValidationError[] = await validate(testObj); + expect(errors.length).toBe(1); + }); + + it("should validate a valid JSON object", async () => { + const testObj = new TestClass(); + testObj.jsonProperty = { name: "John", age: 30 }; + const errors: ValidationError[] = await validate(testObj); + expect(errors.length).toBe(0); + }); + + it("should validate a valid JSON array", async () => { + const testObj = new TestClass(); + testObj.jsonProperty = ["John", "30"]; + const errors: ValidationError[] = await validate(testObj); + expect(errors.length).toBe(0); + }); +}); diff --git a/apps/deployment-orchestrator-server/src/validators/is-json-value-validator.ts b/apps/deployment-orchestrator-server/src/validators/is-json-value-validator.ts new file mode 100644 index 000000000..1002540ab --- /dev/null +++ b/apps/deployment-orchestrator-server/src/validators/is-json-value-validator.ts @@ -0,0 +1,29 @@ +import { + ValidationArguments, + registerDecorator, + ValidationOptions, +} from "class-validator"; +import isJSONValidator from "validator/lib/isJSON"; + +export function IsJSONValue(validationOptions?: ValidationOptions) { + return function (object: Record<string, any>, propertyName: string) { + registerDecorator({ + name: "IsJSONValue", + target: object.constructor, + propertyName: propertyName, + options: validationOptions, + validator: { + validate(value: any, args: ValidationArguments) { + if (typeof value === "string") { + return isJSONValidator(value); + } + + return isJSONValidator(JSON.stringify(value)); + }, + defaultMessage(args: ValidationArguments): string { + return `${args.property} must be a valid json`; + }, + }, + }); + }; +} diff --git a/apps/deployment-orchestrator-server/tsconfig.build.json b/apps/deployment-orchestrator-server/tsconfig.build.json new file mode 100644 index 000000000..e57940178 --- /dev/null +++ b/apps/deployment-orchestrator-server/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["node_modules", "prisma", "test", "dist", "**/*spec.ts", "admin"] +} diff --git a/apps/deployment-orchestrator-server/tsconfig.json b/apps/deployment-orchestrator-server/tsconfig.json new file mode 100644 index 000000000..707e8cd0a --- /dev/null +++ b/apps/deployment-orchestrator-server/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "baseUrl": "./", + "module": "commonjs", + "declaration": false, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "target": "es2022", + "lib": ["es2023"], + "sourceMap": true, + "outDir": "./dist", + "incremental": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true + }, + "include": ["src"] +} From 5fa1d1b1274def44b35d3a57816a8a9cbd97fe0b Mon Sep 17 00:00:00 2001 From: "amplication[bot]" <bot@amplication.com> Date: Mon, 26 May 2025 23:58:32 +0000 Subject: [PATCH 2/2] Amplication build # cmb5qyu1c0txd6zgmwfsa5du1 Commit message: Add custom deployment orchestration API endpoints (start deployment, sync status, validate cloud credentials) and full model relations/fields. Build URL: [https://app.amplication.com/cmb5ob2l90t4f6zgmiv25nof5/cmb5ocxdq0ra2j0tz5cxs6f3r/cmb5pom8f0tfzjwsit3tf1azx/builds/cmb5qyu1c0txd6zgmwfsa5du1](https://app.amplication.com/cmb5ob2l90t4f6zgmiv25nof5/cmb5ocxdq0ra2j0tz5cxs6f3r/cmb5pom8f0tfzjwsit3tf1azx/builds/cmb5qyu1c0txd6zgmwfsa5du1) --- .../cloudConnection/CloudCredentialsInput.ts | 24 +++++++++ .../CloudCredentialsValidation.ts | 26 ++++++++++ .../base/cloudConnection.controller.base.ts | 19 +++++++ .../base/cloudConnection.resolver.base.ts | 10 ++++ .../base/cloudConnection.service.base.ts | 8 +++ .../src/deployment/StartDeploymentInput.ts | 52 +++++++++++++++++++ .../src/deployment/StartDeploymentResult.ts | 34 ++++++++++++ .../src/deployment/SyncStatusInput.ts | 16 ++++++ .../src/deployment/SyncStatusResult.ts | 30 +++++++++++ .../base/deployment.controller.base.ts | 38 ++++++++++++++ .../base/deployment.resolver.base.ts | 20 +++++++ .../base/deployment.service.base.ts | 13 +++++ 12 files changed, 290 insertions(+) create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/CloudCredentialsInput.ts create mode 100644 apps/deployment-orchestrator-server/src/cloudConnection/CloudCredentialsValidation.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/StartDeploymentInput.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/StartDeploymentResult.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/SyncStatusInput.ts create mode 100644 apps/deployment-orchestrator-server/src/deployment/SyncStatusResult.ts diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/CloudCredentialsInput.ts b/apps/deployment-orchestrator-server/src/cloudConnection/CloudCredentialsInput.ts new file mode 100644 index 000000000..b9ca4d1e9 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/CloudCredentialsInput.ts @@ -0,0 +1,24 @@ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { Type } from "class-transformer"; + +@ArgsType() +class CloudCredentialsInput { + @Field(() => String) + @ApiProperty({ + required: true, + type: () => String + }) + @Type(() => String) + provider!: string; + + @Field(() => String) + @ApiProperty({ + required: true, + type: () => String + }) + @Type(() => String) + credentialsJson!: string; +} + +export { CloudCredentialsInput as CloudCredentialsInput }; \ No newline at end of file diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/CloudCredentialsValidation.ts b/apps/deployment-orchestrator-server/src/cloudConnection/CloudCredentialsValidation.ts new file mode 100644 index 000000000..a7cede9b7 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/cloudConnection/CloudCredentialsValidation.ts @@ -0,0 +1,26 @@ +import { ObjectType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { Type } from "class-transformer"; + +@ObjectType("CloudCredentialsValidationObject") +class CloudCredentialsValidation { + @Field(() => Boolean) + @ApiProperty({ + required: true, + type: () => Boolean + }) + @Type(() => Boolean) + isValid!: boolean; + + @Field(() => String, { + nullable: true + }) + @ApiProperty({ + required: false, + type: () => String + }) + @Type(() => String) + message?: string; +} + +export { CloudCredentialsValidation as CloudCredentialsValidation }; \ No newline at end of file diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.controller.base.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.controller.base.ts index 89bd23552..4bccf4a87 100644 --- a/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.controller.base.ts +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.controller.base.ts @@ -22,6 +22,8 @@ import { CloudConnection } from "./CloudConnection"; import { CloudConnectionFindManyArgs } from "./CloudConnectionFindManyArgs"; import { CloudConnectionWhereUniqueInput } from "./CloudConnectionWhereUniqueInput"; import { CloudConnectionUpdateInput } from "./CloudConnectionUpdateInput"; +import { CloudCredentialsInput } from "../CloudCredentialsInput"; +import { CloudCredentialsValidation } from "../CloudCredentialsValidation"; export class CloudConnectionControllerBase { constructor(protected readonly service: CloudConnectionService) {} @@ -191,4 +193,21 @@ export class CloudConnectionControllerBase { throw error; } } + + @common.Post("/validate-credentials") + @swagger.ApiOkResponse({ + type: CloudCredentialsValidation, + }) + @swagger.ApiNotFoundResponse({ + type: errors.NotFoundException, + }) + @swagger.ApiForbiddenResponse({ + type: errors.ForbiddenException, + }) + async ValidateCloudCredentials( + @common.Body() + body: CloudCredentialsInput + ): Promise<CloudCredentialsValidation> { + return this.service.ValidateCloudCredentials(body); + } } diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.resolver.base.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.resolver.base.ts index 7b833a04e..a08fdab6d 100644 --- a/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.resolver.base.ts +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.resolver.base.ts @@ -21,6 +21,8 @@ import { CreateCloudConnectionArgs } from "./CreateCloudConnectionArgs"; import { UpdateCloudConnectionArgs } from "./UpdateCloudConnectionArgs"; import { DeleteCloudConnectionArgs } from "./DeleteCloudConnectionArgs"; import { UserProfile } from "../../userProfile/base/UserProfile"; +import { CloudCredentialsInput } from "../CloudCredentialsInput"; +import { CloudCredentialsValidation } from "../CloudCredentialsValidation"; import { CloudConnectionService } from "../cloudConnection.service"; @graphql.Resolver(() => CloudConnection) export class CloudConnectionResolverBase { @@ -128,4 +130,12 @@ export class CloudConnectionResolverBase { } return result; } + + @graphql.Mutation(() => CloudCredentialsValidation) + async ValidateCloudCredentials( + @graphql.Args() + args: CloudCredentialsInput + ): Promise<CloudCredentialsValidation> { + return this.service.ValidateCloudCredentials(args); + } } diff --git a/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.service.base.ts b/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.service.base.ts index d071e70bf..026b9bbb0 100644 --- a/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.service.base.ts +++ b/apps/deployment-orchestrator-server/src/cloudConnection/base/cloudConnection.service.base.ts @@ -17,6 +17,9 @@ import { UserProfile as PrismaUserProfile, } from "@prisma/client"; +import { CloudCredentialsInput } from "../CloudCredentialsInput"; +import { CloudCredentialsValidation } from "../CloudCredentialsValidation"; + export class CloudConnectionServiceBase { constructor(protected readonly prisma: PrismaService) {} @@ -59,4 +62,9 @@ export class CloudConnectionServiceBase { }) .userProfile(); } + async ValidateCloudCredentials( + args: CloudCredentialsInput + ): Promise<CloudCredentialsValidation> { + throw new Error("Not implemented"); + } } diff --git a/apps/deployment-orchestrator-server/src/deployment/StartDeploymentInput.ts b/apps/deployment-orchestrator-server/src/deployment/StartDeploymentInput.ts new file mode 100644 index 000000000..18e433f2b --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/StartDeploymentInput.ts @@ -0,0 +1,52 @@ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { Type } from "class-transformer"; + +@ArgsType() +class StartDeploymentInput { + @Field(() => String) + @ApiProperty({ + required: true, + type: () => String + }) + @Type(() => String) + prompt!: string; + + @Field(() => [String]) + @ApiProperty({ + required: true, + type: () => [String] + }) + @Type(() => String) + cloudProviders!: string; + + @Field(() => String, { + nullable: true + }) + @ApiProperty({ + required: false, + type: () => String + }) + @Type(() => String) + region?: string; + + @Field(() => String, { + nullable: true + }) + @ApiProperty({ + required: false, + type: () => String + }) + @Type(() => String) + instanceType?: string; + + @Field(() => String) + @ApiProperty({ + required: true, + type: () => String + }) + @Type(() => String) + userId!: string; +} + +export { StartDeploymentInput as StartDeploymentInput }; \ No newline at end of file diff --git a/apps/deployment-orchestrator-server/src/deployment/StartDeploymentResult.ts b/apps/deployment-orchestrator-server/src/deployment/StartDeploymentResult.ts new file mode 100644 index 000000000..b73378bda --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/StartDeploymentResult.ts @@ -0,0 +1,34 @@ +import { ObjectType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { Type } from "class-transformer"; + +@ObjectType("StartDeploymentResultObject") +class StartDeploymentResult { + @Field(() => String) + @ApiProperty({ + required: true, + type: () => String + }) + @Type(() => String) + deploymentId!: string; + + @Field(() => String) + @ApiProperty({ + required: true, + type: () => String + }) + @Type(() => String) + status!: string; + + @Field(() => String, { + nullable: true + }) + @ApiProperty({ + required: false, + type: () => String + }) + @Type(() => String) + details?: string; +} + +export { StartDeploymentResult as StartDeploymentResult }; \ No newline at end of file diff --git a/apps/deployment-orchestrator-server/src/deployment/SyncStatusInput.ts b/apps/deployment-orchestrator-server/src/deployment/SyncStatusInput.ts new file mode 100644 index 000000000..5c72ed90c --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/SyncStatusInput.ts @@ -0,0 +1,16 @@ +import { ArgsType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { Type } from "class-transformer"; + +@ArgsType() +class SyncStatusInput { + @Field(() => String) + @ApiProperty({ + required: true, + type: () => String + }) + @Type(() => String) + deploymentId!: string; +} + +export { SyncStatusInput as SyncStatusInput }; \ No newline at end of file diff --git a/apps/deployment-orchestrator-server/src/deployment/SyncStatusResult.ts b/apps/deployment-orchestrator-server/src/deployment/SyncStatusResult.ts new file mode 100644 index 000000000..10bc2f690 --- /dev/null +++ b/apps/deployment-orchestrator-server/src/deployment/SyncStatusResult.ts @@ -0,0 +1,30 @@ +import { ObjectType, Field } from "@nestjs/graphql"; +import { ApiProperty } from "@nestjs/swagger"; +import { Type } from "class-transformer"; + +@ObjectType("SyncStatusResultObject") +class SyncStatusResult { + @Field(() => String) + @ApiProperty({ + required: true, + type: () => String + }) + @Type(() => String) + deploymentId!: string; + + @Field(() => String) + @ApiProperty({ + required: true, + type: () => String + }) + @Type(() => String) + status!: string; + + @Field(() => Date, { + nullable: true + }) + @Type(() => Date) + updatedAt?: Date; +} + +export { SyncStatusResult as SyncStatusResult }; \ No newline at end of file diff --git a/apps/deployment-orchestrator-server/src/deployment/base/deployment.controller.base.ts b/apps/deployment-orchestrator-server/src/deployment/base/deployment.controller.base.ts index 4358fd167..fcf576c01 100644 --- a/apps/deployment-orchestrator-server/src/deployment/base/deployment.controller.base.ts +++ b/apps/deployment-orchestrator-server/src/deployment/base/deployment.controller.base.ts @@ -25,6 +25,10 @@ import { DeploymentUpdateInput } from "./DeploymentUpdateInput"; import { PromptHandlerFindManyArgs } from "../../promptHandler/base/PromptHandlerFindManyArgs"; import { PromptHandler } from "../../promptHandler/base/PromptHandler"; import { PromptHandlerWhereUniqueInput } from "../../promptHandler/base/PromptHandlerWhereUniqueInput"; +import { StartDeploymentInput } from "../StartDeploymentInput"; +import { StartDeploymentResult } from "../StartDeploymentResult"; +import { SyncStatusInput } from "../SyncStatusInput"; +import { SyncStatusResult } from "../SyncStatusResult"; export class DeploymentControllerBase { constructor(protected readonly service: DeploymentService) {} @@ -292,4 +296,38 @@ export class DeploymentControllerBase { select: { id: true }, }); } + + @common.Post("/start") + @swagger.ApiOkResponse({ + type: StartDeploymentResult, + }) + @swagger.ApiNotFoundResponse({ + type: errors.NotFoundException, + }) + @swagger.ApiForbiddenResponse({ + type: errors.ForbiddenException, + }) + async StartDeployment( + @common.Body() + body: StartDeploymentInput + ): Promise<StartDeploymentResult> { + return this.service.StartDeployment(body); + } + + @common.Post("/sync-status") + @swagger.ApiOkResponse({ + type: SyncStatusResult, + }) + @swagger.ApiNotFoundResponse({ + type: errors.NotFoundException, + }) + @swagger.ApiForbiddenResponse({ + type: errors.ForbiddenException, + }) + async SyncDeploymentStatus( + @common.Body() + body: SyncStatusInput + ): Promise<SyncStatusResult> { + return this.service.SyncDeploymentStatus(body); + } } diff --git a/apps/deployment-orchestrator-server/src/deployment/base/deployment.resolver.base.ts b/apps/deployment-orchestrator-server/src/deployment/base/deployment.resolver.base.ts index 2b63878a2..5d7783d65 100644 --- a/apps/deployment-orchestrator-server/src/deployment/base/deployment.resolver.base.ts +++ b/apps/deployment-orchestrator-server/src/deployment/base/deployment.resolver.base.ts @@ -23,6 +23,10 @@ import { DeleteDeploymentArgs } from "./DeleteDeploymentArgs"; import { PromptHandlerFindManyArgs } from "../../promptHandler/base/PromptHandlerFindManyArgs"; import { PromptHandler } from "../../promptHandler/base/PromptHandler"; import { UserProfile } from "../../userProfile/base/UserProfile"; +import { StartDeploymentInput } from "../StartDeploymentInput"; +import { StartDeploymentResult } from "../StartDeploymentResult"; +import { SyncStatusInput } from "../SyncStatusInput"; +import { SyncStatusResult } from "../SyncStatusResult"; import { DeploymentService } from "../deployment.service"; @graphql.Resolver(() => Deployment) export class DeploymentResolverBase { @@ -144,4 +148,20 @@ export class DeploymentResolverBase { } return result; } + + @graphql.Mutation(() => StartDeploymentResult) + async StartDeployment( + @graphql.Args() + args: StartDeploymentInput + ): Promise<StartDeploymentResult> { + return this.service.StartDeployment(args); + } + + @graphql.Mutation(() => SyncStatusResult) + async SyncDeploymentStatus( + @graphql.Args() + args: SyncStatusInput + ): Promise<SyncStatusResult> { + return this.service.SyncDeploymentStatus(args); + } } diff --git a/apps/deployment-orchestrator-server/src/deployment/base/deployment.service.base.ts b/apps/deployment-orchestrator-server/src/deployment/base/deployment.service.base.ts index bf04778d4..61ff2a896 100644 --- a/apps/deployment-orchestrator-server/src/deployment/base/deployment.service.base.ts +++ b/apps/deployment-orchestrator-server/src/deployment/base/deployment.service.base.ts @@ -18,6 +18,11 @@ import { UserProfile as PrismaUserProfile, } from "@prisma/client"; +import { StartDeploymentInput } from "../StartDeploymentInput"; +import { StartDeploymentResult } from "../StartDeploymentResult"; +import { SyncStatusInput } from "../SyncStatusInput"; +import { SyncStatusResult } from "../SyncStatusResult"; + export class DeploymentServiceBase { constructor(protected readonly prisma: PrismaService) {} @@ -71,4 +76,12 @@ export class DeploymentServiceBase { }) .userProfile(); } + async StartDeployment( + args: StartDeploymentInput + ): Promise<StartDeploymentResult> { + throw new Error("Not implemented"); + } + async SyncDeploymentStatus(args: SyncStatusInput): Promise<SyncStatusResult> { + throw new Error("Not implemented"); + } }