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:
@@ -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',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}>()
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user