chore: improve req type safety in local operations, misc req.files replacements

This commit is contained in:
Jarrod Flesch
2024-01-24 09:47:28 -05:00
parent db935b20a7
commit 2c3dc6ceef
15 changed files with 62 additions and 136 deletions

View File

@@ -82,7 +82,6 @@ export const createPayloadRequest = async ({
// need to add:
// ------------
// - transactionID
// - payloadDataLoader
// - payloadUploadSizes
}

View File

@@ -80,9 +80,7 @@ export default async function createLocal<TSlug extends keyof GeneratedTypes['co
req.payload = payload
req.i18n = i18n
req.t = i18n.t
req.files = {
file: (file ?? (await getFileByPath(filePath))) as UploadedFile, // TODO(NATIVE_REQUEST): fix this type
}
req.file = file ?? (await getFileByPath(filePath))
if (typeof user !== 'undefined') req.user = user

View File

@@ -83,7 +83,7 @@ async function deleteLocal<TSlug extends keyof GeneratedTypes['collections']>(
const i18n = incomingReq?.i18n || getLocalI18n({ config: payload.config })
const req = {
const req: PayloadRequest = {
fallbackLocale: typeof fallbackLocale !== 'undefined' ? fallbackLocale : defaultLocale,
i18n,
locale: locale ?? defaultLocale,

View File

@@ -54,7 +54,7 @@ export default async function restoreVersionLocal<T extends keyof GeneratedTypes
const i18n = incomingReq?.i18n || getLocalI18n({ config: payload.config })
const req = {
const req: PayloadRequest = {
fallbackLocale,
i18n,
locale,

View File

@@ -98,11 +98,9 @@ async function updateLocal<TSlug extends keyof GeneratedTypes['collections']>(
const i18n = incomingReq?.i18n || getLocalI18n({ config: payload.config })
const req = {
const req: PayloadRequest = {
fallbackLocale: typeof fallbackLocale !== 'undefined' ? fallbackLocale : defaultLocale,
files: {
file: file ?? (await getFileByPath(filePath)),
},
file: file ?? (await getFileByPath(filePath)),
i18n,
locale: locale ?? defaultLocale,
payload,
@@ -110,7 +108,7 @@ async function updateLocal<TSlug extends keyof GeneratedTypes['collections']>(
t: i18n.t,
transactionID: incomingReq?.transactionID,
user,
} as unknown as PayloadRequest
} as PayloadRequest
setRequestContext(req, context)
if (!req.payloadDataLoader) req.payloadDataLoader = getDataLoader(req)

View File

@@ -17,10 +17,10 @@ import { afterChange } from '../../fields/hooks/afterChange'
import { afterRead } from '../../fields/hooks/afterRead'
import { beforeChange } from '../../fields/hooks/beforeChange'
import { beforeValidate } from '../../fields/hooks/beforeValidate'
// import { deleteAssociatedFiles } from '../../uploads/deleteAssociatedFiles'
// import { generateFileData } from '../../uploads/generateFileData'
import { deleteAssociatedFiles } from '../../uploads/deleteAssociatedFiles'
import { generateFileData } from '../../uploads/generateFileData'
import { unlinkTempFiles } from '../../uploads/unlinkTempFiles'
// import { uploadFiles } from '../../uploads/uploadFiles'
import { uploadFiles } from '../../uploads/uploadFiles'
import { commitTransaction } from '../../utilities/commitTransaction'
import { initTransaction } from '../../utilities/initTransaction'
import { killTransaction } from '../../utilities/killTransaction'
@@ -150,14 +150,14 @@ export const updateOperation = async <TSlug extends keyof GeneratedTypes['collec
// Generate data for all files and sizes
// /////////////////////////////////////
// const { data: newFileData, files: filesToUpload } = await generateFileData({
// collection,
// config,
// data: bulkUpdateData,
// overwriteExistingFiles,
// req,
// throwOnMissingFile: false,
// })
const { data: newFileData, files: filesToUpload } = await generateFileData({
collection,
config,
data: bulkUpdateData,
overwriteExistingFiles,
req,
throwOnMissingFile: false,
})
const errors = []
@@ -179,14 +179,14 @@ export const updateOperation = async <TSlug extends keyof GeneratedTypes['collec
showHiddenFields: true,
})
// await deleteAssociatedFiles({
// collectionConfig,
// config,
// doc,
// // files: filesToUpload,
// overrideDelete: false,
// req,
// })
await deleteAssociatedFiles({
collectionConfig,
config,
doc,
files: filesToUpload,
overrideDelete: false,
req,
})
// /////////////////////////////////////
// beforeValidate - Fields
@@ -226,9 +226,9 @@ export const updateOperation = async <TSlug extends keyof GeneratedTypes['collec
// Write files to local storage
// /////////////////////////////////////
// if (!collectionConfig.upload.disableLocalStorage) {
// await uploadFiles(payload, filesToUpload, req)
// }
if (!collectionConfig.upload.disableLocalStorage) {
await uploadFiles(payload, filesToUpload, req)
}
// /////////////////////////////////////
// beforeChange - Collection

View File

@@ -16,10 +16,10 @@ import { afterChange } from '../../fields/hooks/afterChange'
import { afterRead } from '../../fields/hooks/afterRead'
import { beforeChange } from '../../fields/hooks/beforeChange'
import { beforeValidate } from '../../fields/hooks/beforeValidate'
// import { deleteAssociatedFiles } from '../../uploads/deleteAssociatedFiles'
// import { generateFileData } from '../../uploads/generateFileData'
import { deleteAssociatedFiles } from '../../uploads/deleteAssociatedFiles'
import { generateFileData } from '../../uploads/generateFileData'
import { unlinkTempFiles } from '../../uploads/unlinkTempFiles'
// import { uploadFiles } from '../../uploads/uploadFiles'
import { uploadFiles } from '../../uploads/uploadFiles'
import { commitTransaction } from '../../utilities/commitTransaction'
import { initTransaction } from '../../utilities/initTransaction'
import { killTransaction } from '../../utilities/killTransaction'
@@ -138,29 +138,29 @@ export const updateByIDOperation = async <TSlug extends keyof GeneratedTypes['co
// Generate data for all files and sizes
// /////////////////////////////////////
// const { data: newFileData, files: filesToUpload } = await generateFileData({
// collection,
// config,
// data,
// overwriteExistingFiles,
// req,
// throwOnMissingFile: false,
// })
const { data: newFileData, files: filesToUpload } = await generateFileData({
collection,
config,
data,
overwriteExistingFiles,
req,
throwOnMissingFile: false,
})
// data = newFileData
data = newFileData
// /////////////////////////////////////
// Delete any associated files
// /////////////////////////////////////
// await deleteAssociatedFiles({
// collectionConfig,
// config,
// doc: docWithLocales,
// files: filesToUpload,
// overrideDelete: false,
// t,
// })
await deleteAssociatedFiles({
collectionConfig,
config,
doc: docWithLocales,
files: filesToUpload,
overrideDelete: false,
req,
})
// /////////////////////////////////////
// beforeValidate - Fields
@@ -200,9 +200,9 @@ export const updateByIDOperation = async <TSlug extends keyof GeneratedTypes['co
// Write files to local storage
// /////////////////////////////////////
// if (!collectionConfig.upload.disableLocalStorage) {
// await uploadFiles(payload, filesToUpload, req)
// }
if (!collectionConfig.upload.disableLocalStorage) {
await uploadFiles(payload, filesToUpload, req)
}
// /////////////////////////////////////
// beforeChange - Collection

View File

@@ -1,72 +0,0 @@
import type { TFunction } from '@payloadcms/translations'
import type DataLoader from 'dataloader'
import type { Request } from 'express'
import type { UploadedFile } from 'express-fileupload'
import type { Payload } from '..'
import type { User } from '../auth/types'
import type { Collection, TypeWithID } from '../collections/config/types'
import type { FindOneArgs } from '../database/types'
/** Express request with some Payload related context added */
export declare type PayloadRequest<U = any> = Request & {
/** Information about the collection that is being accessed
* - Configuration from payload-config.ts
* - MongoDB model for this collection
* - GraphQL type metadata
*/
collection?: Collection
/** context allows you to pass your own data to the request object as context
* This is useful for, for example, passing data from a beforeChange hook to an afterChange hook.
* payoadContext can also be fully typed using declare module
* {@link https://payloadcms.com/docs/hooks/context More info in the Payload Documentation}.
*/
context: RequestContext
/** The locale that should be used for a field when it is not translated to the requested locale */
fallbackLocale?: string
/** Uploaded files */
files?: {
/**
* This is the file that Payload will use for the file upload, other files are ignored.
*
*/
file: UploadedFile
}
/** Cache of documents related to the current request */
findByID?: {
[transactionID: string]: {
[slug: string]: (q: FindOneArgs) => Promise<TypeWithID>
}
}
/** I18next instance */
i18n: any // this file will be removed
/**
* The requested locale if specified
* Only available for localised collections
*/
locale?: string
/** The global payload object */
payload: Payload
/** What triggered this request */
payloadAPI?: 'GraphQL' | 'REST' | 'local'
/** Optimized document loader */
payloadDataLoader: DataLoader<string, TypeWithID>
/** Resized versions of the image that was uploaded during this request */
payloadUploadSizes?: Record<string, Buffer>
/** Get a translation for the admin screen */
t: TFunction
/**
* Identifier for the database transaction for interactions in a single, all-or-nothing operation.
*/
transactionID?: number | string
/**
* Used to ensure consistency when multiple operations try to create a transaction concurrently on the same request
*/
transactionIDPromise?: Promise<void>
/** The signed in user */
user: (U & User) | null
}
export interface RequestContext {
[key: string]: unknown
}

View File

@@ -49,7 +49,7 @@ export default async function findOneLocal<T extends keyof GeneratedTypes['globa
const i18n = options.req?.i18n ?? getLocalI18n({ config: payload.config })
const req = {
const req: PayloadRequest = {
fallbackLocale: fallbackLocale ?? options.req?.fallbackLocale ?? defaultLocale,
i18n,
locale: locale ?? options.req?.locale ?? defaultLocale,

View File

@@ -50,7 +50,7 @@ export default async function findVersionByIDLocal<T extends keyof GeneratedType
const i18n = incomingReq?.i18n || getLocalI18n({ config: payload.config })
const req = {
const req: PayloadRequest = {
fallbackLocale,
i18n,
locale,

View File

@@ -55,7 +55,7 @@ export default async function findVersionsLocal<T extends keyof GeneratedTypes['
const i18n = incomingReq?.i18n || getLocalI18n({ config: payload.config })
const req = {
const req: PayloadRequest = {
fallbackLocale,
i18n,
locale,

View File

@@ -47,7 +47,7 @@ export default async function restoreVersionLocal<T extends keyof GeneratedTypes
const i18n = incomingReq?.i18n || getLocalI18n({ config: payload.config })
const req = {
const req: PayloadRequest = {
fallbackLocale,
i18n,
locale,

View File

@@ -51,7 +51,7 @@ export default async function updateLocal<TSlug extends keyof GeneratedTypes['gl
const i18n = incomingReq?.i18n || getLocalI18n({ config: payload.config })
const req = {
const req: PayloadRequest = {
fallbackLocale,
i18n,
locale,

View File

@@ -8,15 +8,18 @@ export async function getFilePrefix({
req: PayloadRequest
}): Promise<string> {
const imageSizes = (collection?.upload as IncomingUploadType)?.imageSizes || []
const { searchParams } = new URL(req.url)
const filename = searchParams.get('filename')
const files = await req.payload.find({
collection: collection.slug,
where: {
or: [
{
filename: { equals: req.params.filename },
filename: { equals: filename },
},
...imageSizes.map((imageSize) => ({
[`sizes.${imageSize.name}.filename`]: { equals: req.params.filename },
[`sizes.${imageSize.name}.filename`]: { equals: filename },
})),
],
},

View File

@@ -10,7 +10,7 @@ export function getIncomingFiles({
data: Partial<FileData>
req: PayloadRequest
}): File[] {
const file = req.files?.file
const file = req.file
let files: File[] = []