test: add types testing for select and joins (#11138)

Adds additional type testing for `select` and `joins` Local API
properties to ensure we don't break those between changes
This commit is contained in:
Sasha
2025-02-13 18:11:31 +02:00
committed by GitHub
parent cd1117515b
commit 4be410cc4f
3 changed files with 199 additions and 2 deletions

View File

@@ -18,6 +18,39 @@ export default buildConfigWithDefaults({
type: 'text', type: 'text',
name: 'text', name: 'text',
}, },
{
type: 'text',
name: 'title',
},
],
},
{
slug: 'pages',
fields: [
{
type: 'text',
name: 'title',
},
{
type: 'relationship',
relationTo: 'pages-categories',
name: 'category',
},
],
},
{
slug: 'pages-categories',
fields: [
{
type: 'text',
name: 'title',
},
{
type: 'join',
name: 'relatedPages',
collection: 'pages',
on: 'category',
},
], ],
}, },
], ],

View File

@@ -6,20 +6,82 @@
* and re-run `payload generate:types` to regenerate this file. * and re-run `payload generate:types` to regenerate this file.
*/ */
/**
* Supported timezones in IANA format.
*
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "supportedTimezones".
*/
export type SupportedTimezones =
| 'Pacific/Midway'
| 'Pacific/Niue'
| 'Pacific/Honolulu'
| 'Pacific/Rarotonga'
| 'America/Anchorage'
| 'Pacific/Gambier'
| 'America/Los_Angeles'
| 'America/Tijuana'
| 'America/Denver'
| 'America/Phoenix'
| 'America/Chicago'
| 'America/Guatemala'
| 'America/New_York'
| 'America/Bogota'
| 'America/Caracas'
| 'America/Santiago'
| 'America/Buenos_Aires'
| 'America/Sao_Paulo'
| 'Atlantic/South_Georgia'
| 'Atlantic/Azores'
| 'Atlantic/Cape_Verde'
| 'Europe/London'
| 'Europe/Berlin'
| 'Africa/Lagos'
| 'Europe/Athens'
| 'Africa/Cairo'
| 'Europe/Moscow'
| 'Asia/Riyadh'
| 'Asia/Dubai'
| 'Asia/Baku'
| 'Asia/Karachi'
| 'Asia/Tashkent'
| 'Asia/Calcutta'
| 'Asia/Dhaka'
| 'Asia/Almaty'
| 'Asia/Jakarta'
| 'Asia/Bangkok'
| 'Asia/Shanghai'
| 'Asia/Singapore'
| 'Asia/Tokyo'
| 'Asia/Seoul'
| 'Australia/Sydney'
| 'Pacific/Guam'
| 'Pacific/Noumea'
| 'Pacific/Auckland'
| 'Pacific/Fiji';
export interface Config { export interface Config {
auth: { auth: {
users: UserAuthOperations; users: UserAuthOperations;
}; };
collections: { collections: {
posts: Post; posts: Post;
pages: Page;
'pages-categories': PagesCategory;
users: User; users: User;
'payload-locked-documents': PayloadLockedDocument; 'payload-locked-documents': PayloadLockedDocument;
'payload-preferences': PayloadPreference; 'payload-preferences': PayloadPreference;
'payload-migrations': PayloadMigration; 'payload-migrations': PayloadMigration;
}; };
collectionsJoins: {}; collectionsJoins: {
'pages-categories': {
relatedPages: 'pages';
};
};
collectionsSelect: { collectionsSelect: {
posts: PostsSelect<false> | PostsSelect<true>; posts: PostsSelect<false> | PostsSelect<true>;
pages: PagesSelect<false> | PagesSelect<true>;
'pages-categories': PagesCategoriesSelect<false> | PagesCategoriesSelect<true>;
users: UsersSelect<false> | UsersSelect<true>; users: UsersSelect<false> | UsersSelect<true>;
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>; 'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>; 'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
@@ -68,6 +130,32 @@ export interface UserAuthOperations {
export interface Post { export interface Post {
id: string; id: string;
text?: string | null; text?: string | null;
title?: string | null;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "pages".
*/
export interface Page {
id: string;
title?: string | null;
category?: (string | null) | PagesCategory;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "pages-categories".
*/
export interface PagesCategory {
id: string;
title?: string | null;
relatedPages?: {
docs?: (string | Page)[] | null;
hasNextPage?: boolean | null;
} | null;
updatedAt: string; updatedAt: string;
createdAt: string; createdAt: string;
} }
@@ -99,6 +187,14 @@ export interface PayloadLockedDocument {
relationTo: 'posts'; relationTo: 'posts';
value: string | Post; value: string | Post;
} | null) } | null)
| ({
relationTo: 'pages';
value: string | Page;
} | null)
| ({
relationTo: 'pages-categories';
value: string | PagesCategory;
} | null)
| ({ | ({
relationTo: 'users'; relationTo: 'users';
value: string | User; value: string | User;
@@ -151,6 +247,27 @@ export interface PayloadMigration {
*/ */
export interface PostsSelect<T extends boolean = true> { export interface PostsSelect<T extends boolean = true> {
text?: T; text?: T;
title?: T;
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "pages_select".
*/
export interface PagesSelect<T extends boolean = true> {
title?: T;
category?: T;
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "pages-categories_select".
*/
export interface PagesCategoriesSelect<T extends boolean = true> {
title?: T;
relatedPages?: T;
updatedAt?: T; updatedAt?: T;
createdAt?: T; createdAt?: T;
} }

View File

@@ -1,10 +1,21 @@
import type { BulkOperationResult, PaginatedDocs, SelectType, TypeWithVersion } from 'payload' import type {
BulkOperationResult,
JoinQuery,
PaginatedDocs,
SelectType,
TypeWithVersion,
Where,
} from 'payload'
import payload from 'payload' import payload from 'payload'
import { describe, expect, test } from 'tstyche' import { describe, expect, test } from 'tstyche'
import type { Menu, Post, User } from './payload-types.js' import type { Menu, Post, User } from './payload-types.js'
const asType = <T>() => {
return '' as T
}
describe('Types testing', () => { describe('Types testing', () => {
test('payload.find', () => { test('payload.find', () => {
expect(payload.find({ collection: 'users' })).type.toBe<Promise<PaginatedDocs<User>>>() expect(payload.find({ collection: 'users' })).type.toBe<Promise<PaginatedDocs<User>>>()
@@ -77,4 +88,40 @@ describe('Types testing', () => {
Promise<TypeWithVersion<Menu>> Promise<TypeWithVersion<Menu>>
>() >()
}) })
describe('select', () => {
test('should include only ID if select is an empty object', () => {
expect(payload.findByID({ collection: 'posts', id: 'id', select: {} })).type.toBe<
Promise<{ id: Post['id'] }>
>()
})
test('should include only title and ID', () => {
expect(
payload.findByID({ collection: 'posts', id: 'id', select: { title: true } }),
).type.toBe<Promise<{ id: Post['id']; title?: Post['title'] }>>()
})
test('should exclude title', () => {
expect(
payload.findByID({ collection: 'posts', id: 'id', select: { title: false } }),
).type.toBe<Promise<Omit<Post, 'title'>>>()
})
})
describe('joins', () => {
test('join query for pages should have type never as pages does not define any joins', () => {
expect(asType<JoinQuery<'pages'>>()).type.toBe<never>()
})
test('join query for pages-categories should be defined with the relatedPages key', () => {
expect(asType<JoinQuery<'pages-categories'>>()).type.toBeAssignableWith<{
relatedPages?: {
limit?: number
sort?: string
where?: Where
}
}>()
})
})
}) })