* feat: added new columns into the TeamCollections and UserCollections models * feat: completed addition of new data field in TeamCollection * feat: completed addition of new data field in UserCollections * chore: updated all tests in team-collection module * chore: added tests for updateTeamCollection method in team-collection module * chore: refactored all existing testcases in user-collection to reflect new changes * chore: added new testcases for updateUserCollection method in user-collection module * chore: made data field optional in team and user collections * chore: fixed edgecases for data being null * chore: resolved issue with team-request testcases * chore: completed changes requested in PR review * chore: changed target to prod in hoppscotch-old-backend service
444 lines
12 KiB
TypeScript
444 lines
12 KiB
TypeScript
import { UseGuards } from '@nestjs/common';
|
|
import {
|
|
Resolver,
|
|
Mutation,
|
|
Args,
|
|
ID,
|
|
Query,
|
|
ResolveField,
|
|
Parent,
|
|
Subscription,
|
|
} from '@nestjs/graphql';
|
|
import { GqlUser } from 'src/decorators/gql-user.decorator';
|
|
import { GqlAuthGuard } from 'src/guards/gql-auth.guard';
|
|
import { PubSubService } from 'src/pubsub/pubsub.service';
|
|
import { AuthUser } from 'src/types/AuthUser';
|
|
import { UserCollectionService } from './user-collection.service';
|
|
import {
|
|
UserCollection,
|
|
UserCollectionExportJSONData,
|
|
UserCollectionRemovedData,
|
|
UserCollectionReorderData,
|
|
} from './user-collections.model';
|
|
import { throwErr } from 'src/utils';
|
|
import { User } from 'src/user/user.model';
|
|
import { PaginationArgs } from 'src/types/input-types.args';
|
|
import {
|
|
CreateChildUserCollectionArgs,
|
|
CreateRootUserCollectionArgs,
|
|
ImportUserCollectionsFromJSONArgs,
|
|
MoveUserCollectionArgs,
|
|
RenameUserCollectionsArgs,
|
|
UpdateUserCollectionArgs,
|
|
UpdateUserCollectionsArgs,
|
|
} from './input-type.args';
|
|
import { ReqType } from 'src/types/RequestTypes';
|
|
import * as E from 'fp-ts/Either';
|
|
import { GqlThrottlerGuard } from 'src/guards/gql-throttler.guard';
|
|
import { SkipThrottle } from '@nestjs/throttler';
|
|
|
|
@UseGuards(GqlThrottlerGuard)
|
|
@Resolver(() => UserCollection)
|
|
export class UserCollectionResolver {
|
|
constructor(
|
|
private readonly userCollectionService: UserCollectionService,
|
|
private readonly pubSub: PubSubService,
|
|
) {}
|
|
|
|
// Field Resolvers
|
|
@ResolveField(() => User, {
|
|
description: 'User the collection belongs to',
|
|
})
|
|
async user(@GqlUser() user: AuthUser) {
|
|
return user;
|
|
}
|
|
|
|
@ResolveField(() => UserCollection, {
|
|
description: 'Parent user collection (null if root)',
|
|
nullable: true,
|
|
})
|
|
async parent(@Parent() collection: UserCollection) {
|
|
return this.userCollectionService.getParentOfUserCollection(collection.id);
|
|
}
|
|
|
|
@ResolveField(() => [UserCollection], {
|
|
description: 'List of children REST user collection',
|
|
complexity: 3,
|
|
})
|
|
childrenREST(
|
|
@Parent() collection: UserCollection,
|
|
@Args() args: PaginationArgs,
|
|
) {
|
|
return this.userCollectionService.getChildrenOfUserCollection(
|
|
collection.id,
|
|
args.cursor,
|
|
args.take,
|
|
ReqType.REST,
|
|
);
|
|
}
|
|
|
|
@ResolveField(() => [UserCollection], {
|
|
description: 'List of children GraphQL user collection',
|
|
complexity: 3,
|
|
})
|
|
childrenGQL(
|
|
@Parent() collection: UserCollection,
|
|
@Args() args: PaginationArgs,
|
|
) {
|
|
return this.userCollectionService.getChildrenOfUserCollection(
|
|
collection.id,
|
|
args.cursor,
|
|
args.take,
|
|
ReqType.GQL,
|
|
);
|
|
}
|
|
|
|
// Queries
|
|
@Query(() => [UserCollection], {
|
|
description: 'Get the root REST user collections for a user',
|
|
})
|
|
@UseGuards(GqlAuthGuard)
|
|
rootRESTUserCollections(
|
|
@GqlUser() user: AuthUser,
|
|
@Args() args: PaginationArgs,
|
|
) {
|
|
return this.userCollectionService.getUserRootCollections(
|
|
user,
|
|
args.cursor,
|
|
args.take,
|
|
ReqType.REST,
|
|
);
|
|
}
|
|
|
|
@Query(() => [UserCollection], {
|
|
description: 'Get the root GraphQL user collections for a user',
|
|
})
|
|
@UseGuards(GqlAuthGuard)
|
|
rootGQLUserCollections(
|
|
@GqlUser() user: AuthUser,
|
|
@Args() args: PaginationArgs,
|
|
) {
|
|
return this.userCollectionService.getUserRootCollections(
|
|
user,
|
|
args.cursor,
|
|
args.take,
|
|
ReqType.GQL,
|
|
);
|
|
}
|
|
|
|
@Query(() => UserCollection, {
|
|
description: 'Get user collection with ID',
|
|
})
|
|
@UseGuards(GqlAuthGuard)
|
|
async userCollection(
|
|
@Args({
|
|
type: () => ID,
|
|
name: 'userCollectionID',
|
|
description: 'ID of the user collection',
|
|
})
|
|
userCollectionID: string,
|
|
) {
|
|
const userCollection = await this.userCollectionService.getUserCollection(
|
|
userCollectionID,
|
|
);
|
|
|
|
if (E.isLeft(userCollection)) throwErr(userCollection.left);
|
|
return <UserCollection>{
|
|
...userCollection.right,
|
|
userID: userCollection.right.userUid,
|
|
data: !userCollection.right.data
|
|
? null
|
|
: JSON.stringify(userCollection.right.data),
|
|
};
|
|
}
|
|
|
|
@Query(() => UserCollectionExportJSONData, {
|
|
description:
|
|
'Returns the JSON string giving the collections and their contents of a user',
|
|
})
|
|
@UseGuards(GqlAuthGuard)
|
|
async exportUserCollectionsToJSON(
|
|
@GqlUser() user: AuthUser,
|
|
@Args({
|
|
type: () => ID,
|
|
name: 'collectionID',
|
|
description: 'ID of the user collection',
|
|
nullable: true,
|
|
defaultValue: null,
|
|
})
|
|
collectionID: string,
|
|
@Args({
|
|
type: () => ReqType,
|
|
name: 'collectionType',
|
|
description: 'Type of the user collection',
|
|
})
|
|
collectionType: ReqType,
|
|
) {
|
|
const jsonString =
|
|
await this.userCollectionService.exportUserCollectionsToJSON(
|
|
user.uid,
|
|
collectionID,
|
|
collectionType,
|
|
);
|
|
|
|
if (E.isLeft(jsonString)) throwErr(jsonString.left as string);
|
|
return jsonString.right;
|
|
}
|
|
|
|
// Mutations
|
|
@Mutation(() => UserCollection, {
|
|
description: 'Creates root REST user collection(no parent user collection)',
|
|
})
|
|
@UseGuards(GqlAuthGuard)
|
|
async createRESTRootUserCollection(
|
|
@GqlUser() user: AuthUser,
|
|
@Args() args: CreateRootUserCollectionArgs,
|
|
) {
|
|
const userCollection =
|
|
await this.userCollectionService.createUserCollection(
|
|
user,
|
|
args.title,
|
|
args.data,
|
|
null,
|
|
ReqType.REST,
|
|
);
|
|
|
|
if (E.isLeft(userCollection)) throwErr(userCollection.left);
|
|
return userCollection.right;
|
|
}
|
|
|
|
@Mutation(() => UserCollection, {
|
|
description:
|
|
'Creates root GraphQL user collection(no parent user collection)',
|
|
})
|
|
@UseGuards(GqlAuthGuard)
|
|
async createGQLRootUserCollection(
|
|
@GqlUser() user: AuthUser,
|
|
@Args() args: CreateRootUserCollectionArgs,
|
|
) {
|
|
const userCollection =
|
|
await this.userCollectionService.createUserCollection(
|
|
user,
|
|
args.title,
|
|
args.data,
|
|
null,
|
|
ReqType.GQL,
|
|
);
|
|
|
|
if (E.isLeft(userCollection)) throwErr(userCollection.left);
|
|
return userCollection.right;
|
|
}
|
|
|
|
@Mutation(() => UserCollection, {
|
|
description: 'Creates a new child GraphQL user collection',
|
|
})
|
|
@UseGuards(GqlAuthGuard)
|
|
async createGQLChildUserCollection(
|
|
@GqlUser() user: AuthUser,
|
|
@Args() args: CreateChildUserCollectionArgs,
|
|
) {
|
|
const userCollection =
|
|
await this.userCollectionService.createUserCollection(
|
|
user,
|
|
args.title,
|
|
args.data,
|
|
args.parentUserCollectionID,
|
|
ReqType.GQL,
|
|
);
|
|
|
|
if (E.isLeft(userCollection)) throwErr(userCollection.left);
|
|
return userCollection.right;
|
|
}
|
|
|
|
@Mutation(() => UserCollection, {
|
|
description: 'Creates a new child REST user collection',
|
|
})
|
|
@UseGuards(GqlAuthGuard)
|
|
async createRESTChildUserCollection(
|
|
@GqlUser() user: AuthUser,
|
|
@Args() args: CreateChildUserCollectionArgs,
|
|
) {
|
|
const userCollection =
|
|
await this.userCollectionService.createUserCollection(
|
|
user,
|
|
args.title,
|
|
args.data,
|
|
args.parentUserCollectionID,
|
|
ReqType.REST,
|
|
);
|
|
|
|
if (E.isLeft(userCollection)) throwErr(userCollection.left);
|
|
return userCollection.right;
|
|
}
|
|
|
|
@Mutation(() => UserCollection, {
|
|
description: 'Rename a user collection',
|
|
})
|
|
@UseGuards(GqlAuthGuard)
|
|
async renameUserCollection(
|
|
@GqlUser() user: AuthUser,
|
|
@Args() args: RenameUserCollectionsArgs,
|
|
) {
|
|
const updatedUserCollection =
|
|
await this.userCollectionService.renameUserCollection(
|
|
args.newTitle,
|
|
args.userCollectionID,
|
|
user.uid,
|
|
);
|
|
|
|
if (E.isLeft(updatedUserCollection)) throwErr(updatedUserCollection.left);
|
|
return updatedUserCollection.right;
|
|
}
|
|
|
|
@Mutation(() => Boolean, {
|
|
description: 'Delete a user collection',
|
|
})
|
|
@UseGuards(GqlAuthGuard)
|
|
async deleteUserCollection(
|
|
@Args({
|
|
name: 'userCollectionID',
|
|
description: 'ID of the user collection',
|
|
type: () => ID,
|
|
})
|
|
userCollectionID: string,
|
|
@GqlUser() user: AuthUser,
|
|
) {
|
|
const result = await this.userCollectionService.deleteUserCollection(
|
|
userCollectionID,
|
|
user.uid,
|
|
);
|
|
|
|
if (E.isLeft(result)) throwErr(result.left);
|
|
return result.right;
|
|
}
|
|
|
|
@Mutation(() => UserCollection, {
|
|
description: 'Move user collection into new parent or root',
|
|
})
|
|
@UseGuards(GqlAuthGuard)
|
|
async moveUserCollection(
|
|
@Args() args: MoveUserCollectionArgs,
|
|
@GqlUser() user: AuthUser,
|
|
) {
|
|
const res = await this.userCollectionService.moveUserCollection(
|
|
args.userCollectionID,
|
|
args.destCollectionID,
|
|
user.uid,
|
|
);
|
|
if (E.isLeft(res)) {
|
|
throwErr(res.left);
|
|
}
|
|
return res.right;
|
|
}
|
|
|
|
@Mutation(() => Boolean, {
|
|
description:
|
|
'Update the order of UserCollections inside parent collection or in root',
|
|
})
|
|
@UseGuards(GqlAuthGuard)
|
|
async updateUserCollectionOrder(
|
|
@Args() args: UpdateUserCollectionArgs,
|
|
@GqlUser() user: AuthUser,
|
|
) {
|
|
const res = await this.userCollectionService.updateUserCollectionOrder(
|
|
args.collectionID,
|
|
args.nextCollectionID,
|
|
user.uid,
|
|
);
|
|
if (E.isLeft(res)) {
|
|
throwErr(res.left);
|
|
}
|
|
return res.right;
|
|
}
|
|
|
|
@Mutation(() => Boolean, {
|
|
description: 'Import collections from JSON string to the specified Team',
|
|
})
|
|
@UseGuards(GqlAuthGuard)
|
|
async importUserCollectionsFromJSON(
|
|
@Args() args: ImportUserCollectionsFromJSONArgs,
|
|
@GqlUser() user: AuthUser,
|
|
) {
|
|
const importedCollection =
|
|
await this.userCollectionService.importCollectionsFromJSON(
|
|
args.jsonString,
|
|
user.uid,
|
|
args.parentCollectionID,
|
|
args.reqType,
|
|
);
|
|
if (E.isLeft(importedCollection)) throwErr(importedCollection.left);
|
|
return importedCollection.right;
|
|
}
|
|
|
|
@Mutation(() => UserCollection, {
|
|
description: 'Update a UserCollection',
|
|
})
|
|
@UseGuards(GqlAuthGuard)
|
|
async updateUserCollection(
|
|
@GqlUser() user: AuthUser,
|
|
@Args() args: UpdateUserCollectionsArgs,
|
|
) {
|
|
const updatedUserCollection =
|
|
await this.userCollectionService.updateUserCollection(
|
|
args.newTitle,
|
|
args.data,
|
|
args.userCollectionID,
|
|
user.uid,
|
|
);
|
|
|
|
if (E.isLeft(updatedUserCollection)) throwErr(updatedUserCollection.left);
|
|
return updatedUserCollection.right;
|
|
}
|
|
|
|
// Subscriptions
|
|
@Subscription(() => UserCollection, {
|
|
description: 'Listen for User Collection Creation',
|
|
resolve: (value) => value,
|
|
})
|
|
@SkipThrottle()
|
|
@UseGuards(GqlAuthGuard)
|
|
userCollectionCreated(@GqlUser() user: AuthUser) {
|
|
return this.pubSub.asyncIterator(`user_coll/${user.uid}/created`);
|
|
}
|
|
|
|
@Subscription(() => UserCollection, {
|
|
description: 'Listen to when a User Collection has been updated.',
|
|
resolve: (value) => value,
|
|
})
|
|
@SkipThrottle()
|
|
@UseGuards(GqlAuthGuard)
|
|
userCollectionUpdated(@GqlUser() user: AuthUser) {
|
|
return this.pubSub.asyncIterator(`user_coll/${user.uid}/updated`);
|
|
}
|
|
|
|
@Subscription(() => UserCollectionRemovedData, {
|
|
description: 'Listen to when a User Collection has been deleted',
|
|
resolve: (value) => value,
|
|
})
|
|
@SkipThrottle()
|
|
@UseGuards(GqlAuthGuard)
|
|
userCollectionRemoved(@GqlUser() user: AuthUser) {
|
|
return this.pubSub.asyncIterator(`user_coll/${user.uid}/deleted`);
|
|
}
|
|
|
|
@Subscription(() => UserCollection, {
|
|
description: 'Listen to when a User Collection has been moved',
|
|
resolve: (value) => value,
|
|
})
|
|
@SkipThrottle()
|
|
@UseGuards(GqlAuthGuard)
|
|
userCollectionMoved(@GqlUser() user: AuthUser) {
|
|
return this.pubSub.asyncIterator(`user_coll/${user.uid}/moved`);
|
|
}
|
|
|
|
@Subscription(() => UserCollectionReorderData, {
|
|
description: 'Listen to when a User Collections position has changed',
|
|
resolve: (value) => value,
|
|
})
|
|
@SkipThrottle()
|
|
@UseGuards(GqlAuthGuard)
|
|
userCollectionOrderUpdated(@GqlUser() user: AuthUser) {
|
|
return this.pubSub.asyncIterator(`user_coll/${user.uid}/order_updated`);
|
|
}
|
|
}
|