fix: allow to set maxDepth: 0 for join fields, improve join field JSDoc (#10336)
Allows to set `maxDepth: 0` for join fields and improves JSDoc about `maxDepth`, adds tests to confirm that https://github.com/payloadcms/payload/issues/10243 is not an issue, but just happens because the default `maxDepth` is `1`.
This commit is contained in:
@@ -20,7 +20,7 @@ export const sanitizeJoinField = ({
|
||||
if (typeof joins === 'undefined') {
|
||||
throw new APIError('Join fields cannot be added to arrays, blocks or globals.')
|
||||
}
|
||||
if (!field.maxDepth) {
|
||||
if (typeof field.maxDepth === 'undefined') {
|
||||
field.maxDepth = 1
|
||||
}
|
||||
const join: SanitizedJoin = {
|
||||
|
||||
@@ -1416,6 +1416,13 @@ export type JoinField = {
|
||||
* This does not need to be set and will be overridden by the relationship field's localized property.
|
||||
*/
|
||||
localized?: boolean
|
||||
/**
|
||||
* The maximum allowed depth to be permitted application-wide. This setting helps prevent against malicious queries.
|
||||
*
|
||||
* @see https://payloadcms.com/docs/getting-started/concepts#depth
|
||||
*
|
||||
* @default 1
|
||||
*/
|
||||
maxDepth?: number
|
||||
/**
|
||||
* A string for the field in the collection being joined to.
|
||||
|
||||
@@ -168,6 +168,45 @@ export default buildConfigWithDefaults({
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'depth-joins-1',
|
||||
fields: [
|
||||
{
|
||||
name: 'rel',
|
||||
type: 'relationship',
|
||||
relationTo: 'depth-joins-2',
|
||||
},
|
||||
{
|
||||
name: 'joins',
|
||||
type: 'join',
|
||||
collection: 'depth-joins-3',
|
||||
on: 'rel',
|
||||
maxDepth: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'depth-joins-2',
|
||||
fields: [
|
||||
{
|
||||
name: 'joins',
|
||||
type: 'join',
|
||||
collection: 'depth-joins-1',
|
||||
on: 'rel',
|
||||
maxDepth: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'depth-joins-3',
|
||||
fields: [
|
||||
{
|
||||
name: 'rel',
|
||||
type: 'relationship',
|
||||
relationTo: 'depth-joins-1',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
localization: {
|
||||
locales: ['en', 'es'],
|
||||
|
||||
@@ -5,7 +5,7 @@ import { getFileByPath } from 'payload'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import type { NextRESTClient } from '../helpers/NextRESTClient.js'
|
||||
import type { Category, Config, Post, Singular } from './payload-types.js'
|
||||
import type { Category, Config, DepthJoins1, DepthJoins3, Post, Singular } from './payload-types.js'
|
||||
|
||||
import { devUser } from '../credentials.js'
|
||||
import { idToString } from '../helpers/idToString.js'
|
||||
@@ -984,6 +984,35 @@ describe('Joins Field', () => {
|
||||
|
||||
expect((data.joins.docs[0] as TypeWithID).id).toBe(doc_2.id)
|
||||
})
|
||||
|
||||
it('should populate joins on depth 2', async () => {
|
||||
const depthJoin_2 = await payload.create({ collection: 'depth-joins-2', data: {}, depth: 0 })
|
||||
const depthJoin_1 = await payload.create({
|
||||
collection: 'depth-joins-1',
|
||||
data: { rel: depthJoin_2 },
|
||||
depth: 0,
|
||||
})
|
||||
|
||||
const depthJoin_3 = await payload.create({
|
||||
collection: 'depth-joins-3',
|
||||
data: { rel: depthJoin_1 },
|
||||
depth: 0,
|
||||
})
|
||||
|
||||
const data = await payload.findByID({
|
||||
collection: 'depth-joins-2',
|
||||
id: depthJoin_2.id,
|
||||
depth: 2,
|
||||
})
|
||||
|
||||
const joinedDoc = data.joins.docs[0] as DepthJoins1
|
||||
|
||||
expect(joinedDoc.id).toBe(depthJoin_1.id)
|
||||
|
||||
const joinedDoc2 = joinedDoc.joins.docs[0] as DepthJoins3
|
||||
|
||||
expect(joinedDoc2.id).toBe(depthJoin_3.id)
|
||||
})
|
||||
})
|
||||
|
||||
async function createPost(overrides?: Partial<Post>, locale?: Config['locale']) {
|
||||
|
||||
@@ -25,6 +25,9 @@ export interface Config {
|
||||
'categories-join-restricted': CategoriesJoinRestricted;
|
||||
'restricted-posts': RestrictedPost;
|
||||
'collection-restricted': CollectionRestricted;
|
||||
'depth-joins-1': DepthJoins1;
|
||||
'depth-joins-2': DepthJoins2;
|
||||
'depth-joins-3': DepthJoins3;
|
||||
users: User;
|
||||
'payload-locked-documents': PayloadLockedDocument;
|
||||
'payload-preferences': PayloadPreference;
|
||||
@@ -66,6 +69,12 @@ export interface Config {
|
||||
'categories-join-restricted': {
|
||||
collectionRestrictedJoin: 'collection-restricted';
|
||||
};
|
||||
'depth-joins-1': {
|
||||
joins: 'depth-joins-3';
|
||||
};
|
||||
'depth-joins-2': {
|
||||
joins: 'depth-joins-1';
|
||||
};
|
||||
};
|
||||
collectionsSelect: {
|
||||
posts: PostsSelect<false> | PostsSelect<true>;
|
||||
@@ -82,6 +91,9 @@ export interface Config {
|
||||
'categories-join-restricted': CategoriesJoinRestrictedSelect<false> | CategoriesJoinRestrictedSelect<true>;
|
||||
'restricted-posts': RestrictedPostsSelect<false> | RestrictedPostsSelect<true>;
|
||||
'collection-restricted': CollectionRestrictedSelect<false> | CollectionRestrictedSelect<true>;
|
||||
'depth-joins-1': DepthJoins1Select<false> | DepthJoins1Select<true>;
|
||||
'depth-joins-2': DepthJoins2Select<false> | DepthJoins2Select<true>;
|
||||
'depth-joins-3': DepthJoins3Select<false> | DepthJoins3Select<true>;
|
||||
users: UsersSelect<false> | UsersSelect<true>;
|
||||
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
||||
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
|
||||
@@ -451,6 +463,43 @@ export interface RestrictedPost {
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "depth-joins-1".
|
||||
*/
|
||||
export interface DepthJoins1 {
|
||||
id: string;
|
||||
rel?: (string | null) | DepthJoins2;
|
||||
joins?: {
|
||||
docs?: (string | DepthJoins3)[] | null;
|
||||
hasNextPage?: boolean | null;
|
||||
} | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "depth-joins-2".
|
||||
*/
|
||||
export interface DepthJoins2 {
|
||||
id: string;
|
||||
joins?: {
|
||||
docs?: (string | DepthJoins1)[] | null;
|
||||
hasNextPage?: boolean | null;
|
||||
} | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "depth-joins-3".
|
||||
*/
|
||||
export interface DepthJoins3 {
|
||||
id: string;
|
||||
rel?: (string | null) | DepthJoins1;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents".
|
||||
@@ -514,6 +563,18 @@ export interface PayloadLockedDocument {
|
||||
relationTo: 'collection-restricted';
|
||||
value: string | CollectionRestricted;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'depth-joins-1';
|
||||
value: string | DepthJoins1;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'depth-joins-2';
|
||||
value: string | DepthJoins2;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'depth-joins-3';
|
||||
value: string | DepthJoins3;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
@@ -761,6 +822,34 @@ export interface CollectionRestrictedSelect<T extends boolean = true> {
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "depth-joins-1_select".
|
||||
*/
|
||||
export interface DepthJoins1Select<T extends boolean = true> {
|
||||
rel?: T;
|
||||
joins?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "depth-joins-2_select".
|
||||
*/
|
||||
export interface DepthJoins2Select<T extends boolean = true> {
|
||||
joins?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "depth-joins-3_select".
|
||||
*/
|
||||
export interface DepthJoins3Select<T extends boolean = true> {
|
||||
rel?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "users_select".
|
||||
|
||||
Reference in New Issue
Block a user