From 454ee99be2dbf0a42b6dac2222993b9cf2fb16c4 Mon Sep 17 00:00:00 2001 From: Trezy Date: Mon, 6 Jul 2026 10:43:45 -0500 Subject: [PATCH] docs: add login, subscribe, and recommend Signed-off-by: Trezy --- bun.lock | 178 +++++++- packages/docs/next.config.mts | 1 + packages/docs/package.json | 2 + packages/docs/src/app/blog/[slug]/page.tsx | 8 +- .../app/oauth-client-metadata.json/route.ts | 18 + packages/docs/src/app/oauth/callback/page.tsx | 48 +++ .../src/components/engagement-actions.tsx | 403 ++++++++++++++++++ ...comments-loader.tsx => sequoia-loader.tsx} | 2 +- packages/docs/src/lib/atproto-oauth.ts | 28 ++ 9 files changed, 670 insertions(+), 18 deletions(-) create mode 100644 packages/docs/src/app/oauth-client-metadata.json/route.ts create mode 100644 packages/docs/src/app/oauth/callback/page.tsx create mode 100644 packages/docs/src/components/engagement-actions.tsx rename packages/docs/src/components/{sequoia-comments-loader.tsx => sequoia-loader.tsx} (76%) create mode 100644 packages/docs/src/lib/atproto-oauth.ts diff --git a/bun.lock b/bun.lock index 151e3c7..308e8c9 100644 --- a/bun.lock +++ b/bun.lock @@ -16,6 +16,8 @@ "name": "@happyview/docs", "version": "0.0.0", "dependencies": { + "@atproto/api": "^0.20.25", + "@atproto/oauth-client-browser": "^0.4.5", "@happyview/design-system": "workspace:*", "@tailwindcss/postcss": "^4.2.0", "@types/mdast": "^4.0.4", @@ -151,19 +153,19 @@ "@atproto-labs/handle-resolver-node": ["@atproto-labs/handle-resolver-node@0.1.25", "", { "dependencies": { "@atproto-labs/fetch-node": "0.2.0", "@atproto-labs/handle-resolver": "0.3.6", "@atproto/did": "0.3.0" } }, "sha512-NY9WYM2VLd3IuMGRkkmvGBg8xqVEaK/fitv1vD8SMXqFTekdpjOLCCyv7EFtqVHouzmDcL83VOvWRfHVa8V9Yw=="], - "@atproto-labs/identity-resolver": ["@atproto-labs/identity-resolver@0.3.6", "", { "dependencies": { "@atproto-labs/did-resolver": "0.2.6", "@atproto-labs/handle-resolver": "0.3.6" } }, "sha512-qoWqBDRobln0NR8L8dQjSp79E0chGkBhibEgxQa2f9WD+JbJdjQ0YvwwO5yeQn05pJoJmAwmI2wyJ45zjU7aWg=="], + "@atproto-labs/identity-resolver": ["@atproto-labs/identity-resolver@0.4.3", "", { "dependencies": { "@atproto-labs/did-resolver": "^0.3.4", "@atproto-labs/handle-resolver": "^0.4.4" } }, "sha512-3VfQxHA+p/+FlvusCcYYJR6GFrA0qYWgNlwfCnCbW7VaEWl2Ztf3jAbaa5ZHYNu1WBJ0hMhuYC67zgEI+dSZfQ=="], "@atproto-labs/pipe": ["@atproto-labs/pipe@0.1.1", "", {}, "sha512-hdNw2oUs2B6BN1lp+32pF7cp8EMKuIN5Qok2Vvv/aOpG/3tNSJ9YkvfI0k6Zd188LeDDYRUpYpxcoFIcGH/FNg=="], - "@atproto-labs/simple-store": ["@atproto-labs/simple-store@0.3.0", "", {}, "sha512-nOb6ONKBRJHRlukW1sVawUkBqReLlLx6hT35VS3imaNPwiXDxLnTK7lxw3Lrl9k5yugSBDQAkZAq3MPTEFSUBQ=="], + "@atproto-labs/simple-store": ["@atproto-labs/simple-store@0.4.3", "", {}, "sha512-ML1HAEtQIixkcU4FCGbZtAkoHTfmXDi63tNVuSSPG/cVUKyrUURg6Cr1bcfvbbkMTwRj9abEwa3JZR7UUYi4Ew=="], "@atproto-labs/simple-store-memory": ["@atproto-labs/simple-store-memory@0.1.4", "", { "dependencies": { "@atproto-labs/simple-store": "0.3.0", "lru-cache": "^10.2.0" } }, "sha512-3mKY4dP8I7yKPFj9VKpYyCRzGJOi5CEpOLPlRhoJyLmgs3J4RzDrjn323Oakjz2Aj2JzRU/AIvWRAZVhpYNJHw=="], - "@atproto/api": ["@atproto/api@0.18.21", "", { "dependencies": { "@atproto/common-web": "^0.4.16", "@atproto/lexicon": "^0.6.1", "@atproto/syntax": "^0.4.3", "@atproto/xrpc": "^0.7.7", "await-lock": "^2.2.2", "multiformats": "^9.9.0", "tlds": "^1.234.0", "zod": "^3.23.8" } }, "sha512-s35MIJerGT/pKe2xJtKKswqlIr/ola2r2iURBKBL0Mk1OKe6jP4YvTMh1N2d2PEANFzNNTbKoDaLfJPo2Uvc/w=="], + "@atproto/api": ["@atproto/api@0.20.25", "", { "dependencies": { "@atproto/common-web": "^0.5.3", "@atproto/lexicon": "^0.7.4", "@atproto/syntax": "^0.6.4", "@atproto/xrpc": "^0.8.3", "await-lock": "^3.0.0", "multiformats": "^13.0.0", "tlds": "^1.234.0", "zod": "^3.23.8" } }, "sha512-PTwt6X0U45C9vikr8NRi0Qzcep9VqJet52HtfcxgG9R7ofRHxqLVPzfVuN/f2xOaYM6H5IG/Nk1E9kXZcI0mSQ=="], "@atproto/common": ["@atproto/common@0.5.16", "", { "dependencies": { "@atproto/common-web": "^0.4.20", "@atproto/lex-cbor": "^0.0.16", "@atproto/lex-data": "^0.0.15", "multiformats": "^9.9.0", "pino": "^8.21.0" } }, "sha512-DTWgaVlDJN3zDxJ3agZK3pbiSZc+z8QQe9iy15sIuorLrceIp4kHXMO/QqjWBXnmLVTd6+/5BVDzex5amYc0rg=="], - "@atproto/common-web": ["@atproto/common-web@0.4.21", "", { "dependencies": { "@atproto/lex-data": "^0.0.15", "@atproto/lex-json": "^0.0.16", "@atproto/syntax": "^0.5.4", "zod": "^3.23.8" } }, "sha512-Odq+wdk3YNasGCjjlpl3bCIPvqYHige5DLfMkIffNv/2PI/iIj5ZvAvMvJlJ59OhReKSxtpI0invx5UQPc3+fw=="], + "@atproto/common-web": ["@atproto/common-web@0.5.3", "", { "dependencies": { "@atproto/lex-data": "^0.1.4", "@atproto/lex-json": "^0.1.3", "@atproto/syntax": "^0.6.4", "zod": "^3.23.8" } }, "sha512-FkMhOcNv1y7r5984+zXB+uMN4zJ4QFLEbZrYyQo6bNCf/Kfav/pEHXXENlaZEOweq2NYXf+tr2giMssBuM9u5A=="], "@atproto/crypto": ["@atproto/crypto@0.4.5", "", { "dependencies": { "@noble/curves": "^1.7.0", "@noble/hashes": "^1.6.1", "uint8arrays": "3.0.0" } }, "sha512-n40aKkMoCatP0u9Yvhrdk6fXyOHFDDbkdm4h4HCyWW+KlKl8iXfD5iV+ECq+w5BM+QH25aIpt3/j6EUNerhLxw=="], @@ -195,19 +197,21 @@ "@atproto/lex-schema": ["@atproto/lex-schema@0.0.19", "", { "dependencies": { "@atproto/lex-data": "^0.0.15", "@atproto/syntax": "^0.5.4", "@standard-schema/spec": "^1.1.0", "iso-datestring-validator": "^2.2.2", "tslib": "^2.8.1" } }, "sha512-rEVTnbgYx4FwcvfrfnuACXvBcdkb4wqSOALG9leW302YIPB+HLRSwpBVC0iLun+yozEKg7BJdwiS0bvfje6tcQ=="], - "@atproto/lexicon": ["@atproto/lexicon@0.6.2", "", { "dependencies": { "@atproto/common-web": "^0.4.18", "@atproto/syntax": "^0.5.0", "iso-datestring-validator": "^2.2.2", "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-p3Ly6hinVZW0ETuAXZMeUGwuMm3g8HvQMQ41yyEE6AL0hAkfeKFaZKos6BdBrr6CjkpbrDZqE8M+5+QOceysMw=="], + "@atproto/lexicon": ["@atproto/lexicon@0.7.4", "", { "dependencies": { "@atproto/common-web": "^0.5.3", "@atproto/syntax": "^0.6.4", "multiformats": "^13.0.0", "zod": "^3.23.8" } }, "sha512-ulk4RGwMBp4vbkTOZcIwZJeTEPlj3PImOnx9TqxSxMDnBdySxarpd0Aprg7+iAvGyKTsMcrYHpeoLukZaquk0A=="], - "@atproto/oauth-client": ["@atproto/oauth-client@0.6.1", "", { "dependencies": { "@atproto-labs/did-resolver": "^0.2.6", "@atproto-labs/fetch": "^0.2.3", "@atproto-labs/handle-resolver": "^0.3.6", "@atproto-labs/identity-resolver": "^0.3.6", "@atproto-labs/simple-store": "^0.3.0", "@atproto-labs/simple-store-memory": "^0.1.4", "@atproto/did": "^0.3.0", "@atproto/jwk": "^0.6.0", "@atproto/oauth-types": "^0.6.3", "@atproto/xrpc": "^0.7.7", "core-js": "^3", "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-QTLbEFyv7EJuwJf4A8IZnsylK5wwrzrSsxy0INcZf9zktPVQvgckWhSvbfK8alp60M+rwWfQQAlodcCF4WB78A=="], + "@atproto/oauth-client": ["@atproto/oauth-client@0.7.7", "", { "dependencies": { "@atproto-labs/did-resolver": "^0.3.4", "@atproto-labs/fetch": "^0.3.3", "@atproto-labs/handle-resolver": "^0.4.4", "@atproto-labs/identity-resolver": "^0.4.3", "@atproto-labs/simple-store": "^0.4.3", "@atproto-labs/simple-store-memory": "^0.2.3", "@atproto/did": "^0.5.3", "@atproto/jwk": "^0.7.3", "@atproto/oauth-types": "^0.7.4", "@atproto/xrpc": "^0.8.3", "core-js": "^3", "multiformats": "^13.0.0", "zod": "^3.23.8" } }, "sha512-G9KEHtAaLhQsnIcriPULsEITC32tnjl5TnRYpMtxXj6A2rlMsgbfftC4pzG7g/v1X/Ap8VoSBZaNsSQ5PQ9xzQ=="], + + "@atproto/oauth-client-browser": ["@atproto/oauth-client-browser@0.4.5", "", { "dependencies": { "@atproto-labs/did-resolver": "^0.3.4", "@atproto-labs/handle-resolver": "^0.4.4", "@atproto-labs/simple-store": "^0.4.3", "@atproto/did": "^0.5.3", "@atproto/jwk": "^0.7.3", "@atproto/jwk-webcrypto": "^0.3.3", "@atproto/oauth-client": "^0.7.7", "@atproto/oauth-types": "^0.7.4", "core-js": "^3" } }, "sha512-8DpwV9b9Kb1YBUYRFNWU4nyfo/tfy5s7ORaBYGR92EFsHgk8LcWnJwtqDMQUcqnEn1NaUmP7ntUblILqP8yTUw=="], "@atproto/oauth-client-node": ["@atproto/oauth-client-node@0.3.17", "", { "dependencies": { "@atproto-labs/did-resolver": "^0.2.6", "@atproto-labs/handle-resolver-node": "^0.1.25", "@atproto-labs/simple-store": "^0.3.0", "@atproto/did": "^0.3.0", "@atproto/jwk": "^0.6.0", "@atproto/jwk-jose": "^0.1.11", "@atproto/jwk-webcrypto": "^0.2.0", "@atproto/oauth-client": "^0.6.0", "@atproto/oauth-types": "^0.6.3" } }, "sha512-67LNuKAlC35Exe7CB5S0QCAnEqr6fKV9Nvp64jAHFof1N+Vc9Ltt1K9oekE5Ctf7dvpGByrHRF0noUw9l9sWLA=="], - "@atproto/oauth-types": ["@atproto/oauth-types@0.6.3", "", { "dependencies": { "@atproto/did": "^0.3.0", "@atproto/jwk": "^0.6.0", "zod": "^3.23.8" } }, "sha512-jdKuoPknJuh/WjI+mYk7agSbx9mNVMbS6Dr3k1z2YMY2oRiCQjxYBuo4MLKATbxj05nMQaZRWlHRUazoAu5Cng=="], + "@atproto/oauth-types": ["@atproto/oauth-types@0.7.4", "", { "dependencies": { "@atproto/did": "^0.5.3", "@atproto/jwk": "^0.7.3", "zod": "^3.23.8" } }, "sha512-LI6fTaj+G3uPptKADJyiQl36qCFgpBUAzAzCCJUOgavdTq2p3ZY+lz/YjwZjyXcef8fEr8LPT9cMDbHhrvs0og=="], "@atproto/repo": ["@atproto/repo@0.9.1", "", { "dependencies": { "@atproto/common": "^0.5.16", "@atproto/common-web": "^0.4.20", "@atproto/crypto": "^0.4.5", "@atproto/lex-cbor": "^0.0.16", "@atproto/lex-data": "^0.0.15", "@atproto/syntax": "^0.5.3", "varint": "^6.0.0", "zod": "^3.23.8" } }, "sha512-++MUbILqVraIpTiTvixGZK9RK/fIfa2nQvRzT1mrSX6Kd/r1XKTzqz0wCfZkSNU+MsWmQPkvmmaykYBE00RSgg=="], - "@atproto/syntax": ["@atproto/syntax@0.4.3", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-YoZUz40YAJr5nPwvCDWgodEOlt5IftZqPJvA0JDWjuZKD8yXddTwSzXSaKQAzGOpuM+/A3uXRtPzJJqlScc+iA=="], + "@atproto/syntax": ["@atproto/syntax@0.6.4", "", { "dependencies": { "iso-datestring-validator": "^2.2.2", "tslib": "^2.8.1" } }, "sha512-ELgpShRGMF65cvLXcoMCZFL0HBzy67yz/Nlhox3yOtTh120B09KjjvZYXhMysVog3nUJqv2EW5rf1VRYCeM/hw=="], - "@atproto/xrpc": ["@atproto/xrpc@0.7.7", "", { "dependencies": { "@atproto/lexicon": "^0.6.0", "zod": "^3.23.8" } }, "sha512-K1ZyO/BU8JNtXX5dmPp7b5UrkLMMqpsIa/Lrj5D3Su+j1Xwq1m6QJ2XJ1AgjEjkI1v4Muzm7klianLE6XGxtmA=="], + "@atproto/xrpc": ["@atproto/xrpc@0.8.3", "", { "dependencies": { "@atproto/lexicon": "^0.7.4", "zod": "^3.23.8" } }, "sha512-0gUGN71+bSqV3PI5U4cQ4fdnw4nI0eD6czHDQ6jB7hMYBwNcJpwAyfA9W+C1G1wayIvP0SIap/M0H/pSKDWFIQ=="], "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], @@ -751,7 +755,7 @@ "atomic-sleep": ["atomic-sleep@1.0.0", "", {}, "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ=="], - "await-lock": ["await-lock@2.2.2", "", {}, "sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw=="], + "await-lock": ["await-lock@3.0.0", "", {}, "sha512-eO6fLiSnrJrMdjWMNK8zbVRXPs2TKJg78iKZd9wDpN3na5tcoV6EoeiOlMgk2QaAQ1gIrK1YuMsJHXWqz89tSA=="], "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], @@ -1445,7 +1449,7 @@ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - "multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], + "multiformats": ["multiformats@13.4.2", "", {}, "sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ=="], "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], @@ -1919,40 +1923,92 @@ "@antfu/install-pkg/tinyexec": ["tinyexec@1.1.1", "", {}, "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg=="], + "@atproto-labs/did-resolver/@atproto-labs/simple-store": ["@atproto-labs/simple-store@0.3.0", "", {}, "sha512-nOb6ONKBRJHRlukW1sVawUkBqReLlLx6hT35VS3imaNPwiXDxLnTK7lxw3Lrl9k5yugSBDQAkZAq3MPTEFSUBQ=="], + "@atproto-labs/did-resolver/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "@atproto-labs/fetch-node/undici": ["undici@6.25.0", "", {}, "sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg=="], + "@atproto-labs/handle-resolver/@atproto-labs/simple-store": ["@atproto-labs/simple-store@0.3.0", "", {}, "sha512-nOb6ONKBRJHRlukW1sVawUkBqReLlLx6hT35VS3imaNPwiXDxLnTK7lxw3Lrl9k5yugSBDQAkZAq3MPTEFSUBQ=="], + "@atproto-labs/handle-resolver/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "@atproto-labs/identity-resolver/@atproto-labs/did-resolver": ["@atproto-labs/did-resolver@0.3.4", "", { "dependencies": { "@atproto-labs/fetch": "^0.3.3", "@atproto-labs/pipe": "^0.2.3", "@atproto-labs/simple-store": "^0.4.3", "@atproto-labs/simple-store-memory": "^0.2.3", "@atproto/did": "^0.5.3", "zod": "^3.23.8" } }, "sha512-nBECoVG59NfbYthayxfR0s1dLFVdN+RKMaL0p0uaNX/U1SAETksN6Yydmr4oWOKSkyyU3GO9XZeo1yzwHnRcZw=="], + + "@atproto-labs/identity-resolver/@atproto-labs/handle-resolver": ["@atproto-labs/handle-resolver@0.4.4", "", { "dependencies": { "@atproto-labs/simple-store": "^0.4.3", "@atproto-labs/simple-store-memory": "^0.2.3", "@atproto/did": "^0.5.3", "zod": "^3.23.8" } }, "sha512-fQIcAQrsqmixI0Nt/3RRfBr/NLeK58lMFVCtlLoenjVOiVmI1xPBKvfktYTY3yvHcvMbo07r/RiE9ktG9nfCLQ=="], + + "@atproto-labs/simple-store-memory/@atproto-labs/simple-store": ["@atproto-labs/simple-store@0.3.0", "", {}, "sha512-nOb6ONKBRJHRlukW1sVawUkBqReLlLx6hT35VS3imaNPwiXDxLnTK7lxw3Lrl9k5yugSBDQAkZAq3MPTEFSUBQ=="], + "@atproto-labs/simple-store-memory/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], "@atproto/api/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "@atproto/common-web/@atproto/syntax": ["@atproto/syntax@0.5.4", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-9XJOpMAgsGFxMEIp8nJ8AIWv+krrY1xQMj+wULbbXhQztQV+9aZ0TbG9Jtn3Op2or8Kr6OqyWR4ga9Z189kKDw=="], + "@atproto/common/@atproto/common-web": ["@atproto/common-web@0.4.21", "", { "dependencies": { "@atproto/lex-data": "^0.0.15", "@atproto/lex-json": "^0.0.16", "@atproto/syntax": "^0.5.4", "zod": "^3.23.8" } }, "sha512-Odq+wdk3YNasGCjjlpl3bCIPvqYHige5DLfMkIffNv/2PI/iIj5ZvAvMvJlJ59OhReKSxtpI0invx5UQPc3+fw=="], + + "@atproto/common/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], + + "@atproto/common-web/@atproto/lex-data": ["@atproto/lex-data@0.1.4", "", { "dependencies": { "multiformats": "^13.0.0", "tslib": "^2.8.1", "uint8arrays": "^5.0.0", "unicode-segmenter": "^0.14.0" } }, "sha512-f9U95sk0zUtxHktvK59peU+Shd0cIUYV68p//GS7sfdkAxUIeaspvX6CY+Quv9Oa4aozmsXI52SjaNn1wuU8RQ=="], + + "@atproto/common-web/@atproto/lex-json": ["@atproto/lex-json@0.1.3", "", { "dependencies": { "@atproto/lex-data": "^0.1.4", "tslib": "^2.8.1" } }, "sha512-Ch2w9bCLFOwWINFFxpZo6DBW7+ZxkehciU3P8N94gSyENLe3/5WWXHdHvkiH7EXZrpI7fKY8nVWn4GIL0ttqxw=="], "@atproto/common-web/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "@atproto/did/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "@atproto/jwk/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], + "@atproto/jwk/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "@atproto/jwk-webcrypto/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "@atproto/lex-data/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], + "@atproto/lex-installer/@atproto/syntax": ["@atproto/syntax@0.5.4", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-9XJOpMAgsGFxMEIp8nJ8AIWv+krrY1xQMj+wULbbXhQztQV+9aZ0TbG9Jtn3Op2or8Kr6OqyWR4ga9Z189kKDw=="], "@atproto/lex-resolver/@atproto/syntax": ["@atproto/syntax@0.5.4", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-9XJOpMAgsGFxMEIp8nJ8AIWv+krrY1xQMj+wULbbXhQztQV+9aZ0TbG9Jtn3Op2or8Kr6OqyWR4ga9Z189kKDw=="], "@atproto/lex-schema/@atproto/syntax": ["@atproto/syntax@0.5.4", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-9XJOpMAgsGFxMEIp8nJ8AIWv+krrY1xQMj+wULbbXhQztQV+9aZ0TbG9Jtn3Op2or8Kr6OqyWR4ga9Z189kKDw=="], - "@atproto/lexicon/@atproto/syntax": ["@atproto/syntax@0.5.4", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-9XJOpMAgsGFxMEIp8nJ8AIWv+krrY1xQMj+wULbbXhQztQV+9aZ0TbG9Jtn3Op2or8Kr6OqyWR4ga9Z189kKDw=="], - "@atproto/lexicon/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "@atproto/oauth-client/@atproto-labs/did-resolver": ["@atproto-labs/did-resolver@0.3.4", "", { "dependencies": { "@atproto-labs/fetch": "^0.3.3", "@atproto-labs/pipe": "^0.2.3", "@atproto-labs/simple-store": "^0.4.3", "@atproto-labs/simple-store-memory": "^0.2.3", "@atproto/did": "^0.5.3", "zod": "^3.23.8" } }, "sha512-nBECoVG59NfbYthayxfR0s1dLFVdN+RKMaL0p0uaNX/U1SAETksN6Yydmr4oWOKSkyyU3GO9XZeo1yzwHnRcZw=="], + + "@atproto/oauth-client/@atproto-labs/fetch": ["@atproto-labs/fetch@0.3.3", "", { "dependencies": { "@atproto-labs/pipe": "^0.2.3" } }, "sha512-2gABLf0VEI86Sxo6YhGKQYK1tGhTZ4y+3TrCWputnupEZxuS/hw6+pFw9ceXZ3v9nnMNthzsAEcaAQ3V/tXsqg=="], + + "@atproto/oauth-client/@atproto-labs/handle-resolver": ["@atproto-labs/handle-resolver@0.4.4", "", { "dependencies": { "@atproto-labs/simple-store": "^0.4.3", "@atproto-labs/simple-store-memory": "^0.2.3", "@atproto/did": "^0.5.3", "zod": "^3.23.8" } }, "sha512-fQIcAQrsqmixI0Nt/3RRfBr/NLeK58lMFVCtlLoenjVOiVmI1xPBKvfktYTY3yvHcvMbo07r/RiE9ktG9nfCLQ=="], + + "@atproto/oauth-client/@atproto-labs/simple-store-memory": ["@atproto-labs/simple-store-memory@0.2.3", "", { "dependencies": { "@atproto-labs/simple-store": "^0.4.3", "lru-cache": "^10.2.0" } }, "sha512-RtL48op8Db/QFNbW+9Y+Os6DOMqysOkoG5QelTZ0qcZt/j0pUBY8v2zSr5/faVJ5Y30h1cONxMydV48tVWf8pg=="], + + "@atproto/oauth-client/@atproto/did": ["@atproto/did@0.5.3", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-nKcdu5qB9iNJFaBeQOQUJ+6mA1npFcZ3DmD0xB+etkMRd/3UvOQql/CvcMZaYzl+eGoVs1JDdEsvoZz+idfhaw=="], + + "@atproto/oauth-client/@atproto/jwk": ["@atproto/jwk@0.7.3", "", { "dependencies": { "multiformats": "^13.0.0", "zod": "^3.23.8" } }, "sha512-YK0rObYOZ4GphDvNtLyHnq6Z4sapSUESLKU6ty+uoAwK20NKBHep1rNfmiD0IurgZ2jnd3K9Rii49R51Qj4TEg=="], + "@atproto/oauth-client/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "@atproto/oauth-client-browser/@atproto-labs/did-resolver": ["@atproto-labs/did-resolver@0.3.4", "", { "dependencies": { "@atproto-labs/fetch": "^0.3.3", "@atproto-labs/pipe": "^0.2.3", "@atproto-labs/simple-store": "^0.4.3", "@atproto-labs/simple-store-memory": "^0.2.3", "@atproto/did": "^0.5.3", "zod": "^3.23.8" } }, "sha512-nBECoVG59NfbYthayxfR0s1dLFVdN+RKMaL0p0uaNX/U1SAETksN6Yydmr4oWOKSkyyU3GO9XZeo1yzwHnRcZw=="], + + "@atproto/oauth-client-browser/@atproto-labs/handle-resolver": ["@atproto-labs/handle-resolver@0.4.4", "", { "dependencies": { "@atproto-labs/simple-store": "^0.4.3", "@atproto-labs/simple-store-memory": "^0.2.3", "@atproto/did": "^0.5.3", "zod": "^3.23.8" } }, "sha512-fQIcAQrsqmixI0Nt/3RRfBr/NLeK58lMFVCtlLoenjVOiVmI1xPBKvfktYTY3yvHcvMbo07r/RiE9ktG9nfCLQ=="], + + "@atproto/oauth-client-browser/@atproto/did": ["@atproto/did@0.5.3", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-nKcdu5qB9iNJFaBeQOQUJ+6mA1npFcZ3DmD0xB+etkMRd/3UvOQql/CvcMZaYzl+eGoVs1JDdEsvoZz+idfhaw=="], + + "@atproto/oauth-client-browser/@atproto/jwk": ["@atproto/jwk@0.7.3", "", { "dependencies": { "multiformats": "^13.0.0", "zod": "^3.23.8" } }, "sha512-YK0rObYOZ4GphDvNtLyHnq6Z4sapSUESLKU6ty+uoAwK20NKBHep1rNfmiD0IurgZ2jnd3K9Rii49R51Qj4TEg=="], + + "@atproto/oauth-client-browser/@atproto/jwk-webcrypto": ["@atproto/jwk-webcrypto@0.3.3", "", { "dependencies": { "@atproto/jwk": "^0.7.3", "@atproto/jwk-jose": "^0.2.3", "zod": "^3.23.8" } }, "sha512-yOLro2nh8IFjLpN7VQP82NXLhlOcXrglU8mTJn1vHHjdv8M3ii8e9/ePAlR46cwBfCp0qc8kopcGp9wEjDcn9A=="], + + "@atproto/oauth-client-node/@atproto-labs/simple-store": ["@atproto-labs/simple-store@0.3.0", "", {}, "sha512-nOb6ONKBRJHRlukW1sVawUkBqReLlLx6hT35VS3imaNPwiXDxLnTK7lxw3Lrl9k5yugSBDQAkZAq3MPTEFSUBQ=="], + + "@atproto/oauth-client-node/@atproto/oauth-client": ["@atproto/oauth-client@0.6.1", "", { "dependencies": { "@atproto-labs/did-resolver": "^0.2.6", "@atproto-labs/fetch": "^0.2.3", "@atproto-labs/handle-resolver": "^0.3.6", "@atproto-labs/identity-resolver": "^0.3.6", "@atproto-labs/simple-store": "^0.3.0", "@atproto-labs/simple-store-memory": "^0.1.4", "@atproto/did": "^0.3.0", "@atproto/jwk": "^0.6.0", "@atproto/oauth-types": "^0.6.3", "@atproto/xrpc": "^0.7.7", "core-js": "^3", "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-QTLbEFyv7EJuwJf4A8IZnsylK5wwrzrSsxy0INcZf9zktPVQvgckWhSvbfK8alp60M+rwWfQQAlodcCF4WB78A=="], + + "@atproto/oauth-client-node/@atproto/oauth-types": ["@atproto/oauth-types@0.6.3", "", { "dependencies": { "@atproto/did": "^0.3.0", "@atproto/jwk": "^0.6.0", "zod": "^3.23.8" } }, "sha512-jdKuoPknJuh/WjI+mYk7agSbx9mNVMbS6Dr3k1z2YMY2oRiCQjxYBuo4MLKATbxj05nMQaZRWlHRUazoAu5Cng=="], + + "@atproto/oauth-types/@atproto/did": ["@atproto/did@0.5.3", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-nKcdu5qB9iNJFaBeQOQUJ+6mA1npFcZ3DmD0xB+etkMRd/3UvOQql/CvcMZaYzl+eGoVs1JDdEsvoZz+idfhaw=="], + + "@atproto/oauth-types/@atproto/jwk": ["@atproto/jwk@0.7.3", "", { "dependencies": { "multiformats": "^13.0.0", "zod": "^3.23.8" } }, "sha512-YK0rObYOZ4GphDvNtLyHnq6Z4sapSUESLKU6ty+uoAwK20NKBHep1rNfmiD0IurgZ2jnd3K9Rii49R51Qj4TEg=="], + "@atproto/oauth-types/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "@atproto/repo/@atproto/common-web": ["@atproto/common-web@0.4.21", "", { "dependencies": { "@atproto/lex-data": "^0.0.15", "@atproto/lex-json": "^0.0.16", "@atproto/syntax": "^0.5.4", "zod": "^3.23.8" } }, "sha512-Odq+wdk3YNasGCjjlpl3bCIPvqYHige5DLfMkIffNv/2PI/iIj5ZvAvMvJlJ59OhReKSxtpI0invx5UQPc3+fw=="], + "@atproto/repo/@atproto/syntax": ["@atproto/syntax@0.5.4", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-9XJOpMAgsGFxMEIp8nJ8AIWv+krrY1xQMj+wULbbXhQztQV+9aZ0TbG9Jtn3Op2or8Kr6OqyWR4ga9Z189kKDw=="], "@atproto/repo/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], @@ -2351,6 +2407,8 @@ "semantic-release-monorepo/p-each-series": ["p-each-series@2.2.0", "", {}, "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA=="], + "sequoia-cli/@atproto/api": ["@atproto/api@0.18.21", "", { "dependencies": { "@atproto/common-web": "^0.4.16", "@atproto/lexicon": "^0.6.1", "@atproto/syntax": "^0.4.3", "@atproto/xrpc": "^0.7.7", "await-lock": "^2.2.2", "multiformats": "^9.9.0", "tlds": "^1.234.0", "zod": "^3.23.8" } }, "sha512-s35MIJerGT/pKe2xJtKKswqlIr/ola2r2iURBKBL0Mk1OKe6jP4YvTMh1N2d2PEANFzNNTbKoDaLfJPo2Uvc/w=="], + "signale/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="], "signale/figures": ["figures@2.0.0", "", { "dependencies": { "escape-string-regexp": "^1.0.5" } }, "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA=="], @@ -2369,10 +2427,70 @@ "tsup/tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], + "uint8arrays/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], + "wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "@atproto-labs/identity-resolver/@atproto-labs/did-resolver/@atproto-labs/fetch": ["@atproto-labs/fetch@0.3.3", "", { "dependencies": { "@atproto-labs/pipe": "^0.2.3" } }, "sha512-2gABLf0VEI86Sxo6YhGKQYK1tGhTZ4y+3TrCWputnupEZxuS/hw6+pFw9ceXZ3v9nnMNthzsAEcaAQ3V/tXsqg=="], + + "@atproto-labs/identity-resolver/@atproto-labs/did-resolver/@atproto-labs/pipe": ["@atproto-labs/pipe@0.2.3", "", {}, "sha512-hsjkaKGdhEGKhXuOOfIeYyZSQZfw007AXQJak/QTd9pLY1wHUJG85a9+u13xoMeav95gHkBRzswti7+kqsxgdw=="], + + "@atproto-labs/identity-resolver/@atproto-labs/did-resolver/@atproto-labs/simple-store-memory": ["@atproto-labs/simple-store-memory@0.2.3", "", { "dependencies": { "@atproto-labs/simple-store": "^0.4.3", "lru-cache": "^10.2.0" } }, "sha512-RtL48op8Db/QFNbW+9Y+Os6DOMqysOkoG5QelTZ0qcZt/j0pUBY8v2zSr5/faVJ5Y30h1cONxMydV48tVWf8pg=="], + + "@atproto-labs/identity-resolver/@atproto-labs/did-resolver/@atproto/did": ["@atproto/did@0.5.3", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-nKcdu5qB9iNJFaBeQOQUJ+6mA1npFcZ3DmD0xB+etkMRd/3UvOQql/CvcMZaYzl+eGoVs1JDdEsvoZz+idfhaw=="], + + "@atproto-labs/identity-resolver/@atproto-labs/did-resolver/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + + "@atproto-labs/identity-resolver/@atproto-labs/handle-resolver/@atproto-labs/simple-store-memory": ["@atproto-labs/simple-store-memory@0.2.3", "", { "dependencies": { "@atproto-labs/simple-store": "^0.4.3", "lru-cache": "^10.2.0" } }, "sha512-RtL48op8Db/QFNbW+9Y+Os6DOMqysOkoG5QelTZ0qcZt/j0pUBY8v2zSr5/faVJ5Y30h1cONxMydV48tVWf8pg=="], + + "@atproto-labs/identity-resolver/@atproto-labs/handle-resolver/@atproto/did": ["@atproto/did@0.5.3", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-nKcdu5qB9iNJFaBeQOQUJ+6mA1npFcZ3DmD0xB+etkMRd/3UvOQql/CvcMZaYzl+eGoVs1JDdEsvoZz+idfhaw=="], + + "@atproto-labs/identity-resolver/@atproto-labs/handle-resolver/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + + "@atproto/common-web/@atproto/lex-data/uint8arrays": ["uint8arrays@5.1.1", "", { "dependencies": { "multiformats": "^13.0.0" } }, "sha512-9muQwa4wZG4dKi9gMAIBtnk2Pw87SRpvWTH6lOGm19V2Uqxr4uomUf2PGqPnWc+qs06sN8owUU4jfcoWOcfwVQ=="], + + "@atproto/common/@atproto/common-web/@atproto/syntax": ["@atproto/syntax@0.5.4", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-9XJOpMAgsGFxMEIp8nJ8AIWv+krrY1xQMj+wULbbXhQztQV+9aZ0TbG9Jtn3Op2or8Kr6OqyWR4ga9Z189kKDw=="], + + "@atproto/common/@atproto/common-web/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + + "@atproto/oauth-client-browser/@atproto-labs/did-resolver/@atproto-labs/fetch": ["@atproto-labs/fetch@0.3.3", "", { "dependencies": { "@atproto-labs/pipe": "^0.2.3" } }, "sha512-2gABLf0VEI86Sxo6YhGKQYK1tGhTZ4y+3TrCWputnupEZxuS/hw6+pFw9ceXZ3v9nnMNthzsAEcaAQ3V/tXsqg=="], + + "@atproto/oauth-client-browser/@atproto-labs/did-resolver/@atproto-labs/pipe": ["@atproto-labs/pipe@0.2.3", "", {}, "sha512-hsjkaKGdhEGKhXuOOfIeYyZSQZfw007AXQJak/QTd9pLY1wHUJG85a9+u13xoMeav95gHkBRzswti7+kqsxgdw=="], + + "@atproto/oauth-client-browser/@atproto-labs/did-resolver/@atproto-labs/simple-store-memory": ["@atproto-labs/simple-store-memory@0.2.3", "", { "dependencies": { "@atproto-labs/simple-store": "^0.4.3", "lru-cache": "^10.2.0" } }, "sha512-RtL48op8Db/QFNbW+9Y+Os6DOMqysOkoG5QelTZ0qcZt/j0pUBY8v2zSr5/faVJ5Y30h1cONxMydV48tVWf8pg=="], + + "@atproto/oauth-client-browser/@atproto-labs/did-resolver/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + + "@atproto/oauth-client-browser/@atproto-labs/handle-resolver/@atproto-labs/simple-store-memory": ["@atproto-labs/simple-store-memory@0.2.3", "", { "dependencies": { "@atproto-labs/simple-store": "^0.4.3", "lru-cache": "^10.2.0" } }, "sha512-RtL48op8Db/QFNbW+9Y+Os6DOMqysOkoG5QelTZ0qcZt/j0pUBY8v2zSr5/faVJ5Y30h1cONxMydV48tVWf8pg=="], + + "@atproto/oauth-client-browser/@atproto-labs/handle-resolver/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + + "@atproto/oauth-client-browser/@atproto/did/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + + "@atproto/oauth-client-browser/@atproto/jwk/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + + "@atproto/oauth-client-browser/@atproto/jwk-webcrypto/@atproto/jwk-jose": ["@atproto/jwk-jose@0.2.3", "", { "dependencies": { "@atproto/jwk": "^0.7.3", "jose": "^5.2.0" } }, "sha512-y6V+G9qwsKwmMs7eIpSFJy62S/e6oEiGxnhysLPZ2S8m86/Ps/6vqEjTZqYttlc2NufnJnjzS7XQxY40Q0rVsg=="], + + "@atproto/oauth-client-browser/@atproto/jwk-webcrypto/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + + "@atproto/oauth-client-node/@atproto/oauth-client/@atproto-labs/identity-resolver": ["@atproto-labs/identity-resolver@0.3.6", "", { "dependencies": { "@atproto-labs/did-resolver": "0.2.6", "@atproto-labs/handle-resolver": "0.3.6" } }, "sha512-qoWqBDRobln0NR8L8dQjSp79E0chGkBhibEgxQa2f9WD+JbJdjQ0YvwwO5yeQn05pJoJmAwmI2wyJ45zjU7aWg=="], + + "@atproto/oauth-client-node/@atproto/oauth-client/@atproto/xrpc": ["@atproto/xrpc@0.7.7", "", { "dependencies": { "@atproto/lexicon": "^0.6.0", "zod": "^3.23.8" } }, "sha512-K1ZyO/BU8JNtXX5dmPp7b5UrkLMMqpsIa/Lrj5D3Su+j1Xwq1m6QJ2XJ1AgjEjkI1v4Muzm7klianLE6XGxtmA=="], + + "@atproto/oauth-client-node/@atproto/oauth-client/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], + + "@atproto/oauth-client-node/@atproto/oauth-client/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + + "@atproto/oauth-client-node/@atproto/oauth-types/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + + "@atproto/oauth-client/@atproto-labs/did-resolver/@atproto-labs/pipe": ["@atproto-labs/pipe@0.2.3", "", {}, "sha512-hsjkaKGdhEGKhXuOOfIeYyZSQZfw007AXQJak/QTd9pLY1wHUJG85a9+u13xoMeav95gHkBRzswti7+kqsxgdw=="], + + "@atproto/oauth-client/@atproto-labs/fetch/@atproto-labs/pipe": ["@atproto-labs/pipe@0.2.3", "", {}, "sha512-hsjkaKGdhEGKhXuOOfIeYyZSQZfw007AXQJak/QTd9pLY1wHUJG85a9+u13xoMeav95gHkBRzswti7+kqsxgdw=="], + + "@atproto/oauth-client/@atproto-labs/simple-store-memory/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + "@semantic-release/github/aggregate-error/clean-stack": ["clean-stack@5.3.0", "", { "dependencies": { "escape-string-regexp": "5.0.0" } }, "sha512-9ngPTOhYGQqNVSfeJkYXHmF7AGWp4/nN5D/QqNQs3Dvxd1Kk/WpjHfNujKHYUQ/5CoGyOyFNoWSPk5afzP0QVg=="], "@semantic-release/github/aggregate-error/indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="], @@ -2461,6 +2579,20 @@ "semantic-release/yargs/yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], + "sequoia-cli/@atproto/api/@atproto/common-web": ["@atproto/common-web@0.4.21", "", { "dependencies": { "@atproto/lex-data": "^0.0.15", "@atproto/lex-json": "^0.0.16", "@atproto/syntax": "^0.5.4", "zod": "^3.23.8" } }, "sha512-Odq+wdk3YNasGCjjlpl3bCIPvqYHige5DLfMkIffNv/2PI/iIj5ZvAvMvJlJ59OhReKSxtpI0invx5UQPc3+fw=="], + + "sequoia-cli/@atproto/api/@atproto/lexicon": ["@atproto/lexicon@0.6.2", "", { "dependencies": { "@atproto/common-web": "^0.4.18", "@atproto/syntax": "^0.5.0", "iso-datestring-validator": "^2.2.2", "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-p3Ly6hinVZW0ETuAXZMeUGwuMm3g8HvQMQ41yyEE6AL0hAkfeKFaZKos6BdBrr6CjkpbrDZqE8M+5+QOceysMw=="], + + "sequoia-cli/@atproto/api/@atproto/syntax": ["@atproto/syntax@0.4.3", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-YoZUz40YAJr5nPwvCDWgodEOlt5IftZqPJvA0JDWjuZKD8yXddTwSzXSaKQAzGOpuM+/A3uXRtPzJJqlScc+iA=="], + + "sequoia-cli/@atproto/api/@atproto/xrpc": ["@atproto/xrpc@0.7.7", "", { "dependencies": { "@atproto/lexicon": "^0.6.0", "zod": "^3.23.8" } }, "sha512-K1ZyO/BU8JNtXX5dmPp7b5UrkLMMqpsIa/Lrj5D3Su+j1Xwq1m6QJ2XJ1AgjEjkI1v4Muzm7klianLE6XGxtmA=="], + + "sequoia-cli/@atproto/api/await-lock": ["await-lock@2.2.2", "", {}, "sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw=="], + + "sequoia-cli/@atproto/api/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="], + + "sequoia-cli/@atproto/api/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "signale/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], "signale/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="], @@ -2527,6 +2659,16 @@ "wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "@atproto-labs/identity-resolver/@atproto-labs/did-resolver/@atproto-labs/simple-store-memory/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "@atproto-labs/identity-resolver/@atproto-labs/handle-resolver/@atproto-labs/simple-store-memory/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "@atproto/oauth-client-browser/@atproto-labs/did-resolver/@atproto-labs/simple-store-memory/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "@atproto/oauth-client-browser/@atproto-labs/handle-resolver/@atproto-labs/simple-store-memory/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "@atproto/oauth-client-node/@atproto/oauth-client/@atproto/xrpc/@atproto/lexicon": ["@atproto/lexicon@0.6.2", "", { "dependencies": { "@atproto/common-web": "^0.4.18", "@atproto/syntax": "^0.5.0", "iso-datestring-validator": "^2.2.2", "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-p3Ly6hinVZW0ETuAXZMeUGwuMm3g8HvQMQ41yyEE6AL0hAkfeKFaZKos6BdBrr6CjkpbrDZqE8M+5+QOceysMw=="], + "@semantic-release/npm/tempy/unique-string/crypto-random-string": ["crypto-random-string@4.0.0", "", { "dependencies": { "type-fest": "^1.0.1" } }, "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA=="], "cli-highlight/chalk/ansi-styles/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], @@ -2557,10 +2699,18 @@ "semantic-release/yargs/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + "sequoia-cli/@atproto/api/@atproto/common-web/@atproto/syntax": ["@atproto/syntax@0.5.4", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-9XJOpMAgsGFxMEIp8nJ8AIWv+krrY1xQMj+wULbbXhQztQV+9aZ0TbG9Jtn3Op2or8Kr6OqyWR4ga9Z189kKDw=="], + + "sequoia-cli/@atproto/api/@atproto/lexicon/@atproto/syntax": ["@atproto/syntax@0.5.4", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-9XJOpMAgsGFxMEIp8nJ8AIWv+krrY1xQMj+wULbbXhQztQV+9aZ0TbG9Jtn3Op2or8Kr6OqyWR4ga9Z189kKDw=="], + "signale/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], "wrap-ansi/ansi-styles/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + "@atproto/oauth-client-node/@atproto/oauth-client/@atproto/xrpc/@atproto/lexicon/@atproto/common-web": ["@atproto/common-web@0.4.21", "", { "dependencies": { "@atproto/lex-data": "^0.0.15", "@atproto/lex-json": "^0.0.16", "@atproto/syntax": "^0.5.4", "zod": "^3.23.8" } }, "sha512-Odq+wdk3YNasGCjjlpl3bCIPvqYHige5DLfMkIffNv/2PI/iIj5ZvAvMvJlJ59OhReKSxtpI0invx5UQPc3+fw=="], + + "@atproto/oauth-client-node/@atproto/oauth-client/@atproto/xrpc/@atproto/lexicon/@atproto/syntax": ["@atproto/syntax@0.5.4", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-9XJOpMAgsGFxMEIp8nJ8AIWv+krrY1xQMj+wULbbXhQztQV+9aZ0TbG9Jtn3Op2or8Kr6OqyWR4ga9Z189kKDw=="], + "@semantic-release/npm/tempy/unique-string/crypto-random-string/type-fest": ["type-fest@1.4.0", "", {}, "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA=="], "cli-highlight/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], diff --git a/packages/docs/next.config.mts b/packages/docs/next.config.mts index e333034..7d5cb7d 100644 --- a/packages/docs/next.config.mts +++ b/packages/docs/next.config.mts @@ -2,6 +2,7 @@ import { createMDX } from "fumadocs-mdx/next"; import type { NextConfig } from "next"; const config: NextConfig = { + allowedDevOrigins: ["127.0.0.1"], transpilePackages: ["@happyview/design-system"], }; diff --git a/packages/docs/package.json b/packages/docs/package.json index 48c28ea..14535cd 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -10,6 +10,8 @@ "start": "next start" }, "dependencies": { + "@atproto/api": "^0.20.25", + "@atproto/oauth-client-browser": "^0.4.5", "@happyview/design-system": "workspace:*", "@tailwindcss/postcss": "^4.2.0", "@types/mdast": "^4.0.4", diff --git a/packages/docs/src/app/blog/[slug]/page.tsx b/packages/docs/src/app/blog/[slug]/page.tsx index 74e0bbc..7e2f3a8 100644 --- a/packages/docs/src/app/blog/[slug]/page.tsx +++ b/packages/docs/src/app/blog/[slug]/page.tsx @@ -2,7 +2,8 @@ import { blogSource } from '@/lib/source'; import { notFound } from 'next/navigation'; import defaultMdxComponents from 'fumadocs-ui/mdx'; import { Mermaid } from '@/components/mermaid'; -import { SequoiaCommentsLoader } from '@/components/sequoia-comments-loader'; +import { EngagementActions } from '@/components/engagement-actions'; +import { SequoiaLoader } from '@/components/sequoia-loader'; import { VaporwaveGrid } from '@/components/vaporwave-grid'; import { getSequoiaPublicationUri } from '@/lib/sequoia'; import Image from 'next/image'; @@ -27,6 +28,7 @@ export default async function BlogPost(props: { {atUri && ( )} +

{title}

{description && ( @@ -79,8 +81,8 @@ export default async function BlogPost(props: {
-
- +
+
diff --git a/packages/docs/src/app/oauth-client-metadata.json/route.ts b/packages/docs/src/app/oauth-client-metadata.json/route.ts new file mode 100644 index 0000000..058e142 --- /dev/null +++ b/packages/docs/src/app/oauth-client-metadata.json/route.ts @@ -0,0 +1,18 @@ +import { NextRequest } from 'next/server'; + +export function GET(request: NextRequest) { + const origin = new URL(request.url).origin; + + return Response.json({ + client_id: `${origin}/oauth-client-metadata.json`, + client_name: 'HappyView', + client_uri: origin, + redirect_uris: [`${origin}/oauth/callback`], + grant_types: ['authorization_code'], + response_types: ['code'], + scope: 'atproto transition:generic', + token_endpoint_auth_method: 'none', + application_type: 'web', + dpop_bound_access_tokens: true, + }); +} diff --git a/packages/docs/src/app/oauth/callback/page.tsx b/packages/docs/src/app/oauth/callback/page.tsx new file mode 100644 index 0000000..1fe9825 --- /dev/null +++ b/packages/docs/src/app/oauth/callback/page.tsx @@ -0,0 +1,48 @@ +'use client'; + +import { useEffect, useState } from 'react'; +import { getOAuthClient } from '@/lib/atproto-oauth'; + +export default function OAuthCallback() { + const [error, setError] = useState(null); + + useEffect(() => { + getOAuthClient() + .then((client) => client.init()) + .then((result) => { + const returnUrl = result?.state ?? '/blog'; + window.location.replace(returnUrl); + }) + .catch((err) => { + setError(err instanceof Error ? err.message : 'Login failed'); + }); + }, []); + + if (error) { + return ( +
+

+ Login Failed +

+

+ {error} +

+ + Back to blog + +
+ ); + } + + return ( +
+

+ Completing login... +

+
+ ); +} diff --git a/packages/docs/src/components/engagement-actions.tsx b/packages/docs/src/components/engagement-actions.tsx new file mode 100644 index 0000000..8abb09b --- /dev/null +++ b/packages/docs/src/components/engagement-actions.tsx @@ -0,0 +1,403 @@ +'use client'; + +import { useCallback, useEffect, useRef, useState } from 'react'; +import { Agent } from '@atproto/api'; +import { BrowserOAuthClient } from '@atproto/oauth-client-browser'; +import { getOAuthClient } from '@/lib/atproto-oauth'; + +type OAuthSession = Awaited>; +type PendingAction = 'recommend' | 'subscribe'; + +interface EngagementActionsProps { + documentUri?: string; + publicationUri?: string; +} + +export function EngagementActions({ documentUri, publicationUri }: EngagementActionsProps) { + const clientRef = useRef(null); + const [session, setSession] = useState(null); + const [showLogin, setShowLogin] = useState(false); + const [pendingAction, setPendingAction] = useState(null); + const [recommended, setRecommended] = useState(false); + const [subscribed, setSubscribed] = useState(false); + const [loading, setLoading] = useState(null); + + useEffect(() => { + let cancelled = false; + + (async () => { + try { + const client = await getOAuthClient(); + if (cancelled) return; + clientRef.current = client; + const result = await client.init(); + if (!cancelled && result?.session) { + setSession(result.session); + } + } catch { + // OAuth init can fail on localhost — use http://127.0.0.1:PORT instead + } + })(); + + return () => { cancelled = true; }; + }, []); + + useEffect(() => { + if (!session) return; + + const agent = new Agent(session); + + if (documentUri) { + checkExistingRecord(agent, session.did, 'site.standard.graph.recommend', documentUri, 'document') + .then(setRecommended); + } + + if (publicationUri) { + checkExistingRecord(agent, session.did, 'site.standard.graph.subscription', publicationUri, 'publication') + .then(setSubscribed); + } + }, [session, documentUri, publicationUri]); + + const handleAction = useCallback((action: PendingAction) => { + if (!session) { + setPendingAction(action); + setShowLogin(true); + return; + } + + performAction(session, action, documentUri, publicationUri, { + setRecommended, + setSubscribed, + setLoading, + }); + }, [session, documentUri, publicationUri]); + + useEffect(() => { + if (session && pendingAction) { + setPendingAction(null); + handleAction(pendingAction); + } + }, [session, pendingAction, handleAction]); + + const handleLogin = async (handle: string) => { + const client = clientRef.current; + if (!client) return; + + setShowLogin(false); + await client.signInRedirect(handle, { + state: window.location.href, + }); + }; + + const handleLogout = async () => { + if (!session || !clientRef.current) return; + await clientRef.current.revoke(session.did); + setSession(null); + setRecommended(false); + setSubscribed(false); + }; + + return ( +
+ {documentUri && ( + + )} + + {publicationUri && ( + + )} + + {session && ( + + )} + + {showLogin && ( + { + setShowLogin(false); + setPendingAction(null); + }} + /> + )} +
+ ); +} + +function LoginDialog({ + onSubmit, + onClose, +}: { + onSubmit: (handle: string) => void; + onClose: () => void; +}) { + const [handle, setHandle] = useState(''); + const inputRef = useRef(null); + + useEffect(() => { + inputRef.current?.focus(); + }, []); + + useEffect(() => { + const onKeyDown = (e: KeyboardEvent) => { + if (e.key === 'Escape') onClose(); + }; + window.addEventListener('keydown', onKeyDown); + return () => window.removeEventListener('keydown', onKeyDown); + }, [onClose]); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + const trimmed = handle.trim(); + if (trimmed) onSubmit(trimmed); + }; + + return ( +
{ + if (e.target === e.currentTarget) onClose(); + }} + > +
+

+ Log in with AT Protocol +

+

+ Enter your handle to continue. +

+
+ setHandle(e.target.value)} + placeholder="yourname.bsky.social" + className="rounded-lg px-3 py-2 text-sm outline-none" + style={{ + backgroundColor: 'rgb(var(--color-bg))', + color: 'rgb(var(--color-fg))', + borderWidth: '1px', + borderColor: 'rgb(var(--color-border))', + }} + /> +
+ + +
+
+
+
+ ); +} + +async function checkExistingRecord( + agent: Agent, + did: string, + collection: string, + targetUri: string, + subjectField: string, +): Promise { + try { + const { data } = await agent.com.atproto.repo.listRecords({ + repo: did, + collection, + limit: 100, + }); + return data.records.some( + (r) => (r.value as Record)[subjectField] === targetUri, + ); + } catch { + return false; + } +} + +async function performAction( + session: OAuthSession, + action: PendingAction, + documentUri: string | undefined, + publicationUri: string | undefined, + callbacks: { + setRecommended: (v: boolean) => void; + setSubscribed: (v: boolean) => void; + setLoading: (v: PendingAction | null) => void; + }, +) { + const agent = new Agent(session); + callbacks.setLoading(action); + + try { + if (action === 'recommend' && documentUri) { + const existing = await findExistingRecord( + agent, session.did, 'site.standard.graph.recommend', documentUri, 'document', + ); + + if (existing) { + await agent.com.atproto.repo.deleteRecord({ + repo: session.did, + collection: 'site.standard.graph.recommend', + rkey: existing.split('/').pop()!, + }); + callbacks.setRecommended(false); + } else { + await agent.com.atproto.repo.createRecord({ + repo: session.did, + collection: 'site.standard.graph.recommend', + record: { + $type: 'site.standard.graph.recommend', + document: documentUri, + createdAt: new Date().toISOString(), + }, + }); + callbacks.setRecommended(true); + } + } + + if (action === 'subscribe' && publicationUri) { + const existing = await findExistingRecord( + agent, session.did, 'site.standard.graph.subscription', publicationUri, 'publication', + ); + + if (existing) { + await agent.com.atproto.repo.deleteRecord({ + repo: session.did, + collection: 'site.standard.graph.subscription', + rkey: existing.split('/').pop()!, + }); + callbacks.setSubscribed(false); + } else { + await agent.com.atproto.repo.createRecord({ + repo: session.did, + collection: 'site.standard.graph.subscription', + record: { + $type: 'site.standard.graph.subscription', + publication: publicationUri, + createdAt: new Date().toISOString(), + }, + }); + callbacks.setSubscribed(true); + } + } + } catch (err) { + console.error(`Failed to ${action}:`, err); + } finally { + callbacks.setLoading(null); + } +} + +async function findExistingRecord( + agent: Agent, + did: string, + collection: string, + targetUri: string, + subjectField: string, +): Promise { + try { + const { data } = await agent.com.atproto.repo.listRecords({ + repo: did, + collection, + limit: 100, + }); + const match = data.records.find( + (r) => (r.value as Record)[subjectField] === targetUri, + ); + return match?.uri ?? null; + } catch { + return null; + } +} + +function HeartIcon({ filled }: { filled: boolean }) { + return ( + + + + ); +} + +function BellIcon({ filled }: { filled: boolean }) { + return ( + + + + + ); +} diff --git a/packages/docs/src/components/sequoia-comments-loader.tsx b/packages/docs/src/components/sequoia-loader.tsx similarity index 76% rename from packages/docs/src/components/sequoia-comments-loader.tsx rename to packages/docs/src/components/sequoia-loader.tsx index 5256cbf..15fad0c 100644 --- a/packages/docs/src/components/sequoia-comments-loader.tsx +++ b/packages/docs/src/components/sequoia-loader.tsx @@ -2,7 +2,7 @@ import { useEffect } from 'react'; -export function SequoiaCommentsLoader() { +export function SequoiaLoader() { useEffect(() => { import('./sequoia-comments.js'); }, []); diff --git a/packages/docs/src/lib/atproto-oauth.ts b/packages/docs/src/lib/atproto-oauth.ts new file mode 100644 index 0000000..83b4c45 --- /dev/null +++ b/packages/docs/src/lib/atproto-oauth.ts @@ -0,0 +1,28 @@ +import { BrowserOAuthClient } from '@atproto/oauth-client-browser'; + +let clientPromise: Promise | null = null; + +export function getOAuthClient(): Promise { + if (!clientPromise) { + const origin = window.location.origin; + const isLoopback = origin.startsWith('http://localhost') || origin.startsWith('http://127.0.0.1'); + + if (isLoopback) { + const port = window.location.port; + const redirectUri = `http://127.0.0.1:${port}/oauth/callback`; + const clientId = `http://localhost?redirect_uri=${encodeURIComponent(redirectUri)}&scope=${encodeURIComponent('atproto transition:generic')}`; + + clientPromise = BrowserOAuthClient.load({ + clientId, + handleResolver: 'https://bsky.social', + }); + } else { + clientPromise = BrowserOAuthClient.load({ + clientId: `${origin}/oauth-client-metadata.json`, + handleResolver: 'https://bsky.social', + }); + } + } + + return clientPromise; +} -- 2.51.2