Files
payloadcms/test/types/types.spec.ts
T. R. Bernstein 4a5f01a78f
Some checks failed
ci / changes (push) Has been cancelled
ci / lint (push) Has been cancelled
ci / build (push) Has been cancelled
ci / tests-unit (push) Has been cancelled
ci / tests-types (push) Has been cancelled
ci / int-cosmosdb (push) Has been cancelled
ci / int-documentdb (push) Has been cancelled
ci / int-firestore (push) Has been cancelled
ci / int-mongodb (push) Has been cancelled
ci / int-postgres (push) Has been cancelled
ci / int-postgres-custom-schema (push) Has been cancelled
ci / int-postgres-uuid (push) Has been cancelled
ci / int-sqlite (push) Has been cancelled
ci / int-sqlite-uuid (push) Has been cancelled
ci / int-supabase (push) Has been cancelled
ci / e2e-_community (push) Has been cancelled
ci / e2e-access-control (push) Has been cancelled
ci / e2e-admin-bar (push) Has been cancelled
ci / e2e-admin-root (push) Has been cancelled
ci / e2e-admin__e2e__document-view (push) Has been cancelled
ci / e2e-admin__e2e__general (push) Has been cancelled
ci / e2e-admin__e2e__list-view (push) Has been cancelled
ci / e2e-auth (push) Has been cancelled
ci / e2e-auth-basic (push) Has been cancelled
ci / e2e-bulk-edit (push) Has been cancelled
ci / e2e-field-error-states (push) Has been cancelled
ci / e2e-fields-relationship (push) Has been cancelled
ci / e2e-fields__collections__Array (push) Has been cancelled
ci / e2e-fields__collections__Blocks#config.blockreferences.ts (push) Has been cancelled
ci / e2e-fields__collections__Blocks (push) Has been cancelled
ci / e2e-fields__collections__Checkbox (push) Has been cancelled
ci / e2e-fields__collections__Collapsible (push) Has been cancelled
ci / e2e-fields__collections__ConditionalLogic (push) Has been cancelled
ci / e2e-fields__collections__CustomID (push) Has been cancelled
ci / e2e-fields__collections__Date (push) Has been cancelled
ci / e2e-fields__collections__Email (push) Has been cancelled
ci / e2e-fields__collections__Indexed (push) Has been cancelled
ci / e2e-fields__collections__JSON (push) Has been cancelled
ci / e2e-fields__collections__Number (push) Has been cancelled
ci / e2e-fields__collections__Point (push) Has been cancelled
ci / e2e-fields__collections__Radio (push) Has been cancelled
ci / e2e-fields__collections__Relationship (push) Has been cancelled
ci / e2e-fields__collections__Row (push) Has been cancelled
ci / e2e-fields__collections__Select (push) Has been cancelled
ci / e2e-fields__collections__Tabs (push) Has been cancelled
ci / e2e-fields__collections__Tabs2 (push) Has been cancelled
ci / e2e-fields__collections__Text (push) Has been cancelled
ci / e2e-fields__collections__UI (push) Has been cancelled
ci / e2e-fields__collections__Upload (push) Has been cancelled
ci / e2e-folders (push) Has been cancelled
ci / e2e-form-state (push) Has been cancelled
ci / e2e-group-by (push) Has been cancelled
ci / e2e-hooks (push) Has been cancelled
ci / e2e-i18n (push) Has been cancelled
ci / e2e-joins (push) Has been cancelled
ci / e2e-lexical__collections__LexicalHeadingFeature (push) Has been cancelled
ci / e2e-lexical__collections__LexicalJSXConverter (push) Has been cancelled
ci / e2e-lexical__collections__LexicalLinkFeature (push) Has been cancelled
ci / e2e-lexical__collections__Lexical__e2e__blocks#config.blockreferences.ts (push) Has been cancelled
ci / e2e-lexical__collections__Lexical__e2e__blocks (push) Has been cancelled
ci / e2e-lexical__collections__Lexical__e2e__main (push) Has been cancelled
ci / e2e-lexical__collections__OnDemandForm (push) Has been cancelled
ci / e2e-lexical__collections__RichText (push) Has been cancelled
ci / e2e-lexical__collections___LexicalFullyFeatured (push) Has been cancelled
ci / e2e-lexical__collections___LexicalFullyFeatured__db (push) Has been cancelled
ci / e2e-live-preview (push) Has been cancelled
ci / e2e-localization (push) Has been cancelled
ci / e2e-locked-documents (push) Has been cancelled
ci / e2e-plugin-cloud-storage (push) Has been cancelled
ci / e2e-plugin-form-builder (push) Has been cancelled
ci / e2e-plugin-import-export (push) Has been cancelled
ci / e2e-plugin-multi-tenant (push) Has been cancelled
ci / e2e-plugin-nested-docs (push) Has been cancelled
ci / e2e-plugin-seo (push) Has been cancelled
ci / e2e-query-presets (push) Has been cancelled
ci / e2e-sort (push) Has been cancelled
ci / e2e-trash (push) Has been cancelled
ci / e2e-uploads (push) Has been cancelled
ci / e2e-versions (push) Has been cancelled
ci / e2e-turbo-_community (push) Has been cancelled
ci / e2e-turbo-access-control (push) Has been cancelled
ci / e2e-turbo-admin-bar (push) Has been cancelled
ci / e2e-turbo-admin-root (push) Has been cancelled
ci / e2e-turbo-admin__e2e__document-view (push) Has been cancelled
ci / e2e-turbo-admin__e2e__general (push) Has been cancelled
ci / e2e-turbo-admin__e2e__list-view (push) Has been cancelled
ci / e2e-turbo-auth (push) Has been cancelled
ci / e2e-turbo-auth-basic (push) Has been cancelled
ci / e2e-turbo-bulk-edit (push) Has been cancelled
ci / e2e-turbo-field-error-states (push) Has been cancelled
ci / e2e-turbo-fields-relationship (push) Has been cancelled
ci / e2e-turbo-fields__collections__Array (push) Has been cancelled
ci / e2e-turbo-fields__collections__Blocks#config.blockreferences.ts (push) Has been cancelled
ci / e2e-turbo-fields__collections__Blocks (push) Has been cancelled
ci / e2e-turbo-fields__collections__Checkbox (push) Has been cancelled
ci / e2e-turbo-fields__collections__Collapsible (push) Has been cancelled
ci / e2e-turbo-fields__collections__ConditionalLogic (push) Has been cancelled
ci / e2e-turbo-fields__collections__CustomID (push) Has been cancelled
ci / e2e-turbo-fields__collections__Date (push) Has been cancelled
ci / e2e-turbo-fields__collections__Email (push) Has been cancelled
ci / e2e-turbo-fields__collections__Indexed (push) Has been cancelled
ci / e2e-turbo-fields__collections__JSON (push) Has been cancelled
ci / e2e-turbo-fields__collections__Number (push) Has been cancelled
ci / e2e-turbo-fields__collections__Point (push) Has been cancelled
ci / e2e-turbo-fields__collections__Radio (push) Has been cancelled
ci / e2e-turbo-fields__collections__Relationship (push) Has been cancelled
ci / e2e-turbo-fields__collections__Row (push) Has been cancelled
ci / e2e-turbo-fields__collections__Select (push) Has been cancelled
ci / e2e-turbo-fields__collections__Tabs (push) Has been cancelled
ci / e2e-turbo-fields__collections__Tabs2 (push) Has been cancelled
ci / e2e-turbo-fields__collections__Text (push) Has been cancelled
ci / e2e-turbo-fields__collections__UI (push) Has been cancelled
ci / e2e-turbo-fields__collections__Upload (push) Has been cancelled
ci / e2e-turbo-folders (push) Has been cancelled
ci / e2e-turbo-form-state (push) Has been cancelled
ci / e2e-turbo-group-by (push) Has been cancelled
ci / e2e-turbo-hooks (push) Has been cancelled
ci / e2e-turbo-i18n (push) Has been cancelled
ci / e2e-turbo-joins (push) Has been cancelled
ci / e2e-turbo-lexical__collections__LexicalHeadingFeature (push) Has been cancelled
ci / e2e-turbo-lexical__collections__LexicalJSXConverter (push) Has been cancelled
ci / e2e-turbo-lexical__collections__LexicalLinkFeature (push) Has been cancelled
ci / e2e-turbo-lexical__collections__Lexical__e2e__blocks#config.blockreferences.ts (push) Has been cancelled
ci / e2e-turbo-lexical__collections__Lexical__e2e__blocks (push) Has been cancelled
ci / e2e-turbo-lexical__collections__Lexical__e2e__main (push) Has been cancelled
ci / e2e-turbo-lexical__collections__OnDemandForm (push) Has been cancelled
ci / e2e-turbo-lexical__collections__RichText (push) Has been cancelled
ci / e2e-turbo-lexical__collections___LexicalFullyFeatured (push) Has been cancelled
ci / e2e-turbo-lexical__collections___LexicalFullyFeatured__db (push) Has been cancelled
ci / e2e-turbo-live-preview (push) Has been cancelled
ci / e2e-turbo-localization (push) Has been cancelled
ci / e2e-turbo-locked-documents (push) Has been cancelled
ci / e2e-turbo-plugin-cloud-storage (push) Has been cancelled
ci / e2e-turbo-plugin-form-builder (push) Has been cancelled
ci / e2e-turbo-plugin-import-export (push) Has been cancelled
ci / e2e-turbo-plugin-multi-tenant (push) Has been cancelled
ci / e2e-turbo-plugin-nested-docs (push) Has been cancelled
ci / e2e-turbo-plugin-seo (push) Has been cancelled
ci / e2e-turbo-query-presets (push) Has been cancelled
ci / e2e-turbo-sort (push) Has been cancelled
ci / e2e-turbo-trash (push) Has been cancelled
ci / e2e-turbo-uploads (push) Has been cancelled
ci / e2e-turbo-versions (push) Has been cancelled
ci / build-template-blank-mongodb (push) Has been cancelled
ci / build-template-website-mongodb (push) Has been cancelled
ci / build-template-with-payload-cloud-mongodb (push) Has been cancelled
ci / build-template-with-vercel-mongodb-mongodb (push) Has been cancelled
ci / build-template-plugin- (push) Has been cancelled
ci / build-template-with-postgres-postgres (push) Has been cancelled
ci / build-template-with-vercel-postgres-postgres (push) Has been cancelled
ci / tests-type-generation (push) Has been cancelled
ci / All Green (push) Has been cancelled
ci / Publish Canary (push) Has been cancelled
ci / analyze (push) Has been cancelled
publish-prerelease / publish-prerelease-${{ github.ref_name }}-${{ github.sha }} (push) Has been cancelled
lock-issues / lock_issues (push) Has been cancelled
stale / stale (push) Has been cancelled
audit-dependencies / audit (push) Has been cancelled
activity-notifications / run (push) Has been cancelled
chore: Update code to new repo
2025-10-08 23:27:45 +02:00

285 lines
8.4 KiB
TypeScript

import type {
DefaultNodeTypes,
DefaultTypedEditorState,
TypedEditorState,
} from '@tabshiftcms/richtext-lexical'
import type {
BulkOperationResult,
CustomDocumentViewConfig,
DefaultDocumentViewConfig,
JoinQuery,
PaginatedDocs,
SelectType,
TypeWithVersion,
Where,
} from 'tbsh-cms'
import payload from 'tbsh-cms'
import { describe, expect, test } from 'tstyche'
import type {
Menu,
MyRadioOptions,
MySelectOptions,
Post,
SupportedTimezones,
User,
} from './payload-types.js'
const asType = <T>() => {
return '' as T
}
describe('Types testing', () => {
test('payload.find', () => {
expect(payload.find({ collection: 'users' })).type.toBe<Promise<PaginatedDocs<User>>>()
})
test('payload.findByID', () => {
expect(payload.findByID({ id: 1, collection: 'users' })).type.toBe<Promise<User>>()
})
test('payload.findByID with disableErrors: true', () => {
expect(payload.findByID({ id: 1, collection: 'users', disableErrors: true })).type.toBe<
Promise<null | User>
>()
})
test('payload.create', () => {
expect(payload.create({ collection: 'users', data: { email: 'user@email.com' } })).type.toBe<
Promise<User>
>()
})
test('payload.update by ID', () => {
expect(payload.update({ id: 1, collection: 'users', data: {} })).type.toBe<Promise<User>>()
})
test('payload.update many', () => {
expect(payload.update({ where: {}, collection: 'users', data: {} })).type.toBe<
Promise<BulkOperationResult<'users', SelectType>>
>()
})
test('payload.delete by ID', () => {
expect(payload.delete({ id: 1, collection: 'users' })).type.toBe<Promise<User>>()
})
test('payload.delete many', () => {
expect(payload.delete({ where: {}, collection: 'users' })).type.toBe<
Promise<BulkOperationResult<'users', SelectType>>
>()
})
test('payload.findGlobal', () => {
expect(payload.findGlobal({ slug: 'menu' })).type.toBe<Promise<Menu>>()
})
test('payload.updateGlobal', () => {
expect(payload.updateGlobal({ data: {}, slug: 'menu' })).type.toBe<Promise<Menu>>()
})
test('payload.findVersions', () => {
expect(payload.findVersions({ collection: 'posts' })).type.toBe<
Promise<PaginatedDocs<TypeWithVersion<Post>>>
>()
})
test('payload.findVersionByID', () => {
expect(payload.findVersionByID({ id: 'id', collection: 'posts' })).type.toBe<
Promise<TypeWithVersion<Post>>
>()
})
test('payload.findGlobalVersions', () => {
expect(payload.findGlobalVersions({ slug: 'menu' })).type.toBe<
Promise<PaginatedDocs<TypeWithVersion<Menu>>>
>()
})
test('payload.findGlobalVersionByID', () => {
expect(payload.findGlobalVersionByID({ id: 'id', slug: 'menu' })).type.toBe<
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
}
}>()
})
})
describe('generated types', () => {
test('has SupportedTimezones', () => {
expect<SupportedTimezones>().type.toBeAssignableTo<string>()
})
test('has global generated options interface based on select field', () => {
expect(asType<Post['selectField']>()).type.toBe<MySelectOptions>()
})
test('has global generated options interface based on radio field', () => {
expect(asType<Post['radioField']>()).type.toBe<MyRadioOptions>()
})
})
describe('fields', () => {
describe('Group', () => {
test('correctly ignores unnamed group', () => {
expect<Post>().type.toHaveProperty('insideUnnamedGroup')
})
test('generates nested group name', () => {
expect<Post>().type.toHaveProperty('namedGroup')
expect<NonNullable<Post['namedGroup']>>().type.toHaveProperty('insideNamedGroup')
})
})
})
describe('views', () => {
test('default view config', () => {
expect<DefaultDocumentViewConfig>().type.not.toBeAssignableWith<{
path: `/${string}`
}>()
expect<CustomDocumentViewConfig>().type.toBeAssignableWith<{
Component: string
path: `/${string}`
}>()
})
})
describe('lexical', () => {
type _Hardcoded_DefaultNodeTypes =
| 'autolink'
| 'heading'
| 'horizontalrule'
| 'linebreak'
| 'link'
| 'list'
| 'listitem'
| 'paragraph'
| 'quote'
| 'relationship'
| 'tab'
| 'text'
| 'upload'
test('ensure TypedEditorState node type without generic is string', () => {
expect<TypedEditorState['root']['children'][number]['type']>().type.toBe<string>()
})
test('ensure TypedEditorState<1 generic> node type is correct', () => {
expect<
TypedEditorState<{
type: 'custom-node'
version: 1
}>['root']['children'][number]['type']
>().type.toBe<'custom-node'>()
})
test('ensure TypedEditorState<2 generics> node type is correct', () => {
expect<
TypedEditorState<
| {
type: 'custom-node'
version: 1
}
| {
type: 'custom-node-2'
version: 1
}
>['root']['children'][number]['type']
>().type.toBe<'custom-node' | 'custom-node-2'>()
})
test('ensure DefaultTypedEditorState node type is a union of all possible node types', () => {
expect<
DefaultTypedEditorState['root']['children'][number]['type']
>().type.toBe<_Hardcoded_DefaultNodeTypes>()
})
test('ensure TypedEditorState<DefaultNodeTypes> node type is identical to DefaultTypedEditorState', () => {
expect<
TypedEditorState<DefaultNodeTypes>['root']['children'][number]['type']
>().type.toBe<_Hardcoded_DefaultNodeTypes>()
})
test('ensure DefaultTypedEditorState<custom node> adds custom node type to union of default nodes', () => {
expect<
DefaultTypedEditorState<{
type: 'custom-node'
version: 1
}>['root']['children'][number]['type']
>().type.toBe<'custom-node' | _Hardcoded_DefaultNodeTypes>()
})
test('ensure DefaultTypedEditorState<multiple custom nodes> adds custom node types to union of default nodes', () => {
expect<
DefaultTypedEditorState<
| {
type: 'custom-node'
version: 1
}
| {
type: 'custom-node-2'
version: 1
}
>['root']['children'][number]['type']
>().type.toBe<'custom-node' | 'custom-node-2' | _Hardcoded_DefaultNodeTypes>()
})
test("ensure link node automatically narrows type so that node accepts fields property if type === 'link' is checked", () => {
type NodeType = DefaultTypedEditorState['root']['children'][number]
const node = {
type: 'link',
} as NodeType
if (node.type === 'link') {
expect(node).type.toHaveProperty('fields')
} else {
expect(node).type.not.toHaveProperty('fields')
}
})
test('ensure generated richText types can be assigned to DefaultTypedEditorState type', () => {
// If there is a function that expects DefaultTypedEditorState, you should be able to assign the generated type to it
// This ensures that data can be passed directly form the payload local API to a function that expects DefaultTypedEditorState
type GeneratedRichTextType = Post['richText']
expect<DefaultTypedEditorState>().type.toBeAssignableWith<GeneratedRichTextType>()
})
})
})