WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 19a224c

Browse files
authored
Merge pull request #208 from payloadcms/feat/maxdepth-field-property
feat: adds maxDepth to relationships and upload fields
2 parents d6bc6f9 + 470866a commit 19a224c

File tree

8 files changed

+40
-4
lines changed

8 files changed

+40
-4
lines changed

demo/collections/RelationshipA.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ const RelationshipA: PayloadCollectionConfig = {
4141
localized: true,
4242
hasMany: false,
4343
},
44+
{
45+
name: 'postMaxDepth',
46+
maxDepth: 0,
47+
label: 'Post With MaxDepth',
48+
type: 'relationship',
49+
relationTo: 'relationship-b',
50+
hasMany: false,
51+
},
4452
],
4553
timestamps: true,
4654
};

docs/fields/relationship.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ keywords: relationship, fields, config, configuration, documentation, Content Ma
2323
| **`name`** * | To be used as the property name when stored and retrieved from the database. |
2424
| **`*relationTo`** * | Provide one or many collection `slug`s to be able to assign relationships to. |
2525
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many relations instead of only one. |
26+
| **`maxDepth`** | Sets a number limit on iterations of related documents to populate when queried. [Depth](/docs/getting-started/concepts#depth) |
2627
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
2728
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
2829
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |

docs/fields/upload.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ keywords: upload, images media, fields, config, configuration, documentation, Co
2727
| ---------------- | ----------- |
2828
| **`name`** * | To be used as the property name when stored and retrieved from the database. |
2929
| **`*relationTo`** * | Provide a single collection `slug` to allow this field to accept a relation to. <strong>Note: the related collection must be configured to support Uploads.</strong> |
30+
| **`maxDepth`** | Sets a number limit on iterations of related documents to populate when queried. [Depth](/docs/getting-started/concepts#depth) |
3031
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
3132
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
3233
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |

docs/getting-started/concepts.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ For more, visit the [Access Control documentation](/docs/access-control/overview
6969
</Banner>
7070

7171
You can specify population `depth` via query parameter in the REST API and by an option in the local API. *Depth has no effect in the GraphQL API, because there, depth is based on the shape of your queries.*
72-
72+
It is also possible to limit the depth for specific `relation` and `upload` fields using the `maxDepth` property in your configuration.
7373
**For example, let's look the following Collections:** `departments`, `users`, `posts`
7474

7575
```

src/collections/tests/relationships.spec.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ describe('Collections - REST', () => {
5858
const updateA = await fetch(`${url}/api/relationship-a/${createAData.doc.id}`, {
5959
body: JSON.stringify({
6060
post: documentB.id,
61+
postMaxDepth: documentB.id,
6162
}),
6263
headers,
6364
method: 'put',
@@ -90,5 +91,17 @@ describe('Collections - REST', () => {
9091
expect(nested).not.toHaveProperty('post');
9192
expect(nested).toBe(documentA.id);
9293
});
94+
95+
it('should respect max depth at the field level', async () => {
96+
const response = await fetch(`${url}/api/relationship-a?depth=1`, {
97+
headers,
98+
method: 'get',
99+
});
100+
const data = await response.json();
101+
const [doc] = data.docs;
102+
// asserts postMaxDepth is not populated
103+
expect(doc.postMaxDepth).toBe(documentB.id);
104+
expect(doc.postMaxDepth).not.toHaveProperty('post');
105+
});
93106
});
94107
});

src/fields/config/schema.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ export const upload = baseField.keys({
171171
type: joi.string().valid('upload').required(),
172172
relationTo: joi.string().required(),
173173
name: joi.string().required(),
174+
maxDepth: joi.number(),
174175
});
175176

176177
export const checkbox = baseField.keys({
@@ -187,6 +188,7 @@ export const relationship = baseField.keys({
187188
joi.array().items(joi.string()),
188189
),
189190
name: joi.string().required(),
191+
maxDepth: joi.number(),
190192
});
191193

192194
export const blocks = baseField.keys({

src/fields/config/types.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ export type RowField = FieldBase & {
141141
export type UploadField = FieldBase & {
142142
type: 'upload';
143143
relationTo: string;
144+
maxDepth?: number;
144145
}
145146

146147
type CodeAdmin = Admin & {
@@ -164,6 +165,7 @@ export type RelationshipField = FieldBase & {
164165
type: 'relationship';
165166
relationTo: string | string[];
166167
hasMany?: boolean;
168+
maxDepth?: number;
167169
}
168170

169171
type RichTextPlugin = (editor: Editor) => Editor;
@@ -259,6 +261,10 @@ export type FieldWithMany =
259261
SelectField
260262
| RelationshipField
261263

264+
export type FieldWithMaxDepth =
265+
UploadField
266+
| RelationshipField
267+
262268
export function fieldHasSubFields(field: Field): field is FieldWithSubFields {
263269
return (field.type === 'group' || field.type === 'array' || field.type === 'row');
264270
}
@@ -287,4 +293,8 @@ export function fieldSupportsMany(field: Field): field is FieldWithMany {
287293
return field.type === 'select' || field.type === 'relationship';
288294
}
289295

296+
export function fieldHasMaxDepth(field: Field): field is FieldWithMaxDepth {
297+
return (field.type === 'upload' || field.type === 'relationship') && typeof field.maxDepth === 'number';
298+
}
299+
290300
export type HookName = 'beforeChange' | 'beforeValidate' | 'afterChange' | 'afterRead';

src/fields/relationshipPopulationPromise.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { PayloadRequest } from '../express/types';
22
import executeAccess from '../auth/executeAccess';
3-
import { Field, RelationshipField, fieldSupportsMany } from './config/types';
3+
import { Field, RelationshipField, fieldSupportsMany, fieldHasMaxDepth } from './config/types';
44
import { Payload } from '..';
55

66
type PopulateArgs = {
@@ -95,6 +95,7 @@ const relationshipPopulationPromise = ({
9595
payload,
9696
}: PromiseArgs) => async (): Promise<void> => {
9797
const resultingData = data;
98+
const populateDepth = fieldHasMaxDepth(field) && field.maxDepth < depth ? field.maxDepth : depth;
9899

99100
if (fieldSupportsMany(field) && field.hasMany && Array.isArray(data[field.name])) {
100101
const rowPromises = [];
@@ -103,7 +104,7 @@ const relationshipPopulationPromise = ({
103104
const rowPromise = async () => {
104105
if (relatedDoc) {
105106
await populate({
106-
depth,
107+
depth: populateDepth,
107108
currentDepth,
108109
req,
109110
overrideAccess,
@@ -122,7 +123,7 @@ const relationshipPopulationPromise = ({
122123
await Promise.all(rowPromises);
123124
} else if (data[field.name]) {
124125
await populate({
125-
depth,
126+
depth: populateDepth,
126127
currentDepth,
127128
req,
128129
overrideAccess,

0 commit comments

Comments
 (0)