@beignet/provider-storage-vercel-blob

中文文档
0.0.65发布于 2026/11/08MITTypeScriptES Module近 30 天下载 1824

Vercel Blob object storage provider for Beignet

原始使用文档
文档目录11 节
  1. Install
  2. Provider setup
  3. Visibility
  4. Direct port factory
  5. Request cost
  6. Escape hatch
  7. Devtools
  8. Failure behavior
  9. Direct uploads
  10. Local and tests
  11. Deployment notes

@beignet/provider-storage-vercel-blob

Runtime: Beignet requires Node.js 22.12 or newer. Bun is optional.

Vercel Blob object storage provider for Beignet

[!CAUTION] Beignet is experimental alpha software. The 0.0.x package line is for early evaluation, and APIs may change between releases while the framework settles.

This package adapts Vercel Blob to Beignet's StoragePort, so apps deployed on Vercel get durable object storage without hand-writing an adapter.

createVercelBlobStorageProvider(...) returns the stable VercelBlobStorageProvider type. VercelBlobConfig describes its validated config; the Zod schema remains internal.

Install

bun add @beignet/provider-storage-vercel-blob @vercel/blob@^2.8.0

@vercel/blob 2.8.0 or newer within the v2 line is required.

Or scaffold everything — dependencies, provider wiring, ports, env example, and setup notes — with the CLI preset:

bun beignet provider add storage-vercel-blob

Provider setup

// server/providers.ts
import { createVercelBlobStorageProvider } from "@beignet/provider-storage-vercel-blob";

export const providers = [
  // ...
  createVercelBlobStorageProvider(),
] as const;

The provider contributes ports.storage (the standard Beignet StoragePort) and ports.vercelBlob (an escape hatch, see below). Configuration comes from BLOB_* env vars and, for OIDC authentication, VERCEL_OIDC_TOKEN:

Env varMeaning
BLOB_READ_WRITE_TOKENRead-write token. Set automatically on Vercel deployments with a connected Blob store; set it manually elsewhere.
BLOB_ACCESSStore-wide access level: private (default) or public.
BLOB_KEY_PREFIXOptional prefix applied to every object key.
BLOB_STORE_IDOptional store id when authenticating with a Vercel OIDC token.
VERCEL_OIDC_TOKENVercel-provided OIDC token used with BLOB_STORE_ID instead of a read-write token.

Local storage keeps working with zero setup by switching on the available credentials, the same way environment-swapped rate-limit providers work:

import { createLocalStorageProvider } from "@beignet/provider-storage-local";
import { createVercelBlobStorageProvider } from "@beignet/provider-storage-vercel-blob";

const hasVercelBlobCredentials =
  Boolean(process.env.BLOB_READ_WRITE_TOKEN) ||
  Boolean(process.env.BLOB_STORE_ID && process.env.VERCEL_OIDC_TOKEN);

export const providers = [
  // Vercel Blob in deployed environments (local disk does not survive
  // serverless); the local provider keeps dev working with zero setup.
  hasVercelBlobCredentials
    ? createVercelBlobStorageProvider()
    : createLocalStorageProvider(),
] as const;

Visibility

Vercel Blob stores per-object access at write time but does not report it back from head(...), so this adapter keeps the whole store uniform: every object shares the configured access level, and a put(...) that requests a different visibility is rejected with an error instead of silently misreporting visibility on later reads. Run two providers over two Blob stores when an app needs both levels.

publicUrl(...) returns the blob URL for public stores and null for private stores. Serve private objects through app routes that authorize the file record and call createStorageDownloadResponse({ storage, key, fileName }) from @beignet/web or @beignet/next. It streams a non-cacheable attachment and returns null for a missing object.

Vercel Blob has no arbitrary per-object metadata, so StorageObject.metadata is always reported empty. Cache lifetimes map from the Cache-Control max-age directive to Vercel Blob's cacheControlMaxAge seconds; other directives do not survive the mapping.

storage.temporaryUrl(key, { expiresInSeconds, fileName? }) validates its inputs and returns { status: "unsupported" } without contacting Blob or checking existence. Use the authorized streaming route for private downloads. A Blob pathname or private URL alone is not an authorized browser download link.

Direct port factory

Use the direct factory when you own provider wiring or need a second store:

import { createVercelBlobStorage } from "@beignet/provider-storage-vercel-blob";

const storage = createVercelBlobStorage({
  access: "public",
  keyPrefix: "avatars",
  storeId: process.env.AVATARS_BLOB_STORE_ID,
  token: process.env.AVATARS_BLOB_TOKEN,
});

Omit token to let @vercel/blob read BLOB_READ_WRITE_TOKEN from the environment. storeId is forwarded explicitly to every SDK operation for OIDC-authenticated stores; the SDK reads VERCEL_OIDC_TOKEN, and the env-backed provider maps BLOB_STORE_ID to the same option. The client option accepts a fake SDK surface for tests.

beignet doctor --strict and beignet preflight accept either the read-write token or the complete BLOB_STORE_ID plus VERCEL_OIDC_TOKEN pair.

Request cost

Some StoragePort promises need an extra Blob API round-trip:

  • put(...) issues a post-write head(...) because the port returns the authoritative stored object, not an echo of inputs.
  • delete(...) issues a pre-delete head(...) because Vercel Blob's del(...) does not report whether the object existed.

Escape hatch

ports.vercelBlob exposes the raw pieces for integrations the port does not cover:

const { client, access, keyPrefix, storeId, objectKey, checkHealth } =
  ctx.ports.vercelBlob;

await client.list({ prefix: objectKey("exports"), limit: 100 });
const health = await checkHealth();

checkHealth() issues a one-item list(...) and reports { ok, message?, metadata } for readiness endpoints.

Object keys and keyPrefix use the shared validation and prefix helpers from @beignet/core/ports, keeping Blob behavior aligned with memory, local, and S3 storage.

get(...) returns a one-shot response body. Consume one body method, or call await object.cancel() when only inspecting metadata so the unread response releases its resources. Prefer stat(...) for metadata-only reads.

Devtools

When @beignet/devtools is installed before this provider, storage operations appear under the dashboard's Storage watcher. The provider records storage.put, storage.get, storage.stat, storage.delete, storage.exists, and storage.publicUrl events with key, size, and duration; failures are recorded with .failed event names and the original error is rethrown.

Failure behavior

Missing objects resolve to null (get, stat, publicUrl) or false (delete, exists) — BlobNotFoundError never escapes the port. All other SDK errors are rethrown unchanged after an instrumentation event, including missing-token errors, so misconfiguration fails loudly rather than pretending storage is empty.

Direct uploads

This package covers server-mediated storage through StoragePort. Vercel Blob's browser-direct uploads use its own client-token protocol (@vercel/blob/client), which does not fit Beignet's plain presigned-PUT UploadSignerPort; use createS3UploadSigner from @beignet/provider-storage-s3 when direct uploads are a requirement, or Vercel's client SDK directly.

Local and tests

Keep dev and tests on @beignet/provider-storage-local or createMemoryStorage() from @beignet/core/ports; both implement the same port. Inject a fake VercelBlobClient through the client/createClient options to test app code against this adapter without network access.

Deployment notes

Connect a Blob store to the Vercel project and configure one credential path: use BLOB_READ_WRITE_TOKEN, or use Vercel OIDC with VERCEL_OIDC_TOKEN plus BLOB_STORE_ID. Doctor, provider audit, and preflight validate those alternatives without treating the read-write token as the only valid path; run beignet preflight --connect to prove the configured store is reachable. Prefer private stores unless objects are genuinely world-readable: public blob URLs are unauthenticated and long-cached.

版本与发布记录

@beignet/provider-storage-vercel-blob 共发布 37 个版本,首次发布于 2026/07/06;过去 12 个月发布了 37 个版本。

版本发布日期距今
0.0.65latest2026/11/08今天
0.0.642026/11/034 天前
0.0.632026/11/026 天前
0.0.622026/11/017 天前
0.0.612026/11/017 天前
0.0.602026/11/017 天前

关于 @beignet/provider-storage-vercel-blob 的常见问题

@beignet/provider-storage-vercel-blob 是什么?

Vercel Blob object storage provider for Beignet

如何安装 @beignet/provider-storage-vercel-blob?

在项目目录运行 npm install @beignet/provider-storage-vercel-blob,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@vercel/blob(^2.8.0)、@beignet/core(>=0.0.3 <1.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@beignet/provider-storage-vercel-blob 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@beignet/provider-storage-vercel-blob 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@beignet/provider-storage-vercel-blob 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.12.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@beignet/provider-storage-vercel-blob 可以商用吗?

@beignet/provider-storage-vercel-blob 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@beignet/provider-storage-vercel-blob 的下载量有多少?

根据 npm 官方下载统计,@beignet/provider-storage-vercel-blob 在 2026/10/08 – 2026/11/06 这 30 天内被下载 1,824 次,日均约 61 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@beignet/provider-storage-vercel-blob 还在维护吗?

最新版本 0.0.65 发布于 2026/11/08(今天);至今共发布 37 个版本,其中过去 12 个月发布了 37 个;首次发布于 2026/07/06。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。