feat: queriable / sortable / useAsTitle virtual fields linked with a relationship field (#11805)

This PR adds an ability to specify a virtual field in this way
```js
{
  slug: 'posts',
  fields: [
    {
      name: 'title',
      type: 'text',
      required: true,
    },
  ],
},
{
  slug: 'virtual-relations',
  fields: [
    {
      name: 'postTitle',
      type: 'text',
      virtual: 'post.title',
    },
    {
      name: 'post',
      type: 'relationship',
      relationTo: 'posts',
    },
  ],
},
```

Then, every time you query `virtual-relations`, `postTitle` will be
automatically populated (even if using `depth: 0`) on the db level. This
field also, unlike `virtual: true` is available for querying / sorting /
`useAsTitle`.

Also, the field can be deeply nested to 2 or more relationships, for
example:
```
{
  name: 'postCategoryTitle',
  type: 'text',
  virtual: 'post.category.title',
},
```

Where the current collection has `post` - a relationship to `posts`, the
collection `posts` has `category` that's a relationship to `categories`
and finally `categories` has `title`.
This commit is contained in:
Sasha
2025-04-16 22:46:18 +03:00
committed by GitHub
parent c877b1ad43
commit 1c99f46e4f
16 changed files with 568 additions and 39 deletions

View File

@@ -67,6 +67,7 @@ export interface Config {
};
blocks: {};
collections: {
categories: Category;
posts: Post;
'error-on-unnamed-fields': ErrorOnUnnamedField;
'default-values': DefaultValue;
@@ -75,6 +76,7 @@ export interface Config {
'pg-migrations': PgMigration;
'custom-schema': CustomSchema;
places: Place;
'virtual-relations': VirtualRelation;
'fields-persistance': FieldsPersistance;
'custom-ids': CustomId;
'fake-custom-ids': FakeCustomId;
@@ -88,6 +90,7 @@ export interface Config {
};
collectionsJoins: {};
collectionsSelect: {
categories: CategoriesSelect<false> | CategoriesSelect<true>;
posts: PostsSelect<false> | PostsSelect<true>;
'error-on-unnamed-fields': ErrorOnUnnamedFieldsSelect<false> | ErrorOnUnnamedFieldsSelect<true>;
'default-values': DefaultValuesSelect<false> | DefaultValuesSelect<true>;
@@ -96,6 +99,7 @@ export interface Config {
'pg-migrations': PgMigrationsSelect<false> | PgMigrationsSelect<true>;
'custom-schema': CustomSchemaSelect<false> | CustomSchemaSelect<true>;
places: PlacesSelect<false> | PlacesSelect<true>;
'virtual-relations': VirtualRelationsSelect<false> | VirtualRelationsSelect<true>;
'fields-persistance': FieldsPersistanceSelect<false> | FieldsPersistanceSelect<true>;
'custom-ids': CustomIdsSelect<false> | CustomIdsSelect<true>;
'fake-custom-ids': FakeCustomIdsSelect<false> | FakeCustomIdsSelect<true>;
@@ -114,11 +118,13 @@ export interface Config {
global: Global;
'global-2': Global2;
'global-3': Global3;
'virtual-relation-global': VirtualRelationGlobal;
};
globalsSelect: {
global: GlobalSelect<false> | GlobalSelect<true>;
'global-2': Global2Select<false> | Global2Select<true>;
'global-3': Global3Select<false> | Global3Select<true>;
'virtual-relation-global': VirtualRelationGlobalSelect<false> | VirtualRelationGlobalSelect<true>;
};
locale: 'en' | 'es';
user: User & {
@@ -147,6 +153,16 @@ export interface UserAuthOperations {
password: string;
};
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "categories".
*/
export interface Category {
id: string;
title?: string | null;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "posts".
@@ -154,6 +170,9 @@ export interface UserAuthOperations {
export interface Post {
id: string;
title: string;
category?: (string | null) | Category;
localized?: string | null;
text?: string | null;
number?: number | null;
D1?: {
D2?: {
@@ -346,6 +365,20 @@ export interface Place {
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "virtual-relations".
*/
export interface VirtualRelation {
id: string;
postTitle?: string | null;
postCategoryTitle?: string | null;
postLocalized?: string | null;
post?: (string | null) | Post;
updatedAt: string;
createdAt: string;
_status?: ('draft' | 'published') | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "fields-persistance".
@@ -465,6 +498,10 @@ export interface User {
export interface PayloadLockedDocument {
id: string;
document?:
| ({
relationTo: 'categories';
value: string | Category;
} | null)
| ({
relationTo: 'posts';
value: string | Post;
@@ -497,6 +534,10 @@ export interface PayloadLockedDocument {
relationTo: 'places';
value: string | Place;
} | null)
| ({
relationTo: 'virtual-relations';
value: string | VirtualRelation;
} | null)
| ({
relationTo: 'fields-persistance';
value: string | FieldsPersistance;
@@ -567,12 +608,24 @@ export interface PayloadMigration {
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "categories_select".
*/
export interface CategoriesSelect<T extends boolean = true> {
title?: T;
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "posts_select".
*/
export interface PostsSelect<T extends boolean = true> {
title?: T;
category?: T;
localized?: T;
text?: T;
number?: T;
D1?:
| T
@@ -747,6 +800,19 @@ export interface PlacesSelect<T extends boolean = true> {
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "virtual-relations_select".
*/
export interface VirtualRelationsSelect<T extends boolean = true> {
postTitle?: T;
postCategoryTitle?: T;
postLocalized?: T;
post?: T;
updatedAt?: T;
createdAt?: T;
_status?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "fields-persistance_select".
@@ -917,6 +983,17 @@ export interface Global3 {
updatedAt?: string | null;
createdAt?: string | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "virtual-relation-global".
*/
export interface VirtualRelationGlobal {
id: string;
postTitle?: string | null;
post?: (string | null) | Post;
updatedAt?: string | null;
createdAt?: string | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "global_select".
@@ -947,6 +1024,17 @@ export interface Global3Select<T extends boolean = true> {
createdAt?: T;
globalType?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "virtual-relation-global_select".
*/
export interface VirtualRelationGlobalSelect<T extends boolean = true> {
postTitle?: T;
post?: T;
updatedAt?: T;
createdAt?: T;
globalType?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "auth".