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: // need to add:
// ------------ // ------------
// - transactionID
// - payloadDataLoader // - payloadDataLoader
// - payloadUploadSizes // - payloadUploadSizes
} }

View File

@@ -80,9 +80,7 @@ export default async function createLocal<TSlug extends keyof GeneratedTypes['co
req.payload = payload req.payload = payload
req.i18n = i18n req.i18n = i18n
req.t = i18n.t req.t = i18n.t
req.files = { req.file = file ?? (await getFileByPath(filePath))
file: (file ?? (await getFileByPath(filePath))) as UploadedFile, // TODO(NATIVE_REQUEST): fix this type
}
if (typeof user !== 'undefined') req.user = user 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 i18n = incomingReq?.i18n || getLocalI18n({ config: payload.config })
const req = { const req: PayloadRequest = {
fallbackLocale: typeof fallbackLocale !== 'undefined' ? fallbackLocale : defaultLocale, fallbackLocale: typeof fallbackLocale !== 'undefined' ? fallbackLocale : defaultLocale,
i18n, i18n,
locale: locale ?? defaultLocale, 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 i18n = incomingReq?.i18n || getLocalI18n({ config: payload.config })
const req = { const req: PayloadRequest = {
fallbackLocale, fallbackLocale,
i18n, i18n,
locale, locale,

View File

@@ -98,11 +98,9 @@ async function updateLocal<TSlug extends keyof GeneratedTypes['collections']>(
const i18n = incomingReq?.i18n || getLocalI18n({ config: payload.config }) const i18n = incomingReq?.i18n || getLocalI18n({ config: payload.config })
const req = { const req: PayloadRequest = {
fallbackLocale: typeof fallbackLocale !== 'undefined' ? fallbackLocale : defaultLocale, fallbackLocale: typeof fallbackLocale !== 'undefined' ? fallbackLocale : defaultLocale,
files: { file: file ?? (await getFileByPath(filePath)),
file: file ?? (await getFileByPath(filePath)),
},
i18n, i18n,
locale: locale ?? defaultLocale, locale: locale ?? defaultLocale,
payload, payload,
@@ -110,7 +108,7 @@ async function updateLocal<TSlug extends keyof GeneratedTypes['collections']>(
t: i18n.t, t: i18n.t,
transactionID: incomingReq?.transactionID, transactionID: incomingReq?.transactionID,
user, user,
} as unknown as PayloadRequest } as PayloadRequest
setRequestContext(req, context) setRequestContext(req, context)
if (!req.payloadDataLoader) req.payloadDataLoader = getDataLoader(req) 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 { afterRead } from '../../fields/hooks/afterRead'
import { beforeChange } from '../../fields/hooks/beforeChange' import { beforeChange } from '../../fields/hooks/beforeChange'
import { beforeValidate } from '../../fields/hooks/beforeValidate' import { beforeValidate } from '../../fields/hooks/beforeValidate'
// import { deleteAssociatedFiles } from '../../uploads/deleteAssociatedFiles' import { deleteAssociatedFiles } from '../../uploads/deleteAssociatedFiles'
// import { generateFileData } from '../../uploads/generateFileData' import { generateFileData } from '../../uploads/generateFileData'
import { unlinkTempFiles } from '../../uploads/unlinkTempFiles' import { unlinkTempFiles } from '../../uploads/unlinkTempFiles'
// import { uploadFiles } from '../../uploads/uploadFiles' import { uploadFiles } from '../../uploads/uploadFiles'
import { commitTransaction } from '../../utilities/commitTransaction' import { commitTransaction } from '../../utilities/commitTransaction'
import { initTransaction } from '../../utilities/initTransaction' import { initTransaction } from '../../utilities/initTransaction'
import { killTransaction } from '../../utilities/killTransaction' 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 // Generate data for all files and sizes
// ///////////////////////////////////// // /////////////////////////////////////
// const { data: newFileData, files: filesToUpload } = await generateFileData({ const { data: newFileData, files: filesToUpload } = await generateFileData({
// collection, collection,
// config, config,
// data: bulkUpdateData, data: bulkUpdateData,
// overwriteExistingFiles, overwriteExistingFiles,
// req, req,
// throwOnMissingFile: false, throwOnMissingFile: false,
// }) })
const errors = [] const errors = []
@@ -179,14 +179,14 @@ export const updateOperation = async <TSlug extends keyof GeneratedTypes['collec
showHiddenFields: true, showHiddenFields: true,
}) })
// await deleteAssociatedFiles({ await deleteAssociatedFiles({
// collectionConfig, collectionConfig,
// config, config,
// doc, doc,
// // files: filesToUpload, files: filesToUpload,
// overrideDelete: false, overrideDelete: false,
// req, req,
// }) })
// ///////////////////////////////////// // /////////////////////////////////////
// beforeValidate - Fields // beforeValidate - Fields
@@ -226,9 +226,9 @@ export const updateOperation = async <TSlug extends keyof GeneratedTypes['collec
// Write files to local storage // Write files to local storage
// ///////////////////////////////////// // /////////////////////////////////////
// if (!collectionConfig.upload.disableLocalStorage) { if (!collectionConfig.upload.disableLocalStorage) {
// await uploadFiles(payload, filesToUpload, req) await uploadFiles(payload, filesToUpload, req)
// } }
// ///////////////////////////////////// // /////////////////////////////////////
// beforeChange - Collection // beforeChange - Collection

View File

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

View File

@@ -8,15 +8,18 @@ export async function getFilePrefix({
req: PayloadRequest req: PayloadRequest
}): Promise<string> { }): Promise<string> {
const imageSizes = (collection?.upload as IncomingUploadType)?.imageSizes || [] const imageSizes = (collection?.upload as IncomingUploadType)?.imageSizes || []
const { searchParams } = new URL(req.url)
const filename = searchParams.get('filename')
const files = await req.payload.find({ const files = await req.payload.find({
collection: collection.slug, collection: collection.slug,
where: { where: {
or: [ or: [
{ {
filename: { equals: req.params.filename }, filename: { equals: filename },
}, },
...imageSizes.map((imageSize) => ({ ...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> data: Partial<FileData>
req: PayloadRequest req: PayloadRequest
}): File[] { }): File[] {
const file = req.files?.file const file = req.file
let files: File[] = [] let files: File[] = []