{"_id":"@bunny.net/file-manager-core","_rev":"2-58b08c941f6a5dd63cef7d795e9866f7","name":"@bunny.net/file-manager-core","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"@bunny.net/file-manager-core","version":"0.0.1","_id":"@bunny.net/file-manager-core@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":"16e49eeb4c070366b29f2026c71998b2ede3f101","tarball":"https://registry.npmjs.org/@bunny.net/file-manager-core/-/file-manager-core-0.0.1.tgz","fileCount":16,"integrity":"sha512-b7gnRkAgrwo1zLtrVmgdC5bJYzZ53fuH8q+iEVSpUmigAV9lmVUxgCb723wDeuBul+sxV+O3+CED77sHCwrTnQ==","signatures":[{"sig":"MEYCIQCTT1zbz8XBzgk+nWSwXlbt0e1i7MJUe06gHMqxXPgE7AIhAKj8OFLAECuk1pktseaNHWaIiFbNt1to6Et+DSRZM4Rw","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":85965},"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"}},"./actions":{"import":{"types":"./dist/actions.d.ts","default":"./dist/actions.js"},"require":{"types":"./dist/actions.d.cts","default":"./dist/actions.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":"Framework-agnostic file manager engine for [Bunny Storage](https://bunny.net/storage). Handles navigation, selection, CRUD operations, and custom actions.","directories":{},"_nodeVersion":"20.20.1","dependencies":{"@bunny.net/upload-shared":"workspace:*"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.5.0"},"_npmOperationalInternal":{"tmp":"tmp/file-manager-core_0.0.1_1774534838006_0.6303633106311748","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@bunny.net/file-manager-core","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"}},"./actions":{"import":{"types":"./dist/actions.d.ts","default":"./dist/actions.js"},"require":{"types":"./dist/actions.d.cts","default":"./dist/actions.cjs"}}},"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","clean":"rm -rf dist"},"dependencies":{"@bunny.net/upload-shared":"0.0.2"},"devDependencies":{"tsup":"^8.0.0","typescript":"^5.5.0"},"_id":"@bunny.net/file-manager-core@0.0.2","gitHead":"93aa8ca7a45d19966df2a8f738e18ca517a03e01","description":"Framework-agnostic file manager engine for [Bunny Storage](https://bunny.net/storage). Handles navigation, selection, CRUD operations, and custom actions.","_nodeVersion":"20.20.1","_npmVersion":"10.8.2","dist":{"integrity":"sha512-8DbroJZCSox4XZYmJ5LF4LqyibUDJe/2F2TcDB4/rYR5LG4d6mmdgrjyNUC0FrT+tIG6Xfsk4G98U0xPGFGKxA==","shasum":"3035ff22d4fb73b7739db4fc0f6804fba4674b14","tarball":"https://registry.npmjs.org/@bunny.net/file-manager-core/-/file-manager-core-0.0.2.tgz","fileCount":16,"unpackedSize":85959,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFqYIPyiZfzmfb2MOW4hRa9Av+5djsQCr12xivO6quxLAiBhIH5v6mQQ+SzeuKnyPqVp4V36XesQediQW39BIAQW5w=="}]},"_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-core_0.0.2_1774539271972_0.7512271342014796"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-26T14:20:37.908Z","modified":"2026-03-26T15:34:32.258Z","0.0.1":"2026-03-26T14:20:38.173Z","0.0.2":"2026-03-26T15:34:32.126Z"},"description":"Framework-agnostic file manager engine for [Bunny Storage](https://bunny.net/storage). Handles navigation, selection, CRUD operations, and custom actions.","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-core\n\nFramework-agnostic file manager engine for [Bunny Storage](https://bunny.net/storage). Handles navigation, selection, CRUD operations, and custom actions.\n\nThis is the core library — for React, see [`@bunny.net/upload-react`](../react). For the server handler, see [`@bunny.net/file-manager-handler`](../file-manager-handler).\n\n## Install\n\n```bash\nnpm install @bunny.net/file-manager-core\n```\n\n## Usage\n\n```ts\nimport { createFileManager } from \"@bunny.net/file-manager-core\";\n\nconst fm = createFileManager({\n  endpoint: \"/.bunny/files\",\n  initialPath: \"/\",\n});\n\n// Navigate and list files\nawait fm.navigate(\"/images\");\nconst state = fm.getState();\nconsole.log(state.entries); // StorageEntry[]\n\n// Selection\nfm.toggleSelect(state.entries[0].guid);\nfm.selectAll();\nconst selected = fm.getSelected();\n\n// CRUD\nawait fm.createFolder(\"photos\");\nawait fm.deleteEntry(\"/images/old.jpg\");\nawait fm.importFromUrl(\"https://example.com/photo.jpg\");\n\n// URLs\nfm.cdnUrl(\"/images/photo.jpg\");  // https://my-zone.b-cdn.net/images/photo.jpg\nfm.downloadUrl(\"/images/photo.jpg\"); // /.bunny/files?path=%2Fimages%2Fphoto.jpg&download=true\n\n// Clean up\nfm.destroy();\n```\n\n## API\n\n### `createFileManager(options?)`\n\nCreates a new `FileManager` instance.\n\n| Option | Type | Default | Description |\n|---|---|---|---|\n| `endpoint` | `string` | `\"/.bunny/files\"` | Server handler endpoint |\n| `cdnBase` | `string` | — | CDN base URL (auto-detected from server if not set) |\n| `initialPath` | `string` | `\"/\"` | Starting directory path |\n| `actions` | `FileManagerAction[]` | — | Custom actions to register |\n\n### Navigation\n\n| Method | Description |\n|---|---|\n| `navigate(path)` | Navigate to a directory and fetch its entries |\n| `goUp()` | Navigate to parent directory |\n| `refresh()` | Reload current directory |\n| `getBreadcrumbs()` | Get breadcrumb trail as `{ label, path }[]` |\n\n### Selection\n\n| Method | Description |\n|---|---|\n| `select(guid)` | Select an entry |\n| `deselect(guid)` | Deselect an entry |\n| `toggleSelect(guid)` | Toggle an entry's selection |\n| `selectAll()` | Select all entries |\n| `deselectAll()` | Deselect all entries |\n| `getSelected()` | Get selected `StorageEntry[]` |\n\n### CRUD\n\n| Method | Description |\n|---|---|\n| `createFolder(name)` | Create a folder in the current directory |\n| `deleteEntry(path)` | Delete a file or directory |\n| `deleteSelected()` | Delete all selected entries |\n| `importFromUrl(url, filename?)` | Import a file from URL into the current directory |\n| `cdnUrl(path)` | Get the public CDN URL for a path |\n| `downloadUrl(path)` | Get the download URL for a path |\n\n### Custom Actions\n\nRegister actions that operate on selected files:\n\n```ts\nimport { copyUrlAction, downloadAction } from \"@bunny.net/file-manager-core/actions\";\n\nconst fm = createFileManager({\n  actions: [copyUrlAction, downloadAction],\n});\n\n// Or register later\nfm.registerAction({\n  id: \"insert-image\",\n  label: \"Insert Image\",\n  target: \"single\", // \"single\" | \"multi\" | \"both\"\n  isApplicable: (entries) => /\\.(jpg|png|webp)$/i.test(entries[0].objectName),\n  handler: (entries, { fileManager }) => {\n    const url = fileManager.cdnUrl(entries[0].path + entries[0].objectName);\n    editor.insertImage(url);\n  },\n});\n\n// Get applicable actions for current selection\nconst actions = fm.getActions();\nawait fm.executeAction(\"insert-image\");\n```\n\n| Method | Description |\n|---|---|\n| `registerAction(action)` | Register a custom action |\n| `unregisterAction(id)` | Remove a registered action |\n| `getActions(entries?)` | Get actions applicable to the given (or selected) entries |\n| `executeAction(id, entries?)` | Execute an action |\n\n### State & Events\n\n```ts\n// Get current state\nconst state = fm.getState();\n// { currentPath, entries, selected, status, error }\n\n// Subscribe to state changes (for framework integrations)\nconst unsub = fm.subscribe(() => {\n  console.log(fm.getState());\n});\n\n// Listen to specific events\nfm.on(\"navigate\", (path) => console.log(\"Navigated to:\", path));\nfm.on(\"selection-change\", (selected) => console.log(\"Selected:\", selected));\nfm.on(\"entries-loaded\", (entries) => console.log(\"Loaded:\", entries.length));\nfm.on(\"error\", (error) => console.error(error));\nfm.on(\"action-start\", (id, entries) => console.log(\"Action started:\", id));\nfm.on(\"action-complete\", (id, entries) => console.log(\"Action done:\", id));\nfm.on(\"import-start\", (url, path) => console.log(\"Importing:\", url));\nfm.on(\"import-complete\", (url, path) => console.log(\"Imported:\", url));\n```\n\n### Built-in Actions\n\nImport from `@bunny.net/file-manager-core/actions`:\n\n| Action | Description |\n|---|---|\n| `copyUrlAction` | Copies the CDN URL to clipboard (single file) |\n| `downloadAction` | Opens the download URL in a new tab (single file) |\n\n## Types\n\n### StorageEntry\n\n`StorageEntry` is the JSON-serialized subset of `@bunny.net/storage-sdk`'s `StorageFile` type. The server handler converts SDK responses into this shape before sending them to the client. If you're already using the storage SDK, this is the same data — just with dates as ISO strings instead of `Date` objects, and without server-only fields like `userId`, `storageZoneId`, and `data()`.\n\n`@bunny.net/file-manager-core` is the canonical source for this type — both the handler and React packages re-export it from here.\n\n```ts\nimport type { StorageEntry } from \"@bunny.net/file-manager-core\";\n\ninterface StorageEntry {\n  guid: string;\n  objectName: string;\n  path: string;\n  isDirectory: boolean;\n  length: number;\n  contentType: string;\n  lastChanged: string;   // ISO 8601 (serialized from SDK's Date)\n  dateCreated: string;   // ISO 8601 (serialized from SDK's Date)\n  checksum: string | null;\n}\n```\n\n### Other types\n\n```ts\ntype FileManagerStatus = \"idle\" | \"loading\" | \"error\";\n\ninterface FileManagerAction {\n  id: string;\n  label: string;\n  icon?: string;\n  target: \"single\" | \"multi\" | \"both\";\n  isApplicable?: (entries: StorageEntry[]) => boolean;\n  handler: (entries: StorageEntry[], context: ActionContext) => Promise<void> | void;\n}\n```\n","readmeFilename":"README.md"}