diff --git a/packages/drizzle/src/find/traverseFields.ts b/packages/drizzle/src/find/traverseFields.ts index 0ac2b900b30..a9ade33e21e 100644 --- a/packages/drizzle/src/find/traverseFields.ts +++ b/packages/drizzle/src/find/traverseFields.ts @@ -14,7 +14,7 @@ import { type SelectType, type Where, } from 'payload' -import { fieldIsVirtual, fieldShouldBeLocalized } from 'payload/shared' +import { blocks, fieldIsVirtual, fieldShouldBeLocalized } from 'payload/shared' import toSnakeCase from 'to-snake-case' import type { BuildQueryJoinAliases, DrizzleAdapter } from '../types.js' @@ -91,6 +91,7 @@ type TraverseFieldArgs = { depth?: number draftsEnabled?: boolean fields: FlattenedField[] + forceWithFields?: boolean joinQuery: JoinQuery joins?: BuildQueryJoinAliases locale?: string @@ -119,6 +120,7 @@ export const traverseFields = ({ depth, draftsEnabled, fields, + forceWithFields, joinQuery = {}, joins, locale, @@ -231,6 +233,7 @@ export const traverseFields = ({ depth, draftsEnabled, fields: field.flattenedFields, + forceWithFields, joinQuery, locale, parentIsLocalized: parentIsLocalized || field.localized, @@ -358,6 +361,7 @@ export const traverseFields = ({ depth, draftsEnabled, fields: block.flattenedFields, + forceWithFields: blockSelect === true, joinQuery, locale, parentIsLocalized: parentIsLocalized || field.localized, @@ -400,6 +404,7 @@ export const traverseFields = ({ depth, draftsEnabled, fields: field.flattenedFields, + forceWithFields, joinQuery, joins, locale, @@ -862,6 +867,23 @@ export const traverseFields = ({ } default: { + if (forceWithFields) { + if ( + (field.type === 'relationship' || field.type === 'upload') && + (field.hasMany || Array.isArray(field.relationTo)) + ) { + withTabledFields.rels = true + } + + if (field.type === 'number' && field.hasMany) { + withTabledFields.numbers = true + } + + if (field.type === 'text' && field.hasMany) { + withTabledFields.texts = true + } + } + if (!select && !selectAllOnCurrentLevel) { break } diff --git a/test/select/getConfig.ts b/test/select/getConfig.ts index 7712c3e82d0..dd11deece3b 100644 --- a/test/select/getConfig.ts +++ b/test/select/getConfig.ts @@ -37,7 +37,34 @@ export const getConfig: () => Partial = () => ({ }, { slug: 'rels', - fields: [], + fields: [{ type: 'text', name: 'text' }], + }, + { + slug: 'relationships-blocks', + fields: [ + { + type: 'blocks', + name: 'blocks', + blocks: [ + { + slug: 'block', + fields: [ + { + type: 'relationship', + name: 'hasMany', + relationTo: 'rels', + hasMany: true, + }, + { + type: 'relationship', + name: 'hasOne', + relationTo: 'rels', + }, + ], + }, + ], + }, + ], }, CustomID, UsersCollection, diff --git a/test/select/int.spec.ts b/test/select/int.spec.ts index d1bb588029d..5ae8d5c9637 100644 --- a/test/select/int.spec.ts +++ b/test/select/int.spec.ts @@ -2478,6 +2478,57 @@ describe('Select', () => { array, }) }) + + it('should properly return relationships when using select on block with depth 0', async () => { + const rel_1 = await payload.create({ collection: 'rels', data: { text: 'rel-1' } }) + const doc = await payload.create({ + collection: 'relationships-blocks', + data: { + blocks: [ + { + blockType: 'block', + hasMany: [rel_1], + hasOne: rel_1, + }, + ], + }, + }) + const result = await payload.findByID({ + depth: 0, + collection: 'relationships-blocks', + id: doc.id, + select: { blocks: true }, + }) + + expect(result.blocks[0]?.hasOne).toBe(rel_1.id) + expect(result.blocks[0]?.hasMany).toEqual([rel_1.id]) + }) + + it('should populate relationships when using select on block', async () => { + const rel_1 = await payload.create({ collection: 'rels', data: { text: 'rel-1' } }) + const doc = await payload.create({ + collection: 'relationships-blocks', + data: { + blocks: [ + { + blockType: 'block', + hasMany: [rel_1], + hasOne: rel_1, + }, + ], + }, + }) + + const result = await payload.findByID({ + depth: 1, + collection: 'relationships-blocks', + id: doc.id, + select: { blocks: true }, + }) + + expect(result.blocks[0]?.hasOne.text).toBe('rel-1') + expect(result.blocks[0]?.hasMany[0].text).toBe('rel-1') + }) }) async function createPost() { diff --git a/test/select/payload-types.ts b/test/select/payload-types.ts index 7aa1b9136e5..faa0b1d0de9 100644 --- a/test/select/payload-types.ts +++ b/test/select/payload-types.ts @@ -76,6 +76,7 @@ export interface Config { 'force-select': ForceSelect; upload: Upload; rels: Rel; + 'relationships-blocks': RelationshipsBlock; 'custom-ids': CustomId; users: User; 'payload-locked-documents': PayloadLockedDocument; @@ -93,6 +94,7 @@ export interface Config { 'force-select': ForceSelectSelect | ForceSelectSelect; upload: UploadSelect | UploadSelect; rels: RelsSelect | RelsSelect; + 'relationships-blocks': RelationshipsBlocksSelect | RelationshipsBlocksSelect; 'custom-ids': CustomIdsSelect | CustomIdsSelect; users: UsersSelect | UsersSelect; 'payload-locked-documents': PayloadLockedDocumentsSelect | PayloadLockedDocumentsSelect; @@ -100,7 +102,7 @@ export interface Config { 'payload-migrations': PayloadMigrationsSelect | PayloadMigrationsSelect; }; db: { - defaultIDType: number; + defaultIDType: string; }; globals: { 'global-post': GlobalPost; @@ -142,7 +144,7 @@ export interface UserAuthOperations { * via the `definition` "posts". */ export interface Post { - id: number; + id: string; text?: string | null; number?: number | null; select?: ('a' | 'b') | null; @@ -182,17 +184,17 @@ export interface Post { }; unnamedTabText?: string | null; unnamedTabNumber?: number | null; - hasOne?: (number | null) | Rel; - hasMany?: (number | Rel)[] | null; - hasManyUpload?: (number | Upload)[] | null; + hasOne?: (string | null) | Rel; + hasMany?: (string | Rel)[] | null; + hasManyUpload?: (string | Upload)[] | null; hasOnePoly?: { relationTo: 'rels'; - value: number | Rel; + value: string | Rel; } | null; hasManyPoly?: | { relationTo: 'rels'; - value: number | Rel; + value: string | Rel; }[] | null; updatedAt: string; @@ -203,7 +205,8 @@ export interface Post { * via the `definition` "rels". */ export interface Rel { - id: number; + id: string; + text?: string | null; updatedAt: string; createdAt: string; } @@ -212,7 +215,7 @@ export interface Rel { * via the `definition` "upload". */ export interface Upload { - id: number; + id: string; updatedAt: string; createdAt: string; url?: string | null; @@ -230,7 +233,7 @@ export interface Upload { * via the `definition` "localized-posts". */ export interface LocalizedPost { - id: number; + id: string; text?: string | null; number?: number | null; select?: ('a' | 'b') | null; @@ -301,7 +304,7 @@ export interface LocalizedPost { * via the `definition` "versioned-posts". */ export interface VersionedPost { - id: number; + id: string; text?: string | null; number?: number | null; array?: @@ -327,7 +330,7 @@ export interface VersionedPost { * via the `definition` "deep-posts". */ export interface DeepPost { - id: number; + id: string; group?: { array?: | { @@ -369,22 +372,22 @@ export interface DeepPost { * via the `definition` "pages". */ export interface Page { - id: number; - relatedPage?: (number | null) | Page; + id: string; + relatedPage?: (string | null) | Page; content?: | { title: string; link: { docPoly?: { relationTo: 'pages'; - value: number | Page; + value: string | Page; } | null; - doc?: (number | null) | Page; - docMany?: (number | Page)[] | null; + doc?: (string | null) | Page; + docMany?: (string | Page)[] | null; docHasManyPoly?: | { relationTo: 'pages'; - value: number | Page; + value: string | Page; }[] | null; label: string; @@ -393,7 +396,7 @@ export interface Page { root: { type: string; children: { - type: string; + type: any; version: number; [k: string]: unknown; }[]; @@ -440,7 +443,7 @@ export interface Page { * via the `definition` "points". */ export interface Point { - id: number; + id: string; text?: string | null; /** * @minItems 2 @@ -455,7 +458,7 @@ export interface Point { * via the `definition` "force-select". */ export interface ForceSelect { - id: number; + id: string; text?: string | null; forceSelected?: string | null; array?: @@ -467,6 +470,24 @@ export interface ForceSelect { updatedAt: string; createdAt: string; } +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "relationships-blocks". + */ +export interface RelationshipsBlock { + id: string; + blocks?: + | { + hasMany?: (string | Rel)[] | null; + hasOne?: (string | null) | Rel; + id?: string | null; + blockName?: string | null; + blockType: 'block'; + }[] + | null; + updatedAt: string; + createdAt: string; +} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "custom-ids". @@ -482,7 +503,7 @@ export interface CustomId { * via the `definition` "users". */ export interface User { - id: number; + id: string; name?: string | null; number?: number | null; updatedAt: string; @@ -508,43 +529,47 @@ export interface User { * via the `definition` "payload-locked-documents". */ export interface PayloadLockedDocument { - id: number; + id: string; document?: | ({ relationTo: 'posts'; - value: number | Post; + value: string | Post; } | null) | ({ relationTo: 'localized-posts'; - value: number | LocalizedPost; + value: string | LocalizedPost; } | null) | ({ relationTo: 'versioned-posts'; - value: number | VersionedPost; + value: string | VersionedPost; } | null) | ({ relationTo: 'deep-posts'; - value: number | DeepPost; + value: string | DeepPost; } | null) | ({ relationTo: 'pages'; - value: number | Page; + value: string | Page; } | null) | ({ relationTo: 'points'; - value: number | Point; + value: string | Point; } | null) | ({ relationTo: 'force-select'; - value: number | ForceSelect; + value: string | ForceSelect; } | null) | ({ relationTo: 'upload'; - value: number | Upload; + value: string | Upload; } | null) | ({ relationTo: 'rels'; - value: number | Rel; + value: string | Rel; + } | null) + | ({ + relationTo: 'relationships-blocks'; + value: string | RelationshipsBlock; } | null) | ({ relationTo: 'custom-ids'; @@ -552,12 +577,12 @@ export interface PayloadLockedDocument { } | null) | ({ relationTo: 'users'; - value: number | User; + value: string | User; } | null); globalSlug?: string | null; user: { relationTo: 'users'; - value: number | User; + value: string | User; }; updatedAt: string; createdAt: string; @@ -567,10 +592,10 @@ export interface PayloadLockedDocument { * via the `definition` "payload-preferences". */ export interface PayloadPreference { - id: number; + id: string; user: { relationTo: 'users'; - value: number | User; + value: string | User; }; key?: string | null; value?: @@ -590,7 +615,7 @@ export interface PayloadPreference { * via the `definition` "payload-migrations". */ export interface PayloadMigration { - id: number; + id: string; name?: string | null; batch?: number | null; updatedAt: string; @@ -908,6 +933,27 @@ export interface UploadSelect { * via the `definition` "rels_select". */ export interface RelsSelect { + text?: T; + updatedAt?: T; + createdAt?: T; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "relationships-blocks_select". + */ +export interface RelationshipsBlocksSelect { + blocks?: + | T + | { + block?: + | T + | { + hasMany?: T; + hasOne?: T; + id?: T; + blockName?: T; + }; + }; updatedAt?: T; createdAt?: T; } @@ -982,7 +1028,7 @@ export interface PayloadMigrationsSelect { * via the `definition` "global-post". */ export interface GlobalPost { - id: number; + id: string; text?: string | null; number?: number | null; updatedAt?: string | null; @@ -993,7 +1039,7 @@ export interface GlobalPost { * via the `definition` "force-select-global". */ export interface ForceSelectGlobal { - id: number; + id: string; text?: string | null; forceSelected?: string | null; array?: