[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-81536":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":11,"openIssues":12,"contributorsCount":12,"subscribersCount":12,"size":12,"stars1d":12,"stars7d":12,"stars30d":12,"stars90d":12,"forks30d":12,"starsTrendScore":12,"compositeScore":12,"rankGlobal":9,"rankLanguage":9,"license":13,"archived":14,"fork":14,"defaultBranch":15,"hasWiki":16,"hasPages":14,"topics":17,"createdAt":9,"pushedAt":9,"updatedAt":18,"readmeContent":19,"aiSummary":20,"trendingCount":12,"starSnapshotCount":12,"syncStatus":21,"lastSyncTime":22,"discoverSource":23},81536,"share","acoyfellow\u002Fshare","acoyfellow","Temporary, resumable file transfers on your own Cloudflare account.",null,"TypeScript",26,0,"MIT License",false,"main",true,[],"2026-06-12 02:04:16","# Share\n\n[![check](https:\u002F\u002Fgithub.com\u002Facoyfellow\u002Fshare\u002Factions\u002Fworkflows\u002Fcheck.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Facoyfellow\u002Fshare\u002Factions\u002Fworkflows\u002Fcheck.yml)\n[![License: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-black.svg)](.\u002FLICENSE)\n\n[![Deploy to Cloudflare](https:\u002F\u002Fdeploy.workers.cloudflare.com\u002Fbutton)](https:\u002F\u002Fdeploy.workers.cloudflare.com\u002F?url=https:\u002F\u002Fgithub.com\u002Facoyfellow\u002Fshare)\n\n**Temporary, resumable file transfers on your own Cloudflare account.**\n\nShare creates an upload link and a separate download link immediately, then transfers the file in resumable parts through a private R2 bucket. It is an OSS starter for teams that want a small transfer lane, not another collaboration suite.\n\n## Try it\n\n- Demo: https:\u002F\u002Fshare.coey.dev\n- Source: https:\u002F\u002Fgithub.com\u002Facoyfellow\u002Fshare\n- Deploy: https:\u002F\u002Fdeploy.workers.cloudflare.com\u002F?url=https:\u002F\u002Fgithub.com\u002Facoyfellow\u002Fshare\n\n## Tutorial: try Share locally\n\n### What you will run\n\nA single Worker backed by two Durable Objects and one local R2 bucket:\n\n- `ShareSession` owns one temporary share, capability checks, multipart upload, download budget, and expiration.\n- `DemoQuota` reserves bytes and limits anonymous share creation.\n- R2 stores completed bytes privately; the browser never receives a public storage URL.\n- Turnstile gates anonymous creation using Cloudflare's official automated-test keys in local development.\n\n### Start the app\n\nRequirements: Bun and a Cloudflare-compatible browser.\n\n```sh\nbun install\nbun run check\nbunx wrangler dev --local --port 8796 \\\n  --var TURNSTILE_SITE_KEY:1x00000000000000000000AA \\\n  --var TURNSTILE_SECRET_KEY:1x0000000000000000000000000000000AA\n```\n\nOpen `http:\u002F\u002Flocalhost:8796`.\n\nFor an automated browser pass while that server is running:\n\n```sh\nbun run browser:e2e\n```\n\n1. Choose a temporary file.\n2. Complete the visible test Turnstile challenge.\n3. Select **Create secure links and upload**.\n4. Copy the **Share link** into another tab. It contains only a read capability in the URL fragment.\n5. Observe upload readiness and download the finished file.\n6. Use the **Manage link** to resume an interrupted upload or remove the share.\n\nYou have now exercised the same capability boundary and R2 multipart path intended for a public demo deployment.\n\n## How-to guides\n\n### Validate before publishing\n\n```sh\nbun run typecheck\nbun run test\nbun run dry-run\nbun run browser:e2e # with the local Worker running as in the tutorial\n```\n\nThe test suite runs real Worker\u002FDurable Object\u002FR2 behavior under Cloudflare's Workers Vitest pool. It covers capabilities, quota reservation, multipart finalization, range downloads, aborts, and metadata non-disclosure.\n\n### Deploy your own instance\n\nThe **Deploy to Cloudflare** button above creates your Worker, Durable Objects, and private R2 bucket from `wrangler.jsonc`.\n\nDuring setup:\n\n1. Choose your Worker name and R2 bucket name.\n2. Create a Turnstile widget for your assigned Worker hostname (or your custom domain).\n3. Set `TURNSTILE_SITE_KEY` and the secret `TURNSTILE_SECRET_KEY` from that widget.\n4. Optionally set `PUBLIC_URL` when you will use a custom hostname.\n\nA fresh button deploy is reachable on its `workers.dev` hostname with Preview URLs disabled. If you attach a custom domain, switch to a single public surface in your generated repository:\n\n```jsonc\n\"workers_dev\": false,\n\"preview_urls\": false,\n\"routes\": [{ \"pattern\": \"share.example.com\", \"custom_domain\": true }]\n```\n\nManual deployment is also supported:\n\n```sh\nbun install\nbunx wrangler r2 bucket create share-files\nbunx wrangler secret put TURNSTILE_SECRET_KEY\n# Set TURNSTILE_SITE_KEY in wrangler.jsonc\nbunx wrangler deploy\n```\n\nBefore operating a public hosted instance, read `SECURITY.md` and tune its limits for your cost and abuse posture.\n\n### Adjust public-demo limits\n\nAll public limits are explicit Worker variables in `wrangler.jsonc`:\n\n| Variable | Default | Meaning |\n|---|---:|---|\n| `MAX_SHARE_SIZE_BYTES` | `67108864` | Maximum file size, 64 MiB |\n| `MAX_ACTIVE_BYTES` | `1073741824` | Total currently retained or reserved bytes, 1 GiB |\n| `MAX_CREATES_PER_HOUR` | `5` | Creation limit per coarse client key |\n| `PENDING_TTL_SECONDS` | `3600` | Time allowed for incomplete uploads |\n| `READY_TTL_SECONDS` | `86400` | Time completed downloads remain available |\n| `DOWNLOAD_MULTIPLIER` | `4` | Download byte budget as a multiple of file size |\n\n## Explanation\n\n### Why links are immediately available\n\nThe uploader should not need to wait for a large transfer to finish before sharing intent. Share first creates a temporary record and two capabilities, then uploads chunks into R2. The read link can display pending progress and becomes downloadable after completion.\n\n### Why there are two links\n\nPublic demo mode has no user accounts. It therefore uses capability security:\n\n- The **share link** grants status and download access.\n- The **manage link** additionally grants upload resume, cancellation, and deletion.\n\nCapabilities live in URL fragments (`#read=…`, `#manage=…`), which are not sent to the server during navigation. Browser API calls move the selected capability into an `Authorization: ShareCapability …` header. The server stores only capability hashes.\n\n### Why the hosted demo is tightly limited\n\nAn anonymous file-transfer site can otherwise become unbounded storage or distribution infrastructure. Share's defaults demonstrate the architecture while constraining cost and abuse:\n\n- one temporary file per share;\n- no public index or recipient email claims;\n- private object storage and attachment-only downloads;\n- Turnstile before storage reservation;\n- exact retained-byte reservation in a Durable Object;\n- request-time expiry enforcement plus cleanup alarms;\n- bounded upload retry bytes and pre-debited download byte budgets.\n\nFor confidential or regulated file sharing, add identity-backed authorization, scanning, audit, retention, and operator processes rather than increasing public-demo limits.\n\n## Reference\n\n### Routes\n\n| Method | Route | Required capability | Purpose |\n|---|---|---|---|\n| `GET` | `\u002F` | None | Create-share interface |\n| `POST` | `\u002Fapi\u002Fshares` | Valid Turnstile response | Reserve and create a pending share |\n| `GET` | `\u002Fshare\u002F:id#read=…` | Browser-held read capability | Viewer shell; fragment is not sent to the Worker |\n| `GET` | `\u002Fapi\u002Fshares\u002F:id\u002Fstate` | Read or manage | Status and progress |\n| `PUT` | `\u002Fapi\u002Fshares\u002F:id\u002Fparts\u002F:number` | Manage | Upload or retry one R2 multipart part |\n| `POST` | `\u002Fapi\u002Fshares\u002F:id\u002Fcomplete` | Manage | Finalize the object |\n| `POST` | `\u002Fapi\u002Fshares\u002F:id\u002Fabort` | Manage | Cancel pending transfer |\n| `POST` | `\u002Fapi\u002Fshares\u002F:id\u002Fdelete` | Manage | Delete transfer\u002Fobject |\n| `GET` | `\u002Fapi\u002Fshares\u002F:id\u002Fdownload` | Read or manage | Attachment download, including single byte ranges |\n\n### File map\n\n| File | Responsibility |\n|---|---|\n| `src\u002Findex.ts` | Worker pages and capability API routing |\n| `src\u002Fshare-session.ts` | Per-share Durable Object, multipart upload, expiry and downloads |\n| `src\u002Fquota.ts` | Deployment-wide retained-byte and creation limits |\n| `src\u002Fcore.ts` | Capabilities, names, multipart and Range primitives |\n| `src\u002Fturnstile.ts` | Turnstile server validation |\n| `src\u002Fui.ts` | Browser upload, viewer and download interface |\n| `tests\u002F` | Core and Workers-runtime integration suite |\n| `wrangler.jsonc` | Cloudflare bindings and configurable demo limits |\n\n### Cloudflare resources\n\n| Primitive | Role |\n|---|---|\n| Worker | Public UI and scoped HTTP API |\n| Durable Objects | Share authority, cleanup alarms, exact quota authority |\n| R2 | Private multipart object storage |\n| Turnstile | Anonymous share-creation challenge |\n\n## License\n\nMIT\n","Share 是一个基于您自己的 Cloudflare 账户实现的临时可恢复文件传输工具。它使用 TypeScript 编写，能够即时生成上传和下载链接，并通过私有的 R2 存储桶以分段形式传输文件，支持断点续传功能。该项目适用于需要简单文件分享通道而不希望引入复杂协作套件的小团队或个人用户。部署简便，只需点击 GitHub 仓库中的“Deploy to Cloudflare”按钮即可快速设置您的 Worker、Durable Objects 和私有 R2 存储桶，非常适合那些追求高效、安全文件分享解决方案的场景。",2,"2026-06-11 04:05:26","CREATED_QUERY"]