### What? Cannot generate GraphQL schema with hyphenated field names Using field names that do not adhere to the GraphQL `_a-z & A-Z` standard prevent you from generating a schema, even though it will work just fine everywhere else. Example: `my-field-name` will prevent schema generation. ### How? Field name sanitization on generation and querying This PR adds sanitization to the schema generation that sanitizes field names. - It formats field names in a GraphQL safe format for schema generation. **It does not change your config.** - It adds resolvers for field names that do not adhere so they can be mapped from the config name to the GraphQL safe name. Example: - `my-field` will turn into `my_field` in the schema generation - `my_field` will resolve from `my-field` when data comes out ### Other notes - Moves code from `packages/graphql/src/schema/buildObjectType.ts` to `packages/graphql/src/schema/fieldToSchemaMap.ts` - Resolvers are only added when necessary: `if (formatName(field.name) !== field.name)`. --------- Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
72 lines
1.6 KiB
TypeScript
72 lines
1.6 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',
|
|
},
|
|
{
|
|
name: 'hyphenated-name',
|
|
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] },
|
|
),
|
|
)
|
|
}
|
|
},
|
|
})
|