Skip to content

Commit 15ee255

Browse files
committed
fix: finish shared block sanitization before initializing sibling editors
1 parent 0f6c5b0 commit 15ee255

2 files changed

Lines changed: 40 additions & 5 deletions

File tree

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -540,13 +540,11 @@ export const sanitizeConfig = async (incomingConfig: Config): Promise<SanitizedC
540540
}
541541
}
542542

543-
const promises: Promise<void>[] = []
544-
543+
// Shared blocks can be marked sanitized before their asynchronous fields finish.
544+
// Finish each editor before another editor captures those shared field definitions.
545545
for (const sanitizeFunction of richTextSanitizationPromises) {
546-
promises.push(sanitizeFunction(config as SanitizedConfig))
546+
await sanitizeFunction(config as SanitizedConfig)
547547
}
548548

549-
await Promise.all(promises)
550-
551549
return config as SanitizedConfig
552550
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import type { Block, RichTextField, SanitizedConfig } from 'payload'
2+
3+
import { mongooseAdapter } from '@payloadcms/db-mongodb'
4+
import { buildConfig } from 'payload'
5+
import { expect, it } from 'vitest'
6+
7+
import { lexicalEditor, type LexicalRichTextAdapter } from './index.js'
8+
import { BlocksFeature } from './features/blocks/server/index.js'
9+
10+
it('finishes shared block sanitization before another editor captures its fields', async () => {
11+
const shared: Block = {
12+
slug: 'shared',
13+
fields: [
14+
...Array.from({ length: 30 }, (_, i) => ({ name: `text${i}`, type: 'text' as const })),
15+
{ name: 'items', type: 'array', fields: [{ name: 'value', type: 'text' }] },
16+
],
17+
}
18+
const editor = () => lexicalEditor({ features: [BlocksFeature({ blocks: [shared] })] })
19+
const config = await buildConfig({
20+
secret: 'shared-block-test',
21+
db: mongooseAdapter({ url: 'mongodb://127.0.0.1:1/shared-block-test' }),
22+
collections: [{ slug: 'pages', fields: [
23+
{ name: 'one', type: 'richText', editor: editor() },
24+
{ name: 'two', type: 'richText', editor: editor() },
25+
] }],
26+
}) as SanitizedConfig
27+
28+
const collection = config.collections.find(({ slug }) => slug === 'pages')!
29+
for (const name of ['one', 'two']) {
30+
const field = collection.fields?.find(field => 'name' in field && field.name === name) as RichTextField
31+
const adapter = field.editor as LexicalRichTextAdapter
32+
const blocks = adapter.editorConfig.resolvedFeatureMap.get('blocks')!
33+
const node = blocks.nodes!.find(node => node.node.getType() === 'block')!
34+
const fields = node.getSubFields!({ node: { fields: { blockType: 'shared' } } } as never)
35+
expect(fields?.find(field => 'name' in field && field.name === 'items')?.validate).toBeTypeOf('function')
36+
}
37+
})

0 commit comments

Comments
 (0)