Files
payloadcms/test/graphql-schema-gen/config.ts
Patrik 1dc346af04 fix(graphql): invalid enum names when values include brackets (#13597)
### What?

Brackets (`[ ]`) in option values end up in GraphQL enum names via
`formatName`, causing schema generation to fail. This PR adds a single
rule to `formatName`:

- replace `[` and `]` with `_`

### Why?

Using `_` (instead of removing the brackets) is safer and more
consistent:

- Avoid collisions: removal can merge distinct strings (`"A[B]"` →
`"AB"`). `_` keeps them distinct (`"A_B"`).
- **Consistency**: `formatName` already maps punctuation to `_` (`. - /
+ , ( ) '`). Brackets follow the same rule.

Readability: `mb-[150px]` → `mb__150px_` is clearer than `mb150px`.

Digits/units safety: removal can jam characters (`w-[2/3]` → `w23`); `_`
avoids that (`w_2_3_`).

### How?

Update formatName to include a bracket replacement step:

```
.replace(/\[|\]/g, '_')
```

No other call sites or value semantics change; only names containing
brackets are affected.

Fixes #13466 


---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211141396953194
2025-08-26 11:03:26 -07:00

180 lines
4.0 KiB
TypeScript

import path from 'path'
import { fileURLToPath } from 'url'
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
export default buildConfigWithDefaults({
admin: {
importMap: {
baseDir: path.resolve(dirname),
},
},
typescript: {
outputFile: path.resolve(dirname, 'schema.ts'),
},
collections: [
{
slug: 'collection1',
fields: [
{
type: 'row',
fields: [{ type: 'text', required: true, name: 'testing' }],
},
{
type: 'tabs',
tabs: [
{
label: 'Tab 1',
fields: [
{
required: true,
type: 'text',
name: 'title',
},
],
},
],
},
{
type: 'array',
name: 'meta',
interfaceName: 'SharedMetaArray',
fields: [
{
name: 'title',
type: 'text',
},
{
name: 'description',
type: 'text',
},
],
},
{
type: 'blocks',
name: 'blocks',
required: true,
blocks: [
{
slug: 'block1',
interfaceName: 'SharedMetaBlock',
fields: [
{
required: true,
name: 'b1title',
type: 'text',
},
{
name: 'b1description',
type: 'text',
},
],
},
{
slug: 'block2',
interfaceName: 'AnotherSharedBlock',
fields: [
{
name: 'b2title',
type: 'text',
required: true,
},
{
name: 'b2description',
type: 'text',
},
],
},
],
},
],
},
{
slug: 'collection2',
fields: [
{
type: 'array',
name: 'metaArray',
interfaceName: 'SharedMetaArray',
fields: [
{
name: 'title',
type: 'text',
},
{
name: 'description',
type: 'text',
},
],
},
{
type: 'group',
name: 'metaGroup',
interfaceName: 'SharedMeta',
fields: [
{
name: 'title',
type: 'text',
},
{
name: 'description',
type: 'text',
},
],
},
{
type: 'group',
name: 'nestedGroup',
fields: [
{
type: 'group',
name: 'meta',
interfaceName: 'SharedMeta',
fields: [
{
name: 'title',
type: 'text',
},
{
name: 'description',
type: 'text',
},
],
},
],
},
{
name: 'some[text]',
type: 'text',
},
{
name: 'spaceBottom',
type: 'select',
required: false,
defaultValue: 'mb-0',
options: [
{ label: 'None', value: 'mb-0' },
{ label: 'Small', value: 'mb-8' },
{ label: 'Medium', value: 'mb-16' },
{ label: 'Large', value: 'mb-24' },
{ label: 'Extra Large', value: 'mb-[150px]' },
],
},
],
},
{
// this should not be written to the generated schema
slug: 'no-graphql',
graphQL: false,
fields: [
{
name: 'name',
type: 'text',
},
],
},
],
})