diff --git a/packages/hoppscotch-backend/src/team-collection/team-collection.resolver.ts b/packages/hoppscotch-backend/src/team-collection/team-collection.resolver.ts index f5a2ccfb8..4c6b00ea6 100644 --- a/packages/hoppscotch-backend/src/team-collection/team-collection.resolver.ts +++ b/packages/hoppscotch-backend/src/team-collection/team-collection.resolver.ts @@ -331,6 +331,26 @@ export class TeamCollectionResolver { return updatedTeamCollection.right; } + @Mutation(() => Boolean, { + description: 'Duplicate a Team Collection', + }) + @UseGuards(GqlAuthGuard, GqlCollectionTeamMemberGuard) + @RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR) + async duplicateTeamCollection( + @Args({ + name: 'collectionID', + description: 'ID of the collection', + }) + collectionID: string, + ) { + const duplicatedTeamCollection = + await this.teamCollectionService.duplicateTeamCollection(collectionID); + + if (E.isLeft(duplicatedTeamCollection)) + throwErr(duplicatedTeamCollection.left); + return duplicatedTeamCollection.right; + } + // Subscriptions @Subscription(() => TeamCollection, { diff --git a/packages/hoppscotch-backend/src/team-collection/team-collection.service.ts b/packages/hoppscotch-backend/src/team-collection/team-collection.service.ts index b8af9de92..0559e2b8a 100644 --- a/packages/hoppscotch-backend/src/team-collection/team-collection.service.ts +++ b/packages/hoppscotch-backend/src/team-collection/team-collection.service.ts @@ -1446,4 +1446,35 @@ export class TeamCollectionService { return E.left(TEAM_COLL_NOT_FOUND); } } + + /** + * Duplicate a Team Collection + * + * @param collectionID The Collection ID + * @returns Boolean of duplication status + */ + async duplicateTeamCollection(collectionID: string) { + const collection = await this.getCollection(collectionID); + if (E.isLeft(collection)) return E.left(TEAM_INVALID_COLL_ID); + + const collectionJSONObject = await this.exportCollectionToJSONObject( + collection.right.teamID, + collectionID, + ); + if (E.isLeft(collectionJSONObject)) return E.left(TEAM_INVALID_COLL_ID); + + const result = await this.importCollectionsFromJSON( + JSON.stringify([ + { + ...collectionJSONObject.right, + name: `${collection.right.title} - Duplicate`, + }, + ]), + collection.right.teamID, + collection.right.parentID, + ); + if (E.isLeft(result)) return E.left(result.left as string); + + return E.right(true); + } } diff --git a/packages/hoppscotch-backend/src/user-collection/user-collection.resolver.ts b/packages/hoppscotch-backend/src/user-collection/user-collection.resolver.ts index be0c3530e..8bc2f22e5 100644 --- a/packages/hoppscotch-backend/src/user-collection/user-collection.resolver.ts +++ b/packages/hoppscotch-backend/src/user-collection/user-collection.resolver.ts @@ -390,6 +390,36 @@ export class UserCollectionResolver { return updatedUserCollection.right; } + @Mutation(() => Boolean, { + description: 'Duplicate a User Collection', + }) + @UseGuards(GqlAuthGuard) + async duplicateUserCollection( + @GqlUser() user: AuthUser, + @Args({ + name: 'collectionID', + description: 'ID of the collection', + }) + collectionID: string, + @Args({ + name: 'reqType', + description: 'Type of UserCollection', + type: () => ReqType, + }) + reqType: ReqType, + ) { + const duplicatedUserCollection = + await this.userCollectionService.duplicateUserCollection( + collectionID, + user.uid, + reqType, + ); + + if (E.isLeft(duplicatedUserCollection)) + throwErr(duplicatedUserCollection.left); + return duplicatedUserCollection.right; + } + // Subscriptions @Subscription(() => UserCollection, { description: 'Listen for User Collection Creation', diff --git a/packages/hoppscotch-backend/src/user-collection/user-collection.service.ts b/packages/hoppscotch-backend/src/user-collection/user-collection.service.ts index 06128e0fd..dc8c55892 100644 --- a/packages/hoppscotch-backend/src/user-collection/user-collection.service.ts +++ b/packages/hoppscotch-backend/src/user-collection/user-collection.service.ts @@ -1138,4 +1138,45 @@ export class UserCollectionService { return E.left(USER_COLL_NOT_FOUND); } } + + /** + * Duplicate a User Collection + * + * @param collectionID The Collection ID + * @returns Boolean of duplication status + */ + async duplicateUserCollection( + collectionID: string, + userID: string, + reqType: DBReqType, + ) { + const collection = await this.getUserCollection(collectionID); + if (E.isLeft(collection)) return E.left(USER_COLL_NOT_FOUND); + + if (collection.right.userUid !== userID) return E.left(USER_NOT_OWNER); + if (collection.right.type !== reqType) + return E.left(USER_COLL_NOT_SAME_TYPE); + + const collectionJSONObject = await this.exportUserCollectionToJSONObject( + collection.right.userUid, + collectionID, + ); + if (E.isLeft(collectionJSONObject)) + return E.left(collectionJSONObject.left); + + const result = await this.importCollectionsFromJSON( + JSON.stringify([ + { + ...collectionJSONObject.right, + name: `${collection.right.title} - Duplicate`, + }, + ]), + userID, + collection.right.parentID, + reqType, + ); + if (E.isLeft(result)) return E.left(result.left as string); + + return E.right(true); + } }