From e66e30365bd726c10ffc8ebe2873de16eb14c51d Mon Sep 17 00:00:00 2001 From: Umut Sirin Date: Sat, 29 Jul 2023 13:05:01 -0700 Subject: [PATCH] feat(apps/gql): add User.panoPosts resolver & fix pageInfo/cursor things (#565) This implements the panoPosts resolver for user as a connection type so it's already ready for pagination. Also fixed #564 (it was stringifying instead of parsing) --- apps/gql/loaders/user.ts | 1 + apps/gql/schema/resolvers/index.ts | 36 +++++++++++++++++------------- apps/gql/schema/schema.graphql | 8 +++++++ apps/gql/schema/types.generated.ts | 15 +++++++++++++ 4 files changed, 44 insertions(+), 16 deletions(-) diff --git a/apps/gql/loaders/user.ts b/apps/gql/loaders/user.ts index 9c077d74..9c7aea0a 100644 --- a/apps/gql/loaders/user.ts +++ b/apps/gql/loaders/user.ts @@ -31,4 +31,5 @@ export const transformUser = (user: User) => ({ ...user, __typename: "User" as const, username: user.username ?? "", + panoPosts: null, }); diff --git a/apps/gql/schema/resolvers/index.ts b/apps/gql/schema/resolvers/index.ts index 5d60403a..2ec12399 100644 --- a/apps/gql/schema/resolvers/index.ts +++ b/apps/gql/schema/resolvers/index.ts @@ -1,7 +1,7 @@ import { DateResolver, DateTimeResolver } from "graphql-scalars"; import { ConnectionKey } from "@kampus/gql-utils"; -import { type ConnectionArguments } from "@kampus/gql-utils/connection"; +import { type ConnectionArguments, type PageInfo } from "@kampus/gql-utils/connection"; import { parse, stringify } from "@kampus/gql-utils/global-id"; import { type User } from "@kampus/prisma"; import { assertNever } from "@kampus/std"; @@ -14,10 +14,16 @@ import { type Resolvers, type ResolversInterfaceTypes } from "../types.generated type NodeTypename = ResolversInterfaceTypes["Node"]["__typename"]; -const transformConnectionArgs = (type: NodeTypename, args: ConnectionArguments) => ({ +const transformPageInfo = (type: NodeTypename, pageInfo: PageInfo) => ({ + ...pageInfo, + startCursor: stringify(type, pageInfo.startCursor ?? ""), + endCursor: stringify(type, pageInfo.endCursor ?? ""), +}); + +const parseConnectionArgs = (args: ConnectionArguments) => ({ ...args, - after: args.after ? stringify(type, args.after) : null, - before: args.before ? stringify(type, args.before) : null, + after: args.after ? parse(args.after).value : null, + before: args.before ? parse(args.before).value : null, }); export const resolvers = { @@ -70,7 +76,9 @@ export const resolvers = { term: async (_, args, { loaders }) => transformSozlukTerm(await loaders.sozluk.term.load(args.id)), terms: async (_, args, { loaders }) => { - return transformSozlukTermsConnection(await loaders.sozluk.terms.load(args)); + return transformSozlukTermsConnection( + await loaders.sozluk.terms.load(parseConnectionArgs(args)) + ); }, }, SozlukTerm: { @@ -86,11 +94,7 @@ export const resolvers = { }, SozlukTermConnection: { edges: (connection) => connection.edges, - pageInfo: (connection) => ({ - ...connection.pageInfo, - startCursor: stringify("SozlukTerm", connection.pageInfo.startCursor ?? ""), - endCursor: stringify("SozlukTerm", connection.pageInfo.endCursor ?? ""), - }), + pageInfo: (connection) => transformPageInfo("SozlukTerm", connection.pageInfo), totalCount: (connection) => connection.totalCount, }, SozlukTermEdge: { @@ -109,7 +113,7 @@ export const resolvers = { }, allPosts: async (_, args, { loaders }) => { const posts = await loaders.pano.post.all.load( - new ConnectionKey(null, transformConnectionArgs("PanoPost", args)) + new ConnectionKey(null, parseConnectionArgs(args)) ); return transformPanoPostConnection(posts); @@ -130,11 +134,7 @@ export const resolvers = { PanoPostConnection: { nodes: (connection) => connection.nodes, edges: (connection) => connection.edges, - pageInfo: (connection) => ({ - ...connection.pageInfo, - startCursor: stringify("PanoPost", connection.pageInfo.startCursor ?? ""), - endCursor: stringify("PanoPost", connection.pageInfo.endCursor ?? ""), - }), + pageInfo: (connection) => transformPageInfo("PanoPost", connection.pageInfo), totalCount: (connection) => connection.totalCount, }, PanoPostEdge: { @@ -150,5 +150,9 @@ export const resolvers = { User: { id: (user) => stringify("User", user.id), username: (u) => u.username, + panoPosts: async (user, args, { loaders }) => + transformPanoPostConnection( + await loaders.pano.post.byUserID.load(new ConnectionKey(user.id, args)) + ), }, } satisfies Resolvers; diff --git a/apps/gql/schema/schema.graphql b/apps/gql/schema/schema.graphql index fc927a57..61ad7249 100644 --- a/apps/gql/schema/schema.graphql +++ b/apps/gql/schema/schema.graphql @@ -25,6 +25,14 @@ type PageInfo { type User implements Node { id: ID! username: String! + + panoPosts( + after: String + before: String + first: Int + last: Int + filter: PanoPostFilter + ): PanoPostConnection } type SozlukQuery { diff --git a/apps/gql/schema/types.generated.ts b/apps/gql/schema/types.generated.ts index d101f7dc..38c711ce 100644 --- a/apps/gql/schema/types.generated.ts +++ b/apps/gql/schema/types.generated.ts @@ -151,9 +151,18 @@ export type SozlukTermEdge = { export type User = Node & { __typename?: "User"; id: Scalars["ID"]["output"]; + panoPosts: Maybe; username: Scalars["String"]["output"]; }; +export type UserPanoPostsArgs = { + after: InputMaybe; + before: InputMaybe; + filter: InputMaybe; + first: InputMaybe; + last: InputMaybe; +}; + export type WithIndex = TObject & Record; export type ResolversObject = WithIndex; @@ -458,6 +467,12 @@ export type UserResolvers< ParentType extends ResolversParentTypes["User"] = ResolversParentTypes["User"] > = ResolversObject<{ id: Resolver; + panoPosts: Resolver< + Maybe, + ParentType, + ContextType, + Partial + >; username: Resolver; __isTypeOf?: IsTypeOfResolverFn; }>;