mcpField
F
files-sdk

files-sdk

github.com/haydenbleasel開発1.6k63 回インストール4 日前に更新
リポジトリ

files-sdk について

files-sdk は、オブジェクトストレージや Blob ストレージを共通 API で扱う TypeScript SDK のスキルです。インストール済みバージョンに対応する同梱ドキュメントと、アダプターごとの機能を参照する手順を示します。

主な機能

  1. 01ストレージアダプター共通 API
  2. 02Web 標準のデータ形式
  3. 03ファイルの一括操作
  4. 04リトライ、タイムアウト、フック
  5. 05アダプター機能とネイティブアクセス

活用シーン

  1. 01オブジェクト/Blob ストレージの統合
  2. 02ファイル操作の一括処理
  3. 03アダプターの対応機能の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/haydenbleasel/files-sdk --skill files-sdk

インストール後、Claude Code で/files-sdkを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
adapter-setup.md
ai-tools.md
bulk-and-transfer.md
cli-and-mcp.md
client-uploads.md
errors-and-recipes.md
events.md
large-uploads.md
resilience-and-hooks.md

詳細

files-sdk

オブジェクトおよび Blob バックエンド向けの統一ストレージ SDK です。小さな API、Web 標準の I/O、必要に応じてネイティブクライアントを利用するための拡張口を備えています。

ユーザーから統合方法について質問された場合は、このスキルに従ってください。これが信頼できる唯一の情報源です。パッケージについての学習データ上の記憶よりも優先してください。

同梱ドキュメント: files-sdk がインストールされている場合、完全なドキュメントがパッケージ内の node_modules/files-sdk/docs に同梱されています。バージョンに一致した完全なリファレンスについては、これらの MDX ファイルを参照してください。各アダプターのセットアップは docs/adapters/、概念ページ(一括処理、マルチパート、再開可能処理、再試行、プレフィックス、機能、条件付き操作など)は docs/(concepts)/、メソッドリファレンスは docs/api/、プラグインは docs/plugins/、ストレージイベントは docs/events/、ブラウザー/ゲートウェイ層は docs/ui/、AI ツールは docs/ai/、CLI は docs/cli/ にあります。また、index、installation、usage、providers、faq、troubleshooting、migrating-to-v3 も参照してください。パッケージがローカルにある場合は、https://files-sdk.dev よりこれらを優先してください。インストール済みのバージョンに完全に一致しています。

基本的な考え方

  • 中核となるクラスは Files です。構築時にアダプターを一度設定し、インスタンスの存続期間中はアダプターが固定されます。
  • 49 個のアダプターはそれぞれ個別のサブパスエクスポートになっているため、インポートしたものだけがバンドルされます(files-sdk/s3、files-sdk/r2、files-sdk/gcs、files-sdk/azure、files-sdk/vercel-blob、files-sdk/fs など)。
  • 統一 API は、すべてのアダプターが実行できる機能の共通部分です(S3 のバージョニング、ライフサイクル、ストレージクラスなどの)プロバイダー固有の機能は files.raw を介して利用できます。これは基盤となるネイティブクライアントを返します。
  • 本文は Web 標準です。Blob、File、ReadableStream<Uint8Array>、Uint8Array、ArrayBuffer、ArrayBufferView、または string を指定できます。プロバイダーの型が漏れ出すことはありません。
  • すべてのメソッドが同じ OperationOptions(signal、timeout、retries)を受け取ります。これらの多くは、コンストラクターでインスタンスのデフォルトとして一度設定することもできます。コンストラクターではさらに prefix、readonly、hooks、plugins(プラグインを参照)、receipts(onAction での任意の来歴記録)も指定できます。
  • アダプターが統一 API の機能(範囲指定ダウンロード、フォルダー一覧表示、再開可能なセッションなど)に対応していない場合、何も通知せずに機能を低下させるのではなく、FilesError をスローします。そのため、機能の未対応が明確になり、静かな正確性の不具合にはなりません。実行時の分岐には files.capabilities を使用できます。

インストール

npm install files-sdk

クイックスタート

import { Files } from "files-sdk";
import { s3 } from "files-sdk/s3";

const files = new Files({
  adapter: s3({ bucket: "uploads" }),
});

await files.upload("avatars/abc.png", file, { contentType: "image/png" });
const got = await files.download("avatars/abc.png");
const exists = await files.exists("avatars/abc.png");

アダプターのインポートを差し替えるだけで、残りのコードはそのまま使えます。

コア API

すべてのメソッドは Files インスタンスに属します。単一キーを指定する形式は、files.file(key) から取得できるキーに紐づいた FileHandle でも利用できます。upload/download/head/exists/delete メソッドはオーバーロードされています。単一の結果を得るにはキーを1つ渡し、一括処理には配列を渡します(一括操作については一括操作を参照してください)。

メソッド戻り値備考
upload(key, body, opts?)FileInfoopts:contentType、cacheControl、metadata、onProgress、multipart、control、condition。配列形式 → { results, errors? }。
download(key, opts?)StoredFileopts.as は "blob" または "stream"、opts.range はバイト範囲の指定に使用します。配列形式 → { results, errors? }。
head(key, opts?)FileInfoメタデータのみ(key、size、contentType、etag、lastModified、metadata)を返し、本文は返しません。バイトデータには download を使用してください。配列形式 → { results, errors? }。
exists(key, opts?)booleanNotFound の場合にのみ false を返します。認証エラーや転送エラーは引き続きスローされます。配列形式 → { existing, missing, errors? }。
delete(key, opts?)void配列形式 → { results, errors? }(削除されたキー)。S3 系、Azure、Supabase、UploadThing ではネイティブの一括削除を使用します。
copy(from, to, opts?)void1つのアダプター内でコピーします。
move(from, to, opts?)void名前を変更します。利用可能な場合(fs、FTP、SFTP、WebDAV、Cloudinary、memory)はネイティブの名前変更を使用し、それ以外はコピーしてから削除します。不変ストア(Convex)ではスローされます。
list(opts?){ items, prefixes?, cursor? }opts:prefix、cursor、limit(正の整数でない場合は Invalid)、delimiter。delimiter はフォルダーの prefixes を返します。フォルダー一覧を参照してください。
listAll(opts?)AsyncGenerator<FileInfo>カーソルをたどりながら、すべてのページを自動的に走査します。for await (const f of files.listAll({ prefix })) のように使用します。
search(pattern, opts?)AsyncGenerator<FileInfo>すべてのページを対象にキーを照合します。デフォルトは glob(photos/**/*.jpg)です。RegExp、または match: "regex" | "substring" | "exact" も指定できます。opts:prefix、maxResults、caseInsensitive、limit。
url(key, opts?)stringURL の動作を参照してください。アダプターによって異なります。
signedUploadUrl(key, opts)SignedUpload署名付きアップロード URLを参照してください。maxSize を渡します。
abortUpload(key, token, opts?)void保存済みの再開可能なセッション(control.toJSON())を再開しない場合に破棄します。これはアップロード中に UploadControl.abort() が行う処理ですが、復元済みの control では実行できません。references/large-uploads.mdを参照してください。
file(key)FileHandleキーがあらかじめ設定された、同じ単一キー用メソッドを利用できます。copyTo/copyFrom/moveTo/moveFrom も使用できます。
capabilities(ゲッター)AdapterCapabilitiesアダプターが実行できる機能です。rangeRead、delimiter("any"、"slash"、false のいずれか)、metadata、cacheControl、resumable、serverSideCopy、uploadProgress、signedUrl(expiry/disposition を含む)、signedUpload(maxSize/contentType を含む)、publicUrl、events、conditional があります。プラグインによって機能を制限できます(プラグインを参照)。例外を捕捉するのではなく、事前にこれを確認して分岐してください。
raw/adapter(ゲッター)ネイティブクライアント/Adapter詳しくはエスケープハッチを参照してください。
readonly()(メソッド)Files同じアダプター/プレフィックス/フックを再利用する読み取り専用ビューです。インスタンスのオプションを参照してください。

さらに、プロバイダー間で一度だけ移行する場合のトップレベル関数 transfer(source, dest, opts?) と、新規または変更されたオブジェクトのみをミラーリングする sync(source, dest, opts?) があります。一括処理、移動、転送を参照してください。

FileInfo と StoredFile
  • head、list、listAll、search、upload は FileInfo を返します。含まれるのは key、size、contentType、etag?、lastModified?、metadata? で、本文は含まれません。
  • download は StoredFile を返します。これは FileInfo に、File のような name/type エイリアスと arrayBuffer()、text()、blob()、stream() を加えたものです。
条件付き操作

condition はプロバイダーのリクエスト内で ETag の条件を適用します。head() の後に書き込む競合は発生しません。

const created = await files.upload("state.json", body, {
  condition: { type: "create" }, // only if absent
});
await files.upload("state.json", next, {
  condition: { type: "replace", etag: created.etag }, // compare-and-set
});

download と delete は condition: { etag } を受け取ります。copy は condition: { source: { etag }, destination: { type: "create" } } を受け取ります。条件を満たさない場合は FilesError で拒否されます。ネイティブのプリミティブを備えていないアダプターは、I/O を行う前に拒否します(files.capabilities.conditional を確認してください)。一括アップロード、マルチパートアップロード、再開可能なアップロードでは利用できません。

ファイルハンドル

同じキーに対して繰り返し処理を行う場合:

const avatar = files.file("avatars/abc.png");

await avatar.upload(file, { contentType: "image/png" });
if (await avatar.exists()) {
  const meta = await avatar.head();
  const url = await avatar.url({ expiresIn: 300 });
}
await avatar.moveTo("avatars/archived/abc.png");
await avatar.delete();

インスタンスオプション

new Files({ adapter, ... }) に渡します。3 つの OperationOptions(signal、timeout、retries)は呼び出しごとにも指定でき、その場合は呼び出しごとの値が優先されます。

  • prefix — すべてのキーはこのプレフィックスを基準に解決されます。入力時に付加され、出力時に結果から取り除かれます(list、フック、一括処理形式を含む)。アプリケーションコードは独自の名前空間で動作します。new Files({ adapter, prefix: "users" }) → upload("123/a.png") は users/123/a.png を書き込み、結果の key は "123/a.png" になります。
  • readonly: true — すべての書き込み操作(upload、delete、copy、move、signedUploadUrl、abortUpload、および file(key) の書き込みヘルパー)を FilesError { code: "ReadOnly" } でブロックします。読み取りは引き続き可能です。files.readonly() は既存のインスタンスから読み取り専用のビューを作成します(同じアダプター、プレフィックス、タイムアウト、リトライ、フックを使用し、クライアントを追加で作成しません)。files.raw はロックしません。files.isReadOnly でインスタンスが読み取り専用かどうかを確認できます。
  • hooks — 処理を待たずに実行されるオブザーバビリティ機能です。onAction(呼び出しが成功またはエラーで確定するたびに一度実行され、type/key/keys/from/to/status/result/durationMs を受け取ります)、onError(拒否時)、onRetry(スケジュールされたリトライごと)があります。呼び出し元に公開されるペイロードのみを使用し、内部のプレフィックス付きパスは公開しません。フックで例外が発生しても操作は失敗しません。
  • signal — AbortSignal です。中断すると、実行中の単一キーの呼び出しは FilesError { aborted: true } ですぐに失敗します(code: "Provider" のままです)。コンストラクターと呼び出しごとのシグナルは組み合わされ、どちらか一方で中断します。
  • timeout — 試行ごとの期限をミリ秒で指定します(呼び出しごとではありません)。中断され、リトライは行われません。0 または負の値を指定すると無効になります。デフォルト値はありません。
  • retries — 数値({ max })または { max, backoff } を指定します。一時的な Provider エラーのみをリトライします。NotFound/Unauthorized/Conflict、SDK 自体の Invalid/Unsupported/ReadOnly、中断、タイムアウト、ReadableStream のアップロードはリトライされません。デフォルトのバックオフは指数関数的(100ms·2ⁿ、上限 30s)です。

一括処理形式では signal と retries は指定できません — concurrency/stopOnError で処理を管理し、キーごとの失敗を errors[] で返します。references/resilience-and-hooks.md を参照してください。

一括操作

upload、download、head、exists は単一のキーまたは配列を受け取ります。delete は単一または複数のキーを受け取ります。配列形式では同時実行数を制限して処理を並列実行し(デフォルトは 8)、成功と失敗を入力順に分けて保持する構造化された結果を返します。1 つのキーで失敗してもバッチ全体は失敗せず、一部の失敗では例外をスローしません。

const { results, errors } = await files.upload([
  { key: "a.txt", body: "alpha" },
  { key: "b.txt", body: "beta", contentType: "text/plain" },
]);

const { existing, missing } = await files.exists(["a.txt", "b.txt", "c.txt"]);
const { results: deleted } = await files.delete(["a.txt", "b.txt"], {
  concurrency: 16,
});

結果の形式:exists を除くすべての配列形式は { results, errors? } を返します(upload/head → FileInfo[]、download → StoredFile[]、delete → 削除されたキー)。exists → { existing, missing, errors? } となります。errors は { key, error }[] で、すべて成功した場合は完全に省略されます。最初の失敗時に中断するには stopOnError: true を指定します(逐次実行されます)。一括呼び出しはリトライされず、集約された onAction を一度だけ実行します。

大容量で堅牢なアップロード

大きなオブジェクト向けの、呼び出しごとに指定できる upload/download オプションが3つあります。詳細はすべてreferences/large-uploads.mdをご覧ください。

  • upload の multipart — 大きな本文を並列パートに分割します(true、または { partSize, concurrency } を指定します。いずれも正の整数である必要があり、そうでない場合はアップロード時に Invalid がスローされます)。単一リクエストの上限を超える場合や、長さが不明な ReadableStream の本文に適した堅牢な方法です(S3 系アダプターでは、フラグを指定しなくてもマルチパートが自動的に有効になります)。各プロバイダーのネイティブなチャンク分割方式に対応します。バッファー済みの本文しか受け付けない未対応のアダプターでは無視されますが、fetch S3 エンジンではスローされます。
  • upload の control(再開可能なアップロード)— files-sdk からエクスポートされる UploadControl を渡すと、pause()/resume()/abort() を実行できます。また、クラッシュ後に別のプロセスで再開するために、control.toJSON() を永続化できます。長さが既知の本文が必要です(ReadableStream のみの本文は不可)。S3 系、GCS、Firebase、Azure、OneDrive、Dropbox などでサポートされています。未対応のアダプターではスローされます。multipart とは異なり、プロバイダーの再開可能なセッションを制御し、アップロード ID を公開します。
  • download の range — 連続したバイト範囲を取得します({ start, end? }。0 始まりで、end は範囲に含まれます。HTTP の Range セマンティクスであり、slice() ではありません)。動画のシークやダウンロードの再開を実現する基本機能です。範囲取得のプリミティブがないアダプターではスローされます(files.capabilities.rangeRead を確認してください)。
  • upload の onProgress — ({ loaded, total? }) => void。S3 系では真のバイト単位の進捗を報告します(オプションの @aws-sdk/lib-storage ピア依存関係を使用)。

一括処理、移動、転送

  • move(from, to) — アダプター内で名前を変更します(プロバイダーがネイティブな名前変更に対応している場合はそれを使用し、それ以外はコピーして削除します。移動元と移動先が同じ場合は何もしません)。FileHandle には moveTo/moveFrom があります。
  • listAll(opts?) — すべてのページを順次処理する非同期イテラブルです。各ページは実際の list 呼び出しで取得されるため、再試行、タイムアウト、プレフィックスがすべて適用されます。
  • transfer(source, dest, opts?) — トップレベルのエクスポートです。1つの Files インスタンスから別のインスタンスへ、バックエンドをまたいで全オブジェクトをストリーミング転送します(統一されたインターフェイスで唯一可能になる機能です。copy/move は単一アダプター内でのみ動作します)。listAll とストリーミング download、exists、upload を基盤として構築されています。本文、コンテンツタイプ、ユーザーメタデータが引き継がれます(転送先がメタデータをサポートしていない場合、各キーで失敗するのではなく、メタデータは破棄されます)。etag/lastModified は転送先で割り当てられ、Cache-Control は引き継がれません。{ transferred, skipped?, errors? } を返します(一部失敗してもスローされません)。onProgress は処理が完了した各キーについて、status "transferred" | "skipped" | "failed" を報告するため、done は total に達します。onProgress がスローしても無視されます。オプション:prefix、transformKey、overwrite、concurrency(デフォルトは 8)、limit、stopOnError、signal、onProgress。
  • sync(source, dest, opts?) — 繰り返し実行可能なミラーリング用のトップレベルのエクスポートです。新規または変更されたオブジェクトのみをアップロードします(デフォルトでは compare: "etag"、または "size"、あるいは関数を指定できます)。prune: true を指定すると、ソースに存在しなくなった転送先のキーを削除します(破壊的な操作です)。dryRun: true を指定すると、書き込みを行わずに計画を返します。メタデータと onProgress の動作は transfer と同じです(ステータスは "uploaded" | "skipped" | "deleted" | "failed")。{ uploaded, skipped, deleted?, errors? } を返します。
import { Files, transfer } from "files-sdk";
import { s3 } from "files-sdk/s3";
import { r2 } from "files-sdk/r2";

const from = new Files({ adapter: s3({ bucket: "old" }) });
const to = new Files({
  adapter: r2({ bucket: "new", accountId, accessKeyId, secretAccessKey }),
});
const { transferred, errors } = await transfer(from, to, {
  prefix: "uploads/",
});

references/bulk-and-transfer.mdをご覧ください。

フォルダーの一覧表示

list({ delimiter: "/" }) は、キーを区切り文字の位置でまとめ、S3 形式の共通プレフィックスを返します。これはファイルブラウザー UI の基盤となります。prefix: "photos/" を指定すると、items には直下のファイルが入り、ListResult.prefixes にはサブフォルダー(["photos/2023/", "photos/2024/"])が格納されます。オブジェクトストアとフォルダーベースのプロバイダーが対応しています(フォルダーベースのプロバイダーで受け付けられるのは "/" のみです)。フラットストア(UploadThing、Appwrite、PocketBase、Convex、Bunny Storage)ではスローされます。files.capabilities.delimiter を確認してください。カーソルが有効なのは、そのカーソルが生成されたときと完全に同じ prefix および delimiter の組み合わせの場合のみです。

URL の動作

url(key, opts?) は、アダプターが生成できる最も直接的な URL を返します。動作は一律ではありません。

  • 署名アダプター(S3、R2 HTTP、MinIO、RustFS、DigitalOcean Spaces、Storj、Hetzner、Akamai、Backblaze B2、Wasabi、Tigris):opts.expiresIn 秒後に有効期限が切れる、署名付きの GetObject URL を返します(デフォルトは約 3600 秒)。publicBaseUrl を設定すると、通常の url(key) は永続的な URL を返しますが、expiresIn または responseContentDisposition を指定すると、引き続き署名されます。
  • R2 バインディング:publicBaseUrl が設定されていればそれを使用します。HTTP 認証情報も渡されている場合は、HTTP 署名にフォールバックします(ハイブリッド)。それ以外の場合は例外が発生します。
  • Vercel Blob(パブリック):永続的な CDN URL を返します。expiresIn を指定すると Unsupported が発生します。
  • Vercel Blob(プライベート):そのキーに限定された署名付きの GET を返します。expiresIn 秒後に有効期限が切れます(デフォルトは 3600 秒、またはアダプターの defaultUrlExpiresIn。Vercel の上限は 7 日です)。
  • FTP / SFTP / WebDAV:publicBaseUrl(同じツリーを公開する HTTP サーバー)が必要です。設定されていない場合、url() は例外を発生させます。fs は urlBaseUrl が設定されていない限り、file:// URL を返します。
知っておきたい 2 つの UrlOptions
  • expiresIn — 秒数を正の整数で指定します(0、負数、小数、または NaN を指定すると Invalid が発生します)。常に「有効期限付きリンク」を意味します。署名アダプターでは、publicBaseUrl が設定されていても署名付き URL を返します(通常の url(key) は引き続き CDN リンクを返します)。永続リンクのみを提供するアダプター(Vercel Blob パブリック、UploadThing public-read、Convex、Appwrite、fs)では Unsupported が発生します。利用可能な種類は files.capabilities.publicUrl / signedUrl.supported で確認できます。
  • responseContentDisposition — ユーザーアップロード用バケットでは、"attachment"(または 'attachment; filename="..."')を強く推奨します。 これを指定しないと、ユーザーがアップロードした .html やスクリプトを含む SVG がバケットのオリジンでインライン実行される可能性があります(格納型 XSS)。このオプションを渡すと、永続的な CDN URL にはオーバーライドを紐付ける署名がないため、署名アダプターでは署名パスが強制されます(publicBaseUrl が設定されていても同様です)。プリミティブがない Vercel Blob と、HTTP 認証情報のない R2 バインディングでは例外が発生します。
キーのエンコード

キーは生のまま渡してください。publicBaseUrl / urlBaseUrl から構築する URL(および Vercel Blob のパブリック高速パス)では、各キーセグメントが自動的にパーセントエンコードされます。また、署名アダプターではプロバイダーの署名機構を通じてエンコードされます。そのため、キーを事前にエンコードすると二重エンコードされ(%20 → %2520)、署名アダプターでは別のオブジェクトを指すことになります。キーが信頼できない入力に由来する場合は、エスケープするのではなく、検証してください(.. セグメント、制御文字、想定外のプレフィックスを拒否します)。

署名付きアップロード URL

signedUploadUrl(key, opts)。opts: { expiresIn, contentType?, maxSize?, minSize? } です。

  • 必ず maxSize を指定してください。 指定しない場合、アダプターはサーバー側のサイズ制限がない署名付き PUT URL を返します。URL を持つ人は誰でも、expiresIn が経過するまで任意のサイズのファイルをアップロードできます。maxSize を指定すると、対応アダプターはサイズを content-length-range ポリシーで制限する署名付き POST フォームを返します(AWS SDK エンジン上の S3 および S3 互換アダプター、GCS、Firebase)。Vercel Blob は署名付き PUT でサイズを制限します。サイズを制限できないアダプター(R2、Azure、Supabase、fetch S3 エンジンなど)は、安全のため処理を拒否します。
  • minSize のデフォルト値は 1 です(通常はクライアントの不具合を示す空のアップロードを拒否します)。0 バイトのアップロードを許可するには 0 を指定してください。最小サイズの制約がないプロバイダー(Cloudinary、UploadThing、Vercel Blob、Azure、Supabase)では、正の値を明示した minSize を指定するとエラーになります。省略するか、0 を指定してください。
  • プロバイダーが対応している場合、contentType は署名に含まれます。これを強制できないアダプター(bun-s3、Azure、Supabase、Cloudinary、OneDrive、SharePoint)は、参考用のヘッダーを返すのではなく、エラーになります。
  • プロバイダーに有効期限の上限がある場合、expiresIn にはその上限が適用されます。S3 系(bun-s3 と fetch エンジンを含む)では、到着時点ですでに無効な URL を返すのではなく、SigV4 の7日間の上限を超えるとエラーになります。GCS と Firebase の V4 署名も、7日を超えると拒否されます。files.capabilities.signedUrl.maxExpiresIn で上限を確認できます(該当するプロバイダーと UploadThing のプライベートモードでは 604800)。ゲートウェイは要求された有効期限をこの上限に合わせて調整します。
  • 戻り値の形式は次のいずれかです。
    • { method: "PUT", url, headers? }
    • { method: "POST", url, fields } — fields とファイルを含む multipart/form-data で POST します。ファイルは最後にします。

references/client-uploads.mdを参照してください。

エラー

すべてのアダプターエラーは FilesError(files-sdk から再エクスポート)でラップされます。以下のプロパティがあります。

  • .code は FilesErrorCode 型です。値は "NotFound" | "Unauthorized" | "Conflict" | "ReadOnly" | "Invalid" | "Unsupported" | "Provider" です。Invalid は呼び出しが誤っていること(キー、範囲、オプション、設定の不正、または validation() による拒否)を意味します。Unsupported はこのアダプター、モード、プラグインでその操作ができないことを意味します(files.capabilities を確認してください)。Provider はバックエンドまたはトランスポートの失敗を意味します。
  • .aborted — 失敗がキャンセルまたはタイムアウトによる場合は true になります(この場合も code: "Provider" です)。中断と実際のプロバイダー障害を区別するには、コードではなくこのフラグを使います。
  • .cause — 元のプロバイダーエラーです(リクエスト ID やヘッダーが含まれる場合があります。信頼境界を越えて無条件に JSON.stringify しないでください)。
  • .permanent — 同じ呼び出しが常に同じ理由で失敗する場合は true になります。Invalid、Unsupported、ReadOnly では常に true であり、決定的な Provider エラー(Range を無視するホスト、破損した保存データなど)でも true です。再試行は行われず、failover プラグインもこれらのエラーではフェイルオーバーしません。

境界で FilesError をキャッチし、.code に応じて処理してください。再試行されるのは、永続的でない Provider エラーのみです。references/errors-and-recipes.mdを参照してください。

拡張手段

import type { s3 } from "files-sdk/s3";
const native = files.raw; // typed as the native client for the configured adapter

統一 API にないプロバイダー機能(バージョニング、ライフサイクル、ストレージクラスなど)には、これを使用してください。files.adapter から Adapter(例:files.adapter.bucket)にアクセスできます。注:raw は設計上、readonly インスタンスを迂回します。

アダプターカタログ

49 個のアダプターがあります。S3 系および S3 互換のストアは、プロバイダーに合わせたデフォルト設定で s3() アダプターをラップします(MinIO、RustFS、DigitalOcean Spaces、Wasabi、Backblaze B2、Tigris、Railway Buckets、Storj、Hetzner、Scaleway、OVH、Vultr、IBM COS、Oracle、Tencent、Alibaba、Yandex など)。直接バインドするアダプター(R2 worker binding、fs、Vercel Blob、Netlify Blobs、GCS、Azure、Supabase、Dropbox、Google Drive、OneDrive、Box、SharePoint、Cloudinary、UploadThing、Appwrite、Convex、Firebase Storage、PocketBase、FTP、SFTP、WebDAV、Bunny Storage、bun-s3 など)には、それぞれ独自の実装があります。また、files-sdk/memory にはメモリー内アダプターもあります。Map をバックエンドとし、依存関係がなく、アイソモーフィックな完全な Adapter コントラクトを備えており、実際のストレージに触れずに Files を使用するコードをテストできます(url() は不透明な memory:// URL を返します。本番環境での使用には適していません)。

推測ではなく、https://files-sdk.dev の最新リストと各アダプターのオプション(または同梱の docs/adapters/)を必ず確認してください。node_modules/files-sdk/package.json の exports マップが、利用可能なサブパスの正確な情報源です。また、files-sdk/providers は同じカタログをデータとしてエクスポートします(PROVIDERS、getProvider(slug)、各アダプターの環境変数と必須設定)。

S3 互換のラッパーには @aws-sdk/* のピア依存関係が必要です。Cloudflare Workers 上(または AWS SDK を使わない場合)は、files-sdk/s3-fetch(SigV4 の fetch エンジンである s3Fetch())または r2()/minio()/rustfs() の client: "fetch" を使用してください。r2 は Workers 内で自動的にこの方式を選択します。fetch エンジンはマルチパートアップロードとレジューム可能なアップロードに対応していません。

プラグイン

plugins: [...] は、インスタンス上のすべての呼び出しをラップします(plugins[0] が最外層です)。各プラグインはそれぞれ独自のサブパスを持ちます。

サブパスファクトリー機能
files-sdk/validationvalidation()フェイルクローズの書き込みガード:サイズ、MIME タイプ、キーのルールを検証します。
files-sdk/content-typecontentType()マジックバイトを調べて、Content-Type を設定または検証します。
files-sdk/encryptionencryption()クライアント側のエンベロープ AES-256-GCM(generateEncryptionKey())。
files-sdk/compressioncompression()保存時に本文を gzip/deflate で圧縮します。
files-sdk/dedupdedup()コンテンツアドレス方式のストレージ。同一の本文は 1 回だけ保存されます。
files-sdk/versioningversioning()上書き/削除時にスナップショットを作成します。files.versions()/restoreVersion() を使用します。
files-sdk/soft-deletesoftDelete()ごみ箱。trashed()/restoreTrashed()/purge() を使用します。
files-sdk/cachecache()head()/url()/小さなダウンロード用の LRU/KV キャッシュです。カスタム store には、バケット名を指定する namespace が必要です(cache({ store, namespace: "uploads-prod" })。指定しない場合は Invalid)。エントリーは namespace とインスタンスの prefix でスコープされます。インスタンスごとに cache() は 1 つだけ指定できます。書き込み時とプロバイダーのストレージイベント時に無効化されます。
files-sdk/tieringtiering()2 つのバックエンド間で、頻繁に使うオブジェクトとあまり使わないオブジェクトを振り分けます。
files-sdk/failoverfailover()レプリカのバックエンドに対して、プロバイダーの障害時に再試行します。
files-sdk/signed-url-policysignedUrlPolicy()url() の disposition を attachment に固定し、署名付き URL の有効期間に上限を設けます。
files-sdk/auditaudit()変更の実行者・内容・日時を記録するログを、完了まで待機して出力します。
files-sdk/usageusage()操作数とバイト数を計測します。files.usage() を使用します。
files-sdk/tracingtracing()操作ごとに OpenTelemetry スパンを作成します。
files-sdk/zipzip()オブジェクトを ZIP アーカイブとしてストリーミングし、アーカイブをキーに展開します。
files-sdk/eventsevents()バケット通知を単一の FileEvent に正規化します。files.events.on()/dispatch()/webhook() を使用します。ストレージイベントを参照してください。
import { createFiles } from "files-sdk";
import { s3 } from "files-sdk/s3";
import { validation } from "files-sdk/validation";
import { versioning } from "files-sdk/versioning";

const files = createFiles({
  adapter: s3({ bucket: "uploads" }),
  plugins: [validation({ maxSize: 10 * 1024 * 1024 }), versioning()],
});
await files.versions("report.pdf"); // typed because createFiles was used

プラグインがメソッドを追加する場合は new Files ではなく createFiles を使用してください。そうすることで、それらが型に反映されます。順序が重要です。contentType() は validation() より前に配置します。これにより、チェックは主張された型ではなく、スニッフィングされた型を参照します。validation() は versioning()、softDelete()、dedup() より前に配置します。これらの内部キー(スナップショット、ゴミ箱、BLOB)は、それらの後に配置されたプラグインのみを通過するため、さらに後にある validation() はそれらを拒否してしまいます。encryption() は平文を参照する必要があるものの後に配置します([compression(), encryption(key)])。ただし、failover() と tiering() より前に配置します([encryption(key), tiering(...)])。これらはセカンダリ / コールドバックエンドをオニオンの残りの部分の外側で駆動するため、encryption() より前に配置すると、そこにルーティングされるものはすべて暗号化されずに保存されます。他のプラグインを組み合わせる前に、同梱の docs/plugins/ 配下(または https://files-sdk.dev/docs/plugins)にある各プラグインのページを読んでください。

ボディを変換するプラグインは、それをバイパスするものを渡すのではなく、フェイルクローズします。encryption() と compression() は url()、signedUploadUrl()、レンジ読み取り、および再開可能な control アップロードで例外をスローします(また、signedUrl、signedUpload、rangeRead、resumable を非対応として報告します)。dedup() は url()、signedUploadUrl()、および条件付き操作で例外をスローします。これらの拒否は、validation() や contentType() の拒否と同様に permanent であるため、failover() がそれらを、そのプラグインなしで動作するレプリカに再送することはありません。プラグインは FilesPlugin.capabilities?(caps) フックを通じて、何を拒否するかを宣言できます。これは files.capabilities を絞り込むため、呼び出し元とゲートウェイはそれを事前に把握できます(たとえば、ゲートウェイは署名付き URL を使用する代わりにダウンロードとアップロードをプロキシし、プラグインが無効にしたオプションはどのプラグインも実行される前に拒否されます。versioning()、softDelete()、tiering()、および failover() は、それらが拒否するコンペアアンドセット操作の conditional フラグを無効にします)。list() がオブジェクトメタデータを伴わないアダプター(S3 および S3 互換)では、encryption()、compression()、または dedup() 配下の list() 項目は、保存されたオブジェクトのサイズを報告します(dedup() の場合は空のポインターのサイズ)。ただし、download() は引き続きデコードされたコンテンツを返します。

ブラウザアップロードとゲートウェイ(useFiles)

認証情報を配布せずにブラウザに Files API 全体を提供するには、サーバーにゲートウェイをマウントし、クライアントバインディングから呼び出します。

  • サーバー: files-sdk/api の createFilesRouter({ files, authorize, allowedOrigins }) を使用し、フレームワークアダプターの createRouteHandler でマウントします。対応アダプターは files-sdk/next、hono、express、fastify、koa、nitro、astro、sveltekit、tanstack-start です(また、files-sdk/nestjs の FilesModule も使用できます)。ゲートウェイはデフォルトで拒否します。authorize フックも operations 許可リストもない場合、capabilities 以外のすべての動詞は 403 を返します。拒否するには authorize から例外をスローし、制約を返す場合は、通常、"users/<id>/" のようなユーザーごとの keyPrefix を指定します。
    • defaultExpiresIn は URL のデフォルト有効期間にすぎず、上限ではありません。クライアントが要求する有効期間には、authorize から maxExpiresIn を指定して上限を設けてください。
    • キーなしアップロードの場合、presign は maxUploadSize を超える size の申告を拒否します(422、reason: "size")。また、トークンには申告されたサイズ(maxUploadSize が上限)、発行元のオリジン、パス、クエリが紐付けられます。プロキシ経由の PUT はベアラートークンによるアップロードです(トークンだけで、有効期限まで、発行された1つのキーへの書き込みが許可されます。authorize の呼び出しもクライアントの headers もありません)。そのため、リクエストごとに files ファクトリーを使う場合は、インスタンスを URL から選び、Cookie やヘッダーから選ばないでください。complete は、キーが呼び出し元の keyPrefix の範囲外にあるトークンを拒否し、トークンが許可するサイズを超えたオブジェクトを削除します。クライアントのコンテンツタイプが、単一のメディアタイプではない場合(image/png, text/html など)は 422(reason: "type")になります。
    • url() が responseContentDisposition を受け付けないアダプター(Vercel Blob、Box、Dropbox、fs など)では、downloadMode: "auto" がダウンロードをプロキシ経由にするため、attachment が引き続き適用されます。また、authorize の { disposition: "inline" } は disposition を付けずに URL を発行します。このインラインポリシーがない場合、ゲートウェイが attachment を保証できないため、url 操作は 422 の Unsupported エラーで失敗します。
    • Range に対応していないアダプターでプロキシ経由のダウンロードを行う場合、Range: bytes=0-(<video>/<audio> が開く際のリクエスト)にはオブジェクト全体を返します(200)。デフォルトでは、引用符付きの ETag、Last-Modified、Cache-Control: private, no-store、Content-Disposition: attachment; filename="<key's last segment>" を送信し、さらに、適切に形式が整ったタイプと判定されたラスター画像/音声/動画/PDF を除き、保存された HTML/SVG のインラインスクリプト実行を防ぐ Content-Security-Policy: sandbox を送信します。HEAD は本文なしで同じヘッダーを返します。416 では JSON 本文が返されます(Validation、reason range。クライアントでは Invalid がスローされます)。auto モードでは、url() が Unsupported で拒否された場合、プロキシにフォールバックします。
    • versioning()、softDelete()、dedup() のストレージ内にあるキーと list/search のプレフィックス(.versions、.trash、.dedup)は、keyPrefix の範囲内でない限り 403 になります。プラグインの動詞を使用してください。ゲートウェイの Files にないプラグインの動詞は Unsupported(reason capability)になります。filterKeys はバージョン、restoreVersion、restoreTrashed、complete にも適用されます。authorize にはアップロードの params が渡されます(presign:{ files: [{ name, size?, type }], expiresIn? }、キー指定の PUT:{ contentType?, size? })。予約済みプレフィックスは大文字と小文字を区別せず、区切り文字として \ も認識します(.TRASH/x、.trash\x も拒否されます)。
    • FilesError/RouterError 以外の例外(authorize、onUploadComplete、完了ストアからスローされたもの)は、汎用の 500 を返し、ルーターの onError(error, req) に渡されます(デフォルトは console.error)。アダプターの NotFound/Unauthorized/Conflict/Provider のメッセージは固定メッセージ(not found など)に置き換えられます(fs のパスやホスト名が含まれる可能性があるためです)。Provider/Unauthorized のエラーは onError に渡されます。Invalid/Unsupported/ReadOnly と、フックがスローした FilesError はメッセージを保持し、クライアントのキーに書き換えられます。
    • ゲートウェイはクライアント起因の負荷に上限を設けます。maxBatchSize(配列の長さ。デフォルトは 1000、超過時は 413)、maxConcurrency(デフォルトは 16)、maxJsonBodySize(デフォルトは 1 MiB、超過時は 413)を設定できます。search は limit の値にかかわらず、maxListLimit 件ずつページを取得して走査します。1 回の search で読み取るキーは最大 maxSearchScan 件(デフォルトは 10,000 件)で、上限に達すると truncated: true を返します。また、search パターンには maxSearchPatternLength(256)/maxSearchWildcards(4)の上限があります(超過時は 422)。コンパイルできない、またはバックトラッキングが大量に発生する可能性がある match: "regex" パターンも 422 になります。
    • アップロードの記録には、別の「確認」エンドポイントではなく、onUploadComplete({ file, storageKey, files, req, context, uploadId, via }) を使用してください。 このフックは検証済みのアップロードごとに 1 回実行されます。キーなしアップロードでは complete の処理中(head と maxUploadSize の確認後)に、キー指定の upload(key, body) では本文の保存後に実行されます。プロキシ経由の PUT では実行されません。フックの戻り値は、アップロード結果の data としてクライアントに返されます。authorize は context(ユーザー、テナントなど)を返すことができ、フックでは型付きで受け取れます。拒否するには例外をスローします。オブジェクトは削除され(隔離するには onRejected: "keep" を指定します)、クライアントにはエラーが返されます。files-sdk/api の UploadRejectedError を使うと、指定したメッセージとともに 422 を返せます。トークンはステートレスなので、complete が再実行されると、同じ uploadId でフックが再度実行されます。フックを冪等にするか、completions の { get, set } ストア(単一プロセスでは Map ベース、複数インスタンスでは Redis/KV)を渡して完了処理を一度だけにしてください(complete がアップロードを受理した後、プロキシ経由の PUT は 409 を返します)。complete は有効期限切れから completeGracePeriod(デフォルトは 3600 秒)以内のトークンを受け付けます。ただし、ストレージへの直接アップロード用の署名付き URL は、期限切れになるまで引き続き書き込み可能です。クライアントが complete を呼び出さない場合、フックは実行されません。files-sdk/events で照合してください。
  • クライアント: files-sdk/react、files-sdk/vue、files-sdk/svelte の useFiles({ endpoint: "/api/files" }) を使用できます(すべての動詞、アップロードの進行状況、リアクティブな useList/useFile/useSearch に対応)。フレームワークを使用しない場合は、files-sdk/client の createFilesClient を使用してください。useFiles<InferUploadData<typeof router>>() を使ってフックの data に型を指定します(ルーターは型のみをインポートします)。uploads は、呼び出しごと(単体・一括)のファイルごとに 1 つの FileUploadState を蓄積し、reset() で完了済みの状態を消去するまで保持します。各状態は最終的に success、error(error が設定された状態)、または aborted になります。listAll/search の反復処理を含むすべての動詞のエラーは error に反映されます。拒否された呼び出しはすべて FilesError です。ネットワーク障害は Provider(元のエラーは cause に格納)、キャンセルされた呼び出しは aborted: true となり、エンベロープ形式でないレスポンス(認証ミドルウェア、ストレージホストからのレスポンス)はステータスに基づいて分類されます。stopOnError を指定した一括 upload([...])/download([...]) は逐次実行され、SDK と同じく { results, errors } を解決値として返します。クエリーフックの data は現在の入力に属します(キー/エンドポイントの変更時または無効化時にクリアされ、refetch() の間は保持されます)。フックは signal オプションにも対応します。search() のジェネレーターは、ゲートウェイの走査が上限に達して途中で停止した場合、{ truncated }(SearchSummary)を返します。 フレームワークごとのセットアップ、認可、shadcn コンポーネントレジストリについては、同梱の docs/ui/(または https://files-sdk.dev/docs/ui)をご覧ください。

ストレージイベント

files-sdk/events は、各プロバイダーのバケット通知(SQS/Lambda/EventBridge/SNS 経由の S3、MinIO ウェブフック、R2 Queues、GCS Pub/Sub、Pub/Sub 経由の Storj、Azure Event Grid、B2、Tigris、Supabase、Cloudinary、Appwrite、Box)を単一の FileEvent(type: "created" | "deleted"、呼び出し側に公開される key、size?、etag?、versionId?、contentType?、time、source、provider、id、raw)に変換し、files.events.on(type, glob?, handler) にルーティングします。キューコンシューマーは files.events.dispatch(message) を呼び出します。プッシュ型プロバイダーでは、任意のゲートウェイバインディングとともに files.events.webhook({ verify }) をマウントします(verify は必須です。{ token }、{ google: { audience, email } }(両方必須)、{ secret }、{ sns: { topicArn } }(トピックが必須で、署名付きの Timestamp が検証されます)、または false)。他のバケットのイベントはデフォルトで破棄されます(bucket のデフォルトはアダプターのバケットです。false を指定するとすべてのイベントが受け入れられます)。ゲートウェイ経由のアップロードと(events({ sdk: true }) を指定した場合の)インスタンス自身による書き込みは、同じハンドラーに届きます。配信は少なくとも 1 回行われます(Supabase のウェブフックは 1 回のみで、再試行されません)。順序は保証されないため、event.id を使ってハンドラーを冪等にするか、dedupe ストアを渡してください。メモリーアダプターはネイティブにイベントを発行します(テストでは await files.events.settled() を使用します)。references/events.md をご覧ください。

CLI と MCP サーバー

files-sdk には、SDK と完全に同等の機能を備えた files CLI(files バイナリー)が含まれています。グローバルにインストールするか、npx -p files-sdk files … で実行してください。--provider <name>(または FILES_SDK_PROVIDER)でプロバイダーを選択します。認証情報はアダプターの標準環境変数から取得されます。出力はデフォルトで JSON 形式です。本文は標準入力/標準出力を介してストリーム転送されます。

files --provider s3 --bucket uploads upload reports/q1.pdf --file ./q1.pdf
files --provider s3 --bucket uploads list --prefix reports/ --all | jq '.items[].key'
files --provider s3 --bucket old transfer --to '{"provider":"r2","bucket":"new",...}' --prefix uploads/

コマンド:upload download head exists list search copy move delete url sign-upload capabilities transfer sync events mcp(files events parse [file] --format <s3|r2|gcs|…> は、通知の配信内容を正規化したイベントを出力します)。グローバルフラグはコンストラクターに対応しています:--key-prefix(インスタンスのプレフィックス。list --prefix とは別です)、--timeout、--retries。head/exists/delete は複数のキーと --concurrency/--stop-on-error を受け付けます。download --range、upload --multipart/--part-size、list --all、upload --dir/download --out-dir も使用できます。

組み込みの MCP サーバー(files … mcp)は、デフォルトで読み取り専用です。download、head、exists、list、search、url、capabilities を公開します。--allow-writes を渡すと、upload、delete、copy、move、sign-upload も公開されます。さらに、transfer と sync の使用には、オペレーターが固定した送信先を mcp --allow-writes --to '<json>' で指定する必要があります(エージェントが送信先を選ぶことはありません)。プロバイダーと認証情報は起動時にバインドされ、エージェントが渡せるのは操作引数だけで、シークレットは渡せません。バイナリーペイロードは Base64 として往復します。

references/cli-and-mcp.md をご覧ください。(この MCP サーバーは CLI レベルのバインディングです。以下のプロセス内 AI ツールバインディングとは別のものです。)

AI ツール

3 つのサブパスでは、設定済みの Files インスタンスを、AI エージェント向けのプロセス内ツールとして公開します。いずれも同じ 8 つの操作(listFiles、getFileMetadata、downloadFile、getFileUrl、uploadFile、deleteFile、copyFile、signUploadUrl)と、同じ承認ゲートのデフォルト設定(書き込み操作 4 つにはゲートがあり、読み取り操作にはありません)を共有します。downloadFile には maxBytes の上限があり、モデルがサイズ制限のないオブジェクトをコンテキストに取り込むことを防ぎます。

サブパス対象ファクトリー
files-sdk/ai-sdkVercel AI SDK(generateText、streamText、ToolLoopAgent)createFileTools
files-sdk/openaiOpenAI Responses API および Agents SDKcreateResponsesFileTools / createAgentsFileTools
files-sdk/claudeAnthropic Claude Agent SDKcreateClaudeFileTools
import { Files } from "files-sdk";
import { createFileTools } from "files-sdk/ai-sdk";
import { s3 } from "files-sdk/s3";
import { generateText } from "ai";

const files = new Files({ adapter: s3({ bucket: "uploads" }) });

await generateText({
  model,
  tools: createFileTools({ files }),
  prompt: "Find every CSV under reports/ and summarize the latest one.",
});

createFileTools の主なオプション(3 つすべてで共通):

  • readOnly: true — 書き込みツール(uploadFile、deleteFile、copyFile、signUploadUrl)をすべて除外します。モデルはバケットを変更できません。(AI に限定しないロックについては、インスタンスオプションの SDK レベルの readonly を参照してください。)
  • requireApproval — デフォルトは true(すべての書き込み操作に承認が必要です)。false、または { deleteFile: true, uploadFile: false } のようなツールごとのレコードを渡します。
  • overrides — ツールごとの description、title、needsApproval のパッチです。execute、inputSchema、outputSchema は上書きできません。

references/ai-tools.mdを参照してください。

Effect

files-sdk/effect は Files インスタンスを Effect v4 に接続します(オプションのピア依存関係 effect@^4)。Files は Context.Service です。Files.layer(instanceOrOptions) で提供できます(コンストラクターが拒否するオプションがある場合、レイヤーは Invalid の理由で失敗します)。このサービスは Files のメソッドとオプションを反映します。操作は Effect<A, FilesError> を返し、listAll/search は Stream<FileInfo, FilesError> を返します。また、download は DownloadedFile に解決され、その text/arrayBuffer/blob は Effect、stream は Stream<Uint8Array> です。

import { Effect } from "effect";
import { Files } from "files-sdk/effect";
import { s3 } from "files-sdk/s3";

const program = Effect.gen(function* () {
  const files = yield* Files;
  const file = yield* files.download("settings.json");
  return yield* file.text;
}).pipe(
  Effect.catchReason("FilesError", "NotFound", () => Effect.succeed("{}"))
);

await Effect.runPromise(
  program.pipe(Effect.provide(Files.layer({ adapter: s3({ bucket: "app" }) })))
);
  • エラー:1 つの FilesError(タグ "FilesError")があり、その reason は SDK のコードごとにタグ付けされたエラー(NotFound、Unauthorized、Conflict、ReadOnly、Invalid、Unsupported、Provider)です。reason には message、permanent、timedOut、aborted、applied、appliedEtag、cause(SDK の FilesError)が含まれます。Effect.catchReason/catchReasons を使うか、Effect.unwrapReason("FilesError") の後に catchTag を使います。SDK の再試行ポリシーに合わせるには、インスタンスの retries を未設定にしたうえで、Effect.retry({ while: (e) => e.reason._tag === "Provider" && !e.reason.permanent && !e.reason.aborted }) を使います。
  • キャンセル:ファイバーの AbortSignal が signal として渡されます。Effect.timeout/中断は SDK 呼び出しの待機を停止し、キャンセルをアダプターに転送しますが、すべてのプロバイダー SDK が基盤のリクエストを停止できるわけではありません。一括(配列)形式では呼び出しごとのシグナルを受け取らず、完了まで実行されます。バッファー済みの本文アクセサー(text、arrayBuffer、blob)を中断すると、ほかに読み取りを待っている処理がない限り、本文の読み取りがキャンセルされます。キャンセルされた本文を後から読み取ると aborted として失敗するため、再度ダウンロードしてください。
  • ストレージイベント(events() プラグインが必要です。なければ Unsupported):files.events.on(type, glob?, handler) は、Scope の存続期間中 Effect ハンドラーを実行し、ハンドラーの完了を待ってからイベントを配信します(少なくとも 1 回)。files.events.stream() は Stream ですが、バッファー時にイベントを確認するため、プロセスが停止するとバッファー済みイベントは失われます。永続的な処理には on を使ってください。キューのコンシューマーには parse/dispatch を使います。
  • プラグインメソッド(versions()、usage() など)はサービスに含まれません。files.tryPromise((client, signal) => client.versions(key)) を使います。型付きのプラグインメソッドや複数のバケットを扱う場合は、独自の Context.Service<Self, FilesService<typeof client>> を宣言し、make(client) を提供してください。

選択ガイド

  • 「アプリにファイルのアップロードを追加するには?」 → ホスティング先/プロバイダーに合ったアダプターを選び、new Files({ adapter: x({...}) }) と upload/url を示します。
  • プロバイダーを切り替える → サブパスのインポートとアダプターファクトリーの呼び出しを変更します。それ以外のコードは変更不要です。
  • クライアント側での署名付きアップロード → 常に maxSize を指定して signedUploadUrl を使います。PUT と POST で戻り値の形式が異なる点を説明します。
  • 公開ダウンロード URL → files.url(key) を使います。ユーザーコンテンツには responseContentDisposition: "attachment" を推奨します。アダプターが url() でエラーになる場合(設定なしの R2 バインディング、publicBaseUrl のない FTP/SFTP/WebDAV、Netlify Blobs、publicByDefault のない Google Drive/OneDrive/SharePoint)は、download() を使うか、publicBaseUrl/HTTP 認証情報を設定します。
  • 大きなファイル/不安定な接続 → 大きな本体や長さ不明のストリームには multipart を使います。一時停止/再開やクラッシュ後の復旧には再開可能な control(UploadControl)を使います。シーク/再開には download({ range }) を使います。
  • 多数のキーを一度に処理する → 一括配列形式(upload([...])、delete([...]) など)と concurrency/stopOnError を使います。result.errors を確認します。
  • バケットを別のプロバイダーに移行する → トップレベルの transfer(from, to, { prefix }) を使います。バックアップミラーを最新の状態に保つ → sync(from, to, { prune }) を使います。
  • 名前/パターンでファイルを探す → files.search("reports/**/*.pdf") を使います。
  • 新規作成のみ、または比較してから設定する書き込み → upload(..., { condition }) を使います。
  • ストレージを検証、暗号化、バージョン管理、キャッシュ、またはトレースする → 該当するプラグインを使います。
  • ブラウザーからアップロードする → 単一のアップロードフォームには署名付き signedUploadUrl を使い、ブラウザー向けのフル機能のファイルマネージャーにはゲートウェイと useFiles を使います。
  • キーの名前を変更する → move を使います。バケット全体を走査する → listAll を使います。ファイルブラウザーのフォルダー → list({ delimiter: "/" }) を使います。
  • マルチテナント/名前空間付きのキー → new Files({ prefix }) を使います。
  • ストレージを読み取り専用にする → SDK レベルで new Files({ readonly: true })/files.readonly() を使います。
  • 監査ログ/メトリクス/アクティビティフィード → hooks(onAction/onError/onRetry)を使います。
  • シェルスクリプト/CI/バケットの手早い確認 → files CLI を使います。MCP クライアント(Claude Code など)にバケットへのアクセスを許可する → files … mcp を使います(読み取り専用です。書き込みを許可する場合は、意図を明確にして --allow-writes を追加してください)。
  • アプリ内の LLM にバケットへのアクセスを許可する → 該当する AI ツールのサブパスを使います。書き込みでは requireApproval を有効のままにするのがデフォルトです。読み取りだけが必要な場合は readOnly: true を提案します。
  • Effect(v4)のコードベース → files-sdk/effect を使います。Files.layer(...) を提供し、yield* Files を使って、Effect.catchReason("FilesError", "NotFound", …) でエラーを処理します。
  • Files を使用するコードをテストする → files-sdk/memory に差し替えます。
  • 統一 API にない機能 → files.raw とプロバイダーのネイティブクライアントを使います。

参考資料

ユーザーのタスクに関連する参考ファイルのみを読み込んでください。すべてを事前に読み込まないでください。

パッケージがローカルにインストールされている場合、node_modules/files-sdk/docs にバージョンが一致した完全なドキュメントがあります(冒頭の注記を参照)。以下のバンドル済み参考資料にないアダプターごとの詳細については、こちらを参照してください。

  • references/adapter-setup.md — よく使われるアダプター(s3、HTTP・バインディング・ハイブリッド方式の r2、パブリック・プライベート方式の vercel-blob、gcs、azure、minio、fs)の構築スニペットと、わかりにくい設定項目。
  • references/client-uploads.md — 署名付きアップロードの一連のフロー:maxSize を指定して signedUploadUrl を返すサーバールート、PUT と POST のクライアント側の処理、POST のフィールド順序に関する注意点、サーバー側での確認。
  • references/large-uploads.md — マルチパート、再開可能なアップロード(UploadControl、プロセスをまたいだ再開)、範囲指定ダウンロード、onProgress:それぞれを使う場面、アダプターごとの対応状況、注意点(長さが既知のボディ、非対応時の例外、ストリームの自動マルチパート化)。
  • references/bulk-and-transfer.md — 一括操作の配列形式と結果の形、listAll、move、プロバイダーをまたぐ transfer、ミラーリングする sync、delimiter を使ったフォルダー一覧取得。
  • references/resilience-and-hooks.md — retries、timeout、キャンセル(signal)、prefix によるスコープ設定、readonly ビュー、onAction/onError/onRetry フック。
  • references/cli-and-mcp.md — files CLI コマンド(search、sync、capabilities を含む)、グローバルフラグ、JSON/ストリーム出力、組み込み MCP サーバー(読み取り専用と --allow-writes、転送・同期用の --to)を MCP クライアントに接続する方法。
  • references/ai-tools.md — files-sdk/ai-sdk、files-sdk/openai(Responses と Agents)、files-sdk/claude の完全な例。readOnly、細かな承認設定、ツールごとの上書き、ダウンロード時の maxBytes ガード、3 つの選び方を説明します。
  • references/errors-and-recipes.md — FilesError.code の値(ReadOnly を含む)と aborted フラグ、exists()/head() の落とし穴、キーのエンコード規則、@aws-sdk/client-s3、@vercel/blob、@google-cloud/storage からの移行時の書き換え例。

検証

具体的な内容を回答する前に、次の点を確認してください。

  • 選択されたアダプターが実際に存在することを、node_modules/files-sdk/package.json の exports(または files-sdk/providers の PROVIDER_NAMES)を確認して確かめてください。
  • わかりにくい動作(URL 署名、exists の意味、signedUploadUrl の POST と PUT の違い、range/delimiter/再開可能な control に対応するアダプター)については、記憶に頼らず、node_modules/files-sdk/dist/index.d.ts と dist/<adapter>/index.d.ts の JSDoc、またはバンドル済みの docs/ を再確認してください。または、実行時に files.capabilities を確認してください。

コメント