### What?
Adds the ability to set custom validation rules on the root `graphQL`
config property and the ability to define custom complexity on
relationship, join and upload type fields.
### Why?
**Validation Rules**
These give you the option to add your own validation rules. For example,
you may want to prevent introspection queries in production. You can now
do that with the following:
```ts
import { GraphQL } from '@payloadcms/graphql/types'
import { buildConfig } from 'payload'
export default buildConfig({
// ...
graphQL: {
validationRules: (args) => [
NoProductionIntrospection
]
},
// ...
})
const NoProductionIntrospection: GraphQL.ValidationRule = (context) => ({
Field(node) {
if (process.env.NODE_ENV === 'production') {
if (node.name.value === '__schema' || node.name.value === '__type') {
context.reportError(
new GraphQL.GraphQLError(
'GraphQL introspection is not allowed, but the query contained __schema or __type',
{ nodes: [node] }
)
);
}
}
}
})
```
**Custom field complexity**
You can now increase the complexity of a field, this will help users
from running queries that are too expensive. A higher number will make
the `maxComplexity` trigger sooner.
```ts
const fieldWithComplexity = {
name: 'authors',
type: 'relationship',
relationship: 'authors',
graphQL: {
complexity: 100, // highlight-line
}
}
```
68 lines
1.5 KiB
TypeScript
68 lines
1.5 KiB
TypeScript
import { GraphQL } from '@payloadcms/graphql/types'
|
|
import { fileURLToPath } from 'node:url'
|
|
import path from 'path'
|
|
|
|
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
|
|
import { devUser } from '../credentials.js'
|
|
|
|
const filename = fileURLToPath(import.meta.url)
|
|
const dirname = path.dirname(filename)
|
|
|
|
export default buildConfigWithDefaults({
|
|
// ...extend config here
|
|
collections: [
|
|
{
|
|
slug: 'posts',
|
|
fields: [
|
|
{
|
|
name: 'title',
|
|
label: 'Title',
|
|
type: 'text',
|
|
},
|
|
{
|
|
type: 'relationship',
|
|
relationTo: 'posts',
|
|
name: 'relationToSelf',
|
|
graphQL: {
|
|
complexity: 801,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
],
|
|
admin: {
|
|
importMap: {
|
|
baseDir: path.resolve(dirname),
|
|
},
|
|
},
|
|
onInit: async (payload) => {
|
|
await payload.create({
|
|
collection: 'users',
|
|
data: {
|
|
email: devUser.email,
|
|
password: devUser.password,
|
|
},
|
|
})
|
|
},
|
|
typescript: {
|
|
outputFile: path.resolve(dirname, 'payload-types.ts'),
|
|
},
|
|
graphQL: {
|
|
maxComplexity: 800,
|
|
validationRules: () => [NoIntrospection],
|
|
},
|
|
})
|
|
|
|
const NoIntrospection: GraphQL.ValidationRule = (context) => ({
|
|
Field(node) {
|
|
if (node.name.value === '__schema' || node.name.value === '__type') {
|
|
context.reportError(
|
|
new GraphQL.GraphQLError(
|
|
'GraphQL introspection is not allowed, but the query contained __schema or __type',
|
|
{ nodes: [node] },
|
|
),
|
|
)
|
|
}
|
|
},
|
|
})
|