From 0a10f7c6540034a2250f5390743f633ddfb8af03 Mon Sep 17 00:00:00 2001 From: Mir Arif Hasan Date: Fri, 24 Nov 2023 20:37:35 +0600 Subject: [PATCH] feat: update infra configs mutation added --- .../src/admin/admin.module.ts | 2 + .../src/admin/infra.resolver.ts | 36 +++++++++++++++++- packages/hoppscotch-backend/src/errors.ts | 6 +++ .../src/infra-config/infra-config.model.ts | 15 +++++++- .../infra-config/infra-config.service.spec.ts | 6 +-- .../src/infra-config/infra-config.service.ts | 37 ++++++++++++++++++- .../src/infra-config/input-args.ts | 15 ++++++++ 7 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 packages/hoppscotch-backend/src/infra-config/input-args.ts diff --git a/packages/hoppscotch-backend/src/admin/admin.module.ts b/packages/hoppscotch-backend/src/admin/admin.module.ts index 273062d10..593038fc2 100644 --- a/packages/hoppscotch-backend/src/admin/admin.module.ts +++ b/packages/hoppscotch-backend/src/admin/admin.module.ts @@ -12,6 +12,7 @@ import { TeamCollectionModule } from '../team-collection/team-collection.module' import { TeamRequestModule } from '../team-request/team-request.module'; import { InfraResolver } from './infra.resolver'; import { ShortcodeModule } from 'src/shortcode/shortcode.module'; +import { InfraConfigModule } from 'src/infra-config/infra-config.module'; @Module({ imports: [ @@ -25,6 +26,7 @@ import { ShortcodeModule } from 'src/shortcode/shortcode.module'; TeamCollectionModule, TeamRequestModule, ShortcodeModule, + InfraConfigModule, ], providers: [InfraResolver, AdminResolver, AdminService], exports: [AdminService], diff --git a/packages/hoppscotch-backend/src/admin/infra.resolver.ts b/packages/hoppscotch-backend/src/admin/infra.resolver.ts index 40b438a9e..146d510fe 100644 --- a/packages/hoppscotch-backend/src/admin/infra.resolver.ts +++ b/packages/hoppscotch-backend/src/admin/infra.resolver.ts @@ -1,5 +1,12 @@ import { UseGuards } from '@nestjs/common'; -import { Args, ID, Query, ResolveField, Resolver } from '@nestjs/graphql'; +import { + Args, + ID, + Mutation, + Query, + ResolveField, + Resolver, +} from '@nestjs/graphql'; import { GqlThrottlerGuard } from 'src/guards/gql-throttler.guard'; import { Infra } from './infra.model'; import { AdminService } from './admin.service'; @@ -16,11 +23,17 @@ import { Team } from 'src/team/team.model'; import { TeamInvitation } from 'src/team-invitation/team-invitation.model'; import { GqlAdmin } from './decorators/gql-admin.decorator'; import { ShortcodeWithUserEmail } from 'src/shortcode/shortcode.model'; +import { InfraConfig } from 'src/infra-config/infra-config.model'; +import { InfraConfigService } from 'src/infra-config/infra-config.service'; +import { InfraConfigArgs } from 'src/infra-config/input-args'; @UseGuards(GqlThrottlerGuard) @Resolver(() => Infra) export class InfraResolver { - constructor(private adminService: AdminService) {} + constructor( + private adminService: AdminService, + private infraConfigService: InfraConfigService, + ) {} @Query(() => Infra, { description: 'Fetch details of the Infrastructure', @@ -222,4 +235,23 @@ export class InfraResolver { userEmail, ); } + + /* Mutations */ + + @Mutation(() => [InfraConfig], { + description: 'Update Infra Configs', + }) + @UseGuards(GqlAuthGuard, GqlAdminGuard) + async updateInfraConfigs( + @Args({ + name: 'infraConfigs', + type: () => [InfraConfigArgs], + description: 'InfraConfigs to update', + }) + infraConfigs: InfraConfigArgs[], + ) { + const updatedRes = await this.infraConfigService.updateMany(infraConfigs); + if (E.isLeft(updatedRes)) throwErr(updatedRes.left); + return updatedRes.right; + } } diff --git a/packages/hoppscotch-backend/src/errors.ts b/packages/hoppscotch-backend/src/errors.ts index 845a884f2..d51593e4f 100644 --- a/packages/hoppscotch-backend/src/errors.ts +++ b/packages/hoppscotch-backend/src/errors.ts @@ -651,6 +651,12 @@ export const SHORTCODE_PROPERTIES_NOT_FOUND = */ export const INFRA_CONFIG_NOT_FOUND = 'infra_config/not_found' as const; +/** + * Infra Config update failed + * (InfraConfigService) + */ +export const INFRA_CONFIG_UPDATE_FAILED = 'infra_config/update_failed' as const; + /** * Infra Config not listed for onModuleInit creation * (InfraConfigService) diff --git a/packages/hoppscotch-backend/src/infra-config/infra-config.model.ts b/packages/hoppscotch-backend/src/infra-config/infra-config.model.ts index d275726ce..b431721e3 100644 --- a/packages/hoppscotch-backend/src/infra-config/infra-config.model.ts +++ b/packages/hoppscotch-backend/src/infra-config/infra-config.model.ts @@ -1,14 +1,25 @@ -import { Field, ObjectType } from '@nestjs/graphql'; +import { + ArgsType, + Field, + InputType, + ObjectType, + registerEnumType, +} from '@nestjs/graphql'; +import { InfraConfigEnum } from 'src/types/InfraConfig'; @ObjectType() export class InfraConfig { @Field({ description: 'Infra Config Name', }) - name: string; + name: InfraConfigEnum; @Field({ description: 'Infra Config Value', }) value: string; } + +registerEnumType(InfraConfigEnum, { + name: 'InfraConfigEnum', +}); diff --git a/packages/hoppscotch-backend/src/infra-config/infra-config.service.spec.ts b/packages/hoppscotch-backend/src/infra-config/infra-config.service.spec.ts index c7fb4075a..3c5507902 100644 --- a/packages/hoppscotch-backend/src/infra-config/infra-config.service.spec.ts +++ b/packages/hoppscotch-backend/src/infra-config/infra-config.service.spec.ts @@ -2,7 +2,7 @@ import { mockDeep, mockReset } from 'jest-mock-extended'; import { PrismaService } from 'src/prisma/prisma.service'; import { InfraConfigService } from './infra-config.service'; import { InfraConfigEnum } from 'src/types/InfraConfig'; -import { INFRA_CONFIG_NOT_FOUND } from 'src/errors'; +import { INFRA_CONFIG_NOT_FOUND, INFRA_CONFIG_UPDATE_FAILED } from 'src/errors'; import { ConfigService } from '@nestjs/config'; import * as helper from './helper'; @@ -55,14 +55,14 @@ describe('InfraConfigService', () => { expect(mockPrisma.infraConfig.update).toHaveBeenCalledTimes(1); }); - it('should throw an error if the infra config does not exist', async () => { + it('should throw an error if the infra config update failed', async () => { const name = InfraConfigEnum.GOOGLE_CLIENT_ID; const value = 'true'; mockPrisma.infraConfig.update.mockRejectedValueOnce('null'); const result = await infraConfigService.update(name, value); - expect(result).toEqualLeft(INFRA_CONFIG_NOT_FOUND); + expect(result).toEqualLeft(INFRA_CONFIG_UPDATE_FAILED); }); }); diff --git a/packages/hoppscotch-backend/src/infra-config/infra-config.service.ts b/packages/hoppscotch-backend/src/infra-config/infra-config.service.ts index 8976be4d2..51c5c9bc3 100644 --- a/packages/hoppscotch-backend/src/infra-config/infra-config.service.ts +++ b/packages/hoppscotch-backend/src/infra-config/infra-config.service.ts @@ -8,10 +8,12 @@ import { DATABASE_TABLE_NOT_EXIST, INFRA_CONFIG_NOT_FOUND, INFRA_CONFIG_NOT_LISTED, + INFRA_CONFIG_UPDATE_FAILED, } from 'src/errors'; import { throwErr } from 'src/utils'; import { ConfigService } from '@nestjs/config'; import { stopApp } from './helper'; +import { InfraConfigArgs } from './input-args'; @Injectable() export class InfraConfigService implements OnModuleInit { @@ -153,7 +155,40 @@ export class InfraConfigService implements OnModuleInit { return E.right(this.cast(infraConfig)); } catch (e) { - return E.left(INFRA_CONFIG_NOT_FOUND); + return E.left(INFRA_CONFIG_UPDATE_FAILED); + } + } + + /** + * Update InfraConfigs by name + * @param infraConfigs InfraConfigs to update + * @returns InfraConfig model + */ + async updateMany(infraConfigs: InfraConfigArgs[]) { + try { + await this.prisma.$transaction(async (tx) => { + const deleteCount = await tx.infraConfig.deleteMany({ + where: { name: { in: infraConfigs.map((p) => p.name) } }, + }); + + const createCount = await tx.infraConfig.createMany({ + data: infraConfigs.map((p) => ({ + name: p.name, + value: p.value, + })), + }); + + if (deleteCount.count !== createCount.count) { + throwErr(INFRA_CONFIG_UPDATE_FAILED); + } + }); + + stopApp(); + + return E.right(infraConfigs); + } catch (e) { + console.log(e); + return E.left(INFRA_CONFIG_UPDATE_FAILED); } } diff --git a/packages/hoppscotch-backend/src/infra-config/input-args.ts b/packages/hoppscotch-backend/src/infra-config/input-args.ts new file mode 100644 index 000000000..f283ff432 --- /dev/null +++ b/packages/hoppscotch-backend/src/infra-config/input-args.ts @@ -0,0 +1,15 @@ +import { Field, InputType } from '@nestjs/graphql'; +import { InfraConfigEnum } from 'src/types/InfraConfig'; + +@InputType() +export class InfraConfigArgs { + @Field(() => InfraConfigEnum, { + description: 'Infra Config Name', + }) + name: InfraConfigEnum; + + @Field({ + description: 'Infra Config Value', + }) + value: string; +}