Skip to content

Commit d0316ee

Browse files
dcousensemmatown
andauthored
Update documentation for our upcoming major (#9783)
Co-authored-by: Daniel Cousens <dcousens@users.noreply.github.com> Co-authored-by: Emma Hamilton <git@emmas.town>
1 parent bea67bb commit d0316ee

22 files changed

Lines changed: 303 additions & 156 deletions

docs/content/docs/config/auth.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ The following elements will be added to the GraphQL API.
7373
```graphql
7474
type Mutation {
7575
authenticateUserWithPassword(email: String!, password: String!): UserAuthenticationWithPasswordResult!
76-
endSession: Boolean!
7776
}
7877

7978
type Query {

docs/content/docs/config/config.md

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ These database types are powered by their corresponding Prisma database provider
6464
- `url`: The connection URL for your database
6565
- `onConnect`: which takes a [`KeystoneContext`](../context/overview) object, and lets perform any actions you might need at startup, such as data seeding
6666
- `enableLogging` (default: `false`): Enable logging from the Prisma client.
67-
- `idField` (default: `{ kind: "cuid" }`): The kind of id field to use, it can be one of: `cuid`, `uuid` or `autoincrement`.
67+
- `idField` (default: `{ kind: "cuid" }`): The kind of id field to use, it can be one of: `cuid`, `uuid`, `nanoid`, `ulid`, or `autoincrement`.
6868
This can also be customised at the list level `db.idField`.
6969
If you are using `autoincrement`, you can also specify `type: 'BigInt'` on PostgreSQL and MySQL to use BigInts.
7070
- `shadowDatabaseUrl` (default: `undefined`): Enable [shadow databases](https://www.prisma.io/docs/concepts/components/prisma-migrate/shadow-database#cloud-hosted-shadow-databases-must-be-created-manually) for some cloud providers.
@@ -145,7 +145,7 @@ Advanced configuration:
145145

146146
- `publicPages` (default: `[]`): An array of page routes that bypass the `isAccessAllowed` function.
147147
- `pageMiddleware` (default: `undefined`): An async middleware function that can optionally return a redirect
148-
- `getAdditionalFiles` (default: `[]`): An async function returns an array of `AdminFileToWrite` objects indicating files to be added to the system at `build` time.
148+
- `getAdditionalFiles` (default: `undefined`): An async function that returns an array of `AdminFileToWrite` objects indicating files to be added to the system at `build` time.
149149
If the `mode` is `'write'`, then the code to be written to the file should be provided as the `src` argument.
150150
If the `mode` is `'copy'` then an `inputPath` value should be provided.
151151
The `outputPath` indicates where the file should be written or copied to
@@ -160,23 +160,21 @@ export default config<TypeInfo>({
160160

161161
// advanced configuration
162162
publicPages: ['/welcome'],
163-
getAdditionalFiles: [
164-
async (config: KeystoneConfig) => [
165-
{
166-
mode: 'write',
167-
src: `
168-
import { jsx } from '@keystone-ui/core';
169-
export default function Welcome() {
170-
return (<h1>Welcome to my Keystone system</h1>);
171-
}`,
172-
outputPath: 'pages/welcome.js',
173-
},
174-
{
175-
mode: 'copy',
176-
inputPath: '...',
177-
outputPath: 'pages/farewell.js',
178-
}
179-
],
163+
getAdditionalFiles: async () => [
164+
{
165+
mode: 'write',
166+
src: `
167+
import { Heading } from '@keystar/ui/typography';
168+
export default function Welcome() {
169+
return (<h1>Welcome to my Keystone system</h1>);
170+
}`,
171+
outputPath: 'pages/welcome.js',
172+
},
173+
{
174+
mode: 'copy',
175+
inputPath: '...',
176+
outputPath: 'pages/farewell.js',
177+
}
180178
],
181179
},
182180
/* ... */
@@ -357,7 +355,7 @@ It has a TypeScript type of `(schema: import("graphql").GraphQLSchema) => import
357355

358356
```typescript
359357
import type { GraphQLSchema } from 'graphql'
360-
import { config, graphql } from '@keystone-6/core'
358+
import { config, g } from '@keystone-6/core'
361359

362360
export default config<TypeInfo>({
363361
extendGraphqlSchema: (keystoneSchema: GraphQLSchema) => {
@@ -370,6 +368,12 @@ export default config<TypeInfo>({
370368

371369
See the [schema extension guide](../guides/schema-extension) for more details and tooling options on how to extend your GraphQL API.
372370

371+
## OpenTelemetry
372+
373+
Keystone has built-in support for [OpenTelemetry](https://opentelemetry.io/) tracing via `@opentelemetry/api`. When you configure an OpenTelemetry SDK in your application, Keystone will automatically emit trace spans for its internal operations (such as CRUD resolvers and hooks).
374+
375+
No additional Keystone configuration is required — just set up the OpenTelemetry SDK before Keystone starts. See the `logging-opentelemetry` example for a complete setup.
376+
373377
## Related resources
374378

375379
{% related-content %}

docs/content/docs/config/hooks.md

Lines changed: 60 additions & 21 deletions
Large diffs are not rendered by default.

docs/content/docs/config/lists.md

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export default config({
1313
lists: ({
1414
SomeListName: list({
1515
fields: { /* ... */ },
16+
actions: { /* ... */ },
1617
access: { /* ... */ },
1718
ui: { /* ... */ },
1819
hooks: { /* ... */ },
@@ -61,6 +62,69 @@ export default config({
6162

6263
For full details on the available field types and their configuration options please see the [Fields API](../fields/overview).
6364

65+
## actions
66+
67+
The `actions` property of the list configuration object is where you define actions that can triggered for items on your list.
68+
An action can be triggered on individual items or in bulk from the list view in the Admin UI, or directly using GraphQL.
69+
70+
```typescript
71+
import { config, list } from '@keystone-6/core';
72+
import { allowAll } from '@keystone-6/core/access';
73+
import { text, integer } from '@keystone-6/core/fields';
74+
75+
export default config({
76+
lists: {
77+
Post: list({
78+
access: allowAll,
79+
fields: {
80+
title: text(),
81+
votes: integer({ defaultValue: 0 }),
82+
},
83+
actions: {
84+
vote: {
85+
access: allowAll,
86+
async resolve ({ where }, context) {
87+
if (!where) return null
88+
return await context.prisma.post.update({
89+
where: { id: where.id },
90+
data: { votes: { increment: 1 } },
91+
})
92+
},
93+
ui: {
94+
label: 'Vote +1',
95+
icon: 'voteIcon',
96+
},
97+
},
98+
},
99+
}),
100+
},
101+
});
102+
```
103+
104+
Each action accepts the following options:
105+
106+
- `access` (**required**): An access control function that determines who can use this action. Receives `{ context, session, listKey, actionKey }`.
107+
- `resolve` (**required**): The function that performs the action. Receives `{ listKey, actionKey, where }` and `context`. Should return the updated item or `null`.
108+
- `graphql`: Options for the GraphQL schema output.
109+
- `singular`: Override the name of the singular mutation (default: `{action}{list.graphql.singular}`, e.g. `votePost`).
110+
- `plural`: Override the name of the plural mutation (default: `{action}{list.graphql.plural}`, e.g. `votePosts`).
111+
- `description` (default: `undefined`): Sets the description of the associated GraphQL type in the GraphQL schema output.
112+
- `ui` (**required**): Controls how the action appears in the Admin UI.
113+
- `label` (**required**): The label shown on the action button.
114+
- `icon`: An icon name from `@keystar/ui/icon/all` to display alongside the label.
115+
- `messages`: Locale messages for prompts and notifications. Supports template tags: `{singular}`, `{plural}`, `{singular|plural}`, `{itemLabel}`, `{count}`, `{countSuccess}`, `{countFail}`.
116+
- `promptTitle`, `promptTitleMany`, `prompt`, `promptMany`: Confirmation dialog text.
117+
- `promptConfirmLabel`, `promptConfirmLabelMany`: Confirm button text.
118+
- `success`, `successMany`: Success toast messages.
119+
- `fail`, `failMany`: Failure toast messages.
120+
- `itemView`: Controls for the item view.
121+
- `actionMode` (default: `'enabled'`): Can be `'enabled'`, `'disabled'`, or `'hidden'`, or a function that returns one of those values.
122+
- `navigation` (default: `'follow'`): Controls navigation after the action completes. `'follow'` navigates to the returned item (or list view if `null`), `'refetch'` stays and refreshes the item, `'return'` goes back to the list view.
123+
- `hidePrompt` (default: `false`): Do not show a confirmation dialog.
124+
- `hideToast` (default: `false`): Do not show a toast notification.
125+
- `listView`: Controls for the list view.
126+
- `actionMode` (default: `'enabled'`): Can be `'enabled'` or `'hidden'`, or a function that returns one of those values.
127+
64128
## access
65129

66130
The `access` option defines the [Access Control](../guides/auth-and-access-control) rules for the list.
@@ -79,7 +143,6 @@ Options:
79143
- `searchFields`: The fields used by the Admin UI when searching this list on the list view and in relationship fields. Nominated fields need to support the `contains` filter.
80144
It is always possible to search by an id and `'id'` should not be specified in this option.
81145
By default, the `labelField` is used if it has a string `contains` filter, otherwise none.
82-
- `description` (default: `undefined`): Sets the list description displayed in the Admin UI.
83146
- `hideNavigation` (default: `false`): Controls whether the list is visible in the navigation elements of the Admin UI.
84147
Can be either a boolean value or an async function with an argument `{ session, context }` that returns a boolean value.
85148
- `hideCreate` (default: `false`): Controls whether the `create` button is available in the Admin UI for this list.
@@ -106,6 +169,7 @@ Options:
106169
Option `field` is the name of the field to sort by, and `direction` is either `'ASC'` or `'DESC'` for ascending and descending sorting respectively.
107170
If undefined then data will be unsorted.
108171
- `pageSize` (default: lower of `50` or [`graphql.maxTake`](#graphql)): Sets the number of items to show per page in the list view.
172+
- `initialFilter` (default: `undefined`): Sets a default filter to apply to the list view. Accepts a where input object (excluding `AND`, `OR`, `NOT`), or an async function with an argument `{ session, context }` that returns a where input object.
109173
- `label`: The label used to identify the list in navigation etc.
110174
- `singular`: The singular form of the list key. It is used in sentences like `Are you sure you want to delete this {singular}?`
111175
- `plural`: The plural form of the list key. It is used in sentences like `Are you sure you want to delete these {plural}?`
@@ -121,7 +185,6 @@ export default config({
121185
fields: { name: text({ /* ... */ }) },
122186
ui: {
123187
label: 'Some List',
124-
description: '...',
125188

126189
singular: 'Item',
127190
plural: 'Items',
@@ -142,6 +205,7 @@ export default config({
142205
defaultFieldMode: ({ session, context }) => 'read',
143206
initialColumns: ['name', /* ... */],
144207
initialSort: { field: 'name', direction: 'ASC' },
208+
initialFilter: { isPublished: { equals: true } },
145209
pageSize: 50,
146210
},
147211
},
@@ -161,12 +225,11 @@ See the [Hooks API](./hooks) for full details on the available hook options.
161225

162226
## graphql
163227

164-
The `graphql` config option allows you to configure certain aspects of the GraphQL API.
228+
The `graphql` property allows you to configure certain aspects of the GraphQL API.
165229

166230
Options:
167231

168-
- `description` (default: `undefined`): Sets the description of the associated GraphQL type in the generated GraphQL API documentation.
169-
Overrides the list-level `description` config option.
232+
- `description` (default: `undefined`): Sets the description of the associated GraphQL type in the GraphQL schema output.
170233
- `singular`: (default: Singular list key, e.g. `'User'`): Overrides the name used in singular mutations and queries (e.g. `user()`, `updateUser()`, etc).
171234
- `plural`: (default: Pluralised list key, e.g. `'Users'`): Overrides the name used in multiple mutations and queries (e.g. `users()`, `updateUsers()`, etc).
172235
- `maxTake` (default: `undefined`): Allows you to specify the maximum `take` number for query operations on this list in the GraphQL API.

docs/content/docs/context/overview.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const context = {
3737

3838
// New context creators
3939
sudo,
40+
internal,
4041
withRequest,
4142
withSession,
4243

@@ -97,7 +98,9 @@ See the [session API](../config/session#session-context) for more details.
9798
When using the `context.query`, `context.graphql.run`, and `context.graphql.raw` APIs, access control and session information is passed through to these calls from the `context` object.
9899
The following functions will create a new `Context` object with this behaviour modified.
99100

100-
`sudo()`: A function which returns a new `Context` object with access control limitations removed, bypassing your `access` control configuration.
101+
`sudo()`: A function which returns a new `Context` object that bypasses your `access` control configuration when using `context.query`, `context.db` or `context.graphql`.
102+
103+
`internal()`: A function which returns a new `Context` object that bypasses `graphql.omit` on lists and fields, allowing you to query and mutate data that is otherwise omitted from the GraphQL API.
101104

102105
`withRequest(req, res)`: A function which returns a new `Context` object with the `.session` determined by your `sessionStrategy.get` function.
103106

@@ -107,6 +110,9 @@ The following functions will create a new `Context` object with this behaviour m
107110

108111
The `Context` object exposes the underlying database driver directly via `context.prisma`, which is a [Prisma Client](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference) object.
109112

113+
{% hint kind="tip" %}
114+
**\*Warning** Unlike other data access functions (`context.db`, `context.query` or `context.graphql`), `context.prisma` always bypasses the GraphQL schema and your access control. It is the equivalent of using `.sudo()` always.
115+
110116
### Images API
111117

112118
If [support for image fields](../config/config#storage-images-and-files) is enabled in the system, then an `images` API will be made available on the `context` object.

docs/content/docs/fields/bigint.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Javascript `BigInt`s are used since [integers in Javascript are unsafe beyond 2{
1010

1111
Options:
1212

13-
- `defaultValue` (default: `undefined`): Can be either a bigint value or `{ kind: 'autoincrement' }`.
13+
- `defaultValue` (default: `undefined`): Can be either a bigint value, `null`, or `{ kind: 'autoincrement' }`.
1414
This value will be used for the field when creating items if no explicit value is set.
1515
`{ kind: 'autoincrement' }` is only supported on PostgreSQL.
1616
- `db.isNullable` (default: `validation.isRequired ? false : true`): If `false` then this field will be made non-nullable in the database and it will never be possible to set as `null`.

docs/content/docs/fields/decimal.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ A `decimal` field represents a decimal value.
77

88
Options:
99

10-
- `defaultValue` (default: `undefined`): Can be a decimal value written as a string
10+
- `defaultValue` (default: `undefined`): Can be a decimal value written as a string, or `null`.
1111
This value will be used for the field when creating items if no explicit value is set.
1212
- `precision` (default: `18`): Maximum number of digits that are present in the number.
1313
- `scale` (default: `4`): Maximum number of decimal places.

docs/content/docs/fields/float.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ A `float` field represents a floating point value.
77

88
Options:
99

10-
- `defaultValue` (default: `undefined`): Can be a finite float value.
10+
- `defaultValue` (default: `undefined`): Can be a finite float value, or `null`.
1111
This value will be used for the field when creating items if no explicit value is set.
1212
- `db.map`: Adds a [Prisma `@map`](https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#map) attribute to this field which changes the column name in the database
1313
- `db.isNullable` (default: `validation.isRequired ? false : true`): If `false` then this field will be made non-nullable in the database and it will never be possible to set as `null`.

docs/content/docs/fields/integer.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ An `integer` field represents a 32 bit signed integer value.
77

88
Options:
99

10-
- `defaultValue` (default: `undefined`): Can be either an integer value or `{ kind: 'autoincrement' }`.
10+
- `defaultValue` (default: `undefined`): Can be either an integer value, `null`, or `{ kind: 'autoincrement' }`.
1111
This value will be used for the field when creating items if no explicit value is set.
1212
`{ kind: 'autoincrement' }` is only supported on PostgreSQL.
1313
- `db.isNullable` (default: `validation.isRequired ? false : true`): If `false` then this field will be made non-nullable in the database and it will never be possible to set as `null`.

0 commit comments

Comments
 (0)