fix(db-mongodb): strip deleted from the config blocks from the result (#12869)
If you (using the MongoDB adapter) delete a block from the payload config, but still have some data with that block in the DB, you'd receive in the admin panel an error like: ``` Block with type "cta" was found in block data, but no block with that type is defined in the config for field with schema path pages.blocks ``` Now, we remove those "unknown" blocks at the DB adapter level. Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
This commit is contained in:
@@ -277,7 +277,9 @@ const stripFields = ({
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const data of localeData) {
|
let hasNull = false
|
||||||
|
for (let i = 0; i < localeData.length; i++) {
|
||||||
|
const data = localeData[i]
|
||||||
let fields: FlattenedField[] | null = null
|
let fields: FlattenedField[] | null = null
|
||||||
|
|
||||||
if (field.type === 'array') {
|
if (field.type === 'array') {
|
||||||
@@ -286,11 +288,17 @@ const stripFields = ({
|
|||||||
let maybeBlock: FlattenedBlock | undefined = undefined
|
let maybeBlock: FlattenedBlock | undefined = undefined
|
||||||
|
|
||||||
if (field.blockReferences) {
|
if (field.blockReferences) {
|
||||||
const maybeBlockReference = field.blockReferences.find(
|
const maybeBlockReference = field.blockReferences.find((each) => {
|
||||||
(each) => typeof each === 'object' && each.slug === data.blockType,
|
const slug = typeof each === 'string' ? each : each.slug
|
||||||
)
|
return slug === data.blockType
|
||||||
if (maybeBlockReference && typeof maybeBlockReference === 'object') {
|
})
|
||||||
maybeBlock = maybeBlockReference
|
|
||||||
|
if (maybeBlockReference) {
|
||||||
|
if (typeof maybeBlockReference === 'object') {
|
||||||
|
maybeBlock = maybeBlockReference
|
||||||
|
} else {
|
||||||
|
maybeBlock = config.blocks?.find((each) => each.slug === maybeBlockReference)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,6 +308,9 @@ const stripFields = ({
|
|||||||
|
|
||||||
if (maybeBlock) {
|
if (maybeBlock) {
|
||||||
fields = maybeBlock.flattenedFields
|
fields = maybeBlock.flattenedFields
|
||||||
|
} else {
|
||||||
|
localeData[i] = null
|
||||||
|
hasNull = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,6 +321,10 @@ const stripFields = ({
|
|||||||
stripFields({ config, data, fields, reservedKeys })
|
stripFields({ config, data, fields, reservedKeys })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasNull) {
|
||||||
|
fieldData[localeKey] = localeData.filter(Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
stripFields({ config, data: localeData, fields: field.flattenedFields, reservedKeys })
|
stripFields({ config, data: localeData, fields: field.flattenedFields, reservedKeys })
|
||||||
@@ -323,7 +338,10 @@ const stripFields = ({
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const data of fieldData) {
|
let hasNull = false
|
||||||
|
|
||||||
|
for (let i = 0; i < fieldData.length; i++) {
|
||||||
|
const data = fieldData[i]
|
||||||
let fields: FlattenedField[] | null = null
|
let fields: FlattenedField[] | null = null
|
||||||
|
|
||||||
if (field.type === 'array') {
|
if (field.type === 'array') {
|
||||||
@@ -332,12 +350,17 @@ const stripFields = ({
|
|||||||
let maybeBlock: FlattenedBlock | undefined = undefined
|
let maybeBlock: FlattenedBlock | undefined = undefined
|
||||||
|
|
||||||
if (field.blockReferences) {
|
if (field.blockReferences) {
|
||||||
const maybeBlockReference = field.blockReferences.find(
|
const maybeBlockReference = field.blockReferences.find((each) => {
|
||||||
(each) => typeof each === 'object' && each.slug === data.blockType,
|
const slug = typeof each === 'string' ? each : each.slug
|
||||||
)
|
return slug === data.blockType
|
||||||
|
})
|
||||||
|
|
||||||
if (maybeBlockReference && typeof maybeBlockReference === 'object') {
|
if (maybeBlockReference) {
|
||||||
maybeBlock = maybeBlockReference
|
if (typeof maybeBlockReference === 'object') {
|
||||||
|
maybeBlock = maybeBlockReference
|
||||||
|
} else {
|
||||||
|
maybeBlock = config.blocks?.find((each) => each.slug === maybeBlockReference)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,6 +370,9 @@ const stripFields = ({
|
|||||||
|
|
||||||
if (maybeBlock) {
|
if (maybeBlock) {
|
||||||
fields = maybeBlock.flattenedFields
|
fields = maybeBlock.flattenedFields
|
||||||
|
} else {
|
||||||
|
fieldData[i] = null
|
||||||
|
hasNull = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,6 +383,10 @@ const stripFields = ({
|
|||||||
stripFields({ config, data, fields, reservedKeys })
|
stripFields({ config, data, fields, reservedKeys })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasNull) {
|
||||||
|
data[field.name] = fieldData.filter(Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
stripFields({ config, data: fieldData, fields: field.flattenedFields, reservedKeys })
|
stripFields({ config, data: fieldData, fields: field.flattenedFields, reservedKeys })
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* eslint-disable no-restricted-exports */
|
|
||||||
import { fileURLToPath } from 'node:url'
|
import { fileURLToPath } from 'node:url'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
const filename = fileURLToPath(import.meta.url)
|
const filename = fileURLToPath(import.meta.url)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { CustomView as CustomView_c4f0e2747eca2be436a06a63cea31567 } from '../../CustomView/index.js'
|
import { CustomView as CustomView_c4f0e2747eca2be436a06a63cea31567 } from '../../CustomView/index.js'
|
||||||
|
|
||||||
export const importMap = {
|
export const importMap = {
|
||||||
"/CustomView/index.js#CustomView": CustomView_c4f0e2747eca2be436a06a63cea31567
|
'/CustomView/index.js#CustomView': CustomView_c4f0e2747eca2be436a06a63cea31567,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2727,6 +2727,53 @@ describe('database', () => {
|
|||||||
expect(res.blocks[0]?.nested[0]?.nested).toHaveLength(0)
|
expect(res.blocks[0]?.nested[0]?.nested).toHaveLength(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should ignore blocks that exist in the db but not in the config', async () => {
|
||||||
|
// not possible w/ SQL anyway
|
||||||
|
// eslint-disable-next-line jest/no-conditional-in-test
|
||||||
|
if (payload.db.name !== 'mongoose') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await payload.db.collections['blocks-docs']?.collection.insertOne({
|
||||||
|
testBlocks: [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
blockType: 'cta',
|
||||||
|
text: 'valid block',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
blockType: 'cta_2',
|
||||||
|
text: 'non-valid block',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
testBlocksLocalized: {
|
||||||
|
en: [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
blockType: 'cta',
|
||||||
|
text: 'valid block',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
blockType: 'cta_2',
|
||||||
|
text: 'non-valid block',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const doc = await payload.findByID({
|
||||||
|
collection: 'blocks-docs',
|
||||||
|
id: res?.insertedId?.toHexString() as string,
|
||||||
|
locale: 'en',
|
||||||
|
})
|
||||||
|
expect(doc.testBlocks).toHaveLength(1)
|
||||||
|
expect(doc.testBlocks[0].id).toBe('1')
|
||||||
|
expect(doc.testBlocksLocalized).toHaveLength(1)
|
||||||
|
expect(doc.testBlocksLocalized[0].id).toBe('1')
|
||||||
|
})
|
||||||
|
|
||||||
it('should CRUD with blocks as JSON in SQL adapters', async () => {
|
it('should CRUD with blocks as JSON in SQL adapters', async () => {
|
||||||
// eslint-disable-next-line jest/no-conditional-in-test
|
// eslint-disable-next-line jest/no-conditional-in-test
|
||||||
if (!('drizzle' in payload.db)) {
|
if (!('drizzle' in payload.db)) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"id": "e7129a5b-a5af-490a-8ad9-318e3caeca26",
|
"id": "a3dd8ca0-5e09-407b-9178-e0ff7f15da59",
|
||||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||||
"version": "7",
|
"version": "7",
|
||||||
"dialect": "postgresql",
|
"dialect": "postgresql",
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import * as migration_20250624_142145 from './20250624_142145.js'
|
import * as migration_20250624_214621 from './20250624_214621.js'
|
||||||
|
|
||||||
export const migrations = [
|
export const migrations = [
|
||||||
{
|
{
|
||||||
up: migration_20250624_142145.up,
|
up: migration_20250624_214621.up,
|
||||||
down: migration_20250624_142145.down,
|
down: migration_20250624_214621.down,
|
||||||
name: '20250624_142145',
|
name: '20250624_214621',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user