Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/storage-vercel-blob/src/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { uploadFile } from './uploadFile.js'
interface CreateVercelBlobAdapterArgs {
access: 'public'
addRandomSuffix?: boolean
allowOverwrite?: boolean
baseUrl: string
cacheControlMaxAge: number
clientUploads?: ClientUploadsConfig
Expand All @@ -22,6 +23,7 @@ interface CreateVercelBlobAdapterArgs {
export function createVercelBlobAdapter({
access,
addRandomSuffix,
allowOverwrite,
baseUrl,
cacheControlMaxAge,
clientUploads,
Expand Down Expand Up @@ -55,6 +57,7 @@ export function createVercelBlobAdapter({
const result = await uploadFile({
access,
addRandomSuffix,
allowOverwrite,
buffer,
cacheControlMaxAge,
collectionPrefix: prefix,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { formatAdminURL } from 'payload/shared'

export type VercelBlobClientUploadHandlerExtra = {
addRandomSuffix: boolean
allowOverwrite: boolean
useCompositePrefixes: boolean
}

Expand All @@ -22,7 +23,7 @@ export const VercelBlobClientUploadHandler =
apiRoute,
collectionSlug,
docPrefix,
extra: { addRandomSuffix, useCompositePrefixes = false },
extra: { addRandomSuffix, allowOverwrite, useCompositePrefixes = false },
file,
prefix,
serverHandlerPath,
Expand Down
10 changes: 9 additions & 1 deletion packages/storage-vercel-blob/src/getClientUploadRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,21 @@ type Args = {
req: PayloadRequest
}) => boolean | Promise<boolean>
addRandomSuffix?: boolean
allowOverwrite?: boolean
cacheControlMaxAge?: number
token: string
}

const defaultAccess: Args['access'] = ({ req }) => !!req.user

export const getClientUploadRoute =
({ access = defaultAccess, addRandomSuffix, cacheControlMaxAge, token }: Args): PayloadHandler =>
({
access = defaultAccess,
addRandomSuffix,
allowOverwrite,
cacheControlMaxAge,
token,
}: Args): PayloadHandler =>
async (req) => {
const body = (await req.json!()) as HandleUploadBody

Expand All @@ -34,6 +41,7 @@ export const getClientUploadRoute =

return Promise.resolve({
addRandomSuffix,
allowOverwrite,
cacheControlMaxAge,
})
},
Expand Down
14 changes: 14 additions & 0 deletions packages/storage-vercel-blob/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ export type VercelBlobStorageOptions = {
*/
addRandomSuffix?: boolean

/**
* Allow overwriting an existing blob with the same key. Passed through to
* `@vercel/blob`'s `put()`. Useful when `addRandomSuffix: false` is combined
* with `clientUploads: true`, where a failed upload can leave an orphan blob
* that blocks a retry with `"This blob already exists"`.
*
* @default false
*/
allowOverwrite?: boolean

/**
* When enabled, fields (like the prefix field) will always be inserted into
* the collection schema regardless of whether the plugin is enabled. This
Expand Down Expand Up @@ -91,6 +101,7 @@ export type VercelBlobStorageOptions = {
const defaultUploadOptions: Partial<VercelBlobStorageOptions> = {
access: 'public',
addRandomSuffix: false,
allowOverwrite: false,
cacheControlMaxAge: 60 * 60 * 24 * 365, // 1 year
enabled: true,
}
Expand Down Expand Up @@ -134,12 +145,14 @@ export const vercelBlobStorage: VercelBlobStoragePlugin =
enabled: !isPluginDisabled && Boolean(options.clientUploads),
extraClientHandlerProps: () => ({
addRandomSuffix: !!optionsWithDefaults.addRandomSuffix,
allowOverwrite: !!optionsWithDefaults.allowOverwrite,
useCompositePrefixes: !!options.useCompositePrefixes,
}),
serverHandler: getClientUploadRoute({
access:
typeof options.clientUploads === 'object' ? options.clientUploads.access : undefined,
addRandomSuffix: optionsWithDefaults.addRandomSuffix,
allowOverwrite: optionsWithDefaults.allowOverwrite,
cacheControlMaxAge: options.cacheControlMaxAge,
token: options.token ?? '',
}),
Expand Down Expand Up @@ -171,6 +184,7 @@ export const vercelBlobStorage: VercelBlobStoragePlugin =
const adapter = createVercelBlobAdapter({
access: optionsWithDefaults.access ?? 'public',
addRandomSuffix: optionsWithDefaults.addRandomSuffix,
allowOverwrite: optionsWithDefaults.allowOverwrite,
baseUrl,
cacheControlMaxAge: optionsWithDefaults.cacheControlMaxAge ?? 60 * 60 * 24 * 365,
clientUploads: optionsWithDefaults.clientUploads,
Expand Down
3 changes: 3 additions & 0 deletions packages/storage-vercel-blob/src/uploadFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import path from 'path'
interface UploadFileArgs {
access: 'public'
addRandomSuffix?: boolean
allowOverwrite?: boolean
buffer: Buffer
cacheControlMaxAge?: number
collectionPrefix?: string
Expand All @@ -22,6 +23,7 @@ interface UploadFileResult {
export async function uploadFile({
access,
addRandomSuffix,
allowOverwrite,
buffer,
cacheControlMaxAge,
collectionPrefix = '',
Expand All @@ -41,6 +43,7 @@ export async function uploadFile({
const result = await put(fileKey, buffer, {
access,
addRandomSuffix,
allowOverwrite,
cacheControlMaxAge,
contentType: mimeType,
token,
Expand Down
Loading