forked from keystonejs/keystone
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcustom-schema.ts
79 lines (73 loc) · 3 KB
/
custom-schema.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import { graphQLSchemaExtension } from '@keystone-next/keystone';
export const extendGraphqlSchema = graphQLSchemaExtension({
typeDefs: `
type Mutation {
""" Publish a post """
publishPost(id: ID!): Post
}
type Query {
""" Return all posts for a user from the last <days> days """
recentPosts(id: ID!, days: Int! = 7): [Post]
""" Compute statistics for a user """
stats(id: ID!): Statistics
}
""" A custom type to represent statistics for a user """
type Statistics {
draft: Int
published: Int
latest: Post
}`,
resolvers: {
Mutation: {
publishPost: (root, { id }, context) => {
// Note we use `context.db.Post` here as we have a return type
// of Post, and this API provides results in the correct format.
// If you accidentally use `context.query.Post` here you can expect problems
// when accessing the fields in your GraphQL client.
return context.db.Post.updateOne({
where: { id },
data: { status: 'published', publishDate: new Date().toUTCString() },
});
},
},
Query: {
recentPosts: (root, { id, days }, context) => {
// Create a date string <days> in the past from now()
const cutoff = new Date(
new Date().setUTCDate(new Date().getUTCDate() - days)
).toUTCString();
// Note we use `context.db.Post` here as we have a return type
// of [Post], and this API provides results in the correct format.
// If you accidentally use `context.query.Post` here you can expect problems
// when accessing the fields in your GraphQL client.
return context.db.Post.findMany({
where: { author: { id: { equals: id } }, publishDate: { gt: cutoff } },
});
},
stats: async (root, { id }, context) => {
const draft = await context.query.Post.count({
where: { author: { id: { equals: id } }, status: { equals: 'draft' } },
});
const published = await context.query.Post.count({
where: { author: { id: { equals: id } }, status: { equals: 'published' } },
});
const { posts } = await context.query.Author.findOne({
where: { id },
query: 'posts(take: 1, orderBy: { publishDate: desc }) { id }',
});
return { draft, published, latestPostId: posts ? posts[0].id : null };
},
},
Statistics: {
// The stats resolver returns an object which is passed to this resolver as
// the root value. We use that object to further resolve ths specific fields.
// In this case we want to take root.latestPostId and resolve it as a Post object
//
// As above we use the context.db.Post API to achieve this.
latest: (root, args, context) =>
context.db.Post.findOne({ where: { id: root.latestPostId } }),
// We don't need to define resolvers for draft and published, as apollo will
// return root.draft and root.published respectively.
},
},
});