Skip to content

Commit 5855f3a

Browse files
authored
fix: sanitize duplicate blocks (#12440)
1 parent 529bfe1 commit 5855f3a

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

packages/payload/src/fields/config/sanitize.spec.ts

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ import type {
99
TextField,
1010
} from './types.js'
1111

12-
import { InvalidFieldName, InvalidFieldRelationship, MissingFieldType } from '../../errors/index.js'
12+
import {
13+
DuplicateFieldName,
14+
InvalidFieldName,
15+
InvalidFieldRelationship,
16+
MissingFieldType,
17+
} from '../../errors/index.js'
1318
import { sanitizeFields } from './sanitize.js'
1419
import { CollectionConfig } from '../../index.js'
1520

@@ -55,6 +60,68 @@ describe('sanitizeFields', () => {
5560
}).rejects.toThrow(InvalidFieldName)
5661
})
5762

63+
it('should throw on duplicate field name', async () => {
64+
const fields: Field[] = [
65+
{
66+
name: 'someField',
67+
type: 'text',
68+
label: 'someField',
69+
},
70+
{
71+
name: 'someField',
72+
type: 'text',
73+
label: 'someField',
74+
},
75+
]
76+
77+
await expect(async () => {
78+
await sanitizeFields({
79+
config,
80+
collectionConfig,
81+
fields,
82+
validRelationships: [],
83+
})
84+
}).rejects.toThrow(DuplicateFieldName)
85+
})
86+
87+
it('should throw on duplicate block slug', async () => {
88+
const fields: Field[] = [
89+
{
90+
name: 'blocks',
91+
type: 'blocks',
92+
blocks: [
93+
{
94+
slug: 'block',
95+
fields: [
96+
{
97+
name: 'blockField',
98+
type: 'text',
99+
},
100+
],
101+
},
102+
{
103+
slug: 'block',
104+
fields: [
105+
{
106+
name: 'blockField',
107+
type: 'text',
108+
},
109+
],
110+
},
111+
],
112+
},
113+
]
114+
115+
await expect(async () => {
116+
await sanitizeFields({
117+
config,
118+
collectionConfig,
119+
fields,
120+
validRelationships: [],
121+
})
122+
}).rejects.toThrow(DuplicateFieldName)
123+
})
124+
58125
describe('auto-labeling', () => {
59126
it('should populate label if missing', async () => {
60127
const fields: Field[] = [

packages/payload/src/fields/config/sanitize.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ export const sanitizeFields = async ({
242242
if (!field.hooks) {
243243
field.hooks = {}
244244
}
245+
245246
if (!field.access) {
246247
field.access = {}
247248
}
@@ -289,13 +290,25 @@ export const sanitizeFields = async ({
289290
throw new Error('You cannot have both blockReferences and blocks in the same blocks field')
290291
}
291292

293+
const blockSlugs: string[] = []
294+
292295
for (const block of field.blockReferences ?? field.blocks) {
296+
const blockSlug = typeof block === 'string' ? block : block.slug
297+
298+
if (blockSlugs.includes(blockSlug)) {
299+
throw new DuplicateFieldName(blockSlug)
300+
}
301+
302+
blockSlugs.push(blockSlug)
303+
293304
if (typeof block === 'string') {
294305
continue
295306
}
307+
296308
if (block._sanitized === true) {
297309
continue
298310
}
311+
299312
block._sanitized = true
300313
block.fields = block.fields.concat(baseBlockFields)
301314
block.labels = !block.labels ? formatLabels(block.slug) : block.labels

0 commit comments

Comments
 (0)