source for getorbyt.com getorbyt.com/
client bsky orbytapp app orbyt bluesky getorbyt orbytvideo atproto video
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Remove obsolete ADP files and signature; update source.json and wrangler configuration; add script for R2 bucket management

+301 -48
+1
.gitignore
··· 3 3 /test-server.py 4 4 node_modules 5 5 .wrangler/ 6 + .altstore/ 6 7 .env 7 8 .env.* 8 9 !.env.example
+1
README.md
··· 48 48 - **Platform:** Cloudflare Pages (Astro adapter) 49 49 - **Config:** [wrangler.jsonc](wrangler.jsonc) — assets binding, ORBYT_API service 50 50 - **Site:** getorbyt.com (CNAME) 51 + - **AltStore ADP:** host in Cloudflare R2, not `public/`, because IPA files exceed Workers asset limits 51 52 52 53 ## Project Structure 53 54
+62 -40
docs/ALTSTORE_FINISH_SETUP.md
··· 2 2 3 3 Your app is approved, notarized, and AltStore PAL is configured. Complete these steps to make Orbyt available to EU and Japan users. 4 4 5 + **Prerequisites:** These instructions assume `orbyt-app` and `orbyt-site` are sibling directories (e.g. both under `orbyt-master`). Run commands from the parent directory, or adjust paths to your layout. 6 + 7 + **Cloudflare note:** Do not deploy the ADP folder from `public/`. The IPA files are larger than Cloudflare Workers static asset limits. Use R2 for the ADP payload and keep only `source.json` and the icon on the website. 8 + 5 9 --- 6 10 7 - ## Step 1: Download the ADP (if you haven’t already) 11 + ## Step 0: Enable R2 in Cloudflare 12 + 13 + If you have not used R2 before, enable it once in the Cloudflare dashboard for your account. 14 + 15 + Wrangler cannot create buckets until R2 is enabled. 16 + 17 + --- 18 + 19 + ## Step 1: Download the ADP (if you haven't already) 8 20 9 21 Your previous zip may have been corrupted. Download a fresh copy: 10 22 11 23 ```bash 12 - cd /Users/jack/orbyt-master/orbyt-app 24 + cd orbyt-app 13 25 ./scripts/altstore-pal.sh download 4792c770-f63a-47d2-bd86-bb7254e8f9bf 14 26 ``` 15 27 ··· 20 32 ## Step 2: Extract the ADP 21 33 22 34 ```bash 23 - cd /Users/jack/orbyt-master/orbyt-app 35 + cd orbyt-app 24 36 unzip orbyt-adp-4792c770-f63a-47d2-bd86-bb7254e8f9bf.zip -d adp-extracted 25 37 ``` 26 38 ··· 39 51 40 52 --- 41 53 42 - ## Step 3: Upload ADP to getorbyt.com 54 + ## Step 3: Move the ADP out of `public/` 43 55 44 - Upload the extracted ADP contents so they are served at: 56 + Keep the extracted ADP in a local staging folder inside `orbyt-site`, but outside the deployable `public/` directory: 45 57 46 - **Base URL:** `https://getorbyt.com/altstore/adp/` 58 + ```bash 59 + mkdir -p orbyt-site/.altstore 60 + rm -rf orbyt-site/.altstore/adp 61 + mv orbyt-app/adp-extracted orbyt-site/.altstore/adp 62 + ``` 47 63 48 - Options: 64 + The expected structure becomes: 49 65 50 - ### Option A: Add to orbyt-site (Cloudflare Pages) 66 + ``` 67 + orbyt-site/ 68 + .altstore/ 69 + adp/ 70 + manifest.json 71 + signature 72 + variant/ 73 + <uuid>.ipa 74 + ... 75 + ``` 51 76 52 - 1. Copy the extracted contents into `orbyt-site/public/altstore/adp/`: 53 - ```bash 54 - mkdir -p /Users/jack/orbyt-master/orbyt-site/public/altstore/adp 55 - cp -r /Users/jack/orbyt-master/orbyt-app/adp-extracted/* /Users/jack/orbyt-master/orbyt-site/public/altstore/adp/ 56 - ``` 77 + --- 57 78 58 - 2. Deploy orbyt-site. 79 + ## Step 4: Upload ADP to Cloudflare R2 59 80 60 - 3. Verify `manifest.json` is reachable at: 61 - https://getorbyt.com/altstore/adp/manifest.json 81 + From `orbyt-site`, run: 62 82 63 - ### Option B: Use a CDN or object storage 83 + ```bash 84 + npm run altstore:r2 -- setup orbyt-altstore-adp 85 + ``` 86 + 87 + This script will: 64 88 65 - Upload the ADP directory to S3, R2, Backblaze B2, etc., and serve it under a path like `https://getorbyt.com/altstore/adp/` (via a redirect or proxy if needed). 89 + 1. create the R2 bucket if needed 90 + 2. enable the public `r2.dev` URL 91 + 3. upload `manifest.json`, `signature`, and `variant/*.ipa` 92 + 4. update `public/altstore/source.json` so `downloadURL` points to the hosted `manifest.json` 93 + 94 + If you want to use a different bucket name, replace `orbyt-altstore-adp` with your preferred name. 66 95 67 96 --- 68 97 69 - ## Step 4: Add app icon for AltStore 98 + ## Step 5: Add app icon for AltStore 70 99 71 100 Copy the 1024×1024 app icon to the AltStore folder: 72 101 73 102 ```bash 74 - cp /Users/jack/orbyt-master/orbyt-app/src/assets/AppIcons/iOS/orbyt.png \ 75 - /Users/jack/orbyt-master/orbyt-site/public/altstore/orbyt-icon.png 103 + cp orbyt-app/src/assets/AppIcons/iOS/orbyt.png \ 104 + orbyt-site/public/altstore/orbyt-icon.png 76 105 ``` 77 106 78 107 --- 79 108 80 - ## Step 5: Update and host the source JSON 109 + ## Step 6: Deploy and verify the source JSON 81 110 82 - 1. Edit `orbyt-app/altstore-pal-source.json`: 111 + 1. Deploy `orbyt-site`. 83 112 84 - - Confirm `downloadURL` is `https://getorbyt.com/altstore/adp/` (or the URL to `manifest.json`). 85 - - Set `size` from the IPA size in bytes (e.g. from `variants/*.ipa`). 86 - - Confirm `marketplaceID` is your app’s Apple ID from App Store Connect → App Information. 113 + 2. Verify the site source URL: 87 114 88 - 2. Copy the source to the site: 115 + https://getorbyt.com/altstore/source.json 89 116 90 - ```bash 91 - cp /Users/jack/orbyt-master/orbyt-app/altstore-pal-source.json \ 92 - /Users/jack/orbyt-master/orbyt-site/public/altstore/source.json 93 - ``` 94 - 95 - 3. Deploy and verify: 96 - 97 - https://getorbyt.com/altstore/source.json 117 + 3. Verify the ADP manifest URL stored inside `source.json` returns `200`. 98 118 99 119 --- 100 120 101 - ## Step 6: Federate (make it discoverable) 121 + ## Step 7: Federate (make it discoverable) 102 122 103 123 Once the source URL works, federate it so it appears on [explore.alt.store](https://explore.alt.store): 104 124 ··· 114 134 115 135 | Step | Action | 116 136 |------|--------| 137 + | 0 | Enable R2 in Cloudflare once | 117 138 | 1 | Download ADP with the script | 118 139 | 2 | Extract the zip (do not modify contents) | 119 - | 3 | Upload ADP to `https://getorbyt.com/altstore/adp/` | 120 - | 4 | Add `orbyt-icon.png` to `public/altstore/` | 121 - | 5 | Copy and host `altstore-pal-source.json` as `source.json` | 122 - | 6 | Federate via the API | 140 + | 3 | Move the extracted ADP into `.altstore/adp/` | 141 + | 4 | Run `npm run altstore:r2 -- setup <bucket>` | 142 + | 5 | Add `orbyt-icon.png` to `public/altstore/` | 143 + | 6 | Deploy the site and verify `source.json` | 144 + | 7 | Federate via the API | 123 145 124 146 After this, EU and Japan users can add `https://getorbyt.com/altstore/source.json` in AltStore PAL and install Orbyt.
+2 -1
package.json
··· 9 9 "build": "astro build", 10 10 "check": "astro check", 11 11 "preview": "astro preview", 12 - "astro": "astro" 12 + "astro": "astro", 13 + "altstore:r2": "bash ./scripts/altstore-r2.sh" 13 14 }, 14 15 "repository": { 15 16 "type": "git",
+4 -2
public/altstore/README.md
··· 1 1 # AltStore PAL assets 2 2 3 3 - `orbyt-icon.png` — App icon (1024×1024), already added 4 - - `adp/` — Put extracted ADP contents here (manifest.json, signature, variants/) 5 - - `source.json` — Copy from orbyt-app/altstore-pal-source.json after updating 4 + - `source.json` — Hosted from this site 5 + - `.altstore/adp/` — Keep extracted ADP contents here locally, then upload them to R2 6 + 7 + Do not keep the ADP payload in `public/` when deploying to Cloudflare. The IPA files exceed the Workers static asset limit. 6 8 7 9 See docs/ALTSTORE_FINISH_SETUP.md for full instructions.
-1
public/altstore/adp/manifest.json
··· 1 - {"manifestSchemaVersion":"1.0","distributionPackageRevision":1,"appleItemId":"6751679299","bundleId":"com.getorbyt.app","shortVersionString":"1.1.2","bundleVersion":"62","appleVersionId":"877666242","platforms":["ios"],"minimumSystemVersions":{"ios":"16.4"},"requiredDeviceCapabilities":["arm64"],"appInstallDeterminants":[],"hasMessagesExtension":false,"isLaunchProhibited":false,"variants":[{"publicId":"4627ec0d-5f76-3dd3-840e-b4bb4f7e757a","assetPath":"variant/4627ec0d-5f76-3dd3-840e-b4bb4f7e757a.ipa","installTargets":[{"device":"iPad14,2","os":"17.4"},{"device":"iPad14,6-A","os":"17"},{"device":"iPad13,6","os":"17"},{"device":"iPad13,5","os":"17.4"},{"device":"iPad14,3-B","os":"17"},{"device":"iPad11,3","os":"17.4"},{"device":"iPad11,4","os":"17"},{"device":"iPad14,5-B","os":"17.4"},{"device":"iPad13,10","os":"17.4"},{"device":"iPad16,3-A","os":"17.4"},{"device":"iPad8,3","os":"17"},{"device":"iPad8,2","os":"17.4"},{"device":"iPad8,12","os":"17.4"},{"device":"iPad14,9","os":"17.4"},{"device":"iPad14,3-A","os":"17.4"},{"device":"iPad14,1","os":"17.4"},{"device":"iPad14,3-A","os":"17"},{"device":"iPad13,7","os":"17"},{"device":"iPad13,4","os":"17.4"},{"device":"iPad11,2","os":"17.4"},{"device":"iPad8,12","os":"17"},{"device":"iPad13,11","os":"17.4"},{"device":"iPad16,5-B","os":"17.4"},{"device":"iPad8,2","os":"17"},{"device":"iPad8,3","os":"17.4"},{"device":"iPad8,9","os":"17"},{"device":"iPad13,7","os":"17.4"},{"device":"iPad14,3-B","os":"17.4"},{"device":"iPad14,5-B","os":"17"},{"device":"iPad13,10","os":"17"},{"device":"iPad14,6-A","os":"17.4"},{"device":"iPad8,4","os":"17.4"},{"device":"iPad8,11","os":"17"},{"device":"iPad13,16","os":"17.4"},{"device":"iPad13,8","os":"17"},{"device":"iPad16,5-A","os":"17.4"},{"device":"iPad8,1","os":"17"},{"device":"iPad7,4","os":"17"},{"device":"iPad8,8","os":"17"},{"device":"iPad13,11","os":"17"},{"device":"iPad13,6","os":"17.4"},{"device":"iPad11,4","os":"17.4"},{"device":"iPad14,5-A","os":"17"},{"device":"iPad14,6-B","os":"17.4"},{"device":"iPad13,1","os":"17"},{"device":"iPad8,10","os":"17"},{"device":"iPad8,5","os":"17.4"},{"device":"iPad13,9","os":"17"},{"device":"iPad13,17","os":"17.4"},{"device":"iPad7,3","os":"17"},{"device":"iPad8,7","os":"17"},{"device":"iPad13,16","os":"17"},{"device":"iPad13,9","os":"17.4"},{"device":"iPad14,11","os":"17.4"},{"device":"iPad14,4-A","os":"17.4"},{"device":"iPad13,2","os":"17"},{"device":"iPad13,1","os":"17.4"},{"device":"iPad8,6","os":"17.4"},{"device":"iPad16,4-B","os":"17.4"},{"device":"iPad7,2","os":"17"},{"device":"iPad7,1","os":"17.4"},{"device":"iPad8,6","os":"17"},{"device":"iPad11,1","os":"17"},{"device":"iPad13,17","os":"17"},{"device":"iPad14,10","os":"17.4"},{"device":"iPad13,8","os":"17.4"},{"device":"iPad14,4-B","os":"17"},{"device":"iPad14,4-B","os":"17.4"},{"device":"iPad8,7","os":"17.4"},{"device":"iPad16,4-A","os":"17.4"},{"device":"iPad7,1","os":"17"},{"device":"iPad7,2","os":"17.4"},{"device":"iPad8,10","os":"17.4"},{"device":"iPad14,8","os":"17.4"},{"device":"iPad13,4","os":"17"},{"device":"iPad14,4-A","os":"17"},{"device":"iPad11,2","os":"17"},{"device":"iPad14,1","os":"17"},{"device":"iPad11,1","os":"17.4"},{"device":"iPad8,8","os":"17.4"},{"device":"iPad7,3","os":"17.4"},{"device":"iPad8,5","os":"17"},{"device":"iPad16,6-B","os":"17.4"},{"device":"iPad13,5","os":"17"},{"device":"iPad13,2","os":"17.4"},{"device":"iPad11,3","os":"17"},{"device":"iPad14,6-B","os":"17"},{"device":"iPad14,5-A","os":"17.4"},{"device":"iPad14,2","os":"17"},{"device":"iPad8,9","os":"17.4"},{"device":"iPad16,3-B","os":"17.4"},{"device":"iPad16,6-A","os":"17.4"},{"device":"iPad8,1","os":"17.4"},{"device":"iPad7,4","os":"17.4"},{"device":"iPad8,4","os":"17"},{"device":"iPad8,11","os":"17.4"}],"variantDetails":{"compressedSize":70295316,"uncompressedSize":111373312,"hashes":[{"algorithm":"sha256","chunkSize":10485760,"encryptedChunkDigests":["5e81a95e17906fff77bae515e66e9071fab98cb59d2a75727f0a8ebe0262ae66","6472d323e19767b1d272c4f8ce4604f081ccd4830d5673a82655b76244769b55","5070b16ed6eeb0a3b29787437126987f90bba772bb9a1d5e35019da12da7d238","fc355fac746c80010db10feac3f7d2cb33ec64e9c9188e20eff8a1e3bdf1d5a7","def39350aed1269c55215b602ae60bb4298307d3c16f25334ecf4c009184c70a","01c43fca259579868a366c09217f11306c2a935b0037ef1ef6d35c74c4fa242b","4c3b9744df858241c3fb0b5b598d2667e1d4a67284483ea5c071bf7fe037e910"],"unencryptedChunkDigests":["00cb2dbb6040be82eb138f9f0a8aac83b030cfd9091857b2ece7bca641ed7021","1c1f4e29d2a5f5b863e655206ce141f58106c49b2be83488b10a43af9945791b","cfad7db3501402a590c3127d3dcab17702fa3a7f9652ea70fa5f6a6736390178","a9732936f15285fc5e7a5fb92c3d8773af64b373e7dd7686dc6fd11827522a75","f3cf1f9f354e12e3c34afa28af15f58cb78600592c16d4eeb71f718d11cc5ace","1983a88c3bb8afe7056e59ef2673a580f0fe7d70a095758f090ce93d8421ead7","3069e3337282f8704be7e7884f8b8f3e080cdb914fe033630aefe824a5df07c9"]}]}},{"publicId":"f12a1b12-3c3d-3a67-ae2e-4caefdd98320","assetPath":"variant/f12a1b12-3c3d-3a67-ae2e-4caefdd98320.ipa","installTargets":[{"device":"iPhone18,2","os":"26"},{"device":"iPhone17,5","os":"26"},{"device":"iPhone14,7","os":"18"},{"device":"iPhone17,2","os":"18"},{"device":"iPhone15,4","os":"18"},{"device":"iPhone14,2","os":"26"},{"device":"iPhone17,1","os":"26"},{"device":"iPhone15,3","os":"26"},{"device":"iPhone13,1","os":"26"},{"device":"iPhone12,5","os":"18"},{"device":"iPhone14,3","os":"18"},{"device":"iPhone13,2","os":"18"},{"device":"iPhone11,4","os":"18"},{"device":"iPhone16,1","os":"18"},{"device":"iPhone18,3","os":"26"},{"device":"iPhone14,7","os":"26"},{"device":"iPhone16,1","os":"26"},{"device":"iPhone15,5","os":"18"},{"device":"iPhone17,3","os":"18"},{"device":"iPhone14,8","os":"18"},{"device":"iPhone15,4","os":"26"},{"device":"iPhone17,2","os":"26"},{"device":"iPhone14,3","os":"26"},{"device":"iPhone12,5","os":"26"},{"device":"iPhone14,4","os":"18"},{"device":"iPhone13,2","os":"26"},{"device":"iPhone16,2","os":"18"},{"device":"iPhone13,3","os":"18"},{"device":"iPhone17,3","os":"26"},{"device":"iPhone14,8","os":"26"},{"device":"iPhone15,5","os":"26"},{"device":"iPhone18,4","os":"26"},{"device":"iPhone14,4","os":"26"},{"device":"iPhone13,3","os":"26"},{"device":"iPhone14,5","os":"18"},{"device":"iPhone17,4","os":"18"},{"device":"iPhone16,2","os":"26"},{"device":"iPhone13,4","os":"18"},{"device":"iPhone11,6","os":"18"},{"device":"iPhone12,3","os":"18"},{"device":"iPhone15,2","os":"18"},{"device":"iPhone11,2","os":"18"},{"device":"iPhone17,4","os":"26"},{"device":"iPhone18,5","os":"26"},{"device":"iPhone15,2","os":"26"},{"device":"iPhone14,5","os":"26"},{"device":"iPhone17,5","os":"18"},{"device":"iPhone18,1","os":"26"},{"device":"iPhone13,4","os":"26"},{"device":"iPhone12,3","os":"26"},{"device":"iPhone15,3","os":"18"},{"device":"iPhone17,1","os":"18"},{"device":"iPhone14,2","os":"18"},{"device":"iPhone13,1","os":"18"}],"variantDetails":{"compressedSize":70307293,"uncompressedSize":111385600,"hashes":[{"algorithm":"sha256","chunkSize":10485760,"encryptedChunkDigests":["f5c6820b0e4069961b7c18e337d5773f0cbfd82c32d86719b786bffb343491fd","817e4ee10224d6ca6bf72afbe12e9556b1e98258bb186fa5eb9424e445957231","4dd5b08797dbef0c014ebcf16c7c8c67eec8b3115204b091269f220a80b2be10","65d900e5f299edb7f96f5c44851efcc321cacc9ce691cfce599b813e4e25bc7e","ef94345d7d7c8f49843325b1cbed856ee16ccce35bea8c413dc7822b64c54be7","04841e4561eb00f61d9c1826a521ac6db2071e1d4b7df76483b929ebfb8b7192","fb12e6d198b74716369df4922c5e2c34480f302db59b1874472159bf416740c3"],"unencryptedChunkDigests":["a202ebf58684e01ab8825eb06577a903a7fe521aa0fc0830c357791148bb2a70","20d1cbb886876d36e4e6a1abb9cf6fe98775a61b071b17728d8d6eacf1a440aa","d11722fb160ee0151a6f06009dd5a88e4dfd91fccc3dfb4f25d9e2d848cdc58c","adc48ebac01d5545dcd0cf56d1872372ed0ad6e45663e1c76e99e69a0abd5dda","5ee03efb8f519fc9dd0517fdb9a3db72855d4ba04f73de18475396a66abe4dbf","2878c7716accd9de48ffd972fa0da4feb8a6233da2c29826684294fd47061f05","9c3c3b04c49efb4fd9b42eb90355957385c734046df0508c8045a08fd8ef391a"]}]}},{"publicId":"b2e13f32-c30e-3568-9344-0683ffc3c3c2","assetPath":"variant/b2e13f32-c30e-3568-9344-0683ffc3c3c2.ipa","installTargets":[{"device":"iPhone12,8","os":"26"},{"device":"iPhone14,6","os":"26"},{"device":"iPhone14,6","os":"18"},{"device":"iPhone11,8","os":"18"},{"device":"iPhone12,8","os":"18"},{"device":"iPhone12,1","os":"26"},{"device":"iPhone12,1","os":"18"}],"variantDetails":{"compressedSize":70295251,"uncompressedSize":111373312,"hashes":[{"algorithm":"sha256","chunkSize":10485760,"encryptedChunkDigests":["0eb547dc0852f0cab384183acfb22c1c982b9d659c05b42f1b4027c08d0d14d1","e90a73d2d72ac0ef86debd992045da637303ba7c70a8f12a3c59ade504de3378","a781b4973546a96d462e84c00d897c58aa619370038e30b540717bf1d8dc1942","642ecc23b471cd236a23c46869e697efdf7269714f88cc60e7efd71dc60287e1","549451e6a6a0168b9a0c094288064c026d91405024818ad28ea887746af6e88b","85230abfc2d0b45806a1eea8f69e8a3cbd193b02710b6e1dd01b00ce0c6c1cb1","b683415ac620cec10faa5cf8de16125d8dbb2297cc2c14e347b5d75e9dfe403a"],"unencryptedChunkDigests":["a727b1500feabe8fcaab4bf211bf3d4cda5152a773c00a5a92655a54bbfcd501","dd9e5a33e9cd2df45293d2d1ee26d76fe0c9c770e048f5056ede761e518dd82a","82ad47763f21f5216c6a040ea636ae3287f5c75bf0b8c58d3dadc5b26e399072","a637ba996b2eaa92f59c7cac1d7174e9766388fa3b2c060db10caffdaa629777","cba1d3ee50f25c590b26253b41df6c92337a78e22dec1d22922a22ee1c31ad31","d65e35ff2cbd555edd9507490312f4758b782504a62cd0daad8edcad33cfd915","b37ba1221b2fbdb793522e8b82c4aa2c53607f304146a740eb0ded61f5c92ac6"]}]}},{"publicId":"bb597cde-2ec7-3daa-b416-a802df1bab6a","assetPath":"variant/bb597cde-2ec7-3daa-b416-a802df1bab6a.ipa","installTargets":[{"device":"iPhone14,6","os":"17.4"},{"device":"iPhone12,8","os":"17.4"},{"device":"iPhone11,8","os":"17.4"},{"device":"iPhone14,6","os":"17"},{"device":"iPhone12,8","os":"17"},{"device":"iPhone11,8","os":"17"},{"device":"iPhone12,1","os":"17.4"},{"device":"iPhone12,1","os":"17"}],"variantDetails":{"compressedSize":70295158,"uncompressedSize":111373312,"hashes":[{"algorithm":"sha256","chunkSize":10485760,"encryptedChunkDigests":["966bd689867adc33b3c88092f515f0f466632f0f8fbe3e64905005b0921012f5","bd1a1adb2bd18cf580007560c3205dc315619ca9d69403d577a164275e245e2b","fcd5c09d7ec413ed0d66ba09bae2e024c57e4c9e0a1ba68d88618de31e287152","9f1646bc4ffe109f6f2fe9ccc8b8c6bd3e8df5e9aeb4dd47c7f049e93c625408","3fa27a3802b6a2d7a92188d4abb167883abad28ac0570473967cd7672e96ba7f","1ad5e37db745cd199128d4ae4cd78c6e709a73f2856e2098e7751c198f7e05c5","2293c6e4c51cd8f7a179153f1ac605bb1e3757887e8dcd191ab9e0cbc288ad48"],"unencryptedChunkDigests":["7a2d23d1fc80a7d222e400c169c16d517f209b654bafecdc304bea7f1d9f4acc","b7548d9cd9f2a56df74bbab0520a022145cab1de5d3eeb3d1447e2c48d59340b","acb0a235af0b0f6004cf6633bafb13b81d63a408a488e6976912cec3f761509b","0efe90a39611b0c7b640976d9ab53e0685e690d11cdc1a441c90b09414f76ba3","aafebc9fbf23c94c2a9c2652dfac89baa96c28451580978083eaa4d8b597aa89","c31281d32f74d798d46b7ba4574a20fb02fb30de8840f79ca8612202b8133d3d","559b7e46b56d9a9cb65fa1b0a87d2448833a51e1df96f6297f79bfc0a1c98f90"]}]}},{"publicId":"c677be0c-e3ed-3079-958f-c13c627afb6e","assetPath":"variant/c677be0c-e3ed-3079-958f-c13c627afb6e.ipa","installTargets":[{"device":"iPhone14,5","os":"17.4"},{"device":"iPhone13,4","os":"17.4"},{"device":"iPhone15,2","os":"17.4"},{"device":"iPhone11,6","os":"17.4"},{"device":"iPhone15,4","os":"17"},{"device":"iPhone14,7","os":"17"},{"device":"iPhone14,3","os":"17"},{"device":"iPhone12,5","os":"17"},{"device":"iPhone11,4","os":"17"},{"device":"iPhone16,1","os":"17"},{"device":"iPhone13,2","os":"17"},{"device":"iPhone15,3","os":"17.4"},{"device":"iPhone14,2","os":"17.4"},{"device":"iPhone14,8","os":"17"},{"device":"iPhone16,2","os":"17"},{"device":"iPhone11,2","os":"17.4"},{"device":"iPhone14,4","os":"17"},{"device":"iPhone15,5","os":"17"},{"device":"iPhone13,3","os":"17"},{"device":"iPhone12,3","os":"17.4"},{"device":"iPhone14,7","os":"17.4"},{"device":"iPhone15,4","os":"17.4"},{"device":"iPhone12,5","os":"17.4"},{"device":"iPhone16,1","os":"17.4"},{"device":"iPhone14,3","os":"17.4"},{"device":"iPhone14,5","os":"17"},{"device":"iPhone11,6","os":"17"},{"device":"iPhone13,4","os":"17"},{"device":"iPhone13,1","os":"17.4"},{"device":"iPhone15,2","os":"17"},{"device":"iPhone12,3","os":"17"},{"device":"iPhone11,2","os":"17"},{"device":"iPhone14,8","os":"17.4"},{"device":"iPhone15,5","os":"17.4"},{"device":"iPhone16,2","os":"17.4"},{"device":"iPhone14,4","os":"17.4"},{"device":"iPhone13,3","os":"17.4"},{"device":"iPhone15,3","os":"17"},{"device":"iPhone11,4","os":"17.4"},{"device":"iPhone14,2","os":"17"},{"device":"iPhone13,2","os":"17.4"},{"device":"iPhone13,1","os":"17"}],"variantDetails":{"compressedSize":70307231,"uncompressedSize":111385600,"hashes":[{"algorithm":"sha256","chunkSize":10485760,"encryptedChunkDigests":["02c9321b790f96da447f506de0e496b96e70c8759c0b0ec334ed46425005914f","cca3444dbd75b9d5d2c9dd3cdd15c0361d42db94594a71dbba780e839b11ee84","99d49fa558cd56a0176123c87d8693b44e9fea21c4d37bee197b116cdb70bf58","84259089575ea178140557be5e188ac18789798e97648511f51fa7d191e8e043","a084d9e0701d2f5a553ff8aeda6ef50929420c90658aa9b9c8cf3e92976ea66c","bc6bced37d8ccb3c8f3b6552dcaf63ca3b46a052030b067972e50d456433b16f","7d2493782d2e6129055604ff7b833ca0634bf424e1d2f34c33a2f3e8f75593e0"],"unencryptedChunkDigests":["b44077d6a4843ab855b96ccd04a94561866ad76815f39b6dd71ae93ead32a6bb","2db67c5ba46d3c2f446b365cf89ce9136b6e5e6b3aad732c789b56f01dbc94ae","20e00de8408ff5e6b6ec932c9307bdb11e0d70bab5fbfc8f9a2c0b85f793800d","09ff47d7d22e7bf9fec4111ea34591159e416ee42e57028a43cd4d2918136c6a","f480f4905fd02c5371a1a729544c76d314e2b160b227ceb9293e413bdb5e67f4","e6a90ab70867cf2cae7f448d6472edc36e53cd3c5264c883de3b6872016dc184","cb02f6c529f2ebb391a9af270c3bad475cee3ced1cd3245b4d0324647c0536b0"]}]}},{"publicId":"8d49ebe9-f617-3ac2-9a69-164708f238dc","assetPath":"variant/8d49ebe9-f617-3ac2-9a69-164708f238dc.ipa","installTargets":[{"device":"iPad13,11","os":"26"},{"device":"iPad16,3-B","os":"26"},{"device":"iPad14,3-A","os":"26"},{"device":"iPad14,2","os":"26"},{"device":"iPad13,6","os":"18"},{"device":"iPad14,3-B","os":"18"},{"device":"iPad13,5","os":"26"},{"device":"iPad14,6-A","os":"18"},{"device":"iPad11,4","os":"18"},{"device":"iPad11,3","os":"26"},{"device":"iPad17,1-A","os":"26"},{"device":"iPad14,3-A","os":"18"},{"device":"iPad16,6-B","os":"26"},{"device":"iPad8,12","os":"26"},{"device":"iPad8,3","os":"18"},{"device":"iPad8,2","os":"26"},{"device":"iPad16,4-A","os":"18"},{"device":"iPad8,9","os":"26"},{"device":"iPad17,1-B","os":"26"},{"device":"iPad11,4","os":"26"},{"device":"iPad13,7","os":"18"},{"device":"iPad14,5-B","os":"26"},{"device":"iPad17,4-A","os":"26"},{"device":"iPad8,12","os":"18"},{"device":"iPad13,6","os":"26"},{"device":"iPad16,6-A","os":"26"},{"device":"iPad16,6-B","os":"18"},{"device":"iPad8,2","os":"18"},{"device":"iPad8,11","os":"26"},{"device":"iPad8,1","os":"26"},{"device":"iPad16,3-A","os":"18"},{"device":"iPad8,9","os":"18"},{"device":"iPad8,8","os":"26"},{"device":"iPad13,8","os":"18"},{"device":"iPad14,5-B","os":"18"},{"device":"iPad17,4-B","os":"26"},{"device":"iPad14,5-A","os":"26"},{"device":"iPad13,10","os":"18"},{"device":"iPad8,11","os":"18"},{"device":"iPad8,10","os":"26"},{"device":"iPad13,7","os":"26"},{"device":"iPad8,1","os":"18"},{"device":"iPad16,6-A","os":"18"},{"device":"iPad8,8","os":"18"},{"device":"iPad13,10","os":"26"},{"device":"iPad16,3-B","os":"18"},{"device":"iPad8,7","os":"26"},{"device":"iPad16,3-A","os":"26"},{"device":"iPad15,3","os":"18"},{"device":"iPad17,2-A","os":"26"},{"device":"iPad14,5-A","os":"18"},{"device":"iPad13,1","os":"18"},{"device":"iPad13,11","os":"18"},{"device":"iPad8,10","os":"18"},{"device":"iPad13,9","os":"18"},{"device":"iPad13,8","os":"26"},{"device":"iPad16,5-B","os":"26"},{"device":"iPad8,7","os":"18"},{"device":"iPad8,6","os":"26"},{"device":"iPad13,16","os":"18"},{"device":"iPad16,1","os":"18"},{"device":"iPad15,4","os":"18"},{"device":"iPad17,2-B","os":"26"},{"device":"iPad15,3","os":"26"},{"device":"iPad13,2","os":"18"},{"device":"iPad14,4-B","os":"26"},{"device":"iPad13,1","os":"26"},{"device":"iPad14,11","os":"26"},{"device":"iPad16,8","os":"26"},{"device":"iPad13,9","os":"26"},{"device":"iPad16,5-A","os":"26"},{"device":"iPad16,5-B","os":"18"},{"device":"iPad8,5","os":"26"},{"device":"iPad11,1","os":"18"},{"device":"iPad13,16","os":"26"},{"device":"iPad16,11","os":"26"},{"device":"iPad13,17","os":"18"},{"device":"iPad14,4-B","os":"18"},{"device":"iPad13,2","os":"26"},{"device":"iPad14,4-A","os":"26"},{"device":"iPad15,5","os":"18"},{"device":"iPad16,1","os":"26"},{"device":"iPad16,2","os":"18"},{"device":"iPad14,8","os":"18"},{"device":"iPad15,4","os":"26"},{"device":"iPad16,9","os":"26"},{"device":"iPad13,17","os":"26"},{"device":"iPad16,5-A","os":"18"},{"device":"iPad8,6","os":"18"},{"device":"iPad8,4","os":"26"},{"device":"iPad11,2","os":"18"},{"device":"iPad16,4-B","os":"18"},{"device":"iPad16,4-A","os":"26"},{"device":"iPad16,10","os":"26"},{"device":"iPad14,4-A","os":"18"},{"device":"iPad15,6","os":"18"},{"device":"iPad11,1","os":"26"},{"device":"iPad16,2","os":"26"},{"device":"iPad14,1","os":"18"},{"device":"iPad17,3-A","os":"26"},{"device":"iPad14,6-B","os":"26"},{"device":"iPad13,4","os":"18"},{"device":"iPad15,5","os":"26"},{"device":"iPad14,9","os":"18"},{"device":"iPad14,8","os":"26"},{"device":"iPad14,10","os":"18"},{"device":"iPad8,5","os":"18"},{"device":"iPad16,4-B","os":"26"},{"device":"iPad13,5","os":"18"},{"device":"iPad14,1","os":"26"},{"device":"iPad14,3-B","os":"26"},{"device":"iPad13,4","os":"26"},{"device":"iPad14,6-B","os":"18"},{"device":"iPad14,6-A","os":"26"},{"device":"iPad11,3","os":"18"},{"device":"iPad17,3-B","os":"26"},{"device":"iPad14,2","os":"18"},{"device":"iPad11,2","os":"26"},{"device":"iPad14,9","os":"26"},{"device":"iPad14,10","os":"26"},{"device":"iPad15,6","os":"26"},{"device":"iPad14,11","os":"18"},{"device":"iPad8,4","os":"18"},{"device":"iPad8,3","os":"26"}],"variantDetails":{"compressedSize":70295307,"uncompressedSize":111373312,"hashes":[{"algorithm":"sha256","chunkSize":10485760,"encryptedChunkDigests":["334d58f907952e1588c10f4687500b508ebf252e060109284be0ab801a8d53d6","3e45cb41217d2a3fa1190589d12b85053d6323707201fd1a076cff969ec2ffc7","9079d31a24ebc3a41e7a92787af3ab2eade01408b66e04f2192156bd3103c278","cb663659e282ddc3da4652388c24779786dfa2fbd6df9fbd6afac33abb662b5f","fd112b9a98be8727c8b95dd2783145885453ef037bbe83d391759d6f5d305484","fa8a83a8b4716144411e6e56c784a03f9ef788f59241093f3f9827c078437293","d511e6fda27509c08189ef47ef02a8f63fd852b6fd422b5ecc037baf2041a50a"],"unencryptedChunkDigests":["93fac06d90d3267ba7cdaff2037eb98b26ce1a4238f0c2337957f6210887a362","6ccd66af737064abc41f7f38e7c807a1c1b6d5004d7c96204944509ef71608be","8fd66cbec759ca35e126bad9e6d5cb9add2569201e0f81c283dcd21f1468ab8c","ac1df3e0deaec8b80aafbfee82a3899ac77fb7efd1cc1f5a99ec0ba301961f04","5f13a6c0c86dd558e9a6d8e5bbbb9667c3b132c4c4a505873e12423b49e05e83","1e92a988cf63bcb6bbf6ee9573b975922195a7ffc9a087b666d6ec25fef1b798","8c9aea13b62c60dbbfe6c29e131e795e3d17e961d480bdf4d061e78c26af2984"]}]}},{"publicId":"efcc6ae6-7a15-368a-9472-e819e067efba","assetPath":"variant/efcc6ae6-7a15-368a-9472-e819e067efba.ipa","installTargets":[{"device":"iPad13,18","os":"17"},{"device":"iPad7,11","os":"17"},{"device":"iPad11,6","os":"17"},{"device":"iPad11,7","os":"17.4"},{"device":"iPad12,1","os":"17"},{"device":"iPad12,2","os":"17.4"},{"device":"iPad7,12","os":"17.4"},{"device":"iPad7,5","os":"17.4"},{"device":"iPad13,19","os":"17"},{"device":"iPad13,18","os":"17.4"},{"device":"iPad7,6","os":"17"},{"device":"iPad11,7","os":"17"},{"device":"iPad11,6","os":"17.4"},{"device":"iPad7,12","os":"17"},{"device":"iPad12,2","os":"17"},{"device":"iPad12,1","os":"17.4"},{"device":"iPad7,11","os":"17.4"},{"device":"iPad7,6","os":"17.4"},{"device":"iPad13,19","os":"17.4"},{"device":"iPad7,5","os":"17"}],"variantDetails":{"compressedSize":70091552,"uncompressedSize":111168512,"hashes":[{"algorithm":"sha256","chunkSize":10485760,"encryptedChunkDigests":["921ce5e7709e2055085708acaee407b30a3d314fdf74a2c47dca96c2f2cdcfdb","1f4236f6b7dba8913774c85ea76ddf9491288c684b42fd1acf74afb6022dc7e2","a75c73d66c43b03c991df7efb5c49fb8d183f142494d7d9c2f7a6c7d47a3d5d3","218f0855825200438c41e79708ecc56de59d73937ed0856156b5d1df8356a7d3","b46235e94248fd43d96be28faef46b20b36ce64177f604e39e17c741f689f5ff","1262c2681f6f289af43772f9eed562bdb2fdc62572fbff15eb3133e7507c519b","c45a477a259bf20bb82d0a86757ee30d1f94d589ebfe1f49a961f35762ca7c11"],"unencryptedChunkDigests":["dab81fd925cc50cd578431d5330f6e7926f1ac884fb566ad6bab7b5f4d003494","6f03bdbded21362b9918815ec810f7306331b5749848f5271122f3a959e4d24b","3ccbb1494e635a33c52dd053a24d9869c19dc0f65fe9178480945e58cac69f2e","c4e2aa7c8e3cff946430aa558dad5dec311a493d5835c6dc2cc95feb2de5e548","b43094b40124dd588b811f60fa29565b6ad9001643f583f2467fd29798d4daec","f36225d80a775af537fecdef09b690809f831bd4586f11f88f2f544cb07b9beb","8d70a3dd0c586151f7e382618742d18d38568bf3da8347dd53d1b8f92d660834"]}]}},{"publicId":"7d5f0354-8e78-3453-893c-41ca830f64a0","assetPath":"variant/7d5f0354-8e78-3453-893c-41ca830f64a0.ipa","installTargets":[{"device":"iPad12,1","os":"18"},{"device":"iPad7,12","os":"18"},{"device":"iPad13,19","os":"18"},{"device":"iPad7,11","os":"18"},{"device":"iPad13,18","os":"18"},{"device":"iPad11,7","os":"18"},{"device":"iPad12,2","os":"18"},{"device":"iPad11,6","os":"18"},{"device":"iPad12,2","os":"26"},{"device":"iPad12,1","os":"26"},{"device":"iPad15,8","os":"26"},{"device":"iPad15,7","os":"18"},{"device":"iPad15,8","os":"18"},{"device":"iPad15,7","os":"26"},{"device":"iPad13,19","os":"26"},{"device":"iPad13,18","os":"26"}],"variantDetails":{"compressedSize":70091564,"uncompressedSize":111168512,"hashes":[{"algorithm":"sha256","chunkSize":10485760,"encryptedChunkDigests":["b34bb51028cdad1bba55591bdcdbd8d30f54c43f52dc6f9acb1256845e8f33ec","8cefac775e9506f785b2206ca405c8d03663613c395b82a8b406188bd86f9203","071d346c8540cd5bda67ff037b8aafc934abbb080908c69f6e4e72461260827f","d1023b01580570d470e0902fb019aa4a0ee15b479f3875a57fe91cb5c22bb0f7","b7bd547c723c16eeb4e0ce8da2ced434c026e2086bf328fb672091cacb69c281","d20eb7248f5871e8c19c9794999e65dd81fc3eabbaa5f9adb1f938b349482e96","b5ccc9848fcaf666bf39f20d2b17c569c87c2e2f66313c08164a3109b293fae9"],"unencryptedChunkDigests":["525680e7dc706750e35db5f1732d6db0ecdff7573e9f37e888ef6f7124460378","0ffad02258f937c661fa44579980d1506a15832e2072179149b0040f984874ad","60f540c815d03715813936a40fb359061c80e2d628d14313389913a3ca3f2a71","806bbef4a29c55532cd66c699454fde299fbe3c3bd1cbd8ece41813cd9754f0c","fd225b4cd37947d017704e4b114be4372b52fc21c2237485dc18b7d31ebb49ff","73c52b17ea9c3a63a411d8aa337a54e8f7b4da748743ed5f06242239ea10a405","7adc6f43b2378941762d5a5767bcc7a7b271c5f3b56e35a549304dbbbb61a817"]}]}}],"deltas":[]}
public/altstore/adp/signature

This is a binary file and will not be displayed.

public/altstore/adp/variant/4627ec0d-5f76-3dd3-840e-b4bb4f7e757a.ipa

This is a binary file and will not be displayed.

public/altstore/adp/variant/7d5f0354-8e78-3453-893c-41ca830f64a0.ipa

This is a binary file and will not be displayed.

public/altstore/adp/variant/8d49ebe9-f617-3ac2-9a69-164708f238dc.ipa

This is a binary file and will not be displayed.

public/altstore/adp/variant/b2e13f32-c30e-3568-9344-0683ffc3c3c2.ipa

This is a binary file and will not be displayed.

public/altstore/adp/variant/bb597cde-2ec7-3daa-b416-a802df1bab6a.ipa

This is a binary file and will not be displayed.

public/altstore/adp/variant/c677be0c-e3ed-3079-958f-c13c627afb6e.ipa

This is a binary file and will not be displayed.

public/altstore/adp/variant/efcc6ae6-7a15-368a-9472-e819e067efba.ipa

This is a binary file and will not be displayed.

public/altstore/adp/variant/f12a1b12-3c3d-3a67-ae2e-4caefdd98320.ipa

This is a binary file and will not be displayed.

+4 -2
public/altstore/source.json
··· 7 7 "website": "https://getorbyt.com", 8 8 "tintColor": "#9B59B6", 9 9 "fediUsername": "orbyt", 10 - "featuredApps": ["com.getorbyt.app"], 10 + "featuredApps": [ 11 + "com.getorbyt.app" 12 + ], 11 13 "apps": [ 12 14 { 13 15 "name": "Orbyt", ··· 26 28 "buildVersion": "62", 27 29 "date": "2026-03-12", 28 30 "localizedDescription": "Latest release.", 29 - "downloadURL": "https://getorbyt.com/altstore/adp/manifest.json", 31 + "downloadURL": "https://pub-780ccba5b34c4153bd997701d2e4e68d.r2.dev/manifest.json", 30 32 "size": 70307293, 31 33 "minOSVersion": "16.4" 32 34 }
+213
scripts/altstore-r2.sh
··· 1 + #!/usr/bin/env bash 2 + set -euo pipefail 3 + 4 + ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" 5 + DEFAULT_ADP_DIR="${ALTSTORE_ADP_DIR:-$ROOT_DIR/.altstore/adp}" 6 + SOURCE_JSON="$ROOT_DIR/public/altstore/source.json" 7 + DEFAULT_BUCKET_LOCATION="${R2_BUCKET_LOCATION:-weur}" 8 + 9 + usage() { 10 + cat <<'EOF' 11 + Usage: 12 + ./scripts/altstore-r2.sh setup <bucket> [adp_dir] 13 + ./scripts/altstore-r2.sh upload <bucket> [adp_dir] 14 + ./scripts/altstore-r2.sh set-source-url <manifest_url> 15 + ./scripts/altstore-r2.sh check <manifest_url> 16 + 17 + Commands: 18 + setup Create the R2 bucket if needed, enable the public r2.dev URL, 19 + upload the ADP directory, and update public/altstore/source.json. 20 + upload Upload the ADP directory to an existing R2 bucket. 21 + set-source-url Update public/altstore/source.json to point at a manifest URL. 22 + check Fetch a manifest URL and print the HTTP status. 23 + 24 + Environment: 25 + ALTSTORE_ADP_DIR Override the default ADP directory (.altstore/adp) 26 + R2_BUCKET_LOCATION Override the bucket location hint (default: weur) 27 + EOF 28 + } 29 + 30 + fail() { 31 + echo "Error: $*" >&2 32 + exit 1 33 + } 34 + 35 + require_file() { 36 + local path="$1" 37 + [[ -f "$path" ]] || fail "Missing file: $path" 38 + } 39 + 40 + require_dir() { 41 + local path="$1" 42 + [[ -d "$path" ]] || fail "Missing directory: $path" 43 + } 44 + 45 + ensure_prereqs() { 46 + require_file "$SOURCE_JSON" 47 + } 48 + 49 + ensure_adp_dir() { 50 + local adp_dir="$1" 51 + require_dir "$adp_dir" 52 + require_file "$adp_dir/manifest.json" 53 + require_file "$adp_dir/signature" 54 + require_dir "$adp_dir/variant" 55 + } 56 + 57 + mime_type_for() { 58 + local file="$1" 59 + case "$file" in 60 + *.json) 61 + printf '%s' 'application/json' 62 + ;; 63 + *.png) 64 + printf '%s' 'image/png' 65 + ;; 66 + *.jpg|*.jpeg) 67 + printf '%s' 'image/jpeg' 68 + ;; 69 + *.ipa|*/signature|*.bin) 70 + printf '%s' 'application/octet-stream' 71 + ;; 72 + *) 73 + printf '%s' 'application/octet-stream' 74 + ;; 75 + esac 76 + } 77 + 78 + bucket_exists() { 79 + local bucket="$1" 80 + npx wrangler r2 bucket info "$bucket" >/dev/null 2>&1 81 + } 82 + 83 + create_bucket_if_needed() { 84 + local bucket="$1" 85 + 86 + if bucket_exists "$bucket"; then 87 + echo "Bucket '$bucket' already exists." 88 + return 89 + fi 90 + 91 + echo "Creating bucket '$bucket' in location '$DEFAULT_BUCKET_LOCATION'..." 92 + if ! npx wrangler r2 bucket create "$bucket" --location "$DEFAULT_BUCKET_LOCATION"; then 93 + echo >&2 94 + echo "Cloudflare rejected the bucket creation request." >&2 95 + echo "If the error includes code 10042, enable R2 once in the Cloudflare dashboard and run this command again." >&2 96 + exit 1 97 + fi 98 + } 99 + 100 + enable_dev_url() { 101 + local bucket="$1" 102 + 103 + echo "Enabling public r2.dev URL for '$bucket'..." 104 + npx wrangler r2 bucket dev-url enable "$bucket" >/dev/null 105 + } 106 + 107 + get_dev_url() { 108 + local bucket="$1" 109 + local output 110 + 111 + output="$(npx wrangler r2 bucket dev-url get "$bucket")" 112 + printf '%s\n' "$output" | sed -nE 's/.*(https:\/\/[^[:space:]]+\.r2\.dev).*/\1/p' | head -n 1 113 + } 114 + 115 + upload_adp() { 116 + local bucket="$1" 117 + local adp_dir="$2" 118 + 119 + ensure_adp_dir "$adp_dir" 120 + 121 + echo "Uploading ADP files from '$adp_dir' to bucket '$bucket'..." 122 + while IFS= read -r file; do 123 + local rel_path 124 + local content_type 125 + rel_path="${file#$adp_dir/}" 126 + content_type="$(mime_type_for "$file")" 127 + echo " -> $rel_path" 128 + npx wrangler r2 object put "$bucket/$rel_path" --remote --file "$file" --content-type "$content_type" >/dev/null 129 + done < <(find "$adp_dir" -type f | sort) 130 + } 131 + 132 + set_source_url() { 133 + local manifest_url="$1" 134 + 135 + require_file "$SOURCE_JSON" 136 + 137 + node --input-type=commonjs - "$SOURCE_JSON" "$manifest_url" <<'NODE' 138 + const fs = require('node:fs'); 139 + const [filePath, manifestUrl] = process.argv.slice(2); 140 + const raw = fs.readFileSync(filePath, 'utf8'); 141 + const json = JSON.parse(raw); 142 + if (!Array.isArray(json.apps) || json.apps.length === 0) { 143 + throw new Error('source.json has no apps array'); 144 + } 145 + if (!Array.isArray(json.apps[0].versions) || json.apps[0].versions.length === 0) { 146 + throw new Error('source.json has no versions array'); 147 + } 148 + json.apps[0].versions[0].downloadURL = manifestUrl; 149 + fs.writeFileSync(filePath, `${JSON.stringify(json, null, 2)}\n`); 150 + NODE 151 + 152 + echo "Updated source download URL to: $manifest_url" 153 + } 154 + 155 + check_url() { 156 + local url="$1" 157 + curl -sS -o /dev/null -w '%{http_code} %{url_effective}\n' "$url" 158 + } 159 + 160 + setup_bucket() { 161 + local bucket="$1" 162 + local adp_dir="${2:-$DEFAULT_ADP_DIR}" 163 + local dev_url 164 + 165 + ensure_prereqs 166 + ensure_adp_dir "$adp_dir" 167 + create_bucket_if_needed "$bucket" 168 + enable_dev_url "$bucket" 169 + upload_adp "$bucket" "$adp_dir" 170 + 171 + dev_url="$(get_dev_url "$bucket")" 172 + [[ -n "$dev_url" ]] || fail "Unable to determine r2.dev URL for bucket '$bucket'" 173 + 174 + set_source_url "$dev_url/manifest.json" 175 + 176 + echo 177 + echo "R2 setup complete." 178 + echo "Manifest URL: $dev_url/manifest.json" 179 + echo "Next: deploy the site so https://getorbyt.com/altstore/source.json serves the updated metadata." 180 + } 181 + 182 + main() { 183 + local command="${1:-}" 184 + 185 + case "$command" in 186 + setup) 187 + [[ $# -ge 2 ]] || fail "setup requires a bucket name" 188 + setup_bucket "$2" "${3:-$DEFAULT_ADP_DIR}" 189 + ;; 190 + upload) 191 + [[ $# -ge 2 ]] || fail "upload requires a bucket name" 192 + ensure_adp_dir "${3:-$DEFAULT_ADP_DIR}" 193 + upload_adp "$2" "${3:-$DEFAULT_ADP_DIR}" 194 + ;; 195 + set-source-url) 196 + [[ $# -eq 2 ]] || fail "set-source-url requires a manifest URL" 197 + set_source_url "$2" 198 + ;; 199 + check) 200 + [[ $# -eq 2 ]] || fail "check requires a manifest URL" 201 + check_url "$2" 202 + ;; 203 + -h|--help|help) 204 + usage 205 + ;; 206 + *) 207 + usage 208 + [[ -z "$command" ]] || exit 1 209 + ;; 210 + esac 211 + } 212 + 213 + main "$@"
+14 -2
wrangler.jsonc
··· 2 2 "$schema": "./node_modules/wrangler/config-schema.json", 3 3 "name": "orbyt-site", 4 4 "main": "@astrojs/cloudflare/entrypoints/server", 5 - "routes": [{ "pattern": "getorbyt.com/*", "zone_name": "getorbyt.com" }], 5 + "routes": [ 6 + { 7 + "pattern": "getorbyt.com/*", 8 + "zone_name": "getorbyt.com" 9 + } 10 + ], 6 11 "compatibility_date": "2026-01-29", 7 12 "compatibility_flags": [ 8 13 "nodejs_compat", ··· 20 25 ], 21 26 "observability": { 22 27 "enabled": true 23 - } 28 + }, 29 + "r2_buckets": [ 30 + { 31 + "bucket_name": "orbyt-altstore-adp", 32 + "binding": "orbyt_altstore_adp", 33 + "remote": true 34 + } 35 + ] 24 36 }