From 3a642f67a0838522ff3bfe6351c923bd13caa3cc Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Mon, 27 Nov 2023 14:52:13 +0100 Subject: [PATCH 1/3] Added arena flag endpoint, resolver function and types --- src/api/arenaApi.ts | 32 ++++++++++++++++++++++++++++++++ src/resolvers/arenaResolvers.ts | 12 ++++++++++-- src/schema.ts | 9 +++++++++ src/types/schema.d.ts | 30 ++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 2 deletions(-) diff --git a/src/api/arenaApi.ts b/src/api/arenaApi.ts index be48a2ac..2142d098 100644 --- a/src/api/arenaApi.ts +++ b/src/api/arenaApi.ts @@ -8,6 +8,7 @@ import { GQLArenaCategory, + GQLArenaFlag, GQLArenaNotification, GQLArenaNotificationUser, GQLArenaPost, @@ -15,6 +16,7 @@ import { GQLArenaUser, GQLBaseUser, GQLMutationNewArenaTopicArgs, + GQLMutationNewFlagArgs, GQLMutationReplyToTopicArgs, GQLQueryArenaCategoryArgs, GQLQueryArenaTopicArgs, @@ -47,6 +49,7 @@ const toArenaPost = (post: any, mainPid?: any): GQLArenaPost => ({ timestamp: post.timestampISO, isMainPost: post.isMainPost ?? post.pid === mainPid, user: toArenaUser(post.user), + flagId: post.flagId, }); const toTopic = (topic: any): GQLArenaTopic => { @@ -102,6 +105,14 @@ const toNotification = (notification: any): GQLArenaNotification => ({ postId: notification.pid, notificationId: notification.nid, }); + +const toFlag = (flag: any): GQLArenaFlag => ({ + flagId: flag.flagId, + targetId: flag.targetId, + state: flag.state, + datetimeISO: flag.datetimeISO, +}); + export const fetchCsrfTokenForSession = async ( context: Context, ): Promise<{ cookie: string; 'x-csrf-token': string }> => { @@ -234,3 +245,24 @@ export const replyToTopic = async ( const resolved = await resolveJson(response); return toArenaPost(resolved.response, undefined); }; + +export const newFlag = async ( + { type, postId, reason }: GQLMutationNewFlagArgs, + context: Context, +): Promise => { + const csrfHeaders = await fetchCsrfTokenForSession(context); + const response = await fetch(`/groups/api/v3/flags`, context, { + method: 'POST', + headers: { + 'content-type': 'application/json', + ...csrfHeaders, + }, + body: JSON.stringify({ + id: postId, + type: type, + reason: reason, + }), + }); + const resolved = await resolveJson(response); + return toFlag(resolved.response); +}; diff --git a/src/resolvers/arenaResolvers.ts b/src/resolvers/arenaResolvers.ts index 728d9e57..0edf4d9c 100644 --- a/src/resolvers/arenaResolvers.ts +++ b/src/resolvers/arenaResolvers.ts @@ -14,9 +14,9 @@ import { fetchArenaTopic, fetchArenaTopicsByUser, fetchArenaNotifications, - fetchCsrfTokenForSession, newTopic, replyToTopic, + newFlag, } from '../api/arenaApi'; import { GQLArenaCategory, @@ -31,6 +31,7 @@ import { GQLMutationResolvers, GQLMutationMarkNotificationAsReadArgs, GQLArenaPost, + GQLArenaFlag, } from '../types/schema'; export const Query: Pick< @@ -96,7 +97,7 @@ export const Query: Pick< export const Mutations: Pick< GQLMutationResolvers, - 'newArenaTopic' | 'replyToTopic' | 'markNotificationAsRead' + 'newArenaTopic' | 'replyToTopic' | 'markNotificationAsRead' | 'newFlag' > = { async newArenaTopic( _: any, @@ -122,4 +123,11 @@ export const Mutations: Pick< ); return params.topicIds; }, + async newFlag( + _: any, + params, + context: ContextWithLoaders, + ): Promise { + return newFlag(params, context); + }, }; diff --git a/src/schema.ts b/src/schema.ts index e2b73385..02044c01 100644 --- a/src/schema.ts +++ b/src/schema.ts @@ -1222,6 +1222,7 @@ export const typeDefs = gql` timestamp: String! isMainPost: Boolean! user: ArenaUser! + flagId: Int } type ArenaBreadcrumb { @@ -1260,6 +1261,13 @@ export const typeDefs = gql` subject: String! } + type ArenaFlag { + flagId: String! + targetId: String! + state: String! + datetimeISO: String! + } + type Query { resource(id: String!, subjectId: String, topicId: String): Resource articleResource(articleId: String, taxonomyId: String): Resource @@ -1444,6 +1452,7 @@ export const typeDefs = gql` content: String! ): ArenaTopic! replyToTopic(topicId: Int!, content: String!): ArenaPost! + newFlag(type: String!, postId: Int!, reason: String!): ArenaFlag! } `; diff --git a/src/types/schema.d.ts b/src/types/schema.d.ts index e2534c23..9f67eea9 100644 --- a/src/types/schema.d.ts +++ b/src/types/schema.d.ts @@ -43,6 +43,14 @@ export type GQLArenaCategory = { topics?: Maybe>; }; +export type GQLArenaFlag = { + __typename?: 'ArenaFlag'; + datetimeISO: Scalars['String']; + flagId: Scalars['String']; + state: Scalars['String']; + targetId: Scalars['String']; +}; + export type GQLArenaNotification = { __typename?: 'ArenaNotification'; bodyShort: Scalars['String']; @@ -74,6 +82,7 @@ export type GQLArenaNotificationUser = GQLBaseUser & { export type GQLArenaPost = { __typename?: 'ArenaPost'; content: Scalars['String']; + flagId?: Maybe; id: Scalars['Int']; isMainPost: Scalars['Boolean']; timestamp: Scalars['String']; @@ -914,6 +923,7 @@ export type GQLMutation = { deletePersonalData: Scalars['Boolean']; markNotificationAsRead: Array; newArenaTopic: GQLArenaTopic; + newFlag: GQLArenaFlag; replyToTopic: GQLArenaPost; sortFolders: GQLSortResult; sortResources: GQLSortResult; @@ -971,6 +981,13 @@ export type GQLMutationNewArenaTopicArgs = { }; +export type GQLMutationNewFlagArgs = { + postId: Scalars['Int']; + reason: Scalars['String']; + type: Scalars['String']; +}; + + export type GQLMutationReplyToTopicArgs = { content: Scalars['String']; topicId: Scalars['Int']; @@ -1941,6 +1958,7 @@ export type GQLResolversTypes = { AggregationResult: ResolverTypeWrapper; ArenaBreadcrumb: ResolverTypeWrapper; ArenaCategory: ResolverTypeWrapper; + ArenaFlag: ResolverTypeWrapper; ArenaNotification: ResolverTypeWrapper; ArenaNotificationUser: ResolverTypeWrapper; ArenaPost: ResolverTypeWrapper; @@ -2094,6 +2112,7 @@ export type GQLResolversParentTypes = { AggregationResult: GQLAggregationResult; ArenaBreadcrumb: GQLArenaBreadcrumb; ArenaCategory: GQLArenaCategory; + ArenaFlag: GQLArenaFlag; ArenaNotification: GQLArenaNotification; ArenaNotificationUser: GQLArenaNotificationUser; ArenaPost: GQLArenaPost; @@ -2270,6 +2289,14 @@ export type GQLArenaCategoryResolvers; }; +export type GQLArenaFlagResolvers = { + datetimeISO?: Resolver; + flagId?: Resolver; + state?: Resolver; + targetId?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + export type GQLArenaNotificationResolvers = { bodyShort?: Resolver; datetimeISO?: Resolver; @@ -2300,6 +2327,7 @@ export type GQLArenaNotificationUserResolvers = { content?: Resolver; + flagId?: Resolver, ParentType, ContextType>; id?: Resolver; isMainPost?: Resolver; timestamp?: Resolver; @@ -3131,6 +3159,7 @@ export type GQLMutationResolvers; markNotificationAsRead?: Resolver, ParentType, ContextType, RequireFields>; newArenaTopic?: Resolver>; + newFlag?: Resolver>; replyToTopic?: Resolver>; sortFolders?: Resolver>; sortResources?: Resolver>; @@ -3690,6 +3719,7 @@ export type GQLResolvers = { AggregationResult?: GQLAggregationResultResolvers; ArenaBreadcrumb?: GQLArenaBreadcrumbResolvers; ArenaCategory?: GQLArenaCategoryResolvers; + ArenaFlag?: GQLArenaFlagResolvers; ArenaNotification?: GQLArenaNotificationResolvers; ArenaNotificationUser?: GQLArenaNotificationUserResolvers; ArenaPost?: GQLArenaPostResolvers; From 55c27ac3a8e148658e7bda7073f5b25688fa116d Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Tue, 28 Nov 2023 08:51:01 +0100 Subject: [PATCH 2/3] Update newFlag id parameter naming --- src/api/arenaApi.ts | 4 ++-- src/schema.ts | 2 +- src/types/schema.d.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/api/arenaApi.ts b/src/api/arenaApi.ts index 2142d098..78b4af0f 100644 --- a/src/api/arenaApi.ts +++ b/src/api/arenaApi.ts @@ -247,7 +247,7 @@ export const replyToTopic = async ( }; export const newFlag = async ( - { type, postId, reason }: GQLMutationNewFlagArgs, + { type, id, reason }: GQLMutationNewFlagArgs, context: Context, ): Promise => { const csrfHeaders = await fetchCsrfTokenForSession(context); @@ -258,7 +258,7 @@ export const newFlag = async ( ...csrfHeaders, }, body: JSON.stringify({ - id: postId, + id: id, type: type, reason: reason, }), diff --git a/src/schema.ts b/src/schema.ts index 02044c01..84afb7af 100644 --- a/src/schema.ts +++ b/src/schema.ts @@ -1452,7 +1452,7 @@ export const typeDefs = gql` content: String! ): ArenaTopic! replyToTopic(topicId: Int!, content: String!): ArenaPost! - newFlag(type: String!, postId: Int!, reason: String!): ArenaFlag! + newFlag(type: String!, id: Int!, reason: String!): ArenaFlag! } `; diff --git a/src/types/schema.d.ts b/src/types/schema.d.ts index 9f67eea9..a121a074 100644 --- a/src/types/schema.d.ts +++ b/src/types/schema.d.ts @@ -982,7 +982,7 @@ export type GQLMutationNewArenaTopicArgs = { export type GQLMutationNewFlagArgs = { - postId: Scalars['Int']; + id: Scalars['Int']; reason: Scalars['String']; type: Scalars['String']; }; @@ -3159,7 +3159,7 @@ export type GQLMutationResolvers; markNotificationAsRead?: Resolver, ParentType, ContextType, RequireFields>; newArenaTopic?: Resolver>; - newFlag?: Resolver>; + newFlag?: Resolver>; replyToTopic?: Resolver>; sortFolders?: Resolver>; sortResources?: Resolver>; From cce467c7dd008c7c76c68bf271bf254edfd0a038 Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Wed, 29 Nov 2023 13:35:41 +0100 Subject: [PATCH 3/3] Update return type for newFlag. Add error handling. --- src/api/arenaApi.ts | 20 +++++++++----------- src/resolvers/arenaResolvers.ts | 7 +------ src/schema.ts | 9 +-------- src/types/schema.d.ts | 23 ++--------------------- 4 files changed, 13 insertions(+), 46 deletions(-) diff --git a/src/api/arenaApi.ts b/src/api/arenaApi.ts index 78b4af0f..549c15e3 100644 --- a/src/api/arenaApi.ts +++ b/src/api/arenaApi.ts @@ -6,9 +6,9 @@ * */ +import { GraphQLError } from 'graphql'; import { GQLArenaCategory, - GQLArenaFlag, GQLArenaNotification, GQLArenaNotificationUser, GQLArenaPost, @@ -106,13 +106,6 @@ const toNotification = (notification: any): GQLArenaNotification => ({ notificationId: notification.nid, }); -const toFlag = (flag: any): GQLArenaFlag => ({ - flagId: flag.flagId, - targetId: flag.targetId, - state: flag.state, - datetimeISO: flag.datetimeISO, -}); - export const fetchCsrfTokenForSession = async ( context: Context, ): Promise<{ cookie: string; 'x-csrf-token': string }> => { @@ -249,7 +242,7 @@ export const replyToTopic = async ( export const newFlag = async ( { type, id, reason }: GQLMutationNewFlagArgs, context: Context, -): Promise => { +): Promise => { const csrfHeaders = await fetchCsrfTokenForSession(context); const response = await fetch(`/groups/api/v3/flags`, context, { method: 'POST', @@ -263,6 +256,11 @@ export const newFlag = async ( reason: reason, }), }); - const resolved = await resolveJson(response); - return toFlag(resolved.response); + const { status, ok } = response; + const jsonResponse = await response.json(); + + if (ok) return id; + throw new GraphQLError(jsonResponse.status.message, { + extensions: { status }, + }); }; diff --git a/src/resolvers/arenaResolvers.ts b/src/resolvers/arenaResolvers.ts index 0edf4d9c..958d6699 100644 --- a/src/resolvers/arenaResolvers.ts +++ b/src/resolvers/arenaResolvers.ts @@ -31,7 +31,6 @@ import { GQLMutationResolvers, GQLMutationMarkNotificationAsReadArgs, GQLArenaPost, - GQLArenaFlag, } from '../types/schema'; export const Query: Pick< @@ -123,11 +122,7 @@ export const Mutations: Pick< ); return params.topicIds; }, - async newFlag( - _: any, - params, - context: ContextWithLoaders, - ): Promise { + async newFlag(_: any, params, context: ContextWithLoaders): Promise { return newFlag(params, context); }, }; diff --git a/src/schema.ts b/src/schema.ts index 84afb7af..a6ba8ca5 100644 --- a/src/schema.ts +++ b/src/schema.ts @@ -1261,13 +1261,6 @@ export const typeDefs = gql` subject: String! } - type ArenaFlag { - flagId: String! - targetId: String! - state: String! - datetimeISO: String! - } - type Query { resource(id: String!, subjectId: String, topicId: String): Resource articleResource(articleId: String, taxonomyId: String): Resource @@ -1452,7 +1445,7 @@ export const typeDefs = gql` content: String! ): ArenaTopic! replyToTopic(topicId: Int!, content: String!): ArenaPost! - newFlag(type: String!, id: Int!, reason: String!): ArenaFlag! + newFlag(type: String!, id: Int!, reason: String!): Int! } `; diff --git a/src/types/schema.d.ts b/src/types/schema.d.ts index a121a074..7cc71c81 100644 --- a/src/types/schema.d.ts +++ b/src/types/schema.d.ts @@ -43,14 +43,6 @@ export type GQLArenaCategory = { topics?: Maybe>; }; -export type GQLArenaFlag = { - __typename?: 'ArenaFlag'; - datetimeISO: Scalars['String']; - flagId: Scalars['String']; - state: Scalars['String']; - targetId: Scalars['String']; -}; - export type GQLArenaNotification = { __typename?: 'ArenaNotification'; bodyShort: Scalars['String']; @@ -923,7 +915,7 @@ export type GQLMutation = { deletePersonalData: Scalars['Boolean']; markNotificationAsRead: Array; newArenaTopic: GQLArenaTopic; - newFlag: GQLArenaFlag; + newFlag: Scalars['Int']; replyToTopic: GQLArenaPost; sortFolders: GQLSortResult; sortResources: GQLSortResult; @@ -1958,7 +1950,6 @@ export type GQLResolversTypes = { AggregationResult: ResolverTypeWrapper; ArenaBreadcrumb: ResolverTypeWrapper; ArenaCategory: ResolverTypeWrapper; - ArenaFlag: ResolverTypeWrapper; ArenaNotification: ResolverTypeWrapper; ArenaNotificationUser: ResolverTypeWrapper; ArenaPost: ResolverTypeWrapper; @@ -2112,7 +2103,6 @@ export type GQLResolversParentTypes = { AggregationResult: GQLAggregationResult; ArenaBreadcrumb: GQLArenaBreadcrumb; ArenaCategory: GQLArenaCategory; - ArenaFlag: GQLArenaFlag; ArenaNotification: GQLArenaNotification; ArenaNotificationUser: GQLArenaNotificationUser; ArenaPost: GQLArenaPost; @@ -2289,14 +2279,6 @@ export type GQLArenaCategoryResolvers; }; -export type GQLArenaFlagResolvers = { - datetimeISO?: Resolver; - flagId?: Resolver; - state?: Resolver; - targetId?: Resolver; - __isTypeOf?: IsTypeOfResolverFn; -}; - export type GQLArenaNotificationResolvers = { bodyShort?: Resolver; datetimeISO?: Resolver; @@ -3159,7 +3141,7 @@ export type GQLMutationResolvers; markNotificationAsRead?: Resolver, ParentType, ContextType, RequireFields>; newArenaTopic?: Resolver>; - newFlag?: Resolver>; + newFlag?: Resolver>; replyToTopic?: Resolver>; sortFolders?: Resolver>; sortResources?: Resolver>; @@ -3719,7 +3701,6 @@ export type GQLResolvers = { AggregationResult?: GQLAggregationResultResolvers; ArenaBreadcrumb?: GQLArenaBreadcrumbResolvers; ArenaCategory?: GQLArenaCategoryResolvers; - ArenaFlag?: GQLArenaFlagResolvers; ArenaNotification?: GQLArenaNotificationResolvers; ArenaNotificationUser?: GQLArenaNotificationUserResolvers; ArenaPost?: GQLArenaPostResolvers;