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

authored by baileytownsend.dev and committed by tangled.org 7254b408 515c34ff

+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>