-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathschema.ts
142 lines (135 loc) · 5.21 KB
/
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
Welcome to the schema! The schema is the heart of Keystone.
Here we define our 'lists', which will then be used both for the GraphQL
API definition, our database tables, and our Admin UI layout.
Some quick definitions to help out:
A list: A definition of a collection of fields with a name. For the starter
we have `User`, `Post`, and `Tag` lists.
A field: The individual bits of data on your list, each with its own type.
you can see some of the lists in what we use below.
*/
// Like the `config` function we use in keystone.ts, we use functions
// for putting in our config so we get useful errors. With typescript,
// we get these even before code runs.
import { list } from '@keystone-6/core';
// We're using some common fields in the starter. Check out https://keystonejs.com/docs/apis/fields#fields-api
// for the full list of fields.
import {
text,
relationship,
password,
timestamp,
select,
} from '@keystone-6/core/fields';
// The document field is a more complicated field, so it's in its own package
// Keystone aims to have all the base field types, but you can make your own
// custom ones.
import { document } from '@keystone-6/fields-document';
// We are using Typescript, and we want our types experience to be as strict as it can be.
// By providing the Keystone generated `Lists` type to our lists object, we refine
// our types to a stricter subset that is type-aware of other lists in our schema
// that Typescript cannot easily infer.
import { Lists } from '.keystone/types';
// We have a users list, a blogs list, and tags for blog posts, so they can be filtered.
// Each property on the exported object will become the name of a list (a.k.a. the `listKey`),
// with the value being the definition of the list, including the fields.
export const lists: Lists = {
// Here we define the user list.
User: list({
// Here are the fields that `User` will have. We want an email and password so they can log in
// a name so we can refer to them, and a way to connect users to posts.
fields: {
name: text({ validation: { isRequired: true } }),
email: text({
validation: { isRequired: true },
isIndexed: 'unique',
isFilterable: true,
}),
// The password field takes care of hiding details and hashing values
password: password({ validation: { isRequired: true } }),
// Relationships allow us to reference other lists. In this case,
// we want a user to have many posts, and we are saying that the user
// should be referencable by the 'author' field of posts.
// Make sure you read the docs to understand how they work: https://keystonejs.com/docs/guides/relationships#understanding-relationships
posts: relationship({ ref: 'Post.author', many: true }),
},
// Here we can configure the Admin UI. We want to show a user's name and posts in the Admin UI
ui: {
listView: {
initialColumns: ['name', 'posts'],
},
},
}),
// Our second list is the Posts list. We've got a few more fields here
// so we have all the info we need for displaying posts.
Post: list({
fields: {
title: text(),
// Having the status here will make it easy for us to choose whether to display
// posts on a live site.
status: select({
options: [
{ label: 'Published', value: 'published' },
{ label: 'Draft', value: 'draft' },
],
// We want to make sure new posts start off as a draft when they are created
defaultValue: 'draft',
// fields also have the ability to configure their appearance in the Admin UI
ui: {
displayMode: 'segmented-control',
},
}),
// The document field can be used for making highly editable content. Check out our
// guide on the document field https://keystonejs.com/docs/guides/document-fields#how-to-use-document-fields
// for more information
content: document({
formatting: true,
layouts: [
[1, 1],
[1, 1, 1],
[2, 1],
[1, 2],
[1, 2, 1],
],
links: true,
dividers: true,
}),
publishDate: timestamp(),
// Here is the link from post => author.
// We've configured its UI display quite a lot to make the experience of editing posts better.
author: relationship({
ref: 'User.posts',
ui: {
displayMode: 'cards',
cardFields: ['name', 'email'],
inlineEdit: { fields: ['name', 'email'] },
linkToItem: true,
inlineCreate: { fields: ['name', 'email'] },
},
}),
// We also link posts to tags. This is a many <=> many linking.
tags: relationship({
ref: 'Tag.posts',
ui: {
displayMode: 'cards',
cardFields: ['name'],
inlineEdit: { fields: ['name'] },
linkToItem: true,
inlineConnect: true,
inlineCreate: { fields: ['name'] },
},
many: true,
}),
},
}),
// Our final list is the tag list. This field is just a name and a relationship to posts
Tag: list({
ui: {
isHidden: true,
},
fields: {
name: text(),
posts: relationship({ ref: 'Post.tags', many: true }),
},
}),
};