diff --git a/docs/upload/overview.mdx b/docs/upload/overview.mdx index 07adf66bb..2c8218eba 100644 --- a/docs/upload/overview.mdx +++ b/docs/upload/overview.mdx @@ -116,6 +116,7 @@ _An asterisk denotes that an option is required._ | **`withMetadata`** | If specified, appends metadata to the output image file. Accepts a boolean or a function that receives `metadata` and `req`, returning a boolean. | | **`hideFileInputOnCreate`** | Set to `true` to prevent the admin UI from showing file inputs during document creation, useful for programmatic file generation. | | **`hideRemoveFile`** | Set to `true` to prevent the admin UI having a way to remove an existing file while editing. | +| **`modifyResponseHeaders`** | Accepts an object with existing `headers` and allows you to manipulate the response headers for media files. [More](#modifying-response-headers) | ### Payload-wide Upload Options @@ -453,7 +454,7 @@ To fetch files from **restricted URLs** that would otherwise be blocked by CORS, Here’s how to configure the pasteURL option to control remote URL fetching: -``` +```ts import type { CollectionConfig } from 'payload' export const Media: CollectionConfig = { @@ -466,7 +467,7 @@ export const Media: CollectionConfig = { pathname: '', port: '', protocol: 'https', - search: '' + search: '', }, { hostname: 'example.com', @@ -519,3 +520,44 @@ _An asterisk denotes that an option is required._ ## Access Control All files that are uploaded to each Collection automatically support the `read` [Access Control](/docs/access-control/overview) function from the Collection itself. You can use this to control who should be allowed to see your uploads, and who should not. + +## Modifying response headers + +You can modify the response headers for files by specifying the `modifyResponseHeaders` option in your upload config. This option accepts an object with existing headers and allows you to manipulate the response headers for media files. + +### Modifying existing headers + +With this method you can directly interface with the `Headers` object and modify the existing headers to append or remove headers. + +```ts +import type { CollectionConfig } from 'payload' + +export const Media: CollectionConfig = { + slug: 'media', + upload: { + modifyResponseHeaders: ({ headers }) => { + headers.set('X-Frame-Options', 'DENY') // You can directly set headers without returning + }, + }, +} +``` + +### Return new headers + +You can also return a new `Headers` object with the modified headers. This is useful if you want to set new headers or remove existing ones. + +```ts +import type { CollectionConfig } from 'payload' + +export const Media: CollectionConfig = { + slug: 'media', + upload: { + modifyResponseHeaders: ({ headers }) => { + const newHeaders = new Headers(headers) // Copy existing headers + newHeaders.set('X-Frame-Options', 'DENY') // Set new header + + return newHeaders + }, + }, +} +``` diff --git a/packages/payload/src/uploads/endpoints/getFile.ts b/packages/payload/src/uploads/endpoints/getFile.ts index 69a3bfea1..e7b39c079 100644 --- a/packages/payload/src/uploads/endpoints/getFile.ts +++ b/packages/payload/src/uploads/endpoints/getFile.ts @@ -38,9 +38,12 @@ export const getFileHandler: PayloadHandler = async (req) => { if (collection.config.upload.handlers?.length) { let customResponse: null | Response | void = null + const headers = new Headers() + for (const handler of collection.config.upload.handlers) { customResponse = await handler(req, { doc: accessResult, + headers, params: { collection: collection.config.slug, filename, @@ -95,7 +98,7 @@ export const getFileHandler: PayloadHandler = async (req) => { headers.set('Content-Type', fileTypeResult.mime) headers.set('Content-Length', stats.size + '') headers = collection.config.upload?.modifyResponseHeaders - ? collection.config.upload.modifyResponseHeaders({ headers }) + ? collection.config.upload.modifyResponseHeaders({ headers }) || headers : headers return new Response(data, { diff --git a/packages/payload/src/uploads/types.ts b/packages/payload/src/uploads/types.ts index 5674f5588..ff4963833 100644 --- a/packages/payload/src/uploads/types.ts +++ b/packages/payload/src/uploads/types.ts @@ -211,6 +211,7 @@ export type UploadConfig = { req: PayloadRequest, args: { doc: TypeWithID + headers?: Headers params: { clientUploadContext?: unknown; collection: string; filename: string } }, ) => Promise | Promise | Response | void)[] @@ -233,7 +234,7 @@ export type UploadConfig = { * Ability to modify the response headers fetching a file. * @default undefined */ - modifyResponseHeaders?: ({ headers }: { headers: Headers }) => Headers + modifyResponseHeaders?: ({ headers }: { headers: Headers }) => Headers | void /** * Controls the behavior of pasting/uploading files from URLs. * If set to `false`, fetching from remote URLs is disabled. diff --git a/packages/plugin-cloud-storage/src/types.ts b/packages/plugin-cloud-storage/src/types.ts index 8558ccf72..8b8823113 100644 --- a/packages/plugin-cloud-storage/src/types.ts +++ b/packages/plugin-cloud-storage/src/types.ts @@ -58,6 +58,7 @@ export type StaticHandler = ( req: PayloadRequest, args: { doc?: TypeWithID + headers?: Headers params: { clientUploadContext?: unknown; collection: string; filename: string } }, ) => Promise | Response diff --git a/packages/storage-azure/src/staticHandler.ts b/packages/storage-azure/src/staticHandler.ts index 915c7de94..625b4640d 100644 --- a/packages/storage-azure/src/staticHandler.ts +++ b/packages/storage-azure/src/staticHandler.ts @@ -14,7 +14,7 @@ interface Args { } export const getHandler = ({ collection, getStorageClient }: Args): StaticHandler => { - return async (req, { params: { clientUploadContext, filename } }) => { + return async (req, { headers: incomingHeaders, params: { clientUploadContext, filename } }) => { try { const prefix = await getFilePrefix({ clientUploadContext, collection, filename, req }) const blockBlobClient = getStorageClient().getBlockBlobClient( @@ -30,14 +30,34 @@ export const getHandler = ({ collection, getStorageClient }: Args): StaticHandle const response = blob._response + let initHeaders: Headers = { + ...(response.headers.rawHeaders() as unknown as Headers), + } + + // Typescript is difficult here with merging these types from Azure + if (incomingHeaders) { + initHeaders = { + ...initHeaders, + ...incomingHeaders, + } + } + + let headers = new Headers(initHeaders) + const etagFromHeaders = req.headers.get('etag') || req.headers.get('if-none-match') const objectEtag = response.headers.get('etag') + if ( + collection.upload && + typeof collection.upload === 'object' && + typeof collection.upload.modifyResponseHeaders === 'function' + ) { + headers = collection.upload.modifyResponseHeaders({ headers }) || headers + } + if (etagFromHeaders && etagFromHeaders === objectEtag) { return new Response(null, { - headers: new Headers({ - ...response.headers.rawHeaders(), - }), + headers, status: 304, }) } @@ -63,7 +83,7 @@ export const getHandler = ({ collection, getStorageClient }: Args): StaticHandle }) return new Response(readableStream, { - headers: response.headers.rawHeaders(), + headers, status: response.status, }) } catch (err: unknown) { diff --git a/packages/storage-gcs/src/staticHandler.ts b/packages/storage-gcs/src/staticHandler.ts index 258fee971..bceb1b730 100644 --- a/packages/storage-gcs/src/staticHandler.ts +++ b/packages/storage-gcs/src/staticHandler.ts @@ -12,7 +12,7 @@ interface Args { } export const getHandler = ({ bucket, collection, getStorageClient }: Args): StaticHandler => { - return async (req, { params: { clientUploadContext, filename } }) => { + return async (req, { headers: incomingHeaders, params: { clientUploadContext, filename } }) => { try { const prefix = await getFilePrefix({ clientUploadContext, collection, filename, req }) const file = getStorageClient().bucket(bucket).file(path.posix.join(prefix, filename)) @@ -22,13 +22,23 @@ export const getHandler = ({ bucket, collection, getStorageClient }: Args): Stat const etagFromHeaders = req.headers.get('etag') || req.headers.get('if-none-match') const objectEtag = metadata.etag + let headers = new Headers(incomingHeaders) + + headers.append('Content-Length', String(metadata.size)) + headers.append('Content-Type', String(metadata.contentType)) + headers.append('ETag', String(metadata.etag)) + + if ( + collection.upload && + typeof collection.upload === 'object' && + typeof collection.upload.modifyResponseHeaders === 'function' + ) { + headers = collection.upload.modifyResponseHeaders({ headers }) || headers + } + if (etagFromHeaders && etagFromHeaders === objectEtag) { return new Response(null, { - headers: new Headers({ - 'Content-Length': String(metadata.size), - 'Content-Type': String(metadata.contentType), - ETag: String(metadata.etag), - }), + headers, status: 304, }) } @@ -50,11 +60,7 @@ export const getHandler = ({ bucket, collection, getStorageClient }: Args): Stat }) return new Response(readableStream, { - headers: new Headers({ - 'Content-Length': String(metadata.size), - 'Content-Type': String(metadata.contentType), - ETag: String(metadata.etag), - }), + headers, status: 200, }) } catch (err: unknown) { diff --git a/packages/storage-s3/src/staticHandler.ts b/packages/storage-s3/src/staticHandler.ts index 2f068fd65..08d528eca 100644 --- a/packages/storage-s3/src/staticHandler.ts +++ b/packages/storage-s3/src/staticHandler.ts @@ -61,7 +61,7 @@ export const getHandler = ({ getStorageClient, signedDownloads, }: Args): StaticHandler => { - return async (req, { params: { clientUploadContext, filename } }) => { + return async (req, { headers: incomingHeaders, params: { clientUploadContext, filename } }) => { let object: AWS.GetObjectOutput | undefined = undefined try { const prefix = await getFilePrefix({ clientUploadContext, collection, filename, req }) @@ -94,17 +94,31 @@ export const getHandler = ({ Key: key, }) + if (!object.Body) { + return new Response(null, { status: 404, statusText: 'Not Found' }) + } + + let headers = new Headers(incomingHeaders) + + headers.append('Content-Length', String(object.ContentLength)) + headers.append('Content-Type', String(object.ContentType)) + headers.append('Accept-Ranges', String(object.AcceptRanges)) + headers.append('ETag', String(object.ETag)) + const etagFromHeaders = req.headers.get('etag') || req.headers.get('if-none-match') const objectEtag = object.ETag + if ( + collection.upload && + typeof collection.upload === 'object' && + typeof collection.upload.modifyResponseHeaders === 'function' + ) { + headers = collection.upload.modifyResponseHeaders({ headers }) || headers + } + if (etagFromHeaders && etagFromHeaders === objectEtag) { return new Response(null, { - headers: new Headers({ - 'Accept-Ranges': String(object.AcceptRanges), - 'Content-Length': String(object.ContentLength), - 'Content-Type': String(object.ContentType), - ETag: String(object.ETag), - }), + headers, status: 304, }) } @@ -125,12 +139,7 @@ export const getHandler = ({ const bodyBuffer = await streamToBuffer(object.Body) return new Response(bodyBuffer, { - headers: new Headers({ - 'Accept-Ranges': String(object.AcceptRanges), - 'Content-Length': String(object.ContentLength), - 'Content-Type': String(object.ContentType), - ETag: String(object.ETag), - }), + headers, status: 200, }) } catch (err) { diff --git a/packages/storage-uploadthing/src/staticHandler.ts b/packages/storage-uploadthing/src/staticHandler.ts index 3321184f1..a3475e7d1 100644 --- a/packages/storage-uploadthing/src/staticHandler.ts +++ b/packages/storage-uploadthing/src/staticHandler.ts @@ -9,9 +9,13 @@ type Args = { } export const getHandler = ({ utApi }: Args): StaticHandler => { - return async (req, { doc, params: { clientUploadContext, collection, filename } }) => { + return async ( + req, + { doc, headers: incomingHeaders, params: { clientUploadContext, collection, filename } }, + ) => { try { let key: string + const collectionConfig = req.payload.collections[collection]?.config if ( clientUploadContext && @@ -21,7 +25,6 @@ export const getHandler = ({ utApi }: Args): StaticHandler => { ) { key = clientUploadContext.key } else { - const collectionConfig = req.payload.collections[collection]?.config let retrievedDoc = doc if (!retrievedDoc) { @@ -82,23 +85,32 @@ export const getHandler = ({ utApi }: Args): StaticHandler => { const etagFromHeaders = req.headers.get('etag') || req.headers.get('if-none-match') const objectEtag = response.headers.get('etag') + let headers = new Headers(incomingHeaders) + + headers.append('Content-Length', String(blob.size)) + headers.append('Content-Type', blob.type) + + if (objectEtag) { + headers.append('ETag', objectEtag) + } + + if ( + collectionConfig?.upload && + typeof collectionConfig.upload === 'object' && + typeof collectionConfig.upload.modifyResponseHeaders === 'function' + ) { + headers = collectionConfig.upload.modifyResponseHeaders({ headers }) || headers + } + if (etagFromHeaders && etagFromHeaders === objectEtag) { return new Response(null, { - headers: new Headers({ - 'Content-Length': String(blob.size), - 'Content-Type': blob.type, - ETag: objectEtag, - }), + headers, status: 304, }) } return new Response(blob, { - headers: new Headers({ - 'Content-Length': String(blob.size), - 'Content-Type': blob.type, - ETag: objectEtag!, - }), + headers, status: 200, }) } catch (err) { diff --git a/packages/storage-vercel-blob/src/staticHandler.ts b/packages/storage-vercel-blob/src/staticHandler.ts index 153bbb220..074443492 100644 --- a/packages/storage-vercel-blob/src/staticHandler.ts +++ b/packages/storage-vercel-blob/src/staticHandler.ts @@ -15,27 +15,36 @@ export const getStaticHandler = ( { baseUrl, cacheControlMaxAge = 0, token }: StaticHandlerArgs, collection: CollectionConfig, ): StaticHandler => { - return async (req, { params: { clientUploadContext, filename } }) => { + return async (req, { headers: incomingHeaders, params: { clientUploadContext, filename } }) => { try { const prefix = await getFilePrefix({ clientUploadContext, collection, filename, req }) const fileKey = path.posix.join(prefix, encodeURIComponent(filename)) const fileUrl = `${baseUrl}/${fileKey}` const etagFromHeaders = req.headers.get('etag') || req.headers.get('if-none-match') const blobMetadata = await head(fileUrl, { token }) - const uploadedAtString = blobMetadata.uploadedAt.toISOString() + const { contentDisposition, contentType, size, uploadedAt } = blobMetadata + const uploadedAtString = uploadedAt.toISOString() const ETag = `"${fileKey}-${uploadedAtString}"` - const { contentDisposition, contentType, size } = blobMetadata + let headers = new Headers(incomingHeaders) + + headers.append('Cache-Control', `public, max-age=${cacheControlMaxAge}`) + headers.append('Content-Disposition', contentDisposition) + headers.append('Content-Length', String(size)) + headers.append('Content-Type', contentType) + headers.append('ETag', ETag) + + if ( + collection.upload && + typeof collection.upload === 'object' && + typeof collection.upload.modifyResponseHeaders === 'function' + ) { + headers = collection.upload.modifyResponseHeaders({ headers }) || headers + } if (etagFromHeaders && etagFromHeaders === ETag) { return new Response(null, { - headers: new Headers({ - 'Cache-Control': `public, max-age=${cacheControlMaxAge}`, - 'Content-Disposition': contentDisposition, - 'Content-Length': String(size), - 'Content-Type': contentType, - ETag, - }), + headers, status: 304, }) } @@ -55,15 +64,10 @@ export const getStaticHandler = ( const bodyBuffer = await blob.arrayBuffer() + headers.append('Last-Modified', uploadedAtString) + return new Response(bodyBuffer, { - headers: new Headers({ - 'Cache-Control': `public, max-age=${cacheControlMaxAge}`, - 'Content-Disposition': contentDisposition, - 'Content-Length': String(size), - 'Content-Type': contentType, - ETag, - 'Last-Modified': blobMetadata.uploadedAt.toUTCString(), - }), + headers, status: 200, }) } catch (err: unknown) { diff --git a/test/storage-azure/collections/Media.ts b/test/storage-azure/collections/Media.ts index c5997222c..fa2bcf69a 100644 --- a/test/storage-azure/collections/Media.ts +++ b/test/storage-azure/collections/Media.ts @@ -3,6 +3,9 @@ import type { CollectionConfig } from 'payload' export const Media: CollectionConfig = { slug: 'media', upload: { + modifyResponseHeaders({ headers }) { + headers.set('X-Universal-Truth', 'Set') + }, disableLocalStorage: true, resizeOptions: { position: 'center', diff --git a/test/storage-azure/payload-types.ts b/test/storage-azure/payload-types.ts index 7311e4ebb..463543e45 100644 --- a/test/storage-azure/payload-types.ts +++ b/test/storage-azure/payload-types.ts @@ -84,7 +84,7 @@ export interface Config { 'payload-migrations': PayloadMigrationsSelect | PayloadMigrationsSelect; }; db: { - defaultIDType: string; + defaultIDType: number; }; globals: {}; globalsSelect: {}; @@ -120,7 +120,7 @@ export interface UserAuthOperations { * via the `definition` "media". */ export interface Media { - id: string; + id: number; alt?: string | null; updatedAt: string; createdAt: string; @@ -157,7 +157,7 @@ export interface Media { * via the `definition` "media-with-prefix". */ export interface MediaWithPrefix { - id: string; + id: number; prefix?: string | null; updatedAt: string; createdAt: string; @@ -176,7 +176,7 @@ export interface MediaWithPrefix { * via the `definition` "users". */ export interface User { - id: string; + id: number; updatedAt: string; createdAt: string; email: string; @@ -186,6 +186,13 @@ export interface User { hash?: string | null; loginAttempts?: number | null; lockUntil?: string | null; + sessions?: + | { + id: string; + createdAt?: string | null; + expiresAt: string; + }[] + | null; password?: string | null; } /** @@ -193,24 +200,24 @@ export interface User { * via the `definition` "payload-locked-documents". */ export interface PayloadLockedDocument { - id: string; + id: number; document?: | ({ relationTo: 'media'; - value: string | Media; + value: number | Media; } | null) | ({ relationTo: 'media-with-prefix'; - value: string | MediaWithPrefix; + value: number | MediaWithPrefix; } | null) | ({ relationTo: 'users'; - value: string | User; + value: number | User; } | null); globalSlug?: string | null; user: { relationTo: 'users'; - value: string | User; + value: number | User; }; updatedAt: string; createdAt: string; @@ -220,10 +227,10 @@ export interface PayloadLockedDocument { * via the `definition` "payload-preferences". */ export interface PayloadPreference { - id: string; + id: number; user: { relationTo: 'users'; - value: string | User; + value: number | User; }; key?: string | null; value?: @@ -243,7 +250,7 @@ export interface PayloadPreference { * via the `definition` "payload-migrations". */ export interface PayloadMigration { - id: string; + id: number; name?: string | null; batch?: number | null; updatedAt: string; @@ -323,6 +330,13 @@ export interface UsersSelect { hash?: T; loginAttempts?: T; lockUntil?: T; + sessions?: + | T + | { + id?: T; + createdAt?: T; + expiresAt?: T; + }; } /** * This interface was referenced by `Config`'s JSON-Schema diff --git a/test/storage-gcs/collections/Media.ts b/test/storage-gcs/collections/Media.ts index c5997222c..fa2bcf69a 100644 --- a/test/storage-gcs/collections/Media.ts +++ b/test/storage-gcs/collections/Media.ts @@ -3,6 +3,9 @@ import type { CollectionConfig } from 'payload' export const Media: CollectionConfig = { slug: 'media', upload: { + modifyResponseHeaders({ headers }) { + headers.set('X-Universal-Truth', 'Set') + }, disableLocalStorage: true, resizeOptions: { position: 'center', diff --git a/test/storage-s3/collections/Media.ts b/test/storage-s3/collections/Media.ts index c5997222c..fa2bcf69a 100644 --- a/test/storage-s3/collections/Media.ts +++ b/test/storage-s3/collections/Media.ts @@ -3,6 +3,9 @@ import type { CollectionConfig } from 'payload' export const Media: CollectionConfig = { slug: 'media', upload: { + modifyResponseHeaders({ headers }) { + headers.set('X-Universal-Truth', 'Set') + }, disableLocalStorage: true, resizeOptions: { position: 'center', diff --git a/test/storage-uploadthing/collections/Media.ts b/test/storage-uploadthing/collections/Media.ts index c5997222c..fa2bcf69a 100644 --- a/test/storage-uploadthing/collections/Media.ts +++ b/test/storage-uploadthing/collections/Media.ts @@ -3,6 +3,9 @@ import type { CollectionConfig } from 'payload' export const Media: CollectionConfig = { slug: 'media', upload: { + modifyResponseHeaders({ headers }) { + headers.set('X-Universal-Truth', 'Set') + }, disableLocalStorage: true, resizeOptions: { position: 'center', diff --git a/test/storage-uploadthing/payload-types.ts b/test/storage-uploadthing/payload-types.ts index e797a2f87..f98b3f62d 100644 --- a/test/storage-uploadthing/payload-types.ts +++ b/test/storage-uploadthing/payload-types.ts @@ -84,7 +84,7 @@ export interface Config { 'payload-migrations': PayloadMigrationsSelect | PayloadMigrationsSelect; }; db: { - defaultIDType: string; + defaultIDType: number; }; globals: {}; globalsSelect: {}; @@ -120,7 +120,7 @@ export interface UserAuthOperations { * via the `definition` "media". */ export interface Media { - id: string; + id: number; alt?: string | null; _key?: string | null; updatedAt: string; @@ -160,7 +160,7 @@ export interface Media { * via the `definition` "media-with-prefix". */ export interface MediaWithPrefix { - id: string; + id: number; updatedAt: string; createdAt: string; url?: string | null; @@ -178,7 +178,7 @@ export interface MediaWithPrefix { * via the `definition` "users". */ export interface User { - id: string; + id: number; updatedAt: string; createdAt: string; email: string; @@ -188,6 +188,13 @@ export interface User { hash?: string | null; loginAttempts?: number | null; lockUntil?: string | null; + sessions?: + | { + id: string; + createdAt?: string | null; + expiresAt: string; + }[] + | null; password?: string | null; } /** @@ -195,24 +202,24 @@ export interface User { * via the `definition` "payload-locked-documents". */ export interface PayloadLockedDocument { - id: string; + id: number; document?: | ({ relationTo: 'media'; - value: string | Media; + value: number | Media; } | null) | ({ relationTo: 'media-with-prefix'; - value: string | MediaWithPrefix; + value: number | MediaWithPrefix; } | null) | ({ relationTo: 'users'; - value: string | User; + value: number | User; } | null); globalSlug?: string | null; user: { relationTo: 'users'; - value: string | User; + value: number | User; }; updatedAt: string; createdAt: string; @@ -222,10 +229,10 @@ export interface PayloadLockedDocument { * via the `definition` "payload-preferences". */ export interface PayloadPreference { - id: string; + id: number; user: { relationTo: 'users'; - value: string | User; + value: number | User; }; key?: string | null; value?: @@ -245,7 +252,7 @@ export interface PayloadPreference { * via the `definition` "payload-migrations". */ export interface PayloadMigration { - id: string; + id: number; name?: string | null; batch?: number | null; updatedAt: string; @@ -327,6 +334,13 @@ export interface UsersSelect { hash?: T; loginAttempts?: T; lockUntil?: T; + sessions?: + | T + | { + id?: T; + createdAt?: T; + expiresAt?: T; + }; } /** * This interface was referenced by `Config`'s JSON-Schema diff --git a/test/storage-vercel-blob/collections/Media.ts b/test/storage-vercel-blob/collections/Media.ts index 93ece25a9..1d2076fd6 100644 --- a/test/storage-vercel-blob/collections/Media.ts +++ b/test/storage-vercel-blob/collections/Media.ts @@ -3,6 +3,9 @@ import type { CollectionConfig } from 'payload' export const Media: CollectionConfig = { slug: 'media', upload: { + modifyResponseHeaders({ headers }) { + headers.set('X-Universal-Truth', 'Set') + }, resizeOptions: { position: 'center', width: 200, diff --git a/test/storage-vercel-blob/payload-types.ts b/test/storage-vercel-blob/payload-types.ts index 83f98d11f..463543e45 100644 --- a/test/storage-vercel-blob/payload-types.ts +++ b/test/storage-vercel-blob/payload-types.ts @@ -84,7 +84,7 @@ export interface Config { 'payload-migrations': PayloadMigrationsSelect | PayloadMigrationsSelect; }; db: { - defaultIDType: string; + defaultIDType: number; }; globals: {}; globalsSelect: {}; @@ -120,7 +120,7 @@ export interface UserAuthOperations { * via the `definition` "media". */ export interface Media { - id: string; + id: number; alt?: string | null; updatedAt: string; createdAt: string; @@ -157,7 +157,8 @@ export interface Media { * via the `definition` "media-with-prefix". */ export interface MediaWithPrefix { - id: string; + id: number; + prefix?: string | null; updatedAt: string; createdAt: string; url?: string | null; @@ -175,7 +176,7 @@ export interface MediaWithPrefix { * via the `definition` "users". */ export interface User { - id: string; + id: number; updatedAt: string; createdAt: string; email: string; @@ -185,6 +186,13 @@ export interface User { hash?: string | null; loginAttempts?: number | null; lockUntil?: string | null; + sessions?: + | { + id: string; + createdAt?: string | null; + expiresAt: string; + }[] + | null; password?: string | null; } /** @@ -192,24 +200,24 @@ export interface User { * via the `definition` "payload-locked-documents". */ export interface PayloadLockedDocument { - id: string; + id: number; document?: | ({ relationTo: 'media'; - value: string | Media; + value: number | Media; } | null) | ({ relationTo: 'media-with-prefix'; - value: string | MediaWithPrefix; + value: number | MediaWithPrefix; } | null) | ({ relationTo: 'users'; - value: string | User; + value: number | User; } | null); globalSlug?: string | null; user: { relationTo: 'users'; - value: string | User; + value: number | User; }; updatedAt: string; createdAt: string; @@ -219,10 +227,10 @@ export interface PayloadLockedDocument { * via the `definition` "payload-preferences". */ export interface PayloadPreference { - id: string; + id: number; user: { relationTo: 'users'; - value: string | User; + value: number | User; }; key?: string | null; value?: @@ -242,7 +250,7 @@ export interface PayloadPreference { * via the `definition` "payload-migrations". */ export interface PayloadMigration { - id: string; + id: number; name?: string | null; batch?: number | null; updatedAt: string; @@ -295,6 +303,7 @@ export interface MediaSelect { * via the `definition` "media-with-prefix_select". */ export interface MediaWithPrefixSelect { + prefix?: T; updatedAt?: T; createdAt?: T; url?: T; @@ -321,6 +330,13 @@ export interface UsersSelect { hash?: T; loginAttempts?: T; lockUntil?: T; + sessions?: + | T + | { + id?: T; + createdAt?: T; + expiresAt?: T; + }; } /** * This interface was referenced by `Config`'s JSON-Schema