diff --git a/packages/payload/src/uploads/types.ts b/packages/payload/src/uploads/types.ts index 729c40e0329..69f7317b3c7 100644 --- a/packages/payload/src/uploads/types.ts +++ b/packages/payload/src/uploads/types.ts @@ -12,6 +12,15 @@ export type FileSize = { width: null | number } +/** + * FileSize_P4 is a more precise type, and will replace FileSize in Payload v4. + * I am not encouraging users to use this type via tsdoc yet, in case we find more breaking changes to do prior to v4. + * @internal + */ +export type FileSize_P4 = { + url: null | string +} & FileSize + export type FileSizes = { [size: string]: FileSize } diff --git a/packages/richtext-lexical/src/exports/react/components/RichText/converter/converters/upload.tsx b/packages/richtext-lexical/src/exports/react/components/RichText/converter/converters/upload.tsx index 59b724c604c..0eebaceb2f1 100644 --- a/packages/richtext-lexical/src/exports/react/components/RichText/converter/converters/upload.tsx +++ b/packages/richtext-lexical/src/exports/react/components/RichText/converter/converters/upload.tsx @@ -1,23 +1,25 @@ -import type { FileData, FileSize, TypeWithID } from 'payload' +import type { FileSize_P4 } from 'payload' +import type { UploadData_P4 } from '../../../../../../features/upload/server/nodes/UploadNode.js' import type { SerializedUploadNode } from '../../../../../../nodeTypes.js' import type { JSXConverters } from '../types.js' export const UploadJSXConverter: JSXConverters = { upload: ({ node }) => { - const uploadDocument: { - value?: FileData & TypeWithID - } = node as any - - const url = uploadDocument?.value?.url + // TO-DO (v4): SerializedUploadNode should use UploadData_P4 + const uploadDocument = node as UploadData_P4 + if (typeof uploadDocument.value !== 'object') { + return null + } + const url = uploadDocument.value.url /** * If the upload is not an image, return a link to the upload */ - if (!uploadDocument?.value?.mimeType?.startsWith('image')) { + if (!uploadDocument.value.mimeType.startsWith('image')) { return ( - {uploadDocument.value?.filename} + {uploadDocument.value.filename} ) } @@ -25,13 +27,13 @@ export const UploadJSXConverter: JSXConverters = { /** * If the upload is a simple image with no different sizes, return a simple img tag */ - if (!uploadDocument?.value?.sizes || !Object.keys(uploadDocument?.value?.sizes).length) { + if (!Object.keys(uploadDocument.value.sizes).length) { return ( {uploadDocument?.value?.filename} ) } @@ -42,13 +44,12 @@ export const UploadJSXConverter: JSXConverters = { const pictureJSX: React.ReactNode[] = [] // Iterate through each size in the data.sizes object - for (const size in uploadDocument.value?.sizes) { - const imageSize: { - url?: string - } & FileSize = uploadDocument.value?.sizes[size] + for (const size in uploadDocument.value.sizes) { + const imageSize = uploadDocument.value.sizes[size] as FileSize_P4 // Skip if any property of the size object is null if ( + !imageSize || !imageSize.width || !imageSize.height || !imageSize.mimeType || diff --git a/packages/richtext-lexical/src/features/upload/server/nodes/UploadNode.tsx b/packages/richtext-lexical/src/features/upload/server/nodes/UploadNode.tsx index 95875fcc8bb..688d2aa295d 100644 --- a/packages/richtext-lexical/src/features/upload/server/nodes/UploadNode.tsx +++ b/packages/richtext-lexical/src/features/upload/server/nodes/UploadNode.tsx @@ -8,7 +8,7 @@ import type { NodeKey, Spread, } from 'lexical' -import type { CollectionSlug, DataFromCollectionSlug, JsonObject } from 'payload' +import type { FileData, JsonObject, TypedCollection, TypeWithID } from 'payload' import type { JSX } from 'react' import { DecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode.js' @@ -17,15 +17,27 @@ import { $applyNodeReplacement } from 'lexical' import * as React from 'react' export type UploadData = { - [TCollectionSlug in CollectionSlug]: { - fields: TUploadExtraFieldsData - // Every lexical node that has sub-fields needs to have a unique ID. This is the ID of this upload node, not the ID of the linked upload document - id: string - relationTo: TCollectionSlug - // Value can be just the document ID, or the full, populated document - value: DataFromCollectionSlug | number | string - } -}[CollectionSlug] + fields: TUploadExtraFieldsData + /** Every lexical node that has sub-fields needs to have a unique ID. This is the ID of this upload node, not the ID of the linked upload document */ + id: string + relationTo: string + /** Value can be just the document ID, or the full, populated document */ + value: number | string | TypedCollection +} + +/** + * UploadData_P4 is a more precise type, and will replace UploadData in Payload v4. + * I am not encouraging users to use this type via tsdoc yet, in case we find more breaking changes to do prior to v4. + * @internal + */ +export type UploadData_P4 = { + fields: TUploadExtraFieldsData + // Every lexical node that has sub-fields needs to have a unique ID. This is the ID of this upload node, not the ID of the linked upload document + id: string + relationTo: string + // Value can be just the document ID, or the full, populated document + value: (FileData & TypeWithID) | number | string +} export function isGoogleDocCheckboxImg(img: HTMLImageElement): boolean { return (