diff --git a/docs/local-api/overview.mdx b/docs/local-api/overview.mdx index 666be3dceef..28fb938d488 100644 --- a/docs/local-api/overview.mdx +++ b/docs/local-api/overview.mdx @@ -84,6 +84,7 @@ You can specify more options within the Local API vs. REST or GraphQL due to the | `depth` | [Control auto-population](../queries/depth) of nested relationship and upload fields. | | `locale` | Specify [locale](/docs/configuration/localization) for any returned documents. | | `select` | Specify [select](../queries/select) to control which fields to include to the result. | +| `populate` | Specify [populate](../queries/select#populate) to control which fields to include to the result from populated documents. | | `fallbackLocale` | Specify a [fallback locale](/docs/configuration/localization) to use for any returned documents. | | `overrideAccess` | Skip access control. By default, this property is set to true within all Local API operations. | | `overrideLock` | By default, document locks are ignored (`true`). Set to `false` to enforce locks and prevent operations when a document is locked by another user. [More details](../admin/locked-documents). | diff --git a/docs/queries/select.mdx b/docs/queries/select.mdx index 8d987ebc293..4a90b80b9b1 100644 --- a/docs/queries/select.mdx +++ b/docs/queries/select.mdx @@ -128,3 +128,31 @@ export const Pages: CollectionConfig<'pages'> = { ], } ``` + +## `populate` + +You can override `defaultPopulate` with the `populate` property in the Local and REST API + +Local API: +```ts +const getPosts = async () => { + const posts = await payload.find({ + collection: 'posts', + populate: { + // Select only `text` from populated docs in the "pages" collection + pages: { + text: true, + }, // highlight-line + }, + }) + + return posts +} +``` + +REST API: +```ts +fetch('https://localhost:3000/api/posts?populate[pages][text]=true') // highlight-line + .then((res) => res.json()) + .then((data) => console.log(data)) +``` diff --git a/docs/rest-api/overview.mdx b/docs/rest-api/overview.mdx index 69f68a7fd7d..f9f7c692664 100644 --- a/docs/rest-api/overview.mdx +++ b/docs/rest-api/overview.mdx @@ -19,6 +19,7 @@ All Payload API routes are mounted and prefixed to your config's `routes.api` UR - [locale](/docs/configuration/localization#retrieving-localized-docs) - retrieves document(s) in a specific locale - [fallback-locale](/docs/configuration/localization#retrieving-localized-docs) - specifies a fallback locale if no locale value exists - [select](../queries/select) - specifies which fields to include to the result +- [populate](../queries/select#populate) - specifies which fields to include to the result from populated documents ## Collections diff --git a/packages/next/src/routes/rest/collections/create.ts b/packages/next/src/routes/rest/collections/create.ts index e388d8c5a0c..f705bda0128 100644 --- a/packages/next/src/routes/rest/collections/create.ts +++ b/packages/next/src/routes/rest/collections/create.ts @@ -6,6 +6,7 @@ import { isNumber } from 'payload/shared' import type { CollectionRouteHandler } from '../types.js' import { headersWithCors } from '../../../utilities/headersWithCors.js' +import { sanitizePopulate } from '../utilities/sanitizePopulate.js' import { sanitizeSelect } from '../utilities/sanitizeSelect.js' export const create: CollectionRouteHandler = async ({ collection, req }) => { @@ -20,6 +21,7 @@ export const create: CollectionRouteHandler = async ({ collection, req }) => { data: req.data, depth: isNumber(depth) ? depth : undefined, draft, + populate: sanitizePopulate(req.query.populate), req, select: sanitizeSelect(req.query.select), }) diff --git a/packages/next/src/routes/rest/collections/delete.ts b/packages/next/src/routes/rest/collections/delete.ts index 5d5db732bc8..1e2e329df08 100644 --- a/packages/next/src/routes/rest/collections/delete.ts +++ b/packages/next/src/routes/rest/collections/delete.ts @@ -8,12 +8,14 @@ import { isNumber } from 'payload/shared' import type { CollectionRouteHandler } from '../types.js' import { headersWithCors } from '../../../utilities/headersWithCors.js' +import { sanitizePopulate } from '../utilities/sanitizePopulate.js' import { sanitizeSelect } from '../utilities/sanitizeSelect.js' export const deleteDoc: CollectionRouteHandler = async ({ collection, req }) => { - const { depth, overrideLock, select, where } = req.query as { + const { depth, overrideLock, populate, select, where } = req.query as { depth?: string overrideLock?: string + populate?: Record select?: Record where?: Where } @@ -22,6 +24,7 @@ export const deleteDoc: CollectionRouteHandler = async ({ collection, req }) => collection, depth: isNumber(depth) ? Number(depth) : undefined, overrideLock: Boolean(overrideLock === 'true'), + populate: sanitizePopulate(populate), req, select: sanitizeSelect(select), where, diff --git a/packages/next/src/routes/rest/collections/deleteByID.ts b/packages/next/src/routes/rest/collections/deleteByID.ts index 9f4869a6d92..676a16fbf6c 100644 --- a/packages/next/src/routes/rest/collections/deleteByID.ts +++ b/packages/next/src/routes/rest/collections/deleteByID.ts @@ -6,6 +6,7 @@ import type { CollectionRouteHandlerWithID } from '../types.js' import { headersWithCors } from '../../../utilities/headersWithCors.js' import { sanitizeCollectionID } from '../utilities/sanitizeCollectionID.js' +import { sanitizePopulate } from '../utilities/sanitizePopulate.js' import { sanitizeSelect } from '../utilities/sanitizeSelect.js' export const deleteByID: CollectionRouteHandlerWithID = async ({ @@ -28,6 +29,7 @@ export const deleteByID: CollectionRouteHandlerWithID = async ({ collection, depth: isNumber(depth) ? depth : undefined, overrideLock: Boolean(overrideLock === 'true'), + populate: sanitizePopulate(req.query.populate), req, select: sanitizeSelect(req.query.select), }) diff --git a/packages/next/src/routes/rest/collections/duplicate.ts b/packages/next/src/routes/rest/collections/duplicate.ts index 891af1794fe..5a46ca7a504 100644 --- a/packages/next/src/routes/rest/collections/duplicate.ts +++ b/packages/next/src/routes/rest/collections/duplicate.ts @@ -7,6 +7,7 @@ import type { CollectionRouteHandlerWithID } from '../types.js' import { headersWithCors } from '../../../utilities/headersWithCors.js' import { sanitizeCollectionID } from '../utilities/sanitizeCollectionID.js' +import { sanitizePopulate } from '../utilities/sanitizePopulate.js' import { sanitizeSelect } from '../utilities/sanitizeSelect.js' export const duplicate: CollectionRouteHandlerWithID = async ({ @@ -30,6 +31,7 @@ export const duplicate: CollectionRouteHandlerWithID = async ({ collection, depth: isNumber(depth) ? Number(depth) : undefined, draft, + populate: sanitizePopulate(req.query.populate), req, select: sanitizeSelect(req.query.select), }) diff --git a/packages/next/src/routes/rest/collections/find.ts b/packages/next/src/routes/rest/collections/find.ts index 29fbcc21f1f..5e46eff9bc8 100644 --- a/packages/next/src/routes/rest/collections/find.ts +++ b/packages/next/src/routes/rest/collections/find.ts @@ -8,15 +8,17 @@ import type { CollectionRouteHandler } from '../types.js' import { headersWithCors } from '../../../utilities/headersWithCors.js' import { sanitizeJoinParams } from '../utilities/sanitizeJoinParams.js' +import { sanitizePopulate } from '../utilities/sanitizePopulate.js' import { sanitizeSelect } from '../utilities/sanitizeSelect.js' export const find: CollectionRouteHandler = async ({ collection, req }) => { - const { depth, draft, joins, limit, page, select, sort, where } = req.query as { + const { depth, draft, joins, limit, page, populate, select, sort, where } = req.query as { depth?: string draft?: string joins?: JoinQuery limit?: string page?: string + populate?: Record select?: Record sort?: string where?: Where @@ -29,6 +31,7 @@ export const find: CollectionRouteHandler = async ({ collection, req }) => { joins: sanitizeJoinParams(joins), limit: isNumber(limit) ? Number(limit) : undefined, page: isNumber(page) ? Number(page) : undefined, + populate: sanitizePopulate(populate), req, select: sanitizeSelect(select), sort: typeof sort === 'string' ? sort.split(',') : undefined, diff --git a/packages/next/src/routes/rest/collections/findByID.ts b/packages/next/src/routes/rest/collections/findByID.ts index 4faeace3c4f..33e86ac3f89 100644 --- a/packages/next/src/routes/rest/collections/findByID.ts +++ b/packages/next/src/routes/rest/collections/findByID.ts @@ -9,6 +9,7 @@ import type { CollectionRouteHandlerWithID } from '../types.js' import { headersWithCors } from '../../../utilities/headersWithCors.js' import { sanitizeCollectionID } from '../utilities/sanitizeCollectionID.js' import { sanitizeJoinParams } from '../utilities/sanitizeJoinParams.js' +import { sanitizePopulate } from '../utilities/sanitizePopulate.js' import { sanitizeSelect } from '../utilities/sanitizeSelect.js' export const findByID: CollectionRouteHandlerWithID = async ({ @@ -31,6 +32,7 @@ export const findByID: CollectionRouteHandlerWithID = async ({ depth: isNumber(depth) ? Number(depth) : undefined, draft: searchParams.get('draft') === 'true', joins: sanitizeJoinParams(req.query.joins as JoinQuery), + populate: sanitizePopulate(req.query.populate), req, select: sanitizeSelect(req.query.select), }) diff --git a/packages/next/src/routes/rest/collections/findVersionByID.ts b/packages/next/src/routes/rest/collections/findVersionByID.ts index 7ad31fc93a6..ab99120796f 100644 --- a/packages/next/src/routes/rest/collections/findVersionByID.ts +++ b/packages/next/src/routes/rest/collections/findVersionByID.ts @@ -6,6 +6,7 @@ import type { CollectionRouteHandlerWithID } from '../types.js' import { headersWithCors } from '../../../utilities/headersWithCors.js' import { sanitizeCollectionID } from '../utilities/sanitizeCollectionID.js' +import { sanitizePopulate } from '../utilities/sanitizePopulate.js' import { sanitizeSelect } from '../utilities/sanitizeSelect.js' export const findVersionByID: CollectionRouteHandlerWithID = async ({ @@ -26,6 +27,7 @@ export const findVersionByID: CollectionRouteHandlerWithID = async ({ id, collection, depth: isNumber(depth) ? Number(depth) : undefined, + populate: sanitizePopulate(req.query.populate), req, select: sanitizeSelect(req.query.select), }) diff --git a/packages/next/src/routes/rest/collections/findVersions.ts b/packages/next/src/routes/rest/collections/findVersions.ts index 358c3aacc07..0f7b38f18ed 100644 --- a/packages/next/src/routes/rest/collections/findVersions.ts +++ b/packages/next/src/routes/rest/collections/findVersions.ts @@ -7,13 +7,15 @@ import { isNumber } from 'payload/shared' import type { CollectionRouteHandler } from '../types.js' import { headersWithCors } from '../../../utilities/headersWithCors.js' +import { sanitizePopulate } from '../utilities/sanitizePopulate.js' import { sanitizeSelect } from '../utilities/sanitizeSelect.js' export const findVersions: CollectionRouteHandler = async ({ collection, req }) => { - const { depth, limit, page, select, sort, where } = req.query as { + const { depth, limit, page, populate, select, sort, where } = req.query as { depth?: string limit?: string page?: string + populate?: Record select?: Record sort?: string where?: Where @@ -24,6 +26,7 @@ export const findVersions: CollectionRouteHandler = async ({ collection, req }) depth: isNumber(depth) ? Number(depth) : undefined, limit: isNumber(limit) ? Number(limit) : undefined, page: isNumber(page) ? Number(page) : undefined, + populate: sanitizePopulate(populate), req, select: sanitizeSelect(select), sort: typeof sort === 'string' ? sort.split(',') : undefined, diff --git a/packages/next/src/routes/rest/collections/restoreVersion.ts b/packages/next/src/routes/rest/collections/restoreVersion.ts index af7f217b506..f48d5c0ed29 100644 --- a/packages/next/src/routes/rest/collections/restoreVersion.ts +++ b/packages/next/src/routes/rest/collections/restoreVersion.ts @@ -6,6 +6,7 @@ import type { CollectionRouteHandlerWithID } from '../types.js' import { headersWithCors } from '../../../utilities/headersWithCors.js' import { sanitizeCollectionID } from '../utilities/sanitizeCollectionID.js' +import { sanitizePopulate } from '../utilities/sanitizePopulate.js' export const restoreVersion: CollectionRouteHandlerWithID = async ({ id: incomingID, @@ -27,6 +28,7 @@ export const restoreVersion: CollectionRouteHandlerWithID = async ({ collection, depth: isNumber(depth) ? Number(depth) : undefined, draft: draft === 'true' ? true : undefined, + populate: sanitizePopulate(req.query.populate), req, }) diff --git a/packages/next/src/routes/rest/collections/update.ts b/packages/next/src/routes/rest/collections/update.ts index 70e4366fb93..f90ae9ec449 100644 --- a/packages/next/src/routes/rest/collections/update.ts +++ b/packages/next/src/routes/rest/collections/update.ts @@ -8,14 +8,16 @@ import { isNumber } from 'payload/shared' import type { CollectionRouteHandler } from '../types.js' import { headersWithCors } from '../../../utilities/headersWithCors.js' +import { sanitizePopulate } from '../utilities/sanitizePopulate.js' import { sanitizeSelect } from '../utilities/sanitizeSelect.js' export const update: CollectionRouteHandler = async ({ collection, req }) => { - const { depth, draft, limit, overrideLock, select, where } = req.query as { + const { depth, draft, limit, overrideLock, populate, select, where } = req.query as { depth?: string draft?: string limit?: string overrideLock?: string + populate?: Record select?: Record where?: Where } @@ -27,6 +29,7 @@ export const update: CollectionRouteHandler = async ({ collection, req }) => { draft: draft === 'true', limit: isNumber(limit) ? Number(limit) : undefined, overrideLock: Boolean(overrideLock === 'true'), + populate: sanitizePopulate(populate), req, select: sanitizeSelect(select), where, diff --git a/packages/next/src/routes/rest/collections/updateByID.ts b/packages/next/src/routes/rest/collections/updateByID.ts index 7d4b50fdd76..f2868f4badb 100644 --- a/packages/next/src/routes/rest/collections/updateByID.ts +++ b/packages/next/src/routes/rest/collections/updateByID.ts @@ -6,6 +6,7 @@ import type { CollectionRouteHandlerWithID } from '../types.js' import { headersWithCors } from '../../../utilities/headersWithCors.js' import { sanitizeCollectionID } from '../utilities/sanitizeCollectionID.js' +import { sanitizePopulate } from '../utilities/sanitizePopulate.js' import { sanitizeSelect } from '../utilities/sanitizeSelect.js' export const updateByID: CollectionRouteHandlerWithID = async ({ @@ -34,6 +35,7 @@ export const updateByID: CollectionRouteHandlerWithID = async ({ depth: isNumber(depth) ? Number(depth) : undefined, draft, overrideLock: Boolean(overrideLock === 'true'), + populate: sanitizePopulate(req.query.populate), publishSpecificLocale, req, select: sanitizeSelect(req.query.select), diff --git a/packages/next/src/routes/rest/globals/findOne.ts b/packages/next/src/routes/rest/globals/findOne.ts index 115200f90e9..7ee4670161e 100644 --- a/packages/next/src/routes/rest/globals/findOne.ts +++ b/packages/next/src/routes/rest/globals/findOne.ts @@ -5,6 +5,7 @@ import { isNumber } from 'payload/shared' import type { GlobalRouteHandler } from '../types.js' import { headersWithCors } from '../../../utilities/headersWithCors.js' +import { sanitizePopulate } from '../utilities/sanitizePopulate.js' import { sanitizeSelect } from '../utilities/sanitizeSelect.js' export const findOne: GlobalRouteHandler = async ({ globalConfig, req }) => { @@ -16,6 +17,7 @@ export const findOne: GlobalRouteHandler = async ({ globalConfig, req }) => { depth: isNumber(depth) ? Number(depth) : undefined, draft: searchParams.get('draft') === 'true', globalConfig, + populate: sanitizePopulate(req.query.populate), req, select: sanitizeSelect(req.query.select), }) diff --git a/packages/next/src/routes/rest/globals/findVersionByID.ts b/packages/next/src/routes/rest/globals/findVersionByID.ts index 8fd3fd77352..e1c7f58d628 100644 --- a/packages/next/src/routes/rest/globals/findVersionByID.ts +++ b/packages/next/src/routes/rest/globals/findVersionByID.ts @@ -5,6 +5,7 @@ import { isNumber } from 'payload/shared' import type { GlobalRouteHandlerWithID } from '../types.js' import { headersWithCors } from '../../../utilities/headersWithCors.js' +import { sanitizePopulate } from '../utilities/sanitizePopulate.js' import { sanitizeSelect } from '../utilities/sanitizeSelect.js' export const findVersionByID: GlobalRouteHandlerWithID = async ({ id, globalConfig, req }) => { @@ -15,6 +16,7 @@ export const findVersionByID: GlobalRouteHandlerWithID = async ({ id, globalConf id, depth: isNumber(depth) ? Number(depth) : undefined, globalConfig, + populate: sanitizePopulate(req.query.populate), req, select: sanitizeSelect(req.query.select), }) diff --git a/packages/next/src/routes/rest/globals/findVersions.ts b/packages/next/src/routes/rest/globals/findVersions.ts index 095cf99d3f2..7a2ede4bce0 100644 --- a/packages/next/src/routes/rest/globals/findVersions.ts +++ b/packages/next/src/routes/rest/globals/findVersions.ts @@ -7,13 +7,15 @@ import { isNumber } from 'payload/shared' import type { GlobalRouteHandler } from '../types.js' import { headersWithCors } from '../../../utilities/headersWithCors.js' +import { sanitizePopulate } from '../utilities/sanitizePopulate.js' import { sanitizeSelect } from '../utilities/sanitizeSelect.js' export const findVersions: GlobalRouteHandler = async ({ globalConfig, req }) => { - const { depth, limit, page, select, sort, where } = req.query as { + const { depth, limit, page, populate, select, sort, where } = req.query as { depth?: string limit?: string page?: string + populate?: Record select?: Record sort?: string where?: Where @@ -24,6 +26,7 @@ export const findVersions: GlobalRouteHandler = async ({ globalConfig, req }) => globalConfig, limit: isNumber(limit) ? Number(limit) : undefined, page: isNumber(page) ? Number(page) : undefined, + populate: sanitizePopulate(populate), req, select: sanitizeSelect(select), sort: typeof sort === 'string' ? sort.split(',') : undefined, diff --git a/packages/next/src/routes/rest/globals/restoreVersion.ts b/packages/next/src/routes/rest/globals/restoreVersion.ts index 04ac3aa3702..c2e2672b744 100644 --- a/packages/next/src/routes/rest/globals/restoreVersion.ts +++ b/packages/next/src/routes/rest/globals/restoreVersion.ts @@ -5,6 +5,7 @@ import { isNumber } from 'payload/shared' import type { GlobalRouteHandlerWithID } from '../types.js' import { headersWithCors } from '../../../utilities/headersWithCors.js' +import { sanitizePopulate } from '../utilities/sanitizePopulate.js' export const restoreVersion: GlobalRouteHandlerWithID = async ({ id, globalConfig, req }) => { const { searchParams } = req @@ -16,6 +17,7 @@ export const restoreVersion: GlobalRouteHandlerWithID = async ({ id, globalConfi depth: isNumber(depth) ? Number(depth) : undefined, draft: draft === 'true' ? true : undefined, globalConfig, + populate: sanitizePopulate(req.query.populate), req, }) diff --git a/packages/next/src/routes/rest/globals/update.ts b/packages/next/src/routes/rest/globals/update.ts index 5007de78a16..0b9c306a8cc 100644 --- a/packages/next/src/routes/rest/globals/update.ts +++ b/packages/next/src/routes/rest/globals/update.ts @@ -5,6 +5,7 @@ import { isNumber } from 'payload/shared' import type { GlobalRouteHandler } from '../types.js' import { headersWithCors } from '../../../utilities/headersWithCors.js' +import { sanitizePopulate } from '../utilities/sanitizePopulate.js' import { sanitizeSelect } from '../utilities/sanitizeSelect.js' export const update: GlobalRouteHandler = async ({ globalConfig, req }) => { @@ -21,6 +22,7 @@ export const update: GlobalRouteHandler = async ({ globalConfig, req }) => { depth: isNumber(depth) ? Number(depth) : undefined, draft, globalConfig, + populate: sanitizePopulate(req.query.populate), publishSpecificLocale, req, select: sanitizeSelect(req.query.select), diff --git a/packages/next/src/routes/rest/utilities/sanitizePopulate.ts b/packages/next/src/routes/rest/utilities/sanitizePopulate.ts new file mode 100644 index 00000000000..0bdcf180304 --- /dev/null +++ b/packages/next/src/routes/rest/utilities/sanitizePopulate.ts @@ -0,0 +1,15 @@ +import type { PopulateType } from 'payload' + +import { sanitizeSelect } from './sanitizeSelect.js' + +export const sanitizePopulate = (unsanitizedPopulate: unknown): PopulateType | undefined => { + if (!unsanitizedPopulate || typeof unsanitizedPopulate !== 'object') { + return + } + + for (const k in unsanitizedPopulate) { + unsanitizedPopulate[k] = sanitizeSelect(unsanitizedPopulate[k]) + } + + return unsanitizedPopulate as PopulateType +} diff --git a/packages/payload/src/admin/RichText.ts b/packages/payload/src/admin/RichText.ts index 79b276218ae..bb03c692c65 100644 --- a/packages/payload/src/admin/RichText.ts +++ b/packages/payload/src/admin/RichText.ts @@ -13,7 +13,7 @@ import type { } from '../fields/config/types.js' import type { SanitizedGlobalConfig } from '../globals/config/types.js' import type { RequestContext } from '../index.js' -import type { JsonObject, Payload, PayloadRequest } from '../types/index.js' +import type { JsonObject, Payload, PayloadRequest, PopulateType } from '../types/index.js' import type { RichTextFieldClientProps } from './fields/RichText.js' import type { CreateMappedComponent } from './types.js' @@ -29,7 +29,6 @@ export type AfterReadRichTextHookArgs< draft?: boolean fallbackLocale?: string - fieldPromises?: Promise[] /** Boolean to denote if this hook is running against finding one, or finding many within the afterRead hook. */ @@ -44,6 +43,8 @@ export type AfterReadRichTextHookArgs< overrideAccess?: boolean + populate?: PopulateType + populationPromises?: Promise[] showHiddenFields?: boolean triggerAccessControl?: boolean @@ -225,6 +226,7 @@ type RichTextAdapterBase< findMany: boolean flattenLocales: boolean overrideAccess?: boolean + populateArg?: PopulateType populationPromises: Promise[] req: PayloadRequest showHiddenFields: boolean diff --git a/packages/payload/src/collections/operations/create.ts b/packages/payload/src/collections/operations/create.ts index ede23e3316f..574d3e2c6dd 100644 --- a/packages/payload/src/collections/operations/create.ts +++ b/packages/payload/src/collections/operations/create.ts @@ -4,6 +4,7 @@ import type { CollectionSlug, JsonObject } from '../../index.js' import type { Document, PayloadRequest, + PopulateType, SelectType, TransformCollectionWithSelect, } from '../../types/index.js' @@ -44,6 +45,7 @@ export type Arguments = { draft?: boolean overrideAccess?: boolean overwriteExistingFiles?: boolean + populate?: PopulateType req: PayloadRequest select?: SelectType showHiddenFields?: boolean @@ -97,11 +99,12 @@ export const createOperation = async < draft = false, overrideAccess, overwriteExistingFiles = false, + populate, req: { fallbackLocale, locale, payload, - payload: { config, email }, + payload: { config }, }, req, select, @@ -304,6 +307,7 @@ export const createOperation = async < global: null, locale, overrideAccess, + populate, req, select, showHiddenFields, diff --git a/packages/payload/src/collections/operations/delete.ts b/packages/payload/src/collections/operations/delete.ts index 569a7f635cd..90b2dc01775 100644 --- a/packages/payload/src/collections/operations/delete.ts +++ b/packages/payload/src/collections/operations/delete.ts @@ -2,7 +2,7 @@ import httpStatus from 'http-status' import type { AccessResult } from '../../config/types.js' import type { CollectionSlug } from '../../index.js' -import type { PayloadRequest, SelectType, Where } from '../../types/index.js' +import type { PayloadRequest, PopulateType, SelectType, Where } from '../../types/index.js' import type { BeforeOperationHook, BulkOperationResult, @@ -31,6 +31,7 @@ export type Arguments = { disableTransaction?: boolean overrideAccess?: boolean overrideLock?: boolean + populate?: PopulateType req: PayloadRequest select?: SelectType showHiddenFields?: boolean @@ -72,6 +73,7 @@ export const deleteOperation = async < depth, overrideAccess, overrideLock, + populate, req: { fallbackLocale, locale, @@ -203,6 +205,7 @@ export const deleteOperation = async < global: null, locale, overrideAccess, + populate, req, select, showHiddenFields, diff --git a/packages/payload/src/collections/operations/deleteByID.ts b/packages/payload/src/collections/operations/deleteByID.ts index 25be137b7ea..83b4fa1bef6 100644 --- a/packages/payload/src/collections/operations/deleteByID.ts +++ b/packages/payload/src/collections/operations/deleteByID.ts @@ -1,6 +1,7 @@ import type { CollectionSlug } from '../../index.js' import type { PayloadRequest, + PopulateType, SelectType, TransformCollectionWithSelect, } from '../../types/index.js' @@ -27,6 +28,7 @@ export type Arguments = { id: number | string overrideAccess?: boolean overrideLock?: boolean + populate?: PopulateType req: PayloadRequest select?: SelectType showHiddenFields?: boolean @@ -66,6 +68,7 @@ export const deleteByIDOperation = async ( depth, disableErrors, overrideAccess, + populate, req: { fallbackLocale, locale, payload }, req, select, @@ -121,6 +123,7 @@ export const findVersionByIDOperation = async ( global: null, locale, overrideAccess, + populate, req, select: typeof select?.version === 'object' ? select.version : undefined, showHiddenFields, diff --git a/packages/payload/src/collections/operations/findVersions.ts b/packages/payload/src/collections/operations/findVersions.ts index beef8e9ca84..0993131ee24 100644 --- a/packages/payload/src/collections/operations/findVersions.ts +++ b/packages/payload/src/collections/operations/findVersions.ts @@ -1,5 +1,5 @@ import type { PaginatedDocs } from '../../database/types.js' -import type { PayloadRequest, SelectType, Sort, Where } from '../../types/index.js' +import type { PayloadRequest, PopulateType, SelectType, Sort, Where } from '../../types/index.js' import type { TypeWithVersion } from '../../versions/types.js' import type { Collection } from '../config/types.js' @@ -18,6 +18,7 @@ export type Arguments = { overrideAccess?: boolean page?: number pagination?: boolean + populate?: PopulateType req?: PayloadRequest select?: SelectType showHiddenFields?: boolean @@ -35,6 +36,7 @@ export const findVersionsOperation = async overrideAccess, page, pagination = true, + populate, req: { fallbackLocale, locale, payload }, req, select, @@ -129,6 +131,7 @@ export const findVersionsOperation = async global: null, locale, overrideAccess, + populate, req, select: typeof select?.version === 'object' ? select.version : undefined, showHiddenFields, diff --git a/packages/payload/src/collections/operations/local/create.ts b/packages/payload/src/collections/operations/local/create.ts index 9e14fd97a40..6043928f8e4 100644 --- a/packages/payload/src/collections/operations/local/create.ts +++ b/packages/payload/src/collections/operations/local/create.ts @@ -2,6 +2,7 @@ import type { CollectionSlug, Payload, RequestContext, TypedLocale } from '../.. import type { Document, PayloadRequest, + PopulateType, SelectType, TransformCollectionWithSelect, } from '../../../types/index.js' @@ -33,6 +34,7 @@ export type Options = locale?: TypedLocale overrideAccess?: boolean overwriteExistingFiles?: boolean + populate?: PopulateType req?: PayloadRequest select?: TSelect showHiddenFields?: boolean @@ -58,6 +60,7 @@ export default async function createLocal< filePath, overrideAccess = true, overwriteExistingFiles = false, + populate, select, showHiddenFields, } = options @@ -81,6 +84,7 @@ export default async function createLocal< draft, overrideAccess, overwriteExistingFiles, + populate, req, select, showHiddenFields, diff --git a/packages/payload/src/collections/operations/local/delete.ts b/packages/payload/src/collections/operations/local/delete.ts index c82a75e5b1c..729dcde0c40 100644 --- a/packages/payload/src/collections/operations/local/delete.ts +++ b/packages/payload/src/collections/operations/local/delete.ts @@ -2,6 +2,7 @@ import type { CollectionSlug, Payload, RequestContext, TypedLocale } from '../.. import type { Document, PayloadRequest, + PopulateType, SelectType, TransformCollectionWithSelect, Where, @@ -25,6 +26,7 @@ export type BaseOptions = id: number | string locale?: TypedLocale overrideAccess?: boolean + populate?: PopulateType req?: PayloadRequest select?: TSelect showHiddenFields?: boolean @@ -45,6 +47,7 @@ export async function duplicate< disableTransaction, draft, overrideAccess = true, + populate, select, showHiddenFields, } = options @@ -72,6 +75,7 @@ export async function duplicate< disableTransaction, draft, overrideAccess, + populate, req, select, showHiddenFields, diff --git a/packages/payload/src/collections/operations/local/find.ts b/packages/payload/src/collections/operations/local/find.ts index 93cbdc1390c..ce18b599e5f 100644 --- a/packages/payload/src/collections/operations/local/find.ts +++ b/packages/payload/src/collections/operations/local/find.ts @@ -9,6 +9,7 @@ import type { import type { Document, PayloadRequest, + PopulateType, SelectType, Sort, TransformCollectionWithSelect, @@ -38,6 +39,7 @@ export type Options = overrideAccess?: boolean page?: number pagination?: boolean + populate?: PopulateType req?: PayloadRequest select?: TSelect showHiddenFields?: boolean diff --git a/packages/payload/src/collections/operations/local/findByID.ts b/packages/payload/src/collections/operations/local/findByID.ts index c50b1001acd..d7ac4d90789 100644 --- a/packages/payload/src/collections/operations/local/findByID.ts +++ b/packages/payload/src/collections/operations/local/findByID.ts @@ -11,6 +11,7 @@ import type { ApplyDisableErrors, Document, PayloadRequest, + PopulateType, TransformCollectionWithSelect, } from '../../../types/index.js' import type { SelectFromCollectionSlug } from '../../config/types.js' @@ -39,6 +40,7 @@ export type Options< joins?: JoinQuery locale?: 'all' | TypedLocale overrideAccess?: boolean + populate?: PopulateType req?: PayloadRequest select?: TSelect showHiddenFields?: boolean @@ -63,6 +65,7 @@ export default async function findByIDLocal< includeLockStatus, joins, overrideAccess = true, + populate, select, showHiddenFields, } = options @@ -85,6 +88,7 @@ export default async function findByIDLocal< includeLockStatus, joins, overrideAccess, + populate, req: await createLocalReq(options, payload), select, showHiddenFields, diff --git a/packages/payload/src/collections/operations/local/findVersionByID.ts b/packages/payload/src/collections/operations/local/findVersionByID.ts index ee2928191d4..61057ad1538 100644 --- a/packages/payload/src/collections/operations/local/findVersionByID.ts +++ b/packages/payload/src/collections/operations/local/findVersionByID.ts @@ -1,5 +1,5 @@ import type { CollectionSlug, Payload, RequestContext, TypedLocale } from '../../../index.js' -import type { Document, PayloadRequest, SelectType } from '../../../types/index.js' +import type { Document, PayloadRequest, PopulateType, SelectType } from '../../../types/index.js' import type { TypeWithVersion } from '../../../versions/types.js' import type { DataFromCollectionSlug } from '../../config/types.js' @@ -20,6 +20,7 @@ export type Options = { id: string locale?: 'all' | TypedLocale overrideAccess?: boolean + populate?: PopulateType req?: PayloadRequest select?: SelectType showHiddenFields?: boolean @@ -36,6 +37,7 @@ export default async function findVersionByIDLocal depth, disableErrors = false, overrideAccess = true, + populate, select, showHiddenFields, } = options @@ -56,6 +58,7 @@ export default async function findVersionByIDLocal depth, disableErrors, overrideAccess, + populate, req: await createLocalReq(options, payload), select, showHiddenFields, diff --git a/packages/payload/src/collections/operations/local/findVersions.ts b/packages/payload/src/collections/operations/local/findVersions.ts index 68bf2c68dd7..1b5e1d71d47 100644 --- a/packages/payload/src/collections/operations/local/findVersions.ts +++ b/packages/payload/src/collections/operations/local/findVersions.ts @@ -1,6 +1,13 @@ import type { PaginatedDocs } from '../../../database/types.js' import type { CollectionSlug, Payload, RequestContext, TypedLocale } from '../../../index.js' -import type { Document, PayloadRequest, SelectType, Sort, Where } from '../../../types/index.js' +import type { + Document, + PayloadRequest, + PopulateType, + SelectType, + Sort, + Where, +} from '../../../types/index.js' import type { TypeWithVersion } from '../../../versions/types.js' import type { DataFromCollectionSlug } from '../../config/types.js' @@ -21,6 +28,7 @@ export type Options = { locale?: 'all' | TypedLocale overrideAccess?: boolean page?: number + populate?: PopulateType req?: PayloadRequest select?: SelectType showHiddenFields?: boolean @@ -39,6 +47,7 @@ export default async function findVersionsLocal( limit, overrideAccess = true, page, + populate, select, showHiddenFields, sort, @@ -59,6 +68,7 @@ export default async function findVersionsLocal( limit, overrideAccess, page, + populate, req: await createLocalReq(options, payload), select, showHiddenFields, diff --git a/packages/payload/src/collections/operations/local/restoreVersion.ts b/packages/payload/src/collections/operations/local/restoreVersion.ts index 33e24d727fe..83a47d2f0f1 100644 --- a/packages/payload/src/collections/operations/local/restoreVersion.ts +++ b/packages/payload/src/collections/operations/local/restoreVersion.ts @@ -1,5 +1,5 @@ import type { CollectionSlug, Payload, RequestContext, TypedLocale } from '../../../index.js' -import type { Document, PayloadRequest, SelectType } from '../../../types/index.js' +import type { Document, PayloadRequest, PopulateType, SelectType } from '../../../types/index.js' import type { DataFromCollectionSlug } from '../../config/types.js' import { APIError } from '../../../errors/index.js' @@ -18,6 +18,7 @@ export type Options = { id: string locale?: TypedLocale overrideAccess?: boolean + populate?: PopulateType req?: PayloadRequest select?: SelectType showHiddenFields?: boolean @@ -33,6 +34,7 @@ export default async function restoreVersionLocal( collection: collectionSlug, depth, overrideAccess = true, + populate, select, showHiddenFields, } = options @@ -53,6 +55,7 @@ export default async function restoreVersionLocal( depth, overrideAccess, payload, + populate, req: await createLocalReq(options, payload), select, showHiddenFields, diff --git a/packages/payload/src/collections/operations/local/update.ts b/packages/payload/src/collections/operations/local/update.ts index 218477e44fc..8909543cd02 100644 --- a/packages/payload/src/collections/operations/local/update.ts +++ b/packages/payload/src/collections/operations/local/update.ts @@ -4,6 +4,7 @@ import type { CollectionSlug, Payload, RequestContext, TypedLocale } from '../.. import type { Document, PayloadRequest, + PopulateType, SelectType, TransformCollectionWithSelect, Where, @@ -39,6 +40,7 @@ export type BaseOptions( depth, draft, overrideAccess = false, + populate, req, req: { fallbackLocale, locale, payload }, select, @@ -152,6 +154,7 @@ export const restoreVersionOperation = async ( global: null, locale, overrideAccess, + populate, req, select, showHiddenFields, diff --git a/packages/payload/src/collections/operations/update.ts b/packages/payload/src/collections/operations/update.ts index 993fe84ab63..9447f09c7fd 100644 --- a/packages/payload/src/collections/operations/update.ts +++ b/packages/payload/src/collections/operations/update.ts @@ -4,7 +4,7 @@ import httpStatus from 'http-status' import type { AccessResult } from '../../config/types.js' import type { CollectionSlug } from '../../index.js' -import type { PayloadRequest, SelectType, Where } from '../../types/index.js' +import type { PayloadRequest, PopulateType, SelectType, Where } from '../../types/index.js' import type { BulkOperationResult, Collection, @@ -46,6 +46,7 @@ export type Arguments = { overrideAccess?: boolean overrideLock?: boolean overwriteExistingFiles?: boolean + populate?: PopulateType req: PayloadRequest select?: SelectType showHiddenFields?: boolean @@ -89,6 +90,7 @@ export const updateOperation = async < overrideAccess, overrideLock, overwriteExistingFiles = false, + populate, req: { fallbackLocale, locale, @@ -361,6 +363,7 @@ export const updateOperation = async < global: null, locale, overrideAccess, + populate, req, select, showHiddenFields, diff --git a/packages/payload/src/collections/operations/updateByID.ts b/packages/payload/src/collections/operations/updateByID.ts index 5b4a32c0cf2..b0cd080368b 100644 --- a/packages/payload/src/collections/operations/updateByID.ts +++ b/packages/payload/src/collections/operations/updateByID.ts @@ -7,6 +7,7 @@ import type { Args } from '../../fields/hooks/beforeChange/index.js' import type { CollectionSlug } from '../../index.js' import type { PayloadRequest, + PopulateType, SelectType, TransformCollectionWithSelect, } from '../../types/index.js' @@ -51,6 +52,7 @@ export type Arguments = { overrideAccess?: boolean overrideLock?: boolean overwriteExistingFiles?: boolean + populate?: PopulateType publishSpecificLocale?: string req: PayloadRequest select?: SelectType @@ -99,6 +101,7 @@ export const updateByIDOperation = async < overrideAccess, overrideLock, overwriteExistingFiles = false, + populate, publishSpecificLocale, req: { fallbackLocale, @@ -392,6 +395,7 @@ export const updateByIDOperation = async < global: null, locale, overrideAccess, + populate, req, select, showHiddenFields, diff --git a/packages/payload/src/fields/hooks/afterRead/index.ts b/packages/payload/src/fields/hooks/afterRead/index.ts index cc02f1e9758..177a499ebce 100644 --- a/packages/payload/src/fields/hooks/afterRead/index.ts +++ b/packages/payload/src/fields/hooks/afterRead/index.ts @@ -1,7 +1,7 @@ import type { SanitizedCollectionConfig } from '../../../collections/config/types.js' import type { SanitizedGlobalConfig } from '../../../globals/config/types.js' import type { RequestContext } from '../../../index.js' -import type { JsonObject, PayloadRequest, SelectType } from '../../../types/index.js' +import type { JsonObject, PayloadRequest, PopulateType, SelectType } from '../../../types/index.js' import { deepCopyObjectSimple } from '../../../utilities/deepCopyObject.js' import { getSelectMode } from '../../../utilities/getSelectMode.js' @@ -20,6 +20,7 @@ type Args = { global: null | SanitizedGlobalConfig locale: string overrideAccess: boolean + populate?: PopulateType req: PayloadRequest select?: SelectType showHiddenFields: boolean @@ -49,6 +50,7 @@ export async function afterRead(args: Args): Promise global, locale, overrideAccess, + populate, req, select, showHiddenFields, @@ -84,6 +86,7 @@ export async function afterRead(args: Args): Promise locale, overrideAccess, path: [], + populate, populationPromises, req, schemaPath: [], diff --git a/packages/payload/src/fields/hooks/afterRead/promise.ts b/packages/payload/src/fields/hooks/afterRead/promise.ts index 604784ffe7d..4614ca12758 100644 --- a/packages/payload/src/fields/hooks/afterRead/promise.ts +++ b/packages/payload/src/fields/hooks/afterRead/promise.ts @@ -2,7 +2,13 @@ import type { RichTextAdapter } from '../../../admin/RichText.js' import type { SanitizedCollectionConfig } from '../../../collections/config/types.js' import type { SanitizedGlobalConfig } from '../../../globals/config/types.js' import type { RequestContext } from '../../../index.js' -import type { JsonObject, PayloadRequest, SelectMode, SelectType } from '../../../types/index.js' +import type { + JsonObject, + PayloadRequest, + PopulateType, + SelectMode, + SelectType, +} from '../../../types/index.js' import type { Field, TabAsField } from '../../config/types.js' import { MissingEditorProp } from '../../../errors/index.js' @@ -38,6 +44,7 @@ type Args = { * The parent's schemaPath (path without indexes). */ parentSchemaPath: string[] + populate?: PopulateType populationPromises: Promise[] req: PayloadRequest select?: SelectType @@ -73,6 +80,7 @@ export const promise = async ({ overrideAccess, parentPath, parentSchemaPath, + populate, populationPromises, req, select, @@ -323,6 +331,7 @@ export const promise = async ({ field, locale, overrideAccess, + populate, req, showHiddenFields, siblingDoc, @@ -356,6 +365,7 @@ export const promise = async ({ locale, overrideAccess, path: fieldPath, + populate, populationPromises, req, schemaPath: fieldSchemaPath, @@ -397,6 +407,7 @@ export const promise = async ({ locale, overrideAccess, path: [...fieldPath, i], + populate, populationPromises, req, schemaPath: fieldSchemaPath, @@ -428,6 +439,7 @@ export const promise = async ({ locale, overrideAccess, path: [...fieldPath, i], + populate, populationPromises, req, schemaPath: fieldSchemaPath, @@ -497,6 +509,7 @@ export const promise = async ({ locale, overrideAccess, path: [...fieldPath, i], + populate, populationPromises, req, schemaPath: fieldSchemaPath, @@ -534,6 +547,7 @@ export const promise = async ({ locale, overrideAccess, path: [...fieldPath, i], + populate, populationPromises, req, schemaPath: fieldSchemaPath, @@ -571,6 +585,7 @@ export const promise = async ({ locale, overrideAccess, path: fieldPath, + populate, populationPromises, req, schemaPath: fieldSchemaPath, @@ -617,6 +632,7 @@ export const promise = async ({ locale, overrideAccess, path: fieldPath, + populate, populationPromises, req, schemaPath: fieldSchemaPath, @@ -648,6 +664,7 @@ export const promise = async ({ locale, overrideAccess, path: fieldPath, + populate, populationPromises, req, schemaPath: fieldSchemaPath, @@ -701,6 +718,7 @@ export const promise = async ({ originalDoc: doc, overrideAccess, path: fieldPath, + populate, populationPromises, req, schemaPath: fieldSchemaPath, @@ -737,6 +755,7 @@ export const promise = async ({ originalDoc: doc, overrideAccess, path: fieldPath, + populate, populationPromises, req, schemaPath: fieldSchemaPath, diff --git a/packages/payload/src/fields/hooks/afterRead/relationshipPopulationPromise.ts b/packages/payload/src/fields/hooks/afterRead/relationshipPopulationPromise.ts index 1c11a2f3d5b..22a0ebae781 100644 --- a/packages/payload/src/fields/hooks/afterRead/relationshipPopulationPromise.ts +++ b/packages/payload/src/fields/hooks/afterRead/relationshipPopulationPromise.ts @@ -1,4 +1,4 @@ -import type { PayloadRequest } from '../../../types/index.js' +import type { PayloadRequest, PopulateType } from '../../../types/index.js' import type { JoinField, RelationshipField, UploadField } from '../../config/types.js' import { createDataloaderCacheKey } from '../../../collections/dataloader.js' @@ -16,6 +16,7 @@ type PopulateArgs = { key?: string locale: null | string overrideAccess: boolean + populateArg?: PopulateType req: PayloadRequest showHiddenFields: boolean } @@ -32,6 +33,7 @@ const populate = async ({ key, locale, overrideAccess, + populateArg, req, showHiddenFields, }: PopulateArgs) => { @@ -69,7 +71,9 @@ const populate = async ({ fallbackLocale, locale, overrideAccess, - select: relatedCollection.config.defaultPopulate, + select: + populateArg?.[relatedCollection.config.slug] ?? + relatedCollection.config.defaultPopulate, showHiddenFields, transactionID: req.transactionID, }), @@ -110,6 +114,7 @@ type PromiseArgs = { field: JoinField | RelationshipField | UploadField locale: null | string overrideAccess: boolean + populate?: PopulateType req: PayloadRequest showHiddenFields: boolean siblingDoc: Record @@ -123,6 +128,7 @@ export const relationshipPopulationPromise = async ({ field, locale, overrideAccess, + populate: populateArg, req, showHiddenFields, siblingDoc, @@ -154,6 +160,7 @@ export const relationshipPopulationPromise = async ({ key: localeKey, locale, overrideAccess, + populateArg, req, showHiddenFields, }) @@ -183,6 +190,7 @@ export const relationshipPopulationPromise = async ({ index, locale, overrideAccess, + populateArg, req, showHiddenFields, }) @@ -211,6 +219,7 @@ export const relationshipPopulationPromise = async ({ key: localeKey, locale, overrideAccess, + populateArg, req, showHiddenFields, }) @@ -230,6 +239,7 @@ export const relationshipPopulationPromise = async ({ field, locale, overrideAccess, + populateArg, req, showHiddenFields, }) diff --git a/packages/payload/src/fields/hooks/afterRead/traverseFields.ts b/packages/payload/src/fields/hooks/afterRead/traverseFields.ts index e89d467eb32..1ffe4840ddf 100644 --- a/packages/payload/src/fields/hooks/afterRead/traverseFields.ts +++ b/packages/payload/src/fields/hooks/afterRead/traverseFields.ts @@ -1,7 +1,13 @@ import type { SanitizedCollectionConfig } from '../../../collections/config/types.js' import type { SanitizedGlobalConfig } from '../../../globals/config/types.js' import type { RequestContext } from '../../../index.js' -import type { JsonObject, PayloadRequest, SelectMode, SelectType } from '../../../types/index.js' +import type { + JsonObject, + PayloadRequest, + PopulateType, + SelectMode, + SelectType, +} from '../../../types/index.js' import type { Field, TabAsField } from '../../config/types.js' import { promise } from './promise.js' @@ -25,6 +31,7 @@ type Args = { locale: null | string overrideAccess: boolean path: (number | string)[] + populate?: PopulateType populationPromises: Promise[] req: PayloadRequest schemaPath: string[] @@ -52,6 +59,7 @@ export const traverseFields = ({ locale, overrideAccess, path, + populate, populationPromises, req, schemaPath, @@ -81,6 +89,7 @@ export const traverseFields = ({ overrideAccess, parentPath: path, parentSchemaPath: schemaPath, + populate, populationPromises, req, select, diff --git a/packages/payload/src/globals/operations/findOne.ts b/packages/payload/src/globals/operations/findOne.ts index 76e28792b69..542daf7de47 100644 --- a/packages/payload/src/globals/operations/findOne.ts +++ b/packages/payload/src/globals/operations/findOne.ts @@ -1,5 +1,5 @@ import type { AccessResult } from '../../config/types.js' -import type { PayloadRequest, SelectType, Where } from '../../types/index.js' +import type { PayloadRequest, PopulateType, SelectType, Where } from '../../types/index.js' import type { SanitizedGlobalConfig } from '../config/types.js' import executeAccess from '../../auth/executeAccess.js' @@ -14,6 +14,7 @@ type Args = { globalConfig: SanitizedGlobalConfig includeLockStatus?: boolean overrideAccess?: boolean + populate?: PopulateType req: PayloadRequest select?: SelectType showHiddenFields?: boolean @@ -30,6 +31,7 @@ export const findOneOperation = async >( globalConfig, includeLockStatus, overrideAccess = false, + populate, req: { fallbackLocale, locale }, req, select, @@ -169,6 +171,7 @@ export const findOneOperation = async >( global: globalConfig, locale, overrideAccess, + populate, req, select, showHiddenFields, diff --git a/packages/payload/src/globals/operations/findVersionByID.ts b/packages/payload/src/globals/operations/findVersionByID.ts index 31dedd829e4..3c3bf3ea362 100644 --- a/packages/payload/src/globals/operations/findVersionByID.ts +++ b/packages/payload/src/globals/operations/findVersionByID.ts @@ -1,5 +1,5 @@ import type { FindGlobalVersionsArgs } from '../../database/types.js' -import type { PayloadRequest, SelectType } from '../../types/index.js' +import type { PayloadRequest, PopulateType, SelectType } from '../../types/index.js' import type { TypeWithVersion } from '../../versions/types.js' import type { SanitizedGlobalConfig } from '../config/types.js' @@ -8,7 +8,6 @@ import { combineQueries } from '../../database/combineQueries.js' import { Forbidden, NotFound } from '../../errors/index.js' import { afterRead } from '../../fields/hooks/afterRead/index.js' import { deepCopyObjectSimple } from '../../utilities/deepCopyObject.js' -import { getSelectMode } from '../../utilities/getSelectMode.js' import { killTransaction } from '../../utilities/killTransaction.js' export type Arguments = { @@ -18,6 +17,7 @@ export type Arguments = { globalConfig: SanitizedGlobalConfig id: number | string overrideAccess?: boolean + populate?: PopulateType req: PayloadRequest select?: SelectType showHiddenFields?: boolean @@ -33,6 +33,7 @@ export const findVersionByIDOperation = async = an disableErrors, globalConfig, overrideAccess, + populate, req: { fallbackLocale, locale, payload }, req, select, @@ -123,6 +124,7 @@ export const findVersionByIDOperation = async = an global: globalConfig, locale, overrideAccess, + populate, req, select: typeof select?.version === 'object' ? select.version : undefined, showHiddenFields, diff --git a/packages/payload/src/globals/operations/findVersions.ts b/packages/payload/src/globals/operations/findVersions.ts index aa2018cc620..f36f1c95b04 100644 --- a/packages/payload/src/globals/operations/findVersions.ts +++ b/packages/payload/src/globals/operations/findVersions.ts @@ -1,5 +1,5 @@ import type { PaginatedDocs } from '../../database/types.js' -import type { PayloadRequest, SelectType, Sort, Where } from '../../types/index.js' +import type { PayloadRequest, PopulateType, SelectType, Sort, Where } from '../../types/index.js' import type { TypeWithVersion } from '../../versions/types.js' import type { SanitizedGlobalConfig } from '../config/types.js' @@ -18,6 +18,7 @@ export type Arguments = { overrideAccess?: boolean page?: number pagination?: boolean + populate?: PopulateType req?: PayloadRequest select?: SelectType showHiddenFields?: boolean @@ -35,6 +36,7 @@ export const findVersionsOperation = async >( overrideAccess, page, pagination = true, + populate, req: { fallbackLocale, locale, payload }, req, select, @@ -105,6 +107,7 @@ export const findVersionsOperation = async >( global: globalConfig, locale, overrideAccess, + populate, req, select, showHiddenFields, diff --git a/packages/payload/src/globals/operations/local/findOne.ts b/packages/payload/src/globals/operations/local/findOne.ts index 1538de6063c..0676385a6f7 100644 --- a/packages/payload/src/globals/operations/local/findOne.ts +++ b/packages/payload/src/globals/operations/local/findOne.ts @@ -2,6 +2,7 @@ import type { GlobalSlug, Payload, RequestContext, TypedLocale } from '../../../ import type { Document, PayloadRequest, + PopulateType, SelectType, TransformGlobalWithSelect, } from '../../../types/index.js' @@ -19,6 +20,7 @@ export type Options = { includeLockStatus?: boolean locale?: 'all' | TypedLocale overrideAccess?: boolean + populate?: PopulateType req?: PayloadRequest select?: TSelect showHiddenFields?: boolean @@ -39,6 +41,7 @@ export default async function findOneLocal< draft = false, includeLockStatus, overrideAccess = true, + populate, select, showHiddenFields, } = options @@ -56,6 +59,7 @@ export default async function findOneLocal< globalConfig, includeLockStatus, overrideAccess, + populate, req: await createLocalReq(options, payload), select, showHiddenFields, diff --git a/packages/payload/src/globals/operations/local/findVersionByID.ts b/packages/payload/src/globals/operations/local/findVersionByID.ts index 236b5188a2a..df76db573a6 100644 --- a/packages/payload/src/globals/operations/local/findVersionByID.ts +++ b/packages/payload/src/globals/operations/local/findVersionByID.ts @@ -1,5 +1,5 @@ import type { GlobalSlug, Payload, RequestContext, TypedLocale } from '../../../index.js' -import type { Document, PayloadRequest, SelectType } from '../../../types/index.js' +import type { Document, PayloadRequest, PopulateType, SelectType } from '../../../types/index.js' import type { TypeWithVersion } from '../../../versions/types.js' import type { DataFromGlobalSlug } from '../../config/types.js' @@ -15,6 +15,7 @@ export type Options = { id: string locale?: 'all' | TypedLocale overrideAccess?: boolean + populate?: PopulateType req?: PayloadRequest select?: SelectType showHiddenFields?: boolean @@ -33,6 +34,7 @@ export default async function findVersionByIDLocal( depth, disableErrors = false, overrideAccess = true, + populate, select, showHiddenFields, } = options @@ -49,6 +51,7 @@ export default async function findVersionByIDLocal( disableErrors, globalConfig, overrideAccess, + populate, req: await createLocalReq(options, payload), select, showHiddenFields, diff --git a/packages/payload/src/globals/operations/local/findVersions.ts b/packages/payload/src/globals/operations/local/findVersions.ts index 61dd15072e2..042158fbb4c 100644 --- a/packages/payload/src/globals/operations/local/findVersions.ts +++ b/packages/payload/src/globals/operations/local/findVersions.ts @@ -1,7 +1,14 @@ /* eslint-disable no-restricted-exports */ import type { PaginatedDocs } from '../../../database/types.js' import type { GlobalSlug, Payload, RequestContext, TypedLocale } from '../../../index.js' -import type { Document, PayloadRequest, SelectType, Sort, Where } from '../../../types/index.js' +import type { + Document, + PayloadRequest, + PopulateType, + SelectType, + Sort, + Where, +} from '../../../types/index.js' import type { TypeWithVersion } from '../../../versions/types.js' import type { DataFromGlobalSlug } from '../../config/types.js' @@ -17,6 +24,7 @@ export type Options = { locale?: 'all' | TypedLocale overrideAccess?: boolean page?: number + populate?: PopulateType req?: PayloadRequest select?: SelectType showHiddenFields?: boolean @@ -36,6 +44,7 @@ export default async function findVersionsLocal( limit, overrideAccess = true, page, + populate, select, showHiddenFields, sort, @@ -54,6 +63,7 @@ export default async function findVersionsLocal( limit, overrideAccess, page, + populate, req: await createLocalReq(options, payload), select, showHiddenFields, diff --git a/packages/payload/src/globals/operations/local/restoreVersion.ts b/packages/payload/src/globals/operations/local/restoreVersion.ts index f9e683722f2..e2cf93e9b4d 100644 --- a/packages/payload/src/globals/operations/local/restoreVersion.ts +++ b/packages/payload/src/globals/operations/local/restoreVersion.ts @@ -1,6 +1,6 @@ /* eslint-disable no-restricted-exports */ import type { GlobalSlug, Payload, RequestContext, TypedLocale } from '../../../index.js' -import type { Document, PayloadRequest } from '../../../types/index.js' +import type { Document, PayloadRequest, PopulateType } from '../../../types/index.js' import type { DataFromGlobalSlug } from '../../config/types.js' import { APIError } from '../../../errors/index.js' @@ -14,6 +14,7 @@ export type Options = { id: string locale?: TypedLocale overrideAccess?: boolean + populate?: PopulateType req?: PayloadRequest showHiddenFields?: boolean slug: TSlug @@ -24,7 +25,7 @@ export default async function restoreVersionLocal( payload: Payload, options: Options, ): Promise> { - const { id, slug: globalSlug, depth, overrideAccess = true, showHiddenFields } = options + const { id, slug: globalSlug, depth, overrideAccess = true, populate, showHiddenFields } = options const globalConfig = payload.globals.config.find((config) => config.slug === globalSlug) @@ -37,6 +38,7 @@ export default async function restoreVersionLocal( depth, globalConfig, overrideAccess, + populate, req: await createLocalReq(options, payload), showHiddenFields, }) diff --git a/packages/payload/src/globals/operations/local/update.ts b/packages/payload/src/globals/operations/local/update.ts index 7b25843a17e..6a4378a0723 100644 --- a/packages/payload/src/globals/operations/local/update.ts +++ b/packages/payload/src/globals/operations/local/update.ts @@ -4,6 +4,7 @@ import type { GlobalSlug, Payload, RequestContext, TypedLocale } from '../../../ import type { Document, PayloadRequest, + PopulateType, SelectType, TransformGlobalWithSelect, } from '../../../types/index.js' @@ -22,6 +23,7 @@ export type Options = { locale?: TypedLocale overrideAccess?: boolean overrideLock?: boolean + populate?: PopulateType publishSpecificLocale?: TypedLocale req?: PayloadRequest select?: TSelect @@ -44,6 +46,7 @@ export default async function updateLocal< draft, overrideAccess = true, overrideLock, + populate, publishSpecificLocale, select, showHiddenFields, @@ -63,6 +66,7 @@ export default async function updateLocal< globalConfig, overrideAccess, overrideLock, + populate, publishSpecificLocale, req: await createLocalReq(options, payload), select, diff --git a/packages/payload/src/globals/operations/restoreVersion.ts b/packages/payload/src/globals/operations/restoreVersion.ts index d50d554b6a0..50c4a94ead9 100644 --- a/packages/payload/src/globals/operations/restoreVersion.ts +++ b/packages/payload/src/globals/operations/restoreVersion.ts @@ -1,4 +1,4 @@ -import type { PayloadRequest } from '../../types/index.js' +import type { PayloadRequest, PopulateType } from '../../types/index.js' import type { TypeWithVersion } from '../../versions/types.js' import type { SanitizedGlobalConfig } from '../config/types.js' @@ -16,6 +16,7 @@ export type Arguments = { globalConfig: SanitizedGlobalConfig id: number | string overrideAccess?: boolean + populate?: PopulateType req?: PayloadRequest showHiddenFields?: boolean } @@ -29,6 +30,7 @@ export const restoreVersionOperation = async = any draft, globalConfig, overrideAccess, + populate, req: { fallbackLocale, locale, payload }, req, showHiddenFields, @@ -131,6 +133,7 @@ export const restoreVersionOperation = async = any global: globalConfig, locale, overrideAccess, + populate, req, showHiddenFields, }) diff --git a/packages/payload/src/globals/operations/update.ts b/packages/payload/src/globals/operations/update.ts index e59e21eb5f2..03716507707 100644 --- a/packages/payload/src/globals/operations/update.ts +++ b/packages/payload/src/globals/operations/update.ts @@ -4,6 +4,7 @@ import type { GlobalSlug, JsonObject } from '../../index.js' import type { Operation, PayloadRequest, + PopulateType, SelectType, TransformGlobalWithSelect, Where, @@ -37,6 +38,7 @@ type Args = { globalConfig: SanitizedGlobalConfig overrideAccess?: boolean overrideLock?: boolean + populate?: PopulateType publishSpecificLocale?: string req: PayloadRequest select?: SelectType @@ -63,6 +65,7 @@ export const updateOperation = async < globalConfig, overrideAccess, overrideLock, + populate, publishSpecificLocale, req: { fallbackLocale, locale, payload }, req, @@ -307,6 +310,7 @@ export const updateOperation = async < global: globalConfig, locale, overrideAccess, + populate, req, select, showHiddenFields, diff --git a/packages/payload/src/types/index.ts b/packages/payload/src/types/index.ts index 3a5badc901d..27fb68ecbdc 100644 --- a/packages/payload/src/types/index.ts +++ b/packages/payload/src/types/index.ts @@ -13,6 +13,7 @@ import type { DataFromGlobalSlug, GlobalSlug, RequestContext, + TypedCollectionSelect, TypedLocale, TypedUser, } from '../index.js' @@ -219,3 +220,5 @@ export type TransformGlobalWithSelect< > = TSelect extends SelectType ? TransformDataWithSelect, TSelect> : DataFromGlobalSlug + +export type PopulateType = Partial diff --git a/packages/richtext-lexical/src/features/relationship/server/index.ts b/packages/richtext-lexical/src/features/relationship/server/index.ts index cde6b0e0edc..5e18901e99d 100644 --- a/packages/richtext-lexical/src/features/relationship/server/index.ts +++ b/packages/richtext-lexical/src/features/relationship/server/index.ts @@ -62,6 +62,7 @@ export const RelationshipFeature = createServerFeature< draft, node, overrideAccess, + populateArg, populationPromises, req, showHiddenFields, @@ -90,7 +91,8 @@ export const RelationshipFeature = createServerFeature< key: 'value', overrideAccess, req, - select: collection.config.defaultPopulate, + select: + populateArg?.[collection.config.slug] ?? collection.config.defaultPopulate, showHiddenFields, }), ) diff --git a/packages/richtext-lexical/src/features/typesServer.ts b/packages/richtext-lexical/src/features/typesServer.ts index 72d0288ffe3..f5b7bbdea28 100644 --- a/packages/richtext-lexical/src/features/typesServer.ts +++ b/packages/richtext-lexical/src/features/typesServer.ts @@ -15,6 +15,7 @@ import type { Payload, PayloadComponent, PayloadRequest, + PopulateType, ReplaceAny, RequestContext, RichTextField, @@ -147,6 +148,10 @@ export type AfterReadNodeHookArgs = { */ locale: string overrideAccess: boolean + /** + * Only available in `afterRead` hooks. + */ + populateArg?: PopulateType /** * Only available in `afterRead` field hooks. */ diff --git a/packages/richtext-lexical/src/features/upload/server/feature.server.ts b/packages/richtext-lexical/src/features/upload/server/feature.server.ts index d6a00bbad73..c399ddd89cc 100644 --- a/packages/richtext-lexical/src/features/upload/server/feature.server.ts +++ b/packages/richtext-lexical/src/features/upload/server/feature.server.ts @@ -232,6 +232,7 @@ export const UploadFeature = createServerFeature< draft, node, overrideAccess, + populateArg, populationPromises, req, showHiddenFields, @@ -261,7 +262,8 @@ export const UploadFeature = createServerFeature< key: 'value', overrideAccess, req, - select: collection.config.defaultPopulate, + select: + populateArg?.[collection.config.slug] ?? collection.config.defaultPopulate, showHiddenFields, }), ) diff --git a/packages/richtext-lexical/src/index.ts b/packages/richtext-lexical/src/index.ts index 75e91b5a649..42e91d2ef6c 100644 --- a/packages/richtext-lexical/src/index.ts +++ b/packages/richtext-lexical/src/index.ts @@ -313,6 +313,7 @@ export function lexicalEditor(props?: LexicalEditorProps): LexicalRichTextAdapte locale, overrideAccess, path, + populate, populationPromises, req, schemaPath, @@ -360,6 +361,7 @@ export function lexicalEditor(props?: LexicalEditorProps): LexicalRichTextAdapte overrideAccess: overrideAccess!, parentRichTextFieldPath: path, parentRichTextFieldSchemaPath: schemaPath, + populateArg: populate, populationPromises: populationPromises!, req, showHiddenFields: showHiddenFields!, @@ -394,6 +396,7 @@ export function lexicalEditor(props?: LexicalEditorProps): LexicalRichTextAdapte locale: locale!, overrideAccess: overrideAccess!, path, + populate, populationPromises: populationPromises!, req, schemaPath, diff --git a/packages/richtext-slate/src/data/recurseNestedFields.ts b/packages/richtext-slate/src/data/recurseNestedFields.ts index 349fd507eb4..cd92b5f76a9 100644 --- a/packages/richtext-slate/src/data/recurseNestedFields.ts +++ b/packages/richtext-slate/src/data/recurseNestedFields.ts @@ -1,4 +1,4 @@ -import type { Field, PayloadRequest } from 'payload' +import type { Field, PayloadRequest, PopulateType } from 'payload' import { fieldAffectsData, fieldHasSubFields, fieldIsArrayType, tabHasName } from 'payload/shared' @@ -12,6 +12,7 @@ type NestedRichTextFieldsArgs = { draft: boolean fields: Field[] overrideAccess: boolean + populateArg?: PopulateType populationPromises: Promise[] req: PayloadRequest showHiddenFields: boolean @@ -24,6 +25,7 @@ export const recurseNestedFields = ({ draft, fields, overrideAccess = false, + populateArg, populationPromises, req, showHiddenFields, @@ -48,7 +50,8 @@ export const recurseNestedFields = ({ key: i, overrideAccess, req, - select: collection.config.defaultPopulate, + select: + populateArg?.[collection.config.slug] ?? collection.config.defaultPopulate, showHiddenFields, }), ) @@ -70,7 +73,8 @@ export const recurseNestedFields = ({ key: i, overrideAccess, req, - select: collection.config.defaultPopulate, + select: + populateArg?.[collection.config.slug] ?? collection.config.defaultPopulate, showHiddenFields, }), ) @@ -96,7 +100,7 @@ export const recurseNestedFields = ({ key: 'value', overrideAccess, req, - select: collection.config.defaultPopulate, + select: populateArg?.[collection.config.slug] ?? collection.config.defaultPopulate, showHiddenFields, }), ) @@ -117,7 +121,7 @@ export const recurseNestedFields = ({ key: field.name, overrideAccess, req, - select: collection.config.defaultPopulate, + select: populateArg?.[collection.config.slug] ?? collection.config.defaultPopulate, showHiddenFields, }), ) @@ -131,6 +135,7 @@ export const recurseNestedFields = ({ draft, fields: field.fields, overrideAccess, + populateArg, populationPromises, req, showHiddenFields, @@ -143,6 +148,7 @@ export const recurseNestedFields = ({ draft, fields: field.fields, overrideAccess, + populateArg, populationPromises, req, showHiddenFields, @@ -157,6 +163,7 @@ export const recurseNestedFields = ({ draft, fields: tab.fields, overrideAccess, + populateArg, populationPromises, req, showHiddenFields, @@ -174,6 +181,7 @@ export const recurseNestedFields = ({ draft, fields: block.fields, overrideAccess, + populateArg, populationPromises, req, showHiddenFields, @@ -191,6 +199,7 @@ export const recurseNestedFields = ({ draft, fields: field.fields, overrideAccess, + populateArg, populationPromises, req, showHiddenFields, diff --git a/packages/richtext-slate/src/data/richTextRelationshipPromise.ts b/packages/richtext-slate/src/data/richTextRelationshipPromise.ts index e1bd066b850..140fb59485a 100644 --- a/packages/richtext-slate/src/data/richTextRelationshipPromise.ts +++ b/packages/richtext-slate/src/data/richTextRelationshipPromise.ts @@ -1,4 +1,10 @@ -import type { PayloadRequest, RichTextAdapter, RichTextField } from 'payload' +import type { + CollectionConfig, + PayloadRequest, + PopulateType, + RichTextAdapter, + RichTextField, +} from 'payload' import type { AdapterArguments } from '../types.js' @@ -16,6 +22,7 @@ type RecurseRichTextArgs = { draft: boolean field: RichTextField overrideAccess: boolean + populateArg?: PopulateType populationPromises: Promise[] req: PayloadRequest showHiddenFields: boolean @@ -28,6 +35,7 @@ export const recurseRichText = ({ draft, field, overrideAccess = false, + populateArg, populationPromises, req, showHiddenFields, @@ -54,7 +62,10 @@ export const recurseRichText = ({ key: 'value', overrideAccess, req, - select: collection.config.defaultPopulate, + select: + req.payloadAPI !== 'GraphQL' + ? (populateArg?.[collection.config.slug] ?? collection.config.defaultPopulate) + : undefined, showHiddenFields, }), ) @@ -70,6 +81,7 @@ export const recurseRichText = ({ draft, fields: field.admin.upload.collections[element.relationTo].fields, overrideAccess, + populateArg, populationPromises, req, showHiddenFields, @@ -94,7 +106,10 @@ export const recurseRichText = ({ key: 'value', overrideAccess, req, - select: collection.config.defaultPopulate, + select: + req.payloadAPI !== 'GraphQL' + ? (populateArg?.[collection.config.slug] ?? collection.config.defaultPopulate) + : undefined, showHiddenFields, }), ) @@ -109,6 +124,7 @@ export const recurseRichText = ({ draft, fields: field.admin?.link?.fields, overrideAccess, + populateArg, populationPromises, req, showHiddenFields, @@ -124,6 +140,7 @@ export const recurseRichText = ({ draft, field, overrideAccess, + populateArg, populationPromises, req, showHiddenFields, @@ -139,6 +156,7 @@ export const richTextRelationshipPromise = ({ draft, field, overrideAccess, + populateArg, populationPromises, req, showHiddenFields, @@ -151,6 +169,7 @@ export const richTextRelationshipPromise = ({ draft, field, overrideAccess, + populateArg, populationPromises, req, showHiddenFields, diff --git a/packages/richtext-slate/src/index.tsx b/packages/richtext-slate/src/index.tsx index 053196bc46e..c39ddc4f864 100644 --- a/packages/richtext-slate/src/index.tsx +++ b/packages/richtext-slate/src/index.tsx @@ -159,6 +159,7 @@ export function slateEditor( findMany, flattenLocales, overrideAccess, + populate, populationPromises, req, showHiddenFields, @@ -182,6 +183,7 @@ export function slateEditor( findMany, flattenLocales, overrideAccess, + populateArg: populate, populationPromises, req, showHiddenFields, diff --git a/test/helpers/NextRESTClient.ts b/test/helpers/NextRESTClient.ts index fbc89674b76..d49d11f33b2 100644 --- a/test/helpers/NextRESTClient.ts +++ b/test/helpers/NextRESTClient.ts @@ -1,4 +1,4 @@ -import type { JoinQuery, SanitizedConfig, SelectType, Where } from 'payload' +import type { JoinQuery, PopulateType, SanitizedConfig, SelectType, Where } from 'payload' import type { ParsedQs } from 'qs-esm' import { @@ -23,6 +23,7 @@ type RequestOptions = { limit?: number locale?: string page?: number + populate?: PopulateType select?: SelectType sort?: string where?: Where diff --git a/test/select/collections/Pages/index.ts b/test/select/collections/Pages/index.ts index 0f4248f7081..ee8d3c011f1 100644 --- a/test/select/collections/Pages/index.ts +++ b/test/select/collections/Pages/index.ts @@ -11,13 +11,14 @@ export const Pages: CollectionConfig<'pages'> = { defaultPopulate: { slug: true, }, + access: { read: () => true }, fields: [ { name: 'content', type: 'blocks', blocks: [ { - slug: 'cta', + slug: 'introduction', fields: [ { name: 'title', @@ -80,5 +81,9 @@ export const Pages: CollectionConfig<'pages'> = { type: 'text', required: true, }, + { + name: 'additional', + type: 'text', + }, ], } diff --git a/test/select/int.spec.ts b/test/select/int.spec.ts index 2406ae43968..1ef65779a21 100644 --- a/test/select/int.spec.ts +++ b/test/select/int.spec.ts @@ -1612,24 +1612,26 @@ describe('Select', () => { }) }) - describe('defaultPopulate', () => { + describe('populate / defaultPopulate', () => { let homePage: Page let aboutPage: Page let expectedHomePage: { id: number | string; slug: string } + let expectedHomePageOverride: { additional: string; id: number | string } beforeAll(async () => { homePage = await payload.create({ depth: 0, collection: 'pages', - data: { content: [], slug: 'home' }, + data: { content: [], slug: 'home', additional: 'additional-data' }, }) expectedHomePage = { id: homePage.id, slug: homePage.slug } + expectedHomePageOverride = { id: homePage.id, additional: homePage.additional } aboutPage = await payload.create({ depth: 0, collection: 'pages', data: { content: [ { - blockType: 'cta', + blockType: 'introduction', richTextSlate: [ { type: 'relationship', @@ -1745,6 +1747,151 @@ describe('Select', () => { expect(richTextLexicalRel.value).toMatchObject(expectedHomePage) expect(richTextSlateRel.value).toMatchObject(expectedHomePage) }) + + it('graphQL - should retrieve fields against defaultPopulate', async () => { + const query = `query { + Pages { + docs { + id, + content { + ... on Introduction { + link { + doc { + id, + additional, + slug, + } + }, + richTextLexical(depth: 1) + richTextSlate(depth: 1) + } + } + } + } + }` + + const { + data: { + Pages: { + docs: [ + { + content: [ + { + link, + richTextSlate: [richTextSlateRel], + richTextLexical: { + root: { + children: [richTextLexicalRel], + }, + }, + }, + ], + }, + ], + }, + }, + } = await restClient + .GRAPHQL_POST({ + body: JSON.stringify({ query }), + }) + .then((res) => res.json()) + + expect(link.doc).toMatchObject({ + id: homePage.id, + additional: homePage.additional, + slug: homePage.slug, + }) + expect(richTextLexicalRel.value).toMatchObject(homePage) + expect(richTextSlateRel.value).toMatchObject(homePage) + }) + + it('local API - should populate and override defaultSelect select shape from the populate arg', async () => { + const result = await payload.findByID({ + populate: { + pages: { + additional: true, + }, + }, + collection: 'pages', + depth: 1, + id: aboutPage.id, + }) + + const { + content: [ + { + link: { doc, docHasManyPoly, docMany, docPoly }, + richTextSlate: [richTextSlateRel], + richTextLexical: { + root: { + children: [richTextLexicalRel], + }, + }, + }, + ], + } = result + + expect(doc).toStrictEqual(expectedHomePageOverride) + expect(docMany).toStrictEqual([expectedHomePageOverride]) + expect(docPoly).toStrictEqual({ + relationTo: 'pages', + value: expectedHomePageOverride, + }) + expect(docHasManyPoly).toStrictEqual([ + { + relationTo: 'pages', + value: expectedHomePageOverride, + }, + ]) + + expect(richTextLexicalRel.value).toStrictEqual(expectedHomePageOverride) + expect(richTextSlateRel.value).toStrictEqual(expectedHomePageOverride) + }) + + it('rEST API - should populate and override defaultSelect select shape from the populate arg', async () => { + const result = await restClient + .GET(`/pages/${aboutPage.id}`, { + query: { + populate: { + pages: { + additional: true, + }, + }, + depth: 1, + }, + }) + .then((res) => res.json()) + + const { + content: [ + { + link: { doc, docHasManyPoly, docMany, docPoly }, + richTextSlate: [richTextSlateRel], + richTextLexical: { + root: { + children: [richTextLexicalRel], + }, + }, + }, + ], + } = result + + expect(doc).toMatchObject(expectedHomePageOverride) + expect(docMany).toMatchObject([expectedHomePageOverride]) + expect(docPoly).toMatchObject({ + relationTo: 'pages', + value: expectedHomePageOverride, + }) + expect(docHasManyPoly).toMatchObject([ + { + relationTo: 'pages', + value: expectedHomePageOverride, + }, + ]) + + expect(richTextLexicalRel.value).toMatchObject(expectedHomePageOverride) + expect(richTextSlateRel.value).toMatchObject(expectedHomePageOverride) + }) }) }) diff --git a/test/select/payload-types.ts b/test/select/payload-types.ts index 6a1ed46379e..654d2f82d49 100644 --- a/test/select/payload-types.ts +++ b/test/select/payload-types.ts @@ -297,10 +297,11 @@ export interface Page { | null; id?: string | null; blockName?: string | null; - blockType: 'cta'; + blockType: 'introduction'; }[] | null; slug: string; + additional?: string | null; updatedAt: string; createdAt: string; } @@ -605,7 +606,7 @@ export interface PagesSelect { content?: | T | { - cta?: + introduction?: | T | { title?: T; @@ -625,6 +626,7 @@ export interface PagesSelect { }; }; slug?: T; + additional?: T; updatedAt?: T; createdAt?: T; }