diff --git a/packages/payload/src/database/queryValidation/validateSearchParams.ts b/packages/payload/src/database/queryValidation/validateSearchParams.ts index 154e3dee5..42e1d86b8 100644 --- a/packages/payload/src/database/queryValidation/validateSearchParams.ts +++ b/packages/payload/src/database/queryValidation/validateSearchParams.ts @@ -162,7 +162,12 @@ export async function validateSearchParam({ if (versionFields) { fieldAccess = policies[entityType]![entitySlug]!.fields - if (segments[0] === 'parent' || segments[0] === 'version' || segments[0] === 'snapshot') { + if ( + segments[0] === 'parent' || + segments[0] === 'version' || + segments[0] === 'snapshot' || + segments[0] === 'latest' + ) { segments.shift() } } else { diff --git a/test/versions/int.spec.ts b/test/versions/int.spec.ts index 9fad5e64b..b45959f3c 100644 --- a/test/versions/int.spec.ts +++ b/test/versions/int.spec.ts @@ -4,9 +4,11 @@ import { schedulePublishHandler } from '@payloadcms/ui/utilities/schedulePublish import path from 'path' import { createLocalReq, ValidationError } from 'payload' import { wait } from 'payload/shared' +import * as qs from 'qs-esm' import { fileURLToPath } from 'url' import type { NextRESTClient } from '../helpers/NextRESTClient.js' +import type { DraftPost } from './payload-types.js' import { devUser } from '../credentials.js' import { initPayloadInt } from '../helpers/initPayloadInt.js' @@ -1504,6 +1506,79 @@ describe('Versions', () => { const jsonByID = await responseByID.json() expect(jsonByID.parent).toBe(collectionLocalPostID) }) + + it('should allow query by latest', async () => { + async function createVersion({ title }: { title: string }) { + return payload.create({ + collection: draftCollectionSlug, + data: { + title, + description: 'Test Description', + }, + }) + } + + async function updateVersion({ + id, + data, + }: { + data: Partial + id: number | string + }) { + return payload.update({ + collection: draftCollectionSlug, + id, + data, + }) + } + + const version1 = await createVersion({ + title: 'test1', + }) + + await updateVersion({ + id: version1.id, + data: { + title: 'test1 updated', + }, + }) + + const newestVersion = await updateVersion({ + id: version1.id, + data: { + title: 'test2 updated', + }, + }) + + const query = qs.stringify( + { + where: { + and: [ + { + latest: { + equals: true, + }, + }, + { + parent: { + equals: version1.id, + }, + }, + ], + }, + }, + { + addQueryPrefix: true, + }, + ) + + const response = await restClient.GET(`/${draftCollectionSlug}/versions${query}`) + expect(response.status).toBe(200) + const json = await response.json() + expect(json.docs).toHaveLength(1) + + expect(json.docs[0].version.title).toBe(newestVersion.title) + }) }) describe('Globals - Local', () => {