From 7154d47f15d0333145a10e06379c717904703913 Mon Sep 17 00:00:00 2001 From: jamie-at-bunny Date: Mon, 1 Dec 2025 20:33:51 +0000 Subject: [PATCH] docs(bunny-storage): add node and deno examples --- .../examples/deno/batch-upload/README.md | 39 ++ .../examples/deno/batch-upload/deno.json | 8 + .../examples/deno/batch-upload/index.ts | 107 +++ .../examples/deno/delete-file/README.md | 34 + .../examples/deno/delete-file/deno.json | 8 + .../examples/deno/delete-file/index.ts | 49 ++ .../deno/delete-multiple-files/README.md | 34 + .../deno/delete-multiple-files/deno.json | 8 + .../deno/delete-multiple-files/index.ts | 59 ++ .../examples/deno/delete-old-files/README.md | 39 ++ .../examples/deno/delete-old-files/deno.json | 8 + .../examples/deno/delete-old-files/index.ts | 82 +++ .../examples/deno/download-file/README.md | 39 ++ .../examples/deno/download-file/deno.json | 8 + .../examples/deno/download-file/index.ts | 60 ++ .../examples/deno/file-info/README.md | 34 + .../examples/deno/file-info/deno.json | 8 + .../examples/deno/file-info/index.ts | 59 ++ .../examples/deno/file-upload/README.md | 39 ++ .../examples/deno/file-upload/deno.json | 8 + .../examples/deno/file-upload/index.ts | 62 ++ .../examples/deno/form-upload/README.md | 36 ++ .../examples/deno/form-upload/deno.json | 8 + .../examples/deno/form-upload/index.ts | 97 +++ .../examples/deno/list-files/README.md | 36 ++ .../examples/deno/list-files/deno.json | 8 + .../examples/deno/list-files/index.ts | 55 ++ .../examples/node/batch-upload/README.md | 35 + .../examples/node/batch-upload/index.ts | 110 ++++ .../examples/node/batch-upload/package.json | 15 + .../examples/node/delete-file/README.md | 30 + .../examples/node/delete-file/index.ts | 47 ++ .../examples/node/delete-file/package.json | 15 + .../node/delete-multiple-files/README.md | 30 + .../node/delete-multiple-files/index.ts | 57 ++ .../node/delete-multiple-files/package.json | 15 + .../examples/node/delete-old-files/README.md | 35 + .../examples/node/delete-old-files/index.ts | 78 +++ .../node/delete-old-files/package.json | 15 + .../examples/node/download-file/README.md | 35 + .../examples/node/download-file/index.ts | 61 ++ .../examples/node/download-file/package.json | 15 + .../examples/node/file-info/README.md | 30 + .../examples/node/file-info/index.ts | 57 ++ .../examples/node/file-info/package.json | 15 + .../examples/node/file-upload/README.md | 35 + .../examples/node/file-upload/index.ts | 56 ++ .../examples/node/file-upload/package.json | 15 + .../examples/node/form-upload/README.md | 32 + .../examples/node/form-upload/index.ts | 176 +++++ .../examples/node/form-upload/package.json | 15 + .../examples/node/list-files/README.md | 32 + .../examples/node/list-files/index.ts | 55 ++ .../node/list-files/package-lock.json | 607 ++++++++++++++++++ .../examples/node/list-files/package.json | 15 + 55 files changed, 2765 insertions(+) create mode 100644 libs/bunny-storage/examples/deno/batch-upload/README.md create mode 100644 libs/bunny-storage/examples/deno/batch-upload/deno.json create mode 100644 libs/bunny-storage/examples/deno/batch-upload/index.ts create mode 100644 libs/bunny-storage/examples/deno/delete-file/README.md create mode 100644 libs/bunny-storage/examples/deno/delete-file/deno.json create mode 100644 libs/bunny-storage/examples/deno/delete-file/index.ts create mode 100644 libs/bunny-storage/examples/deno/delete-multiple-files/README.md create mode 100644 libs/bunny-storage/examples/deno/delete-multiple-files/deno.json create mode 100644 libs/bunny-storage/examples/deno/delete-multiple-files/index.ts create mode 100644 libs/bunny-storage/examples/deno/delete-old-files/README.md create mode 100644 libs/bunny-storage/examples/deno/delete-old-files/deno.json create mode 100644 libs/bunny-storage/examples/deno/delete-old-files/index.ts create mode 100644 libs/bunny-storage/examples/deno/download-file/README.md create mode 100644 libs/bunny-storage/examples/deno/download-file/deno.json create mode 100644 libs/bunny-storage/examples/deno/download-file/index.ts create mode 100644 libs/bunny-storage/examples/deno/file-info/README.md create mode 100644 libs/bunny-storage/examples/deno/file-info/deno.json create mode 100644 libs/bunny-storage/examples/deno/file-info/index.ts create mode 100644 libs/bunny-storage/examples/deno/file-upload/README.md create mode 100644 libs/bunny-storage/examples/deno/file-upload/deno.json create mode 100644 libs/bunny-storage/examples/deno/file-upload/index.ts create mode 100644 libs/bunny-storage/examples/deno/form-upload/README.md create mode 100644 libs/bunny-storage/examples/deno/form-upload/deno.json create mode 100644 libs/bunny-storage/examples/deno/form-upload/index.ts create mode 100644 libs/bunny-storage/examples/deno/list-files/README.md create mode 100644 libs/bunny-storage/examples/deno/list-files/deno.json create mode 100644 libs/bunny-storage/examples/deno/list-files/index.ts create mode 100644 libs/bunny-storage/examples/node/batch-upload/README.md create mode 100644 libs/bunny-storage/examples/node/batch-upload/index.ts create mode 100644 libs/bunny-storage/examples/node/batch-upload/package.json create mode 100644 libs/bunny-storage/examples/node/delete-file/README.md create mode 100644 libs/bunny-storage/examples/node/delete-file/index.ts create mode 100644 libs/bunny-storage/examples/node/delete-file/package.json create mode 100644 libs/bunny-storage/examples/node/delete-multiple-files/README.md create mode 100644 libs/bunny-storage/examples/node/delete-multiple-files/index.ts create mode 100644 libs/bunny-storage/examples/node/delete-multiple-files/package.json create mode 100644 libs/bunny-storage/examples/node/delete-old-files/README.md create mode 100644 libs/bunny-storage/examples/node/delete-old-files/index.ts create mode 100644 libs/bunny-storage/examples/node/delete-old-files/package.json create mode 100644 libs/bunny-storage/examples/node/download-file/README.md create mode 100644 libs/bunny-storage/examples/node/download-file/index.ts create mode 100644 libs/bunny-storage/examples/node/download-file/package.json create mode 100644 libs/bunny-storage/examples/node/file-info/README.md create mode 100644 libs/bunny-storage/examples/node/file-info/index.ts create mode 100644 libs/bunny-storage/examples/node/file-info/package.json create mode 100644 libs/bunny-storage/examples/node/file-upload/README.md create mode 100644 libs/bunny-storage/examples/node/file-upload/index.ts create mode 100644 libs/bunny-storage/examples/node/file-upload/package.json create mode 100644 libs/bunny-storage/examples/node/form-upload/README.md create mode 100644 libs/bunny-storage/examples/node/form-upload/index.ts create mode 100644 libs/bunny-storage/examples/node/form-upload/package.json create mode 100644 libs/bunny-storage/examples/node/list-files/README.md create mode 100644 libs/bunny-storage/examples/node/list-files/index.ts create mode 100644 libs/bunny-storage/examples/node/list-files/package-lock.json create mode 100644 libs/bunny-storage/examples/node/list-files/package.json diff --git a/libs/bunny-storage/examples/deno/batch-upload/README.md b/libs/bunny-storage/examples/deno/batch-upload/README.md new file mode 100644 index 0000000..799225d --- /dev/null +++ b/libs/bunny-storage/examples/deno/batch-upload/README.md @@ -0,0 +1,39 @@ +# Batch Upload Example + +This example demonstrates how to upload an entire directory (including subdirectories) to Bunny Storage. + +## Prerequisites + +- [Deno](https://deno.land/) installed +- A Bunny Storage zone with API credentials + +### Installing Deno + +```bash +# macOS/Linux +curl -fsSL https://deno.land/install.sh | sh + +# Windows (PowerShell) +irm https://deno.land/install.ps1 | iex +``` + +## Setup + +Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +deno task start ./local-folder /remote-folder +``` + +Arguments: + +- `local-directory` - The local directory to upload +- `remote-directory` - The destination directory in Bunny Storage (default: `/`) diff --git a/libs/bunny-storage/examples/deno/batch-upload/deno.json b/libs/bunny-storage/examples/deno/batch-upload/deno.json new file mode 100644 index 0000000..e3e0f25 --- /dev/null +++ b/libs/bunny-storage/examples/deno/batch-upload/deno.json @@ -0,0 +1,8 @@ +{ + "tasks": { + "start": "deno run --allow-net --allow-env --allow-read index.ts" + }, + "imports": { + "@bunny.net/storage-sdk": "npm:@bunny.net/storage-sdk@latest" + } +} diff --git a/libs/bunny-storage/examples/deno/batch-upload/index.ts b/libs/bunny-storage/examples/deno/batch-upload/index.ts new file mode 100644 index 0000000..e4fac62 --- /dev/null +++ b/libs/bunny-storage/examples/deno/batch-upload/index.ts @@ -0,0 +1,107 @@ +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = Deno.env.get("BUNNY_STORAGE_API_KEY"); +const zoneName = Deno.env.get("BUNNY_STORAGE_ZONE"); +const region = Deno.env.get("BUNNY_STORAGE_REGION") || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + Deno.exit(1); +} + +const localDir = Deno.args[0]; +const remoteDir = Deno.args[1] || "/"; + +if (!localDir) { + console.error( + "Usage: deno run --allow-net --allow-env --allow-read index.ts [remote-directory]", + ); + console.error( + "Example: deno run --allow-net --allow-env --allow-read index.ts ./uploads /backups", + ); + Deno.exit(1); +} + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey, +); + +const results: { + localPath: string; + remotePath: string; + size: number; + success: boolean; + error?: string; +}[] = []; + +async function uploadDirectory(localPath: string, remotePath: string) { + for await (const entry of Deno.readDir(localPath)) { + const entryLocalPath = `${localPath}/${entry.name}`; + const entryRemotePath = `${remotePath}/${entry.name}`; + + if (entry.isDirectory) { + await uploadDirectory(entryLocalPath, entryRemotePath); + } else if (entry.isFile) { + try { + const file = await Deno.open(entryLocalPath, { read: true }); + const fileInfo = await file.stat(); + const stream = file.readable; + + const success = await BunnyStorage.file.upload( + storageZone, + entryRemotePath, + stream, + ); + + results.push({ + localPath: entryLocalPath, + remotePath: entryRemotePath, + size: fileInfo.size, + success, + }); + } catch (error) { + results.push({ + localPath: entryLocalPath, + remotePath: entryRemotePath, + size: 0, + success: false, + error: error.message, + }); + } + } + } +} + +try { + await uploadDirectory(localDir, remoteDir); + + console.log( + JSON.stringify( + { + storageZone: zoneName, + region, + localDirectory: localDir, + remoteDirectory: remoteDir, + results, + summary: { + total: results.length, + successful: results.filter((r) => r.success).length, + failed: results.filter((r) => !r.success).length, + totalSize: results + .filter((r) => r.success) + .reduce((sum, r) => sum + r.size, 0), + }, + }, + null, + 2, + ), + ); +} catch (error) { + console.error("Error:", error.message); + Deno.exit(1); +} diff --git a/libs/bunny-storage/examples/deno/delete-file/README.md b/libs/bunny-storage/examples/deno/delete-file/README.md new file mode 100644 index 0000000..661cc97 --- /dev/null +++ b/libs/bunny-storage/examples/deno/delete-file/README.md @@ -0,0 +1,34 @@ +# Delete File Example + +This example demonstrates how to delete a single file from Bunny Storage. + +## Prerequisites + +- [Deno](https://deno.land/) installed +- A Bunny Storage zone with API credentials + +### Installing Deno + +```bash +# macOS/Linux +curl -fsSL https://deno.land/install.sh | sh + +# Windows (PowerShell) +irm https://deno.land/install.ps1 | iex +``` + +## Setup + +Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +deno task start /path/to/file.txt +``` diff --git a/libs/bunny-storage/examples/deno/delete-file/deno.json b/libs/bunny-storage/examples/deno/delete-file/deno.json new file mode 100644 index 0000000..2c62201 --- /dev/null +++ b/libs/bunny-storage/examples/deno/delete-file/deno.json @@ -0,0 +1,8 @@ +{ + "tasks": { + "start": "deno run --allow-net --allow-env index.ts" + }, + "imports": { + "@bunny.net/storage-sdk": "npm:@bunny.net/storage-sdk@latest" + } +} diff --git a/libs/bunny-storage/examples/deno/delete-file/index.ts b/libs/bunny-storage/examples/deno/delete-file/index.ts new file mode 100644 index 0000000..e12c0ed --- /dev/null +++ b/libs/bunny-storage/examples/deno/delete-file/index.ts @@ -0,0 +1,49 @@ +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = Deno.env.get("BUNNY_STORAGE_API_KEY"); +const zoneName = Deno.env.get("BUNNY_STORAGE_ZONE"); +const region = Deno.env.get("BUNNY_STORAGE_REGION") || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + Deno.exit(1); +} + +const path = Deno.args[0]; + +if (!path) { + console.error("Usage: deno run --allow-net --allow-env index.ts "); + console.error( + "Example: deno run --allow-net --allow-env index.ts /folder/file.txt", + ); + Deno.exit(1); +} + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey, +); + +try { + const success = await BunnyStorage.file.remove(storageZone, path); + + console.log( + JSON.stringify( + { + storageZone: zoneName, + region, + deleted: path, + success, + }, + null, + 2, + ), + ); +} catch (error) { + console.error("Error deleting file:", error.message); + Deno.exit(1); +} diff --git a/libs/bunny-storage/examples/deno/delete-multiple-files/README.md b/libs/bunny-storage/examples/deno/delete-multiple-files/README.md new file mode 100644 index 0000000..e37cc04 --- /dev/null +++ b/libs/bunny-storage/examples/deno/delete-multiple-files/README.md @@ -0,0 +1,34 @@ +# Delete Multiple Files Example + +This example demonstrates how to delete multiple files from Bunny Storage in a single operation. + +## Prerequisites + +- [Deno](https://deno.land/) installed +- A Bunny Storage zone with API credentials + +### Installing Deno + +```bash +# macOS/Linux +curl -fsSL https://deno.land/install.sh | sh + +# Windows (PowerShell) +irm https://deno.land/install.ps1 | iex +``` + +## Setup + +Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +deno task start /file1.txt /file2.txt /folder/file3.txt +``` diff --git a/libs/bunny-storage/examples/deno/delete-multiple-files/deno.json b/libs/bunny-storage/examples/deno/delete-multiple-files/deno.json new file mode 100644 index 0000000..2c62201 --- /dev/null +++ b/libs/bunny-storage/examples/deno/delete-multiple-files/deno.json @@ -0,0 +1,8 @@ +{ + "tasks": { + "start": "deno run --allow-net --allow-env index.ts" + }, + "imports": { + "@bunny.net/storage-sdk": "npm:@bunny.net/storage-sdk@latest" + } +} diff --git a/libs/bunny-storage/examples/deno/delete-multiple-files/index.ts b/libs/bunny-storage/examples/deno/delete-multiple-files/index.ts new file mode 100644 index 0000000..41e6b49 --- /dev/null +++ b/libs/bunny-storage/examples/deno/delete-multiple-files/index.ts @@ -0,0 +1,59 @@ +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = Deno.env.get("BUNNY_STORAGE_API_KEY"); +const zoneName = Deno.env.get("BUNNY_STORAGE_ZONE"); +const region = Deno.env.get("BUNNY_STORAGE_REGION") || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + Deno.exit(1); +} + +const paths = Deno.args; + +if (paths.length === 0) { + console.error( + "Usage: deno run --allow-net --allow-env index.ts ...", + ); + console.error( + "Example: deno run --allow-net --allow-env index.ts /file1.txt /file2.txt /folder/file3.txt", + ); + Deno.exit(1); +} + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey, +); + +const results: { path: string; success: boolean; error?: string }[] = []; + +for (const path of paths) { + try { + const success = await BunnyStorage.file.remove(storageZone, path); + results.push({ path, success }); + } catch (error) { + results.push({ path, success: false, error: error.message }); + } +} + +console.log( + JSON.stringify( + { + storageZone: zoneName, + region, + results, + summary: { + total: results.length, + successful: results.filter((r) => r.success).length, + failed: results.filter((r) => !r.success).length, + }, + }, + null, + 2, + ), +); diff --git a/libs/bunny-storage/examples/deno/delete-old-files/README.md b/libs/bunny-storage/examples/deno/delete-old-files/README.md new file mode 100644 index 0000000..cde4b68 --- /dev/null +++ b/libs/bunny-storage/examples/deno/delete-old-files/README.md @@ -0,0 +1,39 @@ +# Delete Old Files Example + +This example demonstrates how to delete files older than a specified number of days from a directory in Bunny Storage. + +## Prerequisites + +- [Deno](https://deno.land/) installed +- A Bunny Storage zone with API credentials + +### Installing Deno + +```bash +# macOS/Linux +curl -fsSL https://deno.land/install.sh | sh + +# Windows (PowerShell) +irm https://deno.land/install.ps1 | iex +``` + +## Setup + +Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +deno task start /backups 30 +``` + +Arguments: + +- `directory` - The directory to scan for old files +- `days` - Delete files older than this many days (default: 30) diff --git a/libs/bunny-storage/examples/deno/delete-old-files/deno.json b/libs/bunny-storage/examples/deno/delete-old-files/deno.json new file mode 100644 index 0000000..2c62201 --- /dev/null +++ b/libs/bunny-storage/examples/deno/delete-old-files/deno.json @@ -0,0 +1,8 @@ +{ + "tasks": { + "start": "deno run --allow-net --allow-env index.ts" + }, + "imports": { + "@bunny.net/storage-sdk": "npm:@bunny.net/storage-sdk@latest" + } +} diff --git a/libs/bunny-storage/examples/deno/delete-old-files/index.ts b/libs/bunny-storage/examples/deno/delete-old-files/index.ts new file mode 100644 index 0000000..32f8ea8 --- /dev/null +++ b/libs/bunny-storage/examples/deno/delete-old-files/index.ts @@ -0,0 +1,82 @@ +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = Deno.env.get("BUNNY_STORAGE_API_KEY"); +const zoneName = Deno.env.get("BUNNY_STORAGE_ZONE"); +const region = Deno.env.get("BUNNY_STORAGE_REGION") || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + Deno.exit(1); +} + +const directory = Deno.args[0]; +const daysOld = parseInt(Deno.args[1] || "30", 10); + +if (!directory) { + console.error( + "Usage: deno run --allow-net --allow-env index.ts [days]", + ); + console.error( + "Example: deno run --allow-net --allow-env index.ts /backups 30", + ); + console.error(" directory - The directory to scan for old files"); + console.error( + " days - Delete files older than this many days (default: 30)", + ); + Deno.exit(1); +} + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey, +); + +const cutoffDate = new Date(); +cutoffDate.setDate(cutoffDate.getDate() - daysOld); + +try { + const files = await BunnyStorage.file.list(storageZone, directory); + + const oldFiles = files.filter( + (file) => !file.isDirectory && file.lastChanged < cutoffDate, + ); + + const results: { path: string; lastChanged: string; success: boolean }[] = []; + + for (const file of oldFiles) { + const filePath = `${file.path}${file.objectName}`; + const success = await BunnyStorage.file.remove(storageZone, filePath); + results.push({ + path: filePath, + lastChanged: file.lastChanged.toISOString(), + success, + }); + } + + console.log( + JSON.stringify( + { + storageZone: zoneName, + region, + directory, + cutoffDate: cutoffDate.toISOString(), + daysOld, + results, + summary: { + filesScanned: files.filter((f) => !f.isDirectory).length, + filesDeleted: results.filter((r) => r.success).length, + filesFailed: results.filter((r) => !r.success).length, + }, + }, + null, + 2, + ), + ); +} catch (error) { + console.error("Error:", error.message); + Deno.exit(1); +} diff --git a/libs/bunny-storage/examples/deno/download-file/README.md b/libs/bunny-storage/examples/deno/download-file/README.md new file mode 100644 index 0000000..4b9051c --- /dev/null +++ b/libs/bunny-storage/examples/deno/download-file/README.md @@ -0,0 +1,39 @@ +# Download File Example + +This example demonstrates how to download a file from Bunny Storage to your local filesystem. + +## Prerequisites + +- [Deno](https://deno.land/) installed +- A Bunny Storage zone with API credentials + +### Installing Deno + +```bash +# macOS/Linux +curl -fsSL https://deno.land/install.sh | sh + +# Windows (PowerShell) +irm https://deno.land/install.ps1 | iex +``` + +## Setup + +Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +deno task start /remote/path/file.txt ./local-file.txt +``` + +Arguments: + +- `remote-path` - The path to the file in Bunny Storage +- `local-path` - The local path where the file will be saved diff --git a/libs/bunny-storage/examples/deno/download-file/deno.json b/libs/bunny-storage/examples/deno/download-file/deno.json new file mode 100644 index 0000000..23b2e4a --- /dev/null +++ b/libs/bunny-storage/examples/deno/download-file/deno.json @@ -0,0 +1,8 @@ +{ + "tasks": { + "start": "deno run --allow-net --allow-env --allow-write index.ts" + }, + "imports": { + "@bunny.net/storage-sdk": "npm:@bunny.net/storage-sdk@latest" + } +} diff --git a/libs/bunny-storage/examples/deno/download-file/index.ts b/libs/bunny-storage/examples/deno/download-file/index.ts new file mode 100644 index 0000000..6585425 --- /dev/null +++ b/libs/bunny-storage/examples/deno/download-file/index.ts @@ -0,0 +1,60 @@ +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = Deno.env.get("BUNNY_STORAGE_API_KEY"); +const zoneName = Deno.env.get("BUNNY_STORAGE_ZONE"); +const region = Deno.env.get("BUNNY_STORAGE_REGION") || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + Deno.exit(1); +} + +const remotePath = Deno.args[0]; +const localPath = Deno.args[1]; + +if (!remotePath || !localPath) { + console.error( + "Usage: deno run --allow-net --allow-env --allow-write index.ts ", + ); + console.error( + "Example: deno run --allow-net --allow-env --allow-write index.ts /folder/file.txt ./downloaded.txt", + ); + Deno.exit(1); +} + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey, +); + +try { + const { stream, length } = await BunnyStorage.file.download( + storageZone, + remotePath, + ); + + const file = await Deno.open(localPath, { write: true, create: true }); + await stream.pipeTo(file.writable); + + console.log( + JSON.stringify( + { + storageZone: zoneName, + region, + remotePath, + localPath, + size: length, + success: true, + }, + null, + 2, + ), + ); +} catch (error) { + console.error("Error downloading file:", error.message); + Deno.exit(1); +} diff --git a/libs/bunny-storage/examples/deno/file-info/README.md b/libs/bunny-storage/examples/deno/file-info/README.md new file mode 100644 index 0000000..3403c0f --- /dev/null +++ b/libs/bunny-storage/examples/deno/file-info/README.md @@ -0,0 +1,34 @@ +# File Info Example + +This example demonstrates how to get metadata and details about a file in Bunny Storage. + +## Prerequisites + +- [Deno](https://deno.land/) installed +- A Bunny Storage zone with API credentials + +### Installing Deno + +```bash +# macOS/Linux +curl -fsSL https://deno.land/install.sh | sh + +# Windows (PowerShell) +irm https://deno.land/install.ps1 | iex +``` + +## Setup + +Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +deno task start /path/to/file.txt +``` diff --git a/libs/bunny-storage/examples/deno/file-info/deno.json b/libs/bunny-storage/examples/deno/file-info/deno.json new file mode 100644 index 0000000..2c62201 --- /dev/null +++ b/libs/bunny-storage/examples/deno/file-info/deno.json @@ -0,0 +1,8 @@ +{ + "tasks": { + "start": "deno run --allow-net --allow-env index.ts" + }, + "imports": { + "@bunny.net/storage-sdk": "npm:@bunny.net/storage-sdk@latest" + } +} diff --git a/libs/bunny-storage/examples/deno/file-info/index.ts b/libs/bunny-storage/examples/deno/file-info/index.ts new file mode 100644 index 0000000..f0f9667 --- /dev/null +++ b/libs/bunny-storage/examples/deno/file-info/index.ts @@ -0,0 +1,59 @@ +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = Deno.env.get("BUNNY_STORAGE_API_KEY"); +const zoneName = Deno.env.get("BUNNY_STORAGE_ZONE"); +const region = Deno.env.get("BUNNY_STORAGE_REGION") || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + Deno.exit(1); +} + +const path = Deno.args[0]; + +if (!path) { + console.error("Usage: deno run --allow-net --allow-env index.ts "); + console.error( + "Example: deno run --allow-net --allow-env index.ts /folder/file.txt", + ); + Deno.exit(1); +} + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey, +); + +try { + const file = await BunnyStorage.file.get(storageZone, path); + + console.log( + JSON.stringify( + { + storageZone: zoneName, + region, + file: { + path: file.path, + name: file.objectName, + size: file.length, + isDirectory: file.isDirectory, + dateModified: file.lastChanged.toISOString(), + dateCreated: file.dateCreated.toISOString(), + checksum: file.checksum, + contentType: file.contentType, + guid: file.guid, + replicatedZones: file.replicatedZones, + }, + }, + null, + 2, + ), + ); +} catch (error) { + console.error("Error getting file info:", error.message); + Deno.exit(1); +} diff --git a/libs/bunny-storage/examples/deno/file-upload/README.md b/libs/bunny-storage/examples/deno/file-upload/README.md new file mode 100644 index 0000000..3ec14fd --- /dev/null +++ b/libs/bunny-storage/examples/deno/file-upload/README.md @@ -0,0 +1,39 @@ +# File Upload Example + +This example demonstrates how to upload a local file to Bunny Storage. + +## Prerequisites + +- [Deno](https://deno.land/) installed +- A Bunny Storage zone with API credentials + +### Installing Deno + +```bash +# macOS/Linux +curl -fsSL https://deno.land/install.sh | sh + +# Windows (PowerShell) +irm https://deno.land/install.ps1 | iex +``` + +## Setup + +Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +deno task start ./local-file.txt /remote/path/file.txt +``` + +Arguments: + +- `local-path` - The path to the local file to upload +- `remote-path` - The destination path in Bunny Storage diff --git a/libs/bunny-storage/examples/deno/file-upload/deno.json b/libs/bunny-storage/examples/deno/file-upload/deno.json new file mode 100644 index 0000000..e3e0f25 --- /dev/null +++ b/libs/bunny-storage/examples/deno/file-upload/deno.json @@ -0,0 +1,8 @@ +{ + "tasks": { + "start": "deno run --allow-net --allow-env --allow-read index.ts" + }, + "imports": { + "@bunny.net/storage-sdk": "npm:@bunny.net/storage-sdk@latest" + } +} diff --git a/libs/bunny-storage/examples/deno/file-upload/index.ts b/libs/bunny-storage/examples/deno/file-upload/index.ts new file mode 100644 index 0000000..fa74557 --- /dev/null +++ b/libs/bunny-storage/examples/deno/file-upload/index.ts @@ -0,0 +1,62 @@ +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = Deno.env.get("BUNNY_STORAGE_API_KEY"); +const zoneName = Deno.env.get("BUNNY_STORAGE_ZONE"); +const region = Deno.env.get("BUNNY_STORAGE_REGION") || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + Deno.exit(1); +} + +const localPath = Deno.args[0]; +const remotePath = Deno.args[1]; + +if (!localPath || !remotePath) { + console.error( + "Usage: deno run --allow-net --allow-env --allow-read index.ts ", + ); + console.error( + "Example: deno run --allow-net --allow-env --allow-read index.ts ./file.txt /folder/file.txt", + ); + Deno.exit(1); +} + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey, +); + +try { + const file = await Deno.open(localPath, { read: true }); + const fileInfo = await file.stat(); + const stream = file.readable; + + const success = await BunnyStorage.file.upload( + storageZone, + remotePath, + stream, + ); + + console.log( + JSON.stringify( + { + storageZone: zoneName, + region, + localPath, + remotePath, + size: fileInfo.size, + success, + }, + null, + 2, + ), + ); +} catch (error) { + console.error("Error uploading file:", error.message); + Deno.exit(1); +} diff --git a/libs/bunny-storage/examples/deno/form-upload/README.md b/libs/bunny-storage/examples/deno/form-upload/README.md new file mode 100644 index 0000000..0a0a425 --- /dev/null +++ b/libs/bunny-storage/examples/deno/form-upload/README.md @@ -0,0 +1,36 @@ +# Form Upload Example + +This example demonstrates how to upload files to Bunny Storage using an HTML form and multipart form data. + +## Prerequisites + +- [Deno](https://deno.land/) installed +- A Bunny Storage zone with API credentials + +### Installing Deno + +```bash +# macOS/Linux +curl -fsSL https://deno.land/install.sh | sh + +# Windows (PowerShell) +irm https://deno.land/install.ps1 | iex +``` + +## Setup + +Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +deno task start +``` + +Then visit: http://localhost:8080 diff --git a/libs/bunny-storage/examples/deno/form-upload/deno.json b/libs/bunny-storage/examples/deno/form-upload/deno.json new file mode 100644 index 0000000..2c62201 --- /dev/null +++ b/libs/bunny-storage/examples/deno/form-upload/deno.json @@ -0,0 +1,8 @@ +{ + "tasks": { + "start": "deno run --allow-net --allow-env index.ts" + }, + "imports": { + "@bunny.net/storage-sdk": "npm:@bunny.net/storage-sdk@latest" + } +} diff --git a/libs/bunny-storage/examples/deno/form-upload/index.ts b/libs/bunny-storage/examples/deno/form-upload/index.ts new file mode 100644 index 0000000..9a83d78 --- /dev/null +++ b/libs/bunny-storage/examples/deno/form-upload/index.ts @@ -0,0 +1,97 @@ +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = Deno.env.get("BUNNY_STORAGE_API_KEY"); +const zoneName = Deno.env.get("BUNNY_STORAGE_ZONE"); +const region = Deno.env.get("BUNNY_STORAGE_REGION") || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + Deno.exit(1); +} + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey, +); + +const port = 8080; + +console.log(`Starting server on http://localhost:${port}`); +console.log("Upload a file using the form or POST to /upload"); + +Deno.serve({ port }, async (req: Request) => { + const url = new URL(req.url); + + if (url.pathname === "/" && req.method === "GET") { + const html = ` + + + + Bunny Storage Upload + + + +

Bunny Storage Upload

+
+
+
+ +
+
+
+ +
+ +
+ +`; + return new Response(html, { + headers: { "Content-Type": "text/html" }, + }); + } + + if (url.pathname === "/upload" && req.method === "POST") { + try { + const formData = await req.formData(); + const file = formData.get("file") as File; + const remotePath = formData.get("path") as string; + + if (!file || !remotePath) { + return Response.json( + { error: "Missing file or path" }, + { status: 400 }, + ); + } + + const stream = file.stream(); + const success = await BunnyStorage.file.upload( + storageZone, + remotePath, + stream, + { contentType: file.type }, + ); + + return Response.json({ + storageZone: zoneName, + region, + remotePath, + fileName: file.name, + size: file.size, + contentType: file.type, + success, + }); + } catch (error) { + return Response.json({ error: error.message }, { status: 500 }); + } + } + + return new Response("Not Found", { status: 404 }); +}); diff --git a/libs/bunny-storage/examples/deno/list-files/README.md b/libs/bunny-storage/examples/deno/list-files/README.md new file mode 100644 index 0000000..d2c20a2 --- /dev/null +++ b/libs/bunny-storage/examples/deno/list-files/README.md @@ -0,0 +1,36 @@ +# List Files Example + +This example demonstrates how to list files and directories in a Bunny Storage zone. + +## Prerequisites + +- [Deno](https://deno.land/) installed +- A Bunny Storage zone with API credentials + +### Installing Deno + +```bash +# macOS/Linux +curl -fsSL https://deno.land/install.sh | sh + +# Windows (PowerShell) +irm https://deno.land/install.ps1 | iex +``` + +## Setup + +Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +deno task start /path/to/directory +``` + +If no path is provided, it lists the root directory (`/`). diff --git a/libs/bunny-storage/examples/deno/list-files/deno.json b/libs/bunny-storage/examples/deno/list-files/deno.json new file mode 100644 index 0000000..2c62201 --- /dev/null +++ b/libs/bunny-storage/examples/deno/list-files/deno.json @@ -0,0 +1,8 @@ +{ + "tasks": { + "start": "deno run --allow-net --allow-env index.ts" + }, + "imports": { + "@bunny.net/storage-sdk": "npm:@bunny.net/storage-sdk@latest" + } +} diff --git a/libs/bunny-storage/examples/deno/list-files/index.ts b/libs/bunny-storage/examples/deno/list-files/index.ts new file mode 100644 index 0000000..f047c15 --- /dev/null +++ b/libs/bunny-storage/examples/deno/list-files/index.ts @@ -0,0 +1,55 @@ +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = Deno.env.get("BUNNY_STORAGE_API_KEY"); +const zoneName = Deno.env.get("BUNNY_STORAGE_ZONE"); +const region = Deno.env.get("BUNNY_STORAGE_REGION") || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + Deno.exit(1); +} + +const path = Deno.args[0] || "/"; + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey, +); + +try { + const files = await BunnyStorage.file.list(storageZone, path); + + console.log( + JSON.stringify( + { + storageZone: zoneName, + region, + path, + files: files.map((file) => ({ + name: file.objectName, + path: file.path, + size: file.length, + isDirectory: file.isDirectory, + dateModified: file.lastChanged.toISOString(), + contentType: file.contentType, + })), + summary: { + totalFiles: files.filter((f) => !f.isDirectory).length, + totalDirectories: files.filter((f) => f.isDirectory).length, + totalSize: files + .filter((f) => !f.isDirectory) + .reduce((sum, f) => sum + f.length, 0), + }, + }, + null, + 2, + ), + ); +} catch (error) { + console.error("Error listing files:", error.message); + Deno.exit(1); +} diff --git a/libs/bunny-storage/examples/node/batch-upload/README.md b/libs/bunny-storage/examples/node/batch-upload/README.md new file mode 100644 index 0000000..0f8cf14 --- /dev/null +++ b/libs/bunny-storage/examples/node/batch-upload/README.md @@ -0,0 +1,35 @@ +# Batch Upload Example + +This example demonstrates how to upload an entire directory (including subdirectories) to Bunny Storage. + +## Prerequisites + +- [Node.js](https://nodejs.org/) 18+ installed +- A Bunny Storage zone with API credentials + +## Setup + +1. Install dependencies: + +```bash +npm install +``` + +2. Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +npm start -- ./local-folder /remote-folder +``` + +Arguments: + +- `local-directory` - The local directory to upload +- `remote-directory` - The destination directory in Bunny Storage (default: `/`) diff --git a/libs/bunny-storage/examples/node/batch-upload/index.ts b/libs/bunny-storage/examples/node/batch-upload/index.ts new file mode 100644 index 0000000..2bd821c --- /dev/null +++ b/libs/bunny-storage/examples/node/batch-upload/index.ts @@ -0,0 +1,110 @@ +import * as fs from "node:fs"; +import * as path from "node:path"; +import { Readable } from "node:stream"; +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = process.env.BUNNY_STORAGE_API_KEY; +const zoneName = process.env.BUNNY_STORAGE_ZONE; +const region = process.env.BUNNY_STORAGE_REGION || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + process.exit(1); +} + +const localDir = process.argv[2]; +const remoteDir = process.argv[3] || "/"; + +if (!localDir) { + console.error( + "Usage: npx tsx index.ts [remote-directory]" + ); + console.error("Example: npx tsx index.ts ./uploads /backups"); + process.exit(1); +} + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey +); + +const results: { + localPath: string; + remotePath: string; + size: number; + success: boolean; + error?: string; +}[] = []; + +async function uploadDirectory(localPath: string, remotePath: string) { + const entries = fs.readdirSync(localPath, { withFileTypes: true }); + + for (const entry of entries) { + const entryLocalPath = path.join(localPath, entry.name); + const entryRemotePath = `${remotePath}/${entry.name}`; + + if (entry.isDirectory()) { + await uploadDirectory(entryLocalPath, entryRemotePath); + } else if (entry.isFile()) { + try { + const fileStats = fs.statSync(entryLocalPath); + const nodeStream = fs.createReadStream(entryLocalPath); + const stream = Readable.toWeb(nodeStream) as ReadableStream; + + const success = await BunnyStorage.file.upload( + storageZone, + entryRemotePath, + stream + ); + + results.push({ + localPath: entryLocalPath, + remotePath: entryRemotePath, + size: fileStats.size, + success, + }); + } catch (error) { + results.push({ + localPath: entryLocalPath, + remotePath: entryRemotePath, + size: 0, + success: false, + error: (error as Error).message, + }); + } + } + } +} + +try { + await uploadDirectory(localDir, remoteDir); + + console.log( + JSON.stringify( + { + storageZone: zoneName, + region, + localDirectory: localDir, + remoteDirectory: remoteDir, + results, + summary: { + total: results.length, + successful: results.filter((r) => r.success).length, + failed: results.filter((r) => !r.success).length, + totalSize: results + .filter((r) => r.success) + .reduce((sum, r) => sum + r.size, 0), + }, + }, + null, + 2 + ) + ); +} catch (error) { + console.error("Error:", (error as Error).message); + process.exit(1); +} diff --git a/libs/bunny-storage/examples/node/batch-upload/package.json b/libs/bunny-storage/examples/node/batch-upload/package.json new file mode 100644 index 0000000..137f64b --- /dev/null +++ b/libs/bunny-storage/examples/node/batch-upload/package.json @@ -0,0 +1,15 @@ +{ + "name": "batch-upload-example", + "private": true, + "type": "module", + "scripts": { + "start": "npx tsx index.ts" + }, + "dependencies": { + "@bunny.net/storage-sdk": "latest" + }, + "devDependencies": { + "tsx": "^4.0.0", + "@types/node": "^20.0.0" + } +} diff --git a/libs/bunny-storage/examples/node/delete-file/README.md b/libs/bunny-storage/examples/node/delete-file/README.md new file mode 100644 index 0000000..d7d7962 --- /dev/null +++ b/libs/bunny-storage/examples/node/delete-file/README.md @@ -0,0 +1,30 @@ +# Delete File Example + +This example demonstrates how to delete a single file from Bunny Storage. + +## Prerequisites + +- [Node.js](https://nodejs.org/) 18+ installed +- A Bunny Storage zone with API credentials + +## Setup + +1. Install dependencies: + +```bash +npm install +``` + +2. Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +npm start -- /path/to/file.txt +``` diff --git a/libs/bunny-storage/examples/node/delete-file/index.ts b/libs/bunny-storage/examples/node/delete-file/index.ts new file mode 100644 index 0000000..dae2784 --- /dev/null +++ b/libs/bunny-storage/examples/node/delete-file/index.ts @@ -0,0 +1,47 @@ +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = process.env.BUNNY_STORAGE_API_KEY; +const zoneName = process.env.BUNNY_STORAGE_ZONE; +const region = process.env.BUNNY_STORAGE_REGION || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + process.exit(1); +} + +const path = process.argv[2]; + +if (!path) { + console.error("Usage: npx tsx index.ts "); + console.error("Example: npx tsx index.ts /folder/file.txt"); + process.exit(1); +} + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey +); + +try { + const success = await BunnyStorage.file.remove(storageZone, path); + + console.log( + JSON.stringify( + { + storageZone: zoneName, + region, + deleted: path, + success, + }, + null, + 2 + ) + ); +} catch (error) { + console.error("Error deleting file:", (error as Error).message); + process.exit(1); +} diff --git a/libs/bunny-storage/examples/node/delete-file/package.json b/libs/bunny-storage/examples/node/delete-file/package.json new file mode 100644 index 0000000..87cc075 --- /dev/null +++ b/libs/bunny-storage/examples/node/delete-file/package.json @@ -0,0 +1,15 @@ +{ + "name": "delete-file-example", + "private": true, + "type": "module", + "scripts": { + "start": "npx tsx index.ts" + }, + "dependencies": { + "@bunny.net/storage-sdk": "latest" + }, + "devDependencies": { + "tsx": "^4.0.0", + "@types/node": "^20.0.0" + } +} diff --git a/libs/bunny-storage/examples/node/delete-multiple-files/README.md b/libs/bunny-storage/examples/node/delete-multiple-files/README.md new file mode 100644 index 0000000..be326b2 --- /dev/null +++ b/libs/bunny-storage/examples/node/delete-multiple-files/README.md @@ -0,0 +1,30 @@ +# Delete Multiple Files Example + +This example demonstrates how to delete multiple files from Bunny Storage in a single operation. + +## Prerequisites + +- [Node.js](https://nodejs.org/) 18+ installed +- A Bunny Storage zone with API credentials + +## Setup + +1. Install dependencies: + +```bash +npm install +``` + +2. Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +npm start -- /file1.txt /file2.txt /folder/file3.txt +``` diff --git a/libs/bunny-storage/examples/node/delete-multiple-files/index.ts b/libs/bunny-storage/examples/node/delete-multiple-files/index.ts new file mode 100644 index 0000000..ac18668 --- /dev/null +++ b/libs/bunny-storage/examples/node/delete-multiple-files/index.ts @@ -0,0 +1,57 @@ +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = process.env.BUNNY_STORAGE_API_KEY; +const zoneName = process.env.BUNNY_STORAGE_ZONE; +const region = process.env.BUNNY_STORAGE_REGION || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + process.exit(1); +} + +const paths = process.argv.slice(2); + +if (paths.length === 0) { + console.error("Usage: npx tsx index.ts ..."); + console.error( + "Example: npx tsx index.ts /file1.txt /file2.txt /folder/file3.txt" + ); + process.exit(1); +} + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey +); + +const results: { path: string; success: boolean; error?: string }[] = []; + +for (const path of paths) { + try { + const success = await BunnyStorage.file.remove(storageZone, path); + results.push({ path, success }); + } catch (error) { + results.push({ path, success: false, error: (error as Error).message }); + } +} + +console.log( + JSON.stringify( + { + storageZone: zoneName, + region, + results, + summary: { + total: results.length, + successful: results.filter((r) => r.success).length, + failed: results.filter((r) => !r.success).length, + }, + }, + null, + 2 + ) +); diff --git a/libs/bunny-storage/examples/node/delete-multiple-files/package.json b/libs/bunny-storage/examples/node/delete-multiple-files/package.json new file mode 100644 index 0000000..f130103 --- /dev/null +++ b/libs/bunny-storage/examples/node/delete-multiple-files/package.json @@ -0,0 +1,15 @@ +{ + "name": "delete-multiple-files-example", + "private": true, + "type": "module", + "scripts": { + "start": "npx tsx index.ts" + }, + "dependencies": { + "@bunny.net/storage-sdk": "latest" + }, + "devDependencies": { + "tsx": "^4.0.0", + "@types/node": "^20.0.0" + } +} diff --git a/libs/bunny-storage/examples/node/delete-old-files/README.md b/libs/bunny-storage/examples/node/delete-old-files/README.md new file mode 100644 index 0000000..eb98651 --- /dev/null +++ b/libs/bunny-storage/examples/node/delete-old-files/README.md @@ -0,0 +1,35 @@ +# Delete Old Files Example + +This example demonstrates how to delete files older than a specified number of days from a directory in Bunny Storage. + +## Prerequisites + +- [Node.js](https://nodejs.org/) 18+ installed +- A Bunny Storage zone with API credentials + +## Setup + +1. Install dependencies: + +```bash +npm install +``` + +2. Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +npm start -- /backups 30 +``` + +Arguments: + +- `directory` - The directory to scan for old files +- `days` - Delete files older than this many days (default: 30) diff --git a/libs/bunny-storage/examples/node/delete-old-files/index.ts b/libs/bunny-storage/examples/node/delete-old-files/index.ts new file mode 100644 index 0000000..752a648 --- /dev/null +++ b/libs/bunny-storage/examples/node/delete-old-files/index.ts @@ -0,0 +1,78 @@ +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = process.env.BUNNY_STORAGE_API_KEY; +const zoneName = process.env.BUNNY_STORAGE_ZONE; +const region = process.env.BUNNY_STORAGE_REGION || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + process.exit(1); +} + +const directory = process.argv[2]; +const daysOld = parseInt(process.argv[3] || "30", 10); + +if (!directory) { + console.error("Usage: npx tsx index.ts [days]"); + console.error("Example: npx tsx index.ts /backups 30"); + console.error(" directory - The directory to scan for old files"); + console.error( + " days - Delete files older than this many days (default: 30)" + ); + process.exit(1); +} + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey +); + +const cutoffDate = new Date(); +cutoffDate.setDate(cutoffDate.getDate() - daysOld); + +try { + const files = await BunnyStorage.file.list(storageZone, directory); + + const oldFiles = files.filter( + (file) => !file.isDirectory && file.lastChanged < cutoffDate + ); + + const results: { path: string; lastChanged: string; success: boolean }[] = []; + + for (const file of oldFiles) { + const filePath = `${file.path}${file.objectName}`; + const success = await BunnyStorage.file.remove(storageZone, filePath); + results.push({ + path: filePath, + lastChanged: file.lastChanged.toISOString(), + success, + }); + } + + console.log( + JSON.stringify( + { + storageZone: zoneName, + region, + directory, + cutoffDate: cutoffDate.toISOString(), + daysOld, + results, + summary: { + filesScanned: files.filter((f) => !f.isDirectory).length, + filesDeleted: results.filter((r) => r.success).length, + filesFailed: results.filter((r) => !r.success).length, + }, + }, + null, + 2 + ) + ); +} catch (error) { + console.error("Error:", (error as Error).message); + process.exit(1); +} diff --git a/libs/bunny-storage/examples/node/delete-old-files/package.json b/libs/bunny-storage/examples/node/delete-old-files/package.json new file mode 100644 index 0000000..43fa02f --- /dev/null +++ b/libs/bunny-storage/examples/node/delete-old-files/package.json @@ -0,0 +1,15 @@ +{ + "name": "delete-old-files-example", + "private": true, + "type": "module", + "scripts": { + "start": "npx tsx index.ts" + }, + "dependencies": { + "@bunny.net/storage-sdk": "latest" + }, + "devDependencies": { + "tsx": "^4.0.0", + "@types/node": "^20.0.0" + } +} diff --git a/libs/bunny-storage/examples/node/download-file/README.md b/libs/bunny-storage/examples/node/download-file/README.md new file mode 100644 index 0000000..029b3a7 --- /dev/null +++ b/libs/bunny-storage/examples/node/download-file/README.md @@ -0,0 +1,35 @@ +# Download File Example + +This example demonstrates how to download a file from Bunny Storage to your local filesystem. + +## Prerequisites + +- [Node.js](https://nodejs.org/) 18+ installed +- A Bunny Storage zone with API credentials + +## Setup + +1. Install dependencies: + +```bash +npm install +``` + +2. Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +npm start -- /remote/path/file.txt ./local-file.txt +``` + +Arguments: + +- `remote-path` - The path to the file in Bunny Storage +- `local-path` - The local path where the file will be saved diff --git a/libs/bunny-storage/examples/node/download-file/index.ts b/libs/bunny-storage/examples/node/download-file/index.ts new file mode 100644 index 0000000..d992b3c --- /dev/null +++ b/libs/bunny-storage/examples/node/download-file/index.ts @@ -0,0 +1,61 @@ +import * as fs from "node:fs"; +import { Writable } from "node:stream"; +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = process.env.BUNNY_STORAGE_API_KEY; +const zoneName = process.env.BUNNY_STORAGE_ZONE; +const region = process.env.BUNNY_STORAGE_REGION || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + process.exit(1); +} + +const remotePath = process.argv[2]; +const localPath = process.argv[3]; + +if (!remotePath || !localPath) { + console.error("Usage: npx tsx index.ts "); + console.error( + "Example: npx tsx index.ts /folder/file.txt ./downloaded.txt" + ); + process.exit(1); +} + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey +); + +try { + const { stream, length } = await BunnyStorage.file.download( + storageZone, + remotePath + ); + + const fileStream = fs.createWriteStream(localPath); + const writableStream = Writable.toWeb(fileStream); + await stream.pipeTo(writableStream); + + console.log( + JSON.stringify( + { + storageZone: zoneName, + region, + remotePath, + localPath, + size: length, + success: true, + }, + null, + 2 + ) + ); +} catch (error) { + console.error("Error downloading file:", (error as Error).message); + process.exit(1); +} diff --git a/libs/bunny-storage/examples/node/download-file/package.json b/libs/bunny-storage/examples/node/download-file/package.json new file mode 100644 index 0000000..b5cb64b --- /dev/null +++ b/libs/bunny-storage/examples/node/download-file/package.json @@ -0,0 +1,15 @@ +{ + "name": "download-file-example", + "private": true, + "type": "module", + "scripts": { + "start": "npx tsx index.ts" + }, + "dependencies": { + "@bunny.net/storage-sdk": "latest" + }, + "devDependencies": { + "tsx": "^4.0.0", + "@types/node": "^20.0.0" + } +} diff --git a/libs/bunny-storage/examples/node/file-info/README.md b/libs/bunny-storage/examples/node/file-info/README.md new file mode 100644 index 0000000..82b9745 --- /dev/null +++ b/libs/bunny-storage/examples/node/file-info/README.md @@ -0,0 +1,30 @@ +# File Info Example + +This example demonstrates how to get metadata and details about a file in Bunny Storage. + +## Prerequisites + +- [Node.js](https://nodejs.org/) 18+ installed +- A Bunny Storage zone with API credentials + +## Setup + +1. Install dependencies: + +```bash +npm install +``` + +2. Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +npm start -- /path/to/file.txt +``` diff --git a/libs/bunny-storage/examples/node/file-info/index.ts b/libs/bunny-storage/examples/node/file-info/index.ts new file mode 100644 index 0000000..03d329d --- /dev/null +++ b/libs/bunny-storage/examples/node/file-info/index.ts @@ -0,0 +1,57 @@ +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = process.env.BUNNY_STORAGE_API_KEY; +const zoneName = process.env.BUNNY_STORAGE_ZONE; +const region = process.env.BUNNY_STORAGE_REGION || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + process.exit(1); +} + +const path = process.argv[2]; + +if (!path) { + console.error("Usage: npx tsx index.ts "); + console.error("Example: npx tsx index.ts /folder/file.txt"); + process.exit(1); +} + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey +); + +try { + const file = await BunnyStorage.file.get(storageZone, path); + + console.log( + JSON.stringify( + { + storageZone: zoneName, + region, + file: { + path: file.path, + name: file.objectName, + size: file.length, + isDirectory: file.isDirectory, + dateModified: file.lastChanged.toISOString(), + dateCreated: file.dateCreated.toISOString(), + checksum: file.checksum, + contentType: file.contentType, + guid: file.guid, + replicatedZones: file.replicatedZones, + }, + }, + null, + 2 + ) + ); +} catch (error) { + console.error("Error getting file info:", (error as Error).message); + process.exit(1); +} diff --git a/libs/bunny-storage/examples/node/file-info/package.json b/libs/bunny-storage/examples/node/file-info/package.json new file mode 100644 index 0000000..b5a1f62 --- /dev/null +++ b/libs/bunny-storage/examples/node/file-info/package.json @@ -0,0 +1,15 @@ +{ + "name": "file-info-example", + "private": true, + "type": "module", + "scripts": { + "start": "npx tsx index.ts" + }, + "dependencies": { + "@bunny.net/storage-sdk": "latest" + }, + "devDependencies": { + "tsx": "^4.0.0", + "@types/node": "^20.0.0" + } +} diff --git a/libs/bunny-storage/examples/node/file-upload/README.md b/libs/bunny-storage/examples/node/file-upload/README.md new file mode 100644 index 0000000..496524b --- /dev/null +++ b/libs/bunny-storage/examples/node/file-upload/README.md @@ -0,0 +1,35 @@ +# File Upload Example + +This example demonstrates how to upload a local file to Bunny Storage. + +## Prerequisites + +- [Node.js](https://nodejs.org/) 18+ installed +- A Bunny Storage zone with API credentials + +## Setup + +1. Install dependencies: + +```bash +npm install +``` + +2. Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +npm start -- ./local-file.txt /remote/path/file.txt +``` + +Arguments: + +- `local-path` - The path to the local file to upload +- `remote-path` - The destination path in Bunny Storage diff --git a/libs/bunny-storage/examples/node/file-upload/index.ts b/libs/bunny-storage/examples/node/file-upload/index.ts new file mode 100644 index 0000000..d82cdac --- /dev/null +++ b/libs/bunny-storage/examples/node/file-upload/index.ts @@ -0,0 +1,56 @@ +import * as fs from "node:fs"; +import { Readable } from "node:stream"; +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = process.env.BUNNY_STORAGE_API_KEY; +const zoneName = process.env.BUNNY_STORAGE_ZONE; +const region = process.env.BUNNY_STORAGE_REGION || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + process.exit(1); +} + +const localPath = process.argv[2]; +const remotePath = process.argv[3]; + +if (!localPath || !remotePath) { + console.error("Usage: npx tsx index.ts "); + console.error("Example: npx tsx index.ts ./file.txt /folder/file.txt"); + process.exit(1); +} + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey +); + +try { + const fileStats = fs.statSync(localPath); + const nodeStream = fs.createReadStream(localPath); + const stream = Readable.toWeb(nodeStream) as ReadableStream; + + const success = await BunnyStorage.file.upload(storageZone, remotePath, stream); + + console.log( + JSON.stringify( + { + storageZone: zoneName, + region, + localPath, + remotePath, + size: fileStats.size, + success, + }, + null, + 2 + ) + ); +} catch (error) { + console.error("Error uploading file:", (error as Error).message); + process.exit(1); +} diff --git a/libs/bunny-storage/examples/node/file-upload/package.json b/libs/bunny-storage/examples/node/file-upload/package.json new file mode 100644 index 0000000..15ae662 --- /dev/null +++ b/libs/bunny-storage/examples/node/file-upload/package.json @@ -0,0 +1,15 @@ +{ + "name": "file-upload-example", + "private": true, + "type": "module", + "scripts": { + "start": "npx tsx index.ts" + }, + "dependencies": { + "@bunny.net/storage-sdk": "latest" + }, + "devDependencies": { + "tsx": "^4.0.0", + "@types/node": "^20.0.0" + } +} diff --git a/libs/bunny-storage/examples/node/form-upload/README.md b/libs/bunny-storage/examples/node/form-upload/README.md new file mode 100644 index 0000000..2a99d32 --- /dev/null +++ b/libs/bunny-storage/examples/node/form-upload/README.md @@ -0,0 +1,32 @@ +# Form Upload Example + +This example demonstrates how to upload files to Bunny Storage using an HTML form and multipart form data. + +## Prerequisites + +- [Node.js](https://nodejs.org/) 18+ installed +- A Bunny Storage zone with API credentials + +## Setup + +1. Install dependencies: + +```bash +npm install +``` + +2. Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +npm start +``` + +Then visit: http://localhost:8080 diff --git a/libs/bunny-storage/examples/node/form-upload/index.ts b/libs/bunny-storage/examples/node/form-upload/index.ts new file mode 100644 index 0000000..3473490 --- /dev/null +++ b/libs/bunny-storage/examples/node/form-upload/index.ts @@ -0,0 +1,176 @@ +import { createServer } from "node:http"; +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = process.env.BUNNY_STORAGE_API_KEY; +const zoneName = process.env.BUNNY_STORAGE_ZONE; +const region = process.env.BUNNY_STORAGE_REGION || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + process.exit(1); +} + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey +); + +const port = 8080; + +const html = ` + + + + Bunny Storage Upload + + + +

Bunny Storage Upload

+
+
+
+ +
+
+
+ +
+ +
+ +`; + +const server = createServer(async (req, res) => { + const url = new URL(req.url || "/", `http://localhost:${port}`); + + if (url.pathname === "/" && req.method === "GET") { + res.writeHead(200, { "Content-Type": "text/html" }); + res.end(html); + return; + } + + if (url.pathname === "/upload" && req.method === "POST") { + try { + const formData = await parseMultipartForm(req); + const file = formData.file; + const remotePath = formData.path; + + if (!file || !remotePath) { + res.writeHead(400, { "Content-Type": "application/json" }); + res.end(JSON.stringify({ error: "Missing file or path" })); + return; + } + + const stream = new ReadableStream({ + start(controller) { + controller.enqueue(file.data); + controller.close(); + }, + }); + + const success = await BunnyStorage.file.upload( + storageZone, + remotePath, + stream, + { contentType: file.contentType } + ); + + res.writeHead(200, { "Content-Type": "application/json" }); + res.end( + JSON.stringify({ + storageZone: zoneName, + region, + remotePath, + fileName: file.filename, + size: file.data.length, + contentType: file.contentType, + success, + }) + ); + } catch (error) { + res.writeHead(500, { "Content-Type": "application/json" }); + res.end(JSON.stringify({ error: (error as Error).message })); + } + return; + } + + res.writeHead(404); + res.end("Not Found"); +}); + +interface ParsedFile { + filename: string; + contentType: string; + data: Uint8Array; +} + +interface ParsedForm { + path?: string; + file?: ParsedFile; +} + +async function parseMultipartForm( + req: import("node:http").IncomingMessage +): Promise { + return new Promise((resolve, reject) => { + const chunks: Buffer[] = []; + req.on("data", (chunk) => chunks.push(chunk)); + req.on("end", () => { + const body = Buffer.concat(chunks); + const contentType = req.headers["content-type"] || ""; + const boundaryMatch = contentType.match(/boundary=(.+)/); + if (!boundaryMatch) { + reject(new Error("No boundary found")); + return; + } + + const boundary = boundaryMatch[1]; + const parts = body + .toString("binary") + .split(`--${boundary}`) + .filter((p) => p && p !== "--\r\n" && p !== "--"); + + const result: ParsedForm = {}; + + for (const part of parts) { + const [headerSection, ...contentParts] = part.split("\r\n\r\n"); + const content = contentParts.join("\r\n\r\n").replace(/\r\n$/, ""); + + const nameMatch = headerSection.match(/name="([^"]+)"/); + if (!nameMatch) continue; + + const name = nameMatch[1]; + + if (name === "path") { + result.path = content; + } else if (name === "file") { + const filenameMatch = headerSection.match(/filename="([^"]+)"/); + const contentTypeMatch = headerSection.match( + /Content-Type:\s*([^\r\n]+)/i + ); + result.file = { + filename: filenameMatch?.[1] || "unknown", + contentType: contentTypeMatch?.[1] || "application/octet-stream", + data: Buffer.from(content, "binary"), + }; + } + } + + resolve(result); + }); + req.on("error", reject); + }); +} + +server.listen(port, () => { + console.log(`Starting server on http://localhost:${port}`); + console.log("Upload a file using the form or POST to /upload"); +}); diff --git a/libs/bunny-storage/examples/node/form-upload/package.json b/libs/bunny-storage/examples/node/form-upload/package.json new file mode 100644 index 0000000..f298a9e --- /dev/null +++ b/libs/bunny-storage/examples/node/form-upload/package.json @@ -0,0 +1,15 @@ +{ + "name": "form-upload-example", + "private": true, + "type": "module", + "scripts": { + "start": "npx tsx index.ts" + }, + "dependencies": { + "@bunny.net/storage-sdk": "latest" + }, + "devDependencies": { + "tsx": "^4.0.0", + "@types/node": "^20.0.0" + } +} diff --git a/libs/bunny-storage/examples/node/list-files/README.md b/libs/bunny-storage/examples/node/list-files/README.md new file mode 100644 index 0000000..0e26ac8 --- /dev/null +++ b/libs/bunny-storage/examples/node/list-files/README.md @@ -0,0 +1,32 @@ +# List Files Example + +This example demonstrates how to list files and directories in a Bunny Storage zone. + +## Prerequisites + +- [Node.js](https://nodejs.org/) 18+ installed +- A Bunny Storage zone with API credentials + +## Setup + +1. Install dependencies: + +```bash +npm install +``` + +2. Set the required environment variables: + +```bash +export BUNNY_STORAGE_API_KEY="your-storage-api-key" +export BUNNY_STORAGE_ZONE="your-storage-zone-name" +export BUNNY_STORAGE_REGION="de" # Optional, defaults to "de" (Falkenstein) +``` + +## Running the Example + +```bash +npm start -- /path/to/directory +``` + +If no path is provided, it lists the root directory (`/`). diff --git a/libs/bunny-storage/examples/node/list-files/index.ts b/libs/bunny-storage/examples/node/list-files/index.ts new file mode 100644 index 0000000..87e6eac --- /dev/null +++ b/libs/bunny-storage/examples/node/list-files/index.ts @@ -0,0 +1,55 @@ +import * as BunnyStorage from "@bunny.net/storage-sdk"; + +const apiKey = process.env.BUNNY_STORAGE_API_KEY; +const zoneName = process.env.BUNNY_STORAGE_ZONE; +const region = process.env.BUNNY_STORAGE_REGION || "de"; + +if (!apiKey || !zoneName) { + console.error("Missing required environment variables:"); + console.error(" BUNNY_STORAGE_API_KEY - Your storage zone API key"); + console.error(" BUNNY_STORAGE_ZONE - Your storage zone name"); + process.exit(1); +} + +const path = process.argv[2] || "/"; + +const storageRegion = region as BunnyStorage.regions.StorageRegion; +const storageZone = BunnyStorage.zone.connect_with_accesskey( + storageRegion, + zoneName, + apiKey +); + +try { + const files = await BunnyStorage.file.list(storageZone, path); + + console.log( + JSON.stringify( + { + storageZone: zoneName, + region, + path, + files: files.map((file) => ({ + name: file.objectName, + path: file.path, + size: file.length, + isDirectory: file.isDirectory, + dateModified: file.lastChanged.toISOString(), + contentType: file.contentType, + })), + summary: { + totalFiles: files.filter((f) => !f.isDirectory).length, + totalDirectories: files.filter((f) => f.isDirectory).length, + totalSize: files + .filter((f) => !f.isDirectory) + .reduce((sum, f) => sum + f.length, 0), + }, + }, + null, + 2 + ) + ); +} catch (error) { + console.error("Error listing files:", (error as Error).message); + process.exit(1); +} diff --git a/libs/bunny-storage/examples/node/list-files/package-lock.json b/libs/bunny-storage/examples/node/list-files/package-lock.json new file mode 100644 index 0000000..aea3697 --- /dev/null +++ b/libs/bunny-storage/examples/node/list-files/package-lock.json @@ -0,0 +1,607 @@ +{ + "name": "list-files-example", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "list-files-example", + "dependencies": { + "@bunny.net/storage-sdk": "latest" + }, + "devDependencies": { + "@types/node": "^20.0.0", + "tsx": "^4.0.0" + } + }, + "node_modules/@bunny.net/storage-sdk": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@bunny.net/storage-sdk/-/storage-sdk-0.3.0.tgz", + "integrity": "sha512-fRtYdztE01tVdQFX25GlYYnjCeTrW44ZsVlUNOcczKzPg6ellZ/awCzg+WsqY7bwIlUD7dTgy/Jtj8qOTmAs+Q==", + "license": "MIT", + "dependencies": { + "dotenv": "^16.4.7", + "zod": "^3.24.2" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz", + "integrity": "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.0.tgz", + "integrity": "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.0.tgz", + "integrity": "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.0.tgz", + "integrity": "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.0.tgz", + "integrity": "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.0.tgz", + "integrity": "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.0.tgz", + "integrity": "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.0.tgz", + "integrity": "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.0.tgz", + "integrity": "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.0.tgz", + "integrity": "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.0.tgz", + "integrity": "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.0.tgz", + "integrity": "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.0.tgz", + "integrity": "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.0.tgz", + "integrity": "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.0.tgz", + "integrity": "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.0.tgz", + "integrity": "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.0.tgz", + "integrity": "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.0.tgz", + "integrity": "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.0.tgz", + "integrity": "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.0.tgz", + "integrity": "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.0.tgz", + "integrity": "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.0.tgz", + "integrity": "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.0.tgz", + "integrity": "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.0.tgz", + "integrity": "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.0.tgz", + "integrity": "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.0.tgz", + "integrity": "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@types/node": { + "version": "20.19.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz", + "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/esbuild": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.0.tgz", + "integrity": "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.0", + "@esbuild/android-arm": "0.27.0", + "@esbuild/android-arm64": "0.27.0", + "@esbuild/android-x64": "0.27.0", + "@esbuild/darwin-arm64": "0.27.0", + "@esbuild/darwin-x64": "0.27.0", + "@esbuild/freebsd-arm64": "0.27.0", + "@esbuild/freebsd-x64": "0.27.0", + "@esbuild/linux-arm": "0.27.0", + "@esbuild/linux-arm64": "0.27.0", + "@esbuild/linux-ia32": "0.27.0", + "@esbuild/linux-loong64": "0.27.0", + "@esbuild/linux-mips64el": "0.27.0", + "@esbuild/linux-ppc64": "0.27.0", + "@esbuild/linux-riscv64": "0.27.0", + "@esbuild/linux-s390x": "0.27.0", + "@esbuild/linux-x64": "0.27.0", + "@esbuild/netbsd-arm64": "0.27.0", + "@esbuild/netbsd-x64": "0.27.0", + "@esbuild/openbsd-arm64": "0.27.0", + "@esbuild/openbsd-x64": "0.27.0", + "@esbuild/openharmony-arm64": "0.27.0", + "@esbuild/sunos-x64": "0.27.0", + "@esbuild/win32-arm64": "0.27.0", + "@esbuild/win32-ia32": "0.27.0", + "@esbuild/win32-x64": "0.27.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/libs/bunny-storage/examples/node/list-files/package.json b/libs/bunny-storage/examples/node/list-files/package.json new file mode 100644 index 0000000..d09cdd4 --- /dev/null +++ b/libs/bunny-storage/examples/node/list-files/package.json @@ -0,0 +1,15 @@ +{ + "name": "list-files-example", + "private": true, + "type": "module", + "scripts": { + "start": "npx tsx index.ts" + }, + "dependencies": { + "@bunny.net/storage-sdk": "latest" + }, + "devDependencies": { + "tsx": "^4.0.0", + "@types/node": "^20.0.0" + } +}