{"_id":"@adaptive-ds/cfb2","_rev":"5-151ce93f337cc0c94e10ceacad70487b","name":"@adaptive-ds/cfb2","dist-tags":{"latest":"0.5.0"},"versions":{"0.1.0":{"name":"@adaptive-ds/cfb2","version":"0.1.0","keywords":["cloudflare-workers","cloudflare","backblaze-b2","b2","storage-proxy","bandwidth-alliance","object-storage","serverless","cors","cost-optimization","zero-bandwidth-cost"],"license":"MIT","_id":"@adaptive-ds/cfb2@0.1.0","maintainers":[{"name":"david1gp","email":"david1gruppenplan@gmail.com"}],"homepage":"https://github.com/david1gp/cfb2","dist":{"shasum":"b250b210e662a8dd44054f6e1a2d690e0986813a","tarball":"https://registry.npmjs.org/@adaptive-ds/cfb2/-/cfb2-0.1.0.tgz","fileCount":108,"integrity":"sha512-/kl/5f4oLORrToJh7U7fMvj0ofIRqibVdDfazTrk4dAuWTSJgY0RRhPasTVUivc/xivTI6UlVUV23grPPs6eCg==","signatures":[{"sig":"MEUCIQCtrqtIRIVisTsM4pgsEytSh0FB7WYb7CXWhz/SNsS6owIgIUXdBWflgRDOpX/r1bV1PxvqCUDAxxz7WcAwt2RQ8A0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":199691},"type":"module","shasum":"b250b210e662a8dd44054f6e1a2d690e0986813a","private":false,"scripts":{"dev":"wrangler dev --config ./wrangler.jsonc","test":"bun test --env-file=.env --preload ./test/setup.ts","build":"tsc","deploy":"bun run ops/deploy.ts","test:w":"bun test --env-file=.env --preload ./test/setup.ts --watch","build:lib":"tsc -p ./tsconfig.lib.json"},"_npmUser":{"name":"david1gp","email":"david1gruppenplan@gmail.com"},"prettier":{"semi":false,"printWidth":120,"trailingComma":"all"},"_integrity":"sha512-/kl/5f4oLORrToJh7U7fMvj0ofIRqibVdDfazTrk4dAuWTSJgY0RRhPasTVUivc/xivTI6UlVUV23grPPs6eCg==","repository":{"url":"git+https://github.com/david1gp/cfb2.git"},"_npmVersion":"10.8.3","description":"A lightweight Cloudflare Worker that eliminates Backblaze B2 outbound bandwidth costs through the Bandwidth Alliance.","directories":{},"_nodeVersion":"24.3.0","dependencies":{"hono":"^4.11.7","jose":"^6.1.3","dayjs":"^1.11.19","valibot":"^1.2.0","jwt-decode":"^4.0.0","hono-openapi":"^1.2.0","@hono/swagger-ui":"^0.5.3","@adaptive-ds/utils":"link:@adaptive-ds/utils","@valibot/to-json-schema":"^1.5.0","@hono/standard-validator":"^0.2.2"},"_hasShrinkwrap":false,"devDependencies":{"prettier":"^3.8.1","wrangler":"^4.61.1","@types/bun":"^1.3.7","@biomejs/biome":"^2.3.13","@cloudflare/workers-types":"^4.20260129.0"},"peerDependencies":{"typescript":"^5"},"_npmOperationalInternal":{"tmp":"tmp/cfb2_0.1.0_1770907064310_0.08902308238361556","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@adaptive-ds/cfb2","version":"0.2.0","keywords":["cloudflare-workers","cloudflare","backblaze-b2","b2","storage-proxy","bandwidth-alliance","object-storage","serverless","cors","cost-optimization","zero-bandwidth-cost"],"license":"MIT","_id":"@adaptive-ds/cfb2@0.2.0","maintainers":[{"name":"david1gp","email":"david1gruppenplan@gmail.com"}],"homepage":"https://github.com/david1gp/cfb2","bugs":{"url":"https://github.com/david1gp/cfb2/issues"},"dist":{"shasum":"3ba73d6ad03ece0f8e92081ac55fb49fddbac810","tarball":"https://registry.npmjs.org/@adaptive-ds/cfb2/-/cfb2-0.2.0.tgz","fileCount":48,"integrity":"sha512-7JXYiaj93Bs4mJKt+T0HdHFdX6mzT5lfnS+aWqS/luTDy9acPZQkfhqxONAnI1nAAtZGyBH5Yz4D1QGnC6KkNw==","signatures":[{"sig":"MEQCIBhJ9r6gxTwuEhhSR8YBsfmteq8p2HhjoVB5bD6L+QIfAiB7RjpqYE33pvximAoXUAwWQI+7UaUH/nwCD9Um+KaZKA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@adaptive-ds%2fcfb2@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":25822},"type":"module","exports":{"./*":"./dist/*"},"gitHead":"33b02f0dbacde64f74b014a9eddebfcfe4d02655","private":false,"scripts":{"dev":"wrangler dev --config ./wrangler.jsonc","cors":"bun ./src/cors/bucketCors.ts","test":"bun test --env-file=.env --preload ./test/setup.ts","build":"tsc -p ./tsconfig.client.json","deploy":"bun run ops/deploy.ts","test:w":"bun test --env-file=.env --preload ./test/setup.ts --watch","release":"bash ./ops/release.sh"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2e5f76c7-7029-43c3-9455-02a8d01cd4d6"}},"prettier":{"semi":false,"printWidth":120,"trailingComma":"all"},"repository":{"url":"git+https://github.com/david1gp/cfb2.git"},"_npmVersion":"11.10.0","description":"A lightweight Cloudflare Worker that eliminates Backblaze B2 outbound bandwidth costs through the Bandwidth Alliance.","directories":{},"_nodeVersion":"20.20.0","_hasShrinkwrap":false,"devDependencies":{"hono":"^4.11.7","jose":"^6.1.3","dayjs":"^1.11.19","valibot":"^1.2.0","prettier":"^3.8.1","wrangler":"^4.61.1","@types/bun":"^1.3.7","jwt-decode":"^4.0.0","hono-openapi":"^1.2.0","@biomejs/biome":"^2.3.13","@hono/swagger-ui":"^0.5.3","@adaptive-ds/utils":"^0.7.0","@valibot/to-json-schema":"^1.5.0","@hono/standard-validator":"^0.2.2","@cloudflare/workers-types":"^4.20260129.0"},"peerDependencies":{"jose":"^6.1.3","dayjs":"^1.11.19","valibot":"^1.2.0","jwt-decode":"^4.0.0","typescript":"^5","@adaptive-ds/utils":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/cfb2_0.2.0_1771341631004_0.13662321319000603","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@adaptive-ds/cfb2","version":"0.3.0","keywords":["cloudflare-workers","cloudflare","backblaze-b2","b2","storage-proxy","bandwidth-alliance","object-storage","serverless","cors","cost-optimization","zero-bandwidth-cost"],"license":"MIT","_id":"@adaptive-ds/cfb2@0.3.0","maintainers":[{"name":"david1gp","email":"david1gruppenplan@gmail.com"}],"homepage":"https://github.com/david1gp/cfb2","bugs":{"url":"https://github.com/david1gp/cfb2/issues"},"dist":{"shasum":"6c198c31f27d97d58dd35947b9d67fcf92799236","tarball":"https://registry.npmjs.org/@adaptive-ds/cfb2/-/cfb2-0.3.0.tgz","fileCount":48,"integrity":"sha512-0V9SyxfCnrLV8mVARK3yfi1HLhbmt9vq5GteZS1nx/fPnIXGMa8VBxupawLjhR/CAlfxBghpm3vPX2MquQT7XQ==","signatures":[{"sig":"MEUCIHPTx2OzYfOD5twzxkwf5ailNYiO7kOOT2+qkdxJYEdSAiEA0PflrMibmrJEfQny8ZEbbqvxkCsCpKHDL5TbleuoS9A=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@adaptive-ds%2fcfb2@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":25774},"type":"module","exports":{"./*":"./dist/*"},"gitHead":"3a013fe9c39a3bf30d3b48a6d25125b2ab694946","private":false,"scripts":{"dev":"wrangler dev --config ./wrangler.jsonc","cors":"bun ./src/cors/bucketCors.ts","test":"bun test --env-file=.env --preload ./test/setup.ts","build":"tsc -p ./tsconfig.client.json","deploy":"bun run ops/deploy.ts","test:w":"bun test --env-file=.env --preload ./test/setup.ts --watch","release":"bash ./ops/release.sh"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2e5f76c7-7029-43c3-9455-02a8d01cd4d6"}},"prettier":{"semi":false,"printWidth":120,"trailingComma":"all"},"repository":{"url":"git+https://github.com/david1gp/cfb2.git"},"_npmVersion":"11.10.0","description":"A lightweight Cloudflare Worker that eliminates Backblaze B2 outbound bandwidth costs through the Bandwidth Alliance.","directories":{},"_nodeVersion":"20.20.0","_hasShrinkwrap":false,"devDependencies":{"hono":"^4.11.7","jose":"^6.1.3","dayjs":"^1.11.19","valibot":"^1.2.0","prettier":"^3.8.1","wrangler":"^4.61.1","@types/bun":"^1.3.7","jwt-decode":"^4.0.0","hono-openapi":"^1.2.0","@biomejs/biome":"^2.3.13","@hono/swagger-ui":"^0.5.3","@adaptive-ds/utils":"^0.7.0","@valibot/to-json-schema":"^1.5.0","@hono/standard-validator":"^0.2.2","@cloudflare/workers-types":"^4.20260129.0"},"peerDependencies":{"jose":"^6.1.3","dayjs":"^1.11.19","valibot":"^1.2.0","jwt-decode":"^4.0.0","typescript":"^5","@adaptive-ds/utils":"^0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/cfb2_0.3.0_1771400821969_0.4211181638846411","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@adaptive-ds/cfb2","version":"0.4.0","keywords":["cloudflare-workers","cloudflare","backblaze-b2","b2","storage-proxy","bandwidth-alliance","object-storage","serverless","cors","cost-optimization","zero-bandwidth-cost"],"license":"MIT","_id":"@adaptive-ds/cfb2@0.4.0","maintainers":[{"name":"david1gp","email":"david1gruppenplan@gmail.com"}],"homepage":"https://github.com/david1gp/cfb2","bugs":{"url":"https://github.com/david1gp/cfb2/issues"},"dist":{"shasum":"d663456727beba15950e78e855770cf608e10cd7","tarball":"https://registry.npmjs.org/@adaptive-ds/cfb2/-/cfb2-0.4.0.tgz","fileCount":48,"integrity":"sha512-IOg5wMdriUkbph4UDKOOhv69qbmmMrUFCnlfyhHjGV6oZTArpms+uvHyplSUu4B1wbEmc42fbbvSDbQvuFe/Yg==","signatures":[{"sig":"MEYCIQDm/DLQmdN6U+DmnC0wYZbR7f5OYc3/B75oRNfZGmLvUgIhAMJx4F123KoqDQC/qS3/m2/JnjK75vECZ04tRd7TZIlB","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@adaptive-ds%2fcfb2@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":25500},"type":"module","exports":{"./*":"./dist/*"},"gitHead":"17788b4e8fc7d4320a9f370abf427575d6877789","private":false,"scripts":{"dev":"wrangler dev --config ./wrangler.jsonc --env dcc_dev","cors":"bun ./src/cors/bucketCors.ts","test":"bun test --env-file=.env --preload ./test/setup.ts","build":"tsc -p ./tsconfig.client.json","deploy":"bun run ops/deploy.ts","test:w":"bun test --env-file=.env --preload ./test/setup.ts --watch","release":"bash ./ops/release.sh"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2e5f76c7-7029-43c3-9455-02a8d01cd4d6"}},"prettier":{"semi":false,"printWidth":120,"trailingComma":"all"},"repository":{"url":"git+https://github.com/david1gp/cfb2.git"},"_npmVersion":"11.11.1","description":"A lightweight Cloudflare Worker that eliminates Backblaze B2 outbound bandwidth costs through the Bandwidth Alliance.","directories":{},"_nodeVersion":"20.20.0","_hasShrinkwrap":false,"devDependencies":{"hono":"^4.12.8","jose":"^6.2.1","dayjs":"^1.11.20","valibot":"^1.2.0","prettier":"^3.8.1","wrangler":"^4.73.0","@types/bun":"^1.3.10","jwt-decode":"^4.0.0","typescript":"^5.9.3","hono-openapi":"^1.3.0","@biomejs/biome":"^2.4.7","@hono/swagger-ui":"^0.5.3","@valibot/to-json-schema":"^1.5.0","@hono/standard-validator":"^0.2.2","@cloudflare/workers-types":"^4.20260313.1"},"peerDependencies":{"jose":"^6.1.3","dayjs":"^1.11.19","valibot":"^1.2.0","jwt-decode":"^4.0.0","@adaptive-ds/utils":"^0.10.0","@adaptive-ds/result":"^0.3.0"},"_npmOperationalInternal":{"tmp":"tmp/cfb2_0.4.0_1773554433755_0.8024945433648223","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@adaptive-ds/cfb2","version":"0.5.0","scripts":{"dev":"wrangler dev --config ./wrangler.jsonc --env dcc_dev","build":"tsc -p ./tsconfig.client.json","cors":"bun ./src/cors/bucketCors.ts","deploy":"bun run ops/deploy.ts","release":"bash ./ops/release.sh","test":"bun test --env-file=.env --preload ./test/setup.ts","test:w":"bun test --env-file=.env --preload ./test/setup.ts --watch"},"peerDependencies":{"@adaptive-ds/result":"^0.4.0","@adaptive-ds/utils":"^0.10.0","dayjs":"^1.11.19","jose":"^6.1.3","jwt-decode":"^4.0.0","valibot":"^1.2.0"},"devDependencies":{"@biomejs/biome":"^2.4.7","@cloudflare/workers-types":"^4.20260316.1","@hono/standard-validator":"^0.2.2","@hono/swagger-ui":"^0.6.1","@types/bun":"^1.3.10","@valibot/to-json-schema":"^1.5.0","dayjs":"^1.11.20","hono":"^4.12.8","hono-openapi":"^1.3.0","jose":"^6.2.1","jwt-decode":"^4.0.0","prettier":"^3.8.1","typescript":"^5.9.3","valibot":"^1.2.0","wrangler":"^4.74.0"},"prettier":{"semi":false,"printWidth":120,"trailingComma":"all"},"type":"module","private":false,"license":"MIT","homepage":"https://github.com/david1gp/cfb2","description":"A lightweight Cloudflare Worker that eliminates Backblaze B2 outbound bandwidth costs through the Bandwidth Alliance.","keywords":["cloudflare-workers","cloudflare","backblaze-b2","b2","storage-proxy","bandwidth-alliance","object-storage","serverless","cors","cost-optimization","zero-bandwidth-cost"],"repository":{"url":"git+https://github.com/david1gp/cfb2.git"},"exports":{"./*.js":{"types":"./dist/*.d.ts","import":"./dist/*.js"}},"gitHead":"d4e6d32da41543d3330487ed4d4c4a368def5b06","_id":"@adaptive-ds/cfb2@0.5.0","bugs":{"url":"https://github.com/david1gp/cfb2/issues"},"_nodeVersion":"20.20.1","_npmVersion":"11.12.0","dist":{"integrity":"sha512-jKT3NEvlw3BgoxKAg94PFfGLjNmsVaqAtp39ebpPYHhlxnkxIrnYsHXyxRPCM27ueWc/xbmzoMYm/+Ue4METQA==","shasum":"7cae4283d5bf7a9ba6140967da795d78d18be70e","tarball":"https://registry.npmjs.org/@adaptive-ds/cfb2/-/cfb2-0.5.0.tgz","fileCount":48,"unpackedSize":25495,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@adaptive-ds%2fcfb2@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBMZ5TtTRVauU/OvKjjACqIdVg+JehtNDIcPsUT5nXvPAiEA0niwL2h6r9bMUXkJgXyR5aNO1BdZ4UQ1ZxowKjsMjT8="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2e5f76c7-7029-43c3-9455-02a8d01cd4d6"}},"directories":{},"maintainers":[{"name":"david1gp","email":"david1gruppenplan@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/cfb2_0.5.0_1774166151225_0.46406555720940124"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-12T14:37:44.240Z","modified":"2026-03-22T07:55:51.649Z","0.1.0":"2026-02-12T14:37:44.493Z","0.2.0":"2026-02-17T15:20:31.194Z","0.3.0":"2026-02-18T07:47:02.121Z","0.4.0":"2026-03-15T06:00:33.925Z","0.5.0":"2026-03-22T07:55:51.365Z"},"bugs":{"url":"https://github.com/david1gp/cfb2/issues"},"license":"MIT","homepage":"https://github.com/david1gp/cfb2","keywords":["cloudflare-workers","cloudflare","backblaze-b2","b2","storage-proxy","bandwidth-alliance","object-storage","serverless","cors","cost-optimization","zero-bandwidth-cost"],"repository":{"url":"git+https://github.com/david1gp/cfb2.git"},"description":"A lightweight Cloudflare Worker that eliminates Backblaze B2 outbound bandwidth costs through the Bandwidth Alliance.","maintainers":[{"name":"david1gp","email":"david1gruppenplan@gmail.com"}],"readme":"# @adaptive-ds/cfb2 - 🚀 Zero-Cost B2 Object Storage Cloudflare Proxy\n\nA clever Cloudflare Worker that eliminates Backblaze B2 outbound bandwidth costs through using the Cloudflare Network of the Bandwidth Alliance.\n\n- **Zero bandwidth costs** – leverage Cloudflare's Bandwidth Alliance with Backblaze B2 for free outbound traffic.\n- **Lightning fast** – runs on Cloudflare's global edge network with automatic CDN capabilities.\n- **Dead simple** – just point it at your B2 bucket and forget about expensive bandwidth bills.\n- **Production ready** – handles CORS, proper headers, and multiple environments out of the box.\n\nStop paying for outbound bandwidth and start serving your media files smarter, not harder.\n\nQuick Links\n\n- code - https://github.com/david1gp/cfb2\n- npm - https://www.npmjs.com/package/@adaptive-ds/cfb2\n- cloudflare bandwidth alliance - https://www.cloudflare.com/bandwidth-alliance/\n\n## Features\n\n- Proxies requests to Backblaze B2 storage through Cloudflare Workers\n- Eliminates outbound bandwidth costs via Bandwidth Alliance\n- Full CORS support with configurable origins\n- **Multi-project support** – deploy multiple environments for different use cases\n- **Custom domain routing** – clean URLs that hide your raw storage infrastructure\n\n## Architecture\n\nThe Worker acts as a transparent proxy between your users and Backblaze B2:\n\n```\nUser Request → Custom Domain → Cloudflare Worker → Backblaze B2 → Cloudflare Worker → User Response\n```\n\nSince Cloudflare and Backblaze are Bandwidth Alliance partners, the data transfer between them is free, eliminating your outbound bandwidth costs.\n\n### Multi-Project Architecture\n\nDeploy multiple environments for different projects:\n\n```\ncdn.yourdomain.com     → Production Environment (media, assets)\ndev-storage.yourdomain.com → Development Environment\n```\n\nEach environment can point to different B2 buckets with customized CORS and caching settings.\n\n## Prerequisites\n\n- Pnpm/Bun/Npm for package management\n- Cloudflare account (for Workers deployment)\n- Backblaze B2 bucket with public URL\n\n## Local Development\n\n1. Clone the repository.\n2. Install dependencies:\n   ```\n   bun install\n   ```\n\n## Configuration\n\nThe Worker uses environment variables for configuration:\n\n- `B2_BUCKET_PUBLIC_BASE_URL`: Your Backblaze B2 bucket public URL\n- `HEADER_CORS_ALLOW_ORIGIN`: Comma-separated list of allowed origins (default: \"*\")\n- `HEADER_CORS_MAX_AGE`: CORS max-age header value (default: \"300\")\n\n## Deployment to Cloudflare Workers\n\n1. **Login to Cloudflare**:\n\n   ```\n   wrangler login\n   ```\n\n2. **Configure Account ID** (if needed, add to `wrangler.jsonc`):\n\n   ```\n   wrangler whoami\n   ```\n\n   Then update `wrangler.jsonc` with `account_id = \"your-account-id\"`.\n\n3. **Deploy Single Environment**:\n\n   ```\n   bun run deploy\n   ```\n\n4. **Deploy All Environments**:\n\n   ```\n   bun run ops/deploy.ts\n   ```\n\n   This will deploy all configured environments (production, staging, etc.).\n\n5. **Monitor**:\n\n   ```\n   wrangler tail adaptive-cfb2\n   ```\n\n## Environment Setup\n\nThe project supports multiple environments through `wrangler.jsonc`. See [`wrangler.example.jsonc`](./wrangler.example.jsonc) for a comprehensive configuration example.\n\n## Security Considerations\n\n- Root path (`/`) access is blocked against crawlers and bots\n- CORS is configurable per environment\n- No sensitive data is logged or exposed\n- Custom domains hide storage infrastructure details\n- Environment isolation prevents cross-contamination\n\n## License\n\nMIT License - feel free to use this in your projects and save on bandwidth costs!\n","readmeFilename":"README.md"}