fix(db-postgres): allow for nested block fields to be queried (#4237)
Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
This commit is contained in:
@@ -297,6 +297,9 @@ export const getTableColumnFromPath = ({
|
|||||||
table: adapter.tables[newTableName],
|
table: adapter.tables[newTableName],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (pathSegments[1] === 'blockType') {
|
||||||
|
throw new APIError('Querying on blockType is not supported')
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,11 @@ type Args = {
|
|||||||
const flattenWhere = (query: Where): WhereField[] =>
|
const flattenWhere = (query: Where): WhereField[] =>
|
||||||
Object.entries(query).reduce((flattenedConstraints, [key, val]) => {
|
Object.entries(query).reduce((flattenedConstraints, [key, val]) => {
|
||||||
if ((key === 'and' || key === 'or') && Array.isArray(val)) {
|
if ((key === 'and' || key === 'or') && Array.isArray(val)) {
|
||||||
return [...flattenedConstraints, ...val.map((subVal) => flattenWhere(subVal))]
|
const subWhereConstraints: Where[] = val.reduce((acc, subVal) => {
|
||||||
|
const subWhere = flattenWhere(subVal)
|
||||||
|
return [...acc, ...subWhere]
|
||||||
|
}, [])
|
||||||
|
return [...flattenedConstraints, ...subWhereConstraints]
|
||||||
}
|
}
|
||||||
|
|
||||||
return [...flattenedConstraints, { [key]: val }]
|
return [...flattenedConstraints, { [key]: val }]
|
||||||
|
|||||||
@@ -116,12 +116,24 @@ export async function validateSearchParam({
|
|||||||
const segments = fieldPath.split('.')
|
const segments = fieldPath.split('.')
|
||||||
|
|
||||||
if (versionFields) {
|
if (versionFields) {
|
||||||
if (fieldPath === 'parent' || fieldPath === 'version') {
|
fieldAccess = policies[entityType][entitySlug]
|
||||||
fieldAccess = policies[entityType][entitySlug].read.permission
|
if (segments[0] === 'parent' || segments[0] === 'version') {
|
||||||
} else if (segments[0] === 'parent' || segments[0] === 'version') {
|
|
||||||
fieldAccess = policies[entityType][entitySlug].read.permission
|
|
||||||
segments.shift()
|
segments.shift()
|
||||||
|
} else {
|
||||||
|
segments.forEach((segment, pathIndex) => {
|
||||||
|
if (fieldAccess[segment]) {
|
||||||
|
if (pathIndex === segments.length - 1) {
|
||||||
|
fieldAccess = fieldAccess[segment]
|
||||||
|
} else if ('fields' in fieldAccess[segment]) {
|
||||||
|
fieldAccess = fieldAccess[segment].fields
|
||||||
|
} else if ('blocks' in fieldAccess[segment]) {
|
||||||
|
fieldAccess = fieldAccess[segment]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fieldAccess = fieldAccess.read.permission
|
||||||
} else {
|
} else {
|
||||||
fieldAccess = policies[entityType][entitySlug].fields
|
fieldAccess = policies[entityType][entitySlug].fields
|
||||||
|
|
||||||
@@ -129,10 +141,14 @@ export async function validateSearchParam({
|
|||||||
fieldAccess = fieldAccess[field.name]
|
fieldAccess = fieldAccess[field.name]
|
||||||
} else {
|
} else {
|
||||||
segments.forEach((segment, pathIndex) => {
|
segments.forEach((segment, pathIndex) => {
|
||||||
if (pathIndex === segments.length - 1) {
|
if (fieldAccess[segment]) {
|
||||||
fieldAccess = fieldAccess[segment]
|
if (pathIndex === segments.length - 1) {
|
||||||
} else {
|
fieldAccess = fieldAccess[segment]
|
||||||
fieldAccess = fieldAccess[segment].fields
|
} else if ('fields' in fieldAccess[segment]) {
|
||||||
|
fieldAccess = fieldAccess[segment].fields
|
||||||
|
} else if ('blocks' in fieldAccess[segment]) {
|
||||||
|
fieldAccess = fieldAccess[segment]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import type { PaginatedDocs } from '../../packages/payload/src/database/types'
|
|||||||
import type { RichTextField } from './payload-types'
|
import type { RichTextField } from './payload-types'
|
||||||
|
|
||||||
import payload from '../../packages/payload/src'
|
import payload from '../../packages/payload/src'
|
||||||
|
import { devUser } from '../credentials'
|
||||||
import { initPayloadTest } from '../helpers/configHelpers'
|
import { initPayloadTest } from '../helpers/configHelpers'
|
||||||
import { isMongoose } from '../helpers/isMongoose'
|
import { isMongoose } from '../helpers/isMongoose'
|
||||||
import { RESTClient } from '../helpers/rest'
|
import { RESTClient } from '../helpers/rest'
|
||||||
@@ -35,6 +36,7 @@ let graphQLClient: GraphQLClient
|
|||||||
let serverURL: string
|
let serverURL: string
|
||||||
let config: SanitizedConfig
|
let config: SanitizedConfig
|
||||||
let token: string
|
let token: string
|
||||||
|
let user: any
|
||||||
|
|
||||||
describe('Fields', () => {
|
describe('Fields', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
@@ -45,6 +47,14 @@ describe('Fields', () => {
|
|||||||
const graphQLURL = `${serverURL}${config.routes.api}${config.routes.graphQL}`
|
const graphQLURL = `${serverURL}${config.routes.api}${config.routes.graphQL}`
|
||||||
graphQLClient = new GraphQLClient(graphQLURL)
|
graphQLClient = new GraphQLClient(graphQLURL)
|
||||||
token = await client.login()
|
token = await client.login()
|
||||||
|
|
||||||
|
user = await payload.login({
|
||||||
|
collection: 'users',
|
||||||
|
data: {
|
||||||
|
email: devUser.email,
|
||||||
|
password: devUser.password,
|
||||||
|
},
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@@ -834,6 +844,60 @@ describe('Fields', () => {
|
|||||||
|
|
||||||
expect(result.id).toBeDefined()
|
expect(result.id).toBeDefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should filter based on nested block fields', async () => {
|
||||||
|
await payload.create({
|
||||||
|
collection: 'block-fields',
|
||||||
|
data: {
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
blockType: 'content',
|
||||||
|
text: 'green',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await payload.create({
|
||||||
|
collection: 'block-fields',
|
||||||
|
data: {
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
blockType: 'content',
|
||||||
|
text: 'pink',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await payload.create({
|
||||||
|
collection: 'block-fields',
|
||||||
|
data: {
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
blockType: 'content',
|
||||||
|
text: 'green',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const blockFields = await payload.find({
|
||||||
|
collection: 'block-fields',
|
||||||
|
overrideAccess: false,
|
||||||
|
user,
|
||||||
|
where: {
|
||||||
|
and: [
|
||||||
|
{
|
||||||
|
'blocks.text': {
|
||||||
|
equals: 'green',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const { docs } = blockFields
|
||||||
|
expect(docs).toHaveLength(2)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('json', () => {
|
describe('json', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user