feat: add populate property to Local / REST API (#8969)

### What?
Adds `populate` property to Local API and REST API operations that can
be used to specify `select` for a specific collection when it's
populated
```ts
const result = await payload.findByID({
  populate: {
   // type safe if you have generated types
    posts: {
      text: true,
    },
  },
  collection: 'pages',
  depth: 1,
  id: aboutPage.id,
})

result.relatedPost // only has text and id properties
``` 

```ts
fetch('https://localhost:3000/api/pages?populate[posts][text]=true') // highlight-line
  .then((res) => res.json())
  .then((data) => console.log(data))
```

It also overrides
[`defaultPopulate`](https://github.com/payloadcms/payload/pull/8934)

Ensures `defaultPopulate` doesn't affect GraphQL.

### How?
Implements the property for all operations that have the `depth`
argument.
This commit is contained in:
Sasha
2024-11-06 20:50:19 +02:00
committed by GitHub
parent 147d28e62c
commit a22c0e62fa
67 changed files with 487 additions and 47 deletions

View File

@@ -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). |

View File

@@ -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))
```

View File

@@ -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

View File

@@ -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),
})

View File

@@ -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<string, unknown>
select?: Record<string, unknown>
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,

View File

@@ -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),
})

View File

@@ -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),
})

View File

@@ -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<string, unknown>
select?: Record<string, unknown>
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,

View File

@@ -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),
})

View File

@@ -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),
})

View File

@@ -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<string, unknown>
select?: Record<string, unknown>
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,

View File

@@ -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,
})

View File

@@ -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<string, unknown>
select?: Record<string, unknown>
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,

View File

@@ -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),

View File

@@ -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),
})

View File

@@ -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),
})

View File

@@ -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<string, unknown>
select?: Record<string, unknown>
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,

View File

@@ -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,
})

View File

@@ -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),

View File

@@ -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
}

View File

@@ -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<void>[]
/** 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<void>[]
showHiddenFields?: boolean
triggerAccessControl?: boolean
@@ -225,6 +226,7 @@ type RichTextAdapterBase<
findMany: boolean
flattenLocales: boolean
overrideAccess?: boolean
populateArg?: PopulateType
populationPromises: Promise<void>[]
req: PayloadRequest
showHiddenFields: boolean

View File

@@ -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<TSlug extends CollectionSlug> = {
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,

View File

@@ -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,

View File

@@ -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 <TSlug extends CollectionSlug, TSelect
depth,
overrideAccess,
overrideLock,
populate,
req: {
fallbackLocale,
locale,
@@ -188,6 +191,7 @@ export const deleteByIDOperation = async <TSlug extends CollectionSlug, TSelect
global: null,
locale,
overrideAccess,
populate,
req,
select,
showHiddenFields,

View File

@@ -6,6 +6,7 @@ import type { FindOneArgs } from '../../database/types.js'
import type { CollectionSlug } from '../../index.js'
import type {
PayloadRequest,
PopulateType,
SelectType,
TransformCollectionWithSelect,
} from '../../types/index.js'
@@ -41,6 +42,7 @@ export type Arguments = {
draft?: boolean
id: number | string
overrideAccess?: boolean
populate?: PopulateType
req: PayloadRequest
select?: SelectType
showHiddenFields?: boolean
@@ -81,6 +83,7 @@ export const duplicateOperation = async <
depth,
draft: draftArg = true,
overrideAccess,
populate,
req: { fallbackLocale, locale: localeArg, payload },
req,
select,
@@ -306,6 +309,7 @@ export const duplicateOperation = async <
global: null,
locale: localeArg,
overrideAccess,
populate,
req,
select,
showHiddenFields,

View File

@@ -3,6 +3,7 @@ import type { PaginatedDocs } from '../../database/types.js'
import type { CollectionSlug, JoinQuery } from '../../index.js'
import type {
PayloadRequest,
PopulateType,
SelectType,
Sort,
TransformCollectionWithSelect,
@@ -38,6 +39,7 @@ export type Arguments = {
overrideAccess?: boolean
page?: number
pagination?: boolean
populate?: PopulateType
req?: PayloadRequest
select?: SelectType
showHiddenFields?: boolean
@@ -84,6 +86,7 @@ export const findOperation = async <
overrideAccess,
page,
pagination = true,
populate,
req: { fallbackLocale, locale, payload },
req,
select,
@@ -294,6 +297,7 @@ export const findOperation = async <
global: null,
locale,
overrideAccess,
populate,
req,
select,
showHiddenFields,

View File

@@ -3,6 +3,7 @@ import type { CollectionSlug, JoinQuery } from '../../index.js'
import type {
ApplyDisableErrors,
PayloadRequest,
PopulateType,
SelectType,
TransformCollectionWithSelect,
} from '../../types/index.js'
@@ -32,6 +33,7 @@ export type Arguments = {
includeLockStatus?: boolean
joins?: JoinQuery
overrideAccess?: boolean
populate?: PopulateType
req: PayloadRequest
select?: SelectType
showHiddenFields?: boolean
@@ -74,6 +76,7 @@ export const findByIDOperation = async <
includeLockStatus,
joins,
overrideAccess = false,
populate,
req: { fallbackLocale, locale, t },
req,
select,
@@ -241,6 +244,7 @@ export const findByIDOperation = async <
global: null,
locale,
overrideAccess,
populate,
req,
select,
showHiddenFields,

View File

@@ -1,6 +1,6 @@
import httpStatus from 'http-status'
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 { Collection, TypeWithID } from '../config/types.js'
@@ -17,6 +17,7 @@ export type Arguments = {
disableErrors?: boolean
id: number | string
overrideAccess?: boolean
populate?: PopulateType
req: PayloadRequest
select?: SelectType
showHiddenFields?: boolean
@@ -32,6 +33,7 @@ export const findVersionByIDOperation = async <TData extends TypeWithID = any>(
depth,
disableErrors,
overrideAccess,
populate,
req: { fallbackLocale, locale, payload },
req,
select,
@@ -121,6 +123,7 @@ export const findVersionByIDOperation = async <TData extends TypeWithID = any>(
global: null,
locale,
overrideAccess,
populate,
req,
select: typeof select?.version === 'object' ? select.version : undefined,
showHiddenFields,

View File

@@ -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 <TData extends TypeWithVersion<TData>
overrideAccess,
page,
pagination = true,
populate,
req: { fallbackLocale, locale, payload },
req,
select,
@@ -129,6 +131,7 @@ export const findVersionsOperation = async <TData extends TypeWithVersion<TData>
global: null,
locale,
overrideAccess,
populate,
req,
select: typeof select?.version === 'object' ? select.version : undefined,
showHiddenFields,

View File

@@ -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<TSlug extends CollectionSlug, TSelect extends SelectType> =
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,

View File

@@ -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<TSlug extends CollectionSlug, TSelect extends SelectType
locale?: TypedLocale
overrideAccess?: boolean
overrideLock?: boolean
populate?: PopulateType
req?: PayloadRequest
select?: TSelect
showHiddenFields?: boolean
@@ -87,6 +89,7 @@ async function deleteLocal<
disableTransaction,
overrideAccess = true,
overrideLock,
populate,
select,
showHiddenFields,
where,
@@ -107,6 +110,7 @@ async function deleteLocal<
disableTransaction,
overrideAccess,
overrideLock,
populate,
req: await createLocalReq(options, payload),
select,
showHiddenFields,

View File

@@ -3,6 +3,7 @@ import type { Payload, RequestContext } from '../../../index.js'
import type {
Document,
PayloadRequest,
PopulateType,
SelectType,
TransformCollectionWithSelect,
} from '../../../types/index.js'
@@ -25,6 +26,7 @@ export type Options<TSlug extends CollectionSlug, TSelect extends SelectType> =
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,

View File

@@ -9,6 +9,7 @@ import type {
import type {
Document,
PayloadRequest,
PopulateType,
SelectType,
Sort,
TransformCollectionWithSelect,
@@ -38,6 +39,7 @@ export type Options<TSlug extends CollectionSlug, TSelect extends SelectType> =
overrideAccess?: boolean
page?: number
pagination?: boolean
populate?: PopulateType
req?: PayloadRequest
select?: TSelect
showHiddenFields?: boolean

View File

@@ -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,

View File

@@ -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<TSlug extends CollectionSlug> = {
id: string
locale?: 'all' | TypedLocale
overrideAccess?: boolean
populate?: PopulateType
req?: PayloadRequest
select?: SelectType
showHiddenFields?: boolean
@@ -36,6 +37,7 @@ export default async function findVersionByIDLocal<TSlug extends CollectionSlug>
depth,
disableErrors = false,
overrideAccess = true,
populate,
select,
showHiddenFields,
} = options
@@ -56,6 +58,7 @@ export default async function findVersionByIDLocal<TSlug extends CollectionSlug>
depth,
disableErrors,
overrideAccess,
populate,
req: await createLocalReq(options, payload),
select,
showHiddenFields,

View File

@@ -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<TSlug extends CollectionSlug> = {
locale?: 'all' | TypedLocale
overrideAccess?: boolean
page?: number
populate?: PopulateType
req?: PayloadRequest
select?: SelectType
showHiddenFields?: boolean
@@ -39,6 +47,7 @@ export default async function findVersionsLocal<TSlug extends CollectionSlug>(
limit,
overrideAccess = true,
page,
populate,
select,
showHiddenFields,
sort,
@@ -59,6 +68,7 @@ export default async function findVersionsLocal<TSlug extends CollectionSlug>(
limit,
overrideAccess,
page,
populate,
req: await createLocalReq(options, payload),
select,
showHiddenFields,

View File

@@ -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<TSlug extends CollectionSlug> = {
id: string
locale?: TypedLocale
overrideAccess?: boolean
populate?: PopulateType
req?: PayloadRequest
select?: SelectType
showHiddenFields?: boolean
@@ -33,6 +34,7 @@ export default async function restoreVersionLocal<TSlug extends CollectionSlug>(
collection: collectionSlug,
depth,
overrideAccess = true,
populate,
select,
showHiddenFields,
} = options
@@ -53,6 +55,7 @@ export default async function restoreVersionLocal<TSlug extends CollectionSlug>(
depth,
overrideAccess,
payload,
populate,
req: await createLocalReq(options, payload),
select,
showHiddenFields,

View File

@@ -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<TSlug extends CollectionSlug, TSelect extends SelectType
overrideAccess?: boolean
overrideLock?: boolean
overwriteExistingFiles?: boolean
populate?: PopulateType
publishSpecificLocale?: string
req?: PayloadRequest
select?: TSelect
@@ -111,6 +113,7 @@ async function updateLocal<
overrideAccess = true,
overrideLock,
overwriteExistingFiles = false,
populate,
publishSpecificLocale,
select,
showHiddenFields,
@@ -141,6 +144,7 @@ async function updateLocal<
overrideLock,
overwriteExistingFiles,
payload,
populate,
publishSpecificLocale,
req,
select,

View File

@@ -1,7 +1,7 @@
import httpStatus from 'http-status'
import type { FindOneArgs } from '../../database/types.js'
import type { PayloadRequest, SelectType } from '../../types/index.js'
import type { PayloadRequest, PopulateType, SelectType } from '../../types/index.js'
import type { Collection, TypeWithID } from '../config/types.js'
import executeAccess from '../../auth/executeAccess.js'
@@ -21,6 +21,7 @@ export type Arguments = {
draft?: boolean
id: number | string
overrideAccess?: boolean
populate?: PopulateType
req: PayloadRequest
select?: SelectType
showHiddenFields?: boolean
@@ -35,6 +36,7 @@ export const restoreVersionOperation = async <TData extends TypeWithID = any>(
depth,
draft,
overrideAccess = false,
populate,
req,
req: { fallbackLocale, locale, payload },
select,
@@ -152,6 +154,7 @@ export const restoreVersionOperation = async <TData extends TypeWithID = any>(
global: null,
locale,
overrideAccess,
populate,
req,
select,
showHiddenFields,

View File

@@ -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<TSlug extends CollectionSlug> = {
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,

View File

@@ -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<TSlug extends CollectionSlug> = {
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,

View File

@@ -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<T extends JsonObject> = {
global: null | SanitizedGlobalConfig
locale: string
overrideAccess: boolean
populate?: PopulateType
req: PayloadRequest
select?: SelectType
showHiddenFields: boolean
@@ -49,6 +50,7 @@ export async function afterRead<T extends JsonObject>(args: Args<T>): Promise<T>
global,
locale,
overrideAccess,
populate,
req,
select,
showHiddenFields,
@@ -84,6 +86,7 @@ export async function afterRead<T extends JsonObject>(args: Args<T>): Promise<T>
locale,
overrideAccess,
path: [],
populate,
populationPromises,
req,
schemaPath: [],

View File

@@ -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<void>[]
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,

View File

@@ -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<string, any>
@@ -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,
})

View File

@@ -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<void>[]
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,

View File

@@ -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 <T extends Record<string, unknown>>(
globalConfig,
includeLockStatus,
overrideAccess = false,
populate,
req: { fallbackLocale, locale },
req,
select,
@@ -169,6 +171,7 @@ export const findOneOperation = async <T extends Record<string, unknown>>(
global: globalConfig,
locale,
overrideAccess,
populate,
req,
select,
showHiddenFields,

View File

@@ -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 <T extends TypeWithVersion<T> = an
disableErrors,
globalConfig,
overrideAccess,
populate,
req: { fallbackLocale, locale, payload },
req,
select,
@@ -123,6 +124,7 @@ export const findVersionByIDOperation = async <T extends TypeWithVersion<T> = an
global: globalConfig,
locale,
overrideAccess,
populate,
req,
select: typeof select?.version === 'object' ? select.version : undefined,
showHiddenFields,

View File

@@ -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 <T extends TypeWithVersion<T>>(
overrideAccess,
page,
pagination = true,
populate,
req: { fallbackLocale, locale, payload },
req,
select,
@@ -105,6 +107,7 @@ export const findVersionsOperation = async <T extends TypeWithVersion<T>>(
global: globalConfig,
locale,
overrideAccess,
populate,
req,
select,
showHiddenFields,

View File

@@ -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<TSlug extends GlobalSlug, TSelect extends SelectType> = {
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,

View File

@@ -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<TSlug extends GlobalSlug> = {
id: string
locale?: 'all' | TypedLocale
overrideAccess?: boolean
populate?: PopulateType
req?: PayloadRequest
select?: SelectType
showHiddenFields?: boolean
@@ -33,6 +34,7 @@ export default async function findVersionByIDLocal<TSlug extends GlobalSlug>(
depth,
disableErrors = false,
overrideAccess = true,
populate,
select,
showHiddenFields,
} = options
@@ -49,6 +51,7 @@ export default async function findVersionByIDLocal<TSlug extends GlobalSlug>(
disableErrors,
globalConfig,
overrideAccess,
populate,
req: await createLocalReq(options, payload),
select,
showHiddenFields,

View File

@@ -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<TSlug extends GlobalSlug> = {
locale?: 'all' | TypedLocale
overrideAccess?: boolean
page?: number
populate?: PopulateType
req?: PayloadRequest
select?: SelectType
showHiddenFields?: boolean
@@ -36,6 +44,7 @@ export default async function findVersionsLocal<TSlug extends GlobalSlug>(
limit,
overrideAccess = true,
page,
populate,
select,
showHiddenFields,
sort,
@@ -54,6 +63,7 @@ export default async function findVersionsLocal<TSlug extends GlobalSlug>(
limit,
overrideAccess,
page,
populate,
req: await createLocalReq(options, payload),
select,
showHiddenFields,

View File

@@ -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<TSlug extends GlobalSlug> = {
id: string
locale?: TypedLocale
overrideAccess?: boolean
populate?: PopulateType
req?: PayloadRequest
showHiddenFields?: boolean
slug: TSlug
@@ -24,7 +25,7 @@ export default async function restoreVersionLocal<TSlug extends GlobalSlug>(
payload: Payload,
options: Options<TSlug>,
): Promise<DataFromGlobalSlug<TSlug>> {
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<TSlug extends GlobalSlug>(
depth,
globalConfig,
overrideAccess,
populate,
req: await createLocalReq(options, payload),
showHiddenFields,
})

View File

@@ -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<TSlug extends GlobalSlug, TSelect extends SelectType> = {
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,

View File

@@ -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 <T extends TypeWithVersion<T> = any
draft,
globalConfig,
overrideAccess,
populate,
req: { fallbackLocale, locale, payload },
req,
showHiddenFields,
@@ -131,6 +133,7 @@ export const restoreVersionOperation = async <T extends TypeWithVersion<T> = any
global: globalConfig,
locale,
overrideAccess,
populate,
req,
showHiddenFields,
})

View File

@@ -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<TSlug extends GlobalSlug> = {
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,

View File

@@ -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<DataFromGlobalSlug<TSlug>, TSelect>
: DataFromGlobalSlug<TSlug>
export type PopulateType = Partial<TypedCollectionSelect>

View File

@@ -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,
}),
)

View File

@@ -15,6 +15,7 @@ import type {
Payload,
PayloadComponent,
PayloadRequest,
PopulateType,
ReplaceAny,
RequestContext,
RichTextField,
@@ -147,6 +148,10 @@ export type AfterReadNodeHookArgs<T extends SerializedLexicalNode> = {
*/
locale: string
overrideAccess: boolean
/**
* Only available in `afterRead` hooks.
*/
populateArg?: PopulateType
/**
* Only available in `afterRead` field hooks.
*/

View File

@@ -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,
}),
)

View File

@@ -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,

View File

@@ -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<void>[]
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,

View File

@@ -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<any[], any, any>
overrideAccess: boolean
populateArg?: PopulateType
populationPromises: Promise<void>[]
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,

View File

@@ -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,

View File

@@ -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

View File

@@ -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',
},
],
}

View File

@@ -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)
})
})
})

View File

@@ -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<T extends boolean = true> {
content?:
| T
| {
cta?:
introduction?:
| T
| {
title?: T;
@@ -625,6 +626,7 @@ export interface PagesSelect<T extends boolean = true> {
};
};
slug?: T;
additional?: T;
updatedAt?: T;
createdAt?: T;
}