diff --git a/src/collections/operations/find.ts b/src/collections/operations/find.ts index 7867d7e713..ed74909b68 100644 --- a/src/collections/operations/find.ts +++ b/src/collections/operations/find.ts @@ -136,29 +136,33 @@ async function find(incomingArgs: Arguments): Promis locale, }); - const optionsToExecute = { + const usePagination = pagination && limit !== 0; + const limitToUse = limit ?? (usePagination ? 10 : 0); + const paginatedDocs = await Model.paginate(query, { page: page || 1, - limit: limit || 10, sort: { [sortProperty]: sortOrder, }, + limit: limitToUse, lean: true, leanWithId: true, useEstimatedCount, - pagination, + pagination: usePagination, useCustomCountFn: pagination ? undefined : () => Promise.resolve(1), - }; + options: { + // limit must also be set here, it's ignored when pagination is false + limit: limitToUse, + }, + }); - const paginatedDocs = await Model.paginate(query, optionsToExecute); - - let result = { + let result: PaginatedDocs = { ...paginatedDocs, docs: paginatedDocs.docs.map((doc) => { const sanitizedDoc = JSON.parse(JSON.stringify(doc)); sanitizedDoc.id = sanitizedDoc._id; return sanitizeInternalFields(sanitizedDoc); }), - } as PaginatedDocs; + }; // ///////////////////////////////////// // Replace documents with drafts if available diff --git a/src/collections/operations/findVersions.ts b/src/collections/operations/findVersions.ts index 6b6ed8ac42..4fb5842da6 100644 --- a/src/collections/operations/findVersions.ts +++ b/src/collections/operations/findVersions.ts @@ -98,18 +98,16 @@ async function findVersions = any>(args: Arguments) locale, }); - const optionsToExecute = { + const paginatedDocs = await VersionsModel.paginate(query, { page: page || 1, - limit: limit || 10, + limit: limit ?? 10, sort: { [sortProperty]: sortOrder, }, lean: true, leanWithId: true, useEstimatedCount, - }; - - const paginatedDocs = await VersionsModel.paginate(query, optionsToExecute); + }); // ///////////////////////////////////// // beforeRead - Collection diff --git a/src/collections/requestHandlers/find.ts b/src/collections/requestHandlers/find.ts index 660f77c998..9f94102a84 100644 --- a/src/collections/requestHandlers/find.ts +++ b/src/collections/requestHandlers/find.ts @@ -5,6 +5,7 @@ import { TypeWithID } from '../config/types'; import { PaginatedDocs } from '../../mongoose/types'; import find from '../operations/find'; import { Where } from '../../types'; +import { isNumber } from '../../utilities/isNumber'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export default async function findHandler(req: PayloadRequest, res: Response, next: NextFunction): Promise> | void> { @@ -24,9 +25,9 @@ export default async function findHandler(req: Paylo collection: req.collection, where: req.query.where as Where, // This is a little shady page, - limit: Number(req.query.limit), + limit: isNumber(req.query.limit) ? Number(req.query.limit) : undefined, sort: req.query.sort as string, - depth: Number(req.query.depth), + depth: isNumber(req.query.depth) ? Number(req.query.depth) : undefined, draft: req.query.draft === 'true', }); diff --git a/src/globals/operations/findVersions.ts b/src/globals/operations/findVersions.ts index 3feb2bce28..f2bfce95f3 100644 --- a/src/globals/operations/findVersions.ts +++ b/src/globals/operations/findVersions.ts @@ -96,18 +96,16 @@ async function findVersions = any>(args: Arguments) locale, }); - const optionsToExecute = { + const paginatedDocs = await VersionsModel.paginate(query, { page: page || 1, - limit: limit || 10, + limit: limit ?? 10, sort: { [sortProperty]: sortOrder, }, lean: true, leanWithId: true, useEstimatedCount, - }; - - const paginatedDocs = await VersionsModel.paginate(query, optionsToExecute); + }); // ///////////////////////////////////// // afterRead - Fields diff --git a/src/mongoose/types.ts b/src/mongoose/types.ts index 884e5e9f22..cc61754c58 100644 --- a/src/mongoose/types.ts +++ b/src/mongoose/types.ts @@ -3,10 +3,10 @@ export type PaginatedDocs = { totalDocs: number limit: number totalPages: number - page: number + page?: number pagingCounter: number hasPrevPage: boolean hasNextPage: boolean - prevPage: number | null - nextPage: number | null + prevPage?: number | null | undefined + nextPage?: number | null | undefined } diff --git a/src/utilities/isNumber.ts b/src/utilities/isNumber.ts new file mode 100644 index 0000000000..1604de7ff2 --- /dev/null +++ b/src/utilities/isNumber.ts @@ -0,0 +1,3 @@ +export function isNumber(value: unknown): boolean { + return !Number.isNaN(Number(value)); +} diff --git a/test/collections-rest/int.spec.ts b/test/collections-rest/int.spec.ts index 32ae8493ec..fffe890fbf 100644 --- a/test/collections-rest/int.spec.ts +++ b/test/collections-rest/int.spec.ts @@ -622,6 +622,40 @@ describe('collections-rest', () => { expect(result.totalDocs).toEqual(1); expect(result.docs).toEqual([post1]); }); + + describe('limit', () => { + beforeEach(async () => { + await mapAsync([...Array(50)], async (_, i) => createPost({ title: 'limit-test', number: i })); + }); + + it('should query a limited set of docs', async () => { + const { status, result } = await client.find({ + limit: 15, + query: { + title: { + equals: 'limit-test', + }, + }, + }); + + expect(status).toEqual(200); + expect(result.docs).toHaveLength(15); + }); + + it('should query all docs when limit=0', async () => { + const { status, result } = await client.find({ + limit: 0, + query: { + title: { + equals: 'limit-test', + }, + }, + }); + + expect(status).toEqual(200); + expect(result.totalDocs).toEqual(50); + }); + }); }); }); }); diff --git a/test/helpers/rest.ts b/test/helpers/rest.ts index 59b0358568..67d4c2e75b 100644 --- a/test/helpers/rest.ts +++ b/test/helpers/rest.ts @@ -154,7 +154,11 @@ export class RESTClient { }; const slug = args?.slug || this.defaultSlug; - const whereQuery = qs.stringify(args?.query ? { where: args.query } : {}, { + const whereQuery = qs.stringify({ + ...(args?.query ? { where: args.query } : {}), + limit: args?.limit, + page: args?.page, + }, { addQueryPrefix: true, }); const fetchURL = `${this.serverURL}/api/${slug}${whereQuery}`;