diff --git a/packages/schema/__generated__/ResGraphSchema.res b/packages/schema/__generated__/ResGraphSchema.res index 5f3a377..132ac5f 100644 --- a/packages/schema/__generated__/ResGraphSchema.res +++ b/packages/schema/__generated__/ResGraphSchema.res @@ -159,10 +159,14 @@ let t_PageInfo: ref = Obj.magic({"contents": Js.null}) let get_PageInfo = () => t_PageInfo.contents let t_Pills: ref = Obj.magic({"contents": Js.null}) let get_Pills = () => t_Pills.contents +let t_Profile: ref = Obj.magic({"contents": Js.null}) +let get_Profile = () => t_Profile.contents let t_Query: ref = Obj.magic({"contents": Js.null}) let get_Query = () => t_Query.contents let t_Skill: ref = Obj.magic({"contents": Js.null}) let get_Skill = () => t_Skill.contents +let t_Socials: ref = Obj.magic({"contents": Js.null}) +let get_Socials = () => t_Socials.contents let t_Todo: ref = Obj.magic({"contents": Js.null}) let get_Todo = () => t_Todo.contents let t_TodoConnection: ref = Obj.magic({"contents": Js.null}) @@ -331,6 +335,7 @@ let union_TodoUpdateResult_resolveType = (v: TodoMutations.todoUpdateResult) => let interface_Node_resolveType = (v: Interface_node.Resolver.t) => switch v { | User(_) => "User" + | Profile(_) => "Profile" | Listing(_) => "Listing" | Skill(_) => "Skill" | Todo(_) => "Todo" @@ -961,6 +966,97 @@ t_Pills.contents = GraphQLObjectType.make({ }, }->makeFields, }) +t_Profile.contents = GraphQLObjectType.make({ + name: "Profile", + description: ?None, + interfaces: [get_Node()], + fields: () => + { + "bio": { + typ: Scalars.string->Scalars.toGraphQLType, + description: ?None, + deprecationReason: ?None, + resolve: makeResolveFn((src, _args, _ctx, _info) => { + let src = typeUnwrapper(src) + src["bio"] + }), + }, + "categories": { + typ: GraphQLListType.make(enum_Category->GraphQLEnumType.toGraphQLType->nonNull) + ->GraphQLListType.toGraphQLType + ->nonNull, + description: ?None, + deprecationReason: ?None, + resolve: makeResolveFn((src, _args, _ctx, _info) => { + let src = typeUnwrapper(src) + src["categories"] + }), + }, + "createdAt": { + typ: Scalars.float->Scalars.toGraphQLType->nonNull, + description: ?None, + deprecationReason: ?None, + resolve: makeResolveFn((src, _args, _ctx, _info) => { + let src = typeUnwrapper(src) + src["createdAt"] + }), + }, + "hearts": { + typ: Scalars.float->Scalars.toGraphQLType, + description: ?None, + deprecationReason: ?None, + resolve: makeResolveFn((src, _args, _ctx, _info) => { + let src = typeUnwrapper(src) + src["hearts"] + }), + }, + "id": { + typ: Scalars.id->Scalars.toGraphQLType->nonNull, + description: "The id of the object.", + deprecationReason: ?None, + resolve: makeResolveFn((src, args, ctx, info) => { + let src = typeUnwrapper(src) + NodeInterfaceResolver.id(src, ~typename=Profile) + }), + }, + "pills": { + typ: get_Pills()->GraphQLObjectType.toGraphQLType->nonNull, + description: ?None, + deprecationReason: ?None, + resolve: makeResolveFn((src, _args, _ctx, _info) => { + let src = typeUnwrapper(src) + src["pills"] + }), + }, + "portfolioLink": { + typ: Scalars.string->Scalars.toGraphQLType, + description: ?None, + deprecationReason: ?None, + resolve: makeResolveFn((src, _args, _ctx, _info) => { + let src = typeUnwrapper(src) + src["portfolioLink"] + }), + }, + "sendid": { + typ: Scalars.float->Scalars.toGraphQLType->nonNull, + description: ?None, + deprecationReason: ?None, + resolve: makeResolveFn((src, _args, _ctx, _info) => { + let src = typeUnwrapper(src) + src["sendid"] + }), + }, + "socials": { + typ: get_Socials()->GraphQLObjectType.toGraphQLType->nonNull, + description: ?None, + deprecationReason: ?None, + resolve: makeResolveFn((src, _args, _ctx, _info) => { + let src = typeUnwrapper(src) + src["socials"] + }), + }, + }->makeFields, +}) t_Query.contents = GraphQLObjectType.make({ name: "Query", description: ?None, @@ -1093,6 +1189,16 @@ t_Query.contents = GraphQLObjectType.make({ ) }), }, + "profileBySendId": { + typ: get_Profile()->GraphQLObjectType.toGraphQLType, + description: "Get a profile by it's sendid", + deprecationReason: ?None, + args: {"sendid": {typ: Scalars.float->Scalars.toGraphQLType->nonNull}}->makeArgs, + resolve: makeResolveFn((src, args, ctx, info) => { + let src = typeUnwrapper(src) + ProfileResolvers.profileBySendId(src, ~ctx, ~sendid=args["sendid"]) + }), + }, }->makeFields, }) t_Skill.contents = GraphQLObjectType.make({ @@ -1121,6 +1227,32 @@ t_Skill.contents = GraphQLObjectType.make({ }, }->makeFields, }) +t_Socials.contents = GraphQLObjectType.make({ + name: "Socials", + description: ?None, + interfaces: [], + fields: () => + { + "telegram": { + typ: Scalars.string->Scalars.toGraphQLType->nonNull, + description: ?None, + deprecationReason: ?None, + resolve: makeResolveFn((src, _args, _ctx, _info) => { + let src = typeUnwrapper(src) + src["telegram"] + }), + }, + "x": { + typ: Scalars.string->Scalars.toGraphQLType->nonNull, + description: ?None, + deprecationReason: ?None, + resolve: makeResolveFn((src, _args, _ctx, _info) => { + let src = typeUnwrapper(src) + src["x"] + }), + }, + }->makeFields, +}) t_Todo.contents = GraphQLObjectType.make({ name: "Todo", description: "A single todo item.", @@ -1513,7 +1645,9 @@ let schema = GraphQLSchemaType.make({ get_Todo()->GraphQLObjectType.toGraphQLType, get_MakeSessionResultError()->GraphQLObjectType.toGraphQLType, get_MakeListingResultError()->GraphQLObjectType.toGraphQLType, + get_Socials()->GraphQLObjectType.toGraphQLType, get_PageInfo()->GraphQLObjectType.toGraphQLType, + get_Profile()->GraphQLObjectType.toGraphQLType, get_ListingEdge()->GraphQLObjectType.toGraphQLType, get_MakeListingResultOk()->GraphQLObjectType.toGraphQLType, get_User()->GraphQLObjectType.toGraphQLType, diff --git a/packages/schema/__generated__/interface_node.res b/packages/schema/__generated__/interface_node.res index 83da7f3..4bcda90 100644 --- a/packages/schema/__generated__/interface_node.res +++ b/packages/schema/__generated__/interface_node.res @@ -4,15 +4,21 @@ module Resolver = { @gql.interfaceResolver("node") - type t = Listing(Listing.listing) | Skill(Listing.skill) | Todo(Todo.todo) | User(User.user) + type t = + | Listing(Listing.listing) + | Profile(Profile.profile) + | Skill(Listing.skill) + | Todo(Todo.todo) + | User(User.user) } module ImplementedBy = { - type t = Listing | Skill | Todo | User + type t = Listing | Profile | Skill | Todo | User let decode = (str: string) => switch str { | "Listing" => Some(Listing) + | "Profile" => Some(Profile) | "Skill" => Some(Skill) | "Todo" => Some(Todo) | "User" => Some(User) @@ -24,6 +30,7 @@ module ImplementedBy = { type typeMap<'a> = { @as("Listing") listing: 'a, + @as("Profile") profile: 'a, @as("Skill") skill: 'a, @as("Todo") todo: 'a, @as("User") user: 'a, diff --git a/packages/schema/__generated__/schema.graphql b/packages/schema/__generated__/schema.graphql index 253c9ba..74cb9a3 100644 --- a/packages/schema/__generated__/schema.graphql +++ b/packages/schema/__generated__/schema.graphql @@ -306,6 +306,20 @@ type Pills { send: BigInt! } +type Profile implements Node { + categories: [Category!]! + createdAt: Float! + sendid: Float! + bio: String + hearts: Float + pills: Pills! + portfolioLink: String + socials: Socials! + + """The id of the object.""" + id: ID! +} + type Query { """The currently logged in user.""" @@ -317,6 +331,9 @@ type Query { """The current time on the server, as a timestamp.""" currentTime: Float + """Get a profile by it's sendid""" + profileBySendId(sendid: Float!): Profile + """Fetches objects given their IDs.""" nodes(ids: [ID!]!): [Node]! @@ -340,6 +357,11 @@ type Skill implements Node { id: ID! } +type Socials { + x: String! + telegram: String! +} + """A single todo item.""" type Todo implements Node { diff --git a/packages/schema/edgedb/__generated__/Profile__edgeql.res b/packages/schema/edgedb/__generated__/Profile__edgeql.res new file mode 100644 index 0000000..c92bf26 --- /dev/null +++ b/packages/schema/edgedb/__generated__/Profile__edgeql.res @@ -0,0 +1,91 @@ +// @sourceHash 96238cd1d4ae5b5667f84bfb23398e44 + +module ProfileById = { + let queryText = `# @name profileById + with + id := $id + select Profile{*} filter .id = id limit 1` + + @live + type args = { + id: string, + } + + type response__pills = { + usdc: bigint, + eth: bigint, + send: bigint, + } + + type response__socials = { + x: string, + telegram: string, + } + + type response = { + id: string, + categories: Null.t>, + created_at: Date.t, + sendid: float, + bio: Null.t, + hearts: Null.t, + pills: response__pills, + portfolio_link: Null.t, + socials: response__socials, + } + + @live + let query = (client: EdgeDB.Client.t, args: args, ~onError=?): promise> => { + client->EdgeDB.QueryHelpers.single(queryText, ~args, ~onError?) + } + + @live + let transaction = (transaction: EdgeDB.Transaction.t, args: args, ~onError=?): promise> => { + transaction->EdgeDB.TransactionHelpers.single(queryText, ~args, ~onError?) + } +} + +module ProfileBySendId = { + let queryText = `# @name profileBySendId + with + sendid := $sendid + select Profile{*} filter .sendid = sendid limit 1` + + @live + type args = { + sendid: float, + } + + type response__pills = { + usdc: bigint, + eth: bigint, + send: bigint, + } + + type response__socials = { + x: string, + telegram: string, + } + + type response = { + id: string, + categories: Null.t>, + created_at: Date.t, + sendid: float, + bio: Null.t, + hearts: Null.t, + pills: response__pills, + portfolio_link: Null.t, + socials: response__socials, + } + + @live + let query = (client: EdgeDB.Client.t, args: args, ~onError=?): promise> => { + client->EdgeDB.QueryHelpers.single(queryText, ~args, ~onError?) + } + + @live + let transaction = (transaction: EdgeDB.Transaction.t, args: args, ~onError=?): promise> => { + transaction->EdgeDB.TransactionHelpers.single(queryText, ~args, ~onError?) + } +} \ No newline at end of file diff --git a/packages/schema/src/DataLoaders.res b/packages/schema/src/DataLoaders.res index c13b271..d17b4b4 100644 --- a/packages/schema/src/DataLoaders.res +++ b/packages/schema/src/DataLoaders.res @@ -2,10 +2,12 @@ type t = { user: UserDataLoaders.t, todo: TodoDataLoaders.t, listing: ListingDataLoaders.t, + profile: ProfileDataLoaders.t, } let make = () => { user: UserDataLoaders.make(), todo: TodoDataLoaders.make(), listing: ListingDataLoaders.make(), + profile: ProfileDataLoaders.make(), } diff --git a/packages/schema/src/Mutations.res b/packages/schema/src/Mutations.res index 1257df3..bfacaeb 100644 --- a/packages/schema/src/Mutations.res +++ b/packages/schema/src/Mutations.res @@ -52,7 +52,6 @@ type makeListingResult = | Ok({newListing: Listing.listing}) | Error({name: string, reason: string}) - @gql.field let makeListing = async ( _: Schema.mutation, diff --git a/packages/schema/src/NodeInterfaceResolver.res b/packages/schema/src/NodeInterfaceResolver.res index 310fc11..2891e46 100644 --- a/packages/schema/src/NodeInterfaceResolver.res +++ b/packages/schema/src/NodeInterfaceResolver.res @@ -7,6 +7,7 @@ let typeMap: Interface_node.typeMap = { todo: 2, listing: 3, skill: 4, + profile: 5, } /** A typemap helping us produce compressed node IDs via the map defined above. */ @@ -61,6 +62,11 @@ let node = async (_: Schema.query, ~id, ~ctx: ResGraphContext.context): option< | None => None | Some(listing) => Some(Listing(listing)) } + | Profile => + switch await ctx.dataLoaders.profile.byId->DataLoader.load((ctx.edgedbClient, id)) { + | None => None + | Some(profile) => Some(Profile(profile)) + } | Skill => panic("Not implemented") } } diff --git a/packages/schema/src/Profile.res b/packages/schema/src/Profile.res new file mode 100644 index 0000000..6d2afce --- /dev/null +++ b/packages/schema/src/Profile.res @@ -0,0 +1,76 @@ +let byId = %edgeql(` + # @name profileById + with + id := $id + select Profile{*} filter .id = id limit 1 +`) + +let bySendId = %edgeql(` + # @name profileBySendId + with + sendid := $sendid + select Profile{*} filter .sendid = sendid limit 1 +`) + +@gql.type +type pills = { + @gql.field + usdc: Schema.BigInt.t, + @gql.field + eth: Schema.BigInt.t, + @gql.field + send: Schema.BigInt.t, +} + +@gql.type +type socials = { + @gql.field + x: string, + @gql.field + telegram: string, +} + +/* A profile linked to a send account */ +@gql.type +type profile = { + ...NodeInterface.node, + @gql.field + categories: array, + @gql.field + createdAt: float, + @gql.field + sendid: float, + @gql.field + bio?: string, + @gql.field + hearts?: float, + @gql.field + pills: pills, + @gql.field + portfolioLink?: string, + @gql.field + socials: socials, +} + +let castOneToResgraph = (profile: Profile__edgeql.ProfileById.response): profile => { + { + id: profile.id, + categories: profile.categories->Null.mapOr([], category => + category->Array.map(category => category->Schema.Category.castFromDb) + ), + createdAt: profile.created_at->Date.getTime, + sendid: profile.sendid, + bio: ?profile.bio->Null.toOption, + hearts: ?profile.hearts->Null.toOption, + pills: { + usdc: profile.pills.usdc, + eth: profile.pills.eth, + send: profile.pills.send, + }, + portfolioLink: ?profile.portfolio_link->Null.toOption, + socials: { + x: profile.socials.x, + telegram: profile.socials.telegram, + }, + } +} diff --git a/packages/schema/src/ProfileDataLoaders.res b/packages/schema/src/ProfileDataLoaders.res new file mode 100644 index 0000000..c22f5d0 --- /dev/null +++ b/packages/schema/src/ProfileDataLoaders.res @@ -0,0 +1,19 @@ +type t = { + byId: DataLoader.t<(EdgeDB.Client.t, string), option>, + bySendId: DataLoader.t<(EdgeDB.Client.t, float), option>, +} + +let make = () => { + byId: DataLoader.makeSingle(async ((edgedbClient, id)) => { + (await Profile.byId(edgedbClient, {id: id}, ~onError=Console.error))->Option.map( + Profile.castOneToResgraph, + ) + }), + bySendId: DataLoader.makeSingle(async ((edgedbClient, sendid)) => { + ( + await Profile.bySendId(edgedbClient, {sendid: sendid}, ~onError=Console.error) + )->Option.map(profile => + (profile :> Profile__edgeql.ProfileById.response)->Profile.castOneToResgraph + ) + }), +} diff --git a/packages/schema/src/ProfileResolvers.res b/packages/schema/src/ProfileResolvers.res new file mode 100644 index 0000000..8140536 --- /dev/null +++ b/packages/schema/src/ProfileResolvers.res @@ -0,0 +1,12 @@ +/** Get a profile by it's sendid */ +@gql.field +let profileBySendId = async ( + _: Schema.query, + ~ctx: ResGraphContext.context, + ~sendid: float, +): option => { + switch await ctx.dataLoaders.profile.bySendId->DataLoader.load((ctx.edgedbClient, sendid)) { + | None => None + | Some(profile) => Some(profile) + } +}