mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 15:13:07 +00:00
Make posts seed idempotent against the shared Vercel Blob store
The Vercel Blob store is shared across environments and the @payloadcms/storage-vercel-blob plugin uploads via put() without allowOverwrite (and exposes no option to enable it). Cover images left under the deterministic <slug>.<ext> key by an earlier run therefore made the prod seed abort with "This blob already exists" on the first upload. Delete any orphan blob at that key (via @vercel/blob del, idempotent) right before creating a new media doc, so uploads are deterministic and the seed stays re-runnable. Existing media rows are still reused, so no duplicate media is created.
This commit is contained in:
parent
28647e4760
commit
bcb6c6c014
3 changed files with 23 additions and 0 deletions
|
|
@ -84,6 +84,7 @@
|
|||
"@types/node": "22.19.9",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vercel/blob": "2.3.1",
|
||||
"@vitejs/plugin-react": "4.5.2",
|
||||
"eslint": "^9.39.2",
|
||||
"eslint-config-next": "15.4.11",
|
||||
|
|
|
|||
|
|
@ -129,6 +129,9 @@ importers:
|
|||
'@types/react-dom':
|
||||
specifier: ^19.2.3
|
||||
version: 19.2.3(@types/react@19.2.14)
|
||||
'@vercel/blob':
|
||||
specifier: 2.3.1
|
||||
version: 2.3.1
|
||||
'@vitejs/plugin-react':
|
||||
specifier: 4.5.2
|
||||
version: 4.5.2(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.77.4)(tsx@4.21.0)(yaml@2.8.2))
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
import { config as loadEnv } from 'dotenv'
|
||||
import { JSDOM } from 'jsdom'
|
||||
import { convertHTMLToLexical, editorConfigFactory } from '@payloadcms/richtext-lexical'
|
||||
import { del as blobDel } from '@vercel/blob'
|
||||
import { getPayload } from 'payload'
|
||||
|
||||
// Mirror Next.js precedence (.env.local wins over .env) without clobbering a
|
||||
|
|
@ -418,6 +419,24 @@ async function ensureCoverMedia(payload, { slug, coverUrl, alt }) {
|
|||
if (existing.docs.length > 0) return { id: existing.docs[0].id, created: false }
|
||||
|
||||
const buffer = Buffer.from(await res.arrayBuffer())
|
||||
|
||||
// The Vercel Blob store is SHARED across environments, and the storage plugin
|
||||
// (@payloadcms/storage-vercel-blob) calls `put()` without `allowOverwrite` and
|
||||
// exposes no option to enable it. So a blob left behind under this deterministic
|
||||
// key (`<slug>.<ext>`) by an earlier run in another environment would make the
|
||||
// upload throw "This blob already exists". We have no DB media row for it here
|
||||
// (checked above), so it's an orphan — delete it first so the upload is
|
||||
// deterministic and this seed stays re-runnable. `del` is idempotent (no-op
|
||||
// when the blob is absent).
|
||||
const blobToken = process.env.BLOB_READ_WRITE_TOKEN
|
||||
if (blobToken) {
|
||||
try {
|
||||
await blobDel(filename, { token: blobToken })
|
||||
} catch (err) {
|
||||
console.warn(`[seed:posts] blob pre-delete skipped for ${filename}: ${err.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
const media = await payload.create({
|
||||
collection: 'media',
|
||||
data: { alt: alt || slug },
|
||||
|
|
|
|||
Loading…
Reference in a new issue