Client side atproto account migrator in your web browser, along with services for backups and adversarial migrations. pdsmoover.com
pds atproto migrations moo cow

some small qol

+336 -269
+1 -1
.oxlintrc.json
··· 1 { 2 "$schema": "https://unpkg.com/oxlint/configuration_schema.json", 3 - "plugins": ["unicorn", "typescript", "oxc", "vue", "vitest"], 4 "jsPlugins": ["@e18e/eslint-plugin", "eslint-plugin-regexp"], 5 "categories": { 6 "correctness": "error",
··· 1 { 2 "$schema": "https://unpkg.com/oxlint/configuration_schema.json", 3 + "plugins": ["unicorn", "typescript", "oxc"], 4 "jsPlugins": ["@e18e/eslint-plugin", "eslint-plugin-regexp"], 5 "categories": { 6 "correctness": "error",
+65 -45
packages/moover/lib/pdsmoover.js
··· 32 this.migratePrefs = true 33 /** @type {boolean} */ 34 this.migratePlcRecord = true 35 } 36 37 /** ··· 61 twoFactorCode = null, 62 verificationCode = null, 63 ) { 64 - //Leaving this logic that either sets the agent to bsky.social, or the PDS since it's what I found worked best for migrations. 65 - // handleAndPDSResolver should be able to handle it, but there have been edge cases and this was what worked best 66 oldHandle = cleanHandle(oldHandle) 67 let oldAgent 68 let usersDid ··· 143 } catch (error) { 144 // Ideally should catch if the repo already exists, and if so silently log it and move along to the next step 145 if (error?.error === 'AlreadyExists') { 146 console.log('Repo already exists, logging in') 147 } else { 148 // Catches any other error and stops the migration process ··· 186 limit: 100, 187 }) 188 189 - for (const cid of listedBlobs.data.cids) { 190 - try { 191 - const blobRes = await oldAgent.com.atproto.sync.getBlob({ 192 - did: usersDid, 193 - cid, 194 - }) 195 - await newAgent.com.atproto.repo.uploadBlob(blobRes.data, { 196 - encoding: blobRes.headers['content-type'], 197 - }) 198 - uploadedBlobs++ 199 - if (uploadedBlobs % 10 === 0) { 200 - safeStatusUpdate( 201 - statusUpdateHandler, 202 - `Migrating blobs: ${uploadedBlobs}/${newAccountStatus.data.expectedBlobs}`, 203 - ) 204 - } 205 - } catch (error) { 206 - console.error(error) 207 - } 208 - } 209 blobCursor = listedBlobs.data.cursor 210 } while (blobCursor) 211 } 212 213 if (this.migrateMissingBlobs) { ··· 233 limit: 100, 234 }) 235 236 - for (const recordBlob of missingBlobs.data.blobs) { 237 - try { 238 - const blobRes = await oldAgent.com.atproto.sync.getBlob({ 239 - did: usersDid, 240 - cid: recordBlob.cid, 241 - }) 242 - await newAgent.com.atproto.repo.uploadBlob(blobRes.data, { 243 - encoding: blobRes.headers['content-type'], 244 - }) 245 - if (missingUploadedBlobs % 10 === 0) { 246 - safeStatusUpdate( 247 - statusUpdateHandler, 248 - `Migrating blobs: ${missingUploadedBlobs}/${totalMissingBlobs}`, 249 - ) 250 - } 251 - missingUploadedBlobs++ 252 - } catch (error) { 253 - //TODO silently logging prob should list them so user can manually download 254 - console.error(error) 255 - this.missingBlobs.push(recordBlob.cid) 256 - } 257 - } 258 missingBlobCursor = missingBlobs.data.cursor 259 } while (missingBlobCursor) 260 } 261 } 262 if (this.migratePrefs) { ··· 269 270 if (this.migratePlcRecord) { 271 await oldAgent.com.atproto.identity.requestPlcOperationSignature() 272 - safeStatusUpdate(statusUpdateHandler, 'Please check your email for a PLC token') 273 } 274 } 275
··· 32 this.migratePrefs = true 33 /** @type {boolean} */ 34 this.migratePlcRecord = true 35 + /** 36 + * How many blobs have been uploaded to the new PDS in the current step 37 + @type {number} */ 38 + this.uploadedBlobsCount = 0 39 + } 40 + 41 + /** 42 + * Uploads blobs to the new PDS 43 + * @param {AtpAgent} oldAgent 44 + * @param {AtpAgent} newAgent 45 + * @param {string} usersDid 46 + * @param {[string]} cids 47 + * @param {number} totalBlobs 48 + * @param {function|null} statusUpdateHandler 49 + */ 50 + async uploadBlobs(oldAgent, newAgent, usersDid, cids, totalBlobs, statusUpdateHandler) { 51 + console.log('uploading blobs', cids) 52 + for (const cid of cids) { 53 + try { 54 + const blobRes = await oldAgent.com.atproto.sync.getBlob({ 55 + did: usersDid, 56 + cid, 57 + }) 58 + await newAgent.com.atproto.repo.uploadBlob(blobRes.data, { 59 + encoding: blobRes.headers['content-type'], 60 + }) 61 + this.uploadedBlobsCount++ 62 + if (this.uploadedBlobsCount % 10 === 0) { 63 + safeStatusUpdate( 64 + statusUpdateHandler, 65 + `Migrating blobs: ${this.uploadedBlobsCount}/${totalBlobs}`, 66 + ) 67 + } 68 + } catch (error) { 69 + console.error(error) 70 + } 71 + } 72 } 73 74 /** ··· 98 twoFactorCode = null, 99 verificationCode = null, 100 ) { 101 oldHandle = cleanHandle(oldHandle) 102 let oldAgent 103 let usersDid ··· 178 } catch (error) { 179 // Ideally should catch if the repo already exists, and if so silently log it and move along to the next step 180 if (error?.error === 'AlreadyExists') { 181 + // Sets the migrate blobs flag to false so it moves on to just migrate missing blobs in the event of a retry 182 + this.migrateBlobs = false 183 console.log('Repo already exists, logging in') 184 } else { 185 // Catches any other error and stops the migration process ··· 223 limit: 100, 224 }) 225 226 + await this.uploadBlobs( 227 + oldAgent, 228 + newAgent, 229 + usersDid, 230 + listedBlobs.data.cids, 231 + newAccountStatus.data.expectedBlobs, 232 + statusUpdateHandler, 233 + ) 234 blobCursor = listedBlobs.data.cursor 235 } while (blobCursor) 236 + // Resets since this is a shared state with missing blobs job 237 + this.uploadedBlobsCount = 0 238 } 239 240 if (this.migrateMissingBlobs) { ··· 260 limit: 100, 261 }) 262 263 + let missingCids = missingBlobs.data.blobs.map(blob => blob.cid) 264 + await this.uploadBlobs( 265 + oldAgent, 266 + newAgent, 267 + usersDid, 268 + missingCids, 269 + totalMissingBlobs, 270 + statusUpdateHandler, 271 + ) 272 + 273 missingBlobCursor = missingBlobs.data.cursor 274 } while (missingBlobCursor) 275 + // Resets since this is a shared state with the migrate blobs job 276 + this.uploadedBlobsCount = 0 277 } 278 } 279 if (this.migratePrefs) { ··· 286 287 if (this.migratePlcRecord) { 288 await oldAgent.com.atproto.identity.requestPlcOperationSignature() 289 + safeStatusUpdate( 290 + statusUpdateHandler, 291 + 'Please check your email attached to your previous account for a PLC token', 292 + ) 293 } 294 } 295
+2 -2
packages/moover/package.json
··· 34 "scripts": { 35 "dev": "vite", 36 "build": "vite build", 37 "gen:types": "tsc -p .", 38 - "preview": "vite preview", 39 - "generate:lexicons": "lex build --lexicons lexicons --out lib/lexicons --clear" 40 }, 41 "devDependencies": { 42 "eslint": "^9.34.0",
··· 34 "scripts": { 35 "dev": "vite", 36 "build": "vite build", 37 + "build:watch": "vite build --watch", 38 "gen:types": "tsc -p .", 39 + "preview": "vite preview" 40 }, 41 "devDependencies": { 42 "eslint": "^9.34.0",
+2 -1
web-ui/package.json
··· 17 "@atcute/client": "^4.0.5", 18 "@atcute/lexicons": "^1.2.2", 19 "@pds-moover/lexicons": "^1.0.1", 20 - "@pds-moover/moover": "^1.0.6" 21 }, 22 "devDependencies": { 23 "@eslint/compat": "^1.4.0", ··· 30 "eslint": "^9.36.0", 31 "eslint-plugin-svelte": "^3.12.4", 32 "globals": "^16.4.0", 33 "svelte": "^5.39.5", 34 "svelte-check": "^4.3.2", 35 "typescript": "^5.9.2",
··· 17 "@atcute/client": "^4.0.5", 18 "@atcute/lexicons": "^1.2.2", 19 "@pds-moover/lexicons": "^1.0.1", 20 + "@pds-moover/moover": "link:../packages/moover" 21 }, 22 "devDependencies": { 23 "@eslint/compat": "^1.4.0", ··· 30 "eslint": "^9.36.0", 31 "eslint-plugin-svelte": "^3.12.4", 32 "globals": "^16.4.0", 33 + "oxlint": "^1.48.0", 34 "svelte": "^5.39.5", 35 "svelte-check": "^4.3.2", 36 "typescript": "^5.9.2",
+208 -189
web-ui/pnpm-lock.yaml
··· 21 specifier: ^1.0.1 22 version: 1.0.1 23 '@pds-moover/moover': 24 - specifier: ^1.0.6 25 - version: 1.0.6(@atcute/identity@1.1.1)(vite@7.1.12(@types/node@22.19.0)) 26 devDependencies: 27 '@eslint/compat': 28 specifier: ^1.4.0 ··· 54 globals: 55 specifier: ^16.4.0 56 version: 16.5.0 57 svelte: 58 specifier: ^5.39.5 59 version: 5.43.2 ··· 79 '@atcute/atproto@3.1.9': 80 resolution: {integrity: sha512-DyWwHCTdR4hY2BPNbLXgVmm7lI+fceOwWbE4LXbGvbvVtSn+ejSVFaAv01Ra3kWDha0whsOmbJL8JP0QPpf1+w==} 81 82 - '@atcute/cbor@2.3.2': 83 - resolution: {integrity: sha512-xP2SORSau/VVI00x2V4BjwIkHr6EQ7l/MXEOPaa4LGYtePFc4gnD4L1yN10dT5NEuUnvGEuCh6arLB7gz1smVQ==} 84 - 85 - '@atcute/cid@2.4.1': 86 - resolution: {integrity: sha512-bwhna69RCv7yetXudtj+2qrMPYvhhIQqvJz6YUpUS98v7OdF3X2dnye9Nig2NDrklZcuyOsu7sQo7GOykJXRLQ==} 87 - 88 '@atcute/client@4.0.5': 89 resolution: {integrity: sha512-R8Qen8goGmEkynYGg2m6XFlVmz0GTDvQ+9w+4QqOob+XMk8/WDpF4aImev7WKEde/rV2gjcqW7zM8E6W9NShDA==} 90 91 - '@atcute/crypto@2.3.0': 92 - resolution: {integrity: sha512-w5pkJKCjbNMQu+F4JRHbR3ROQyhi1wbn+GSC6WDQamcYHkZmEZk1/eoI354bIQOOfkEM6aFLv718iskrkon4GQ==} 93 - 94 - '@atcute/did-plc@0.1.7': 95 - resolution: {integrity: sha512-a7yOQNqViae3rB5/xa3U0EPJbFD9l8zOHXx6XASZ5F8+Vy2uTgXK3omurpNZ5UxRpy1ni1AMhSohXr61cqWbkg==} 96 - 97 - '@atcute/identity-resolver@1.2.2': 98 - resolution: {integrity: sha512-eUh/UH4bFvuXS0X7epYCeJC/kj4rbBXfSRumLEH4smMVwNOgTo7cL/0Srty+P/qVPoZEyXdfEbS0PHJyzoXmHw==} 99 - peerDependencies: 100 - '@atcute/identity': ^1.0.0 101 - 102 '@atcute/identity@1.1.1': 103 resolution: {integrity: sha512-zax42n693VEhnC+5tndvO2KLDTMkHOz8UExwmklvJv7R9VujfEwiSWhcv6Jgwb3ellaG8wjiQ1lMOIjLLvwh0Q==} 104 105 '@atcute/lexicons@1.2.2': 106 resolution: {integrity: sha512-bgEhJq5Z70/0TbK5sx+tAkrR8FsCODNiL2gUEvS5PuJfPxmFmRYNWaMGehxSPaXWpU2+Oa9ckceHiYbrItDTkA==} 107 - 108 - '@atcute/lexicons@1.2.9': 109 - resolution: {integrity: sha512-/RRHm2Cw9o8Mcsrq0eo8fjS9okKYLGfuFwrQ0YoP/6sdSDsXshaTLJsvLlcUcaDaSJ1YFOuHIo3zr2Om2F/16g==} 110 - 111 - '@atcute/multibase@1.1.8': 112 - resolution: {integrity: sha512-pJgtImMZKCjqwRbu+2GzB+4xQjKBXDwdZOzeqe0u97zYKRGftpGYGvYv3+pMe2xXe+msDyu7Nv8iJp+U14otTA==} 113 - 114 - '@atcute/uint8array@1.1.1': 115 - resolution: {integrity: sha512-3LsC8XB8TKe9q/5hOA5sFuzGaIFdJZJNewC5OKa3o/eU6+K7JR6see9Zy2JbQERNVnRl11EzbNov1efgLMAs4g==} 116 - 117 - '@atcute/util-fetch@1.0.5': 118 - resolution: {integrity: sha512-qjHj01BGxjSjIFdPiAjSARnodJIIyKxnCMMEcXMESo9TAyND6XZQqrie5fia+LlYWVXdpsTds8uFQwc9jdKTig==} 119 - 120 - '@atcute/util-text@1.1.1': 121 - resolution: {integrity: sha512-JH0SxzUQJAmbOBTYyhxQbkkI6M33YpjlVLEcbP5GYt43xgFArzV0FJVmEpvIj0kjsmphHB45b6IitdvxPdec9w==} 122 - 123 - '@atproto/api@0.16.11': 124 - resolution: {integrity: sha512-1dhfQNHiclb102RW+Ea8Nft5olfqU0Ev/vlQaSX6mWNo1aP5zT+sPODJ8+BTUOYk3vcuvL7QMkqA/rLYy2PMyw==} 125 126 '@atproto/common-web@0.4.3': 127 resolution: {integrity: sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg==} ··· 374 '@jridgewell/trace-mapping@0.3.31': 375 resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} 376 377 - '@noble/secp256k1@3.0.0': 378 - resolution: {integrity: sha512-NJBaR352KyIvj3t6sgT/+7xrNyF9Xk9QlLSIqUGVUYlsnDTAUqY8LOmwpcgEx4AMJXRITQ5XEVHD+mMaPfr3mg==} 379 - 380 '@nodelib/fs.scandir@2.1.5': 381 resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 382 engines: {node: '>= 8'} ··· 389 resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 390 engines: {node: '>= 8'} 391 392 '@pds-moover/lexicons@1.0.1': 393 resolution: {integrity: sha512-fv5b/DtHM7FEo/JklyF9gdK0ainlb6mWjWrBe6cmSAeg9G/4O2jBlQUOqfOAICY9gOcrCpkOrk9PHgGw//JQ2A==} 394 - 395 - '@pds-moover/moover@1.0.6': 396 - resolution: {integrity: sha512-Zy+wcrZwoyne7NhuG+5MDFoJ+lpteCpfS6w2pmma9F2IKrVTj2G3Pca7ZVDaibGmCMTJMo21XYaPg+9nLXFD4Q==} 397 398 '@polka/url@1.0.0-next.29': 399 resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} ··· 547 '@standard-schema/spec@1.0.0': 548 resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} 549 550 - '@standard-schema/spec@1.1.0': 551 - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} 552 - 553 '@sveltejs/acorn-typescript@1.0.6': 554 resolution: {integrity: sha512-4awhxtMh4cx9blePWl10HRHj8Iivtqj+2QdDCSMDzxG+XKa9+VCNupQuCuvzEhYPzZSrX+0gC+0lHA/0fFKKQQ==} 555 peerDependencies: ··· 667 resolution: {integrity: sha512-uk574k8IU0rOF/AjniX8qbLSGURJVUCeM5e4MIMKBFFi8weeiLrG1fyQejyLXQpRZbU/1BuQasleV/RfHC3hHg==} 668 engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 669 670 - '@vue/reactivity@3.1.5': 671 - resolution: {integrity: sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==} 672 - 673 - '@vue/shared@3.1.5': 674 - resolution: {integrity: sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==} 675 - 676 acorn-jsx@5.3.2: 677 resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} 678 peerDependencies: ··· 686 ajv@6.12.6: 687 resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} 688 689 - alpinejs@3.15.8: 690 - resolution: {integrity: sha512-zxIfCRTBGvF1CCLIOMQOxAyBuqibxSEwS6Jm1a3HGA9rgrJVcjEWlwLcQTVGAWGS8YhAsTRLVrtQ5a5QT9bSSQ==} 691 - 692 ansi-styles@4.3.0: 693 resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 694 engines: {node: '>=8'} ··· 700 resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} 701 engines: {node: '>= 0.4'} 702 703 - await-lock@2.2.2: 704 - resolution: {integrity: sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==} 705 - 706 axobject-query@4.1.0: 707 resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} 708 engines: {node: '>= 0.4'} ··· 1062 resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} 1063 engines: {node: '>= 0.8.0'} 1064 1065 p-limit@3.1.0: 1066 resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} 1067 engines: {node: '>=10'} ··· 1229 resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} 1230 engines: {node: '>=12.0.0'} 1231 1232 - tlds@1.261.0: 1233 - resolution: {integrity: sha512-QXqwfEl9ddlGBaRFXIvNKK6OhipSiLXuRuLJX5DErz0o0Q0rYxulWLdFryTkV5PkdZct5iMInwYEGe/eR++1AA==} 1234 - hasBin: true 1235 - 1236 to-regex-range@5.0.1: 1237 resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1238 engines: {node: '>=8.0'} ··· 1269 undici-types@6.21.0: 1270 resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} 1271 1272 - unicode-segmenter@0.14.5: 1273 - resolution: {integrity: sha512-jHGmj2LUuqDcX3hqY12Ql+uhUTn8huuxNZGq7GvtF6bSybzH3aFgedYu/KTzQStEgt1Ra2F3HxadNXsNjb3m3g==} 1274 - 1275 uri-js@4.4.1: 1276 resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 1277 1278 util-deprecate@1.0.2: 1279 resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 1280 1281 - vite-plugin-full-reload@1.2.0: 1282 - resolution: {integrity: sha512-kz18NW79x0IHbxRSHm0jttP4zoO9P9gXh+n6UTwlNKnviTTEpOlum6oS9SmecrTtSr+muHEn5TUuC75UovQzcA==} 1283 - 1284 - vite-rs-plugin@1.0.1: 1285 - resolution: {integrity: sha512-YhgflKQIRzuS5x66J3yICoVLH25D2fNU+jThK8tpYl/jGrXeIKT4w5VH1lkLPRC0SjK2ZCm9S6K9Z2ZFVDHjPQ==} 1286 - hasBin: true 1287 - peerDependencies: 1288 - vite: ^5.0.0 1289 - 1290 vite@7.1.12: 1291 resolution: {integrity: sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==} 1292 engines: {node: ^20.19.0 || >=22.12.0} ··· 1364 dependencies: 1365 '@atcute/lexicons': 1.2.2 1366 1367 - '@atcute/cbor@2.3.2': 1368 - dependencies: 1369 - '@atcute/cid': 2.4.1 1370 - '@atcute/multibase': 1.1.8 1371 - '@atcute/uint8array': 1.1.1 1372 - 1373 - '@atcute/cid@2.4.1': 1374 - dependencies: 1375 - '@atcute/multibase': 1.1.8 1376 - '@atcute/uint8array': 1.1.1 1377 - 1378 '@atcute/client@4.0.5': 1379 dependencies: 1380 '@atcute/identity': 1.1.1 1381 '@atcute/lexicons': 1.2.2 1382 1383 - '@atcute/crypto@2.3.0': 1384 - dependencies: 1385 - '@atcute/multibase': 1.1.8 1386 - '@atcute/uint8array': 1.1.1 1387 - '@noble/secp256k1': 3.0.0 1388 - 1389 - '@atcute/did-plc@0.1.7': 1390 - dependencies: 1391 - '@atcute/cbor': 2.3.2 1392 - '@atcute/cid': 2.4.1 1393 - '@atcute/crypto': 2.3.0 1394 - '@atcute/identity': 1.1.1 1395 - '@atcute/lexicons': 1.2.2 1396 - '@atcute/multibase': 1.1.8 1397 - '@atcute/uint8array': 1.1.1 1398 - '@badrap/valita': 0.4.6 1399 - 1400 - '@atcute/identity-resolver@1.2.2(@atcute/identity@1.1.1)': 1401 - dependencies: 1402 - '@atcute/identity': 1.1.1 1403 - '@atcute/lexicons': 1.2.9 1404 - '@atcute/util-fetch': 1.0.5 1405 - '@badrap/valita': 0.4.6 1406 - 1407 '@atcute/identity@1.1.1': 1408 dependencies: 1409 '@atcute/lexicons': 1.2.2 ··· 1413 dependencies: 1414 '@standard-schema/spec': 1.0.0 1415 esm-env: 1.2.2 1416 - 1417 - '@atcute/lexicons@1.2.9': 1418 - dependencies: 1419 - '@atcute/uint8array': 1.1.1 1420 - '@atcute/util-text': 1.1.1 1421 - '@standard-schema/spec': 1.1.0 1422 - esm-env: 1.2.2 1423 - 1424 - '@atcute/multibase@1.1.8': 1425 - dependencies: 1426 - '@atcute/uint8array': 1.1.1 1427 - 1428 - '@atcute/uint8array@1.1.1': {} 1429 - 1430 - '@atcute/util-fetch@1.0.5': 1431 - dependencies: 1432 - '@badrap/valita': 0.4.6 1433 - 1434 - '@atcute/util-text@1.1.1': 1435 - dependencies: 1436 - unicode-segmenter: 0.14.5 1437 - 1438 - '@atproto/api@0.16.11': 1439 - dependencies: 1440 - '@atproto/common-web': 0.4.3 1441 - '@atproto/lexicon': 0.5.1 1442 - '@atproto/syntax': 0.4.1 1443 - '@atproto/xrpc': 0.7.5 1444 - await-lock: 2.2.2 1445 - multiformats: 9.9.0 1446 - tlds: 1.261.0 1447 - zod: 3.25.76 1448 1449 '@atproto/common-web@0.4.3': 1450 dependencies: ··· 1630 '@jridgewell/resolve-uri': 3.1.2 1631 '@jridgewell/sourcemap-codec': 1.5.5 1632 1633 - '@noble/secp256k1@3.0.0': {} 1634 - 1635 '@nodelib/fs.scandir@2.1.5': 1636 dependencies: 1637 '@nodelib/fs.stat': 2.0.5 ··· 1644 '@nodelib/fs.scandir': 2.1.5 1645 fastq: 1.19.1 1646 1647 '@pds-moover/lexicons@1.0.1': 1648 dependencies: 1649 '@atproto/lexicon': 0.5.1 1650 '@atproto/xrpc': 0.7.5 1651 - 1652 - '@pds-moover/moover@1.0.6(@atcute/identity@1.1.1)(vite@7.1.12(@types/node@22.19.0))': 1653 - dependencies: 1654 - '@atcute/cbor': 2.3.2 1655 - '@atcute/client': 4.0.5 1656 - '@atcute/crypto': 2.3.0 1657 - '@atcute/did-plc': 0.1.7 1658 - '@atcute/identity-resolver': 1.2.2(@atcute/identity@1.1.1) 1659 - '@atcute/lexicons': 1.2.2 1660 - '@atcute/multibase': 1.1.8 1661 - '@atproto/api': 0.16.11 1662 - '@pds-moover/lexicons': 1.0.1 1663 - alpinejs: 3.15.8 1664 - vite-plugin-full-reload: 1.2.0 1665 - vite-rs-plugin: 1.0.1(vite@7.1.12(@types/node@22.19.0)) 1666 - transitivePeerDependencies: 1667 - - '@atcute/identity' 1668 - - vite 1669 1670 '@polka/url@1.0.0-next.29': {} 1671 ··· 1773 1774 '@standard-schema/spec@1.0.0': {} 1775 1776 - '@standard-schema/spec@1.1.0': {} 1777 - 1778 '@sveltejs/acorn-typescript@1.0.6(acorn@8.15.0)': 1779 dependencies: 1780 acorn: 8.15.0 ··· 1936 '@typescript-eslint/types': 8.46.3 1937 eslint-visitor-keys: 4.2.1 1938 1939 - '@vue/reactivity@3.1.5': 1940 - dependencies: 1941 - '@vue/shared': 3.1.5 1942 - 1943 - '@vue/shared@3.1.5': {} 1944 - 1945 acorn-jsx@5.3.2(acorn@8.15.0): 1946 dependencies: 1947 acorn: 8.15.0 ··· 1955 json-schema-traverse: 0.4.1 1956 uri-js: 4.4.1 1957 1958 - alpinejs@3.15.8: 1959 - dependencies: 1960 - '@vue/reactivity': 3.1.5 1961 - 1962 ansi-styles@4.3.0: 1963 dependencies: 1964 color-convert: 2.0.1 ··· 1966 argparse@2.0.1: {} 1967 1968 aria-query@5.3.2: {} 1969 - 1970 - await-lock@2.2.2: {} 1971 1972 axobject-query@4.1.0: {} 1973 ··· 2329 type-check: 0.4.0 2330 word-wrap: 1.2.5 2331 2332 p-limit@3.1.0: 2333 dependencies: 2334 yocto-queue: 0.1.0 ··· 2504 fdir: 6.5.0(picomatch@4.0.3) 2505 picomatch: 4.0.3 2506 2507 - tlds@1.261.0: {} 2508 - 2509 to-regex-range@5.0.1: 2510 dependencies: 2511 is-number: 7.0.0 ··· 2539 2540 undici-types@6.21.0: {} 2541 2542 - unicode-segmenter@0.14.5: {} 2543 - 2544 uri-js@4.4.1: 2545 dependencies: 2546 punycode: 2.3.1 2547 2548 util-deprecate@1.0.2: {} 2549 - 2550 - vite-plugin-full-reload@1.2.0: 2551 - dependencies: 2552 - picocolors: 1.1.1 2553 - picomatch: 2.3.1 2554 - 2555 - vite-rs-plugin@1.0.1(vite@7.1.12(@types/node@22.19.0)): 2556 - dependencies: 2557 - vite: 7.1.12(@types/node@22.19.0) 2558 - vite-plugin-full-reload: 1.2.0 2559 2560 vite@7.1.12(@types/node@22.19.0): 2561 dependencies:
··· 21 specifier: ^1.0.1 22 version: 1.0.1 23 '@pds-moover/moover': 24 + specifier: link:../packages/moover 25 + version: link:../packages/moover 26 devDependencies: 27 '@eslint/compat': 28 specifier: ^1.4.0 ··· 54 globals: 55 specifier: ^16.4.0 56 version: 16.5.0 57 + oxlint: 58 + specifier: ^1.48.0 59 + version: 1.48.0 60 svelte: 61 specifier: ^5.39.5 62 version: 5.43.2 ··· 82 '@atcute/atproto@3.1.9': 83 resolution: {integrity: sha512-DyWwHCTdR4hY2BPNbLXgVmm7lI+fceOwWbE4LXbGvbvVtSn+ejSVFaAv01Ra3kWDha0whsOmbJL8JP0QPpf1+w==} 84 85 '@atcute/client@4.0.5': 86 resolution: {integrity: sha512-R8Qen8goGmEkynYGg2m6XFlVmz0GTDvQ+9w+4QqOob+XMk8/WDpF4aImev7WKEde/rV2gjcqW7zM8E6W9NShDA==} 87 88 '@atcute/identity@1.1.1': 89 resolution: {integrity: sha512-zax42n693VEhnC+5tndvO2KLDTMkHOz8UExwmklvJv7R9VujfEwiSWhcv6Jgwb3ellaG8wjiQ1lMOIjLLvwh0Q==} 90 91 '@atcute/lexicons@1.2.2': 92 resolution: {integrity: sha512-bgEhJq5Z70/0TbK5sx+tAkrR8FsCODNiL2gUEvS5PuJfPxmFmRYNWaMGehxSPaXWpU2+Oa9ckceHiYbrItDTkA==} 93 94 '@atproto/common-web@0.4.3': 95 resolution: {integrity: sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg==} ··· 342 '@jridgewell/trace-mapping@0.3.31': 343 resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} 344 345 '@nodelib/fs.scandir@2.1.5': 346 resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 347 engines: {node: '>= 8'} ··· 354 resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 355 engines: {node: '>= 8'} 356 357 + '@oxlint/binding-android-arm-eabi@1.48.0': 358 + resolution: {integrity: sha512-1Pz/stJvveO9ZO7ll4ZoEY3f6j2FiUgBLBcCRCiW6ylId9L9UKs+gn3X28m3eTnoiFCkhKwmJJ+VO6vwsu7Qtg==} 359 + engines: {node: ^20.19.0 || >=22.12.0} 360 + cpu: [arm] 361 + os: [android] 362 + 363 + '@oxlint/binding-android-arm64@1.48.0': 364 + resolution: {integrity: sha512-Zc42RWGE8huo6Ht0lXKjd0NH2lWNmimQHUmD0JFcvShLOuwN+RSEE/kRakc2/0LIgOUuU/R7PaDMCOdQlPgNUQ==} 365 + engines: {node: ^20.19.0 || >=22.12.0} 366 + cpu: [arm64] 367 + os: [android] 368 + 369 + '@oxlint/binding-darwin-arm64@1.48.0': 370 + resolution: {integrity: sha512-jgZs563/4vaG5jH2RSt2TSh8A2jwsFdmhLXrElMdm3Mmto0HPf85FgInLSNi9HcwzQFvkYV8JofcoUg2GH1HTA==} 371 + engines: {node: ^20.19.0 || >=22.12.0} 372 + cpu: [arm64] 373 + os: [darwin] 374 + 375 + '@oxlint/binding-darwin-x64@1.48.0': 376 + resolution: {integrity: sha512-kvo87BujEUjCJREuWDC4aPh1WoXCRFFWE4C7uF6wuoMw2f6N2hypA/cHHcYn9DdL8R2RrgUZPefC8JExyeIMKA==} 377 + engines: {node: ^20.19.0 || >=22.12.0} 378 + cpu: [x64] 379 + os: [darwin] 380 + 381 + '@oxlint/binding-freebsd-x64@1.48.0': 382 + resolution: {integrity: sha512-eyzzPaHQKn0RIM+ueDfgfJF2RU//Wp4oaKs2JVoVYcM5HjbCL36+O0S3wO5Xe1NWpcZIG3cEHc/SuOCDRqZDSg==} 383 + engines: {node: ^20.19.0 || >=22.12.0} 384 + cpu: [x64] 385 + os: [freebsd] 386 + 387 + '@oxlint/binding-linux-arm-gnueabihf@1.48.0': 388 + resolution: {integrity: sha512-p3kSloztK7GRO7FyO3u38UCjZxQTl92VaLDsMQAq0eGoiNmeeEF1KPeE4+Fr+LSkQhF8WvJKSuls6TwOlurdPA==} 389 + engines: {node: ^20.19.0 || >=22.12.0} 390 + cpu: [arm] 391 + os: [linux] 392 + 393 + '@oxlint/binding-linux-arm-musleabihf@1.48.0': 394 + resolution: {integrity: sha512-uWM+wiTqLW/V0ZmY/eyTWs8ykhIkzU+K2tz/8m35YepYEzohiUGRbnkpAFXj2ioXpQL+GUe5vmM3SLH6ozlfFw==} 395 + engines: {node: ^20.19.0 || >=22.12.0} 396 + cpu: [arm] 397 + os: [linux] 398 + 399 + '@oxlint/binding-linux-arm64-gnu@1.48.0': 400 + resolution: {integrity: sha512-OhQNPjs/OICaYqxYJjKKMaIY7p3nJ9IirXcFoHKD+CQE1BZFCeUUAknMzUeLclDCfudH9Vb/UgjFm8+ZM5puAg==} 401 + engines: {node: ^20.19.0 || >=22.12.0} 402 + cpu: [arm64] 403 + os: [linux] 404 + 405 + '@oxlint/binding-linux-arm64-musl@1.48.0': 406 + resolution: {integrity: sha512-adu5txuwGvQ4C4fjYHJD+vnY+OCwCixBzn7J3KF3iWlVHBBImcosSv+Ye+fbMMJui4HGjifNXzonjKm9pXmOiw==} 407 + engines: {node: ^20.19.0 || >=22.12.0} 408 + cpu: [arm64] 409 + os: [linux] 410 + 411 + '@oxlint/binding-linux-ppc64-gnu@1.48.0': 412 + resolution: {integrity: sha512-inlQQRUnHCny/7b7wA6NjEoJSSZPNea4qnDhWyeqBYWx8ukf2kzNDSiamfhOw6bfAYPm/PVlkVRYaNXQbkLeTQ==} 413 + engines: {node: ^20.19.0 || >=22.12.0} 414 + cpu: [ppc64] 415 + os: [linux] 416 + 417 + '@oxlint/binding-linux-riscv64-gnu@1.48.0': 418 + resolution: {integrity: sha512-YiJx6sW6bYebQDZRVWLKm/Drswx/hcjIgbLIhULSn0rRcBKc7d9V6mkqPjKDbhcxJgQD5Zi0yVccJiOdF40AWA==} 419 + engines: {node: ^20.19.0 || >=22.12.0} 420 + cpu: [riscv64] 421 + os: [linux] 422 + 423 + '@oxlint/binding-linux-riscv64-musl@1.48.0': 424 + resolution: {integrity: sha512-zwSqxMgmb2ITamNfDv9Q9EKBc/4ZhCBP9gkg2hhcgR6sEVGPUDl1AKPC89CBKMxkmPUi3685C38EvqtZn5OtHw==} 425 + engines: {node: ^20.19.0 || >=22.12.0} 426 + cpu: [riscv64] 427 + os: [linux] 428 + 429 + '@oxlint/binding-linux-s390x-gnu@1.48.0': 430 + resolution: {integrity: sha512-c/+2oUWAOsQB5JTem0rW8ODlZllF6pAtGSGXoLSvPTonKI1vAwaKhD9Qw1X36jRbcI3Etkpu/9z/RRjMba8vFQ==} 431 + engines: {node: ^20.19.0 || >=22.12.0} 432 + cpu: [s390x] 433 + os: [linux] 434 + 435 + '@oxlint/binding-linux-x64-gnu@1.48.0': 436 + resolution: {integrity: sha512-PhauDqeFW5DGed6QxCY5lXZYKSlcBdCXJnH03ZNU6QmDZ0BFM/zSy1oPT2MNb1Afx1G6yOOVk8ErjWsQ7c59ng==} 437 + engines: {node: ^20.19.0 || >=22.12.0} 438 + cpu: [x64] 439 + os: [linux] 440 + 441 + '@oxlint/binding-linux-x64-musl@1.48.0': 442 + resolution: {integrity: sha512-6d7LIFFZGiavbHndhf1cK9kG9qmy2Dmr37sV9Ep7j3H+ciFdKSuOzdLh85mEUYMih+b+esMDlF5DU0WQRZPQjw==} 443 + engines: {node: ^20.19.0 || >=22.12.0} 444 + cpu: [x64] 445 + os: [linux] 446 + 447 + '@oxlint/binding-openharmony-arm64@1.48.0': 448 + resolution: {integrity: sha512-r+0KK9lK6vFp3tXAgDMOW32o12dxvKS3B9La1uYMGdWAMoSeu2RzG34KmzSpXu6MyLDl4aSVyZLFM8KGdEjwaw==} 449 + engines: {node: ^20.19.0 || >=22.12.0} 450 + cpu: [arm64] 451 + os: [openharmony] 452 + 453 + '@oxlint/binding-win32-arm64-msvc@1.48.0': 454 + resolution: {integrity: sha512-Nkw/MocyT3HSp0OJsKPXrcbxZqSPMTYnLLfsqsoiFKoL1ppVNL65MFa7vuTxJehPlBkjy+95gUgacZtuNMECrg==} 455 + engines: {node: ^20.19.0 || >=22.12.0} 456 + cpu: [arm64] 457 + os: [win32] 458 + 459 + '@oxlint/binding-win32-ia32-msvc@1.48.0': 460 + resolution: {integrity: sha512-reO1SpefvRmeZSP+WeyWkQd1ArxxDD1MyKgMUKuB8lNuUoxk9QEohYtKnsfsxJuFwMT0JTr7p9wZjouA85GzGQ==} 461 + engines: {node: ^20.19.0 || >=22.12.0} 462 + cpu: [ia32] 463 + os: [win32] 464 + 465 + '@oxlint/binding-win32-x64-msvc@1.48.0': 466 + resolution: {integrity: sha512-T6zwhfcsrorqAybkOglZdPkTLlEwipbtdO1qjE+flbawvwOMsISoyiuaa7vM7zEyfq1hmDvMq1ndvkYFioranA==} 467 + engines: {node: ^20.19.0 || >=22.12.0} 468 + cpu: [x64] 469 + os: [win32] 470 + 471 '@pds-moover/lexicons@1.0.1': 472 resolution: {integrity: sha512-fv5b/DtHM7FEo/JklyF9gdK0ainlb6mWjWrBe6cmSAeg9G/4O2jBlQUOqfOAICY9gOcrCpkOrk9PHgGw//JQ2A==} 473 474 '@polka/url@1.0.0-next.29': 475 resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} ··· 623 '@standard-schema/spec@1.0.0': 624 resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} 625 626 '@sveltejs/acorn-typescript@1.0.6': 627 resolution: {integrity: sha512-4awhxtMh4cx9blePWl10HRHj8Iivtqj+2QdDCSMDzxG+XKa9+VCNupQuCuvzEhYPzZSrX+0gC+0lHA/0fFKKQQ==} 628 peerDependencies: ··· 740 resolution: {integrity: sha512-uk574k8IU0rOF/AjniX8qbLSGURJVUCeM5e4MIMKBFFi8weeiLrG1fyQejyLXQpRZbU/1BuQasleV/RfHC3hHg==} 741 engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 742 743 acorn-jsx@5.3.2: 744 resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} 745 peerDependencies: ··· 753 ajv@6.12.6: 754 resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} 755 756 ansi-styles@4.3.0: 757 resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 758 engines: {node: '>=8'} ··· 764 resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} 765 engines: {node: '>= 0.4'} 766 767 axobject-query@4.1.0: 768 resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} 769 engines: {node: '>= 0.4'} ··· 1123 resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} 1124 engines: {node: '>= 0.8.0'} 1125 1126 + oxlint@1.48.0: 1127 + resolution: {integrity: sha512-m5vyVBgPtPhVCJc3xI//8je9lRc8bYuYB4R/1PH3VPGOjA4vjVhkHtyJukdEjYEjwrw4Qf1eIf+pP9xvfhfMow==} 1128 + engines: {node: ^20.19.0 || >=22.12.0} 1129 + hasBin: true 1130 + peerDependencies: 1131 + oxlint-tsgolint: '>=0.12.2' 1132 + peerDependenciesMeta: 1133 + oxlint-tsgolint: 1134 + optional: true 1135 + 1136 p-limit@3.1.0: 1137 resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} 1138 engines: {node: '>=10'} ··· 1300 resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} 1301 engines: {node: '>=12.0.0'} 1302 1303 to-regex-range@5.0.1: 1304 resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1305 engines: {node: '>=8.0'} ··· 1336 undici-types@6.21.0: 1337 resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} 1338 1339 uri-js@4.4.1: 1340 resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 1341 1342 util-deprecate@1.0.2: 1343 resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 1344 1345 vite@7.1.12: 1346 resolution: {integrity: sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==} 1347 engines: {node: ^20.19.0 || >=22.12.0} ··· 1419 dependencies: 1420 '@atcute/lexicons': 1.2.2 1421 1422 '@atcute/client@4.0.5': 1423 dependencies: 1424 '@atcute/identity': 1.1.1 1425 '@atcute/lexicons': 1.2.2 1426 1427 '@atcute/identity@1.1.1': 1428 dependencies: 1429 '@atcute/lexicons': 1.2.2 ··· 1433 dependencies: 1434 '@standard-schema/spec': 1.0.0 1435 esm-env: 1.2.2 1436 1437 '@atproto/common-web@0.4.3': 1438 dependencies: ··· 1618 '@jridgewell/resolve-uri': 3.1.2 1619 '@jridgewell/sourcemap-codec': 1.5.5 1620 1621 '@nodelib/fs.scandir@2.1.5': 1622 dependencies: 1623 '@nodelib/fs.stat': 2.0.5 ··· 1630 '@nodelib/fs.scandir': 2.1.5 1631 fastq: 1.19.1 1632 1633 + '@oxlint/binding-android-arm-eabi@1.48.0': 1634 + optional: true 1635 + 1636 + '@oxlint/binding-android-arm64@1.48.0': 1637 + optional: true 1638 + 1639 + '@oxlint/binding-darwin-arm64@1.48.0': 1640 + optional: true 1641 + 1642 + '@oxlint/binding-darwin-x64@1.48.0': 1643 + optional: true 1644 + 1645 + '@oxlint/binding-freebsd-x64@1.48.0': 1646 + optional: true 1647 + 1648 + '@oxlint/binding-linux-arm-gnueabihf@1.48.0': 1649 + optional: true 1650 + 1651 + '@oxlint/binding-linux-arm-musleabihf@1.48.0': 1652 + optional: true 1653 + 1654 + '@oxlint/binding-linux-arm64-gnu@1.48.0': 1655 + optional: true 1656 + 1657 + '@oxlint/binding-linux-arm64-musl@1.48.0': 1658 + optional: true 1659 + 1660 + '@oxlint/binding-linux-ppc64-gnu@1.48.0': 1661 + optional: true 1662 + 1663 + '@oxlint/binding-linux-riscv64-gnu@1.48.0': 1664 + optional: true 1665 + 1666 + '@oxlint/binding-linux-riscv64-musl@1.48.0': 1667 + optional: true 1668 + 1669 + '@oxlint/binding-linux-s390x-gnu@1.48.0': 1670 + optional: true 1671 + 1672 + '@oxlint/binding-linux-x64-gnu@1.48.0': 1673 + optional: true 1674 + 1675 + '@oxlint/binding-linux-x64-musl@1.48.0': 1676 + optional: true 1677 + 1678 + '@oxlint/binding-openharmony-arm64@1.48.0': 1679 + optional: true 1680 + 1681 + '@oxlint/binding-win32-arm64-msvc@1.48.0': 1682 + optional: true 1683 + 1684 + '@oxlint/binding-win32-ia32-msvc@1.48.0': 1685 + optional: true 1686 + 1687 + '@oxlint/binding-win32-x64-msvc@1.48.0': 1688 + optional: true 1689 + 1690 '@pds-moover/lexicons@1.0.1': 1691 dependencies: 1692 '@atproto/lexicon': 0.5.1 1693 '@atproto/xrpc': 0.7.5 1694 1695 '@polka/url@1.0.0-next.29': {} 1696 ··· 1798 1799 '@standard-schema/spec@1.0.0': {} 1800 1801 '@sveltejs/acorn-typescript@1.0.6(acorn@8.15.0)': 1802 dependencies: 1803 acorn: 8.15.0 ··· 1959 '@typescript-eslint/types': 8.46.3 1960 eslint-visitor-keys: 4.2.1 1961 1962 acorn-jsx@5.3.2(acorn@8.15.0): 1963 dependencies: 1964 acorn: 8.15.0 ··· 1972 json-schema-traverse: 0.4.1 1973 uri-js: 4.4.1 1974 1975 ansi-styles@4.3.0: 1976 dependencies: 1977 color-convert: 2.0.1 ··· 1979 argparse@2.0.1: {} 1980 1981 aria-query@5.3.2: {} 1982 1983 axobject-query@4.1.0: {} 1984 ··· 2340 type-check: 0.4.0 2341 word-wrap: 1.2.5 2342 2343 + oxlint@1.48.0: 2344 + optionalDependencies: 2345 + '@oxlint/binding-android-arm-eabi': 1.48.0 2346 + '@oxlint/binding-android-arm64': 1.48.0 2347 + '@oxlint/binding-darwin-arm64': 1.48.0 2348 + '@oxlint/binding-darwin-x64': 1.48.0 2349 + '@oxlint/binding-freebsd-x64': 1.48.0 2350 + '@oxlint/binding-linux-arm-gnueabihf': 1.48.0 2351 + '@oxlint/binding-linux-arm-musleabihf': 1.48.0 2352 + '@oxlint/binding-linux-arm64-gnu': 1.48.0 2353 + '@oxlint/binding-linux-arm64-musl': 1.48.0 2354 + '@oxlint/binding-linux-ppc64-gnu': 1.48.0 2355 + '@oxlint/binding-linux-riscv64-gnu': 1.48.0 2356 + '@oxlint/binding-linux-riscv64-musl': 1.48.0 2357 + '@oxlint/binding-linux-s390x-gnu': 1.48.0 2358 + '@oxlint/binding-linux-x64-gnu': 1.48.0 2359 + '@oxlint/binding-linux-x64-musl': 1.48.0 2360 + '@oxlint/binding-openharmony-arm64': 1.48.0 2361 + '@oxlint/binding-win32-arm64-msvc': 1.48.0 2362 + '@oxlint/binding-win32-ia32-msvc': 1.48.0 2363 + '@oxlint/binding-win32-x64-msvc': 1.48.0 2364 + 2365 p-limit@3.1.0: 2366 dependencies: 2367 yocto-queue: 0.1.0 ··· 2537 fdir: 6.5.0(picomatch@4.0.3) 2538 picomatch: 4.0.3 2539 2540 to-regex-range@5.0.1: 2541 dependencies: 2542 is-number: 7.0.0 ··· 2570 2571 undici-types@6.21.0: {} 2572 2573 uri-js@4.4.1: 2574 dependencies: 2575 punycode: 2.3.1 2576 2577 util-deprecate@1.0.2: {} 2578 2579 vite@7.1.12(@types/node@22.19.0): 2580 dependencies:
+15 -6
web-ui/src/lib/assets/style.css
··· 138 justify-content: center; 139 } 140 141 - 142 .section { 143 margin-top: 30px; 144 } ··· 179 } 180 181 .form-checkbox { 182 - 183 font-size: 2rem; 184 font-weight: bold; 185 line-height: 1.1; ··· 244 text-decoration: none; 245 padding: 6px 10px; 246 border-radius: 8px; 247 - transition: background-color 0.2s ease, color 0.2s ease; 248 } 249 250 .nav-links a:hover, ··· 326 flex-direction: column; 327 gap: 4px; 328 padding: 10px 16px 12px 16px; 329 - background: rgba(36, 36, 36, 0.95); /* solid enough to not bleed into title */ 330 backdrop-filter: saturate(180%) blur(10px); 331 border-bottom: 1px solid rgba(255, 255, 255, 0.08); 332 z-index: 1001; /* above page content */ ··· 426 } 427 } 428 429 - 430 /* Stats grid and cards for the index page */ 431 .stats-grid { 432 display: grid; ··· 462 font-size: 0.85rem; 463 opacity: 0.7; 464 margin-top: 6px; 465 - }
··· 138 justify-content: center; 139 } 140 141 .section { 142 margin-top: 30px; 143 } ··· 178 } 179 180 .form-checkbox { 181 font-size: 2rem; 182 font-weight: bold; 183 line-height: 1.1; ··· 242 text-decoration: none; 243 padding: 6px 10px; 244 border-radius: 8px; 245 + transition: 246 + background-color 0.2s ease, 247 + color 0.2s ease; 248 } 249 250 .nav-links a:hover, ··· 326 flex-direction: column; 327 gap: 4px; 328 padding: 10px 16px 12px 16px; 329 + background: rgba( 330 + 36, 331 + 36, 332 + 36, 333 + 0.95 334 + ); /* solid enough to not bleed into title */ 335 backdrop-filter: saturate(180%) blur(10px); 336 border-bottom: 1px solid rgba(255, 255, 255, 0.08); 337 z-index: 1001; /* above page content */ ··· 431 } 432 } 433 434 /* Stats grid and cards for the index page */ 435 .stats-grid { 436 display: grid; ··· 466 font-size: 0.85rem; 467 opacity: 0.7; 468 margin-top: 6px; 469 + } 470 + 471 + .warning { 472 + /*text-decoration: underline;*/ 473 + font-weight: bold; 474 + }
+33 -18
web-ui/src/routes/moover/[[pds]]/+page.svelte
··· 4 import {resolve} from '$app/paths'; 5 import {Migrator} from '@pds-moover/moover'; 6 import SignThePapers from './SignThePapers.svelte'; 7 - import Captcha from './Captcha.svelte'; 8 9 let {data} = $props(); 10 ··· 66 let askForPlcToken = $state(false); 67 let disableSubmit = $state(false); 68 let showCaptcha = $state(false); 69 70 let errorMessage: null | string = $state(null); 71 let statusMessage: null | string = $state(null); ··· 134 135 async function performMigration() { 136 try { 137 - 138 if (showTwoFactorCodeInput) { 139 if (showTwoFactorCodeInput === null) { 140 errorMessage = 'Please enter the 2FA that was sent to your email.' ··· 151 migrator.migratePrefs = formData.migratePrefs; 152 migrator.migratePlcRecord = formData.migratePlcRecord; 153 154 - console.log(formData.newPds, newHandle); 155 156 updateStatusHandler('Starting migration...'); 157 showStatusMessage = true; ··· 183 } 184 //@ts-expect-error: JS being js. doesn't like not having the type' 185 errorMessage = error.message; 186 } 187 } 188 </script> 189 190 <svelte:head> ··· 194 </svelte:head> 195 196 <div class="container"> 197 - <MooHeader title="PDS MOOver"/> 198 - {#if !askForPlcToken} 199 <a href={resolve('/info')}>Idk if I trust a cow to move my atproto account to a new PDS</a> 200 <br/> 201 <a href="https://blacksky.community/profile/did:plc:g7j6qok5us4hjqlwjxwrrkjm/post/3lw3hcuojck2u">Video guide for 202 joining blacksky.app</a> 203 {#if showCaptcha} 204 <Captcha 205 - pdsUrl={formData.newPds} 206 handle={newHandle} 207 onSuccess={handleCaptchaSuccess} 208 onError={handleCaptchaError} ··· 388 <span>I understand</span> 389 </label> 390 </div> 391 {#if errorMessage !== null} 392 <div class="error-message">{errorMessage}</div> 393 {/if} 394 395 {#if showStatusMessage} 396 - <div id="warning">*Please make sure to stay on this page during the MOOve for the 397 - best result 398 - </div> 399 <div id="status-message" class="status-message">{statusMessage}</div> 400 {/if} 401 402 403 - <div> 404 - <button disabled={disableSubmit} 405 - type="submit">{selectedPds ? `MOOve to ${cleanSelectedPds}` : 'MOOve'}</button> 406 - </div> 407 - 408 - </form> 409 - {/if} 410 - {:else} 411 <SignThePapers migrator={migrator} newHandle={newHandle}/> 412 {/if} 413 - </div>
··· 4 import {resolve} from '$app/paths'; 5 import {Migrator} from '@pds-moover/moover'; 6 import SignThePapers from './SignThePapers.svelte'; 7 + import Captcha from '$lib/components/Captcha.svelte'; 8 + 9 10 let {data} = $props(); 11 ··· 67 let askForPlcToken = $state(false); 68 let disableSubmit = $state(false); 69 let showCaptcha = $state(false); 70 + let migrationInProgress = $state(false); 71 72 let errorMessage: null | string = $state(null); 73 let statusMessage: null | string = $state(null); ··· 136 137 async function performMigration() { 138 try { 139 + migrationInProgress = true; 140 if (showTwoFactorCodeInput) { 141 if (showTwoFactorCodeInput === null) { 142 errorMessage = 'Please enter the 2FA that was sent to your email.' ··· 153 migrator.migratePrefs = formData.migratePrefs; 154 migrator.migratePlcRecord = formData.migratePlcRecord; 155 156 157 updateStatusHandler('Starting migration...'); 158 showStatusMessage = true; ··· 184 } 185 //@ts-expect-error: JS being js. doesn't like not having the type' 186 errorMessage = error.message; 187 + // migrationInProgress = false; 188 } 189 } 190 + 191 </script> 192 193 <svelte:head> ··· 197 </svelte:head> 198 199 <div class="container"> 200 + <MooHeader title="PDS MOOver"/> 201 + {#if !migrationInProgress} 202 <a href={resolve('/info')}>Idk if I trust a cow to move my atproto account to a new PDS</a> 203 <br/> 204 <a href="https://blacksky.community/profile/did:plc:g7j6qok5us4hjqlwjxwrrkjm/post/3lw3hcuojck2u">Video guide for 205 joining blacksky.app</a> 206 {#if showCaptcha} 207 <Captcha 208 + pdsUrl={`https://${cleanSelectedPds}`} 209 handle={newHandle} 210 onSuccess={handleCaptchaSuccess} 211 onError={handleCaptchaError} ··· 391 <span>I understand</span> 392 </label> 393 </div> 394 + <div> 395 + <button disabled={disableSubmit} 396 + type="submit">{selectedPds ? `MOOve to ${cleanSelectedPds}` : 'MOOve'}</button> 397 + </div> 398 + 399 + </form> 400 + {/if} 401 + {:else} 402 + {#if !askForPlcToken} 403 + <div id="messageBoxes"> 404 + <div class="warning">***Please make sure to stay on this page during the MOOve for the 405 + best result.*** 406 + </div> 407 + 408 {#if errorMessage !== null} 409 <div class="error-message">{errorMessage}</div> 410 + 411 + <div id="status-message" class="status-message">A error has occurred. Please take a screenshot of this screen for support. You can also retry by refreshing the page, it will not harm your account.</div> 412 + 413 {/if} 414 415 {#if showStatusMessage} 416 <div id="status-message" class="status-message">{statusMessage}</div> 417 {/if} 418 + </div> 419 + {/if} 420 + {/if} 421 422 423 + {#if askForPlcToken} 424 <SignThePapers migrator={migrator} newHandle={newHandle}/> 425 {/if} 426 + 427 + 428 + </div>
+3 -1
web-ui/src/routes/moover/[[pds]]/Captcha.svelte web-ui/src/lib/components/Captcha.svelte
··· 1 <script lang="ts"> 2 import {onMount} from 'svelte'; 3 4 interface CaptchaProps { 5 pdsUrl: string; ··· 21 let isLoading = $state(true); 22 23 24 const gateUrl = $derived( 25 - `${pdsUrl}/gate/signup?state=${encodeURIComponent(captcha_state)}&handle=${encodeURIComponent(handle)}&redirect_url=${encodeURIComponent(window.location.origin)}`, 26 ); 27 28 // Monitor iframe for URL changes
··· 1 <script lang="ts"> 2 import {onMount} from 'svelte'; 3 + import { browser } from '$app/environment'; 4 5 interface CaptchaProps { 6 pdsUrl: string; ··· 22 let isLoading = $state(true); 23 24 25 + 26 const gateUrl = $derived( 27 + `${pdsUrl}/gate/signup?state=${encodeURIComponent(captcha_state)}&handle=${encodeURIComponent(handle)}&redirect_url=${encodeURIComponent(browser ? window.location.origin : 'https://pdsmoover.com')}`, 28 ); 29 30 // Monitor iframe for URL changes
+7 -6
web-ui/src/routes/moover/[[pds]]/SignThePapers.svelte
··· 80 <form onsubmit="{signPlcOperation}"> 81 {#if !done} 82 <div> 83 - <h2>Please enter your PLC Token you received in an email</h2> 84 <div class="form-group"> 85 <label for="plc-token">PLC Token:</label> 86 <input type="text" id="plc-token" name="plc-token" bind:value={plcToken} required> 87 </div> 88 - <p style="text-align: left">You can now select to add a new Rotation Key during migration and sign up 89 - for PDS MOOver's free backup service. With a Rotation Key and backups if your new PDS ever goes down 90 - you can recover your account and it's data.</p> 91 <div class="form-group"> 92 <label for="rotation-key" class="moove-checkbox-label"> 93 <input bind:checked={createANewRotationKey} type="checkbox" id="rotation-key" ··· 165 166 {#if done} 167 <div class="status-message">Congratulations! You have MOOved to a new PDS! Remember to use 168 - your new PDS URL under "Hosting provider" when logging in on Bluesky. Can find more detail information 169 <a href={resolve('/info#cant-login')}>here.</a></div> 170 {:else } 171 <div> ··· 175 176 177 </form> 178 - </div>
··· 80 <form onsubmit="{signPlcOperation}"> 81 {#if !done} 82 <div> 83 + <h2>Please check your email attached to your previous account for a PLC token to enter below</h2> 84 <div class="form-group"> 85 <label for="plc-token">PLC Token:</label> 86 <input type="text" id="plc-token" name="plc-token" bind:value={plcToken} required> 87 </div> 88 + <p style="text-align: left"> 89 + Please check the boxes below if you would like to add a Rotation Key to your account and to sign up for PDS MOOver's free backup service. 90 + With a Rotation Key and backups if your new PDS ever goes down 91 + you can recover your account and it's data. This is not required but highly recommended.</p> 92 <div class="form-group"> 93 <label for="rotation-key" class="moove-checkbox-label"> 94 <input bind:checked={createANewRotationKey} type="checkbox" id="rotation-key" ··· 166 167 {#if done} 168 <div class="status-message">Congratulations! You have MOOved to a new PDS! Remember to use 169 + your new PDS URL under "Hosting provider" when logging in on Bluesky. If you cannot login or see "Your account is deactivated" please follow the directions here 170 <a href={resolve('/info#cant-login')}>here.</a></div> 171 {:else } 172 <div> ··· 176 177 178 </form> 179 + </div>