{"_id":"@bunny.net/file-manager-handler","_rev":"2-d6895c753f8634ab06c45105e21961cc","name":"@bunny.net/file-manager-handler","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"@bunny.net/file-manager-handler","version":"0.0.1","_id":"@bunny.net/file-manager-handler@0.0.1","maintainers":[{"name":"kevin_at_bunny","email":"kevin@bunny.net"},{"name":"antho-bunny","email":"anthony@bunny.net"},{"name":"notrab","email":"jamie@notrab.dev"},{"name":"bogdan-at-bunny","email":"bogdan@bunny.net"}],"dist":{"shasum":"35cb750a00b2dc326a3164038f20ad4b3c4d7cde","tarball":"https://registry.npmjs.org/@bunny.net/file-manager-handler/-/file-manager-handler-0.0.1.tgz","fileCount":8,"integrity":"sha512-571oSdc/QpFGKxc7V+fLvUolhAc1aDCHD9XR2UhwRFO3riZ8bOfXSTbielOcoeKbr4TaJs7aDm7gvC7vI2QOcw==","signatures":[{"sig":"MEYCIQDvMoHPwRAZA5YiHjXwhzpOIr5yd3cfxe49D11Nscjg3wIhAIhSxzzXI6Gyp7dWDSZmXpeJ2cvCCfCPLMDHamPNlaEd","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":53235},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"e30b7b82d2997aaa97925aead3cee193bfe1935e","scripts":{"dev":"tsup --watch","build":"tsup","clean":"rm -rf dist","typecheck":"tsc --noEmit"},"_npmUser":{"name":"notrab","email":"jamie@notrab.dev"},"_npmVersion":"10.8.2","description":"Server-side handler for browsing, creating, deleting, and importing files in [Bunny Storage](https://bunny.net/storage). Works with any framework that supports standard `Request`/`Response`.","directories":{},"_nodeVersion":"20.20.1","dependencies":{"@bunny.net/storage-sdk":"^0.3.1","@bunny.net/upload-shared":"workspace:*","@bunny.net/file-manager-core":"workspace:*"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.5.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/file-manager-handler_0.0.1_1774534838305_0.3128605127349988","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@bunny.net/file-manager-handler","publishConfig":{"access":"public"},"version":"0.0.2","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","clean":"rm -rf dist"},"dependencies":{"@bunny.net/file-manager-core":"0.0.2","@bunny.net/storage-sdk":"^0.3.1","@bunny.net/upload-shared":"0.0.2"},"devDependencies":{"@types/node":"^22.0.0","tsup":"^8.0.0","typescript":"^5.5.0"},"_id":"@bunny.net/file-manager-handler@0.0.2","gitHead":"93aa8ca7a45d19966df2a8f738e18ca517a03e01","description":"Server-side handler for browsing, creating, deleting, and importing files in [Bunny Storage](https://bunny.net/storage). Works with any framework that supports standard `Request`/`Response`.","_nodeVersion":"20.20.1","_npmVersion":"10.8.2","dist":{"integrity":"sha512-wa54xPhA/BkSLfR6E2j6ih2DNo5a5XMKz7Zs+Wu6vgmg5/ftykpOt1B8TrbdYDTJp4z9x7/J9DK544tpKjT9zw==","shasum":"1e1d4905e6c9f09f934bed746a6c116b71acf088","tarball":"https://registry.npmjs.org/@bunny.net/file-manager-handler/-/file-manager-handler-0.0.2.tgz","fileCount":8,"unpackedSize":53223,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFw9whkLrouchJcPIR9/4gI+15PMF1AC2E+qUWPrjRZvAiAF2cdSLOhAj1Hl9YBm7ab4cgaLBUiLMEhYS7rTpuwGYQ=="}]},"_npmUser":{"name":"notrab","email":"jamie@notrab.dev"},"directories":{},"maintainers":[{"name":"kevin_at_bunny","email":"kevin@bunny.net"},{"name":"antho-bunny","email":"anthony@bunny.net"},{"name":"notrab","email":"jamie@notrab.dev"},{"name":"bogdan-at-bunny","email":"bogdan@bunny.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/file-manager-handler_0.0.2_1774539271844_0.9087674169204021"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-26T14:20:38.229Z","modified":"2026-03-26T15:34:32.193Z","0.0.1":"2026-03-26T14:20:38.444Z","0.0.2":"2026-03-26T15:34:31.988Z"},"description":"Server-side handler for browsing, creating, deleting, and importing files in [Bunny Storage](https://bunny.net/storage). Works with any framework that supports standard `Request`/`Response`.","maintainers":[{"name":"kevin_at_bunny","email":"kevin@bunny.net"},{"name":"antho-bunny","email":"anthony@bunny.net"},{"name":"notrab","email":"jamie@notrab.dev"},{"name":"bogdan-at-bunny","email":"bogdan@bunny.net"}],"readme":"# @bunny.net/file-manager-handler\n\nServer-side handler for browsing, creating, deleting, and importing files in [Bunny Storage](https://bunny.net/storage). Works with any framework that supports standard `Request`/`Response`.\n\nFor the client-side engine, see [`@bunny.net/file-manager-core`](../file-manager-core). For React components, see [`@bunny.net/upload-react`](../react).\n\n## Install\n\n```bash\nnpm install @bunny.net/file-manager-handler\n```\n\n## Environment variables\n\n```env\nBUNNY_STORAGE_ZONE=my-zone\nBUNNY_STORAGE_PASSWORD=my-password\nBUNNY_CDN_BASE=https://my-zone.b-cdn.net\nBUNNY_STORAGE_REGION=de          # optional, defaults to Falkenstein\n```\n\n## Setup\n\n### Next.js\n\n```ts\n// app/.bunny/files/route.ts\nimport { serveBunnyFileManager } from \"@bunny.net/upload-next\";\nimport { createFileManagerHandler } from \"@bunny.net/file-manager-handler\";\n\nexport const { GET, POST, DELETE } = serveBunnyFileManager(\n  createFileManagerHandler()\n);\n```\n\n### Hono\n\n```ts\nimport { Hono } from \"hono\";\nimport { createFileManagerHandler } from \"@bunny.net/file-manager-handler\";\n\nconst app = new Hono();\nconst handler = createFileManagerHandler();\n\napp.all(\"/.bunny/files\", (c) => handler(c.req.raw));\n```\n\n### React Router / Remix\n\n```ts\n// app/routes/files.ts\nimport { createFileManagerHandler } from \"@bunny.net/file-manager-handler\";\n\nconst handler = createFileManagerHandler();\n\nexport async function loader({ request }: { request: Request }) {\n  return handler(request);\n}\n\nexport async function action({ request }: { request: Request }) {\n  return handler(request);\n}\n```\n\n### SolidStart\n\n```ts\n// src/routes/.bunny/files.ts\nimport type { APIEvent } from \"@solidjs/start/server\";\nimport { createFileManagerHandler } from \"@bunny.net/file-manager-handler\";\n\nconst handler = createFileManagerHandler();\n\nexport async function GET(event: APIEvent) {\n  return handler(event.request);\n}\nexport async function POST(event: APIEvent) {\n  return handler(event.request);\n}\nexport async function DELETE(event: APIEvent) {\n  return handler(event.request);\n}\n```\n\n## API\n\n### `createFileManagerHandler(options?)`\n\nReturns an async `(request: Request) => Promise<Response>` handler.\n\n| Option | Type | Default | Description |\n|---|---|---|---|\n| `storageZone` | `string` | `BUNNY_STORAGE_ZONE` | Storage zone name |\n| `storagePassword` | `string` | `BUNNY_STORAGE_PASSWORD` | Storage zone password |\n| `cdnBase` | `string` | `BUNNY_CDN_BASE` | CDN base URL |\n| `storageRegion` | `regions.StorageRegion` | `Falkenstein` | Storage region (re-exported from `@bunny.net/storage-sdk`) |\n\n### Lifecycle hooks\n\nAll hooks receive the relevant path and the original `Request`. Throw a `FileManagerError` to return an error response.\n\n| Hook | Signature | Description |\n|---|---|---|\n| `onBeforeList` | `(path, req) => void` | Before listing a directory |\n| `onBeforeDelete` | `(path, req) => void` | Before deleting a file or folder |\n| `onBeforeCreateFolder` | `(path, req) => void` | Before creating a folder |\n| `onBeforeDownload` | `(path, req) => void` | Before downloading a file |\n| `onBeforeImport` | `(url, path, req) => void` | Before importing a file from URL |\n\n```ts\nimport { createFileManagerHandler, FileManagerError } from \"@bunny.net/file-manager-handler\";\n\nconst handler = createFileManagerHandler({\n  onBeforeList: async (path, req) => {\n    const session = await getSession(req.headers.get(\"cookie\"));\n    if (!session) throw new FileManagerError(\"Unauthorized\", 401);\n  },\n  onBeforeDelete: async (path, req) => {\n    if (path.startsWith(\"/protected/\")) {\n      throw new FileManagerError(\"Cannot delete protected files\", 403);\n    }\n  },\n});\n```\n\n## HTTP endpoints\n\nThe handler responds to all methods on a single route:\n\n| Method | Query / Body | Description |\n|---|---|---|\n| `GET` | `?path=/dir/` | List directory contents |\n| `GET` | `?path=/file.jpg&download=true` | Download a file |\n| `POST` | `{ path: \"/dir/new-folder/\" }` | Create a folder |\n| `DELETE` | `?path=/file.jpg` | Delete a file (trailing `/` for directories) |\n| `PUT` | `{ url: \"https://...\", path: \"/dest.jpg\" }` | Import file from URL |\n\n### Response format\n\n**List directory:**\n\nThe handler converts `@bunny.net/storage-sdk`'s `StorageFile` objects into [`StorageEntry`](../file-manager-core) objects — the same type used by the client-side file manager. Dates are serialized to ISO 8601 strings and server-only fields are stripped.\n\n```json\n{\n  \"path\": \"/images/\",\n  \"entries\": [\n    {\n      \"guid\": \"abc-123\",\n      \"objectName\": \"photo.jpg\",\n      \"path\": \"/images/\",\n      \"isDirectory\": false,\n      \"length\": 204800,\n      \"contentType\": \"image/jpeg\",\n      \"lastChanged\": \"2024-01-15T10:30:00.000Z\",\n      \"dateCreated\": \"2024-01-15T10:30:00.000Z\",\n      \"checksum\": \"abc123...\"\n    }\n  ],\n  \"cdnBase\": \"https://my-zone.b-cdn.net\"\n}\n```\n\nSee [`@bunny.net/file-manager-core`](../file-manager-core#storageentry) for the full `StorageEntry` type definition.\n","readmeFilename":"README.md"}